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

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