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

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: Clean up formatting and address nits 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
« no previous file with comments | « include/gpu/GrDistanceFieldTextContext.h ('k') | src/core/SkDrawProcs.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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) {
1446 // hairline glyphs are fast enough so we don't need to cache them
1447 if (SkPaint::kStroke_Style == paint.getStyle() && 0 == paint.getStrokeWidth( )) {
1448 return true;
1449 }
1450
1451 // we don't cache perspective
1452 if (ctm.hasPerspective()) {
1453 return true;
1454 }
1455
1456 SkMatrix textM;
1457 return SkPaint::TooBigToUseCache(ctm, *paint.setTextMatrix(&textM));
1458 }
1459
1461 void SkDraw::drawText_asPaths(const char text[], size_t byteLength, 1460 void SkDraw::drawText_asPaths(const char text[], size_t byteLength,
1462 SkScalar x, SkScalar y, 1461 SkScalar x, SkScalar y,
1463 const SkPaint& paint) const { 1462 const SkPaint& paint) const {
1464 SkDEBUGCODE(this->validate();) 1463 SkDEBUGCODE(this->validate();)
1465 1464
1466 SkTextToPathIter iter(text, byteLength, paint, true); 1465 SkTextToPathIter iter(text, byteLength, paint, true);
1467 1466
1468 SkMatrix matrix; 1467 SkMatrix matrix;
1469 matrix.setScale(iter.getPathScale(), iter.getPathScale()); 1468 matrix.setScale(iter.getPathScale(), iter.getPathScale());
1470 matrix.postTranslate(x, y); 1469 matrix.postTranslate(x, y);
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after
1709 1708
1710 // SkScalarRec doesn't currently have a way of representing hairline stroke and 1709 // SkScalarRec doesn't currently have a way of representing hairline stroke and
1711 // will fill if its frame-width is 0. 1710 // will fill if its frame-width is 0.
1712 if (ShouldDrawTextAsPaths(paint, *fMatrix)) { 1711 if (ShouldDrawTextAsPaths(paint, *fMatrix)) {
1713 this->drawText_asPaths(text, byteLength, x, y, paint); 1712 this->drawText_asPaths(text, byteLength, x, y, paint);
1714 return; 1713 return;
1715 } 1714 }
1716 1715
1717 SkDrawCacheProc glyphCacheProc = paint.getDrawCacheProc(); 1716 SkDrawCacheProc glyphCacheProc = paint.getDrawCacheProc();
1718 1717
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); 1718 SkAutoGlyphCache autoCache(paint, &fDevice->fLeakyProperties, fMatrix);
1736 #endif
1737 SkGlyphCache* cache = autoCache.getCache(); 1719 SkGlyphCache* cache = autoCache.getCache();
1738 1720
1739 // transform our starting point 1721 // transform our starting point
1740 #if SK_DISTANCEFIELD_FONTS
1741 if (!(procFlags & SkDrawProcs::kSkipBakedGlyphTransform_Flag))
1742 #endif
1743 { 1722 {
1744 SkPoint loc; 1723 SkPoint loc;
1745 fMatrix->mapXY(x, y, &loc); 1724 fMatrix->mapXY(x, y, &loc);
1746 x = loc.fX; 1725 x = loc.fX;
1747 y = loc.fY; 1726 y = loc.fY;
1748 } 1727 }
1749 1728
1750 // need to measure first 1729 // need to measure first
1751 if (paint.getTextAlign() != SkPaint::kLeft_Align) { 1730 if (paint.getTextAlign() != SkPaint::kLeft_Align) {
1752 SkVector stop; 1731 SkVector stop;
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1791 d1g.fHalfSampleY = SK_FixedHalf; 1770 d1g.fHalfSampleY = SK_FixedHalf;
1792 } else if (kY_SkAxisAlignment == baseline) { 1771 } else if (kY_SkAxisAlignment == baseline) {
1793 fxMask = 0; 1772 fxMask = 0;
1794 d1g.fHalfSampleX = SK_FixedHalf; 1773 d1g.fHalfSampleX = SK_FixedHalf;
1795 } 1774 }
1796 } 1775 }
1797 1776
1798 SkFixed fx = SkScalarToFixed(x) + d1g.fHalfSampleX; 1777 SkFixed fx = SkScalarToFixed(x) + d1g.fHalfSampleX;
1799 SkFixed fy = SkScalarToFixed(y) + d1g.fHalfSampleY; 1778 SkFixed fy = SkScalarToFixed(y) + d1g.fHalfSampleY;
1800 1779
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) { 1780 while (text < stop) {
1808 const SkGlyph& glyph = glyphCacheProc(cache, &text, fx & fxMask, fy & fy Mask); 1781 const SkGlyph& glyph = glyphCacheProc(cache, &text, fx & fxMask, fy & fy Mask);
1809 1782
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); 1783 fx += autokern.adjust(glyph);
1818 #endif
1819 1784
1820 if (glyph.fWidth) { 1785 if (glyph.fWidth) {
1821 proc(d1g, fx, fy, glyph); 1786 proc(d1g, fx, fy, glyph);
1822 } 1787 }
1823 1788
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; 1789 fx += glyph.fAdvanceX;
1834 fy += glyph.fAdvanceY; 1790 fy += glyph.fAdvanceY;
1835 #endif
1836 } 1791 }
1837 } 1792 }
1838 1793
1839 // last parameter is interpreted as SkFixed [x, y] 1794 // last parameter is interpreted as SkFixed [x, y]
1840 // return the fixed position, which may be rounded or not by the caller 1795 // return the fixed position, which may be rounded or not by the caller
1841 // e.g. subpixel doesn't round 1796 // e.g. subpixel doesn't round
1842 typedef void (*AlignProc)(const SkPoint&, const SkGlyph&, SkIPoint*); 1797 typedef void (*AlignProc)(const SkPoint&, const SkGlyph&, SkIPoint*);
1843 1798
1844 static void leftAlignProc(const SkPoint& loc, const SkGlyph& glyph, SkIPoint* ds t) { 1799 static void leftAlignProc(const SkPoint& loc, const SkGlyph& glyph, SkIPoint* ds t) {
1845 dst->set(SkScalarToFixed(loc.fX), SkScalarToFixed(loc.fY)); 1800 dst->set(SkScalarToFixed(loc.fX), SkScalarToFixed(loc.fY));
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
2006 return; 1961 return;
2007 } 1962 }
2008 1963
2009 if (ShouldDrawTextAsPaths(paint, *fMatrix)) { 1964 if (ShouldDrawTextAsPaths(paint, *fMatrix)) {
2010 this->drawPosText_asPaths(text, byteLength, pos, constY, 1965 this->drawPosText_asPaths(text, byteLength, pos, constY,
2011 scalarsPerPosition, paint); 1966 scalarsPerPosition, paint);
2012 return; 1967 return;
2013 } 1968 }
2014 1969
2015 SkDrawCacheProc glyphCacheProc = paint.getDrawCacheProc(); 1970 SkDrawCacheProc glyphCacheProc = paint.getDrawCacheProc();
2016 #if SK_DISTANCEFIELD_FONTS
2017 const SkMatrix* ctm = fMatrix;
2018 const SkPaint* paintRef = &paint;
2019 SkPaint paintCopy;
2020 uint32_t procFlags = fProcs ? fProcs->fFlags : 0;
2021 if (procFlags & SkDrawProcs::kUseScaledGlyphs_Flag) {
2022 paintCopy = paint;
2023 paintCopy.setTextSize(SkDrawProcs::kBaseDFFontSize);
2024 paintRef = &paintCopy;
2025 }
2026 if (procFlags & SkDrawProcs::kSkipBakedGlyphTransform_Flag) {
2027 ctm = &SkMatrix::I();
2028 }
2029 SkAutoGlyphCache autoCache(*paintRef, &fDevice->fLeakyProperties, ctm);
2030 #else
2031 SkAutoGlyphCache autoCache(paint, &fDevice->fLeakyProperties, fMatrix); 1971 SkAutoGlyphCache autoCache(paint, &fDevice->fLeakyProperties, fMatrix);
2032 #endif
2033 SkGlyphCache* cache = autoCache.getCache(); 1972 SkGlyphCache* cache = autoCache.getCache();
2034 1973
2035 SkAAClipBlitterWrapper wrapper; 1974 SkAAClipBlitterWrapper wrapper;
2036 SkAutoBlitterChoose blitterChooser; 1975 SkAutoBlitterChoose blitterChooser;
2037 SkBlitter* blitter = NULL; 1976 SkBlitter* blitter = NULL;
2038 if (needsRasterTextBlit(*this)) { 1977 if (needsRasterTextBlit(*this)) {
2039 blitterChooser.choose(*fBitmap, *fMatrix, paint); 1978 blitterChooser.choose(*fBitmap, *fMatrix, paint);
2040 blitter = blitterChooser.get(); 1979 blitter = blitterChooser.get();
2041 if (fRC->isAA()) { 1980 if (fRC->isAA()) {
2042 wrapper.init(*fRC, blitter); 1981 wrapper.init(*fRC, blitter);
2043 blitter = wrapper.getBlitter(); 1982 blitter = wrapper.getBlitter();
2044 } 1983 }
2045 } 1984 }
2046 1985
2047 const char* stop = text + byteLength; 1986 const char* stop = text + byteLength;
2048 AlignProc alignProc = pick_align_proc(paint.getTextAlign()); 1987 AlignProc alignProc = pick_align_proc(paint.getTextAlign());
2049 SkDraw1Glyph d1g; 1988 SkDraw1Glyph d1g;
2050 SkDraw1Glyph::Proc proc = d1g.init(this, blitter, cache, paint); 1989 SkDraw1Glyph::Proc proc = d1g.init(this, blitter, cache, paint);
2051 #if SK_DISTANCEFIELD_FONTS
2052 TextMapState tms(*ctm, constY);
2053 #else
2054 TextMapState tms(*fMatrix, constY); 1990 TextMapState tms(*fMatrix, constY);
2055 #endif
2056 TextMapState::Proc tmsProc = tms.pickProc(scalarsPerPosition); 1991 TextMapState::Proc tmsProc = tms.pickProc(scalarsPerPosition);
2057 1992
2058 if (cache->isSubpixel()) { 1993 if (cache->isSubpixel()) {
2059 // maybe we should skip the rounding if linearText is set 1994 // maybe we should skip the rounding if linearText is set
2060 SkAxisAlignment baseline = SkComputeAxisAlignmentForHText(*fMatrix); 1995 SkAxisAlignment baseline = SkComputeAxisAlignmentForHText(*fMatrix);
2061 1996
2062 SkFixed fxMask = ~0; 1997 SkFixed fxMask = ~0;
2063 SkFixed fyMask = ~0; 1998 SkFixed fyMask = ~0;
2064 if (kX_SkAxisAlignment == baseline) { 1999 if (kX_SkAxisAlignment == baseline) {
2065 fyMask = 0; 2000 fyMask = 0;
2066 #ifndef SK_IGNORE_SUBPIXEL_AXIS_ALIGN_FIX 2001 #ifndef SK_IGNORE_SUBPIXEL_AXIS_ALIGN_FIX
2067 d1g.fHalfSampleY = SK_FixedHalf; 2002 d1g.fHalfSampleY = SK_FixedHalf;
2068 #endif 2003 #endif
2069 } else if (kY_SkAxisAlignment == baseline) { 2004 } else if (kY_SkAxisAlignment == baseline) {
2070 fxMask = 0; 2005 fxMask = 0;
2071 #ifndef SK_IGNORE_SUBPIXEL_AXIS_ALIGN_FIX 2006 #ifndef SK_IGNORE_SUBPIXEL_AXIS_ALIGN_FIX
2072 d1g.fHalfSampleX = SK_FixedHalf; 2007 d1g.fHalfSampleX = SK_FixedHalf;
2073 #endif 2008 #endif
2074 } 2009 }
2075 2010
2076 if (SkPaint::kLeft_Align == paint.getTextAlign()) { 2011 if (SkPaint::kLeft_Align == paint.getTextAlign()) {
2077 while (text < stop) { 2012 while (text < stop) {
2078 #if SK_DISTANCEFIELD_FONTS
2079 if (procFlags & SkDrawProcs::kSkipBakedGlyphTransform_Flag) {
2080 tms.fLoc.fX = *pos;
2081 tms.fLoc.fY = *(pos+1);
2082 } else {
2083 tmsProc(tms, pos);
2084 }
2085 #else
2086 tmsProc(tms, pos); 2013 tmsProc(tms, pos);
2087 #endif
2088 SkFixed fx = SkScalarToFixed(tms.fLoc.fX) + d1g.fHalfSampleX; 2014 SkFixed fx = SkScalarToFixed(tms.fLoc.fX) + d1g.fHalfSampleX;
2089 SkFixed fy = SkScalarToFixed(tms.fLoc.fY) + d1g.fHalfSampleY; 2015 SkFixed fy = SkScalarToFixed(tms.fLoc.fY) + d1g.fHalfSampleY;
2090 2016
2091 const SkGlyph& glyph = glyphCacheProc(cache, &text, 2017 const SkGlyph& glyph = glyphCacheProc(cache, &text,
2092 fx & fxMask, fy & fyMask); 2018 fx & fxMask, fy & fyMask);
2093 2019
2094 if (glyph.fWidth) { 2020 if (glyph.fWidth) {
2095 proc(d1g, fx, fy, glyph); 2021 proc(d1g, fx, fy, glyph);
2096 } 2022 }
2097 pos += scalarsPerPosition; 2023 pos += scalarsPerPosition;
(...skipping 797 matching lines...) Expand 10 before | Expand all | Expand 10 after
2895 mask->fImage = SkMask::AllocImage(size); 2821 mask->fImage = SkMask::AllocImage(size);
2896 memset(mask->fImage, 0, mask->computeImageSize()); 2822 memset(mask->fImage, 0, mask->computeImageSize());
2897 } 2823 }
2898 2824
2899 if (SkMask::kJustComputeBounds_CreateMode != mode) { 2825 if (SkMask::kJustComputeBounds_CreateMode != mode) {
2900 draw_into_mask(*mask, devPath, style); 2826 draw_into_mask(*mask, devPath, style);
2901 } 2827 }
2902 2828
2903 return true; 2829 return true;
2904 } 2830 }
OLDNEW
« no previous file with comments | « include/gpu/GrDistanceFieldTextContext.h ('k') | src/core/SkDrawProcs.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698