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"
25 typedef struct _GtkPrintContextClass GtkPrintContextClass;
27 #define GTK_IS_PRINT_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_PRINT_CONTEXT))
28 #define GTK_PRINT_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_PRINT_CONTEXT, GtkPrintContextClass))
29 #define GTK_PRINT_CONTEXT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_PRINT_CONTEXT, GtkPrintContextClass))
31 #define MM_PER_INCH 25.4
32 #define POINTS_PER_INCH 72
34 struct _GtkPrintContext
36 GObject parent_instance;
38 GtkPrintOperation *op;
40 GtkPageSetup *page_setup;
42 gdouble surface_dpi_x;
43 gdouble surface_dpi_y;
45 gdouble pixels_per_unit_x;
46 gdouble pixels_per_unit_y;
48 gboolean has_hard_margins;
49 gdouble hard_margin_top;
50 gdouble hard_margin_bottom;
51 gdouble hard_margin_left;
52 gdouble hard_margin_right;
56 struct _GtkPrintContextClass
58 GObjectClass parent_class;
61 G_DEFINE_TYPE (GtkPrintContext, gtk_print_context, G_TYPE_OBJECT)
64 gtk_print_context_finalize (GObject *object)
66 GtkPrintContext *context = GTK_PRINT_CONTEXT (object);
68 if (context->page_setup)
69 g_object_unref (context->page_setup);
72 cairo_destroy (context->cr);
74 G_OBJECT_CLASS (gtk_print_context_parent_class)->finalize (object);
78 gtk_print_context_init (GtkPrintContext *context)
83 gtk_print_context_class_init (GtkPrintContextClass *class)
85 GObjectClass *gobject_class = (GObjectClass *)class;
87 gobject_class->finalize = gtk_print_context_finalize;
92 _gtk_print_context_new (GtkPrintOperation *op)
94 GtkPrintContext *context;
96 context = g_object_new (GTK_TYPE_PRINT_CONTEXT, NULL);
100 context->has_hard_margins = FALSE;
105 static PangoFontMap *
106 _gtk_print_context_get_fontmap (GtkPrintContext *context)
108 return pango_cairo_font_map_get_default ();
112 * gtk_print_context_set_cairo_context:
113 * @context: a #GtkPrintContext
114 * @cr: the cairo context
115 * @dpi_x: the horizontal resolution to use with @cr
116 * @dpi_y: the vertical resolution to use with @cr
118 * Sets a new cairo context on a print context.
120 * This function is intended to be used when implementing
121 * an internal print preview, it is not needed for printing,
122 * since GTK+ itself creates a suitable cairo context in that
128 gtk_print_context_set_cairo_context (GtkPrintContext *context,
134 cairo_destroy (context->cr);
136 context->cr = cairo_reference (cr);
137 context->surface_dpi_x = dpi_x;
138 context->surface_dpi_y = dpi_y;
140 switch (context->op->priv->unit)
144 /* Do nothing, this is the cairo default unit */
145 context->pixels_per_unit_x = 1.0;
146 context->pixels_per_unit_y = 1.0;
148 case GTK_UNIT_POINTS:
149 context->pixels_per_unit_x = dpi_x / POINTS_PER_INCH;
150 context->pixels_per_unit_y = dpi_y / POINTS_PER_INCH;
153 context->pixels_per_unit_x = dpi_x;
154 context->pixels_per_unit_y = dpi_y;
157 context->pixels_per_unit_x = dpi_x / MM_PER_INCH;
158 context->pixels_per_unit_y = dpi_y / MM_PER_INCH;
161 cairo_scale (context->cr,
162 context->pixels_per_unit_x,
163 context->pixels_per_unit_y);
168 _gtk_print_context_rotate_according_to_orientation (GtkPrintContext *context)
170 cairo_t *cr = context->cr;
171 cairo_matrix_t matrix;
172 GtkPaperSize *paper_size;
173 gdouble width, height;
175 paper_size = gtk_page_setup_get_paper_size (context->page_setup);
177 width = gtk_paper_size_get_width (paper_size, GTK_UNIT_INCH);
178 width = width * context->surface_dpi_x / context->pixels_per_unit_x;
179 height = gtk_paper_size_get_height (paper_size, GTK_UNIT_INCH);
180 height = height * context->surface_dpi_y / context->pixels_per_unit_y;
182 switch (gtk_page_setup_get_orientation (context->page_setup))
185 case GTK_PAGE_ORIENTATION_PORTRAIT:
187 case GTK_PAGE_ORIENTATION_LANDSCAPE:
188 cairo_translate (cr, 0, height);
189 cairo_matrix_init (&matrix,
193 cairo_transform (cr, &matrix);
195 case GTK_PAGE_ORIENTATION_REVERSE_PORTRAIT:
196 cairo_translate (cr, width, height);
197 cairo_matrix_init (&matrix,
201 cairo_transform (cr, &matrix);
203 case GTK_PAGE_ORIENTATION_REVERSE_LANDSCAPE:
204 cairo_translate (cr, width, 0);
205 cairo_matrix_init (&matrix,
209 cairo_transform (cr, &matrix);
215 _gtk_print_context_translate_into_margin (GtkPrintContext *context)
217 GtkPrintOperationPrivate *priv;
220 g_return_if_fail (GTK_IS_PRINT_CONTEXT (context));
222 priv = context->op->priv;
224 /* We do it this way to also handle GTK_UNIT_PIXELS */
226 left = gtk_page_setup_get_left_margin (context->page_setup, GTK_UNIT_INCH);
227 top = gtk_page_setup_get_top_margin (context->page_setup, GTK_UNIT_INCH);
229 cairo_translate (context->cr,
230 left * context->surface_dpi_x / context->pixels_per_unit_x,
231 top * context->surface_dpi_y / context->pixels_per_unit_y);
235 _gtk_print_context_set_page_setup (GtkPrintContext *context,
236 GtkPageSetup *page_setup)
238 g_return_if_fail (GTK_IS_PRINT_CONTEXT (context));
239 g_return_if_fail (page_setup == NULL ||
240 GTK_IS_PAGE_SETUP (page_setup));
242 g_object_ref (page_setup);
244 if (context->page_setup != NULL)
245 g_object_unref (context->page_setup);
247 context->page_setup = page_setup;
251 * gtk_print_context_get_cairo_context:
252 * @context: a #GtkPrintContext
254 * Obtains the cairo context that is associated with the
257 * Return value: the cairo context of @context
262 gtk_print_context_get_cairo_context (GtkPrintContext *context)
264 g_return_val_if_fail (GTK_IS_PRINT_CONTEXT (context), NULL);
270 * gtk_print_context_get_page_setup:
271 * @context: a #GtkPrintContext
273 * Obtains the #GtkPageSetup that determines the page
274 * dimensions of the #GtkPrintContext.
276 * Return value: the page setup of @context
281 gtk_print_context_get_page_setup (GtkPrintContext *context)
283 g_return_val_if_fail (GTK_IS_PRINT_CONTEXT (context), NULL);
285 return context->page_setup;
289 * gtk_print_context_get_width:
290 * @context: a #GtkPrintContext
292 * Obtains the width of the #GtkPrintContext, in pixels.
294 * Return value: the width of @context
299 gtk_print_context_get_width (GtkPrintContext *context)
301 GtkPrintOperationPrivate *priv;
304 g_return_val_if_fail (GTK_IS_PRINT_CONTEXT (context), 0);
306 priv = context->op->priv;
308 if (priv->use_full_page)
309 width = gtk_page_setup_get_paper_width (context->page_setup, GTK_UNIT_INCH);
311 width = gtk_page_setup_get_page_width (context->page_setup, GTK_UNIT_INCH);
313 /* Really dpi_x? What about landscape? what does dpi_x mean in that case? */
314 return width * context->surface_dpi_x / context->pixels_per_unit_x;
318 * gtk_print_context_get_height:
319 * @context: a #GtkPrintContext
321 * Obtains the height of the #GtkPrintContext, in pixels.
323 * Return value: the height of @context
328 gtk_print_context_get_height (GtkPrintContext *context)
330 GtkPrintOperationPrivate *priv;
333 g_return_val_if_fail (GTK_IS_PRINT_CONTEXT (context), 0);
335 priv = context->op->priv;
337 if (priv->use_full_page)
338 height = gtk_page_setup_get_paper_height (context->page_setup, GTK_UNIT_INCH);
340 height = gtk_page_setup_get_page_height (context->page_setup, GTK_UNIT_INCH);
342 /* Really dpi_y? What about landscape? what does dpi_y mean in that case? */
343 return height * context->surface_dpi_y / context->pixels_per_unit_y;
347 * gtk_print_context_get_dpi_x:
348 * @context: a #GtkPrintContext
350 * Obtains the horizontal resolution of the #GtkPrintContext,
353 * Return value: the horizontal resolution of @context
358 gtk_print_context_get_dpi_x (GtkPrintContext *context)
360 g_return_val_if_fail (GTK_IS_PRINT_CONTEXT (context), 0);
362 return context->surface_dpi_x;
366 * gtk_print_context_get_dpi_y:
367 * @context: a #GtkPrintContext
369 * Obtains the vertical resolution of the #GtkPrintContext,
372 * Return value: the vertical resolution of @context
377 gtk_print_context_get_dpi_y (GtkPrintContext *context)
379 g_return_val_if_fail (GTK_IS_PRINT_CONTEXT (context), 0);
381 return context->surface_dpi_y;
385 * gtk_print_context_get_hard_margins:
386 * @context: a #GtkPrintContext
387 * @top: top hardware printer margin
388 * @bottom: bottom hardware printer margin
389 * @left: left hardware printer margin
390 * @right: right hardware printer margin
392 * Obtains the hardware printer margins of the #GtkPrintContext, in units.
394 * Return value: %TRUE if the hard margins were retrieved
399 gtk_print_context_get_hard_margins (GtkPrintContext *context,
405 if (context->has_hard_margins)
407 *top = context->hard_margin_top / context->pixels_per_unit_y;
408 *bottom = context->hard_margin_bottom / context->pixels_per_unit_y;
409 *left = context->hard_margin_left / context->pixels_per_unit_x;
410 *right = context->hard_margin_right / context->pixels_per_unit_x;
413 return context->has_hard_margins;
417 * gtk_print_context_set_hard_margins:
418 * @context: a #GtkPrintContext
419 * @top: top hardware printer margin
420 * @bottom: bottom hardware printer margin
421 * @left: left hardware printer margin
422 * @right: right hardware printer margin
424 * set the hard margins in pixel coordinates
427 _gtk_print_context_set_hard_margins (GtkPrintContext *context,
433 context->hard_margin_top = top;
434 context->hard_margin_bottom = bottom;
435 context->hard_margin_left = left;
436 context->hard_margin_right = right;
437 context->has_hard_margins = TRUE;
441 * gtk_print_context_get_pango_fontmap:
442 * @context: a #GtkPrintContext
444 * Returns a #PangoFontMap that is suitable for use
445 * with the #GtkPrintContext.
447 * Return value: the font map of @context
452 gtk_print_context_get_pango_fontmap (GtkPrintContext *context)
454 g_return_val_if_fail (GTK_IS_PRINT_CONTEXT (context), NULL);
456 return _gtk_print_context_get_fontmap (context);
460 * gtk_print_context_create_pango_context:
461 * @context: a #GtkPrintContext
463 * Creates a new #PangoContext that can be used with the
466 * Return value: a new Pango context for @context
471 gtk_print_context_create_pango_context (GtkPrintContext *context)
473 PangoContext *pango_context;
474 cairo_font_options_t *options;
476 g_return_val_if_fail (GTK_IS_PRINT_CONTEXT (context), NULL);
478 pango_context = pango_cairo_font_map_create_context (PANGO_CAIRO_FONT_MAP (_gtk_print_context_get_fontmap (context)));
480 options = cairo_font_options_create ();
481 cairo_font_options_set_hint_metrics (options, CAIRO_HINT_METRICS_OFF);
482 pango_cairo_context_set_font_options (pango_context, options);
483 cairo_font_options_destroy (options);
485 /* We use the unit-scaled resolution, as we still want
486 * fonts given in points to work
488 pango_cairo_context_set_resolution (pango_context,
489 context->surface_dpi_y / context->pixels_per_unit_y);
490 return pango_context;
494 * gtk_print_context_create_pango_layout:
495 * @context: a #GtkPrintContext
497 * Creates a new #PangoLayout that is suitable for use
498 * with the #GtkPrintContext.
500 * Return value: a new Pango layout for @context
505 gtk_print_context_create_pango_layout (GtkPrintContext *context)
507 PangoContext *pango_context;
510 g_return_val_if_fail (GTK_IS_PRINT_CONTEXT (context), NULL);
512 pango_context = gtk_print_context_create_pango_context (context);
513 layout = pango_layout_new (pango_context);
515 pango_cairo_update_context (context->cr, pango_context);
516 g_object_unref (pango_context);
522 #define __GTK_PRINT_CONTEXT_C__
523 #include "gtkaliasdef.c"