Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */
  2. /* cairo - a vector graphics library with display and print output
  3.  *
  4.  * Copyright © 2002 University of Southern California
  5.  * Copyright © 2005 Red Hat Inc.
  6.  *
  7.  * This library is free software; you can redistribute it and/or
  8.  * modify it either under the terms of the GNU Lesser General Public
  9.  * License version 2.1 as published by the Free Software Foundation
  10.  * (the "LGPL") or, at your option, under the terms of the Mozilla
  11.  * Public License Version 1.1 (the "MPL"). If you do not alter this
  12.  * notice, a recipient may use your version of this file under either
  13.  * the MPL or the LGPL.
  14.  *
  15.  * You should have received a copy of the LGPL along with this library
  16.  * in the file COPYING-LGPL-2.1; if not, write to the Free Software
  17.  * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
  18.  * You should have received a copy of the MPL along with this library
  19.  * in the file COPYING-MPL-1.1
  20.  *
  21.  * The contents of this file are subject to the Mozilla Public License
  22.  * Version 1.1 (the "License"); you may not use this file except in
  23.  * compliance with the License. You may obtain a copy of the License at
  24.  * http://www.mozilla.org/MPL/
  25.  *
  26.  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
  27.  * OF ANY KIND, either express or implied. See the LGPL or the MPL for
  28.  * the specific language governing rights and limitations.
  29.  *
  30.  * The Original Code is the cairo graphics library.
  31.  *
  32.  * The Initial Developer of the Original Code is University of Southern
  33.  * California.
  34.  *
  35.  * Contributor(s):
  36.  *      Carl D. Worth <cworth@cworth.org>
  37.  *      Graydon Hoare <graydon@redhat.com>
  38.  *      Owen Taylor <otaylor@redhat.com>
  39.  */
  40.  
  41. #include "cairoint.h"
  42. #include "cairo-error-private.h"
  43.  
  44. /**
  45.  * SECTION:cairo-font-face
  46.  * @Title: cairo_font_face_t
  47.  * @Short_Description: Base class for font faces
  48.  * @See_Also: #cairo_scaled_font_t
  49.  *
  50.  * #cairo_font_face_t represents a particular font at a particular weight,
  51.  * slant, and other characteristic but no size, transformation, or size.
  52.  *
  53.  * Font faces are created using <firstterm>font-backend</firstterm>-specific
  54.  * constructors, typically of the form
  55.  * <function>cairo_<emphasis>backend</emphasis>_font_face_create(<!-- -->)</function>,
  56.  * or implicitly using the <firstterm>toy</firstterm> text API by way of
  57.  * cairo_select_font_face().  The resulting face can be accessed using
  58.  * cairo_get_font_face().
  59.  **/
  60.  
  61. /* #cairo_font_face_t */
  62.  
  63. const cairo_font_face_t _cairo_font_face_nil = {
  64.     { 0 },                              /* hash_entry */
  65.     CAIRO_STATUS_NO_MEMORY,             /* status */
  66.     CAIRO_REFERENCE_COUNT_INVALID,      /* ref_count */
  67.     { 0, 0, 0, NULL },                  /* user_data */
  68.     NULL
  69. };
  70.  
  71. cairo_status_t
  72. _cairo_font_face_set_error (cairo_font_face_t *font_face,
  73.                             cairo_status_t     status)
  74. {
  75.     if (status == CAIRO_STATUS_SUCCESS)
  76.         return status;
  77.  
  78.     /* Don't overwrite an existing error. This preserves the first
  79.      * error, which is the most significant. */
  80.     _cairo_status_set_error (&font_face->status, status);
  81.  
  82.     return _cairo_error (status);
  83. }
  84.  
  85. void
  86. _cairo_font_face_init (cairo_font_face_t               *font_face,
  87.                        const cairo_font_face_backend_t *backend)
  88. {
  89.     CAIRO_MUTEX_INITIALIZE ();
  90.  
  91.     font_face->status = CAIRO_STATUS_SUCCESS;
  92.     CAIRO_REFERENCE_COUNT_INIT (&font_face->ref_count, 1);
  93.     font_face->backend = backend;
  94.  
  95.     _cairo_user_data_array_init (&font_face->user_data);
  96. }
  97.  
  98. /**
  99.  * cairo_font_face_reference:
  100.  * @font_face: a #cairo_font_face_t, (may be %NULL in which case this
  101.  * function does nothing).
  102.  *
  103.  * Increases the reference count on @font_face by one. This prevents
  104.  * @font_face from being destroyed until a matching call to
  105.  * cairo_font_face_destroy() is made.
  106.  *
  107.  * The number of references to a #cairo_font_face_t can be get using
  108.  * cairo_font_face_get_reference_count().
  109.  *
  110.  * Return value: the referenced #cairo_font_face_t.
  111.  *
  112.  * Since: 1.0
  113.  **/
  114. cairo_font_face_t *
  115. cairo_font_face_reference (cairo_font_face_t *font_face)
  116. {
  117.     if (font_face == NULL ||
  118.             CAIRO_REFERENCE_COUNT_IS_INVALID (&font_face->ref_count))
  119.         return font_face;
  120.  
  121.     /* We would normally assert that we have a reference here but we
  122.      * can't get away with that due to the zombie case as documented
  123.      * in _cairo_ft_font_face_destroy. */
  124.  
  125.     _cairo_reference_count_inc (&font_face->ref_count);
  126.  
  127.     return font_face;
  128. }
  129. slim_hidden_def (cairo_font_face_reference);
  130.  
  131. /**
  132.  * cairo_font_face_destroy:
  133.  * @font_face: a #cairo_font_face_t
  134.  *
  135.  * Decreases the reference count on @font_face by one. If the result
  136.  * is zero, then @font_face and all associated resources are freed.
  137.  * See cairo_font_face_reference().
  138.  *
  139.  * Since: 1.0
  140.  **/
  141. void
  142. cairo_font_face_destroy (cairo_font_face_t *font_face)
  143. {
  144.     if (font_face == NULL ||
  145.             CAIRO_REFERENCE_COUNT_IS_INVALID (&font_face->ref_count))
  146.         return;
  147.  
  148.     assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&font_face->ref_count));
  149.  
  150.     if (! _cairo_reference_count_dec_and_test (&font_face->ref_count))
  151.         return;
  152.  
  153.     if (font_face->backend->destroy)
  154.         font_face->backend->destroy (font_face);
  155.  
  156.     /* We allow resurrection to deal with some memory management for the
  157.      * FreeType backend where cairo_ft_font_face_t and cairo_ft_unscaled_font_t
  158.      * need to effectively mutually reference each other
  159.      */
  160.     if (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&font_face->ref_count))
  161.         return;
  162.  
  163.     _cairo_user_data_array_fini (&font_face->user_data);
  164.  
  165.     free (font_face);
  166. }
  167. slim_hidden_def (cairo_font_face_destroy);
  168.  
  169. /**
  170.  * cairo_font_face_get_type:
  171.  * @font_face: a font face
  172.  *
  173.  * This function returns the type of the backend used to create
  174.  * a font face. See #cairo_font_type_t for available types.
  175.  *
  176.  * Return value: The type of @font_face.
  177.  *
  178.  * Since: 1.2
  179.  **/
  180. cairo_font_type_t
  181. cairo_font_face_get_type (cairo_font_face_t *font_face)
  182. {
  183.     if (CAIRO_REFERENCE_COUNT_IS_INVALID (&font_face->ref_count))
  184.         return CAIRO_FONT_TYPE_TOY;
  185.  
  186.     return font_face->backend->type;
  187. }
  188.  
  189. /**
  190.  * cairo_font_face_get_reference_count:
  191.  * @font_face: a #cairo_font_face_t
  192.  *
  193.  * Returns the current reference count of @font_face.
  194.  *
  195.  * Return value: the current reference count of @font_face.  If the
  196.  * object is a nil object, 0 will be returned.
  197.  *
  198.  * Since: 1.4
  199.  **/
  200. unsigned int
  201. cairo_font_face_get_reference_count (cairo_font_face_t *font_face)
  202. {
  203.     if (font_face == NULL ||
  204.             CAIRO_REFERENCE_COUNT_IS_INVALID (&font_face->ref_count))
  205.         return 0;
  206.  
  207.     return CAIRO_REFERENCE_COUNT_GET_VALUE (&font_face->ref_count);
  208. }
  209.  
  210. /**
  211.  * cairo_font_face_status:
  212.  * @font_face: a #cairo_font_face_t
  213.  *
  214.  * Checks whether an error has previously occurred for this
  215.  * font face
  216.  *
  217.  * Return value: %CAIRO_STATUS_SUCCESS or another error such as
  218.  *   %CAIRO_STATUS_NO_MEMORY.
  219.  *
  220.  * Since: 1.0
  221.  **/
  222. cairo_status_t
  223. cairo_font_face_status (cairo_font_face_t *font_face)
  224. {
  225.     return font_face->status;
  226. }
  227.  
  228. /**
  229.  * cairo_font_face_get_user_data:
  230.  * @font_face: a #cairo_font_face_t
  231.  * @key: the address of the #cairo_user_data_key_t the user data was
  232.  * attached to
  233.  *
  234.  * Return user data previously attached to @font_face using the specified
  235.  * key.  If no user data has been attached with the given key this
  236.  * function returns %NULL.
  237.  *
  238.  * Return value: the user data previously attached or %NULL.
  239.  *
  240.  * Since: 1.0
  241.  **/
  242. void *
  243. cairo_font_face_get_user_data (cairo_font_face_t           *font_face,
  244.                                const cairo_user_data_key_t *key)
  245. {
  246.     return _cairo_user_data_array_get_data (&font_face->user_data,
  247.                                             key);
  248. }
  249. slim_hidden_def (cairo_font_face_get_user_data);
  250.  
  251. /**
  252.  * cairo_font_face_set_user_data:
  253.  * @font_face: a #cairo_font_face_t
  254.  * @key: the address of a #cairo_user_data_key_t to attach the user data to
  255.  * @user_data: the user data to attach to the font face
  256.  * @destroy: a #cairo_destroy_func_t which will be called when the
  257.  * font face is destroyed or when new user data is attached using the
  258.  * same key.
  259.  *
  260.  * Attach user data to @font_face.  To remove user data from a font face,
  261.  * call this function with the key that was used to set it and %NULL
  262.  * for @data.
  263.  *
  264.  * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY if a
  265.  * slot could not be allocated for the user data.
  266.  *
  267.  * Since: 1.0
  268.  **/
  269. cairo_status_t
  270. cairo_font_face_set_user_data (cairo_font_face_t           *font_face,
  271.                                const cairo_user_data_key_t *key,
  272.                                void                        *user_data,
  273.                                cairo_destroy_func_t         destroy)
  274. {
  275.     if (CAIRO_REFERENCE_COUNT_IS_INVALID (&font_face->ref_count))
  276.         return font_face->status;
  277.  
  278.     return _cairo_user_data_array_set_data (&font_face->user_data,
  279.                                             key, user_data, destroy);
  280. }
  281. slim_hidden_def (cairo_font_face_set_user_data);
  282.  
  283. void
  284. _cairo_unscaled_font_init (cairo_unscaled_font_t               *unscaled_font,
  285.                            const cairo_unscaled_font_backend_t *backend)
  286. {
  287.     CAIRO_REFERENCE_COUNT_INIT (&unscaled_font->ref_count, 1);
  288.     unscaled_font->backend = backend;
  289. }
  290.  
  291. cairo_unscaled_font_t *
  292. _cairo_unscaled_font_reference (cairo_unscaled_font_t *unscaled_font)
  293. {
  294.     if (unscaled_font == NULL)
  295.         return NULL;
  296.  
  297.     assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&unscaled_font->ref_count));
  298.  
  299.     _cairo_reference_count_inc (&unscaled_font->ref_count);
  300.  
  301.     return unscaled_font;
  302. }
  303.  
  304. void
  305. _cairo_unscaled_font_destroy (cairo_unscaled_font_t *unscaled_font)
  306. {
  307.     if (unscaled_font == NULL)
  308.         return;
  309.  
  310.     assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&unscaled_font->ref_count));
  311.  
  312.     if (! _cairo_reference_count_dec_and_test (&unscaled_font->ref_count))
  313.         return;
  314.  
  315.     unscaled_font->backend->destroy (unscaled_font);
  316.  
  317.     free (unscaled_font);
  318. }
  319.