Go to most recent revision | Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
4680 | right-hear | 1 | #include "fitz.h" |
2 | |||
3 | #define MAX4(a,b,c,d) MAX(MAX(a,b), MAX(c,d)) |
||
4 | #define MIN4(a,b,c,d) MIN(MIN(a,b), MIN(c,d)) |
||
5 | |||
6 | /* Matrices, points and affine transformations */ |
||
7 | |||
8 | const fz_matrix fz_identity = { 1, 0, 0, 1, 0, 0 }; |
||
9 | |||
10 | fz_matrix |
||
11 | fz_concat(fz_matrix one, fz_matrix two) |
||
12 | { |
||
13 | fz_matrix dst; |
||
14 | dst.a = one.a * two.a + one.b * two.c; |
||
15 | dst.b = one.a * two.b + one.b * two.d; |
||
16 | dst.c = one.c * two.a + one.d * two.c; |
||
17 | dst.d = one.c * two.b + one.d * two.d; |
||
18 | dst.e = one.e * two.a + one.f * two.c + two.e; |
||
19 | dst.f = one.e * two.b + one.f * two.d + two.f; |
||
20 | return dst; |
||
21 | } |
||
22 | |||
23 | fz_matrix |
||
24 | fz_scale(float sx, float sy) |
||
25 | { |
||
26 | fz_matrix m; |
||
27 | m.a = sx; m.b = 0; |
||
28 | m.c = 0; m.d = sy; |
||
29 | m.e = 0; m.f = 0; |
||
30 | return m; |
||
31 | } |
||
32 | |||
33 | fz_matrix |
||
34 | fz_shear(float h, float v) |
||
35 | { |
||
36 | fz_matrix m; |
||
37 | m.a = 1; m.b = v; |
||
38 | m.c = h; m.d = 1; |
||
39 | m.e = 0; m.f = 0; |
||
40 | return m; |
||
41 | } |
||
42 | |||
43 | fz_matrix |
||
44 | fz_rotate(float theta) |
||
45 | { |
||
46 | fz_matrix m; |
||
47 | float s; |
||
48 | float c; |
||
49 | |||
50 | while (theta < 0) |
||
51 | theta += 360; |
||
52 | while (theta >= 360) |
||
53 | theta -= 360; |
||
54 | |||
55 | if (fabsf(0 - theta) < FLT_EPSILON) |
||
56 | { |
||
57 | s = 0; |
||
58 | c = 1; |
||
59 | } |
||
60 | else if (fabsf(90.0f - theta) < FLT_EPSILON) |
||
61 | { |
||
62 | s = 1; |
||
63 | c = 0; |
||
64 | } |
||
65 | else if (fabsf(180.0f - theta) < FLT_EPSILON) |
||
66 | { |
||
67 | s = 0; |
||
68 | c = -1; |
||
69 | } |
||
70 | else if (fabsf(270.0f - theta) < FLT_EPSILON) |
||
71 | { |
||
72 | s = -1; |
||
73 | c = 0; |
||
74 | } |
||
75 | else |
||
76 | { |
||
77 | s = sinf(theta * (float)M_PI / 180); |
||
78 | c = cosf(theta * (float)M_PI / 180); |
||
79 | } |
||
80 | |||
81 | m.a = c; m.b = s; |
||
82 | m.c = -s; m.d = c; |
||
83 | m.e = 0; m.f = 0; |
||
84 | return m; |
||
85 | } |
||
86 | |||
87 | fz_matrix |
||
88 | fz_translate(float tx, float ty) |
||
89 | { |
||
90 | fz_matrix m; |
||
91 | m.a = 1; m.b = 0; |
||
92 | m.c = 0; m.d = 1; |
||
93 | m.e = tx; m.f = ty; |
||
94 | return m; |
||
95 | } |
||
96 | |||
97 | fz_matrix |
||
98 | fz_invert_matrix(fz_matrix src) |
||
99 | { |
||
100 | fz_matrix dst; |
||
101 | float rdet = 1 / (src.a * src.d - src.b * src.c); |
||
102 | dst.a = src.d * rdet; |
||
103 | dst.b = -src.b * rdet; |
||
104 | dst.c = -src.c * rdet; |
||
105 | dst.d = src.a * rdet; |
||
106 | dst.e = -src.e * dst.a - src.f * dst.c; |
||
107 | dst.f = -src.e * dst.b - src.f * dst.d; |
||
108 | return dst; |
||
109 | } |
||
110 | |||
111 | int |
||
112 | fz_is_rectilinear(fz_matrix m) |
||
113 | { |
||
114 | return (fabsf(m.b) < FLT_EPSILON && fabsf(m.c) < FLT_EPSILON) || |
||
115 | (fabsf(m.a) < FLT_EPSILON && fabsf(m.d) < FLT_EPSILON); |
||
116 | } |
||
117 | |||
118 | float |
||
119 | fz_matrix_expansion(fz_matrix m) |
||
120 | { |
||
121 | return sqrtf(fabsf(m.a * m.d - m.b * m.c)); |
||
122 | } |
||
123 | |||
124 | fz_point |
||
125 | fz_transform_point(fz_matrix m, fz_point p) |
||
126 | { |
||
127 | fz_point t; |
||
128 | t.x = p.x * m.a + p.y * m.c + m.e; |
||
129 | t.y = p.x * m.b + p.y * m.d + m.f; |
||
130 | return t; |
||
131 | } |
||
132 | |||
133 | fz_point |
||
134 | fz_transform_vector(fz_matrix m, fz_point p) |
||
135 | { |
||
136 | fz_point t; |
||
137 | t.x = p.x * m.a + p.y * m.c; |
||
138 | t.y = p.x * m.b + p.y * m.d; |
||
139 | return t; |
||
140 | } |
||
141 | |||
142 | /* Rectangles and bounding boxes */ |
||
143 | |||
144 | const fz_rect fz_infinite_rect = { 1, 1, -1, -1 }; |
||
145 | const fz_rect fz_empty_rect = { 0, 0, 0, 0 }; |
||
146 | const fz_rect fz_unit_rect = { 0, 0, 1, 1 }; |
||
147 | |||
148 | const fz_bbox fz_infinite_bbox = { 1, 1, -1, -1 }; |
||
149 | const fz_bbox fz_empty_bbox = { 0, 0, 0, 0 }; |
||
150 | const fz_bbox fz_unit_bbox = { 0, 0, 1, 1 }; |
||
151 | |||
152 | fz_bbox |
||
153 | fz_round_rect(fz_rect f) |
||
154 | { |
||
155 | fz_bbox i; |
||
156 | i.x0 = floorf(f.x0 + 0.001f); /* adjust by 0.001 to compensate for precision errors */ |
||
157 | i.y0 = floorf(f.y0 + 0.001f); |
||
158 | i.x1 = ceilf(f.x1 - 0.001f); |
||
159 | i.y1 = ceilf(f.y1 - 0.001f); |
||
160 | return i; |
||
161 | } |
||
162 | |||
163 | fz_rect |
||
164 | fz_intersect_rect(fz_rect a, fz_rect b) |
||
165 | { |
||
166 | fz_rect r; |
||
167 | if (fz_is_infinite_rect(a)) return b; |
||
168 | if (fz_is_infinite_rect(b)) return a; |
||
169 | if (fz_is_empty_rect(a)) return fz_empty_rect; |
||
170 | if (fz_is_empty_rect(b)) return fz_empty_rect; |
||
171 | r.x0 = MAX(a.x0, b.x0); |
||
172 | r.y0 = MAX(a.y0, b.y0); |
||
173 | r.x1 = MIN(a.x1, b.x1); |
||
174 | r.y1 = MIN(a.y1, b.y1); |
||
175 | return (r.x1 < r.x0 || r.y1 < r.y0) ? fz_empty_rect : r; |
||
176 | } |
||
177 | |||
178 | fz_rect |
||
179 | fz_union_rect(fz_rect a, fz_rect b) |
||
180 | { |
||
181 | fz_rect r; |
||
182 | if (fz_is_infinite_rect(a)) return a; |
||
183 | if (fz_is_infinite_rect(b)) return b; |
||
184 | if (fz_is_empty_rect(a)) return b; |
||
185 | if (fz_is_empty_rect(b)) return a; |
||
186 | r.x0 = MIN(a.x0, b.x0); |
||
187 | r.y0 = MIN(a.y0, b.y0); |
||
188 | r.x1 = MAX(a.x1, b.x1); |
||
189 | r.y1 = MAX(a.y1, b.y1); |
||
190 | return r; |
||
191 | } |
||
192 | |||
193 | fz_bbox |
||
194 | fz_intersect_bbox(fz_bbox a, fz_bbox b) |
||
195 | { |
||
196 | fz_bbox r; |
||
197 | if (fz_is_infinite_rect(a)) return b; |
||
198 | if (fz_is_infinite_rect(b)) return a; |
||
199 | if (fz_is_empty_rect(a)) return fz_empty_bbox; |
||
200 | if (fz_is_empty_rect(b)) return fz_empty_bbox; |
||
201 | r.x0 = MAX(a.x0, b.x0); |
||
202 | r.y0 = MAX(a.y0, b.y0); |
||
203 | r.x1 = MIN(a.x1, b.x1); |
||
204 | r.y1 = MIN(a.y1, b.y1); |
||
205 | return (r.x1 < r.x0 || r.y1 < r.y0) ? fz_empty_bbox : r; |
||
206 | } |
||
207 | |||
208 | fz_bbox |
||
209 | fz_union_bbox(fz_bbox a, fz_bbox b) |
||
210 | { |
||
211 | fz_bbox r; |
||
212 | if (fz_is_infinite_rect(a)) return a; |
||
213 | if (fz_is_infinite_rect(b)) return b; |
||
214 | if (fz_is_empty_rect(a)) return b; |
||
215 | if (fz_is_empty_rect(b)) return a; |
||
216 | r.x0 = MIN(a.x0, b.x0); |
||
217 | r.y0 = MIN(a.y0, b.y0); |
||
218 | r.x1 = MAX(a.x1, b.x1); |
||
219 | r.y1 = MAX(a.y1, b.y1); |
||
220 | return r; |
||
221 | } |
||
222 | |||
223 | fz_rect |
||
224 | fz_transform_rect(fz_matrix m, fz_rect r) |
||
225 | { |
||
226 | fz_point s, t, u, v; |
||
227 | |||
228 | if (fz_is_infinite_rect(r)) |
||
229 | return r; |
||
230 | |||
231 | s.x = r.x0; s.y = r.y0; |
||
232 | t.x = r.x0; t.y = r.y1; |
||
233 | u.x = r.x1; u.y = r.y1; |
||
234 | v.x = r.x1; v.y = r.y0; |
||
235 | s = fz_transform_point(m, s); |
||
236 | t = fz_transform_point(m, t); |
||
237 | u = fz_transform_point(m, u); |
||
238 | v = fz_transform_point(m, v); |
||
239 | r.x0 = MIN4(s.x, t.x, u.x, v.x); |
||
240 | r.y0 = MIN4(s.y, t.y, u.y, v.y); |
||
241 | r.x1 = MAX4(s.x, t.x, u.x, v.x); |
||
242 | r.y1 = MAX4(s.y, t.y, u.y, v.y); |
||
243 | return r; |
||
244 | } |
||
245 | |||
246 | fz_bbox |
||
247 | fz_transform_bbox(fz_matrix m, fz_bbox b) |
||
248 | { |
||
249 | fz_point s, t, u, v; |
||
250 | |||
251 | if (fz_is_infinite_bbox(b)) |
||
252 | return b; |
||
253 | |||
254 | s.x = b.x0; s.y = b.y0; |
||
255 | t.x = b.x0; t.y = b.y1; |
||
256 | u.x = b.x1; u.y = b.y1; |
||
257 | v.x = b.x1; v.y = b.y0; |
||
258 | s = fz_transform_point(m, s); |
||
259 | t = fz_transform_point(m, t); |
||
260 | u = fz_transform_point(m, u); |
||
261 | v = fz_transform_point(m, v); |
||
262 | b.x0 = MIN4(s.x, t.x, u.x, v.x); |
||
263 | b.y0 = MIN4(s.y, t.y, u.y, v.y); |
||
264 | b.x1 = MAX4(s.x, t.x, u.x, v.x); |
||
265 | b.y1 = MAX4(s.y, t.y, u.y, v.y); |
||
266 | return b; |
||
267 | |||
268 | }>>>>>>>>>>>>> |