src/openvg/qpaintengine_vg.cpp
branchRCL_3
changeset 7 3f74d0d4af4c
parent 4 3b1da2848fc7
child 13 c0432d11811c
equal deleted inserted replaced
6:dee5afe5301f 7:3f74d0d4af4c
   181     QTransform transform;   // Currently active transform.
   181     QTransform transform;   // Currently active transform.
   182     bool simpleTransform;   // True if the transform is simple (non-projective).
   182     bool simpleTransform;   // True if the transform is simple (non-projective).
   183     qreal penScale;         // Pen scaling factor from "transform".
   183     qreal penScale;         // Pen scaling factor from "transform".
   184 
   184 
   185     QTransform pathTransform;  // Calculated VG path transformation.
   185     QTransform pathTransform;  // Calculated VG path transformation.
       
   186     QTransform glyphTransform; // Calculated VG glyph transformation.
   186     QTransform imageTransform; // Calculated VG image transformation.
   187     QTransform imageTransform; // Calculated VG image transformation.
   187     bool pathTransformSet;  // True if path transform set in the VG context.
   188     bool pathTransformSet;  // True if path transform set in the VG context.
   188 
   189 
   189     bool maskValid;         // True if vgMask() contains valid data.
   190     bool maskValid;         // True if vgMask() contains valid data.
   190     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.
       
   192     bool scissorMask;       // True if scissor is used in place of the mask.
   191     bool rawVG;             // True if processing a raw VG escape.
   193     bool rawVG;             // True if processing a raw VG escape.
   192 
   194 
   193     QRect maskRect;         // Rectangle version of mask if it is simple.
   195     QRect maskRect;         // Rectangle version of mask if it is simple.
   194 
   196 
   195     QTransform penTransform;   // Transform for the pen.
   197     QTransform penTransform;   // Transform for the pen.
   353     pathTransformSet = false;
   355     pathTransformSet = false;
   354     penScale = 1.0;
   356     penScale = 1.0;
   355 
   357 
   356     maskValid = false;
   358     maskValid = false;
   357     maskIsSet = false;
   359     maskIsSet = false;
       
   360     scissorMask = false;
   358     rawVG = false;
   361     rawVG = false;
   359 
   362 
   360     scissorActive = false;
   363     scissorActive = false;
   361     scissorDirty = false;
   364     scissorDirty = false;
   362 
   365 
   496 
   499 
   497 extern bool qt_scaleForTransform(const QTransform &transform, qreal *scale);
   500 extern bool qt_scaleForTransform(const QTransform &transform, qreal *scale);
   498 
   501 
   499 void QVGPaintEnginePrivate::updateTransform(QPaintDevice *pdev)
   502 void QVGPaintEnginePrivate::updateTransform(QPaintDevice *pdev)
   500 {
   503 {
   501     VGfloat devh = pdev->height() - 1;
   504     VGfloat devh = pdev->height();
   502 
   505 
   503     // Construct the VG transform by combining the Qt transform with
   506     // Construct the VG transform by combining the Qt transform with
   504     // the following viewport transformation:
   507     // the following viewport transformation:
   505     //        | 1  0  0   |   | 1 0  0.5 |   | 1  0     0.5      |
   508     //        | 1  0  0   |
   506     //        | 0 -1 devh | * | 0 1 -0.5 | = | 0 -1 (0.5 + devh) |
   509     //        | 0 -1 devh |
   507     //        | 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       |
   508     // The full VG transform is effectively:
   515     // The full VG transform is effectively:
   509     //      1. Apply the user's transformation matrix.
   516     //      1. Apply the user's transformation matrix.
   510     //      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).
   511     //         the centre of the pixel at different positions.
       
   512     //      3. Flip the co-ordinate system upside down.
   518     //      3. Flip the co-ordinate system upside down.
   513     QTransform viewport(1.0f, 0.0f, 0.0f,
   519     QTransform viewport(1.0f, 0.0f, 0.0f,
   514                         0.0f, -1.0f, 0.0f,
   520                         0.0f, -1.0f, 0.0f,
   515                         0.5f, devh + 0.5f, 1.0f);
   521                         0.0f, devh, 1.0f);
   516 
   522     QTransform gviewport(1.0f, 0.0f, 0.0f,
   517     // The image transform is always the full transformation,
   523                         0.0f, -1.0f, 0.0f,
   518     // because it can be projective.
   524                         0.5f, devh - 0.5f, 1.0f);
   519     imageTransform = transform * viewport;
   525 
   520 
   526     // Compute the path transform and determine if it is projective.
   521     // Determine if the transformation is projective.
   527     pathTransform = transform * viewport;
   522     bool projective = (imageTransform.m13() != 0.0f ||
   528     glyphTransform = transform * gviewport;
   523                        imageTransform.m23() != 0.0f ||
   529     bool projective = (pathTransform.m13() != 0.0f ||
   524                        imageTransform.m33() != 1.0f);
   530                        pathTransform.m23() != 0.0f ||
       
   531                        pathTransform.m33() != 1.0f);
   525     if (projective) {
   532     if (projective) {
   526         // The engine cannot do projective path transforms for us,
   533         // The engine cannot do projective path transforms for us,
   527         // so we will have to convert the co-ordinates ourselves.
   534         // so we will have to convert the co-ordinates ourselves.
   528         // Change the matrix to just the viewport transformation.
   535         // Change the matrix to just the viewport transformation.
   529         pathTransform = viewport;
   536         pathTransform = viewport;
       
   537         glyphTransform = gviewport;
   530         simpleTransform = false;
   538         simpleTransform = false;
   531     } else {
   539     } else {
   532         pathTransform = imageTransform;
       
   533         simpleTransform = true;
   540         simpleTransform = true;
   534     }
   541     }
   535     pathTransformSet = false;
   542     pathTransformSet = false;
       
   543 
       
   544     // The image transform is always the full transformation,
       
   545     imageTransform = transform * viewport;
   536 
   546 
   537     // Calculate the scaling factor to use for turning cosmetic pens
   547     // Calculate the scaling factor to use for turning cosmetic pens
   538     // into ordinary non-cosmetic pens.
   548     // into ordinary non-cosmetic pens.
   539     qt_scaleForTransform(transform, &penScale);
   549     qt_scaleForTransform(transform, &penScale);
   540 }
   550 }
  1540 // rectangle-based clipping with vgMask().  Simple transforms most
  1550 // rectangle-based clipping with vgMask().  Simple transforms most
  1541 // often result from origin translations.
  1551 // often result from origin translations.
  1542 static inline bool clipTransformIsSimple(const QTransform& transform)
  1552 static inline bool clipTransformIsSimple(const QTransform& transform)
  1543 {
  1553 {
  1544     QTransform::TransformationType type = transform.type();
  1554     QTransform::TransformationType type = transform.type();
  1545     return (type == QTransform::TxNone || type == QTransform::TxTranslate);
  1555     if (type == QTransform::TxNone || type == QTransform::TxTranslate)
       
  1556         return true;
       
  1557     if (type == QTransform::TxRotate) {
       
  1558         // Check for 0, 90, 180, and 270 degree rotations.
       
  1559         // (0 might happen after 4 rotations of 90 degrees).
       
  1560         qreal m11 = transform.m11();
       
  1561         qreal m12 = transform.m12();
       
  1562         qreal m21 = transform.m21();
       
  1563         qreal m22 = transform.m22();
       
  1564         if (m11 == 0.0f && m22 == 0.0f) {
       
  1565             if (m12 == 1.0f && m21 == -1.0f)
       
  1566                 return true;    // 90 degrees.
       
  1567             else if (m12 == -1.0f && m21 == 1.0f)
       
  1568                 return true;    // 270 degrees.
       
  1569         } else if (m12 == 0.0f && m21 == 0.0f) {
       
  1570             if (m11 == -1.0f && m22 == -1.0f)
       
  1571                 return true;    // 180 degrees.
       
  1572             else if (m11 == 1.0f && m22 == 1.0f)
       
  1573                 return true;    // 0 degrees.
       
  1574         }
       
  1575     }
       
  1576     return false;
  1546 }
  1577 }
  1547 
  1578 
  1548 #if defined(QVG_SCISSOR_CLIP)
  1579 #if defined(QVG_SCISSOR_CLIP)
  1549 
  1580 
  1550 void QVGPaintEngine::clip(const QVectorPath &path, Qt::ClipOperation op)
  1581 void QVGPaintEngine::clip(const QVectorPath &path, Qt::ClipOperation op)
  1662     d->dirty |= QPaintEngine::DirtyClipRegion;
  1693     d->dirty |= QPaintEngine::DirtyClipRegion;
  1663 
  1694 
  1664     if (op == Qt::NoClip) {
  1695     if (op == Qt::NoClip) {
  1665         d->maskValid = false;
  1696         d->maskValid = false;
  1666         d->maskIsSet = true;
  1697         d->maskIsSet = true;
       
  1698         d->scissorMask = false;
  1667         d->maskRect = QRect();
  1699         d->maskRect = QRect();
  1668         vgSeti(VG_MASKING, VG_FALSE);
  1700         vgSeti(VG_MASKING, VG_FALSE);
  1669         return;
  1701         return;
  1670     }
  1702     }
  1671 
  1703 
  1672 #if defined(QVG_NO_RENDER_TO_MASK)
       
  1673     // We don't have vgRenderToMask(), so handle simple QRectF's only.
  1704     // We don't have vgRenderToMask(), so handle simple QRectF's only.
  1674     if (path.shape() == QVectorPath::RectangleHint &&
  1705     if (path.shape() == QVectorPath::RectangleHint &&
  1675             path.elementCount() == 4 && clipTransformIsSimple(d->transform)) {
  1706             path.elementCount() == 4 && clipTransformIsSimple(d->transform)) {
  1676         // Clipping region that resulted from QPainter::setClipRect(QRectF).
  1707         // Clipping region that resulted from QPainter::setClipRect(QRectF).
  1677         // Convert it into a QRect and apply.
  1708         // Convert it into a QRect and apply.
  1678         const qreal *points = path.points();
  1709         const qreal *points = path.points();
  1679         QRectF rect(points[0], points[1], points[2] - points[0],
  1710         QRectF rect(points[0], points[1], points[2] - points[0],
  1680                     points[5] - points[1]);
  1711                     points[5] - points[1]);
  1681         clip(rect.toRect(), op);
  1712         clip(rect.toRect(), op);
  1682     }
  1713         return;
  1683 #else
  1714     }
       
  1715 
       
  1716 #if !defined(QVG_NO_RENDER_TO_MASK)
  1684     QPaintDevice *pdev = paintDevice();
  1717     QPaintDevice *pdev = paintDevice();
  1685     int width = pdev->width();
  1718     int width = pdev->width();
  1686     int height = pdev->height();
  1719     int height = pdev->height();
  1687 
  1720 
  1688     if (op == Qt::ReplaceClip) {
  1721     if (op == Qt::ReplaceClip) {
  1709     vgDestroyPath(vgpath);
  1742     vgDestroyPath(vgpath);
  1710 
  1743 
  1711     vgSeti(VG_MASKING, VG_TRUE);
  1744     vgSeti(VG_MASKING, VG_TRUE);
  1712     d->maskValid = true;
  1745     d->maskValid = true;
  1713     d->maskIsSet = false;
  1746     d->maskIsSet = false;
       
  1747     d->scissorMask = false;
  1714 #endif
  1748 #endif
  1715 }
  1749 }
  1716 
  1750 
  1717 void QVGPaintEngine::clip(const QRect &rect, Qt::ClipOperation op)
  1751 void QVGPaintEngine::clip(const QRect &rect, Qt::ClipOperation op)
  1718 {
  1752 {
  1729     switch (op) {
  1763     switch (op) {
  1730         case Qt::NoClip:
  1764         case Qt::NoClip:
  1731         {
  1765         {
  1732             d->maskValid = false;
  1766             d->maskValid = false;
  1733             d->maskIsSet = true;
  1767             d->maskIsSet = true;
       
  1768             d->scissorMask = false;
  1734             d->maskRect = QRect();
  1769             d->maskRect = QRect();
  1735             vgSeti(VG_MASKING, VG_FALSE);
  1770             vgSeti(VG_MASKING, VG_FALSE);
  1736         }
  1771         }
  1737         break;
  1772         break;
  1738 
  1773 
  1744                 // same as turning off clipping.
  1779                 // same as turning off clipping.
  1745                 if (d->maskValid)
  1780                 if (d->maskValid)
  1746                     vgSeti(VG_MASKING, VG_FALSE);
  1781                     vgSeti(VG_MASKING, VG_FALSE);
  1747                 d->maskValid = false;
  1782                 d->maskValid = false;
  1748                 d->maskIsSet = true;
  1783                 d->maskIsSet = true;
       
  1784                 d->scissorMask = false;
  1749                 d->maskRect = QRect();
  1785                 d->maskRect = QRect();
  1750             } else {
  1786             } else {
  1751                 // Special case: if the intersection of the system
  1787                 // Special case: if the intersection of the system
  1752                 // clip and "r" is a single rectangle, then use the
  1788                 // clip and "r" is a single rectangle, then use the
  1753                 // scissor for clipping.  We try to avoid allocating a
  1789                 // scissor for clipping.  We try to avoid allocating a
  1761                 } else {
  1797                 } else {
  1762                     clip = clip.intersect(r);
  1798                     clip = clip.intersect(r);
  1763                     if (clip.rectCount() != 1) {
  1799                     if (clip.rectCount() != 1) {
  1764                         d->maskValid = false;
  1800                         d->maskValid = false;
  1765                         d->maskIsSet = false;
  1801                         d->maskIsSet = false;
       
  1802                         d->scissorMask = false;
  1766                         d->maskRect = QRect();
  1803                         d->maskRect = QRect();
  1767                         d->modifyMask(this, VG_FILL_MASK, r);
  1804                         d->modifyMask(this, VG_FILL_MASK, r);
  1768                         break;
  1805                         break;
  1769                     }
  1806                     }
  1770                     clipRect = clip.boundingRect();
  1807                     clipRect = clip.boundingRect();
  1771                 }
  1808                 }
  1772                 d->maskValid = false;
  1809                 d->maskValid = false;
  1773                 d->maskIsSet = false;
  1810                 d->maskIsSet = false;
       
  1811                 d->scissorMask = true;
  1774                 d->maskRect = clipRect;
  1812                 d->maskRect = clipRect;
  1775                 vgSeti(VG_MASKING, VG_FALSE);
  1813                 vgSeti(VG_MASKING, VG_FALSE);
  1776                 updateScissor();
  1814                 updateScissor();
  1777             }
  1815             }
  1778         }
  1816         }
  1779         break;
  1817         break;
  1780 
  1818 
  1781         case Qt::IntersectClip:
  1819         case Qt::IntersectClip:
  1782         {
  1820         {
  1783             QRect r = d->transform.mapRect(rect);
  1821             QRect r = d->transform.mapRect(rect);
  1784             if (d->maskIsSet && isDefaultClipRect(r)) {
  1822             if (!d->maskValid) {
       
  1823                 // Mask has not been used yet, so intersect with
       
  1824                 // the previous scissor-based region in maskRect.
       
  1825                 if (d->scissorMask)
       
  1826                     r = r.intersect(d->maskRect);
       
  1827                 if (isDefaultClipRect(r)) {
       
  1828                     // The clip is the full window, so turn off clipping.
       
  1829                     d->maskIsSet = true;
       
  1830                     d->maskRect = QRect();
       
  1831                 } else {
       
  1832                     // Activate the scissor on a smaller maskRect.
       
  1833                     d->maskIsSet = false;
       
  1834                     d->maskRect = r;
       
  1835                 }
       
  1836                 d->scissorMask = true;
       
  1837                 updateScissor();
       
  1838             } else if (d->maskIsSet && isDefaultClipRect(r)) {
  1785                 // Intersecting a full-window clip with a full-window
  1839                 // Intersecting a full-window clip with a full-window
  1786                 // region is the same as turning off clipping.
  1840                 // region is the same as turning off clipping.
  1787                 if (d->maskValid)
  1841                 if (d->maskValid)
  1788                     vgSeti(VG_MASKING, VG_FALSE);
  1842                     vgSeti(VG_MASKING, VG_FALSE);
  1789                 d->maskValid = false;
  1843                 d->maskValid = false;
  1790                 d->maskIsSet = true;
  1844                 d->maskIsSet = true;
       
  1845                 d->scissorMask = false;
  1791                 d->maskRect = QRect();
  1846                 d->maskRect = QRect();
  1792             } else {
  1847             } else {
  1793                 d->modifyMask(this, VG_INTERSECT_MASK, r);
  1848                 d->modifyMask(this, VG_INTERSECT_MASK, r);
  1794             }
  1849             }
  1795         }
  1850         }
  1827     switch (op) {
  1882     switch (op) {
  1828         case Qt::NoClip:
  1883         case Qt::NoClip:
  1829         {
  1884         {
  1830             d->maskValid = false;
  1885             d->maskValid = false;
  1831             d->maskIsSet = true;
  1886             d->maskIsSet = true;
       
  1887             d->scissorMask = false;
  1832             d->maskRect = QRect();
  1888             d->maskRect = QRect();
  1833             vgSeti(VG_MASKING, VG_FALSE);
  1889             vgSeti(VG_MASKING, VG_FALSE);
  1834         }
  1890         }
  1835         break;
  1891         break;
  1836 
  1892 
  1842                 // same as turning off clipping.
  1898                 // same as turning off clipping.
  1843                 if (d->maskValid)
  1899                 if (d->maskValid)
  1844                     vgSeti(VG_MASKING, VG_FALSE);
  1900                     vgSeti(VG_MASKING, VG_FALSE);
  1845                 d->maskValid = false;
  1901                 d->maskValid = false;
  1846                 d->maskIsSet = true;
  1902                 d->maskIsSet = true;
       
  1903                 d->scissorMask = false;
  1847                 d->maskRect = QRect();
  1904                 d->maskRect = QRect();
  1848             } else {
  1905             } else {
  1849                 // Special case: if the intersection of the system
  1906                 // Special case: if the intersection of the system
  1850                 // clip and the region is a single rectangle, then
  1907                 // clip and the region is a single rectangle, then
  1851                 // use the scissor for clipping.
  1908                 // use the scissor for clipping.
  1855                 else
  1912                 else
  1856                     clip = clip.intersect(r);
  1913                     clip = clip.intersect(r);
  1857                 if (clip.rectCount() == 1) {
  1914                 if (clip.rectCount() == 1) {
  1858                     d->maskValid = false;
  1915                     d->maskValid = false;
  1859                     d->maskIsSet = false;
  1916                     d->maskIsSet = false;
       
  1917                     d->scissorMask = true;
  1860                     d->maskRect = clip.boundingRect();
  1918                     d->maskRect = clip.boundingRect();
  1861                     vgSeti(VG_MASKING, VG_FALSE);
  1919                     vgSeti(VG_MASKING, VG_FALSE);
  1862                     updateScissor();
  1920                     updateScissor();
  1863                 } else {
  1921                 } else {
  1864                     d->maskValid = false;
  1922                     d->maskValid = false;
  1865                     d->maskIsSet = false;
  1923                     d->maskIsSet = false;
       
  1924                     d->scissorMask = false;
  1866                     d->maskRect = QRect();
  1925                     d->maskRect = QRect();
  1867                     d->modifyMask(this, VG_FILL_MASK, r);
  1926                     d->modifyMask(this, VG_FILL_MASK, r);
  1868                 }
  1927                 }
  1869             }
  1928             }
  1870         }
  1929         }
  1885                 // region is the same as turning off clipping.
  1944                 // region is the same as turning off clipping.
  1886                 if (d->maskValid)
  1945                 if (d->maskValid)
  1887                     vgSeti(VG_MASKING, VG_FALSE);
  1946                     vgSeti(VG_MASKING, VG_FALSE);
  1888                 d->maskValid = false;
  1947                 d->maskValid = false;
  1889                 d->maskIsSet = true;
  1948                 d->maskIsSet = true;
       
  1949                 d->scissorMask = false;
  1890                 d->maskRect = QRect();
  1950                 d->maskRect = QRect();
  1891             } else {
  1951             } else {
  1892                 d->modifyMask(this, VG_INTERSECT_MASK, r);
  1952                 d->modifyMask(this, VG_INTERSECT_MASK, r);
  1893             }
  1953             }
  1894         }
  1954         }
  1963     d->dirty |= QPaintEngine::DirtyClipRegion;
  2023     d->dirty |= QPaintEngine::DirtyClipRegion;
  1964 
  2024 
  1965     if (op == Qt::NoClip) {
  2025     if (op == Qt::NoClip) {
  1966         d->maskValid = false;
  2026         d->maskValid = false;
  1967         d->maskIsSet = true;
  2027         d->maskIsSet = true;
       
  2028         d->scissorMask = false;
  1968         d->maskRect = QRect();
  2029         d->maskRect = QRect();
  1969         vgSeti(VG_MASKING, VG_FALSE);
  2030         vgSeti(VG_MASKING, VG_FALSE);
  1970         return;
  2031         return;
  1971     }
  2032     }
  1972 
  2033 
  1998     vgDestroyPath(vgpath);
  2059     vgDestroyPath(vgpath);
  1999 
  2060 
  2000     vgSeti(VG_MASKING, VG_TRUE);
  2061     vgSeti(VG_MASKING, VG_TRUE);
  2001     d->maskValid = true;
  2062     d->maskValid = true;
  2002     d->maskIsSet = false;
  2063     d->maskIsSet = false;
       
  2064     d->scissorMask = false;
  2003 #else
  2065 #else
  2004     QPaintEngineEx::clip(path, op);
  2066     QPaintEngineEx::clip(path, op);
  2005 #endif
  2067 #endif
  2006 }
  2068 }
  2007 
  2069 
  2008 void QVGPaintEnginePrivate::ensureMask
  2070 void QVGPaintEnginePrivate::ensureMask
  2009         (QVGPaintEngine *engine, int width, int height)
  2071         (QVGPaintEngine *engine, int width, int height)
  2010 {
  2072 {
       
  2073     scissorMask = false;
  2011     if (maskIsSet) {
  2074     if (maskIsSet) {
  2012         vgMask(VG_INVALID_HANDLE, VG_FILL_MASK, 0, 0, width, height);
  2075         vgMask(VG_INVALID_HANDLE, VG_FILL_MASK, 0, 0, width, height);
  2013         maskRect = QRect();
  2076         maskRect = QRect();
  2014     } else {
  2077     } else {
  2015         vgMask(VG_INVALID_HANDLE, VG_CLEAR_MASK, 0, 0, width, height);
  2078         vgMask(VG_INVALID_HANDLE, VG_CLEAR_MASK, 0, 0, width, height);
  2041     }
  2104     }
  2042 
  2105 
  2043     vgSeti(VG_MASKING, VG_TRUE);
  2106     vgSeti(VG_MASKING, VG_TRUE);
  2044     maskValid = true;
  2107     maskValid = true;
  2045     maskIsSet = false;
  2108     maskIsSet = false;
       
  2109     scissorMask = false;
  2046 }
  2110 }
  2047 
  2111 
  2048 void QVGPaintEnginePrivate::modifyMask
  2112 void QVGPaintEnginePrivate::modifyMask
  2049         (QVGPaintEngine *engine, VGMaskOperation op, const QRect& rect)
  2113         (QVGPaintEngine *engine, VGMaskOperation op, const QRect& rect)
  2050 {
  2114 {
  2062     }
  2126     }
  2063 
  2127 
  2064     vgSeti(VG_MASKING, VG_TRUE);
  2128     vgSeti(VG_MASKING, VG_TRUE);
  2065     maskValid = true;
  2129     maskValid = true;
  2066     maskIsSet = false;
  2130     maskIsSet = false;
       
  2131     scissorMask = false;
  2067 }
  2132 }
  2068 
  2133 
  2069 #endif // !QVG_SCISSOR_CLIP
  2134 #endif // !QVG_SCISSOR_CLIP
  2070 
  2135 
  2071 void QVGPaintEngine::updateScissor()
  2136 void QVGPaintEngine::updateScissor()
  2094     } else
  2159     } else
  2095 #endif
  2160 #endif
  2096     {
  2161     {
  2097 #if !defined(QVG_SCISSOR_CLIP)
  2162 #if !defined(QVG_SCISSOR_CLIP)
  2098         // Combine the system clip with the simple mask rectangle.
  2163         // Combine the system clip with the simple mask rectangle.
  2099         if (!d->maskRect.isNull()) {
  2164         if (d->scissorMask) {
  2100             if (region.isEmpty())
  2165             if (region.isEmpty())
  2101                 region = d->maskRect;
  2166                 region = d->maskRect;
  2102             else
  2167             else
  2103                 region = region.intersect(d->maskRect);
  2168                 region = region.intersect(d->maskRect);
  2104             if (isDefaultClipRegion(region)) {
  2169             if (isDefaultClipRegion(region)) {
  2185     d->dirty |= QPaintEngine::DirtyClipEnabled;
  2250     d->dirty |= QPaintEngine::DirtyClipEnabled;
  2186     if (s->clipEnabled && s->clipOperation != Qt::NoClip) {
  2251     if (s->clipEnabled && s->clipOperation != Qt::NoClip) {
  2187         // Replay the entire clip stack to put the mask into the right state.
  2252         // Replay the entire clip stack to put the mask into the right state.
  2188         d->maskValid = false;
  2253         d->maskValid = false;
  2189         d->maskIsSet = true;
  2254         d->maskIsSet = true;
       
  2255         d->scissorMask = false;
  2190         d->maskRect = QRect();
  2256         d->maskRect = QRect();
  2191         s->clipRegion = defaultClipRegion();
  2257         s->clipRegion = defaultClipRegion();
  2192         d->replayClipOperations();
  2258         d->replayClipOperations();
  2193         d->transform = s->transform();
  2259         d->transform = s->transform();
  2194         d->updateTransform(paintDevice());
  2260         d->updateTransform(paintDevice());
  2195     } else {
  2261     } else {
  2196         vgSeti(VG_MASKING, VG_FALSE);
  2262         vgSeti(VG_MASKING, VG_FALSE);
  2197         d->maskValid = false;
  2263         d->maskValid = false;
  2198         d->maskIsSet = false;
  2264         d->maskIsSet = false;
       
  2265         d->scissorMask = false;
  2199         d->maskRect = QRect();
  2266         d->maskRect = QRect();
  2200     }
  2267     }
  2201 #endif
  2268 #endif
  2202 }
  2269 }
  2203 
  2270 
  2312 bool QVGPaintEngine::clearRect(const QRectF &rect, const QColor &color)
  2379 bool QVGPaintEngine::clearRect(const QRectF &rect, const QColor &color)
  2313 {
  2380 {
  2314     Q_D(QVGPaintEngine);
  2381     Q_D(QVGPaintEngine);
  2315     QVGPainterState *s = state();
  2382     QVGPainterState *s = state();
  2316     if (!s->clipEnabled || s->clipOperation == Qt::NoClip) {
  2383     if (!s->clipEnabled || s->clipOperation == Qt::NoClip) {
  2317         // The transform will either be identity or a simple translation,
  2384         QRect r = d->transform.mapRect(rect).toRect();
  2318         // so do a simpler version of "r = d->transform.map(rect).toRect()".
       
  2319         QRect r = QRect(qRound(rect.x() + d->transform.dx()),
       
  2320                         qRound(rect.y() + d->transform.dy()),
       
  2321                         qRound(rect.width()),
       
  2322                         qRound(rect.height()));
       
  2323         int height = paintDevice()->height();
  2385         int height = paintDevice()->height();
  2324         if (d->clearColor != color || d->clearOpacity != s->opacity) {
  2386         if (d->clearColor != color || d->clearOpacity != s->opacity) {
  2325             VGfloat values[4];
  2387             VGfloat values[4];
  2326             values[0] = color.redF();
  2388             values[0] = color.redF();
  2327             values[1] = color.greenF();
  2389             values[1] = color.greenF();
  2344 
  2406 
  2345     if (brush.style() == Qt::NoBrush)
  2407     if (brush.style() == Qt::NoBrush)
  2346         return;
  2408         return;
  2347 
  2409 
  2348     // Check to see if we can use vgClear() for faster filling.
  2410     // Check to see if we can use vgClear() for faster filling.
  2349     if (brush.style() == Qt::SolidPattern &&
  2411     if (brush.style() == Qt::SolidPattern && brush.isOpaque() &&
  2350             clipTransformIsSimple(d->transform) && d->opacity == 1.0f &&
  2412             clipTransformIsSimple(d->transform) && d->opacity == 1.0f &&
  2351             clearRect(rect, brush.color())) {
  2413             clearRect(rect, brush.color())) {
  2352         return;
  2414         return;
  2353     }
  2415     }
  2354 
  2416 
  2387 void QVGPaintEngine::fillRect(const QRectF &rect, const QColor &color)
  2449 void QVGPaintEngine::fillRect(const QRectF &rect, const QColor &color)
  2388 {
  2450 {
  2389     Q_D(QVGPaintEngine);
  2451     Q_D(QVGPaintEngine);
  2390 
  2452 
  2391     // Check to see if we can use vgClear() for faster filling.
  2453     // Check to see if we can use vgClear() for faster filling.
  2392     if (clipTransformIsSimple(d->transform) && d->opacity == 1.0f &&
  2454     if (clipTransformIsSimple(d->transform) && d->opacity == 1.0f && color.alpha() == 255 &&
  2393             clearRect(rect, color)) {
  2455             clearRect(rect, color)) {
  2394         return;
  2456         return;
  2395     }
  2457     }
  2396 
  2458 
  2397 #if !defined(QVG_NO_MODIFY_PATH)
  2459 #if !defined(QVG_NO_MODIFY_PATH)
  3256         QObject::connect(ti.fontEngine, SIGNAL(destroyed()),
  3318         QObject::connect(ti.fontEngine, SIGNAL(destroyed()),
  3257                          d->fontEngineCleaner, SLOT(fontEngineDestroyed()));
  3319                          d->fontEngineCleaner, SLOT(fontEngineDestroyed()));
  3258     }
  3320     }
  3259 
  3321 
  3260     // Set the transformation to use for drawing the current glyphs.
  3322     // Set the transformation to use for drawing the current glyphs.
  3261     QTransform glyphTransform(d->pathTransform);
  3323     QTransform glyphTransform(d->glyphTransform);
  3262     glyphTransform.translate(p.x(), p.y());
  3324     glyphTransform.translate(p.x(), p.y());
  3263 #if defined(QVG_NO_IMAGE_GLYPHS)
  3325 #if defined(QVG_NO_IMAGE_GLYPHS)
  3264     glyphTransform.scale(glyphCache->scaleX, glyphCache->scaleY);
  3326     glyphTransform.scale(glyphCache->scaleX, glyphCache->scaleY);
  3265 #endif
  3327 #endif
  3266     d->setTransform(VG_MATRIX_GLYPH_USER_TO_SURFACE, glyphTransform);
  3328     d->setTransform(VG_MATRIX_GLYPH_USER_TO_SURFACE, glyphTransform);
  3396     if ((dirty & (QPaintEngine::DirtyClipRegion |
  3458     if ((dirty & (QPaintEngine::DirtyClipRegion |
  3397                   QPaintEngine::DirtyClipPath |
  3459                   QPaintEngine::DirtyClipPath |
  3398                   QPaintEngine::DirtyClipEnabled)) != 0) {
  3460                   QPaintEngine::DirtyClipEnabled)) != 0) {
  3399         d->maskValid = false;
  3461         d->maskValid = false;
  3400         d->maskIsSet = false;
  3462         d->maskIsSet = false;
       
  3463         d->scissorMask = false;
  3401         d->maskRect = QRect();
  3464         d->maskRect = QRect();
  3402         clipEnabledChanged();
  3465         clipEnabledChanged();
  3403     }
  3466     }
  3404 
  3467 
  3405 #if defined(QVG_SCISSOR_CLIP)
  3468 #if defined(QVG_SCISSOR_CLIP)
  3588             }
  3651             }
  3589         }
  3652         }
  3590 
  3653 
  3591     } else {
  3654     } else {
  3592         // Set the path transform to the default viewport transformation.
  3655         // Set the path transform to the default viewport transformation.
  3593         VGfloat devh = screenSize.height() - 1;
  3656         VGfloat devh = screenSize.height();
  3594         QTransform viewport(1.0f, 0.0f, 0.0f,
  3657         QTransform viewport(1.0f, 0.0f, 0.0f,
  3595                             0.0f, -1.0f, 0.0f,
  3658                             0.0f, -1.0f, 0.0f,
  3596                             -0.5f, devh + 0.5f, 1.0f);
  3659                             0.0f, devh, 1.0f);
  3597         d->setTransform(VG_MATRIX_PATH_USER_TO_SURFACE, viewport);
  3660         d->setTransform(VG_MATRIX_PATH_USER_TO_SURFACE, viewport);
  3598 
  3661 
  3599         // Set the brush to use to fill the background.
  3662         // Set the brush to use to fill the background.
  3600         d->ensureBrush(brush);
  3663         d->ensureBrush(brush);
  3601         d->setFillRule(VG_EVEN_ODD);
  3664         d->setFillRule(VG_EVEN_ODD);
  3627         if (vgpd->isValid())
  3690         if (vgpd->isValid())
  3628             vgImage = vgpd->toVGImage();
  3691             vgImage = vgpd->toVGImage();
  3629     }
  3692     }
  3630 
  3693 
  3631     // Set the image transformation and modes.
  3694     // Set the image transformation and modes.
  3632     VGfloat devh = screenSize.height() - 1;
  3695     VGfloat devh = screenSize.height();
  3633     QTransform transform(1.0f, 0.0f, 0.0f,
  3696     QTransform transform(1.0f, 0.0f, 0.0f,
  3634                          0.0f, -1.0f, 0.0f,
  3697                          0.0f, -1.0f, 0.0f,
  3635                          -0.5f, devh + 0.5f, 1.0f);
  3698                          0.0f, devh, 1.0f);
  3636     transform.translate(offset.x(), offset.y());
  3699     transform.translate(offset.x(), offset.y());
  3637     d->setTransform(VG_MATRIX_IMAGE_USER_TO_SURFACE, transform);
  3700     d->setTransform(VG_MATRIX_IMAGE_USER_TO_SURFACE, transform);
  3638     d->setImageMode(VG_DRAW_IMAGE_NORMAL);
  3701     d->setImageMode(VG_DRAW_IMAGE_NORMAL);
  3639 
  3702 
  3640     // Draw the VGImage.
  3703     // Draw the VGImage.