Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /* cairo - a vector graphics library with display and print output
  2.  *
  3.  * Copyright © 2005 Red Hat, Inc
  4.  *
  5.  * This library is free software; you can redistribute it and/or
  6.  * modify it either under the terms of the GNU Lesser General Public
  7.  * License version 2.1 as published by the Free Software Foundation
  8.  * (the "LGPL") or, at your option, under the terms of the Mozilla
  9.  * Public License Version 1.1 (the "MPL"). If you do not alter this
  10.  * notice, a recipient may use your version of this file under either
  11.  * the MPL or the LGPL.
  12.  *
  13.  * You should have received a copy of the LGPL along with this library
  14.  * in the file COPYING-LGPL-2.1; if not, write to the Free Software
  15.  * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
  16.  * You should have received a copy of the MPL along with this library
  17.  * in the file COPYING-MPL-1.1
  18.  *
  19.  * The contents of this file are subject to the Mozilla Public License
  20.  * Version 1.1 (the "License"); you may not use this file except in
  21.  * compliance with the License. You may obtain a copy of the License at
  22.  * http://www.mozilla.org/MPL/
  23.  *
  24.  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
  25.  * OF ANY KIND, either express or implied. See the LGPL or the MPL for
  26.  * the specific language governing rights and limitations.
  27.  *
  28.  * The Original Code is the cairo graphics library.
  29.  *
  30.  * The Initial Developer of the Original Code is Red Hat, Inc.
  31.  *
  32.  * Contributor(s):
  33.  *      Carl Worth <cworth@cworth.org>
  34.  */
  35.  
  36. /* This isn't a "real" surface, but just something to be used by the
  37.  * test suite to help exercise the paginated-surface paths in cairo.
  38.  *
  39.  * The defining feature of this backend is that it uses a paginated
  40.  * surface to record all operations, and then replays everything to an
  41.  * image surface.
  42.  *
  43.  * It's possible that this code might serve as a good starting point
  44.  * for someone working on bringing up a new paginated-surface-based
  45.  * backend.
  46.  */
  47.  
  48. #include "cairoint.h"
  49.  
  50. #include "test-paginated-surface.h"
  51.  
  52. #include "cairo-default-context-private.h"
  53. #include "cairo-error-private.h"
  54. #include "cairo-paginated-private.h"
  55. #include "cairo-surface-backend-private.h"
  56.  
  57. typedef struct _test_paginated_surface {
  58.     cairo_surface_t base;
  59.     cairo_surface_t *target;
  60.     cairo_paginated_mode_t paginated_mode;
  61. } test_paginated_surface_t;
  62.  
  63. static const cairo_surface_backend_t test_paginated_surface_backend;
  64. static const cairo_paginated_surface_backend_t test_paginated_surface_paginated_backend;
  65.  
  66. cairo_surface_t *
  67. _cairo_test_paginated_surface_create (cairo_surface_t *target)
  68. {
  69.     cairo_status_t status;
  70.     cairo_surface_t *paginated;
  71.     test_paginated_surface_t *surface;
  72.  
  73.     status = cairo_surface_status (target);
  74.     if (unlikely (status))
  75.         return _cairo_surface_create_in_error (status);
  76.  
  77.     surface = malloc (sizeof (test_paginated_surface_t));
  78.     if (unlikely (surface == NULL))
  79.         return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
  80.  
  81.     _cairo_surface_init (&surface->base,
  82.                          &test_paginated_surface_backend,
  83.                          NULL, /* device */
  84.                          target->content);
  85.  
  86.     surface->target = cairo_surface_reference (target);
  87.  
  88.     paginated =  _cairo_paginated_surface_create (&surface->base,
  89.                                                   target->content,
  90.                                                   &test_paginated_surface_paginated_backend);
  91.     status = paginated->status;
  92.     if (status == CAIRO_STATUS_SUCCESS) {
  93.         /* paginated keeps the only reference to surface now, drop ours */
  94.         cairo_surface_destroy (&surface->base);
  95.         return paginated;
  96.     }
  97.  
  98.     cairo_surface_destroy (target);
  99.     free (surface);
  100.     return _cairo_surface_create_in_error (status);
  101. }
  102.  
  103. static cairo_status_t
  104. _test_paginated_surface_finish (void *abstract_surface)
  105. {
  106.     test_paginated_surface_t *surface = abstract_surface;
  107.  
  108.     cairo_surface_destroy (surface->target);
  109.  
  110.     return CAIRO_STATUS_SUCCESS;
  111. }
  112.  
  113. static cairo_bool_t
  114. _test_paginated_surface_get_extents (void                       *abstract_surface,
  115.                                      cairo_rectangle_int_t      *rectangle)
  116. {
  117.     test_paginated_surface_t *surface = abstract_surface;
  118.  
  119.     return _cairo_surface_get_extents (surface->target, rectangle);
  120. }
  121.  
  122. static cairo_int_status_t
  123. _test_paginated_surface_paint (void             *abstract_surface,
  124.                                cairo_operator_t  op,
  125.                                const cairo_pattern_t    *source,
  126.                                const cairo_clip_t       *clip)
  127. {
  128.     test_paginated_surface_t *surface = abstract_surface;
  129.  
  130.     if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
  131.         return CAIRO_STATUS_SUCCESS;
  132.  
  133.     return _cairo_surface_paint (surface->target, op, source, clip);
  134. }
  135.  
  136. static cairo_int_status_t
  137. _test_paginated_surface_mask (void              *abstract_surface,
  138.                               cairo_operator_t   op,
  139.                               const cairo_pattern_t     *source,
  140.                               const cairo_pattern_t     *mask,
  141.                               const cairo_clip_t        *clip)
  142. {
  143.     test_paginated_surface_t *surface = abstract_surface;
  144.  
  145.     if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
  146.         return CAIRO_STATUS_SUCCESS;
  147.  
  148.     return _cairo_surface_mask (surface->target,
  149.                                 op, source, mask, clip);
  150. }
  151.  
  152. static cairo_int_status_t
  153. _test_paginated_surface_stroke (void                            *abstract_surface,
  154.                                 cairo_operator_t                 op,
  155.                                 const cairo_pattern_t           *source,
  156.                                 const cairo_path_fixed_t                *path,
  157.                                 const cairo_stroke_style_t              *style,
  158.                                 const cairo_matrix_t                    *ctm,
  159.                                 const cairo_matrix_t                    *ctm_inverse,
  160.                                 double                           tolerance,
  161.                                 cairo_antialias_t                antialias,
  162.                                 const cairo_clip_t              *clip)
  163. {
  164.     test_paginated_surface_t *surface = abstract_surface;
  165.  
  166.     if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
  167.         return CAIRO_STATUS_SUCCESS;
  168.  
  169.     return _cairo_surface_stroke (surface->target, op, source,
  170.                                   path, style,
  171.                                   ctm, ctm_inverse,
  172.                                   tolerance, antialias,
  173.                                   clip);
  174. }
  175.  
  176. static cairo_int_status_t
  177. _test_paginated_surface_fill (void                              *abstract_surface,
  178.                               cairo_operator_t                   op,
  179.                               const cairo_pattern_t             *source,
  180.                               const cairo_path_fixed_t          *path,
  181.                               cairo_fill_rule_t                  fill_rule,
  182.                               double                             tolerance,
  183.                               cairo_antialias_t                  antialias,
  184.                               const cairo_clip_t                *clip)
  185. {
  186.     test_paginated_surface_t *surface = abstract_surface;
  187.  
  188.     if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
  189.         return CAIRO_STATUS_SUCCESS;
  190.  
  191.     return _cairo_surface_fill (surface->target, op, source,
  192.                                 path, fill_rule,
  193.                                 tolerance, antialias,
  194.                                 clip);
  195. }
  196.  
  197. static cairo_bool_t
  198. _test_paginated_surface_has_show_text_glyphs (void *abstract_surface)
  199. {
  200.     test_paginated_surface_t *surface = abstract_surface;
  201.  
  202.     return cairo_surface_has_show_text_glyphs (surface->target);
  203. }
  204.  
  205. static cairo_int_status_t
  206. _test_paginated_surface_show_text_glyphs (void                      *abstract_surface,
  207.                                           cairo_operator_t           op,
  208.                                           const cairo_pattern_t     *source,
  209.                                           const char                *utf8,
  210.                                           int                        utf8_len,
  211.                                           cairo_glyph_t             *glyphs,
  212.                                           int                        num_glyphs,
  213.                                           const cairo_text_cluster_t *clusters,
  214.                                           int                        num_clusters,
  215.                                           cairo_text_cluster_flags_t cluster_flags,
  216.                                           cairo_scaled_font_t       *scaled_font,
  217.                                           const cairo_clip_t        *clip)
  218. {
  219.     test_paginated_surface_t *surface = abstract_surface;
  220.  
  221.     if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
  222.         return CAIRO_STATUS_SUCCESS;
  223.  
  224.     return _cairo_surface_show_text_glyphs (surface->target, op, source,
  225.                                             utf8, utf8_len,
  226.                                             glyphs, num_glyphs,
  227.                                             clusters, num_clusters,
  228.                                             cluster_flags,
  229.                                             scaled_font,
  230.                                             clip);
  231. }
  232.  
  233.  
  234. static void
  235. _test_paginated_surface_set_paginated_mode (void                        *abstract_surface,
  236.                                             cairo_paginated_mode_t       mode)
  237. {
  238.     test_paginated_surface_t *surface = abstract_surface;
  239.  
  240.     surface->paginated_mode = mode;
  241. }
  242.  
  243. static const cairo_surface_backend_t test_paginated_surface_backend = {
  244.     CAIRO_INTERNAL_SURFACE_TYPE_TEST_PAGINATED,
  245.     _test_paginated_surface_finish,
  246.     _cairo_default_context_create,
  247.  
  248.     /* Since we are a paginated user, we get to regard most of the
  249.      * surface backend interface as historical cruft and ignore it. */
  250.  
  251.     NULL, /* create_similar */
  252.     NULL, /* create similar image */
  253.     NULL, /* map to image */
  254.     NULL, /* unmap image */
  255.  
  256.     _cairo_surface_default_source,
  257.     NULL, /* acquire_source_image */
  258.     NULL, /* release_source_image */
  259.     NULL, /* snapshot */
  260.  
  261.     NULL, /* copy_page */
  262.     NULL, /* show_page */
  263.  
  264.     _test_paginated_surface_get_extents,
  265.     NULL, /* get_font_options */
  266.  
  267.     NULL, /* flush */
  268.     NULL, /* mark_dirty_rectangle */
  269.  
  270.     /* Here is the more "modern" section of the surface backend
  271.      * interface which is mostly just drawing functions */
  272.  
  273.     _test_paginated_surface_paint,
  274.     _test_paginated_surface_mask,
  275.     _test_paginated_surface_stroke,
  276.     _test_paginated_surface_fill,
  277.     NULL, /* fill-stroke */
  278.     NULL, /* replaced by show_text_glyphs */
  279.     _test_paginated_surface_has_show_text_glyphs,
  280.     _test_paginated_surface_show_text_glyphs
  281. };
  282.  
  283. static const cairo_paginated_surface_backend_t test_paginated_surface_paginated_backend = {
  284.     NULL, /* start_page */
  285.     _test_paginated_surface_set_paginated_mode
  286. };
  287.