OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2008 The Android Open Source Project | 3 * Copyright 2008 The Android Open Source Project |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 | 8 |
9 | 9 |
10 #include "SkCanvas.h" | 10 #include "SkCanvas.h" |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
84 const int count = fPixelRef ? fPixelRef->getLockCount() : 0; | 84 const int count = fPixelRef ? fPixelRef->getLockCount() : 0; |
85 SkASSERT(count == fLockCount); | 85 SkASSERT(count == fLockCount); |
86 } | 86 } |
87 | 87 |
88 private: | 88 private: |
89 const SkPixelRef* fPixelRef; | 89 const SkPixelRef* fPixelRef; |
90 int fLockCount; | 90 int fLockCount; |
91 }; | 91 }; |
92 #endif | 92 #endif |
93 | 93 |
94 class AutoCheckNoSetContext { | |
95 public: | |
96 AutoCheckNoSetContext(const SkPaint& paint) : fPaint(paint) { | |
97 this->assertNoSetContext(fPaint); | |
98 } | |
99 ~AutoCheckNoSetContext() { | |
100 this->assertNoSetContext(fPaint); | |
101 } | |
102 | |
103 private: | |
104 const SkPaint& fPaint; | |
105 | |
106 void assertNoSetContext(const SkPaint& paint) { | |
107 SkShader* s = paint.getShader(); | |
108 if (s) { | |
109 SkASSERT(!s->setContextHasBeenCalled()); | |
110 } | |
111 } | |
112 }; | |
113 | |
114 #define CHECK_LOCKCOUNT_BALANCE(bitmap) AutoCheckLockCountBalance clcb(bitmap) | 94 #define CHECK_LOCKCOUNT_BALANCE(bitmap) AutoCheckLockCountBalance clcb(bitmap) |
115 #define CHECK_SHADER_NOSETCONTEXT(paint) AutoCheckNoSetContext cshsc(paint) | |
116 | 95 |
117 #else | 96 #else |
118 #define CHECK_LOCKCOUNT_BALANCE(bitmap) | 97 #define CHECK_LOCKCOUNT_BALANCE(bitmap) |
119 #define CHECK_SHADER_NOSETCONTEXT(paint) | |
120 #endif | 98 #endif |
121 | 99 |
122 typedef SkTLazy<SkPaint> SkLazyPaint; | 100 typedef SkTLazy<SkPaint> SkLazyPaint; |
123 | 101 |
124 void SkCanvas::predrawNotify() { | 102 void SkCanvas::predrawNotify() { |
125 if (fSurfaceBase) { | 103 if (fSurfaceBase) { |
126 fSurfaceBase->aboutToDraw(SkSurface::kRetain_ContentChangeMode); | 104 fSurfaceBase->aboutToDraw(SkSurface::kRetain_ContentChangeMode); |
127 } | 105 } |
128 } | 106 } |
129 | 107 |
(...skipping 1633 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1763 while (iter.next()) { | 1741 while (iter.next()) { |
1764 iter.fDevice->clear(color); | 1742 iter.fDevice->clear(color); |
1765 } | 1743 } |
1766 } | 1744 } |
1767 | 1745 |
1768 void SkCanvas::drawPaint(const SkPaint& paint) { | 1746 void SkCanvas::drawPaint(const SkPaint& paint) { |
1769 this->internalDrawPaint(paint); | 1747 this->internalDrawPaint(paint); |
1770 } | 1748 } |
1771 | 1749 |
1772 void SkCanvas::internalDrawPaint(const SkPaint& paint) { | 1750 void SkCanvas::internalDrawPaint(const SkPaint& paint) { |
1773 CHECK_SHADER_NOSETCONTEXT(paint); | |
1774 | |
1775 LOOPER_BEGIN(paint, SkDrawFilter::kPaint_Type, NULL) | 1751 LOOPER_BEGIN(paint, SkDrawFilter::kPaint_Type, NULL) |
1776 | 1752 |
1777 while (iter.next()) { | 1753 while (iter.next()) { |
1778 iter.fDevice->drawPaint(iter, looper.paint()); | 1754 iter.fDevice->drawPaint(iter, looper.paint()); |
1779 } | 1755 } |
1780 | 1756 |
1781 LOOPER_END | 1757 LOOPER_END |
1782 } | 1758 } |
1783 | 1759 |
1784 void SkCanvas::drawPoints(PointMode mode, size_t count, const SkPoint pts[], | 1760 void SkCanvas::drawPoints(PointMode mode, size_t count, const SkPoint pts[], |
1785 const SkPaint& paint) { | 1761 const SkPaint& paint) { |
1786 if ((long)count <= 0) { | 1762 if ((long)count <= 0) { |
1787 return; | 1763 return; |
1788 } | 1764 } |
1789 | 1765 |
1790 CHECK_SHADER_NOSETCONTEXT(paint); | |
1791 | |
1792 SkRect r, storage; | 1766 SkRect r, storage; |
1793 const SkRect* bounds = NULL; | 1767 const SkRect* bounds = NULL; |
1794 if (paint.canComputeFastBounds()) { | 1768 if (paint.canComputeFastBounds()) { |
1795 // special-case 2 points (common for drawing a single line) | 1769 // special-case 2 points (common for drawing a single line) |
1796 if (2 == count) { | 1770 if (2 == count) { |
1797 r.set(pts[0], pts[1]); | 1771 r.set(pts[0], pts[1]); |
1798 } else { | 1772 } else { |
1799 r.set(pts, SkToInt(count)); | 1773 r.set(pts, SkToInt(count)); |
1800 } | 1774 } |
1801 bounds = &paint.computeFastStrokeBounds(r, &storage); | 1775 bounds = &paint.computeFastStrokeBounds(r, &storage); |
1802 if (this->quickReject(*bounds)) { | 1776 if (this->quickReject(*bounds)) { |
1803 return; | 1777 return; |
1804 } | 1778 } |
1805 } | 1779 } |
1806 | 1780 |
1807 SkASSERT(pts != NULL); | 1781 SkASSERT(pts != NULL); |
1808 | 1782 |
1809 LOOPER_BEGIN(paint, SkDrawFilter::kPoint_Type, bounds) | 1783 LOOPER_BEGIN(paint, SkDrawFilter::kPoint_Type, bounds) |
1810 | 1784 |
1811 while (iter.next()) { | 1785 while (iter.next()) { |
1812 iter.fDevice->drawPoints(iter, mode, count, pts, looper.paint()); | 1786 iter.fDevice->drawPoints(iter, mode, count, pts, looper.paint()); |
1813 } | 1787 } |
1814 | 1788 |
1815 LOOPER_END | 1789 LOOPER_END |
1816 } | 1790 } |
1817 | 1791 |
1818 void SkCanvas::drawRect(const SkRect& r, const SkPaint& paint) { | 1792 void SkCanvas::drawRect(const SkRect& r, const SkPaint& paint) { |
1819 CHECK_SHADER_NOSETCONTEXT(paint); | |
1820 | |
1821 SkRect storage; | 1793 SkRect storage; |
1822 const SkRect* bounds = NULL; | 1794 const SkRect* bounds = NULL; |
1823 if (paint.canComputeFastBounds()) { | 1795 if (paint.canComputeFastBounds()) { |
1824 bounds = &paint.computeFastBounds(r, &storage); | 1796 bounds = &paint.computeFastBounds(r, &storage); |
1825 if (this->quickReject(*bounds)) { | 1797 if (this->quickReject(*bounds)) { |
1826 return; | 1798 return; |
1827 } | 1799 } |
1828 } | 1800 } |
1829 | 1801 |
1830 LOOPER_BEGIN(paint, SkDrawFilter::kRect_Type, bounds) | 1802 LOOPER_BEGIN(paint, SkDrawFilter::kRect_Type, bounds) |
1831 | 1803 |
1832 while (iter.next()) { | 1804 while (iter.next()) { |
1833 iter.fDevice->drawRect(iter, r, looper.paint()); | 1805 iter.fDevice->drawRect(iter, r, looper.paint()); |
1834 } | 1806 } |
1835 | 1807 |
1836 LOOPER_END | 1808 LOOPER_END |
1837 } | 1809 } |
1838 | 1810 |
1839 void SkCanvas::drawOval(const SkRect& oval, const SkPaint& paint) { | 1811 void SkCanvas::drawOval(const SkRect& oval, const SkPaint& paint) { |
1840 CHECK_SHADER_NOSETCONTEXT(paint); | |
1841 | |
1842 SkRect storage; | 1812 SkRect storage; |
1843 const SkRect* bounds = NULL; | 1813 const SkRect* bounds = NULL; |
1844 if (paint.canComputeFastBounds()) { | 1814 if (paint.canComputeFastBounds()) { |
1845 bounds = &paint.computeFastBounds(oval, &storage); | 1815 bounds = &paint.computeFastBounds(oval, &storage); |
1846 if (this->quickReject(*bounds)) { | 1816 if (this->quickReject(*bounds)) { |
1847 return; | 1817 return; |
1848 } | 1818 } |
1849 } | 1819 } |
1850 | 1820 |
1851 LOOPER_BEGIN(paint, SkDrawFilter::kOval_Type, bounds) | 1821 LOOPER_BEGIN(paint, SkDrawFilter::kOval_Type, bounds) |
1852 | 1822 |
1853 while (iter.next()) { | 1823 while (iter.next()) { |
1854 iter.fDevice->drawOval(iter, oval, looper.paint()); | 1824 iter.fDevice->drawOval(iter, oval, looper.paint()); |
1855 } | 1825 } |
1856 | 1826 |
1857 LOOPER_END | 1827 LOOPER_END |
1858 } | 1828 } |
1859 | 1829 |
1860 void SkCanvas::drawRRect(const SkRRect& rrect, const SkPaint& paint) { | 1830 void SkCanvas::drawRRect(const SkRRect& rrect, const SkPaint& paint) { |
1861 CHECK_SHADER_NOSETCONTEXT(paint); | |
1862 | |
1863 SkRect storage; | 1831 SkRect storage; |
1864 const SkRect* bounds = NULL; | 1832 const SkRect* bounds = NULL; |
1865 if (paint.canComputeFastBounds()) { | 1833 if (paint.canComputeFastBounds()) { |
1866 bounds = &paint.computeFastBounds(rrect.getBounds(), &storage); | 1834 bounds = &paint.computeFastBounds(rrect.getBounds(), &storage); |
1867 if (this->quickReject(*bounds)) { | 1835 if (this->quickReject(*bounds)) { |
1868 return; | 1836 return; |
1869 } | 1837 } |
1870 } | 1838 } |
1871 | 1839 |
1872 if (rrect.isRect()) { | 1840 if (rrect.isRect()) { |
(...skipping 10 matching lines...) Expand all Loading... |
1883 | 1851 |
1884 while (iter.next()) { | 1852 while (iter.next()) { |
1885 iter.fDevice->drawRRect(iter, rrect, looper.paint()); | 1853 iter.fDevice->drawRRect(iter, rrect, looper.paint()); |
1886 } | 1854 } |
1887 | 1855 |
1888 LOOPER_END | 1856 LOOPER_END |
1889 } | 1857 } |
1890 | 1858 |
1891 void SkCanvas::onDrawDRRect(const SkRRect& outer, const SkRRect& inner, | 1859 void SkCanvas::onDrawDRRect(const SkRRect& outer, const SkRRect& inner, |
1892 const SkPaint& paint) { | 1860 const SkPaint& paint) { |
1893 CHECK_SHADER_NOSETCONTEXT(paint); | |
1894 | |
1895 SkRect storage; | 1861 SkRect storage; |
1896 const SkRect* bounds = NULL; | 1862 const SkRect* bounds = NULL; |
1897 if (paint.canComputeFastBounds()) { | 1863 if (paint.canComputeFastBounds()) { |
1898 bounds = &paint.computeFastBounds(outer.getBounds(), &storage); | 1864 bounds = &paint.computeFastBounds(outer.getBounds(), &storage); |
1899 if (this->quickReject(*bounds)) { | 1865 if (this->quickReject(*bounds)) { |
1900 return; | 1866 return; |
1901 } | 1867 } |
1902 } | 1868 } |
1903 | 1869 |
1904 LOOPER_BEGIN(paint, SkDrawFilter::kRRect_Type, bounds) | 1870 LOOPER_BEGIN(paint, SkDrawFilter::kRRect_Type, bounds) |
1905 | 1871 |
1906 while (iter.next()) { | 1872 while (iter.next()) { |
1907 iter.fDevice->drawDRRect(iter, outer, inner, looper.paint()); | 1873 iter.fDevice->drawDRRect(iter, outer, inner, looper.paint()); |
1908 } | 1874 } |
1909 | 1875 |
1910 LOOPER_END | 1876 LOOPER_END |
1911 } | 1877 } |
1912 | 1878 |
1913 void SkCanvas::drawPath(const SkPath& path, const SkPaint& paint) { | 1879 void SkCanvas::drawPath(const SkPath& path, const SkPaint& paint) { |
1914 CHECK_SHADER_NOSETCONTEXT(paint); | |
1915 | |
1916 if (!path.isFinite()) { | 1880 if (!path.isFinite()) { |
1917 return; | 1881 return; |
1918 } | 1882 } |
1919 | 1883 |
1920 SkRect storage; | 1884 SkRect storage; |
1921 const SkRect* bounds = NULL; | 1885 const SkRect* bounds = NULL; |
1922 if (!path.isInverseFillType() && paint.canComputeFastBounds()) { | 1886 if (!path.isInverseFillType() && paint.canComputeFastBounds()) { |
1923 const SkRect& pathBounds = path.getBounds(); | 1887 const SkRect& pathBounds = path.getBounds(); |
1924 bounds = &paint.computeFastBounds(pathBounds, &storage); | 1888 bounds = &paint.computeFastBounds(pathBounds, &storage); |
1925 if (this->quickReject(*bounds)) { | 1889 if (this->quickReject(*bounds)) { |
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2181 start.fY); | 2145 start.fY); |
2182 r.fTop = offset; | 2146 r.fTop = offset; |
2183 r.fBottom = offset + height; | 2147 r.fBottom = offset + height; |
2184 DrawRect(draw, paint, r, textSize); | 2148 DrawRect(draw, paint, r, textSize); |
2185 } | 2149 } |
2186 } | 2150 } |
2187 } | 2151 } |
2188 | 2152 |
2189 void SkCanvas::drawText(const void* text, size_t byteLength, | 2153 void SkCanvas::drawText(const void* text, size_t byteLength, |
2190 SkScalar x, SkScalar y, const SkPaint& paint) { | 2154 SkScalar x, SkScalar y, const SkPaint& paint) { |
2191 CHECK_SHADER_NOSETCONTEXT(paint); | |
2192 | |
2193 LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, NULL) | 2155 LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, NULL) |
2194 | 2156 |
2195 while (iter.next()) { | 2157 while (iter.next()) { |
2196 SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint()); | 2158 SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint()); |
2197 iter.fDevice->drawText(iter, text, byteLength, x, y, dfp.paint()); | 2159 iter.fDevice->drawText(iter, text, byteLength, x, y, dfp.paint()); |
2198 DrawTextDecorations(iter, dfp.paint(), | 2160 DrawTextDecorations(iter, dfp.paint(), |
2199 static_cast<const char*>(text), byteLength, x, y); | 2161 static_cast<const char*>(text), byteLength, x, y); |
2200 } | 2162 } |
2201 | 2163 |
2202 LOOPER_END | 2164 LOOPER_END |
2203 } | 2165 } |
2204 | 2166 |
2205 void SkCanvas::drawPosText(const void* text, size_t byteLength, | 2167 void SkCanvas::drawPosText(const void* text, size_t byteLength, |
2206 const SkPoint pos[], const SkPaint& paint) { | 2168 const SkPoint pos[], const SkPaint& paint) { |
2207 CHECK_SHADER_NOSETCONTEXT(paint); | |
2208 | |
2209 LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, NULL) | 2169 LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, NULL) |
2210 | 2170 |
2211 while (iter.next()) { | 2171 while (iter.next()) { |
2212 SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint()); | 2172 SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint()); |
2213 iter.fDevice->drawPosText(iter, text, byteLength, &pos->fX, 0, 2, | 2173 iter.fDevice->drawPosText(iter, text, byteLength, &pos->fX, 0, 2, |
2214 dfp.paint()); | 2174 dfp.paint()); |
2215 } | 2175 } |
2216 | 2176 |
2217 LOOPER_END | 2177 LOOPER_END |
2218 } | 2178 } |
2219 | 2179 |
2220 void SkCanvas::drawPosTextH(const void* text, size_t byteLength, | 2180 void SkCanvas::drawPosTextH(const void* text, size_t byteLength, |
2221 const SkScalar xpos[], SkScalar constY, | 2181 const SkScalar xpos[], SkScalar constY, |
2222 const SkPaint& paint) { | 2182 const SkPaint& paint) { |
2223 CHECK_SHADER_NOSETCONTEXT(paint); | |
2224 | |
2225 LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, NULL) | 2183 LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, NULL) |
2226 | 2184 |
2227 while (iter.next()) { | 2185 while (iter.next()) { |
2228 SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint()); | 2186 SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint()); |
2229 iter.fDevice->drawPosText(iter, text, byteLength, xpos, constY, 1, | 2187 iter.fDevice->drawPosText(iter, text, byteLength, xpos, constY, 1, |
2230 dfp.paint()); | 2188 dfp.paint()); |
2231 } | 2189 } |
2232 | 2190 |
2233 LOOPER_END | 2191 LOOPER_END |
2234 } | 2192 } |
2235 | 2193 |
2236 void SkCanvas::drawTextOnPath(const void* text, size_t byteLength, | 2194 void SkCanvas::drawTextOnPath(const void* text, size_t byteLength, |
2237 const SkPath& path, const SkMatrix* matrix, | 2195 const SkPath& path, const SkMatrix* matrix, |
2238 const SkPaint& paint) { | 2196 const SkPaint& paint) { |
2239 CHECK_SHADER_NOSETCONTEXT(paint); | |
2240 | |
2241 LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, NULL) | 2197 LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, NULL) |
2242 | 2198 |
2243 while (iter.next()) { | 2199 while (iter.next()) { |
2244 iter.fDevice->drawTextOnPath(iter, text, byteLength, path, | 2200 iter.fDevice->drawTextOnPath(iter, text, byteLength, path, |
2245 matrix, looper.paint()); | 2201 matrix, looper.paint()); |
2246 } | 2202 } |
2247 | 2203 |
2248 LOOPER_END | 2204 LOOPER_END |
2249 } | 2205 } |
2250 | 2206 |
2251 void SkCanvas::drawVertices(VertexMode vmode, int vertexCount, | 2207 void SkCanvas::drawVertices(VertexMode vmode, int vertexCount, |
2252 const SkPoint verts[], const SkPoint texs[], | 2208 const SkPoint verts[], const SkPoint texs[], |
2253 const SkColor colors[], SkXfermode* xmode, | 2209 const SkColor colors[], SkXfermode* xmode, |
2254 const uint16_t indices[], int indexCount, | 2210 const uint16_t indices[], int indexCount, |
2255 const SkPaint& paint) { | 2211 const SkPaint& paint) { |
2256 CHECK_SHADER_NOSETCONTEXT(paint); | |
2257 | |
2258 LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type, NULL) | 2212 LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type, NULL) |
2259 | 2213 |
2260 while (iter.next()) { | 2214 while (iter.next()) { |
2261 iter.fDevice->drawVertices(iter, vmode, vertexCount, verts, texs, | 2215 iter.fDevice->drawVertices(iter, vmode, vertexCount, verts, texs, |
2262 colors, xmode, indices, indexCount, | 2216 colors, xmode, indices, indexCount, |
2263 looper.paint()); | 2217 looper.paint()); |
2264 } | 2218 } |
2265 | 2219 |
2266 LOOPER_END | 2220 LOOPER_END |
2267 } | 2221 } |
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2463 if (!bitmap.allocPixels(info)) { | 2417 if (!bitmap.allocPixels(info)) { |
2464 return NULL; | 2418 return NULL; |
2465 } | 2419 } |
2466 | 2420 |
2467 // should this functionality be moved into allocPixels()? | 2421 // should this functionality be moved into allocPixels()? |
2468 if (!bitmap.info().isOpaque()) { | 2422 if (!bitmap.info().isOpaque()) { |
2469 bitmap.eraseColor(0); | 2423 bitmap.eraseColor(0); |
2470 } | 2424 } |
2471 return SkNEW_ARGS(SkCanvas, (bitmap)); | 2425 return SkNEW_ARGS(SkCanvas, (bitmap)); |
2472 } | 2426 } |
OLD | NEW |