Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | 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.  * cairo_<emphasis>backend</emphasis>_font_face_create(), or implicitly
  56.  * 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. cairo_font_face_t *
  113. cairo_font_face_reference (cairo_font_face_t *font_face)
  114. {
  115.     if (font_face == NULL ||
  116.             CAIRO_REFERENCE_COUNT_IS_INVALID (&font_face->ref_count))
  117.         return font_face;
  118.  
  119.     /* We would normally assert that we have a reference here but we
  120.      * can't get away with that due to the zombie case as documented
  121.      * in _cairo_ft_font_face_destroy. */
  122.  
  123.     _cairo_reference_count_inc (&font_face->ref_count);
  124.  
  125.     return font_face;
  126. }
  127. slim_hidden_def (cairo_font_face_reference);
  128.  
  129. /**
  130.  * cairo_font_face_destroy:
  131.  * @font_face: a #cairo_font_face_t
  132.  *
  133.  * Decreases the reference count on @font_face by one. If the result
  134.  * is zero, then @font_face and all associated resources are freed.
  135.  * See cairo_font_face_reference().
  136.  **/
  137. void
  138. cairo_font_face_destroy (cairo_font_face_t *font_face)
  139. {
  140.     if (font_face == NULL ||
  141.             CAIRO_REFERENCE_COUNT_IS_INVALID (&font_face->ref_count))
  142.         return;
  143.  
  144.     assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&font_face->ref_count));
  145.  
  146.     if (! _cairo_reference_count_dec_and_test (&font_face->ref_count))
  147.         return;
  148.  
  149.     if (font_face->backend->destroy)
  150.         font_face->backend->destroy (font_face);
  151.  
  152.     /* We allow resurrection to deal with some memory management for the
  153.      * FreeType backend where cairo_ft_font_face_t and cairo_ft_unscaled_font_t
  154.      * need to effectively mutually reference each other
  155.      */
  156.     if (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&font_face->ref_count))
  157.         return;
  158.  
  159.     _cairo_user_data_array_fini (&font_face->user_data);
  160.  
  161.     free (font_face);
  162. }
  163. slim_hidden_def (cairo_font_face_destroy);
  164.  
  165. /**
  166.  * cairo_font_face_get_type:
  167.  * @font_face: a font face
  168.  *
  169.  * This function returns the type of the backend used to create
  170.  * a font face. See #cairo_font_type_t for available types.
  171.  *
  172.  * Return value: The type of @font_face.
  173.  *
  174.  * Since: 1.2
  175.  **/
  176. cairo_font_type_t
  177. cairo_font_face_get_type (cairo_font_face_t *font_face)
  178. {
  179.     if (CAIRO_REFERENCE_COUNT_IS_INVALID (&font_face->ref_count))
  180.         return CAIRO_FONT_TYPE_TOY;
  181.  
  182.     return font_face->backend->type;
  183. }
  184.  
  185. /**
  186.  * cairo_font_face_get_reference_count:
  187.  * @font_face: a #cairo_font_face_t
  188.  *
  189.  * Returns the current reference count of @font_face.
  190.  *
  191.  * Return value: the current reference count of @font_face.  If the
  192.  * object is a nil object, 0 will be returned.
  193.  *
  194.  * Since: 1.4
  195.  **/
  196. unsigned int
  197. cairo_font_face_get_reference_count (cairo_font_face_t *font_face)
  198. {
  199.     if (font_face == NULL ||
  200.             CAIRO_REFERENCE_COUNT_IS_INVALID (&font_face->ref_count))
  201.         return 0;
  202.  
  203.     return CAIRO_REFERENCE_COUNT_GET_VALUE (&font_face->ref_count);
  204. }
  205.  
  206. /**
  207.  * cairo_font_face_status:
  208.  * @font_face: a #cairo_font_face_t
  209.  *
  210.  * Checks whether an error has previously occurred for this
  211.  * font face
  212.  *
  213.  * Return value: %CAIRO_STATUS_SUCCESS or another error such as
  214.  *   %CAIRO_STATUS_NO_MEMORY.
  215.  **/
  216. cairo_status_t
  217. cairo_font_face_status (cairo_font_face_t *font_face)
  218. {
  219.     return font_face->status;
  220. }
  221.  
  222. /**
  223.  * cairo_font_face_get_user_data:
  224.  * @font_face: a #cairo_font_face_t
  225.  * @key: the address of the #cairo_user_data_key_t the user data was
  226.  * attached to
  227.  *
  228.  * Return user data previously attached to @font_face using the specified
  229.  * key.  If no user data has been attached with the given key this
  230.  * function returns %NULL.
  231.  *
  232.  * Return value: the user data previously attached or %NULL.
  233.  **/
  234. void *
  235. cairo_font_face_get_user_data (cairo_font_face_t           *font_face,
  236.                                const cairo_user_data_key_t *key)
  237. {
  238.     return _cairo_user_data_array_get_data (&font_face->user_data,
  239.                                             key);
  240. }
  241. slim_hidden_def (cairo_font_face_get_user_data);
  242.  
  243. /**
  244.  * cairo_font_face_set_user_data:
  245.  * @font_face: a #cairo_font_face_t
  246.  * @key: the address of a #cairo_user_data_key_t to attach the user data to
  247.  * @user_data: the user data to attach to the font face
  248.  * @destroy: a #cairo_destroy_func_t which will be called when the
  249.  * font face is destroyed or when new user data is attached using the
  250.  * same key.
  251.  *
  252.  * Attach user data to @font_face.  To remove user data from a font face,
  253.  * call this function with the key that was used to set it and %NULL
  254.  * for @data.
  255.  *
  256.  * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY if a
  257.  * slot could not be allocated for the user data.
  258.  **/
  259. cairo_status_t
  260. cairo_font_face_set_user_data (cairo_font_face_t           *font_face,
  261.                                const cairo_user_data_key_t *key,
  262.                                void                        *user_data,
  263.                                cairo_destroy_func_t         destroy)
  264. {
  265.     if (CAIRO_REFERENCE_COUNT_IS_INVALID (&font_face->ref_count))
  266.         return font_face->status;
  267.  
  268.     return _cairo_user_data_array_set_data (&font_face->user_data,
  269.                                             key, user_data, destroy);
  270. }
  271. slim_hidden_def (cairo_font_face_set_user_data);
  272.  
  273. void
  274. _cairo_unscaled_font_init (cairo_unscaled_font_t               *unscaled_font,
  275.                            const cairo_unscaled_font_backend_t *backend)
  276. {
  277.     CAIRO_REFERENCE_COUNT_INIT (&unscaled_font->ref_count, 1);
  278.     unscaled_font->backend = backend;
  279. }
  280.  
  281. cairo_unscaled_font_t *
  282. _cairo_unscaled_font_reference (cairo_unscaled_font_t *unscaled_font)
  283. {
  284.     if (unscaled_font == NULL)
  285.         return NULL;
  286.  
  287.     assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&unscaled_font->ref_count));
  288.  
  289.     _cairo_reference_count_inc (&unscaled_font->ref_count);
  290.  
  291.     return unscaled_font;
  292. }
  293.  
  294. void
  295. _cairo_unscaled_font_destroy (cairo_unscaled_font_t *unscaled_font)
  296. {
  297.     if (unscaled_font == NULL)
  298.         return;
  299.  
  300.     assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&unscaled_font->ref_count));
  301.  
  302.     if (! _cairo_reference_count_dec_and_test (&unscaled_font->ref_count))
  303.         return;
  304.  
  305.     unscaled_font->backend->destroy (unscaled_font);
  306.  
  307.     free (unscaled_font);
  308. }
  309.