Subversion Repositories Kolibri OS

Rev

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
}