qdistancefield.cpp

Absolute File Name:/home/qt/qt5_coco/qt5/qtbase/src/gui/text/qdistancefield.cpp
Switch to Source codePreprocessed file
LineSourceCount
1-
2-
3-
4namespace-
5{-
6 enum FillHDir-
7 {-
8 LeftToRight,-
9 RightToLeft-
10 };-
11-
12 enum FillVDir-
13 {-
14 TopDown,-
15 BottomUp-
16 };-
17-
18 enum FillClip-
19 {-
20 NoClip,-
21 Clip-
22 };-
23}-
24-
25template <FillClip clip, FillHDir dir>-
26inline void fillLine(qint32 *, int, int, int, qint32, qint32)-
27{-
28}-
29-
30template <>-
31inline void fillLine<Clip, LeftToRight>(qint32 *line, int width, int lx, int rx, qint32 d, qint32 dd)-
32{-
33 int fromX = qMax(0, lx >> 8);-
34 int toX = qMin(width, rx >> 8);-
35 int x = toX - fromX;-
36 if (x <= 0)-
37 return;-
38 qint32 val = d + (((fromX << 8) + 0xff - lx) * dd >> 8);-
39 line += fromX;-
40 do {-
41 *line = abs(val) < abs(*line) ? val : *line;-
42 val += dd;-
43 ++line;-
44 } while (--x);-
45}-
46-
47template <>-
48inline void fillLine<Clip, RightToLeft>(qint32 *line, int width, int lx, int rx, qint32 d, qint32 dd)-
49{-
50 int fromX = qMax(0, lx >> 8);-
51 int toX = qMin(width, rx >> 8);-
52 int x = toX - fromX;-
53 if (x <= 0)-
54 return;-
55 qint32 val = d + (((toX << 8) + 0xff - rx) * dd >> 8);-
56 line += toX;-
57 do {-
58 val -= dd;-
59 --line;-
60 *line = abs(val) < abs(*line) ? val : *line;-
61 } while (--x);-
62}-
63-
64template <>-
65inline void fillLine<NoClip, LeftToRight>(qint32 *line, int, int lx, int rx, qint32 d, qint32 dd)-
66{-
67 int fromX = lx >> 8;-
68 int toX = rx >> 8;-
69 int x = toX - fromX;-
70 if (x <= 0)-
71 return;-
72 qint32 val = d + ((~lx & 0xff) * dd >> 8);-
73 line += fromX;-
74 do {-
75 *line = abs(val) < abs(*line) ? val : *line;-
76 val += dd;-
77 ++line;-
78 } while (--x);-
79}-
80-
81template <>-
82inline void fillLine<NoClip, RightToLeft>(qint32 *line, int, int lx, int rx, qint32 d, qint32 dd)-
83{-
84 int fromX = lx >> 8;-
85 int toX = rx >> 8;-
86 int x = toX - fromX;-
87 if (x <= 0)-
88 return;-
89 qint32 val = d + ((~rx & 0xff) * dd >> 8);-
90 line += toX;-
91 do {-
92 val -= dd;-
93 --line;-
94 *line = abs(val) < abs(*line) ? val : *line;-
95 } while (--x);-
96}-
97-
98template <FillClip clip, FillVDir vDir, FillHDir hDir>-
99inline void fillLines(qint32 *bits, int width, int height, int upperY, int lowerY,-
100 int &lx, int ldx, int &rx, int rdx, qint32 &d, qint32 ddy, qint32 ddx)-
101{-
102 (void)height;;-
103 ((!(upperY < lowerY)) ? qt_assert("upperY < lowerY",__FILE__,141147) : qt_noop());-
104 int y = lowerY - upperY;-
105 if (vDir == TopDown) {-
106 qint32 *line = bits + upperY * width;-
107 do {-
108 fillLine<clip, hDir>(line, width, lx, rx, d, ddx);-
109 lx += ldx;-
110 d += ddy;-
111 rx += rdx;-
112 line += width;-
113 } while (--y);-
114 } else {-
115 qint32 *line = bits + lowerY * width;-
116 do {-
117 lx -= ldx;-
118 d -= ddy;-
119 rx -= rdx;-
120 line -= width;-
121 fillLine<clip, hDir>(line, width, lx, rx, d, ddx);-
122 } while (--y);-
123 }-
124}-
125-
126template <FillClip clip>-
127void drawTriangle(qint32 *bits, int width, int height, const QPoint *center,-
128 const QPoint *v1, const QPoint *v2, qint32 value)-
129{-
130 const int y1 = clip == Clip ? qBound(0, v1->y() >> 8, height) : v1->y() >> 8;-
131 const int y2 = clip == Clip ? qBound(0, v2->y() >> 8, height) : v2->y() >> 8;-
132 const int yC = clip == Clip ? qBound(0, center->y() >> 8, height) : center->y() >> 8;-
133-
134 const int v1Frac = clip == Clip ? (y1 << 8) + 0xff - v1->y() : ~v2->y() & 0xff;-
135 const int v2Frac = clip == Clip ? (y2 << 8) + 0xff - v2->y() : ~v1->y() & 0xff;-
136 const int centerFrac = clip == Clip ? (yC << 8) + 0xff - center->y() : ~center->y() & 0xff;-
137-
138 int dx1 = 0, x1 = 0, dx2 = 0, x2 = 0;-
139 qint32 dd1, d1, dd2, d2;-
140 if (v1->y() != center->y()) {-
141 dx1 = ((v1->x() - center->x()) << 8) / (v1->y() - center->y());-
142 x1 = center->x() + centerFrac * (v1->x() - center->x()) / (v1->y() - center->y());-
143 }-
144 if (v2->y() != center->y()) {-
145 dx2 = ((v2->x() - center->x()) << 8) / (v2->y() - center->y());-
146 x2 = center->x() + centerFrac * (v2->x() - center->x()) / (v2->y() - center->y());-
147 }-
148-
149 const qint32 div = (v2->x() - center->x()) * (v1->y() - center->y())-
150 - (v2->y() - center->y()) * (v1->x() - center->x());-
151 const qint32 dd = div ? qint32((qint64(value * (v1->y() - v2->y())) << 8) / div) : 0;-
152-
153 if (y2 < yC) {-
154 if (y1 < yC) {-
155-
156 if (y2 < y1) {-
157-
158-
159 d1 = centerFrac * value / (v1->y() - center->y());-
160 dd1 = ((value << 8) / (v1->y() - center->y()));-
161 fillLines<clip, BottomUp, LeftToRight>(bits, width, height, y1, yC, x1, dx1,-
162 x2, dx2, d1, dd1, dd);-
163 dx1 = ((v1->x() - v2->x()) << 8) / (v1->y() - v2->y());-
164 x1 = v1->x() + v1Frac * (v1->x() - v2->x()) / (v1->y() - v2->y());-
165 fillLines<clip, BottomUp, LeftToRight>(bits, width, height, y2, y1, x1, dx1,-
166 x2, dx2, value, 0, dd);-
167 } else {-
168-
169-
170 d2 = centerFrac * value / (v2->y() - center->y());-
171 dd2 = ((value << 8) / (v2->y() - center->y()));-
172 fillLines<clip, BottomUp, RightToLeft>(bits, width, height, y2, yC, x1, dx1,-
173 x2, dx2, d2, dd2, dd);-
174 if (y1 != y2) {-
175 dx2 = ((v1->x() - v2->x()) << 8) / (v1->y() - v2->y());-
176 x2 = v2->x() + v2Frac * (v1->x() - v2->x()) / (v1->y() - v2->y());-
177 fillLines<clip, BottomUp, RightToLeft>(bits, width, height, y1, y2, x1, dx1,-
178 x2, dx2, value, 0, dd);-
179 }-
180 }-
181 } else {-
182-
183-
184 int dx = ((v1->x() - v2->x()) << 8) / (v1->y() - v2->y());-
185 int xUp, xDn;-
186 xUp = xDn = v2->x() + (clip == Clip ? (yC << 8) + 0xff - v2->y()-
187 : (center->y() | 0xff) - v2->y())-
188 * (v1->x() - v2->x()) / (v1->y() - v2->y());-
189 fillLines<clip, BottomUp, LeftToRight>(bits, width, height, y2, yC, xUp, dx,-
190 x2, dx2, value, 0, dd);-
191 if (yC != y1)-
192 fillLines<clip, TopDown, LeftToRight>(bits, width, height, yC, y1, xDn, dx,-
193 x1, dx1, value, 0, dd);-
194 }-
195 } else {-
196 if (y1 < yC) {-
197-
198-
199 int dx = ((v1->x() - v2->x()) << 8) / (v1->y() - v2->y());-
200 int xUp, xDn;-
201 xUp = xDn = v1->x() + (clip == Clip ? (yC << 8) + 0xff - v1->y()-
202 : (center->y() | 0xff) - v1->y())-
203 * (v1->x() - v2->x()) / (v1->y() - v2->y());-
204 fillLines<clip, BottomUp, RightToLeft>(bits, width, height, y1, yC, x1, dx1,-
205 xUp, dx, value, 0, dd);-
206 if (yC != y2)-
207 fillLines<clip, TopDown, RightToLeft>(bits, width, height, yC, y2, x2, dx2,-
208 xDn, dx, value, 0, dd);-
209 } else {-
210-
211 if (y2 < y1) {-
212-
213-
214 if (yC != y2) {-
215 d2 = centerFrac * value / (v2->y() - center->y());-
216 dd2 = ((value << 8) / (v2->y() - center->y()));-
217 fillLines<clip, TopDown, LeftToRight>(bits, width, height, yC, y2, x2, dx2,-
218 x1, dx1, d2, dd2, dd);-
219 }-
220 dx2 = ((v1->x() - v2->x()) << 8) / (v1->y() - v2->y());-
221 x2 = v2->x() + v2Frac * (v1->x() - v2->x()) / (v1->y() - v2->y());-
222 fillLines<clip, TopDown, LeftToRight>(bits, width, height, y2, y1, x2, dx2,-
223 x1, dx1, value, 0, dd);-
224 } else {-
225-
226-
227 if (yC != y1) {-
228 d1 = centerFrac * value / (v1->y() - center->y());-
229 dd1 = ((value << 8) / (v1->y() - center->y()));-
230 fillLines<clip, TopDown, RightToLeft>(bits, width, height, yC, y1, x2, dx2,-
231 x1, dx1, d1, dd1, dd);-
232 }-
233 if (y1 != y2) {-
234 dx1 = ((v1->x() - v2->x()) << 8) / (v1->y() - v2->y());-
235 x1 = v1->x() + v1Frac * (v1->x() - v2->x()) / (v1->y() - v2->y());-
236 fillLines<clip, TopDown, RightToLeft>(bits, width, height, y1, y2, x2, dx2,-
237 x1, dx1, value, 0, dd);-
238 }-
239 }-
240 }-
241 }-
242}-
243-
244template <FillClip clip>-
245void drawRectangle(qint32 *bits, int width, int height,-
246 const QPoint *int1, const QPoint *center1, const QPoint *ext1,-
247 const QPoint *int2, const QPoint *center2, const QPoint *ext2,-
248 qint32 extValue)-
249{-
250 if (center1->y() > center2->y()) {-
251 qSwap(center1, center2);-
252 qSwap(int1, ext2);-
253 qSwap(ext1, int2);-
254 extValue = -extValue;-
255 }-
256-
257 ((!(ext1->x() - center1->x() == center1->x() - int1->x())) ? qt_assert("ext1->x() - center1->x() == center1->x() - int1->x()",__FILE__,295301) : qt_noop());-
258 ((!(ext1->y() - center1->y() == center1->y() - int1->y())) ? qt_assert("ext1->y() - center1->y() == center1->y() - int1->y()",__FILE__,296302) : qt_noop());-
259 ((!(ext2->x() - center2->x() == center2->x() - int2->x())) ? qt_assert("ext2->x() - center2->x() == center2->x() - int2->x()",__FILE__,297303) : qt_noop());-
260 ((!(ext2->y() - center2->y() == center2->y() - int2->y())) ? qt_assert("ext2->y() - center2->y() == center2->y() - int2->y()",__FILE__,298304) : qt_noop());-
261-
262 const int yc1 = clip == Clip ? qBound(0, center1->y() >> 8, height) : center1->y() >> 8;-
263 const int yc2 = clip == Clip ? qBound(0, center2->y() >> 8, height) : center2->y() >> 8;-
264 const int yi1 = clip == Clip ? qBound(0, int1->y() >> 8, height) : int1->y() >> 8;-
265 const int yi2 = clip == Clip ? qBound(0, int2->y() >> 8, height) : int2->y() >> 8;-
266 const int ye1 = clip == Clip ? qBound(0, ext1->y() >> 8, height) : ext1->y() >> 8;-
267 const int ye2 = clip == Clip ? qBound(0, ext2->y() >> 8, height) : ext2->y() >> 8;-
268-
269 const int center1Frac = clip == Clip ? (yc1 << 8) + 0xff - center1->y() : ~center1->y() & 0xff;-
270 const int center2Frac = clip == Clip ? (yc2 << 8) + 0xff - center2->y() : ~center2->y() & 0xff;-
271 const int int1Frac = clip == Clip ? (yi1 << 8) + 0xff - int1->y() : ~int1->y() & 0xff;-
272 const int ext1Frac = clip == Clip ? (ye1 << 8) + 0xff - ext1->y() : ~ext1->y() & 0xff;-
273-
274 int dxC = 0, dxE = 0;-
275 qint32 ddC = 0;-
276 if (ext1->y() != int1->y()) {-
277 dxC = ((ext1->x() - int1->x()) << 8) / (ext1->y() - int1->y());-
278 ddC = (extValue << 9) / (ext1->y() - int1->y());-
279 }-
280 if (ext1->y() != ext2->y())-
281 dxE = ((ext1->x() - ext2->x()) << 8) / (ext1->y() - ext2->y());-
282-
283 const qint32 div = (ext1->x() - int1->x()) * (ext2->y() - int1->y())-
284 - (ext1->y() - int1->y()) * (ext2->x() - int1->x());-
285 const qint32 dd = div ? qint32((qint64(extValue * (ext2->y() - ext1->y())) << 9) / div) : 0;-
286-
287 int xe1, xe2, xc1, xc2;-
288 qint32 d;-
289-
290 qint32 intValue = -extValue;-
291-
292 if (center2->x() < center1->x()) {-
293-
294 if (int1->y() < ext2->y()) {-
295-
296 ((!(ext1->y() != ext2->y())) ? qt_assert("ext1->y() != ext2->y()",__FILE__,334340) : qt_noop());-
297 xe1 = ext1->x() + ext1Frac * (ext1->x() - ext2->x()) / (ext1->y() - ext2->y());-
298 xe2 = int1->x() + int1Frac * (ext1->x() - ext2->x()) / (ext1->y() - ext2->y());-
299 if (ye1 != yi1) {-
300 xc2 = center1->x() + center1Frac * (ext1->x() - int1->x()) / (ext1->y() - int1->y());-
301 xc2 += (ye1 - yc1) * dxC;-
302 fillLines<clip, TopDown, LeftToRight>(bits, width, height, ye1, yi1, xe1, dxE,-
303 xc2, dxC, extValue, 0, dd);-
304 }-
305 if (yi1 != ye2)-
306 fillLines<clip, TopDown, LeftToRight>(bits, width, height, yi1, ye2, xe1, dxE,-
307 xe2, dxE, extValue, 0, dd);-
308 if (ye2 != yi2) {-
309 xc1 = center2->x() + center2Frac * (ext1->x() - int1->x()) / (ext1->y() - int1->y());-
310 xc1 += (ye2 - yc2) * dxC;-
311 fillLines<clip, TopDown, RightToLeft>(bits, width, height, ye2, yi2, xc1, dxC,-
312 xe2, dxE, intValue, 0, dd);-
313 }-
314 } else {-
315-
316 ((!(ext1->y() != int1->y())) ? qt_assert("ext1->y() != int1->y()",__FILE__,354360) : qt_noop());-
317 xc1 = center2->x() + center2Frac * (ext1->x() - int1->x()) / (ext1->y() - int1->y());-
318 xc2 = center1->x() + center1Frac * (ext1->x() - int1->x()) / (ext1->y() - int1->y());-
319 xc1 += (ye2 - yc2) * dxC;-
320 xc2 += (ye1 - yc1) * dxC;-
321 if (ye1 != ye2) {-
322 xe1 = ext1->x() + ext1Frac * (ext1->x() - ext2->x()) / (ext1->y() - ext2->y());-
323 fillLines<clip, TopDown, LeftToRight>(bits, width, height, ye1, ye2, xe1, dxE,-
324 xc2, dxC, extValue, 0, dd);-
325 }-
326 if (ye2 != yi1) {-
327 d = (clip == Clip ? (ye2 << 8) + 0xff - center2->y()-
328 : (ext2->y() | 0xff) - center2->y())-
329 * 2 * extValue / (ext1->y() - int1->y());-
330 fillLines<clip, TopDown, LeftToRight>(bits, width, height, ye2, yi1, xc1, dxC,-
331 xc2, dxC, d, ddC, dd);-
332 }-
333 if (yi1 != yi2) {-
334 xe2 = int1->x() + int1Frac * (ext1->x() - ext2->x()) / (ext1->y() - ext2->y());-
335 fillLines<clip, TopDown, RightToLeft>(bits, width, height, yi1, yi2, xc1, dxC,-
336 xe2, dxE, intValue, 0, dd);-
337 }-
338 }-
339 } else {-
340-
341 if (ext1->y() < int2->y()) {-
342-
343 ((!(ext1->y() != ext2->y())) ? qt_assert("ext1->y() != ext2->y()",__FILE__,381387) : qt_noop());-
344 xe1 = ext1->x() + ext1Frac * (ext1->x() - ext2->x()) / (ext1->y() - ext2->y());-
345 xe2 = int1->x() + int1Frac * (ext1->x() - ext2->x()) / (ext1->y() - ext2->y());-
346 if (yi1 != ye1) {-
347 xc1 = center1->x() + center1Frac * (ext1->x() - int1->x()) / (ext1->y() - int1->y());-
348 xc1 += (yi1 - yc1) * dxC;-
349 fillLines<clip, TopDown, RightToLeft>(bits, width, height, yi1, ye1, xc1, dxC,-
350 xe2, dxE, intValue, 0, dd);-
351 }-
352 if (ye1 != yi2)-
353 fillLines<clip, TopDown, RightToLeft>(bits, width, height, ye1, yi2, xe1, dxE,-
354 xe2, dxE, intValue, 0, dd);-
355 if (yi2 != ye2) {-
356 xc2 = center2->x() + center2Frac * (ext1->x() - int1->x()) / (ext1->y() - int1->y());-
357 xc2 += (yi2 - yc2) * dxC;-
358 fillLines<clip, TopDown, LeftToRight>(bits, width, height, yi2, ye2, xe1, dxE,-
359 xc2, dxC, extValue, 0, dd);-
360 }-
361 } else {-
362-
363 ((!(ext1->y() != int1->y())) ? qt_assert("ext1->y() != int1->y()",__FILE__,401407) : qt_noop());-
364 xc1 = center1->x() + center1Frac * (ext1->x() - int1->x()) / (ext1->y() - int1->y());-
365 xc2 = center2->x() + center2Frac * (ext1->x() - int1->x()) / (ext1->y() - int1->y());-
366 xc1 += (yi1 - yc1) * dxC;-
367 xc2 += (yi2 - yc2) * dxC;-
368 if (yi1 != yi2) {-
369 xe2 = int1->x() + int1Frac * (ext1->x() - ext2->x()) / (ext1->y() - ext2->y());-
370 fillLines<clip, TopDown, RightToLeft>(bits, width, height, yi1, yi2, xc1, dxC,-
371 xe2, dxE, intValue, 0, dd);-
372 }-
373 if (yi2 != ye1) {-
374 d = (clip == Clip ? (yi2 << 8) + 0xff - center2->y()-
375 : (int2->y() | 0xff) - center2->y())-
376 * 2 * extValue / (ext1->y() - int1->y());-
377 fillLines<clip, TopDown, RightToLeft>(bits, width, height, yi2, ye1, xc1, dxC,-
378 xc2, dxC, d, ddC, dd);-
379 }-
380 if (ye1 != ye2) {-
381 xe1 = ext1->x() + ext1Frac * (ext1->x() - ext2->x()) / (ext1->y() - ext2->y());-
382 fillLines<clip, TopDown, LeftToRight>(bits, width, height, ye1, ye2, xe1, dxE,-
383 xc2, dxC, extValue, 0, dd);-
384 }-
385 }-
386 }-
387}-
388-
389static void drawPolygons(qint32 *bits, int width, int height, const QPoint *vertices,-
390 const quint32 *indices, int indexCount, qint32 value)-
391{-
392 ((!(indexCount != 0)) ? qt_assert("indexCount != 0",__FILE__,430436) : qt_noop());-
393 typedef((!(height <= 128)) ? qt_assert("height <= 128",__FILE__,437) : qt_noop());-
394 QVarLengthArray<quint8, 16> ScanLine;-
QVarLengthArray<ScanLine, 128> scans(height);[128];
395 int first = 0;-
396 for (int i = 1; i < indexCount
i < indexCountDescription
TRUEnever evaluated
FALSEnever evaluated
; ++i) {
0
397 quint32 idx1 = indices[i - 1];-
398 quint32 idx2 = indices[i];-
399 ((!(idx1 != quint32(-1))) ? qt_assert("idx1 != quint32(-1)",__FILE__,437443) : qt_noop());-
400 if (idx2 == quint32(-1)
idx2 == quint32(-1)Description
TRUEnever evaluated
FALSEnever evaluated
) {
0
401 idx2 = indices[first];-
402 ((!(idx2 != quint32(-1))) ? qt_assert("idx2 != quint32(-1)",__FILE__,440446) : qt_noop());-
403 first = ++i;-
404 }
never executed: end of block
0
405 const QPoint *v1 = &vertices[idx1];-
406 const QPoint *v2 = &vertices[idx2];-
407 if (v2->y() < v1->y()
v2->y() < v1->y()Description
TRUEnever evaluated
FALSEnever evaluated
)
0
408 qSwap(v1, v2);
never executed: qSwap(v1, v2);
0
409 int fromY = qMax(0, v1->y() >> 8);-
410 int toY = qMin(height, v2->y() >> 8);-
411 if (fromY >= toY
fromY >= toYDescription
TRUEnever evaluated
FALSEnever evaluated
)
0
412 continue;
never executed: continue;
0
413 int dx = ((v2->x() - v1->x()) << 8) / (v2->y() - v1->y());-
414 int x = v1->x() + ((fromY << 8) + 0xff - v1->y()) * (v2->x() - v1->x()) / (v2->y() - v1->y());-
415 for (int y = fromY; y < toY
y < toYDescription
TRUEnever evaluated
FALSEnever evaluated
; ++y) {
0
416 quint32 c = quint32(x >> 8);-
417 if (c < quint32(width)
c < quint32(width)Description
TRUEnever evaluated
FALSEnever evaluated
)
0
418 scans[y].append(quint8(c));
never executed: scans[y].append(quint8(c));
0
419 x += dx;-
420 }
never executed: end of block
0
421 }
never executed: end of block
0
422 for (int i = 0; i < height
i < heightDescription
TRUEnever evaluated
FALSEnever evaluated
; ++i) {
0
423 quint8 *scanline = scans[i].data();-
424 int size = scans[i].size();-
425 for (int j = 1; j < size
j < sizeDescription
TRUEnever evaluated
FALSEnever evaluated
; ++j) {
0
426 int k = j;-
427 quint8 value = scanline[k];-
428 for (; k != 0
k != 0Description
TRUEnever evaluated
FALSEnever evaluated
&& value < scanline[k - 1]
value < scanline[k - 1]Description
TRUEnever evaluated
FALSEnever evaluated
; --k)
0
429 scanline[k] = scanline[k - 1];
never executed: scanline[k] = scanline[k - 1];
0
430 scanline[k] = value;-
431 }
never executed: end of block
0
432 qint32 *line = bits + i * width;-
433 int j = 0;-
434 for (; j + 1 < size
j + 1 < sizeDescription
TRUEnever evaluated
FALSEnever evaluated
; j += 2) {
0
435 for (quint8 x = scanline[j]; x < scanline[j + 1]
x < scanline[j + 1]Description
TRUEnever evaluated
FALSEnever evaluated
; ++x)
0
436 line[x] = value;
never executed: line[x] = value;
0
437 }
never executed: end of block
0
438 if (j < size
j < sizeDescription
TRUEnever evaluated
FALSEnever evaluated
) {
0
439 for (int x = scanline[j]; x < width
x < widthDescription
TRUEnever evaluated
FALSEnever evaluated
; ++x)
0
440 line[x] = value;
never executed: line[x] = value;
0
441 }
never executed: end of block
0
442 }
never executed: end of block
0
443}
never executed: end of block
0
444-
445static void makeDistanceField(QDistanceFieldData *data, const QPainterPath &path, int dfScale, int offs)-
446{-
447 if (!data || !data->data)-
448 return;-
449-
450 if (path.isEmpty()) {-
451 memset(data->data, 0, data->nbytes);-
452 return;-
453 }-
454-
455 int imgWidth = data->width;-
456 int imgHeight = data->height;-
457-
458 QTransform transform;-
459 transform.translate(offs, offs);-
460 transform.scale(qreal(1) / dfScale, qreal(1) / dfScale);-
461-
462 QDataBuffer<quint32> pathIndices(0);-
463 QDataBuffer<QPoint> pathVertices(0);-
464 qSimplifyPath(path, pathVertices, pathIndices, transform);-
465-
466 const qint32 interiorColor = -0x7f80;-
467 const qint32 exteriorColor = 0x7f80;-
468-
469 QScopedArrayPointer<qint32> bits(new qint32[imgWidth * imgHeight]);-
470 for (int i = 0; i < imgWidth * imgHeight; ++i)-
471 bits[i] = exteriorColor;-
472-
473 const qreal angleStep = qreal(15 * 3.141592653589793238 / 180);-
474 const QPoint rotation(qRound(qCos(angleStep) * 0x4000),-
475 qRound(qSin(angleStep) * 0x4000));-
476-
477 const quint32 *indices = pathIndices.data();-
478 QVarLengthArray<QPoint> normals;-
479 QVarLengthArray<QPoint> vertices;-
480 QVarLengthArray<bool> isConvex;-
481 QVarLengthArray<bool> needsClipping;-
482-
483 drawPolygons(bits.data(), imgWidth, imgHeight, pathVertices.data(),-
484 indices, pathIndices.size(), interiorColor);-
485-
486 int index = 0;-
487-
488 while (index < pathIndices.size()) {-
489 normals.clear();-
490 vertices.clear();-
491 needsClipping.clear();-
492-
493-
494 int end = index;-
495 while (indices[end] != quint32(-1))-
496 ++end;-
497-
498-
499 for (int next = index, prev = end - 1; next < end; prev = next++) {-
500 quint32 fromVertexIndex = indices[prev];-
501 quint32 toVertexIndex = indices[next];-
502-
503 const QPoint &from = pathVertices.at(fromVertexIndex);-
504 const QPoint &to = pathVertices.at(toVertexIndex);-
505-
506 QPoint n(to.y() - from.y(), from.x() - to.x());-
507 if (n.x() == 0 && n.y() == 0)-
508 continue;-
509 int scale = qRound((offs << 16) / qSqrt(qreal(n.x()) * n.x() + qreal(n.y()) * n.y()));-
510 ((!(scale != 0)) ? qt_assert("scale != 0",__FILE__,548554) : qt_noop());-
511-
512 n.rx() = n.x() * scale >> 8;-
513 n.ry() = n.y() * scale >> 8;-
514 normals.append(n);-
515 QPoint v(to.x() + 0x7f, to.y() + 0x7f);-
516 vertices.append(v);-
517 needsClipping.append((to.x() < offs << 8) || (to.x() >= (imgWidth - offs) << 8)-
518 || (to.y() < offs << 8) || (to.y() >= (imgHeight - offs) << 8));-
519 }-
520-
521 isConvex.resize(normals.count());-
522 for (int next = 0, prev = normals.count() - 1; next < normals.count(); prev = next++) {-
523 isConvex[prev] = normals.at(prev).x() * normals.at(next).y()-
524 - normals.at(prev).y() * normals.at(next).x() < 0;-
525 }-
526-
527-
528 for (int next = 0, prev = normals.count() - 1; next < normals.count(); prev = next++) {-
529 QPoint n = normals.at(next);-
530 QPoint intPrev = vertices.at(prev);-
531 QPoint extPrev = vertices.at(prev);-
532 QPoint intNext = vertices.at(next);-
533 QPoint extNext = vertices.at(next);-
534-
535 extPrev.rx() -= n.x();-
536 extPrev.ry() -= n.y();-
537 intPrev.rx() += n.x();-
538 intPrev.ry() += n.y();-
539 extNext.rx() -= n.x();-
540 extNext.ry() -= n.y();-
541 intNext.rx() += n.x();-
542 intNext.ry() += n.y();-
543-
544 if (needsClipping[prev] || needsClipping[next]) {-
545 drawRectangle<Clip>(bits.data(), imgWidth, imgHeight,-
546 &intPrev, &vertices.at(prev), &extPrev,-
547 &intNext, &vertices.at(next), &extNext,-
548 exteriorColor);-
549 } else {-
550 drawRectangle<NoClip>(bits.data(), imgWidth, imgHeight,-
551 &intPrev, &vertices.at(prev), &extPrev,-
552 &intNext, &vertices.at(next), &extNext,-
553 exteriorColor);-
554 }-
555-
556 if (isConvex.at(prev)) {-
557 QPoint p = extPrev;-
558 if (needsClipping[prev]) {-
559 for (;;) {-
560 QPoint rn((n.x() * rotation.x() - n.y() * rotation.y()) >> 14,-
561 (n.y() * rotation.x() + n.x() * rotation.y()) >> 14);-
562 n = rn;-
563 if (n.x() * normals.at(prev).y() - n.y() * normals.at(prev).x() <= 0) {-
564 p.rx() = vertices.at(prev).x() - normals.at(prev).x();-
565 p.ry() = vertices.at(prev).y() - normals.at(prev).y();-
566 drawTriangle<Clip>(bits.data(), imgWidth, imgHeight, &vertices.at(prev),-
567 &extPrev, &p, exteriorColor);-
568 break;-
569 }-
570-
571 p.rx() = vertices.at(prev).x() - n.x();-
572 p.ry() = vertices.at(prev).y() - n.y();-
573 drawTriangle<Clip>(bits.data(), imgWidth, imgHeight, &vertices.at(prev),-
574 &extPrev, &p, exteriorColor);-
575 extPrev = p;-
576 }-
577 } else {-
578 for (;;) {-
579 QPoint rn((n.x() * rotation.x() - n.y() * rotation.y()) >> 14,-
580 (n.y() * rotation.x() + n.x() * rotation.y()) >> 14);-
581 n = rn;-
582 if (n.x() * normals.at(prev).y() - n.y() * normals.at(prev).x() <= 0) {-
583 p.rx() = vertices.at(prev).x() - normals.at(prev).x();-
584 p.ry() = vertices.at(prev).y() - normals.at(prev).y();-
585 drawTriangle<NoClip>(bits.data(), imgWidth, imgHeight, &vertices.at(prev),-
586 &extPrev, &p, exteriorColor);-
587 break;-
588 }-
589-
590 p.rx() = vertices.at(prev).x() - n.x();-
591 p.ry() = vertices.at(prev).y() - n.y();-
592 drawTriangle<NoClip>(bits.data(), imgWidth, imgHeight, &vertices.at(prev),-
593 &extPrev, &p, exteriorColor);-
594 extPrev = p;-
595 }-
596 }-
597 } else {-
598 QPoint p = intPrev;-
599 if (needsClipping[prev]) {-
600 for (;;) {-
601 QPoint rn((n.x() * rotation.x() + n.y() * rotation.y()) >> 14,-
602 (n.y() * rotation.x() - n.x() * rotation.y()) >> 14);-
603 n = rn;-
604 if (n.x() * normals.at(prev).y() - n.y() * normals.at(prev).x() >= 0) {-
605 p.rx() = vertices.at(prev).x() + normals.at(prev).x();-
606 p.ry() = vertices.at(prev).y() + normals.at(prev).y();-
607 drawTriangle<Clip>(bits.data(), imgWidth, imgHeight, &vertices.at(prev),-
608 &p, &intPrev, interiorColor);-
609 break;-
610 }-
611-
612 p.rx() = vertices.at(prev).x() + n.x();-
613 p.ry() = vertices.at(prev).y() + n.y();-
614 drawTriangle<Clip>(bits.data(), imgWidth, imgHeight, &vertices.at(prev),-
615 &p, &intPrev, interiorColor);-
616 intPrev = p;-
617 }-
618 } else {-
619 for (;;) {-
620 QPoint rn((n.x() * rotation.x() + n.y() * rotation.y()) >> 14,-
621 (n.y() * rotation.x() - n.x() * rotation.y()) >> 14);-
622 n = rn;-
623 if (n.x() * normals.at(prev).y() - n.y() * normals.at(prev).x() >= 0) {-
624 p.rx() = vertices.at(prev).x() + normals.at(prev).x();-
625 p.ry() = vertices.at(prev).y() + normals.at(prev).y();-
626 drawTriangle<NoClip>(bits.data(), imgWidth, imgHeight, &vertices.at(prev),-
627 &p, &intPrev, interiorColor);-
628 break;-
629 }-
630-
631 p.rx() = vertices.at(prev).x() + n.x();-
632 p.ry() = vertices.at(prev).y() + n.y();-
633 drawTriangle<NoClip>(bits.data(), imgWidth, imgHeight, &vertices.at(prev),-
634 &p, &intPrev, interiorColor);-
635 intPrev = p;-
636 }-
637 }-
638 }-
639 }-
640-
641 index = end + 1;-
642 }-
643-
644 const qint32 *inLine = bits.data();-
645 uchar *outLine = data->data;-
646 for (int y = 0; y < imgHeight; ++y) {-
647 for (int x = 0; x < imgWidth; ++x, ++inLine, ++outLine)-
648 *outLine = uchar((0x7f80 - *inLine) >> 8);-
649 }-
650}-
651-
652static bool imageHasNarrowOutlines(const QImage &im)-
653{-
654 if (im.isNull() || im.width() < 1 || im.height() < 1)-
655 return false;-
656 else if (im.width() == 1 || im.height() == 1)-
657 return true;-
658-
659 int minHThick = 999;-
660 int minVThick = 999;-
661-
662 int thick = 0;-
663 bool in = false;-
664 int y = (im.height() + 1) / 2;-
665 for (int x = 0; x < im.width(); ++x) {-
666 int a = qAlpha(im.pixel(x, y));-
667 if (a > 127) {-
668 in = true;-
669 ++thick;-
670 } else if (in) {-
671 in = false;-
672 minHThick = qMin(minHThick, thick);-
673 thick = 0;-
674 }-
675 }-
676-
677 thick = 0;-
678 in = false;-
679 int x = (im.width() + 1) / 2;-
680 for (int y = 0; y < im.height(); ++y) {-
681 int a = qAlpha(im.pixel(x, y));-
682 if (a > 127) {-
683 in = true;-
684 ++thick;-
685 } else if (in) {-
686 in = false;-
687 minVThick = qMin(minVThick, thick);-
688 thick = 0;-
689 }-
690 }-
691-
692 return minHThick == 1 || minVThick == 1;-
693}-
694-
695bool qt_fontHasNarrowOutlines(QFontEngine *fontEngine)-
696{-
697 QFontEngine *fe = fontEngine->cloneWithSize(54);-
698 if (!fe)-
699 return false;-
700-
701 QImage im;-
702-
703 const glyph_t glyph = fe->glyphIndex('O');-
704 if (glyph != 0)-
705 im = fe->alphaMapForGlyph(glyph, QFixed(), QTransform());-
706-
707 ((!(fe->ref.load() == 0)) ? qt_assert("fe->ref.load() == 0",__FILE__,745751) : qt_noop());-
708 delete fe;-
709-
710 return imageHasNarrowOutlines(im);-
711}-
712-
713bool qt_fontHasNarrowOutlines(const QRawFont &f)-
714{-
715 QRawFont font = f;-
716 font.setPixelSize(54);-
717 if (!font.isValid())-
718 return false;-
719-
720 QVector<quint32> glyphIndices = font.glyphIndexesForString(QLatin1String("O"));-
721 if (glyphIndices.isEmpty() || glyphIndices[0] == 0)-
722 return false;-
723-
724 return imageHasNarrowOutlines(font.alphaMapForGlyph(glyphIndices.at(0),-
725 QRawFont::PixelAntialiasing));-
726}-
727-
728-
729QDistanceFieldData::QDistanceFieldData(const QDistanceFieldData &other)-
730 : QSharedData(other)-
731 , glyph(other.glyph)-
732 , width(other.width)-
733 , height(other.height)-
734 , nbytes(other.nbytes)-
735{-
736 if (nbytes && other.data)-
737 data = (uchar *)memcpy(malloc(nbytes), other.data, nbytes);-
738 else-
739 data = 0;-
740}-
741-
742QDistanceFieldData::~QDistanceFieldData()-
743{-
744 free(data);-
745}-
746-
747QDistanceFieldData *QDistanceFieldData::create(const QSize &size)-
748{-
749 QDistanceFieldData *data = new QDistanceFieldData;-
750-
751 if (size.isValid()) {-
752 data->width = size.width();-
753 data->height = size.height();-
754-
755 data->nbytes = data->width * data->height;-
756 data->data = (uchar *)malloc(data->nbytes);-
757 }-
758-
759 return data;-
760}-
761-
762QDistanceFieldData *QDistanceFieldData::create(const QPainterPath &path, bool doubleResolution)-
763{-
764 int dfMargin = (doubleResolution ? 80 / 2 : 80) / (doubleResolution ? 16 / 2 : 16);-
765 int glyphWidth = qCeil(path.boundingRect().width() / (doubleResolution ? 16 / 2 : 16)) + dfMargin * 2;-
766 int glyphHeight = qCeil(path.boundingRect().height() / (doubleResolution ? 16 / 2 : 16)) + dfMargin * 2;-
767-
768 QDistanceFieldData *data = create(QSize(glyphWidth, glyphHeight));-
769-
770 makeDistanceField(data,-
771 path,-
772 (doubleResolution ? 16 / 2 : 16),-
773 (doubleResolution ? 80 / 2 : 80) / (doubleResolution ? 16 / 2 : 16));-
774 return data;-
775}-
776-
777-
778QDistanceField::QDistanceField()-
779 : d(new QDistanceFieldData)-
780{-
781}-
782-
783QDistanceField::QDistanceField(int width, int height)-
784 : d(QDistanceFieldData::create(QSize(width, height)))-
785{-
786}-
787-
788QDistanceField::QDistanceField(const QDistanceField &other)-
789{-
790 d = other.d;-
791}-
792-
793QDistanceField::QDistanceField(const QRawFont &font, glyph_t glyph, bool doubleResolution)-
794{-
795 setGlyph(font, glyph, doubleResolution);-
796}-
797-
798QDistanceField::QDistanceField(QFontEngine *fontEngine, glyph_t glyph, bool doubleResolution)-
799{-
800 setGlyph(fontEngine, glyph, doubleResolution);-
801}-
802-
803QDistanceField::QDistanceField(const QPainterPath &path, glyph_t glyph, bool doubleResolution)-
804{-
805 QPainterPath dfPath = path;-
806 dfPath.translate(-dfPath.boundingRect().topLeft());-
807 dfPath.setFillRule(Qt::WindingFill);-
808-
809 d = QDistanceFieldData::create(dfPath, doubleResolution);-
810 d->glyph = glyph;-
811}-
812-
813-
814QDistanceField::QDistanceField(QDistanceFieldData *data)-
815 : d(data)-
816{-
817}-
818-
819bool QDistanceField::isNull() const-
820{-
821 return !d->data;-
822}-
823-
824glyph_t QDistanceField::glyph() const-
825{-
826 return d->glyph;-
827}-
828-
829void QDistanceField::setGlyph(const QRawFont &font, glyph_t glyph, bool doubleResolution)-
830{-
831 QRawFont renderFont = font;-
832 renderFont.setPixelSize((doubleResolution ? 54 * 2 : 54) * (doubleResolution ? 16 / 2 : 16));-
833-
834 QPainterPath path = renderFont.pathForGlyph(glyph);-
835 path.translate(-path.boundingRect().topLeft());-
836 path.setFillRule(Qt::WindingFill);-
837-
838 d = QDistanceFieldData::create(path, doubleResolution);-
839 d->glyph = glyph;-
840}-
841-
842void QDistanceField::setGlyph(QFontEngine *fontEngine, glyph_t glyph, bool doubleResolution)-
843{-
844 QFixedPoint position;-
845 QPainterPath path;-
846 fontEngine->addGlyphsToPath(&glyph, &position, 1, &path, 0);-
847 path.translate(-path.boundingRect().topLeft());-
848 path.setFillRule(Qt::WindingFill);-
849-
850 d = QDistanceFieldData::create(path, doubleResolution);-
851 d->glyph = glyph;-
852}-
853-
854int QDistanceField::width() const-
855{-
856 return d->width;-
857}-
858-
859int QDistanceField::height() const-
860{-
861 return d->height;-
862}-
863-
864QDistanceField QDistanceField::copy(const QRect &r) const-
865{-
866 if (isNull())-
867 return QDistanceField();-
868-
869 if (r.isNull())-
870 return QDistanceField(new QDistanceFieldData(*d));-
871-
872 int x = r.x();-
873 int y = r.y();-
874 int w = r.width();-
875 int h = r.height();-
876-
877 int dx = 0;-
878 int dy = 0;-
879 if (w <= 0 || h <= 0)-
880 return QDistanceField();-
881-
882 QDistanceField df(w, h);-
883 if (df.isNull())-
884 return df;-
885-
886 if (x < 0 || y < 0 || x + w > d->width || y + h > d->height) {-
887 memset(df.d->data, 0, df.d->nbytes);-
888 if (x < 0) {-
889 dx = -x;-
890 x = 0;-
891 }-
892 if (y < 0) {-
893 dy = -y;-
894 y = 0;-
895 }-
896 }-
897-
898 int pixels_to_copy = qMax(w - dx, 0);-
899 if (x > d->width)-
900 pixels_to_copy = 0;-
901 else if (pixels_to_copy > d->width - x)-
902 pixels_to_copy = d->width - x;-
903 int lines_to_copy = qMax(h - dy, 0);-
904 if (y > d->height)-
905 lines_to_copy = 0;-
906 else if (lines_to_copy > d->height - y)-
907 lines_to_copy = d->height - y;-
908-
909 const uchar *src = d->data + x + y * d->width;-
910 uchar *dest = df.d->data + dx + dy * df.d->width;-
911 for (int i = 0; i < lines_to_copy; ++i) {-
912 memcpy(dest, src, pixels_to_copy);-
913 src += d->width;-
914 dest += df.d->width;-
915 }-
916-
917 df.d->glyph = d->glyph;-
918-
919 return df;-
920}-
921-
922uchar *QDistanceField::bits()-
923{-
924 return d->data;-
925}-
926-
927const uchar *QDistanceField::bits() const-
928{-
929 return d->data;-
930}-
931-
932const uchar *QDistanceField::constBits() const-
933{-
934 return d->data;-
935}-
936-
937uchar *QDistanceField::scanLine(int i)-
938{-
939 if (isNull())-
940 return 0;-
941-
942 ((!(i >= 0 && i < d->height)) ? qt_assert("i >= 0 && i < d->height",__FILE__,980986) : qt_noop());-
943 return d->data + i * d->width;-
944}-
945-
946const uchar *QDistanceField::scanLine(int i) const-
947{-
948 if (isNull())-
949 return 0;-
950-
951 ((!(i >= 0 && i < d->height)) ? qt_assert("i >= 0 && i < d->height",__FILE__,989995) : qt_noop());-
952 return d->data + i * d->width;-
953}-
954-
955const uchar *QDistanceField::constScanLine(int i) const-
956{-
957 if (isNull())-
958 return 0;-
959-
960 ((!(i >= 0 && i < d->height)) ? qt_assert("i >= 0 && i < d->height",__FILE__,9981004) : qt_noop());-
961 return d->data + i * d->width;-
962}-
963-
964QImage QDistanceField::toImage(QImage::Format format) const-
965{-
966 if (isNull())-
967 return QImage();-
968-
969 QImage image(d->width, d->height, qt_depthForFormat(format) == 8 ?-
970 format : QImage::Format_ARGB32_Premultiplied);-
971 if (image.isNull())-
972 return image;-
973-
974 if (image.depth() == 8) {-
975 for (int y = 0; y < d->height; ++y)-
976 memcpy(image.scanLine(y), scanLine(y), d->width);-
977 } else {-
978 for (int y = 0; y < d->height; ++y) {-
979 for (int x = 0; x < d->width; ++x) {-
980 uint alpha = *(d->data + x + y * d->width);-
981 image.setPixel(x, y, alpha << 24);-
982 }-
983 }-
984-
985 if (image.format() != format)-
986 image = image.convertToFormat(format);-
987 }-
988-
989 return image;-
990}-
991-
992-
Switch to Source codePreprocessed file

Generated by Squish Coco Non-Commercial 4.3.0-BETA-master-30-08-2018-4cb69e9