617 lines
17 KiB
C
617 lines
17 KiB
C
/* GTK - The GIMP Toolkit
|
|
* 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
|
|
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "config.h"
|
|
#include "gtkprintoperation-private.h"
|
|
|
|
|
|
/**
|
|
* GtkPrintContext:
|
|
*
|
|
* A `GtkPrintContext` encapsulates context information that is required when
|
|
* drawing pages for printing.
|
|
*
|
|
* 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.
|
|
*
|
|
* `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.
|
|
*
|
|
* ## Using GtkPrintContext in a ::draw-page callback
|
|
*
|
|
* ```c
|
|
* static void
|
|
* draw_page (GtkPrintOperation *operation,
|
|
* GtkPrintContext *context,
|
|
* int page_nr)
|
|
* {
|
|
* 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
|
|
* layout = gtk_print_context_create_pango_layout (context);
|
|
* 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);
|
|
* }
|
|
* ```
|
|
*/
|
|
|
|
|
|
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;
|
|
|
|
double surface_dpi_x;
|
|
double surface_dpi_y;
|
|
|
|
double pixels_per_unit_x;
|
|
double pixels_per_unit_y;
|
|
|
|
gboolean has_hard_margins;
|
|
double hard_margin_top;
|
|
double hard_margin_bottom;
|
|
double hard_margin_left;
|
|
double hard_margin_right;
|
|
|
|
};
|
|
|
|
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);
|
|
|
|
if (context->cr)
|
|
cairo_destroy (context->cr);
|
|
|
|
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;
|
|
|
|
context = g_object_new (GTK_TYPE_PRINT_CONTEXT, NULL);
|
|
|
|
context->op = op;
|
|
context->cr = NULL;
|
|
context->has_hard_margins = FALSE;
|
|
|
|
return context;
|
|
}
|
|
|
|
static PangoFontMap *
|
|
_gtk_print_context_get_fontmap (GtkPrintContext *context)
|
|
{
|
|
return pango_cairo_font_map_get_default ();
|
|
}
|
|
|
|
/**
|
|
* gtk_print_context_set_cairo_context:
|
|
* @context: a `GtkPrintContext`
|
|
* @cr: the cairo context
|
|
* @dpi_x: the horizontal resolution to use with @cr
|
|
* @dpi_y: the vertical resolution to use with @cr
|
|
*
|
|
* Sets a new cairo context on a print context.
|
|
*
|
|
* This function is intended to be used when implementing
|
|
* an internal print preview, it is not needed for printing,
|
|
* since GTK itself creates a suitable cairo context in that
|
|
* case.
|
|
*/
|
|
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;
|
|
|
|
switch (context->op->priv->unit)
|
|
{
|
|
default:
|
|
case GTK_UNIT_NONE:
|
|
/* 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:
|
|
context->pixels_per_unit_x = dpi_x / POINTS_PER_INCH;
|
|
context->pixels_per_unit_y = dpi_y / POINTS_PER_INCH;
|
|
break;
|
|
case GTK_UNIT_INCH:
|
|
context->pixels_per_unit_x = dpi_x;
|
|
context->pixels_per_unit_y = dpi_y;
|
|
break;
|
|
case GTK_UNIT_MM:
|
|
context->pixels_per_unit_x = dpi_x / MM_PER_INCH;
|
|
context->pixels_per_unit_y = dpi_y / MM_PER_INCH;
|
|
break;
|
|
}
|
|
cairo_scale (context->cr,
|
|
context->pixels_per_unit_x,
|
|
context->pixels_per_unit_y);
|
|
}
|
|
|
|
|
|
void
|
|
_gtk_print_context_rotate_according_to_orientation (GtkPrintContext *context)
|
|
{
|
|
cairo_t *cr = context->cr;
|
|
cairo_matrix_t matrix;
|
|
GtkPaperSize *paper_size;
|
|
double width, height;
|
|
|
|
paper_size = gtk_page_setup_get_paper_size (context->page_setup);
|
|
|
|
width = gtk_paper_size_get_width (paper_size, GTK_UNIT_INCH);
|
|
width = width * context->surface_dpi_x / context->pixels_per_unit_x;
|
|
height = gtk_paper_size_get_height (paper_size, 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:
|
|
break;
|
|
case GTK_PAGE_ORIENTATION_LANDSCAPE:
|
|
cairo_translate (cr, 0, height);
|
|
cairo_matrix_init (&matrix,
|
|
0, -1,
|
|
1, 0,
|
|
0, 0);
|
|
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:
|
|
cairo_translate (cr, width, 0);
|
|
cairo_matrix_init (&matrix,
|
|
0, 1,
|
|
-1, 0,
|
|
0, 0);
|
|
cairo_transform (cr, &matrix);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void
|
|
_gtk_print_context_reverse_according_to_orientation (GtkPrintContext *context)
|
|
{
|
|
cairo_t *cr = context->cr;
|
|
cairo_matrix_t matrix;
|
|
double width, height;
|
|
|
|
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;
|
|
}
|
|
}
|
|
|
|
void
|
|
_gtk_print_context_translate_into_margin (GtkPrintContext *context)
|
|
{
|
|
double dx, dy;
|
|
|
|
g_return_if_fail (GTK_IS_PRINT_CONTEXT (context));
|
|
|
|
/* We do it this way to also handle GTK_UNIT_NONE */
|
|
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;
|
|
}
|
|
|
|
cairo_translate (context->cr,
|
|
dx * context->surface_dpi_x / context->pixels_per_unit_x,
|
|
dy * context->surface_dpi_y / context->pixels_per_unit_y);
|
|
}
|
|
|
|
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));
|
|
|
|
if (page_setup != NULL)
|
|
g_object_ref (page_setup);
|
|
|
|
if (context->page_setup != NULL)
|
|
g_object_unref (context->page_setup);
|
|
|
|
context->page_setup = page_setup;
|
|
}
|
|
|
|
/**
|
|
* gtk_print_context_get_cairo_context:
|
|
* @context: a `GtkPrintContext`
|
|
*
|
|
* Obtains the cairo context that is associated with the
|
|
* `GtkPrintContext`.
|
|
*
|
|
* Returns: (transfer none): the cairo context of @context
|
|
*/
|
|
cairo_t *
|
|
gtk_print_context_get_cairo_context (GtkPrintContext *context)
|
|
{
|
|
g_return_val_if_fail (GTK_IS_PRINT_CONTEXT (context), NULL);
|
|
|
|
return context->cr;
|
|
}
|
|
|
|
/**
|
|
* gtk_print_context_get_page_setup:
|
|
* @context: a `GtkPrintContext`
|
|
*
|
|
* Obtains the `GtkPageSetup` that determines the page
|
|
* dimensions of the `GtkPrintContext`.
|
|
*
|
|
* Returns: (transfer none): the page setup of @context
|
|
*/
|
|
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:
|
|
* @context: a `GtkPrintContext`
|
|
*
|
|
* Obtains the width of the `GtkPrintContext`, in pixels.
|
|
*
|
|
* Returns: the width of @context
|
|
*/
|
|
double
|
|
gtk_print_context_get_width (GtkPrintContext *context)
|
|
{
|
|
GtkPrintOperationPrivate *priv;
|
|
double width;
|
|
|
|
g_return_val_if_fail (GTK_IS_PRINT_CONTEXT (context), 0);
|
|
|
|
priv = context->op->priv;
|
|
|
|
if (priv->use_full_page)
|
|
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? */
|
|
return width * context->surface_dpi_x / context->pixels_per_unit_x;
|
|
}
|
|
|
|
/**
|
|
* gtk_print_context_get_height:
|
|
* @context: a `GtkPrintContext`
|
|
*
|
|
* Obtains the height of the `GtkPrintContext`, in pixels.
|
|
*
|
|
* Returns: the height of @context
|
|
*/
|
|
double
|
|
gtk_print_context_get_height (GtkPrintContext *context)
|
|
{
|
|
GtkPrintOperationPrivate *priv;
|
|
double height;
|
|
|
|
g_return_val_if_fail (GTK_IS_PRINT_CONTEXT (context), 0);
|
|
|
|
priv = context->op->priv;
|
|
|
|
if (priv->use_full_page)
|
|
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);
|
|
|
|
/* 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;
|
|
}
|
|
|
|
/**
|
|
* gtk_print_context_get_dpi_x:
|
|
* @context: a `GtkPrintContext`
|
|
*
|
|
* Obtains the horizontal resolution of the `GtkPrintContext`,
|
|
* in dots per inch.
|
|
*
|
|
* Returns: the horizontal resolution of @context
|
|
*/
|
|
double
|
|
gtk_print_context_get_dpi_x (GtkPrintContext *context)
|
|
{
|
|
g_return_val_if_fail (GTK_IS_PRINT_CONTEXT (context), 0);
|
|
|
|
return context->surface_dpi_x;
|
|
}
|
|
|
|
/**
|
|
* gtk_print_context_get_dpi_y:
|
|
* @context: a `GtkPrintContext`
|
|
*
|
|
* Obtains the vertical resolution of the `GtkPrintContext`,
|
|
* in dots per inch.
|
|
*
|
|
* Returns: the vertical resolution of @context
|
|
*/
|
|
double
|
|
gtk_print_context_get_dpi_y (GtkPrintContext *context)
|
|
{
|
|
g_return_val_if_fail (GTK_IS_PRINT_CONTEXT (context), 0);
|
|
|
|
return context->surface_dpi_y;
|
|
}
|
|
|
|
/**
|
|
* gtk_print_context_get_hard_margins:
|
|
* @context: a `GtkPrintContext`
|
|
* @top: (out): top hardware printer margin
|
|
* @bottom: (out): bottom hardware printer margin
|
|
* @left: (out): left hardware printer margin
|
|
* @right: (out): right hardware printer margin
|
|
*
|
|
* Obtains the hardware printer margins of the `GtkPrintContext`,
|
|
* in units.
|
|
*
|
|
* Returns: %TRUE if the hard margins were retrieved
|
|
*/
|
|
gboolean
|
|
gtk_print_context_get_hard_margins (GtkPrintContext *context,
|
|
double *top,
|
|
double *bottom,
|
|
double *left,
|
|
double *right)
|
|
{
|
|
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:
|
|
* @context: a `GtkPrintContext`
|
|
* @top: top hardware printer margin
|
|
* @bottom: bottom hardware printer margin
|
|
* @left: left hardware printer margin
|
|
* @right: right hardware printer margin
|
|
*
|
|
* Sets the hard margins in pixels.
|
|
*/
|
|
void
|
|
_gtk_print_context_set_hard_margins (GtkPrintContext *context,
|
|
double top,
|
|
double bottom,
|
|
double left,
|
|
double right)
|
|
{
|
|
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;
|
|
}
|
|
|
|
/**
|
|
* gtk_print_context_get_pango_fontmap:
|
|
* @context: a `GtkPrintContext`
|
|
*
|
|
* Returns a `PangoFontMap` that is suitable for use
|
|
* with the `GtkPrintContext`.
|
|
*
|
|
* Returns: (transfer none): the font map of @context
|
|
*/
|
|
PangoFontMap *
|
|
gtk_print_context_get_pango_fontmap (GtkPrintContext *context)
|
|
{
|
|
g_return_val_if_fail (GTK_IS_PRINT_CONTEXT (context), NULL);
|
|
|
|
return _gtk_print_context_get_fontmap (context);
|
|
}
|
|
|
|
/**
|
|
* gtk_print_context_create_pango_context:
|
|
* @context: a `GtkPrintContext`
|
|
*
|
|
* Creates a new `PangoContext` that can be used with the
|
|
* `GtkPrintContext`.
|
|
*
|
|
* Returns: (transfer full): a new Pango context for @context
|
|
*/
|
|
PangoContext *
|
|
gtk_print_context_create_pango_context (GtkPrintContext *context)
|
|
{
|
|
PangoContext *pango_context;
|
|
cairo_font_options_t *options;
|
|
|
|
g_return_val_if_fail (GTK_IS_PRINT_CONTEXT (context), NULL);
|
|
|
|
pango_context = pango_font_map_create_context (_gtk_print_context_get_fontmap (context));
|
|
|
|
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);
|
|
|
|
/* 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);
|
|
return pango_context;
|
|
}
|
|
|
|
/**
|
|
* gtk_print_context_create_pango_layout:
|
|
* @context: a `GtkPrintContext`
|
|
*
|
|
* Creates a new `PangoLayout` that is suitable for use
|
|
* with the `GtkPrintContext`.
|
|
*
|
|
* Returns: (transfer full): a new Pango layout for @context
|
|
*/
|
|
PangoLayout *
|
|
gtk_print_context_create_pango_layout (GtkPrintContext *context)
|
|
{
|
|
PangoContext *pango_context;
|
|
PangoLayout *layout;
|
|
|
|
g_return_val_if_fail (GTK_IS_PRINT_CONTEXT (context), NULL);
|
|
|
|
pango_context = gtk_print_context_create_pango_context (context);
|
|
layout = pango_layout_new (pango_context);
|
|
|
|
pango_cairo_update_context (context->cr, pango_context);
|
|
g_object_unref (pango_context);
|
|
|
|
return layout;
|
|
}
|