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,
243 QPainterPath::MoveToElement, QPainterPath::LineToElement,
244 QPainterPath::MoveToElement, QPainterPath::LineToElement,
245 QPainterPath::MoveToElement, 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,
278 QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement,
279 QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement,
280 QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement,
285 QPainterPath::MoveToElement,
286 QPainterPath::LineToElement,
287 QPainterPath::CurveToElement,
288 QPainterPath::CurveToDataElement,
289 QPainterPath::CurveToDataElement,
290 QPainterPath::LineToElement,
291 QPainterPath::CurveToElement,
292 QPainterPath::CurveToDataElement,
293 QPainterPath::CurveToDataElement,
294 QPainterPath::LineToElement,
295 QPainterPath::CurveToElement,
296 QPainterPath::CurveToDataElement,
297 QPainterPath::CurveToDataElement,
298 QPainterPath::LineToElement,
299 QPainterPath::CurveToElement,
300 QPainterPath::CurveToDataElement,
301 QPainterPath::CurveToDataElement
353void QPaintEngineEx::stroke(
const QVectorPath &path,
const QPen &inPen)
356 qDebug() <<
"QPaintEngineEx::stroke()" << inPen;
364 if (!d->strokeHandler) {
365 d->strokeHandler =
new StrokeHandler(path.elementCount()+4);
366 d->stroker.setMoveToHook(qpaintengineex_moveTo);
367 d->stroker.setLineToHook(qpaintengineex_lineTo);
368 d->stroker.setCubicToHook(qpaintengineex_cubicTo);
373 if (pen.style() > Qt::SolidLine) {
374 QRectF cpRect = path.controlPointRect();
375 const QTransform &xf = state()->matrix;
376 if (pen.isCosmetic()) {
377 clipRect = d->exDeviceRect;
378 cpRect.translate(xf.dx(), xf.dy());
380 clipRect = xf.inverted().mapRect(QRectF(d->exDeviceRect));
383 qreal pw = pen.widthF() ? pen.widthF() : 1;
384 QRectF extentRect = cpRect.adjusted(-pw, -pw, pw, pw) & clipRect;
385 qreal extent = qMax(extentRect.width(), extentRect.height());
386 qreal patternLength = 0;
387 const QList<qreal> pattern = pen.dashPattern();
388 const int patternSize = qMin(pattern.size(), 32);
389 for (
int i = 0; i < patternSize; i++)
390 patternLength += qMax(pattern.at(i), qreal(0));
392 if (qFuzzyIsNull(patternLength)) {
393 pen.setStyle(Qt::NoPen);
394 }
else if (extent / patternLength > QDashStroker::repetitionLimit()) {
396 pen.setStyle(Qt::SolidLine);
397 QColor color(pen.color());
398 color.setAlpha(color.alpha() / 2);
403 if (!qpen_fast_equals(pen, d->strokerPen)) {
405 d->stroker.setJoinStyle(pen.joinStyle());
406 d->stroker.setCapStyle(pen.capStyle());
407 d->stroker.setMiterLimit(pen.miterLimit());
408 qreal penWidth = pen.widthF();
410 d->stroker.setStrokeWidth(1);
412 d->stroker.setStrokeWidth(penWidth);
414 Qt::PenStyle style = pen.style();
415 if (style == Qt::SolidLine) {
416 d->activeStroker = &d->stroker;
417 }
else if (style == Qt::NoPen) {
418 d->activeStroker =
nullptr;
420 d->dasher.setDashPattern(pen.dashPattern());
421 d->dasher.setDashOffset(pen.dashOffset());
422 d->activeStroker = &d->dasher;
426 if (!d->activeStroker) {
430 if (!clipRect.isNull())
431 d->activeStroker->setClipRect(clipRect);
433 if (d->activeStroker == &d->stroker)
434 d->stroker.setForceOpen(path.hasExplicitOpen());
436 const QPainterPath::ElementType *types = path.elements();
437 const qreal *points = path.points();
438 int pointCount = path.elementCount();
440 const qreal *lastPoint = points + (pointCount<<1);
442 d->strokeHandler->types.reset();
443 d->strokeHandler->pts.reset();
446 uint flags = QVectorPath::WindingFill;
448 if (path.elementCount() > 2)
449 flags |= QVectorPath::NonConvexShapeMask;
451 if (d->stroker.capStyle() == Qt::RoundCap || d->stroker.joinStyle() == Qt::RoundJoin)
452 flags |= QVectorPath::CurvedShapeMask;
455 if (!pen.isCosmetic()) {
460 d->activeStroker->setCurveThresholdFromTransform(state()->matrix);
461 d->activeStroker->begin(d->strokeHandler);
463 while (points < lastPoint) {
465 case QPainterPath::MoveToElement:
466 d->activeStroker->moveTo(points[0], points[1]);
470 case QPainterPath::LineToElement:
471 d->activeStroker->lineTo(points[0], points[1]);
475 case QPainterPath::CurveToElement:
476 d->activeStroker->cubicTo(points[0], points[1],
477 points[2], points[3],
478 points[4], points[5]);
481 flags |= QVectorPath::CurvedShapeMask;
487 if (path.hasImplicitClose())
488 d->activeStroker->lineTo(path.points()[0], path.points()[1]);
491 d->activeStroker->moveTo(points[0], points[1]);
493 while (points < lastPoint) {
494 d->activeStroker->lineTo(points[0], points[1]);
497 if (path.hasImplicitClose())
498 d->activeStroker->lineTo(path.points()[0], path.points()[1]);
500 d->activeStroker->end();
502 if (!d->strokeHandler->types.size())
505 QVectorPath strokePath(d->strokeHandler->pts.data(),
506 d->strokeHandler->types.size(),
507 d->strokeHandler->types.data(),
509 fill(strokePath, pen.brush());
512 if (state()->matrix.type() >= QTransform::TxProject) {
513 QPainterPath painterPath = state()->matrix.map(path.convertToPainterPath());
514 d->activeStroker->strokePath(painterPath, d->strokeHandler, QTransform());
516 d->activeStroker->setCurveThresholdFromTransform(QTransform());
517 d->activeStroker->begin(d->strokeHandler);
519 while (points < lastPoint) {
521 case QPainterPath::MoveToElement: {
522 QPointF pt = (*(
const QPointF *) points) * state()->matrix;
523 d->activeStroker->moveTo(pt.x(), pt.y());
528 case QPainterPath::LineToElement: {
529 QPointF pt = (*(
const QPointF *) points) * state()->matrix;
530 d->activeStroker->lineTo(pt.x(), pt.y());
535 case QPainterPath::CurveToElement: {
536 QPointF c1 = ((
const QPointF *) points)[0] * state()->matrix;
537 QPointF c2 = ((
const QPointF *) points)[1] * state()->matrix;
538 QPointF e = ((
const QPointF *) points)[2] * state()->matrix;
539 d->activeStroker->cubicTo(c1.x(), c1.y(), c2.x(), c2.y(), e.x(), e.y());
542 flags |= QVectorPath::CurvedShapeMask;
549 if (path.hasImplicitClose()) {
550 QPointF pt = * ((
const QPointF *) path.points()) * state()->matrix;
551 d->activeStroker->lineTo(pt.x(), pt.y());
555 QPointF p = ((
const QPointF *)points)[0] * state()->matrix;
556 d->activeStroker->moveTo(p.x(), p.y());
558 while (points < lastPoint) {
559 QPointF p = ((
const QPointF *)points)[0] * state()->matrix;
560 d->activeStroker->lineTo(p.x(), p.y());
563 if (path.hasImplicitClose())
564 d->activeStroker->lineTo(p.x(), p.y());
566 d->activeStroker->end();
569 QVectorPath strokePath(d->strokeHandler->pts.data(),
570 d->strokeHandler->types.size(),
571 d->strokeHandler->types.data(),
574 QTransform xform = state()->matrix;
575 state()->matrix = QTransform();
578 QBrush brush = pen.brush();
579 if (qbrush_style(brush) != Qt::SolidPattern)
580 brush.setTransform(brush.transform() * xform);
582 fill(strokePath, brush);
584 state()->matrix = xform;
735void QPaintEngineEx::drawRoundedRect(
const QRectF &rect, qreal xRadius, qreal yRadius,
738 qreal x1 = rect.left();
739 qreal x2 = rect.right();
740 qreal y1 = rect.top();
741 qreal y2 = rect.bottom();
743 if (mode == Qt::RelativeSize) {
744 xRadius = xRadius * rect.width() / 200.;
745 yRadius = yRadius * rect.height() / 200.;
748 xRadius = qMin(xRadius, rect.width() / 2);
749 yRadius = qMin(yRadius, rect.height() / 2);
754 x2 - (1 - KAPPA) * xRadius, y1,
755 x2, y1 + (1 - KAPPA) * yRadius,
758 x2, y2 - (1 - KAPPA) * yRadius,
759 x2 - (1 - KAPPA) * xRadius, y2,
762 x1 + (1 - KAPPA) * xRadius, y2,
763 x1, y2 - (1 - KAPPA) * yRadius,
766 x1, y1 + (1 - KAPPA) * yRadius,
767 x1 + (1 - KAPPA) * xRadius, y1,
771 QVectorPath path(pts, 17, qpaintengineex_roundedrect_types, QVectorPath::RoundedRectHint);
960void QPaintEngineEx::drawPixmapFragments(
const QPainter::PixmapFragment *fragments,
int fragmentCount,
961 const QPixmap &pixmap, QPainter::PixmapFragmentHints )
966 qreal oldOpacity = state()->opacity;
967 QTransform oldTransform = state()->matrix;
969 for (
int i = 0; i < fragmentCount; ++i) {
970 QTransform transform = oldTransform;
971 transform.translate(fragments[i].x, fragments[i].y);
972 transform.rotate(fragments[i].rotation);
973 state()->opacity = oldOpacity * fragments[i].opacity;
974 state()->matrix = transform;
978 qreal w = fragments[i].scaleX * fragments[i].width;
979 qreal h = fragments[i].scaleY * fragments[i].height;
980 QRectF sourceRect(fragments[i].sourceLeft, fragments[i].sourceTop,
981 fragments[i].width, fragments[i].height);
982 drawPixmap(QRectF(-0.5 * w, -0.5 * h, w, h), pixmap, sourceRect);
985 state()->opacity = oldOpacity;
986 state()->matrix = oldTransform;
1002Q_GUI_EXPORT
QPainterPath qt_painterPathFromVectorPath(
const QVectorPath &path)
1004 const qreal *points = path.points();
1005 const QPainterPath::ElementType *types = path.elements();
1010 for (
int i=0; i<path.elementCount(); ++i) {
1012 case QPainterPath::MoveToElement:
1013 p.moveTo(QPointF(points[id], points[id+1]));
1016 case QPainterPath::LineToElement:
1017 p.lineTo(QPointF(points[id], points[id+1]));
1020 case QPainterPath::CurveToElement: {
1021 QPointF p1(points[id], points[id+1]);
1022 QPointF p2(points[id+2], points[id+3]);
1023 QPointF p3(points[id+4], points[id+5]);
1024 p.cubicTo(p1, p2, p3);
1028 case QPainterPath::CurveToDataElement:
1034 p.moveTo(QPointF(points[0], points[1]));
1036 for (
int i=1; i<path.elementCount(); ++i) {
1037 p.lineTo(QPointF(points[id], points[id+1]));
1041 if (path.hints() & QVectorPath::WindingFill)
1042 p.setFillRule(Qt::WindingFill);