changeset 19 | fcece45ef507 |
parent 18 | 2f34d5167611 |
child 22 | 79de32ba3296 |
18:2f34d5167611 | 19:fcece45ef507 |
---|---|
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 inline void releasePath(VGPath path); |
134 VGPath vectorPathToVGPath(const QVectorPath& path); |
135 VGPath vectorPathToVGPath(const QVectorPath& path, bool forceNewPath = false); |
135 VGPath painterPathToVGPath(const QPainterPath& path); |
136 VGPath painterPathToVGPath(const QPainterPath& path, bool forceNewPath = false); |
|
137 VGPath roundedRectPath(const QRectF &rect, qreal xRadius, qreal yRadius, Qt::SizeMode mode); |
136 VGPath roundedRectPath(const QRectF &rect, qreal xRadius, qreal yRadius, Qt::SizeMode mode); |
138 VGPaintType setBrush |
137 VGPaintType setBrush |
139 (VGPaint paint, const QBrush& brush, VGMatrixMode mode, |
138 (VGPaint paint, const QBrush& brush, VGMatrixMode mode, |
140 VGPaintType prevPaintType); |
139 VGPaintType prevPaintType); |
141 void setPenParams(const QPen& pen); |
140 void setPenParams(const QPen& pen); |
177 VGPath rectPath; // Cached path for quick drawing of rectangles. |
176 VGPath rectPath; // Cached path for quick drawing of rectangles. |
178 VGPath linePath; // Cached path for quick drawing of lines. |
177 VGPath linePath; // Cached path for quick drawing of lines. |
179 VGPath roundRectPath; // Cached path for quick drawing of rounded rects. |
178 VGPath roundRectPath; // Cached path for quick drawing of rounded rects. |
180 #endif |
179 #endif |
181 |
180 |
182 VGPath reusablePath; // Reusable path for vectorPathToVGPath(), etc. |
|
183 |
|
184 QTransform transform; // Currently active transform. |
181 QTransform transform; // Currently active transform. |
185 bool simpleTransform; // True if the transform is simple (non-projective). |
182 bool simpleTransform; // True if the transform is simple (non-projective). |
186 qreal penScale; // Pen scaling factor from "transform". |
183 qreal penScale; // Pen scaling factor from "transform". |
187 |
184 |
188 QTransform pathTransform; // Calculated VG path transformation. |
185 QTransform pathTransform; // Calculated VG path transformation. |
186 QTransform glyphTransform; // Calculated VG glyph transformation. |
|
189 QTransform imageTransform; // Calculated VG image transformation. |
187 QTransform imageTransform; // Calculated VG image transformation. |
190 bool pathTransformSet; // True if path transform set in the VG context. |
188 bool pathTransformSet; // True if path transform set in the VG context. |
191 |
189 |
192 bool maskValid; // True if vgMask() contains valid data. |
190 bool maskValid; // True if vgMask() contains valid data. |
193 bool maskIsSet; // True if mask would be fully set if it was valid. |
191 bool maskIsSet; // True if mask would be fully set if it was valid. |
350 #if !defined(QVG_NO_MODIFY_PATH) |
348 #if !defined(QVG_NO_MODIFY_PATH) |
351 rectPath = 0; |
349 rectPath = 0; |
352 linePath = 0; |
350 linePath = 0; |
353 roundRectPath = 0; |
351 roundRectPath = 0; |
354 #endif |
352 #endif |
355 |
|
356 reusablePath = 0; |
|
357 |
353 |
358 simpleTransform = true; |
354 simpleTransform = true; |
359 pathTransformSet = false; |
355 pathTransformSet = false; |
360 penScale = 1.0; |
356 penScale = 1.0; |
361 |
357 |
449 2, // segmentCapacityHint |
445 2, // segmentCapacityHint |
450 4, // coordCapacityHint |
446 4, // coordCapacityHint |
451 VG_PATH_CAPABILITY_ALL); |
447 VG_PATH_CAPABILITY_ALL); |
452 vgAppendPathData(linePath, 2, segments, coords); |
448 vgAppendPathData(linePath, 2, segments, coords); |
453 #endif |
449 #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); |
|
463 } |
450 } |
464 |
451 |
465 void QVGPaintEnginePrivate::destroy() |
452 void QVGPaintEnginePrivate::destroy() |
466 { |
453 { |
467 if (penPaint) |
454 if (penPaint) |
477 if (linePath) |
464 if (linePath) |
478 vgDestroyPath(linePath); |
465 vgDestroyPath(linePath); |
479 if (roundRectPath) |
466 if (roundRectPath) |
480 vgDestroyPath(roundRectPath); |
467 vgDestroyPath(roundRectPath); |
481 #endif |
468 #endif |
482 if (reusablePath) |
|
483 vgDestroyPath(reusablePath); |
|
484 |
469 |
485 #if !defined(QVG_NO_DRAW_GLYPHS) |
470 #if !defined(QVG_NO_DRAW_GLYPHS) |
486 QVGFontCache::Iterator it; |
471 QVGFontCache::Iterator it; |
487 for (it = fontCache.begin(); it != fontCache.end(); ++it) |
472 for (it = fontCache.begin(); it != fontCache.end(); ++it) |
488 delete it.value(); |
473 delete it.value(); |
514 |
499 |
515 extern bool qt_scaleForTransform(const QTransform &transform, qreal *scale); |
500 extern bool qt_scaleForTransform(const QTransform &transform, qreal *scale); |
516 |
501 |
517 void QVGPaintEnginePrivate::updateTransform(QPaintDevice *pdev) |
502 void QVGPaintEnginePrivate::updateTransform(QPaintDevice *pdev) |
518 { |
503 { |
519 VGfloat devh = pdev->height() - 1; |
504 VGfloat devh = pdev->height(); |
520 |
505 |
521 // Construct the VG transform by combining the Qt transform with |
506 // Construct the VG transform by combining the Qt transform with |
522 // the following viewport transformation: |
507 // the following viewport transformation: |
523 // | 1 0 0 | | 1 0 0.5 | | 1 0 0.5 | |
508 // | 1 0 0 | |
524 // | 0 -1 devh | * | 0 1 -0.5 | = | 0 -1 (0.5 + devh) | |
509 // | 0 -1 devh | |
525 // | 0 0 1 | | 0 0 1 | | 0 0 1 | |
510 // | 0 0 1 | |
511 // The glyph transform uses a slightly different transformation: |
|
512 // | 1 0 0 | | 1 0 0.5 | | 1 0 0.5 | |
|
513 // | 0 -1 devh - 1 | * | 0 1 -0.5 | = | 0 -1 (devh - 0.5) | |
|
514 // | 0 0 1 | | 0 0 1 | | 0 0 1 | |
|
526 // The full VG transform is effectively: |
515 // The full VG transform is effectively: |
527 // 1. Apply the user's transformation matrix. |
516 // 1. Apply the user's transformation matrix. |
528 // 2. Translate by (0.5, -0.5) to correct for Qt and VG putting |
517 // 2. Translate glyphs by an extra (0.5, -0.5). |
529 // the centre of the pixel at different positions. |
|
530 // 3. Flip the co-ordinate system upside down. |
518 // 3. Flip the co-ordinate system upside down. |
531 QTransform viewport(1.0f, 0.0f, 0.0f, |
519 QTransform viewport(1.0f, 0.0f, 0.0f, |
532 0.0f, -1.0f, 0.0f, |
520 0.0f, -1.0f, 0.0f, |
533 0.5f, devh + 0.5f, 1.0f); |
521 0.0f, devh, 1.0f); |
534 |
522 QTransform gviewport(1.0f, 0.0f, 0.0f, |
535 // Compute the path transform and determine if it is projective. |
523 0.0f, -1.0f, 0.0f, |
536 pathTransform = transform * viewport; |
524 0.5f, devh - 0.5f, 1.0f); |
537 bool projective = (pathTransform.m13() != 0.0f || |
525 |
538 pathTransform.m23() != 0.0f || |
526 // Compute the path transform and determine if it is projective. |
539 pathTransform.m33() != 1.0f); |
527 pathTransform = transform * viewport; |
540 |
528 glyphTransform = transform * gviewport; |
529 bool projective = (pathTransform.m13() != 0.0f || |
|
530 pathTransform.m23() != 0.0f || |
|
531 pathTransform.m33() != 1.0f); |
|
541 if (projective) { |
532 if (projective) { |
542 // The engine cannot do projective path transforms for us, |
533 // The engine cannot do projective path transforms for us, |
543 // so we will have to convert the co-ordinates ourselves. |
534 // so we will have to convert the co-ordinates ourselves. |
544 // Change the matrix to just the viewport transformation. |
535 // Change the matrix to just the viewport transformation. |
545 pathTransform = viewport; |
536 pathTransform = viewport; |
537 glyphTransform = gviewport; |
|
546 simpleTransform = false; |
538 simpleTransform = false; |
547 } else { |
539 } else { |
548 simpleTransform = true; |
540 simpleTransform = true; |
549 } |
541 } |
550 pathTransformSet = false; |
542 pathTransformSet = false; |
551 |
543 |
552 // The image transform is always the full transformation, |
544 // The image transform is always the full transformation, |
553 // because it can be projective. It also does not need the |
545 imageTransform = transform * viewport; |
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; |
|
560 |
546 |
561 // Calculate the scaling factor to use for turning cosmetic pens |
547 // Calculate the scaling factor to use for turning cosmetic pens |
562 // into ordinary non-cosmetic pens. |
548 // into ordinary non-cosmetic pens. |
563 qt_scaleForTransform(transform, &penScale); |
549 qt_scaleForTransform(transform, &penScale); |
564 } |
550 } |
565 |
551 |
566 inline void QVGPaintEnginePrivate::releasePath(VGPath path) |
552 VGPath QVGPaintEnginePrivate::vectorPathToVGPath(const QVectorPath& 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) |
|
575 { |
553 { |
576 int count = path.elementCount(); |
554 int count = path.elementCount(); |
577 const qreal *points = path.points(); |
555 const qreal *points = path.points(); |
578 const QPainterPath::ElementType *elements = path.elements(); |
556 const QPainterPath::ElementType *elements = path.elements(); |
579 |
557 |
580 VGPath vgpath; |
558 VGPath vgpath = vgCreatePath(VG_PATH_FORMAT_STANDARD, |
581 if (forceNewPath) { |
559 VG_PATH_DATATYPE_F, |
582 vgpath = vgCreatePath(VG_PATH_FORMAT_STANDARD, |
560 1.0f, // scale |
583 VG_PATH_DATATYPE_F, |
561 0.0f, // bias |
584 1.0f, // scale |
562 count + 1, // segmentCapacityHint |
585 0.0f, // bias |
563 count * 2, // coordCapacityHint |
586 count + 1, // segmentCapacityHint |
564 VG_PATH_CAPABILITY_ALL); |
587 count * 2, // coordCapacityHint |
|
588 VG_PATH_CAPABILITY_ALL); |
|
589 } else { |
|
590 vgpath = reusablePath; |
|
591 } |
|
592 |
565 |
593 // Size is sufficient segments for drawRoundedRect() paths. |
566 // Size is sufficient segments for drawRoundedRect() paths. |
594 QVarLengthArray<VGubyte, 20> segments; |
567 QVarLengthArray<VGubyte, 20> segments; |
595 |
568 |
596 if (sizeof(qreal) == sizeof(VGfloat) && elements && simpleTransform) { |
569 if (sizeof(qreal) == sizeof(VGfloat) && elements && simpleTransform) { |
758 segments.constData(), coords.constData()); |
731 segments.constData(), coords.constData()); |
759 |
732 |
760 return vgpath; |
733 return vgpath; |
761 } |
734 } |
762 |
735 |
763 VGPath QVGPaintEnginePrivate::painterPathToVGPath(const QPainterPath& path, bool forceNewPath) |
736 VGPath QVGPaintEnginePrivate::painterPathToVGPath(const QPainterPath& path) |
764 { |
737 { |
765 int count = path.elementCount(); |
738 int count = path.elementCount(); |
766 |
739 |
767 VGPath vgpath; |
740 VGPath vgpath = vgCreatePath(VG_PATH_FORMAT_STANDARD, |
768 if (forceNewPath) { |
741 VG_PATH_DATATYPE_F, |
769 vgpath = vgCreatePath(VG_PATH_FORMAT_STANDARD, |
742 1.0f, // scale |
770 VG_PATH_DATATYPE_F, |
743 0.0f, // bias |
771 1.0f, // scale |
744 count + 1, // segmentCapacityHint |
772 0.0f, // bias |
745 count * 2, // coordCapacityHint |
773 count + 1, // segmentCapacityHint |
746 VG_PATH_CAPABILITY_ALL); |
774 count * 2, // coordCapacityHint |
|
775 VG_PATH_CAPABILITY_ALL); |
|
776 } else { |
|
777 vgpath = reusablePath; |
|
778 } |
|
779 |
747 |
780 if (count == 0) |
748 if (count == 0) |
781 return vgpath; |
749 return vgpath; |
782 |
750 |
783 const QPainterPath::Element *elements = &(path.elementAt(0)); |
751 const QPainterPath::Element *elements = &(path.elementAt(0)); |
992 roundRectPath = vgpath; |
960 roundRectPath = vgpath; |
993 } else { |
961 } else { |
994 vgModifyPathCoords(vgpath, 0, 9, pts); |
962 vgModifyPathCoords(vgpath, 0, 9, pts); |
995 } |
963 } |
996 #else |
964 #else |
997 VGPath vgpath = reusablePath; |
965 VGPath vgpath = vgCreatePath(VG_PATH_FORMAT_STANDARD, |
966 VG_PATH_DATATYPE_F, |
|
967 1.0f, // scale |
|
968 0.0f, // bias |
|
969 10, // segmentCapacityHint |
|
970 17 * 2, // coordCapacityHint |
|
971 VG_PATH_CAPABILITY_ALL); |
|
998 vgAppendPathData(vgpath, 10, roundedrect_types, pts); |
972 vgAppendPathData(vgpath, 10, roundedrect_types, pts); |
999 #endif |
973 #endif |
1000 |
974 |
1001 return vgpath; |
975 return vgpath; |
1002 } |
976 } |
1548 VGPath vgpath = d->vectorPathToVGPath(path); |
1522 VGPath vgpath = d->vectorPathToVGPath(path); |
1549 if (!path.hasWindingFill()) |
1523 if (!path.hasWindingFill()) |
1550 d->draw(vgpath, s->pen, s->brush, VG_EVEN_ODD); |
1524 d->draw(vgpath, s->pen, s->brush, VG_EVEN_ODD); |
1551 else |
1525 else |
1552 d->draw(vgpath, s->pen, s->brush, VG_NON_ZERO); |
1526 d->draw(vgpath, s->pen, s->brush, VG_NON_ZERO); |
1553 d->releasePath(vgpath); |
1527 vgDestroyPath(vgpath); |
1554 } |
1528 } |
1555 |
1529 |
1556 void QVGPaintEngine::fill(const QVectorPath &path, const QBrush &brush) |
1530 void QVGPaintEngine::fill(const QVectorPath &path, const QBrush &brush) |
1557 { |
1531 { |
1558 Q_D(QVGPaintEngine); |
1532 Q_D(QVGPaintEngine); |
1559 VGPath vgpath = d->vectorPathToVGPath(path); |
1533 VGPath vgpath = d->vectorPathToVGPath(path); |
1560 if (!path.hasWindingFill()) |
1534 if (!path.hasWindingFill()) |
1561 d->fill(vgpath, brush, VG_EVEN_ODD); |
1535 d->fill(vgpath, brush, VG_EVEN_ODD); |
1562 else |
1536 else |
1563 d->fill(vgpath, brush, VG_NON_ZERO); |
1537 d->fill(vgpath, brush, VG_NON_ZERO); |
1564 d->releasePath(vgpath); |
1538 vgDestroyPath(vgpath); |
1565 } |
1539 } |
1566 |
1540 |
1567 void QVGPaintEngine::stroke(const QVectorPath &path, const QPen &pen) |
1541 void QVGPaintEngine::stroke(const QVectorPath &path, const QPen &pen) |
1568 { |
1542 { |
1569 Q_D(QVGPaintEngine); |
1543 Q_D(QVGPaintEngine); |
1570 VGPath vgpath = d->vectorPathToVGPath(path); |
1544 VGPath vgpath = d->vectorPathToVGPath(path); |
1571 d->stroke(vgpath, pen); |
1545 d->stroke(vgpath, pen); |
1572 d->releasePath(vgpath); |
1546 vgDestroyPath(vgpath); |
1573 } |
1547 } |
1574 |
1548 |
1575 // Determine if a co-ordinate transform is simple enough to allow |
1549 // Determine if a co-ordinate transform is simple enough to allow |
1576 // rectangle-based clipping with vgMask(). Simple transforms most |
1550 // rectangle-based clipping with vgMask(). Simple transforms most |
1577 // often result from origin translations. |
1551 // often result from origin translations. |
1763 vgRenderToMask(vgpath, VG_FILL_PATH, VG_INTERSECT_MASK); |
1737 vgRenderToMask(vgpath, VG_FILL_PATH, VG_INTERSECT_MASK); |
1764 break; |
1738 break; |
1765 |
1739 |
1766 default: break; |
1740 default: break; |
1767 } |
1741 } |
1768 d->releasePath(vgpath); |
1742 vgDestroyPath(vgpath); |
1769 |
1743 |
1770 vgSeti(VG_MASKING, VG_TRUE); |
1744 vgSeti(VG_MASKING, VG_TRUE); |
1771 d->maskValid = true; |
1745 d->maskValid = true; |
1772 d->maskIsSet = false; |
1746 d->maskIsSet = false; |
1773 d->scissorMask = false; |
1747 d->scissorMask = false; |
2080 vgRenderToMask(vgpath, VG_FILL_PATH, VG_INTERSECT_MASK); |
2054 vgRenderToMask(vgpath, VG_FILL_PATH, VG_INTERSECT_MASK); |
2081 break; |
2055 break; |
2082 |
2056 |
2083 default: break; |
2057 default: break; |
2084 } |
2058 } |
2085 d->releasePath(vgpath); |
2059 vgDestroyPath(vgpath); |
2086 |
2060 |
2087 vgSeti(VG_MASKING, VG_TRUE); |
2061 vgSeti(VG_MASKING, VG_TRUE); |
2088 d->maskValid = true; |
2062 d->maskValid = true; |
2089 d->maskIsSet = false; |
2063 d->maskIsSet = false; |
2090 d->scissorMask = false; |
2064 d->scissorMask = false; |
2094 } |
2068 } |
2095 |
2069 |
2096 void QVGPaintEnginePrivate::ensureMask |
2070 void QVGPaintEnginePrivate::ensureMask |
2097 (QVGPaintEngine *engine, int width, int height) |
2071 (QVGPaintEngine *engine, int width, int height) |
2098 { |
2072 { |
2099 scissorMask = false; |
2073 scissorMask = false; |
2100 if (maskIsSet) { |
2074 if (maskIsSet) { |
2101 vgMask(VG_INVALID_HANDLE, VG_FILL_MASK, 0, 0, width, height); |
2075 vgMask(VG_INVALID_HANDLE, VG_FILL_MASK, 0, 0, width, height); |
2102 maskRect = QRect(); |
2076 maskRect = QRect(); |
2103 } else { |
2077 } else { |
2104 vgMask(VG_INVALID_HANDLE, VG_CLEAR_MASK, 0, 0, width, height); |
2078 vgMask(VG_INVALID_HANDLE, VG_CLEAR_MASK, 0, 0, width, height); |
2520 if (d->simpleTransform) { |
2494 if (d->simpleTransform) { |
2521 QVGPainterState *s = state(); |
2495 QVGPainterState *s = state(); |
2522 VGPath vgpath = d->roundedRectPath(rect, xrad, yrad, mode); |
2496 VGPath vgpath = d->roundedRectPath(rect, xrad, yrad, mode); |
2523 d->draw(vgpath, s->pen, s->brush); |
2497 d->draw(vgpath, s->pen, s->brush); |
2524 #if defined(QVG_NO_MODIFY_PATH) |
2498 #if defined(QVG_NO_MODIFY_PATH) |
2525 d->releasePath(vgpath); |
2499 vgDestroyPath(vgpath); |
2526 #endif |
2500 #endif |
2527 } else { |
2501 } else { |
2528 QPaintEngineEx::drawRoundedRect(rect, xrad, yrad, mode); |
2502 QPaintEngineEx::drawRoundedRect(rect, xrad, yrad, mode); |
2529 } |
2503 } |
2530 } |
2504 } |
2669 // Based on the description of vguEllipse() in the OpenVG specification. |
2643 // Based on the description of vguEllipse() in the OpenVG specification. |
2670 // We don't use vguEllipse(), to avoid unnecessary library dependencies. |
2644 // We don't use vguEllipse(), to avoid unnecessary library dependencies. |
2671 Q_D(QVGPaintEngine); |
2645 Q_D(QVGPaintEngine); |
2672 if (d->simpleTransform) { |
2646 if (d->simpleTransform) { |
2673 QVGPainterState *s = state(); |
2647 QVGPainterState *s = state(); |
2674 VGPath path = d->reusablePath; |
2648 VGPath path = vgCreatePath(VG_PATH_FORMAT_STANDARD, |
2649 VG_PATH_DATATYPE_F, |
|
2650 1.0f, // scale |
|
2651 0.0f, // bias |
|
2652 4, // segmentCapacityHint |
|
2653 12, // coordCapacityHint |
|
2654 VG_PATH_CAPABILITY_ALL); |
|
2675 static VGubyte segments[4] = { |
2655 static VGubyte segments[4] = { |
2676 VG_MOVE_TO_ABS, |
2656 VG_MOVE_TO_ABS, |
2677 VG_SCCWARC_TO_REL, |
2657 VG_SCCWARC_TO_REL, |
2678 VG_SCCWARC_TO_REL, |
2658 VG_SCCWARC_TO_REL, |
2679 VG_CLOSE_PATH |
2659 VG_CLOSE_PATH |
2693 coords[9] = 0.0f; |
2673 coords[9] = 0.0f; |
2694 coords[10] = r.width(); |
2674 coords[10] = r.width(); |
2695 coords[11] = 0.0f; |
2675 coords[11] = 0.0f; |
2696 vgAppendPathData(path, 4, segments, coords); |
2676 vgAppendPathData(path, 4, segments, coords); |
2697 d->draw(path, s->pen, s->brush); |
2677 d->draw(path, s->pen, s->brush); |
2698 d->releasePath(path); |
2678 vgDestroyPath(path); |
2699 } else { |
2679 } else { |
2700 // The projective transform version of an ellipse is difficult. |
2680 // The projective transform version of an ellipse is difficult. |
2701 // Generate a QVectorPath containing cubic curves and transform that. |
2681 // Generate a QVectorPath containing cubic curves and transform that. |
2702 QPaintEngineEx::drawEllipse(r); |
2682 QPaintEngineEx::drawEllipse(r); |
2703 } |
2683 } |
2717 VGPath vgpath = d->painterPathToVGPath(path); |
2697 VGPath vgpath = d->painterPathToVGPath(path); |
2718 if (path.fillRule() == Qt::OddEvenFill) |
2698 if (path.fillRule() == Qt::OddEvenFill) |
2719 d->draw(vgpath, s->pen, s->brush, VG_EVEN_ODD); |
2699 d->draw(vgpath, s->pen, s->brush, VG_EVEN_ODD); |
2720 else |
2700 else |
2721 d->draw(vgpath, s->pen, s->brush, VG_NON_ZERO); |
2701 d->draw(vgpath, s->pen, s->brush, VG_NON_ZERO); |
2722 d->releasePath(vgpath); |
2702 vgDestroyPath(vgpath); |
2723 } |
2703 } |
2724 |
2704 |
2725 void QVGPaintEngine::drawPoints(const QPointF *points, int pointCount) |
2705 void QVGPaintEngine::drawPoints(const QPointF *points, int pointCount) |
2726 { |
2706 { |
2727 #if !defined(QVG_NO_MODIFY_PATH) |
2707 #if !defined(QVG_NO_MODIFY_PATH) |
2792 |
2772 |
2793 void QVGPaintEngine::drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode) |
2773 void QVGPaintEngine::drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode) |
2794 { |
2774 { |
2795 Q_D(QVGPaintEngine); |
2775 Q_D(QVGPaintEngine); |
2796 QVGPainterState *s = state(); |
2776 QVGPainterState *s = state(); |
2797 VGPath path = d->reusablePath; |
2777 VGPath path = vgCreatePath(VG_PATH_FORMAT_STANDARD, |
2778 VG_PATH_DATATYPE_F, |
|
2779 1.0f, // scale |
|
2780 0.0f, // bias |
|
2781 pointCount + 1, // segmentCapacityHint |
|
2782 pointCount * 2, // coordCapacityHint |
|
2783 VG_PATH_CAPABILITY_ALL); |
|
2798 QVarLengthArray<VGfloat, 16> coords; |
2784 QVarLengthArray<VGfloat, 16> coords; |
2799 QVarLengthArray<VGubyte, 10> segments; |
2785 QVarLengthArray<VGubyte, 10> segments; |
2800 for (int i = 0; i < pointCount; ++i, ++points) { |
2786 for (int i = 0; i < pointCount; ++i, ++points) { |
2801 if (d->simpleTransform) { |
2787 if (d->simpleTransform) { |
2802 coords.append(points->x()); |
2788 coords.append(points->x()); |
2826 |
2812 |
2827 default: |
2813 default: |
2828 d->draw(path, s->pen, s->brush, VG_EVEN_ODD); |
2814 d->draw(path, s->pen, s->brush, VG_EVEN_ODD); |
2829 break; |
2815 break; |
2830 } |
2816 } |
2831 d->releasePath(path); |
2817 vgDestroyPath(path); |
2832 } |
2818 } |
2833 |
2819 |
2834 void QVGPaintEngine::drawPolygon(const QPoint *points, int pointCount, PolygonDrawMode mode) |
2820 void QVGPaintEngine::drawPolygon(const QPoint *points, int pointCount, PolygonDrawMode mode) |
2835 { |
2821 { |
2836 Q_D(QVGPaintEngine); |
2822 Q_D(QVGPaintEngine); |
2837 QVGPainterState *s = state(); |
2823 QVGPainterState *s = state(); |
2838 VGPath path = d->reusablePath; |
2824 VGPath path = vgCreatePath(VG_PATH_FORMAT_STANDARD, |
2825 VG_PATH_DATATYPE_F, |
|
2826 1.0f, // scale |
|
2827 0.0f, // bias |
|
2828 pointCount + 1, // segmentCapacityHint |
|
2829 pointCount * 2, // coordCapacityHint |
|
2830 VG_PATH_CAPABILITY_ALL); |
|
2839 QVarLengthArray<VGfloat, 16> coords; |
2831 QVarLengthArray<VGfloat, 16> coords; |
2840 QVarLengthArray<VGubyte, 10> segments; |
2832 QVarLengthArray<VGubyte, 10> segments; |
2841 for (int i = 0; i < pointCount; ++i, ++points) { |
2833 for (int i = 0; i < pointCount; ++i, ++points) { |
2842 if (d->simpleTransform) { |
2834 if (d->simpleTransform) { |
2843 coords.append(points->x()); |
2835 coords.append(points->x()); |
2867 |
2859 |
2868 default: |
2860 default: |
2869 d->draw(path, s->pen, s->brush, VG_EVEN_ODD); |
2861 d->draw(path, s->pen, s->brush, VG_EVEN_ODD); |
2870 break; |
2862 break; |
2871 } |
2863 } |
2872 d->releasePath(path); |
2864 vgDestroyPath(path); |
2873 } |
2865 } |
2874 |
2866 |
2875 void QVGPaintEnginePrivate::setImageOptions() |
2867 void QVGPaintEnginePrivate::setImageOptions() |
2876 { |
2868 { |
2877 if (opacity != 1.0f && simpleTransform) { |
2869 if (opacity != 1.0f && simpleTransform) { |
3266 // Calculate the path for the glyph and cache it. |
3258 // Calculate the path for the glyph and cache it. |
3267 QPainterPath path; |
3259 QPainterPath path; |
3268 ti.fontEngine->getUnscaledGlyph(glyph, &path, &metrics); |
3260 ti.fontEngine->getUnscaledGlyph(glyph, &path, &metrics); |
3269 VGPath vgPath; |
3261 VGPath vgPath; |
3270 if (!path.isEmpty()) { |
3262 if (!path.isEmpty()) { |
3271 vgPath = d->painterPathToVGPath(path, true); |
3263 vgPath = d->painterPathToVGPath(path); |
3272 } else { |
3264 } else { |
3273 // Probably a "space" character with no visible outline. |
3265 // Probably a "space" character with no visible outline. |
3274 vgPath = VG_INVALID_HANDLE; |
3266 vgPath = VG_INVALID_HANDLE; |
3275 } |
3267 } |
3276 origin[0] = 0; |
3268 origin[0] = 0; |
3326 QObject::connect(ti.fontEngine, SIGNAL(destroyed()), |
3318 QObject::connect(ti.fontEngine, SIGNAL(destroyed()), |
3327 d->fontEngineCleaner, SLOT(fontEngineDestroyed())); |
3319 d->fontEngineCleaner, SLOT(fontEngineDestroyed())); |
3328 } |
3320 } |
3329 |
3321 |
3330 // Set the transformation to use for drawing the current glyphs. |
3322 // Set the transformation to use for drawing the current glyphs. |
3331 QTransform glyphTransform(d->pathTransform); |
3323 QTransform glyphTransform(d->glyphTransform); |
3332 glyphTransform.translate(p.x(), p.y()); |
3324 glyphTransform.translate(p.x(), p.y()); |
3333 #if defined(QVG_NO_IMAGE_GLYPHS) |
3325 #if defined(QVG_NO_IMAGE_GLYPHS) |
3334 glyphTransform.scale(glyphCache->scaleX, glyphCache->scaleY); |
3326 glyphTransform.scale(glyphCache->scaleX, glyphCache->scaleY); |
3335 #endif |
3327 #endif |
3336 d->setTransform(VG_MATRIX_GLYPH_USER_TO_SURFACE, glyphTransform); |
3328 d->setTransform(VG_MATRIX_GLYPH_USER_TO_SURFACE, glyphTransform); |
3659 } |
3651 } |
3660 } |
3652 } |
3661 |
3653 |
3662 } else { |
3654 } else { |
3663 // Set the path transform to the default viewport transformation. |
3655 // Set the path transform to the default viewport transformation. |
3664 VGfloat devh = screenSize.height() - 1; |
3656 VGfloat devh = screenSize.height(); |
3665 QTransform viewport(1.0f, 0.0f, 0.0f, |
3657 QTransform viewport(1.0f, 0.0f, 0.0f, |
3666 0.0f, -1.0f, 0.0f, |
3658 0.0f, -1.0f, 0.0f, |
3667 -0.5f, devh + 0.5f, 1.0f); |
3659 0.0f, devh, 1.0f); |
3668 d->setTransform(VG_MATRIX_PATH_USER_TO_SURFACE, viewport); |
3660 d->setTransform(VG_MATRIX_PATH_USER_TO_SURFACE, viewport); |
3669 |
3661 |
3670 // Set the brush to use to fill the background. |
3662 // Set the brush to use to fill the background. |
3671 d->ensureBrush(brush); |
3663 d->ensureBrush(brush); |
3672 d->setFillRule(VG_EVEN_ODD); |
3664 d->setFillRule(VG_EVEN_ODD); |
3698 if (vgpd->isValid()) |
3690 if (vgpd->isValid()) |
3699 vgImage = vgpd->toVGImage(); |
3691 vgImage = vgpd->toVGImage(); |
3700 } |
3692 } |
3701 |
3693 |
3702 // Set the image transformation and modes. |
3694 // Set the image transformation and modes. |
3703 VGfloat devh = screenSize.height() - 1; |
3695 VGfloat devh = screenSize.height(); |
3704 QTransform transform(1.0f, 0.0f, 0.0f, |
3696 QTransform transform(1.0f, 0.0f, 0.0f, |
3705 0.0f, -1.0f, 0.0f, |
3697 0.0f, -1.0f, 0.0f, |
3706 -0.5f, devh + 0.5f, 1.0f); |
3698 0.0f, devh, 1.0f); |
3707 transform.translate(offset.x(), offset.y()); |
3699 transform.translate(offset.x(), offset.y()); |
3708 d->setTransform(VG_MATRIX_IMAGE_USER_TO_SURFACE, transform); |
3700 d->setTransform(VG_MATRIX_IMAGE_USER_TO_SURFACE, transform); |
3709 d->setImageMode(VG_DRAW_IMAGE_NORMAL); |
3701 d->setImageMode(VG_DRAW_IMAGE_NORMAL); |
3710 |
3702 |
3711 // Draw the VGImage. |
3703 // Draw the VGImage. |