Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(863)

Side by Side Diff: src/core/SkDraw.cpp

Issue 85653004: Move distance field font code into SkGpuDevice (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 #include "SkDraw.h" 8 #include "SkDraw.h"
9 #include "SkBlitter.h" 9 #include "SkBlitter.h"
10 #include "SkBounder.h" 10 #include "SkBounder.h"
(...skipping 14 matching lines...) Expand all
25 #include "SkStroke.h" 25 #include "SkStroke.h"
26 #include "SkTemplatesPriv.h" 26 #include "SkTemplatesPriv.h"
27 #include "SkTLazy.h" 27 #include "SkTLazy.h"
28 #include "SkUtils.h" 28 #include "SkUtils.h"
29 29
30 #include "SkAutoKern.h" 30 #include "SkAutoKern.h"
31 #include "SkBitmapProcShader.h" 31 #include "SkBitmapProcShader.h"
32 #include "SkDrawProcs.h" 32 #include "SkDrawProcs.h"
33 #include "SkMatrixUtils.h" 33 #include "SkMatrixUtils.h"
34 34
35 bool SkDraw::ShouldDrawTextAsPaths(const SkPaint& paint, const SkMatrix& ctm) {
36 // we don't cache hairlines in the cache
37 if (SkPaint::kStroke_Style == paint.getStyle() &&
38 0 == paint.getStrokeWidth()) {
39 return true;
40 }
41
42 // we don't cache perspective
43 if (ctm.hasPerspective()) {
44 return true;
45 }
46
47 SkMatrix textM;
48 return SkPaint::TooBigToUseCache(ctm, *paint.setTextMatrix(&textM));
49 }
50
51 //#define TRACE_BITMAP_DRAWS 35 //#define TRACE_BITMAP_DRAWS
52 36
53 #define kBlitterStorageLongCount (sizeof(SkBitmapProcShader) >> 2) 37 #define kBlitterStorageLongCount (sizeof(SkBitmapProcShader) >> 2)
54 38
55 /** Helper for allocating small blitters on the stack. 39 /** Helper for allocating small blitters on the stack.
56 */ 40 */
57 class SkAutoBlitterChoose : SkNoncopyable { 41 class SkAutoBlitterChoose : SkNoncopyable {
58 public: 42 public:
59 SkAutoBlitterChoose() { 43 SkAutoBlitterChoose() {
60 fBlitter = NULL; 44 fBlitter = NULL;
(...skipping 1390 matching lines...) Expand 10 before | Expand all | Expand 10 after
1451 const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0); 1435 const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0);
1452 1436
1453 x += autokern.adjust(glyph) + glyph.fAdvanceX; 1437 x += autokern.adjust(glyph) + glyph.fAdvanceX;
1454 y += glyph.fAdvanceY; 1438 y += glyph.fAdvanceY;
1455 } 1439 }
1456 stopVector->set(SkFixedToScalar(x), SkFixedToScalar(y)); 1440 stopVector->set(SkFixedToScalar(x), SkFixedToScalar(y));
1457 1441
1458 SkASSERT(text == stop); 1442 SkASSERT(text == stop);
1459 } 1443 }
1460 1444
1445 bool SkDraw::shouldDrawTextAsPaths(const SkPaint& paint, const SkMatrix& ctm) co nst {
1446 // we don't cache hairlines in the cache
robertphillips 2013/11/25 20:39:44 line up? or 1 line? Shouldn't this comment be "//
1447 if (SkPaint::kStroke_Style == paint.getStyle() &&
1448 0 == paint.getStrokeWidth()) {
1449 return true;
1450 }
1451
1452 // we don't cache perspective
1453 if (ctm.hasPerspective()) {
1454 return true;
1455 }
1456
1457 SkMatrix textM;
1458 return SkPaint::TooBigToUseCache(ctm, *paint.setTextMatrix(&textM));
1459 }
1460
1461 void SkDraw::drawText_asPaths(const char text[], size_t byteLength, 1461 void SkDraw::drawText_asPaths(const char text[], size_t byteLength,
1462 SkScalar x, SkScalar y, 1462 SkScalar x, SkScalar y,
1463 const SkPaint& paint) const { 1463 const SkPaint& paint) const {
1464 SkDEBUGCODE(this->validate();) 1464 SkDEBUGCODE(this->validate();)
1465 1465
1466 SkTextToPathIter iter(text, byteLength, paint, true); 1466 SkTextToPathIter iter(text, byteLength, paint, true);
1467 1467
1468 SkMatrix matrix; 1468 SkMatrix matrix;
1469 matrix.setScale(iter.getPathScale(), iter.getPathScale()); 1469 matrix.setScale(iter.getPathScale(), iter.getPathScale());
1470 matrix.postTranslate(x, y); 1470 matrix.postTranslate(x, y);
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after
1701 SkASSERT(byteLength == 0 || text != NULL); 1701 SkASSERT(byteLength == 0 || text != NULL);
1702 1702
1703 SkDEBUGCODE(this->validate();) 1703 SkDEBUGCODE(this->validate();)
1704 1704
1705 // nothing to draw 1705 // nothing to draw
1706 if (text == NULL || byteLength == 0 || fRC->isEmpty()) { 1706 if (text == NULL || byteLength == 0 || fRC->isEmpty()) {
1707 return; 1707 return;
1708 } 1708 }
1709 1709
1710 // SkScalarRec doesn't currently have a way of representing hairline stroke and 1710 // SkScalarRec doesn't currently have a way of representing hairline stroke and
1711 // will fill if its frame-width is 0. 1711 // will fill if its frame-width is 0.
robertphillips 2013/11/25 20:39:44 this->
1712 if (ShouldDrawTextAsPaths(paint, *fMatrix)) { 1712 if (shouldDrawTextAsPaths(paint, *fMatrix)) {
1713 this->drawText_asPaths(text, byteLength, x, y, paint); 1713 this->drawText_asPaths(text, byteLength, x, y, paint);
1714 return; 1714 return;
1715 } 1715 }
1716 1716
1717 SkDrawCacheProc glyphCacheProc = paint.getDrawCacheProc(); 1717 SkDrawCacheProc glyphCacheProc = paint.getDrawCacheProc();
1718 1718
1719 #if SK_DISTANCEFIELD_FONTS
1720 const SkMatrix* ctm = fMatrix;
1721 const SkPaint* paintRef = &paint;
1722 SkPaint paintCopy;
1723 uint32_t procFlags = fProcs ? fProcs->fFlags : 0;
1724 if (procFlags & SkDrawProcs::kUseScaledGlyphs_Flag) {
1725 paintCopy = paint;
1726 paintCopy.setTextSize(SkDrawProcs::kBaseDFFontSize);
1727 paintCopy.setLCDRenderText(false);
1728 paintRef = &paintCopy;
1729 }
1730 if (procFlags & SkDrawProcs::kSkipBakedGlyphTransform_Flag) {
1731 ctm = NULL;
1732 }
1733 SkAutoGlyphCache autoCache(*paintRef, &fDevice->fLeakyProperties, ctm);
1734 #else
1735 SkAutoGlyphCache autoCache(paint, &fDevice->fLeakyProperties, fMatrix); 1719 SkAutoGlyphCache autoCache(paint, &fDevice->fLeakyProperties, fMatrix);
1736 #endif
1737 SkGlyphCache* cache = autoCache.getCache(); 1720 SkGlyphCache* cache = autoCache.getCache();
1738 1721
1739 // transform our starting point 1722 // transform our starting point
1740 #if SK_DISTANCEFIELD_FONTS
1741 if (!(procFlags & SkDrawProcs::kSkipBakedGlyphTransform_Flag))
1742 #endif
1743 { 1723 {
1744 SkPoint loc; 1724 SkPoint loc;
1745 fMatrix->mapXY(x, y, &loc); 1725 fMatrix->mapXY(x, y, &loc);
1746 x = loc.fX; 1726 x = loc.fX;
1747 y = loc.fY; 1727 y = loc.fY;
1748 } 1728 }
1749 1729
1750 // need to measure first 1730 // need to measure first
1751 if (paint.getTextAlign() != SkPaint::kLeft_Align) { 1731 if (paint.getTextAlign() != SkPaint::kLeft_Align) {
1752 SkVector stop; 1732 SkVector stop;
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1791 d1g.fHalfSampleY = SK_FixedHalf; 1771 d1g.fHalfSampleY = SK_FixedHalf;
1792 } else if (kY_SkAxisAlignment == baseline) { 1772 } else if (kY_SkAxisAlignment == baseline) {
1793 fxMask = 0; 1773 fxMask = 0;
1794 d1g.fHalfSampleX = SK_FixedHalf; 1774 d1g.fHalfSampleX = SK_FixedHalf;
1795 } 1775 }
1796 } 1776 }
1797 1777
1798 SkFixed fx = SkScalarToFixed(x) + d1g.fHalfSampleX; 1778 SkFixed fx = SkScalarToFixed(x) + d1g.fHalfSampleX;
1799 SkFixed fy = SkScalarToFixed(y) + d1g.fHalfSampleY; 1779 SkFixed fy = SkScalarToFixed(y) + d1g.fHalfSampleY;
1800 1780
1801 #if SK_DISTANCEFIELD_FONTS
1802 SkFixed fixedScale;
1803 if (procFlags & SkDrawProcs::kUseScaledGlyphs_Flag) {
1804 fixedScale = SkScalarToFixed(paint.getTextSize()/(float)SkDrawProcs::kBa seDFFontSize);
1805 }
1806 #endif
1807 while (text < stop) { 1781 while (text < stop) {
1808 const SkGlyph& glyph = glyphCacheProc(cache, &text, fx & fxMask, fy & fy Mask); 1782 const SkGlyph& glyph = glyphCacheProc(cache, &text, fx & fxMask, fy & fy Mask);
1809 1783
1810 #if SK_DISTANCEFIELD_FONTS
1811 if (procFlags & SkDrawProcs::kUseScaledGlyphs_Flag) {
1812 fx += SkFixedMul_portable(autokern.adjust(glyph), fixedScale);
1813 } else {
1814 fx += autokern.adjust(glyph);
1815 }
1816 #else
1817 fx += autokern.adjust(glyph); 1784 fx += autokern.adjust(glyph);
1818 #endif
1819 1785
1820 if (glyph.fWidth) { 1786 if (glyph.fWidth) {
1821 proc(d1g, fx, fy, glyph); 1787 proc(d1g, fx, fy, glyph);
1822 } 1788 }
1823 1789
1824 #if SK_DISTANCEFIELD_FONTS
1825 if (procFlags & SkDrawProcs::kUseScaledGlyphs_Flag) {
1826 fx += SkFixedMul_portable(glyph.fAdvanceX, fixedScale);
1827 fy += SkFixedMul_portable(glyph.fAdvanceY, fixedScale);
1828 } else {
1829 fx += glyph.fAdvanceX;
1830 fy += glyph.fAdvanceY;
1831 }
1832 #else
1833 fx += glyph.fAdvanceX; 1790 fx += glyph.fAdvanceX;
1834 fy += glyph.fAdvanceY; 1791 fy += glyph.fAdvanceY;
1835 #endif
1836 } 1792 }
1837 } 1793 }
1838 1794
1839 // last parameter is interpreted as SkFixed [x, y] 1795 // last parameter is interpreted as SkFixed [x, y]
1840 // return the fixed position, which may be rounded or not by the caller 1796 // return the fixed position, which may be rounded or not by the caller
1841 // e.g. subpixel doesn't round 1797 // e.g. subpixel doesn't round
1842 typedef void (*AlignProc)(const SkPoint&, const SkGlyph&, SkIPoint*); 1798 typedef void (*AlignProc)(const SkPoint&, const SkGlyph&, SkIPoint*);
1843 1799
1844 static void leftAlignProc(const SkPoint& loc, const SkGlyph& glyph, 1800 static void leftAlignProc(const SkPoint& loc, const SkGlyph& glyph,
1845 SkIPoint* dst) { 1801 SkIPoint* dst) {
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
1975 int scalarsPerPosition, const SkPaint& paint) const { 1931 int scalarsPerPosition, const SkPaint& paint) const {
1976 SkASSERT(byteLength == 0 || text != NULL); 1932 SkASSERT(byteLength == 0 || text != NULL);
1977 SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition); 1933 SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition);
1978 1934
1979 SkDEBUGCODE(this->validate();) 1935 SkDEBUGCODE(this->validate();)
1980 1936
1981 // nothing to draw 1937 // nothing to draw
1982 if (text == NULL || byteLength == 0 || fRC->isEmpty()) { 1938 if (text == NULL || byteLength == 0 || fRC->isEmpty()) {
1983 return; 1939 return;
1984 } 1940 }
1985 1941
robertphillips 2013/11/25 20:39:44 this->
1986 if (ShouldDrawTextAsPaths(paint, *fMatrix)) { 1942 if (shouldDrawTextAsPaths(paint, *fMatrix)) {
1987 this->drawPosText_asPaths(text, byteLength, pos, constY, 1943 this->drawPosText_asPaths(text, byteLength, pos, constY,
1988 scalarsPerPosition, paint); 1944 scalarsPerPosition, paint);
1989 return; 1945 return;
1990 } 1946 }
1991 1947
1992 SkDrawCacheProc glyphCacheProc = paint.getDrawCacheProc(); 1948 SkDrawCacheProc glyphCacheProc = paint.getDrawCacheProc();
1993 #if SK_DISTANCEFIELD_FONTS
1994 const SkMatrix* ctm = fMatrix;
1995 const SkPaint* paintRef = &paint;
1996 SkPaint paintCopy;
1997 uint32_t procFlags = fProcs ? fProcs->fFlags : 0;
1998 if (procFlags & SkDrawProcs::kUseScaledGlyphs_Flag) {
1999 paintCopy = paint;
2000 paintCopy.setTextSize(SkDrawProcs::kBaseDFFontSize);
2001 paintRef = &paintCopy;
2002 }
2003 if (procFlags & SkDrawProcs::kSkipBakedGlyphTransform_Flag) {
2004 ctm = &SkMatrix::I();
2005 }
2006 SkAutoGlyphCache autoCache(*paintRef, &fDevice->fLeakyProperties, ctm);
2007 #else
2008 SkAutoGlyphCache autoCache(paint, &fDevice->fLeakyProperties, fMatrix); 1949 SkAutoGlyphCache autoCache(paint, &fDevice->fLeakyProperties, fMatrix);
2009 #endif
2010 SkGlyphCache* cache = autoCache.getCache(); 1950 SkGlyphCache* cache = autoCache.getCache();
2011 1951
2012 SkAAClipBlitterWrapper wrapper; 1952 SkAAClipBlitterWrapper wrapper;
2013 SkAutoBlitterChoose blitterChooser; 1953 SkAutoBlitterChoose blitterChooser;
2014 SkBlitter* blitter = NULL; 1954 SkBlitter* blitter = NULL;
2015 if (needsRasterTextBlit(*this)) { 1955 if (needsRasterTextBlit(*this)) {
2016 blitterChooser.choose(*fBitmap, *fMatrix, paint); 1956 blitterChooser.choose(*fBitmap, *fMatrix, paint);
2017 blitter = blitterChooser.get(); 1957 blitter = blitterChooser.get();
2018 if (fRC->isAA()) { 1958 if (fRC->isAA()) {
2019 wrapper.init(*fRC, blitter); 1959 wrapper.init(*fRC, blitter);
2020 blitter = wrapper.getBlitter(); 1960 blitter = wrapper.getBlitter();
2021 } 1961 }
2022 } 1962 }
2023 1963
2024 const char* stop = text + byteLength; 1964 const char* stop = text + byteLength;
2025 AlignProc alignProc = pick_align_proc(paint.getTextAlign()); 1965 AlignProc alignProc = pick_align_proc(paint.getTextAlign());
2026 SkDraw1Glyph d1g; 1966 SkDraw1Glyph d1g;
2027 SkDraw1Glyph::Proc proc = d1g.init(this, blitter, cache, paint); 1967 SkDraw1Glyph::Proc proc = d1g.init(this, blitter, cache, paint);
2028 #if SK_DISTANCEFIELD_FONTS
2029 TextMapState tms(*ctm, constY);
2030 #else
2031 TextMapState tms(*fMatrix, constY); 1968 TextMapState tms(*fMatrix, constY);
2032 #endif
2033 TextMapState::Proc tmsProc = tms.pickProc(scalarsPerPosition); 1969 TextMapState::Proc tmsProc = tms.pickProc(scalarsPerPosition);
2034 1970
2035 if (cache->isSubpixel()) { 1971 if (cache->isSubpixel()) {
2036 // maybe we should skip the rounding if linearText is set 1972 // maybe we should skip the rounding if linearText is set
2037 SkAxisAlignment baseline = SkComputeAxisAlignmentForHText(*fMatrix); 1973 SkAxisAlignment baseline = SkComputeAxisAlignmentForHText(*fMatrix);
2038 1974
2039 SkFixed fxMask = ~0; 1975 SkFixed fxMask = ~0;
2040 SkFixed fyMask = ~0; 1976 SkFixed fyMask = ~0;
2041 if (kX_SkAxisAlignment == baseline) { 1977 if (kX_SkAxisAlignment == baseline) {
2042 fyMask = 0; 1978 fyMask = 0;
2043 #ifndef SK_IGNORE_SUBPIXEL_AXIS_ALIGN_FIX 1979 #ifndef SK_IGNORE_SUBPIXEL_AXIS_ALIGN_FIX
2044 d1g.fHalfSampleY = SK_FixedHalf; 1980 d1g.fHalfSampleY = SK_FixedHalf;
2045 #endif 1981 #endif
2046 } else if (kY_SkAxisAlignment == baseline) { 1982 } else if (kY_SkAxisAlignment == baseline) {
2047 fxMask = 0; 1983 fxMask = 0;
2048 #ifndef SK_IGNORE_SUBPIXEL_AXIS_ALIGN_FIX 1984 #ifndef SK_IGNORE_SUBPIXEL_AXIS_ALIGN_FIX
2049 d1g.fHalfSampleX = SK_FixedHalf; 1985 d1g.fHalfSampleX = SK_FixedHalf;
2050 #endif 1986 #endif
2051 } 1987 }
2052 1988
2053 if (SkPaint::kLeft_Align == paint.getTextAlign()) { 1989 if (SkPaint::kLeft_Align == paint.getTextAlign()) {
2054 while (text < stop) { 1990 while (text < stop) {
2055 #if SK_DISTANCEFIELD_FONTS
2056 if (procFlags & SkDrawProcs::kSkipBakedGlyphTransform_Flag) {
2057 tms.fLoc.fX = *pos;
2058 tms.fLoc.fY = *(pos+1);
2059 } else {
2060 tmsProc(tms, pos);
2061 }
2062 #else
2063 tmsProc(tms, pos); 1991 tmsProc(tms, pos);
2064 #endif
2065 SkFixed fx = SkScalarToFixed(tms.fLoc.fX) + d1g.fHalfSampleX; 1992 SkFixed fx = SkScalarToFixed(tms.fLoc.fX) + d1g.fHalfSampleX;
2066 SkFixed fy = SkScalarToFixed(tms.fLoc.fY) + d1g.fHalfSampleY; 1993 SkFixed fy = SkScalarToFixed(tms.fLoc.fY) + d1g.fHalfSampleY;
2067 1994
2068 const SkGlyph& glyph = glyphCacheProc(cache, &text, 1995 const SkGlyph& glyph = glyphCacheProc(cache, &text,
2069 fx & fxMask, fy & fyMask); 1996 fx & fxMask, fy & fyMask);
2070 1997
2071 if (glyph.fWidth) { 1998 if (glyph.fWidth) {
2072 proc(d1g, fx, fy, glyph); 1999 proc(d1g, fx, fy, glyph);
2073 } 2000 }
2074 pos += scalarsPerPosition; 2001 pos += scalarsPerPosition;
(...skipping 797 matching lines...) Expand 10 before | Expand all | Expand 10 after
2872 mask->fImage = SkMask::AllocImage(size); 2799 mask->fImage = SkMask::AllocImage(size);
2873 memset(mask->fImage, 0, mask->computeImageSize()); 2800 memset(mask->fImage, 0, mask->computeImageSize());
2874 } 2801 }
2875 2802
2876 if (SkMask::kJustComputeBounds_CreateMode != mode) { 2803 if (SkMask::kJustComputeBounds_CreateMode != mode) {
2877 draw_into_mask(*mask, devPath, style); 2804 draw_into_mask(*mask, devPath, style);
2878 } 2805 }
2879 2806
2880 return true; 2807 return true;
2881 } 2808 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698