LCOV - code coverage report
Current view: top level - gfx/cairo/cairo/src - cairo-boxes.c (source / functions) Hit Total Coverage
Test: output.info Lines: 0 148 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 8 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 © 2009 Intel Corporation
       4             :  *
       5             :  * This library is free software; you can redistribute it and/or
       6             :  * modify it either under the terms of the GNU Lesser General Public
       7             :  * License version 2.1 as published by the Free Software Foundation
       8             :  * (the "LGPL") or, at your option, under the terms of the Mozilla
       9             :  * Public License Version 1.1 (the "MPL"). If you do not alter this
      10             :  * notice, a recipient may use your version of this file under either
      11             :  * the MPL or the LGPL.
      12             :  *
      13             :  * You should have received a copy of the LGPL along with this library
      14             :  * in the file COPYING-LGPL-2.1; if not, write to the Free Software
      15             :  * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
      16             :  * You should have received a copy of the MPL along with this library
      17             :  * in the file COPYING-MPL-1.1
      18             :  *
      19             :  * The contents of this file are subject to the Mozilla Public License
      20             :  * Version 1.1 (the "License"); you may not use this file except in
      21             :  * compliance with the License. You may obtain a copy of the License at
      22             :  * http://www.mozilla.org/MPL/
      23             :  *
      24             :  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
      25             :  * OF ANY KIND, either express or implied. See the LGPL or the MPL for
      26             :  * the specific language governing rights and limitations.
      27             :  *
      28             :  * The Original Code is the cairo graphics library.
      29             :  *
      30             :  * Contributor(s):
      31             :  *      Chris Wilson <chris@chris-wilson.co.uk>
      32             :  */
      33             : 
      34             : #include "cairoint.h"
      35             : 
      36             : #include "cairo-boxes-private.h"
      37             : #include "cairo-error-private.h"
      38             : 
      39             : void
      40           0 : _cairo_boxes_init (cairo_boxes_t *boxes)
      41             : {
      42           0 :     boxes->status = CAIRO_STATUS_SUCCESS;
      43           0 :     boxes->num_limits = 0;
      44           0 :     boxes->num_boxes = 0;
      45             : 
      46           0 :     boxes->tail = &boxes->chunks;
      47           0 :     boxes->chunks.next = NULL;
      48           0 :     boxes->chunks.base = boxes->boxes_embedded;
      49           0 :     boxes->chunks.size = ARRAY_LENGTH (boxes->boxes_embedded);
      50           0 :     boxes->chunks.count = 0;
      51             : 
      52           0 :     boxes->is_pixel_aligned = TRUE;
      53           0 : }
      54             : 
      55             : void
      56           0 : _cairo_boxes_init_for_array (cairo_boxes_t *boxes,
      57             :                              cairo_box_t *array,
      58             :                              int num_boxes)
      59             : {
      60             :     int n;
      61             : 
      62           0 :     boxes->status = CAIRO_STATUS_SUCCESS;
      63           0 :     boxes->num_limits = 0;
      64           0 :     boxes->num_boxes = num_boxes;
      65             : 
      66           0 :     boxes->tail = &boxes->chunks;
      67           0 :     boxes->chunks.next = NULL;
      68           0 :     boxes->chunks.base = array;
      69           0 :     boxes->chunks.size = num_boxes;
      70           0 :     boxes->chunks.count = num_boxes;
      71             : 
      72           0 :     for (n = 0; n < num_boxes; n++) {
      73           0 :         if (! _cairo_fixed_is_integer (array[n].p1.x) ||
      74           0 :             ! _cairo_fixed_is_integer (array[n].p1.y) ||
      75           0 :             ! _cairo_fixed_is_integer (array[n].p2.x) ||
      76           0 :             ! _cairo_fixed_is_integer (array[n].p2.y))
      77             :         {
      78             :             break;
      79             :         }
      80             :     }
      81             : 
      82           0 :     boxes->is_pixel_aligned = n == num_boxes;
      83           0 : }
      84             : 
      85             : void
      86           0 : _cairo_boxes_limit (cairo_boxes_t       *boxes,
      87             :                     const cairo_box_t   *limits,
      88             :                     int                  num_limits)
      89             : {
      90             :     int n;
      91             : 
      92           0 :     boxes->limits = limits;
      93           0 :     boxes->num_limits = num_limits;
      94             : 
      95           0 :     if (boxes->num_limits) {
      96           0 :         boxes->limit = limits[0];
      97           0 :         for (n = 1; n < num_limits; n++) {
      98           0 :             if (limits[n].p1.x < boxes->limit.p1.x)
      99           0 :                 boxes->limit.p1.x = limits[n].p1.x;
     100             : 
     101           0 :             if (limits[n].p1.y < boxes->limit.p1.y)
     102           0 :                 boxes->limit.p1.y = limits[n].p1.y;
     103             : 
     104           0 :             if (limits[n].p2.x > boxes->limit.p2.x)
     105           0 :                 boxes->limit.p2.x = limits[n].p2.x;
     106             : 
     107           0 :             if (limits[n].p2.y > boxes->limit.p2.y)
     108           0 :                 boxes->limit.p2.y = limits[n].p2.y;
     109             :         }
     110             :     }
     111           0 : }
     112             : 
     113             : static void
     114           0 : _cairo_boxes_add_internal (cairo_boxes_t *boxes,
     115             :                            const cairo_box_t *box)
     116             : {
     117             :     struct _cairo_boxes_chunk *chunk;
     118             : 
     119           0 :     if (unlikely (boxes->status))
     120           0 :         return;
     121             : 
     122           0 :     chunk = boxes->tail;
     123           0 :     if (unlikely (chunk->count == chunk->size)) {
     124             :         int size;
     125             : 
     126           0 :         size = chunk->size * 2;
     127           0 :         chunk->next = _cairo_malloc_ab_plus_c (size,
     128             :                                                sizeof (cairo_box_t),
     129             :                                                sizeof (struct _cairo_boxes_chunk));
     130             : 
     131           0 :         if (unlikely (chunk->next == NULL)) {
     132           0 :             boxes->status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
     133           0 :             return;
     134             :         }
     135             : 
     136           0 :         chunk = chunk->next;
     137           0 :         boxes->tail = chunk;
     138             : 
     139           0 :         chunk->next = NULL;
     140           0 :         chunk->count = 0;
     141           0 :         chunk->size = size;
     142           0 :         chunk->base = (cairo_box_t *) (chunk + 1);
     143             :     }
     144             : 
     145           0 :     chunk->base[chunk->count++] = *box;
     146           0 :     boxes->num_boxes++;
     147             : 
     148           0 :     if (boxes->is_pixel_aligned) {
     149           0 :         boxes->is_pixel_aligned =
     150           0 :             _cairo_fixed_is_integer (box->p1.x) &&
     151           0 :             _cairo_fixed_is_integer (box->p1.y) &&
     152           0 :             _cairo_fixed_is_integer (box->p2.x) &&
     153           0 :             _cairo_fixed_is_integer (box->p2.y);
     154             :     }
     155             : }
     156             : 
     157             : cairo_status_t
     158           0 : _cairo_boxes_add (cairo_boxes_t *boxes,
     159             :                   const cairo_box_t *box)
     160             : {
     161           0 :     if (box->p1.y == box->p2.y)
     162           0 :         return CAIRO_STATUS_SUCCESS;
     163             : 
     164           0 :     if (box->p1.x == box->p2.x)
     165           0 :         return CAIRO_STATUS_SUCCESS;
     166             : 
     167           0 :     if (boxes->num_limits) {
     168             :         cairo_point_t p1, p2;
     169           0 :         cairo_bool_t reversed = FALSE;
     170             :         int n;
     171             : 
     172             :         /* support counter-clockwise winding for rectangular tessellation */
     173           0 :         if (box->p1.x < box->p2.x) {
     174           0 :             p1.x = box->p1.x;
     175           0 :             p2.x = box->p2.x;
     176             :         } else {
     177           0 :             p2.x = box->p1.x;
     178           0 :             p1.x = box->p2.x;
     179           0 :             reversed = ! reversed;
     180             :         }
     181             : 
     182           0 :         if (p1.x >= boxes->limit.p2.x || p2.x <= boxes->limit.p1.x)
     183           0 :             return CAIRO_STATUS_SUCCESS;
     184             : 
     185           0 :         if (box->p1.y < box->p2.y) {
     186           0 :             p1.y = box->p1.y;
     187           0 :             p2.y = box->p2.y;
     188             :         } else {
     189           0 :             p2.y = box->p1.y;
     190           0 :             p1.y = box->p2.y;
     191           0 :             reversed = ! reversed;
     192             :         }
     193             : 
     194           0 :         if (p1.y >= boxes->limit.p2.y || p2.y <= boxes->limit.p1.y)
     195           0 :             return CAIRO_STATUS_SUCCESS;
     196             : 
     197           0 :         for (n = 0; n < boxes->num_limits; n++) {
     198           0 :             const cairo_box_t *limits = &boxes->limits[n];
     199             :             cairo_box_t _box;
     200             :             cairo_point_t _p1, _p2;
     201             : 
     202           0 :             if (p1.x >= limits->p2.x || p2.x <= limits->p1.x)
     203           0 :                 continue;
     204           0 :             if (p1.y >= limits->p2.y || p2.y <= limits->p1.y)
     205           0 :                 continue;
     206             : 
     207             :             /* Otherwise, clip the box to the limits. */
     208           0 :             _p1 = p1;
     209           0 :             if (_p1.x < limits->p1.x)
     210           0 :                 _p1.x = limits->p1.x;
     211           0 :             if (_p1.y < limits->p1.y)
     212           0 :                 _p1.y = limits->p1.y;
     213             : 
     214           0 :             _p2 = p2;
     215           0 :             if (_p2.x > limits->p2.x)
     216           0 :                 _p2.x = limits->p2.x;
     217           0 :             if (_p2.y > limits->p2.y)
     218           0 :                 _p2.y = limits->p2.y;
     219             : 
     220           0 :             if (_p2.y <= _p1.y || _p2.x <= _p1.x)
     221           0 :                 continue;
     222             : 
     223           0 :             _box.p1.y = _p1.y;
     224           0 :             _box.p2.y = _p2.y;
     225           0 :             if (reversed) {
     226           0 :                 _box.p1.x = _p2.x;
     227           0 :                 _box.p2.x = _p1.x;
     228             :             } else {
     229           0 :                 _box.p1.x = _p1.x;
     230           0 :                 _box.p2.x = _p2.x;
     231             :             }
     232             : 
     233           0 :             _cairo_boxes_add_internal (boxes, &_box);
     234             :         }
     235             :     } else {
     236           0 :         _cairo_boxes_add_internal (boxes, box);
     237             :     }
     238             : 
     239           0 :     return boxes->status;
     240             : }
     241             : 
     242             : void
     243           0 : _cairo_boxes_extents (const cairo_boxes_t *boxes,
     244             :                       cairo_rectangle_int_t *extents)
     245             : {
     246             :     const struct _cairo_boxes_chunk *chunk;
     247             :     cairo_box_t box;
     248             :     int i;
     249             : 
     250           0 :     box.p1.y = box.p1.x = INT_MAX;
     251           0 :     box.p2.y = box.p2.x = INT_MIN;
     252             : 
     253           0 :     for (chunk = &boxes->chunks; chunk != NULL; chunk = chunk->next) {
     254           0 :         const cairo_box_t *b = chunk->base;
     255           0 :         for (i = 0; i < chunk->count; i++) {
     256           0 :             if (b[i].p1.x < box.p1.x)
     257           0 :                 box.p1.x = b[i].p1.x;
     258             : 
     259           0 :             if (b[i].p1.y < box.p1.y)
     260           0 :                 box.p1.y = b[i].p1.y;
     261             : 
     262           0 :             if (b[i].p2.x > box.p2.x)
     263           0 :                 box.p2.x = b[i].p2.x;
     264             : 
     265           0 :             if (b[i].p2.y > box.p2.y)
     266           0 :                 box.p2.y = b[i].p2.y;
     267             :         }
     268             :     }
     269             : 
     270           0 :     _cairo_box_round_to_rectangle (&box, extents);
     271           0 : }
     272             : 
     273             : void
     274           0 : _cairo_boxes_clear (cairo_boxes_t *boxes)
     275             : {
     276             :     struct _cairo_boxes_chunk *chunk, *next;
     277             : 
     278           0 :     for (chunk = boxes->chunks.next; chunk != NULL; chunk = next) {
     279           0 :         next = chunk->next;
     280           0 :         free (chunk);
     281             :     }
     282             : 
     283           0 :     boxes->tail = &boxes->chunks;
     284           0 :     boxes->chunks.next = 0;
     285           0 :     boxes->chunks.count = 0;
     286           0 :     boxes->num_boxes = 0;
     287             : 
     288           0 :     boxes->is_pixel_aligned = TRUE;
     289           0 : }
     290             : 
     291             : void
     292           0 : _cairo_boxes_fini (cairo_boxes_t *boxes)
     293             : {
     294             :     struct _cairo_boxes_chunk *chunk, *next;
     295             : 
     296           0 :     for (chunk = boxes->chunks.next; chunk != NULL; chunk = next) {
     297           0 :         next = chunk->next;
     298           0 :         free (chunk);
     299             :     }
     300           0 : }

Generated by: LCOV version 1.13