qpaintengine_raster.cpp

Absolute File Name:/home/qt/qt5_coco/qt5/qtbase/src/gui/painting/qpaintengine_raster.cpp
Switch to Source codePreprocessed file
LineSourceCount
1-
2-
3-
4-
5-
6-
7-
8-
9-
10-
11-
12-
13-
14-
15-
16class QRectVectorPath : public QVectorPath {-
17public:-
18 inline void set(const QRect &r) {-
19 qreal left = r.x();-
20 qreal right = r.x() + r.width();-
21 qreal top = r.y();-
22 qreal bottom = r.y() + r.height();-
23 pts[0] = left;-
24 pts[1] = top;-
25 pts[2] = right;-
26 pts[3] = top;-
27 pts[4] = right;-
28 pts[5] = bottom;-
29 pts[6] = left;-
30 pts[7] = bottom;-
31 }-
32-
33 inline void set(const QRectF &r) {-
34 qreal left = r.x();-
35 qreal right = r.x() + r.width();-
36 qreal top = r.y();-
37 qreal bottom = r.y() + r.height();-
38 pts[0] = left;-
39 pts[1] = top;-
40 pts[2] = right;-
41 pts[3] = top;-
42 pts[4] = right;-
43 pts[5] = bottom;-
44 pts[6] = left;-
45 pts[7] = bottom;-
46 }-
47 inline QRectVectorPath(const QRect &r)-
48 : QVectorPath(pts, 4, 0, QVectorPath::RectangleHint | QVectorPath::ImplicitClose)-
49 {-
50 set(r);-
51 }-
52 inline QRectVectorPath(const QRectF &r)-
53 : QVectorPath(pts, 4, 0, QVectorPath::RectangleHint | QVectorPath::ImplicitClose)-
54 {-
55 set(r);-
56 }-
57 inline QRectVectorPath()-
58 : QVectorPath(pts, 4, 0, QVectorPath::RectangleHint | QVectorPath::ImplicitClose)-
59 { }-
60-
61 qreal pts[8];-
62};-
63-
64__attribute__((visibility("default"))) extern bool qt_scaleForTransform(const QTransform &transform, qreal *scale);-
65static const qreal aliasedCoordinateDelta = 0.5 - 0.015625;-
66static void qt_span_fill_clipRect(int count, const QSpan *spans, void *userData);-
67static void qt_span_fill_clipped(int count, const QSpan *spans, void *userData);-
68static void qt_span_clip(int count, const QSpan *spans, void *userData);-
69-
70struct ClipData-
71{-
72 QClipData *oldClip;-
73 QClipData *newClip;-
74 Qt::ClipOperation operation;-
75};-
76-
77enum LineDrawMode {-
78 LineDrawClipped,-
79 LineDrawNormal,-
80 LineDrawIncludeLastPixel-
81};-
82-
83static void drawEllipse_midpoint_i(const QRect &rect, const QRect &clip,-
84 ProcessSpans pen_func, ProcessSpans brush_func,-
85 QSpanData *pen_data, QSpanData *brush_data);-
86-
87struct QRasterFloatPoint {-
88 qreal x;-
89 qreal y;-
90};-
91static void qt_ft_outline_move_to(qfixed x, qfixed y, void *data)-
92{-
93 ((QOutlineMapper *) data)->moveTo(QPointF(x, y));-
94}-
95-
96static void qt_ft_outline_line_to(qfixed x, qfixed y, void *data)-
97{-
98 ((QOutlineMapper *) data)->lineTo(QPointF(x, y));-
99}-
100-
101static void qt_ft_outline_cubic_to(qfixed c1x, qfixed c1y,-
102 qfixed c2x, qfixed c2y,-
103 qfixed ex, qfixed ey,-
104 void *data)-
105{-
106 ((QOutlineMapper *) data)->curveTo(QPointF(c1x, c1y),-
107 QPointF(c2x, c2y),-
108 QPointF(ex, ey));-
109}-
110QRasterPaintEnginePrivate::QRasterPaintEnginePrivate() :-
111 QPaintEngineExPrivate(),-
112 cachedLines(0)-
113{-
114}-
115QRasterPaintEngine::QRasterPaintEngine(QPaintDevice *device)-
116 : QPaintEngineEx(*(new QRasterPaintEnginePrivate))-
117{-
118 d_func()->device = device;-
119 init();-
120}-
121-
122-
123-
124-
125QRasterPaintEngine::QRasterPaintEngine(QRasterPaintEnginePrivate &dd, QPaintDevice *device)-
126 : QPaintEngineEx(dd)-
127{-
128 d_func()->device = device;-
129 init();-
130}-
131-
132void QRasterPaintEngine::init()-
133{-
134 QRasterPaintEnginePrivate * const d = d_func();-
135-
136-
137-
138-
139-
140-
141-
142 d->grayRaster.reset(new QT_FT_Raster);-
143 do {if(!(d->grayRaster.data()))qt_check_pointer(__FILE__,358364);} while (0);-
144 if (qt_ft_grays_raster.raster_new(d->grayRaster.data()))-
145 qt_noop();-
146-
147-
148 d->rasterizer.reset(new QRasterizer);-
149 d->rasterBuffer.reset(new QRasterBuffer());-
150 d->outlineMapper.reset(new QOutlineMapper);-
151 d->outlinemapper_xform_dirty = true;-
152-
153 d->basicStroker.setMoveToHook(qt_ft_outline_move_to);-
154 d->basicStroker.setLineToHook(qt_ft_outline_line_to);-
155 d->basicStroker.setCubicToHook(qt_ft_outline_cubic_to);-
156-
157 d->baseClip.reset(new QClipData(d->device->height()));-
158 d->baseClip->setClipRect(QRect(0, 0, d->device->width(), d->device->height()));-
159-
160 d->image_filler.init(d->rasterBuffer.data(), this);-
161 d->image_filler.type = QSpanData::Texture;-
162-
163 d->image_filler_xform.init(d->rasterBuffer.data(), this);-
164 d->image_filler_xform.type = QSpanData::Texture;-
165-
166 d->solid_color_filler.init(d->rasterBuffer.data(), this);-
167 d->solid_color_filler.type = QSpanData::Solid;-
168-
169 d->deviceDepth = d->device->depth();-
170-
171 d->mono_surface = false;-
172 gccaps &= ~PorterDuff;-
173-
174 QImage::Format format = QImage::Format_Invalid;-
175-
176 switch (d->device->devType()) {-
177 case QInternal::Pixmap:-
178 QMessageLogger(__FILE__, 393399, __PRETTY_FUNCTION__).warning("QRasterPaintEngine: unsupported for pixmaps...");-
179 break;-
180 case QInternal::Image:-
181 format = d->rasterBuffer->prepare(static_cast<QImage *>(d->device));-
182 break;-
183 default:-
184 QMessageLogger(__FILE__, 399405, __PRETTY_FUNCTION__).warning("QRasterPaintEngine: unsupported target device %d\n", d->device->devType());-
185 d->device = 0;-
186 return;-
187 }-
188-
189 switch (format) {-
190 case QImage::Format_MonoLSB:-
191 case QImage::Format_Mono:-
192 d->mono_surface = true;-
193 break;-
194 default:-
195 if (QImage::toPixelFormat(format).alphaUsage() == QPixelFormat::UsesAlpha)-
196 gccaps |= PorterDuff;-
197 break;-
198 }-
199}-
200-
201-
202-
203-
204-
205QRasterPaintEngine::~QRasterPaintEngine()-
206{-
207 QRasterPaintEnginePrivate * const d = d_func();-
208-
209 qt_ft_grays_raster.raster_done(*d->grayRaster.data());-
210}-
211-
212-
213-
214-
215bool QRasterPaintEngine::begin(QPaintDevice *device)-
216{-
217 QRasterPaintEnginePrivate * const d = d_func();-
218-
219 if (device->devType() == QInternal::Pixmap) {-
220 QPixmap *pixmap = static_cast<QPixmap *>(device);-
221 QPlatformPixmap *pd = pixmap->handle();-
222 if (pd->classId() == QPlatformPixmap::RasterClass || pd->classId() == QPlatformPixmap::BlitterClass)-
223 d->device = pd->buffer();-
224 } else {-
225 d->device = device;-
226 }-
227-
228-
229 d->pdev = d->device;-
230-
231 ((!(d->device->devType() == QInternal::Image || d->device->devType() == QInternal::CustomRaster)) ? qt_assert("d->device->devType() == QInternal::Image || d->device->devType() == QInternal::CustomRaster",-
232 __FILE__-
233 ,-
234 447453-
235 ) : qt_noop())-
236 ;-
237-
238 d->systemStateChanged();-
239-
240 QRasterPaintEngineState *s = state();-
241 ensureOutlineMapper();-
242 d->outlineMapper->m_clip_rect = d->deviceRect;-
243-
244 if (d->outlineMapper->m_clip_rect.width() > QT_RASTER_COORD_LIMIT)-
245 d->outlineMapper->m_clip_rect.setWidth(QT_RASTER_COORD_LIMIT);-
246 if (d->outlineMapper->m_clip_rect.height() > QT_RASTER_COORD_LIMIT)-
247 d->outlineMapper->m_clip_rect.setHeight(QT_RASTER_COORD_LIMIT);-
248-
249 d->rasterizer->setClipRect(d->deviceRect);-
250-
251 s->penData.init(d->rasterBuffer.data(), this);-
252 s->penData.setup(s->pen.brush(), s->intOpacity, s->composition_mode);-
253 s->stroker = &d->basicStroker;-
254 d->basicStroker.setClipRect(d->deviceRect);-
255-
256 s->brushData.init(d->rasterBuffer.data(), this);-
257 s->brushData.setup(s->brush, s->intOpacity, s->composition_mode);-
258-
259 d->rasterBuffer->compositionMode = QPainter::CompositionMode_SourceOver;-
260-
261 setDirty(DirtyBrushOrigin);-
262 if (d->mono_surface)-
263 d->glyphCacheFormat = QFontEngine::Format_Mono;-
264-
265-
266-
267 else if (false)-
268-
269 {
dead code: { QImage::Format format = static_cast<QImage *>(d->device)->format(); if (format == QImage::Format_ARGB32_Premultiplied || format == QImage::Format_RGB32) d->glyphCacheFormat = QFontEngine::Format_A32; else d->glyphCacheFormat = QFontEngine::Format_A8; }
-
270 QImage::Format format = static_cast<QImage *>(d->device)->format();
dead code: { QImage::Format format = static_cast<QImage *>(d->device)->format(); if (format == QImage::Format_ARGB32_Premultiplied || format == QImage::Format_RGB32) d->glyphCacheFormat = QFontEngine::Format_A32; else d->glyphCacheFormat = QFontEngine::Format_A8; }
-
271 if (format == QImage::Format_ARGB32_Premultiplied || format == QImage::Format_RGB32)
dead code: { QImage::Format format = static_cast<QImage *>(d->device)->format(); if (format == QImage::Format_ARGB32_Premultiplied || format == QImage::Format_RGB32) d->glyphCacheFormat = QFontEngine::Format_A32; else d->glyphCacheFormat = QFontEngine::Format_A8; }
-
272 d->glyphCacheFormat = QFontEngine::Format_A32;
dead code: { QImage::Format format = static_cast<QImage *>(d->device)->format(); if (format == QImage::Format_ARGB32_Premultiplied || format == QImage::Format_RGB32) d->glyphCacheFormat = QFontEngine::Format_A32; else d->glyphCacheFormat = QFontEngine::Format_A8; }
-
273 else
dead code: { QImage::Format format = static_cast<QImage *>(d->device)->format(); if (format == QImage::Format_ARGB32_Premultiplied || format == QImage::Format_RGB32) d->glyphCacheFormat = QFontEngine::Format_A32; else d->glyphCacheFormat = QFontEngine::Format_A8; }
-
274 d->glyphCacheFormat = QFontEngine::Format_A8;
dead code: { QImage::Format format = static_cast<QImage *>(d->device)->format(); if (format == QImage::Format_ARGB32_Premultiplied || format == QImage::Format_RGB32) d->glyphCacheFormat = QFontEngine::Format_A32; else d->glyphCacheFormat = QFontEngine::Format_A8; }
-
275 }
dead code: { QImage::Format format = static_cast<QImage *>(d->device)->format(); if (format == QImage::Format_ARGB32_Premultiplied || format == QImage::Format_RGB32) d->glyphCacheFormat = QFontEngine::Format_A32; else d->glyphCacheFormat = QFontEngine::Format_A8; }
else
-
276 d->glyphCacheFormat = QFontEngine::Format_A8;-
277-
278 setActive(true);-
279 return true;-
280}-
281-
282-
283-
284-
285bool QRasterPaintEngine::end()-
286{-
287 return true;-
288}-
289-
290-
291-
292-
293void QRasterPaintEngine::releaseBuffer()-
294{-
295 QRasterPaintEnginePrivate * const d = d_func();-
296 d->rasterBuffer.reset(new QRasterBuffer);-
297}-
298-
299-
300-
301-
302QSize QRasterPaintEngine::size() const-
303{-
304 const QRasterPaintEnginePrivate * const d = d_func();-
305 return QSize(d->rasterBuffer->width(), d->rasterBuffer->height());-
306}-
307-
308-
309-
310-
311-
312void QRasterPaintEngine::saveBuffer(const QString &s) const-
313{-
314 const QRasterPaintEnginePrivate * const d = d_func();-
315 d->rasterBuffer->bufferImage().save(s, "PNG");-
316}-
317-
318-
319-
320-
321-
322void QRasterPaintEngine::updateMatrix(const QTransform &matrix)-
323{-
324 QRasterPaintEngineState *s = state();-
325-
326 s->matrix = matrix;-
327 QTransform::TransformationType txop = s->matrix.type();-
328-
329 switch (txop) {-
330-
331 case QTransform::TxNone:-
332 s->flags.int_xform = true;-
333 break;-
334-
335 case QTransform::TxTranslate:-
336 s->flags.int_xform = qreal(int(s->matrix.dx())) == s->matrix.dx()-
337 && qreal(int(s->matrix.dy())) == s->matrix.dy();-
338 break;-
339-
340 case QTransform::TxScale:-
341 s->flags.int_xform = qreal(int(s->matrix.dx())) == s->matrix.dx()-
342 && qreal(int(s->matrix.dy())) == s->matrix.dy()-
343 && qreal(int(s->matrix.m11())) == s->matrix.m11()-
344 && qreal(int(s->matrix.m22())) == s->matrix.m22();-
345 break;-
346-
347 default:-
348 s->flags.int_xform = false;-
349 break;-
350 }-
351-
352 s->flags.tx_noshear = qt_scaleForTransform(s->matrix, &s->txscale);-
353-
354 ensureOutlineMapper();-
355}-
356-
357-
358-
359QRasterPaintEngineState::~QRasterPaintEngineState()-
360{-
361 if (flags.has_clip_ownership)-
362 delete clip;-
363}-
364-
365-
366QRasterPaintEngineState::QRasterPaintEngineState()-
367{-
368 stroker = 0;-
369-
370 fillFlags = 0;-
371 strokeFlags = 0;-
372 pixmapFlags = 0;-
373-
374 intOpacity = 256;-
375-
376 txscale = 1.;-
377-
378 flags.fast_pen = true;-
379 flags.antialiased = false;-
380 flags.bilinear = false;-
381 flags.legacy_rounding = false;-
382 flags.fast_text = true;-
383 flags.int_xform = true;-
384 flags.tx_noshear = true;-
385 flags.fast_images = true;-
386-
387 clip = 0;-
388 flags.has_clip_ownership = false;-
389-
390 dirty = 0;-
391}-
392-
393QRasterPaintEngineState::QRasterPaintEngineState(QRasterPaintEngineState &s)-
394 : QPainterState(s)-
395 , lastPen(s.lastPen)-
396 , penData(s.penData)-
397 , stroker(s.stroker)-
398 , strokeFlags(s.strokeFlags)-
399 , lastBrush(s.lastBrush)-
400 , brushData(s.brushData)-
401 , fillFlags(s.fillFlags)-
402 , pixmapFlags(s.pixmapFlags)-
403 , intOpacity(s.intOpacity)-
404 , txscale(s.txscale)-
405 , clip(s.clip)-
406 , dirty(s.dirty)-
407 , flag_bits(s.flag_bits)-
408{-
409 brushData.tempImage = 0;-
410 penData.tempImage = 0;-
411 flags.has_clip_ownership = false;-
412}-
413-
414-
415-
416-
417QPainterState *QRasterPaintEngine::createState(QPainterState *orig) const-
418{-
419 QRasterPaintEngineState *s;-
420 if (!orig)-
421 s = new QRasterPaintEngineState();-
422 else-
423 s = new QRasterPaintEngineState(*static_cast<QRasterPaintEngineState *>(orig));-
424-
425 return s;-
426}-
427-
428-
429-
430-
431void QRasterPaintEngine::setState(QPainterState *s)-
432{-
433 QRasterPaintEnginePrivate * const d = d_func();-
434 QPaintEngineEx::setState(s);-
435 d->rasterBuffer->compositionMode = s->composition_mode;-
436}-
437void QRasterPaintEngine::penChanged()-
438{-
439-
440-
441-
442 QRasterPaintEngineState *s = state();-
443 ((!(s)) ? qt_assert("s",__FILE__,686692) : qt_noop());-
444 s->strokeFlags |= DirtyPen;-
445 s->dirty |= DirtyPen;-
446}-
447-
448-
449-
450-
451void QRasterPaintEngine::updatePen(const QPen &pen)-
452{-
453 QRasterPaintEnginePrivate * const d = d_func();-
454 QRasterPaintEngineState *s = state();-
455-
456-
457-
458-
459 Qt::PenStyle pen_style = qpen_style(pen);-
460-
461 s->lastPen = pen;-
462 s->strokeFlags = 0;-
463-
464 s->penData.clip = d->clip();-
465 s->penData.setup(pen_style == Qt::NoPen ? QBrush() : pen.brush(), s->intOpacity, s->composition_mode);-
466-
467 if (s->strokeFlags & QRasterPaintEngine::DirtyTransform-
468 || pen.brush().transform().type() >= QTransform::TxNone) {-
469 d->updateMatrixData(&s->penData, pen.brush(), s->matrix);-
470 }-
471-
472-
473-
474-
475 if (pen_style == Qt::CustomDashLine && pen.dashPattern().size() == 0) {-
476 pen_style = Qt::SolidLine;-
477 s->lastPen.setStyle(Qt::SolidLine);-
478 }-
479-
480 d->basicStroker.setJoinStyle(qpen_joinStyle(pen));-
481 d->basicStroker.setCapStyle(qpen_capStyle(pen));-
482 d->basicStroker.setMiterLimit(pen.miterLimit());-
483-
484 qreal penWidth = qpen_widthf(pen);-
485 if (penWidth == 0)-
486 d->basicStroker.setStrokeWidth(1);-
487 else-
488 d->basicStroker.setStrokeWidth(penWidth);-
489-
490 if(pen_style == Qt::SolidLine) {-
491 s->stroker = &d->basicStroker;-
492 } else if (pen_style != Qt::NoPen) {-
493 if (!d->dashStroker)-
494 d->dashStroker.reset(new QDashStroker(&d->basicStroker));-
495 if (qt_pen_is_cosmetic(pen, s->renderHints)) {-
496 d->dashStroker->setClipRect(d->deviceRect);-
497 } else {-
498-
499 QRectF clipRect = s->matrix.inverted().mapRect(QRectF(d->deviceRect));-
500 d->dashStroker->setClipRect(clipRect);-
501 }-
502 d->dashStroker->setDashPattern(pen.dashPattern());-
503 d->dashStroker->setDashOffset(pen.dashOffset());-
504 s->stroker = d->dashStroker.data();-
505 } else {-
506 s->stroker = 0;-
507 }-
508-
509 ensureRasterState();-
510 bool cosmetic = qt_pen_is_cosmetic(pen, s->renderHints);-
511 s->flags.fast_pen = pen_style > Qt::NoPen-
512 && s->penData.blend-
513 && ((cosmetic && penWidth <= 1)-
514 || (!cosmetic && s->flags.tx_noshear && penWidth * s->txscale <= 1));-
515-
516 s->flags.non_complex_pen = qpen_capStyle(s->lastPen) <= Qt::SquareCap && s->flags.tx_noshear;-
517-
518 s->strokeFlags = 0;-
519}-
520-
521-
522-
523-
524-
525-
526void QRasterPaintEngine::brushOriginChanged()-
527{-
528 QRasterPaintEngineState *s = state();-
529-
530-
531-
532-
533 s->fillFlags |= DirtyBrushOrigin;-
534}-
535-
536-
537-
538-
539-
540void QRasterPaintEngine::brushChanged()-
541{-
542 QRasterPaintEngineState *s = state();-
543-
544-
545-
546 s->fillFlags |= DirtyBrush;-
547}-
548-
549-
550-
551-
552-
553-
554-
555void QRasterPaintEngine::updateBrush(const QBrush &brush)-
556{-
557-
558-
559-
560 QRasterPaintEnginePrivate * const d = d_func();-
561 QRasterPaintEngineState *s = state();-
562-
563 s->brushData.clip = d->clip();-
564 s->brushData.setup(brush, s->intOpacity, s->composition_mode);-
565 if (s->fillFlags & DirtyTransform-
566 || brush.transform().type() >= QTransform::TxNone)-
567 d_func()->updateMatrixData(&s->brushData, brush, d->brushMatrix());-
568 s->lastBrush = brush;-
569 s->fillFlags = 0;-
570}-
571-
572void QRasterPaintEngine::updateOutlineMapper()-
573{-
574 QRasterPaintEnginePrivate * const d = d_func();-
575 d->outlineMapper->setMatrix(state()->matrix);-
576}-
577-
578void QRasterPaintEngine::updateRasterState()-
579{-
580 QRasterPaintEngineState *s = state();-
581-
582 if (s->dirty & DirtyTransform)-
583 updateMatrix(s->matrix);-
584-
585 if (s->dirty & (DirtyPen|DirtyCompositionMode|DirtyOpacity)) {-
586 const QPainter::CompositionMode mode = s->composition_mode;-
587 s->flags.fast_text = (s->penData.type == QSpanData::Solid)-
588 && s->intOpacity == 256-
589 && (mode == QPainter::CompositionMode_Source-
590 || (mode == QPainter::CompositionMode_SourceOver-
591 && s->penData.solid.color.isOpaque()));-
592 }-
593-
594 s->dirty = 0;-
595}-
596-
597-
598-
599-
600-
601void QRasterPaintEngine::opacityChanged()-
602{-
603 QRasterPaintEngineState *s = state();-
604-
605-
606-
607-
608-
609 s->fillFlags |= DirtyOpacity;-
610 s->strokeFlags |= DirtyOpacity;-
611 s->pixmapFlags |= DirtyOpacity;-
612 s->dirty |= DirtyOpacity;-
613 s->intOpacity = (int) (s->opacity * 256);-
614}-
615-
616-
617-
618-
619void QRasterPaintEngine::compositionModeChanged()-
620{-
621 QRasterPaintEnginePrivate * const d = d_func();-
622 QRasterPaintEngineState *s = state();-
623-
624-
625-
626-
627-
628 s->fillFlags |= DirtyCompositionMode;-
629 s->dirty |= DirtyCompositionMode;-
630-
631 s->strokeFlags |= DirtyCompositionMode;-
632 d->rasterBuffer->compositionMode = s->composition_mode;-
633-
634 d->recalculateFastImages();-
635}-
636-
637-
638-
639-
640void QRasterPaintEngine::renderHintsChanged()-
641{-
642 QRasterPaintEngineState *s = state();-
643-
644-
645-
646-
647-
648 bool was_aa = s->flags.antialiased;-
649 bool was_bilinear = s->flags.bilinear;-
650-
651 s->flags.antialiased = bool(s->renderHints & (QPainter::Antialiasing | QPainter::HighQualityAntialiasing));-
652 s->flags.bilinear = bool(s->renderHints & QPainter::SmoothPixmapTransform);-
653 s->flags.legacy_rounding = !bool(s->renderHints & QPainter::Antialiasing) && bool(s->renderHints & QPainter::Qt4CompatiblePainting);-
654-
655 if (was_aa != s->flags.antialiased)-
656 s->strokeFlags |= DirtyHints;-
657-
658 if (was_bilinear != s->flags.bilinear) {-
659 s->strokeFlags |= DirtyPen;-
660 s->fillFlags |= DirtyBrush;-
661 }-
662-
663 QRasterPaintEnginePrivate * const d = d_func();-
664 d->recalculateFastImages();-
665}-
666-
667-
668-
669-
670void QRasterPaintEngine::transformChanged()-
671{-
672 QRasterPaintEngineState *s = state();-
673-
674-
675-
676-
677-
678 s->fillFlags |= DirtyTransform;-
679 s->strokeFlags |= DirtyTransform;-
680-
681 s->dirty |= DirtyTransform;-
682-
683 QRasterPaintEnginePrivate * const d = d_func();-
684 d->recalculateFastImages();-
685}-
686-
687-
688-
689-
690void QRasterPaintEngine::clipEnabledChanged()-
691{-
692 QRasterPaintEngineState *s = state();-
693-
694-
695-
696-
697-
698 if (s->clip) {-
699 s->clip->enabled = s->clipEnabled;-
700 s->fillFlags |= DirtyClipEnabled;-
701 s->strokeFlags |= DirtyClipEnabled;-
702 s->pixmapFlags |= DirtyClipEnabled;-
703 }-
704}-
705-
706void QRasterPaintEnginePrivate::drawImage(const QPointF &pt,-
707 const QImage &img,-
708 SrcOverBlendFunc func,-
709 const QRect &clip,-
710 int alpha,-
711 const QRect &sr)-
712{-
713 if (alpha == 0 || !clip.isValid())-
714 return;-
715-
716 ((!(img.depth() >= 8)) ? qt_assert("img.depth() >= 8",__FILE__,959965) : qt_noop());-
717-
718 int srcBPL = img.bytesPerLine();-
719 const uchar *srcBits = img.bits();-
720 int srcSize = img.depth() >> 3;-
721 int iw = img.width();-
722 int ih = img.height();-
723-
724 if (!sr.isEmpty()) {-
725 iw = sr.width();-
726 ih = sr.height();-
727-
728 srcBits += ((sr.y() * srcBPL) + sr.x() * srcSize);-
729 }-
730-
731-
732 int x = qRound(pt.x());-
733 int cx1 = clip.x();-
734 int cx2 = clip.x() + clip.width();-
735 if (x < cx1) {-
736 int d = cx1 - x;-
737 srcBits += srcSize * d;-
738 iw -= d;-
739 x = cx1;-
740 }-
741 if (x + iw > cx2) {-
742 int d = x + iw - cx2;-
743 iw -= d;-
744 }-
745 if (iw <= 0)-
746 return;-
747-
748-
749 int cy1 = clip.y();-
750 int cy2 = clip.y() + clip.height();-
751 int y = qRound(pt.y());-
752 if (y < cy1) {-
753 int d = cy1 - y;-
754 srcBits += srcBPL * d;-
755 ih -= d;-
756 y = cy1;-
757 }-
758 if (y + ih > cy2) {-
759 int d = y + ih - cy2;-
760 ih -= d;-
761 }-
762 if (ih <= 0)-
763 return;-
764-
765-
766 int dstSize = rasterBuffer->bytesPerPixel();-
767 int dstBPL = rasterBuffer->bytesPerLine();-
768 func(rasterBuffer->buffer() + x * dstSize + y * dstBPL, dstBPL,-
769 srcBits, srcBPL,-
770 iw, ih,-
771 alpha);-
772}-
773-
774-
775void QRasterPaintEnginePrivate::systemStateChanged()-
776{-
777 deviceRectUnclipped = QRect(0, 0,-
778 qMin(QT_RASTER_COORD_LIMIT, device->width()),-
779 qMin(QT_RASTER_COORD_LIMIT, device->height()));-
780-
781 if (!systemClip.isEmpty()) {-
782 QRegion clippedDeviceRgn = systemClip & deviceRectUnclipped;-
783 deviceRect = clippedDeviceRgn.boundingRect();-
784 baseClip->setClipRegion(clippedDeviceRgn);-
785 } else {-
786 deviceRect = deviceRectUnclipped;-
787 baseClip->setClipRect(deviceRect);-
788 }-
789-
790-
791-
792-
793 exDeviceRect = deviceRect;-
794-
795 QRasterPaintEngine * const q = q_func();-
796 if (q->state()) {-
797 q->state()->strokeFlags |= QPaintEngine::DirtyClipRegion;-
798 q->state()->fillFlags |= QPaintEngine::DirtyClipRegion;-
799 q->state()->pixmapFlags |= QPaintEngine::DirtyClipRegion;-
800 }-
801}-
802-
803void QRasterPaintEnginePrivate::updateMatrixData(QSpanData *spanData, const QBrush &b, const QTransform &m)-
804{-
805 if (b.d->style == Qt::NoBrush || b.d->style == Qt::SolidPattern)-
806 return;-
807-
808 QRasterPaintEngine * const q = q_func();-
809 bool bilinear = q->state()->flags.bilinear;-
810-
811 if (b.d->transform.type() > QTransform::TxNone) {-
812 spanData->setupMatrix(b.transform() * m, bilinear);-
813 } else {-
814 if (m.type() <= QTransform::TxTranslate) {-
815-
816-
817 spanData->m11 = 1;-
818 spanData->m12 = 0;-
819 spanData->m13 = 0;-
820 spanData->m21 = 0;-
821 spanData->m22 = 1;-
822 spanData->m23 = 0;-
823 spanData->m33 = 1;-
824 spanData->dx = -m.dx();-
825 spanData->dy = -m.dy();-
826 spanData->txop = m.type();-
827 spanData->bilinear = bilinear;-
828 spanData->fast_matrix = qAbs(m.dx()) < 1e4 && qAbs(m.dy()) < 1e4;-
829 spanData->adjustSpanMethods();-
830 } else {-
831 spanData->setupMatrix(m, bilinear);-
832 }-
833 }-
834}-
835static void qrasterpaintengine_state_setNoClip(QRasterPaintEngineState *s)-
836{-
837 if (s->flags.has_clip_ownership)-
838 delete s->clip;-
839 s->clip = 0;-
840 s->flags.has_clip_ownership = false;-
841}-
842-
843static void qrasterpaintengine_dirty_clip(QRasterPaintEnginePrivate *d, QRasterPaintEngineState *s)-
844{-
845 s->fillFlags |= QPaintEngine::DirtyClipPath;-
846 s->strokeFlags |= QPaintEngine::DirtyClipPath;-
847 s->pixmapFlags |= QPaintEngine::DirtyClipPath;-
848-
849 d->solid_color_filler.clip = d->clip();-
850 d->solid_color_filler.adjustSpanMethods();-
851-
852-
853-
854-
855-
856}-
857-
858-
859-
860-
861-
862void QRasterPaintEngine::clip(const QVectorPath &path, Qt::ClipOperation op)-
863{-
864 QRasterPaintEnginePrivate * const d = d_func();-
865 QRasterPaintEngineState *s = state();-
866-
867-
868 if (op != Qt::IntersectClip
op != Qt::IntersectClipDescription
TRUEnever evaluated
FALSEnever evaluated
|| !s->clip
!s->clipDescription
TRUEnever evaluated
FALSEnever evaluated
|| s->clip->hasRectClip
s->clip->hasRectClipDescription
TRUEnever evaluated
FALSEnever evaluated
|| s->clip->hasRegionClip
s->clip->hasRegionClipDescription
TRUEnever evaluated
FALSEnever evaluated
) {
0
869 if (s->matrix.type() <= QTransform::TxScale
s->matrix.type...sform::TxScaleDescription
TRUEnever evaluated
FALSEnever evaluated
0
870 && path.isRect()
path.isRect()Description
TRUEnever evaluated
FALSEnever evaluated
) {
0
871-
872-
873-
874 const qreal *points = path.points();-
875 QRectF r(points[0], points[1], points[4]-points[0], points[5]-points[1]);-
876 if (setClipRectInDeviceCoords(s->matrix.mapRect(r).toRect(), op)
setClipRectInD....toRect(), op)Description
TRUEnever evaluated
FALSEnever evaluated
)
0
877 return;
never executed: return;
0
878 }
never executed: end of block
0
879 }
never executed: end of block
0
880-
881 if (op == Qt::NoClip
op == Qt::NoClipDescription
TRUEnever evaluated
FALSEnever evaluated
) {
0
882 qrasterpaintengine_state_setNoClip(s);-
883-
884 }
never executed: end of block
else {
0
885 QClipData *base = d->baseClip.data();-
886-
887-
888 if (op == Qt::IntersectClip
op == Qt::IntersectClipDescription
TRUEnever evaluated
FALSEnever evaluated
&& s->clip
s->clipDescription
TRUEnever evaluated
FALSEnever evaluated
)
0
889 base = s->clip;
never executed: base = s->clip;
0
890-
891-
892-
893-
894 Qt::ClipOperation isectOp = Qt::IntersectClip;-
895 if (base == 0
base == 0Description
TRUEnever evaluated
FALSEnever evaluated
)
0
896 isectOp = Qt::ReplaceClip;
never executed: isectOp = Qt::ReplaceClip;
0
897-
898 QClipData *newClip = new QClipData(d->rasterBuffer->height());-
899 newClip->initialize();-
900 ClipData clipData = { base, newClip, isectOp };-
901 ensureOutlineMapper();-
902 d->rasterize(d->outlineMapper->convertPath(path), qt_span_clip, &clipData, 0);-
903-
904 newClip->fixup();-
905-
906 if (s->flags.has_clip_ownership
s->flags.has_clip_ownershipDescription
TRUEnever evaluated
FALSEnever evaluated
)
0
907 delete s->clip;
never executed: delete s->clip;
0
908-
909 s->clip = newClip;-
910 s->flags.has_clip_ownership = true;-
911 }
never executed: end of block
0
912 qrasterpaintengine_dirty_clip(d, s);-
913}
never executed: end of block
0
914-
915-
916-
917-
918-
919-
920void QRasterPaintEngine::clip(const QRect &rect, Qt::ClipOperation op)-
921{-
922-
923-
924-
925-
926 QRasterPaintEngineState *s = state();-
927-
928 if (op == Qt::NoClip) {-
929 qrasterpaintengine_state_setNoClip(s);-
930-
931 } else if (s->matrix.type() > QTransform::TxScale) {-
932 QPaintEngineEx::clip(rect, op);-
933 return;-
934-
935 } else if (!setClipRectInDeviceCoords(s->matrix.mapRect(rect), op)) {-
936 QPaintEngineEx::clip(rect, op);-
937 return;-
938 }-
939}-
940-
941-
942bool QRasterPaintEngine::setClipRectInDeviceCoords(const QRect &r, Qt::ClipOperation op)-
943{-
944 QRasterPaintEnginePrivate * const d = d_func();-
945 QRect clipRect = r & d->deviceRect;-
946 QRasterPaintEngineState *s = state();-
947-
948 if (op == Qt::ReplaceClip || s->clip == 0) {-
949-
950-
951-
952 QRegion clipRegion = systemClip();-
953 QClipData *clip = new QClipData(d->rasterBuffer->height());-
954-
955 if (clipRegion.isEmpty())-
956 clip->setClipRect(clipRect);-
957 else-
958 clip->setClipRegion(clipRegion & clipRect);-
959-
960 if (s->flags.has_clip_ownership)-
961 delete s->clip;-
962-
963 s->clip = clip;-
964 s->clip->enabled = true;-
965 s->flags.has_clip_ownership = true;-
966-
967 } else if (op == Qt::IntersectClip){-
968 QClipData *base = s->clip;-
969-
970 ((!(base)) ? qt_assert("base",__FILE__,12581264) : qt_noop());-
971 if (base->hasRectClip || base->hasRegionClip) {-
972 if (!s->flags.has_clip_ownership) {-
973 s->clip = new QClipData(d->rasterBuffer->height());-
974 s->flags.has_clip_ownership = true;-
975 }-
976 if (base->hasRectClip)-
977 s->clip->setClipRect(base->clipRect & clipRect);-
978 else-
979 s->clip->setClipRegion(base->clipRegion & clipRect);-
980 s->clip->enabled = true;-
981 } else {-
982 return false;-
983 }-
984 } else {-
985 return false;-
986 }-
987-
988 qrasterpaintengine_dirty_clip(d, s);-
989 return true;-
990}-
991-
992-
993-
994-
995-
996void QRasterPaintEngine::clip(const QRegion &region, Qt::ClipOperation op)-
997{-
998-
999-
1000-
1001-
1002 QRasterPaintEnginePrivate * const d = d_func();-
1003-
1004 if (region.rectCount() == 1) {-
1005 clip(region.boundingRect(), op);-
1006 return;-
1007 }-
1008-
1009 QRasterPaintEngineState *s = state();-
1010 const QClipData *clip = d->clip();-
1011 const QClipData *baseClip = d->baseClip.data();-
1012-
1013 if (op == Qt::NoClip) {-
1014 qrasterpaintengine_state_setNoClip(s);-
1015 } else if (s->matrix.type() > QTransform::TxScale-
1016 || (op == Qt::IntersectClip && !clip->hasRectClip && !clip->hasRegionClip)-
1017 || (op == Qt::ReplaceClip && !baseClip->hasRectClip && !baseClip->hasRegionClip)) {-
1018 QPaintEngineEx::clip(region, op);-
1019 } else {-
1020 const QClipData *curClip;-
1021 QClipData *newClip;-
1022-
1023 if (op == Qt::IntersectClip)-
1024 curClip = clip;-
1025 else-
1026 curClip = baseClip;-
1027-
1028 if (s->flags.has_clip_ownership) {-
1029 newClip = s->clip;-
1030 ((!(newClip)) ? qt_assert("newClip",__FILE__,13181324) : qt_noop());-
1031 } else {-
1032 newClip = new QClipData(d->rasterBuffer->height());-
1033 s->clip = newClip;-
1034 s->flags.has_clip_ownership = true;-
1035 }-
1036-
1037 QRegion r = s->matrix.map(region);-
1038 if (curClip->hasRectClip)-
1039 newClip->setClipRegion(r & curClip->clipRect);-
1040 else if (curClip->hasRegionClip)-
1041 newClip->setClipRegion(r & curClip->clipRegion);-
1042-
1043 qrasterpaintengine_dirty_clip(d, s);-
1044 }-
1045}-
1046void QRasterPaintEngine::fillPath(const QPainterPath &path, QSpanData *fillData)-
1047{-
1048-
1049-
1050-
1051-
1052 if (!fillData->blend)-
1053 return;-
1054-
1055 QRasterPaintEnginePrivate * const d = d_func();-
1056-
1057 const QRectF controlPointRect = path.controlPointRect();-
1058-
1059 QRasterPaintEngineState *s = state();-
1060 const QRect deviceRect = s->matrix.mapRect(controlPointRect).toRect();-
1061 ProcessSpans blend = d->getBrushFunc(deviceRect, fillData);-
1062 const bool do_clip = (deviceRect.left() < -QT_RASTER_COORD_LIMIT-
1063 || deviceRect.right() > QT_RASTER_COORD_LIMIT-
1064 || deviceRect.top() < -QT_RASTER_COORD_LIMIT-
1065 || deviceRect.bottom() > QT_RASTER_COORD_LIMIT);-
1066-
1067 if (!s->flags.antialiased && !do_clip) {-
1068 d->initializeRasterizer(fillData);-
1069 d->rasterizer->rasterize(path * s->matrix, path.fillRule());-
1070 return;-
1071 }-
1072-
1073 ensureOutlineMapper();-
1074 d->rasterize(d->outlineMapper->convertPath(path), blend, fillData, d->rasterBuffer.data());-
1075}-
1076-
1077static void fillRect_normalized(const QRect &r, QSpanData *data,-
1078 QRasterPaintEnginePrivate *pe)-
1079{-
1080 int x1, x2, y1, y2;-
1081-
1082 bool rectClipped = true;-
1083-
1084 if (data->clip) {-
1085 x1 = qMax(r.x(), data->clip->xmin);-
1086 x2 = qMin(r.x() + r.width(), data->clip->xmax);-
1087 y1 = qMax(r.y(), data->clip->ymin);-
1088 y2 = qMin(r.y() + r.height(), data->clip->ymax);-
1089 rectClipped = data->clip->hasRectClip;-
1090-
1091 } else if (pe) {-
1092 x1 = qMax(r.x(), pe->deviceRect.x());-
1093 x2 = qMin(r.x() + r.width(), pe->deviceRect.x() + pe->deviceRect.width());-
1094 y1 = qMax(r.y(), pe->deviceRect.y());-
1095 y2 = qMin(r.y() + r.height(), pe->deviceRect.y() + pe->deviceRect.height());-
1096 } else {-
1097 x1 = qMax(r.x(), 0);-
1098 x2 = qMin(r.x() + r.width(), data->rasterBuffer->width());-
1099 y1 = qMax(r.y(), 0);-
1100 y2 = qMin(r.y() + r.height(), data->rasterBuffer->height());-
1101 }-
1102-
1103 if (x2 <= x1 || y2 <= y1)-
1104 return;-
1105-
1106 const int width = x2 - x1;-
1107 const int height = y2 - y1;-
1108-
1109 bool isUnclipped = rectClipped-
1110 || (pe && pe->isUnclipped_normalized(QRect(x1, y1, width, height)));-
1111-
1112 if (pe && isUnclipped) {-
1113 const QPainter::CompositionMode mode = pe->rasterBuffer->compositionMode;-
1114-
1115 if (data->fillRect && (mode == QPainter::CompositionMode_Source-
1116 || (mode == QPainter::CompositionMode_SourceOver-
1117 && data->solid.color.isOpaque())))-
1118 {-
1119 data->fillRect(data->rasterBuffer, x1, y1, width, height, data->solid.color);-
1120 return;-
1121 }-
1122 }-
1123-
1124 ProcessSpans blend = isUnclipped ? data->unclipped_blend : data->blend;-
1125-
1126 const int nspans = 256;-
1127 QT_FT_Span spans[nspans];-
1128-
1129 ((!(data->blend)) ? qt_assert("data->blend",__FILE__,14281434) : qt_noop());-
1130 int y = y1;-
1131 while (y < y2) {-
1132 int n = qMin(nspans, y2 - y);-
1133 int i = 0;-
1134 while (i < n) {-
1135 spans[i].x = x1;-
1136 spans[i].len = width;-
1137 spans[i].y = y + i;-
1138 spans[i].coverage = 255;-
1139 ++i;-
1140 }-
1141-
1142 blend(n, spans, data);-
1143 y += n;-
1144 }-
1145}-
1146-
1147-
1148-
1149-
1150void QRasterPaintEngine::drawRects(const QRect *rects, int rectCount)-
1151{-
1152-
1153-
1154-
1155 QRasterPaintEnginePrivate * const d = d_func();-
1156 ensureRasterState();-
1157 QRasterPaintEngineState *s = state();-
1158-
1159-
1160 ensureBrush();-
1161 if (s->brushData.blend) {-
1162 if (!s->flags.antialiased && s->matrix.type() <= QTransform::TxTranslate) {-
1163 const QRect *r = rects;-
1164 const QRect *lastRect = rects + rectCount;-
1165-
1166 int offset_x = int(s->matrix.dx());-
1167 int offset_y = int(s->matrix.dy());-
1168 while (r < lastRect) {-
1169 QRect rect = r->normalized();-
1170 QRect rr = rect.translated(offset_x, offset_y);-
1171 fillRect_normalized(rr, &s->brushData, d);-
1172 ++r;-
1173 }-
1174 } else {-
1175 QRectVectorPath path;-
1176 for (int i=0; i<rectCount; ++i) {-
1177 path.set(rects[i]);-
1178 fill(path, s->brush);-
1179 }-
1180 }-
1181 }-
1182-
1183 ensurePen();-
1184 if (s->penData.blend) {-
1185 QRectVectorPath path;-
1186 if (s->flags.fast_pen) {-
1187 QCosmeticStroker stroker(s, d->deviceRect, d->deviceRectUnclipped);-
1188 stroker.setLegacyRoundingEnabled(s->flags.legacy_rounding);-
1189 for (int i = 0; i < rectCount; ++i) {-
1190 path.set(rects[i]);-
1191 stroker.drawPath(path);-
1192 }-
1193 } else {-
1194 for (int i = 0; i < rectCount; ++i) {-
1195 path.set(rects[i]);-
1196 stroke(path, s->pen);-
1197 }-
1198 }-
1199 }-
1200}-
1201-
1202-
1203-
1204-
1205void QRasterPaintEngine::drawRects(const QRectF *rects, int rectCount)-
1206{-
1207-
1208-
1209-
1210-
1211 QRasterPaintEnginePrivate * const d = d_func();-
1212 ensureRasterState();-
1213 QRasterPaintEngineState *s = state();-
1214-
1215-
1216 if (s->flags.tx_noshear) {-
1217 ensureBrush();-
1218 if (s->brushData.blend) {-
1219 d->initializeRasterizer(&s->brushData);-
1220 for (int i = 0; i < rectCount; ++i) {-
1221 const QRectF &rect = rects[i].normalized();-
1222 if (rect.isEmpty())-
1223 continue;-
1224 const QPointF a = s->matrix.map((rect.topLeft() + rect.bottomLeft()) * 0.5f);-
1225 const QPointF b = s->matrix.map((rect.topRight() + rect.bottomRight()) * 0.5f);-
1226 d->rasterizer->rasterizeLine(a, b, rect.height() / rect.width());-
1227 }-
1228 }-
1229-
1230 ensurePen();-
1231 if (s->penData.blend) {-
1232 QRectVectorPath path;-
1233 if (s->flags.fast_pen) {-
1234 QCosmeticStroker stroker(s, d->deviceRect, d->deviceRectUnclipped);-
1235 stroker.setLegacyRoundingEnabled(s->flags.legacy_rounding);-
1236 for (int i = 0; i < rectCount; ++i) {-
1237 path.set(rects[i]);-
1238 stroker.drawPath(path);-
1239 }-
1240 } else {-
1241 for (int i = 0; i < rectCount; ++i) {-
1242 path.set(rects[i]);-
1243 QPaintEngineEx::stroke(path, s->lastPen);-
1244 }-
1245 }-
1246 }-
1247-
1248 return;-
1249 }-
1250-
1251 QPaintEngineEx::drawRects(rects, rectCount);-
1252}-
1253-
1254-
1255-
1256-
1257-
1258void QRasterPaintEngine::stroke(const QVectorPath &path, const QPen &pen)-
1259{-
1260 QRasterPaintEnginePrivate * const d = d_func();-
1261 QRasterPaintEngineState *s = state();-
1262-
1263 ensurePen(pen);-
1264 if (!s->penData.blend)-
1265 return;-
1266-
1267 if (s->flags.fast_pen) {-
1268 QCosmeticStroker stroker(s, d->deviceRect, d->deviceRectUnclipped);-
1269 stroker.setLegacyRoundingEnabled(s->flags.legacy_rounding);-
1270 stroker.drawPath(path);-
1271 } else if (s->flags.non_complex_pen && path.shape() == QVectorPath::LinesHint) {-
1272 qreal width = qt_pen_is_cosmetic(s->lastPen, s->renderHints)-
1273 ? (qpen_widthf(s->lastPen) == 0 ? 1 : qpen_widthf(s->lastPen))-
1274 : qpen_widthf(s->lastPen) * s->txscale;-
1275 int dashIndex = 0;-
1276 qreal dashOffset = s->lastPen.dashOffset();-
1277 bool inDash = true;-
1278 qreal patternLength = 0;-
1279 const QVector<qreal> pattern = s->lastPen.dashPattern();-
1280 for (int i = 0; i < pattern.size(); ++i)-
1281 patternLength += pattern.at(i);-
1282-
1283 if (patternLength > 0) {-
1284 int n = qFloor(dashOffset / patternLength);-
1285 dashOffset -= n * patternLength;-
1286 while (dashOffset >= pattern.at(dashIndex)) {-
1287 dashOffset -= pattern.at(dashIndex);-
1288 if (++dashIndex >= pattern.size())-
1289 dashIndex = 0;-
1290 inDash = !inDash;-
1291 }-
1292 }-
1293-
1294 QRasterPaintEnginePrivate * const d = d_func();-
1295 d->initializeRasterizer(&s->penData);-
1296 int lineCount = path.elementCount() / 2;-
1297 const QLineF *lines = reinterpret_cast<const QLineF *>(path.points());-
1298-
1299 for (int i = 0; i < lineCount; ++i) {-
1300 if (lines[i].p1() == lines[i].p2()) {-
1301 if (s->lastPen.capStyle() != Qt::FlatCap) {-
1302 QPointF p = lines[i].p1();-
1303 QLineF line = s->matrix.map(QLineF(QPointF(p.x() - width*0.5, p.y()),-
1304 QPointF(p.x() + width*0.5, p.y())));-
1305 d->rasterizer->rasterizeLine(line.p1(), line.p2(), 1);-
1306 }-
1307 continue;-
1308 }-
1309-
1310 const QLineF line = s->matrix.map(lines[i]);-
1311 if (qpen_style(s->lastPen) == Qt::SolidLine) {-
1312 d->rasterizer->rasterizeLine(line.p1(), line.p2(),-
1313 width / line.length(),-
1314 s->lastPen.capStyle() == Qt::SquareCap);-
1315 } else {-
1316 d->rasterizeLine_dashed(line, width,-
1317 &dashIndex, &dashOffset, &inDash);-
1318 }-
1319 }-
1320 }-
1321 else-
1322 QPaintEngineEx::stroke(path, pen);-
1323}-
1324-
1325QRect QRasterPaintEngine::toNormalizedFillRect(const QRectF &rect)-
1326{-
1327 QRasterPaintEngineState *s = state();-
1328-
1329 qreal delta = s->flags.legacy_rounding ? aliasedCoordinateDelta : qreal(0);-
1330-
1331 int x1 = qRound(rect.x() + delta);-
1332 int y1 = qRound(rect.y() + delta);-
1333 int x2 = qRound(rect.right() + delta);-
1334 int y2 = qRound(rect.bottom() + delta);-
1335-
1336 if (x2 < x1)-
1337 qSwap(x1, x2);-
1338 if (y2 < y1)-
1339 qSwap(y1, y2);-
1340-
1341 return QRect(x1, y1, x2 - x1, y2 - y1);-
1342}-
1343-
1344-
1345-
1346-
1347void QRasterPaintEngine::fill(const QVectorPath &path, const QBrush &brush)-
1348{-
1349 if (path.isEmpty()
path.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
)
0
1350 return;
never executed: return;
0
1351 QRasterPaintEnginePrivate * const d = d_func();-
1352 QRasterPaintEngineState *s = state();-
1353-
1354 ensureBrush(brush);-
1355 if (!s->brushData.blend
!s->brushData.blendDescription
TRUEnever evaluated
FALSEnever evaluated
)
0
1356 return;
never executed: return;
0
1357-
1358 if (path.shape() == QVectorPath::RectangleHint
path.shape() =...:RectangleHintDescription
TRUEnever evaluated
FALSEnever evaluated
) {
0
1359 if (!s->flags.antialiased
!s->flags.antialiasedDescription
TRUEnever evaluated
FALSEnever evaluated
&& s->matrix.type() <= QTransform::TxScale
s->matrix.type...sform::TxScaleDescription
TRUEnever evaluated
FALSEnever evaluated
) {
0
1360 const qreal *p = path.points();-
1361 QPointF tl = QPointF(p[0], p[1]) * s->matrix;-
1362 QPointF br = QPointF(p[4], p[5]) * s->matrix;-
1363 fillRect_normalized(toNormalizedFillRect(QRectF(tl, br)), &s->brushData, d);-
1364 return;
never executed: return;
0
1365 }-
1366 ensureRasterState();-
1367 if (s->flags.tx_noshear
s->flags.tx_noshearDescription
TRUEnever evaluated
FALSEnever evaluated
) {
0
1368 d->initializeRasterizer(&s->brushData);-
1369-
1370 const qreal *p = path.points();-
1371 QRectF r = QRectF(p[0], p[1], p[2] - p[0], p[7] - p[1]).normalized();-
1372 if (!r.isEmpty()
!r.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
) {
0
1373 const QPointF a = s->matrix.map((r.topLeft() + r.bottomLeft()) * 0.5f);-
1374 const QPointF b = s->matrix.map((r.topRight() + r.bottomRight()) * 0.5f);-
1375 d->rasterizer->rasterizeLine(a, b, r.height() / r.width());-
1376 }
never executed: end of block
0
1377 return;
never executed: return;
0
1378 }-
1379 }
never executed: end of block
0
1380-
1381-
1382 QRectF cpRect = path.controlPointRect();-
1383 const QRect deviceRectpathDeviceRect = s->matrix.mapRect(cpRect).toRect();-
1384-
1385 if (!pathDeviceRect.intersects(d->deviceRect)
!pathDeviceRec...d->deviceRect)Description
TRUEnever evaluated
FALSEnever evaluated
)
0
1386 return;
never executed: return;
0
1387-
1388 ProcessSpans blend = d->getBrushFunc(deviceRectpathDeviceRect, &s->brushData);-
1389 ensureOutlineMapper();-
1390 d->rasterize(d->outlineMapper->convertPath(path), blend, &s->brushData, d->rasterBuffer.data());-
1391}
never executed: end of block
0
1392-
1393void QRasterPaintEngine::fillRect(const QRectF &r, QSpanData *data)-
1394{-
1395 QRasterPaintEnginePrivate * const d = d_func();-
1396 QRasterPaintEngineState *s = state();-
1397-
1398 if (!s->flags.antialiased) {-
1399 uint txop = s->matrix.type();-
1400 if (txop == QTransform::TxNone) {-
1401 fillRect_normalized(toNormalizedFillRect(r), data, d);-
1402 return;-
1403 } else if (txop == QTransform::TxTranslate) {-
1404 const QRect rr = toNormalizedFillRect(r.translated(s->matrix.dx(), s->matrix.dy()));-
1405 fillRect_normalized(rr, data, d);-
1406 return;-
1407 } else if (txop == QTransform::TxScale) {-
1408 const QRect rr = toNormalizedFillRect(s->matrix.mapRect(r));-
1409 fillRect_normalized(rr, data, d);-
1410 return;-
1411 }-
1412 }-
1413 ensureRasterState();-
1414 if (s->flags.tx_noshear) {-
1415 d->initializeRasterizer(data);-
1416 QRectF nr = r.normalized();-
1417 if (!nr.isEmpty()) {-
1418 const QPointF a = s->matrix.map((nr.topLeft() + nr.bottomLeft()) * 0.5f);-
1419 const QPointF b = s->matrix.map((nr.topRight() + nr.bottomRight()) * 0.5f);-
1420 d->rasterizer->rasterizeLine(a, b, nr.height() / nr.width());-
1421 }-
1422 return;-
1423 }-
1424-
1425 QPainterPath path;-
1426 path.addRect(r);-
1427 ensureOutlineMapper();-
1428 fillPath(path, data);-
1429}-
1430-
1431-
1432-
1433-
1434void QRasterPaintEngine::fillRect(const QRectF &r, const QBrush &brush)-
1435{-
1436-
1437-
1438-
1439 QRasterPaintEngineState *s = state();-
1440-
1441 ensureBrush(brush);-
1442 if (!s->brushData.blend)-
1443 return;-
1444-
1445 fillRect(r, &s->brushData);-
1446}-
1447-
1448-
1449-
1450-
1451void QRasterPaintEngine::fillRect(const QRectF &r, const QColor &color)-
1452{-
1453-
1454-
1455-
1456 QRasterPaintEnginePrivate * const d = d_func();-
1457 QRasterPaintEngineState *s = state();-
1458-
1459 d->solid_color_filler.solid.color = qPremultiply(combineAlpha256(color.rgba64(), s->intOpacity));-
1460-
1461 if (d->solid_color_filler.solid.color.isTransparent()-
1462 && s->composition_mode == QPainter::CompositionMode_SourceOver) {-
1463 return;-
1464 }-
1465 d->solid_color_filler.clip = d->clip();-
1466 d->solid_color_filler.adjustSpanMethods();-
1467 fillRect(r, &d->solid_color_filler);-
1468}-
1469-
1470static inline bool isAbove(const QPointF *a, const QPointF *b)-
1471{-
1472 return a->y() < b->y();-
1473}-
1474-
1475static bool splitPolygon(const QPointF *points, int pointCount, QVector<QPointF> *upper, QVector<QPointF> *lower)-
1476{-
1477 ((!(upper)) ? qt_assert("upper",__FILE__,17941804) : qt_noop());-
1478 ((!(lower)) ? qt_assert("lower",__FILE__,17951805) : qt_noop());-
1479-
1480 ((!(pointCount >= 2)) ? qt_assert("pointCount >= 2",__FILE__,17971807) : qt_noop());-
1481-
1482 QVector<const QPointF *> sorted;-
1483 sorted.reserve(pointCount);-
1484-
1485 upper->reserve(pointCount * 3 / 4);-
1486 lower->reserve(pointCount * 3 / 4);-
1487-
1488 for (int i = 0; i < pointCount; ++i)-
1489 sorted << points + i;-
1490-
1491 std::sort(sorted.begin(), sorted.end(), isAbove);-
1492-
1493 qreal splitY = sorted.at(sorted.size() / 2)->y();-
1494-
1495 const QPointF *end = points + pointCount;-
1496 const QPointF *last = end - 1;-
1497-
1498 QVector<QPointF> *bin[2] = { upper, lower };-
1499-
1500 for (const QPointF *p = points; p < end; ++p) {-
1501 int side = p->y() < splitY;-
1502 int lastSide = last->y() < splitY;-
1503-
1504 if (side != lastSide) {-
1505 if (qFuzzyCompare(p->y(), splitY)) {-
1506 bin[!side]->append(*p);-
1507 } else if (qFuzzyCompare(last->y(), splitY)) {-
1508 bin[side]->append(*last);-
1509 } else {-
1510 QPointF delta = *p - *last;-
1511 QPointF intersection(p->x() + delta.x() * (splitY - p->y()) / delta.y(), splitY);-
1512-
1513 bin[0]->append(intersection);-
1514 bin[1]->append(intersection);-
1515 }-
1516 }-
1517-
1518 bin[side]->append(*p);-
1519-
1520 last = p;-
1521 }-
1522-
1523-
1524 return upper->size() < pointCount && lower->size() < pointCount;-
1525}-
1526-
1527-
1528-
1529-
1530void QRasterPaintEngine::fillPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode)-
1531{-
1532 QRasterPaintEnginePrivate * const d = d_func();-
1533 QRasterPaintEngineState *s = state();-
1534-
1535 const int maxPoints = 0xffff;-
1536-
1537-
1538 if (pointCount > maxPoints) {-
1539 QVector<QPointF> upper, lower;-
1540-
1541 if (splitPolygon(points, pointCount, &upper, &lower)) {-
1542 fillPolygon(upper.constData(), upper.size(), mode);-
1543 fillPolygon(lower.constData(), lower.size(), mode);-
1544 } else-
1545 QMessageLogger(__FILE__, 18621872, __PRETTY_FUNCTION__).warning("Polygon too complex for filling.");-
1546-
1547 return;-
1548 }-
1549-
1550-
1551 QVectorPath vp((const qreal *) points, pointCount, 0, QVectorPath::polygonFlags(mode));-
1552 ensureOutlineMapper();-
1553 QT_FT_Outline *outline = d->outlineMapper->convertPath(vp);-
1554-
1555-
1556 ProcessSpans brushBlend = d->getBrushFunc(d->outlineMapper->controlPointRect,-
1557 &s->brushData);-
1558 d->rasterize(outline, brushBlend, &s->brushData, d->rasterBuffer.data());-
1559}-
1560-
1561-
1562-
1563-
1564void QRasterPaintEngine::drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode)-
1565{-
1566 QRasterPaintEnginePrivate * const d = d_func();-
1567 QRasterPaintEngineState *s = state();-
1568-
1569-
1570-
1571-
1572-
1573-
1574 ((!(pointCount >= 2)) ? qt_assert("pointCount >= 2",__FILE__,18911901) : qt_noop());-
1575-
1576 if (mode != PolylineMode && QVectorPath::isRect((const qreal *) points, pointCount)) {-
1577 QRectF r(points[0], points[2]);-
1578 drawRects(&r, 1);-
1579 return;-
1580 }-
1581-
1582 ensurePen();-
1583 if (mode != PolylineMode) {-
1584-
1585 ensureBrush();-
1586 if (s->brushData.blend)-
1587 fillPolygon(points, pointCount, mode);-
1588 }-
1589-
1590-
1591 if (s->penData.blend) {-
1592 QVectorPath vp((const qreal *) points, pointCount, 0, QVectorPath::polygonFlags(mode));-
1593 if (s->flags.fast_pen) {-
1594 QCosmeticStroker stroker(s, d->deviceRect, d->deviceRectUnclipped);-
1595 stroker.setLegacyRoundingEnabled(s->flags.legacy_rounding);-
1596 stroker.drawPath(vp);-
1597 } else {-
1598 QPaintEngineEx::stroke(vp, s->lastPen);-
1599 }-
1600 }-
1601}-
1602-
1603-
1604-
1605-
1606void QRasterPaintEngine::drawPolygon(const QPoint *points, int pointCount, PolygonDrawMode mode)-
1607{-
1608 QRasterPaintEnginePrivate * const d = d_func();-
1609 QRasterPaintEngineState *s = state();-
1610-
1611-
1612-
1613-
1614-
1615-
1616 ((!(pointCount >= 2)) ? qt_assert("pointCount >= 2",__FILE__,19331943) : qt_noop());-
1617 if (mode != PolylineMode && QVectorPath::isRect((const int *) points, pointCount)) {-
1618 QRect r(points[0].x(),-
1619 points[0].y(),-
1620 points[2].x() - points[0].x(),-
1621 points[2].y() - points[0].y());-
1622 drawRects(&r, 1);-
1623 return;-
1624 }-
1625-
1626 ensurePen();-
1627-
1628-
1629 if (mode != PolylineMode) {-
1630 ensureBrush();-
1631 if (s->brushData.blend) {-
1632-
1633 ensureOutlineMapper();-
1634 d->outlineMapper->beginOutline(mode == WindingMode ? Qt::WindingFill : Qt::OddEvenFill);-
1635 d->outlineMapper->moveTo(*points);-
1636 const QPoint *p = points;-
1637 const QPoint *ep = points + pointCount - 1;-
1638 do {-
1639 d->outlineMapper->lineTo(*(++p));-
1640 } while (p < ep);-
1641 d->outlineMapper->endOutline();-
1642-
1643-
1644 ProcessSpans brushBlend = d->getBrushFunc(d->outlineMapper->controlPointRect,-
1645 &s->brushData);-
1646 d->rasterize(d->outlineMapper->outline(), brushBlend, &s->brushData, d->rasterBuffer.data());-
1647 }-
1648 }-
1649-
1650-
1651 if (s->penData.blend) {-
1652 int count = pointCount * 2;-
1653 QVarLengthArray<qreal> fpoints(count);-
1654 for (int i=0; i<count; ++i)-
1655 fpoints[i] = ((const int *) points)[i];-
1656 QVectorPath vp((qreal *) fpoints.data(), pointCount, 0, QVectorPath::polygonFlags(mode));-
1657-
1658 if (s->flags.fast_pen) {-
1659 QCosmeticStroker stroker(s, d->deviceRect, d->deviceRectUnclipped);-
1660 stroker.setLegacyRoundingEnabled(s->flags.legacy_rounding);-
1661 stroker.drawPath(vp);-
1662 } else {-
1663 QPaintEngineEx::stroke(vp, s->lastPen);-
1664 }-
1665 }-
1666}-
1667-
1668-
1669-
1670-
1671void QRasterPaintEngine::drawPixmap(const QPointF &pos, const QPixmap &pixmap)-
1672{-
1673-
1674-
1675-
1676-
1677 QPlatformPixmap *pd = pixmap.handle();-
1678 if (pd->classId() == QPlatformPixmap::RasterClass) {-
1679 const QImage &image = static_cast<QRasterPlatformPixmap *>(pd)->image;-
1680 if (image.depth() == 1) {-
1681 QRasterPaintEnginePrivate * const d = d_func();-
1682 QRasterPaintEngineState *s = state();-
1683 if (s->matrix.type() <= QTransform::TxTranslate) {-
1684 ensurePen();-
1685 drawBitmap(pos + QPointF(s->matrix.dx(), s->matrix.dy()), image, &s->penData);-
1686 } else {-
1687 drawImage(pos, d->rasterBuffer->colorizeBitmap(image, s->pen.color()));-
1688 }-
1689 } else {-
1690 QRasterPaintEngine::drawImage(pos, image);-
1691 }-
1692 } else {-
1693 const QImage image = pixmap.toImage();-
1694 if (pixmap.depth() == 1) {-
1695 QRasterPaintEnginePrivate * const d = d_func();-
1696 QRasterPaintEngineState *s = state();-
1697 if (s->matrix.type() <= QTransform::TxTranslate) {-
1698 ensurePen();-
1699 drawBitmap(pos + QPointF(s->matrix.dx(), s->matrix.dy()), image, &s->penData);-
1700 } else {-
1701 drawImage(pos, d->rasterBuffer->colorizeBitmap(image, s->pen.color()));-
1702 }-
1703 } else {-
1704 QRasterPaintEngine::drawImage(pos, image);-
1705 }-
1706 }-
1707}-
1708-
1709-
1710-
1711-
1712void QRasterPaintEngine::drawPixmap(const QRectF &r, const QPixmap &pixmap, const QRectF &sr)-
1713{-
1714-
1715-
1716-
1717-
1718 QPlatformPixmap* pd = pixmap.handle();-
1719 if (pd->classId() == QPlatformPixmap::RasterClass) {-
1720 const QImage &image = static_cast<QRasterPlatformPixmap *>(pd)->image;-
1721 if (image.depth() == 1) {-
1722 QRasterPaintEnginePrivate * const d = d_func();-
1723 QRasterPaintEngineState *s = state();-
1724 if (s->matrix.type() <= QTransform::TxTranslate-
1725 && r.size() == sr.size()-
1726 && r.size() == pixmap.size()) {-
1727 ensurePen();-
1728 drawBitmap(r.topLeft() + QPointF(s->matrix.dx(), s->matrix.dy()), image, &s->penData);-
1729 return;-
1730 } else {-
1731 drawImage(r, d->rasterBuffer->colorizeBitmap(image, s->pen.color()), sr);-
1732 }-
1733 } else {-
1734 drawImage(r, image, sr);-
1735 }-
1736 } else {-
1737 QRect clippedSource = sr.toAlignedRect().intersected(pixmap.rect());-
1738 const QImage image = pd->toImage(clippedSource);-
1739 QRectF translatedSource = sr.translated(-clippedSource.topLeft());-
1740 if (image.depth() == 1) {-
1741 QRasterPaintEnginePrivate * const d = d_func();-
1742 QRasterPaintEngineState *s = state();-
1743 if (s->matrix.type() <= QTransform::TxTranslate-
1744 && r.size() == sr.size()-
1745 && r.size() == pixmap.size()) {-
1746 ensurePen();-
1747 drawBitmap(r.topLeft() + QPointF(s->matrix.dx(), s->matrix.dy()), image, &s->penData);-
1748 return;-
1749 } else {-
1750 drawImage(r, d->rasterBuffer->colorizeBitmap(image, s->pen.color()), translatedSource);-
1751 }-
1752 } else {-
1753 drawImage(r, image, translatedSource);-
1754 }-
1755 }-
1756}-
1757-
1758static inline int fast_ceil_positive(const qreal &v)-
1759{-
1760 const int iv = int(v);-
1761 if (v - iv == 0)-
1762 return iv;-
1763 else-
1764 return iv + 1;-
1765}-
1766-
1767static inline const QRect toAlignedRect_positive(const QRectF &rect)-
1768{-
1769 const int xmin = int(rect.x());-
1770 const int xmax = int(fast_ceil_positive(rect.right()));-
1771 const int ymin = int(rect.y());-
1772 const int ymax = int(fast_ceil_positive(rect.bottom()));-
1773 return QRect(xmin, ymin, xmax - xmin, ymax - ymin);-
1774}-
1775-
1776-
1777-
1778-
1779void QRasterPaintEngine::drawImage(const QPointF &p, const QImage &img)-
1780{-
1781-
1782-
1783-
1784-
1785 QRasterPaintEnginePrivate * const d = d_func();-
1786 QRasterPaintEngineState *s = state();-
1787 qreal scale = img.devicePixelRatio();-
1788-
1789 if (scale > 1.0 || s->matrix.type() > QTransform::TxTranslate) {-
1790 drawImage(QRectF(p.x(), p.y(), img.width() / scale, img.height() / scale),-
1791 img,-
1792 QRectF(0, 0, img.width(), img.height()));-
1793 } else {-
1794-
1795 const QClipData *clip = d->clip();-
1796 QPointF pt(p.x() + s->matrix.dx(), p.y() + s->matrix.dy());-
1797-
1798 if (d->canUseFastImageBlending(d->rasterBuffer->compositionMode, img)) {-
1799 SrcOverBlendFunc func = qBlendFunctions[d->rasterBuffer->format][img.format()];-
1800 if (func) {-
1801 if (!clip) {-
1802 d->drawImage(pt, img, func, d->deviceRect, s->intOpacity);-
1803 return;-
1804 } else if (clip->hasRectClip) {-
1805 d->drawImage(pt, img, func, clip->clipRect, s->intOpacity);-
1806 return;-
1807 }-
1808 }-
1809 }-
1810-
1811-
1812-
1813 d->image_filler.clip = clip;-
1814 d->image_filler.initTexture(&img, s->intOpacity, QTextureData::Plain, img.rect());-
1815 if (!d->image_filler.blend)-
1816 return;-
1817 d->image_filler.dx = -pt.x();-
1818 d->image_filler.dy = -pt.y();-
1819 QRect rr = img.rect().translated(qRound(pt.x()), qRound(pt.y()));-
1820-
1821 fillRect_normalized(rr, &d->image_filler, d);-
1822 }-
1823-
1824}-
1825-
1826QRectF qt_mapRect_non_normalizing(const QRectF &r, const QTransform &t)-
1827{-
1828 return QRectF(r.topLeft() * t, r.bottomRight() * t);-
1829}-
1830-
1831namespace {-
1832 enum RotationType {-
1833 Rotation90,-
1834 Rotation180,-
1835 Rotation270,-
1836 NoRotation-
1837 };-
1838-
1839 inline RotationType qRotationType(const QTransform &transform)-
1840 {-
1841 QTransform::TransformationType type = transform.type();-
1842-
1843 if (type > QTransform::TxRotate)-
1844 return NoRotation;-
1845-
1846 if (type == QTransform::TxRotate && qFuzzyIsNull(transform.m11()) && qFuzzyCompare(transform.m12(), qreal(-1))-
1847 && qFuzzyCompare(transform.m21(), qreal(1)) && qFuzzyIsNull(transform.m22()))-
1848 return Rotation90;-
1849-
1850 if (type == QTransform::TxScale && qFuzzyCompare(transform.m11(), qreal(-1)) && qFuzzyIsNull(transform.m12())-
1851 && qFuzzyIsNull(transform.m21()) && qFuzzyCompare(transform.m22(), qreal(-1)))-
1852 return Rotation180;-
1853-
1854 if (type == QTransform::TxRotate && qFuzzyIsNull(transform.m11()) && qFuzzyCompare(transform.m12(), qreal(1))-
1855 && qFuzzyCompare(transform.m21(), qreal(-1)) && qFuzzyIsNull(transform.m22()))-
1856 return Rotation270;-
1857-
1858 return NoRotation;-
1859 }-
1860-
1861 inline bool isPixelAligned(const QRectF &rect) {-
1862 return QRectF(rect.toRect()) == rect;-
1863 }-
1864}-
1865-
1866-
1867-
1868-
1869void QRasterPaintEngine::drawImage(const QRectF &r, const QImage &img, const QRectF &sr,-
1870 Qt::ImageConversionFlags)-
1871{-
1872-
1873-
1874-
1875-
1876 if (r.isEmpty())-
1877 return;-
1878-
1879 QRasterPaintEnginePrivate * const d = d_func();-
1880 QRasterPaintEngineState *s = state();-
1881 ((!(s)) ? qt_assert("s",__FILE__,21982208) : qt_noop());-
1882 int sr_l = qFloor(sr.left());-
1883 int sr_r = qCeil(sr.right()) - 1;-
1884 int sr_t = qFloor(sr.top());-
1885 int sr_b = qCeil(sr.bottom()) - 1;-
1886-
1887 if (s->matrix.type() <= QTransform::TxScale && !s->flags.antialiased && sr_l == sr_r && sr_t == sr_b) {-
1888-
1889-
1890 QTransform old = s->matrix;-
1891-
1892 if (s->flags.legacy_rounding)-
1893 s->matrix = s->matrix * QTransform::fromTranslate(-aliasedCoordinateDelta, -aliasedCoordinateDelta);-
1894-
1895-
1896 QRgb color = img.pixel(sr_l, sr_t);-
1897 switch (img.format()) {-
1898 case QImage::Format_ARGB32_Premultiplied:-
1899 case QImage::Format_ARGB8565_Premultiplied:-
1900 case QImage::Format_ARGB6666_Premultiplied:-
1901 case QImage::Format_ARGB8555_Premultiplied:-
1902 case QImage::Format_ARGB4444_Premultiplied:-
1903 case QImage::Format_RGBA8888_Premultiplied:-
1904 case QImage::Format_A2BGR30_Premultiplied:-
1905 case QImage::Format_A2RGB30_Premultiplied:-
1906-
1907 d->solid_color_filler.solid.color = multiplyAlpha256(QRgba64::fromArgb32(color), s->intOpacity);-
1908 break;-
1909 default:-
1910 d->solid_color_filler.solid.color = qPremultiply(combineAlpha256(QRgba64::fromArgb32(color), s->intOpacity));-
1911 break;-
1912 }-
1913-
1914 if (d->solid_color_filler.solid.color.isTransparent() && s->composition_mode == QPainter::CompositionMode_SourceOver)-
1915 return;-
1916-
1917 d->solid_color_filler.clip = d->clip();-
1918 d->solid_color_filler.adjustSpanMethods();-
1919 fillRect(r, &d->solid_color_filler);-
1920-
1921 s->matrix = old;-
1922 return;-
1923 }-
1924-
1925 bool stretch_sr = r.width() != sr.width() || r.height() != sr.height();-
1926-
1927 const QClipData *clip = d->clip();-
1928-
1929 if (s->matrix.type() > QTransform::TxTranslate-
1930 && !stretch_sr-
1931 && (!clip || clip->hasRectClip)-
1932 && s->intOpacity == 256-
1933 && (d->rasterBuffer->compositionMode == QPainter::CompositionMode_SourceOver-
1934 || d->rasterBuffer->compositionMode == QPainter::CompositionMode_Source)-
1935 && d->rasterBuffer->format == img.format()-
1936 && (d->rasterBuffer->format == QImage::Format_RGB16-
1937 || d->rasterBuffer->format == QImage::Format_RGB32-
1938 || (d->rasterBuffer->format == QImage::Format_ARGB32_Premultiplied-
1939 && d->rasterBuffer->compositionMode == QPainter::CompositionMode_Source)))-
1940 {-
1941 RotationType rotationType = qRotationType(s->matrix);-
1942-
1943 if (rotationType != NoRotation && qMemRotateFunctions[d->rasterBuffer->format][rotationType] && img.rect().contains(sr.toAlignedRect())) {-
1944 QRectF transformedTargetRect = s->matrix.mapRect(r);-
1945-
1946 if ((!(s->renderHints & QPainter::SmoothPixmapTransform) && !(s->renderHints & QPainter::Antialiasing))-
1947 || (isPixelAligned(transformedTargetRect) && isPixelAligned(sr)))-
1948 {-
1949 QRect clippedTransformedTargetRect = transformedTargetRect.toRect().intersected(clip ? clip->clipRect : d->deviceRect);-
1950 if (clippedTransformedTargetRect.isNull())-
1951 return;-
1952-
1953 QRectF clippedTargetRect = s->matrix.inverted().mapRect(QRectF(clippedTransformedTargetRect));-
1954-
1955 QRect clippedSourceRect-
1956 = QRectF(sr.x() + clippedTargetRect.x() - r.x(), sr.y() + clippedTargetRect.y() - r.y(),-
1957 clippedTargetRect.width(), clippedTargetRect.height()).toRect();-
1958-
1959 clippedSourceRect = clippedSourceRect.intersected(img.rect());-
1960-
1961 uint dbpl = d->rasterBuffer->bytesPerLine();-
1962 uint sbpl = img.bytesPerLine();-
1963-
1964 uchar *dst = d->rasterBuffer->buffer();-
1965 uint bpp = img.depth() >> 3;-
1966-
1967 const uchar *srcBase = img.bits() + clippedSourceRect.y() * sbpl + clippedSourceRect.x() * bpp;-
1968 uchar *dstBase = dst + clippedTransformedTargetRect.y() * dbpl + clippedTransformedTargetRect.x() * bpp;-
1969-
1970 uint cw = clippedSourceRect.width();-
1971 uint ch = clippedSourceRect.height();-
1972-
1973 qMemRotateFunctions[d->rasterBuffer->format][rotationType](srcBase, cw, ch, sbpl, dstBase, dbpl);-
1974-
1975 return;-
1976 }-
1977 }-
1978 }-
1979-
1980 if (s->matrix.type() > QTransform::TxTranslate || stretch_sr) {-
1981-
1982 QRectF targetBounds = s->matrix.mapRect(r);-
1983 bool exceedsPrecision = targetBounds.width() > 0xffff-
1984 || targetBounds.height() > 0xffff;-
1985-
1986 if (!exceedsPrecision && d->canUseFastImageBlending(d->rasterBuffer->compositionMode, img)) {-
1987 if (s->matrix.type() > QTransform::TxScale) {-
1988 SrcOverTransformFunc func = qTransformFunctions[d->rasterBuffer->format][img.format()];-
1989 if (func && (!clip || clip->hasRectClip)) {-
1990 func(d->rasterBuffer->buffer(), d->rasterBuffer->bytesPerLine(), img.bits(),-
1991 img.bytesPerLine(), r, sr, !clip ? d->deviceRect : clip->clipRect,-
1992 s->matrix, s->intOpacity);-
1993 return;-
1994 }-
1995 } else {-
1996-
1997 bool sourceRect2x = r.width() * 2 == sr.width() && r.height() * 2 == sr.height();-
1998 bool scale2x = (s->matrix.m11() == qreal(2)) && (s->matrix.m22() == qreal(2));-
1999 if (s->matrix.type() == QTransform::TxScale && sourceRect2x && scale2x) {-
2000 SrcOverBlendFunc func = qBlendFunctions[d->rasterBuffer->format][img.format()];-
2001 if (func) {-
2002 QPointF pt(r.x() * 2 + s->matrix.dx(), r.y() * 2 + s->matrix.dy());-
2003 if (!clip) {-
2004 d->drawImage(pt, img, func, d->deviceRect, s->intOpacity, sr.toRect());-
2005 return;-
2006 } else if (clip->hasRectClip) {-
2007 d->drawImage(pt, img, func, clip->clipRect, s->intOpacity, sr.toRect());-
2008 return;-
2009 }-
2010 }-
2011 }-
2012 SrcOverScaleFunc func = qScaleFunctions[d->rasterBuffer->format][img.format()];-
2013 if (func && (!clip || clip->hasRectClip)) {-
2014 func(d->rasterBuffer->buffer(), d->rasterBuffer->bytesPerLine(),-
2015 img.bits(), img.bytesPerLine(), img.height(),-
2016 qt_mapRect_non_normalizing(r, s->matrix), sr,-
2017 !clip ? d->deviceRect : clip->clipRect,-
2018 s->intOpacity);-
2019 return;-
2020 }-
2021 }-
2022 }-
2023-
2024 QTransform copy = s->matrix;-
2025 copy.translate(r.x(), r.y());-
2026 if (stretch_sr)-
2027 copy.scale(r.width() / sr.width(), r.height() / sr.height());-
2028 copy.translate(-sr.x(), -sr.y());-
2029-
2030 d->image_filler_xform.clip = clip;-
2031 d->image_filler_xform.initTexture(&img, s->intOpacity, QTextureData::Plain, toAlignedRect_positive(sr));-
2032 if (!d->image_filler_xform.blend)-
2033 return;-
2034 d->image_filler_xform.setupMatrix(copy, s->flags.bilinear);-
2035-
2036 if (!s->flags.antialiased && s->matrix.type() == QTransform::TxScale) {-
2037 QRectF rr = s->matrix.mapRect(r);-
2038-
2039 const int x1 = qRound(rr.x());-
2040 const int y1 = qRound(rr.y());-
2041 const int x2 = qRound(rr.right());-
2042 const int y2 = qRound(rr.bottom());-
2043-
2044 fillRect_normalized(QRect(x1, y1, x2-x1, y2-y1), &d->image_filler_xform, d);-
2045 return;-
2046 }-
2047-
2048-
2049 ensureRasterState();-
2050 if (s->flags.tx_noshear || s->matrix.type() == QTransform::TxScale) {-
2051 d->initializeRasterizer(&d->image_filler_xform);-
2052 d->rasterizer->setAntialiased(s->flags.antialiased);-
2053 d->rasterizer->setLegacyRoundingEnabled(s->flags.legacy_rounding);-
2054-
2055 const QPointF offs = s->flags.legacy_rounding ? QPointF(aliasedCoordinateDelta, aliasedCoordinateDelta) : QPointF();-
2056-
2057 const QRectF &rect = r.normalized();-
2058 const QPointF a = s->matrix.map((rect.topLeft() + rect.bottomLeft()) * 0.5f) - offs;-
2059 const QPointF b = s->matrix.map((rect.topRight() + rect.bottomRight()) * 0.5f) - offs;-
2060-
2061 if (s->flags.tx_noshear)-
2062 d->rasterizer->rasterizeLine(a, b, rect.height() / rect.width());-
2063 else-
2064 d->rasterizer->rasterizeLine(a, b, qAbs((s->matrix.m22() * rect.height()) / (s->matrix.m11() * rect.width())));-
2065 return;-
2066 }-
2067-
2068 const qreal offs = s->flags.legacy_rounding ? aliasedCoordinateDelta : qreal(0);-
2069 QPainterPath path;-
2070 path.addRect(r);-
2071 QTransform m = s->matrix;-
2072 s->matrix = QTransform(m.m11(), m.m12(), m.m13(),-
2073 m.m21(), m.m22(), m.m23(),-
2074 m.m31() - offs, m.m32() - offs, m.m33());-
2075 fillPath(path, &d->image_filler_xform);-
2076 s->matrix = m;-
2077 } else {-
2078 if (d->canUseFastImageBlending(d->rasterBuffer->compositionMode, img)) {-
2079 SrcOverBlendFunc func = qBlendFunctions[d->rasterBuffer->format][img.format()];-
2080 if (func) {-
2081 QPointF pt(r.x() + s->matrix.dx(), r.y() + s->matrix.dy());-
2082 if (!clip) {-
2083 d->drawImage(pt, img, func, d->deviceRect, s->intOpacity, sr.toRect());-
2084 return;-
2085 } else if (clip->hasRectClip) {-
2086 d->drawImage(pt, img, func, clip->clipRect, s->intOpacity, sr.toRect());-
2087 return;-
2088 }-
2089 }-
2090 }-
2091-
2092 d->image_filler.clip = clip;-
2093 d->image_filler.initTexture(&img, s->intOpacity, QTextureData::Plain, toAlignedRect_positive(sr));-
2094 if (!d->image_filler.blend)-
2095 return;-
2096 d->image_filler.dx = -(r.x() + s->matrix.dx()) + sr.x();-
2097 d->image_filler.dy = -(r.y() + s->matrix.dy()) + sr.y();-
2098-
2099 QRectF rr = r;-
2100 rr.translate(s->matrix.dx(), s->matrix.dy());-
2101-
2102 const int x1 = qRound(rr.x());-
2103 const int y1 = qRound(rr.y());-
2104 const int x2 = qRound(rr.right());-
2105 const int y2 = qRound(rr.bottom());-
2106-
2107 fillRect_normalized(QRect(x1, y1, x2-x1, y2-y1), &d->image_filler, d);-
2108 }-
2109}-
2110-
2111-
2112-
2113-
2114void QRasterPaintEngine::drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPointF &sr)-
2115{-
2116-
2117-
2118-
2119 QRasterPaintEnginePrivate * const d = d_func();-
2120 QRasterPaintEngineState *s = state();-
2121 ((!(s)) ? qt_assert("s",__FILE__,24382448) : qt_noop());-
2122-
2123 QImage image;-
2124-
2125 QPlatformPixmap *pd = pixmap.handle();-
2126 if (pd->classId() == QPlatformPixmap::RasterClass) {-
2127 image = static_cast<QRasterPlatformPixmap *>(pd)->image;-
2128 } else {-
2129 image = pixmap.toImage();-
2130 }-
2131-
2132 if (image.depth() == 1)-
2133 image = d->rasterBuffer->colorizeBitmap(image, s->pen.color());-
2134-
2135 if (s->matrix.type() > QTransform::TxTranslate) {-
2136 QTransform copy = s->matrix;-
2137 copy.translate(r.x(), r.y());-
2138 copy.translate(-sr.x(), -sr.y());-
2139 d->image_filler_xform.clip = d->clip();-
2140 d->image_filler_xform.initTexture(&image, s->intOpacity, QTextureData::Tiled);-
2141 if (!d->image_filler_xform.blend)-
2142 return;-
2143 d->image_filler_xform.setupMatrix(copy, s->flags.bilinear);-
2144-
2145-
2146 ensureRasterState();-
2147 if (s->flags.tx_noshear || s->matrix.type() == QTransform::TxScale) {-
2148 d->initializeRasterizer(&d->image_filler_xform);-
2149 d->rasterizer->setAntialiased(s->flags.antialiased);-
2150 d->rasterizer->setLegacyRoundingEnabled(s->flags.legacy_rounding);-
2151-
2152 const QRectF &rect = r.normalized();-
2153 const QPointF a = s->matrix.map((rect.topLeft() + rect.bottomLeft()) * 0.5f);-
2154 const QPointF b = s->matrix.map((rect.topRight() + rect.bottomRight()) * 0.5f);-
2155 if (s->flags.tx_noshear)-
2156 d->rasterizer->rasterizeLine(a, b, rect.height() / rect.width());-
2157 else-
2158 d->rasterizer->rasterizeLine(a, b, qAbs((s->matrix.m22() * rect.height()) / (s->matrix.m11() * rect.width())));-
2159 return;-
2160 }-
2161-
2162 QPainterPath path;-
2163 path.addRect(r);-
2164 fillPath(path, &d->image_filler_xform);-
2165 } else {-
2166 d->image_filler.clip = d->clip();-
2167-
2168 d->image_filler.initTexture(&image, s->intOpacity, QTextureData::Tiled);-
2169 if (!d->image_filler.blend)-
2170 return;-
2171 d->image_filler.dx = -(r.x() + s->matrix.dx()) + sr.x();-
2172 d->image_filler.dy = -(r.y() + s->matrix.dy()) + sr.y();-
2173-
2174 QRectF rr = r;-
2175 rr.translate(s->matrix.dx(), s->matrix.dy());-
2176 fillRect_normalized(rr.toRect().normalized(), &d->image_filler, d);-
2177 }-
2178}-
2179-
2180-
2181-
2182static inline bool monoVal(const uchar* s, int x)-
2183{-
2184 return (s[x>>3] << (x&7)) & 0x80;-
2185}-
2186-
2187-
2188-
2189-
2190QRasterBuffer *QRasterPaintEngine::rasterBuffer()-
2191{-
2192 QRasterPaintEnginePrivate * const d = d_func();-
2193 return d->rasterBuffer.data();-
2194}-
2195-
2196-
2197-
2198-
2199void QRasterPaintEngine::alphaPenBlt(const void* src, int bpl, int depth, int rx,int ry,int w,int h)-
2200{-
2201 QRasterPaintEnginePrivate * const d = d_func();-
2202 QRasterPaintEngineState *s = state();-
2203-
2204 if (!s->penData.blend)-
2205 return;-
2206-
2207 QRasterBuffer *rb = d->rasterBuffer.data();-
2208-
2209 const QRect rect(rx, ry, w, h);-
2210 const QClipData *clip = d->clip();-
2211 bool unclipped = false;-
2212 if (clip) {-
2213-
2214 const bool intersects = qMax(clip->xmin, rect.left()) <= qMin(clip->xmax - 1, rect.right())-
2215 && qMax(clip->ymin, rect.top()) <= qMin(clip->ymax - 1, rect.bottom());-
2216-
2217 if (clip->hasRectClip) {-
2218 unclipped = rx > clip->xmin-
2219 && rx + w < clip->xmax-
2220 && ry > clip->ymin-
2221 && ry + h < clip->ymax;-
2222 }-
2223-
2224 if (!intersects)-
2225 return;-
2226 } else {-
2227-
2228 const bool intersects = qMax(0, rect.left()) <= qMin(rb->width() - 1, rect.right())-
2229 && qMax(0, rect.top()) <= qMin(rb->height() - 1, rect.bottom());-
2230 if (!intersects)-
2231 return;-
2232-
2233-
2234 const bool contains = rect.left() >= 0 && rect.right() < rb->width()-
2235 && rect.top() >= 0 && rect.bottom() < rb->height();-
2236-
2237 unclipped = contains && d->isUnclipped_normalized(rect);-
2238 }-
2239-
2240 ProcessSpans blend = unclipped ? s->penData.unclipped_blend : s->penData.blend;-
2241 const uchar * scanline = static_cast<const uchar *>(src);-
2242-
2243 if (s->flags.fast_text) {-
2244 if (unclipped) {-
2245 if (depth == 1) {-
2246 if (s->penData.bitmapBlit) {-
2247 s->penData.bitmapBlit(rb, rx, ry, s->penData.solid.color,-
2248 scanline, w, h, bpl);-
2249 return;-
2250 }-
2251 } else if (depth == 8) {-
2252 if (s->penData.alphamapBlit) {-
2253 s->penData.alphamapBlit(rb, rx, ry, s->penData.solid.color,-
2254 scanline, w, h, bpl, 0);-
2255 return;-
2256 }-
2257 } else if (depth == 32) {-
2258-
2259 if (s->penData.alphaRGBBlit) {-
2260 s->penData.alphaRGBBlit(rb, rx, ry, s->penData.solid.color,-
2261 (const uint *) scanline, w, h, bpl / 4, 0);-
2262 return;-
2263 }-
2264 }-
2265 } else if (d->deviceDepth == 32 && ((depth == 8 && s->penData.alphamapBlit) || (depth == 32 && s->penData.alphaRGBBlit))) {-
2266-
2267 if (!clip) {-
2268 int nx = qMax(0, rx);-
2269 int ny = qMax(0, ry);-
2270-
2271-
2272 int xdiff = nx - rx;-
2273 int ydiff = ny - ry;-
2274 scanline += ydiff * bpl;-
2275 scanline += xdiff * (depth == 32 ? 4 : 1);-
2276-
2277 w -= xdiff;-
2278 h -= ydiff;-
2279-
2280 if (nx + w > d->rasterBuffer->width())-
2281 w = d->rasterBuffer->width() - nx;-
2282 if (ny + h > d->rasterBuffer->height())-
2283 h = d->rasterBuffer->height() - ny;-
2284-
2285 rx = nx;-
2286 ry = ny;-
2287 }-
2288 if (depth == 8)-
2289 s->penData.alphamapBlit(rb, rx, ry, s->penData.solid.color,-
2290 scanline, w, h, bpl, clip);-
2291 else if (depth == 32)-
2292 s->penData.alphaRGBBlit(rb, rx, ry, s->penData.solid.color,-
2293 (const uint *) scanline, w, h, bpl / 4, clip);-
2294 return;-
2295 }-
2296 }-
2297-
2298 int x0 = 0;-
2299 if (rx < 0) {-
2300 x0 = -rx;-
2301 w -= x0;-
2302 }-
2303-
2304 int y0 = 0;-
2305 if (ry < 0) {-
2306 y0 = -ry;-
2307 scanline += bpl * y0;-
2308 h -= y0;-
2309 }-
2310-
2311 w = qMin(w, rb->width() - qMax(0, rx));-
2312 h = qMin(h, rb->height() - qMax(0, ry));-
2313-
2314 if (w <= 0 || h <= 0)-
2315 return;-
2316-
2317 const int NSPANS = 256;-
2318 QSpan spans[NSPANS];-
2319 int current = 0;-
2320-
2321 const int x1 = x0 + w;-
2322 const int y1 = y0 + h;-
2323-
2324 if (depth == 1) {-
2325 for (int y = y0; y < y1; ++y) {-
2326 for (int x = x0; x < x1; ) {-
2327 if (!monoVal(scanline, x)) {-
2328 ++x;-
2329 continue;-
2330 }-
2331-
2332 if (current == NSPANS) {-
2333 blend(current, spans, &s->penData);-
2334 current = 0;-
2335 }-
2336 spans[current].x = x + rx;-
2337 spans[current].y = y + ry;-
2338 spans[current].coverage = 255;-
2339 int len = 1;-
2340 ++x;-
2341-
2342 while (x < x1 && monoVal(scanline, x)) {-
2343 ++x;-
2344 ++len;-
2345 }-
2346 spans[current].len = len;-
2347 ++current;-
2348 }-
2349 scanline += bpl;-
2350 }-
2351 } else if (depth == 8) {-
2352 for (int y = y0; y < y1; ++y) {-
2353 for (int x = x0; x < x1; ) {-
2354-
2355 if (scanline[x] == 0) {-
2356 ++x;-
2357 continue;-
2358 }-
2359-
2360 if (current == NSPANS) {-
2361 blend(current, spans, &s->penData);-
2362 current = 0;-
2363 }-
2364 int coverage = scanline[x];-
2365 spans[current].x = x + rx;-
2366 spans[current].y = y + ry;-
2367 spans[current].coverage = coverage;-
2368 int len = 1;-
2369 ++x;-
2370-
2371-
2372 while (x < x1 && scanline[x] == coverage) {-
2373 ++x;-
2374 ++len;-
2375 }-
2376 spans[current].len = len;-
2377 ++current;-
2378 }-
2379 scanline += bpl;-
2380 }-
2381 } else {-
2382 const uint *sl = (const uint *) scanline;-
2383 for (int y = y0; y < y1; ++y) {-
2384 for (int x = x0; x < x1; ) {-
2385-
2386 if ((sl[x] & 0x00ffffff) == 0) {-
2387 ++x;-
2388 continue;-
2389 }-
2390-
2391 if (current == NSPANS) {-
2392 blend(current, spans, &s->penData);-
2393 current = 0;-
2394 }-
2395 uint rgbCoverage = sl[x];-
2396 int coverage = qGreen(rgbCoverage);-
2397 spans[current].x = x + rx;-
2398 spans[current].y = y + ry;-
2399 spans[current].coverage = coverage;-
2400 int len = 1;-
2401 ++x;-
2402-
2403-
2404 while (x < x1 && sl[x] == rgbCoverage) {-
2405 ++x;-
2406 ++len;-
2407 }-
2408 spans[current].len = len;-
2409 ++current;-
2410 }-
2411 sl += bpl / sizeof(uint);-
2412 }-
2413 }-
2414-
2415-
2416-
2417 if (current != 0)-
2418 blend(current, spans, &s->penData);-
2419}-
2420-
2421-
2422-
2423-
2424bool QRasterPaintEngine::drawCachedGlyphs(int numGlyphs, const glyph_t *glyphs,-
2425 const QFixedPoint *positions, QFontEngine *fontEngine)-
2426{-
2427 QRasterPaintEnginePrivate * const d = d_func();-
2428 QRasterPaintEngineState *s = state();-
2429-
2430 if (fontEngine->hasInternalCaching()) {-
2431 QFontEngine::GlyphFormat neededFormat =-
2432 painter()->device()->devType() == QInternal::Widget-
2433 ? QFontEngine::Format_None-
2434 : QFontEngine::Format_A8;-
2435-
2436 if (d_func()->mono_surface)-
2437 neededFormat = QFontEngine::Format_Mono;-
2438-
2439 for (int i = 0; i < numGlyphs; i++) {-
2440 QFixed spp = fontEngine->subPixelPositionForX(positions[i].x);-
2441-
2442 QPoint offset;-
2443 const QImage *alphaMap = fontEngine->lockedAlphaMapForGlyph(glyphs[i], spp, neededFormat, s->matrix,-
2444 &offset);-
2445 if (alphaMap == 0 || alphaMap->isNull())-
2446 continue;-
2447-
2448 alphaPenBlt(alphaMap->constBits(), alphaMap->bytesPerLine(), alphaMap->depth(),-
2449 qFloor(positions[i].x) + offset.x(),-
2450 qRound(positions[i].y) + offset.y(),-
2451 alphaMap->width(), alphaMap->height());-
2452-
2453 fontEngine->unlockAlphaMapForGlyph();-
2454 }-
2455-
2456 } else {-
2457 QFontEngine::GlyphFormat glyphFormat = fontEngine->glyphFormat != QFontEngine::Format_None ? fontEngine->glyphFormat : d->glyphCacheFormat;-
2458-
2459 QImageTextureGlyphCache *cache =-
2460 static_cast<QImageTextureGlyphCache *>(fontEngine->glyphCache(0, glyphFormat, s->matrix));-
2461 if (!cache) {-
2462 cache = new QImageTextureGlyphCache(glyphFormat, s->matrix);-
2463 fontEngine->setGlyphCache(0, cache);-
2464 }-
2465-
2466 cache->populate(fontEngine, numGlyphs, glyphs, positions);-
2467 cache->fillInPendingGlyphs();-
2468-
2469 const QImage &image = cache->image();-
2470 int bpl = image.bytesPerLine();-
2471-
2472 int depth = image.depth();-
2473 int rightShift = 0;-
2474 int leftShift = 0;-
2475 if (depth == 32)-
2476 leftShift = 2;-
2477 else if (depth == 1)-
2478 rightShift = 3;-
2479-
2480 int margin = fontEngine->glyphMargin(glyphFormat);-
2481 const uchar *bits = image.bits();-
2482 for (int i=0; i<numGlyphs; ++i) {-
2483-
2484 QFixed subPixelPosition = fontEngine->subPixelPositionForX(positions[i].x);-
2485 QTextureGlyphCache::GlyphAndSubPixelPosition glyph(glyphs[i], subPixelPosition);-
2486 const QTextureGlyphCache::Coord &c = cache->coords[glyph];-
2487 if (c.isNull())-
2488 continue;-
2489-
2490 int x = qFloor(positions[i].x) + c.baseLineX - margin;-
2491 int y = qRound(positions[i].y) - c.baseLineY - margin;-
2492 const uchar *glyphBits = bits + ((c.x << leftShift) >> rightShift) + c.y * bpl;-
2493-
2494 if (glyphFormat == QFontEngine::Format_ARGB) {-
2495-
2496-
2497-
2498 QTransform originalTransform = s->matrix;-
2499 s->matrix = QTransform();-
2500 drawImage(QPoint(x, y), QImage(glyphBits, c.w, c.h, bpl, image.format()));-
2501 s->matrix = originalTransform;-
2502 } else {-
2503 alphaPenBlt(glyphBits, bpl, depth, x, y, c.w, c.h);-
2504 }-
2505 }-
2506 }-
2507 return true;-
2508}-
2509-
2510-
2511-
2512-
2513-
2514-
2515bool QRasterPaintEnginePrivate::isUnclipped_normalized(const QRect &r) const-
2516{-
2517 const QClipData *cl = clip();-
2518 if (!cl) {-
2519-
2520 const QRect &r1 = deviceRect;-
2521 return (r.left() >= r1.left() && r.right() <= r1.right()-
2522 && r.top() >= r1.top() && r.bottom() <= r1.bottom());-
2523 }-
2524-
2525-
2526 if (cl->hasRectClip) {-
2527-
2528 if (cl->clipRect == deviceRect)-
2529 return true;-
2530-
2531-
2532 const QRect &r1 = cl->clipRect;-
2533 return (r.left() >= r1.left() && r.right() <= r1.right()-
2534 && r.top() >= r1.top() && r.bottom() <= r1.bottom());-
2535 } else {-
2536 return qt_region_strictContains(cl->clipRegion, r);-
2537 }-
2538}-
2539-
2540bool QRasterPaintEnginePrivate::isUnclipped(const QRect &rect,-
2541 int penWidth) const-
2542{-
2543 const QRasterPaintEngine * const q = q_func();-
2544 const QRasterPaintEngineState *s = q->state();-
2545 const QClipData *cl = clip();-
2546 if (!cl) {-
2547 QRect r = rect.normalized();-
2548-
2549 const QRect &r1 = deviceRect;-
2550 return (r.left() >= r1.left() && r.right() <= r1.right()-
2551 && r.top() >= r1.top() && r.bottom() <= r1.bottom());-
2552 }-
2553-
2554-
2555-
2556 if (cl->hasRectClip && cl->clipRect == deviceRect)-
2557 return true;-
2558-
2559 if (s->flags.antialiased)-
2560 ++penWidth;-
2561-
2562 QRect r = rect.normalized();-
2563 if (penWidth > 0) {-
2564 r.setX(r.x() - penWidth);-
2565 r.setY(r.y() - penWidth);-
2566 r.setWidth(r.width() + 2 * penWidth);-
2567 r.setHeight(r.height() + 2 * penWidth);-
2568 }-
2569-
2570 if (cl->hasRectClip) {-
2571-
2572 const QRect &r1 = cl->clipRect;-
2573 return (r.left() >= r1.left() && r.right() <= r1.right()-
2574 && r.top() >= r1.top() && r.bottom() <= r1.bottom());-
2575 } else {-
2576 return qt_region_strictContains(cl->clipRegion, r);-
2577 }-
2578}-
2579-
2580inline bool QRasterPaintEnginePrivate::isUnclipped(const QRectF &rect,-
2581 int penWidth) const-
2582{-
2583 return isUnclipped(rect.normalized().toAlignedRect(), penWidth);-
2584}-
2585-
2586inline ProcessSpans-
2587QRasterPaintEnginePrivate::getBrushFunc(const QRect &rect,-
2588 const QSpanData *data) const-
2589{-
2590 return isUnclipped(rect, 0) ? data->unclipped_blend : data->blend;-
2591}-
2592-
2593inline ProcessSpans-
2594QRasterPaintEnginePrivate::getBrushFunc(const QRectF &rect,-
2595 const QSpanData *data) const-
2596{-
2597 return isUnclipped(rect, 0) ? data->unclipped_blend : data->blend;-
2598}-
2599-
2600inline ProcessSpans-
2601QRasterPaintEnginePrivate::getPenFunc(const QRectF &rect,-
2602 const QSpanData *data) const-
2603{-
2604 const QRasterPaintEngine * const q = q_func();-
2605 const QRasterPaintEngineState *s = q->state();-
2606-
2607 if (!s->flags.fast_pen && s->matrix.type() > QTransform::TxTranslate)-
2608 return data->blend;-
2609 const int penWidth = s->flags.fast_pen ? 1 : qCeil(s->lastPen.widthF());-
2610 return isUnclipped(rect, penWidth) ? data->unclipped_blend : data->blend;-
2611}-
2612-
2613static QPair<int, int> visibleGlyphRange(const QRectF &clip, QFontEngine *fontEngine,-
2614 glyph_t *glyphs, QFixedPoint *positions, int numGlyphs)-
2615{-
2616 QFixed clipLeft = QFixed::fromReal(clip.left());-
2617 QFixed clipRight = QFixed::fromReal(clip.right());-
2618 QFixed clipTop = QFixed::fromReal(clip.top());-
2619 QFixed clipBottom = QFixed::fromReal(clip.bottom());-
2620-
2621 int first = 0;-
2622 while (first < numGlyphs) {-
2623 glyph_metrics_t metrics = fontEngine->boundingBox(glyphs[first]);-
2624 QFixed left = metrics.x + positions[first].x;-
2625 QFixed top = metrics.y + positions[first].y;-
2626 QFixed right = left + metrics.width;-
2627 QFixed bottom = top + metrics.height;-
2628 if (left < clipRight && right > clipLeft && top < clipBottom && bottom > clipTop)-
2629 break;-
2630 ++first;-
2631 }-
2632 int last = numGlyphs - 1;-
2633 while (last > first) {-
2634 glyph_metrics_t metrics = fontEngine->boundingBox(glyphs[last]);-
2635 QFixed left = metrics.x + positions[last].x;-
2636 QFixed top = metrics.y + positions[last].y;-
2637 QFixed right = left + metrics.width;-
2638 QFixed bottom = top + metrics.height;-
2639 if (left < clipRight && right > clipLeft && top < clipBottom && bottom > clipTop)-
2640 break;-
2641 --last;-
2642 }-
2643 return QPair<int, int>(first, last + 1);-
2644}-
2645-
2646-
2647-
2648-
2649void QRasterPaintEngine::drawStaticTextItem(QStaticTextItem *textItem)-
2650{-
2651 if (textItem->numGlyphs == 0)-
2652 return;-
2653-
2654 ensurePen();-
2655 ensureRasterState();-
2656-
2657 QTransform matrix = state()->matrix;-
2658-
2659 QFontEngine *fontEngine = textItem->fontEngine();-
2660 if (shouldDrawCachedGlyphs(fontEngine, matrix)) {-
2661 drawCachedGlyphs(textItem->numGlyphs, textItem->glyphs, textItem->glyphPositions,-
2662 fontEngine);-
2663 } else if (matrix.type() < QTransform::TxProject) {-
2664 bool invertible;-
2665 QTransform invMat = matrix.inverted(&invertible);-
2666 if (!invertible)-
2667 return;-
2668-
2669 QPair<int, int> range = visibleGlyphRange(invMat.mapRect(clipBoundingRect()),-
2670 textItem->fontEngine(), textItem->glyphs,-
2671 textItem->glyphPositions, textItem->numGlyphs);-
2672 QStaticTextItem copy = *textItem;-
2673 copy.glyphs += range.first;-
2674 copy.glyphPositions += range.first;-
2675 copy.numGlyphs = range.second - range.first;-
2676 QPaintEngineEx::drawStaticTextItem(&copy);-
2677 } else {-
2678 QPaintEngineEx::drawStaticTextItem(textItem);-
2679 }-
2680}-
2681-
2682-
2683-
2684-
2685void QRasterPaintEngine::drawTextItem(const QPointF &p, const QTextItem &textItem)-
2686{-
2687 const QTextItemInt &ti = static_cast<const QTextItemInt &>(textItem);-
2688 if (ti.glyphs.numGlyphs == 0)-
2689 return;-
2690 ensurePen();-
2691 ensureRasterState();-
2692-
2693 QRasterPaintEngineState *s = state();-
2694 QTransform matrix = s->matrix;-
2695-
2696 if (shouldDrawCachedGlyphs(ti.fontEngine, matrix)) {-
2697 QVarLengthArray<QFixedPoint> positions;-
2698 QVarLengthArray<glyph_t> glyphs;-
2699-
2700 matrix.translate(p.x(), p.y());-
2701 ti.fontEngine->getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions);-
2702-
2703 drawCachedGlyphs(glyphs.size(), glyphs.constData(), positions.constData(), ti.fontEngine);-
2704 } else if (matrix.type() < QTransform::TxProject-
2705 && ti.fontEngine->supportsTransformation(matrix)) {-
2706 bool invertible;-
2707 QTransform invMat = matrix.inverted(&invertible);-
2708 if (!invertible)-
2709 return;-
2710-
2711 QVarLengthArray<QFixedPoint> positions;-
2712 QVarLengthArray<glyph_t> glyphs;-
2713-
2714 ti.fontEngine->getGlyphPositions(ti.glyphs, QTransform::fromTranslate(p.x(), p.y()),-
2715 ti.flags, glyphs, positions);-
2716 QPair<int, int> range = visibleGlyphRange(invMat.mapRect(clipBoundingRect()),-
2717 ti.fontEngine, glyphs.data(), positions.data(),-
2718 glyphs.size());-
2719-
2720 if (range.first >= range.second)-
2721 return;-
2722-
2723 QStaticTextItem staticTextItem;-
2724 staticTextItem.color = s->pen.color();-
2725 staticTextItem.font = s->font;-
2726 staticTextItem.setFontEngine(ti.fontEngine);-
2727 staticTextItem.numGlyphs = range.second - range.first;-
2728 staticTextItem.glyphs = glyphs.data() + range.first;-
2729 staticTextItem.glyphPositions = positions.data() + range.first;-
2730 QPaintEngineEx::drawStaticTextItem(&staticTextItem);-
2731 } else {-
2732 QPaintEngineEx::drawTextItem(p, ti);-
2733 }-
2734}-
2735-
2736-
2737-
2738-
2739void QRasterPaintEngine::drawPoints(const QPointF *points, int pointCount)-
2740{-
2741 QRasterPaintEnginePrivate * const d = d_func();-
2742 QRasterPaintEngineState *s = state();-
2743-
2744 ensurePen();-
2745 if (!s->penData.blend)-
2746 return;-
2747-
2748 if (!s->flags.fast_pen) {-
2749 QPaintEngineEx::drawPoints(points, pointCount);-
2750 return;-
2751 }-
2752-
2753 QCosmeticStroker stroker(s, d->deviceRect, d->deviceRectUnclipped);-
2754 stroker.setLegacyRoundingEnabled(s->flags.legacy_rounding);-
2755 stroker.drawPoints(points, pointCount);-
2756}-
2757-
2758-
2759void QRasterPaintEngine::drawPoints(const QPoint *points, int pointCount)-
2760{-
2761 QRasterPaintEnginePrivate * const d = d_func();-
2762 QRasterPaintEngineState *s = state();-
2763-
2764 ensurePen();-
2765 if (!s->penData.blend)-
2766 return;-
2767-
2768 if (!s->flags.fast_pen) {-
2769 QPaintEngineEx::drawPoints(points, pointCount);-
2770 return;-
2771 }-
2772-
2773 QCosmeticStroker stroker(s, d->deviceRect, d->deviceRectUnclipped);-
2774 stroker.setLegacyRoundingEnabled(s->flags.legacy_rounding);-
2775 stroker.drawPoints(points, pointCount);-
2776}-
2777-
2778-
2779-
2780-
2781void QRasterPaintEngine::drawLines(const QLine *lines, int lineCount)-
2782{-
2783-
2784-
2785-
2786 QRasterPaintEnginePrivate * const d = d_func();-
2787 QRasterPaintEngineState *s = state();-
2788-
2789 ensurePen();-
2790 if (!s->penData.blend)-
2791 return;-
2792-
2793 if (s->flags.fast_pen) {-
2794 QCosmeticStroker stroker(s, d->deviceRect, d->deviceRectUnclipped);-
2795 stroker.setLegacyRoundingEnabled(s->flags.legacy_rounding);-
2796 for (int i=0; i<lineCount; ++i) {-
2797 const QLine &l = lines[i];-
2798 stroker.drawLine(l.p1(), l.p2());-
2799 }-
2800 } else {-
2801 QPaintEngineEx::drawLines(lines, lineCount);-
2802 }-
2803}-
2804-
2805void QRasterPaintEnginePrivate::rasterizeLine_dashed(QLineF line,-
2806 qreal width,-
2807 int *dashIndex,-
2808 qreal *dashOffset,-
2809 bool *inDash)-
2810{-
2811 QRasterPaintEngine * const q = q_func();-
2812 QRasterPaintEngineState *s = q->state();-
2813-
2814 const QPen &pen = s->lastPen;-
2815 const bool squareCap = (pen.capStyle() == Qt::SquareCap);-
2816 const QVector<qreal> pattern = pen.dashPattern();-
2817-
2818 qreal patternLength = 0;-
2819 for (int i = 0; i < pattern.size()
i < pattern.size()Description
TRUEnever evaluated
FALSEnever evaluated
; ++i)
0
2820 patternLength += pattern.at(i);
never executed: patternLength += pattern.at(i);
0
2821-
2822 if (patternLength <= 0
patternLength <= 0Description
TRUEnever evaluated
FALSEnever evaluated
)
0
2823 return;
never executed: return;
0
2824-
2825 qreal length = line.length();-
2826 ((!(length > 0)) ? qt_assert("length > 0",__FILE__,31603170) : qt_noop());-
2827 while (length > 0
length > 0Description
TRUEnever evaluated
FALSEnever evaluated
) {
0
2828 const bool rasterize = *inDash;-
2829 qreal dash = (pattern.at(*dashIndex) - *dashOffset) * width;-
2830 QLineF l = line;-
2831-
2832 if (dash >= length
dash >= lengthDescription
TRUEnever evaluated
FALSEnever evaluated
) {
0
2833 dash = line.length();;-
2834 *dashOffset += dash / width;-
2835 length = 0;-
2836 }
never executed: end of block
else {
0
2837 *dashOffset = 0;-
2838 *inDash = !(*inDash);-
2839 if (++*
++*dashIndex >= pattern.size()Description
TRUEnever evaluated
FALSEnever evaluated
dashIndex >= pattern.size()
++*dashIndex >= pattern.size()Description
TRUEnever evaluated
FALSEnever evaluated
)
0
2840 *
never executed: *dashIndex = 0;
dashIndex = 0;
never executed: *dashIndex = 0;
0
2841 length -= dash;-
2842 l.setLength(dash);-
2843 line.setP1(l.p2());-
2844 }
never executed: end of block
0
2845-
2846 if (rasterize
rasterizeDescription
TRUEnever evaluated
FALSEnever evaluated
&& dash > 0
dash > 0Description
TRUEnever evaluated
FALSEnever evaluated
)
0
2847 rasterizer->rasterizeLine(l.p1(), l.p2(), width / dash, squareCap);
never executed: rasterizer->rasterizeLine(l.p1(), l.p2(), width / dash, squareCap);
0
2848 }
never executed: end of block
0
2849}
never executed: end of block
0
2850-
2851-
2852-
2853-
2854void QRasterPaintEngine::drawLines(const QLineF *lines, int lineCount)-
2855{-
2856-
2857-
2858-
2859 QRasterPaintEnginePrivate * const d = d_func();-
2860 QRasterPaintEngineState *s = state();-
2861-
2862 ensurePen();-
2863 if (!s->penData.blend)-
2864 return;-
2865 if (s->flags.fast_pen) {-
2866 QCosmeticStroker stroker(s, d->deviceRect, d->deviceRectUnclipped);-
2867 stroker.setLegacyRoundingEnabled(s->flags.legacy_rounding);-
2868 for (int i=0; i<lineCount; ++i) {-
2869 QLineF line = lines[i];-
2870 stroker.drawLine(line.p1(), line.p2());-
2871 }-
2872 } else {-
2873 QPaintEngineEx::drawLines(lines, lineCount);-
2874 }-
2875}-
2876-
2877-
2878-
2879-
2880-
2881void QRasterPaintEngine::drawEllipse(const QRectF &rect)-
2882{-
2883 QRasterPaintEnginePrivate * const d = d_func();-
2884 QRasterPaintEngineState *s = state();-
2885-
2886 ensurePen();-
2887 if (((qpen_style(s->lastPen) == Qt::SolidLine && s->flags.fast_pen)-
2888 || (qpen_style(s->lastPen) == Qt::NoPen))-
2889 && !s->flags.antialiased-
2890 && qMax(rect.width(), rect.height()) < QT_RASTER_COORD_LIMIT-
2891 && !rect.isEmpty()-
2892 && s->matrix.type() <= QTransform::TxScale)-
2893 {-
2894 ensureBrush();-
2895 const QRectF r = s->matrix.mapRect(rect);-
2896 ProcessSpans penBlend = d->getPenFunc(r, &s->penData);-
2897 ProcessSpans brushBlend = d->getBrushFunc(r, &s->brushData);-
2898 const QRect brect = QRect(int(r.x()), int(r.y()),-
2899 (int(r.x()+r.width()) - int(r.x())),-
2900 (int(r.y()+r.height()) - int(r.y())));-
2901 if (brect == r) {-
2902 drawEllipse_midpoint_i(brect, d->deviceRect, penBlend, brushBlend,-
2903 &s->penData, &s->brushData);-
2904 return;-
2905 }-
2906 }-
2907 QPaintEngineEx::drawEllipse(rect);-
2908}-
2909bool QRasterPaintEngine::requiresPretransformedGlyphPositions(QFontEngine *fontEngine, const QTransform &m) const-
2910{-
2911-
2912 if (shouldDrawCachedGlyphs(fontEngine, m))-
2913 return true;-
2914-
2915-
2916 return QPaintEngineEx::requiresPretransformedGlyphPositions(fontEngine, m);-
2917}-
2918-
2919-
2920-
2921-
2922-
2923bool QRasterPaintEngine::shouldDrawCachedGlyphs(QFontEngine *fontEngine, const QTransform &m) const-
2924{-
2925-
2926 if (m.type() >= QTransform::TxProject)-
2927 return false;-
2928-
2929-
2930-
2931-
2932-
2933-
2934 if (!fontEngine->hasInternalCaching() && !fontEngine->supportsTransformation(m))-
2935 return false;-
2936-
2937 return QPaintEngineEx::shouldDrawCachedGlyphs(fontEngine, m);-
2938}-
2939-
2940-
2941-
2942-
2943QPoint QRasterPaintEngine::coordinateOffset() const-
2944{-
2945 return QPoint(0, 0);-
2946}-
2947-
2948void QRasterPaintEngine::drawBitmap(const QPointF &pos, const QImage &image, QSpanData *fg)-
2949{-
2950 ((!(fg)) ? qt_assert("fg",__FILE__,33163326) : qt_noop());-
2951 if (!fg->blend)-
2952 return;-
2953 QRasterPaintEnginePrivate * const d = d_func();-
2954-
2955 ((!(image.depth() == 1)) ? qt_assert("image.depth() == 1",__FILE__,33213331) : qt_noop());-
2956-
2957 const int spanCount = 256;-
2958 QT_FT_Span spans[spanCount];-
2959 int n = 0;-
2960-
2961-
2962 int w = image.width();-
2963 int h = image.height();-
2964 int ymax = qMin(qRound(pos.y() + h), d->rasterBuffer->height());-
2965 int ymin = qMax(qRound(pos.y()), 0);-
2966 int xmax = qMin(qRound(pos.x() + w), d->rasterBuffer->width());-
2967 int xmin = qMax(qRound(pos.x()), 0);-
2968-
2969 int x_offset = xmin - qRound(pos.x());-
2970-
2971 QImage::Format format = image.format();-
2972 for (int y = ymin; y < ymax; ++y) {-
2973 const uchar *src = image.scanLine(y - qRound(pos.y()));-
2974 if (format == QImage::Format_MonoLSB) {-
2975 for (int x = 0; x < xmax - xmin; ++x) {-
2976 int src_x = x + x_offset;-
2977 uchar pixel = src[src_x >> 3];-
2978 if (!pixel) {-
2979 x += 7 - (src_x%8);-
2980 continue;-
2981 }-
2982 if (pixel & (0x1 << (src_x & 7))) {-
2983 spans[n].x = xmin + x;-
2984 spans[n].y = y;-
2985 spans[n].coverage = 255;-
2986 int len = 1;-
2987 while (src_x+1 < w && src[(src_x+1) >> 3] & (0x1 << ((src_x+1) & 7))) {-
2988 ++src_x;-
2989 ++len;-
2990 }-
2991 spans[n].len = ((len + spans[n].x) > xmax) ? (xmax - spans[n].x) : len;-
2992 x += len;-
2993 ++n;-
2994 if (n == spanCount) {-
2995 fg->blend(n, spans, fg);-
2996 n = 0;-
2997 }-
2998 }-
2999 }-
3000 } else {-
3001 for (int x = 0; x < xmax - xmin; ++x) {-
3002 int src_x = x + x_offset;-
3003 uchar pixel = src[src_x >> 3];-
3004 if (!pixel) {-
3005 x += 7 - (src_x%8);-
3006 continue;-
3007 }-
3008 if (pixel & (0x80 >> (x & 7))) {-
3009 spans[n].x = xmin + x;-
3010 spans[n].y = y;-
3011 spans[n].coverage = 255;-
3012 int len = 1;-
3013 while (src_x+1 < w && src[(src_x+1) >> 3] & (0x80 >> ((src_x+1) & 7))) {-
3014 ++src_x;-
3015 ++len;-
3016 }-
3017 spans[n].len = ((len + spans[n].x) > xmax) ? (xmax - spans[n].x) : len;-
3018 x += len;-
3019 ++n;-
3020 if (n == spanCount) {-
3021 fg->blend(n, spans, fg);-
3022 n = 0;-
3023 }-
3024 }-
3025 }-
3026 }-
3027 }-
3028 if (n) {-
3029 fg->blend(n, spans, fg);-
3030 n = 0;-
3031 }-
3032}-
3033QRasterPaintEngine::ClipType QRasterPaintEngine::clipType() const-
3034{-
3035 const QRasterPaintEnginePrivate * const d = d_func();-
3036-
3037 const QClipData *clip = d->clip();-
3038 if (!clip || clip->hasRectClip)-
3039 return RectClip;-
3040 else-
3041 return ComplexClip;-
3042}-
3043-
3044-
3045-
3046-
3047-
3048QRect QRasterPaintEngine::clipBoundingRect() const-
3049{-
3050 const QRasterPaintEnginePrivate * const d = d_func();-
3051-
3052 const QClipData *clip = d->clip();-
3053-
3054 if (!clip)-
3055 return d->deviceRect;-
3056-
3057 if (clip->hasRectClip)-
3058 return clip->clipRect;-
3059-
3060 return QRect(clip->xmin, clip->ymin, clip->xmax - clip->xmin, clip->ymax - clip->ymin);-
3061}-
3062-
3063void QRasterPaintEnginePrivate::initializeRasterizer(QSpanData *data)-
3064{-
3065 QRasterPaintEngine * const q = q_func();-
3066 QRasterPaintEngineState *s = q->state();-
3067-
3068 rasterizer->setAntialiased(s->flags.antialiased);-
3069 rasterizer->setLegacyRoundingEnabled(s->flags.legacy_rounding);-
3070-
3071 QRect clipRect(deviceRect);-
3072 ProcessSpans blend;-
3073-
3074-
3075 const QClipData *c = clip();-
3076 if (c) {-
3077 const QRect r(QPoint(c->xmin, c->ymin),-
3078 QSize(c->xmax - c->xmin, c->ymax - c->ymin));-
3079 clipRect = clipRect.intersected(r);-
3080 blend = data->blend;-
3081 } else {-
3082 blend = data->unclipped_blend;-
3083 }-
3084-
3085 rasterizer->setClipRect(clipRect);-
3086 rasterizer->initialize(blend, data);-
3087}-
3088-
3089void QRasterPaintEnginePrivate::rasterize(QT_FT_Outline *outline,-
3090 ProcessSpans callback,-
3091 QSpanData *spanData, QRasterBuffer *rasterBuffer)-
3092{-
3093 if (!callback || !outline)-
3094 return;-
3095-
3096 QRasterPaintEngine * const q = q_func();-
3097 QRasterPaintEngineState *s = q->state();-
3098-
3099 if (!s->flags.antialiased) {-
3100 initializeRasterizer(spanData);-
3101-
3102 const Qt::FillRule fillRule = outline->flags == 0x0-
3103 ? Qt::WindingFill-
3104 : Qt::OddEvenFill;-
3105-
3106 rasterizer->rasterize(outline, fillRule);-
3107 return;-
3108 }-
3109-
3110 rasterize(outline, callback, (void *)spanData, rasterBuffer);-
3111}-
3112-
3113extern "C" {-
3114 int q_gray_rendered_spans(QT_FT_Raster raster);-
3115}-
3116-
3117static inline uchar *alignAddress(uchar *address, quintptr alignmentMask)-
3118{-
3119 return (uchar *)(((quintptr)address + alignmentMask) & ~alignmentMask);-
3120}-
3121-
3122void QRasterPaintEnginePrivate::rasterize(QT_FT_Outline *outline,-
3123 ProcessSpans callback,-
3124 void *userData, QRasterBuffer *)-
3125{-
3126 if (!callback || !outline)-
3127 return;-
3128-
3129 QRasterPaintEngine * const q = q_func();-
3130 QRasterPaintEngineState *s = q->state();-
3131-
3132 if (!s->flags.antialiased) {-
3133 rasterizer->setAntialiased(s->flags.antialiased);-
3134 rasterizer->setLegacyRoundingEnabled(s->flags.legacy_rounding);-
3135 rasterizer->setClipRect(deviceRect);-
3136 rasterizer->initialize(callback, userData);-
3137-
3138 const Qt::FillRule fillRule = outline->flags == 0x0-
3139 ? Qt::WindingFill-
3140 : Qt::OddEvenFill;-
3141-
3142 rasterizer->rasterize(outline, fillRule);-
3143 return;-
3144 }-
3145-
3146-
3147-
3148-
3149-
3150 int rasterPoolSize = 8192;-
3151 uchar rasterPoolOnStack[8192 + 0xf];-
3152 uchar *rasterPoolBase = alignAddress(rasterPoolOnStack, 0xf);-
3153 uchar *rasterPoolOnHeap = 0;-
3154-
3155 qt_ft_grays_raster.raster_reset(*grayRaster.data(), rasterPoolBase, rasterPoolSize);-
3156-
3157 void *data = userData;-
3158-
3159 QT_FT_BBox clip_box = { deviceRect.x(),-
3160 deviceRect.y(),-
3161 deviceRect.x() + deviceRect.width(),-
3162 deviceRect.y() + deviceRect.height() };-
3163-
3164 QT_FT_Raster_Params rasterParams;-
3165 rasterParams.target = 0;-
3166 rasterParams.source = outline;-
3167 rasterParams.flags = 0x4;-
3168 rasterParams.gray_spans = 0;-
3169 rasterParams.black_spans = 0;-
3170 rasterParams.bit_test = 0;-
3171 rasterParams.bit_set = 0;-
3172 rasterParams.user = data;-
3173 rasterParams.clip_box = clip_box;-
3174-
3175 bool done = false;-
3176 int error;-
3177-
3178 int rendered_spans = 0;-
3179-
3180 while (!done) {-
3181-
3182 rasterParams.flags |= (0x1 | 0x2);-
3183 rasterParams.gray_spans = callback;-
3184 rasterParams.skip_spans = rendered_spans;-
3185 error = qt_ft_grays_raster.raster_render(*grayRaster.data(), &rasterParams);-
3186-
3187-
3188 if (error == -6) {-
3189 rasterPoolSize *= 2;-
3190 if (rasterPoolSize > 1024 * 1024) {-
3191 QMessageLogger(__FILE__, 35703580, __PRETTY_FUNCTION__).warning("QPainter: Rasterization of primitive failed");-
3192 break;-
3193 }-
3194-
3195 rendered_spans += q_gray_rendered_spans(*grayRaster.data());-
3196-
3197 free(rasterPoolOnHeap);-
3198 rasterPoolOnHeap = (uchar *)malloc(rasterPoolSize + 0xf);-
3199-
3200 do {if(!(rasterPoolOnHeap))qt_check_pointer(__FILE__,35793589);} while (0);-
3201-
3202 rasterPoolBase = alignAddress(rasterPoolOnHeap, 0xf);-
3203-
3204 qt_ft_grays_raster.raster_done(*grayRaster.data());-
3205 qt_ft_grays_raster.raster_new(grayRaster.data());-
3206 qt_ft_grays_raster.raster_reset(*grayRaster.data(), rasterPoolBase, rasterPoolSize);-
3207 } else {-
3208 done = true;-
3209 }-
3210 }-
3211-
3212 free(rasterPoolOnHeap);-
3213}-
3214-
3215void QRasterPaintEnginePrivate::recalculateFastImages()-
3216{-
3217 QRasterPaintEngine * const q = q_func();-
3218 QRasterPaintEngineState *s = q->state();-
3219-
3220 s->flags.fast_images = !(s->renderHints & QPainter::SmoothPixmapTransform)-
3221 && s->matrix.type() <= QTransform::TxShear;-
3222}-
3223-
3224bool QRasterPaintEnginePrivate::canUseFastImageBlending(QPainter::CompositionMode mode, const QImage &image) const-
3225{-
3226 const QRasterPaintEngine * const q = q_func();-
3227 const QRasterPaintEngineState *s = q->state();-
3228-
3229 return s->flags.fast_images-
3230 && (mode == QPainter::CompositionMode_SourceOver-
3231 || (mode == QPainter::CompositionMode_Source-
3232 && !image.hasAlphaChannel()));-
3233}-
3234-
3235QImage QRasterBuffer::colorizeBitmap(const QImage &image, const QColor &color)-
3236{-
3237 ((!(image.depth() == 1)) ? qt_assert("image.depth() == 1",__FILE__,36163626) : qt_noop());-
3238-
3239 const QImage sourceImage = image.convertToFormat(QImage::Format_MonoLSB);-
3240 QImage dest = QImage(sourceImage.size(), QImage::Format_ARGB32_Premultiplied);-
3241-
3242 QRgb fg = qPremultiply(color.rgba());-
3243 QRgb bg = 0;-
3244-
3245 int height = sourceImage.height();-
3246 int width = sourceImage.width();-
3247 for (int y=0; y<height; ++y) {-
3248 const uchar *source = sourceImage.constScanLine(y);-
3249 QRgb *target = reinterpret_cast<QRgb *>(dest.scanLine(y));-
3250 if (!source || !target)-
3251 qt_noop();-
3252 for (int x=0; x < width; ++x)-
3253 target[x] = (source[x>>3] >> (x&7)) & 1 ? fg : bg;-
3254 }-
3255 return dest;-
3256}-
3257-
3258QRasterBuffer::~QRasterBuffer()-
3259{-
3260}-
3261-
3262void QRasterBuffer::init()-
3263{-
3264 compositionMode = QPainter::CompositionMode_SourceOver;-
3265 monoDestinationWithClut = false;-
3266 destColor0 = 0;-
3267 destColor1 = 0;-
3268}-
3269-
3270QImage::Format QRasterBuffer::prepare(QImage *image)-
3271{-
3272 m_buffer = (uchar *)image->bits();-
3273 m_width = qMin(QT_RASTER_COORD_LIMIT, image->width());-
3274 m_height = qMin(QT_RASTER_COORD_LIMIT, image->height());-
3275 bytes_per_pixel = image->depth()/8;-
3276 bytes_per_line = image->bytesPerLine();-
3277-
3278 format = image->format();-
3279 drawHelper = qDrawHelper + format;-
3280 if (image->depth() == 1 && image->colorTable().size() == 2) {-
3281 monoDestinationWithClut = true;-
3282 const QVector<QRgb> colorTable = image->colorTable();-
3283 destColor0 = qPremultiply(colorTable[0]);-
3284 destColor1 = qPremultiply(colorTable[1]);-
3285 }-
3286-
3287 return format;-
3288}-
3289-
3290void QRasterBuffer::resetBuffer(int val)-
3291{-
3292 memset(m_buffer, val, m_height*bytes_per_line);-
3293}-
3294-
3295QClipData::QClipData(int height)-
3296{-
3297 clipSpanHeight = height;-
3298 m_clipLines = 0;-
3299-
3300 allocated = 0;-
3301 m_spans = 0;-
3302 xmin = xmax = ymin = ymax = 0;-
3303 count = 0;-
3304-
3305 enabled = true;-
3306 hasRectClip = hasRegionClip = false;-
3307}-
3308-
3309QClipData::~QClipData()-
3310{-
3311 if (m_clipLines)-
3312 free(m_clipLines);-
3313 if (m_spans)-
3314 free(m_spans);-
3315}-
3316-
3317void QClipData::initialize()-
3318{-
3319 if (m_spans)-
3320 return;-
3321-
3322 if (!m_clipLines)-
3323 m_clipLines = (ClipLine *)calloc(sizeof(ClipLine), clipSpanHeight);-
3324-
3325 do {if(!(m_clipLines))qt_check_pointer(__FILE__,37043714);} while (0);-
3326 if (true) {-
3327 m_spans = (QSpan *)malloc(clipSpanHeight*sizeof(QSpan));-
3328 allocated = clipSpanHeight;-
3329 do {if(!(m_spans))qt_check_pointer(__FILE__,37083718);} while (0);-
3330-
3331 if (true) {-
3332 if (hasRectClip) {-
3333 int y = 0;-
3334 while (y < ymin) {-
3335 m_clipLines[y].spans = 0;-
3336 m_clipLines[y].count = 0;-
3337 ++y;-
3338 }-
3339-
3340 const int len = clipRect.width();-
3341 count = 0;-
3342 while (y < ymax) {-
3343 QSpan *span = m_spans + count;-
3344 span->x = xmin;-
3345 span->len = len;-
3346 span->y = y;-
3347 span->coverage = 255;-
3348 ++count;-
3349-
3350 m_clipLines[y].spans = span;-
3351 m_clipLines[y].count = 1;-
3352 ++y;-
3353 }-
3354-
3355 while (y < clipSpanHeight) {-
3356 m_clipLines[y].spans = 0;-
3357 m_clipLines[y].count = 0;-
3358 ++y;-
3359 }-
3360 } else if (hasRegionClip) {-
3361-
3362 const QVector<QRect> rects = clipRegion.rects();-
3363 const int numRects = rects.size();-
3364-
3365 {-
3366 const int maxSpans = (ymax - ymin) * numRects;-
3367 if (maxSpans > allocated) {-
3368 m_spans = q_check_ptr((QSpan *)realloc(m_spans, maxSpans * sizeof(QSpan)));-
3369 allocated = maxSpans;-
3370 }-
3371 }-
3372-
3373 int y = 0;-
3374 int firstInBand = 0;-
3375 count = 0;-
3376 while (firstInBand < numRects) {-
3377 const int currMinY = rects.at(firstInBand).y();-
3378 const int currMaxY = currMinY + rects.at(firstInBand).height();-
3379-
3380 while (y < currMinY) {-
3381 m_clipLines[y].spans = 0;-
3382 m_clipLines[y].count = 0;-
3383 ++y;-
3384 }-
3385-
3386 int lastInBand = firstInBand;-
3387 while (lastInBand + 1 < numRects && rects.at(lastInBand+1).top() == y)-
3388 ++lastInBand;-
3389-
3390 while (y < currMaxY) {-
3391-
3392 m_clipLines[y].spans = m_spans + count;-
3393 m_clipLines[y].count = lastInBand - firstInBand + 1;-
3394-
3395 for (int r = firstInBand; r <= lastInBand; ++r) {-
3396 const QRect &currRect = rects.at(r);-
3397 QSpan *span = m_spans + count;-
3398 span->x = currRect.x();-
3399 span->len = currRect.width();-
3400 span->y = y;-
3401 span->coverage = 255;-
3402 ++count;-
3403 }-
3404 ++y;-
3405 }-
3406-
3407 firstInBand = lastInBand + 1;-
3408 }-
3409-
3410 ((!(count <= allocated)) ? qt_assert("count <= allocated",__FILE__,37893799) : qt_noop());-
3411-
3412 while (y < clipSpanHeight) {-
3413 m_clipLines[y].spans = 0;-
3414 m_clipLines[y].count = 0;-
3415 ++y;-
3416 }-
3417-
3418 }-
3419 } else {
dead code: { free(m_spans); m_spans = 0; qt_noop(); }
-
3420 free(m_spans);
dead code: { free(m_spans); m_spans = 0; qt_noop(); }
-
3421 m_spans = 0;
dead code: { free(m_spans); m_spans = 0; qt_noop(); }
-
3422 qt_noop();
dead code: { free(m_spans); m_spans = 0; qt_noop(); }
-
3423 }
dead code: { free(m_spans); m_spans = 0; qt_noop(); }
-
3424 } else {
dead code: { free(m_clipLines); m_clipLines = 0; qt_noop(); }
-
3425 free(m_clipLines);
dead code: { free(m_clipLines); m_clipLines = 0; qt_noop(); }
-
3426 m_clipLines = 0;
dead code: { free(m_clipLines); m_clipLines = 0; qt_noop(); }
-
3427 qt_noop();
dead code: { free(m_clipLines); m_clipLines = 0; qt_noop(); }
-
3428 }
dead code: { free(m_clipLines); m_clipLines = 0; qt_noop(); }
-
3429}-
3430-
3431void QClipData::fixup()-
3432{-
3433 ((!(m_spans)) ? qt_assert("m_spans",__FILE__,38123822) : qt_noop());-
3434-
3435 if (count == 0) {-
3436 ymin = ymax = xmin = xmax = 0;-
3437 return;-
3438 }-
3439-
3440 int y = -1;-
3441 ymin = m_spans[0].y;-
3442 ymax = m_spans[count-1].y + 1;-
3443 xmin = 2147483647;-
3444 xmax = 0;-
3445-
3446 const int firstLeft = m_spans[0].x;-
3447 const int firstRight = m_spans[0].x + m_spans[0].len;-
3448 bool isRect = true;-
3449-
3450 for (int i = 0; i < count; ++i) {-
3451 QT_FT_Span_& span = m_spans[i];-
3452-
3453 if (span.y != y) {-
3454 if (span.y != y + 1 && y != -1)-
3455 isRect = false;-
3456 y = span.y;-
3457 m_clipLines[y].spans = &span;-
3458 m_clipLines[y].count = 1;-
3459 } else-
3460 ++m_clipLines[y].count;-
3461-
3462 const int spanLeft = span.x;-
3463 const int spanRight = spanLeft + span.len;-
3464-
3465 if (spanLeft < xmin)-
3466 xmin = spanLeft;-
3467-
3468 if (spanRight > xmax)-
3469 xmax = spanRight;-
3470-
3471 if (spanLeft != firstLeft || spanRight != firstRight)-
3472 isRect = false;-
3473 }-
3474-
3475 if (isRect) {-
3476 hasRectClip = true;-
3477 clipRect.setRect(xmin, ymin, xmax - xmin, ymax - ymin);-
3478 }-
3479}-
3480-
3481-
3482-
3483-
3484void QClipData::setClipRect(const QRect &rect)-
3485{-
3486 if (hasRectClip && rect == clipRect)-
3487 return;-
3488-
3489-
3490 hasRectClip = true;-
3491 hasRegionClip = false;-
3492 clipRect = rect;-
3493-
3494 xmin = rect.x();-
3495 xmax = rect.x() + rect.width();-
3496 ymin = qMin(rect.y(), clipSpanHeight);-
3497 ymax = qMin(rect.y() + rect.height(), clipSpanHeight);-
3498-
3499 if (m_spans) {-
3500 free(m_spans);-
3501 m_spans = 0;-
3502 }-
3503-
3504-
3505}-
3506-
3507-
3508-
3509-
3510void QClipData::setClipRegion(const QRegion &region)-
3511{-
3512 if (region.rectCount() == 1) {-
3513 setClipRect(region.boundingRect());-
3514 return;-
3515 }-
3516-
3517 hasRegionClip = true;-
3518 hasRectClip = false;-
3519 clipRegion = region;-
3520-
3521 {-
3522 const QRect rect = region.boundingRect();-
3523 xmin = rect.x();-
3524 xmax = rect.x() + rect.width();-
3525 ymin = rect.y();-
3526 ymax = rect.y() + rect.height();-
3527 }-
3528-
3529 if (m_spans) {-
3530 free(m_spans);-
3531 m_spans = 0;-
3532 }-
3533-
3534}-
3535-
3536-
3537-
3538-
3539-
3540static const QSpan *qt_intersect_spans(const QClipData *clip, int *currentClip,-
3541 const QSpan *spans, const QSpan *end,-
3542 QSpan **outSpans, int available)-
3543{-
3544 const_cast<QClipData *>(clip)->initialize();-
3545-
3546 QSpan *out = *outSpans;-
3547-
3548 const QSpan *clipSpans = clip->m_spans + *currentClip;-
3549 const QSpan *clipEnd = clip->m_spans + clip->count;-
3550-
3551 while (available && spans < end ) {-
3552 if (clipSpans >= clipEnd) {-
3553 spans = end;-
3554 break;-
3555 }-
3556 if (clipSpans->y > spans->y) {-
3557 ++spans;-
3558 continue;-
3559 }-
3560 if (spans->y != clipSpans->y) {-
3561 if (spans->y < clip->count && clip->m_clipLines[spans->y].spans)-
3562 clipSpans = clip->m_clipLines[spans->y].spans;-
3563 else-
3564 ++clipSpans;-
3565 continue;-
3566 }-
3567 ((!(spans->y == clipSpans->y)) ? qt_assert("spans->y == clipSpans->y",__FILE__,39463956) : qt_noop());-
3568-
3569 int sx1 = spans->x;-
3570 int sx2 = sx1 + spans->len;-
3571 int cx1 = clipSpans->x;-
3572 int cx2 = cx1 + clipSpans->len;-
3573-
3574 if (cx1 < sx1 && cx2 < sx1) {-
3575 ++clipSpans;-
3576 continue;-
3577 } else if (sx1 < cx1 && sx2 < cx1) {-
3578 ++spans;-
3579 continue;-
3580 }-
3581 int x = qMax(sx1, cx1);-
3582 int len = qMin(sx2, cx2) - x;-
3583 if (len) {-
3584 out->x = qMax(sx1, cx1);-
3585 out->len = qMin(sx2, cx2) - out->x;-
3586 out->y = spans->y;-
3587 out->coverage = qt_div_255(spans->coverage * clipSpans->coverage);-
3588 ++out;-
3589 --available;-
3590 }-
3591 if (sx2 < cx2) {-
3592 ++spans;-
3593 } else {-
3594 ++clipSpans;-
3595 }-
3596 }-
3597-
3598 *outSpans = out;-
3599 *currentClip = clipSpans - clip->m_spans;-
3600 return spans;-
3601}-
3602-
3603static void qt_span_fill_clipped(int spanCount, const QSpan *spans, void *userData)-
3604{-
3605-
3606 QSpanData *fillData = reinterpret_cast<QSpanData *>(userData);-
3607-
3608 ((!(fillData->blend && fillData->unclipped_blend)) ? qt_assert("fillData->blend && fillData->unclipped_blend",__FILE__,39873997) : qt_noop());-
3609-
3610 const int NSPANS = 256;-
3611 QSpan cspans[NSPANS];-
3612 int currentClip = 0;-
3613 const QSpan *end = spans + spanCount;-
3614 while (spans < end) {-
3615 QSpan *clipped = cspans;-
3616 spans = qt_intersect_spans(fillData->clip, &currentClip, spans, end, &clipped, NSPANS);-
3617-
3618-
3619-
3620 if (clipped - cspans)-
3621 fillData->unclipped_blend(clipped - cspans, cspans, fillData);-
3622 }-
3623}-
3624-
3625-
3626-
3627-
3628-
3629-
3630static int qt_intersect_spans(QT_FT_Span *spans, int numSpans,-
3631 const QRect &clip)-
3632{-
3633 const short minx = clip.left();-
3634 const short miny = clip.top();-
3635 const short maxx = clip.right();-
3636 const short maxy = clip.bottom();-
3637-
3638 int n = 0;-
3639 for (int i = 0; i < numSpans; ++i) {-
3640 if (spans[i].y > maxy)-
3641 break;-
3642 if (spans[i].y < miny-
3643 || spans[i].x > maxx-
3644 || spans[i].x + spans[i].len <= minx) {-
3645 continue;-
3646 }-
3647 if (spans[i].x < minx) {-
3648 spans[n].len = qMin(spans[i].len - (minx - spans[i].x), maxx - minx + 1);-
3649 spans[n].x = minx;-
3650 } else {-
3651 spans[n].x = spans[i].x;-
3652 spans[n].len = qMin(spans[i].len, ushort(maxx - spans[n].x + 1));-
3653 }-
3654 if (spans[n].len == 0)-
3655 continue;-
3656 spans[n].y = spans[i].y;-
3657 spans[n].coverage = spans[i].coverage;-
3658 ++n;-
3659 }-
3660 return n;-
3661}-
3662-
3663-
3664static void qt_span_fill_clipRect(int count, const QSpan *spans,-
3665 void *userData)-
3666{-
3667 QSpanData *fillData = reinterpret_cast<QSpanData *>(userData);-
3668 ((!(fillData->blend && fillData->unclipped_blend)) ? qt_assert("fillData->blend && fillData->unclipped_blend",__FILE__,40474057) : qt_noop());-
3669-
3670 ((!(fillData->clip)) ? qt_assert("fillData->clip",__FILE__,40494059) : qt_noop());-
3671 ((!(!fillData->clip->clipRect.isEmpty())) ? qt_assert("!fillData->clip->clipRect.isEmpty()",__FILE__,40504060) : qt_noop());-
3672-
3673-
3674 count = qt_intersect_spans(const_cast<QSpan*>(spans), count,-
3675 fillData->clip->clipRect);-
3676 if (count > 0)-
3677 fillData->unclipped_blend(count, spans, fillData);-
3678}-
3679-
3680static void qt_span_clip(int count, const QSpan *spans, void *userData)-
3681{-
3682 ClipData *clipData = reinterpret_cast<ClipData *>(userData);-
3683-
3684-
3685-
3686-
3687-
3688-
3689 switch (clipData->operation) {-
3690-
3691 case Qt::IntersectClip:-
3692 {-
3693 QClipData *newClip = clipData->newClip;-
3694 newClip->initialize();-
3695-
3696 int currentClip = 0;-
3697 const QSpan *end = spans + count;-
3698 while (spans < end) {-
3699 QSpan *newspans = newClip->m_spans + newClip->count;-
3700 spans = qt_intersect_spans(clipData->oldClip, &currentClip, spans, end,-
3701 &newspans, newClip->allocated - newClip->count);-
3702 newClip->count = newspans - newClip->m_spans;-
3703 if (spans < end) {-
3704 newClip->m_spans = q_check_ptr((QSpan *)realloc(newClip->m_spans, newClip->allocated*2*sizeof(QSpan)));-
3705 newClip->allocated *= 2;-
3706 }-
3707 }-
3708 }-
3709 break;-
3710-
3711 case Qt::ReplaceClip:-
3712 clipData->newClip->appendSpans(spans, count);-
3713 break;-
3714 case Qt::NoClip:-
3715 break;-
3716 }-
3717}-
3718-
3719-
3720QImage QRasterBuffer::bufferImage() const-
3721{-
3722 QImage image(m_width, m_height, QImage::Format_ARGB32_Premultiplied);-
3723-
3724 for (int y = 0; y < m_height; ++y) {-
3725 uint *span = (uint *)const_cast<QRasterBuffer *>(this)->scanLine(y);-
3726-
3727 for (int x=0; x<m_width; ++x) {-
3728 uint argb = span[x];-
3729 image.setPixel(x, y, argb);-
3730 }-
3731 }-
3732 return image;-
3733}-
3734-
3735-
3736-
3737void QRasterBuffer::flushToARGBImage(QImage *target) const-
3738{-
3739 int w = qMin(m_width, target->width());-
3740 int h = qMin(m_height, target->height());-
3741-
3742 for (int y=0; y<h; ++y) {-
3743 uint *sourceLine = (uint *)const_cast<QRasterBuffer *>(this)->scanLine(y);-
3744 QRgb *dest = (QRgb *) target->scanLine(y);-
3745 for (int x=0; x<w; ++x) {-
3746 QRgb pixel = sourceLine[x];-
3747 int alpha = qAlpha(pixel);-
3748 if (!alpha) {-
3749 dest[x] = 0;-
3750 } else {-
3751 dest[x] = (alpha << 24)-
3752 | ((255*qRed(pixel)/alpha) << 16)-
3753 | ((255*qGreen(pixel)/alpha) << 8)-
3754 | ((255*qBlue(pixel)/alpha) << 0);-
3755 }-
3756 }-
3757 }-
3758}-
3759-
3760-
3761class QGradientCache-
3762{-
3763public:-
3764 struct CacheInfo : QSpanData::Pinnablepublic QSharedData-
3765 {-
3766 inline CacheInfo(QGradientStops s, int op, QGradient::InterpolationMode mode) :-
3767 stops(std::move(s)), opacity(op), interpolationMode(mode) {}-
3768 QRgba64 buffer64[1024];-
3769 QRgb buffer32[1024];-
3770 QGradientStops stops;-
3771 int opacity;-
3772 QGradient::InterpolationMode interpolationMode;-
3773 };-
3774-
3775 typedef QMultiHash<quint64, QSharedPointerQExplicitlySharedDataPointer<const CacheInfo> > QGradientColorTableHash;-
3776-
3777 inline QSharedPointerQExplicitlySharedDataPointer<const CacheInfo> getBuffer(const QGradient &gradient, int opacity) {-
3778 quint64 hash_val = 0;-
3779-
3780 const QGradientStops stops = gradient.stops();-
3781 for (int i = 0; i < stops.size()
i < stops.size()Description
TRUEnever evaluated
FALSEnever evaluated
&& i <= 2
i <= 2Description
TRUEnever evaluated
FALSEnever evaluated
; i++)
0
3782 hash_val += stops[i].second.rgba64();
never executed: hash_val += stops[i].second.rgba64();
0
3783-
3784 QMutexLocker lock(&mutex);-
3785 QGradientColorTableHash::const_iterator it = cache.constFind(hash_val);-
3786-
3787 if (it == cache.constEnd()
it == cache.constEnd()Description
TRUEnever evaluated
FALSEnever evaluated
)
0
3788 return
never executed: return addCacheElement(hash_val, gradient, opacity);
addCacheElement(hash_val, gradient, opacity);
never executed: return addCacheElement(hash_val, gradient, opacity);
0
3789 else {-
3790 do {-
3791 const QSharedPointerQExplicitlySharedDataPointer<const CacheInfo> &cache_info = it.value();-
3792 if (cache_info->stops == stops
cache_info->stops == stopsDescription
TRUEnever evaluated
FALSEnever evaluated
&& cache_info->opacity == opacity
cache_info->opacity == opacityDescription
TRUEnever evaluated
FALSEnever evaluated
&& cache_info->interpolationMode == gradient.interpolationMode()
cache_info->in...polationMode()Description
TRUEnever evaluated
FALSEnever evaluated
)
0
3793 return
never executed: return cache_info;
cache_info;
never executed: return cache_info;
0
3794 ++it;-
3795 }
never executed: end of block
while (it != cache.constEnd()
it != cache.constEnd()Description
TRUEnever evaluated
FALSEnever evaluated
&& it.key() == hash_val
it.key() == hash_valDescription
TRUEnever evaluated
FALSEnever evaluated
);
0
3796-
3797 return
never executed: return addCacheElement(hash_val, gradient, opacity);
addCacheElement(hash_val, gradient, opacity);
never executed: return addCacheElement(hash_val, gradient, opacity);
0
3798 }-
3799 }-
3800-
3801 inline int paletteSize() const { return 1024; }-
3802protected:-
3803 inline int maxCacheSize() const { return 60; }-
3804 inline void generateGradientColorTable(const QGradient& g,-
3805 QRgba64 *colorTable,-
3806 int size, int opacity) const;-
3807 QSharedPointerQExplicitlySharedDataPointer<const CacheInfo> addCacheElement(quint64 hash_val, const QGradient &gradient, int opacity) {-
3808 if (cache.size() == maxCacheSize()
cache.size() == maxCacheSize()Description
TRUEnever evaluated
FALSEnever evaluated
) {
0
3809-
3810 cache.erase(cache.begin() + (qrand() % maxCacheSize()));-
3811 }
never executed: end of block
0
3812 QSharedPointerQExplicitlySharedDataPointer<CacheInfo> cache_entry(new CacheInfo (gradient.stops(), opacity, gradient.interpolationMode()));-
3813 generateGradientColorTable(gradient, cache_entry->buffer64, paletteSize(), opacity);-
3814 for (int i = 0; i < 1024
i < 1024Description
TRUEnever evaluated
FALSEnever evaluated
; ++i)
0
3815 cache_entry->buffer32[i] = cache_entry->buffer64[i].toArgb32();
never executed: cache_entry->buffer32[i] = cache_entry->buffer64[i].toArgb32();
0
3816 return
never executed: return cache.insert(hash_val, cache_entry).value();
cache.insert(hash_val, cache_entry).value();
never executed: return cache.insert(hash_val, cache_entry).value();
0
3817 }-
3818-
3819 QGradientColorTableHash cache;-
3820 QMutex mutex;-
3821};-
3822-
3823void QGradientCache::generateGradientColorTable(const QGradient& gradient, QRgba64 *colorTable, int size, int opacity) const-
3824{-
3825 const QGradientStops stops = gradient.stops();-
3826 int stopCount = stops.count();-
3827 ((!(stopCount > 0)) ? qt_assert("stopCount > 0",__FILE__,42064216) : qt_noop());-
3828-
3829 bool colorInterpolation = (gradient.interpolationMode() == QGradient::ColorInterpolation);-
3830-
3831 if (stopCount == 2) {-
3832 QRgba64 first_color = combineAlpha256(stops[0].second.rgba64(), opacity);-
3833 QRgba64 second_color = combineAlpha256(stops[1].second.rgba64(), opacity);-
3834-
3835 qreal first_stop = stops[0].first;-
3836 qreal second_stop = stops[1].first;-
3837-
3838 if (second_stop < first_stop) {-
3839 quint64 tmp = first_color;-
3840 first_color = second_color;-
3841 second_color = tmp;-
3842 qSwap(first_stop, second_stop);-
3843 }-
3844-
3845 if (colorInterpolation) {-
3846 first_color = qPremultiply(first_color);-
3847 second_color = qPremultiply(second_color);-
3848 }-
3849-
3850 int first_index = qRound(first_stop * (1024 -1));-
3851 int second_index = qRound(second_stop * (1024 -1));-
3852-
3853 uint red_first = uint(first_color.red()) << 16;-
3854 uint green_first = uint(first_color.green()) << 16;-
3855 uint blue_first = uint(first_color.blue()) << 16;-
3856 uint alpha_first = uint(first_color.alpha()) << 16;-
3857-
3858 uint red_second = uint(second_color.red()) << 16;-
3859 uint green_second = uint(second_color.green()) << 16;-
3860 uint blue_second = uint(second_color.blue()) << 16;-
3861 uint alpha_second = uint(second_color.alpha()) << 16;-
3862-
3863 int i = 0;-
3864 for (; i <= qMin(1024, first_index); ++i) {-
3865 if (colorInterpolation)-
3866 colorTable[i] = first_color;-
3867 else-
3868 colorTable[i] = qPremultiply(first_color);-
3869 }-
3870-
3871 if (i < second_index) {-
3872 qreal reciprocal = qreal(1) / (second_index - first_index);-
3873-
3874 int red_delta = qRound((qreal(red_second) - red_first) * reciprocal);-
3875 int green_delta = qRound((qreal(green_second) - green_first) * reciprocal);-
3876 int blue_delta = qRound((qreal(blue_second) - blue_first) * reciprocal);-
3877 int alpha_delta = qRound((qreal(alpha_second) - alpha_first) * reciprocal);-
3878-
3879-
3880 red_first += 1 << 15;-
3881 green_first += 1 << 15;-
3882 blue_first += 1 << 15;-
3883 alpha_first += 1 << 15;-
3884-
3885 for (; i < qMin(1024, second_index); ++i) {-
3886 red_first += red_delta;-
3887 green_first += green_delta;-
3888 blue_first += blue_delta;-
3889 alpha_first += alpha_delta;-
3890-
3891 const QRgba64 color = qRgba64(red_first >> 16, green_first >> 16, blue_first >> 16, alpha_first >> 16);-
3892-
3893 if (colorInterpolation)-
3894 colorTable[i] = color;-
3895 else-
3896 colorTable[i] = qPremultiply(color);-
3897 }-
3898 }-
3899-
3900 for (; i < 1024; ++i) {-
3901 if (colorInterpolation)-
3902 colorTable[i] = second_color;-
3903 else-
3904 colorTable[i] = qPremultiply(second_color);-
3905 }-
3906-
3907 return;-
3908 }-
3909-
3910 QRgba64 current_color = combineAlpha256(stops[0].second.rgba64(), opacity);-
3911 if (stopCount == 1) {-
3912 current_color = qPremultiply(current_color);-
3913 for (int i = 0; i < size; ++i)-
3914 colorTable[i] = current_color;-
3915 return;-
3916 }-
3917-
3918-
3919 qreal begin_pos = stops[0].first;-
3920 qreal end_pos = stops[stopCount-1].first;-
3921-
3922 int pos = 0;-
3923 QRgba64 next_color;-
3924-
3925 qreal incr = 1 / qreal(size);-
3926 qreal dpos = 1.5 * incr;-
3927-
3928-
3929 colorTable[pos++] = qPremultiply(current_color);-
3930 while (dpos <= begin_pos) {-
3931 colorTable[pos] = colorTable[pos - 1];-
3932 ++pos;-
3933 dpos += incr;-
3934 }-
3935-
3936 int current_stop = 0;-
3937-
3938 qreal t;-
3939 qreal t_delta;-
3940-
3941 if (dpos < end_pos) {-
3942-
3943 while (dpos > stops[current_stop+1].first)-
3944 ++current_stop;-
3945-
3946 if (current_stop != 0)-
3947 current_color = combineAlpha256(stops[current_stop].second.rgba64(), opacity);-
3948 next_color = combineAlpha256(stops[current_stop+1].second.rgba64(), opacity);-
3949-
3950 if (colorInterpolation) {-
3951 current_color = qPremultiply(current_color);-
3952 next_color = qPremultiply(next_color);-
3953 }-
3954-
3955 qreal diff = stops[current_stop+1].first - stops[current_stop].first;-
3956 qreal c = (diff == 0) ? qreal(0) : 256 / diff;-
3957 t = (dpos - stops[current_stop].first) * c;-
3958 t_delta = incr * c;-
3959-
3960 while (true) {-
3961 ((!(current_stop < stopCount)) ? qt_assert("current_stop < stopCount",__FILE__,43404350) : qt_noop());-
3962-
3963 int dist = qRound(t);-
3964 int idist = 256 - dist;-
3965-
3966 if (colorInterpolation)-
3967 colorTable[pos] = interpolate256(current_color, idist, next_color, dist);-
3968 else-
3969 colorTable[pos] = qPremultiply(interpolate256(current_color, idist, next_color, dist));-
3970-
3971 ++pos;-
3972 dpos += incr;-
3973-
3974 if (dpos >= end_pos)-
3975 break;-
3976-
3977 t += t_delta;-
3978-
3979 int skip = 0;-
3980 while (dpos > stops[current_stop+skip+1].first)-
3981 ++skip;-
3982-
3983 if (skip != 0) {-
3984 current_stop += skip;-
3985 if (skip == 1)-
3986 current_color = next_color;-
3987 else-
3988 current_color = combineAlpha256(stops[current_stop].second.rgba64(), opacity);-
3989 next_color = combineAlpha256(stops[current_stop+1].second.rgba64(), opacity);-
3990-
3991 if (colorInterpolation) {-
3992 if (skip != 1)-
3993 current_color = qPremultiply(current_color);-
3994 next_color = qPremultiply(next_color);-
3995 }-
3996-
3997 qreal diff = stops[current_stop+1].first - stops[current_stop].first;-
3998 qreal c = (diff == 0) ? qreal(0) : 256 / diff;-
3999 t = (dpos - stops[current_stop].first) * c;-
4000 t_delta = incr * c;-
4001 }-
4002 }-
4003 }-
4004-
4005-
4006 current_color = qPremultiply(combineAlpha256(stops[stopCount - 1].second.rgba64(), opacity));-
4007 while (pos < size - 1) {-
4008 colorTable[pos] = current_color;-
4009 ++pos;-
4010 }-
4011-
4012-
4013 colorTable[size - 1] = current_color;-
4014}-
4015-
4016namespace { namespace Q_QGS_qt_gradient_cache { typedef QGradientCache Type; QBasicAtomicInt guard = { QtGlobalStatic::Uninitialized }; __attribute__((visibility("hidden"))) inline Type *innerFunction() { struct HolderBase { ~HolderBase() noexcept { if (guard.load() == QtGlobalStatic::Initialized) guard.store(QtGlobalStatic::Destroyed); } }; static struct Holder : public HolderBase { Type value; Holder() noexcept(noexcept(Type ())) : value () { guard.store(QtGlobalStatic::Initialized); } } holder; return &holder.value; } } } static QGlobalStatic<QGradientCache, Q_QGS_qt_gradient_cache::innerFunction, Q_QGS_qt_gradient_cache::guard> qt_gradient_cache;-
4017-
4018-
4019void QSpanData::init(QRasterBuffer *rb, const QRasterPaintEngine *pe)-
4020{-
4021 rasterBuffer = rb;-
4022 type = None;-
4023 txop = 0;-
4024 bilinear = false;-
4025 m11 = m22 = m33 = 1.;-
4026 m12 = m13 = m21 = m23 = dx = dy = 0.0;-
4027 clip = pe ? pe->d_func()->clip() : 0;-
4028}-
4029-
4030__attribute__((visibility("default"))) extern QImage qt_imageForBrush(int brushStyle, bool invert);-
4031-
4032void QSpanData::setup(const QBrush &brush, int alpha, QPainter::CompositionMode compositionMode)-
4033{-
4034 Qt::BrushStyle brushStyle = qbrush_style(brush);-
4035 cachedGradient.reset();-
4036 switch (brushStyle) {-
4037 case
never executed: case Qt::SolidPattern:
Qt::SolidPattern:
never executed: case Qt::SolidPattern:
{
0
4038 type = Solid;-
4039 QColor c = qbrush_color(brush);-
4040 solid.color = qPremultiply(combineAlpha256(c.rgba64(), alpha));-
4041 if (solid.color.isTransparent()
solid.color.isTransparent()Description
TRUEnever evaluated
FALSEnever evaluated
&& compositionMode == QPainter::CompositionMode_SourceOver
compositionMod...ode_SourceOverDescription
TRUEnever evaluated
FALSEnever evaluated
)
0
4042 type = None;
never executed: type = None;
0
4043 break;
never executed: break;
0
4044 }-
4045-
4046 case
never executed: case Qt::LinearGradientPattern:
Qt::LinearGradientPattern:
never executed: case Qt::LinearGradientPattern:
0
4047 {-
4048 type = LinearGradient;-
4049 const QLinearGradient *g = static_cast<const QLinearGradient *>(brush.gradient());-
4050 gradient.alphaColor = !brush.isOpaque()
!brush.isOpaque()Description
TRUEnever evaluated
FALSEnever evaluated
|| alpha != 256
alpha != 256Description
TRUEnever evaluated
FALSEnever evaluated
;
0
4051-
4052 QSharedPointerQExplicitlySharedDataPointer<const QGradientCache::CacheInfo> cacheInfo = qt_gradient_cache()->getBuffer(*g, alpha);-
4053 cachedGradient = cacheInfo;-
4054 gradient.colorTable32 = cacheInfo->buffer32;-
4055 gradient.colorTable64 = cacheInfo->buffer64;-
4056-
4057 gradient.spread = g->spread();-
4058-
4059 QLinearGradientData &linearData = gradient.linear;-
4060-
4061 linearData.origin.x = g->start().x();-
4062 linearData.origin.y = g->start().y();-
4063 linearData.end.x = g->finalStop().x();-
4064 linearData.end.y = g->finalStop().y();-
4065 break;
never executed: break;
0
4066 }-
4067-
4068 case
never executed: case Qt::RadialGradientPattern:
Qt::RadialGradientPattern:
never executed: case Qt::RadialGradientPattern:
0
4069 {-
4070 type = RadialGradient;-
4071 const QRadialGradient *g = static_cast<const QRadialGradient *>(brush.gradient());-
4072 gradient.alphaColor = !brush.isOpaque()
!brush.isOpaque()Description
TRUEnever evaluated
FALSEnever evaluated
|| alpha != 256
alpha != 256Description
TRUEnever evaluated
FALSEnever evaluated
;
0
4073-
4074 QSharedPointerQExplicitlySharedDataPointer<const QGradientCache::CacheInfo> cacheInfo = qt_gradient_cache()->getBuffer(*g, alpha);-
4075 cachedGradient = cacheInfo;-
4076 gradient.colorTable32 = cacheInfo->buffer32;-
4077 gradient.colorTable64 = cacheInfo->buffer64;-
4078-
4079 gradient.spread = g->spread();-
4080-
4081 QRadialGradientData &radialData = gradient.radial;-
4082-
4083 QPointF center = g->center();-
4084 radialData.center.x = center.x();-
4085 radialData.center.y = center.y();-
4086 radialData.center.radius = g->centerRadius();-
4087 QPointF focal = g->focalPoint();-
4088 radialData.focal.x = focal.x();-
4089 radialData.focal.y = focal.y();-
4090 radialData.focal.radius = g->focalRadius();-
4091 }-
4092 break;
never executed: break;
0
4093-
4094 case
never executed: case Qt::ConicalGradientPattern:
Qt::ConicalGradientPattern:
never executed: case Qt::ConicalGradientPattern:
0
4095 {-
4096 type = ConicalGradient;-
4097 const QConicalGradient *g = static_cast<const QConicalGradient *>(brush.gradient());-
4098 gradient.alphaColor = !brush.isOpaque()
!brush.isOpaque()Description
TRUEnever evaluated
FALSEnever evaluated
|| alpha != 256
alpha != 256Description
TRUEnever evaluated
FALSEnever evaluated
;
0
4099-
4100 QSharedPointerQExplicitlySharedDataPointer<const QGradientCache::CacheInfo> cacheInfo = qt_gradient_cache()->getBuffer(*g, alpha);-
4101 cachedGradient = cacheInfo;-
4102 gradient.colorTable32 = cacheInfo->buffer32;-
4103 gradient.colorTable64 = cacheInfo->buffer64;-
4104-
4105 gradient.spread = QGradient::RepeatSpread;-
4106-
4107 QConicalGradientData &conicalData = gradient.conical;-
4108-
4109 QPointF center = g->center();-
4110 conicalData.center.x = center.x();-
4111 conicalData.center.y = center.y();-
4112 conicalData.angle = qDegreesToRadians(g->angle());-
4113 }-
4114 break;
never executed: break;
0
4115-
4116 case
never executed: case Qt::Dense1Pattern:
Qt::Dense1Pattern:
never executed: case Qt::Dense1Pattern:
0
4117 case
never executed: case Qt::Dense2Pattern:
Qt::Dense2Pattern:
never executed: case Qt::Dense2Pattern:
0
4118 case
never executed: case Qt::Dense3Pattern:
Qt::Dense3Pattern:
never executed: case Qt::Dense3Pattern:
0
4119 case
never executed: case Qt::Dense4Pattern:
Qt::Dense4Pattern:
never executed: case Qt::Dense4Pattern:
0
4120 case
never executed: case Qt::Dense5Pattern:
Qt::Dense5Pattern:
never executed: case Qt::Dense5Pattern:
0
4121 case
never executed: case Qt::Dense6Pattern:
Qt::Dense6Pattern:
never executed: case Qt::Dense6Pattern:
0
4122 case
never executed: case Qt::Dense7Pattern:
Qt::Dense7Pattern:
never executed: case Qt::Dense7Pattern:
0
4123 case
never executed: case Qt::HorPattern:
Qt::HorPattern:
never executed: case Qt::HorPattern:
0
4124 case
never executed: case Qt::VerPattern:
Qt::VerPattern:
never executed: case Qt::VerPattern:
0
4125 case
never executed: case Qt::CrossPattern:
Qt::CrossPattern:
never executed: case Qt::CrossPattern:
0
4126 case
never executed: case Qt::BDiagPattern:
Qt::BDiagPattern:
never executed: case Qt::BDiagPattern:
0
4127 case
never executed: case Qt::FDiagPattern:
Qt::FDiagPattern:
never executed: case Qt::FDiagPattern:
0
4128 case
never executed: case Qt::DiagCrossPattern:
Qt::DiagCrossPattern:
never executed: case Qt::DiagCrossPattern:
0
4129 type = Texture;-
4130 if (!tempImage
!tempImageDescription
TRUEnever evaluated
FALSEnever evaluated
)
0
4131 tempImage = new QImage();
never executed: tempImage = new QImage();
0
4132 *tempImage = rasterBuffer->colorizeBitmap(qt_imageForBrush(brushStyle, true), brush.color());-
4133 initTexture(tempImage, alpha, QTextureData::Tiled);-
4134 break;
never executed: break;
0
4135 case
never executed: case Qt::TexturePattern:
Qt::TexturePattern:
never executed: case Qt::TexturePattern:
0
4136 type = Texture;-
4137 if (!tempImage
!tempImageDescription
TRUEnever evaluated
FALSEnever evaluated
)
0
4138 tempImage = new QImage();
never executed: tempImage = new QImage();
0
4139-
4140 if (qHasPixmapTexture(brush)
qHasPixmapTexture(brush)Description
TRUEnever evaluated
FALSEnever evaluated
&& brush.texture().isQBitmap()
brush.texture().isQBitmap()Description
TRUEnever evaluated
FALSEnever evaluated
)
0
4141 *
never executed: *tempImage = rasterBuffer->colorizeBitmap(brush.textureImage(), brush.color());
tempImage = rasterBuffer->colorizeBitmap(brush.textureImage(), brush.color());
never executed: *tempImage = rasterBuffer->colorizeBitmap(brush.textureImage(), brush.color());
0
4142 else-
4143 *
never executed: *tempImage = brush.textureImage();
tempImage = brush.textureImage();
never executed: *tempImage = brush.textureImage();
0
4144 initTexture(tempImage, alpha, QTextureData::Tiled, tempImage->rect());-
4145 break;
never executed: break;
0
4146-
4147 case
never executed: case Qt::NoBrush:
Qt::NoBrush:
never executed: case Qt::NoBrush:
0
4148 default
never executed: default:
:
never executed: default:
0
4149 type = None;-
4150 break;
never executed: break;
0
4151 }-
4152 adjustSpanMethods();-
4153}
never executed: end of block
0
4154-
4155void QSpanData::adjustSpanMethods()-
4156{-
4157 bitmapBlit = 0;-
4158 alphamapBlit = 0;-
4159 alphaRGBBlit = 0;-
4160-
4161 fillRect = 0;-
4162-
4163 switch(type) {-
4164 case None:-
4165 unclipped_blend = 0;-
4166 break;-
4167 case Solid:-
4168 unclipped_blend = rasterBuffer->drawHelper->blendColor;-
4169 bitmapBlit = rasterBuffer->drawHelper->bitmapBlit;-
4170 alphamapBlit = rasterBuffer->drawHelper->alphamapBlit;-
4171 alphaRGBBlit = rasterBuffer->drawHelper->alphaRGBBlit;-
4172 fillRect = rasterBuffer->drawHelper->fillRect;-
4173 break;-
4174 case LinearGradient:-
4175 case RadialGradient:-
4176 case ConicalGradient:-
4177 unclipped_blend = rasterBuffer->drawHelper->blendGradient;-
4178 break;-
4179 case Texture:-
4180 unclipped_blend = qBlendTexture;-
4181 if (!texture.imageData)-
4182 unclipped_blend = 0;-
4183-
4184 break;-
4185 }-
4186-
4187 if (!unclipped_blend) {-
4188 blend = 0;-
4189 } else if (!clip) {-
4190 blend = unclipped_blend;-
4191 } else if (clip->hasRectClip) {-
4192 blend = clip->clipRect.isEmpty() ? 0 : qt_span_fill_clipRect;-
4193 } else {-
4194 blend = qt_span_fill_clipped;-
4195 }-
4196}-
4197-
4198void QSpanData::setupMatrix(const QTransform &matrix, int bilin)-
4199{-
4200 QTransform delta;-
4201-
4202 delta.translate(1.0 / 65536, 1.0 / 65536);-
4203-
4204 QTransform inv = (delta * matrix).inverted();-
4205 m11 = inv.m11();-
4206 m12 = inv.m12();-
4207 m13 = inv.m13();-
4208 m21 = inv.m21();-
4209 m22 = inv.m22();-
4210 m23 = inv.m23();-
4211 m33 = inv.m33();-
4212 dx = inv.dx();-
4213 dy = inv.dy();-
4214 txop = inv.type();-
4215 bilinear = bilin;-
4216-
4217 const bool affine = inv.isAffine();-
4218 fast_matrix = affine-
4219 && m11 * m11 + m21 * m21 < 1e4-
4220 && m12 * m12 + m22 * m22 < 1e4-
4221 && qAbs(dx) < 1e4-
4222 && qAbs(dy) < 1e4;-
4223-
4224 adjustSpanMethods();-
4225}-
4226-
4227void QSpanData::initTexture(const QImage *image, int alpha, QTextureData::Type _type, const QRect &sourceRect)-
4228{-
4229 const QImageData *d = const_cast<QImage *>(image)->data_ptr();-
4230 if (!d || d->height == 0) {-
4231 texture.imageData = 0;-
4232 texture.width = 0;-
4233 texture.height = 0;-
4234 texture.x1 = 0;-
4235 texture.y1 = 0;-
4236 texture.x2 = 0;-
4237 texture.y2 = 0;-
4238 texture.bytesPerLine = 0;-
4239 texture.format = QImage::Format_Invalid;-
4240 texture.colorTable = 0;-
4241 texture.hasAlpha = alpha != 256;-
4242 } else {-
4243 texture.imageData = d->data;-
4244 texture.width = d->width;-
4245 texture.height = d->height;-
4246-
4247 if (sourceRect.isNull()) {-
4248 texture.x1 = 0;-
4249 texture.y1 = 0;-
4250 texture.x2 = texture.width;-
4251 texture.y2 = texture.height;-
4252 } else {-
4253 texture.x1 = sourceRect.x();-
4254 texture.y1 = sourceRect.y();-
4255 texture.x2 = qMin(texture.x1 + sourceRect.width(), d->width);-
4256 texture.y2 = qMin(texture.y1 + sourceRect.height(), d->height);-
4257 }-
4258-
4259 texture.bytesPerLine = d->bytes_per_line;-
4260-
4261 texture.format = d->format;-
4262 texture.colorTable = (d->format <= QImage::Format_Indexed8 && !d->colortable.isEmpty()) ? &d->colortable : 0;-
4263 texture.hasAlpha = image->hasAlphaChannel() || alpha != 256;-
4264 }-
4265 texture.const_alpha = alpha;-
4266 texture.type = _type;-
4267-
4268 adjustSpanMethods();-
4269}-
4270-
4271-
4272-
4273-
4274-
4275static inline void drawEllipsePoints(int x, int y, int length,-
4276 const QRect &rect,-
4277 const QRect &clip,-
4278 ProcessSpans pen_func, ProcessSpans brush_func,-
4279 QSpanData *pen_data, QSpanData *brush_data)-
4280{-
4281 if (length == 0)-
4282 return;-
4283-
4284 QT_FT_Span outline[4];-
4285 const int midx = rect.x() + (rect.width() + 1) / 2;-
4286 const int midy = rect.y() + (rect.height() + 1) / 2;-
4287-
4288 x = x + midx;-
4289 y = midy - y;-
4290-
4291-
4292 outline[0].x = midx + (midx - x) - (length - 1) - (rect.width() & 0x1);-
4293 outline[0].len = qMin(length, x - outline[0].x);-
4294 outline[0].y = y;-
4295 outline[0].coverage = 255;-
4296-
4297-
4298 outline[1].x = x;-
4299 outline[1].len = length;-
4300 outline[1].y = y;-
4301 outline[1].coverage = 255;-
4302-
4303-
4304 outline[2].x = outline[0].x;-
4305 outline[2].len = outline[0].len;-
4306 outline[2].y = midy + (midy - y) - (rect.height() & 0x1);-
4307 outline[2].coverage = 255;-
4308-
4309-
4310 outline[3].x = x;-
4311 outline[3].len = length;-
4312 outline[3].y = outline[2].y;-
4313 outline[3].coverage = 255;-
4314-
4315 if (brush_func && outline[0].x + outline[0].len < outline[1].x) {-
4316 QT_FT_Span fill[2];-
4317-
4318-
4319 fill[0].x = outline[0].x + outline[0].len - 1;-
4320 fill[0].len = qMax(0, outline[1].x - fill[0].x);-
4321 fill[0].y = outline[1].y;-
4322 fill[0].coverage = 255;-
4323-
4324-
4325 fill[1].x = outline[2].x + outline[2].len - 1;-
4326 fill[1].len = qMax(0, outline[3].x - fill[1].x);-
4327 fill[1].y = outline[3].y;-
4328 fill[1].coverage = 255;-
4329-
4330 int n = (fill[0].y >= fill[1].y ? 1 : 2);-
4331 n = qt_intersect_spans(fill, n, clip);-
4332 if (n > 0)-
4333 brush_func(n, fill, brush_data);-
4334 }-
4335 if (pen_func) {-
4336 int n = (outline[1].y >= outline[2].y ? 2 : 4);-
4337 n = qt_intersect_spans(outline, n, clip);-
4338 if (n > 0)-
4339 pen_func(n, outline, pen_data);-
4340 }-
4341}-
4342-
4343-
4344-
4345-
4346-
4347static void drawEllipse_midpoint_i(const QRect &rect, const QRect &clip,-
4348 ProcessSpans pen_func, ProcessSpans brush_func,-
4349 QSpanData *pen_data, QSpanData *brush_data)-
4350{-
4351 const qreal a = qreal(rect.width()) / 2;-
4352 const qreal b = qreal(rect.height()) / 2;-
4353 qreal d = b*b - (a*a*b) + 0.25*a*a;-
4354-
4355 int x = 0;-
4356 int y = (rect.height() + 1) / 2;-
4357 int startx = x;-
4358-
4359-
4360 while (a*a*(2*y - 1) > 2*b*b*(x + 1)) {-
4361 if (d < 0) {-
4362 d += b*b*(2*x + 3);-
4363 ++x;-
4364 } else {-
4365 d += b*b*(2*x + 3) + a*a*(-2*y + 2);-
4366 drawEllipsePoints(startx, y, x - startx + 1, rect, clip,-
4367 pen_func, brush_func, pen_data, brush_data);-
4368 startx = ++x;-
4369 --y;-
4370 }-
4371 }-
4372 drawEllipsePoints(startx, y, x - startx + 1, rect, clip,-
4373 pen_func, brush_func, pen_data, brush_data);-
4374-
4375-
4376 d = b*b*(x + 0.5)*(x + 0.5) + a*a*((y - 1)*(y - 1) - b*b);-
4377 const int miny = rect.height() & 0x1;-
4378 while (y > miny) {-
4379 if (d < 0) {-
4380 d += b*b*(2*x + 2) + a*a*(-2*y + 3);-
4381 ++x;-
4382 } else {-
4383 d += a*a*(-2*y + 3);-
4384 }-
4385 --y;-
4386 drawEllipsePoints(x, y, 1, rect, clip,-
4387 pen_func, brush_func, pen_data, brush_data);-
4388 }-
4389}-
4390-
Switch to Source codePreprocessed file

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