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 #define TEXT_AS_PATHS_PAINT_FLAGS_TO_IGNORE ( \ | |
1857 SkPaint::kDevKernText_Flag | \ | |
1858 SkPaint::kLinearText_Flag | \ | |
1859 SkPaint::kLCDRenderText_Flag | \ | |
1860 SkPaint::kEmbeddedBitmapText_Flag | \ | |
1861 SkPaint::kAutoHinting_Flag | \ | |
1862 SkPaint::kGenA8FromLCD_Flag ) | |
1863 | |
1864 #define TEXT_AS_PATHS_PAINT_FLAGS_TO_SET ( \ | |
1865 SkPaint::kSubpixelText_Flag ) | |
bungeman-skia
2013/06/04 14:27:58
I think you also want kNo_Hinting.
reed1
2013/06/04 15:58:22
Done.
| |
1866 | |
1867 void SkDraw::drawPosText_asPaths(const char text[], size_t byteLength, | |
1868 const SkScalar pos[], SkScalar constY, | |
1869 int scalarsPerPosition, | |
1870 const SkPaint& origPaint) const { | |
1871 const SkScalar stdSize = SkIntToScalar(SkPaint::kCanonicalTextSizeForPaths); | |
1872 | |
1873 // setup our std paint, in hopes of getting hits in the cache | |
1874 SkPaint paint(origPaint); | |
1875 paint.setFlags((paint.getFlags() & ~TEXT_AS_PATHS_PAINT_FLAGS_TO_IGNORE) | |
1876 | TEXT_AS_PATHS_PAINT_FLAGS_TO_SET); | |
1877 paint.setTextSize(stdSize); | |
1878 | |
1879 SkDraw draw(*this); | |
1880 | |
1881 // Now modify our matrix to account for the canonical text size | |
1882 SkMatrix matrix = *fMatrix; | |
1883 const SkScalar matrixScale = origPaint.getTextSize() / stdSize; | |
1884 matrix.preScale(matrixScale, matrixScale); | |
1885 const SkScalar posScale = SkScalarInvert(matrixScale); | |
1886 | |
1887 SkDrawCacheProc glyphCacheProc = paint.getDrawCacheProc(); | |
1888 SkAutoGlyphCache autoCache(paint, NULL, NULL); | |
1889 SkGlyphCache* cache = autoCache.getCache(); | |
1890 | |
1891 const char* stop = text + byteLength; | |
1892 AlignProc alignProc = pick_align_proc(paint.getTextAlign()); | |
1893 TextMapState tms(SkMatrix::I(), constY); | |
1894 TextMapState::Proc tmsProc = tms.pickProc(scalarsPerPosition); | |
1895 | |
1896 while (text < stop) { | |
1897 const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0); | |
1898 if (glyph.fWidth) { | |
1899 const SkPath* path = cache->findPath(glyph); | |
1900 if (path) { | |
1901 tmsProc(tms, pos); | |
1902 SkIPoint fixedLoc; | |
1903 alignProc(tms.fLoc, glyph, &fixedLoc); | |
1904 | |
1905 SkMatrix localMatrix = matrix; | |
1906 localMatrix.preTranslate(SkFixedToScalar(fixedLoc.fX) * posScale , | |
1907 SkFixedToScalar(fixedLoc.fY) * posScale ); | |
1908 draw.fMatrix = &localMatrix; | |
1909 draw.drawPath(*path, paint); | |
1910 } | |
1911 } | |
1912 pos += scalarsPerPosition; | |
1913 } | |
1914 } | |
1915 | |
1842 void SkDraw::drawPosText(const char text[], size_t byteLength, | 1916 void SkDraw::drawPosText(const char text[], size_t byteLength, |
1843 const SkScalar pos[], SkScalar constY, | 1917 const SkScalar pos[], SkScalar constY, |
1844 int scalarsPerPosition, const SkPaint& paint) const { | 1918 int scalarsPerPosition, const SkPaint& paint) const { |
1845 SkASSERT(byteLength == 0 || text != NULL); | 1919 SkASSERT(byteLength == 0 || text != NULL); |
1846 SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition); | 1920 SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition); |
1847 | 1921 |
1848 SkDEBUGCODE(this->validate();) | 1922 SkDEBUGCODE(this->validate();) |
1849 | 1923 |
1850 // nothing to draw | 1924 // nothing to draw |
1851 if (text == NULL || byteLength == 0 || fRC->isEmpty()) { | 1925 if (text == NULL || byteLength == 0 || fRC->isEmpty()) { |
1852 return; | 1926 return; |
1853 } | 1927 } |
1854 | 1928 |
1855 if (/*paint.isLinearText() ||*/ | 1929 if (ShouldDrawTextAsPaths(paint, *fMatrix)) { |
1856 (fMatrix->hasPerspective())) { | 1930 this->drawPosText_asPaths(text, byteLength, pos, constY, |
1857 // TODO !!!! | 1931 scalarsPerPosition, paint); |
1858 // this->drawText_asPaths(text, byteLength, x, y, paint); | |
1859 return; | 1932 return; |
1860 } | 1933 } |
1861 | 1934 |
1862 SkDrawCacheProc glyphCacheProc = paint.getDrawCacheProc(); | 1935 SkDrawCacheProc glyphCacheProc = paint.getDrawCacheProc(); |
1863 SkAutoGlyphCache autoCache(paint, &fDevice->fLeakyProperties, fMatrix); | 1936 SkAutoGlyphCache autoCache(paint, &fDevice->fLeakyProperties, fMatrix); |
1864 SkGlyphCache* cache = autoCache.getCache(); | 1937 SkGlyphCache* cache = autoCache.getCache(); |
1865 | 1938 |
1866 SkAAClipBlitterWrapper wrapper; | 1939 SkAAClipBlitterWrapper wrapper; |
1867 SkAutoBlitterChoose blitterChooser; | 1940 SkAutoBlitterChoose blitterChooser; |
1868 SkBlitter* blitter = NULL; | 1941 SkBlitter* blitter = NULL; |
(...skipping 908 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2777 mask->fImage = SkMask::AllocImage(size); | 2850 mask->fImage = SkMask::AllocImage(size); |
2778 memset(mask->fImage, 0, mask->computeImageSize()); | 2851 memset(mask->fImage, 0, mask->computeImageSize()); |
2779 } | 2852 } |
2780 | 2853 |
2781 if (SkMask::kJustComputeBounds_CreateMode != mode) { | 2854 if (SkMask::kJustComputeBounds_CreateMode != mode) { |
2782 draw_into_mask(*mask, devPath, style); | 2855 draw_into_mask(*mask, devPath, style); |
2783 } | 2856 } |
2784 | 2857 |
2785 return true; | 2858 return true; |
2786 } | 2859 } |
OLD | NEW |