/*
    I prefer to treat the distances in the page in millimeters, so I call
gtk_print_operation_set_unit (po, GTK_UNIT_MM), but then the <sup> and <sub> tags of Pango markup
look ugly; commenting that function call fixes the problem but then I don't have distances in
millimeters.
    I guess I could put a transformation in my Cairo context as a workaround but I would like to
know what I am doing wrong or what I am missing :-/.

    Compile with:
gcc pango_problem.c `pkg-config --cflags --libs gtk+-3.0` -o pango_problem
*/
#include <gtk/gtk.h>


static void beginprint (GtkPrintOperation * const po, GtkPrintContext * const pc, gpointer data)
{
    //Doesn't set it in millimeters, it fails, gets ignored or is too late to apply:
    //gtk_print_operation_set_unit (po, GTK_UNIT_MM);
    gtk_print_operation_set_n_pages (po, 1);
}


static void drawpage (GtkPrintOperation * const po, GtkPrintContext * const pc, const gint pagenum,
    gpointer data)
{
    //Doesn't set it in millimeters, it fails, gets ignored or is too late to apply:
    //gtk_print_operation_set_unit (po, GTK_UNIT_MM);
    cairo_t * const cr = gtk_print_context_get_cairo_context (pc);
    PangoLayout * const pl = gtk_print_context_create_pango_layout (pc);
    PangoFontDescription * const pfd = pango_font_description_from_string (
            "lucida sans typewriter,lucida console,courier new,monospace 7");
    pango_layout_set_font_description (pl, pfd);
    pango_font_description_free (pfd);
    pango_layout_set_width (pl, gtk_print_context_get_width(pc) * PANGO_SCALE);
    pango_layout_set_alignment (pl, PANGO_ALIGN_LEFT);

    cairo_rectangle (cr, 20.0, 20.0, 50.0, 50.0); //50 millimeters = 5 centimeters.
    cairo_stroke (cr);

    cairo_move_to (cr, 20.0, 80.0);
    int plwidth, plheight;

    pango_layout_set_markup (pl, "First line, ignore.\n", -1);
    pango_layout_get_size (pl, &plwidth, &plheight);
    pango_cairo_show_layout (cr, pl);
    cairo_rel_move_to (cr, 0, pango_units_to_double(plheight));
    fprintf (stderr, "Pango Units %i, Double %f.\n", plheight, pango_units_to_double(plheight));

    pango_layout_set_markup (pl, "First a <sub>subscript</sub> then a <sup>superscript</sup>.\n",
        -1);
    pango_layout_get_size (pl, &plwidth, &plheight);
    pango_cairo_show_layout (cr, pl);
    cairo_rel_move_to (cr, 0, pango_units_to_double(plheight));
    fprintf (stderr, "Pango Units %i, Double %f.\n", plheight, pango_units_to_double(plheight));

    pango_layout_set_markup (pl, "Last line, ignore.\n", -1);
    pango_layout_get_size (pl, &plwidth, &plheight);
    pango_cairo_show_layout (cr, pl);
    cairo_rel_move_to (cr, 0, pango_units_to_double(plheight));
    fprintf (stderr, "Pango Units %i, Double %f.\n", plheight, pango_units_to_double(plheight));

    g_object_unref (pl);
}


static void button_clicked (GtkButton *button, gpointer user_data)
{
    GtkPrintOperation * const po = gtk_print_operation_new ();
    g_signal_connect (po, "begin-print", G_CALLBACK (beginprint), NULL);
    g_signal_connect (po, "draw-page", G_CALLBACK (drawpage), NULL);
    gtk_print_operation_set_use_full_page (po, TRUE);
    //Commenting out the following line fixes the problem with <sub> and <sup> but then it is not in
    //millimeters:
    gtk_print_operation_set_unit (po, GTK_UNIT_MM);
    gtk_print_operation_set_embed_page_setup (po, TRUE);
    GError *err = NULL;
    gtk_print_operation_run (po, GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG, user_data, &err);
    g_object_unref (po);
    if (err) {
        fprintf (stderr, "Error printing: %s.\n", err->message);
        g_error_free (err);
    }
}


static void activate (GtkApplication *app, gpointer user_data)
{
    GtkWidget * const window = gtk_application_window_new (app);
    gtk_window_set_title (GTK_WINDOW (window), "Pango Problem");
    //gtk_window_set_default_size (GTK_WINDOW (window), 210, 70);
    gtk_container_set_border_width (GTK_CONTAINER (window), 5);

    GtkWidget * const button = gtk_button_new_with_label ("Print Dialog");
    g_signal_connect (button, "clicked", G_CALLBACK (button_clicked), window);

    /* Create a grid and arrange everything accordingly */
    GtkWidget * const grid = gtk_grid_new ();
    gtk_grid_set_column_spacing (GTK_GRID (grid), 5);
    //gtk_grid_set_column_homogeneous (GTK_GRID (grid), TRUE);
    gtk_grid_attach (GTK_GRID (grid), button, 0, 0, 1, 1);

    gtk_container_add (GTK_CONTAINER (window), grid);

    gtk_widget_show_all (window);
}


int main (int argc, char **argv)
{
    GtkApplication *app;
    int status;

    app = gtk_application_new ("org.gtk.example", G_APPLICATION_FLAGS_NONE);
    g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
    status = g_application_run (G_APPLICATION (app), argc, argv);
    g_object_unref (app);

    return status;
}

