#include <gtk/gtk.h>

typedef struct {
    PangoFontDescription *font;
    char *string;
    gboolean preview;
} Stuff;

static void
begin_print (GtkPrintOperation *operation,
             GtkPrintContext   *context)
{
    gtk_print_operation_set_n_pages (operation, 1);
}

static void
draw_page (GtkPrintOperation *operation,
           GtkPrintContext   *context,
           gint               page_nr,
           Stuff             *stuff)
{
    PangoLayout *layout;
    cairo_t *cr;
    double y, page_height, line_height;
    PangoRectangle rect;
    char *string;
    int i;

    cr = gtk_print_context_get_cairo_context (context);

    layout = gtk_print_context_create_pango_layout (context);

    if (stuff->font)
        pango_layout_set_font_description (layout, stuff->font);

    page_height = gtk_print_context_get_height (context);
    y = 0.;
    i = 0;

    while (TRUE)
    {
        string = g_strdup_printf ("%03d %s", ++i, stuff->string);
        pango_layout_set_text (layout, string, -1);
        g_free (string);

        pango_layout_get_extents (layout, NULL, &rect);
        line_height = (double) rect.height / (double) PANGO_SCALE;

        if (y + line_height >= page_height)
            break;

        cairo_move_to (cr, 0., y);
        pango_cairo_show_layout (cr, layout);
        y += line_height;
    }
}


static void
do_print (const char *pdf_file,
          Stuff      *stuff)
{
    GtkPrintOperation *operation;
    GError *error = NULL;
    PangoFontDescription *font;
    GtkPrintOperationAction action = GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG;

    operation = gtk_print_operation_new ();
    g_signal_connect (G_OBJECT (operation), "begin-print",
                      G_CALLBACK (begin_print), stuff);
    g_signal_connect (G_OBJECT (operation), "draw-page",
                      G_CALLBACK (draw_page), stuff);

    if (pdf_file)
    {
        action = GTK_PRINT_OPERATION_ACTION_EXPORT;
        g_object_set (operation, "export-filename", pdf_file, NULL);
    }
    else if (stuff->preview)
    {
        action = GTK_PRINT_OPERATION_ACTION_PREVIEW;
    }

    gtk_print_operation_run (operation, action, NULL, NULL);

    g_object_unref (operation);
}


int
main (int argc, char *argv[])
{
    GOptionContext *opt_ctx;
    char *pdf_file = NULL;
    char *font = NULL;
    Stuff stuff = {NULL, NULL, FALSE};

    GOptionEntry opt_entries[] =
    {
      { "pdf", 0, 0, G_OPTION_ARG_FILENAME, &pdf_file, "Pdf file to create", "FILE" },
      { "font", 0, 0, G_OPTION_ARG_STRING, &font, "Font to use", "FONT" },
      { "string", 0, 0, G_OPTION_ARG_STRING, &stuff.string, "String to print", "STRING" },
      { "preview", 0, 0, G_OPTION_ARG_NONE, &stuff.preview, "Show print preview instead of printing", NULL },
      { NULL }
    };

    opt_ctx = g_option_context_new ("- test printing");
    g_option_context_add_main_entries (opt_ctx, opt_entries, NULL);
    g_option_context_add_group (opt_ctx, gtk_get_option_group (TRUE));
    g_option_context_parse (opt_ctx, &argc, &argv, NULL);

    if (font)
        stuff.font = pango_font_description_from_string (font);
    if (!stuff.string)
        stuff.string = g_strdup ("Blah blah blah");

    do_print (pdf_file, &stuff);

    return 0;
}
