OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2006 The Android Open Source Project | 2 * Copyright 2006 The Android Open Source Project |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 | 8 |
9 #include "SkDraw.h" | 9 #include "SkDraw.h" |
10 #include "SkBlitter.h" | 10 #include "SkBlitter.h" |
(...skipping 13 matching lines...) Expand all Loading... |
24 #include "SkStroke.h" | 24 #include "SkStroke.h" |
25 #include "SkTemplatesPriv.h" | 25 #include "SkTemplatesPriv.h" |
26 #include "SkTLazy.h" | 26 #include "SkTLazy.h" |
27 #include "SkUtils.h" | 27 #include "SkUtils.h" |
28 | 28 |
29 #include "SkAutoKern.h" | 29 #include "SkAutoKern.h" |
30 #include "SkBitmapProcShader.h" | 30 #include "SkBitmapProcShader.h" |
31 #include "SkDrawProcs.h" | 31 #include "SkDrawProcs.h" |
32 #include "SkMatrixUtils.h" | 32 #include "SkMatrixUtils.h" |
33 | 33 |
| 34 bool SkDraw::ShouldDrawTextAsPaths(const SkPaint& paint, const SkMatrix& ctm) { |
| 35 // we don't cache hairlines in the cache |
| 36 if (SkPaint::kStroke_Style == paint.getStyle() && |
| 37 0 == paint.getStrokeWidth()) { |
| 38 return true; |
| 39 } |
| 40 |
| 41 // we don't cache perspective |
| 42 if (ctm.hasPerspective()) { |
| 43 return true; |
| 44 } |
| 45 |
| 46 SkMatrix textM; |
| 47 return SkPaint::TooBigToUseCache(ctm, *paint.setTextMatrix(&textM)); |
| 48 } |
| 49 |
34 //#define TRACE_BITMAP_DRAWS | 50 //#define TRACE_BITMAP_DRAWS |
35 | 51 |
36 #define kBlitterStorageLongCount (sizeof(SkBitmapProcShader) >> 2) | 52 #define kBlitterStorageLongCount (sizeof(SkBitmapProcShader) >> 2) |
37 | 53 |
38 /** Helper for allocating small blitters on the stack. | 54 /** Helper for allocating small blitters on the stack. |
39 */ | 55 */ |
40 class SkAutoBlitterChoose : SkNoncopyable { | 56 class SkAutoBlitterChoose : SkNoncopyable { |
41 public: | 57 public: |
42 SkAutoBlitterChoose() { | 58 SkAutoBlitterChoose() { |
43 fBlitter = NULL; | 59 fBlitter = NULL; |
(...skipping 1612 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1656 | 1672 |
1657 SkDEBUGCODE(this->validate();) | 1673 SkDEBUGCODE(this->validate();) |
1658 | 1674 |
1659 // nothing to draw | 1675 // nothing to draw |
1660 if (text == NULL || byteLength == 0 || fRC->isEmpty()) { | 1676 if (text == NULL || byteLength == 0 || fRC->isEmpty()) { |
1661 return; | 1677 return; |
1662 } | 1678 } |
1663 | 1679 |
1664 // SkScalarRec doesn't currently have a way of representing hairline stroke
and | 1680 // SkScalarRec doesn't currently have a way of representing hairline stroke
and |
1665 // will fill if its frame-width is 0. | 1681 // will fill if its frame-width is 0. |
1666 if (/*paint.isLinearText() ||*/ | 1682 if (ShouldDrawTextAsPaths(paint, *fMatrix)) { |
1667 (fMatrix->hasPerspective()) || | |
1668 (0 == paint.getStrokeWidth() && SkPaint::kStroke_Style == paint.getStyle
())) { | |
1669 this->drawText_asPaths(text, byteLength, x, y, paint); | 1683 this->drawText_asPaths(text, byteLength, x, y, paint); |
1670 return; | 1684 return; |
1671 } | 1685 } |
1672 | 1686 |
1673 SkDrawCacheProc glyphCacheProc = paint.getDrawCacheProc(); | 1687 SkDrawCacheProc glyphCacheProc = paint.getDrawCacheProc(); |
1674 | 1688 |
1675 SkAutoGlyphCache autoCache(paint, &fDevice->fLeakyProperties, fMatrix); | 1689 SkAutoGlyphCache autoCache(paint, &fDevice->fLeakyProperties, fMatrix); |
1676 SkGlyphCache* cache = autoCache.getCache(); | 1690 SkGlyphCache* cache = autoCache.getCache(); |
1677 | 1691 |
1678 // transform our starting point | 1692 // transform our starting point |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1832 return (mtype & SkMatrix::kScale_Mask) ? | 1846 return (mtype & SkMatrix::kScale_Mask) ? |
1833 MapOnlyScaleXProc : MapOnlyTransXProc; | 1847 MapOnlyScaleXProc : MapOnlyTransXProc; |
1834 } | 1848 } |
1835 } else { | 1849 } else { |
1836 return MapXYProc; | 1850 return MapXYProc; |
1837 } | 1851 } |
1838 } | 1852 } |
1839 | 1853 |
1840 ////////////////////////////////////////////////////////////////////////////// | 1854 ////////////////////////////////////////////////////////////////////////////// |
1841 | 1855 |
| 1856 void SkDraw::drawPosText_asPaths(const char text[], size_t byteLength, |
| 1857 const SkScalar pos[], SkScalar constY, |
| 1858 int scalarsPerPosition, |
| 1859 const SkPaint& origPaint) const { |
| 1860 // setup our std paint, in hopes of getting hits in the cache |
| 1861 SkPaint paint(origPaint); |
| 1862 SkScalar matrixScale = paint.setupForAsPaths(); |
| 1863 |
| 1864 SkDraw draw(*this); |
| 1865 |
| 1866 // Now modify our matrix to account for the canonical text size |
| 1867 SkMatrix matrix = *fMatrix; |
| 1868 matrix.preScale(matrixScale, matrixScale); |
| 1869 const SkScalar posScale = SkScalarInvert(matrixScale); |
| 1870 |
| 1871 SkDrawCacheProc glyphCacheProc = paint.getDrawCacheProc(); |
| 1872 SkAutoGlyphCache autoCache(paint, NULL, NULL); |
| 1873 SkGlyphCache* cache = autoCache.getCache(); |
| 1874 |
| 1875 const char* stop = text + byteLength; |
| 1876 AlignProc alignProc = pick_align_proc(paint.getTextAlign()); |
| 1877 TextMapState tms(SkMatrix::I(), constY); |
| 1878 TextMapState::Proc tmsProc = tms.pickProc(scalarsPerPosition); |
| 1879 |
| 1880 while (text < stop) { |
| 1881 const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0); |
| 1882 if (glyph.fWidth) { |
| 1883 const SkPath* path = cache->findPath(glyph); |
| 1884 if (path) { |
| 1885 tmsProc(tms, pos); |
| 1886 SkIPoint fixedLoc; |
| 1887 alignProc(tms.fLoc, glyph, &fixedLoc); |
| 1888 |
| 1889 SkMatrix localMatrix = matrix; |
| 1890 localMatrix.preTranslate(SkFixedToScalar(fixedLoc.fX) * posScale
, |
| 1891 SkFixedToScalar(fixedLoc.fY) * posScale
); |
| 1892 draw.fMatrix = &localMatrix; |
| 1893 draw.drawPath(*path, paint); |
| 1894 } |
| 1895 } |
| 1896 pos += scalarsPerPosition; |
| 1897 } |
| 1898 } |
| 1899 |
1842 void SkDraw::drawPosText(const char text[], size_t byteLength, | 1900 void SkDraw::drawPosText(const char text[], size_t byteLength, |
1843 const SkScalar pos[], SkScalar constY, | 1901 const SkScalar pos[], SkScalar constY, |
1844 int scalarsPerPosition, const SkPaint& paint) const { | 1902 int scalarsPerPosition, const SkPaint& paint) const { |
1845 SkASSERT(byteLength == 0 || text != NULL); | 1903 SkASSERT(byteLength == 0 || text != NULL); |
1846 SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition); | 1904 SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition); |
1847 | 1905 |
1848 SkDEBUGCODE(this->validate();) | 1906 SkDEBUGCODE(this->validate();) |
1849 | 1907 |
1850 // nothing to draw | 1908 // nothing to draw |
1851 if (text == NULL || byteLength == 0 || fRC->isEmpty()) { | 1909 if (text == NULL || byteLength == 0 || fRC->isEmpty()) { |
1852 return; | 1910 return; |
1853 } | 1911 } |
1854 | 1912 |
1855 if (/*paint.isLinearText() ||*/ | 1913 if (ShouldDrawTextAsPaths(paint, *fMatrix)) { |
1856 (fMatrix->hasPerspective())) { | 1914 this->drawPosText_asPaths(text, byteLength, pos, constY, |
1857 // TODO !!!! | 1915 scalarsPerPosition, paint); |
1858 // this->drawText_asPaths(text, byteLength, x, y, paint); | |
1859 return; | 1916 return; |
1860 } | 1917 } |
1861 | 1918 |
1862 SkDrawCacheProc glyphCacheProc = paint.getDrawCacheProc(); | 1919 SkDrawCacheProc glyphCacheProc = paint.getDrawCacheProc(); |
1863 SkAutoGlyphCache autoCache(paint, &fDevice->fLeakyProperties, fMatrix); | 1920 SkAutoGlyphCache autoCache(paint, &fDevice->fLeakyProperties, fMatrix); |
1864 SkGlyphCache* cache = autoCache.getCache(); | 1921 SkGlyphCache* cache = autoCache.getCache(); |
1865 | 1922 |
1866 SkAAClipBlitterWrapper wrapper; | 1923 SkAAClipBlitterWrapper wrapper; |
1867 SkAutoBlitterChoose blitterChooser; | 1924 SkAutoBlitterChoose blitterChooser; |
1868 SkBlitter* blitter = NULL; | 1925 SkBlitter* blitter = NULL; |
(...skipping 908 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2777 mask->fImage = SkMask::AllocImage(size); | 2834 mask->fImage = SkMask::AllocImage(size); |
2778 memset(mask->fImage, 0, mask->computeImageSize()); | 2835 memset(mask->fImage, 0, mask->computeImageSize()); |
2779 } | 2836 } |
2780 | 2837 |
2781 if (SkMask::kJustComputeBounds_CreateMode != mode) { | 2838 if (SkMask::kJustComputeBounds_CreateMode != mode) { |
2782 draw_into_mask(*mask, devPath, style); | 2839 draw_into_mask(*mask, devPath, style); |
2783 } | 2840 } |
2784 | 2841 |
2785 return true; | 2842 return true; |
2786 } | 2843 } |
OLD | NEW |