OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2013 Google Inc. | 2 * Copyright 2013 Google Inc. |
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 #include "GrBitmapTextContext.h" | 7 #include "GrBitmapTextContext.h" |
8 | 8 |
9 #include "GrAtlas.h" | 9 #include "GrAtlas.h" |
10 #include "GrBatch.h" | 10 #include "GrBatch.h" |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
94 } | 94 } |
95 | 95 |
96 bool GrBitmapTextContextB::MustRegenerateBlob(const BitmapTextBlob& blob, const
SkPaint& paint, | 96 bool GrBitmapTextContextB::MustRegenerateBlob(const BitmapTextBlob& blob, const
SkPaint& paint, |
97 const SkMatrix& viewMatrix, SkScala
r x, SkScalar y) { | 97 const SkMatrix& viewMatrix, SkScala
r x, SkScalar y) { |
98 // We always regenerate blobs with patheffects or mask filters we could cach
e these | 98 // We always regenerate blobs with patheffects or mask filters we could cach
e these |
99 // TODO find some way to cache the maskfilter / patheffects on the textblob | 99 // TODO find some way to cache the maskfilter / patheffects on the textblob |
100 return !blob.fViewMatrix.cheapEqualTo(viewMatrix) || blob.fX != x || blob.fY
!= y || | 100 return !blob.fViewMatrix.cheapEqualTo(viewMatrix) || blob.fX != x || blob.fY
!= y || |
101 paint.getMaskFilter() || paint.getPathEffect() || paint.getStyle() !
= blob.fStyle; | 101 paint.getMaskFilter() || paint.getPathEffect() || paint.getStyle() !
= blob.fStyle; |
102 } | 102 } |
103 | 103 |
| 104 |
| 105 inline SkGlyphCache* GrBitmapTextContextB::setupCache(BitmapTextBlob::Run* run, |
| 106 const SkPaint& skPaint, |
| 107 const SkMatrix& viewMatrix
) { |
| 108 skPaint.getScalerContextDescriptor(&run->fDescriptor, &fDeviceProperties, &v
iewMatrix, false); |
| 109 run->fTypeface.reset(SkSafeRef(skPaint.getTypeface())); |
| 110 return SkGlyphCache::DetachCache(run->fTypeface, run->fDescriptor.getDesc())
; |
| 111 } |
| 112 |
| 113 inline void GrBitmapTextContextB::BlobGlyphCount(int* glyphCount, int* runCount, |
| 114 const SkTextBlob* blob) { |
| 115 SkTextBlob::RunIterator itCounter(blob); |
| 116 for (; !itCounter.done(); itCounter.next(), (*runCount)++) { |
| 117 *glyphCount += itCounter.glyphCount(); |
| 118 } |
| 119 } |
| 120 |
| 121 GrBitmapTextContextB::BitmapTextBlob* GrBitmapTextContextB::CreateBlob(int glyph
Count, |
| 122 int runCo
unt) { |
| 123 // We allocate size for the BitmapTextBlob itself, plus size for the vertice
s array, |
| 124 // and size for the glyphIds array. |
| 125 SK_COMPILE_ASSERT(kGrayTextVASize >= kColorTextVASize && kGrayTextVASize >=
kLCDTextVASize, |
| 126 vertex_attribute_changed); |
| 127 size_t verticesCount = glyphCount * kVerticesPerGlyph * kGrayTextVASize; |
| 128 size_t length = sizeof(BitmapTextBlob) + |
| 129 verticesCount + |
| 130 glyphCount * sizeof(GrGlyph::PackedID) + |
| 131 sizeof(BitmapTextBlob::Run) * runCount; |
| 132 |
| 133 BitmapTextBlob* cacheBlob = SkNEW_PLACEMENT(sk_malloc_throw(length), BitmapT
extBlob); |
| 134 |
| 135 // setup offsets for vertices / glyphs |
| 136 cacheBlob->fVertices = sizeof(BitmapTextBlob) + reinterpret_cast<unsigned ch
ar*>(cacheBlob); |
| 137 cacheBlob->fGlyphIDs = |
| 138 reinterpret_cast<GrGlyph::PackedID*>(cacheBlob->fVertices + vertices
Count); |
| 139 cacheBlob->fRuns = reinterpret_cast<BitmapTextBlob::Run*>(cacheBlob->fGlyphI
Ds + glyphCount); |
| 140 |
| 141 // Initialize runs |
| 142 for (int i = 0; i < runCount; i++) { |
| 143 SkNEW_PLACEMENT(&cacheBlob->fRuns[i], BitmapTextBlob::Run); |
| 144 } |
| 145 cacheBlob->fRunCount = runCount; |
| 146 return cacheBlob; |
| 147 } |
| 148 |
104 void GrBitmapTextContextB::drawTextBlob(GrRenderTarget* rt, const GrClip& clip, | 149 void GrBitmapTextContextB::drawTextBlob(GrRenderTarget* rt, const GrClip& clip, |
105 const SkPaint& skPaint, const SkMatrix&
viewMatrix, | 150 const SkPaint& skPaint, const SkMatrix&
viewMatrix, |
106 const SkTextBlob* blob, SkScalar x, SkSc
alar y, | 151 const SkTextBlob* blob, SkScalar x, SkSc
alar y, |
107 SkDrawFilter* drawFilter, const SkIRect&
clipBounds) { | 152 SkDrawFilter* drawFilter, const SkIRect&
clipBounds) { |
108 BitmapTextBlob* cacheBlob; | 153 BitmapTextBlob* cacheBlob; |
109 BitmapTextBlob** foundBlob = fCache.find(blob->uniqueID()); | 154 BitmapTextBlob** foundBlob = fCache.find(blob->uniqueID()); |
110 | |
111 SkIRect clipRect; | 155 SkIRect clipRect; |
112 clip.getConservativeBounds(rt->width(), rt->height(), &clipRect); | 156 clip.getConservativeBounds(rt->width(), rt->height(), &clipRect); |
113 | 157 |
114 if (foundBlob) { | 158 if (foundBlob) { |
115 cacheBlob = *foundBlob; | 159 cacheBlob = *foundBlob; |
116 if (MustRegenerateBlob(*cacheBlob, skPaint, viewMatrix, x, y)) { | 160 if (MustRegenerateBlob(*cacheBlob, skPaint, viewMatrix, x, y)) { |
117 // We can get away with reusing the blob if there are no outstanding
refs on it. | 161 // We have to remake the blob because changes may invalidate our mas
ks. |
118 // However, we still have to reset all of the runs. | 162 // TODO we could probably get away reuse most of the time if the poi
nter is unique, |
119 if (!cacheBlob->unique()) { | 163 // but we'd have to clear the subrun information |
120 cacheBlob->unref(); | 164 cacheBlob->unref(); |
121 cacheBlob = SkNEW(BitmapTextBlob); | 165 int glyphCount = 0; |
122 fCache.set(blob->uniqueID(), cacheBlob); | 166 int runCount = 0; |
123 } | 167 BlobGlyphCount(&glyphCount, &runCount, blob); |
| 168 cacheBlob = CreateBlob(glyphCount, runCount); |
| 169 fCache.set(blob->uniqueID(), cacheBlob); |
124 this->regenerateTextBlob(cacheBlob, skPaint, viewMatrix, blob, x, y,
drawFilter, | 170 this->regenerateTextBlob(cacheBlob, skPaint, viewMatrix, blob, x, y,
drawFilter, |
125 clipRect); | 171 clipRect); |
126 } | 172 } |
127 } else { | 173 } else { |
128 cacheBlob = SkNEW(BitmapTextBlob); | 174 int glyphCount = 0; |
| 175 int runCount = 0; |
| 176 BlobGlyphCount(&glyphCount, &runCount, blob); |
| 177 cacheBlob = CreateBlob(glyphCount, runCount); |
129 fCache.set(blob->uniqueID(), cacheBlob); | 178 fCache.set(blob->uniqueID(), cacheBlob); |
130 this->regenerateTextBlob(cacheBlob, skPaint, viewMatrix, blob, x, y, dra
wFilter, clipRect); | 179 this->regenerateTextBlob(cacheBlob, skPaint, viewMatrix, blob, x, y, dra
wFilter, clipRect); |
131 } | 180 } |
132 | 181 |
133 // Though for the time being runs in the textblob can override the paint, th
ey only touch font | 182 // Though for the time being runs in the textblob can override the paint, th
ey only touch font |
134 // info. | 183 // info. |
135 GrPaint grPaint; | 184 GrPaint grPaint; |
136 SkPaint2GrPaintShader(fContext, rt, skPaint, viewMatrix, true, &grPaint); | 185 SkPaint2GrPaintShader(fContext, rt, skPaint, viewMatrix, true, &grPaint); |
137 | 186 |
138 this->flush(fContext->getTextTarget(), cacheBlob, rt, grPaint, clip, viewMat
rix, | 187 this->flush(fContext->getTextTarget(), cacheBlob, rt, grPaint, clip, viewMat
rix, |
139 fSkPaint.getAlpha()); | 188 fSkPaint.getAlpha()); |
140 } | 189 } |
141 | 190 |
142 void GrBitmapTextContextB::regenerateTextBlob(BitmapTextBlob* cacheBlob, | 191 void GrBitmapTextContextB::regenerateTextBlob(BitmapTextBlob* cacheBlob, |
143 const SkPaint& skPaint, const SkMa
trix& viewMatrix, | 192 const SkPaint& skPaint, const SkMa
trix& viewMatrix, |
144 const SkTextBlob* blob, SkScalar x
, SkScalar y, | 193 const SkTextBlob* blob, SkScalar x
, SkScalar y, |
145 SkDrawFilter* drawFilter, const Sk
IRect& clipRect) { | 194 SkDrawFilter* drawFilter, const Sk
IRect& clipRect) { |
146 cacheBlob->fViewMatrix = viewMatrix; | 195 cacheBlob->fViewMatrix = viewMatrix; |
147 cacheBlob->fX = x; | 196 cacheBlob->fX = x; |
148 cacheBlob->fY = y; | 197 cacheBlob->fY = y; |
149 cacheBlob->fStyle = skPaint.getStyle(); | 198 cacheBlob->fStyle = skPaint.getStyle(); |
150 cacheBlob->fRuns.reset(blob->fRunCount); | |
151 | 199 |
152 // Regenerate textblob | 200 // Regenerate textblob |
153 SkPaint runPaint = skPaint; | 201 SkPaint runPaint = skPaint; |
154 SkTextBlob::RunIterator it(blob); | 202 SkTextBlob::RunIterator it(blob); |
155 for (int run = 0; !it.done(); it.next(), run++) { | 203 for (int run = 0; !it.done(); it.next(), run++) { |
156 size_t textLen = it.glyphCount() * sizeof(uint16_t); | 204 int glyphCount = it.glyphCount(); |
| 205 size_t textLen = glyphCount * sizeof(uint16_t); |
157 const SkPoint& offset = it.offset(); | 206 const SkPoint& offset = it.offset(); |
158 // applyFontToPaint() always overwrites the exact same attributes, | 207 // applyFontToPaint() always overwrites the exact same attributes, |
159 // so it is safe to not re-seed the paint for this reason. | 208 // so it is safe to not re-seed the paint for this reason. |
160 it.applyFontToPaint(&runPaint); | 209 it.applyFontToPaint(&runPaint); |
161 | 210 |
162 if (drawFilter && !drawFilter->filter(&runPaint, SkDrawFilter::kText_Typ
e)) { | 211 if (drawFilter && !drawFilter->filter(&runPaint, SkDrawFilter::kText_Typ
e)) { |
163 // A false return from filter() means we should abort the current dr
aw. | 212 // A false return from filter() means we should abort the current dr
aw. |
164 runPaint = skPaint; | 213 runPaint = skPaint; |
165 continue; | 214 continue; |
166 } | 215 } |
167 | 216 |
168 runPaint.setFlags(fGpuDevice->filterTextFlags(runPaint)); | 217 runPaint.setFlags(fGpuDevice->filterTextFlags(runPaint)); |
169 | 218 |
| 219 SkGlyphCache* cache = this->setupCache(&cacheBlob->fRuns[run], runPaint,
viewMatrix); |
| 220 |
| 221 // setup vertex / glyphIndex for the new run |
| 222 if (run > 0) { |
| 223 PerSubRunInfo& newRun = cacheBlob->fRuns[run].fSubRunInfo.back(); |
| 224 PerSubRunInfo& lastRun = cacheBlob->fRuns[run - 1].fSubRunInfo.back(
); |
| 225 |
| 226 newRun.fVertexStartIndex = lastRun.fVertexEndIndex; |
| 227 newRun.fVertexEndIndex = lastRun.fVertexEndIndex; |
| 228 |
| 229 newRun.fGlyphStartIndex = lastRun.fGlyphEndIndex; |
| 230 newRun.fGlyphEndIndex = lastRun.fGlyphEndIndex; |
| 231 } |
| 232 |
170 switch (it.positioning()) { | 233 switch (it.positioning()) { |
171 case SkTextBlob::kDefault_Positioning: | 234 case SkTextBlob::kDefault_Positioning: |
172 this->internalDrawText(cacheBlob, run, runPaint, viewMatrix, | 235 this->internalDrawText(cacheBlob, run, cache, runPaint, viewMatr
ix, |
173 (const char *)it.glyphs(), textLen, | 236 (const char *)it.glyphs(), textLen, |
174 x + offset.x(), y + offset.y(), clipRect)
; | 237 x + offset.x(), y + offset.y(), clipRect)
; |
175 break; | 238 break; |
176 case SkTextBlob::kHorizontal_Positioning: | 239 case SkTextBlob::kHorizontal_Positioning: |
177 this->internalDrawPosText(cacheBlob, run, runPaint, viewMatrix, | 240 this->internalDrawPosText(cacheBlob, run, cache, runPaint, viewM
atrix, |
178 (const char*)it.glyphs(), textLen, it.
pos(), 1, | 241 (const char*)it.glyphs(), textLen, it.
pos(), 1, |
179 SkPoint::Make(x, y + offset.y()), clip
Rect); | 242 SkPoint::Make(x, y + offset.y()), clip
Rect); |
180 break; | 243 break; |
181 case SkTextBlob::kFull_Positioning: | 244 case SkTextBlob::kFull_Positioning: |
182 this->internalDrawPosText(cacheBlob, run, runPaint, viewMatrix, | 245 this->internalDrawPosText(cacheBlob, run, cache, runPaint, viewM
atrix, |
183 (const char*)it.glyphs(), textLen, it.
pos(), 2, | 246 (const char*)it.glyphs(), textLen, it.
pos(), 2, |
184 SkPoint::Make(x, y), clipRect); | 247 SkPoint::Make(x, y), clipRect); |
185 break; | 248 break; |
186 } | 249 } |
187 | 250 |
188 if (drawFilter) { | 251 if (drawFilter) { |
189 // A draw filter may change the paint arbitrarily, so we must re-see
d in this case. | 252 // A draw filter may change the paint arbitrarily, so we must re-see
d in this case. |
190 runPaint = skPaint; | 253 runPaint = skPaint; |
191 } | 254 } |
| 255 |
| 256 SkGlyphCache::AttachCache(cache); |
192 } | 257 } |
193 } | 258 } |
194 | 259 |
195 void GrBitmapTextContextB::onDrawText(GrRenderTarget* rt, const GrClip& clip, | 260 void GrBitmapTextContextB::onDrawText(GrRenderTarget* rt, const GrClip& clip, |
196 const GrPaint& paint, const SkPaint& skPain
t, | 261 const GrPaint& paint, const SkPaint& skPain
t, |
197 const SkMatrix& viewMatrix, | 262 const SkMatrix& viewMatrix, |
198 const char text[], size_t byteLength, | 263 const char text[], size_t byteLength, |
199 SkScalar x, SkScalar y, const SkIRect& regi
onClipBounds) { | 264 SkScalar x, SkScalar y, const SkIRect& regi
onClipBounds) { |
200 SkAutoTUnref<BitmapTextBlob> blob(SkNEW(BitmapTextBlob)); | 265 int glyphCount = skPaint.countText(text, byteLength); |
| 266 SkAutoTUnref<BitmapTextBlob> blob(CreateBlob(glyphCount, 1)); |
201 blob->fViewMatrix = viewMatrix; | 267 blob->fViewMatrix = viewMatrix; |
202 blob->fX = x; | 268 blob->fX = x; |
203 blob->fY = y; | 269 blob->fY = y; |
204 blob->fStyle = skPaint.getStyle(); | 270 blob->fStyle = skPaint.getStyle(); |
205 blob->fRuns.push_back(); | |
206 | 271 |
207 SkIRect clipRect; | 272 SkIRect clipRect; |
208 clip.getConservativeBounds(rt->width(), rt->height(), &clipRect); | 273 clip.getConservativeBounds(rt->width(), rt->height(), &clipRect); |
209 this->internalDrawText(blob, 0, skPaint, viewMatrix, text, byteLength, x, y,
clipRect); | 274 |
| 275 // setup cache |
| 276 SkGlyphCache* cache = this->setupCache(&blob->fRuns[0], skPaint, viewMatrix)
; |
| 277 this->internalDrawText(blob, 0, cache, skPaint, viewMatrix, text, byteLength
, x, y, clipRect); |
| 278 SkGlyphCache::AttachCache(cache); |
| 279 |
210 this->flush(fContext->getTextTarget(), blob, rt, paint, clip, viewMatrix, sk
Paint.getAlpha()); | 280 this->flush(fContext->getTextTarget(), blob, rt, paint, clip, viewMatrix, sk
Paint.getAlpha()); |
211 } | 281 } |
212 | 282 |
213 void GrBitmapTextContextB::internalDrawText(BitmapTextBlob* blob, int runIndex, | 283 void GrBitmapTextContextB::internalDrawText(BitmapTextBlob* blob, int runIndex, |
214 const SkPaint& skPaint, | 284 SkGlyphCache* cache, const SkPaint&
skPaint, |
215 const SkMatrix& viewMatrix, | 285 const SkMatrix& viewMatrix, |
216 const char text[], size_t byteLength, | 286 const char text[], size_t byteLength, |
217 SkScalar x, SkScalar y, const SkIRect
& clipRect) { | 287 SkScalar x, SkScalar y, const SkIRect
& clipRect) { |
218 SkASSERT(byteLength == 0 || text != NULL); | 288 SkASSERT(byteLength == 0 || text != NULL); |
219 | 289 |
220 // nothing to draw | 290 // nothing to draw |
221 if (text == NULL || byteLength == 0) { | 291 if (text == NULL || byteLength == 0) { |
222 return; | 292 return; |
223 } | 293 } |
224 | 294 |
225 fCurrStrike = NULL; | 295 fCurrStrike = NULL; |
226 SkDrawCacheProc glyphCacheProc = skPaint.getDrawCacheProc(); | 296 SkDrawCacheProc glyphCacheProc = skPaint.getDrawCacheProc(); |
227 | 297 |
228 // Get GrFontScaler from cache | 298 // Get GrFontScaler from cache |
229 BitmapTextBlob::Run& run = blob->fRuns[runIndex]; | |
230 run.fDescriptor.reset(skPaint.getScalerContextDescriptor(&fDeviceProperties,
&viewMatrix, | |
231 false)); | |
232 run.fTypeface.reset(SkSafeRef(skPaint.getTypeface())); | |
233 const SkDescriptor* desc = reinterpret_cast<const SkDescriptor*>(run.fDescri
ptor->data()); | |
234 SkGlyphCache* cache = SkGlyphCache::DetachCache(run.fTypeface, desc); | |
235 GrFontScaler* fontScaler = GetGrFontScaler(cache); | 299 GrFontScaler* fontScaler = GetGrFontScaler(cache); |
236 | 300 |
237 // transform our starting point | 301 // transform our starting point |
238 { | 302 { |
239 SkPoint loc; | 303 SkPoint loc; |
240 viewMatrix.mapXY(x, y, &loc); | 304 viewMatrix.mapXY(x, y, &loc); |
241 x = loc.fX; | 305 x = loc.fX; |
242 y = loc.fY; | 306 y = loc.fY; |
243 } | 307 } |
244 | 308 |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
296 GrGlyph::kCoverage_MaskStyle), | 360 GrGlyph::kCoverage_MaskStyle), |
297 Sk48Dot16FloorToInt(fx), | 361 Sk48Dot16FloorToInt(fx), |
298 Sk48Dot16FloorToInt(fy), | 362 Sk48Dot16FloorToInt(fy), |
299 fontScaler, | 363 fontScaler, |
300 clipRect); | 364 clipRect); |
301 } | 365 } |
302 | 366 |
303 fx += glyph.fAdvanceX; | 367 fx += glyph.fAdvanceX; |
304 fy += glyph.fAdvanceY; | 368 fy += glyph.fAdvanceY; |
305 } | 369 } |
306 | |
307 SkGlyphCache::AttachCache(cache); | |
308 } | 370 } |
309 | 371 |
310 void GrBitmapTextContextB::onDrawPosText(GrRenderTarget* rt, const GrClip& clip, | 372 void GrBitmapTextContextB::onDrawPosText(GrRenderTarget* rt, const GrClip& clip, |
311 const GrPaint& paint, const SkPaint& skP
aint, | 373 const GrPaint& paint, const SkPaint& skP
aint, |
312 const SkMatrix& viewMatrix, | 374 const SkMatrix& viewMatrix, |
313 const char text[], size_t byteLength, | 375 const char text[], size_t byteLength, |
314 const SkScalar pos[], int scalarsPerPosi
tion, | 376 const SkScalar pos[], int scalarsPerPosi
tion, |
315 const SkPoint& offset, const SkIRect& re
gionClipBounds) { | 377 const SkPoint& offset, const SkIRect& re
gionClipBounds) { |
316 SkAutoTUnref<BitmapTextBlob> blob(SkNEW(BitmapTextBlob)); | 378 int glyphCount = skPaint.countText(text, byteLength); |
| 379 SkAutoTUnref<BitmapTextBlob> blob(CreateBlob(glyphCount, 1)); |
317 blob->fStyle = skPaint.getStyle(); | 380 blob->fStyle = skPaint.getStyle(); |
318 blob->fRuns.push_back(); | |
319 blob->fViewMatrix = viewMatrix; | 381 blob->fViewMatrix = viewMatrix; |
320 | 382 |
321 SkIRect clipRect; | 383 SkIRect clipRect; |
322 clip.getConservativeBounds(rt->width(), rt->height(), &clipRect); | 384 clip.getConservativeBounds(rt->width(), rt->height(), &clipRect); |
323 this->internalDrawPosText(blob, 0, skPaint, viewMatrix, text, byteLength, po
s, | 385 |
| 386 // setup cache |
| 387 SkGlyphCache* cache = this->setupCache(&blob->fRuns[0], skPaint, viewMatrix)
; |
| 388 this->internalDrawPosText(blob, 0, cache, skPaint, viewMatrix, text, byteLen
gth, pos, |
324 scalarsPerPosition, offset, clipRect); | 389 scalarsPerPosition, offset, clipRect); |
| 390 SkGlyphCache::AttachCache(cache); |
| 391 |
325 this->flush(fContext->getTextTarget(), blob, rt, paint, clip, viewMatrix, fS
kPaint.getAlpha()); | 392 this->flush(fContext->getTextTarget(), blob, rt, paint, clip, viewMatrix, fS
kPaint.getAlpha()); |
326 } | 393 } |
327 | 394 |
328 void GrBitmapTextContextB::internalDrawPosText(BitmapTextBlob* blob, int runInde
x, | 395 void GrBitmapTextContextB::internalDrawPosText(BitmapTextBlob* blob, int runInde
x, |
329 const SkPaint& skPaint, | 396 SkGlyphCache* cache, const SkPain
t& skPaint, |
330 const SkMatrix& viewMatrix, | 397 const SkMatrix& viewMatrix, |
331 const char text[], size_t byteLeng
th, | 398 const char text[], size_t byteLeng
th, |
332 const SkScalar pos[], int scalarsP
erPosition, | 399 const SkScalar pos[], int scalarsP
erPosition, |
333 const SkPoint& offset, const SkIRe
ct& clipRect) { | 400 const SkPoint& offset, const SkIRe
ct& clipRect) { |
334 SkASSERT(byteLength == 0 || text != NULL); | 401 SkASSERT(byteLength == 0 || text != NULL); |
335 SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition); | 402 SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition); |
336 | 403 |
337 // nothing to draw | 404 // nothing to draw |
338 if (text == NULL || byteLength == 0) { | 405 if (text == NULL || byteLength == 0) { |
339 return; | 406 return; |
340 } | 407 } |
341 | 408 |
342 fCurrStrike = NULL; | 409 fCurrStrike = NULL; |
343 SkDrawCacheProc glyphCacheProc = skPaint.getDrawCacheProc(); | 410 SkDrawCacheProc glyphCacheProc = skPaint.getDrawCacheProc(); |
344 | 411 |
345 // Get GrFontScaler from cache | 412 // Get GrFontScaler from cache |
346 BitmapTextBlob::Run& run = blob->fRuns[runIndex]; | |
347 run.fDescriptor.reset(skPaint.getScalerContextDescriptor(&fDeviceProperties,
&viewMatrix, | |
348 false)); | |
349 run.fTypeface.reset(SkSafeRef(skPaint.getTypeface())); | |
350 const SkDescriptor* desc = reinterpret_cast<const SkDescriptor*>(run.fDescri
ptor->data()); | |
351 SkGlyphCache* cache = SkGlyphCache::DetachCache(run.fTypeface, desc); | |
352 GrFontScaler* fontScaler = GetGrFontScaler(cache); | 413 GrFontScaler* fontScaler = GetGrFontScaler(cache); |
353 | 414 |
354 const char* stop = text + byteLength; | 415 const char* stop = text + byteLength; |
355 SkTextAlignProc alignProc(skPaint.getTextAlign()); | 416 SkTextAlignProc alignProc(skPaint.getTextAlign()); |
356 SkTextMapStateProc tmsProc(viewMatrix, offset, scalarsPerPosition); | 417 SkTextMapStateProc tmsProc(viewMatrix, offset, scalarsPerPosition); |
357 SkScalar halfSampleX = 0, halfSampleY = 0; | 418 SkScalar halfSampleX = 0, halfSampleY = 0; |
358 | 419 |
359 if (cache->isSubpixel()) { | 420 if (cache->isSubpixel()) { |
360 // maybe we should skip the rounding if linearText is set | 421 // maybe we should skip the rounding if linearText is set |
361 SkAxisAlignment baseline = SkComputeAxisAlignmentForHText(viewMatrix); | 422 SkAxisAlignment baseline = SkComputeAxisAlignmentForHText(viewMatrix); |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
480 GrGlyph::kCoverage_MaskStyle
), | 541 GrGlyph::kCoverage_MaskStyle
), |
481 Sk48Dot16FloorToInt(fx), | 542 Sk48Dot16FloorToInt(fx), |
482 Sk48Dot16FloorToInt(fy), | 543 Sk48Dot16FloorToInt(fy), |
483 fontScaler, | 544 fontScaler, |
484 clipRect); | 545 clipRect); |
485 } | 546 } |
486 pos += scalarsPerPosition; | 547 pos += scalarsPerPosition; |
487 } | 548 } |
488 } | 549 } |
489 } | 550 } |
490 SkGlyphCache::AttachCache(cache); | |
491 } | 551 } |
492 | 552 |
493 static size_t get_vertex_stride(GrMaskFormat maskFormat) { | 553 static size_t get_vertex_stride(GrMaskFormat maskFormat) { |
494 switch (maskFormat) { | 554 switch (maskFormat) { |
495 case kA8_GrMaskFormat: | 555 case kA8_GrMaskFormat: |
496 return kGrayTextVASize; | 556 return kGrayTextVASize; |
497 case kARGB_GrMaskFormat: | 557 case kARGB_GrMaskFormat: |
498 return kColorTextVASize; | 558 return kColorTextVASize; |
499 default: | 559 default: |
500 return kLCDTextVASize; | 560 return kLCDTextVASize; |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
533 // flag the glyph as being dead? | 593 // flag the glyph as being dead? |
534 SkDELETE(path); | 594 SkDELETE(path); |
535 return; | 595 return; |
536 } | 596 } |
537 glyph->fPath = path; | 597 glyph->fPath = path; |
538 } | 598 } |
539 SkASSERT(glyph->fPath); | 599 SkASSERT(glyph->fPath); |
540 blob->fBigGlyphs.push_back(BitmapTextBlob::BigGlyph(*glyph->fPath, vx, v
y)); | 600 blob->fBigGlyphs.push_back(BitmapTextBlob::BigGlyph(*glyph->fPath, vx, v
y)); |
541 return; | 601 return; |
542 } | 602 } |
| 603 |
| 604 Run& run = blob->fRuns[runIndex]; |
| 605 |
543 GrMaskFormat format = glyph->fMaskFormat; | 606 GrMaskFormat format = glyph->fMaskFormat; |
| 607 |
| 608 PerSubRunInfo* subRun = &run.fSubRunInfo.back(); |
| 609 if (run.fInitialized && subRun->fMaskFormat != format) { |
| 610 PerSubRunInfo* newSubRun = &run.fSubRunInfo.push_back(); |
| 611 newSubRun->fGlyphStartIndex = subRun->fGlyphEndIndex; |
| 612 newSubRun->fGlyphEndIndex = subRun->fGlyphEndIndex; |
| 613 |
| 614 newSubRun->fVertexStartIndex = subRun->fVertexEndIndex; |
| 615 newSubRun->fVertexEndIndex = subRun->fVertexEndIndex; |
| 616 |
| 617 subRun = newSubRun; |
| 618 } |
| 619 |
| 620 run.fInitialized = true; |
| 621 subRun->fMaskFormat = format; |
| 622 blob->fGlyphIDs[subRun->fGlyphEndIndex] = packed; |
| 623 |
544 size_t vertexStride = get_vertex_stride(format); | 624 size_t vertexStride = get_vertex_stride(format); |
545 | 625 |
546 BitmapTextBlob::Run& run = blob->fRuns[runIndex]; | |
547 int glyphIdx = run.fInfos[format].fGlyphIDs.count(); | |
548 *run.fInfos[format].fGlyphIDs.append() = packed; | |
549 run.fInfos[format].fVertices.append(static_cast<int>(vertexStride * kVertice
sPerGlyph)); | |
550 | |
551 SkRect r; | 626 SkRect r; |
552 r.fLeft = SkIntToScalar(x); | 627 r.fLeft = SkIntToScalar(x); |
553 r.fTop = SkIntToScalar(y); | 628 r.fTop = SkIntToScalar(y); |
554 r.fRight = r.fLeft + SkIntToScalar(width); | 629 r.fRight = r.fLeft + SkIntToScalar(width); |
555 r.fBottom = r.fTop + SkIntToScalar(height); | 630 r.fBottom = r.fTop + SkIntToScalar(height); |
556 | 631 |
557 run.fVertexBounds.joinNonEmptyArg(r); | 632 run.fVertexBounds.joinNonEmptyArg(r); |
558 GrColor color = fPaint.getColor(); | 633 GrColor color = fPaint.getColor(); |
559 run.fColor = color; | 634 run.fColor = color; |
560 | 635 |
561 intptr_t vertex = reinterpret_cast<intptr_t>(run.fInfos[format].fVertices.be
gin()); | 636 intptr_t vertex = reinterpret_cast<intptr_t>(blob->fVertices + subRun->fVert
exEndIndex); |
562 vertex += vertexStride * glyphIdx * kVerticesPerGlyph; | |
563 | 637 |
564 // V0 | 638 // V0 |
565 SkPoint* position = reinterpret_cast<SkPoint*>(vertex); | 639 SkPoint* position = reinterpret_cast<SkPoint*>(vertex); |
566 position->set(r.fLeft, r.fTop); | 640 position->set(r.fLeft, r.fTop); |
567 if (kA8_GrMaskFormat == format) { | 641 if (kA8_GrMaskFormat == format) { |
568 SkColor* colorPtr = reinterpret_cast<SkColor*>(vertex + sizeof(SkPoint))
; | 642 SkColor* colorPtr = reinterpret_cast<SkColor*>(vertex + sizeof(SkPoint))
; |
569 *colorPtr = color; | 643 *colorPtr = color; |
570 } | 644 } |
571 vertex += vertexStride; | 645 vertex += vertexStride; |
572 | 646 |
(...skipping 15 matching lines...) Expand all Loading... |
588 } | 662 } |
589 vertex += vertexStride; | 663 vertex += vertexStride; |
590 | 664 |
591 // V3 | 665 // V3 |
592 position = reinterpret_cast<SkPoint*>(vertex); | 666 position = reinterpret_cast<SkPoint*>(vertex); |
593 position->set(r.fRight, r.fTop); | 667 position->set(r.fRight, r.fTop); |
594 if (kA8_GrMaskFormat == format) { | 668 if (kA8_GrMaskFormat == format) { |
595 SkColor* colorPtr = reinterpret_cast<SkColor*>(vertex + sizeof(SkPoint))
; | 669 SkColor* colorPtr = reinterpret_cast<SkColor*>(vertex + sizeof(SkPoint))
; |
596 *colorPtr = color; | 670 *colorPtr = color; |
597 } | 671 } |
| 672 |
| 673 subRun->fGlyphEndIndex++; |
| 674 subRun->fVertexEndIndex += vertexStride * kVerticesPerGlyph; |
598 } | 675 } |
599 | 676 |
600 class BitmapTextBatch : public GrBatch { | 677 class BitmapTextBatch : public GrBatch { |
601 public: | 678 public: |
602 typedef GrBitmapTextContextB::BitmapTextBlob Blob; | 679 typedef GrBitmapTextContextB::BitmapTextBlob Blob; |
603 typedef Blob::Run Run; | 680 typedef Blob::Run Run; |
604 typedef Run::PerFormatInfo TextInfo; | 681 typedef Run::SubRunInfo TextInfo; |
605 struct Geometry { | 682 struct Geometry { |
606 Geometry() {} | 683 Geometry() {} |
607 Geometry(const Geometry& geometry) | 684 Geometry(const Geometry& geometry) |
608 : fBlob(SkRef(geometry.fBlob.get())) | 685 : fBlob(SkRef(geometry.fBlob.get())) |
609 , fRun(geometry.fRun) | 686 , fRun(geometry.fRun) |
| 687 , fSubRun(geometry.fSubRun) |
610 , fColor(geometry.fColor) {} | 688 , fColor(geometry.fColor) {} |
611 SkAutoTUnref<Blob> fBlob; | 689 SkAutoTUnref<Blob> fBlob; |
612 int fRun; | 690 int fRun; |
| 691 int fSubRun; |
613 GrColor fColor; | 692 GrColor fColor; |
614 }; | 693 }; |
615 | 694 |
616 static GrBatch* Create(const Geometry& geometry, GrColor color, GrMaskFormat
maskFormat, | 695 static GrBatch* Create(const Geometry& geometry, GrColor color, GrMaskFormat
maskFormat, |
617 GrBatchFontCache* fontCache) { | 696 int glyphCount, GrBatchFontCache* fontCache) { |
618 return SkNEW_ARGS(BitmapTextBatch, (geometry, color, maskFormat, fontCac
he)); | 697 return SkNEW_ARGS(BitmapTextBatch, (geometry, color, maskFormat, glyphCo
unt, fontCache)); |
619 } | 698 } |
620 | 699 |
621 const char* name() const override { return "BitmapTextBatch"; } | 700 const char* name() const override { return "BitmapTextBatch"; } |
622 | 701 |
623 void getInvariantOutputColor(GrInitInvariantOutput* out) const override { | 702 void getInvariantOutputColor(GrInitInvariantOutput* out) const override { |
624 if (kARGB_GrMaskFormat == fMaskFormat) { | 703 if (kARGB_GrMaskFormat == fMaskFormat) { |
625 out->setUnknownFourComponents(); | 704 out->setUnknownFourComponents(); |
626 } else { | 705 } else { |
627 out->setKnownFourComponents(fBatch.fColor); | 706 out->setKnownFourComponents(fBatch.fColor); |
628 } | 707 } |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
711 drawInfo.setIndicesPerInstance(kIndicesPerGlyph); | 790 drawInfo.setIndicesPerInstance(kIndicesPerGlyph); |
712 drawInfo.adjustStartVertex(firstVertex); | 791 drawInfo.adjustStartVertex(firstVertex); |
713 drawInfo.setVertexBuffer(vertexBuffer); | 792 drawInfo.setVertexBuffer(vertexBuffer); |
714 drawInfo.setIndexBuffer(quadIndexBuffer); | 793 drawInfo.setIndexBuffer(quadIndexBuffer); |
715 | 794 |
716 int instancesToFlush = 0; | 795 int instancesToFlush = 0; |
717 for (int i = 0; i < instanceCount; i++) { | 796 for (int i = 0; i < instanceCount; i++) { |
718 Geometry& args = fGeoData[i]; | 797 Geometry& args = fGeoData[i]; |
719 Blob* blob = args.fBlob; | 798 Blob* blob = args.fBlob; |
720 Run& run = blob->fRuns[args.fRun]; | 799 Run& run = blob->fRuns[args.fRun]; |
721 TextInfo& info = run.fInfos[fMaskFormat]; | 800 TextInfo& info = run.fSubRunInfo[args.fSubRun]; |
722 | 801 |
723 uint64_t currentAtlasGen = fFontCache->atlasGeneration(fMaskFormat); | 802 uint64_t currentAtlasGen = fFontCache->atlasGeneration(fMaskFormat); |
724 bool regenerateTextureCoords = info.fAtlasGeneration != currentAtlas
Gen; | 803 bool regenerateTextureCoords = info.fAtlasGeneration != currentAtlas
Gen; |
725 bool regenerateColors = kA8_GrMaskFormat == fMaskFormat && run.fColo
r != args.fColor; | 804 bool regenerateColors = kA8_GrMaskFormat == fMaskFormat && run.fColo
r != args.fColor; |
726 int glyphCount = info.fGlyphIDs.count(); | 805 int glyphCount = info.fGlyphEndIndex - info.fGlyphStartIndex; |
727 | 806 |
728 // We regenerate both texture coords and colors in the blob itself,
and update the | 807 // We regenerate both texture coords and colors in the blob itself,
and update the |
729 // atlas generation. If we don't end up purging any unused plots, w
e can avoid | 808 // atlas generation. If we don't end up purging any unused plots, w
e can avoid |
730 // regenerating the coords. We could take a finer grained approach
to updating texture | 809 // regenerating the coords. We could take a finer grained approach
to updating texture |
731 // coords but its not clear if the extra bookkeeping would offset an
y gains. | 810 // coords but its not clear if the extra bookkeeping would offset an
y gains. |
732 // To avoid looping over the glyphs twice, we do one loop and condit
ionally update color | 811 // To avoid looping over the glyphs twice, we do one loop and condit
ionally update color |
733 // or coords as needed. One final note, if we have to break a run f
or an atlas eviction | 812 // or coords as needed. One final note, if we have to break a run f
or an atlas eviction |
734 // then we can't really trust the atlas has all of the correct data.
Atlas evictions | 813 // then we can't really trust the atlas has all of the correct data.
Atlas evictions |
735 // should be pretty rare, so we just always regenerate in those case
s | 814 // should be pretty rare, so we just always regenerate in those case
s |
736 if (regenerateTextureCoords || regenerateColors) { | 815 if (regenerateTextureCoords || regenerateColors) { |
737 // first regenerate texture coordinates / colors if need be | 816 // first regenerate texture coordinates / colors if need be |
738 const SkDescriptor* desc = NULL; | 817 const SkDescriptor* desc = NULL; |
739 SkGlyphCache* cache = NULL; | 818 SkGlyphCache* cache = NULL; |
740 GrFontScaler* scaler = NULL; | 819 GrFontScaler* scaler = NULL; |
741 GrBatchTextStrike* strike = NULL; | 820 GrBatchTextStrike* strike = NULL; |
742 bool brokenRun = false; | 821 bool brokenRun = false; |
743 if (regenerateTextureCoords) { | 822 if (regenerateTextureCoords) { |
744 desc = reinterpret_cast<const SkDescriptor*>(run.fDescriptor
->data()); | 823 desc = run.fDescriptor.getDesc(); |
745 cache = SkGlyphCache::DetachCache(run.fTypeface, desc); | 824 cache = SkGlyphCache::DetachCache(run.fTypeface, desc); |
746 scaler = GrTextContext::GetGrFontScaler(cache); | 825 scaler = GrTextContext::GetGrFontScaler(cache); |
747 strike = fFontCache->getStrike(scaler); | 826 strike = fFontCache->getStrike(scaler); |
748 } | 827 } |
749 for (int glyphIdx = 0; glyphIdx < glyphCount; glyphIdx++) { | 828 for (int glyphIdx = 0; glyphIdx < glyphCount; glyphIdx++) { |
750 GrGlyph::PackedID glyphID = info.fGlyphIDs[glyphIdx]; | 829 GrGlyph::PackedID glyphID = blob->fGlyphIDs[glyphIdx + info.
fGlyphStartIndex]; |
751 | 830 |
752 if (regenerateTextureCoords) { | 831 if (regenerateTextureCoords) { |
753 // Upload the glyph only if needed | 832 // Upload the glyph only if needed |
754 GrGlyph* glyph = strike->getGlyph(glyphID, scaler); | 833 GrGlyph* glyph = strike->getGlyph(glyphID, scaler); |
755 SkASSERT(glyph); | 834 SkASSERT(glyph); |
756 | 835 |
757 if (!fFontCache->hasGlyph(glyph) && | 836 if (!fFontCache->hasGlyph(glyph) && |
758 !strike->addGlyphToAtlas(batchTarget, glyph, scaler)
) { | 837 !strike->addGlyphToAtlas(batchTarget, glyph, scaler)
) { |
759 this->flush(batchTarget, &drawInfo, instancesToFlush
, | 838 this->flush(batchTarget, &drawInfo, instancesToFlush
, |
760 maxInstancesPerDraw); | 839 maxInstancesPerDraw); |
761 this->initDraw(batchTarget, gp, pipeline); | 840 this->initDraw(batchTarget, gp, pipeline); |
762 instancesToFlush = 0; | 841 instancesToFlush = 0; |
763 brokenRun = glyphIdx > 0; | 842 brokenRun = glyphIdx > 0; |
764 | 843 |
765 SkDEBUGCODE(bool success =) strike->addGlyphToAtlas(
batchTarget, glyph, | 844 SkDEBUGCODE(bool success =) strike->addGlyphToAtlas(
batchTarget, glyph, |
766
scaler); | 845
scaler); |
767 SkASSERT(success); | 846 SkASSERT(success); |
768 } | 847 } |
769 | 848 |
770 fFontCache->setGlyphRefToken(glyph, batchTarget->current
Token()); | 849 fFontCache->setGlyphRefToken(glyph, batchTarget->current
Token()); |
771 | 850 |
772 // Texture coords are the last vertex attribute so we ge
t a pointer to the | 851 // Texture coords are the last vertex attribute so we ge
t a pointer to the |
773 // first one and then map with stride in regenerateTextu
reCoords | 852 // first one and then map with stride in regenerateTextu
reCoords |
774 intptr_t vertex = reinterpret_cast<intptr_t>(info.fVerti
ces.begin()); | 853 intptr_t vertex = reinterpret_cast<intptr_t>(blob->fVert
ices); |
| 854 vertex += info.fVertexStartIndex; |
775 vertex += vertexStride * glyphIdx * kVerticesPerGlyph; | 855 vertex += vertexStride * glyphIdx * kVerticesPerGlyph; |
776 vertex += vertexStride - sizeof(SkIPoint16); | 856 vertex += vertexStride - sizeof(SkIPoint16); |
777 | 857 |
778 this->regenerateTextureCoords(glyph, vertex, vertexStrid
e); | 858 this->regenerateTextureCoords(glyph, vertex, vertexStrid
e); |
779 } | 859 } |
780 | 860 |
781 if (regenerateColors) { | 861 if (regenerateColors) { |
782 intptr_t vertex = reinterpret_cast<intptr_t>(info.fVerti
ces.begin()); | 862 intptr_t vertex = reinterpret_cast<intptr_t>(blob->fVert
ices); |
| 863 vertex += info.fVertexStartIndex; |
783 vertex += vertexStride * glyphIdx * kVerticesPerGlyph +
sizeof(SkPoint); | 864 vertex += vertexStride * glyphIdx * kVerticesPerGlyph +
sizeof(SkPoint); |
784 this->regenerateColors(vertex, vertexStride, args.fColor
); | 865 this->regenerateColors(vertex, vertexStride, args.fColor
); |
785 } | 866 } |
786 | 867 |
787 instancesToFlush++; | 868 instancesToFlush++; |
788 } | 869 } |
789 | 870 |
790 if (regenerateTextureCoords) { | 871 if (regenerateTextureCoords) { |
791 SkGlyphCache::AttachCache(cache); | 872 SkGlyphCache::AttachCache(cache); |
792 info.fAtlasGeneration = brokenRun ? GrBatchAtlas::kInvalidAt
lasGeneration : | 873 info.fAtlasGeneration = brokenRun ? GrBatchAtlas::kInvalidAt
lasGeneration : |
793 fFontCache->atlasGenerat
ion(fMaskFormat); | 874 fFontCache->atlasGenerat
ion(fMaskFormat); |
794 } | 875 } |
795 } else { | 876 } else { |
796 instancesToFlush += glyphCount; | 877 instancesToFlush += glyphCount; |
797 } | 878 } |
798 | 879 |
799 // now copy all vertices | 880 // now copy all vertices |
800 int byteCount = info.fVertices.count(); | 881 size_t byteCount = info.fVertexEndIndex - info.fVertexStartIndex; |
801 memcpy(currVertex, info.fVertices.begin(), byteCount); | 882 memcpy(currVertex, blob->fVertices + info.fVertexStartIndex, byteCou
nt); |
802 | 883 |
803 currVertex += byteCount; | 884 currVertex += byteCount; |
804 } | 885 } |
805 | 886 |
806 this->flush(batchTarget, &drawInfo, instancesToFlush, maxInstancesPerDra
w); | 887 this->flush(batchTarget, &drawInfo, instancesToFlush, maxInstancesPerDra
w); |
807 } | 888 } |
808 | 889 |
809 SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } | 890 SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } |
810 | 891 |
811 private: | 892 private: |
812 BitmapTextBatch(const Geometry& geometry, GrColor color, GrMaskFormat maskFo
rmat, | 893 BitmapTextBatch(const Geometry& geometry, GrColor color, GrMaskFormat maskFo
rmat, |
813 GrBatchFontCache* fontCache) | 894 int glyphCount, GrBatchFontCache* fontCache) |
814 : fMaskFormat(maskFormat) | 895 : fMaskFormat(maskFormat) |
815 , fPixelConfig(fontCache->getPixelConfig(maskFormat)) | 896 , fPixelConfig(fontCache->getPixelConfig(maskFormat)) |
816 , fFontCache(fontCache) { | 897 , fFontCache(fontCache) { |
817 this->initClassID<BitmapTextBatch>(); | 898 this->initClassID<BitmapTextBatch>(); |
818 fGeoData.push_back(geometry); | 899 fGeoData.push_back(geometry); |
819 fBatch.fColor = color; | 900 fBatch.fColor = color; |
820 fBatch.fViewMatrix = geometry.fBlob->fViewMatrix; | 901 fBatch.fViewMatrix = geometry.fBlob->fViewMatrix; |
821 int numGlyphs = geometry.fBlob->fRuns[geometry.fRun].fInfos[maskFormat].
fGlyphIDs.count(); | 902 fBatch.fNumGlyphs = glyphCount; |
822 fBatch.fNumGlyphs = numGlyphs; | |
823 } | 903 } |
824 | 904 |
825 void regenerateTextureCoords(GrGlyph* glyph, intptr_t vertex, size_t vertexS
tride) { | 905 void regenerateTextureCoords(GrGlyph* glyph, intptr_t vertex, size_t vertexS
tride) { |
826 int width = glyph->fBounds.width(); | 906 int width = glyph->fBounds.width(); |
827 int height = glyph->fBounds.height(); | 907 int height = glyph->fBounds.height(); |
828 int u0 = glyph->fAtlasLocation.fX; | 908 int u0 = glyph->fAtlasLocation.fX; |
829 int v0 = glyph->fAtlasLocation.fY; | 909 int v0 = glyph->fAtlasLocation.fY; |
830 int u1 = u0 + width; | 910 int u1 = u0 + width; |
831 int v1 = v0 + height; | 911 int v1 = v0 + height; |
832 | 912 |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
925 int fNumGlyphs; | 1005 int fNumGlyphs; |
926 }; | 1006 }; |
927 | 1007 |
928 BatchTracker fBatch; | 1008 BatchTracker fBatch; |
929 SkSTArray<1, Geometry, true> fGeoData; | 1009 SkSTArray<1, Geometry, true> fGeoData; |
930 GrMaskFormat fMaskFormat; | 1010 GrMaskFormat fMaskFormat; |
931 GrPixelConfig fPixelConfig; | 1011 GrPixelConfig fPixelConfig; |
932 GrBatchFontCache* fFontCache; | 1012 GrBatchFontCache* fFontCache; |
933 }; | 1013 }; |
934 | 1014 |
935 void GrBitmapTextContextB::flushSubRun(GrDrawTarget* target, BitmapTextBlob* blo
b, int i, | |
936 GrPipelineBuilder* pipelineBuilder, GrMas
kFormat format, | |
937 GrColor color, int paintAlpha) { | |
938 if (0 == blob->fRuns[i].fInfos[format].fGlyphIDs.count()) { | |
939 return; | |
940 } | |
941 | |
942 if (kARGB_GrMaskFormat == format) { | |
943 color = SkColorSetARGB(paintAlpha, paintAlpha, paintAlpha, paintAlpha); | |
944 } | |
945 | |
946 BitmapTextBatch::Geometry geometry; | |
947 geometry.fBlob.reset(SkRef(blob)); | |
948 geometry.fRun = i; | |
949 geometry.fColor = color; | |
950 SkAutoTUnref<GrBatch> batch(BitmapTextBatch::Create(geometry, color, format, | |
951 fContext->getBatchFontCa
che())); | |
952 | |
953 target->drawBatch(pipelineBuilder, batch, &blob->fRuns[i].fVertexBounds); | |
954 } | |
955 | |
956 void GrBitmapTextContextB::flush(GrDrawTarget* target, BitmapTextBlob* blob, GrR
enderTarget* rt, | 1015 void GrBitmapTextContextB::flush(GrDrawTarget* target, BitmapTextBlob* blob, GrR
enderTarget* rt, |
957 const GrPaint& paint, const GrClip& clip, | 1016 const GrPaint& paint, const GrClip& clip, |
958 const SkMatrix& viewMatrix, int paintAlpha) { | 1017 const SkMatrix& viewMatrix, int paintAlpha) { |
959 GrPipelineBuilder pipelineBuilder; | 1018 GrPipelineBuilder pipelineBuilder; |
960 pipelineBuilder.setFromPaint(paint, rt, clip); | 1019 pipelineBuilder.setFromPaint(paint, rt, clip); |
961 | 1020 |
962 GrColor color = paint.getColor(); | 1021 GrColor color = paint.getColor(); |
963 for (int i = 0; i < blob->fRuns.count(); i++) { | 1022 for (uint32_t run = 0; run < blob->fRunCount; run++) { |
964 this->flushSubRun(target, blob, i, &pipelineBuilder, kA8_GrMaskFormat, c
olor, paintAlpha); | 1023 for (int subRun = 0; subRun < blob->fRuns[run].fSubRunInfo.count(); subR
un++) { |
965 this->flushSubRun(target, blob, i, &pipelineBuilder, kA565_GrMaskFormat,
color, paintAlpha); | 1024 PerSubRunInfo& info = blob->fRuns[run].fSubRunInfo[subRun]; |
966 this->flushSubRun(target, blob, i, &pipelineBuilder, kARGB_GrMaskFormat,
color, paintAlpha); | 1025 int glyphCount = info.fGlyphEndIndex - info.fGlyphStartIndex; |
| 1026 if (0 == glyphCount) { |
| 1027 continue; |
| 1028 } |
| 1029 |
| 1030 GrMaskFormat format = info.fMaskFormat; |
| 1031 if (kARGB_GrMaskFormat == format) { |
| 1032 color = SkColorSetARGB(paintAlpha, paintAlpha, paintAlpha, paint
Alpha); |
| 1033 } |
| 1034 |
| 1035 BitmapTextBatch::Geometry geometry; |
| 1036 geometry.fBlob.reset(SkRef(blob)); |
| 1037 geometry.fRun = run; |
| 1038 geometry.fSubRun = subRun; |
| 1039 geometry.fColor = color; |
| 1040 SkAutoTUnref<GrBatch> batch(BitmapTextBatch::Create(geometry, color,
format, glyphCount, |
| 1041 fContext->getBat
chFontCache())); |
| 1042 |
| 1043 target->drawBatch(&pipelineBuilder, batch, &blob->fRuns[run].fVertex
Bounds); |
| 1044 } |
967 } | 1045 } |
968 | 1046 |
969 // Now flush big glyphs | 1047 // Now flush big glyphs |
970 for (int i = 0; i < blob->fBigGlyphs.count(); i++) { | 1048 for (int i = 0; i < blob->fBigGlyphs.count(); i++) { |
971 BitmapTextBlob::BigGlyph& bigGlyph = blob->fBigGlyphs[i]; | 1049 BitmapTextBlob::BigGlyph& bigGlyph = blob->fBigGlyphs[i]; |
972 SkMatrix translate; | 1050 SkMatrix translate; |
973 translate.setTranslate(SkIntToScalar(bigGlyph.fVx), SkIntToScalar(bigGly
ph.fVy)); | 1051 translate.setTranslate(SkIntToScalar(bigGlyph.fVx), SkIntToScalar(bigGly
ph.fVy)); |
974 SkPath tmpPath(bigGlyph.fPath); | 1052 SkPath tmpPath(bigGlyph.fPath); |
975 tmpPath.transform(translate); | 1053 tmpPath.transform(translate); |
976 GrStrokeInfo strokeInfo(SkStrokeRec::kFill_InitStyle); | 1054 GrStrokeInfo strokeInfo(SkStrokeRec::kFill_InitStyle); |
(...skipping 576 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1553 SkSafeSetNull(fCurrTexture); | 1631 SkSafeSetNull(fCurrTexture); |
1554 } | 1632 } |
1555 } | 1633 } |
1556 | 1634 |
1557 inline void GrBitmapTextContext::finish() { | 1635 inline void GrBitmapTextContext::finish() { |
1558 this->flush(); | 1636 this->flush(); |
1559 fTotalVertexCount = 0; | 1637 fTotalVertexCount = 0; |
1560 | 1638 |
1561 GrTextContext::finish(); | 1639 GrTextContext::finish(); |
1562 } | 1640 } |
OLD | NEW |