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