227 QPainterPath::MoveToElement, QPainterPath::LineToElement,
228 QPainterPath::MoveToElement, QPainterPath::LineToElement,
229 QPainterPath::MoveToElement, QPainterPath::LineToElement,
230 QPainterPath::MoveToElement, QPainterPath::LineToElement,
231 QPainterPath::MoveToElement, QPainterPath::LineToElement,
232 QPainterPath::MoveToElement, QPainterPath::LineToElement,
233 QPainterPath::MoveToElement, QPainterPath::LineToElement,
234 QPainterPath::MoveToElement, QPainterPath::LineToElement,
235 QPainterPath::MoveToElement, QPainterPath::LineToElement,
236 QPainterPath::MoveToElement, QPainterPath::LineToElement,
237 QPainterPath::MoveToElement, QPainterPath::LineToElement,
238 QPainterPath::MoveToElement, QPainterPath::LineToElement,
239 QPainterPath::MoveToElement, QPainterPath::LineToElement,
240 QPainterPath::MoveToElement, QPainterPath::LineToElement,
241 QPainterPath::MoveToElement, QPainterPath::LineToElement,
242 QPainterPath::MoveToElement, QPainterPath::LineToElement
246 QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement,
247 QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement,
248 QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement,
249 QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement,
250 QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement,
251 QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement,
252 QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement,
253 QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement,
254 QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement,
255 QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement,
256 QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement,
257 QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement,
258 QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement,
259 QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement,
260 QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement,
261 QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement,
262 QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement,
263 QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement,
264 QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement,
265 QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement,
266 QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement,
267 QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement,
268 QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement,
269 QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement,
270 QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement,
271 QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement,
272 QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement,
273 QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement,
274 QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement,
275 QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement,
276 QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement,
277 QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement,
282 QPainterPath::MoveToElement,
283 QPainterPath::LineToElement,
284 QPainterPath::CurveToElement,
285 QPainterPath::CurveToDataElement,
286 QPainterPath::CurveToDataElement,
287 QPainterPath::LineToElement,
288 QPainterPath::CurveToElement,
289 QPainterPath::CurveToDataElement,
290 QPainterPath::CurveToDataElement,
291 QPainterPath::LineToElement,
292 QPainterPath::CurveToElement,
293 QPainterPath::CurveToDataElement,
294 QPainterPath::CurveToDataElement,
295 QPainterPath::LineToElement,
296 QPainterPath::CurveToElement,
297 QPainterPath::CurveToDataElement,
298 QPainterPath::CurveToDataElement
350void QPaintEngineEx::stroke(
const QVectorPath &path,
const QPen &inPen)
353 qDebug() <<
"QPaintEngineEx::stroke()" << inPen;
361 if (!d->strokeHandler) {
362 d->strokeHandler =
new StrokeHandler(path.elementCount()+4);
363 d->stroker.setMoveToHook(qpaintengineex_moveTo);
364 d->stroker.setLineToHook(qpaintengineex_lineTo);
365 d->stroker.setCubicToHook(qpaintengineex_cubicTo);
370 if (pen.style() > Qt::SolidLine) {
371 QRectF cpRect = path.controlPointRect();
372 const QTransform &xf = state()->matrix;
373 if (pen.isCosmetic()) {
374 clipRect = d->exDeviceRect;
375 cpRect.translate(xf.dx(), xf.dy());
377 clipRect = xf.inverted().mapRect(QRectF(d->exDeviceRect));
380 qreal pw = pen.widthF() ? pen.widthF() : 1;
381 QRectF extentRect = cpRect.adjusted(-pw, -pw, pw, pw) & clipRect;
382 qreal extent = qMax(extentRect.width(), extentRect.height());
383 qreal patternLength = 0;
384 const QList<qreal> pattern = pen.dashPattern();
385 const int patternSize = qMin(pattern.size(), 32);
386 for (
int i = 0; i < patternSize; i++)
387 patternLength += qMax(pattern.at(i), qreal(0));
389 if (qFuzzyIsNull(patternLength)) {
390 pen.setStyle(Qt::NoPen);
391 }
else if (extent / patternLength > QDashStroker::repetitionLimit()) {
393 pen.setStyle(Qt::SolidLine);
394 QColor color(pen.color());
395 color.setAlpha(color.alpha() / 2);
400 if (!qpen_fast_equals(pen, d->strokerPen)) {
402 d->stroker.setJoinStyle(pen.joinStyle());
403 d->stroker.setCapStyle(pen.capStyle());
404 d->stroker.setMiterLimit(pen.miterLimit());
405 qreal penWidth = pen.widthF();
407 d->stroker.setStrokeWidth(1);
409 d->stroker.setStrokeWidth(penWidth);
411 Qt::PenStyle style = pen.style();
412 if (style == Qt::SolidLine) {
413 d->activeStroker = &d->stroker;
414 }
else if (style == Qt::NoPen) {
415 d->activeStroker =
nullptr;
417 d->dasher.setDashPattern(pen.dashPattern());
418 d->dasher.setDashOffset(pen.dashOffset());
419 d->activeStroker = &d->dasher;
423 if (!d->activeStroker) {
427 if (!clipRect.isNull())
428 d->activeStroker->setClipRect(clipRect);
430 if (d->activeStroker == &d->stroker)
431 d->stroker.setForceOpen(path.hasExplicitOpen());
433 const QPainterPath::ElementType *types = path.elements();
434 const qreal *points = path.points();
435 int pointCount = path.elementCount();
437 const qreal *lastPoint = points + (pointCount<<1);
439 d->strokeHandler->types.reset();
440 d->strokeHandler->pts.reset();
443 uint flags = QVectorPath::WindingFill;
445 if (path.elementCount() > 2)
446 flags |= QVectorPath::NonConvexShapeMask;
448 if (d->stroker.capStyle() == Qt::RoundCap || d->stroker.joinStyle() == Qt::RoundJoin)
449 flags |= QVectorPath::CurvedShapeMask;
452 if (!pen.isCosmetic()) {
457 d->activeStroker->setCurveThresholdFromTransform(state()->matrix);
458 d->activeStroker->begin(d->strokeHandler);
460 while (points < lastPoint) {
462 case QPainterPath::MoveToElement:
463 d->activeStroker->moveTo(points[0], points[1]);
467 case QPainterPath::LineToElement:
468 d->activeStroker->lineTo(points[0], points[1]);
472 case QPainterPath::CurveToElement:
473 d->activeStroker->cubicTo(points[0], points[1],
474 points[2], points[3],
475 points[4], points[5]);
478 flags |= QVectorPath::CurvedShapeMask;
484 if (path.hasImplicitClose())
485 d->activeStroker->lineTo(path.points()[0], path.points()[1]);
488 d->activeStroker->moveTo(points[0], points[1]);
490 while (points < lastPoint) {
491 d->activeStroker->lineTo(points[0], points[1]);
494 if (path.hasImplicitClose())
495 d->activeStroker->lineTo(path.points()[0], path.points()[1]);
497 d->activeStroker->end();
499 if (!d->strokeHandler->types.size())
502 QVectorPath strokePath(d->strokeHandler->pts.data(),
503 d->strokeHandler->types.size(),
504 d->strokeHandler->types.data(),
506 fill(strokePath, pen.brush());
509 if (state()->matrix.type() >= QTransform::TxProject) {
510 QPainterPath painterPath = state()->matrix.map(path.convertToPainterPath());
511 d->activeStroker->strokePath(painterPath, d->strokeHandler, QTransform());
513 d->activeStroker->setCurveThresholdFromTransform(QTransform());
514 d->activeStroker->begin(d->strokeHandler);
516 while (points < lastPoint) {
518 case QPainterPath::MoveToElement: {
519 QPointF pt = (*(
const QPointF *) points) * state()->matrix;
520 d->activeStroker->moveTo(pt.x(), pt.y());
525 case QPainterPath::LineToElement: {
526 QPointF pt = (*(
const QPointF *) points) * state()->matrix;
527 d->activeStroker->lineTo(pt.x(), pt.y());
532 case QPainterPath::CurveToElement: {
533 QPointF c1 = ((
const QPointF *) points)[0] * state()->matrix;
534 QPointF c2 = ((
const QPointF *) points)[1] * state()->matrix;
535 QPointF e = ((
const QPointF *) points)[2] * state()->matrix;
536 d->activeStroker->cubicTo(c1.x(), c1.y(), c2.x(), c2.y(), e.x(), e.y());
539 flags |= QVectorPath::CurvedShapeMask;
546 if (path.hasImplicitClose()) {
547 QPointF pt = * ((
const QPointF *) path.points()) * state()->matrix;
548 d->activeStroker->lineTo(pt.x(), pt.y());
552 QPointF p = ((
const QPointF *)points)[0] * state()->matrix;
553 d->activeStroker->moveTo(p.x(), p.y());
555 while (points < lastPoint) {
556 QPointF p = ((
const QPointF *)points)[0] * state()->matrix;
557 d->activeStroker->lineTo(p.x(), p.y());
560 if (path.hasImplicitClose())
561 d->activeStroker->lineTo(p.x(), p.y());
563 d->activeStroker->end();
566 QVectorPath strokePath(d->strokeHandler->pts.data(),
567 d->strokeHandler->types.size(),
568 d->strokeHandler->types.data(),
571 QTransform xform = state()->matrix;
572 state()->matrix = QTransform();
575 QBrush brush = pen.brush();
576 if (qbrush_style(brush) != Qt::SolidPattern)
577 brush.setTransform(brush.transform() * xform);
579 fill(strokePath, brush);
581 state()->matrix = xform;
732void QPaintEngineEx::drawRoundedRect(
const QRectF &rect, qreal xRadius, qreal yRadius,
735 qreal x1 = rect.left();
736 qreal x2 = rect.right();
737 qreal y1 = rect.top();
738 qreal y2 = rect.bottom();
740 if (mode == Qt::RelativeSize) {
741 xRadius = xRadius * rect.width() / 200.;
742 yRadius = yRadius * rect.height() / 200.;
745 xRadius = qMin(xRadius, rect.width() / 2);
746 yRadius = qMin(yRadius, rect.height() / 2);
751 x2 - (1 - KAPPA) * xRadius, y1,
752 x2, y1 + (1 - KAPPA) * yRadius,
755 x2, y2 - (1 - KAPPA) * yRadius,
756 x2 - (1 - KAPPA) * xRadius, y2,
759 x1 + (1 - KAPPA) * xRadius, y2,
760 x1, y2 - (1 - KAPPA) * yRadius,
763 x1, y1 + (1 - KAPPA) * yRadius,
764 x1 + (1 - KAPPA) * xRadius, y1,
768 QVectorPath path(pts, 17, qpaintengineex_roundedrect_types, QVectorPath::RoundedRectHint);
957void QPaintEngineEx::drawPixmapFragments(
const QPainter::PixmapFragment *fragments,
int fragmentCount,
958 const QPixmap &pixmap, QPainter::PixmapFragmentHints )
963 qreal oldOpacity = state()->opacity;
964 QTransform oldTransform = state()->matrix;
966 for (
int i = 0; i < fragmentCount; ++i) {
967 QTransform transform = oldTransform;
968 transform.translate(fragments[i].x, fragments[i].y);
969 transform.rotate(fragments[i].rotation);
970 state()->opacity = oldOpacity * fragments[i].opacity;
971 state()->matrix = transform;
975 qreal w = fragments[i].scaleX * fragments[i].width;
976 qreal h = fragments[i].scaleY * fragments[i].height;
977 QRectF sourceRect(fragments[i].sourceLeft, fragments[i].sourceTop,
978 fragments[i].width, fragments[i].height);
979 drawPixmap(QRectF(-0.5 * w, -0.5 * h, w, h), pixmap, sourceRect);
982 state()->opacity = oldOpacity;
983 state()->matrix = oldTransform;
999Q_GUI_EXPORT
QPainterPath qt_painterPathFromVectorPath(
const QVectorPath &path)
1001 const qreal *points = path.points();
1002 const QPainterPath::ElementType *types = path.elements();
1007 for (
int i=0; i<path.elementCount(); ++i) {
1009 case QPainterPath::MoveToElement:
1010 p.moveTo(QPointF(points[id], points[id+1]));
1013 case QPainterPath::LineToElement:
1014 p.lineTo(QPointF(points[id], points[id+1]));
1017 case QPainterPath::CurveToElement: {
1018 QPointF p1(points[id], points[id+1]);
1019 QPointF p2(points[id+2], points[id+3]);
1020 QPointF p3(points[id+4], points[id+5]);
1021 p.cubicTo(p1, p2, p3);
1025 case QPainterPath::CurveToDataElement:
1031 p.moveTo(QPointF(points[0], points[1]));
1033 for (
int i=1; i<path.elementCount(); ++i) {
1034 p.lineTo(QPointF(points[id], points[id+1]));
1038 if (path.hints() & QVectorPath::WindingFill)
1039 p.setFillRule(Qt::WindingFill);