LCOV - code coverage report
Current view: directory - gfx/cairo/cairo/src - cairo-surface-wrapper.c (source / functions) Found Hit Coverage
Test: app.info Lines: 328 0 0.0 %
Date: 2012-06-02 Functions: 20 0 0.0 %

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

Generated by: LCOV version 1.7