Subversion Repositories Kolibri OS

Rev

Rev 1892 | Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. /* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
  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.  */
  38.  
  39. #include "cairoint.h"
  40.  
  41. #include "cairo-array-private.h"
  42. #include "cairo-clip-inline.h"
  43. #include "cairo-clip-private.h"
  44. #include "cairo-damage-private.h"
  45. #include "cairo-device-private.h"
  46. #include "cairo-error-private.h"
  47. #include "cairo-list-inline.h"
  48. #include "cairo-image-surface-inline.h"
  49. #include "cairo-recording-surface-private.h"
  50. #include "cairo-region-private.h"
  51. #include "cairo-surface-inline.h"
  52. #include "cairo-tee-surface-private.h"
  53.  
  54. /**
  55.  * SECTION:cairo-surface
  56.  * @Title: cairo_surface_t
  57.  * @Short_Description: Base class for surfaces
  58.  * @See_Also: #cairo_t, #cairo_pattern_t
  59.  *
  60.  * #cairo_surface_t is the abstract type representing all different drawing
  61.  * targets that cairo can render to.  The actual drawings are
  62.  * performed using a cairo <firstterm>context</firstterm>.
  63.  *
  64.  * A cairo surface is created by using <firstterm>backend</firstterm>-specific
  65.  * constructors, typically of the form
  66.  * <function>cairo_<emphasis>backend</emphasis>_surface_create(<!-- -->)</function>.
  67.  *
  68.  * Most surface types allow accessing the surface without using Cairo
  69.  * functions. If you do this, keep in mind that it is mandatory that you call
  70.  * cairo_surface_flush() before reading from or writing to the surface and that
  71.  * you must use cairo_surface_mark_dirty() after modifying it.
  72.  * <example>
  73.  * <title>Directly modifying an image surface</title>
  74.  * <programlisting>
  75.  * void
  76.  * modify_image_surface (cairo_surface_t *surface)
  77.  * {
  78.  *   unsigned char *data;
  79.  *   int width, height, stride;
  80.  *
  81.  *   // flush to ensure all writing to the image was done
  82.  *   cairo_surface_flush (surface);
  83.  *
  84.  *   // modify the image
  85.  *   data = cairo_image_surface_get_data (surface);
  86.  *   width = cairo_image_surface_get_width (surface);
  87.  *   height = cairo_image_surface_get_height (surface);
  88.  *   stride = cairo_image_surface_get_stride (surface);
  89.  *   modify_image_data (data, width, height, stride);
  90.  *
  91.  *   // mark the image dirty so Cairo clears its caches.
  92.  *   cairo_surface_mark_dirty (surface);
  93.  * }
  94.  * </programlisting>
  95.  * </example>
  96.  * Note that for other surface types it might be necessary to acquire the
  97.  * surface's device first. See cairo_device_acquire() for a discussion of
  98.  * devices.
  99.  **/
  100.  
  101. #define DEFINE_NIL_SURFACE(status, name)                        \
  102. const cairo_surface_t name = {                                  \
  103.     NULL,                               /* backend */           \
  104.     NULL,                               /* device */            \
  105.     CAIRO_SURFACE_TYPE_IMAGE,           /* type */              \
  106.     CAIRO_CONTENT_COLOR,                /* content */           \
  107.     CAIRO_REFERENCE_COUNT_INVALID,      /* ref_count */         \
  108.     status,                             /* status */            \
  109.     0,                                  /* unique id */         \
  110.     0,                                  /* serial */            \
  111.     NULL,                               /* damage */            \
  112.     FALSE,                              /* _finishing */        \
  113.     FALSE,                              /* finished */          \
  114.     TRUE,                               /* is_clear */          \
  115.     FALSE,                              /* has_font_options */  \
  116.     FALSE,                              /* owns_device */       \
  117.     { 0, 0, 0, NULL, },                 /* user_data */         \
  118.     { 0, 0, 0, NULL, },                 /* mime_data */         \
  119.     { 1.0, 0.0, 0.0, 1.0, 0.0, 0.0 },   /* device_transform */  \
  120.     { 1.0, 0.0, 0.0, 1.0, 0.0, 0.0 },   /* device_transform_inverse */  \
  121.     { NULL, NULL },                     /* device_transform_observers */ \
  122.     0.0,                                /* x_resolution */      \
  123.     0.0,                                /* y_resolution */      \
  124.     0.0,                                /* x_fallback_resolution */     \
  125.     0.0,                                /* y_fallback_resolution */     \
  126.     NULL,                               /* snapshot_of */       \
  127.     NULL,                               /* snapshot_detach */   \
  128.     { NULL, NULL },                     /* snapshots */         \
  129.     { NULL, NULL },                     /* snapshot */          \
  130.     { CAIRO_ANTIALIAS_DEFAULT,          /* antialias */         \
  131.       CAIRO_SUBPIXEL_ORDER_DEFAULT,     /* subpixel_order */    \
  132.       CAIRO_LCD_FILTER_DEFAULT,         /* lcd_filter */        \
  133.       CAIRO_HINT_STYLE_DEFAULT,         /* hint_style */        \
  134.       CAIRO_HINT_METRICS_DEFAULT,       /* hint_metrics */      \
  135.       CAIRO_ROUND_GLYPH_POS_DEFAULT     /* round_glyph_positions */     \
  136.     }                                   /* font_options */      \
  137. }
  138.  
  139. /* XXX error object! */
  140.  
  141. static DEFINE_NIL_SURFACE(CAIRO_STATUS_NO_MEMORY, _cairo_surface_nil);
  142. static DEFINE_NIL_SURFACE(CAIRO_STATUS_SURFACE_TYPE_MISMATCH, _cairo_surface_nil_surface_type_mismatch);
  143. static DEFINE_NIL_SURFACE(CAIRO_STATUS_INVALID_STATUS, _cairo_surface_nil_invalid_status);
  144. static DEFINE_NIL_SURFACE(CAIRO_STATUS_INVALID_CONTENT, _cairo_surface_nil_invalid_content);
  145. static DEFINE_NIL_SURFACE(CAIRO_STATUS_INVALID_FORMAT, _cairo_surface_nil_invalid_format);
  146. static DEFINE_NIL_SURFACE(CAIRO_STATUS_INVALID_VISUAL, _cairo_surface_nil_invalid_visual);
  147. static DEFINE_NIL_SURFACE(CAIRO_STATUS_FILE_NOT_FOUND, _cairo_surface_nil_file_not_found);
  148. static DEFINE_NIL_SURFACE(CAIRO_STATUS_TEMP_FILE_ERROR, _cairo_surface_nil_temp_file_error);
  149. static DEFINE_NIL_SURFACE(CAIRO_STATUS_READ_ERROR, _cairo_surface_nil_read_error);
  150. static DEFINE_NIL_SURFACE(CAIRO_STATUS_WRITE_ERROR, _cairo_surface_nil_write_error);
  151. static DEFINE_NIL_SURFACE(CAIRO_STATUS_INVALID_STRIDE, _cairo_surface_nil_invalid_stride);
  152. static DEFINE_NIL_SURFACE(CAIRO_STATUS_INVALID_SIZE, _cairo_surface_nil_invalid_size);
  153. static DEFINE_NIL_SURFACE(CAIRO_STATUS_DEVICE_TYPE_MISMATCH, _cairo_surface_nil_device_type_mismatch);
  154. static DEFINE_NIL_SURFACE(CAIRO_STATUS_DEVICE_ERROR, _cairo_surface_nil_device_error);
  155.  
  156. static DEFINE_NIL_SURFACE(CAIRO_INT_STATUS_UNSUPPORTED, _cairo_surface_nil_unsupported);
  157. static DEFINE_NIL_SURFACE(CAIRO_INT_STATUS_NOTHING_TO_DO, _cairo_surface_nil_nothing_to_do);
  158.  
  159. static void _cairo_surface_finish_snapshots (cairo_surface_t *surface);
  160. static void _cairo_surface_finish (cairo_surface_t *surface);
  161.  
  162. /**
  163.  * _cairo_surface_set_error:
  164.  * @surface: a surface
  165.  * @status: a status value indicating an error
  166.  *
  167.  * Atomically sets surface->status to @status and calls _cairo_error;
  168.  * Does nothing if status is %CAIRO_STATUS_SUCCESS or any of the internal
  169.  * status values.
  170.  *
  171.  * All assignments of an error status to surface->status should happen
  172.  * through _cairo_surface_set_error(). Note that due to the nature of
  173.  * the atomic operation, it is not safe to call this function on the
  174.  * nil objects.
  175.  *
  176.  * The purpose of this function is to allow the user to set a
  177.  * breakpoint in _cairo_error() to generate a stack trace for when the
  178.  * user causes cairo to detect an error.
  179.  *
  180.  * Return value: the error status.
  181.  **/
  182. cairo_int_status_t
  183. _cairo_surface_set_error (cairo_surface_t *surface,
  184.                           cairo_int_status_t status)
  185. {
  186.     /* NOTHING_TO_DO is magic. We use it to break out of the inner-most
  187.      * surface function, but anything higher just sees "success".
  188.      */
  189.     if (status == CAIRO_INT_STATUS_NOTHING_TO_DO)
  190.         status = CAIRO_INT_STATUS_SUCCESS;
  191.  
  192.     if (status == CAIRO_INT_STATUS_SUCCESS ||
  193.         status >= (int)CAIRO_INT_STATUS_LAST_STATUS)
  194.         return status;
  195.  
  196.     /* Don't overwrite an existing error. This preserves the first
  197.      * error, which is the most significant. */
  198.     _cairo_status_set_error (&surface->status, (cairo_status_t)status);
  199.  
  200.     return _cairo_error (status);
  201. }
  202.  
  203. /**
  204.  * cairo_surface_get_type:
  205.  * @surface: a #cairo_surface_t
  206.  *
  207.  * This function returns the type of the backend used to create
  208.  * a surface. See #cairo_surface_type_t for available types.
  209.  *
  210.  * Return value: The type of @surface.
  211.  *
  212.  * Since: 1.2
  213.  **/
  214. cairo_surface_type_t
  215. cairo_surface_get_type (cairo_surface_t *surface)
  216. {
  217.     /* We don't use surface->backend->type here so that some of the
  218.      * special "wrapper" surfaces such as cairo_paginated_surface_t
  219.      * can override surface->type with the type of the "child"
  220.      * surface. */
  221.     return surface->type;
  222. }
  223.  
  224. /**
  225.  * cairo_surface_get_content:
  226.  * @surface: a #cairo_surface_t
  227.  *
  228.  * This function returns the content type of @surface which indicates
  229.  * whether the surface contains color and/or alpha information. See
  230.  * #cairo_content_t.
  231.  *
  232.  * Return value: The content type of @surface.
  233.  *
  234.  * Since: 1.2
  235.  **/
  236. cairo_content_t
  237. cairo_surface_get_content (cairo_surface_t *surface)
  238. {
  239.     return surface->content;
  240. }
  241.  
  242. /**
  243.  * cairo_surface_status:
  244.  * @surface: a #cairo_surface_t
  245.  *
  246.  * Checks whether an error has previously occurred for this
  247.  * surface.
  248.  *
  249.  * Return value: %CAIRO_STATUS_SUCCESS, %CAIRO_STATUS_NULL_POINTER,
  250.  * %CAIRO_STATUS_NO_MEMORY, %CAIRO_STATUS_READ_ERROR,
  251.  * %CAIRO_STATUS_INVALID_CONTENT, %CAIRO_STATUS_INVALID_FORMAT, or
  252.  * %CAIRO_STATUS_INVALID_VISUAL.
  253.  *
  254.  * Since: 1.0
  255.  **/
  256. cairo_status_t
  257. cairo_surface_status (cairo_surface_t *surface)
  258. {
  259.     return surface->status;
  260. }
  261. slim_hidden_def (cairo_surface_status);
  262.  
  263. static unsigned int
  264. _cairo_surface_allocate_unique_id (void)
  265. {
  266.     static cairo_atomic_int_t unique_id;
  267.  
  268. #if CAIRO_NO_MUTEX
  269.     if (++unique_id == 0)
  270.         unique_id = 1;
  271.     return unique_id;
  272. #else
  273.     cairo_atomic_int_t old, id;
  274.  
  275.     do {
  276.         old = _cairo_atomic_uint_get (&unique_id);
  277.         id = old + 1;
  278.         if (id == 0)
  279.             id = 1;
  280.     } while (! _cairo_atomic_uint_cmpxchg (&unique_id, old, id));
  281.  
  282.     return id;
  283. #endif
  284. }
  285.  
  286. /**
  287.  * cairo_surface_get_device:
  288.  * @surface: a #cairo_surface_t
  289.  *
  290.  * This function returns the device for a @surface.
  291.  * See #cairo_device_t.
  292.  *
  293.  * Return value: The device for @surface or %NULL if the surface does
  294.  *               not have an associated device.
  295.  *
  296.  * Since: 1.10
  297.  **/
  298. cairo_device_t *
  299. cairo_surface_get_device (cairo_surface_t *surface)
  300. {
  301.     if (unlikely (surface->status))
  302.         return _cairo_device_create_in_error (surface->status);
  303.  
  304.     return surface->device;
  305. }
  306.  
  307. static cairo_bool_t
  308. _cairo_surface_has_snapshots (cairo_surface_t *surface)
  309. {
  310.     return ! cairo_list_is_empty (&surface->snapshots);
  311. }
  312.  
  313. static cairo_bool_t
  314. _cairo_surface_has_mime_data (cairo_surface_t *surface)
  315. {
  316.     return surface->mime_data.num_elements != 0;
  317. }
  318.  
  319. static void
  320. _cairo_surface_detach_mime_data (cairo_surface_t *surface)
  321. {
  322.     if (! _cairo_surface_has_mime_data (surface))
  323.         return;
  324.  
  325.     _cairo_user_data_array_fini (&surface->mime_data);
  326.     _cairo_user_data_array_init (&surface->mime_data);
  327. }
  328.  
  329. static void
  330. _cairo_surface_detach_snapshots (cairo_surface_t *surface)
  331. {
  332.     while (_cairo_surface_has_snapshots (surface)) {
  333.         _cairo_surface_detach_snapshot (cairo_list_first_entry (&surface->snapshots,
  334.                                                                 cairo_surface_t,
  335.                                                                 snapshot));
  336.     }
  337. }
  338.  
  339. void
  340. _cairo_surface_detach_snapshot (cairo_surface_t *snapshot)
  341. {
  342.     assert (snapshot->snapshot_of != NULL);
  343.  
  344.     snapshot->snapshot_of = NULL;
  345.     cairo_list_del (&snapshot->snapshot);
  346.  
  347.     if (snapshot->snapshot_detach != NULL)
  348.         snapshot->snapshot_detach (snapshot);
  349.  
  350.     cairo_surface_destroy (snapshot);
  351. }
  352.  
  353. void
  354. _cairo_surface_attach_snapshot (cairo_surface_t *surface,
  355.                                  cairo_surface_t *snapshot,
  356.                                  cairo_surface_func_t detach_func)
  357. {
  358.     assert (surface != snapshot);
  359.     assert (snapshot->snapshot_of != surface);
  360.  
  361.     cairo_surface_reference (snapshot);
  362.  
  363.     if (snapshot->snapshot_of != NULL)
  364.         _cairo_surface_detach_snapshot (snapshot);
  365.  
  366.     snapshot->snapshot_of = surface;
  367.     snapshot->snapshot_detach = detach_func;
  368.  
  369.     cairo_list_add (&snapshot->snapshot, &surface->snapshots);
  370.  
  371.     assert (_cairo_surface_has_snapshot (surface, snapshot->backend) == snapshot);
  372. }
  373.  
  374. cairo_surface_t *
  375. _cairo_surface_has_snapshot (cairo_surface_t *surface,
  376.                              const cairo_surface_backend_t *backend)
  377. {
  378.     cairo_surface_t *snapshot;
  379.  
  380.     cairo_list_foreach_entry (snapshot, cairo_surface_t,
  381.                               &surface->snapshots, snapshot)
  382.     {
  383.         if (snapshot->backend == backend)
  384.             return snapshot;
  385.     }
  386.  
  387.     return NULL;
  388. }
  389.  
  390. cairo_status_t
  391. _cairo_surface_begin_modification (cairo_surface_t *surface)
  392. {
  393.     assert (surface->status == CAIRO_STATUS_SUCCESS);
  394.     assert (! surface->finished);
  395.  
  396.     return _cairo_surface_flush (surface, 1);
  397. }
  398.  
  399. void
  400. _cairo_surface_init (cairo_surface_t                    *surface,
  401.                      const cairo_surface_backend_t      *backend,
  402.                      cairo_device_t                     *device,
  403.                      cairo_content_t                     content)
  404. {
  405.     CAIRO_MUTEX_INITIALIZE ();
  406.  
  407.     surface->backend = backend;
  408.     surface->device = cairo_device_reference (device);
  409.     surface->content = content;
  410.     surface->type = backend->type;
  411.  
  412.     CAIRO_REFERENCE_COUNT_INIT (&surface->ref_count, 1);
  413.     surface->status = CAIRO_STATUS_SUCCESS;
  414.     surface->unique_id = _cairo_surface_allocate_unique_id ();
  415.     surface->finished = FALSE;
  416.     surface->_finishing = FALSE;
  417.     surface->is_clear = FALSE;
  418.     surface->serial = 0;
  419.     surface->damage = NULL;
  420.     surface->owns_device = (device != NULL);
  421.  
  422.     _cairo_user_data_array_init (&surface->user_data);
  423.     _cairo_user_data_array_init (&surface->mime_data);
  424.  
  425.     cairo_matrix_init_identity (&surface->device_transform);
  426.     cairo_matrix_init_identity (&surface->device_transform_inverse);
  427.     cairo_list_init (&surface->device_transform_observers);
  428.  
  429.     surface->x_resolution = CAIRO_SURFACE_RESOLUTION_DEFAULT;
  430.     surface->y_resolution = CAIRO_SURFACE_RESOLUTION_DEFAULT;
  431.  
  432.     surface->x_fallback_resolution = CAIRO_SURFACE_FALLBACK_RESOLUTION_DEFAULT;
  433.     surface->y_fallback_resolution = CAIRO_SURFACE_FALLBACK_RESOLUTION_DEFAULT;
  434.  
  435.     cairo_list_init (&surface->snapshots);
  436.     surface->snapshot_of = NULL;
  437.  
  438.     surface->has_font_options = FALSE;
  439. }
  440.  
  441. static void
  442. _cairo_surface_copy_similar_properties (cairo_surface_t *surface,
  443.                                         cairo_surface_t *other)
  444. {
  445.     if (other->has_font_options || other->backend != surface->backend) {
  446.         cairo_font_options_t options;
  447.  
  448.         cairo_surface_get_font_options (other, &options);
  449.         _cairo_surface_set_font_options (surface, &options);
  450.     }
  451.  
  452.     cairo_surface_set_fallback_resolution (surface,
  453.                                            other->x_fallback_resolution,
  454.                                            other->y_fallback_resolution);
  455. }
  456.  
  457. cairo_surface_t *
  458. _cairo_surface_create_similar_scratch (cairo_surface_t *other,
  459.                                        cairo_content_t  content,
  460.                                        int              width,
  461.                                        int              height)
  462. {
  463.     cairo_surface_t *surface;
  464.  
  465.     if (unlikely (other->status))
  466.         return _cairo_surface_create_in_error (other->status);
  467.  
  468.     surface = NULL;
  469.     if (other->backend->create_similar)
  470.         surface = other->backend->create_similar (other, content, width, height);
  471.     if (surface == NULL)
  472.         surface = cairo_surface_create_similar_image (other,
  473.                                                       _cairo_format_from_content (content),
  474.                                                       width, height);
  475.  
  476.     if (unlikely (surface->status))
  477.         return surface;
  478.  
  479.     _cairo_surface_copy_similar_properties (surface, other);
  480.  
  481.     return surface;
  482. }
  483.  
  484. /**
  485.  * cairo_surface_create_similar:
  486.  * @other: an existing surface used to select the backend of the new surface
  487.  * @content: the content for the new surface
  488.  * @width: width of the new surface, (in device-space units)
  489.  * @height: height of the new surface (in device-space units)
  490.  *
  491.  * Create a new surface that is as compatible as possible with an
  492.  * existing surface. For example the new surface will have the same
  493.  * fallback resolution and font options as @other. Generally, the new
  494.  * surface will also use the same backend as @other, unless that is
  495.  * not possible for some reason. The type of the returned surface may
  496.  * be examined with cairo_surface_get_type().
  497.  *
  498.  * Initially the surface contents are all 0 (transparent if contents
  499.  * have transparency, black otherwise.)
  500.  *
  501.  * Use cairo_surface_create_similar_image() if you need an image surface
  502.  * which can be painted quickly to the target surface.
  503.  *
  504.  * Return value: a pointer to the newly allocated surface. The caller
  505.  * owns the surface and should call cairo_surface_destroy() when done
  506.  * with it.
  507.  *
  508.  * This function always returns a valid pointer, but it will return a
  509.  * pointer to a "nil" surface if @other is already in an error state
  510.  * or any other error occurs.
  511.  *
  512.  * Since: 1.0
  513.  **/
  514. cairo_surface_t *
  515. cairo_surface_create_similar (cairo_surface_t  *other,
  516.                               cairo_content_t   content,
  517.                               int               width,
  518.                               int               height)
  519. {
  520.     cairo_surface_t *surface;
  521.  
  522.     if (unlikely (other->status))
  523.         return _cairo_surface_create_in_error (other->status);
  524.     if (unlikely (other->finished))
  525.         return _cairo_surface_create_in_error (CAIRO_STATUS_SURFACE_FINISHED);
  526.     if (unlikely (width < 0 || height < 0))
  527.         return _cairo_surface_create_in_error (CAIRO_STATUS_INVALID_SIZE);
  528.  
  529.     if (unlikely (! CAIRO_CONTENT_VALID (content)))
  530.         return _cairo_surface_create_in_error (CAIRO_STATUS_INVALID_CONTENT);
  531.  
  532.     surface = _cairo_surface_create_similar_solid (other,
  533.                                                    content, width, height,
  534.                                                    CAIRO_COLOR_TRANSPARENT);
  535.     assert (surface->is_clear);
  536.  
  537.     return surface;
  538. }
  539.  
  540. /**
  541.  * cairo_surface_create_similar_image:
  542.  * @other: an existing surface used to select the preference of the new surface
  543.  * @format: the format for the new surface
  544.  * @width: width of the new surface, (in device-space units)
  545.  * @height: height of the new surface (in device-space units)
  546.  *
  547.  * Create a new image surface that is as compatible as possible for uploading
  548.  * to and the use in conjunction with an existing surface. However, this surface
  549.  * can still be used like any normal image surface.
  550.  *
  551.  * Initially the surface contents are all 0 (transparent if contents
  552.  * have transparency, black otherwise.)
  553.  *
  554.  * Use cairo_surface_create_similar() if you don't need an image surface.
  555.  *
  556.  * Return value: a pointer to the newly allocated image surface. The caller
  557.  * owns the surface and should call cairo_surface_destroy() when done
  558.  * with it.
  559.  *
  560.  * This function always returns a valid pointer, but it will return a
  561.  * pointer to a "nil" surface if @other is already in an error state
  562.  * or any other error occurs.
  563.  *
  564.  * Since: 1.12
  565.  **/
  566. cairo_surface_t *
  567. cairo_surface_create_similar_image (cairo_surface_t  *other,
  568.                                     cairo_format_t    format,
  569.                                     int         width,
  570.                                     int         height)
  571. {
  572.     cairo_surface_t *image;
  573.  
  574.     if (unlikely (other->status))
  575.         return _cairo_surface_create_in_error (other->status);
  576.     if (unlikely (other->finished))
  577.         return _cairo_surface_create_in_error (CAIRO_STATUS_SURFACE_FINISHED);
  578.  
  579.     if (unlikely (width < 0 || height < 0))
  580.         return _cairo_surface_create_in_error (CAIRO_STATUS_INVALID_SIZE);
  581.     if (unlikely (! CAIRO_FORMAT_VALID (format)))
  582.         return _cairo_surface_create_in_error (CAIRO_STATUS_INVALID_FORMAT);
  583.  
  584.     image = NULL;
  585.     if (other->backend->create_similar_image)
  586.         image = other->backend->create_similar_image (other,
  587.                                                       format, width, height);
  588.     if (image == NULL)
  589.         image = cairo_image_surface_create (format, width, height);
  590.  
  591.     assert (image->is_clear);
  592.  
  593.     return image;
  594. }
  595. slim_hidden_def (cairo_surface_create_similar_image);
  596.  
  597. /**
  598.  * _cairo_surface_map_to_image:
  599.  * @surface: an existing surface used to extract the image from
  600.  * @extents: limit the extraction to an rectangular region
  601.  *
  602.  * Returns an image surface that is the most efficient mechanism for
  603.  * modifying the backing store of the target surface. The region
  604.  * retrieved is limited to @extents.
  605.  *
  606.  * Note, the use of the original surface as a target or source whilst
  607.  * it is mapped is undefined. The result of mapping the surface
  608.  * multiple times is undefined. Calling cairo_surface_destroy() or
  609.  * cairo_surface_finish() on the resulting image surface results in
  610.  * undefined behavior. Changing the device transform of the image
  611.  * surface or of @surface before the image surface is unmapped results
  612.  * in undefined behavior.
  613.  *
  614.  * Assumes that @surface is valid (CAIRO_STATUS_SUCCESS,
  615.  * non-finished).
  616.  *
  617.  * Return value: a pointer to the newly allocated image surface. The
  618.  * caller must use _cairo_surface_unmap_image() to destroy this image
  619.  * surface.
  620.  *
  621.  * This function always returns a valid pointer, but it will return a
  622.  * pointer to a "nil" surface if @other is already in an error state
  623.  * or any other error occurs.
  624.  *
  625.  * The returned image might have a %CAIRO_FORMAT_INVALID format.
  626.  **/
  627. cairo_image_surface_t *
  628. _cairo_surface_map_to_image (cairo_surface_t  *surface,
  629.                              const cairo_rectangle_int_t *extents)
  630. {
  631.     cairo_image_surface_t *image = NULL;
  632.  
  633.     assert (extents != NULL);
  634.  
  635.     /* TODO: require map_to_image != NULL */
  636.     if (surface->backend->map_to_image)
  637.         image = surface->backend->map_to_image (surface, extents);
  638.  
  639.     if (image == NULL)
  640.         image = _cairo_image_surface_clone_subimage (surface, extents);
  641.  
  642.     return image;
  643. }
  644.  
  645. /**
  646.  * _cairo_surface_unmap_image:
  647.  * @surface: the surface passed to _cairo_surface_map_to_image().
  648.  * @image: the currently mapped image
  649.  *
  650.  * Unmaps the image surface as returned from
  651.  * _cairo_surface_map_to_image().
  652.  *
  653.  * The content of the image will be uploaded to the target surface.
  654.  * Afterwards, the image is destroyed.
  655.  *
  656.  * Using an image surface which wasn't returned by
  657.  * _cairo_surface_map_to_image() results in undefined behavior.
  658.  *
  659.  * An image surface in error status can be passed to
  660.  * _cairo_surface_unmap_image().
  661.  *
  662.  * Return value: the unmap status.
  663.  *
  664.  * Even if the unmap status is not successful, @image is destroyed.
  665.  **/
  666. cairo_int_status_t
  667. _cairo_surface_unmap_image (cairo_surface_t       *surface,
  668.                             cairo_image_surface_t *image)
  669. {
  670.     cairo_surface_pattern_t pattern;
  671.     cairo_rectangle_int_t extents;
  672.     cairo_clip_t *clip;
  673.     cairo_int_status_t status;
  674.  
  675.     /* map_to_image can return error surfaces */
  676.     if (unlikely (image->base.status)) {
  677.         status = image->base.status;
  678.         goto destroy;
  679.     }
  680.  
  681.     /* If the image is untouched just skip the update */
  682.     if (image->base.serial == 0) {
  683.         status = CAIRO_STATUS_SUCCESS;
  684.         goto destroy;
  685.     }
  686.  
  687.     /* TODO: require unmap_image != NULL */
  688.     if (surface->backend->unmap_image &&
  689.         ! _cairo_image_surface_is_clone (image))
  690.     {
  691.         status = surface->backend->unmap_image (surface, image);
  692.         if (status != CAIRO_INT_STATUS_UNSUPPORTED)
  693.             return status;
  694.     }
  695.  
  696.     _cairo_pattern_init_for_surface (&pattern, &image->base);
  697.     pattern.base.filter = CAIRO_FILTER_NEAREST;
  698.  
  699.     /* We have to apply the translate from map_to_image's extents.x and .y */
  700.     cairo_matrix_init_translate (&pattern.base.matrix,
  701.                                  image->base.device_transform.x0,
  702.                                  image->base.device_transform.y0);
  703.  
  704.     /* And we also have to clip the operation to the image's extents */
  705.     extents.x = image->base.device_transform_inverse.x0;
  706.     extents.y = image->base.device_transform_inverse.y0;
  707.     extents.width  = image->width;
  708.     extents.height = image->height;
  709.     clip = _cairo_clip_intersect_rectangle (NULL, &extents);
  710.  
  711.     status = _cairo_surface_paint (surface,
  712.                                    CAIRO_OPERATOR_SOURCE,
  713.                                    &pattern.base,
  714.                                    clip);
  715.  
  716.     _cairo_pattern_fini (&pattern.base);
  717.     _cairo_clip_destroy (clip);
  718.  
  719. destroy:
  720.     cairo_surface_finish (&image->base);
  721.     cairo_surface_destroy (&image->base);
  722.  
  723.     return status;
  724. }
  725.  
  726. /**
  727.  * cairo_surface_map_to_image:
  728.  * @surface: an existing surface used to extract the image from
  729.  * @extents: limit the extraction to an rectangular region
  730.  *
  731.  * Returns an image surface that is the most efficient mechanism for
  732.  * modifying the backing store of the target surface. The region retrieved
  733.  * may be limited to the @extents or %NULL for the whole surface
  734.  *
  735.  * Note, the use of the original surface as a target or source whilst
  736.  * it is mapped is undefined. The result of mapping the surface
  737.  * multiple times is undefined. Calling cairo_surface_destroy() or
  738.  * cairo_surface_finish() on the resulting image surface results in
  739.  * undefined behavior. Changing the device transform of the image
  740.  * surface or of @surface before the image surface is unmapped results
  741.  * in undefined behavior.
  742.  *
  743.  * Return value: a pointer to the newly allocated image surface. The caller
  744.  * must use cairo_surface_unmap_image() to destroy this image surface.
  745.  *
  746.  * This function always returns a valid pointer, but it will return a
  747.  * pointer to a "nil" surface if @other is already in an error state
  748.  * or any other error occurs. If the returned pointer does not have an
  749.  * error status, it is guaranteed to be an image surface whose format
  750.  * is not %CAIRO_FORMAT_INVALID.
  751.  *
  752.  * Since: 1.12
  753.  **/
  754. cairo_surface_t *
  755. cairo_surface_map_to_image (cairo_surface_t  *surface,
  756.                             const cairo_rectangle_int_t *extents)
  757. {
  758.     cairo_rectangle_int_t rect;
  759.     cairo_image_surface_t *image;
  760.     cairo_status_t status;
  761.  
  762.     if (unlikely (surface->status))
  763.         return _cairo_surface_create_in_error (surface->status);
  764.     if (unlikely (surface->finished))
  765.         return _cairo_surface_create_in_error (CAIRO_STATUS_SURFACE_FINISHED);
  766.  
  767.     if (extents == NULL) {
  768.         if (unlikely (! surface->backend->get_extents (surface, &rect)))
  769.             return _cairo_surface_create_in_error (CAIRO_STATUS_INVALID_SIZE);
  770.  
  771.         extents = &rect;
  772.     } else {
  773.         cairo_rectangle_int_t surface_extents;
  774.  
  775.         /* If this surface is bounded, we can't map parts
  776.          * that are outside of it. */
  777.         if (likely (surface->backend->get_extents (surface, &surface_extents))) {
  778.             if (unlikely (! _cairo_rectangle_contains_rectangle (&surface_extents, extents)))
  779.                 return _cairo_surface_create_in_error (CAIRO_STATUS_INVALID_SIZE);
  780.         }
  781.     }
  782.  
  783.     image = _cairo_surface_map_to_image (surface, extents);
  784.  
  785.     status = image->base.status;
  786.     if (unlikely (status)) {
  787.         cairo_surface_destroy (&image->base);
  788.         return _cairo_surface_create_in_error (status);
  789.     }
  790.  
  791.     if (image->format == CAIRO_FORMAT_INVALID) {
  792.         cairo_surface_destroy (&image->base);
  793.         image = _cairo_image_surface_clone_subimage (surface, extents);
  794.     }
  795.  
  796.     return &image->base;
  797. }
  798.  
  799. /**
  800.  * cairo_surface_unmap_image:
  801.  * @surface: the surface passed to cairo_surface_map_to_image().
  802.  * @image: the currently mapped image
  803.  *
  804.  * Unmaps the image surface as returned from #cairo_surface_map_to_image().
  805.  *
  806.  * The content of the image will be uploaded to the target surface.
  807.  * Afterwards, the image is destroyed.
  808.  *
  809.  * Using an image surface which wasn't returned by cairo_surface_map_to_image()
  810.  * results in undefined behavior.
  811.  *
  812.  * Since: 1.12
  813.  **/
  814. void
  815. cairo_surface_unmap_image (cairo_surface_t *surface,
  816.                            cairo_surface_t *image)
  817. {
  818.     cairo_int_status_t status = CAIRO_STATUS_SUCCESS;
  819.  
  820.     if (unlikely (surface->status)) {
  821.         status = surface->status;
  822.         goto error;
  823.     }
  824.     if (unlikely (surface->finished)) {
  825.         status = _cairo_error (CAIRO_STATUS_SURFACE_FINISHED);
  826.         goto error;
  827.     }
  828.     if (unlikely (image->status)) {
  829.         status = image->status;
  830.         goto error;
  831.     }
  832.     if (unlikely (image->finished)) {
  833.         status = _cairo_error (CAIRO_STATUS_SURFACE_FINISHED);
  834.         goto error;
  835.     }
  836.     if (unlikely (! _cairo_surface_is_image (image))) {
  837.         status = _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
  838.         goto error;
  839.     }
  840.  
  841.     status = _cairo_surface_unmap_image (surface,
  842.                                          (cairo_image_surface_t *) image);
  843.     if (unlikely (status))
  844.         _cairo_surface_set_error (surface, status);
  845.  
  846.     return;
  847.  
  848. error:
  849.     _cairo_surface_set_error (surface, status);
  850.     cairo_surface_finish (image);
  851.     cairo_surface_destroy (image);
  852. }
  853.  
  854. cairo_surface_t *
  855. _cairo_surface_create_similar_solid (cairo_surface_t     *other,
  856.                                      cairo_content_t      content,
  857.                                      int                  width,
  858.                                      int                  height,
  859.                                      const cairo_color_t *color)
  860. {
  861.     cairo_status_t status;
  862.     cairo_surface_t *surface;
  863.     cairo_solid_pattern_t pattern;
  864.  
  865.     surface = _cairo_surface_create_similar_scratch (other, content,
  866.                                                      width, height);
  867.     if (unlikely (surface->status))
  868.         return surface;
  869.  
  870.     _cairo_pattern_init_solid (&pattern, color);
  871.     status = _cairo_surface_paint (surface,
  872.                                    color == CAIRO_COLOR_TRANSPARENT ?
  873.                                    CAIRO_OPERATOR_CLEAR : CAIRO_OPERATOR_SOURCE,
  874.                                    &pattern.base, NULL);
  875.     if (unlikely (status)) {
  876.         cairo_surface_destroy (surface);
  877.         surface = _cairo_surface_create_in_error (status);
  878.     }
  879.  
  880.     return surface;
  881. }
  882.  
  883. /**
  884.  * cairo_surface_reference:
  885.  * @surface: a #cairo_surface_t
  886.  *
  887.  * Increases the reference count on @surface by one. This prevents
  888.  * @surface from being destroyed until a matching call to
  889.  * cairo_surface_destroy() is made.
  890.  *
  891.  * The number of references to a #cairo_surface_t can be get using
  892.  * cairo_surface_get_reference_count().
  893.  *
  894.  * Return value: the referenced #cairo_surface_t.
  895.  *
  896.  * Since: 1.0
  897.  **/
  898. cairo_surface_t *
  899. cairo_surface_reference (cairo_surface_t *surface)
  900. {
  901.     if (surface == NULL ||
  902.             CAIRO_REFERENCE_COUNT_IS_INVALID (&surface->ref_count))
  903.         return surface;
  904.  
  905.     assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&surface->ref_count));
  906.  
  907.     _cairo_reference_count_inc (&surface->ref_count);
  908.  
  909.     return surface;
  910. }
  911. slim_hidden_def (cairo_surface_reference);
  912.  
  913. /**
  914.  * cairo_surface_destroy:
  915.  * @surface: a #cairo_surface_t
  916.  *
  917.  * Decreases the reference count on @surface by one. If the result is
  918.  * zero, then @surface and all associated resources are freed.  See
  919.  * cairo_surface_reference().
  920.  *
  921.  * Since: 1.0
  922.  **/
  923. void
  924. cairo_surface_destroy (cairo_surface_t *surface)
  925. {
  926.     if (surface == NULL ||
  927.             CAIRO_REFERENCE_COUNT_IS_INVALID (&surface->ref_count))
  928.         return;
  929.  
  930.     assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&surface->ref_count));
  931.  
  932.     if (! _cairo_reference_count_dec_and_test (&surface->ref_count))
  933.         return;
  934.  
  935.     assert (surface->snapshot_of == NULL);
  936.  
  937.     if (! surface->finished) {
  938.         _cairo_surface_finish_snapshots (surface);
  939.         /* We may have been referenced by a snapshot prior to have
  940.          * detaching it with the copy-on-write.
  941.          */
  942.         if (CAIRO_REFERENCE_COUNT_GET_VALUE (&surface->ref_count))
  943.             return;
  944.  
  945.         _cairo_surface_finish (surface);
  946.     }
  947.  
  948.     if (surface->damage)
  949.         _cairo_damage_destroy (surface->damage);
  950.  
  951.     _cairo_user_data_array_fini (&surface->user_data);
  952.     _cairo_user_data_array_fini (&surface->mime_data);
  953.  
  954.     if (surface->owns_device)
  955.         cairo_device_destroy (surface->device);
  956.  
  957.     assert (surface->snapshot_of == NULL);
  958.     assert (! _cairo_surface_has_snapshots (surface));
  959.     /* paranoid check that nobody took a reference whilst finishing */
  960.     assert (! CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&surface->ref_count));
  961.  
  962.     free (surface);
  963. }
  964. slim_hidden_def(cairo_surface_destroy);
  965.  
  966. /**
  967.  * cairo_surface_get_reference_count:
  968.  * @surface: a #cairo_surface_t
  969.  *
  970.  * Returns the current reference count of @surface.
  971.  *
  972.  * Return value: the current reference count of @surface.  If the
  973.  * object is a nil object, 0 will be returned.
  974.  *
  975.  * Since: 1.4
  976.  **/
  977. unsigned int
  978. cairo_surface_get_reference_count (cairo_surface_t *surface)
  979. {
  980.     if (surface == NULL ||
  981.             CAIRO_REFERENCE_COUNT_IS_INVALID (&surface->ref_count))
  982.         return 0;
  983.  
  984.     return CAIRO_REFERENCE_COUNT_GET_VALUE (&surface->ref_count);
  985. }
  986.  
  987. static void
  988. _cairo_surface_finish_snapshots (cairo_surface_t *surface)
  989. {
  990.     cairo_status_t status;
  991.  
  992.     /* update the snapshots *before* we declare the surface as finished */
  993.     surface->_finishing = TRUE;
  994.     status = _cairo_surface_flush (surface, 0);
  995.     (void) status;
  996. }
  997.  
  998. static void
  999. _cairo_surface_finish (cairo_surface_t *surface)
  1000. {
  1001.     cairo_status_t status;
  1002.  
  1003.     surface->finished = TRUE;
  1004.  
  1005.     /* call finish even if in error mode */
  1006.     if (surface->backend->finish) {
  1007.         status = surface->backend->finish (surface);
  1008.         if (unlikely (status))
  1009.             _cairo_surface_set_error (surface, status);
  1010.     }
  1011.  
  1012.     assert (surface->snapshot_of == NULL);
  1013.     assert (!_cairo_surface_has_snapshots (surface));
  1014. }
  1015.  
  1016. /**
  1017.  * cairo_surface_finish:
  1018.  * @surface: the #cairo_surface_t to finish
  1019.  *
  1020.  * This function finishes the surface and drops all references to
  1021.  * external resources.  For example, for the Xlib backend it means
  1022.  * that cairo will no longer access the drawable, which can be freed.
  1023.  * After calling cairo_surface_finish() the only valid operations on a
  1024.  * surface are getting and setting user, referencing and
  1025.  * destroying, and flushing and finishing it.
  1026.  * Further drawing to the surface will not affect the
  1027.  * surface but will instead trigger a %CAIRO_STATUS_SURFACE_FINISHED
  1028.  * error.
  1029.  *
  1030.  * When the last call to cairo_surface_destroy() decreases the
  1031.  * reference count to zero, cairo will call cairo_surface_finish() if
  1032.  * it hasn't been called already, before freeing the resources
  1033.  * associated with the surface.
  1034.  *
  1035.  * Since: 1.0
  1036.  **/
  1037. void
  1038. cairo_surface_finish (cairo_surface_t *surface)
  1039. {
  1040.     if (surface == NULL)
  1041.         return;
  1042.  
  1043.     if (CAIRO_REFERENCE_COUNT_IS_INVALID (&surface->ref_count))
  1044.         return;
  1045.  
  1046.     if (surface->finished)
  1047.         return;
  1048.  
  1049.     /* We have to be careful when decoupling potential reference cycles */
  1050.     cairo_surface_reference (surface);
  1051.  
  1052.     _cairo_surface_finish_snapshots (surface);
  1053.     /* XXX need to block and wait for snapshot references */
  1054.     _cairo_surface_finish (surface);
  1055.  
  1056.     cairo_surface_destroy (surface);
  1057. }
  1058. slim_hidden_def (cairo_surface_finish);
  1059.  
  1060. /**
  1061.  * _cairo_surface_release_device_reference:
  1062.  * @surface: a #cairo_surface_t
  1063.  *
  1064.  * This function makes @surface release the reference to its device. The
  1065.  * function is intended to be used for avoiding cycling references for
  1066.  * surfaces that are owned by their device, for example cache surfaces.
  1067.  * Note that the @surface will still assume that the device is available.
  1068.  * So it is the caller's responsibility to ensure the device stays around
  1069.  * until the @surface is destroyed. Just calling cairo_surface_finish() is
  1070.  * not enough.
  1071.  **/
  1072. void
  1073. _cairo_surface_release_device_reference (cairo_surface_t *surface)
  1074. {
  1075.     assert (surface->owns_device);
  1076.  
  1077.     cairo_device_destroy (surface->device);
  1078.     surface->owns_device = FALSE;
  1079. }
  1080.  
  1081. /**
  1082.  * cairo_surface_get_user_data:
  1083.  * @surface: a #cairo_surface_t
  1084.  * @key: the address of the #cairo_user_data_key_t the user data was
  1085.  * attached to
  1086.  *
  1087.  * Return user data previously attached to @surface using the specified
  1088.  * key.  If no user data has been attached with the given key this
  1089.  * function returns %NULL.
  1090.  *
  1091.  * Return value: the user data previously attached or %NULL.
  1092.  *
  1093.  * Since: 1.0
  1094.  **/
  1095. void *
  1096. cairo_surface_get_user_data (cairo_surface_t             *surface,
  1097.                              const cairo_user_data_key_t *key)
  1098. {
  1099.     /* Prevent reads of the array during teardown */
  1100.     if (! CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&surface->ref_count))
  1101.         return NULL;
  1102.  
  1103.     return _cairo_user_data_array_get_data (&surface->user_data, key);
  1104. }
  1105.  
  1106. /**
  1107.  * cairo_surface_set_user_data:
  1108.  * @surface: a #cairo_surface_t
  1109.  * @key: the address of a #cairo_user_data_key_t to attach the user data to
  1110.  * @user_data: the user data to attach to the surface
  1111.  * @destroy: a #cairo_destroy_func_t which will be called when the
  1112.  * surface is destroyed or when new user data is attached using the
  1113.  * same key.
  1114.  *
  1115.  * Attach user data to @surface.  To remove user data from a surface,
  1116.  * call this function with the key that was used to set it and %NULL
  1117.  * for @data.
  1118.  *
  1119.  * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY if a
  1120.  * slot could not be allocated for the user data.
  1121.  *
  1122.  * Since: 1.0
  1123.  **/
  1124. cairo_status_t
  1125. cairo_surface_set_user_data (cairo_surface_t             *surface,
  1126.                              const cairo_user_data_key_t *key,
  1127.                              void                        *user_data,
  1128.                              cairo_destroy_func_t        destroy)
  1129. {
  1130.     if (CAIRO_REFERENCE_COUNT_IS_INVALID (&surface->ref_count))
  1131.         return surface->status;
  1132.  
  1133.     if (! CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&surface->ref_count))
  1134.         return _cairo_error (CAIRO_STATUS_SURFACE_FINISHED);
  1135.  
  1136.     return _cairo_user_data_array_set_data (&surface->user_data,
  1137.                                             key, user_data, destroy);
  1138. }
  1139.  
  1140. /**
  1141.  * cairo_surface_get_mime_data:
  1142.  * @surface: a #cairo_surface_t
  1143.  * @mime_type: the mime type of the image data
  1144.  * @data: the image data to attached to the surface
  1145.  * @length: the length of the image data
  1146.  *
  1147.  * Return mime data previously attached to @surface using the
  1148.  * specified mime type.  If no data has been attached with the given
  1149.  * mime type, @data is set %NULL.
  1150.  *
  1151.  * Since: 1.10
  1152.  **/
  1153. void
  1154. cairo_surface_get_mime_data (cairo_surface_t            *surface,
  1155.                              const char                 *mime_type,
  1156.                              const unsigned char       **data,
  1157.                              unsigned long              *length)
  1158. {
  1159.     cairo_user_data_slot_t *slots;
  1160.     int i, num_slots;
  1161.  
  1162.     *data = NULL;
  1163.     *length = 0;
  1164.  
  1165.     /* Prevent reads of the array during teardown */
  1166.     if (! CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&surface->ref_count))
  1167.         return;
  1168.  
  1169.     /* The number of mime-types attached to a surface is usually small,
  1170.      * typically zero. Therefore it is quicker to do a strcmp() against
  1171.      * each key than it is to intern the string (i.e. compute a hash,
  1172.      * search the hash table, and do a final strcmp).
  1173.      */
  1174.     num_slots = surface->mime_data.num_elements;
  1175.     slots = _cairo_array_index (&surface->mime_data, 0);
  1176.     for (i = 0; i < num_slots; i++) {
  1177.         if (slots[i].key != NULL && strcmp ((char *) slots[i].key, mime_type) == 0) {
  1178.             cairo_mime_data_t *mime_data = slots[i].user_data;
  1179.  
  1180.             *data = mime_data->data;
  1181.             *length = mime_data->length;
  1182.             return;
  1183.         }
  1184.     }
  1185. }
  1186. slim_hidden_def (cairo_surface_get_mime_data);
  1187.  
  1188. static void
  1189. _cairo_mime_data_destroy (void *ptr)
  1190. {
  1191.     cairo_mime_data_t *mime_data = ptr;
  1192.  
  1193.     if (! _cairo_reference_count_dec_and_test (&mime_data->ref_count))
  1194.         return;
  1195.  
  1196.     if (mime_data->destroy && mime_data->closure)
  1197.         mime_data->destroy (mime_data->closure);
  1198.  
  1199.     free (mime_data);
  1200. }
  1201.  
  1202. /**
  1203.  * CAIRO_MIME_TYPE_JP2:
  1204.  *
  1205.  * The Joint Photographic Experts Group (JPEG) 2000 image coding standard (ISO/IEC 15444-1).
  1206.  *
  1207.  * Since: 1.10
  1208.  **/
  1209.  
  1210. /**
  1211.  * CAIRO_MIME_TYPE_JPEG:
  1212.  *
  1213.  * The Joint Photographic Experts Group (JPEG) image coding standard (ISO/IEC 10918-1).
  1214.  *
  1215.  * Since: 1.10
  1216.  **/
  1217.  
  1218. /**
  1219.  * CAIRO_MIME_TYPE_PNG:
  1220.  *
  1221.  * The Portable Network Graphics image file format (ISO/IEC 15948).
  1222.  *
  1223.  * Since: 1.10
  1224.  **/
  1225.  
  1226. /**
  1227.  * CAIRO_MIME_TYPE_URI:
  1228.  *
  1229.  * URI for an image file (unofficial MIME type).
  1230.  *
  1231.  * Since: 1.10
  1232.  **/
  1233.  
  1234. /**
  1235.  * CAIRO_MIME_TYPE_UNIQUE_ID:
  1236.  *
  1237.  * Unique identifier for a surface (cairo specific MIME type).
  1238.  *
  1239.  * Since: 1.12
  1240.  **/
  1241.  
  1242. /**
  1243.  * cairo_surface_set_mime_data:
  1244.  * @surface: a #cairo_surface_t
  1245.  * @mime_type: the MIME type of the image data
  1246.  * @data: the image data to attach to the surface
  1247.  * @length: the length of the image data
  1248.  * @destroy: a #cairo_destroy_func_t which will be called when the
  1249.  * surface is destroyed or when new image data is attached using the
  1250.  * same mime type.
  1251.  * @closure: the data to be passed to the @destroy notifier
  1252.  *
  1253.  * Attach an image in the format @mime_type to @surface. To remove
  1254.  * the data from a surface, call this function with same mime type
  1255.  * and %NULL for @data.
  1256.  *
  1257.  * The attached image (or filename) data can later be used by backends
  1258.  * which support it (currently: PDF, PS, SVG and Win32 Printing
  1259.  * surfaces) to emit this data instead of making a snapshot of the
  1260.  * @surface.  This approach tends to be faster and requires less
  1261.  * memory and disk space.
  1262.  *
  1263.  * The recognized MIME types are the following: %CAIRO_MIME_TYPE_JPEG,
  1264.  * %CAIRO_MIME_TYPE_PNG, %CAIRO_MIME_TYPE_JP2, %CAIRO_MIME_TYPE_URI,
  1265.  * %CAIRO_MIME_TYPE_UNIQUE_ID.
  1266.  *
  1267.  * See corresponding backend surface docs for details about which MIME
  1268.  * types it can handle. Caution: the associated MIME data will be
  1269.  * discarded if you draw on the surface afterwards. Use this function
  1270.  * with care.
  1271.  *
  1272.  * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY if a
  1273.  * slot could not be allocated for the user data.
  1274.  *
  1275.  * Since: 1.10
  1276.  **/
  1277. cairo_status_t
  1278. cairo_surface_set_mime_data (cairo_surface_t            *surface,
  1279.                              const char                 *mime_type,
  1280.                              const unsigned char        *data,
  1281.                              unsigned long               length,
  1282.                              cairo_destroy_func_t        destroy,
  1283.                              void                       *closure)
  1284. {
  1285.     cairo_status_t status;
  1286.     cairo_mime_data_t *mime_data;
  1287.  
  1288.     if (CAIRO_REFERENCE_COUNT_IS_INVALID (&surface->ref_count))
  1289.         return surface->status;
  1290.  
  1291.     if (! CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&surface->ref_count))
  1292.         return _cairo_error (CAIRO_STATUS_SURFACE_FINISHED);
  1293.  
  1294.     if (unlikely (surface->status))
  1295.         return surface->status;
  1296.     if (unlikely (surface->finished))
  1297.         return _cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
  1298.  
  1299.     status = _cairo_intern_string (&mime_type, -1);
  1300.     if (unlikely (status))
  1301.         return _cairo_surface_set_error (surface, status);
  1302.  
  1303.     if (data != NULL) {
  1304.         mime_data = malloc (sizeof (cairo_mime_data_t));
  1305.         if (unlikely (mime_data == NULL))
  1306.             return _cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_NO_MEMORY));
  1307.  
  1308.         CAIRO_REFERENCE_COUNT_INIT (&mime_data->ref_count, 1);
  1309.  
  1310.         mime_data->data = (unsigned char *) data;
  1311.         mime_data->length = length;
  1312.         mime_data->destroy = destroy;
  1313.         mime_data->closure = closure;
  1314.     } else
  1315.         mime_data = NULL;
  1316.  
  1317.     status = _cairo_user_data_array_set_data (&surface->mime_data,
  1318.                                               (cairo_user_data_key_t *) mime_type,
  1319.                                               mime_data,
  1320.                                               _cairo_mime_data_destroy);
  1321.     if (unlikely (status)) {
  1322.         free (mime_data);
  1323.  
  1324.         return _cairo_surface_set_error (surface, status);
  1325.     }
  1326.  
  1327.     return CAIRO_STATUS_SUCCESS;
  1328. }
  1329. slim_hidden_def (cairo_surface_set_mime_data);
  1330.  
  1331. /**
  1332.  * cairo_surface_supports_mime_type:
  1333.  * @surface: a #cairo_surface_t
  1334.  * @mime_type: the mime type
  1335.  *
  1336.  * Return whether @surface supports @mime_type.
  1337.  *
  1338.  * Return value: %TRUE if @surface supports
  1339.  *               @mime_type, %FALSE otherwise
  1340.  *
  1341.  * Since: 1.12
  1342.  **/
  1343. cairo_bool_t
  1344. cairo_surface_supports_mime_type (cairo_surface_t               *surface,
  1345.                                   const char                    *mime_type)
  1346. {
  1347.     const char **types;
  1348.  
  1349.     if (unlikely (surface->status))
  1350.         return FALSE;
  1351.     if (unlikely (surface->finished)) {
  1352.         _cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
  1353.         return FALSE;
  1354.     }
  1355.  
  1356.     if (surface->backend->get_supported_mime_types) {
  1357.         types = surface->backend->get_supported_mime_types (surface);
  1358.         if (types) {
  1359.             while (*types) {
  1360.                 if (strcmp (*types, mime_type) == 0)
  1361.                     return TRUE;
  1362.                 types++;
  1363.             }
  1364.         }
  1365.     }
  1366.  
  1367.     return FALSE;
  1368. }
  1369. slim_hidden_def (cairo_surface_supports_mime_type);
  1370.  
  1371. static void
  1372. _cairo_mime_data_reference (const void *key, void *elt, void *closure)
  1373. {
  1374.     cairo_mime_data_t *mime_data = elt;
  1375.  
  1376.     _cairo_reference_count_inc (&mime_data->ref_count);
  1377. }
  1378.  
  1379. cairo_status_t
  1380. _cairo_surface_copy_mime_data (cairo_surface_t *dst,
  1381.                                cairo_surface_t *src)
  1382. {
  1383.     cairo_status_t status;
  1384.  
  1385.     if (dst->status)
  1386.         return dst->status;
  1387.  
  1388.     if (src->status)
  1389.         return _cairo_surface_set_error (dst, src->status);
  1390.  
  1391.     /* first copy the mime-data, discarding any already set on dst */
  1392.     status = _cairo_user_data_array_copy (&dst->mime_data, &src->mime_data);
  1393.     if (unlikely (status))
  1394.         return _cairo_surface_set_error (dst, status);
  1395.  
  1396.     /* now increment the reference counters for the copies */
  1397.     _cairo_user_data_array_foreach (&dst->mime_data,
  1398.                                     _cairo_mime_data_reference,
  1399.                                     NULL);
  1400.  
  1401.     return CAIRO_STATUS_SUCCESS;
  1402. }
  1403.  
  1404. /**
  1405.  * _cairo_surface_set_font_options:
  1406.  * @surface: a #cairo_surface_t
  1407.  * @options: a #cairo_font_options_t object that contains the
  1408.  *   options to use for this surface instead of backend's default
  1409.  *   font options.
  1410.  *
  1411.  * Sets the default font rendering options for the surface.
  1412.  * This is useful to correctly propagate default font options when
  1413.  * falling back to an image surface in a backend implementation.
  1414.  * This affects the options returned in cairo_surface_get_font_options().
  1415.  *
  1416.  * If @options is %NULL the surface options are reset to those of
  1417.  * the backend default.
  1418.  **/
  1419. void
  1420. _cairo_surface_set_font_options (cairo_surface_t       *surface,
  1421.                                  cairo_font_options_t  *options)
  1422. {
  1423.     if (surface->status)
  1424.         return;
  1425.  
  1426.     assert (surface->snapshot_of == NULL);
  1427.  
  1428.     if (surface->finished) {
  1429.         _cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
  1430.         return;
  1431.     }
  1432.  
  1433.     if (options) {
  1434.         surface->has_font_options = TRUE;
  1435.         _cairo_font_options_init_copy (&surface->font_options, options);
  1436.     } else {
  1437.         surface->has_font_options = FALSE;
  1438.     }
  1439. }
  1440.  
  1441. /**
  1442.  * cairo_surface_get_font_options:
  1443.  * @surface: a #cairo_surface_t
  1444.  * @options: a #cairo_font_options_t object into which to store
  1445.  *   the retrieved options. All existing values are overwritten
  1446.  *
  1447.  * Retrieves the default font rendering options for the surface.
  1448.  * This allows display surfaces to report the correct subpixel order
  1449.  * for rendering on them, print surfaces to disable hinting of
  1450.  * metrics and so forth. The result can then be used with
  1451.  * cairo_scaled_font_create().
  1452.  *
  1453.  * Since: 1.0
  1454.  **/
  1455. void
  1456. cairo_surface_get_font_options (cairo_surface_t       *surface,
  1457.                                 cairo_font_options_t  *options)
  1458. {
  1459.     if (cairo_font_options_status (options))
  1460.         return;
  1461.  
  1462.     if (surface->status) {
  1463.         _cairo_font_options_init_default (options);
  1464.         return;
  1465.     }
  1466.  
  1467.     if (! surface->has_font_options) {
  1468.         surface->has_font_options = TRUE;
  1469.  
  1470.         _cairo_font_options_init_default (&surface->font_options);
  1471.  
  1472.         if (!surface->finished && surface->backend->get_font_options) {
  1473.             surface->backend->get_font_options (surface, &surface->font_options);
  1474.         }
  1475.     }
  1476.  
  1477.     _cairo_font_options_init_copy (options, &surface->font_options);
  1478. }
  1479. slim_hidden_def (cairo_surface_get_font_options);
  1480.  
  1481. cairo_status_t
  1482. _cairo_surface_flush (cairo_surface_t *surface, unsigned flags)
  1483. {
  1484.     /* update the current snapshots *before* the user updates the surface */
  1485.     _cairo_surface_detach_snapshots (surface);
  1486.     if (surface->snapshot_of != NULL)
  1487.         _cairo_surface_detach_snapshot (surface);
  1488.     _cairo_surface_detach_mime_data (surface);
  1489.  
  1490.     return __cairo_surface_flush (surface, flags);
  1491. }
  1492.  
  1493. /**
  1494.  * cairo_surface_flush:
  1495.  * @surface: a #cairo_surface_t
  1496.  *
  1497.  * Do any pending drawing for the surface and also restore any
  1498.  * temporary modifications cairo has made to the surface's
  1499.  * state. This function must be called before switching from
  1500.  * drawing on the surface with cairo to drawing on it directly
  1501.  * with native APIs. If the surface doesn't support direct access,
  1502.  * then this function does nothing.
  1503.  *
  1504.  * Since: 1.0
  1505.  **/
  1506. void
  1507. cairo_surface_flush (cairo_surface_t *surface)
  1508. {
  1509.     cairo_status_t status;
  1510.  
  1511.     if (surface->status)
  1512.         return;
  1513.  
  1514.     if (surface->finished)
  1515.         return;
  1516.  
  1517.     status = _cairo_surface_flush (surface, 0);
  1518.     if (unlikely (status))
  1519.         _cairo_surface_set_error (surface, status);
  1520. }
  1521. slim_hidden_def (cairo_surface_flush);
  1522.  
  1523. /**
  1524.  * cairo_surface_mark_dirty:
  1525.  * @surface: a #cairo_surface_t
  1526.  *
  1527.  * Tells cairo that drawing has been done to surface using means other
  1528.  * than cairo, and that cairo should reread any cached areas. Note
  1529.  * that you must call cairo_surface_flush() before doing such drawing.
  1530.  *
  1531.  * Since: 1.0
  1532.  **/
  1533. void
  1534. cairo_surface_mark_dirty (cairo_surface_t *surface)
  1535. {
  1536.     cairo_rectangle_int_t extents;
  1537.  
  1538.     if (unlikely (surface->status))
  1539.         return;
  1540.     if (unlikely (surface->finished)) {
  1541.         _cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
  1542.         return;
  1543.     }
  1544.  
  1545.     _cairo_surface_get_extents (surface, &extents);
  1546.     cairo_surface_mark_dirty_rectangle (surface,
  1547.                                         extents.x, extents.y,
  1548.                                         extents.width, extents.height);
  1549. }
  1550. slim_hidden_def (cairo_surface_mark_dirty);
  1551.  
  1552. /**
  1553.  * cairo_surface_mark_dirty_rectangle:
  1554.  * @surface: a #cairo_surface_t
  1555.  * @x: X coordinate of dirty rectangle
  1556.  * @y: Y coordinate of dirty rectangle
  1557.  * @width: width of dirty rectangle
  1558.  * @height: height of dirty rectangle
  1559.  *
  1560.  * Like cairo_surface_mark_dirty(), but drawing has been done only to
  1561.  * the specified rectangle, so that cairo can retain cached contents
  1562.  * for other parts of the surface.
  1563.  *
  1564.  * Any cached clip set on the surface will be reset by this function,
  1565.  * to make sure that future cairo calls have the clip set that they
  1566.  * expect.
  1567.  *
  1568.  * Since: 1.0
  1569.  **/
  1570. void
  1571. cairo_surface_mark_dirty_rectangle (cairo_surface_t *surface,
  1572.                                     int              x,
  1573.                                     int              y,
  1574.                                     int              width,
  1575.                                     int              height)
  1576. {
  1577.     cairo_status_t status;
  1578.  
  1579.     if (unlikely (surface->status))
  1580.         return;
  1581.  
  1582.     assert (surface->snapshot_of == NULL);
  1583.  
  1584.     if (unlikely (surface->finished)) {
  1585.         _cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
  1586.         return;
  1587.     }
  1588.  
  1589.     /* The application *should* have called cairo_surface_flush() before
  1590.      * modifying the surface independently of cairo (and thus having to
  1591.      * call mark_dirty()). */
  1592.     assert (! _cairo_surface_has_snapshots (surface));
  1593.     assert (! _cairo_surface_has_mime_data (surface));
  1594.  
  1595.     surface->is_clear = FALSE;
  1596.     surface->serial++;
  1597.  
  1598.     if (surface->damage) {
  1599.         cairo_box_t box;
  1600.  
  1601.         box.p1.x = x;
  1602.         box.p1.y = y;
  1603.         box.p2.x = x + width;
  1604.         box.p2.y = y + height;
  1605.  
  1606.         surface->damage = _cairo_damage_add_box (surface->damage, &box);
  1607.     }
  1608.  
  1609.     if (surface->backend->mark_dirty_rectangle != NULL) {
  1610.         /* XXX: FRAGILE: We're ignoring the scaling component of
  1611.          * device_transform here. I don't know what the right thing to
  1612.          * do would actually be if there were some scaling here, but
  1613.          * we avoid this since device_transfom scaling is not exported
  1614.          * publicly and mark_dirty is not used internally. */
  1615.         status = surface->backend->mark_dirty_rectangle (surface,
  1616.                                                          x + surface->device_transform.x0,
  1617.                                                          y + surface->device_transform.y0,
  1618.                                                          width, height);
  1619.  
  1620.         if (unlikely (status))
  1621.             _cairo_surface_set_error (surface, status);
  1622.     }
  1623. }
  1624. slim_hidden_def (cairo_surface_mark_dirty_rectangle);
  1625.  
  1626. /**
  1627.  * _cairo_surface_set_device_scale:
  1628.  * @surface: a #cairo_surface_t
  1629.  * @sx: a scale factor in the X direction
  1630.  * @sy: a scale factor in the Y direction
  1631.  *
  1632.  * Private function for setting an extra scale factor to affect all
  1633.  * drawing to a surface. This is used, for example, when replaying a
  1634.  * recording surface to an image fallback intended for an eventual
  1635.  * vector-oriented backend. Since the recording surface will record
  1636.  * coordinates in one backend space, but the image fallback uses a
  1637.  * different backend space, (differing by the fallback resolution
  1638.  * scale factors), we need a scale factor correction.
  1639.  *
  1640.  * Caution: Not all places we use device transform correctly handle
  1641.  * both a translate and a scale.  An audit would be nice.
  1642.  **/
  1643. void
  1644. _cairo_surface_set_device_scale (cairo_surface_t *surface,
  1645.                                  double           sx,
  1646.                                  double           sy)
  1647. {
  1648.     cairo_status_t status;
  1649.  
  1650.     if (unlikely (surface->status))
  1651.         return;
  1652.  
  1653.     assert (surface->snapshot_of == NULL);
  1654.  
  1655.     if (unlikely (surface->finished)) {
  1656.         _cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
  1657.         return;
  1658.     }
  1659.  
  1660.     status = _cairo_surface_begin_modification (surface);
  1661.     if (unlikely (status)) {
  1662.         _cairo_surface_set_error (surface, status);
  1663.         return;
  1664.     }
  1665.  
  1666.     surface->device_transform.xx = sx;
  1667.     surface->device_transform.yy = sy;
  1668.     surface->device_transform.xy = 0.0;
  1669.     surface->device_transform.yx = 0.0;
  1670.  
  1671.     surface->device_transform_inverse = surface->device_transform;
  1672.     status = cairo_matrix_invert (&surface->device_transform_inverse);
  1673.     /* should always be invertible unless given pathological input */
  1674.     assert (status == CAIRO_STATUS_SUCCESS);
  1675.  
  1676.     _cairo_observers_notify (&surface->device_transform_observers, surface);
  1677. }
  1678.  
  1679. /**
  1680.  * cairo_surface_set_device_offset:
  1681.  * @surface: a #cairo_surface_t
  1682.  * @x_offset: the offset in the X direction, in device units
  1683.  * @y_offset: the offset in the Y direction, in device units
  1684.  *
  1685.  * Sets an offset that is added to the device coordinates determined
  1686.  * by the CTM when drawing to @surface. One use case for this function
  1687.  * is when we want to create a #cairo_surface_t that redirects drawing
  1688.  * for a portion of an onscreen surface to an offscreen surface in a
  1689.  * way that is completely invisible to the user of the cairo
  1690.  * API. Setting a transformation via cairo_translate() isn't
  1691.  * sufficient to do this, since functions like
  1692.  * cairo_device_to_user() will expose the hidden offset.
  1693.  *
  1694.  * Note that the offset affects drawing to the surface as well as
  1695.  * using the surface in a source pattern.
  1696.  *
  1697.  * Since: 1.0
  1698.  **/
  1699. void
  1700. cairo_surface_set_device_offset (cairo_surface_t *surface,
  1701.                                  double           x_offset,
  1702.                                  double           y_offset)
  1703. {
  1704.     cairo_status_t status;
  1705.  
  1706.     if (unlikely (surface->status))
  1707.         return;
  1708.  
  1709.     assert (surface->snapshot_of == NULL);
  1710.  
  1711.     if (unlikely (surface->finished)) {
  1712.         _cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
  1713.         return;
  1714.     }
  1715.  
  1716.     status = _cairo_surface_begin_modification (surface);
  1717.     if (unlikely (status)) {
  1718.         _cairo_surface_set_error (surface, status);
  1719.         return;
  1720.     }
  1721.  
  1722.     surface->device_transform.x0 = x_offset;
  1723.     surface->device_transform.y0 = y_offset;
  1724.  
  1725.     surface->device_transform_inverse = surface->device_transform;
  1726.     status = cairo_matrix_invert (&surface->device_transform_inverse);
  1727.     /* should always be invertible unless given pathological input */
  1728.     assert (status == CAIRO_STATUS_SUCCESS);
  1729.  
  1730.     _cairo_observers_notify (&surface->device_transform_observers, surface);
  1731. }
  1732. slim_hidden_def (cairo_surface_set_device_offset);
  1733.  
  1734. /**
  1735.  * cairo_surface_get_device_offset:
  1736.  * @surface: a #cairo_surface_t
  1737.  * @x_offset: the offset in the X direction, in device units
  1738.  * @y_offset: the offset in the Y direction, in device units
  1739.  *
  1740.  * This function returns the previous device offset set by
  1741.  * cairo_surface_set_device_offset().
  1742.  *
  1743.  * Since: 1.2
  1744.  **/
  1745. void
  1746. cairo_surface_get_device_offset (cairo_surface_t *surface,
  1747.                                  double          *x_offset,
  1748.                                  double          *y_offset)
  1749. {
  1750.     if (x_offset)
  1751.         *x_offset = surface->device_transform.x0;
  1752.     if (y_offset)
  1753.         *y_offset = surface->device_transform.y0;
  1754. }
  1755. slim_hidden_def (cairo_surface_get_device_offset);
  1756.  
  1757. /**
  1758.  * cairo_surface_set_fallback_resolution:
  1759.  * @surface: a #cairo_surface_t
  1760.  * @x_pixels_per_inch: horizontal setting for pixels per inch
  1761.  * @y_pixels_per_inch: vertical setting for pixels per inch
  1762.  *
  1763.  * Set the horizontal and vertical resolution for image fallbacks.
  1764.  *
  1765.  * When certain operations aren't supported natively by a backend,
  1766.  * cairo will fallback by rendering operations to an image and then
  1767.  * overlaying that image onto the output. For backends that are
  1768.  * natively vector-oriented, this function can be used to set the
  1769.  * resolution used for these image fallbacks, (larger values will
  1770.  * result in more detailed images, but also larger file sizes).
  1771.  *
  1772.  * Some examples of natively vector-oriented backends are the ps, pdf,
  1773.  * and svg backends.
  1774.  *
  1775.  * For backends that are natively raster-oriented, image fallbacks are
  1776.  * still possible, but they are always performed at the native
  1777.  * device resolution. So this function has no effect on those
  1778.  * backends.
  1779.  *
  1780.  * Note: The fallback resolution only takes effect at the time of
  1781.  * completing a page (with cairo_show_page() or cairo_copy_page()) so
  1782.  * there is currently no way to have more than one fallback resolution
  1783.  * in effect on a single page.
  1784.  *
  1785.  * The default fallback resoultion is 300 pixels per inch in both
  1786.  * dimensions.
  1787.  *
  1788.  * Since: 1.2
  1789.  **/
  1790. void
  1791. cairo_surface_set_fallback_resolution (cairo_surface_t  *surface,
  1792.                                        double            x_pixels_per_inch,
  1793.                                        double            y_pixels_per_inch)
  1794. {
  1795.     cairo_status_t status;
  1796.  
  1797.     if (unlikely (surface->status))
  1798.         return;
  1799.  
  1800.     assert (surface->snapshot_of == NULL);
  1801.  
  1802.     if (unlikely (surface->finished)) {
  1803.         _cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
  1804.         return;
  1805.     }
  1806.  
  1807.     if (x_pixels_per_inch <= 0 || y_pixels_per_inch <= 0) {
  1808.         /* XXX Could delay raising the error until we fallback, but throwing
  1809.          * the error here means that we can catch the real culprit.
  1810.          */
  1811.         _cairo_surface_set_error (surface, CAIRO_STATUS_INVALID_MATRIX);
  1812.         return;
  1813.     }
  1814.  
  1815.     status = _cairo_surface_begin_modification (surface);
  1816.     if (unlikely (status)) {
  1817.         _cairo_surface_set_error (surface, status);
  1818.         return;
  1819.     }
  1820.  
  1821.     surface->x_fallback_resolution = x_pixels_per_inch;
  1822.     surface->y_fallback_resolution = y_pixels_per_inch;
  1823. }
  1824. slim_hidden_def (cairo_surface_set_fallback_resolution);
  1825.  
  1826. /**
  1827.  * cairo_surface_get_fallback_resolution:
  1828.  * @surface: a #cairo_surface_t
  1829.  * @x_pixels_per_inch: horizontal pixels per inch
  1830.  * @y_pixels_per_inch: vertical pixels per inch
  1831.  *
  1832.  * This function returns the previous fallback resolution set by
  1833.  * cairo_surface_set_fallback_resolution(), or default fallback
  1834.  * resolution if never set.
  1835.  *
  1836.  * Since: 1.8
  1837.  **/
  1838. void
  1839. cairo_surface_get_fallback_resolution (cairo_surface_t  *surface,
  1840.                                        double           *x_pixels_per_inch,
  1841.                                        double           *y_pixels_per_inch)
  1842. {
  1843.     if (x_pixels_per_inch)
  1844.         *x_pixels_per_inch = surface->x_fallback_resolution;
  1845.     if (y_pixels_per_inch)
  1846.         *y_pixels_per_inch = surface->y_fallback_resolution;
  1847. }
  1848.  
  1849. cairo_bool_t
  1850. _cairo_surface_has_device_transform (cairo_surface_t *surface)
  1851. {
  1852.     return ! _cairo_matrix_is_identity (&surface->device_transform);
  1853. }
  1854.  
  1855. /**
  1856.  * _cairo_surface_acquire_source_image:
  1857.  * @surface: a #cairo_surface_t
  1858.  * @image_out: location to store a pointer to an image surface that
  1859.  *    has identical contents to @surface. This surface could be @surface
  1860.  *    itself, a surface held internal to @surface, or it could be a new
  1861.  *    surface with a copy of the relevant portion of @surface.
  1862.  * @image_extra: location to store image specific backend data
  1863.  *
  1864.  * Gets an image surface to use when drawing as a fallback when drawing with
  1865.  * @surface as a source. _cairo_surface_release_source_image() must be called
  1866.  * when finished.
  1867.  *
  1868.  * Return value: %CAIRO_STATUS_SUCCESS if an image was stored in @image_out.
  1869.  * %CAIRO_INT_STATUS_UNSUPPORTED if an image cannot be retrieved for the specified
  1870.  * surface. Or %CAIRO_STATUS_NO_MEMORY.
  1871.  **/
  1872. cairo_status_t
  1873. _cairo_surface_acquire_source_image (cairo_surface_t         *surface,
  1874.                                      cairo_image_surface_t  **image_out,
  1875.                                      void                   **image_extra)
  1876. {
  1877.     cairo_status_t status;
  1878.  
  1879.     if (unlikely (surface->status))
  1880.         return surface->status;
  1881.  
  1882.     assert (!surface->finished);
  1883.  
  1884.     if (surface->backend->acquire_source_image == NULL)
  1885.         return CAIRO_INT_STATUS_UNSUPPORTED;
  1886.  
  1887.     status = surface->backend->acquire_source_image (surface,
  1888.                                                      image_out, image_extra);
  1889.     if (unlikely (status))
  1890.         return _cairo_surface_set_error (surface, status);
  1891.  
  1892.     _cairo_debug_check_image_surface_is_defined (&(*image_out)->base);
  1893.  
  1894.     return CAIRO_STATUS_SUCCESS;
  1895. }
  1896.  
  1897. cairo_status_t
  1898. _cairo_surface_default_acquire_source_image (void                    *_surface,
  1899.                                              cairo_image_surface_t  **image_out,
  1900.                                              void                   **image_extra)
  1901. {
  1902.     cairo_surface_t *surface = _surface;
  1903.     cairo_rectangle_int_t extents;
  1904.  
  1905.     if (unlikely (! surface->backend->get_extents (surface, &extents)))
  1906.         return _cairo_error (CAIRO_STATUS_INVALID_SIZE);
  1907.  
  1908.     *image_out = _cairo_surface_map_to_image (surface, &extents);
  1909.     *image_extra = NULL;
  1910.     return (*image_out)->base.status;
  1911. }
  1912.  
  1913. /**
  1914.  * _cairo_surface_release_source_image:
  1915.  * @surface: a #cairo_surface_t
  1916.  * @image_extra: same as return from the matching _cairo_surface_acquire_source_image()
  1917.  *
  1918.  * Releases any resources obtained with _cairo_surface_acquire_source_image()
  1919.  **/
  1920. void
  1921. _cairo_surface_release_source_image (cairo_surface_t        *surface,
  1922.                                      cairo_image_surface_t  *image,
  1923.                                      void                   *image_extra)
  1924. {
  1925.     assert (!surface->finished);
  1926.  
  1927.     if (surface->backend->release_source_image)
  1928.         surface->backend->release_source_image (surface, image, image_extra);
  1929. }
  1930.  
  1931. void
  1932. _cairo_surface_default_release_source_image (void                   *surface,
  1933.                                              cairo_image_surface_t  *image,
  1934.                                              void                   *image_extra)
  1935. {
  1936.     cairo_status_t ignored;
  1937.  
  1938.     ignored = _cairo_surface_unmap_image (surface, image);
  1939.     (void)ignored;
  1940. }
  1941.  
  1942.  
  1943. cairo_surface_t *
  1944. _cairo_surface_get_source (cairo_surface_t *surface,
  1945.                            cairo_rectangle_int_t *extents)
  1946. {
  1947.     assert (surface->backend->source);
  1948.     return surface->backend->source (surface, extents);
  1949. }
  1950.  
  1951. cairo_surface_t *
  1952. _cairo_surface_default_source (void *surface,
  1953.                                cairo_rectangle_int_t *extents)
  1954. {
  1955.     if (extents)
  1956.         _cairo_surface_get_extents(surface, extents);
  1957.     return surface;
  1958. }
  1959.  
  1960. static cairo_status_t
  1961. _pattern_has_error (const cairo_pattern_t *pattern)
  1962. {
  1963.     const cairo_surface_pattern_t *spattern;
  1964.  
  1965.     if (unlikely (pattern->status))
  1966.         return pattern->status;
  1967.  
  1968.     if (pattern->type != CAIRO_PATTERN_TYPE_SURFACE)
  1969.         return CAIRO_STATUS_SUCCESS;
  1970.  
  1971.     spattern = (const cairo_surface_pattern_t *) pattern;
  1972.     if (unlikely (spattern->surface->status))
  1973.         return spattern->surface->status;
  1974.  
  1975.     if (unlikely (spattern->surface->finished))
  1976.         return _cairo_error (CAIRO_STATUS_SURFACE_FINISHED);
  1977.  
  1978.     return CAIRO_STATUS_SUCCESS;
  1979. }
  1980.  
  1981. static cairo_bool_t
  1982. nothing_to_do (cairo_surface_t *surface,
  1983.                cairo_operator_t op,
  1984.                const cairo_pattern_t *source)
  1985. {
  1986.     if (_cairo_pattern_is_clear (source)) {
  1987.         if (op == CAIRO_OPERATOR_OVER || op == CAIRO_OPERATOR_ADD)
  1988.             return TRUE;
  1989.  
  1990.         if (op == CAIRO_OPERATOR_SOURCE)
  1991.             op = CAIRO_OPERATOR_CLEAR;
  1992.     }
  1993.  
  1994.     if (op == CAIRO_OPERATOR_CLEAR && surface->is_clear)
  1995.         return TRUE;
  1996.  
  1997.     if (op == CAIRO_OPERATOR_ATOP && (surface->content & CAIRO_CONTENT_COLOR) ==0)
  1998.         return TRUE;
  1999.  
  2000.     return FALSE;
  2001. }
  2002.  
  2003. cairo_status_t
  2004. _cairo_surface_paint (cairo_surface_t           *surface,
  2005.                       cairo_operator_t           op,
  2006.                       const cairo_pattern_t     *source,
  2007.                       const cairo_clip_t        *clip)
  2008. {
  2009.     cairo_int_status_t status;
  2010.  
  2011.     TRACE ((stderr, "%s\n", __FUNCTION__));
  2012.     if (unlikely (surface->status))
  2013.         return surface->status;
  2014.     if (unlikely (surface->finished))
  2015.         return _cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
  2016.  
  2017.     if (_cairo_clip_is_all_clipped (clip))
  2018.         return CAIRO_STATUS_SUCCESS;
  2019.  
  2020.     status = _pattern_has_error (source);
  2021.     if (unlikely (status))
  2022.         return status;
  2023.  
  2024.     if (nothing_to_do (surface, op, source))
  2025.         return CAIRO_STATUS_SUCCESS;
  2026.  
  2027.     status = _cairo_surface_begin_modification (surface);
  2028.     if (unlikely (status))
  2029.         return status;
  2030.  
  2031.     status = surface->backend->paint (surface, op, source, clip);
  2032.     if (status != CAIRO_INT_STATUS_NOTHING_TO_DO) {
  2033.         surface->is_clear = op == CAIRO_OPERATOR_CLEAR && clip == NULL;
  2034.         surface->serial++;
  2035.     }
  2036.  
  2037.     return _cairo_surface_set_error (surface, status);
  2038. }
  2039.  
  2040. cairo_status_t
  2041. _cairo_surface_mask (cairo_surface_t            *surface,
  2042.                      cairo_operator_t            op,
  2043.                      const cairo_pattern_t      *source,
  2044.                      const cairo_pattern_t      *mask,
  2045.                      const cairo_clip_t         *clip)
  2046. {
  2047.     cairo_int_status_t status;
  2048.  
  2049.     TRACE ((stderr, "%s\n", __FUNCTION__));
  2050.     if (unlikely (surface->status))
  2051.         return surface->status;
  2052.     if (unlikely (surface->finished))
  2053.         return _cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
  2054.  
  2055.     if (_cairo_clip_is_all_clipped (clip))
  2056.         return CAIRO_STATUS_SUCCESS;
  2057.  
  2058.     /* If the mask is blank, this is just an expensive no-op */
  2059.     if (_cairo_pattern_is_clear (mask) &&
  2060.         _cairo_operator_bounded_by_mask (op))
  2061.     {
  2062.         return CAIRO_STATUS_SUCCESS;
  2063.     }
  2064.  
  2065.     status = _pattern_has_error (source);
  2066.     if (unlikely (status))
  2067.         return status;
  2068.  
  2069.     status = _pattern_has_error (mask);
  2070.     if (unlikely (status))
  2071.         return status;
  2072.  
  2073.     if (nothing_to_do (surface, op, source))
  2074.         return CAIRO_STATUS_SUCCESS;
  2075.  
  2076.     status = _cairo_surface_begin_modification (surface);
  2077.     if (unlikely (status))
  2078.         return status;
  2079.  
  2080.     status = surface->backend->mask (surface, op, source, mask, clip);
  2081.     if (status != CAIRO_INT_STATUS_NOTHING_TO_DO) {
  2082.         surface->is_clear = FALSE;
  2083.         surface->serial++;
  2084.     }
  2085.  
  2086.     return _cairo_surface_set_error (surface, status);
  2087. }
  2088.  
  2089. cairo_status_t
  2090. _cairo_surface_fill_stroke (cairo_surface_t         *surface,
  2091.                             cairo_operator_t         fill_op,
  2092.                             const cairo_pattern_t   *fill_source,
  2093.                             cairo_fill_rule_t        fill_rule,
  2094.                             double                   fill_tolerance,
  2095.                             cairo_antialias_t        fill_antialias,
  2096.                             cairo_path_fixed_t      *path,
  2097.                             cairo_operator_t         stroke_op,
  2098.                             const cairo_pattern_t   *stroke_source,
  2099.                             const cairo_stroke_style_t    *stroke_style,
  2100.                             const cairo_matrix_t            *stroke_ctm,
  2101.                             const cairo_matrix_t            *stroke_ctm_inverse,
  2102.                             double                   stroke_tolerance,
  2103.                             cairo_antialias_t        stroke_antialias,
  2104.                             const cairo_clip_t      *clip)
  2105. {
  2106.     cairo_int_status_t status;
  2107.  
  2108.     TRACE ((stderr, "%s\n", __FUNCTION__));
  2109.     if (unlikely (surface->status))
  2110.         return surface->status;
  2111.     if (unlikely (surface->finished))
  2112.         return _cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
  2113.  
  2114.     if (_cairo_clip_is_all_clipped (clip))
  2115.         return CAIRO_STATUS_SUCCESS;
  2116.  
  2117.     if (surface->is_clear &&
  2118.         fill_op == CAIRO_OPERATOR_CLEAR &&
  2119.         stroke_op == CAIRO_OPERATOR_CLEAR)
  2120.     {
  2121.         return CAIRO_STATUS_SUCCESS;
  2122.     }
  2123.  
  2124.     status = _pattern_has_error (fill_source);
  2125.     if (unlikely (status))
  2126.         return status;
  2127.  
  2128.     status = _pattern_has_error (stroke_source);
  2129.     if (unlikely (status))
  2130.         return status;
  2131.  
  2132.     status = _cairo_surface_begin_modification (surface);
  2133.     if (unlikely (status))
  2134.         return status;
  2135.  
  2136.     if (surface->backend->fill_stroke) {
  2137.         cairo_matrix_t dev_ctm = *stroke_ctm;
  2138.         cairo_matrix_t dev_ctm_inverse = *stroke_ctm_inverse;
  2139.  
  2140.         status = surface->backend->fill_stroke (surface,
  2141.                                                 fill_op, fill_source, fill_rule,
  2142.                                                 fill_tolerance, fill_antialias,
  2143.                                                 path,
  2144.                                                 stroke_op, stroke_source,
  2145.                                                 stroke_style,
  2146.                                                 &dev_ctm, &dev_ctm_inverse,
  2147.                                                 stroke_tolerance, stroke_antialias,
  2148.                                                 clip);
  2149.  
  2150.         if (status != CAIRO_INT_STATUS_UNSUPPORTED)
  2151.             goto FINISH;
  2152.     }
  2153.  
  2154.     status = _cairo_surface_fill (surface, fill_op, fill_source, path,
  2155.                                   fill_rule, fill_tolerance, fill_antialias,
  2156.                                   clip);
  2157.     if (unlikely (status))
  2158.         goto FINISH;
  2159.  
  2160.     status = _cairo_surface_stroke (surface, stroke_op, stroke_source, path,
  2161.                                     stroke_style, stroke_ctm, stroke_ctm_inverse,
  2162.                                     stroke_tolerance, stroke_antialias,
  2163.                                     clip);
  2164.     if (unlikely (status))
  2165.         goto FINISH;
  2166.  
  2167.   FINISH:
  2168.     if (status != CAIRO_INT_STATUS_NOTHING_TO_DO) {
  2169.         surface->is_clear = FALSE;
  2170.         surface->serial++;
  2171.     }
  2172.  
  2173.     return _cairo_surface_set_error (surface, status);
  2174. }
  2175.  
  2176. cairo_status_t
  2177. _cairo_surface_stroke (cairo_surface_t                  *surface,
  2178.                        cairo_operator_t                  op,
  2179.                        const cairo_pattern_t            *source,
  2180.                        const cairo_path_fixed_t         *path,
  2181.                        const cairo_stroke_style_t       *stroke_style,
  2182.                        const cairo_matrix_t             *ctm,
  2183.                        const cairo_matrix_t             *ctm_inverse,
  2184.                        double                            tolerance,
  2185.                        cairo_antialias_t                 antialias,
  2186.                        const cairo_clip_t               *clip)
  2187. {
  2188.     cairo_int_status_t status;
  2189.  
  2190.     TRACE ((stderr, "%s\n", __FUNCTION__));
  2191.     if (unlikely (surface->status))
  2192.         return surface->status;
  2193.     if (unlikely (surface->finished))
  2194.         return _cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
  2195.  
  2196.     if (_cairo_clip_is_all_clipped (clip))
  2197.         return CAIRO_STATUS_SUCCESS;
  2198.  
  2199.     status = _pattern_has_error (source);
  2200.     if (unlikely (status))
  2201.         return status;
  2202.  
  2203.     if (nothing_to_do (surface, op, source))
  2204.         return CAIRO_STATUS_SUCCESS;
  2205.  
  2206.     status = _cairo_surface_begin_modification (surface);
  2207.     if (unlikely (status))
  2208.         return status;
  2209.  
  2210.     status = surface->backend->stroke (surface, op, source,
  2211.                                        path, stroke_style,
  2212.                                        ctm, ctm_inverse,
  2213.                                        tolerance, antialias,
  2214.                                        clip);
  2215.     if (status != CAIRO_INT_STATUS_NOTHING_TO_DO) {
  2216.         surface->is_clear = FALSE;
  2217.         surface->serial++;
  2218.     }
  2219.  
  2220.     return _cairo_surface_set_error (surface, status);
  2221. }
  2222.  
  2223. cairo_status_t
  2224. _cairo_surface_fill (cairo_surface_t            *surface,
  2225.                      cairo_operator_t            op,
  2226.                      const cairo_pattern_t       *source,
  2227.                      const cairo_path_fixed_t   *path,
  2228.                      cairo_fill_rule_t           fill_rule,
  2229.                      double                      tolerance,
  2230.                      cairo_antialias_t           antialias,
  2231.                      const cairo_clip_t         *clip)
  2232. {
  2233.     cairo_int_status_t status;
  2234.  
  2235.     TRACE ((stderr, "%s\n", __FUNCTION__));
  2236.     if (unlikely (surface->status))
  2237.         return surface->status;
  2238.     if (unlikely (surface->finished))
  2239.         return _cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
  2240.  
  2241.     if (_cairo_clip_is_all_clipped (clip))
  2242.         return CAIRO_STATUS_SUCCESS;
  2243.  
  2244.     status = _pattern_has_error (source);
  2245.     if (unlikely (status))
  2246.         return status;
  2247.  
  2248.     if (nothing_to_do (surface, op, source))
  2249.         return CAIRO_STATUS_SUCCESS;
  2250.  
  2251.     status = _cairo_surface_begin_modification (surface);
  2252.     if (unlikely (status))
  2253.         return status;
  2254.  
  2255.     status = surface->backend->fill (surface, op, source,
  2256.                                      path, fill_rule,
  2257.                                      tolerance, antialias,
  2258.                                      clip);
  2259.     if (status != CAIRO_INT_STATUS_NOTHING_TO_DO) {
  2260.         surface->is_clear = FALSE;
  2261.         surface->serial++;
  2262.     }
  2263.  
  2264.     return _cairo_surface_set_error (surface, status);
  2265. }
  2266.  
  2267. /**
  2268.  * cairo_surface_copy_page:
  2269.  * @surface: a #cairo_surface_t
  2270.  *
  2271.  * Emits the current page for backends that support multiple pages,
  2272.  * but doesn't clear it, so that the contents of the current page will
  2273.  * be retained for the next page.  Use cairo_surface_show_page() if you
  2274.  * want to get an empty page after the emission.
  2275.  *
  2276.  * There is a convenience function for this that takes a #cairo_t,
  2277.  * namely cairo_copy_page().
  2278.  *
  2279.  * Since: 1.6
  2280.  **/
  2281. void
  2282. cairo_surface_copy_page (cairo_surface_t *surface)
  2283. {
  2284.     if (unlikely (surface->status))
  2285.         return;
  2286.  
  2287.     assert (surface->snapshot_of == NULL);
  2288.  
  2289.     if (unlikely (surface->finished)) {
  2290.         _cairo_surface_set_error (surface, CAIRO_STATUS_SURFACE_FINISHED);
  2291.         return;
  2292.     }
  2293.  
  2294.     /* It's fine if some backends don't implement copy_page */
  2295.     if (surface->backend->copy_page == NULL)
  2296.         return;
  2297.  
  2298.     _cairo_surface_set_error (surface, surface->backend->copy_page (surface));
  2299. }
  2300. slim_hidden_def (cairo_surface_copy_page);
  2301.  
  2302. /**
  2303.  * cairo_surface_show_page:
  2304.  * @surface: a #cairo_Surface_t
  2305.  *
  2306.  * Emits and clears the current page for backends that support multiple
  2307.  * pages.  Use cairo_surface_copy_page() if you don't want to clear the page.
  2308.  *
  2309.  * There is a convenience function for this that takes a #cairo_t,
  2310.  * namely cairo_show_page().
  2311.  *
  2312.  * Since: 1.6
  2313.  **/
  2314. void
  2315. cairo_surface_show_page (cairo_surface_t *surface)
  2316. {
  2317.     cairo_status_t status;
  2318.  
  2319.     if (unlikely (surface->status))
  2320.         return;
  2321.  
  2322.     if (unlikely (surface->finished)) {
  2323.         _cairo_surface_set_error (surface, CAIRO_STATUS_SURFACE_FINISHED);
  2324.         return;
  2325.     }
  2326.  
  2327.     status = _cairo_surface_begin_modification (surface);
  2328.     if (unlikely (status)) {
  2329.         _cairo_surface_set_error (surface, status);
  2330.         return;
  2331.     }
  2332.  
  2333.     /* It's fine if some backends don't implement show_page */
  2334.     if (surface->backend->show_page == NULL)
  2335.         return;
  2336.  
  2337.     _cairo_surface_set_error (surface, surface->backend->show_page (surface));
  2338. }
  2339. slim_hidden_def (cairo_surface_show_page);
  2340.  
  2341. /**
  2342.  * _cairo_surface_get_extents:
  2343.  * @surface: the #cairo_surface_t to fetch extents for
  2344.  *
  2345.  * This function returns a bounding box for the surface.  The surface
  2346.  * bounds are defined as a region beyond which no rendering will
  2347.  * possibly be recorded, in other words, it is the maximum extent of
  2348.  * potentially usable coordinates.
  2349.  *
  2350.  * For vector surfaces, (PDF, PS, SVG and recording-surfaces), the surface
  2351.  * might be conceived as unbounded, but we force the user to provide a
  2352.  * maximum size at the time of surface_create. So get_extents uses
  2353.  * that size.
  2354.  *
  2355.  * Note: The coordinates returned are in "backend" space rather than
  2356.  * "surface" space. That is, they are relative to the true (0,0)
  2357.  * origin rather than the device_transform origin. This might seem a
  2358.  * bit inconsistent with other #cairo_surface_t interfaces, but all
  2359.  * current callers are within the surface layer where backend space is
  2360.  * desired.
  2361.  *
  2362.  * This behavior would have to be changed is we ever exported a public
  2363.  * variant of this function.
  2364.  **/
  2365. cairo_bool_t
  2366. _cairo_surface_get_extents (cairo_surface_t         *surface,
  2367.                             cairo_rectangle_int_t   *extents)
  2368. {
  2369.     cairo_bool_t bounded;
  2370.  
  2371.     if (unlikely (surface->status))
  2372.         goto zero_extents;
  2373.     if (unlikely (surface->finished)) {
  2374.         _cairo_surface_set_error(surface, CAIRO_STATUS_SURFACE_FINISHED);
  2375.         goto zero_extents;
  2376.     }
  2377.  
  2378.     bounded = FALSE;
  2379.     if (surface->backend->get_extents != NULL)
  2380.         bounded = surface->backend->get_extents (surface, extents);
  2381.  
  2382.     if (! bounded)
  2383.         _cairo_unbounded_rectangle_init (extents);
  2384.  
  2385.     return bounded;
  2386.  
  2387. zero_extents:
  2388.     extents->x = extents->y = 0;
  2389.     extents->width = extents->height = 0;
  2390.     return TRUE;
  2391. }
  2392.  
  2393. /**
  2394.  * cairo_surface_has_show_text_glyphs:
  2395.  * @surface: a #cairo_surface_t
  2396.  *
  2397.  * Returns whether the surface supports
  2398.  * sophisticated cairo_show_text_glyphs() operations.  That is,
  2399.  * whether it actually uses the provided text and cluster data
  2400.  * to a cairo_show_text_glyphs() call.
  2401.  *
  2402.  * Note: Even if this function returns %FALSE, a
  2403.  * cairo_show_text_glyphs() operation targeted at @surface will
  2404.  * still succeed.  It just will
  2405.  * act like a cairo_show_glyphs() operation.  Users can use this
  2406.  * function to avoid computing UTF-8 text and cluster mapping if the
  2407.  * target surface does not use it.
  2408.  *
  2409.  * Return value: %TRUE if @surface supports
  2410.  *               cairo_show_text_glyphs(), %FALSE otherwise
  2411.  *
  2412.  * Since: 1.8
  2413.  **/
  2414. cairo_bool_t
  2415. cairo_surface_has_show_text_glyphs (cairo_surface_t         *surface)
  2416. {
  2417.     if (unlikely (surface->status))
  2418.         return FALSE;
  2419.  
  2420.     if (unlikely (surface->finished)) {
  2421.         _cairo_surface_set_error (surface, CAIRO_STATUS_SURFACE_FINISHED);
  2422.         return FALSE;
  2423.     }
  2424.  
  2425.     if (surface->backend->has_show_text_glyphs)
  2426.         return surface->backend->has_show_text_glyphs (surface);
  2427.     else
  2428.         return surface->backend->show_text_glyphs != NULL;
  2429. }
  2430. slim_hidden_def (cairo_surface_has_show_text_glyphs);
  2431.  
  2432. /* Note: the backends may modify the contents of the glyph array as long as
  2433.  * they do not return %CAIRO_INT_STATUS_UNSUPPORTED. This makes it possible to
  2434.  * avoid copying the array again and again, and edit it in-place.
  2435.  * Backends are in fact free to use the array as a generic buffer as they
  2436.  * see fit.
  2437.  *
  2438.  * For show_glyphs backend method, and NOT for show_text_glyphs method,
  2439.  * when they do return UNSUPPORTED, they may adjust remaining_glyphs to notify
  2440.  * that they have successfully rendered some of the glyphs (from the beginning
  2441.  * of the array), but not all.  If they don't touch remaining_glyphs, it
  2442.  * defaults to all glyphs.
  2443.  *
  2444.  * See commits 5a9642c5746fd677aed35ce620ce90b1029b1a0c and
  2445.  * 1781e6018c17909311295a9cc74b70500c6b4d0a for the rationale.
  2446.  */
  2447. cairo_status_t
  2448. _cairo_surface_show_text_glyphs (cairo_surface_t            *surface,
  2449.                                  cairo_operator_t            op,
  2450.                                  const cairo_pattern_t      *source,
  2451.                                  const char                 *utf8,
  2452.                                  int                         utf8_len,
  2453.                                  cairo_glyph_t              *glyphs,
  2454.                                  int                         num_glyphs,
  2455.                                  const cairo_text_cluster_t *clusters,
  2456.                                  int                         num_clusters,
  2457.                                  cairo_text_cluster_flags_t  cluster_flags,
  2458.                                  cairo_scaled_font_t        *scaled_font,
  2459.                                  const cairo_clip_t             *clip)
  2460. {
  2461.     cairo_int_status_t status;
  2462.     cairo_scaled_font_t *dev_scaled_font = scaled_font;
  2463.  
  2464.     TRACE ((stderr, "%s\n", __FUNCTION__));
  2465.     if (unlikely (surface->status))
  2466.         return surface->status;
  2467.     if (unlikely (surface->finished))
  2468.         return _cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
  2469.  
  2470.     if (num_glyphs == 0 && utf8_len == 0)
  2471.         return CAIRO_STATUS_SUCCESS;
  2472.  
  2473.     if (_cairo_clip_is_all_clipped (clip))
  2474.         return CAIRO_STATUS_SUCCESS;
  2475.  
  2476.     status = _pattern_has_error (source);
  2477.     if (unlikely (status))
  2478.         return status;
  2479.  
  2480.     if (nothing_to_do (surface, op, source))
  2481.         return CAIRO_STATUS_SUCCESS;
  2482.  
  2483.     status = _cairo_surface_begin_modification (surface);
  2484.     if (unlikely (status))
  2485.         return status;
  2486.  
  2487.     if (_cairo_surface_has_device_transform (surface) &&
  2488.         ! _cairo_matrix_is_integer_translation (&surface->device_transform, NULL, NULL))
  2489.     {
  2490.         cairo_font_options_t font_options;
  2491.         cairo_matrix_t dev_ctm, font_matrix;
  2492.  
  2493.         cairo_scaled_font_get_font_matrix (scaled_font, &font_matrix);
  2494.         cairo_scaled_font_get_ctm (scaled_font, &dev_ctm);
  2495.         cairo_matrix_multiply (&dev_ctm, &dev_ctm, &surface->device_transform);
  2496.         cairo_scaled_font_get_font_options (scaled_font, &font_options);
  2497.         dev_scaled_font = cairo_scaled_font_create (cairo_scaled_font_get_font_face (scaled_font),
  2498.                                                     &font_matrix,
  2499.                                                     &dev_ctm,
  2500.                                                     &font_options);
  2501.     }
  2502.     status = cairo_scaled_font_status (dev_scaled_font);
  2503.     if (unlikely (status))
  2504.         return _cairo_surface_set_error (surface, status);
  2505.  
  2506.     status = CAIRO_INT_STATUS_UNSUPPORTED;
  2507.  
  2508.     /* The logic here is duplicated in _cairo_analysis_surface show_glyphs and
  2509.      * show_text_glyphs.  Keep in synch. */
  2510.     if (clusters) {
  2511.         /* A real show_text_glyphs call.  Try show_text_glyphs backend
  2512.          * method first */
  2513.         if (surface->backend->show_text_glyphs != NULL) {
  2514.             status = surface->backend->show_text_glyphs (surface, op,
  2515.                                                          source,
  2516.                                                          utf8, utf8_len,
  2517.                                                          glyphs, num_glyphs,
  2518.                                                          clusters, num_clusters, cluster_flags,
  2519.                                                          dev_scaled_font,
  2520.                                                          clip);
  2521.         }
  2522.         if (status == CAIRO_INT_STATUS_UNSUPPORTED &&
  2523.             surface->backend->show_glyphs)
  2524.         {
  2525.             status = surface->backend->show_glyphs (surface, op,
  2526.                                                     source,
  2527.                                                     glyphs, num_glyphs,
  2528.                                                     dev_scaled_font,
  2529.                                                     clip);
  2530.         }
  2531.     } else {
  2532.         /* A mere show_glyphs call.  Try show_glyphs backend method first */
  2533.         if (surface->backend->show_glyphs != NULL) {
  2534.             status = surface->backend->show_glyphs (surface, op,
  2535.                                                     source,
  2536.                                                     glyphs, num_glyphs,
  2537.                                                     dev_scaled_font,
  2538.                                                     clip);
  2539.         } else if (surface->backend->show_text_glyphs != NULL) {
  2540.             /* Intentionally only try show_text_glyphs method for show_glyphs
  2541.              * calls if backend does not have show_glyphs.  If backend has
  2542.              * both methods implemented, we don't fallback from show_glyphs to
  2543.              * show_text_glyphs, and hence the backend can assume in its
  2544.              * show_text_glyphs call that clusters is not NULL (which also
  2545.              * implies that UTF-8 is not NULL, unless the text is
  2546.              * zero-length).
  2547.              */
  2548.             status = surface->backend->show_text_glyphs (surface, op,
  2549.                                                          source,
  2550.                                                          utf8, utf8_len,
  2551.                                                          glyphs, num_glyphs,
  2552.                                                          clusters, num_clusters, cluster_flags,
  2553.                                                          dev_scaled_font,
  2554.                                                          clip);
  2555.         }
  2556.     }
  2557.  
  2558.     if (dev_scaled_font != scaled_font)
  2559.         cairo_scaled_font_destroy (dev_scaled_font);
  2560.  
  2561.     if (status != CAIRO_INT_STATUS_NOTHING_TO_DO) {
  2562.         surface->is_clear = FALSE;
  2563.         surface->serial++;
  2564.     }
  2565.  
  2566.     return _cairo_surface_set_error (surface, status);
  2567. }
  2568.  
  2569. /**
  2570.  * _cairo_surface_set_resolution:
  2571.  * @surface: the surface
  2572.  * @x_res: x resolution, in dpi
  2573.  * @y_res: y resolution, in dpi
  2574.  *
  2575.  * Set the actual surface resolution of @surface to the given x and y DPI.
  2576.  * Mainly used for correctly computing the scale factor when fallback
  2577.  * rendering needs to take place in the paginated surface.
  2578.  **/
  2579. void
  2580. _cairo_surface_set_resolution (cairo_surface_t *surface,
  2581.                                double x_res,
  2582.                                double y_res)
  2583. {
  2584.     if (surface->status)
  2585.         return;
  2586.  
  2587.     surface->x_resolution = x_res;
  2588.     surface->y_resolution = y_res;
  2589. }
  2590.  
  2591. cairo_surface_t *
  2592. _cairo_surface_create_in_error (cairo_status_t status)
  2593. {
  2594.     assert (status < CAIRO_STATUS_LAST_STATUS);
  2595.     switch (status) {
  2596.     case CAIRO_STATUS_NO_MEMORY:
  2597.         return (cairo_surface_t *) &_cairo_surface_nil;
  2598.     case CAIRO_STATUS_SURFACE_TYPE_MISMATCH:
  2599.         return (cairo_surface_t *) &_cairo_surface_nil_surface_type_mismatch;
  2600.     case CAIRO_STATUS_INVALID_STATUS:
  2601.         return (cairo_surface_t *) &_cairo_surface_nil_invalid_status;
  2602.     case CAIRO_STATUS_INVALID_CONTENT:
  2603.         return (cairo_surface_t *) &_cairo_surface_nil_invalid_content;
  2604.     case CAIRO_STATUS_INVALID_FORMAT:
  2605.         return (cairo_surface_t *) &_cairo_surface_nil_invalid_format;
  2606.     case CAIRO_STATUS_INVALID_VISUAL:
  2607.         return (cairo_surface_t *) &_cairo_surface_nil_invalid_visual;
  2608.     case CAIRO_STATUS_READ_ERROR:
  2609.         return (cairo_surface_t *) &_cairo_surface_nil_read_error;
  2610.     case CAIRO_STATUS_WRITE_ERROR:
  2611.         return (cairo_surface_t *) &_cairo_surface_nil_write_error;
  2612.     case CAIRO_STATUS_FILE_NOT_FOUND:
  2613.         return (cairo_surface_t *) &_cairo_surface_nil_file_not_found;
  2614.     case CAIRO_STATUS_TEMP_FILE_ERROR:
  2615.         return (cairo_surface_t *) &_cairo_surface_nil_temp_file_error;
  2616.     case CAIRO_STATUS_INVALID_STRIDE:
  2617.         return (cairo_surface_t *) &_cairo_surface_nil_invalid_stride;
  2618.     case CAIRO_STATUS_INVALID_SIZE:
  2619.         return (cairo_surface_t *) &_cairo_surface_nil_invalid_size;
  2620.     case CAIRO_STATUS_DEVICE_TYPE_MISMATCH:
  2621.         return (cairo_surface_t *) &_cairo_surface_nil_device_type_mismatch;
  2622.     case CAIRO_STATUS_DEVICE_ERROR:
  2623.         return (cairo_surface_t *) &_cairo_surface_nil_device_error;
  2624.     case CAIRO_STATUS_SUCCESS:
  2625.     case CAIRO_STATUS_LAST_STATUS:
  2626.         ASSERT_NOT_REACHED;
  2627.         /* fall-through */
  2628.     case CAIRO_STATUS_INVALID_RESTORE:
  2629.     case CAIRO_STATUS_INVALID_POP_GROUP:
  2630.     case CAIRO_STATUS_NO_CURRENT_POINT:
  2631.     case CAIRO_STATUS_INVALID_MATRIX:
  2632.     case CAIRO_STATUS_NULL_POINTER:
  2633.     case CAIRO_STATUS_INVALID_STRING:
  2634.     case CAIRO_STATUS_INVALID_PATH_DATA:
  2635.     case CAIRO_STATUS_SURFACE_FINISHED:
  2636.     case CAIRO_STATUS_PATTERN_TYPE_MISMATCH:
  2637.     case CAIRO_STATUS_INVALID_DASH:
  2638.     case CAIRO_STATUS_INVALID_DSC_COMMENT:
  2639.     case CAIRO_STATUS_INVALID_INDEX:
  2640.     case CAIRO_STATUS_CLIP_NOT_REPRESENTABLE:
  2641.     case CAIRO_STATUS_FONT_TYPE_MISMATCH:
  2642.     case CAIRO_STATUS_USER_FONT_IMMUTABLE:
  2643.     case CAIRO_STATUS_USER_FONT_ERROR:
  2644.     case CAIRO_STATUS_NEGATIVE_COUNT:
  2645.     case CAIRO_STATUS_INVALID_CLUSTERS:
  2646.     case CAIRO_STATUS_INVALID_SLANT:
  2647.     case CAIRO_STATUS_INVALID_WEIGHT:
  2648.     case CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED:
  2649.     case CAIRO_STATUS_INVALID_MESH_CONSTRUCTION:
  2650.     case CAIRO_STATUS_DEVICE_FINISHED:
  2651.     default:
  2652.         _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
  2653.         return (cairo_surface_t *) &_cairo_surface_nil;
  2654.     }
  2655. }
  2656.  
  2657. cairo_surface_t *
  2658. _cairo_int_surface_create_in_error (cairo_int_status_t status)
  2659. {
  2660.     if (status < CAIRO_INT_STATUS_LAST_STATUS)
  2661.         return _cairo_surface_create_in_error (status);
  2662.  
  2663.     switch ((int)status) {
  2664.     case CAIRO_INT_STATUS_UNSUPPORTED:
  2665.         return (cairo_surface_t *) &_cairo_surface_nil_unsupported;
  2666.     case CAIRO_INT_STATUS_NOTHING_TO_DO:
  2667.         return (cairo_surface_t *) &_cairo_surface_nil_nothing_to_do;
  2668.     default:
  2669.         _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
  2670.         return (cairo_surface_t *) &_cairo_surface_nil;
  2671.     }
  2672. }
  2673.  
  2674. /*  LocalWords:  rasterized
  2675.  */
  2676.