1 /* CPML - Cairo Path Manipulation Library
2 * Copyright (C) 2008, 2009 Nicola Fontana <ntd at entidi.it>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
22 * SECTION:cpml-extents
23 * @Section_Id:CpmlExtents
25 * @short_description: A rectangular area representing a bounding box
27 * The #CpmlExtents struct groups two pairs representing the rectangular
28 * area of a bounding box.
33 * @is_defined: set to %0 when these extents are undefined
34 * @org: the lowest x,y coordinates
35 * @size: the width (x) and height (y) of the extents
37 * A structure defining a bounding box area. These APIs expect the
38 * size of the extents to be always positives, so be careful while
39 * directly accessing the @size field.
43 #include "cpml-extents.h"
52 * @extents: the destination #CpmlExtents
53 * @src: the source #CpmlExtents
55 * Copies @src in @extents.
57 * Return value: @extents
60 cpml_extents_copy(CpmlExtents
*extents
, const CpmlExtents
*src
)
62 return memcpy(extents
, src
, sizeof(CpmlExtents
));
66 * cpml_extents_from_cairo_text:
67 * @extents: the destination #CpmlExtents
68 * @cairo_extents: the source cairo_text_extents_t struct
70 * Converts @cairo_extents in a #CpmlExtents format and stores the
76 cpml_extents_from_cairo_text(CpmlExtents
*extents
,
77 const cairo_text_extents_t
*cairo_extents
)
79 extents
->is_defined
= 1;
80 extents
->org
.x
= cairo_extents
->x_bearing
;
81 extents
->org
.y
= cairo_extents
->y_bearing
;
82 extents
->size
.x
= cairo_extents
->width
;
83 extents
->size
.y
= cairo_extents
->height
;
90 * @extents: the destination #CpmlExtents
91 * @src: the extents to add
93 * Merges @extents and @src and store the result in @extents.
96 cpml_extents_add(CpmlExtents
*extents
, const CpmlExtents
*src
)
100 if (src
->is_defined
== 0)
103 cpml_pair_copy(&pair
, &src
->org
);
104 cpml_extents_pair_add(extents
, &pair
);
106 cpml_pair_add(&pair
, &src
->size
);
107 cpml_extents_pair_add(extents
, &pair
);
111 * cpml_extents_pair_add:
112 * @extents: the destination #CpmlExtents
113 * @src: the #AdgPair to add
115 * Extends @extents, if required, to include @src. If @extents is
116 * undefined, the origin of @extents is set to @src and its size
120 cpml_extents_pair_add(CpmlExtents
*extents
, const CpmlPair
*src
)
122 if (extents
->is_defined
== 0) {
123 extents
->is_defined
= 1;
124 cpml_pair_copy(&extents
->org
, src
);
130 if (src
->x
< extents
->org
.x
) {
131 extents
->size
.x
+= extents
->org
.x
- src
->x
;
132 extents
->org
.x
= src
->x
;
133 } else if (src
->x
> extents
->org
.x
+ extents
->size
.x
) {
134 extents
->size
.x
= src
->x
- extents
->org
.x
;
137 if (src
->y
< extents
->org
.y
) {
138 extents
->size
.y
+= extents
->org
.y
- src
->y
;
139 extents
->org
.y
= src
->y
;
140 } else if (src
->y
> extents
->org
.y
+ extents
->size
.y
) {
141 extents
->size
.y
= src
->y
- extents
->org
.y
;
146 * cpml_extents_is_inside:
147 * @extents: the container #CpmlExtents
148 * @src: the subject #CpmlExtents
150 * Checks wheter @src is enterely contained by @extents. If @extents
151 * is undefined, %0 will be returned. If @src is undefined, %1 will
152 * be returned. The border of @extents is considered inside.
154 * Returns: %1 if @src is totally inside @extents, %0 otherwise
157 cpml_extents_is_inside(const CpmlExtents
*extents
, const CpmlExtents
*src
)
161 if (extents
->is_defined
== 0)
164 if (src
->is_defined
== 0)
167 cpml_pair_copy(&pe
, &extents
->org
);
168 cpml_pair_copy(&ps
, &src
->org
);
170 if (ps
.x
< pe
.x
|| ps
.y
< pe
.y
)
173 cpml_pair_add(&pe
, &extents
->size
);
174 cpml_pair_add(&ps
, &src
->size
);
176 if (ps
.x
> pe
.x
|| ps
.y
> pe
.y
)
183 * cpml_extents_pair_is_inside:
184 * @extents: the container #CpmlExtents
185 * @src: the subject #CpmlPair
187 * Checks wheter @src is inside @extents. If @extents is undefined,
188 * %0 will be returned. The border of @extents is considered inside.
190 * Returns: %1 if @src is inside @extents, %0 otherwise
193 cpml_extents_pair_is_inside(const CpmlExtents
*extents
, const CpmlPair
*src
)
195 if (extents
->is_defined
== 0)
198 if (src
->x
< extents
->org
.x
|| src
->y
< extents
->org
.y
||
199 src
->x
> extents
->org
.x
+ extents
->size
.x
||
200 src
->y
> extents
->org
.y
+ extents
->size
.y
)
207 * cpml_extents_transform:
208 * @extents: the container #CpmlExtents
209 * @matrix: the transformation matrix
211 * Shortcut to apply a specific transformation matrix to @extents.
212 * It basically convert the <structfield>org</structfield> field
213 * with cairo_matrix_transform_point() and <structfield>size</structfield>
214 * with cairo_matrix_transform_distance().
217 cpml_extents_transform(CpmlExtents
*extents
, const cairo_matrix_t
*matrix
)
219 if (extents
->is_defined
== 0)
222 cairo_matrix_transform_point(matrix
, &extents
->org
.x
, &extents
->org
.y
);
223 cairo_matrix_transform_distance(matrix
, &extents
->size
.x
, &extents
->size
.y
);