gtkprintcontext.c 17 KB
Newer Older
Cody Russell's avatar
Cody Russell committed
1
/* GTK - The GIMP Toolkit
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 * gtkprintcontext.c: Print Context
 * Copyright (C) 2006, Red Hat, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
Javier Jardón's avatar
Javier Jardón committed
16
 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
17
18
19
20
21
 */

#include "config.h"
#include "gtkprintoperation-private.h"

22
23

/**
Matthias Clasen's avatar
Matthias Clasen committed
24
 * GtkPrintContext:
25
 *
Matthias Clasen's avatar
Matthias Clasen committed
26
27
 * A `GtkPrintContext` encapsulates context information that is required when
 * drawing pages for printing.
28
 *
Matthias Clasen's avatar
Matthias Clasen committed
29
30
31
 * This includes the cairo context and important parameters like page size
 * and resolution. It also lets you easily create [class@Pango.Layout] and
 * [class@Pango.Context] objects that match the font metrics of the cairo surface.
32
 *
Matthias Clasen's avatar
Matthias Clasen committed
33
34
35
36
37
38
 * `GtkPrintContext` objects get passed to the
 * [signal@Gtk.PrintOperation::begin-print],
 * [signal@Gtk.PrintOperation::end-print],
 * [signal@Gtk.PrintOperation::request-page-setup] and
 * [signal@Gtk.PrintOperation::draw-page] signals on the
 * [class@Gtk.PrintOperation] object.
39
 *
Matthias Clasen's avatar
Matthias Clasen committed
40
41
42
 * ## Using GtkPrintContext in a ::draw-page callback
 *
 * ```c
43
44
 * static void
 * draw_page (GtkPrintOperation *operation,
Matthias Clasen's avatar
Matthias Clasen committed
45
46
 *            GtkPrintContext   *context,
 *            int                page_nr)
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
 * {
 *   cairo_t *cr;
 *   PangoLayout *layout;
 *   PangoFontDescription *desc;
 *
 *   cr = gtk_print_context_get_cairo_context (context);
 *
 *   // Draw a red rectangle, as wide as the paper (inside the margins)
 *   cairo_set_source_rgb (cr, 1.0, 0, 0);
 *   cairo_rectangle (cr, 0, 0, gtk_print_context_get_width (context), 50);
 *
 *   cairo_fill (cr);
 *
 *   // Draw some lines
 *   cairo_move_to (cr, 20, 10);
 *   cairo_line_to (cr, 40, 20);
 *   cairo_arc (cr, 60, 60, 20, 0, M_PI);
 *   cairo_line_to (cr, 80, 20);
 *
 *   cairo_set_source_rgb (cr, 0, 0, 0);
 *   cairo_set_line_width (cr, 5);
 *   cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
 *   cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND);
 *
 *   cairo_stroke (cr);
 *
 *   // Draw some text
74
 *   layout = gtk_print_context_create_pango_layout (context);
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
 *   pango_layout_set_text (layout, "Hello World! Printing is easy", -1);
 *   desc = pango_font_description_from_string ("sans 28");
 *   pango_layout_set_font_description (layout, desc);
 *   pango_font_description_free (desc);
 *
 *   cairo_move_to (cr, 30, 20);
 *   pango_cairo_layout_path (cr, layout);
 *
 *   // Font Outline
 *   cairo_set_source_rgb (cr, 0.93, 1.0, 0.47);
 *   cairo_set_line_width (cr, 0.5);
 *   cairo_stroke_preserve (cr);
 *
 *   // Font Fill
 *   cairo_set_source_rgb (cr, 0, 0.0, 1.0);
 *   cairo_fill (cr);
 *
 *   g_object_unref (layout);
 * }
Matthias Clasen's avatar
Matthias Clasen committed
94
 * ```
95
96
97
 */


98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
typedef struct _GtkPrintContextClass GtkPrintContextClass;

#define GTK_IS_PRINT_CONTEXT_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_PRINT_CONTEXT))
#define GTK_PRINT_CONTEXT_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_PRINT_CONTEXT, GtkPrintContextClass))
#define GTK_PRINT_CONTEXT_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_PRINT_CONTEXT, GtkPrintContextClass))

#define MM_PER_INCH 25.4
#define POINTS_PER_INCH 72

struct _GtkPrintContext
{
  GObject parent_instance;

  GtkPrintOperation *op;
  cairo_t *cr;
  GtkPageSetup *page_setup;

115
116
  double surface_dpi_x;
  double surface_dpi_y;
117
  
118
119
  double pixels_per_unit_x;
  double pixels_per_unit_y;
120
121

  gboolean has_hard_margins;
122
123
124
125
  double hard_margin_top;
  double hard_margin_bottom;
  double hard_margin_left;
  double hard_margin_right;
126

127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
};

struct _GtkPrintContextClass
{
  GObjectClass parent_class;
};

G_DEFINE_TYPE (GtkPrintContext, gtk_print_context, G_TYPE_OBJECT)

static void
gtk_print_context_finalize (GObject *object)
{
  GtkPrintContext *context = GTK_PRINT_CONTEXT (object);

  if (context->page_setup)
    g_object_unref (context->page_setup);

144
145
  if (context->cr)
    cairo_destroy (context->cr);
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
  
  G_OBJECT_CLASS (gtk_print_context_parent_class)->finalize (object);
}

static void
gtk_print_context_init (GtkPrintContext *context)
{
}

static void
gtk_print_context_class_init (GtkPrintContextClass *class)
{
  GObjectClass *gobject_class = (GObjectClass *)class;

  gobject_class->finalize = gtk_print_context_finalize;
}


GtkPrintContext *
_gtk_print_context_new (GtkPrintOperation *op)
{
  GtkPrintContext *context;
168

169
170
171
  context = g_object_new (GTK_TYPE_PRINT_CONTEXT, NULL);

  context->op = op;
172
  context->cr = NULL;
173
  context->has_hard_margins = FALSE;
174
175
176
  
  return context;
}
177
178
179
180
181
182
183

static PangoFontMap *
_gtk_print_context_get_fontmap (GtkPrintContext *context)
{
  return pango_cairo_font_map_get_default ();
}

184
185
/**
 * gtk_print_context_set_cairo_context:
Matthias Clasen's avatar
Matthias Clasen committed
186
 * @context: a `GtkPrintContext`
187
188
189
190
 * @cr: the cairo context
 * @dpi_x: the horizontal resolution to use with @cr
 * @dpi_y: the vertical resolution to use with @cr
 *
Matthias Clasen's avatar
Matthias Clasen committed
191
192
 * Sets a new cairo context on a print context.
 *
193
194
 * This function is intended to be used when implementing
 * an internal print preview, it is not needed for printing,
Matthias Clasen's avatar
Matthias Clasen committed
195
 * since GTK itself creates a suitable cairo context in that
196
197
 * case.
 */
198
199
200
201
202
203
204
205
206
207
208
209
void
gtk_print_context_set_cairo_context (GtkPrintContext *context,
				     cairo_t         *cr,
				     double           dpi_x,
				     double           dpi_y)
{
  if (context->cr)
    cairo_destroy (context->cr);

  context->cr = cairo_reference (cr);
  context->surface_dpi_x = dpi_x;
  context->surface_dpi_y = dpi_y;
210

211
  switch (context->op->priv->unit)
212
213
    {
    default:
214
    case GTK_UNIT_NONE:
215
216
217
218
219
      /* Do nothing, this is the cairo default unit */
      context->pixels_per_unit_x = 1.0;
      context->pixels_per_unit_y = 1.0;
      break;
    case GTK_UNIT_POINTS:
220
221
      context->pixels_per_unit_x = dpi_x / POINTS_PER_INCH;
      context->pixels_per_unit_y = dpi_y / POINTS_PER_INCH;
222
223
      break;
    case GTK_UNIT_INCH:
224
225
      context->pixels_per_unit_x = dpi_x;
      context->pixels_per_unit_y = dpi_y;
226
227
      break;
    case GTK_UNIT_MM:
228
229
      context->pixels_per_unit_x = dpi_x / MM_PER_INCH;
      context->pixels_per_unit_y = dpi_y / MM_PER_INCH;
230
231
232
233
234
235
236
      break;
    }
  cairo_scale (context->cr,
	       context->pixels_per_unit_x,
	       context->pixels_per_unit_y);
}

237

238
239
240
241
242
243
void
_gtk_print_context_rotate_according_to_orientation (GtkPrintContext *context)
{
  cairo_t *cr = context->cr;
  cairo_matrix_t matrix;
  GtkPaperSize *paper_size;
244
  double width, height;
245
246
247
248

  paper_size = gtk_page_setup_get_paper_size (context->page_setup);

  width = gtk_paper_size_get_width (paper_size, GTK_UNIT_INCH);
249
  width = width * context->surface_dpi_x / context->pixels_per_unit_x;
250
  height = gtk_paper_size_get_height (paper_size, GTK_UNIT_INCH);
251
  height = height * context->surface_dpi_y / context->pixels_per_unit_y;
252
253
254
255
256
257
258
  
  switch (gtk_page_setup_get_orientation (context->page_setup))
    {
    default:
    case GTK_PAGE_ORIENTATION_PORTRAIT:
      break;
    case GTK_PAGE_ORIENTATION_LANDSCAPE:
259
      cairo_translate (cr, 0, height);
260
      cairo_matrix_init (&matrix,
261
262
263
			 0, -1,
			 1,  0,
			 0,  0);
264
265
266
267
268
269
270
271
272
273
274
      cairo_transform (cr, &matrix);
      break;
    case GTK_PAGE_ORIENTATION_REVERSE_PORTRAIT:
      cairo_translate (cr, width, height);
      cairo_matrix_init (&matrix,
			 -1,  0,
			  0, -1,
			  0,  0);
      cairo_transform (cr, &matrix);
      break;
    case GTK_PAGE_ORIENTATION_REVERSE_LANDSCAPE:
275
      cairo_translate (cr, width, 0);
276
      cairo_matrix_init (&matrix,
277
278
279
			  0,  1,
			 -1,  0,
			  0,  0);
280
281
282
283
284
      cairo_transform (cr, &matrix);
      break;
    }
}

285
286
287
288
289
void
_gtk_print_context_reverse_according_to_orientation (GtkPrintContext *context)
{
  cairo_t *cr = context->cr;
  cairo_matrix_t matrix;
290
  double width, height;
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314

  width = gtk_page_setup_get_paper_width (context->page_setup, GTK_UNIT_INCH);
  width = width * context->surface_dpi_x / context->pixels_per_unit_x;
  height = gtk_page_setup_get_paper_height (context->page_setup, GTK_UNIT_INCH);
  height = height * context->surface_dpi_y / context->pixels_per_unit_y;

  switch (gtk_page_setup_get_orientation (context->page_setup))
    {
    default:
    case GTK_PAGE_ORIENTATION_PORTRAIT:
    case GTK_PAGE_ORIENTATION_LANDSCAPE:
      break;
    case GTK_PAGE_ORIENTATION_REVERSE_PORTRAIT:
    case GTK_PAGE_ORIENTATION_REVERSE_LANDSCAPE:
      cairo_translate (cr, width, height);
      cairo_matrix_init (&matrix,
			 -1,  0,
			  0, -1,
			  0,  0);
      cairo_transform (cr, &matrix);
      break;
    }
}

315
316
317
void
_gtk_print_context_translate_into_margin (GtkPrintContext *context)
{
318
  double dx, dy;
319
320
321

  g_return_if_fail (GTK_IS_PRINT_CONTEXT (context));

322
  /* We do it this way to also handle GTK_UNIT_NONE */
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
  switch (gtk_page_setup_get_orientation (context->page_setup))
    {
      default:
      case GTK_PAGE_ORIENTATION_PORTRAIT:
        dx = gtk_page_setup_get_left_margin (context->page_setup, GTK_UNIT_INCH);
        dy = gtk_page_setup_get_top_margin (context->page_setup, GTK_UNIT_INCH);
        break;
      case GTK_PAGE_ORIENTATION_LANDSCAPE:
        dx = gtk_page_setup_get_bottom_margin (context->page_setup, GTK_UNIT_INCH);
        dy = gtk_page_setup_get_left_margin (context->page_setup, GTK_UNIT_INCH);
        break;
      case GTK_PAGE_ORIENTATION_REVERSE_PORTRAIT:
        dx = gtk_page_setup_get_right_margin (context->page_setup, GTK_UNIT_INCH);
        dy = gtk_page_setup_get_bottom_margin (context->page_setup, GTK_UNIT_INCH);
        break;
      case GTK_PAGE_ORIENTATION_REVERSE_LANDSCAPE:
        dx = gtk_page_setup_get_top_margin (context->page_setup, GTK_UNIT_INCH);
        dy = gtk_page_setup_get_right_margin (context->page_setup, GTK_UNIT_INCH);
        break;
    }
343
344

  cairo_translate (context->cr,
345
346
                   dx * context->surface_dpi_x / context->pixels_per_unit_x,
                   dy * context->surface_dpi_y / context->pixels_per_unit_y);
347
348
349
350
351
352
353
354
355
}

void
_gtk_print_context_set_page_setup (GtkPrintContext *context,
				   GtkPageSetup    *page_setup)
{
  g_return_if_fail (GTK_IS_PRINT_CONTEXT (context));
  g_return_if_fail (page_setup == NULL ||
		    GTK_IS_PAGE_SETUP (page_setup));
356
357
358

  if (page_setup != NULL)
    g_object_ref (page_setup);
359
360
361
362
363
364
365
366

  if (context->page_setup != NULL)
    g_object_unref (context->page_setup);

  context->page_setup = page_setup;
}

/**
367
 * gtk_print_context_get_cairo_context:
Matthias Clasen's avatar
Matthias Clasen committed
368
 * @context: a `GtkPrintContext`
369
370
 *
 * Obtains the cairo context that is associated with the
Matthias Clasen's avatar
Matthias Clasen committed
371
 * `GtkPrintContext`.
372
 *
373
 * Returns: (transfer none): the cairo context of @context
374
375
 */
cairo_t *
376
gtk_print_context_get_cairo_context (GtkPrintContext *context)
377
378
379
380
381
382
383
384
{
  g_return_val_if_fail (GTK_IS_PRINT_CONTEXT (context), NULL);

  return context->cr;
}

/**
 * gtk_print_context_get_page_setup:
Matthias Clasen's avatar
Matthias Clasen committed
385
 * @context: a `GtkPrintContext`
386
 *
Matthias Clasen's avatar
Matthias Clasen committed
387
388
 * Obtains the `GtkPageSetup` that determines the page
 * dimensions of the `GtkPrintContext`.
389
 *
390
 * Returns: (transfer none): the page setup of @context
391
392
393
394
395
396
397
398
399
400
401
 */
GtkPageSetup *
gtk_print_context_get_page_setup (GtkPrintContext *context)
{
  g_return_val_if_fail (GTK_IS_PRINT_CONTEXT (context), NULL);

  return context->page_setup;
}

/**
 * gtk_print_context_get_width:
Matthias Clasen's avatar
Matthias Clasen committed
402
 * @context: a `GtkPrintContext`
403
 *
Matthias Clasen's avatar
Matthias Clasen committed
404
 * Obtains the width of the `GtkPrintContext`, in pixels.
405
 *
406
 * Returns: the width of @context
407
 */
408
double
409
410
gtk_print_context_get_width (GtkPrintContext *context)
{
411
  GtkPrintOperationPrivate *priv;
412
  double width;
413
414
415

  g_return_val_if_fail (GTK_IS_PRINT_CONTEXT (context), 0);

416
417
418
  priv = context->op->priv;

  if (priv->use_full_page)
419
420
421
422
423
    width = gtk_page_setup_get_paper_width (context->page_setup, GTK_UNIT_INCH);
  else
    width = gtk_page_setup_get_page_width (context->page_setup, GTK_UNIT_INCH);

  /* Really dpi_x? What about landscape? what does dpi_x mean in that case? */
424
  return width * context->surface_dpi_x / context->pixels_per_unit_x;
425
426
427
428
}

/**
 * gtk_print_context_get_height:
Matthias Clasen's avatar
Matthias Clasen committed
429
430
431
 * @context: a `GtkPrintContext`
 *
 * Obtains the height of the `GtkPrintContext`, in pixels.
432
 *
433
 * Returns: the height of @context
434
 */
435
double
436
437
gtk_print_context_get_height (GtkPrintContext *context)
{
438
  GtkPrintOperationPrivate *priv;
439
  double height;
440
441
442

  g_return_val_if_fail (GTK_IS_PRINT_CONTEXT (context), 0);

443
444
445
  priv = context->op->priv;

  if (priv->use_full_page)
446
447
448
449
    height = gtk_page_setup_get_paper_height (context->page_setup, GTK_UNIT_INCH);
  else
    height = gtk_page_setup_get_page_height (context->page_setup, GTK_UNIT_INCH);

450
451
  /* Really dpi_y? What about landscape? what does dpi_y mean in that case? */
  return height * context->surface_dpi_y / context->pixels_per_unit_y;
452
453
454
455
}

/**
 * gtk_print_context_get_dpi_x:
Matthias Clasen's avatar
Matthias Clasen committed
456
457
458
 * @context: a `GtkPrintContext`
 *
 * Obtains the horizontal resolution of the `GtkPrintContext`,
459
460
 * in dots per inch.
 *
461
 * Returns: the horizontal resolution of @context
462
 */
463
double
464
465
466
467
gtk_print_context_get_dpi_x (GtkPrintContext *context)
{
  g_return_val_if_fail (GTK_IS_PRINT_CONTEXT (context), 0);

468
  return context->surface_dpi_x;
469
470
471
472
}

/**
 * gtk_print_context_get_dpi_y:
Matthias Clasen's avatar
Matthias Clasen committed
473
474
475
 * @context: a `GtkPrintContext`
 *
 * Obtains the vertical resolution of the `GtkPrintContext`,
476
477
 * in dots per inch.
 *
478
 * Returns: the vertical resolution of @context
479
 */
480
double
481
482
483
484
gtk_print_context_get_dpi_y (GtkPrintContext *context)
{
  g_return_val_if_fail (GTK_IS_PRINT_CONTEXT (context), 0);

485
  return context->surface_dpi_y;
486
487
}

488
489
/**
 * gtk_print_context_get_hard_margins:
Matthias Clasen's avatar
Matthias Clasen committed
490
 * @context: a `GtkPrintContext`
491
492
493
494
 * @top: (out): top hardware printer margin
 * @bottom: (out): bottom hardware printer margin
 * @left: (out): left hardware printer margin
 * @right: (out): right hardware printer margin
495
 *
Matthias Clasen's avatar
Matthias Clasen committed
496
497
 * Obtains the hardware printer margins of the `GtkPrintContext`,
 * in units.
498
 *
499
 * Returns: %TRUE if the hard margins were retrieved
500
501
502
 */
gboolean
gtk_print_context_get_hard_margins (GtkPrintContext *context,
503
504
505
506
				    double          *top,
				    double          *bottom,
				    double          *left,
				    double          *right)
507
508
509
510
511
512
513
514
515
516
517
518
519
520
{
  if (context->has_hard_margins)
    {
      *top    = context->hard_margin_top / context->pixels_per_unit_y;
      *bottom = context->hard_margin_bottom / context->pixels_per_unit_y;
      *left   = context->hard_margin_left / context->pixels_per_unit_x;
      *right  = context->hard_margin_right / context->pixels_per_unit_x;
    }

  return context->has_hard_margins;
}

/**
 * gtk_print_context_set_hard_margins:
Matthias Clasen's avatar
Matthias Clasen committed
521
 * @context: a `GtkPrintContext`
522
523
524
525
526
 * @top: top hardware printer margin
 * @bottom: bottom hardware printer margin
 * @left: left hardware printer margin
 * @right: right hardware printer margin
 *
Matthias Clasen's avatar
Matthias Clasen committed
527
 * Sets the hard margins in pixels.
528
529
530
 */
void
_gtk_print_context_set_hard_margins (GtkPrintContext *context,
531
532
533
534
				     double           top,
				     double           bottom,
				     double           left,
				     double           right)
535
536
537
538
539
540
541
542
{
  context->hard_margin_top    = top;
  context->hard_margin_bottom = bottom;
  context->hard_margin_left   = left;
  context->hard_margin_right  = right;
  context->has_hard_margins   = TRUE;
}

543
/**
544
 * gtk_print_context_get_pango_fontmap:
Matthias Clasen's avatar
Matthias Clasen committed
545
 * @context: a `GtkPrintContext`
546
 *
Matthias Clasen's avatar
Matthias Clasen committed
547
548
 * Returns a `PangoFontMap` that is suitable for use
 * with the `GtkPrintContext`.
549
 *
550
 * Returns: (transfer none): the font map of @context
551
552
 */
PangoFontMap *
553
gtk_print_context_get_pango_fontmap (GtkPrintContext *context)
554
555
556
{
  g_return_val_if_fail (GTK_IS_PRINT_CONTEXT (context), NULL);

557
  return _gtk_print_context_get_fontmap (context);
558
559
560
}

/**
561
 * gtk_print_context_create_pango_context:
Matthias Clasen's avatar
Matthias Clasen committed
562
 * @context: a `GtkPrintContext`
563
 *
Matthias Clasen's avatar
Matthias Clasen committed
564
565
 * Creates a new `PangoContext` that can be used with the
 * `GtkPrintContext`.
566
 *
567
 * Returns: (transfer full): a new Pango context for @context
568
569
 */
PangoContext *
570
gtk_print_context_create_pango_context (GtkPrintContext *context)
571
572
{
  PangoContext *pango_context;
573
  cairo_font_options_t *options;
574
575
576

  g_return_val_if_fail (GTK_IS_PRINT_CONTEXT (context), NULL);
  
577
  pango_context = pango_font_map_create_context (_gtk_print_context_get_fontmap (context));
578
579
580
581
582

  options = cairo_font_options_create ();
  cairo_font_options_set_hint_metrics (options, CAIRO_HINT_METRICS_OFF);
  pango_cairo_context_set_font_options (pango_context, options);
  cairo_font_options_destroy (options);
583
  
584
585
586
587
588
  /* We use the unit-scaled resolution, as we still want 
   * fonts given in points to work 
   */
  pango_cairo_context_set_resolution (pango_context,
				      context->surface_dpi_y / context->pixels_per_unit_y);
589
590
591
592
  return pango_context;
}

/**
593
 * gtk_print_context_create_pango_layout:
Matthias Clasen's avatar
Matthias Clasen committed
594
595
596
597
 * @context: a `GtkPrintContext`
 *
 * Creates a new `PangoLayout` that is suitable for use
 * with the `GtkPrintContext`.
598
 *
599
 * Returns: (transfer full): a new Pango layout for @context
600
601
 */
PangoLayout *
602
gtk_print_context_create_pango_layout (GtkPrintContext *context)
603
604
605
606
607
608
{
  PangoContext *pango_context;
  PangoLayout *layout;

  g_return_val_if_fail (GTK_IS_PRINT_CONTEXT (context), NULL);

609
  pango_context = gtk_print_context_create_pango_context (context);
610
611
612
613
614
615
616
  layout = pango_layout_new (pango_context);

  pango_cairo_update_context (context->cr, pango_context);
  g_object_unref (pango_context);

  return layout;
}