| 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 |