1 /* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
3 * Copyright © 2011 Intel Corporation
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.
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
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/
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.
28 * The Original Code is the cairo graphics library.
30 * The Initial Developer of the Original Code is Chris Wilson
33 * Chris Wilson <chris@chris-wilsonc.co.uk>
38 #include "cairo-error-private.h"
39 #include "cairo-tristrip-private.h"
42 _cairo_tristrip_init (cairo_tristrip_t
*strip
)
44 VG (VALGRIND_MAKE_MEM_UNDEFINED (strip
, sizeof (cairo_tristrip_t
)));
46 strip
->status
= CAIRO_STATUS_SUCCESS
;
48 strip
->num_limits
= 0;
49 strip
->num_points
= 0;
51 strip
->size_points
= ARRAY_LENGTH (strip
->points_embedded
);
52 strip
->points
= strip
->points_embedded
;
56 _cairo_tristrip_fini (cairo_tristrip_t
*strip
)
58 if (strip
->points
!= strip
->points_embedded
)
61 VG (VALGRIND_MAKE_MEM_NOACCESS (strip
, sizeof (cairo_tristrip_t
)));
66 _cairo_tristrip_limit (cairo_tristrip_t
*strip
,
67 const cairo_box_t
*limits
,
70 strip
->limits
= limits
;
71 strip
->num_limits
= num_limits
;
75 _cairo_tristrip_init_with_clip (cairo_tristrip_t
*strip
,
76 const cairo_clip_t
*clip
)
78 _cairo_tristrip_init (strip
);
80 _cairo_tristrip_limit (strip
, clip
->boxes
, clip
->num_boxes
);
83 /* make room for at least one more trap */
85 _cairo_tristrip_grow (cairo_tristrip_t
*strip
)
87 cairo_point_t
*points
;
88 int new_size
= 4 * strip
->size_points
;
90 if (CAIRO_INJECT_FAULT ()) {
91 strip
->status
= _cairo_error (CAIRO_STATUS_NO_MEMORY
);
95 if (strip
->points
== strip
->points_embedded
) {
96 points
= _cairo_malloc_ab (new_size
, sizeof (cairo_point_t
));
98 memcpy (points
, strip
->points
, sizeof (strip
->points_embedded
));
100 points
= _cairo_realloc_ab (strip
->points
,
101 new_size
, sizeof (cairo_trapezoid_t
));
104 if (unlikely (points
== NULL
)) {
105 strip
->status
= _cairo_error (CAIRO_STATUS_NO_MEMORY
);
109 strip
->points
= points
;
110 strip
->size_points
= new_size
;
115 _cairo_tristrip_add_point (cairo_tristrip_t
*strip
,
116 const cairo_point_t
*p
)
118 if (unlikely (strip
->num_points
== strip
->size_points
)) {
119 if (unlikely (! _cairo_tristrip_grow (strip
)))
123 strip
->points
[strip
->num_points
++] = *p
;
126 /* Insert degenerate triangles to advance to the given point. The
127 * next point inserted must also be @p. */
129 _cairo_tristrip_move_to (cairo_tristrip_t
*strip
,
130 const cairo_point_t
*p
)
132 if (strip
->num_points
== 0)
135 _cairo_tristrip_add_point (strip
, &strip
->points
[strip
->num_points
-1]);
136 _cairo_tristrip_add_point (strip
, p
);
138 /* and one more for luck! (to preserve cw/ccw ordering) */
139 _cairo_tristrip_add_point (strip
, p
);
144 _cairo_tristrip_translate (cairo_tristrip_t
*strip
, int x
, int y
)
146 cairo_fixed_t xoff
, yoff
;
150 xoff
= _cairo_fixed_from_int (x
);
151 yoff
= _cairo_fixed_from_int (y
);
153 for (i
= 0, p
= strip
->points
; i
< strip
->num_points
; i
++, p
++) {
160 _cairo_tristrip_extents (const cairo_tristrip_t
*strip
,
161 cairo_box_t
*extents
)
165 if (strip
->num_points
== 0) {
166 extents
->p1
.x
= extents
->p1
.y
= 0;
167 extents
->p2
.x
= extents
->p2
.y
= 0;
171 extents
->p2
= extents
->p1
= strip
->points
[0];
172 for (i
= 1; i
< strip
->num_points
; i
++) {
173 const cairo_point_t
*p
= &strip
->points
[i
];
175 if (p
->x
< extents
->p1
.x
)
176 extents
->p1
.x
= p
->x
;
177 else if (p
->x
> extents
->p2
.x
)
178 extents
->p2
.x
= p
->x
;
180 if (p
->y
< extents
->p1
.y
)
181 extents
->p1
.y
= p
->y
;
182 else if (p
->y
> extents
->p2
.y
)
183 extents
->p2
.y
= p
->y
;