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.  * 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-clip-inline.h"
  41. #include "cairo-error-private.h"
  42. #include "cairo-pattern-private.h"
  43. #include "cairo-surface-offset-private.h"
  44.  
  45. /* A collection of routines to facilitate drawing to an alternate surface. */
  46.  
  47. static void
  48. _copy_transformed_pattern (cairo_pattern_t *pattern,
  49.                            const cairo_pattern_t *original,
  50.                            const cairo_matrix_t  *ctm_inverse)
  51. {
  52.     _cairo_pattern_init_static_copy (pattern, original);
  53.  
  54.     if (! _cairo_matrix_is_identity (ctm_inverse))
  55.         _cairo_pattern_transform (pattern, ctm_inverse);
  56. }
  57.  
  58. cairo_status_t
  59. _cairo_surface_offset_paint (cairo_surface_t            *target,
  60.                              int x, int y,
  61.                              cairo_operator_t            op,
  62.                              const cairo_pattern_t      *source,
  63.                              const cairo_clip_t         *clip)
  64. {
  65.     cairo_status_t status;
  66.     cairo_clip_t *dev_clip = (cairo_clip_t *) clip;
  67.     cairo_pattern_union_t source_copy;
  68.  
  69.     if (unlikely (target->status))
  70.         return target->status;
  71.  
  72.     if (_cairo_clip_is_all_clipped (clip))
  73.         return CAIRO_STATUS_SUCCESS;
  74.  
  75.     if (x | y) {
  76.         cairo_matrix_t m;
  77.  
  78.         dev_clip = _cairo_clip_copy_with_translation (clip, -x, -y);
  79.  
  80.         cairo_matrix_init_translate (&m, x, y);
  81.         _copy_transformed_pattern (&source_copy.base, source, &m);
  82.         source = &source_copy.base;
  83.     }
  84.  
  85.     status = _cairo_surface_paint (target, op, source, dev_clip);
  86.  
  87.     if (dev_clip != clip)
  88.         _cairo_clip_destroy (dev_clip);
  89.  
  90.     return status;
  91. }
  92.  
  93. cairo_status_t
  94. _cairo_surface_offset_mask (cairo_surface_t             *target,
  95.                             int x, int y,
  96.                             cairo_operator_t             op,
  97.                             const cairo_pattern_t       *source,
  98.                             const cairo_pattern_t       *mask,
  99.                             const cairo_clip_t          *clip)
  100. {
  101.     cairo_status_t status;
  102.     cairo_clip_t *dev_clip = (cairo_clip_t *) clip;
  103.     cairo_pattern_union_t source_copy;
  104.     cairo_pattern_union_t mask_copy;
  105.  
  106.     if (unlikely (target->status))
  107.         return target->status;
  108.  
  109.     if (_cairo_clip_is_all_clipped (clip))
  110.         return CAIRO_STATUS_SUCCESS;
  111.  
  112.     if (x | y) {
  113.         cairo_matrix_t m;
  114.  
  115.         dev_clip = _cairo_clip_copy_with_translation (clip, -x, -y);
  116.  
  117.         cairo_matrix_init_translate (&m, x, y);
  118.         _copy_transformed_pattern (&source_copy.base, source, &m);
  119.         _copy_transformed_pattern (&mask_copy.base, mask, &m);
  120.         source = &source_copy.base;
  121.         mask = &mask_copy.base;
  122.     }
  123.  
  124.     status = _cairo_surface_mask (target, op,
  125.                                   source, mask,
  126.                                   dev_clip);
  127.  
  128.     if (dev_clip != clip)
  129.         _cairo_clip_destroy (dev_clip);
  130.  
  131.     return status;
  132. }
  133.  
  134. cairo_status_t
  135. _cairo_surface_offset_stroke (cairo_surface_t           *surface,
  136.                               int x, int y,
  137.                               cairo_operator_t           op,
  138.                               const cairo_pattern_t     *source,
  139.                               const cairo_path_fixed_t  *path,
  140.                               const cairo_stroke_style_t*stroke_style,
  141.                               const cairo_matrix_t      *ctm,
  142.                               const cairo_matrix_t      *ctm_inverse,
  143.                               double                     tolerance,
  144.                               cairo_antialias_t          antialias,
  145.                               const cairo_clip_t                *clip)
  146. {
  147.     cairo_path_fixed_t path_copy, *dev_path = (cairo_path_fixed_t *) path;
  148.     cairo_clip_t *dev_clip = (cairo_clip_t *) clip;
  149.     cairo_matrix_t dev_ctm = *ctm;
  150.     cairo_matrix_t dev_ctm_inverse = *ctm_inverse;
  151.     cairo_pattern_union_t source_copy;
  152.     cairo_status_t status;
  153.  
  154.     if (unlikely (surface->status))
  155.         return surface->status;
  156.  
  157.     if (_cairo_clip_is_all_clipped (clip))
  158.         return CAIRO_STATUS_SUCCESS;
  159.  
  160.     if (x | y) {
  161.         cairo_matrix_t m;
  162.  
  163.         dev_clip = _cairo_clip_copy_with_translation (clip, -x, -y);
  164.  
  165.         status = _cairo_path_fixed_init_copy (&path_copy, dev_path);
  166.         if (unlikely (status))
  167.             goto FINISH;
  168.  
  169.         _cairo_path_fixed_translate (&path_copy,
  170.                                      _cairo_fixed_from_int (-x),
  171.                                      _cairo_fixed_from_int (-y));
  172.         dev_path = &path_copy;
  173.  
  174.         cairo_matrix_init_translate (&m, -x, -y);
  175.         cairo_matrix_multiply (&dev_ctm, &dev_ctm, &m);
  176.  
  177.         cairo_matrix_init_translate (&m, x, y);
  178.         _copy_transformed_pattern (&source_copy.base, source, &m);
  179.         source = &source_copy.base;
  180.         cairo_matrix_multiply (&dev_ctm_inverse, &m, &dev_ctm_inverse);
  181.     }
  182.  
  183.     status = _cairo_surface_stroke (surface, op, source,
  184.                                     dev_path, stroke_style,
  185.                                     &dev_ctm, &dev_ctm_inverse,
  186.                                     tolerance, antialias,
  187.                                     dev_clip);
  188.  
  189. FINISH:
  190.     if (dev_path != path)
  191.         _cairo_path_fixed_fini (dev_path);
  192.     if (dev_clip != clip)
  193.         _cairo_clip_destroy (dev_clip);
  194.  
  195.     return status;
  196. }
  197.  
  198. cairo_status_t
  199. _cairo_surface_offset_fill (cairo_surface_t     *surface,
  200.                             int x, int y,
  201.                             cairo_operator_t     op,
  202.                             const cairo_pattern_t*source,
  203.                             const cairo_path_fixed_t    *path,
  204.                             cairo_fill_rule_t    fill_rule,
  205.                             double               tolerance,
  206.                             cairo_antialias_t    antialias,
  207.                             const cairo_clip_t  *clip)
  208. {
  209.     cairo_status_t status;
  210.     cairo_path_fixed_t path_copy, *dev_path = (cairo_path_fixed_t *) path;
  211.     cairo_clip_t *dev_clip = (cairo_clip_t *) clip;
  212.     cairo_pattern_union_t source_copy;
  213.  
  214.     if (unlikely (surface->status))
  215.         return surface->status;
  216.  
  217.     if (_cairo_clip_is_all_clipped (clip))
  218.         return CAIRO_STATUS_SUCCESS;
  219.  
  220.     if (x | y) {
  221.         cairo_matrix_t m;
  222.  
  223.         dev_clip = _cairo_clip_copy_with_translation (clip, -x, -y);
  224.  
  225.         status = _cairo_path_fixed_init_copy (&path_copy, dev_path);
  226.         if (unlikely (status))
  227.             goto FINISH;
  228.  
  229.         _cairo_path_fixed_translate (&path_copy,
  230.                                      _cairo_fixed_from_int (-x),
  231.                                      _cairo_fixed_from_int (-y));
  232.         dev_path = &path_copy;
  233.  
  234.         cairo_matrix_init_translate (&m, x, y);
  235.         _copy_transformed_pattern (&source_copy.base, source, &m);
  236.         source = &source_copy.base;
  237.     }
  238.  
  239.     status = _cairo_surface_fill (surface, op, source,
  240.                                   dev_path, fill_rule,
  241.                                   tolerance, antialias,
  242.                                   dev_clip);
  243.  
  244. FINISH:
  245.     if (dev_path != path)
  246.         _cairo_path_fixed_fini (dev_path);
  247.     if (dev_clip != clip)
  248.         _cairo_clip_destroy (dev_clip);
  249.  
  250.     return status;
  251. }
  252.  
  253. cairo_status_t
  254. _cairo_surface_offset_glyphs (cairo_surface_t           *surface,
  255.                               int x, int y,
  256.                               cairo_operator_t           op,
  257.                               const cairo_pattern_t     *source,
  258.                               cairo_scaled_font_t       *scaled_font,
  259.                               cairo_glyph_t             *glyphs,
  260.                               int                        num_glyphs,
  261.                               const cairo_clip_t        *clip)
  262. {
  263.     cairo_status_t status;
  264.     cairo_clip_t *dev_clip = (cairo_clip_t *) clip;
  265.     cairo_pattern_union_t source_copy;
  266.     cairo_glyph_t *dev_glyphs;
  267.     int i;
  268.  
  269.     if (unlikely (surface->status))
  270.         return surface->status;
  271.  
  272.     if (_cairo_clip_is_all_clipped (clip))
  273.         return CAIRO_STATUS_SUCCESS;
  274.  
  275.     dev_glyphs = _cairo_malloc_ab (num_glyphs, sizeof (cairo_glyph_t));
  276.     if (dev_glyphs == NULL)
  277.         return _cairo_error (CAIRO_STATUS_NO_MEMORY);
  278.  
  279.     memcpy (dev_glyphs, glyphs, sizeof (cairo_glyph_t) * num_glyphs);
  280.  
  281.     if (x | y) {
  282.         cairo_matrix_t m;
  283.  
  284.         dev_clip = _cairo_clip_copy_with_translation (clip, -x, -y);
  285.  
  286.         cairo_matrix_init_translate (&m, x, y);
  287.         _copy_transformed_pattern (&source_copy.base, source, &m);
  288.         source = &source_copy.base;
  289.  
  290.         for (i = 0; i < num_glyphs; i++) {
  291.             dev_glyphs[i].x -= x;
  292.             dev_glyphs[i].y -= y;
  293.         }
  294.     }
  295.  
  296.     status = _cairo_surface_show_text_glyphs (surface, op, source,
  297.                                               NULL, 0,
  298.                                               dev_glyphs, num_glyphs,
  299.                                               NULL, 0, 0,
  300.                                               scaled_font,
  301.                                               dev_clip);
  302.  
  303.     if (dev_clip != clip)
  304.         _cairo_clip_destroy (dev_clip);
  305.     free (dev_glyphs);
  306.  
  307.     return status;
  308. }
  309.