qcosmeticstroker.cpp

Absolute File Name:/home/qt/qt5_coco/qt5/qtbase/src/gui/painting/qcosmeticstroker.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 "qcosmeticstroker_p.h"-
35#include "private/qpainterpath_p.h"-
36#include "private/qrgba64_p.h"-
37#include <qdebug.h>-
38-
39QT_BEGIN_NAMESPACE-
40-
41#if 0-
42inline QString capString(int caps)-
43{-
44 QString str;-
45 if (caps & QCosmeticStroker::CapBegin) {-
46 str += "CapBegin ";-
47 }-
48 if (caps & QCosmeticStroker::CapEnd) {-
49 str += "CapEnd ";-
50 }-
51 return str;-
52}-
53#endif-
54-
55#define toF26Dot6(x) ((int)((x)*64.))-
56-
57static inline uint sourceOver(uint d, uint color)-
58{-
59 return color + BYTE_MUL(d, qAlpha(~color));
never executed: return color + BYTE_MUL(d, qAlpha(~color));
0
60}-
61-
62inline static int F16Dot16FixedDiv(int x, int y)-
63{-
64 if (qAbs(x) > 0x7fff)
qAbs(x) > 0x7fffDescription
TRUEnever evaluated
FALSEnever evaluated
0
65 return qlonglong(x) * (1<<16) / y;
never executed: return qlonglong(x) * (1<<16) / y;
0
66 return x * (1<<16) / y;
never executed: return x * (1<<16) / y;
0
67}-
68-
69typedef void (*DrawPixel)(QCosmeticStroker *stroker, int x, int y, int coverage);-
70-
71namespace {-
72-
73struct Dasher {-
74 QCosmeticStroker *stroker;-
75 int *pattern;-
76 int offset;-
77 int dashIndex;-
78 int dashOn;-
79-
80 Dasher(QCosmeticStroker *s, bool reverse, int start, int stop)-
81 : stroker(s)-
82 {-
83 int delta = stop - start;-
84 if (reverse) {
reverseDescription
TRUEnever evaluated
FALSEnever evaluated
0
85 pattern = stroker->reversePattern;-
86 offset = stroker->patternLength - stroker->patternOffset - delta - ((start & 63) - 32);-
87 dashOn = 0;-
88 } else {
never executed: end of block
0
89 pattern = stroker->pattern;-
90 offset = stroker->patternOffset - ((start & 63) - 32);-
91 dashOn = 1;-
92 }
never executed: end of block
0
93 offset %= stroker->patternLength;-
94 if (offset < 0)
offset < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
95 offset += stroker->patternLength;
never executed: offset += stroker->patternLength;
0
96-
97 dashIndex = 0;-
98 while (offset>= pattern[dashIndex])
offset>= pattern[dashIndex]Description
TRUEnever evaluated
FALSEnever evaluated
0
99 ++dashIndex;
never executed: ++dashIndex;
0
100-
101// qDebug() << " dasher" << offset/64. << reverse << dashIndex;-
102 stroker->patternOffset += delta;-
103 stroker->patternOffset %= stroker->patternLength;-
104 }
never executed: end of block
0
105-
106 bool on() const {-
107 return (dashIndex + dashOn) & 1;
never executed: return (dashIndex + dashOn) & 1;
0
108 }-
109 void adjust() {-
110 offset += 64;-
111 if (offset >= pattern[dashIndex]) {
offset >= pattern[dashIndex]Description
TRUEnever evaluated
FALSEnever evaluated
0
112 ++dashIndex;-
113 dashIndex %= stroker->patternSize;-
114 }
never executed: end of block
0
115 offset %= stroker->patternLength;-
116// qDebug() << "dasher.adjust" << offset/64. << dashIndex;-
117 }
never executed: end of block
0
118};-
119-
120struct NoDasher {-
121 NoDasher(QCosmeticStroker *, bool, int, int) {}-
122 bool on() const { return true; }
never executed: return true;
0
123 void adjust(int = 0) {}-
124};-
125-
126};-
127-
128/*-
129 * The return value is the result of the clipLine() call performed at the start-
130 * of each of the two functions, aka "false" means completely outside the devices-
131 * rect.-
132 */-
133template<DrawPixel drawPixel, class Dasher>-
134static bool drawLine(QCosmeticStroker *stroker, qreal x1, qreal y1, qreal x2, qreal y2, int caps);-
135template<DrawPixel drawPixel, class Dasher>-
136static bool drawLineAA(QCosmeticStroker *stroker, qreal x1, qreal y1, qreal x2, qreal y2, int caps);-
137-
138inline void drawPixel(QCosmeticStroker *stroker, int x, int y, int coverage)-
139{-
140 const QRect &cl = stroker->clip;-
141 if (x < cl.x() || x > cl.right() || y < cl.y() || y > cl.bottom())
x < cl.x()Description
TRUEnever evaluated
FALSEnever evaluated
x > cl.right()Description
TRUEnever evaluated
FALSEnever evaluated
y < cl.y()Description
TRUEnever evaluated
FALSEnever evaluated
y > cl.bottom()Description
TRUEnever evaluated
FALSEnever evaluated
0
142 return;
never executed: return;
0
143-
144 if (stroker->current_span > 0) {
stroker->current_span > 0Description
TRUEnever evaluated
FALSEnever evaluated
0
145 const int lastx = stroker->spans[stroker->current_span-1].x + stroker->spans[stroker->current_span-1].len ;-
146 const int lasty = stroker->spans[stroker->current_span-1].y;-
147-
148 if (stroker->current_span == QCosmeticStroker::NSPANS || y < lasty || (y == lasty && x < lastx)) {
stroker->curre...troker::NSPANSDescription
TRUEnever evaluated
FALSEnever evaluated
y < lastyDescription
TRUEnever evaluated
FALSEnever evaluated
y == lastyDescription
TRUEnever evaluated
FALSEnever evaluated
x < lastxDescription
TRUEnever evaluated
FALSEnever evaluated
0
149 stroker->blend(stroker->current_span, stroker->spans, &stroker->state->penData);-
150 stroker->current_span = 0;-
151 }
never executed: end of block
0
152 }
never executed: end of block
0
153-
154 stroker->spans[stroker->current_span].x = ushort(x);-
155 stroker->spans[stroker->current_span].len = 1;-
156 stroker->spans[stroker->current_span].y = y;-
157 stroker->spans[stroker->current_span].coverage = coverage*stroker->opacity >> 8;-
158 ++stroker->current_span;-
159}
never executed: end of block
0
160-
161inline void drawPixelARGB32(QCosmeticStroker *stroker, int x, int y, int coverage)-
162{-
163 const QRect &cl = stroker->clip;-
164 if (x < cl.x() || x > cl.right() || y < cl.y() || y > cl.bottom())
x < cl.x()Description
TRUEnever evaluated
FALSEnever evaluated
x > cl.right()Description
TRUEnever evaluated
FALSEnever evaluated
y < cl.y()Description
TRUEnever evaluated
FALSEnever evaluated
y > cl.bottom()Description
TRUEnever evaluated
FALSEnever evaluated
0
165 return;
never executed: return;
0
166-
167 int offset = x + stroker->ppl*y;-
168 uint c = BYTE_MUL(stroker->color, coverage);-
169 stroker->pixels[offset] = sourceOver(stroker->pixels[offset], c);-
170}
never executed: end of block
0
171-
172inline void drawPixelARGB32Opaque(QCosmeticStroker *stroker, int x, int y, int)-
173{-
174 const QRect &cl = stroker->clip;-
175 if (x < cl.x() || x > cl.right() || y < cl.y() || y > cl.bottom())
x < cl.x()Description
TRUEnever evaluated
FALSEnever evaluated
x > cl.right()Description
TRUEnever evaluated
FALSEnever evaluated
y < cl.y()Description
TRUEnever evaluated
FALSEnever evaluated
y > cl.bottom()Description
TRUEnever evaluated
FALSEnever evaluated
0
176 return;
never executed: return;
0
177-
178 int offset = x + stroker->ppl*y;-
179 stroker->pixels[offset] = sourceOver(stroker->pixels[offset], stroker->color);-
180}
never executed: end of block
0
181-
182enum StrokeSelection {-
183 Aliased = 0,-
184 AntiAliased = 1,-
185 Solid = 0,-
186 Dashed = 2,-
187 RegularDraw = 0,-
188 FastDraw = 4-
189};-
190-
191static StrokeLine strokeLine(int strokeSelection)-
192{-
193 StrokeLine stroke;-
194-
195 switch (strokeSelection) {-
196 case Aliased|Solid|RegularDraw:
never executed: case Aliased|Solid|RegularDraw:
0
197 stroke = &QT_PREPEND_NAMESPACE(drawLine)<drawPixel, NoDasher>;-
198 break;
never executed: break;
0
199 case Aliased|Solid|FastDraw:
never executed: case Aliased|Solid|FastDraw:
0
200 stroke = &QT_PREPEND_NAMESPACE(drawLine)<drawPixelARGB32Opaque, NoDasher>;-
201 break;
never executed: break;
0
202 case Aliased|Dashed|RegularDraw:
never executed: case Aliased|Dashed|RegularDraw:
0
203 stroke = &QT_PREPEND_NAMESPACE(drawLine)<drawPixel, Dasher>;-
204 break;
never executed: break;
0
205 case Aliased|Dashed|FastDraw:
never executed: case Aliased|Dashed|FastDraw:
0
206 stroke = &QT_PREPEND_NAMESPACE(drawLine)<drawPixelARGB32Opaque, Dasher>;-
207 break;
never executed: break;
0
208 case AntiAliased|Solid|RegularDraw:
never executed: case AntiAliased|Solid|RegularDraw:
0
209 stroke = &QT_PREPEND_NAMESPACE(drawLineAA)<drawPixel, NoDasher>;-
210 break;
never executed: break;
0
211 case AntiAliased|Solid|FastDraw:
never executed: case AntiAliased|Solid|FastDraw:
0
212 stroke = &QT_PREPEND_NAMESPACE(drawLineAA)<drawPixelARGB32, NoDasher>;-
213 break;
never executed: break;
0
214 case AntiAliased|Dashed|RegularDraw:
never executed: case AntiAliased|Dashed|RegularDraw:
0
215 stroke = &QT_PREPEND_NAMESPACE(drawLineAA)<drawPixel, Dasher>;-
216 break;
never executed: break;
0
217 case AntiAliased|Dashed|FastDraw:
never executed: case AntiAliased|Dashed|FastDraw:
0
218 stroke = &QT_PREPEND_NAMESPACE(drawLineAA)<drawPixelARGB32, Dasher>;-
219 break;
never executed: break;
0
220 default:
never executed: default:
0
221 Q_ASSERT(false);-
222 stroke = 0;-
223 }
never executed: end of block
0
224 return stroke;
never executed: return stroke;
0
225}-
226-
227void QCosmeticStroker::setup()-
228{-
229 blend = state->penData.blend;-
230 if (state->clip && state->clip->enabled && state->clip->hasRectClip && !state->clip->clipRect.isEmpty()) {
state->clipDescription
TRUEnever evaluated
FALSEnever evaluated
state->clip->enabledDescription
TRUEnever evaluated
FALSEnever evaluated
state->clip->hasRectClipDescription
TRUEnever evaluated
FALSEnever evaluated
!state->clip->...Rect.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
231 clip &= state->clip->clipRect;-
232 blend = state->penData.unclipped_blend;-
233 }
never executed: end of block
0
234-
235 int strokeSelection = 0;-
236 if (blend == state->penData.unclipped_blend
blend == state...nclipped_blendDescription
TRUEnever evaluated
FALSEnever evaluated
0
237 && state->penData.type == QSpanData::Solid
state->penData...panData::SolidDescription
TRUEnever evaluated
FALSEnever evaluated
0
238 && (state->penData.rasterBuffer->format == QImage::Format_ARGB32_Premultiplied
state->penData..._PremultipliedDescription
TRUEnever evaluated
FALSEnever evaluated
0
239 || state->penData.rasterBuffer->format == QImage::Format_RGB32)
state->penData...::Format_RGB32Description
TRUEnever evaluated
FALSEnever evaluated
0
240 && state->compositionMode() == QPainter::CompositionMode_SourceOver)
state->composi...ode_SourceOverDescription
TRUEnever evaluated
FALSEnever evaluated
0
241 strokeSelection |= FastDraw;
never executed: strokeSelection |= FastDraw;
0
242-
243 if (state->renderHints & QPainter::Antialiasing)
state->renderH...::AntialiasingDescription
TRUEnever evaluated
FALSEnever evaluated
0
244 strokeSelection |= AntiAliased;
never executed: strokeSelection |= AntiAliased;
0
245-
246 const QVector<qreal> &penPattern = state->lastPen.dashPattern();-
247 if (penPattern.isEmpty()) {
penPattern.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
248 Q_ASSERT(!pattern && !reversePattern);-
249 pattern = 0;-
250 reversePattern = 0;-
251 patternLength = 0;-
252 patternSize = 0;-
253 } else {
never executed: end of block
0
254 pattern = (int *)malloc(penPattern.size()*sizeof(int));-
255 reversePattern = (int *)malloc(penPattern.size()*sizeof(int));-
256 patternSize = penPattern.size();-
257-
258 patternLength = 0;-
259 for (int i = 0; i < patternSize; ++i) {
i < patternSizeDescription
TRUEnever evaluated
FALSEnever evaluated
0
260 patternLength += (int) qMax(1. , penPattern.at(i)*64.);-
261 pattern[i] = patternLength;-
262 }
never executed: end of block
0
263 patternLength = 0;-
264 for (int i = 0; i < patternSize; ++i) {
i < patternSizeDescription
TRUEnever evaluated
FALSEnever evaluated
0
265 patternLength += (int) qMax(1., penPattern.at(patternSize - 1 - i)*64.);-
266 reversePattern[i] = patternLength;-
267 }
never executed: end of block
0
268 strokeSelection |= Dashed;-
269// qDebug() << "setup: size=" << patternSize << "length=" << patternLength/64.;-
270 }
never executed: end of block
0
271-
272 stroke = strokeLine(strokeSelection);-
273-
274 qreal width = state->lastPen.widthF();-
275 if (width == 0)
width == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
276 opacity = 256;
never executed: opacity = 256;
0
277 else if (qt_pen_is_cosmetic(state->lastPen, state->renderHints))
qt_pen_is_cosm...->renderHints)Description
TRUEnever evaluated
FALSEnever evaluated
0
278 opacity = (int) 256*width;
never executed: opacity = (int) 256*width;
0
279 else-
280 opacity = (int) 256*width*state->txscale;
never executed: opacity = (int) 256*width*state->txscale;
0
281 opacity = qBound(0, opacity, 256);-
282-
283 drawCaps = state->lastPen.capStyle() != Qt::FlatCap;-
284-
285 if (strokeSelection & FastDraw) {
strokeSelection & FastDrawDescription
TRUEnever evaluated
FALSEnever evaluated
0
286 color = multiplyAlpha256(state->penData.solid.color, opacity).toArgb32();-
287 QRasterBuffer *buffer = state->penData.rasterBuffer;-
288 pixels = (uint *)buffer->buffer();-
289 ppl = buffer->bytesPerLine()>>2;-
290 }
never executed: end of block
0
291-
292 // line drawing produces different results with different clips, so-
293 // we need to clip consistently when painting to the same device-
294-
295 // setup FP clip bounds-
296 xmin = deviceRect.left() - 1;-
297 xmax = deviceRect.right() + 2;-
298 ymin = deviceRect.top() - 1;-
299 ymax = deviceRect.bottom() + 2;-
300-
301 lastPixel.x = -1;-
302 lastPixel.y = -1;-
303}
never executed: end of block
0
304-
305// returns true if the whole line gets clipped away-
306bool QCosmeticStroker::clipLine(qreal &x1, qreal &y1, qreal &x2, qreal &y2)-
307{-
308 // basic/rough clipping is done in floating point coordinates to avoid-
309 // integer overflow problems.-
310 if (x1 < xmin) {
x1 < xminDescription
TRUEnever evaluated
FALSEnever evaluated
0
311 if (x2 <= xmin)
x2 <= xminDescription
TRUEnever evaluated
FALSEnever evaluated
0
312 goto clipped;
never executed: goto clipped;
0
313 y1 += (y2 - y1)/(x2 - x1) * (xmin - x1);-
314 x1 = xmin;-
315 } else if (x1 > xmax) {
never executed: end of block
x1 > xmaxDescription
TRUEnever evaluated
FALSEnever evaluated
0
316 if (x2 >= xmax)
x2 >= xmaxDescription
TRUEnever evaluated
FALSEnever evaluated
0
317 goto clipped;
never executed: goto clipped;
0
318 y1 += (y2 - y1)/(x2 - x1) * (xmax - x1);-
319 x1 = xmax;-
320 }
never executed: end of block
0
321 if (x2 < xmin) {
x2 < xminDescription
TRUEnever evaluated
FALSEnever evaluated
0
322 lastPixel.x = -1;-
323 y2 += (y2 - y1)/(x2 - x1) * (xmin - x2);-
324 x2 = xmin;-
325 } else if (x2 > xmax) {
never executed: end of block
x2 > xmaxDescription
TRUEnever evaluated
FALSEnever evaluated
0
326 lastPixel.x = -1;-
327 y2 += (y2 - y1)/(x2 - x1) * (xmax - x2);-
328 x2 = xmax;-
329 }
never executed: end of block
0
330-
331 if (y1 < ymin) {
y1 < yminDescription
TRUEnever evaluated
FALSEnever evaluated
0
332 if (y2 <= ymin)
y2 <= yminDescription
TRUEnever evaluated
FALSEnever evaluated
0
333 goto clipped;
never executed: goto clipped;
0
334 x1 += (x2 - x1)/(y2 - y1) * (ymin - y1);-
335 y1 = ymin;-
336 } else if (y1 > ymax) {
never executed: end of block
y1 > ymaxDescription
TRUEnever evaluated
FALSEnever evaluated
0
337 if (y2 >= ymax)
y2 >= ymaxDescription
TRUEnever evaluated
FALSEnever evaluated
0
338 goto clipped;
never executed: goto clipped;
0
339 x1 += (x2 - x1)/(y2 - y1) * (ymax - y1);-
340 y1 = ymax;-
341 }
never executed: end of block
0
342 if (y2 < ymin) {
y2 < yminDescription
TRUEnever evaluated
FALSEnever evaluated
0
343 lastPixel.x = -1;-
344 x2 += (x2 - x1)/(y2 - y1) * (ymin - y2);-
345 y2 = ymin;-
346 } else if (y2 > ymax) {
never executed: end of block
y2 > ymaxDescription
TRUEnever evaluated
FALSEnever evaluated
0
347 lastPixel.x = -1;-
348 x2 += (x2 - x1)/(y2 - y1) * (ymax - y2);-
349 y2 = ymax;-
350 }
never executed: end of block
0
351-
352 return false;
never executed: return false;
0
353-
354 clipped:-
355 lastPixel.x = -1;-
356 return true;
never executed: return true;
0
357}-
358-
359-
360void QCosmeticStroker::drawLine(const QPointF &p1, const QPointF &p2)-
361{-
362 if (p1 == p2) {
p1 == p2Description
TRUEnever evaluated
FALSEnever evaluated
0
363 drawPoints(&p1, 1);-
364 return;
never executed: return;
0
365 }-
366-
367 QPointF start = p1 * state->matrix;-
368 QPointF end = p2 * state->matrix;-
369-
370 patternOffset = state->lastPen.dashOffset()*64;-
371 lastPixel.x = -1;-
372-
373 stroke(this, start.x(), start.y(), end.x(), end.y(), drawCaps ? CapBegin|CapEnd : 0);-
374-
375 blend(current_span, spans, &state->penData);-
376 current_span = 0;-
377}
never executed: end of block
0
378-
379void QCosmeticStroker::drawPoints(const QPoint *points, int num)-
380{-
381 const QPoint *end = points + num;-
382 while (points < end) {
points < endDescription
TRUEnever evaluated
FALSEnever evaluated
0
383 QPointF p = QPointF(*points) * state->matrix;-
384 drawPixel(this, qRound(p.x()), qRound(p.y()), 255);-
385 ++points;-
386 }
never executed: end of block
0
387-
388 blend(current_span, spans, &state->penData);-
389 current_span = 0;-
390}
never executed: end of block
0
391-
392void QCosmeticStroker::drawPoints(const QPointF *points, int num)-
393{-
394 const QPointF *end = points + num;-
395 while (points < end) {
points < endDescription
TRUEnever evaluated
FALSEnever evaluated
0
396 QPointF p = (*points) * state->matrix;-
397 drawPixel(this, qRound(p.x()), qRound(p.y()), 255);-
398 ++points;-
399 }
never executed: end of block
0
400-
401 blend(current_span, spans, &state->penData);-
402 current_span = 0;-
403}
never executed: end of block
0
404-
405void QCosmeticStroker::calculateLastPoint(qreal rx1, qreal ry1, qreal rx2, qreal ry2)-
406{-
407 // this is basically the same code as used in the aliased stroke method,-
408 // but it only determines the direction and last point of a line-
409 //-
410 // This is being used to have proper dropout control for closed contours-
411 // by calculating the direction and last pixel of the last segment in the contour.-
412 // the info is then used to perform dropout control when drawing the first line segment-
413 // of the contour-
414 lastPixel.x = -1;-
415 lastPixel.y = -1;-
416-
417 if (clipLine(rx1, ry1, rx2, ry2))
clipLine(rx1, ry1, rx2, ry2)Description
TRUEnever evaluated
FALSEnever evaluated
0
418 return;
never executed: return;
0
419-
420 const int half = legacyRounding ? 31 : 0;
legacyRoundingDescription
TRUEnever evaluated
FALSEnever evaluated
0
421 int x1 = toF26Dot6(rx1) + half;-
422 int y1 = toF26Dot6(ry1) + half;-
423 int x2 = toF26Dot6(rx2) + half;-
424 int y2 = toF26Dot6(ry2) + half;-
425-
426 int dx = qAbs(x2 - x1);-
427 int dy = qAbs(y2 - y1);-
428-
429 if (dx < dy) {
dx < dyDescription
TRUEnever evaluated
FALSEnever evaluated
0
430 // vertical-
431 bool swapped = false;-
432 if (y1 > y2) {
y1 > y2Description
TRUEnever evaluated
FALSEnever evaluated
0
433 swapped = true;-
434 qSwap(y1, y2);-
435 qSwap(x1, x2);-
436 }
never executed: end of block
0
437 int xinc = F16Dot16FixedDiv(x2 - x1, y2 - y1);-
438 int x = x1 * (1<<10);-
439-
440 int y = (y1 + 32) >> 6;-
441 int ys = (y2 + 32) >> 6;-
442-
443 int round = (xinc > 0) ? 32 : 0;
(xinc > 0)Description
TRUEnever evaluated
FALSEnever evaluated
0
444 if (y != ys) {
y != ysDescription
TRUEnever evaluated
FALSEnever evaluated
0
445 x += ((y * (1<<6)) + round - y1) * xinc >> 6;-
446-
447 if (swapped) {
swappedDescription
TRUEnever evaluated
FALSEnever evaluated
0
448 lastPixel.x = x >> 16;-
449 lastPixel.y = y;-
450 lastDir = QCosmeticStroker::BottomToTop;-
451 } else {
never executed: end of block
0
452 lastPixel.x = (x + (ys - y - 1)*xinc) >> 16;-
453 lastPixel.y = ys - 1;-
454 lastDir = QCosmeticStroker::TopToBottom;-
455 }
never executed: end of block
0
456 lastAxisAligned = qAbs(xinc) < (1 << 14);-
457 }
never executed: end of block
0
458 } else {
never executed: end of block
0
459 // horizontal-
460 if (!dx)
!dxDescription
TRUEnever evaluated
FALSEnever evaluated
0
461 return;
never executed: return;
0
462-
463 bool swapped = false;-
464 if (x1 > x2) {
x1 > x2Description
TRUEnever evaluated
FALSEnever evaluated
0
465 swapped = true;-
466 qSwap(x1, x2);-
467 qSwap(y1, y2);-
468 }
never executed: end of block
0
469 int yinc = F16Dot16FixedDiv(y2 - y1, x2 - x1);-
470 int y = y1 << 10;-
471-
472 int x = (x1 + 32) >> 6;-
473 int xs = (x2 + 32) >> 6;-
474-
475 int round = (yinc > 0) ? 32 : 0;
(yinc > 0)Description
TRUEnever evaluated
FALSEnever evaluated
0
476 if (x != xs) {
x != xsDescription
TRUEnever evaluated
FALSEnever evaluated
0
477 y += ((x * (1<<6)) + round - x1) * yinc >> 6;-
478-
479 if (swapped) {
swappedDescription
TRUEnever evaluated
FALSEnever evaluated
0
480 lastPixel.x = x;-
481 lastPixel.y = y >> 16;-
482 lastDir = QCosmeticStroker::RightToLeft;-
483 } else {
never executed: end of block
0
484 lastPixel.x = xs - 1;-
485 lastPixel.y = (y + (xs - x - 1)*yinc) >> 16;-
486 lastDir = QCosmeticStroker::LeftToRight;-
487 }
never executed: end of block
0
488 lastAxisAligned = qAbs(yinc) < (1 << 14);-
489 }
never executed: end of block
0
490 }
never executed: end of block
0
491// qDebug() << " moveTo: setting last pixel to x/y dir" << lastPixel.x << lastPixel.y << lastDir;-
492}-
493-
494static inline const QPainterPath::ElementType *subPath(const QPainterPath::ElementType *t, const QPainterPath::ElementType *end,-
495 const qreal *points, bool *closed)-
496{-
497 const QPainterPath::ElementType *start = t;-
498 ++t;-
499-
500 // find out if the subpath is closed-
501 while (t < end) {
t < endDescription
TRUEnever evaluated
FALSEnever evaluated
0
502 if (*t == QPainterPath::MoveToElement)
*t == QPainter...:MoveToElementDescription
TRUEnever evaluated
FALSEnever evaluated
0
503 break;
never executed: break;
0
504 ++t;-
505 }
never executed: end of block
0
506-
507 int offset = t - start - 1;-
508// qDebug() << "subpath" << offset << points[0] << points[1] << points[2*offset] << points[2*offset+1];-
509 *closed = (points[0] == points[2*offset] && points[1] == points[2*offset + 1]);
points[0] == points[2*offset]Description
TRUEnever evaluated
FALSEnever evaluated
points[1] == p...[2*offset + 1]Description
TRUEnever evaluated
FALSEnever evaluated
0
510-
511 return t;
never executed: return t;
0
512}-
513-
514void QCosmeticStroker::drawPath(const QVectorPath &path)-
515{-
516// qDebug() << ">>>> drawpath" << path.convertToPainterPath()-
517// << "antialiasing:" << (bool)(state->renderHints & QPainter::Antialiasing) << " implicit close:" << path.hasImplicitClose();-
518 if (path.isEmpty())
path.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
519 return;
never executed: return;
0
520-
521 const qreal *points = path.points();-
522 const QPainterPath::ElementType *type = path.elements();-
523-
524 if (type) {
typeDescription
TRUEnever evaluated
FALSEnever evaluated
0
525 const QPainterPath::ElementType *end = type + path.elementCount();-
526-
527 while (type < end) {
type < endDescription
TRUEnever evaluated
FALSEnever evaluated
0
528 Q_ASSERT(type == path.elements() || *type == QPainterPath::MoveToElement);-
529-
530 QPointF p = QPointF(points[0], points[1]) * state->matrix;-
531 patternOffset = state->lastPen.dashOffset()*64;-
532 lastPixel.x = INT_MIN;-
533 lastPixel.y = INT_MIN;-
534-
535 bool closed;-
536 const QPainterPath::ElementType *e = subPath(type, end, points, &closed);-
537 if (closed) {
closedDescription
TRUEnever evaluated
FALSEnever evaluated
0
538 const qreal *p = points + 2*(e-type);-
539 QPointF p1 = QPointF(p[-4], p[-3]) * state->matrix;-
540 QPointF p2 = QPointF(p[-2], p[-1]) * state->matrix;-
541 calculateLastPoint(p1.x(), p1.y(), p2.x(), p2.y());-
542 }
never executed: end of block
0
543 int caps = (!closed & drawCaps) ? CapBegin : NoCaps;
(!closed & drawCaps)Description
TRUEnever evaluated
FALSEnever evaluated
0
544// qDebug() << "closed =" << closed << capString(caps);-
545-
546 points += 2;-
547 ++type;-
548-
549 while (type < e) {
type < eDescription
TRUEnever evaluated
FALSEnever evaluated
0
550 QPointF p2 = QPointF(points[0], points[1]) * state->matrix;-
551 switch (*type) {-
552 case QPainterPath::MoveToElement:
never executed: case QPainterPath::MoveToElement:
0
553 Q_ASSERT(!"Logic error");-
554 break;
never executed: break;
0
555-
556 case QPainterPath::LineToElement:
never executed: case QPainterPath::LineToElement:
0
557 if (!closed && drawCaps && type == e - 1)
!closedDescription
TRUEnever evaluated
FALSEnever evaluated
drawCapsDescription
TRUEnever evaluated
FALSEnever evaluated
type == e - 1Description
TRUEnever evaluated
FALSEnever evaluated
0
558 caps |= CapEnd;
never executed: caps |= CapEnd;
0
559 stroke(this, p.x(), p.y(), p2.x(), p2.y(), caps);-
560 p = p2;-
561 points += 2;-
562 ++type;-
563 break;
never executed: break;
0
564-
565 case QPainterPath::CurveToElement: {
never executed: case QPainterPath::CurveToElement:
0
566 if (!closed && drawCaps && type == e - 3)
!closedDescription
TRUEnever evaluated
FALSEnever evaluated
drawCapsDescription
TRUEnever evaluated
FALSEnever evaluated
type == e - 3Description
TRUEnever evaluated
FALSEnever evaluated
0
567 caps |= CapEnd;
never executed: caps |= CapEnd;
0
568 QPointF p3 = QPointF(points[2], points[3]) * state->matrix;-
569 QPointF p4 = QPointF(points[4], points[5]) * state->matrix;-
570 renderCubic(p, p2, p3, p4, caps);-
571 p = p4;-
572 type += 3;-
573 points += 6;-
574 break;
never executed: break;
0
575 }-
576 case QPainterPath::CurveToDataElement:
never executed: case QPainterPath::CurveToDataElement:
0
577 Q_ASSERT(!"QPainterPath::toSubpathPolygons(), bad element type");-
578 break;
never executed: break;
0
579 }-
580 caps = NoCaps;-
581 }
never executed: end of block
0
582 }
never executed: end of block
0
583 } else { // !type, simple polygon
never executed: end of block
0
584 QPointF p = QPointF(points[0], points[1]) * state->matrix;-
585 QPointF movedTo = p;-
586 patternOffset = state->lastPen.dashOffset()*64;-
587 lastPixel.x = INT_MIN;-
588 lastPixel.y = INT_MIN;-
589-
590 const qreal *begin = points;-
591 const qreal *end = points + 2*path.elementCount();-
592 // handle closed path case-
593 bool closed = path.hasImplicitClose() || (points[0] == end[-2] && points[1] == end[-1]);
path.hasImplicitClose()Description
TRUEnever evaluated
FALSEnever evaluated
points[0] == end[-2]Description
TRUEnever evaluated
FALSEnever evaluated
points[1] == end[-1]Description
TRUEnever evaluated
FALSEnever evaluated
0
594 int caps = (!closed & drawCaps) ? CapBegin : NoCaps;
(!closed & drawCaps)Description
TRUEnever evaluated
FALSEnever evaluated
0
595 if (closed) {
closedDescription
TRUEnever evaluated
FALSEnever evaluated
0
596 QPointF p2 = QPointF(end[-2], end[-1]) * state->matrix;-
597 calculateLastPoint(p2.x(), p2.y(), p.x(), p.y());-
598 }
never executed: end of block
0
599-
600 bool fastPenAliased = (state->flags.fast_pen && !state->flags.antialiased);
state->flags.fast_penDescription
TRUEnever evaluated
FALSEnever evaluated
!state->flags.antialiasedDescription
TRUEnever evaluated
FALSEnever evaluated
0
601 points += 2;-
602 while (points < end) {
points < endDescription
TRUEnever evaluated
FALSEnever evaluated
0
603 QPointF p2 = QPointF(points[0], points[1]) * state->matrix;-
604-
605 if (!closed && drawCaps && points == end - 2)
!closedDescription
TRUEnever evaluated
FALSEnever evaluated
drawCapsDescription
TRUEnever evaluated
FALSEnever evaluated
points == end - 2Description
TRUEnever evaluated
FALSEnever evaluated
0
606 caps |= CapEnd;
never executed: caps |= CapEnd;
0
607-
608 bool moveNextStart = stroke(this, p.x(), p.y(), p2.x(), p2.y(), caps);-
609-
610 /* fix for gaps in polylines with fastpen and aliased in a sequence-
611 of points with small distances: if current point p2 has been dropped-
612 out, keep last non dropped point p.-
613-
614 However, if the line was completely outside the devicerect, we-
615 still need to update p to avoid drawing the line after this one from-
616 a bad starting position.-
617 */-
618 if (!fastPenAliased || moveNextStart || points == begin + 2 || points == end - 2)
!fastPenAliasedDescription
TRUEnever evaluated
FALSEnever evaluated
moveNextStartDescription
TRUEnever evaluated
FALSEnever evaluated
points == begin + 2Description
TRUEnever evaluated
FALSEnever evaluated
points == end - 2Description
TRUEnever evaluated
FALSEnever evaluated
0
619 p = p2;
never executed: p = p2;
0
620 points += 2;-
621 caps = NoCaps;-
622 }
never executed: end of block
0
623 if (path.hasImplicitClose())
path.hasImplicitClose()Description
TRUEnever evaluated
FALSEnever evaluated
0
624 stroke(this, p.x(), p.y(), movedTo.x(), movedTo.y(), NoCaps);
never executed: stroke(this, p.x(), p.y(), movedTo.x(), movedTo.y(), NoCaps);
0
625 }
never executed: end of block
0
626-
627-
628 blend(current_span, spans, &state->penData);-
629 current_span = 0;-
630}
never executed: end of block
0
631-
632void QCosmeticStroker::renderCubic(const QPointF &p1, const QPointF &p2, const QPointF &p3, const QPointF &p4, int caps)-
633{-
634// qDebug() << ">>>> renderCubic" << p1 << p2 << p3 << p4 << capString(caps);-
635 const int maxSubDivisions = 6;-
636 PointF points[3*maxSubDivisions + 4];-
637-
638 points[3].x = p1.x();-
639 points[3].y = p1.y();-
640 points[2].x = p2.x();-
641 points[2].y = p2.y();-
642 points[1].x = p3.x();-
643 points[1].y = p3.y();-
644 points[0].x = p4.x();-
645 points[0].y = p4.y();-
646-
647 PointF *p = points;-
648 int level = maxSubDivisions;-
649-
650 renderCubicSubdivision(p, level, caps);-
651}
never executed: end of block
0
652-
653static void splitCubic(QCosmeticStroker::PointF *points)-
654{-
655 const qreal half = .5;-
656 qreal a, b, c, d;-
657-
658 points[6].x = points[3].x;-
659 c = points[1].x;-
660 d = points[2].x;-
661 points[1].x = a = ( points[0].x + c ) * half;-
662 points[5].x = b = ( points[3].x + d ) * half;-
663 c = ( c + d ) * half;-
664 points[2].x = a = ( a + c ) * half;-
665 points[4].x = b = ( b + c ) * half;-
666 points[3].x = ( a + b ) * half;-
667-
668 points[6].y = points[3].y;-
669 c = points[1].y;-
670 d = points[2].y;-
671 points[1].y = a = ( points[0].y + c ) * half;-
672 points[5].y = b = ( points[3].y + d ) * half;-
673 c = ( c + d ) * half;-
674 points[2].y = a = ( a + c ) * half;-
675 points[4].y = b = ( b + c ) * half;-
676 points[3].y = ( a + b ) * half;-
677}
never executed: end of block
0
678-
679void QCosmeticStroker::renderCubicSubdivision(QCosmeticStroker::PointF *points, int level, int caps)-
680{-
681 if (level) {
levelDescription
TRUEnever evaluated
FALSEnever evaluated
0
682 qreal dx = points[3].x - points[0].x;-
683 qreal dy = points[3].y - points[0].y;-
684 qreal len = ((qreal).25) * (qAbs(dx) + qAbs(dy));-
685-
686 if (qAbs(dx * (points[0].y - points[2].y) - dy * (points[0].x - points[2].x)) >= len ||
qAbs(dx * (poi...[2].x)) >= lenDescription
TRUEnever evaluated
FALSEnever evaluated
0
687 qAbs(dx * (points[0].y - points[1].y) - dy * (points[0].x - points[1].x)) >= len) {
qAbs(dx * (poi...[1].x)) >= lenDescription
TRUEnever evaluated
FALSEnever evaluated
0
688 splitCubic(points);-
689-
690 --level;-
691 renderCubicSubdivision(points + 3, level, caps & CapBegin);-
692 renderCubicSubdivision(points, level, caps & CapEnd);-
693 return;
never executed: return;
0
694 }-
695 }
never executed: end of block
0
696-
697 stroke(this, points[3].x, points[3].y, points[0].x, points[0].y, caps);-
698}
never executed: end of block
0
699-
700static inline int swapCaps(int caps)-
701{-
702 return ((caps & QCosmeticStroker::CapBegin) << 1) |
never executed: return ((caps & QCosmeticStroker::CapBegin) << 1) | ((caps & QCosmeticStroker::CapEnd) >> 1);
0
703 ((caps & QCosmeticStroker::CapEnd) >> 1);
never executed: return ((caps & QCosmeticStroker::CapBegin) << 1) | ((caps & QCosmeticStroker::CapEnd) >> 1);
0
704}-
705-
706// adjust line by half a pixel-
707static inline void capAdjust(int caps, int &x1, int &x2, int &y, int yinc)-
708{-
709 if (caps & QCosmeticStroker::CapBegin) {
caps & QCosmet...oker::CapBeginDescription
TRUEnever evaluated
FALSEnever evaluated
0
710 x1 -= 32;-
711 y -= yinc >> 1;-
712 }
never executed: end of block
0
713 if (caps & QCosmeticStroker::CapEnd) {
caps & QCosmet...troker::CapEndDescription
TRUEnever evaluated
FALSEnever evaluated
0
714 x2 += 32;-
715 }
never executed: end of block
0
716}
never executed: end of block
0
717-
718/*-
719 The hard part about this is dropout control and avoiding douple drawing of points when-
720 the drawing shifts from horizontal to vertical or back.-
721 */-
722template<DrawPixel drawPixel, class Dasher>-
723static bool drawLine(QCosmeticStroker *stroker, qreal rx1, qreal ry1, qreal rx2, qreal ry2, int caps)-
724{-
725 bool didDraw = qAbs(rx2 - rx1) + qAbs(ry2 - ry1) >= 1.0;-
726-
727 if (stroker->clipLine(rx1, ry1, rx2, ry2))
stroker->clipL...ry1, rx2, ry2)Description
TRUEnever evaluated
FALSEnever evaluated
0
728 return true;
never executed: return true;
0
729-
730 const int half = stroker->legacyRounding ? 31 : 0;-
731 int x1 = toF26Dot6(rx1) + half;-
732 int y1 = toF26Dot6(ry1) + half;-
733 int x2 = toF26Dot6(rx2) + half;-
734 int y2 = toF26Dot6(ry2) + half;-
735-
736 int dx = qAbs(x2 - x1);-
737 int dy = qAbs(y2 - y1);-
738-
739 QCosmeticStroker::Point last = stroker->lastPixel;-
740-
741// qDebug() << "stroke" << x1/64. << y1/64. << x2/64. << y2/64.;-
742-
743 if (dx < dy) {
dx < dyDescription
TRUEnever evaluated
FALSEnever evaluated
0
744 // vertical-
745 QCosmeticStroker::Direction dir = QCosmeticStroker::TopToBottom;-
746-
747 bool swapped = false;-
748 if (y1 > y2) {
y1 > y2Description
TRUEnever evaluated
FALSEnever evaluated
0
749 swapped = true;-
750 qSwap(y1, y2);-
751 qSwap(x1, x2);-
752 caps = swapCaps(caps);-
753 dir = QCosmeticStroker::BottomToTop;-
754 }
never executed: end of block
0
755 int xinc = F16Dot16FixedDiv(x2 - x1, y2 - y1);-
756 int x = x1 * (1<<10);-
757-
758 if ((stroker->lastDir ^ QCosmeticStroker::VerticalMask) == dir)
(stroker->last...alMask) == dirDescription
TRUEnever evaluated
FALSEnever evaluated
0
759 caps |= swapped ? QCosmeticStroker::CapEnd : QCosmeticStroker::CapBegin;
never executed: caps |= swapped ? QCosmeticStroker::CapEnd : QCosmeticStroker::CapBegin;
swappedDescription
TRUEnever evaluated
FALSEnever evaluated
0
760-
761 capAdjust(caps, y1, y2, x, xinc);-
762-
763 int y = (y1 + 32) >> 6;-
764 int ys = (y2 + 32) >> 6;-
765 int round = (xinc > 0) ? 32 : 0;
(xinc > 0)Description
TRUEnever evaluated
FALSEnever evaluated
0
766-
767 if (y != ys) {
y != ysDescription
TRUEnever evaluated
FALSEnever evaluated
0
768 x += ((y * (1<<6)) + round - y1) * xinc >> 6;-
769-
770 // calculate first and last pixel and perform dropout control-
771 QCosmeticStroker::Point first;-
772 first.x = x >> 16;-
773 first.y = y;-
774 last.x = (x + (ys - y - 1)*xinc) >> 16;-
775 last.y = ys - 1;-
776 if (swapped)
swappedDescription
TRUEnever evaluated
FALSEnever evaluated
0
777 qSwap(first, last);
never executed: qSwap(first, last);
0
778-
779 bool axisAligned = qAbs(xinc) < (1 << 14);-
780 if (stroker->lastPixel.x >= 0) {
stroker->lastPixel.x >= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
781 if (first.x == stroker->lastPixel.x &&
first.x == str...r->lastPixel.xDescription
TRUEnever evaluated
FALSEnever evaluated
0
782 first.y == stroker->lastPixel.y) {
first.y == str...r->lastPixel.yDescription
TRUEnever evaluated
FALSEnever evaluated
0
783 // remove duplicated pixel-
784 if (swapped) {
swappedDescription
TRUEnever evaluated
FALSEnever evaluated
0
785 --ys;-
786 } else {
never executed: end of block
0
787 ++y;-
788 x += xinc;-
789 }
never executed: end of block
0
790 } else if (stroker->lastDir != dir &&
stroker->lastDir != dirDescription
TRUEnever evaluated
FALSEnever evaluated
0
791 (((axisAligned && stroker->lastAxisAligned) &&
axisAlignedDescription
TRUEnever evaluated
FALSEnever evaluated
stroker->lastAxisAlignedDescription
TRUEnever evaluated
FALSEnever evaluated
0
792 stroker->lastPixel.x != first.x && stroker->lastPixel.y != first.y) ||
stroker->lastP...l.x != first.xDescription
TRUEnever evaluated
FALSEnever evaluated
stroker->lastP...l.y != first.yDescription
TRUEnever evaluated
FALSEnever evaluated
0
793 (qAbs(stroker->lastPixel.x - first.x) > 1 ||
qAbs(stroker->...- first.x) > 1Description
TRUEnever evaluated
FALSEnever evaluated
0
794 qAbs(stroker->lastPixel.y - first.y) > 1))) {
qAbs(stroker->...- first.y) > 1Description
TRUEnever evaluated
FALSEnever evaluated
0
795 // have a missing pixel, insert it-
796 if (swapped) {
swappedDescription
TRUEnever evaluated
FALSEnever evaluated
0
797 ++ys;-
798 } else {
never executed: end of block
0
799 --y;-
800 x -= xinc;-
801 }
never executed: end of block
0
802 }-
803 }
never executed: end of block
0
804 stroker->lastDir = dir;-
805 stroker->lastAxisAligned = axisAligned;-
806-
807 Dasher dasher(stroker, swapped, y * (1<<6), ys * (1<<6));-
808-
809 do {-
810 if (dasher.on())
dasher.on()Description
TRUEnever evaluated
FALSEnever evaluated
0
811 drawPixel(stroker, x >> 16, y, 255);
never executed: drawPixel(stroker, x >> 16, y, 255);
0
812 dasher.adjust();-
813 x += xinc;-
814 } while (++y < ys);
never executed: end of block
++y < ysDescription
TRUEnever evaluated
FALSEnever evaluated
0
815 didDraw = true;-
816 }
never executed: end of block
0
817 } else {
never executed: end of block
0
818 // horizontal-
819 if (!dx)
!dxDescription
TRUEnever evaluated
FALSEnever evaluated
0
820 return true;
never executed: return true;
0
821-
822 QCosmeticStroker::Direction dir = QCosmeticStroker::LeftToRight;-
823-
824 bool swapped = false;-
825 if (x1 > x2) {
x1 > x2Description
TRUEnever evaluated
FALSEnever evaluated
0
826 swapped = true;-
827 qSwap(x1, x2);-
828 qSwap(y1, y2);-
829 caps = swapCaps(caps);-
830 dir = QCosmeticStroker::RightToLeft;-
831 }
never executed: end of block
0
832 int yinc = F16Dot16FixedDiv(y2 - y1, x2 - x1);-
833 int y = y1 * (1<<10);-
834-
835 if ((stroker->lastDir ^ QCosmeticStroker::HorizontalMask) == dir)
(stroker->last...alMask) == dirDescription
TRUEnever evaluated
FALSEnever evaluated
0
836 caps |= swapped ? QCosmeticStroker::CapEnd : QCosmeticStroker::CapBegin;
never executed: caps |= swapped ? QCosmeticStroker::CapEnd : QCosmeticStroker::CapBegin;
swappedDescription
TRUEnever evaluated
FALSEnever evaluated
0
837-
838 capAdjust(caps, x1, x2, y, yinc);-
839-
840 int x = (x1 + 32) >> 6;-
841 int xs = (x2 + 32) >> 6;-
842 int round = (yinc > 0) ? 32 : 0;
(yinc > 0)Description
TRUEnever evaluated
FALSEnever evaluated
0
843-
844 if (x != xs) {
x != xsDescription
TRUEnever evaluated
FALSEnever evaluated
0
845 y += ((x * (1<<6)) + round - x1) * yinc >> 6;-
846-
847 // calculate first and last pixel to perform dropout control-
848 QCosmeticStroker::Point first;-
849 first.x = x;-
850 first.y = y >> 16;-
851 last.x = xs - 1;-
852 last.y = (y + (xs - x - 1)*yinc) >> 16;-
853 if (swapped)
swappedDescription
TRUEnever evaluated
FALSEnever evaluated
0
854 qSwap(first, last);
never executed: qSwap(first, last);
0
855-
856 bool axisAligned = qAbs(yinc) < (1 << 14);-
857 if (stroker->lastPixel.x >= 0) {
stroker->lastPixel.x >= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
858 if (first.x == stroker->lastPixel.x && first.y == stroker->lastPixel.y) {
first.x == str...r->lastPixel.xDescription
TRUEnever evaluated
FALSEnever evaluated
first.y == str...r->lastPixel.yDescription
TRUEnever evaluated
FALSEnever evaluated
0
859 // remove duplicated pixel-
860 if (swapped) {
swappedDescription
TRUEnever evaluated
FALSEnever evaluated
0
861 --xs;-
862 } else {
never executed: end of block
0
863 ++x;-
864 y += yinc;-
865 }
never executed: end of block
0
866 } else if (stroker->lastDir != dir &&
stroker->lastDir != dirDescription
TRUEnever evaluated
FALSEnever evaluated
0
867 (((axisAligned && stroker->lastAxisAligned) &&
axisAlignedDescription
TRUEnever evaluated
FALSEnever evaluated
stroker->lastAxisAlignedDescription
TRUEnever evaluated
FALSEnever evaluated
0
868 stroker->lastPixel.x != first.x && stroker->lastPixel.y != first.y) ||
stroker->lastP...l.x != first.xDescription
TRUEnever evaluated
FALSEnever evaluated
stroker->lastP...l.y != first.yDescription
TRUEnever evaluated
FALSEnever evaluated
0
869 (qAbs(stroker->lastPixel.x - first.x) > 1 ||
qAbs(stroker->...- first.x) > 1Description
TRUEnever evaluated
FALSEnever evaluated
0
870 qAbs(stroker->lastPixel.y - first.y) > 1))) {
qAbs(stroker->...- first.y) > 1Description
TRUEnever evaluated
FALSEnever evaluated
0
871 // have a missing pixel, insert it-
872 if (swapped) {
swappedDescription
TRUEnever evaluated
FALSEnever evaluated
0
873 ++xs;-
874 } else {
never executed: end of block
0
875 --x;-
876 y -= yinc;-
877 }
never executed: end of block
0
878 }-
879 }
never executed: end of block
0
880 stroker->lastDir = dir;-
881 stroker->lastAxisAligned = axisAligned;-
882-
883 Dasher dasher(stroker, swapped, x * (1<<6), xs * (1<<6));-
884-
885 do {-
886 if (dasher.on())
dasher.on()Description
TRUEnever evaluated
FALSEnever evaluated
0
887 drawPixel(stroker, x, y >> 16, 255);
never executed: drawPixel(stroker, x, y >> 16, 255);
0
888 dasher.adjust();-
889 y += yinc;-
890 } while (++x < xs);
never executed: end of block
++x < xsDescription
TRUEnever evaluated
FALSEnever evaluated
0
891 didDraw = true;-
892 }
never executed: end of block
0
893 }
never executed: end of block
0
894 stroker->lastPixel = last;-
895 return didDraw;
never executed: return didDraw;
0
896}-
897-
898-
899template<DrawPixel drawPixel, class Dasher>-
900static bool drawLineAA(QCosmeticStroker *stroker, qreal rx1, qreal ry1, qreal rx2, qreal ry2, int caps)-
901{-
902 if (stroker->clipLine(rx1, ry1, rx2, ry2))
stroker->clipL...ry1, rx2, ry2)Description
TRUEnever evaluated
FALSEnever evaluated
0
903 return true;
never executed: return true;
0
904-
905 int x1 = toF26Dot6(rx1);-
906 int y1 = toF26Dot6(ry1);-
907 int x2 = toF26Dot6(rx2);-
908 int y2 = toF26Dot6(ry2);-
909-
910 int dx = x2 - x1;-
911 int dy = y2 - y1;-
912-
913 if (qAbs(dx) < qAbs(dy)) {
qAbs(dx) < qAbs(dy)Description
TRUEnever evaluated
FALSEnever evaluated
0
914 // vertical-
915-
916 int xinc = F16Dot16FixedDiv(dx, dy);-
917-
918 bool swapped = false;-
919 if (y1 > y2) {
y1 > y2Description
TRUEnever evaluated
FALSEnever evaluated
0
920 qSwap(y1, y2);-
921 qSwap(x1, x2);-
922 swapped = true;-
923 caps = swapCaps(caps);-
924 }
never executed: end of block
0
925-
926 int x = (x1 - 32) * (1<<10);-
927 x -= ( ((y1 & 63) - 32) * xinc ) >> 6;-
928-
929 capAdjust(caps, y1, y2, x, xinc);-
930-
931 Dasher dasher(stroker, swapped, y1, y2);-
932-
933 int y = y1 >> 6;-
934 int ys = y2 >> 6;-
935-
936 int alphaStart, alphaEnd;-
937 if (y == ys) {
y == ysDescription
TRUEnever evaluated
FALSEnever evaluated
0
938 alphaStart = y2 - y1;-
939 Q_ASSERT(alphaStart >= 0 && alphaStart < 64);-
940 alphaEnd = 0;-
941 } else {
never executed: end of block
0
942 alphaStart = 64 - (y1 & 63);-
943 alphaEnd = (y2 & 63);-
944 }
never executed: end of block
0
945// qDebug() << "vertical" << x1/64. << y1/64. << x2/64. << y2/64.;-
946// qDebug() << " x=" << x << "dx=" << dx << "xi=" << (x>>16) << "xsi=" << ((x+(ys-y)*dx)>>16) << "y=" << y << "ys=" << ys;-
947-
948 // draw first pixel-
949 if (dasher.on()) {
dasher.on()Description
TRUEnever evaluated
FALSEnever evaluated
0
950 uint alpha = (quint8)(x >> 8);-
951 drawPixel(stroker, x>>16, y, (255-alpha) * alphaStart >> 6);-
952 drawPixel(stroker, (x>>16) + 1, y, alpha * alphaStart >> 6);-
953 }
never executed: end of block
0
954 dasher.adjust();-
955 x += xinc;-
956 ++y;-
957 if (y < ys) {
y < ysDescription
TRUEnever evaluated
FALSEnever evaluated
0
958 do {-
959 if (dasher.on()) {
dasher.on()Description
TRUEnever evaluated
FALSEnever evaluated
0
960 uint alpha = (quint8)(x >> 8);-
961 drawPixel(stroker, x>>16, y, (255-alpha));-
962 drawPixel(stroker, (x>>16) + 1, y, alpha);-
963 }
never executed: end of block
0
964 dasher.adjust();-
965 x += xinc;-
966 } while (++y < ys);
never executed: end of block
++y < ysDescription
TRUEnever evaluated
FALSEnever evaluated
0
967 }
never executed: end of block
0
968 // draw last pixel-
969 if (alphaEnd && dasher.on()) {
alphaEndDescription
TRUEnever evaluated
FALSEnever evaluated
dasher.on()Description
TRUEnever evaluated
FALSEnever evaluated
0
970 uint alpha = (quint8)(x >> 8);-
971 drawPixel(stroker, x>>16, y, (255-alpha) * alphaEnd >> 6);-
972 drawPixel(stroker, (x>>16) + 1, y, alpha * alphaEnd >> 6);-
973 }
never executed: end of block
0
974 } else {
never executed: end of block
0
975 // horizontal-
976 if (!dx)
!dxDescription
TRUEnever evaluated
FALSEnever evaluated
0
977 return true;
never executed: return true;
0
978-
979 int yinc = F16Dot16FixedDiv(dy, dx);-
980-
981 bool swapped = false;-
982 if (x1 > x2) {
x1 > x2Description
TRUEnever evaluated
FALSEnever evaluated
0
983 qSwap(x1, x2);-
984 qSwap(y1, y2);-
985 swapped = true;-
986 caps = swapCaps(caps);-
987 }
never executed: end of block
0
988-
989 int y = (y1 - 32) * (1<<10);-
990 y -= ( ((x1 & 63) - 32) * yinc ) >> 6;-
991-
992 capAdjust(caps, x1, x2, y, yinc);-
993-
994 Dasher dasher(stroker, swapped, x1, x2);-
995-
996 int x = x1 >> 6;-
997 int xs = x2 >> 6;-
998-
999// qDebug() << "horizontal" << x1/64. << y1/64. << x2/64. << y2/64.;-
1000// qDebug() << " y=" << y << "dy=" << dy << "x=" << x << "xs=" << xs << "yi=" << (y>>16) << "ysi=" << ((y+(xs-x)*dy)>>16);-
1001 int alphaStart, alphaEnd;-
1002 if (x == xs) {
x == xsDescription
TRUEnever evaluated
FALSEnever evaluated
0
1003 alphaStart = x2 - x1;-
1004 Q_ASSERT(alphaStart >= 0 && alphaStart < 64);-
1005 alphaEnd = 0;-
1006 } else {
never executed: end of block
0
1007 alphaStart = 64 - (x1 & 63);-
1008 alphaEnd = (x2 & 63);-
1009 }
never executed: end of block
0
1010-
1011 // draw first pixel-
1012 if (dasher.on()) {
dasher.on()Description
TRUEnever evaluated
FALSEnever evaluated
0
1013 uint alpha = (quint8)(y >> 8);-
1014 drawPixel(stroker, x, y>>16, (255-alpha) * alphaStart >> 6);-
1015 drawPixel(stroker, x, (y>>16) + 1, alpha * alphaStart >> 6);-
1016 }
never executed: end of block
0
1017 dasher.adjust();-
1018 y += yinc;-
1019 ++x;-
1020 // draw line-
1021 if (x < xs) {
x < xsDescription
TRUEnever evaluated
FALSEnever evaluated
0
1022 do {-
1023 if (dasher.on()) {
dasher.on()Description
TRUEnever evaluated
FALSEnever evaluated
0
1024 uint alpha = (quint8)(y >> 8);-
1025 drawPixel(stroker, x, y>>16, (255-alpha));-
1026 drawPixel(stroker, x, (y>>16) + 1, alpha);-
1027 }
never executed: end of block
0
1028 dasher.adjust();-
1029 y += yinc;-
1030 } while (++x < xs);
never executed: end of block
++x < xsDescription
TRUEnever evaluated
FALSEnever evaluated
0
1031 }
never executed: end of block
0
1032 // draw last pixel-
1033 if (alphaEnd && dasher.on()) {
alphaEndDescription
TRUEnever evaluated
FALSEnever evaluated
dasher.on()Description
TRUEnever evaluated
FALSEnever evaluated
0
1034 uint alpha = (quint8)(y >> 8);-
1035 drawPixel(stroker, x, y>>16, (255-alpha) * alphaEnd >> 6);-
1036 drawPixel(stroker, x, (y>>16) + 1, alpha * alphaEnd >> 6);-
1037 }
never executed: end of block
0
1038 }
never executed: end of block
0
1039 return true;
never executed: return true;
0
1040}-
1041-
1042QT_END_NAMESPACE-
Source codeSwitch to Preprocessed file

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