OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright 2010 Google Inc. | |
3 * | |
4 * Use of this source code is governed by a BSD-style license that can be | |
5 * found in the LICENSE file. | |
6 */ | |
7 | |
8 #include "GrTextContext.h" | |
9 #include "GrContext.h" | |
10 #include "GrFontScaler.h" | |
11 #include "GrTextUtils.h" | |
12 | |
13 #include "SkDrawFilter.h" | |
14 #include "SkGlyphCache.h" | |
15 #include "SkGrPriv.h" | |
16 #include "SkTextBlobRunIterator.h" | |
17 | |
18 GrTextContext::GrTextContext(GrContext* context, const SkSurfaceProps& surfacePr
ops) | |
19 : fFallbackTextContext(nullptr) | |
20 , fContext(context) | |
21 , fSurfaceProps(surfaceProps) { | |
22 } | |
23 | |
24 GrTextContext::~GrTextContext() { | |
25 delete fFallbackTextContext; | |
26 } | |
27 | |
28 void GrTextContext::drawText(GrDrawContext* dc, | |
29 const GrClip& clip, const GrPaint& paint, | |
30 const SkPaint& skPaint, const SkMatrix& viewMatrix, | |
31 const char text[], size_t byteLength, | |
32 SkScalar x, SkScalar y, const SkIRect& clipBounds)
{ | |
33 if (fContext->abandoned()) { | |
34 return; | |
35 } | |
36 | |
37 GrTextContext* textContext = this; | |
38 do { | |
39 if (textContext->canDraw(skPaint, viewMatrix)) { | |
40 textContext->onDrawText(dc, clip, paint, skPaint, viewMatrix, | |
41 text, byteLength, x, y, clipBounds); | |
42 return; | |
43 } | |
44 textContext = textContext->fFallbackTextContext; | |
45 } while (textContext); | |
46 | |
47 // fall back to drawing as a path | |
48 GrTextUtils::DrawTextAsPath(fContext, dc, clip, skPaint, viewMatrix, text, b
yteLength, x, y, | |
49 clipBounds); | |
50 } | |
51 | |
52 void GrTextContext::drawPosText(GrDrawContext* dc, | |
53 const GrClip& clip, const GrPaint& paint, | |
54 const SkPaint& skPaint, const SkMatrix& viewMatr
ix, | |
55 const char text[], size_t byteLength, | |
56 const SkScalar pos[], int scalarsPerPosition, | |
57 const SkPoint& offset, const SkIRect& clipBounds
) { | |
58 if (fContext->abandoned()) { | |
59 return; | |
60 } | |
61 | |
62 GrTextContext* textContext = this; | |
63 do { | |
64 if (textContext->canDraw(skPaint, viewMatrix)) { | |
65 textContext->onDrawPosText(dc, clip, paint, skPaint, viewMatrix, | |
66 text, byteLength, pos, | |
67 scalarsPerPosition, offset, clipBounds); | |
68 return; | |
69 } | |
70 textContext = textContext->fFallbackTextContext; | |
71 } while (textContext); | |
72 | |
73 // fall back to drawing as a path | |
74 GrTextUtils::DrawPosTextAsPath(fContext, dc, fSurfaceProps, clip, skPaint, v
iewMatrix, text, | |
75 byteLength, pos, scalarsPerPosition, offset,
clipBounds); | |
76 } | |
77 | |
78 bool GrTextContext::ShouldDisableLCD(const SkPaint& paint) { | |
79 if (!SkXfermode::AsMode(paint.getXfermode(), nullptr) || | |
80 paint.getMaskFilter() || | |
81 paint.getRasterizer() || | |
82 paint.getPathEffect() || | |
83 paint.isFakeBoldText() || | |
84 paint.getStyle() != SkPaint::kFill_Style) | |
85 { | |
86 return true; | |
87 } | |
88 return false; | |
89 } | |
90 | |
91 uint32_t GrTextContext::FilterTextFlags(const SkSurfaceProps& surfaceProps, cons
t SkPaint& paint) { | |
92 uint32_t flags = paint.getFlags(); | |
93 | |
94 if (!paint.isLCDRenderText() || !paint.isAntiAlias()) { | |
95 return flags; | |
96 } | |
97 | |
98 if (kUnknown_SkPixelGeometry == surfaceProps.pixelGeometry() || ShouldDisabl
eLCD(paint)) { | |
99 flags &= ~SkPaint::kLCDRenderText_Flag; | |
100 flags |= SkPaint::kGenA8FromLCD_Flag; | |
101 } | |
102 | |
103 return flags; | |
104 } | |
105 | |
106 void GrTextContext::drawTextBlob(GrDrawContext* dc, | |
107 const GrClip& clip, const SkPaint& skPaint, | |
108 const SkMatrix& viewMatrix, const SkTextBlob* b
lob, | |
109 SkScalar x, SkScalar y, | |
110 SkDrawFilter* drawFilter, const SkIRect& clipBo
unds) { | |
111 SkPaint runPaint = skPaint; | |
112 | |
113 SkTextBlobRunIterator it(blob); | |
114 for (;!it.done(); it.next()) { | |
115 size_t textLen = it.glyphCount() * sizeof(uint16_t); | |
116 const SkPoint& offset = it.offset(); | |
117 // applyFontToPaint() always overwrites the exact same attributes, | |
118 // so it is safe to not re-seed the paint for this reason. | |
119 it.applyFontToPaint(&runPaint); | |
120 | |
121 if (drawFilter && !drawFilter->filter(&runPaint, SkDrawFilter::kText_Typ
e)) { | |
122 // A false return from filter() means we should abort the current dr
aw. | |
123 runPaint = skPaint; | |
124 continue; | |
125 } | |
126 | |
127 runPaint.setFlags(FilterTextFlags(fSurfaceProps, runPaint)); | |
128 | |
129 GrPaint grPaint; | |
130 if (!SkPaintToGrPaint(fContext, runPaint, viewMatrix, &grPaint)) { | |
131 return; | |
132 } | |
133 | |
134 switch (it.positioning()) { | |
135 case SkTextBlob::kDefault_Positioning: | |
136 this->drawText(dc, clip, grPaint, runPaint, viewMatrix, (const char
*)it.glyphs(), | |
137 textLen, x + offset.x(), y + offset.y(), clipBounds); | |
138 break; | |
139 case SkTextBlob::kHorizontal_Positioning: | |
140 this->drawPosText(dc, clip, grPaint, runPaint, viewMatrix, (const ch
ar*)it.glyphs(), | |
141 textLen, it.pos(), 1, SkPoint::Make(x, y + offset.
y()), clipBounds); | |
142 break; | |
143 case SkTextBlob::kFull_Positioning: | |
144 this->drawPosText(dc, clip, grPaint, runPaint, viewMatrix, (const ch
ar*)it.glyphs(), | |
145 textLen, it.pos(), 2, SkPoint::Make(x, y), clipBou
nds); | |
146 break; | |
147 default: | |
148 SkFAIL("unhandled positioning mode"); | |
149 } | |
150 | |
151 if (drawFilter) { | |
152 // A draw filter may change the paint arbitrarily, so we must re-see
d in this case. | |
153 runPaint = skPaint; | |
154 } | |
155 } | |
156 } | |
157 | |
158 static void GlyphCacheAuxProc(void* data) { | |
159 GrFontScaler* scaler = (GrFontScaler*)data; | |
160 SkSafeUnref(scaler); | |
161 } | |
162 | |
163 GrFontScaler* GrTextContext::GetGrFontScaler(SkGlyphCache* cache) { | |
164 void* auxData; | |
165 GrFontScaler* scaler = nullptr; | |
166 | |
167 if (cache->getAuxProcData(GlyphCacheAuxProc, &auxData)) { | |
168 scaler = (GrFontScaler*)auxData; | |
169 } | |
170 if (nullptr == scaler) { | |
171 scaler = new GrFontScaler(cache); | |
172 cache->setAuxProc(GlyphCacheAuxProc, scaler); | |
173 } | |
174 | |
175 return scaler; | |
176 } | |
OLD | NEW |