/*
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 :-/.
P.s.: also see
https://bugzilla.gnome.org/show_bug.cgi?id=519146 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;
}
--
Iván Baldo