1 /* GTK - The GIMP Toolkit
2 * gtkprintcontext.c: Print Context
3 * Copyright (C) 2006, Red Hat, Inc.
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
22 #include "gtkprintoperation-private.h"
24 typedef struct _GtkPrintContextClass GtkPrintContextClass;
26 #define GTK_IS_PRINT_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_PRINT_CONTEXT))
27 #define GTK_PRINT_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_PRINT_CONTEXT, GtkPrintContextClass))
28 #define GTK_PRINT_CONTEXT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_PRINT_CONTEXT, GtkPrintContextClass))
30 #define MM_PER_INCH 25.4
31 #define POINTS_PER_INCH 72
33 struct _GtkPrintContext
35 GObject parent_instance;
37 GtkPrintOperation *op;
39 GtkPageSetup *page_setup;
41 gdouble surface_dpi_x;
42 gdouble surface_dpi_y;
44 gdouble pixels_per_unit_x;
45 gdouble pixels_per_unit_y;
47 gboolean has_hard_margins;
48 gdouble hard_margin_top;
49 gdouble hard_margin_bottom;
50 gdouble hard_margin_left;
51 gdouble hard_margin_right;
55 struct _GtkPrintContextClass
57 GObjectClass parent_class;
60 G_DEFINE_TYPE (GtkPrintContext, gtk_print_context, G_TYPE_OBJECT)
63 gtk_print_context_finalize (GObject *object)
65 GtkPrintContext *context = GTK_PRINT_CONTEXT (object);
67 if (context->page_setup)
68 g_object_unref (context->page_setup);
71 cairo_destroy (context->cr);
73 G_OBJECT_CLASS (gtk_print_context_parent_class)->finalize (object);
77 gtk_print_context_init (GtkPrintContext *context)
82 gtk_print_context_class_init (GtkPrintContextClass *class)
84 GObjectClass *gobject_class = (GObjectClass *)class;
86 gobject_class->finalize = gtk_print_context_finalize;
91 _gtk_print_context_new (GtkPrintOperation *op)
93 GtkPrintContext *context;
95 context = g_object_new (GTK_TYPE_PRINT_CONTEXT, NULL);
99 context->has_hard_margins = FALSE;
104 static PangoFontMap *
105 _gtk_print_context_get_fontmap (GtkPrintContext *context)
107 return pango_cairo_font_map_get_default ();
111 * gtk_print_context_set_cairo_context:
112 * @context: a #GtkPrintContext
113 * @cr: the cairo context
114 * @dpi_x: the horizontal resolution to use with @cr
115 * @dpi_y: the vertical resolution to use with @cr
117 * Sets a new cairo context on a print context.
119 * This function is intended to be used when implementing
120 * an internal print preview, it is not needed for printing,
121 * since GTK+ itself creates a suitable cairo context in that
127 gtk_print_context_set_cairo_context (GtkPrintContext *context,
133 cairo_destroy (context->cr);
135 context->cr = cairo_reference (cr);
136 context->surface_dpi_x = dpi_x;
137 context->surface_dpi_y = dpi_y;
139 switch (context->op->priv->unit)
143 /* Do nothing, this is the cairo default unit */
144 context->pixels_per_unit_x = 1.0;
145 context->pixels_per_unit_y = 1.0;
147 case GTK_UNIT_POINTS:
148 context->pixels_per_unit_x = dpi_x / POINTS_PER_INCH;
149 context->pixels_per_unit_y = dpi_y / POINTS_PER_INCH;
152 context->pixels_per_unit_x = dpi_x;
153 context->pixels_per_unit_y = dpi_y;
156 context->pixels_per_unit_x = dpi_x / MM_PER_INCH;
157 context->pixels_per_unit_y = dpi_y / MM_PER_INCH;
160 cairo_scale (context->cr,
161 context->pixels_per_unit_x,
162 context->pixels_per_unit_y);
167 _gtk_print_context_rotate_according_to_orientation (GtkPrintContext *context)
169 cairo_t *cr = context->cr;
170 cairo_matrix_t matrix;
171 GtkPaperSize *paper_size;
172 gdouble width, height;
174 paper_size = gtk_page_setup_get_paper_size (context->page_setup);
176 width = gtk_paper_size_get_width (paper_size, GTK_UNIT_INCH);
177 width = width * context->surface_dpi_x / context->pixels_per_unit_x;
178 height = gtk_paper_size_get_height (paper_size, GTK_UNIT_INCH);
179 height = height * context->surface_dpi_y / context->pixels_per_unit_y;
181 switch (gtk_page_setup_get_orientation (context->page_setup))
184 case GTK_PAGE_ORIENTATION_PORTRAIT:
186 case GTK_PAGE_ORIENTATION_LANDSCAPE:
187 cairo_translate (cr, 0, height);
188 cairo_matrix_init (&matrix,
192 cairo_transform (cr, &matrix);
194 case GTK_PAGE_ORIENTATION_REVERSE_PORTRAIT:
195 cairo_translate (cr, width, height);
196 cairo_matrix_init (&matrix,
200 cairo_transform (cr, &matrix);
202 case GTK_PAGE_ORIENTATION_REVERSE_LANDSCAPE:
203 cairo_translate (cr, width, 0);
204 cairo_matrix_init (&matrix,
208 cairo_transform (cr, &matrix);
214 _gtk_print_context_translate_into_margin (GtkPrintContext *context)
218 g_return_if_fail (GTK_IS_PRINT_CONTEXT (context));
220 /* We do it this way to also handle GTK_UNIT_PIXELS */
221 left = gtk_page_setup_get_left_margin (context->page_setup, GTK_UNIT_INCH);
222 top = gtk_page_setup_get_top_margin (context->page_setup, GTK_UNIT_INCH);
224 cairo_translate (context->cr,
225 left * context->surface_dpi_x / context->pixels_per_unit_x,
226 top * context->surface_dpi_y / context->pixels_per_unit_y);
230 _gtk_print_context_set_page_setup (GtkPrintContext *context,
231 GtkPageSetup *page_setup)
233 g_return_if_fail (GTK_IS_PRINT_CONTEXT (context));
234 g_return_if_fail (page_setup == NULL ||
235 GTK_IS_PAGE_SETUP (page_setup));
237 g_object_ref (page_setup);
239 if (context->page_setup != NULL)
240 g_object_unref (context->page_setup);
242 context->page_setup = page_setup;
246 * gtk_print_context_get_cairo_context:
247 * @context: a #GtkPrintContext
249 * Obtains the cairo context that is associated with the
252 * Return value: (transfer none): the cairo context of @context
257 gtk_print_context_get_cairo_context (GtkPrintContext *context)
259 g_return_val_if_fail (GTK_IS_PRINT_CONTEXT (context), NULL);
265 * gtk_print_context_get_page_setup:
266 * @context: a #GtkPrintContext
268 * Obtains the #GtkPageSetup that determines the page
269 * dimensions of the #GtkPrintContext.
271 * Return value: (transfer none): the page setup of @context
276 gtk_print_context_get_page_setup (GtkPrintContext *context)
278 g_return_val_if_fail (GTK_IS_PRINT_CONTEXT (context), NULL);
280 return context->page_setup;
284 * gtk_print_context_get_width:
285 * @context: a #GtkPrintContext
287 * Obtains the width of the #GtkPrintContext, in pixels.
289 * Return value: the width of @context
294 gtk_print_context_get_width (GtkPrintContext *context)
296 GtkPrintOperationPrivate *priv;
299 g_return_val_if_fail (GTK_IS_PRINT_CONTEXT (context), 0);
301 priv = context->op->priv;
303 if (priv->use_full_page)
304 width = gtk_page_setup_get_paper_width (context->page_setup, GTK_UNIT_INCH);
306 width = gtk_page_setup_get_page_width (context->page_setup, GTK_UNIT_INCH);
308 /* Really dpi_x? What about landscape? what does dpi_x mean in that case? */
309 return width * context->surface_dpi_x / context->pixels_per_unit_x;
313 * gtk_print_context_get_height:
314 * @context: a #GtkPrintContext
316 * Obtains the height of the #GtkPrintContext, in pixels.
318 * Return value: the height of @context
323 gtk_print_context_get_height (GtkPrintContext *context)
325 GtkPrintOperationPrivate *priv;
328 g_return_val_if_fail (GTK_IS_PRINT_CONTEXT (context), 0);
330 priv = context->op->priv;
332 if (priv->use_full_page)
333 height = gtk_page_setup_get_paper_height (context->page_setup, GTK_UNIT_INCH);
335 height = gtk_page_setup_get_page_height (context->page_setup, GTK_UNIT_INCH);
337 /* Really dpi_y? What about landscape? what does dpi_y mean in that case? */
338 return height * context->surface_dpi_y / context->pixels_per_unit_y;
342 * gtk_print_context_get_dpi_x:
343 * @context: a #GtkPrintContext
345 * Obtains the horizontal resolution of the #GtkPrintContext,
348 * Return value: the horizontal resolution of @context
353 gtk_print_context_get_dpi_x (GtkPrintContext *context)
355 g_return_val_if_fail (GTK_IS_PRINT_CONTEXT (context), 0);
357 return context->surface_dpi_x;
361 * gtk_print_context_get_dpi_y:
362 * @context: a #GtkPrintContext
364 * Obtains the vertical resolution of the #GtkPrintContext,
367 * Return value: the vertical resolution of @context
372 gtk_print_context_get_dpi_y (GtkPrintContext *context)
374 g_return_val_if_fail (GTK_IS_PRINT_CONTEXT (context), 0);
376 return context->surface_dpi_y;
380 * gtk_print_context_get_hard_margins:
381 * @context: a #GtkPrintContext
382 * @top: (out): top hardware printer margin
383 * @bottom: (out): bottom hardware printer margin
384 * @left: (out): left hardware printer margin
385 * @right: (out): right hardware printer margin
387 * Obtains the hardware printer margins of the #GtkPrintContext, in units.
389 * Return value: %TRUE if the hard margins were retrieved
394 gtk_print_context_get_hard_margins (GtkPrintContext *context,
400 if (context->has_hard_margins)
402 *top = context->hard_margin_top / context->pixels_per_unit_y;
403 *bottom = context->hard_margin_bottom / context->pixels_per_unit_y;
404 *left = context->hard_margin_left / context->pixels_per_unit_x;
405 *right = context->hard_margin_right / context->pixels_per_unit_x;
408 return context->has_hard_margins;
412 * gtk_print_context_set_hard_margins:
413 * @context: a #GtkPrintContext
414 * @top: top hardware printer margin
415 * @bottom: bottom hardware printer margin
416 * @left: left hardware printer margin
417 * @right: right hardware printer margin
419 * set the hard margins in pixel coordinates
422 _gtk_print_context_set_hard_margins (GtkPrintContext *context,
428 context->hard_margin_top = top;
429 context->hard_margin_bottom = bottom;
430 context->hard_margin_left = left;
431 context->hard_margin_right = right;
432 context->has_hard_margins = TRUE;
436 * gtk_print_context_get_pango_fontmap:
437 * @context: a #GtkPrintContext
439 * Returns a #PangoFontMap that is suitable for use
440 * with the #GtkPrintContext.
442 * Return value: (transfer none): the font map of @context
447 gtk_print_context_get_pango_fontmap (GtkPrintContext *context)
449 g_return_val_if_fail (GTK_IS_PRINT_CONTEXT (context), NULL);
451 return _gtk_print_context_get_fontmap (context);
455 * gtk_print_context_create_pango_context:
456 * @context: a #GtkPrintContext
458 * Creates a new #PangoContext that can be used with the
461 * Return value: (transfer full): a new Pango context for @context
466 gtk_print_context_create_pango_context (GtkPrintContext *context)
468 PangoContext *pango_context;
469 cairo_font_options_t *options;
471 g_return_val_if_fail (GTK_IS_PRINT_CONTEXT (context), NULL);
473 pango_context = pango_cairo_font_map_create_context (PANGO_CAIRO_FONT_MAP (_gtk_print_context_get_fontmap (context)));
475 options = cairo_font_options_create ();
476 cairo_font_options_set_hint_metrics (options, CAIRO_HINT_METRICS_OFF);
477 pango_cairo_context_set_font_options (pango_context, options);
478 cairo_font_options_destroy (options);
480 /* We use the unit-scaled resolution, as we still want
481 * fonts given in points to work
483 pango_cairo_context_set_resolution (pango_context,
484 context->surface_dpi_y / context->pixels_per_unit_y);
485 return pango_context;
489 * gtk_print_context_create_pango_layout:
490 * @context: a #GtkPrintContext
492 * Creates a new #PangoLayout that is suitable for use
493 * with the #GtkPrintContext.
495 * Return value: (transfer full): a new Pango layout for @context
500 gtk_print_context_create_pango_layout (GtkPrintContext *context)
502 PangoContext *pango_context;
505 g_return_val_if_fail (GTK_IS_PRINT_CONTEXT (context), NULL);
507 pango_context = gtk_print_context_create_pango_context (context);
508 layout = pango_layout_new (pango_context);
510 pango_cairo_update_context (context->cr, pango_context);
511 g_object_unref (pango_context);