129 void setTransform(VGMatrixMode mode, const QTransform& transform); |
129 void setTransform(VGMatrixMode mode, const QTransform& transform); |
130 void updateTransform(QPaintDevice *pdev); |
130 void updateTransform(QPaintDevice *pdev); |
131 void draw(VGPath path, const QPen& pen, const QBrush& brush, VGint rule = VG_EVEN_ODD); |
131 void draw(VGPath path, const QPen& pen, const QBrush& brush, VGint rule = VG_EVEN_ODD); |
132 void stroke(VGPath path, const QPen& pen); |
132 void stroke(VGPath path, const QPen& pen); |
133 void fill(VGPath path, const QBrush& brush, VGint rule = VG_EVEN_ODD); |
133 void fill(VGPath path, const QBrush& brush, VGint rule = VG_EVEN_ODD); |
134 VGPath vectorPathToVGPath(const QVectorPath& path); |
134 inline void releasePath(VGPath path); |
135 VGPath painterPathToVGPath(const QPainterPath& path); |
135 VGPath vectorPathToVGPath(const QVectorPath& path, bool forceNewPath = false); |
|
136 VGPath painterPathToVGPath(const QPainterPath& path, bool forceNewPath = false); |
136 VGPath roundedRectPath(const QRectF &rect, qreal xRadius, qreal yRadius, Qt::SizeMode mode); |
137 VGPath roundedRectPath(const QRectF &rect, qreal xRadius, qreal yRadius, Qt::SizeMode mode); |
137 VGPaintType setBrush |
138 VGPaintType setBrush |
138 (VGPaint paint, const QBrush& brush, VGMatrixMode mode, |
139 (VGPaint paint, const QBrush& brush, VGMatrixMode mode, |
139 VGPaintType prevPaintType); |
140 VGPaintType prevPaintType); |
140 void setPenParams(const QPen& pen); |
141 void setPenParams(const QPen& pen); |
176 VGPath rectPath; // Cached path for quick drawing of rectangles. |
177 VGPath rectPath; // Cached path for quick drawing of rectangles. |
177 VGPath linePath; // Cached path for quick drawing of lines. |
178 VGPath linePath; // Cached path for quick drawing of lines. |
178 VGPath roundRectPath; // Cached path for quick drawing of rounded rects. |
179 VGPath roundRectPath; // Cached path for quick drawing of rounded rects. |
179 #endif |
180 #endif |
180 |
181 |
|
182 VGPath reusablePath; // Reusable path for vectorPathToVGPath(), etc. |
|
183 |
181 QTransform transform; // Currently active transform. |
184 QTransform transform; // Currently active transform. |
182 bool simpleTransform; // True if the transform is simple (non-projective). |
185 bool simpleTransform; // True if the transform is simple (non-projective). |
183 qreal penScale; // Pen scaling factor from "transform". |
186 qreal penScale; // Pen scaling factor from "transform". |
184 |
187 |
185 QTransform pathTransform; // Calculated VG path transformation. |
188 QTransform pathTransform; // Calculated VG path transformation. |
186 QTransform imageTransform; // Calculated VG image transformation. |
189 QTransform imageTransform; // Calculated VG image transformation. |
187 bool pathTransformSet; // True if path transform set in the VG context. |
190 bool pathTransformSet; // True if path transform set in the VG context. |
188 |
191 |
189 bool maskValid; // True if vgMask() contains valid data. |
192 bool maskValid; // True if vgMask() contains valid data. |
190 bool maskIsSet; // True if mask would be fully set if it was valid. |
193 bool maskIsSet; // True if mask would be fully set if it was valid. |
|
194 bool scissorMask; // True if scissor is used in place of the mask. |
191 bool rawVG; // True if processing a raw VG escape. |
195 bool rawVG; // True if processing a raw VG escape. |
192 |
196 |
193 QRect maskRect; // Rectangle version of mask if it is simple. |
197 QRect maskRect; // Rectangle version of mask if it is simple. |
194 |
198 |
195 QTransform penTransform; // Transform for the pen. |
199 QTransform penTransform; // Transform for the pen. |
440 2, // segmentCapacityHint |
449 2, // segmentCapacityHint |
441 4, // coordCapacityHint |
450 4, // coordCapacityHint |
442 VG_PATH_CAPABILITY_ALL); |
451 VG_PATH_CAPABILITY_ALL); |
443 vgAppendPathData(linePath, 2, segments, coords); |
452 vgAppendPathData(linePath, 2, segments, coords); |
444 #endif |
453 #endif |
|
454 |
|
455 // This path can be reused over and over by calling vgClearPath(). |
|
456 reusablePath = vgCreatePath(VG_PATH_FORMAT_STANDARD, |
|
457 VG_PATH_DATATYPE_F, |
|
458 1.0f, // scale |
|
459 0.0f, // bias |
|
460 32 + 1, // segmentCapacityHint |
|
461 32 * 2, // coordCapacityHint |
|
462 VG_PATH_CAPABILITY_ALL); |
445 } |
463 } |
446 |
464 |
447 void QVGPaintEnginePrivate::destroy() |
465 void QVGPaintEnginePrivate::destroy() |
448 { |
466 { |
449 if (penPaint) |
467 if (penPaint) |
510 // 3. Flip the co-ordinate system upside down. |
530 // 3. Flip the co-ordinate system upside down. |
511 QTransform viewport(1.0f, 0.0f, 0.0f, |
531 QTransform viewport(1.0f, 0.0f, 0.0f, |
512 0.0f, -1.0f, 0.0f, |
532 0.0f, -1.0f, 0.0f, |
513 0.5f, devh + 0.5f, 1.0f); |
533 0.5f, devh + 0.5f, 1.0f); |
514 |
534 |
515 // The image transform is always the full transformation, |
535 // Compute the path transform and determine if it is projective. |
516 // because it can be projective. |
536 pathTransform = transform * viewport; |
517 imageTransform = transform * viewport; |
537 bool projective = (pathTransform.m13() != 0.0f || |
518 |
538 pathTransform.m23() != 0.0f || |
519 // Determine if the transformation is projective. |
539 pathTransform.m33() != 1.0f); |
520 bool projective = (imageTransform.m13() != 0.0f || |
540 |
521 imageTransform.m23() != 0.0f || |
|
522 imageTransform.m33() != 1.0f); |
|
523 if (projective) { |
541 if (projective) { |
524 // The engine cannot do projective path transforms for us, |
542 // The engine cannot do projective path transforms for us, |
525 // so we will have to convert the co-ordinates ourselves. |
543 // so we will have to convert the co-ordinates ourselves. |
526 // Change the matrix to just the viewport transformation. |
544 // Change the matrix to just the viewport transformation. |
527 pathTransform = viewport; |
545 pathTransform = viewport; |
528 simpleTransform = false; |
546 simpleTransform = false; |
529 } else { |
547 } else { |
530 pathTransform = imageTransform; |
|
531 simpleTransform = true; |
548 simpleTransform = true; |
532 } |
549 } |
533 pathTransformSet = false; |
550 pathTransformSet = false; |
|
551 |
|
552 // The image transform is always the full transformation, |
|
553 // because it can be projective. It also does not need the |
|
554 // (0.5, -0.5) translation because vgDrawImage() implicitly |
|
555 // adds 0.5 to each co-ordinate. |
|
556 QTransform viewport2(1.0f, 0.0f, 0.0f, |
|
557 0.0f, -1.0f, 0.0f, |
|
558 0.0f, devh, 1.0f); |
|
559 imageTransform = transform * viewport2; |
534 |
560 |
535 // Calculate the scaling factor to use for turning cosmetic pens |
561 // Calculate the scaling factor to use for turning cosmetic pens |
536 // into ordinary non-cosmetic pens. |
562 // into ordinary non-cosmetic pens. |
537 qt_scaleForTransform(transform, &penScale); |
563 qt_scaleForTransform(transform, &penScale); |
538 } |
564 } |
539 |
565 |
540 VGPath QVGPaintEnginePrivate::vectorPathToVGPath(const QVectorPath& path) |
566 inline void QVGPaintEnginePrivate::releasePath(VGPath path) |
|
567 { |
|
568 if (path == reusablePath) |
|
569 vgClearPath(path, VG_PATH_CAPABILITY_ALL); |
|
570 else |
|
571 vgDestroyPath(path); |
|
572 } |
|
573 |
|
574 VGPath QVGPaintEnginePrivate::vectorPathToVGPath(const QVectorPath& path, bool forceNewPath) |
541 { |
575 { |
542 int count = path.elementCount(); |
576 int count = path.elementCount(); |
543 const qreal *points = path.points(); |
577 const qreal *points = path.points(); |
544 const QPainterPath::ElementType *elements = path.elements(); |
578 const QPainterPath::ElementType *elements = path.elements(); |
545 |
579 |
546 VGPath vgpath = vgCreatePath(VG_PATH_FORMAT_STANDARD, |
580 VGPath vgpath; |
547 VG_PATH_DATATYPE_F, |
581 if (forceNewPath) { |
548 1.0f, // scale |
582 vgpath = vgCreatePath(VG_PATH_FORMAT_STANDARD, |
549 0.0f, // bias |
583 VG_PATH_DATATYPE_F, |
550 count + 1, // segmentCapacityHint |
584 1.0f, // scale |
551 count * 2, // coordCapacityHint |
585 0.0f, // bias |
552 VG_PATH_CAPABILITY_ALL); |
586 count + 1, // segmentCapacityHint |
|
587 count * 2, // coordCapacityHint |
|
588 VG_PATH_CAPABILITY_ALL); |
|
589 } else { |
|
590 vgpath = reusablePath; |
|
591 } |
553 |
592 |
554 // Size is sufficient segments for drawRoundedRect() paths. |
593 // Size is sufficient segments for drawRoundedRect() paths. |
555 QVarLengthArray<VGubyte, 20> segments; |
594 QVarLengthArray<VGubyte, 20> segments; |
556 |
595 |
557 if (sizeof(qreal) == sizeof(VGfloat) && elements && simpleTransform) { |
596 if (sizeof(qreal) == sizeof(VGfloat) && elements && simpleTransform) { |
719 segments.constData(), coords.constData()); |
758 segments.constData(), coords.constData()); |
720 |
759 |
721 return vgpath; |
760 return vgpath; |
722 } |
761 } |
723 |
762 |
724 VGPath QVGPaintEnginePrivate::painterPathToVGPath(const QPainterPath& path) |
763 VGPath QVGPaintEnginePrivate::painterPathToVGPath(const QPainterPath& path, bool forceNewPath) |
725 { |
764 { |
726 int count = path.elementCount(); |
765 int count = path.elementCount(); |
727 |
766 |
728 VGPath vgpath = vgCreatePath(VG_PATH_FORMAT_STANDARD, |
767 VGPath vgpath; |
729 VG_PATH_DATATYPE_F, |
768 if (forceNewPath) { |
730 1.0f, // scale |
769 vgpath = vgCreatePath(VG_PATH_FORMAT_STANDARD, |
731 0.0f, // bias |
770 VG_PATH_DATATYPE_F, |
732 count + 1, // segmentCapacityHint |
771 1.0f, // scale |
733 count * 2, // coordCapacityHint |
772 0.0f, // bias |
734 VG_PATH_CAPABILITY_ALL); |
773 count + 1, // segmentCapacityHint |
|
774 count * 2, // coordCapacityHint |
|
775 VG_PATH_CAPABILITY_ALL); |
|
776 } else { |
|
777 vgpath = reusablePath; |
|
778 } |
735 |
779 |
736 if (count == 0) |
780 if (count == 0) |
737 return vgpath; |
781 return vgpath; |
738 |
782 |
739 const QPainterPath::Element *elements = &(path.elementAt(0)); |
783 const QPainterPath::Element *elements = &(path.elementAt(0)); |
1015 img = image.convertToFormat(QImage::Format_ARGB32_Premultiplied, flags); |
1056 img = image.convertToFormat(QImage::Format_ARGB32_Premultiplied, flags); |
1016 format = VG_sARGB_8888_PRE; |
1057 format = VG_sARGB_8888_PRE; |
1017 break; |
1058 break; |
1018 } |
1059 } |
1019 |
1060 |
1020 const uchar *pixels = img.bits(); |
1061 const uchar *pixels = qt_vg_imageBits(img); |
1021 |
1062 |
1022 VGImage vgImg = QVGImagePool::instance()->createPermanentImage |
1063 VGImage vgImg = QVGImagePool::instance()->createPermanentImage |
1023 (format, img.width(), img.height(), VG_IMAGE_QUALITY_FASTER); |
1064 (format, img.width(), img.height(), VG_IMAGE_QUALITY_FASTER); |
1024 vgImageSubData |
1065 vgImageSubData |
1025 (vgImg, pixels, img.bytesPerLine(), format, 0, 0, |
1066 (vgImg, pixels, img.bytesPerLine(), format, 0, 0, |
1081 painter.begin(&img); |
1122 painter.begin(&img); |
1082 painter.setOpacity(opacity); |
1123 painter.setOpacity(opacity); |
1083 painter.drawImage(0, 0, image); |
1124 painter.drawImage(0, 0, image); |
1084 painter.end(); |
1125 painter.end(); |
1085 |
1126 |
1086 const uchar *pixels = img.bits(); |
1127 const uchar *pixels = qt_vg_imageBits(img); |
1087 |
1128 |
1088 VGImage vgImg = QVGImagePool::instance()->createPermanentImage |
1129 VGImage vgImg = QVGImagePool::instance()->createPermanentImage |
1089 (VG_sARGB_8888_PRE, img.width(), img.height(), VG_IMAGE_QUALITY_FASTER); |
1130 (VG_sARGB_8888_PRE, img.width(), img.height(), VG_IMAGE_QUALITY_FASTER); |
1090 vgImageSubData |
1131 vgImageSubData |
1091 (vgImg, pixels, img.bytesPerLine(), VG_sARGB_8888_PRE, 0, 0, |
1132 (vgImg, pixels, img.bytesPerLine(), VG_sARGB_8888_PRE, 0, 0, |
1103 painter.begin(&img); |
1144 painter.begin(&img); |
1104 painter.setOpacity(opacity); |
1145 painter.setOpacity(opacity); |
1105 painter.drawImage(QPoint(0, 0), image, sr); |
1146 painter.drawImage(QPoint(0, 0), image, sr); |
1106 painter.end(); |
1147 painter.end(); |
1107 |
1148 |
1108 const uchar *pixels = img.bits(); |
1149 const uchar *pixels = qt_vg_imageBits(img); |
1109 |
1150 |
1110 VGImage vgImg = QVGImagePool::instance()->createPermanentImage |
1151 VGImage vgImg = QVGImagePool::instance()->createPermanentImage |
1111 (VG_sARGB_8888_PRE, img.width(), img.height(), VG_IMAGE_QUALITY_FASTER); |
1152 (VG_sARGB_8888_PRE, img.width(), img.height(), VG_IMAGE_QUALITY_FASTER); |
1112 vgImageSubData |
1153 vgImageSubData |
1113 (vgImg, pixels, img.bytesPerLine(), VG_sARGB_8888_PRE, 0, 0, |
1154 (vgImg, pixels, img.bytesPerLine(), VG_sARGB_8888_PRE, 0, 0, |
1507 VGPath vgpath = d->vectorPathToVGPath(path); |
1548 VGPath vgpath = d->vectorPathToVGPath(path); |
1508 if (!path.hasWindingFill()) |
1549 if (!path.hasWindingFill()) |
1509 d->draw(vgpath, s->pen, s->brush, VG_EVEN_ODD); |
1550 d->draw(vgpath, s->pen, s->brush, VG_EVEN_ODD); |
1510 else |
1551 else |
1511 d->draw(vgpath, s->pen, s->brush, VG_NON_ZERO); |
1552 d->draw(vgpath, s->pen, s->brush, VG_NON_ZERO); |
1512 vgDestroyPath(vgpath); |
1553 d->releasePath(vgpath); |
1513 } |
1554 } |
1514 |
1555 |
1515 void QVGPaintEngine::fill(const QVectorPath &path, const QBrush &brush) |
1556 void QVGPaintEngine::fill(const QVectorPath &path, const QBrush &brush) |
1516 { |
1557 { |
1517 Q_D(QVGPaintEngine); |
1558 Q_D(QVGPaintEngine); |
1518 VGPath vgpath = d->vectorPathToVGPath(path); |
1559 VGPath vgpath = d->vectorPathToVGPath(path); |
1519 if (!path.hasWindingFill()) |
1560 if (!path.hasWindingFill()) |
1520 d->fill(vgpath, brush, VG_EVEN_ODD); |
1561 d->fill(vgpath, brush, VG_EVEN_ODD); |
1521 else |
1562 else |
1522 d->fill(vgpath, brush, VG_NON_ZERO); |
1563 d->fill(vgpath, brush, VG_NON_ZERO); |
1523 vgDestroyPath(vgpath); |
1564 d->releasePath(vgpath); |
1524 } |
1565 } |
1525 |
1566 |
1526 void QVGPaintEngine::stroke(const QVectorPath &path, const QPen &pen) |
1567 void QVGPaintEngine::stroke(const QVectorPath &path, const QPen &pen) |
1527 { |
1568 { |
1528 Q_D(QVGPaintEngine); |
1569 Q_D(QVGPaintEngine); |
1529 VGPath vgpath = d->vectorPathToVGPath(path); |
1570 VGPath vgpath = d->vectorPathToVGPath(path); |
1530 d->stroke(vgpath, pen); |
1571 d->stroke(vgpath, pen); |
1531 vgDestroyPath(vgpath); |
1572 d->releasePath(vgpath); |
1532 } |
1573 } |
1533 |
1574 |
1534 // Determine if a co-ordinate transform is simple enough to allow |
1575 // Determine if a co-ordinate transform is simple enough to allow |
1535 // rectangle-based clipping with vgMask(). Simple transforms most |
1576 // rectangle-based clipping with vgMask(). Simple transforms most |
1536 // often result from origin translations. |
1577 // often result from origin translations. |
1537 static inline bool clipTransformIsSimple(const QTransform& transform) |
1578 static inline bool clipTransformIsSimple(const QTransform& transform) |
1538 { |
1579 { |
1539 QTransform::TransformationType type = transform.type(); |
1580 QTransform::TransformationType type = transform.type(); |
1540 return (type == QTransform::TxNone || type == QTransform::TxTranslate); |
1581 if (type == QTransform::TxNone || type == QTransform::TxTranslate) |
|
1582 return true; |
|
1583 if (type == QTransform::TxRotate) { |
|
1584 // Check for 0, 90, 180, and 270 degree rotations. |
|
1585 // (0 might happen after 4 rotations of 90 degrees). |
|
1586 qreal m11 = transform.m11(); |
|
1587 qreal m12 = transform.m12(); |
|
1588 qreal m21 = transform.m21(); |
|
1589 qreal m22 = transform.m22(); |
|
1590 if (m11 == 0.0f && m22 == 0.0f) { |
|
1591 if (m12 == 1.0f && m21 == -1.0f) |
|
1592 return true; // 90 degrees. |
|
1593 else if (m12 == -1.0f && m21 == 1.0f) |
|
1594 return true; // 270 degrees. |
|
1595 } else if (m12 == 0.0f && m21 == 0.0f) { |
|
1596 if (m11 == -1.0f && m22 == -1.0f) |
|
1597 return true; // 180 degrees. |
|
1598 else if (m11 == 1.0f && m22 == 1.0f) |
|
1599 return true; // 0 degrees. |
|
1600 } |
|
1601 } |
|
1602 return false; |
1541 } |
1603 } |
1542 |
1604 |
1543 #if defined(QVG_SCISSOR_CLIP) |
1605 #if defined(QVG_SCISSOR_CLIP) |
1544 |
1606 |
1545 void QVGPaintEngine::clip(const QVectorPath &path, Qt::ClipOperation op) |
1607 void QVGPaintEngine::clip(const QVectorPath &path, Qt::ClipOperation op) |
1657 d->dirty |= QPaintEngine::DirtyClipRegion; |
1719 d->dirty |= QPaintEngine::DirtyClipRegion; |
1658 |
1720 |
1659 if (op == Qt::NoClip) { |
1721 if (op == Qt::NoClip) { |
1660 d->maskValid = false; |
1722 d->maskValid = false; |
1661 d->maskIsSet = true; |
1723 d->maskIsSet = true; |
|
1724 d->scissorMask = false; |
1662 d->maskRect = QRect(); |
1725 d->maskRect = QRect(); |
1663 vgSeti(VG_MASKING, VG_FALSE); |
1726 vgSeti(VG_MASKING, VG_FALSE); |
1664 return; |
1727 return; |
1665 } |
1728 } |
1666 |
1729 |
1667 #if defined(QVG_NO_RENDER_TO_MASK) |
|
1668 // We don't have vgRenderToMask(), so handle simple QRectF's only. |
1730 // We don't have vgRenderToMask(), so handle simple QRectF's only. |
1669 if (path.shape() == QVectorPath::RectangleHint && |
1731 if (path.shape() == QVectorPath::RectangleHint && |
1670 path.elementCount() == 4 && clipTransformIsSimple(d->transform)) { |
1732 path.elementCount() == 4 && clipTransformIsSimple(d->transform)) { |
1671 // Clipping region that resulted from QPainter::setClipRect(QRectF). |
1733 // Clipping region that resulted from QPainter::setClipRect(QRectF). |
1672 // Convert it into a QRect and apply. |
1734 // Convert it into a QRect and apply. |
1673 const qreal *points = path.points(); |
1735 const qreal *points = path.points(); |
1674 QRectF rect(points[0], points[1], points[2] - points[0], |
1736 QRectF rect(points[0], points[1], points[2] - points[0], |
1675 points[5] - points[1]); |
1737 points[5] - points[1]); |
1676 clip(rect.toRect(), op); |
1738 clip(rect.toRect(), op); |
1677 } |
1739 return; |
1678 #else |
1740 } |
|
1741 |
|
1742 #if !defined(QVG_NO_RENDER_TO_MASK) |
1679 QPaintDevice *pdev = paintDevice(); |
1743 QPaintDevice *pdev = paintDevice(); |
1680 int width = pdev->width(); |
1744 int width = pdev->width(); |
1681 int height = pdev->height(); |
1745 int height = pdev->height(); |
1682 |
1746 |
1683 if (op == Qt::ReplaceClip) { |
1747 if (op == Qt::ReplaceClip) { |
1739 // same as turning off clipping. |
1805 // same as turning off clipping. |
1740 if (d->maskValid) |
1806 if (d->maskValid) |
1741 vgSeti(VG_MASKING, VG_FALSE); |
1807 vgSeti(VG_MASKING, VG_FALSE); |
1742 d->maskValid = false; |
1808 d->maskValid = false; |
1743 d->maskIsSet = true; |
1809 d->maskIsSet = true; |
|
1810 d->scissorMask = false; |
1744 d->maskRect = QRect(); |
1811 d->maskRect = QRect(); |
1745 } else { |
1812 } else { |
1746 // Special case: if the intersection of the system |
1813 // Special case: if the intersection of the system |
1747 // clip and "r" is a single rectangle, then use the |
1814 // clip and "r" is a single rectangle, then use the |
1748 // scissor for clipping. We try to avoid allocating a |
1815 // scissor for clipping. We try to avoid allocating a |
1756 } else { |
1823 } else { |
1757 clip = clip.intersect(r); |
1824 clip = clip.intersect(r); |
1758 if (clip.rectCount() != 1) { |
1825 if (clip.rectCount() != 1) { |
1759 d->maskValid = false; |
1826 d->maskValid = false; |
1760 d->maskIsSet = false; |
1827 d->maskIsSet = false; |
|
1828 d->scissorMask = false; |
1761 d->maskRect = QRect(); |
1829 d->maskRect = QRect(); |
1762 d->modifyMask(this, VG_FILL_MASK, r); |
1830 d->modifyMask(this, VG_FILL_MASK, r); |
1763 break; |
1831 break; |
1764 } |
1832 } |
1765 clipRect = clip.boundingRect(); |
1833 clipRect = clip.boundingRect(); |
1766 } |
1834 } |
1767 d->maskValid = false; |
1835 d->maskValid = false; |
1768 d->maskIsSet = false; |
1836 d->maskIsSet = false; |
|
1837 d->scissorMask = true; |
1769 d->maskRect = clipRect; |
1838 d->maskRect = clipRect; |
1770 vgSeti(VG_MASKING, VG_FALSE); |
1839 vgSeti(VG_MASKING, VG_FALSE); |
1771 updateScissor(); |
1840 updateScissor(); |
1772 } |
1841 } |
1773 } |
1842 } |
1774 break; |
1843 break; |
1775 |
1844 |
1776 case Qt::IntersectClip: |
1845 case Qt::IntersectClip: |
1777 { |
1846 { |
1778 QRect r = d->transform.mapRect(rect); |
1847 QRect r = d->transform.mapRect(rect); |
1779 if (d->maskIsSet && isDefaultClipRect(r)) { |
1848 if (!d->maskValid) { |
|
1849 // Mask has not been used yet, so intersect with |
|
1850 // the previous scissor-based region in maskRect. |
|
1851 if (d->scissorMask) |
|
1852 r = r.intersect(d->maskRect); |
|
1853 if (isDefaultClipRect(r)) { |
|
1854 // The clip is the full window, so turn off clipping. |
|
1855 d->maskIsSet = true; |
|
1856 d->maskRect = QRect(); |
|
1857 } else { |
|
1858 // Activate the scissor on a smaller maskRect. |
|
1859 d->maskIsSet = false; |
|
1860 d->maskRect = r; |
|
1861 } |
|
1862 d->scissorMask = true; |
|
1863 updateScissor(); |
|
1864 } else if (d->maskIsSet && isDefaultClipRect(r)) { |
1780 // Intersecting a full-window clip with a full-window |
1865 // Intersecting a full-window clip with a full-window |
1781 // region is the same as turning off clipping. |
1866 // region is the same as turning off clipping. |
1782 if (d->maskValid) |
1867 if (d->maskValid) |
1783 vgSeti(VG_MASKING, VG_FALSE); |
1868 vgSeti(VG_MASKING, VG_FALSE); |
1784 d->maskValid = false; |
1869 d->maskValid = false; |
1785 d->maskIsSet = true; |
1870 d->maskIsSet = true; |
|
1871 d->scissorMask = false; |
1786 d->maskRect = QRect(); |
1872 d->maskRect = QRect(); |
1787 } else { |
1873 } else { |
1788 d->modifyMask(this, VG_INTERSECT_MASK, r); |
1874 d->modifyMask(this, VG_INTERSECT_MASK, r); |
1789 } |
1875 } |
1790 } |
1876 } |
1837 // same as turning off clipping. |
1924 // same as turning off clipping. |
1838 if (d->maskValid) |
1925 if (d->maskValid) |
1839 vgSeti(VG_MASKING, VG_FALSE); |
1926 vgSeti(VG_MASKING, VG_FALSE); |
1840 d->maskValid = false; |
1927 d->maskValid = false; |
1841 d->maskIsSet = true; |
1928 d->maskIsSet = true; |
|
1929 d->scissorMask = false; |
1842 d->maskRect = QRect(); |
1930 d->maskRect = QRect(); |
1843 } else { |
1931 } else { |
1844 // Special case: if the intersection of the system |
1932 // Special case: if the intersection of the system |
1845 // clip and the region is a single rectangle, then |
1933 // clip and the region is a single rectangle, then |
1846 // use the scissor for clipping. |
1934 // use the scissor for clipping. |
1850 else |
1938 else |
1851 clip = clip.intersect(r); |
1939 clip = clip.intersect(r); |
1852 if (clip.rectCount() == 1) { |
1940 if (clip.rectCount() == 1) { |
1853 d->maskValid = false; |
1941 d->maskValid = false; |
1854 d->maskIsSet = false; |
1942 d->maskIsSet = false; |
|
1943 d->scissorMask = true; |
1855 d->maskRect = clip.boundingRect(); |
1944 d->maskRect = clip.boundingRect(); |
1856 vgSeti(VG_MASKING, VG_FALSE); |
1945 vgSeti(VG_MASKING, VG_FALSE); |
1857 updateScissor(); |
1946 updateScissor(); |
1858 } else { |
1947 } else { |
1859 d->maskValid = false; |
1948 d->maskValid = false; |
1860 d->maskIsSet = false; |
1949 d->maskIsSet = false; |
|
1950 d->scissorMask = false; |
1861 d->maskRect = QRect(); |
1951 d->maskRect = QRect(); |
1862 d->modifyMask(this, VG_FILL_MASK, r); |
1952 d->modifyMask(this, VG_FILL_MASK, r); |
1863 } |
1953 } |
1864 } |
1954 } |
1865 } |
1955 } |
1988 vgRenderToMask(vgpath, VG_FILL_PATH, VG_INTERSECT_MASK); |
2080 vgRenderToMask(vgpath, VG_FILL_PATH, VG_INTERSECT_MASK); |
1989 break; |
2081 break; |
1990 |
2082 |
1991 default: break; |
2083 default: break; |
1992 } |
2084 } |
1993 vgDestroyPath(vgpath); |
2085 d->releasePath(vgpath); |
1994 |
2086 |
1995 vgSeti(VG_MASKING, VG_TRUE); |
2087 vgSeti(VG_MASKING, VG_TRUE); |
1996 d->maskValid = true; |
2088 d->maskValid = true; |
1997 d->maskIsSet = false; |
2089 d->maskIsSet = false; |
|
2090 d->scissorMask = false; |
1998 #else |
2091 #else |
1999 QPaintEngineEx::clip(path, op); |
2092 QPaintEngineEx::clip(path, op); |
2000 #endif |
2093 #endif |
2001 } |
2094 } |
2002 |
2095 |
2003 void QVGPaintEnginePrivate::ensureMask |
2096 void QVGPaintEnginePrivate::ensureMask |
2004 (QVGPaintEngine *engine, int width, int height) |
2097 (QVGPaintEngine *engine, int width, int height) |
2005 { |
2098 { |
|
2099 scissorMask = false; |
2006 if (maskIsSet) { |
2100 if (maskIsSet) { |
2007 vgMask(VG_INVALID_HANDLE, VG_FILL_MASK, 0, 0, width, height); |
2101 vgMask(VG_INVALID_HANDLE, VG_FILL_MASK, 0, 0, width, height); |
2008 maskRect = QRect(); |
2102 maskRect = QRect(); |
2009 } else { |
2103 } else { |
2010 vgMask(VG_INVALID_HANDLE, VG_CLEAR_MASK, 0, 0, width, height); |
2104 vgMask(VG_INVALID_HANDLE, VG_CLEAR_MASK, 0, 0, width, height); |
2081 if (isDefaultClipRegion(region)) { |
2177 if (isDefaultClipRegion(region)) { |
2082 // The scissor region is the entire drawing surface, |
2178 // The scissor region is the entire drawing surface, |
2083 // so there is no point doing any scissoring. |
2179 // so there is no point doing any scissoring. |
2084 vgSeti(VG_SCISSORING, VG_FALSE); |
2180 vgSeti(VG_SCISSORING, VG_FALSE); |
2085 d->scissorActive = false; |
2181 d->scissorActive = false; |
|
2182 d->scissorDirty = false; |
2086 return; |
2183 return; |
2087 } |
2184 } |
2088 } else |
2185 } else |
2089 #endif |
2186 #endif |
2090 { |
2187 { |
2091 #if !defined(QVG_SCISSOR_CLIP) |
2188 #if !defined(QVG_SCISSOR_CLIP) |
2092 // Combine the system clip with the simple mask rectangle. |
2189 // Combine the system clip with the simple mask rectangle. |
2093 if (!d->maskRect.isNull()) { |
2190 if (d->scissorMask) { |
2094 if (region.isEmpty()) |
2191 if (region.isEmpty()) |
2095 region = d->maskRect; |
2192 region = d->maskRect; |
2096 else |
2193 else |
2097 region = region.intersect(d->maskRect); |
2194 region = region.intersect(d->maskRect); |
2098 if (isDefaultClipRegion(region)) { |
2195 if (isDefaultClipRegion(region)) { |
2099 // The scissor region is the entire drawing surface, |
2196 // The scissor region is the entire drawing surface, |
2100 // so there is no point doing any scissoring. |
2197 // so there is no point doing any scissoring. |
2101 vgSeti(VG_SCISSORING, VG_FALSE); |
2198 vgSeti(VG_SCISSORING, VG_FALSE); |
2102 d->scissorActive = false; |
2199 d->scissorActive = false; |
|
2200 d->scissorDirty = false; |
2103 return; |
2201 return; |
2104 } |
2202 } |
2105 } else |
2203 } else |
2106 #endif |
2204 #endif |
2107 |
2205 |
2108 // Disable the scissor completely if the system clip is empty. |
2206 // Disable the scissor completely if the system clip is empty. |
2109 if (region.isEmpty()) { |
2207 if (region.isEmpty()) { |
2110 vgSeti(VG_SCISSORING, VG_FALSE); |
2208 vgSeti(VG_SCISSORING, VG_FALSE); |
2111 d->scissorActive = false; |
2209 d->scissorActive = false; |
|
2210 d->scissorDirty = false; |
2112 return; |
2211 return; |
2113 } |
2212 } |
2114 } |
2213 } |
2115 |
2214 |
2116 if (d->scissorActive && region == d->scissorRegion) |
2215 if (d->scissorActive && region == d->scissorRegion && !d->scissorDirty) |
2117 return; |
2216 return; |
2118 |
2217 |
2119 QVector<QRect> rects = region.rects(); |
2218 QVector<QRect> rects = region.rects(); |
2120 int count = rects.count(); |
2219 int count = rects.count(); |
2121 if (count > d->maxScissorRects) |
2220 if (count > d->maxScissorRects) |
2176 d->dirty |= QPaintEngine::DirtyClipEnabled; |
2276 d->dirty |= QPaintEngine::DirtyClipEnabled; |
2177 if (s->clipEnabled && s->clipOperation != Qt::NoClip) { |
2277 if (s->clipEnabled && s->clipOperation != Qt::NoClip) { |
2178 // Replay the entire clip stack to put the mask into the right state. |
2278 // Replay the entire clip stack to put the mask into the right state. |
2179 d->maskValid = false; |
2279 d->maskValid = false; |
2180 d->maskIsSet = true; |
2280 d->maskIsSet = true; |
|
2281 d->scissorMask = false; |
2181 d->maskRect = QRect(); |
2282 d->maskRect = QRect(); |
2182 s->clipRegion = defaultClipRegion(); |
2283 s->clipRegion = defaultClipRegion(); |
2183 d->replayClipOperations(); |
2284 d->replayClipOperations(); |
2184 d->transform = s->transform(); |
2285 d->transform = s->transform(); |
2185 d->updateTransform(paintDevice()); |
2286 d->updateTransform(paintDevice()); |
2186 } else { |
2287 } else { |
2187 vgSeti(VG_MASKING, VG_FALSE); |
2288 vgSeti(VG_MASKING, VG_FALSE); |
2188 d->maskValid = false; |
2289 d->maskValid = false; |
2189 d->maskIsSet = false; |
2290 d->maskIsSet = false; |
|
2291 d->scissorMask = false; |
2190 d->maskRect = QRect(); |
2292 d->maskRect = QRect(); |
2191 } |
2293 } |
2192 #endif |
2294 #endif |
2193 } |
2295 } |
2194 |
2296 |
2303 bool QVGPaintEngine::clearRect(const QRectF &rect, const QColor &color) |
2405 bool QVGPaintEngine::clearRect(const QRectF &rect, const QColor &color) |
2304 { |
2406 { |
2305 Q_D(QVGPaintEngine); |
2407 Q_D(QVGPaintEngine); |
2306 QVGPainterState *s = state(); |
2408 QVGPainterState *s = state(); |
2307 if (!s->clipEnabled || s->clipOperation == Qt::NoClip) { |
2409 if (!s->clipEnabled || s->clipOperation == Qt::NoClip) { |
2308 // The transform will either be identity or a simple translation, |
2410 QRect r = d->transform.mapRect(rect).toRect(); |
2309 // so do a simpler version of "r = d->transform.map(rect).toRect()". |
|
2310 QRect r = QRect(qRound(rect.x() + d->transform.dx()), |
|
2311 qRound(rect.y() + d->transform.dy()), |
|
2312 qRound(rect.width()), |
|
2313 qRound(rect.height())); |
|
2314 int height = paintDevice()->height(); |
2411 int height = paintDevice()->height(); |
2315 if (d->clearColor != color || d->clearOpacity != s->opacity) { |
2412 if (d->clearColor != color || d->clearOpacity != s->opacity) { |
2316 VGfloat values[4]; |
2413 VGfloat values[4]; |
2317 values[0] = color.redF(); |
2414 values[0] = color.redF(); |
2318 values[1] = color.greenF(); |
2415 values[1] = color.greenF(); |
2423 if (d->simpleTransform) { |
2520 if (d->simpleTransform) { |
2424 QVGPainterState *s = state(); |
2521 QVGPainterState *s = state(); |
2425 VGPath vgpath = d->roundedRectPath(rect, xrad, yrad, mode); |
2522 VGPath vgpath = d->roundedRectPath(rect, xrad, yrad, mode); |
2426 d->draw(vgpath, s->pen, s->brush); |
2523 d->draw(vgpath, s->pen, s->brush); |
2427 #if defined(QVG_NO_MODIFY_PATH) |
2524 #if defined(QVG_NO_MODIFY_PATH) |
2428 vgDestroyPath(vgpath); |
2525 d->releasePath(vgpath); |
2429 #endif |
2526 #endif |
2430 } else { |
2527 } else { |
2431 QPaintEngineEx::drawRoundedRect(rect, xrad, yrad, mode); |
2528 QPaintEngineEx::drawRoundedRect(rect, xrad, yrad, mode); |
2432 } |
2529 } |
2433 } |
2530 } |
2572 // Based on the description of vguEllipse() in the OpenVG specification. |
2669 // Based on the description of vguEllipse() in the OpenVG specification. |
2573 // We don't use vguEllipse(), to avoid unnecessary library dependencies. |
2670 // We don't use vguEllipse(), to avoid unnecessary library dependencies. |
2574 Q_D(QVGPaintEngine); |
2671 Q_D(QVGPaintEngine); |
2575 if (d->simpleTransform) { |
2672 if (d->simpleTransform) { |
2576 QVGPainterState *s = state(); |
2673 QVGPainterState *s = state(); |
2577 VGPath path = vgCreatePath(VG_PATH_FORMAT_STANDARD, |
2674 VGPath path = d->reusablePath; |
2578 VG_PATH_DATATYPE_F, |
|
2579 1.0f, // scale |
|
2580 0.0f, // bias |
|
2581 4, // segmentCapacityHint |
|
2582 12, // coordCapacityHint |
|
2583 VG_PATH_CAPABILITY_ALL); |
|
2584 static VGubyte segments[4] = { |
2675 static VGubyte segments[4] = { |
2585 VG_MOVE_TO_ABS, |
2676 VG_MOVE_TO_ABS, |
2586 VG_SCCWARC_TO_REL, |
2677 VG_SCCWARC_TO_REL, |
2587 VG_SCCWARC_TO_REL, |
2678 VG_SCCWARC_TO_REL, |
2588 VG_CLOSE_PATH |
2679 VG_CLOSE_PATH |
2602 coords[9] = 0.0f; |
2693 coords[9] = 0.0f; |
2603 coords[10] = r.width(); |
2694 coords[10] = r.width(); |
2604 coords[11] = 0.0f; |
2695 coords[11] = 0.0f; |
2605 vgAppendPathData(path, 4, segments, coords); |
2696 vgAppendPathData(path, 4, segments, coords); |
2606 d->draw(path, s->pen, s->brush); |
2697 d->draw(path, s->pen, s->brush); |
2607 vgDestroyPath(path); |
2698 d->releasePath(path); |
2608 } else { |
2699 } else { |
2609 // The projective transform version of an ellipse is difficult. |
2700 // The projective transform version of an ellipse is difficult. |
2610 // Generate a QVectorPath containing cubic curves and transform that. |
2701 // Generate a QVectorPath containing cubic curves and transform that. |
2611 QPaintEngineEx::drawEllipse(r); |
2702 QPaintEngineEx::drawEllipse(r); |
2612 } |
2703 } |
2626 VGPath vgpath = d->painterPathToVGPath(path); |
2717 VGPath vgpath = d->painterPathToVGPath(path); |
2627 if (path.fillRule() == Qt::OddEvenFill) |
2718 if (path.fillRule() == Qt::OddEvenFill) |
2628 d->draw(vgpath, s->pen, s->brush, VG_EVEN_ODD); |
2719 d->draw(vgpath, s->pen, s->brush, VG_EVEN_ODD); |
2629 else |
2720 else |
2630 d->draw(vgpath, s->pen, s->brush, VG_NON_ZERO); |
2721 d->draw(vgpath, s->pen, s->brush, VG_NON_ZERO); |
2631 vgDestroyPath(vgpath); |
2722 d->releasePath(vgpath); |
2632 } |
2723 } |
2633 |
2724 |
2634 void QVGPaintEngine::drawPoints(const QPointF *points, int pointCount) |
2725 void QVGPaintEngine::drawPoints(const QPointF *points, int pointCount) |
2635 { |
2726 { |
2636 #if !defined(QVG_NO_MODIFY_PATH) |
2727 #if !defined(QVG_NO_MODIFY_PATH) |
2701 |
2792 |
2702 void QVGPaintEngine::drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode) |
2793 void QVGPaintEngine::drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode) |
2703 { |
2794 { |
2704 Q_D(QVGPaintEngine); |
2795 Q_D(QVGPaintEngine); |
2705 QVGPainterState *s = state(); |
2796 QVGPainterState *s = state(); |
2706 VGPath path = vgCreatePath(VG_PATH_FORMAT_STANDARD, |
2797 VGPath path = d->reusablePath; |
2707 VG_PATH_DATATYPE_F, |
|
2708 1.0f, // scale |
|
2709 0.0f, // bias |
|
2710 pointCount + 1, // segmentCapacityHint |
|
2711 pointCount * 2, // coordCapacityHint |
|
2712 VG_PATH_CAPABILITY_ALL); |
|
2713 QVarLengthArray<VGfloat, 16> coords; |
2798 QVarLengthArray<VGfloat, 16> coords; |
2714 QVarLengthArray<VGubyte, 10> segments; |
2799 QVarLengthArray<VGubyte, 10> segments; |
2715 for (int i = 0; i < pointCount; ++i, ++points) { |
2800 for (int i = 0; i < pointCount; ++i, ++points) { |
2716 if (d->simpleTransform) { |
2801 if (d->simpleTransform) { |
2717 coords.append(points->x()); |
2802 coords.append(points->x()); |
2741 |
2826 |
2742 default: |
2827 default: |
2743 d->draw(path, s->pen, s->brush, VG_EVEN_ODD); |
2828 d->draw(path, s->pen, s->brush, VG_EVEN_ODD); |
2744 break; |
2829 break; |
2745 } |
2830 } |
2746 vgDestroyPath(path); |
2831 d->releasePath(path); |
2747 } |
2832 } |
2748 |
2833 |
2749 void QVGPaintEngine::drawPolygon(const QPoint *points, int pointCount, PolygonDrawMode mode) |
2834 void QVGPaintEngine::drawPolygon(const QPoint *points, int pointCount, PolygonDrawMode mode) |
2750 { |
2835 { |
2751 Q_D(QVGPaintEngine); |
2836 Q_D(QVGPaintEngine); |
2752 QVGPainterState *s = state(); |
2837 QVGPainterState *s = state(); |
2753 VGPath path = vgCreatePath(VG_PATH_FORMAT_STANDARD, |
2838 VGPath path = d->reusablePath; |
2754 VG_PATH_DATATYPE_F, |
|
2755 1.0f, // scale |
|
2756 0.0f, // bias |
|
2757 pointCount + 1, // segmentCapacityHint |
|
2758 pointCount * 2, // coordCapacityHint |
|
2759 VG_PATH_CAPABILITY_ALL); |
|
2760 QVarLengthArray<VGfloat, 16> coords; |
2839 QVarLengthArray<VGfloat, 16> coords; |
2761 QVarLengthArray<VGubyte, 10> segments; |
2840 QVarLengthArray<VGubyte, 10> segments; |
2762 for (int i = 0; i < pointCount; ++i, ++points) { |
2841 for (int i = 0; i < pointCount; ++i, ++points) { |
2763 if (d->simpleTransform) { |
2842 if (d->simpleTransform) { |
2764 coords.append(points->x()); |
2843 coords.append(points->x()); |
3164 VGImage vgImage = VG_INVALID_HANDLE; |
3243 VGImage vgImage = VG_INVALID_HANDLE; |
3165 metrics = ti.fontEngine->boundingBox(glyph); |
3244 metrics = ti.fontEngine->boundingBox(glyph); |
3166 if (!scaledImage.isNull()) { // Not a space character |
3245 if (!scaledImage.isNull()) { // Not a space character |
3167 if (scaledImage.format() == QImage::Format_Indexed8) { |
3246 if (scaledImage.format() == QImage::Format_Indexed8) { |
3168 vgImage = vgCreateImage(VG_A_8, scaledImage.width(), scaledImage.height(), VG_IMAGE_QUALITY_FASTER); |
3247 vgImage = vgCreateImage(VG_A_8, scaledImage.width(), scaledImage.height(), VG_IMAGE_QUALITY_FASTER); |
3169 vgImageSubData(vgImage, scaledImage.bits(), scaledImage.bytesPerLine(), VG_A_8, 0, 0, scaledImage.width(), scaledImage.height()); |
3248 vgImageSubData(vgImage, qt_vg_imageBits(scaledImage), scaledImage.bytesPerLine(), VG_A_8, 0, 0, scaledImage.width(), scaledImage.height()); |
3170 } else if (scaledImage.format() == QImage::Format_Mono) { |
3249 } else if (scaledImage.format() == QImage::Format_Mono) { |
3171 QImage img = scaledImage.convertToFormat(QImage::Format_Indexed8); |
3250 QImage img = scaledImage.convertToFormat(QImage::Format_Indexed8); |
3172 vgImage = vgCreateImage(VG_A_8, img.width(), img.height(), VG_IMAGE_QUALITY_FASTER); |
3251 vgImage = vgCreateImage(VG_A_8, img.width(), img.height(), VG_IMAGE_QUALITY_FASTER); |
3173 vgImageSubData(vgImage, img.bits(), img.bytesPerLine(), VG_A_8, 0, 0, img.width(), img.height()); |
3252 vgImageSubData(vgImage, qt_vg_imageBits(img), img.bytesPerLine(), VG_A_8, 0, 0, img.width(), img.height()); |
3174 } else { |
3253 } else { |
3175 QImage img = scaledImage.convertToFormat(QImage::Format_ARGB32_Premultiplied); |
3254 QImage img = scaledImage.convertToFormat(QImage::Format_ARGB32_Premultiplied); |
3176 vgImage = vgCreateImage(VG_sARGB_8888_PRE, img.width(), img.height(), VG_IMAGE_QUALITY_FASTER); |
3255 vgImage = vgCreateImage(VG_sARGB_8888_PRE, img.width(), img.height(), VG_IMAGE_QUALITY_FASTER); |
3177 vgImageSubData(vgImage, img.bits(), img.bytesPerLine(), VG_sARGB_8888_PRE, 0, 0, img.width(), img.height()); |
3256 vgImageSubData(vgImage, qt_vg_imageBits(img), img.bytesPerLine(), VG_sARGB_8888_PRE, 0, 0, img.width(), img.height()); |
3178 } |
3257 } |
3179 } |
3258 } |
3180 origin[0] = -metrics.x.toReal() + 0.5f; |
3259 origin[0] = -metrics.x.toReal() + 0.5f; |
3181 origin[1] = -metrics.y.toReal() + 0.5f; |
3260 origin[1] = -metrics.y.toReal() + 0.5f; |
3182 escapement[0] = metrics.xoff.toReal(); |
3261 escapement[0] = metrics.xoff.toReal(); |
3331 d->forceBrushChange = true; |
3410 d->forceBrushChange = true; |
3332 d->penType = (VGPaintType)0; |
3411 d->penType = (VGPaintType)0; |
3333 d->brushType = (VGPaintType)0; |
3412 d->brushType = (VGPaintType)0; |
3334 d->clearColor = QColor(); |
3413 d->clearColor = QColor(); |
3335 d->fillPaint = d->brushPaint; |
3414 d->fillPaint = d->brushPaint; |
|
3415 d->scissorDirty = true; |
3336 restoreState(QPaintEngine::AllDirty); |
3416 restoreState(QPaintEngine::AllDirty); |
3337 d->dirty = dirty; |
3417 d->dirty = dirty; |
3338 d->rawVG = false; |
3418 d->rawVG = false; |
3339 vgSetPaint(d->penPaint, VG_STROKE_PATH); |
3419 vgSetPaint(d->penPaint, VG_STROKE_PATH); |
3340 vgSetPaint(d->brushPaint, VG_FILL_PATH); |
3420 vgSetPaint(d->brushPaint, VG_FILL_PATH); |
3638 (VG_sARGB_8888_PRE, img.width(), img.height(), |
3719 (VG_sARGB_8888_PRE, img.width(), img.height(), |
3639 VG_IMAGE_QUALITY_FASTER); |
3720 VG_IMAGE_QUALITY_FASTER); |
3640 if (vgImage == VG_INVALID_HANDLE) |
3721 if (vgImage == VG_INVALID_HANDLE) |
3641 return; |
3722 return; |
3642 vgImageSubData |
3723 vgImageSubData |
3643 (vgImage, img.bits() + img.bytesPerLine() * (img.height() - 1), |
3724 (vgImage, qt_vg_imageBits(img) + img.bytesPerLine() * (img.height() - 1), |
3644 -(img.bytesPerLine()), VG_sARGB_8888_PRE, 0, 0, |
3725 -(img.bytesPerLine()), VG_sARGB_8888_PRE, 0, 0, |
3645 img.width(), img.height()); |
3726 img.width(), img.height()); |
3646 |
3727 |
3647 vgDrawImage(vgImage); |
3728 vgDrawImage(vgImage); |
3648 vgDestroyImage(vgImage); |
3729 vgDestroyImage(vgImage); |
3664 params[i * 4 + 3] = rects[i].height(); |
3745 params[i * 4 + 3] = rects[i].height(); |
3665 } |
3746 } |
3666 |
3747 |
3667 vgSetiv(VG_SCISSOR_RECTS, count * 4, params.data()); |
3748 vgSetiv(VG_SCISSOR_RECTS, count * 4, params.data()); |
3668 vgSeti(VG_SCISSORING, VG_TRUE); |
3749 vgSeti(VG_SCISSORING, VG_TRUE); |
|
3750 d->scissorDirty = false; |
3669 d->scissorActive = true; |
3751 d->scissorActive = true; |
3670 d->scissorRegion = region; |
3752 d->scissorRegion = region; |
3671 } |
3753 } |
3672 |
3754 |
3673 void QVGCompositionHelper::clearScissor() |
3755 void QVGCompositionHelper::clearScissor() |
3674 { |
3756 { |
3675 if (d->scissorActive) { |
3757 if (d->scissorActive || d->scissorDirty) { |
3676 vgSeti(VG_SCISSORING, VG_FALSE); |
3758 vgSeti(VG_SCISSORING, VG_FALSE); |
3677 d->scissorActive = false; |
3759 d->scissorActive = false; |
|
3760 d->scissorDirty = false; |
3678 } |
3761 } |
3679 } |
3762 } |
3680 |
3763 |
3681 #endif // !QVG_NO_SINGLE_CONTEXT && !QT_NO_EGL |
3764 #endif // !QVG_NO_SINGLE_CONTEXT && !QT_NO_EGL |
3682 |
3765 |