LCOV - code coverage report
Current view: top level - gfx/cairo/cairo/src - cairo-surface-wrapper.c (source / functions) Hit Total Coverage
Test: output.info Lines: 0 323 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 20 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* cairo - a vector graphics library with display and print output
       2             :  *
       3             :  * Copyright © 2005 Red Hat, Inc
       4             :  * Copyright © 2007 Adrian Johnson
       5             :  * Copyright © 2009 Chris Wilson
       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 Red Hat, Inc.
      33             :  *
      34             :  * Contributor(s):
      35             :  *      Chris Wilson <chris@chris-wilson.co.uk>
      36             :  */
      37             : 
      38             : #include "cairoint.h"
      39             : 
      40             : #include "cairo-error-private.h"
      41             : #include "cairo-surface-wrapper-private.h"
      42             : 
      43             : /* A collection of routines to facilitate surface wrapping */
      44             : 
      45             : static void
      46           0 : _copy_transformed_pattern (cairo_pattern_t *pattern,
      47             :                            const cairo_pattern_t *original,
      48             :                            const cairo_matrix_t  *ctm_inverse)
      49             : {
      50           0 :     _cairo_pattern_init_static_copy (pattern, original);
      51             : 
      52             :     /* Device transform should already have been applied before cairo_surface_wrapper_* functions
      53             :      * are called in _cairo_gstate_copy_transformed_pattern which all the gstate drawing
      54             :      * functions call through _cairo_gstate_copy_transformed_source and such. */
      55             : 
      56           0 :     if (! _cairo_matrix_is_identity (ctm_inverse))
      57           0 :         _cairo_pattern_transform (pattern, ctm_inverse);
      58           0 : }
      59             : 
      60             : static inline cairo_bool_t
      61           0 : _cairo_surface_wrapper_needs_device_transform (cairo_surface_wrapper_t *wrapper)
      62             : {
      63           0 :     return ! _cairo_matrix_is_identity (&wrapper->target->device_transform);
      64             : }
      65             : 
      66             : static cairo_bool_t
      67           0 : _cairo_surface_wrapper_needs_extents_transform (cairo_surface_wrapper_t *wrapper)
      68             : {
      69           0 :     return wrapper->has_extents && (wrapper->extents.x | wrapper->extents.y);
      70             : }
      71             : 
      72             : cairo_status_t
      73           0 : _cairo_surface_wrapper_acquire_source_image (cairo_surface_wrapper_t *wrapper,
      74             :                                              cairo_image_surface_t  **image_out,
      75             :                                              void                   **image_extra)
      76             : {
      77           0 :     if (unlikely (wrapper->target->status))
      78           0 :         return wrapper->target->status;
      79             : 
      80           0 :     return _cairo_surface_acquire_source_image (wrapper->target,
      81             :                                                 image_out, image_extra);
      82             : }
      83             : 
      84             : void
      85           0 : _cairo_surface_wrapper_release_source_image (cairo_surface_wrapper_t *wrapper,
      86             :                                              cairo_image_surface_t  *image,
      87             :                                              void                   *image_extra)
      88             : {
      89           0 :     _cairo_surface_release_source_image (wrapper->target, image, image_extra);
      90           0 : }
      91             : 
      92             : cairo_status_t
      93           0 : _cairo_surface_wrapper_paint (cairo_surface_wrapper_t *wrapper,
      94             :                               cairo_operator_t   op,
      95             :                               const cairo_pattern_t *source,
      96             :                               cairo_clip_t          *clip)
      97             : {
      98             :     cairo_status_t status;
      99           0 :     cairo_clip_t clip_copy, *dev_clip = clip;
     100             :     cairo_pattern_union_t source_copy;
     101             :     cairo_clip_t target_clip;
     102             : 
     103           0 :     if (unlikely (wrapper->target->status))
     104           0 :         return wrapper->target->status;
     105             : 
     106           0 :     if (wrapper->has_extents) {
     107           0 :         _cairo_clip_init_copy (&target_clip, clip);
     108           0 :         status = _cairo_clip_rectangle (&target_clip, &wrapper->extents);
     109           0 :         if (unlikely (status))
     110           0 :             goto FINISH;
     111             : 
     112           0 :         dev_clip = clip = &target_clip;
     113             :     }
     114             : 
     115           0 :     if (clip && clip->all_clipped) {
     116           0 :         status = CAIRO_STATUS_SUCCESS;
     117           0 :         goto FINISH;
     118             :     }
     119             : 
     120           0 :     if (_cairo_surface_wrapper_needs_device_transform (wrapper) ||
     121           0 :         _cairo_surface_wrapper_needs_extents_transform (wrapper))
     122             :     {
     123             :         cairo_matrix_t m;
     124             : 
     125           0 :         cairo_matrix_init_identity (&m);
     126             : 
     127           0 :         if (_cairo_surface_wrapper_needs_extents_transform (wrapper))
     128           0 :             cairo_matrix_translate (&m, -wrapper->extents.x, -wrapper->extents.y);
     129             : 
     130           0 :         if (_cairo_surface_wrapper_needs_device_transform (wrapper))
     131           0 :             cairo_matrix_multiply (&m, &wrapper->target->device_transform, &m);
     132             : 
     133           0 :         if (clip != NULL) {
     134           0 :             status = _cairo_clip_init_copy_transformed (&clip_copy, clip, &m);
     135           0 :             if (unlikely (status))
     136           0 :                 goto FINISH;
     137             : 
     138           0 :             dev_clip = &clip_copy;
     139             :         }
     140             : 
     141           0 :         status = cairo_matrix_invert (&m);
     142           0 :         assert (status == CAIRO_STATUS_SUCCESS);
     143             : 
     144           0 :         _copy_transformed_pattern (&source_copy.base, source, &m);
     145           0 :         source = &source_copy.base;
     146             :     }
     147             : 
     148           0 :     status = _cairo_surface_paint (wrapper->target, op, source, dev_clip);
     149             : 
     150             :   FINISH:
     151           0 :     if (wrapper->has_extents)
     152           0 :         _cairo_clip_reset (&target_clip);
     153           0 :     if (dev_clip != clip)
     154           0 :         _cairo_clip_reset (dev_clip);
     155           0 :     return status;
     156             : }
     157             : 
     158             : cairo_status_t
     159           0 : _cairo_surface_wrapper_mask (cairo_surface_wrapper_t *wrapper,
     160             :                              cairo_operator_t    op,
     161             :                              const cairo_pattern_t *source,
     162             :                              const cairo_pattern_t *mask,
     163             :                              cairo_clip_t           *clip)
     164             : {
     165             :     cairo_status_t status;
     166           0 :     cairo_clip_t clip_copy, *dev_clip = clip;
     167             :     cairo_pattern_union_t source_copy;
     168             :     cairo_pattern_union_t mask_copy;
     169             :     cairo_clip_t target_clip;
     170             : 
     171           0 :     if (unlikely (wrapper->target->status))
     172           0 :         return wrapper->target->status;
     173             : 
     174           0 :     if (wrapper->has_extents) {
     175           0 :         _cairo_clip_init_copy (&target_clip, clip);
     176           0 :         status = _cairo_clip_rectangle (&target_clip, &wrapper->extents);
     177           0 :         if (unlikely (status))
     178           0 :             goto FINISH;
     179             : 
     180           0 :         dev_clip = clip = &target_clip;
     181             :     }
     182             : 
     183           0 :     if (clip && clip->all_clipped) {
     184           0 :         status = CAIRO_STATUS_SUCCESS;
     185           0 :         goto FINISH;
     186             :     }
     187             : 
     188           0 :     if (_cairo_surface_wrapper_needs_device_transform (wrapper) ||
     189           0 :         _cairo_surface_wrapper_needs_extents_transform (wrapper))
     190             :     {
     191             :         cairo_matrix_t m;
     192             : 
     193           0 :         cairo_matrix_init_identity (&m);
     194             : 
     195           0 :         if (_cairo_surface_wrapper_needs_extents_transform (wrapper))
     196           0 :             cairo_matrix_translate (&m, -wrapper->extents.x, -wrapper->extents.y);
     197             : 
     198           0 :         if (_cairo_surface_wrapper_needs_device_transform (wrapper))
     199           0 :             cairo_matrix_multiply (&m, &wrapper->target->device_transform, &m);
     200             : 
     201           0 :         if (clip != NULL) {
     202           0 :             status = _cairo_clip_init_copy_transformed (&clip_copy, clip, &m);
     203           0 :             if (unlikely (status))
     204           0 :                 goto FINISH;
     205             : 
     206           0 :             dev_clip = &clip_copy;
     207             :         }
     208             : 
     209           0 :         status = cairo_matrix_invert (&m);
     210           0 :         assert (status == CAIRO_STATUS_SUCCESS);
     211             : 
     212           0 :         _copy_transformed_pattern (&source_copy.base, source, &m);
     213           0 :         source = &source_copy.base;
     214             : 
     215           0 :         _copy_transformed_pattern (&mask_copy.base, mask, &m);
     216           0 :         mask = &mask_copy.base;
     217             :     }
     218             : 
     219           0 :     status = _cairo_surface_mask (wrapper->target, op, source, mask, dev_clip);
     220             : 
     221             :   FINISH:
     222           0 :     if (wrapper->has_extents)
     223           0 :         _cairo_clip_reset (&target_clip);
     224           0 :     if (dev_clip != clip)
     225           0 :         _cairo_clip_reset (dev_clip);
     226           0 :     return status;
     227             : }
     228             : 
     229             : cairo_status_t
     230           0 : _cairo_surface_wrapper_stroke (cairo_surface_wrapper_t *wrapper,
     231             :                                cairo_operator_t          op,
     232             :                                const cairo_pattern_t    *source,
     233             :                                cairo_path_fixed_t       *path,
     234             :                                const cairo_stroke_style_t       *stroke_style,
     235             :                                const cairo_matrix_t             *ctm,
     236             :                                const cairo_matrix_t             *ctm_inverse,
     237             :                                double                    tolerance,
     238             :                                cairo_antialias_t         antialias,
     239             :                                cairo_clip_t             *clip)
     240             : {
     241             :     cairo_status_t status;
     242           0 :     cairo_path_fixed_t path_copy, *dev_path = path;
     243           0 :     cairo_clip_t clip_copy, *dev_clip = clip;
     244           0 :     cairo_matrix_t dev_ctm = *ctm;
     245           0 :     cairo_matrix_t dev_ctm_inverse = *ctm_inverse;
     246             :     cairo_pattern_union_t source_copy;
     247             :     cairo_clip_t target_clip;
     248             : 
     249           0 :     if (unlikely (wrapper->target->status))
     250           0 :         return wrapper->target->status;
     251             : 
     252           0 :     if (wrapper->has_extents) {
     253           0 :         _cairo_clip_init_copy (&target_clip, clip);
     254           0 :         status = _cairo_clip_rectangle (&target_clip, &wrapper->extents);
     255           0 :         if (unlikely (status))
     256           0 :             goto FINISH;
     257             : 
     258           0 :         dev_clip = clip = &target_clip;
     259             :     }
     260             : 
     261           0 :     if (clip && clip->all_clipped) {
     262           0 :         status = CAIRO_STATUS_SUCCESS;
     263           0 :         goto FINISH;
     264             :     }
     265             : 
     266           0 :     if (_cairo_surface_wrapper_needs_device_transform (wrapper) ||
     267           0 :         _cairo_surface_wrapper_needs_extents_transform (wrapper))
     268           0 :     {
     269             :         cairo_matrix_t m;
     270             : 
     271           0 :         cairo_matrix_init_identity (&m);
     272             : 
     273           0 :         if (_cairo_surface_wrapper_needs_extents_transform (wrapper))
     274           0 :             cairo_matrix_translate (&m, -wrapper->extents.x, -wrapper->extents.y);
     275             : 
     276           0 :         if (_cairo_surface_wrapper_needs_device_transform (wrapper))
     277           0 :             cairo_matrix_multiply (&m, &wrapper->target->device_transform, &m);
     278             : 
     279           0 :         status = _cairo_path_fixed_init_copy (&path_copy, dev_path);
     280           0 :         if (unlikely (status))
     281           0 :             goto FINISH;
     282             : 
     283           0 :         _cairo_path_fixed_transform (&path_copy, &m);
     284           0 :         dev_path = &path_copy;
     285             : 
     286           0 :         if (clip != NULL) {
     287           0 :             status = _cairo_clip_init_copy_transformed (&clip_copy, clip, &m);
     288           0 :             if (unlikely (status))
     289           0 :                 goto FINISH;
     290             : 
     291           0 :             dev_clip = &clip_copy;
     292             :         }
     293             : 
     294           0 :         cairo_matrix_multiply (&dev_ctm, &dev_ctm, &m);
     295             : 
     296           0 :         status = cairo_matrix_invert (&m);
     297           0 :         assert (status == CAIRO_STATUS_SUCCESS);
     298             : 
     299           0 :         cairo_matrix_multiply (&dev_ctm_inverse, &m, &dev_ctm_inverse);
     300             : 
     301           0 :         _copy_transformed_pattern (&source_copy.base, source, &m);
     302           0 :         source = &source_copy.base;
     303             :     }
     304             :     else
     305             :     {
     306           0 :         if (clip != NULL) {
     307           0 :             dev_clip = &clip_copy;
     308           0 :             _cairo_clip_init_copy (&clip_copy, clip);
     309             :         }
     310             :     }
     311             : 
     312           0 :     status = _cairo_surface_stroke (wrapper->target, op, source,
     313             :                                     dev_path, stroke_style,
     314             :                                     &dev_ctm, &dev_ctm_inverse,
     315             :                                     tolerance, antialias,
     316             :                                     dev_clip);
     317             : 
     318             :  FINISH:
     319           0 :     if (dev_path != path)
     320           0 :         _cairo_path_fixed_fini (dev_path);
     321           0 :     if (wrapper->has_extents)
     322           0 :         _cairo_clip_reset (&target_clip);
     323           0 :     if (dev_clip != clip)
     324           0 :         _cairo_clip_reset (dev_clip);
     325           0 :     return status;
     326             : }
     327             : 
     328             : cairo_status_t
     329           0 : _cairo_surface_wrapper_fill_stroke (cairo_surface_wrapper_t *wrapper,
     330             :                                     cairo_operator_t         fill_op,
     331             :                                     const cairo_pattern_t   *fill_source,
     332             :                                     cairo_fill_rule_t        fill_rule,
     333             :                                     double                   fill_tolerance,
     334             :                                     cairo_antialias_t        fill_antialias,
     335             :                                     cairo_path_fixed_t      *path,
     336             :                                     cairo_operator_t         stroke_op,
     337             :                                     const cairo_pattern_t   *stroke_source,
     338             :                                     const cairo_stroke_style_t    *stroke_style,
     339             :                                     const cairo_matrix_t            *stroke_ctm,
     340             :                                     const cairo_matrix_t            *stroke_ctm_inverse,
     341             :                                     double                   stroke_tolerance,
     342             :                                     cairo_antialias_t        stroke_antialias,
     343             :                                     cairo_clip_t            *clip)
     344             : {
     345             :     cairo_status_t status;
     346           0 :     cairo_path_fixed_t path_copy, *dev_path = path;
     347           0 :     cairo_clip_t clip_copy, *dev_clip = clip;
     348           0 :     cairo_matrix_t dev_ctm = *stroke_ctm;
     349           0 :     cairo_matrix_t dev_ctm_inverse = *stroke_ctm_inverse;
     350             :     cairo_pattern_union_t stroke_source_copy;
     351             :     cairo_pattern_union_t fill_source_copy;
     352             :     cairo_clip_t target_clip;
     353             : 
     354           0 :     if (unlikely (wrapper->target->status))
     355           0 :         return wrapper->target->status;
     356             : 
     357           0 :     if (wrapper->has_extents) {
     358           0 :         _cairo_clip_init_copy (&target_clip, clip);
     359           0 :         status = _cairo_clip_rectangle (&target_clip, &wrapper->extents);
     360           0 :         if (unlikely (status))
     361           0 :             goto FINISH;
     362             : 
     363           0 :         dev_clip = clip = &target_clip;
     364             :     }
     365             : 
     366           0 :     if (clip && clip->all_clipped) {
     367           0 :         status = CAIRO_STATUS_SUCCESS;
     368           0 :         goto FINISH;
     369             :     }
     370             : 
     371           0 :     if (_cairo_surface_wrapper_needs_device_transform (wrapper) ||
     372           0 :         _cairo_surface_wrapper_needs_extents_transform (wrapper))
     373           0 :     {
     374             :         cairo_matrix_t m;
     375             : 
     376           0 :         cairo_matrix_init_identity (&m);
     377             : 
     378           0 :         if (_cairo_surface_wrapper_needs_extents_transform (wrapper))
     379           0 :             cairo_matrix_translate (&m, -wrapper->extents.x, -wrapper->extents.y);
     380             : 
     381           0 :         if (_cairo_surface_wrapper_needs_device_transform (wrapper))
     382           0 :             cairo_matrix_multiply (&m, &wrapper->target->device_transform, &m);
     383             : 
     384           0 :         status = _cairo_path_fixed_init_copy (&path_copy, dev_path);
     385           0 :         if (unlikely (status))
     386           0 :             goto FINISH;
     387             : 
     388           0 :         _cairo_path_fixed_transform (&path_copy, &m);
     389           0 :         dev_path = &path_copy;
     390             : 
     391           0 :         if (clip != NULL) {
     392           0 :             status = _cairo_clip_init_copy_transformed (&clip_copy, clip, &m);
     393           0 :             if (unlikely (status))
     394           0 :                 goto FINISH;
     395             : 
     396           0 :             dev_clip = &clip_copy;
     397             :         }
     398             : 
     399           0 :         cairo_matrix_multiply (&dev_ctm, &dev_ctm, &m);
     400             : 
     401           0 :         status = cairo_matrix_invert (&m);
     402           0 :         assert (status == CAIRO_STATUS_SUCCESS);
     403             : 
     404           0 :         cairo_matrix_multiply (&dev_ctm_inverse, &m, &dev_ctm_inverse);
     405             : 
     406           0 :         _copy_transformed_pattern (&stroke_source_copy.base, stroke_source, &m);
     407           0 :         stroke_source = &stroke_source_copy.base;
     408             : 
     409           0 :         _copy_transformed_pattern (&fill_source_copy.base, fill_source, &m);
     410           0 :         fill_source = &fill_source_copy.base;
     411             :     }
     412             :     else
     413             :     {
     414           0 :         if (clip != NULL) {
     415           0 :             dev_clip = &clip_copy;
     416           0 :             _cairo_clip_init_copy (&clip_copy, clip);
     417             :         }
     418             :     }
     419             : 
     420           0 :     status = _cairo_surface_fill_stroke (wrapper->target,
     421             :                                          fill_op, fill_source, fill_rule,
     422             :                                          fill_tolerance, fill_antialias,
     423             :                                          dev_path,
     424             :                                          stroke_op, stroke_source,
     425             :                                          stroke_style,
     426             :                                          &dev_ctm, &dev_ctm_inverse,
     427             :                                          stroke_tolerance, stroke_antialias,
     428             :                                          dev_clip);
     429             : 
     430             :   FINISH:
     431           0 :     if (dev_path != path)
     432           0 :         _cairo_path_fixed_fini (dev_path);
     433           0 :     if (wrapper->has_extents)
     434           0 :         _cairo_clip_reset (&target_clip);
     435           0 :     if (dev_clip != clip)
     436           0 :         _cairo_clip_reset (dev_clip);
     437           0 :     return status;
     438             : }
     439             : 
     440             : cairo_status_t
     441           0 : _cairo_surface_wrapper_fill (cairo_surface_wrapper_t    *wrapper,
     442             :                              cairo_operator_t    op,
     443             :                              const cairo_pattern_t *source,
     444             :                              cairo_path_fixed_t *path,
     445             :                              cairo_fill_rule_t   fill_rule,
     446             :                              double              tolerance,
     447             :                              cairo_antialias_t   antialias,
     448             :                              cairo_clip_t       *clip)
     449             : {
     450             :     cairo_status_t status;
     451           0 :     cairo_path_fixed_t path_copy, *dev_path = path;
     452           0 :     cairo_clip_t clip_copy, *dev_clip = clip;
     453             :     cairo_pattern_union_t source_copy;
     454             :     cairo_clip_t target_clip;
     455             : 
     456           0 :     if (unlikely (wrapper->target->status))
     457           0 :         return wrapper->target->status;
     458             : 
     459           0 :     if (wrapper->has_extents) {
     460           0 :         _cairo_clip_init_copy (&target_clip, clip);
     461           0 :         status = _cairo_clip_rectangle (&target_clip, &wrapper->extents);
     462           0 :         if (unlikely (status))
     463           0 :             goto FINISH;
     464             : 
     465           0 :         dev_clip = clip = &target_clip;
     466             :     }
     467             : 
     468           0 :     if (clip && clip->all_clipped) {
     469           0 :         status = CAIRO_STATUS_SUCCESS;
     470           0 :         goto FINISH;
     471             :     }
     472             : 
     473           0 :     if (_cairo_surface_wrapper_needs_device_transform (wrapper) ||
     474           0 :         _cairo_surface_wrapper_needs_extents_transform (wrapper))
     475           0 :     {
     476             :         cairo_matrix_t m;
     477             : 
     478           0 :         cairo_matrix_init_identity (&m);
     479             : 
     480           0 :         if (_cairo_surface_wrapper_needs_extents_transform (wrapper))
     481           0 :             cairo_matrix_translate (&m, -wrapper->extents.x, -wrapper->extents.y);
     482             : 
     483           0 :         if (_cairo_surface_wrapper_needs_device_transform (wrapper))
     484           0 :             cairo_matrix_multiply (&m, &wrapper->target->device_transform, &m);
     485             : 
     486           0 :         status = _cairo_path_fixed_init_copy (&path_copy, dev_path);
     487           0 :         if (unlikely (status))
     488           0 :             goto FINISH;
     489             : 
     490           0 :         _cairo_path_fixed_transform (&path_copy, &m);
     491           0 :         dev_path = &path_copy;
     492             : 
     493           0 :         if (clip != NULL) {
     494           0 :             status = _cairo_clip_init_copy_transformed (&clip_copy, clip, &m);
     495           0 :             if (unlikely (status))
     496           0 :                 goto FINISH;
     497             : 
     498           0 :             dev_clip = &clip_copy;
     499             :         }
     500             : 
     501           0 :         status = cairo_matrix_invert (&m);
     502           0 :         assert (status == CAIRO_STATUS_SUCCESS);
     503             : 
     504           0 :         _copy_transformed_pattern (&source_copy.base, source, &m);
     505           0 :         source = &source_copy.base;
     506             :     }
     507             :     else
     508             :     {
     509           0 :         if (clip != NULL) {
     510           0 :             dev_clip = &clip_copy;
     511           0 :             _cairo_clip_init_copy (&clip_copy, clip);
     512             :         }
     513             :     }
     514             : 
     515           0 :     status = _cairo_surface_fill (wrapper->target, op, source,
     516             :                                   dev_path, fill_rule,
     517             :                                   tolerance, antialias,
     518             :                                   dev_clip);
     519             : 
     520             :  FINISH:
     521           0 :     if (dev_path != path)
     522           0 :         _cairo_path_fixed_fini (dev_path);
     523           0 :     if (wrapper->has_extents)
     524           0 :         _cairo_clip_reset (&target_clip);
     525           0 :     if (dev_clip != clip)
     526           0 :         _cairo_clip_reset (dev_clip);
     527           0 :     return status;
     528             : }
     529             : 
     530             : cairo_status_t
     531           0 : _cairo_surface_wrapper_show_text_glyphs (cairo_surface_wrapper_t *wrapper,
     532             :                                          cairo_operator_t            op,
     533             :                                          const cairo_pattern_t      *source,
     534             :                                          const char                 *utf8,
     535             :                                          int                         utf8_len,
     536             :                                          cairo_glyph_t              *glyphs,
     537             :                                          int                         num_glyphs,
     538             :                                          const cairo_text_cluster_t *clusters,
     539             :                                          int                         num_clusters,
     540             :                                          cairo_text_cluster_flags_t  cluster_flags,
     541             :                                          cairo_scaled_font_t        *scaled_font,
     542             :                                          cairo_clip_t               *clip)
     543             : {
     544             :     cairo_status_t status;
     545           0 :     cairo_clip_t clip_copy, *dev_clip = clip;
     546           0 :     cairo_glyph_t *dev_glyphs = glyphs;
     547             :     cairo_pattern_union_t source_copy;
     548             :     cairo_clip_t target_clip;
     549             : 
     550           0 :     if (unlikely (wrapper->target->status))
     551           0 :         return wrapper->target->status;
     552             : 
     553           0 :     if (glyphs == NULL || num_glyphs == 0)
     554           0 :         return CAIRO_STATUS_SUCCESS;
     555             : 
     556           0 :     if (wrapper->has_extents) {
     557           0 :         _cairo_clip_init_copy (&target_clip, clip);
     558           0 :         status = _cairo_clip_rectangle (&target_clip, &wrapper->extents);
     559           0 :         if (unlikely (status))
     560           0 :             goto FINISH;
     561             : 
     562           0 :         dev_clip = clip = &target_clip;
     563             :     }
     564             : 
     565           0 :     if (clip && clip->all_clipped) {
     566           0 :         status = CAIRO_STATUS_SUCCESS;
     567           0 :         goto FINISH;
     568             :     }
     569             : 
     570           0 :     if (_cairo_surface_wrapper_needs_device_transform (wrapper) ||
     571           0 :         _cairo_surface_wrapper_needs_extents_transform (wrapper))
     572           0 :     {
     573             :         cairo_matrix_t m;
     574             :         int i;
     575             : 
     576           0 :         cairo_matrix_init_identity (&m);
     577             : 
     578           0 :         if (_cairo_surface_wrapper_needs_extents_transform (wrapper))
     579           0 :             cairo_matrix_translate (&m, -wrapper->extents.x, -wrapper->extents.y);
     580             : 
     581           0 :         if (_cairo_surface_wrapper_needs_device_transform (wrapper))
     582           0 :             cairo_matrix_multiply (&m, &wrapper->target->device_transform, &m);
     583             : 
     584           0 :         if (clip != NULL) {
     585           0 :             status = _cairo_clip_init_copy_transformed (&clip_copy, clip, &m);
     586           0 :             if (unlikely (status))
     587           0 :                 goto FINISH;
     588             : 
     589           0 :             dev_clip = &clip_copy;
     590             :         }
     591             : 
     592           0 :         dev_glyphs = _cairo_malloc_ab (num_glyphs, sizeof (cairo_glyph_t));
     593           0 :         if (dev_glyphs == NULL) {
     594           0 :             status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
     595           0 :             goto FINISH;
     596             :         }
     597             : 
     598           0 :         for (i = 0; i < num_glyphs; i++) {
     599           0 :             dev_glyphs[i] = glyphs[i];
     600           0 :             cairo_matrix_transform_point (&m, &dev_glyphs[i].x, &dev_glyphs[i].y);
     601             :         }
     602             : 
     603           0 :         status = cairo_matrix_invert (&m);
     604           0 :         assert (status == CAIRO_STATUS_SUCCESS);
     605             : 
     606           0 :         _copy_transformed_pattern (&source_copy.base, source, &m);
     607           0 :         source = &source_copy.base;
     608             :     }
     609             :     else
     610             :     {
     611           0 :         if (clip != NULL) {
     612           0 :             dev_clip = &clip_copy;
     613           0 :             _cairo_clip_init_copy (&clip_copy, clip);
     614             :         }
     615             :     }
     616             : 
     617           0 :     status = _cairo_surface_show_text_glyphs (wrapper->target, op, source,
     618             :                                               utf8, utf8_len,
     619             :                                               dev_glyphs, num_glyphs,
     620             :                                               clusters, num_clusters,
     621             :                                               cluster_flags,
     622             :                                               scaled_font,
     623             :                                               dev_clip);
     624             : 
     625             :  FINISH:
     626           0 :     if (dev_clip != clip)
     627           0 :         _cairo_clip_reset (dev_clip);
     628           0 :     if (wrapper->has_extents)
     629           0 :         _cairo_clip_reset (&target_clip);
     630           0 :     if (dev_glyphs != glyphs)
     631           0 :         free (dev_glyphs);
     632           0 :     return status;
     633             : }
     634             : 
     635             : cairo_surface_t *
     636           0 : _cairo_surface_wrapper_create_similar (cairo_surface_wrapper_t *wrapper,
     637             :                                        cairo_content_t  content,
     638             :                                        int              width,
     639             :                                        int              height)
     640             : {
     641           0 :     return _cairo_surface_create_similar_scratch (wrapper->target,
     642             :                                                   content, width, height);
     643             : }
     644             : 
     645             : cairo_bool_t
     646           0 : _cairo_surface_wrapper_get_extents (cairo_surface_wrapper_t *wrapper,
     647             :                                     cairo_rectangle_int_t   *extents)
     648             : {
     649           0 :     if (wrapper->has_extents) {
     650           0 :         if (_cairo_surface_get_extents (wrapper->target, extents))
     651           0 :             _cairo_rectangle_intersect (extents, &wrapper->extents);
     652             :         else
     653           0 :             *extents = wrapper->extents;
     654             : 
     655           0 :         return TRUE;
     656             :     } else {
     657           0 :         return _cairo_surface_get_extents (wrapper->target, extents);
     658             :     }
     659             : }
     660             : 
     661             : void
     662           0 : _cairo_surface_wrapper_set_extents (cairo_surface_wrapper_t *wrapper,
     663             :                                     const cairo_rectangle_int_t *extents)
     664             : {
     665           0 :     if (extents != NULL) {
     666           0 :         wrapper->extents = *extents;
     667           0 :         wrapper->has_extents = TRUE;
     668             :     } else {
     669           0 :         wrapper->has_extents = FALSE;
     670             :     }
     671           0 : }
     672             : 
     673             : void
     674           0 : _cairo_surface_wrapper_get_font_options (cairo_surface_wrapper_t    *wrapper,
     675             :                                          cairo_font_options_t       *options)
     676             : {
     677           0 :     cairo_surface_get_font_options (wrapper->target, options);
     678           0 : }
     679             : 
     680             : cairo_surface_t *
     681           0 : _cairo_surface_wrapper_snapshot (cairo_surface_wrapper_t *wrapper)
     682             : {
     683           0 :     return _cairo_surface_snapshot (wrapper->target);
     684             : }
     685             : 
     686             : cairo_bool_t
     687           0 : _cairo_surface_wrapper_has_show_text_glyphs (cairo_surface_wrapper_t *wrapper)
     688             : {
     689           0 :     return cairo_surface_has_show_text_glyphs (wrapper->target);
     690             : }
     691             : 
     692             : void
     693           0 : _cairo_surface_wrapper_init (cairo_surface_wrapper_t *wrapper,
     694             :                              cairo_surface_t *target)
     695             : {
     696           0 :     wrapper->target = cairo_surface_reference (target);
     697           0 :     wrapper->has_extents = FALSE;
     698           0 : }
     699             : 
     700             : void
     701           0 : _cairo_surface_wrapper_fini (cairo_surface_wrapper_t *wrapper)
     702             : {
     703           0 :     cairo_surface_destroy (wrapper->target);
     704           0 : }
     705             : 
     706             : cairo_status_t
     707           0 : _cairo_surface_wrapper_flush (cairo_surface_wrapper_t *wrapper)
     708             : {
     709           0 :     if (wrapper->target->backend->flush) {
     710           0 :         return wrapper->target->backend->flush(wrapper->target);
     711             :     }
     712           0 :     return CAIRO_STATUS_SUCCESS;
     713             : }

Generated by: LCOV version 1.13