#include <stdlib.h>
#include <error.h>
#include <unistd.h>

#include <X11/Xlib.h>
#include <X11/Xft/Xft.h>

#include <cairo.h>
#include <cairo-xlib.h>
#include <cairo-ft.h>

#include <pango/pangocairo.h>

static void
pango_draw_text(cairo_t *cr,
                const char *fontname,
                const char *text)
{
  PangoLayout *layout = pango_cairo_create_layout(cr);
  PangoFontDescription *font_desc = pango_font_description_from_string(fontname);

  pango_layout_set_text(layout, text, -1);
  pango_layout_set_font_description(layout, font_desc);

  /* Get extents */
  PangoRectangle ext;
  pango_layout_get_pixel_extents(layout, NULL, &ext);

  PangoContext *context = pango_layout_get_context(layout);
  PangoFontMetrics *font_metrics = pango_context_get_metrics(context, font_desc, NULL);

  printf("PANGO\nx: %d\ny: %d\nwidth: %d\nheight: %d\nascent: %d\ndescent: %d\n",
         ext.x, ext.y, ext.width, ext.height,
         PANGO_PIXELS(pango_font_metrics_get_ascent(font_metrics)),
         PANGO_PIXELS(pango_font_metrics_get_descent(font_metrics)));

  pango_font_description_free(font_desc);
  g_object_unref(layout);
}

static void
cairo_draw_text(Display *display,
                const int screen,
                cairo_t *cr,
                const char *fontname,
                const char *text)
{
  XftFont *font = XftFontOpenName(display, screen, fontname);

  cairo_font_face_t *font_face = cairo_ft_font_face_create_for_pattern(font->pattern);

  cairo_set_font_face(cr, font_face);
  cairo_set_font_size(cr, font->height);

  cairo_text_extents_t te;
  cairo_text_extents(cr, text, &te);

  printf("XFT\nx_bearing: %.2f\ny_bearing: %.2f\nwidth: %.2f\n"
         "height: %.2f\nx_advance: %.2f\ny_advance: %.2f\nascent: %d\ndescent: %d\n",
         te.x_bearing, te.y_bearing, te.width, te.height,
         te.x_advance, te.y_advance, font->ascent, font->descent);

  cairo_font_face_destroy(font_face);
  XftFontClose(display, font);
}

int
main(void)
{
  Display *display;
  if(!(display = XOpenDisplay(NULL)))
    error(EXIT_FAILURE, 0, "Cannot open display");

  int screen = DefaultScreen(display);
  Window win = XCreateSimpleWindow(display,
                                   RootWindow(display, screen),
                                   1, 1,
                                   DisplayWidth(display, screen),
                                   DisplayHeight(display, screen),
                                   0,
                                   WhitePixel(display, screen),
                                   WhitePixel(display, screen));

  XStoreName(display, win, "hello");
  XMapWindow(display, win);

  cairo_surface_t *surface = cairo_xlib_surface_create(display, win,
                                                       DefaultVisual(display, screen),
                                                       DisplayWidth(display, screen),
                                                       DisplayHeight(display, screen));

  cairo_t *cr = cairo_create(surface);

  const char *text = "Text rendering using cairo";

  /* Display the text using xft and cairo */
  cairo_draw_text(display, screen, cr, "vera-10", text);

  cairo_set_source_rgb(cr, 0.0, 0.0, 0.0);
  cairo_move_to(cr, 200, 20);
  cairo_show_text(cr, text);
  /* End drawing using xft and cairo */

  /* Display the text using pango and cairo */
  pango_draw_text(cr, "vera 10", text);

  cairo_set_source_rgb(cr, 0.0, 0.0, 0.0);
  cairo_move_to(cr, 0, 20);
  cairo_show_text(cr, text);
  /* End drawing using pango and cairo */

  XSync(display, False);
  pause();
  
  cairo_destroy(cr);
  cairo_surface_destroy(surface);

  XCloseDisplay(display);

  return EXIT_SUCCESS;
}

