GCC Code Coverage Report


Directory: ./
File: src/2geom/rect.cpp
Date: 2024-03-18 17:01:34
Exec Total Coverage
Lines: 21 96 21.9%
Functions: 2 7 28.6%
Branches: 11 52 21.2%

Line Branch Exec Source
1 /* Axis-aligned rectangle
2 *
3 * Authors:
4 * Michael Sloan <mgsloan@gmail.com>
5 * Krzysztof KosiƄski <tweenk.pl@gmail.com>
6 * Copyright 2007-2011 Authors
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it either under the terms of the GNU Lesser General Public
10 * License version 2.1 as published by the Free Software Foundation
11 * (the "LGPL") or, at your option, under the terms of the Mozilla
12 * Public License Version 1.1 (the "MPL"). If you do not alter this
13 * notice, a recipient may use your version of this file under either
14 * the MPL or the LGPL.
15 *
16 * You should have received a copy of the LGPL along with this library
17 * in the file COPYING-LGPL-2.1; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 * You should have received a copy of the MPL along with this library
20 * in the file COPYING-MPL-1.1
21 *
22 * The contents of this file are subject to the Mozilla Public License
23 * Version 1.1 (the "License"); you may not use this file except in
24 * compliance with the License. You may obtain a copy of the License at
25 * http://www.mozilla.org/MPL/
26 *
27 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
28 * OF ANY KIND, either express or implied. See the LGPL or the MPL for
29 * the specific language governing rights and limitations.
30 */
31
32 #include <2geom/rect.h>
33 #include <2geom/transforms.h>
34
35 namespace Geom {
36
37 Point align_factors(Align g) {
38 Point p;
39 switch (g) {
40 case ALIGN_XMIN_YMIN:
41 p[X] = 0.0;
42 p[Y] = 0.0;
43 break;
44 case ALIGN_XMID_YMIN:
45 p[X] = 0.5;
46 p[Y] = 0.0;
47 break;
48 case ALIGN_XMAX_YMIN:
49 p[X] = 1.0;
50 p[Y] = 0.0;
51 break;
52 case ALIGN_XMIN_YMID:
53 p[X] = 0.0;
54 p[Y] = 0.5;
55 break;
56 case ALIGN_XMID_YMID:
57 p[X] = 0.5;
58 p[Y] = 0.5;
59 break;
60 case ALIGN_XMAX_YMID:
61 p[X] = 1.0;
62 p[Y] = 0.5;
63 break;
64 case ALIGN_XMIN_YMAX:
65 p[X] = 0.0;
66 p[Y] = 1.0;
67 break;
68 case ALIGN_XMID_YMAX:
69 p[X] = 0.5;
70 p[Y] = 1.0;
71 break;
72 case ALIGN_XMAX_YMAX:
73 p[X] = 1.0;
74 p[Y] = 1.0;
75 break;
76 default:
77 break;
78 }
79 return p;
80 }
81
82
83 /** @brief Transform the rectangle by an affine.
84 * The result of the transformation might not be axis-aligned. The return value
85 * of this operation will be the smallest axis-aligned rectangle containing
86 * all points of the true result. */
87 100 Rect &Rect::operator*=(Affine const &m) {
88 100 Point pts[4];
89
3/4
✓ Branch 3 taken 400 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 400 times.
✓ Branch 7 taken 100 times.
500 for (unsigned i=0; i<4; ++i) pts[i] = corner(i) * m;
90 100 Coord minx = std::min(std::min(pts[0][X], pts[1][X]), std::min(pts[2][X], pts[3][X]));
91 100 Coord miny = std::min(std::min(pts[0][Y], pts[1][Y]), std::min(pts[2][Y], pts[3][Y]));
92 100 Coord maxx = std::max(std::max(pts[0][X], pts[1][X]), std::max(pts[2][X], pts[3][X]));
93 100 Coord maxy = std::max(std::max(pts[0][Y], pts[1][Y]), std::max(pts[2][Y], pts[3][Y]));
94 100 f[X].setMin(minx); f[X].setMax(maxx);
95 100 f[Y].setMin(miny); f[Y].setMax(maxy);
96 100 return *this;
97 }
98
99 Affine Rect::transformTo(Rect const &viewport, Aspect const &aspect) const
100 {
101 // 1. translate viewbox to origin
102 Geom::Affine total = Translate(-min());
103
104 // 2. compute scale
105 Geom::Point vdims = viewport.dimensions();
106 Geom::Point dims = dimensions();
107 Geom::Scale scale(vdims[X] / dims[X], vdims[Y] / dims[Y]);
108
109 if (aspect.align == ALIGN_NONE) {
110 // apply non-uniform scale
111 total *= scale * Translate(viewport.min());
112 } else {
113 double uscale = 0;
114 if (aspect.expansion == EXPANSION_MEET) {
115 uscale = std::min(scale[X], scale[Y]);
116 } else {
117 uscale = std::max(scale[X], scale[Y]);
118 }
119 scale = Scale(uscale);
120
121 // compute offset for align
122 Geom::Point offset = vdims - dims * scale;
123 offset *= Scale(align_factors(aspect.align));
124 total *= scale * Translate(viewport.min() + offset);
125 }
126
127 return total;
128 }
129
130 Coord distanceSq(Point const &p, Rect const &rect)
131 {
132 double dx = 0, dy = 0;
133 if ( p[X] < rect.left() ) {
134 dx = p[X] - rect.left();
135 } else if ( p[X] > rect.right() ) {
136 dx = rect.right() - p[X];
137 }
138 if (p[Y] < rect.top() ) {
139 dy = rect.top() - p[Y];
140 } else if ( p[Y] > rect.bottom() ) {
141 dy = p[Y] - rect.bottom();
142 }
143 return dx*dx+dy*dy;
144 }
145
146 /** @brief Returns the smallest distance between p and rect.
147 * @relates Rect */
148 26 Coord distance(Point const &p, Rect const &rect)
149 {
150 // copy of distanceSq, because we need to use hypot()
151 26 double dx = 0, dy = 0;
152
2/2
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 23 times.
26 if ( p[X] < rect.left() ) {
153 3 dx = p[X] - rect.left();
154
2/2
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 13 times.
23 } else if ( p[X] > rect.right() ) {
155 10 dx = rect.right() - p[X];
156 }
157
2/2
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 24 times.
26 if (p[Y] < rect.top() ) {
158 2 dy = rect.top() - p[Y];
159
2/2
✓ Branch 2 taken 9 times.
✓ Branch 3 taken 15 times.
24 } else if ( p[Y] > rect.bottom() ) {
160 9 dy = p[Y] - rect.bottom();
161 }
162 26 return hypot(dx, dy);
163 }
164
165 Coord distanceSq(Point const &p, OptRect const &rect)
166 {
167 if (!rect) return std::numeric_limits<Coord>::max();
168 return distanceSq(p, *rect);
169 }
170 Coord distance(Point const &p, OptRect const &rect)
171 {
172 if (!rect) return std::numeric_limits<Coord>::max();
173 return distance(p, *rect);
174 }
175
176 } // namespace Geom
177
178 /*
179 Local Variables:
180 mode:c++
181 c-file-style:"stroustrup"
182 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
183 indent-tabs-mode:nil
184 fill-column:99
185 End:
186 */
187 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
188