qrasterizer.cpp

Absolute File Name:/home/qt/qt5_coco/qt5/qtbase/src/gui/painting/qrasterizer.cpp
Source codeSwitch to Preprocessed file
LineSourceCount
1/****************************************************************************-
2**-
3** Copyright (C) 2016 The Qt Company Ltd.-
4** Contact: https://www.qt.io/licensing/-
5**-
6** This file is part of the QtGui module of the Qt Toolkit.-
7**-
8** $QT_BEGIN_LICENSE:LGPL$-
9** Commercial License Usage-
10** Licensees holding valid commercial Qt licenses may use this file in-
11** accordance with the commercial license agreement provided with the-
12** Software or, alternatively, in accordance with the terms contained in-
13** a written agreement between you and The Qt Company. For licensing terms-
14** and conditions see https://www.qt.io/terms-conditions. For further-
15** information use the contact form at https://www.qt.io/contact-us.-
16**-
17** GNU Lesser General Public License Usage-
18** Alternatively, this file may be used under the terms of the GNU Lesser-
19** General Public License version 3 as published by the Free Software-
20** Foundation and appearing in the file LICENSE.LGPL3 included in the-
21** packaging of this file. Please review the following information to-
22** ensure the GNU Lesser General Public License version 3 requirements-
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.-
24**-
25** GNU General Public License Usage-
26** Alternatively, this file may be used under the terms of the GNU-
27** General Public License version 2.0 or (at your option) the GNU General-
28** Public license version 3 or any later version approved by the KDE Free-
29** Qt Foundation. The licenses are as published by the Free Software-
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3-
31** included in the packaging of this file. Please review the following-
32** information to ensure the GNU General Public License requirements will-
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and-
34** https://www.gnu.org/licenses/gpl-3.0.html.-
35**-
36** $QT_END_LICENSE$-
37**-
38****************************************************************************/-
39-
40#include "qrasterizer_p.h"-
41-
42#include <QPoint>-
43#include <QRect>-
44-
45#include <private/qmath_p.h>-
46#include <private/qdatabuffer_p.h>-
47#include <private/qdrawhelper_p.h>-
48-
49#include <algorithm>-
50-
51QT_BEGIN_NAMESPACE-
52-
53typedef int Q16Dot16;-
54#define Q16Dot16ToFloat(i) ((i)/65536.)-
55#define FloatToQ16Dot16(i) (int)((i) * 65536.)-
56#define IntToQ16Dot16(i) ((i) * (1 << 16))-
57#define Q16Dot16ToInt(i) ((i) >> 16)-
58#define Q16Dot16Factor 65536-
59-
60#define Q16Dot16Multiply(x, y) (int)((qlonglong(x) * qlonglong(y)) >> 16)-
61#define Q16Dot16FastMultiply(x, y) (((x) * (y)) >> 16)-
62-
63#define SPAN_BUFFER_SIZE 256-
64-
65#define COORD_ROUNDING 1 // 0: round up, 1: round down-
66#define COORD_OFFSET 32 // 26.6, 32 is half a pixel-
67-
68static inline QT_FT_Vector PointToVector(const QPointF &p)-
69{-
70 QT_FT_Vector result = { QT_FT_Pos(p.x() * 64), QT_FT_Pos(p.y() * 64) };-
71 return result;
never executed: return result;
0
72}-
73-
74class QSpanBuffer {-
75public:-
76 QSpanBuffer(ProcessSpans blend, void *data, const QRect &clipRect)-
77 : m_spanCount(0)-
78 , m_blend(blend)-
79 , m_data(data)-
80 , m_clipRect(clipRect)-
81 {-
82 }
never executed: end of block
0
83-
84 ~QSpanBuffer()-
85 {-
86 flushSpans();-
87 }
never executed: end of block
0
88-
89 void addSpan(int x, unsigned int len, int y, unsigned char coverage)-
90 {-
91 if (!coverage || !len)
!coverageDescription
TRUEnever evaluated
FALSEnever evaluated
!lenDescription
TRUEnever evaluated
FALSEnever evaluated
0
92 return;
never executed: return;
0
93-
94 Q_ASSERT(y >= m_clipRect.top());-
95 Q_ASSERT(y <= m_clipRect.bottom());-
96 Q_ASSERT(x >= m_clipRect.left());-
97 Q_ASSERT(x + int(len) - 1 <= m_clipRect.right());-
98-
99 m_spans[m_spanCount].x = x;-
100 m_spans[m_spanCount].len = len;-
101 m_spans[m_spanCount].y = y;-
102 m_spans[m_spanCount].coverage = coverage;-
103-
104 if (++m_spanCount == SPAN_BUFFER_SIZE)
++m_spanCount == 256Description
TRUEnever evaluated
FALSEnever evaluated
0
105 flushSpans();
never executed: flushSpans();
0
106 }
never executed: end of block
0
107-
108private:-
109 void flushSpans()-
110 {-
111 m_blend(m_spanCount, m_spans, m_data);-
112 m_spanCount = 0;-
113 }
never executed: end of block
0
114-
115 QT_FT_Span m_spans[SPAN_BUFFER_SIZE];-
116 int m_spanCount;-
117-
118 ProcessSpans m_blend;-
119 void *m_data;-
120-
121 QRect m_clipRect;-
122};-
123-
124#define CHUNK_SIZE 64-
125class QScanConverter-
126{-
127public:-
128 QScanConverter();-
129 ~QScanConverter();-
130-
131 void begin(int top, int bottom, int left, int right,-
132 Qt::FillRule fillRule, bool legacyRounding, QSpanBuffer *spanBuffer);-
133 void end();-
134-
135 void mergeCurve(const QT_FT_Vector &a, const QT_FT_Vector &b,-
136 const QT_FT_Vector &c, const QT_FT_Vector &d);-
137 void mergeLine(QT_FT_Vector a, QT_FT_Vector b);-
138-
139 struct Line-
140 {-
141 Q16Dot16 x;-
142 Q16Dot16 delta;-
143-
144 int top, bottom;-
145-
146 int winding;-
147 };-
148-
149private:-
150 struct Intersection-
151 {-
152 int x;-
153 int winding;-
154-
155 int left, right;-
156 };-
157-
158 inline bool clip(Q16Dot16 &xFP, int &iTop, int &iBottom, Q16Dot16 slopeFP, Q16Dot16 edgeFP, int winding);-
159 inline void mergeIntersection(Intersection *head, const Intersection &isect);-
160-
161 void prepareChunk();-
162-
163 void emitNode(const Intersection *node);-
164 void emitSpans(int chunk);-
165-
166 inline void allocate(int size);-
167-
168 QDataBuffer<Line> m_lines;-
169-
170 int m_alloc;-
171 int m_size;-
172-
173 int m_top;-
174 int m_bottom;-
175-
176 Q16Dot16 m_leftFP;-
177 Q16Dot16 m_rightFP;-
178-
179 int m_fillRuleMask;-
180 bool m_legacyRounding;-
181-
182 int m_x;-
183 int m_y;-
184 int m_winding;-
185-
186 Intersection *m_intersections;-
187-
188 QSpanBuffer *m_spanBuffer;-
189-
190 QDataBuffer<Line *> m_active;-
191-
192 template <typename T>-
193 friend void qScanConvert(QScanConverter &d, T allVertical);-
194};-
195-
196class QRasterizerPrivate-
197{-
198public:-
199 bool antialiased;-
200 bool legacyRounding;-
201 ProcessSpans blend;-
202 void *data;-
203 QRect clipRect;-
204-
205 QScanConverter scanConverter;-
206};-
207-
208QScanConverter::QScanConverter()-
209 : m_lines(0)-
210 , m_alloc(0)-
211 , m_size(0)-
212 , m_intersections(0)-
213 , m_active(0)-
214{-
215}
never executed: end of block
0
216-
217QScanConverter::~QScanConverter()-
218{-
219 if (m_intersections)
m_intersectionsDescription
TRUEnever evaluated
FALSEnever evaluated
0
220 free(m_intersections);
never executed: free(m_intersections);
0
221}
never executed: end of block
0
222-
223void QScanConverter::begin(int top, int bottom, int left, int right,-
224 Qt::FillRule fillRule, bool legacyRounding,-
225 QSpanBuffer *spanBuffer)-
226{-
227 m_top = top;-
228 m_bottom = bottom;-
229 m_leftFP = IntToQ16Dot16(left);-
230 m_rightFP = IntToQ16Dot16(right + 1);-
231-
232 m_lines.reset();-
233-
234 m_fillRuleMask = fillRule == Qt::WindingFill ? ~0x0 : 0x1;
fillRule == Qt::WindingFillDescription
TRUEnever evaluated
FALSEnever evaluated
0
235 m_legacyRounding = legacyRounding;-
236 m_spanBuffer = spanBuffer;-
237}
never executed: end of block
0
238-
239void QScanConverter::prepareChunk()-
240{-
241 m_size = CHUNK_SIZE;-
242-
243 allocate(CHUNK_SIZE);-
244 memset(m_intersections, 0, CHUNK_SIZE * sizeof(Intersection));-
245}
never executed: end of block
0
246-
247void QScanConverter::emitNode(const Intersection *node)-
248{-
249tail_call:-
250 if (node->left)
node->leftDescription
TRUEnever evaluated
FALSEnever evaluated
0
251 emitNode(node + node->left);
never executed: emitNode(node + node->left);
0
252-
253 if (m_winding & m_fillRuleMask)
m_winding & m_fillRuleMaskDescription
TRUEnever evaluated
FALSEnever evaluated
0
254 m_spanBuffer->addSpan(m_x, node->x - m_x, m_y, 0xff);
never executed: m_spanBuffer->addSpan(m_x, node->x - m_x, m_y, 0xff);
0
255-
256 m_x = node->x;-
257 m_winding += node->winding;-
258-
259 if (node->right) {
node->rightDescription
TRUEnever evaluated
FALSEnever evaluated
0
260 node += node->right;-
261 goto tail_call;
never executed: goto tail_call;
0
262 }-
263}
never executed: end of block
0
264-
265void QScanConverter::emitSpans(int chunk)-
266{-
267 for (int dy = 0; dy < CHUNK_SIZE; ++dy) {
dy < 64Description
TRUEnever evaluated
FALSEnever evaluated
0
268 m_x = 0;-
269 m_y = chunk + dy;-
270 m_winding = 0;-
271-
272 emitNode(&m_intersections[dy]);-
273 }
never executed: end of block
0
274}
never executed: end of block
0
275-
276// split control points b[0] ... b[3] into-
277// left (b[0] ... b[3]) and right (b[3] ... b[6])-
278static void split(QT_FT_Vector *b)-
279{-
280 b[6] = b[3];-
281-
282 {-
283 const QT_FT_Pos temp = (b[1].x + b[2].x)/2;-
284-
285 b[1].x = (b[0].x + b[1].x)/2;-
286 b[5].x = (b[2].x + b[3].x)/2;-
287 b[2].x = (b[1].x + temp)/2;-
288 b[4].x = (b[5].x + temp)/2;-
289 b[3].x = (b[2].x + b[4].x)/2;-
290 }-
291 {-
292 const QT_FT_Pos temp = (b[1].y + b[2].y)/2;-
293-
294 b[1].y = (b[0].y + b[1].y)/2;-
295 b[5].y = (b[2].y + b[3].y)/2;-
296 b[2].y = (b[1].y + temp)/2;-
297 b[4].y = (b[5].y + temp)/2;-
298 b[3].y = (b[2].y + b[4].y)/2;-
299 }-
300}
never executed: end of block
0
301-
302static inline bool topOrder(const QScanConverter::Line &a, const QScanConverter::Line &b)-
303{-
304 return a.top < b.top;
never executed: return a.top < b.top;
0
305}-
306-
307static inline bool xOrder(const QScanConverter::Line *a, const QScanConverter::Line *b)-
308{-
309 return a->x < b->x;
never executed: return a->x < b->x;
0
310}-
311-
312template <bool B>-
313struct QBoolToType-
314{-
315 inline bool operator()() const-
316 {-
317 return B;
never executed: return B;
0
318 }-
319};-
320-
321// should be a member function but VC6 doesn't support member template functions-
322template <typename T>-
323void qScanConvert(QScanConverter &d, T allVertical)-
324{-
325 if (!d.m_lines.size()) {
!d.m_lines.size()Description
TRUEnever evaluated
FALSEnever evaluated
0
326 d.m_active.reset();-
327 return;
never executed: return;
0
328 }-
329 std::sort(d.m_lines.data(), d.m_lines.data() + d.m_lines.size(), QT_PREPEND_NAMESPACE(topOrder));-
330 int line = 0;-
331 for (int y = d.m_lines.first().top; y <= d.m_bottom; ++y) {
y <= d.m_bottomDescription
TRUEnever evaluated
FALSEnever evaluated
0
332 for (; line < d.m_lines.size() && d.m_lines.at(line).top == y; ++line) {
line < d.m_lines.size()Description
TRUEnever evaluated
FALSEnever evaluated
d.m_lines.at(line).top == yDescription
TRUEnever evaluated
FALSEnever evaluated
0
333 // add node to active list-
334 if (allVertical()) {
allVertical()Description
TRUEnever evaluated
FALSEnever evaluated
0
335 QScanConverter::Line *l = &d.m_lines.at(line);-
336 d.m_active.resize(d.m_active.size() + 1);-
337 int j;-
338 for (j = d.m_active.size() - 2; j >= 0 && QT_PREPEND_NAMESPACE(xOrder)(l, d.m_active.at(j)); --j)
j >= 0Description
TRUEnever evaluated
FALSEnever evaluated
::xOrder(l, d.m_active.at(j))Description
TRUEnever evaluated
FALSEnever evaluated
0
339 d.m_active.at(j+1) = d.m_active.at(j);
never executed: d.m_active.at(j+1) = d.m_active.at(j);
0
340 d.m_active.at(j+1) = l;-
341 } else {
never executed: end of block
0
342 d.m_active << &d.m_lines.at(line);-
343 }
never executed: end of block
0
344 }-
345-
346 int numActive = d.m_active.size();-
347 if (!allVertical()) {
!allVertical()Description
TRUEnever evaluated
FALSEnever evaluated
0
348 // use insertion sort instead of qSort, as the active edge list is quite small-
349 // and in the average case already sorted-
350 for (int i = 1; i < numActive; ++i) {
i < numActiveDescription
TRUEnever evaluated
FALSEnever evaluated
0
351 QScanConverter::Line *l = d.m_active.at(i);-
352 int j;-
353 for (j = i-1; j >= 0 && QT_PREPEND_NAMESPACE(xOrder)(l, d.m_active.at(j)); --j)
j >= 0Description
TRUEnever evaluated
FALSEnever evaluated
::xOrder(l, d.m_active.at(j))Description
TRUEnever evaluated
FALSEnever evaluated
0
354 d.m_active.at(j+1) = d.m_active.at(j);
never executed: d.m_active.at(j+1) = d.m_active.at(j);
0
355 d.m_active.at(j+1) = l;-
356 }
never executed: end of block
0
357 }
never executed: end of block
0
358-
359 int x = 0;-
360 int winding = 0;-
361 for (int i = 0; i < numActive; ++i) {
i < numActiveDescription
TRUEnever evaluated
FALSEnever evaluated
0
362 QScanConverter::Line *node = d.m_active.at(i);-
363-
364 const int current = Q16Dot16ToInt(node->x);-
365 if (winding & d.m_fillRuleMask)
winding & d.m_fillRuleMaskDescription
TRUEnever evaluated
FALSEnever evaluated
0
366 d.m_spanBuffer->addSpan(x, current - x, y, 0xff);
never executed: d.m_spanBuffer->addSpan(x, current - x, y, 0xff);
0
367-
368 x = current;-
369 winding += node->winding;-
370-
371 if (node->bottom == y) {
node->bottom == yDescription
TRUEnever evaluated
FALSEnever evaluated
0
372 // remove node from active list-
373 for (int j = i; j < numActive - 1; ++j)
j < numActive - 1Description
TRUEnever evaluated
FALSEnever evaluated
0
374 d.m_active.at(j) = d.m_active.at(j+1);
never executed: d.m_active.at(j) = d.m_active.at(j+1);
0
375-
376 d.m_active.resize(--numActive);-
377 --i;-
378 } else if (!allVertical())
never executed: end of block
!allVertical()Description
TRUEnever evaluated
FALSEnever evaluated
0
379 node->x += node->delta;
never executed: node->x += node->delta;
0
380 }
never executed: end of block
0
381 }
never executed: end of block
0
382 d.m_active.reset();-
383}
never executed: end of block
0
384-
385void QScanConverter::end()-
386{-
387 if (m_lines.isEmpty())
m_lines.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
388 return;
never executed: return;
0
389-
390 if (m_lines.size() <= 32) {
m_lines.size() <= 32Description
TRUEnever evaluated
FALSEnever evaluated
0
391 bool allVertical = true;-
392 for (int i = 0; i < m_lines.size(); ++i) {
i < m_lines.size()Description
TRUEnever evaluated
FALSEnever evaluated
0
393 if (m_lines.at(i).delta) {
m_lines.at(i).deltaDescription
TRUEnever evaluated
FALSEnever evaluated
0
394 allVertical = false;-
395 break;
never executed: break;
0
396 }-
397 }
never executed: end of block
0
398 if (allVertical)
allVerticalDescription
TRUEnever evaluated
FALSEnever evaluated
0
399 qScanConvert(*this, QBoolToType<true>());
never executed: qScanConvert(*this, QBoolToType<true>());
0
400 else-
401 qScanConvert(*this, QBoolToType<false>());
never executed: qScanConvert(*this, QBoolToType<false>());
0
402 } else {-
403 for (int chunkTop = m_top; chunkTop <= m_bottom; chunkTop += CHUNK_SIZE) {
chunkTop <= m_bottomDescription
TRUEnever evaluated
FALSEnever evaluated
0
404 prepareChunk();-
405-
406 Intersection isect = { 0, 0, 0, 0 };-
407-
408 const int chunkBottom = chunkTop + CHUNK_SIZE;-
409 for (int i = 0; i < m_lines.size(); ++i) {
i < m_lines.size()Description
TRUEnever evaluated
FALSEnever evaluated
0
410 Line &line = m_lines.at(i);-
411-
412 if ((line.bottom < chunkTop) || (line.top > chunkBottom))
(line.bottom < chunkTop)Description
TRUEnever evaluated
FALSEnever evaluated
(line.top > chunkBottom)Description
TRUEnever evaluated
FALSEnever evaluated
0
413 continue;
never executed: continue;
0
414-
415 const int top = qMax(0, line.top - chunkTop);-
416 const int bottom = qMin(CHUNK_SIZE, line.bottom + 1 - chunkTop);-
417 allocate(m_size + bottom - top);-
418-
419 isect.winding = line.winding;-
420-
421 Intersection *it = m_intersections + top;-
422 Intersection *end = m_intersections + bottom;-
423-
424 if (line.delta) {
line.deltaDescription
TRUEnever evaluated
FALSEnever evaluated
0
425 for (; it != end; ++it) {
it != endDescription
TRUEnever evaluated
FALSEnever evaluated
0
426 isect.x = Q16Dot16ToInt(line.x);-
427 line.x += line.delta;-
428 mergeIntersection(it, isect);-
429 }
never executed: end of block
0
430 } else {
never executed: end of block
0
431 isect.x = Q16Dot16ToInt(line.x);-
432 for (; it != end; ++it)
it != endDescription
TRUEnever evaluated
FALSEnever evaluated
0
433 mergeIntersection(it, isect);
never executed: mergeIntersection(it, isect);
0
434 }
never executed: end of block
0
435 }-
436-
437 emitSpans(chunkTop);-
438 }
never executed: end of block
0
439 }
never executed: end of block
0
440-
441 if (m_alloc > 1024) {
m_alloc > 1024Description
TRUEnever evaluated
FALSEnever evaluated
0
442 free(m_intersections);-
443 m_alloc = 0;-
444 m_size = 0;-
445 m_intersections = 0;-
446 }
never executed: end of block
0
447-
448 if (m_lines.size() > 1024)
m_lines.size() > 1024Description
TRUEnever evaluated
FALSEnever evaluated
0
449 m_lines.shrink(1024);
never executed: m_lines.shrink(1024);
0
450}
never executed: end of block
0
451-
452inline void QScanConverter::allocate(int size)-
453{-
454 if (m_alloc < size) {
m_alloc < sizeDescription
TRUEnever evaluated
FALSEnever evaluated
0
455 int newAlloc = qMax(size, 2 * m_alloc);-
456 m_intersections = q_check_ptr((Intersection *)realloc(m_intersections, newAlloc * sizeof(Intersection)));-
457 m_alloc = newAlloc;-
458 }
never executed: end of block
0
459}
never executed: end of block
0
460-
461inline void QScanConverter::mergeIntersection(Intersection *it, const Intersection &isect)-
462{-
463 Intersection *current = it;-
464-
465 while (isect.x != current->x) {
isect.x != current->xDescription
TRUEnever evaluated
FALSEnever evaluated
0
466 int &next = isect.x < current->x ? current->left : current->right;
isect.x < current->xDescription
TRUEnever evaluated
FALSEnever evaluated
0
467 if (next)
nextDescription
TRUEnever evaluated
FALSEnever evaluated
0
468 current += next;
never executed: current += next;
0
469 else {-
470 Intersection *last = m_intersections + m_size;-
471 next = last - current;-
472 *last = isect;-
473 ++m_size;-
474 return;
never executed: return;
0
475 }-
476 }-
477-
478 current->winding += isect.winding;-
479}
never executed: end of block
0
480-
481void QScanConverter::mergeCurve(const QT_FT_Vector &pa, const QT_FT_Vector &pb,-
482 const QT_FT_Vector &pc, const QT_FT_Vector &pd)-
483{-
484 // make room for 32 splits-
485 QT_FT_Vector beziers[4 + 3 * 32];-
486-
487 QT_FT_Vector *b = beziers;-
488-
489 b[0] = pa;-
490 b[1] = pb;-
491 b[2] = pc;-
492 b[3] = pd;-
493-
494 const QT_FT_Pos flatness = 16;-
495-
496 while (b >= beziers) {
b >= beziersDescription
TRUEnever evaluated
FALSEnever evaluated
0
497 QT_FT_Vector delta = { b[3].x - b[0].x, b[3].y - b[0].y };-
498 QT_FT_Pos l = qAbs(delta.x) + qAbs(delta.y);-
499-
500 bool belowThreshold;-
501 if (l > 64) {
l > 64Description
TRUEnever evaluated
FALSEnever evaluated
0
502 qlonglong d2 = qAbs(qlonglong(b[1].x-b[0].x) * qlonglong(delta.y) --
503 qlonglong(b[1].y-b[0].y) * qlonglong(delta.x));-
504 qlonglong d3 = qAbs(qlonglong(b[2].x-b[0].x) * qlonglong(delta.y) --
505 qlonglong(b[2].y-b[0].y) * qlonglong(delta.x));-
506-
507 qlonglong d = d2 + d3;-
508-
509 belowThreshold = (d <= qlonglong(flatness) * qlonglong(l));-
510 } else {
never executed: end of block
0
511 QT_FT_Pos d = qAbs(b[0].x-b[1].x) + qAbs(b[0].y-b[1].y) +-
512 qAbs(b[0].x-b[2].x) + qAbs(b[0].y-b[2].y);-
513-
514 belowThreshold = (d <= flatness);-
515 }
never executed: end of block
0
516-
517 if (belowThreshold || b == beziers + 3 * 32) {
belowThresholdDescription
TRUEnever evaluated
FALSEnever evaluated
b == beziers + 3 * 32Description
TRUEnever evaluated
FALSEnever evaluated
0
518 mergeLine(b[0], b[3]);-
519 b -= 3;-
520 continue;
never executed: continue;
0
521 }-
522-
523 split(b);-
524 b += 3;-
525 }
never executed: end of block
0
526}
never executed: end of block
0
527-
528inline bool QScanConverter::clip(Q16Dot16 &xFP, int &iTop, int &iBottom, Q16Dot16 slopeFP, Q16Dot16 edgeFP, int winding)-
529{-
530 bool right = edgeFP == m_rightFP;-
531-
532 if (xFP == edgeFP) {
xFP == edgeFPDescription
TRUEnever evaluated
FALSEnever evaluated
0
533 if ((slopeFP > 0) ^ right)
(slopeFP > 0) ^ rightDescription
TRUEnever evaluated
FALSEnever evaluated
0
534 return false;
never executed: return false;
0
535 else {-
536 Line line = { edgeFP, 0, iTop, iBottom, winding };-
537 m_lines.add(line);-
538 return true;
never executed: return true;
0
539 }-
540 }-
541-
542 Q16Dot16 lastFP = xFP + slopeFP * (iBottom - iTop);-
543-
544 if (lastFP == edgeFP) {
lastFP == edgeFPDescription
TRUEnever evaluated
FALSEnever evaluated
0
545 if ((slopeFP < 0) ^ right)
(slopeFP < 0) ^ rightDescription
TRUEnever evaluated
FALSEnever evaluated
0
546 return false;
never executed: return false;
0
547 else {-
548 Line line = { edgeFP, 0, iTop, iBottom, winding };-
549 m_lines.add(line);-
550 return true;
never executed: return true;
0
551 }-
552 }-
553-
554 // does line cross edge?-
555 if ((lastFP < edgeFP) ^ (xFP < edgeFP)) {
(lastFP < edge...(xFP < edgeFP)Description
TRUEnever evaluated
FALSEnever evaluated
0
556 Q16Dot16 deltaY = Q16Dot16((edgeFP - xFP) / Q16Dot16ToFloat(slopeFP));-
557-
558 if ((xFP < edgeFP) ^ right) {
(xFP < edgeFP) ^ rightDescription
TRUEnever evaluated
FALSEnever evaluated
0
559 // top segment needs to be clipped-
560 int iHeight = Q16Dot16ToInt(deltaY + 1);-
561 int iMiddle = iTop + iHeight;-
562-
563 Line line = { edgeFP, 0, iTop, iMiddle, winding };-
564 m_lines.add(line);-
565-
566 if (iMiddle != iBottom) {
iMiddle != iBottomDescription
TRUEnever evaluated
FALSEnever evaluated
0
567 xFP += slopeFP * (iHeight + 1);-
568 iTop = iMiddle + 1;-
569 } else
never executed: end of block
0
570 return true;
never executed: return true;
0
571 } else {-
572 // bottom segment needs to be clipped-
573 int iHeight = Q16Dot16ToInt(deltaY);-
574 int iMiddle = iTop + iHeight;-
575-
576 if (iMiddle != iBottom) {
iMiddle != iBottomDescription
TRUEnever evaluated
FALSEnever evaluated
0
577 Line line = { edgeFP, 0, iMiddle + 1, iBottom, winding };-
578 m_lines.add(line);-
579-
580 iBottom = iMiddle;-
581 }
never executed: end of block
0
582 }
never executed: end of block
0
583 return false;
never executed: return false;
0
584 } else if ((xFP < edgeFP) ^ right) {
(xFP < edgeFP) ^ rightDescription
TRUEnever evaluated
FALSEnever evaluated
0
585 Line line = { edgeFP, 0, iTop, iBottom, winding };-
586 m_lines.add(line);-
587 return true;
never executed: return true;
0
588 }-
589-
590 return false;
never executed: return false;
0
591}-
592-
593void QScanConverter::mergeLine(QT_FT_Vector a, QT_FT_Vector b)-
594{-
595 int winding = 1;-
596-
597 if (a.y > b.y) {
a.y > b.yDescription
TRUEnever evaluated
FALSEnever evaluated
0
598 qSwap(a, b);-
599 winding = -1;-
600 }
never executed: end of block
0
601-
602 if (m_legacyRounding) {
m_legacyRoundingDescription
TRUEnever evaluated
FALSEnever evaluated
0
603 a.x += COORD_OFFSET;-
604 a.y += COORD_OFFSET;-
605 b.x += COORD_OFFSET;-
606 b.y += COORD_OFFSET;-
607 }
never executed: end of block
0
608-
609 int rounding = m_legacyRounding ? COORD_ROUNDING : 0;
m_legacyRoundingDescription
TRUEnever evaluated
FALSEnever evaluated
0
610-
611 int iTop = qMax(m_top, int((a.y + 32 - rounding) >> 6));-
612 int iBottom = qMin(m_bottom, int((b.y - 32 - rounding) >> 6));-
613-
614 if (iTop <= iBottom) {
iTop <= iBottomDescription
TRUEnever evaluated
FALSEnever evaluated
0
615 Q16Dot16 aFP = Q16Dot16Factor/2 + (a.x * (1 << 10)) - rounding;-
616-
617 if (b.x == a.x) {
b.x == a.xDescription
TRUEnever evaluated
FALSEnever evaluated
0
618 Line line = { qBound(m_leftFP, aFP, m_rightFP), 0, iTop, iBottom, winding };-
619 m_lines.add(line);-
620 } else {
never executed: end of block
0
621 const qreal slope = (b.x - a.x) / qreal(b.y - a.y);-
622-
623 const Q16Dot16 slopeFP = FloatToQ16Dot16(slope);-
624-
625 Q16Dot16 xFP = aFP + Q16Dot16Multiply(slopeFP,-
626 IntToQ16Dot16(iTop)-
627 + Q16Dot16Factor/2 - (a.y * (1 << 10)));-
628-
629 if (clip(xFP, iTop, iBottom, slopeFP, m_leftFP, winding))
clip(xFP, iTop...ftFP, winding)Description
TRUEnever evaluated
FALSEnever evaluated
0
630 return;
never executed: return;
0
631-
632 if (clip(xFP, iTop, iBottom, slopeFP, m_rightFP, winding))
clip(xFP, iTop...htFP, winding)Description
TRUEnever evaluated
FALSEnever evaluated
0
633 return;
never executed: return;
0
634-
635 Q_ASSERT(xFP >= m_leftFP);-
636-
637 Line line = { xFP, slopeFP, iTop, iBottom, winding };-
638 m_lines.add(line);-
639 }
never executed: end of block
0
640 }-
641}
never executed: end of block
0
642-
643QRasterizer::QRasterizer()-
644 : d(new QRasterizerPrivate)-
645{-
646 d->legacyRounding = false;-
647}
never executed: end of block
0
648-
649QRasterizer::~QRasterizer()-
650{-
651 delete d;-
652}
never executed: end of block
0
653-
654void QRasterizer::setAntialiased(bool antialiased)-
655{-
656 d->antialiased = antialiased;-
657}
never executed: end of block
0
658-
659void QRasterizer::initialize(ProcessSpans blend, void *data)-
660{-
661 d->blend = blend;-
662 d->data = data;-
663}
never executed: end of block
0
664-
665void QRasterizer::setClipRect(const QRect &clipRect)-
666{-
667 d->clipRect = clipRect;-
668}
never executed: end of block
0
669-
670void QRasterizer::setLegacyRoundingEnabled(bool legacyRoundingEnabled)-
671{-
672 d->legacyRounding = legacyRoundingEnabled;-
673}
never executed: end of block
0
674-
675static Q16Dot16 intersectPixelFP(int x, Q16Dot16 top, Q16Dot16 bottom, Q16Dot16 leftIntersectX, Q16Dot16 rightIntersectX, Q16Dot16 slope, Q16Dot16 invSlope)-
676{-
677 Q16Dot16 leftX = IntToQ16Dot16(x);-
678 Q16Dot16 rightX = IntToQ16Dot16(x) + Q16Dot16Factor;-
679-
680 Q16Dot16 leftIntersectY, rightIntersectY;-
681 if (slope > 0) {
slope > 0Description
TRUEnever evaluated
FALSEnever evaluated
0
682 leftIntersectY = top + Q16Dot16Multiply(leftX - leftIntersectX, invSlope);-
683 rightIntersectY = leftIntersectY + invSlope;-
684 } else {
never executed: end of block
0
685 leftIntersectY = top + Q16Dot16Multiply(leftX - rightIntersectX, invSlope);-
686 rightIntersectY = leftIntersectY + invSlope;-
687 }
never executed: end of block
0
688-
689 if (leftIntersectX >= leftX && rightIntersectX <= rightX) {
leftIntersectX >= leftXDescription
TRUEnever evaluated
FALSEnever evaluated
rightIntersectX <= rightXDescription
TRUEnever evaluated
FALSEnever evaluated
0
690 return Q16Dot16Multiply(bottom - top, leftIntersectX - leftX + ((rightIntersectX - leftIntersectX) >> 1));
never executed: return (int)((qlonglong(bottom - top) * qlonglong(leftIntersectX - leftX + ((rightIntersectX - leftIntersectX) >> 1))) >> 16);
0
691 } else if (leftIntersectX >= rightX) {
leftIntersectX >= rightXDescription
TRUEnever evaluated
FALSEnever evaluated
0
692 return bottom - top;
never executed: return bottom - top;
0
693 } else if (leftIntersectX >= leftX) {
leftIntersectX >= leftXDescription
TRUEnever evaluated
FALSEnever evaluated
0
694 if (slope > 0) {
slope > 0Description
TRUEnever evaluated
FALSEnever evaluated
0
695 return (bottom - top) - Q16Dot16FastMultiply((rightX - leftIntersectX) >> 1, rightIntersectY - top);
never executed: return (bottom - top) - ((((rightX - leftIntersectX) >> 1) * (rightIntersectY - top)) >> 16);
0
696 } else {-
697 return (bottom - top) - Q16Dot16FastMultiply((rightX - leftIntersectX) >> 1, bottom - rightIntersectY);
never executed: return (bottom - top) - ((((rightX - leftIntersectX) >> 1) * (bottom - rightIntersectY)) >> 16);
0
698 }-
699 } else if (rightIntersectX <= leftX) {
rightIntersectX <= leftXDescription
TRUEnever evaluated
FALSEnever evaluated
0
700 return 0;
never executed: return 0;
0
701 } else if (rightIntersectX <= rightX) {
rightIntersectX <= rightXDescription
TRUEnever evaluated
FALSEnever evaluated
0
702 if (slope > 0) {
slope > 0Description
TRUEnever evaluated
FALSEnever evaluated
0
703 return Q16Dot16FastMultiply((rightIntersectX - leftX) >> 1, bottom - leftIntersectY);
never executed: return ((((rightIntersectX - leftX) >> 1) * (bottom - leftIntersectY)) >> 16);
0
704 } else {-
705 return Q16Dot16FastMultiply((rightIntersectX - leftX) >> 1, leftIntersectY - top);
never executed: return ((((rightIntersectX - leftX) >> 1) * (leftIntersectY - top)) >> 16);
0
706 }-
707 } else {-
708 if (slope > 0) {
slope > 0Description
TRUEnever evaluated
FALSEnever evaluated
0
709 return (bottom - rightIntersectY) + ((rightIntersectY - leftIntersectY) >> 1);
never executed: return (bottom - rightIntersectY) + ((rightIntersectY - leftIntersectY) >> 1);
0
710 } else {-
711 return (rightIntersectY - top) + ((leftIntersectY - rightIntersectY) >> 1);
never executed: return (rightIntersectY - top) + ((leftIntersectY - rightIntersectY) >> 1);
0
712 }-
713 }-
714}-
715-
716static inline bool q26Dot6Compare(qreal p1, qreal p2)-
717{-
718 return int((p2 - p1) * 64.) == 0;
never executed: return int((p2 - p1) * 64.) == 0;
0
719}-
720-
721static inline QPointF snapTo26Dot6Grid(const QPointF &p)-
722{-
723 return QPointF(std::floor(p.x() * 64) * (1 / qreal(64)),
never executed: return QPointF(std::floor(p.x() * 64) * (1 / qreal(64)), std::floor(p.y() * 64) * (1 / qreal(64)));
0
724 std::floor(p.y() * 64) * (1 / qreal(64)));
never executed: return QPointF(std::floor(p.x() * 64) * (1 / qreal(64)), std::floor(p.y() * 64) * (1 / qreal(64)));
0
725}-
726-
727/*-
728 The rasterize line function relies on some div by zero which should-
729 result in +/-inf values. However, when floating point exceptions are-
730 enabled, this will cause crashes, so we return high numbers instead.-
731 As the returned value is used in further arithmetic, returning-
732 FLT_MAX/DBL_MAX will also cause values, so instead return a value-
733 that is well outside the int-range.-
734 */-
735static inline qreal qSafeDivide(qreal x, qreal y)-
736{-
737 if (y == 0)
y == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
738 return x > 0 ? 1e20 : -1e20;
never executed: return x > 0 ? 1e20 : -1e20;
0
739 return x / y;
never executed: return x / y;
0
740}-
741-
742/* Conversion to int fails if the value is too large to fit into INT_MAX or-
743 too small to fit into INT_MIN, so we need this slightly safer conversion-
744 when floating point exceptions are enabled-
745 */-
746static inline int qSafeFloatToQ16Dot16(qreal x)-
747{-
748 qreal tmp = x * 65536.;-
749 if (tmp > qreal(INT_MAX))
tmp > qreal(2147483647)Description
TRUEnever evaluated
FALSEnever evaluated
0
750 return INT_MAX;
never executed: return 2147483647;
0
751 else if (tmp < qreal(INT_MIN))
tmp < qreal((-2147483647 - 1))Description
TRUEnever evaluated
FALSEnever evaluated
0
752 return -INT_MAX;
never executed: return -2147483647;
0
753 return int(tmp);
never executed: return int(tmp);
0
754}-
755-
756void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width, bool squareCap)-
757{-
758 if (a == b || width == 0 || d->clipRect.isEmpty())
a == bDescription
TRUEnever evaluated
FALSEnever evaluated
width == 0Description
TRUEnever evaluated
FALSEnever evaluated
d->clipRect.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
759 return;
never executed: return;
0
760-
761 Q_ASSERT(width > 0.0);-
762-
763 QPointF pa = a;-
764 QPointF pb = b;-
765-
766 if (squareCap) {
squareCapDescription
TRUEnever evaluated
FALSEnever evaluated
0
767 QPointF delta = pb - pa;-
768 pa -= (0.5f * width) * delta;-
769 pb += (0.5f * width) * delta;-
770 }
never executed: end of block
0
771-
772 QPointF offs = QPointF(qAbs(b.y() - a.y()), qAbs(b.x() - a.x())) * width * 0.5;-
773 const QRectF clip(d->clipRect.topLeft() - offs, d->clipRect.bottomRight() + QPoint(1, 1) + offs);-
774-
775 if (!clip.contains(pa) || !clip.contains(pb)) {
!clip.contains(pa)Description
TRUEnever evaluated
FALSEnever evaluated
!clip.contains(pb)Description
TRUEnever evaluated
FALSEnever evaluated
0
776 qreal t1 = 0;-
777 qreal t2 = 1;-
778-
779 const qreal o[2] = { pa.x(), pa.y() };-
780 const qreal d[2] = { pb.x() - pa.x(), pb.y() - pa.y() };-
781-
782 const qreal low[2] = { clip.left(), clip.top() };-
783 const qreal high[2] = { clip.right(), clip.bottom() };-
784-
785 for (int i = 0; i < 2; ++i) {
i < 2Description
TRUEnever evaluated
FALSEnever evaluated
0
786 if (d[i] == 0) {
d[i] == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
787 if (o[i] <= low[i] || o[i] >= high[i])
o[i] <= low[i]Description
TRUEnever evaluated
FALSEnever evaluated
o[i] >= high[i]Description
TRUEnever evaluated
FALSEnever evaluated
0
788 return;
never executed: return;
0
789 continue;
never executed: continue;
0
790 }-
791 const qreal d_inv = 1 / d[i];-
792 qreal t_low = (low[i] - o[i]) * d_inv;-
793 qreal t_high = (high[i] - o[i]) * d_inv;-
794 if (t_low > t_high)
t_low > t_highDescription
TRUEnever evaluated
FALSEnever evaluated
0
795 qSwap(t_low, t_high);
never executed: qSwap(t_low, t_high);
0
796 if (t1 < t_low)
t1 < t_lowDescription
TRUEnever evaluated
FALSEnever evaluated
0
797 t1 = t_low;
never executed: t1 = t_low;
0
798 if (t2 > t_high)
t2 > t_highDescription
TRUEnever evaluated
FALSEnever evaluated
0
799 t2 = t_high;
never executed: t2 = t_high;
0
800 if (t1 >= t2)
t1 >= t2Description
TRUEnever evaluated
FALSEnever evaluated
0
801 return;
never executed: return;
0
802 }
never executed: end of block
0
803-
804 QPointF npa = pa + (pb - pa) * t1;-
805 QPointF npb = pa + (pb - pa) * t2;-
806-
807 pa = npa;-
808 pb = npb;-
809 }
never executed: end of block
0
810-
811 if (!d->antialiased && d->legacyRounding) {
!d->antialiasedDescription
TRUEnever evaluated
FALSEnever evaluated
d->legacyRoundingDescription
TRUEnever evaluated
FALSEnever evaluated
0
812 pa.rx() += (COORD_OFFSET - COORD_ROUNDING)/64.;-
813 pa.ry() += (COORD_OFFSET - COORD_ROUNDING)/64.;-
814 pb.rx() += (COORD_OFFSET - COORD_ROUNDING)/64.;-
815 pb.ry() += (COORD_OFFSET - COORD_ROUNDING)/64.;-
816 }
never executed: end of block
0
817-
818 {-
819 // old delta-
820 const QPointF d0 = a - b;-
821 const qreal w0 = d0.x() * d0.x() + d0.y() * d0.y();-
822-
823 // new delta-
824 const QPointF d = pa - pb;-
825 const qreal w = d.x() * d.x() + d.y() * d.y();-
826-
827 if (w == 0)
w == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
828 return;
never executed: return;
0
829-
830 // adjust width which is given relative to |b - a|-
831 width *= qSqrt(w0 / w);-
832 }-
833-
834 QSpanBuffer buffer(d->blend, d->data, d->clipRect);-
835-
836 if (q26Dot6Compare(pa.y(), pb.y())) {
q26Dot6Compare(pa.y(), pb.y())Description
TRUEnever evaluated
FALSEnever evaluated
0
837 const qreal x = (pa.x() + pb.x()) * 0.5f;-
838 const qreal dx = qAbs(pb.x() - pa.x()) * 0.5f;-
839-
840 const qreal y = pa.y();-
841 const qreal dy = width * dx;-
842-
843 pa = QPointF(x, y - dy);-
844 pb = QPointF(x, y + dy);-
845-
846 width = 1 / width;-
847 }
never executed: end of block
0
848-
849 if (q26Dot6Compare(pa.x(), pb.x())) {
q26Dot6Compare(pa.x(), pb.x())Description
TRUEnever evaluated
FALSEnever evaluated
0
850 if (pa.y() > pb.y())
pa.y() > pb.y()Description
TRUEnever evaluated
FALSEnever evaluated
0
851 qSwap(pa, pb);
never executed: qSwap(pa, pb);
0
852-
853 const qreal dy = pb.y() - pa.y();-
854 const qreal halfWidth = 0.5f * width * dy;-
855-
856 qreal left = pa.x() - halfWidth;-
857 qreal right = pa.x() + halfWidth;-
858-
859 left = qBound(qreal(d->clipRect.left()), left, qreal(d->clipRect.right() + 1));-
860 right = qBound(qreal(d->clipRect.left()), right, qreal(d->clipRect.right() + 1));-
861-
862 pa.ry() = qBound(qreal(d->clipRect.top()), pa.y(), qreal(d->clipRect.bottom() + 1));-
863 pb.ry() = qBound(qreal(d->clipRect.top()), pb.y(), qreal(d->clipRect.bottom() + 1));-
864-
865 if (q26Dot6Compare(left, right) || q26Dot6Compare(pa.y(), pb.y()))
q26Dot6Compare(left, right)Description
TRUEnever evaluated
FALSEnever evaluated
q26Dot6Compare(pa.y(), pb.y())Description
TRUEnever evaluated
FALSEnever evaluated
0
866 return;
never executed: return;
0
867-
868 if (d->antialiased) {
d->antialiasedDescription
TRUEnever evaluated
FALSEnever evaluated
0
869 const Q16Dot16 iLeft = int(left);-
870 const Q16Dot16 iRight = int(right);-
871 const Q16Dot16 leftWidth = IntToQ16Dot16(iLeft + 1)-
872 - qSafeFloatToQ16Dot16(left);-
873 const Q16Dot16 rightWidth = qSafeFloatToQ16Dot16(right)-
874 - IntToQ16Dot16(iRight);-
875-
876 Q16Dot16 coverage[3];-
877 int x[3];-
878 int len[3];-
879-
880 int n = 1;-
881 if (iLeft == iRight) {
iLeft == iRightDescription
TRUEnever evaluated
FALSEnever evaluated
0
882 coverage[0] = (leftWidth + rightWidth) * 255;-
883 x[0] = iLeft;-
884 len[0] = 1;-
885 } else {
never executed: end of block
0
886 coverage[0] = leftWidth * 255;-
887 x[0] = iLeft;-
888 len[0] = 1;-
889 if (leftWidth == Q16Dot16Factor) {
leftWidth == 65536Description
TRUEnever evaluated
FALSEnever evaluated
0
890 len[0] = iRight - iLeft;-
891 } else if (iRight - iLeft > 1) {
never executed: end of block
iRight - iLeft > 1Description
TRUEnever evaluated
FALSEnever evaluated
0
892 coverage[1] = IntToQ16Dot16(255);-
893 x[1] = iLeft + 1;-
894 len[1] = iRight - iLeft - 1;-
895 ++n;-
896 }
never executed: end of block
0
897 if (rightWidth) {
rightWidthDescription
TRUEnever evaluated
FALSEnever evaluated
0
898 coverage[n] = rightWidth * 255;-
899 x[n] = iRight;-
900 len[n] = 1;-
901 ++n;-
902 }
never executed: end of block
0
903 }
never executed: end of block
0
904-
905 const Q16Dot16 iTopFP = IntToQ16Dot16(int(pa.y()));-
906 const Q16Dot16 iBottomFP = IntToQ16Dot16(int(pb.y()));-
907 const Q16Dot16 yPa = qSafeFloatToQ16Dot16(pa.y());-
908 const Q16Dot16 yPb = qSafeFloatToQ16Dot16(pb.y());-
909 for (Q16Dot16 yFP = iTopFP; yFP <= iBottomFP; yFP += Q16Dot16Factor) {
yFP <= iBottomFPDescription
TRUEnever evaluated
FALSEnever evaluated
0
910 const Q16Dot16 rowHeight = qMin(yFP + Q16Dot16Factor, yPb)-
911 - qMax(yFP, yPa);-
912 const int y = Q16Dot16ToInt(yFP);-
913 if (y > d->clipRect.bottom())
y > d->clipRect.bottom()Description
TRUEnever evaluated
FALSEnever evaluated
0
914 break;
never executed: break;
0
915 for (int i = 0; i < n; ++i) {
i < nDescription
TRUEnever evaluated
FALSEnever evaluated
0
916 buffer.addSpan(x[i], len[i], y,-
917 Q16Dot16ToInt(Q16Dot16Multiply(rowHeight, coverage[i])));-
918 }
never executed: end of block
0
919 }
never executed: end of block
0
920 } else { // aliased
never executed: end of block
0
921 int iTop = int(pa.y() + 0.5f);-
922 int iBottom = pb.y() < 0.5f ? -1 : int(pb.y() - 0.5f);
pb.y() < 0.5fDescription
TRUEnever evaluated
FALSEnever evaluated
0
923 int iLeft = int(left + 0.5f);-
924 int iRight = right < 0.5f ? -1 : int(right - 0.5f);
right < 0.5fDescription
TRUEnever evaluated
FALSEnever evaluated
0
925-
926 int iWidth = iRight - iLeft + 1;-
927 for (int y = iTop; y <= iBottom; ++y)
y <= iBottomDescription
TRUEnever evaluated
FALSEnever evaluated
0
928 buffer.addSpan(iLeft, iWidth, y, 255);
never executed: buffer.addSpan(iLeft, iWidth, y, 255);
0
929 }
never executed: end of block
0
930 } else {-
931 if (pa.y() > pb.y())
pa.y() > pb.y()Description
TRUEnever evaluated
FALSEnever evaluated
0
932 qSwap(pa, pb);
never executed: qSwap(pa, pb);
0
933-
934 QPointF delta = pb - pa;-
935 delta *= 0.5f * width;-
936 const QPointF perp(delta.y(), -delta.x());-
937-
938 QPointF top;-
939 QPointF left;-
940 QPointF right;-
941 QPointF bottom;-
942-
943 if (pa.x() < pb.x()) {
pa.x() < pb.x()Description
TRUEnever evaluated
FALSEnever evaluated
0
944 top = pa + perp;-
945 left = pa - perp;-
946 right = pb + perp;-
947 bottom = pb - perp;-
948 } else {
never executed: end of block
0
949 top = pa - perp;-
950 left = pb - perp;-
951 right = pa + perp;-
952 bottom = pb + perp;-
953 }
never executed: end of block
0
954-
955 top = snapTo26Dot6Grid(top);-
956 bottom = snapTo26Dot6Grid(bottom);-
957 left = snapTo26Dot6Grid(left);-
958 right = snapTo26Dot6Grid(right);-
959-
960 const qreal topBound = qBound(qreal(d->clipRect.top()), top.y(), qreal(d->clipRect.bottom()));-
961 const qreal bottomBound = qBound(qreal(d->clipRect.top()), bottom.y(), qreal(d->clipRect.bottom()));-
962-
963 const QPointF topLeftEdge = left - top;-
964 const QPointF topRightEdge = right - top;-
965 const QPointF bottomLeftEdge = bottom - left;-
966 const QPointF bottomRightEdge = bottom - right;-
967-
968 const qreal topLeftSlope = qSafeDivide(topLeftEdge.x(), topLeftEdge.y());-
969 const qreal bottomLeftSlope = qSafeDivide(bottomLeftEdge.x(), bottomLeftEdge.y());-
970-
971 const qreal topRightSlope = qSafeDivide(topRightEdge.x(), topRightEdge.y());-
972 const qreal bottomRightSlope = qSafeDivide(bottomRightEdge.x(), bottomRightEdge.y());-
973-
974 const Q16Dot16 topLeftSlopeFP = qSafeFloatToQ16Dot16(topLeftSlope);-
975 const Q16Dot16 topRightSlopeFP = qSafeFloatToQ16Dot16(topRightSlope);-
976-
977 const Q16Dot16 bottomLeftSlopeFP = qSafeFloatToQ16Dot16(bottomLeftSlope);-
978 const Q16Dot16 bottomRightSlopeFP = qSafeFloatToQ16Dot16(bottomRightSlope);-
979-
980 const Q16Dot16 invTopLeftSlopeFP = qSafeFloatToQ16Dot16(qSafeDivide(1, topLeftSlope));-
981 const Q16Dot16 invTopRightSlopeFP = qSafeFloatToQ16Dot16(qSafeDivide(1, topRightSlope));-
982-
983 const Q16Dot16 invBottomLeftSlopeFP = qSafeFloatToQ16Dot16(qSafeDivide(1, bottomLeftSlope));-
984 const Q16Dot16 invBottomRightSlopeFP = qSafeFloatToQ16Dot16(qSafeDivide(1, bottomRightSlope));-
985-
986 if (d->antialiased) {
d->antialiasedDescription
TRUEnever evaluated
FALSEnever evaluated
0
987 const Q16Dot16 iTopFP = IntToQ16Dot16(int(topBound));-
988 const Q16Dot16 iLeftFP = IntToQ16Dot16(int(left.y()));-
989 const Q16Dot16 iRightFP = IntToQ16Dot16(int(right.y()));-
990 const Q16Dot16 iBottomFP = IntToQ16Dot16(int(bottomBound));-
991-
992 Q16Dot16 leftIntersectAf = qSafeFloatToQ16Dot16(top.x() + (int(topBound) - top.y()) * topLeftSlope);-
993 Q16Dot16 rightIntersectAf = qSafeFloatToQ16Dot16(top.x() + (int(topBound) - top.y()) * topRightSlope);-
994 Q16Dot16 leftIntersectBf = 0;-
995 Q16Dot16 rightIntersectBf = 0;-
996-
997 if (iLeftFP < iTopFP)
iLeftFP < iTopFPDescription
TRUEnever evaluated
FALSEnever evaluated
0
998 leftIntersectBf = qSafeFloatToQ16Dot16(left.x() + (int(topBound) - left.y()) * bottomLeftSlope);
never executed: leftIntersectBf = qSafeFloatToQ16Dot16(left.x() + (int(topBound) - left.y()) * bottomLeftSlope);
0
999-
1000 if (iRightFP < iTopFP)
iRightFP < iTopFPDescription
TRUEnever evaluated
FALSEnever evaluated
0
1001 rightIntersectBf = qSafeFloatToQ16Dot16(right.x() + (int(topBound) - right.y()) * bottomRightSlope);
never executed: rightIntersectBf = qSafeFloatToQ16Dot16(right.x() + (int(topBound) - right.y()) * bottomRightSlope);
0
1002-
1003 Q16Dot16 rowTop, rowBottomLeft, rowBottomRight, rowTopLeft, rowTopRight, rowBottom;-
1004 Q16Dot16 topLeftIntersectAf, topLeftIntersectBf, topRightIntersectAf, topRightIntersectBf;-
1005 Q16Dot16 bottomLeftIntersectAf, bottomLeftIntersectBf, bottomRightIntersectAf, bottomRightIntersectBf;-
1006-
1007 int leftMin, leftMax, rightMin, rightMax;-
1008-
1009 const Q16Dot16 yTopFP = qSafeFloatToQ16Dot16(top.y());-
1010 const Q16Dot16 yLeftFP = qSafeFloatToQ16Dot16(left.y());-
1011 const Q16Dot16 yRightFP = qSafeFloatToQ16Dot16(right.y());-
1012 const Q16Dot16 yBottomFP = qSafeFloatToQ16Dot16(bottom.y());-
1013-
1014 rowTop = qMax(iTopFP, yTopFP);-
1015 topLeftIntersectAf = leftIntersectAf +-
1016 Q16Dot16Multiply(topLeftSlopeFP, rowTop - iTopFP);-
1017 topRightIntersectAf = rightIntersectAf +-
1018 Q16Dot16Multiply(topRightSlopeFP, rowTop - iTopFP);-
1019-
1020 Q16Dot16 yFP = iTopFP;-
1021 while (yFP <= iBottomFP) {
yFP <= iBottomFPDescription
TRUEnever evaluated
FALSEnever evaluated
0
1022 rowBottomLeft = qMin(yFP + Q16Dot16Factor, yLeftFP);-
1023 rowBottomRight = qMin(yFP + Q16Dot16Factor, yRightFP);-
1024 rowTopLeft = qMax(yFP, yLeftFP);-
1025 rowTopRight = qMax(yFP, yRightFP);-
1026 rowBottom = qMin(yFP + Q16Dot16Factor, yBottomFP);-
1027-
1028 if (yFP == iLeftFP) {
yFP == iLeftFPDescription
TRUEnever evaluated
FALSEnever evaluated
0
1029 const int y = Q16Dot16ToInt(yFP);-
1030 leftIntersectBf = qSafeFloatToQ16Dot16(left.x() + (y - left.y()) * bottomLeftSlope);-
1031 topLeftIntersectBf = leftIntersectBf + Q16Dot16Multiply(bottomLeftSlopeFP, rowTopLeft - yFP);-
1032 bottomLeftIntersectAf = leftIntersectAf + Q16Dot16Multiply(topLeftSlopeFP, rowBottomLeft - yFP);-
1033 } else {
never executed: end of block
0
1034 topLeftIntersectBf = leftIntersectBf;-
1035 bottomLeftIntersectAf = leftIntersectAf + topLeftSlopeFP;-
1036 }
never executed: end of block
0
1037-
1038 if (yFP == iRightFP) {
yFP == iRightFPDescription
TRUEnever evaluated
FALSEnever evaluated
0
1039 const int y = Q16Dot16ToInt(yFP);-
1040 rightIntersectBf = qSafeFloatToQ16Dot16(right.x() + (y - right.y()) * bottomRightSlope);-
1041 topRightIntersectBf = rightIntersectBf + Q16Dot16Multiply(bottomRightSlopeFP, rowTopRight - yFP);-
1042 bottomRightIntersectAf = rightIntersectAf + Q16Dot16Multiply(topRightSlopeFP, rowBottomRight - yFP);-
1043 } else {
never executed: end of block
0
1044 topRightIntersectBf = rightIntersectBf;-
1045 bottomRightIntersectAf = rightIntersectAf + topRightSlopeFP;-
1046 }
never executed: end of block
0
1047-
1048 if (yFP == iBottomFP) {
yFP == iBottomFPDescription
TRUEnever evaluated
FALSEnever evaluated
0
1049 bottomLeftIntersectBf = leftIntersectBf + Q16Dot16Multiply(bottomLeftSlopeFP, rowBottom - yFP);-
1050 bottomRightIntersectBf = rightIntersectBf + Q16Dot16Multiply(bottomRightSlopeFP, rowBottom - yFP);-
1051 } else {
never executed: end of block
0
1052 bottomLeftIntersectBf = leftIntersectBf + bottomLeftSlopeFP;-
1053 bottomRightIntersectBf = rightIntersectBf + bottomRightSlopeFP;-
1054 }
never executed: end of block
0
1055-
1056 if (yFP < iLeftFP) {
yFP < iLeftFPDescription
TRUEnever evaluated
FALSEnever evaluated
0
1057 leftMin = Q16Dot16ToInt(bottomLeftIntersectAf);-
1058 leftMax = Q16Dot16ToInt(topLeftIntersectAf);-
1059 } else if (yFP == iLeftFP) {
never executed: end of block
yFP == iLeftFPDescription
TRUEnever evaluated
FALSEnever evaluated
0
1060 leftMin = Q16Dot16ToInt(qMax(bottomLeftIntersectAf, topLeftIntersectBf));-
1061 leftMax = Q16Dot16ToInt(qMax(topLeftIntersectAf, bottomLeftIntersectBf));-
1062 } else {
never executed: end of block
0
1063 leftMin = Q16Dot16ToInt(topLeftIntersectBf);-
1064 leftMax = Q16Dot16ToInt(bottomLeftIntersectBf);-
1065 }
never executed: end of block
0
1066-
1067 leftMin = qBound(d->clipRect.left(), leftMin, d->clipRect.right());-
1068 leftMax = qBound(d->clipRect.left(), leftMax, d->clipRect.right());-
1069-
1070 if (yFP < iRightFP) {
yFP < iRightFPDescription
TRUEnever evaluated
FALSEnever evaluated
0
1071 rightMin = Q16Dot16ToInt(topRightIntersectAf);-
1072 rightMax = Q16Dot16ToInt(bottomRightIntersectAf);-
1073 } else if (yFP == iRightFP) {
never executed: end of block
yFP == iRightFPDescription
TRUEnever evaluated
FALSEnever evaluated
0
1074 rightMin = Q16Dot16ToInt(qMin(topRightIntersectAf, bottomRightIntersectBf));-
1075 rightMax = Q16Dot16ToInt(qMin(bottomRightIntersectAf, topRightIntersectBf));-
1076 } else {
never executed: end of block
0
1077 rightMin = Q16Dot16ToInt(bottomRightIntersectBf);-
1078 rightMax = Q16Dot16ToInt(topRightIntersectBf);-
1079 }
never executed: end of block
0
1080-
1081 rightMin = qBound(d->clipRect.left(), rightMin, d->clipRect.right());-
1082 rightMax = qBound(d->clipRect.left(), rightMax, d->clipRect.right());-
1083-
1084 if (leftMax > rightMax)
leftMax > rightMaxDescription
TRUEnever evaluated
FALSEnever evaluated
0
1085 leftMax = rightMax;
never executed: leftMax = rightMax;
0
1086 if (rightMin < leftMin)
rightMin < leftMinDescription
TRUEnever evaluated
FALSEnever evaluated
0
1087 rightMin = leftMin;
never executed: rightMin = leftMin;
0
1088-
1089 Q16Dot16 rowHeight = rowBottom - rowTop;-
1090-
1091 int x = leftMin;-
1092 while (x <= leftMax) {
x <= leftMaxDescription
TRUEnever evaluated
FALSEnever evaluated
0
1093 Q16Dot16 excluded = 0;-
1094-
1095 if (yFP <= iLeftFP)
yFP <= iLeftFPDescription
TRUEnever evaluated
FALSEnever evaluated
0
1096 excluded += intersectPixelFP(x, rowTop, rowBottomLeft,
never executed: excluded += intersectPixelFP(x, rowTop, rowBottomLeft, bottomLeftIntersectAf, topLeftIntersectAf, topLeftSlopeFP, invTopLeftSlopeFP);
0
1097 bottomLeftIntersectAf, topLeftIntersectAf,
never executed: excluded += intersectPixelFP(x, rowTop, rowBottomLeft, bottomLeftIntersectAf, topLeftIntersectAf, topLeftSlopeFP, invTopLeftSlopeFP);
0
1098 topLeftSlopeFP, invTopLeftSlopeFP);
never executed: excluded += intersectPixelFP(x, rowTop, rowBottomLeft, bottomLeftIntersectAf, topLeftIntersectAf, topLeftSlopeFP, invTopLeftSlopeFP);
0
1099 if (yFP >= iLeftFP)
yFP >= iLeftFPDescription
TRUEnever evaluated
FALSEnever evaluated
0
1100 excluded += intersectPixelFP(x, rowTopLeft, rowBottom,
never executed: excluded += intersectPixelFP(x, rowTopLeft, rowBottom, topLeftIntersectBf, bottomLeftIntersectBf, bottomLeftSlopeFP, invBottomLeftSlopeFP);
0
1101 topLeftIntersectBf, bottomLeftIntersectBf,
never executed: excluded += intersectPixelFP(x, rowTopLeft, rowBottom, topLeftIntersectBf, bottomLeftIntersectBf, bottomLeftSlopeFP, invBottomLeftSlopeFP);
0
1102 bottomLeftSlopeFP, invBottomLeftSlopeFP);
never executed: excluded += intersectPixelFP(x, rowTopLeft, rowBottom, topLeftIntersectBf, bottomLeftIntersectBf, bottomLeftSlopeFP, invBottomLeftSlopeFP);
0
1103-
1104 if (x >= rightMin) {
x >= rightMinDescription
TRUEnever evaluated
FALSEnever evaluated
0
1105 if (yFP <= iRightFP)
yFP <= iRightFPDescription
TRUEnever evaluated
FALSEnever evaluated
0
1106 excluded += (rowBottomRight - rowTop) - intersectPixelFP(x, rowTop, rowBottomRight,
never executed: excluded += (rowBottomRight - rowTop) - intersectPixelFP(x, rowTop, rowBottomRight, topRightIntersectAf, bottomRightIntersectAf, topRightSlopeFP, invTopRightSlopeFP);
0
1107 topRightIntersectAf, bottomRightIntersectAf,
never executed: excluded += (rowBottomRight - rowTop) - intersectPixelFP(x, rowTop, rowBottomRight, topRightIntersectAf, bottomRightIntersectAf, topRightSlopeFP, invTopRightSlopeFP);
0
1108 topRightSlopeFP, invTopRightSlopeFP);
never executed: excluded += (rowBottomRight - rowTop) - intersectPixelFP(x, rowTop, rowBottomRight, topRightIntersectAf, bottomRightIntersectAf, topRightSlopeFP, invTopRightSlopeFP);
0
1109 if (yFP >= iRightFP)
yFP >= iRightFPDescription
TRUEnever evaluated
FALSEnever evaluated
0
1110 excluded += (rowBottom - rowTopRight) - intersectPixelFP(x, rowTopRight, rowBottom,
never executed: excluded += (rowBottom - rowTopRight) - intersectPixelFP(x, rowTopRight, rowBottom, bottomRightIntersectBf, topRightIntersectBf, bottomRightSlopeFP, invBottomRightSlopeFP);
0
1111 bottomRightIntersectBf, topRightIntersectBf,
never executed: excluded += (rowBottom - rowTopRight) - intersectPixelFP(x, rowTopRight, rowBottom, bottomRightIntersectBf, topRightIntersectBf, bottomRightSlopeFP, invBottomRightSlopeFP);
0
1112 bottomRightSlopeFP, invBottomRightSlopeFP);
never executed: excluded += (rowBottom - rowTopRight) - intersectPixelFP(x, rowTopRight, rowBottom, bottomRightIntersectBf, topRightIntersectBf, bottomRightSlopeFP, invBottomRightSlopeFP);
0
1113 }
never executed: end of block
0
1114-
1115 Q16Dot16 coverage = rowHeight - excluded;-
1116 buffer.addSpan(x, 1, Q16Dot16ToInt(yFP),-
1117 Q16Dot16ToInt(255 * coverage));-
1118 ++x;-
1119 }
never executed: end of block
0
1120 if (x < rightMin) {
x < rightMinDescription
TRUEnever evaluated
FALSEnever evaluated
0
1121 buffer.addSpan(x, rightMin - x, Q16Dot16ToInt(yFP),-
1122 Q16Dot16ToInt(255 * rowHeight));-
1123 x = rightMin;-
1124 }
never executed: end of block
0
1125 while (x <= rightMax) {
x <= rightMaxDescription
TRUEnever evaluated
FALSEnever evaluated
0
1126 Q16Dot16 excluded = 0;-
1127 if (yFP <= iRightFP)
yFP <= iRightFPDescription
TRUEnever evaluated
FALSEnever evaluated
0
1128 excluded += (rowBottomRight - rowTop) - intersectPixelFP(x, rowTop, rowBottomRight,
never executed: excluded += (rowBottomRight - rowTop) - intersectPixelFP(x, rowTop, rowBottomRight, topRightIntersectAf, bottomRightIntersectAf, topRightSlopeFP, invTopRightSlopeFP);
0
1129 topRightIntersectAf, bottomRightIntersectAf,
never executed: excluded += (rowBottomRight - rowTop) - intersectPixelFP(x, rowTop, rowBottomRight, topRightIntersectAf, bottomRightIntersectAf, topRightSlopeFP, invTopRightSlopeFP);
0
1130 topRightSlopeFP, invTopRightSlopeFP);
never executed: excluded += (rowBottomRight - rowTop) - intersectPixelFP(x, rowTop, rowBottomRight, topRightIntersectAf, bottomRightIntersectAf, topRightSlopeFP, invTopRightSlopeFP);
0
1131 if (yFP >= iRightFP)
yFP >= iRightFPDescription
TRUEnever evaluated
FALSEnever evaluated
0
1132 excluded += (rowBottom - rowTopRight) - intersectPixelFP(x, rowTopRight, rowBottom,
never executed: excluded += (rowBottom - rowTopRight) - intersectPixelFP(x, rowTopRight, rowBottom, bottomRightIntersectBf, topRightIntersectBf, bottomRightSlopeFP, invBottomRightSlopeFP);
0
1133 bottomRightIntersectBf, topRightIntersectBf,
never executed: excluded += (rowBottom - rowTopRight) - intersectPixelFP(x, rowTopRight, rowBottom, bottomRightIntersectBf, topRightIntersectBf, bottomRightSlopeFP, invBottomRightSlopeFP);
0
1134 bottomRightSlopeFP, invBottomRightSlopeFP);
never executed: excluded += (rowBottom - rowTopRight) - intersectPixelFP(x, rowTopRight, rowBottom, bottomRightIntersectBf, topRightIntersectBf, bottomRightSlopeFP, invBottomRightSlopeFP);
0
1135-
1136 Q16Dot16 coverage = rowHeight - excluded;-
1137 buffer.addSpan(x, 1, Q16Dot16ToInt(yFP),-
1138 Q16Dot16ToInt(255 * coverage));-
1139 ++x;-
1140 }
never executed: end of block
0
1141-
1142 leftIntersectAf += topLeftSlopeFP;-
1143 leftIntersectBf += bottomLeftSlopeFP;-
1144 rightIntersectAf += topRightSlopeFP;-
1145 rightIntersectBf += bottomRightSlopeFP;-
1146 topLeftIntersectAf = leftIntersectAf;-
1147 topRightIntersectAf = rightIntersectAf;-
1148-
1149 yFP += Q16Dot16Factor;-
1150 rowTop = yFP;-
1151 }
never executed: end of block
0
1152 } else { // aliased
never executed: end of block
0
1153 int iTop = int(top.y() + 0.5f);-
1154 int iLeft = left.y() < 0.5f ? -1 : int(left.y() - 0.5f);
left.y() < 0.5fDescription
TRUEnever evaluated
FALSEnever evaluated
0
1155 int iRight = right.y() < 0.5f ? -1 : int(right.y() - 0.5f);
right.y() < 0.5fDescription
TRUEnever evaluated
FALSEnever evaluated
0
1156 int iBottom = bottom.y() < 0.5f? -1 : int(bottom.y() - 0.5f);
bottom.y() < 0.5fDescription
TRUEnever evaluated
FALSEnever evaluated
0
1157 int iMiddle = qMin(iLeft, iRight);-
1158-
1159 Q16Dot16 leftIntersectAf = qSafeFloatToQ16Dot16(top.x() + 0.5f + (iTop + 0.5f - top.y()) * topLeftSlope);-
1160 Q16Dot16 leftIntersectBf = qSafeFloatToQ16Dot16(left.x() + 0.5f + (iLeft + 1.5f - left.y()) * bottomLeftSlope);-
1161 Q16Dot16 rightIntersectAf = qSafeFloatToQ16Dot16(top.x() - 0.5f + (iTop + 0.5f - top.y()) * topRightSlope);-
1162 Q16Dot16 rightIntersectBf = qSafeFloatToQ16Dot16(right.x() - 0.5f + (iRight + 1.5f - right.y()) * bottomRightSlope);-
1163-
1164 int ny;-
1165 int y = iTop;-
1166#define DO_SEGMENT(next, li, ri, ls, rs) \-
1167 ny = qMin(next + 1, d->clipRect.top()); \-
1168 if (y < ny) { \-
1169 li += ls * (ny - y); \-
1170 ri += rs * (ny - y); \-
1171 y = ny; \-
1172 } \-
1173 if (next > d->clipRect.bottom()) \-
1174 next = d->clipRect.bottom(); \-
1175 for (; y <= next; ++y) { \-
1176 const int x1 = qMax(Q16Dot16ToInt(li), d->clipRect.left()); \-
1177 const int x2 = qMin(Q16Dot16ToInt(ri), d->clipRect.right()); \-
1178 if (x2 >= x1) \-
1179 buffer.addSpan(x1, x2 - x1 + 1, y, 255); \-
1180 li += ls; \-
1181 ri += rs; \-
1182 }-
1183-
1184 DO_SEGMENT(iMiddle, leftIntersectAf, rightIntersectAf, topLeftSlopeFP, topRightSlopeFP)
never executed: end of block
never executed: iMiddle = d->clipRect.bottom();
never executed: buffer.addSpan(x1, x2 - x1 + 1, y, 255);
never executed: end of block
y < nyDescription
TRUEnever evaluated
FALSEnever evaluated
iMiddle > d->clipRect.bottom()Description
TRUEnever evaluated
FALSEnever evaluated
x2 >= x1Description
TRUEnever evaluated
FALSEnever evaluated
y <= iMiddleDescription
TRUEnever evaluated
FALSEnever evaluated
0
1185 DO_SEGMENT(iRight, leftIntersectBf, rightIntersectAf, bottomLeftSlopeFP, topRightSlopeFP)
never executed: end of block
never executed: iRight = d->clipRect.bottom();
never executed: buffer.addSpan(x1, x2 - x1 + 1, y, 255);
never executed: end of block
y < nyDescription
TRUEnever evaluated
FALSEnever evaluated
iRight > d->clipRect.bottom()Description
TRUEnever evaluated
FALSEnever evaluated
x2 >= x1Description
TRUEnever evaluated
FALSEnever evaluated
y <= iRightDescription
TRUEnever evaluated
FALSEnever evaluated
0
1186 DO_SEGMENT(iLeft, leftIntersectAf, rightIntersectBf, topLeftSlopeFP, bottomRightSlopeFP);
never executed: end of block
never executed: iLeft = d->clipRect.bottom();
never executed: buffer.addSpan(x1, x2 - x1 + 1, y, 255);
never executed: end of block
y < nyDescription
TRUEnever evaluated
FALSEnever evaluated
iLeft > d->clipRect.bottom()Description
TRUEnever evaluated
FALSEnever evaluated
x2 >= x1Description
TRUEnever evaluated
FALSEnever evaluated
y <= iLeftDescription
TRUEnever evaluated
FALSEnever evaluated
0
1187 DO_SEGMENT(iBottom, leftIntersectBf, rightIntersectBf, bottomLeftSlopeFP, bottomRightSlopeFP);
never executed: end of block
never executed: iBottom = d->clipRect.bottom();
never executed: buffer.addSpan(x1, x2 - x1 + 1, y, 255);
never executed: end of block
y < nyDescription
TRUEnever evaluated
FALSEnever evaluated
iBottom > d->clipRect.bottom()Description
TRUEnever evaluated
FALSEnever evaluated
x2 >= x1Description
TRUEnever evaluated
FALSEnever evaluated
y <= iBottomDescription
TRUEnever evaluated
FALSEnever evaluated
0
1188#undef DO_SEGMENT-
1189 }
never executed: end of block
0
1190 }-
1191}-
1192-
1193void QRasterizer::rasterize(const QT_FT_Outline *outline, Qt::FillRule fillRule)-
1194{-
1195 if (outline->n_points < 3 || outline->n_contours == 0)
outline->n_points < 3Description
TRUEnever evaluated
FALSEnever evaluated
outline->n_contours == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1196 return;
never executed: return;
0
1197-
1198 const QT_FT_Vector *points = outline->points;-
1199-
1200 QSpanBuffer buffer(d->blend, d->data, d->clipRect);-
1201-
1202 // ### QT_FT_Outline already has a bounding rect which is-
1203 // ### precomputed at this point, so we should probably just be-
1204 // ### using that instead...-
1205 QT_FT_Pos min_y = points[0].y, max_y = points[0].y;-
1206 for (int i = 1; i < outline->n_points; ++i) {
i < outline->n_pointsDescription
TRUEnever evaluated
FALSEnever evaluated
0
1207 const QT_FT_Vector &p = points[i];-
1208 min_y = qMin(p.y, min_y);-
1209 max_y = qMax(p.y, max_y);-
1210 }
never executed: end of block
0
1211-
1212 int rounding = d->legacyRounding ? COORD_OFFSET - COORD_ROUNDING : 0;
d->legacyRoundingDescription
TRUEnever evaluated
FALSEnever evaluated
0
1213-
1214 int iTopBound = qMax(d->clipRect.top(), int((min_y + 32 + rounding) >> 6));-
1215 int iBottomBound = qMin(d->clipRect.bottom(), int((max_y - 32 + rounding) >> 6));-
1216-
1217 if (iTopBound > iBottomBound)
iTopBound > iBottomBoundDescription
TRUEnever evaluated
FALSEnever evaluated
0
1218 return;
never executed: return;
0
1219-
1220 d->scanConverter.begin(iTopBound, iBottomBound, d->clipRect.left(), d->clipRect.right(), fillRule, d->legacyRounding, &buffer);-
1221-
1222 int first = 0;-
1223 for (int i = 0; i < outline->n_contours; ++i) {
i < outline->n_contoursDescription
TRUEnever evaluated
FALSEnever evaluated
0
1224 const int last = outline->contours[i];-
1225 for (int j = first; j < last; ++j) {
j < lastDescription
TRUEnever evaluated
FALSEnever evaluated
0
1226 if (outline->tags[j+1] == QT_FT_CURVE_TAG_CUBIC) {
outline->tags[j+1] == 2Description
TRUEnever evaluated
FALSEnever evaluated
0
1227 Q_ASSERT(outline->tags[j+2] == QT_FT_CURVE_TAG_CUBIC);-
1228 d->scanConverter.mergeCurve(points[j], points[j+1], points[j+2], points[j+3]);-
1229 j += 2;-
1230 } else {
never executed: end of block
0
1231 d->scanConverter.mergeLine(points[j], points[j+1]);-
1232 }
never executed: end of block
0
1233 }-
1234-
1235 first = last + 1;-
1236 }
never executed: end of block
0
1237-
1238 d->scanConverter.end();-
1239}
never executed: end of block
0
1240-
1241void QRasterizer::rasterize(const QPainterPath &path, Qt::FillRule fillRule)-
1242{-
1243 if (path.isEmpty())
path.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
1244 return;
never executed: return;
0
1245-
1246 QSpanBuffer buffer(d->blend, d->data, d->clipRect);-
1247-
1248 QRectF bounds = path.controlPointRect();-
1249-
1250 double rounding = d->legacyRounding ? (COORD_OFFSET - COORD_ROUNDING) / 64. : 0.0;
d->legacyRoundingDescription
TRUEnever evaluated
FALSEnever evaluated
0
1251-
1252 int iTopBound = qMax(d->clipRect.top(), int(bounds.top() + 0.5 + rounding));-
1253 int iBottomBound = qMin(d->clipRect.bottom(), int(bounds.bottom() - 0.5 + rounding));-
1254-
1255 if (iTopBound > iBottomBound)
iTopBound > iBottomBoundDescription
TRUEnever evaluated
FALSEnever evaluated
0
1256 return;
never executed: return;
0
1257-
1258 d->scanConverter.begin(iTopBound, iBottomBound, d->clipRect.left(), d->clipRect.right(), fillRule, d->legacyRounding, &buffer);-
1259-
1260 int subpathStart = 0;-
1261 QT_FT_Vector last = { 0, 0 };-
1262 for (int i = 0; i < path.elementCount(); ++i) {
i < path.elementCount()Description
TRUEnever evaluated
FALSEnever evaluated
0
1263 switch (path.elementAt(i).type) {-
1264 case QPainterPath::LineToElement:
never executed: case QPainterPath::LineToElement:
0
1265 {-
1266 QT_FT_Vector p1 = last;-
1267 QT_FT_Vector p2 = PointToVector(path.elementAt(i));-
1268 d->scanConverter.mergeLine(p1, p2);-
1269 last = p2;-
1270 break;
never executed: break;
0
1271 }-
1272 case QPainterPath::MoveToElement:
never executed: case QPainterPath::MoveToElement:
0
1273 {-
1274 if (i != 0) {
i != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1275 QT_FT_Vector first = PointToVector(path.elementAt(subpathStart));-
1276 // close previous subpath-
1277 if (first.x != last.x || first.y != last.y)
first.x != last.xDescription
TRUEnever evaluated
FALSEnever evaluated
first.y != last.yDescription
TRUEnever evaluated
FALSEnever evaluated
0
1278 d->scanConverter.mergeLine(last, first);
never executed: d->scanConverter.mergeLine(last, first);
0
1279 }
never executed: end of block
0
1280 subpathStart = i;-
1281 last = PointToVector(path.elementAt(i));-
1282 break;
never executed: break;
0
1283 }-
1284 case QPainterPath::CurveToElement:
never executed: case QPainterPath::CurveToElement:
0
1285 {-
1286 QT_FT_Vector p1 = last;-
1287 QT_FT_Vector p2 = PointToVector(path.elementAt(i));-
1288 QT_FT_Vector p3 = PointToVector(path.elementAt(++i));-
1289 QT_FT_Vector p4 = PointToVector(path.elementAt(++i));-
1290 d->scanConverter.mergeCurve(p1, p2, p3, p4);-
1291 last = p4;-
1292 break;
never executed: break;
0
1293 }-
1294 default:
never executed: default:
0
1295 Q_ASSERT(false);-
1296 break;
never executed: break;
0
1297 }-
1298 }-
1299-
1300 QT_FT_Vector first = PointToVector(path.elementAt(subpathStart));-
1301-
1302 // close path-
1303 if (first.x != last.x || first.y != last.y)
first.x != last.xDescription
TRUEnever evaluated
FALSEnever evaluated
first.y != last.yDescription
TRUEnever evaluated
FALSEnever evaluated
0
1304 d->scanConverter.mergeLine(last, first);
never executed: d->scanConverter.mergeLine(last, first);
0
1305-
1306 d->scanConverter.end();-
1307}
never executed: end of block
0
1308-
1309QT_END_NAMESPACE-
Source codeSwitch to Preprocessed file

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