"SfR Fresh" - the SfR Freeware/Shareware Archive

Member "pango-1.20.5/pango/pangocairo-context.c" of archive pango-1.20.5.tar.gz:


As a special service "SfR Fresh" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. That can be also achieved for any archive member file by clicking within an archive contents listing on the first character of the file(path) respectively on the according byte size field.
    1 /* Pango
    2  * pangocairo-fontmap.c: Cairo font handling
    3  *
    4  * Copyright (C) 2000-2005 Red Hat Software
    5  *
    6  * This library is free software; you can redistribute it and/or
    7  * modify it under the terms of the GNU Library General Public
    8  * License as published by the Free Software Foundation; either
    9  * version 2 of the License, or (at your option) any later version.
   10  *
   11  * This library is distributed in the hope that it will be useful,
   12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
   14  * Library General Public License for more details.
   15  *
   16  * You should have received a copy of the GNU Library General Public
   17  * License along with this library; if not, write to the
   18  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   19  * Boston, MA 02111-1307, USA.
   20  */
   21 
   22 #include <config.h>
   23 
   24 #include "pangocairo.h"
   25 #include "pangocairo-private.h"
   26 #include "pango-impl-utils.h"
   27 
   28 #include <string.h>
   29 
   30 typedef struct _PangoCairoContextInfo PangoCairoContextInfo;
   31 
   32 struct _PangoCairoContextInfo
   33 {
   34   double dpi;
   35 
   36   cairo_font_options_t *set_options;
   37   cairo_font_options_t *surface_options;
   38   cairo_font_options_t *merged_options;
   39 
   40   PangoCairoShapeRendererFunc shape_renderer_func;
   41   gpointer                    shape_renderer_data;
   42   GDestroyNotify              shape_renderer_notify;
   43 };
   44 
   45 static void
   46 free_context_info (PangoCairoContextInfo *info)
   47 {
   48   if (info->set_options)
   49     cairo_font_options_destroy (info->set_options);
   50   if (info->surface_options)
   51     cairo_font_options_destroy (info->surface_options);
   52   if (info->merged_options)
   53     cairo_font_options_destroy (info->merged_options);
   54 
   55   if (info->shape_renderer_notify)
   56     info->shape_renderer_notify (info->shape_renderer_data);
   57 
   58   g_slice_free (PangoCairoContextInfo, info);
   59 }
   60 
   61 static PangoCairoContextInfo *
   62 get_context_info (PangoContext *context,
   63 		  gboolean      create)
   64 {
   65   static GQuark context_info_quark;
   66   PangoCairoContextInfo *info;
   67 
   68   if (G_UNLIKELY (!context_info_quark))
   69     context_info_quark = g_quark_from_static_string ("pango-cairo-context-info");
   70 
   71   info = g_object_get_qdata (G_OBJECT (context), context_info_quark);
   72 
   73   if (G_UNLIKELY (!info) && create)
   74     {
   75       info = g_slice_new0 (PangoCairoContextInfo);
   76       info->dpi = -1.0;
   77 
   78       g_object_set_qdata_full (G_OBJECT (context), context_info_quark,
   79 			       info, (GDestroyNotify)free_context_info);
   80     }
   81 
   82   return info;
   83 }
   84 
   85 static gboolean
   86 _pango_cairo_update_context (cairo_t      *cr,
   87 			     PangoContext *context)
   88 {
   89   PangoCairoContextInfo *info;
   90   cairo_matrix_t cairo_matrix;
   91   cairo_surface_t *target;
   92   PangoMatrix pango_matrix;
   93   const PangoMatrix *current_matrix, identity_matrix = PANGO_MATRIX_INIT;
   94   const cairo_font_options_t *merged_options;
   95   gboolean changed = FALSE;
   96 
   97   info = get_context_info (context, TRUE);
   98 
   99 
  100   target = cairo_get_target (cr);
  101 
  102   if (!info->surface_options) {
  103     info->surface_options = cairo_font_options_create ();
  104     changed = TRUE;
  105     cairo_surface_get_font_options (target, info->surface_options);
  106   } else {
  107     cairo_font_options_t *surface_options = cairo_font_options_create ();
  108     cairo_surface_get_font_options (target, surface_options);
  109     if (!cairo_font_options_equal (surface_options, info->surface_options))
  110       {
  111 	cairo_surface_get_font_options (target, info->surface_options);
  112 	changed = TRUE;
  113       }
  114     cairo_font_options_destroy (surface_options);
  115   }
  116 
  117   if (info->merged_options)
  118     {
  119       cairo_font_options_destroy (info->merged_options);
  120       info->merged_options = NULL;
  121     }
  122 
  123   merged_options = _pango_cairo_context_get_merged_font_options (context);
  124 
  125 
  126   cairo_get_matrix (cr, &cairo_matrix);
  127   pango_matrix.xx = cairo_matrix.xx;
  128   pango_matrix.yx = cairo_matrix.yx;
  129   pango_matrix.xy = cairo_matrix.xy;
  130   pango_matrix.yy = cairo_matrix.yy;
  131   pango_matrix.x0 = cairo_matrix.x0;
  132   pango_matrix.y0 = cairo_matrix.y0;
  133 
  134   current_matrix = pango_context_get_matrix (context);
  135   if (!current_matrix)
  136     current_matrix = &identity_matrix;
  137 
  138   /* layout is matrix-independent if metrics-hinting is off.
  139    * also ignore matrix translation offsets */
  140   if ((cairo_font_options_get_hint_metrics (merged_options) != CAIRO_HINT_METRICS_OFF) &&
  141       (0 != memcmp (&pango_matrix, current_matrix, 4 * sizeof (double))))
  142     changed = TRUE;
  143 
  144   pango_context_set_matrix (context, &pango_matrix);
  145 
  146 
  147   return changed;
  148 }
  149 
  150 /**
  151  * pango_cairo_update_context:
  152  * @cr: a Cairo context
  153  * @context: a #PangoContext, from pango_cairo_font_map_create_context()
  154  *
  155  * Updates a #PangoContext previously created for use with Cairo to
  156  * match the current transformation and target surface of a Cairo
  157  * context. If any layouts have been created for the context,
  158  * it's necessary to call pango_layout_context_changed() on those
  159  * layouts.
  160  *
  161  * Since: 1.10
  162  **/
  163 void
  164 pango_cairo_update_context (cairo_t      *cr,
  165 			    PangoContext *context)
  166 {
  167   g_return_if_fail (cr != NULL);
  168   g_return_if_fail (PANGO_IS_CONTEXT (context));
  169 
  170   (void) _pango_cairo_update_context (cr, context);
  171 }
  172 
  173 /**
  174  * pango_cairo_context_set_resolution:
  175  * @context: a #PangoContext, from pango_cairo_font_map_create_context()
  176  * @dpi: the resolution in "dots per inch". (Physical inches aren't actually
  177  *   involved; the terminology is conventional.) A 0 or negative value
  178  *   means to use the resolution from the font map.
  179  *
  180  * Sets the resolution for the context. This is a scale factor between
  181  * points specified in a #PangoFontDescription and Cairo units. The
  182  * default value is 96, meaning that a 10 point font will be 13
  183  * units high. (10 * 96. / 72. = 13.3).
  184  *
  185  * Since: 1.10
  186  **/
  187 void
  188 pango_cairo_context_set_resolution (PangoContext *context,
  189 				    double        dpi)
  190 {
  191   PangoCairoContextInfo *info = get_context_info (context, TRUE);
  192   info->dpi = dpi;
  193 }
  194 
  195 /**
  196  * pango_cairo_context_get_resolution:
  197  * @context: a #PangoContext, from pango_cairo_font_map_create_context()
  198  *
  199  * Gets the resolution for the context. See pango_cairo_context_set_resolution()
  200  *
  201  * Return value: the resolution in "dots per inch". A negative value will
  202  *  be returned if no resolution has previously been set.
  203  *
  204  * Since: 1.10
  205  **/
  206 double
  207 pango_cairo_context_get_resolution (PangoContext *context)
  208 {
  209   PangoCairoContextInfo *info = get_context_info (context, FALSE);
  210 
  211   if (info)
  212     return info->dpi;
  213   else
  214     return -1.0;
  215 }
  216 
  217 /**
  218  * pango_cairo_context_set_font_options:
  219  * @context: a #PangoContext, from pango_cairo_font_map_create_context()
  220  * @options: a #cairo_font_options_t, or %NULL to unset any previously set
  221  *           options. A copy is made.
  222  *
  223  * Sets the font options used when rendering text with this context.
  224  * These options override any options that pango_cairo_update_context()
  225  * derives from the target surface.
  226  *
  227  * Since: 1.10
  228  */
  229 void
  230 pango_cairo_context_set_font_options (PangoContext               *context,
  231 				      const cairo_font_options_t *options)
  232 {
  233   PangoCairoContextInfo *info;
  234 
  235   g_return_if_fail (PANGO_IS_CONTEXT (context));
  236 
  237   info  = get_context_info (context, TRUE);
  238 
  239   if (info->set_options)
  240     cairo_font_options_destroy (info->set_options);
  241 
  242   if (options)
  243     info->set_options = cairo_font_options_copy (options);
  244   else
  245     info->set_options = NULL;
  246 
  247   if (info->merged_options)
  248     {
  249       cairo_font_options_destroy (info->merged_options);
  250       info->merged_options = NULL;
  251     }
  252 }
  253 
  254 /**
  255  * pango_cairo_context_get_font_options:
  256  * @context: a #PangoContext, from pango_cairo_font_map_create_context()
  257  *
  258  * Retrieves any font rendering options previously set with
  259  * pango_cairo_font_map_set_font_options(). This functions not report options
  260  * that are derived from the target surface by pango_cairo_update_context()
  261  *
  262  * Return value: the font options previously set on the context, or %NULL
  263  *   if no options have been set. This value is owned by the context
  264  *   and must not be modified or freed.
  265  *
  266  * Since: 1.10
  267  **/
  268 G_CONST_RETURN cairo_font_options_t *
  269 pango_cairo_context_get_font_options (PangoContext *context)
  270 {
  271   PangoCairoContextInfo *info;
  272 
  273   g_return_val_if_fail (PANGO_IS_CONTEXT (context), NULL);
  274 
  275   info = get_context_info (context, FALSE);
  276 
  277   if (info)
  278     return info->set_options;
  279   else
  280     return NULL;
  281 }
  282 
  283 /**
  284  * _pango_cairo_context_merge_font_options:
  285  * @context: a #PangoContext
  286  * @options: a #cairo_font_options_t
  287  *
  288  * Merge together options from the target surface and explicitly set
  289  * on the context.
  290  *
  291  * Return value: the combined set of font options. This value is owned
  292  * by the context and must not be modified or freed.
  293  **/
  294 G_CONST_RETURN cairo_font_options_t *
  295 _pango_cairo_context_get_merged_font_options (PangoContext *context)
  296 {
  297   PangoCairoContextInfo *info = get_context_info (context, TRUE);
  298 
  299   if (!info->merged_options)
  300     {
  301       info->merged_options = cairo_font_options_create ();
  302 
  303       if (info->surface_options)
  304 	cairo_font_options_merge (info->merged_options, info->surface_options);
  305       if (info->set_options)
  306 	cairo_font_options_merge (info->merged_options, info->set_options);
  307     }
  308 
  309   return info->merged_options;
  310 }
  311 
  312 /**
  313  * pango_cairo_context_set_shape_renderer:
  314  * @context: a #PangoContext, from pango_cairo_font_map_create_context()
  315  * @func: Callback function for rendering attributes of type
  316  * %PANGO_ATTR_SHAPE, or %NULL to disable shape rendering.
  317  * @data: User data that will be passed to @func.
  318  * @dnotify: Callback that will be called when the
  319  *           context is freed to release @data, or %NULL.
  320  *
  321  * Sets callback function for context to use for rendering attributes
  322  * of type %PANGO_ATTR_SHAPE.  See #PangoCairoShapeRendererFunc for
  323  * details.
  324  *
  325  * Since: 1.18
  326  */
  327 void
  328 pango_cairo_context_set_shape_renderer (PangoContext                *context,
  329 					PangoCairoShapeRendererFunc  func,
  330 					gpointer                     data,
  331 					GDestroyNotify               dnotify)
  332 {
  333   PangoCairoContextInfo *info;
  334 
  335   g_return_if_fail (PANGO_IS_CONTEXT (context));
  336 
  337   info  = get_context_info (context, TRUE);
  338 
  339   if (info->shape_renderer_notify)
  340     info->shape_renderer_notify (info->shape_renderer_data);
  341 
  342   info->shape_renderer_func   = func;
  343   info->shape_renderer_data   = data;
  344   info->shape_renderer_notify = dnotify;
  345 }
  346 
  347 /**
  348  * pango_cairo_context_get_shape_renderer:
  349  * @context: a #PangoContext, from pango_cairo_font_map_create_context()
  350  * @data: Pointer to #gpointer to return user data
  351  *
  352  * Sets callback function for context to use for rendering attributes
  353  * of type %PANGO_ATTR_SHAPE.  See #PangoCairoShapeRendererFunc for
  354  * details.
  355  *
  356  * Retrieves callback function and associated user data for rendering
  357  * attributes of type %PANGO_ATTR_SHAPE as set by
  358  * pango_cairo_context_set_shape_renderer(), if any.
  359  *
  360  * Return value: the shape rendering callback previously set on the context, or %NULL
  361  *   if no shape rendering callback have been set.
  362  *
  363  * Since: 1.18
  364  */
  365 PangoCairoShapeRendererFunc
  366 pango_cairo_context_get_shape_renderer (PangoContext                *context,
  367 					gpointer                    *data)
  368 {
  369   PangoCairoContextInfo *info;
  370 
  371   g_return_val_if_fail (PANGO_IS_CONTEXT (context), NULL);
  372 
  373   info = get_context_info (context, FALSE);
  374 
  375   if (info)
  376     {
  377       if (data)
  378         *data = info->shape_renderer_data;
  379       return info->shape_renderer_func;
  380     }
  381   else
  382     {
  383       if (data)
  384         *data = NULL;
  385       return NULL;
  386     }
  387 }
  388 
  389 /**
  390  * pango_cairo_create_layout:
  391  * @cr: a Cairo context
  392  *
  393  * Creates a layout object set up to match the current transformation
  394  * and target surface of the Cairo context.  This layout can then be
  395  * used for text measurement with functions like
  396  * pango_layout_get_size() or drawing with functions like
  397  * pango_cairo_show_layout(). If you change the transformation
  398  * or target surface for @cr, you need to call pango_cairo_update_layout()
  399  *
  400  * This function is the most convenient way to use Cairo with Pango,
  401  * however it is slightly inefficient since it creates a separate
  402  * #PangoContext object for each layout. This might matter in an
  403  * application that was laying out large amounts of text.
  404  *
  405  * Return value: the newly created #PangoLayout. Free with
  406  *   g_object_unref().
  407  *
  408  * Since: 1.10
  409  **/
  410 PangoLayout *
  411 pango_cairo_create_layout  (cairo_t *cr)
  412 {
  413   PangoFontMap *fontmap;
  414   PangoContext *context;
  415   PangoLayout *layout;
  416 
  417   g_return_val_if_fail (cr != NULL, NULL);
  418 
  419   fontmap = pango_cairo_font_map_get_default ();
  420   context = pango_cairo_font_map_create_context ((PangoCairoFontMap *) (fontmap));
  421   layout = pango_layout_new (context);
  422 
  423   pango_cairo_update_context (cr, context);
  424   g_object_unref (context);
  425 
  426   return layout;
  427 }
  428 
  429 /**
  430  * pango_cairo_update_layout:
  431  * @cr: a Cairo context
  432  * @layout: a #PangoLayout, from pango_cairo_create_layout()
  433  *
  434  * Updates the private #PangoContext of a #PangoLayout created with
  435  * pango_cairo_create_layout() to match the current transformation
  436  * and target surface of a Cairo context.
  437  *
  438  * Since: 1.10
  439  **/
  440 void
  441 pango_cairo_update_layout (cairo_t     *cr,
  442 			   PangoLayout *layout)
  443 {
  444   g_return_if_fail (cr != NULL);
  445   g_return_if_fail (PANGO_IS_LAYOUT (layout));
  446 
  447   if (_pango_cairo_update_context (cr, pango_layout_get_context (layout)))
  448     pango_layout_context_changed (layout);
  449 }
  450