OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 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 "GrAtlasTextContext.h" | 7 #include "GrAtlasTextContext.h" |
8 | 8 |
9 #include "GrDrawContext.h" | 9 #include "GrDrawContext.h" |
10 #include "GrDrawTarget.h" | 10 #include "GrDrawTarget.h" |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
159 if (cacheBlob) { | 159 if (cacheBlob) { |
160 if (cacheBlob->mustRegenerate(&transX, &transY, skPaint, grPaint.getColo
r(), blurRec, | 160 if (cacheBlob->mustRegenerate(&transX, &transY, skPaint, grPaint.getColo
r(), blurRec, |
161 viewMatrix, x, y)) { | 161 viewMatrix, x, y)) { |
162 // We have to remake the blob because changes may invalidate our mas
ks. | 162 // We have to remake the blob because changes may invalidate our mas
ks. |
163 // TODO we could probably get away reuse most of the time if the poi
nter is unique, | 163 // TODO we could probably get away reuse most of the time if the poi
nter is unique, |
164 // but we'd have to clear the subrun information | 164 // but we'd have to clear the subrun information |
165 fCache->remove(cacheBlob); | 165 fCache->remove(cacheBlob); |
166 cacheBlob.reset(SkRef(fCache->createCachedBlob(blob, key, blurRec, s
kPaint, | 166 cacheBlob.reset(SkRef(fCache->createCachedBlob(blob, key, blurRec, s
kPaint, |
167 GrAtlasTextBlob::kGra
yTextVASize))); | 167 GrAtlasTextBlob::kGra
yTextVASize))); |
168 this->regenerateTextBlob(cacheBlob, skPaint, grPaint.getColor(), vie
wMatrix, | 168 this->regenerateTextBlob(cacheBlob, skPaint, grPaint.getColor(), vie
wMatrix, |
169 blob, x, y, drawFilter, clip); | 169 blob, x, y, drawFilter); |
170 } else { | 170 } else { |
171 fCache->makeMRU(cacheBlob); | 171 fCache->makeMRU(cacheBlob); |
172 #ifdef CACHE_SANITY_CHECK | 172 #ifdef CACHE_SANITY_CHECK |
173 { | 173 { |
174 int glyphCount = 0; | 174 int glyphCount = 0; |
175 int runCount = 0; | 175 int runCount = 0; |
176 GrTextBlobCache::BlobGlyphCount(&glyphCount, &runCount, blob); | 176 GrTextBlobCache::BlobGlyphCount(&glyphCount, &runCount, blob); |
177 SkAutoTUnref<GrAtlasTextBlob> sanityBlob(fCache->createBlob(glyp
hCount, runCount, | 177 SkAutoTUnref<GrAtlasTextBlob> sanityBlob(fCache->createBlob(glyp
hCount, runCount, |
178 kGra
yTextVASize)); | 178 kGra
yTextVASize)); |
179 GrTextBlobCache::SetupCacheBlobKey(sanityBlob, key, blurRec, skP
aint); | 179 GrTextBlobCache::SetupCacheBlobKey(sanityBlob, key, blurRec, skP
aint); |
180 this->regenerateTextBlob(sanityBlob, skPaint, grPaint.getColor()
, viewMatrix, | 180 this->regenerateTextBlob(sanityBlob, skPaint, grPaint.getColor()
, viewMatrix, |
181 blob, x, y, drawFilter, clip); | 181 blob, x, y, drawFilter); |
182 GrAtlasTextBlob::AssertEqual(*sanityBlob, *cacheBlob); | 182 GrAtlasTextBlob::AssertEqual(*sanityBlob, *cacheBlob); |
183 } | 183 } |
184 | 184 |
185 #endif | 185 #endif |
186 } | 186 } |
187 } else { | 187 } else { |
188 if (canCache) { | 188 if (canCache) { |
189 cacheBlob.reset(SkRef(fCache->createCachedBlob(blob, key, blurRec, s
kPaint, | 189 cacheBlob.reset(SkRef(fCache->createCachedBlob(blob, key, blurRec, s
kPaint, |
190 GrAtlasTextBlob::kGra
yTextVASize))); | 190 GrAtlasTextBlob::kGra
yTextVASize))); |
191 } else { | 191 } else { |
192 cacheBlob.reset(fCache->createBlob(blob, GrAtlasTextBlob::kGrayTextV
ASize)); | 192 cacheBlob.reset(fCache->createBlob(blob, GrAtlasTextBlob::kGrayTextV
ASize)); |
193 } | 193 } |
194 this->regenerateTextBlob(cacheBlob, skPaint, grPaint.getColor(), viewMat
rix, | 194 this->regenerateTextBlob(cacheBlob, skPaint, grPaint.getColor(), viewMat
rix, |
195 blob, x, y, drawFilter, clip); | 195 blob, x, y, drawFilter); |
196 } | 196 } |
197 | 197 |
198 cacheBlob->flushCached(fContext, dc, blob, fSurfaceProps, fDistanceAdjustTab
le, skPaint, | 198 cacheBlob->flushCached(fContext, dc, blob, fSurfaceProps, fDistanceAdjustTab
le, skPaint, |
199 grPaint, drawFilter, clip, viewMatrix, clipBounds, x,
y, transX, transY); | 199 grPaint, drawFilter, clip, viewMatrix, clipBounds, x,
y, transX, transY); |
200 } | 200 } |
201 | 201 |
202 inline bool GrAtlasTextContext::canDrawAsDistanceFields(const SkPaint& skPaint, | 202 inline bool GrAtlasTextContext::canDrawAsDistanceFields(const SkPaint& skPaint, |
203 const SkMatrix& viewMatr
ix) { | 203 const SkMatrix& viewMatr
ix) { |
204 // TODO: support perspective (need getMaxScale replacement) | 204 // TODO: support perspective (need getMaxScale replacement) |
205 if (viewMatrix.hasPerspective()) { | 205 if (viewMatrix.hasPerspective()) { |
(...skipping 29 matching lines...) Expand all Loading... |
235 return false; | 235 return false; |
236 } | 236 } |
237 | 237 |
238 return true; | 238 return true; |
239 } | 239 } |
240 | 240 |
241 void GrAtlasTextContext::regenerateTextBlob(GrAtlasTextBlob* cacheBlob, | 241 void GrAtlasTextContext::regenerateTextBlob(GrAtlasTextBlob* cacheBlob, |
242 const SkPaint& skPaint, GrColor colo
r, | 242 const SkPaint& skPaint, GrColor colo
r, |
243 const SkMatrix& viewMatrix, | 243 const SkMatrix& viewMatrix, |
244 const SkTextBlob* blob, SkScalar x,
SkScalar y, | 244 const SkTextBlob* blob, SkScalar x,
SkScalar y, |
245 SkDrawFilter* drawFilter, | 245 SkDrawFilter* drawFilter) { |
246 const GrClip& clip) { | |
247 // The color here is the GrPaint color, and it is used to determine whether
we | 246 // The color here is the GrPaint color, and it is used to determine whether
we |
248 // have to regenerate LCD text blobs. | 247 // have to regenerate LCD text blobs. |
249 // We use this color vs the SkPaint color because it has the colorfilter app
lied. | 248 // We use this color vs the SkPaint color because it has the colorfilter app
lied. |
250 cacheBlob->fPaintColor = color; | 249 cacheBlob->fPaintColor = color; |
251 cacheBlob->fViewMatrix = viewMatrix; | 250 cacheBlob->fViewMatrix = viewMatrix; |
252 cacheBlob->fX = x; | 251 cacheBlob->fX = x; |
253 cacheBlob->fY = y; | 252 cacheBlob->fY = y; |
254 | 253 |
255 // Regenerate textblob | 254 // Regenerate textblob |
256 SkPaint runPaint = skPaint; | 255 SkPaint runPaint = skPaint; |
(...skipping 10 matching lines...) Expand all Loading... |
267 // A false return from filter() means we should abort the current dr
aw. | 266 // A false return from filter() means we should abort the current dr
aw. |
268 runPaint = skPaint; | 267 runPaint = skPaint; |
269 continue; | 268 continue; |
270 } | 269 } |
271 | 270 |
272 runPaint.setFlags(FilterTextFlags(fSurfaceProps, runPaint)); | 271 runPaint.setFlags(FilterTextFlags(fSurfaceProps, runPaint)); |
273 | 272 |
274 cacheBlob->push_back_run(run); | 273 cacheBlob->push_back_run(run); |
275 | 274 |
276 if (this->canDrawAsDistanceFields(runPaint, viewMatrix)) { | 275 if (this->canDrawAsDistanceFields(runPaint, viewMatrix)) { |
277 cacheBlob->setHasDistanceField(); | |
278 SkPaint dfPaint = runPaint; | |
279 SkScalar textRatio; | |
280 this->initDistanceFieldPaint(cacheBlob, &dfPaint, &textRatio, viewMa
trix); | |
281 Run& runIdx = cacheBlob->fRuns[run]; | |
282 PerSubRunInfo& subRun = runIdx.fSubRunInfo.back(); | |
283 subRun.setUseLCDText(runPaint.isLCDRenderText()); | |
284 subRun.setDrawAsDistanceFields(); | |
285 | |
286 switch (it.positioning()) { | 276 switch (it.positioning()) { |
287 case SkTextBlob::kDefault_Positioning: { | 277 case SkTextBlob::kDefault_Positioning: { |
288 this->internalDrawDFText(cacheBlob, run, dfPaint, color, vie
wMatrix, | 278 this->internalDrawDFText(cacheBlob, run, runPaint, color, vi
ewMatrix, |
289 (const char *)it.glyphs(), textLen, | 279 (const char *)it.glyphs(), textLen, |
290 x + offset.x(), y + offset.y(), tex
tRatio, runPaint); | 280 x + offset.x(), y + offset.y()); |
291 break; | 281 break; |
292 } | 282 } |
293 case SkTextBlob::kHorizontal_Positioning: { | 283 case SkTextBlob::kHorizontal_Positioning: { |
294 SkPoint dfOffset = SkPoint::Make(x, y + offset.y()); | 284 SkPoint dfOffset = SkPoint::Make(x, y + offset.y()); |
295 this->internalDrawDFPosText(cacheBlob, run, dfPaint, color,
viewMatrix, | 285 this->internalDrawDFPosText(cacheBlob, run, runPaint, color,
viewMatrix, |
296 (const char*)it.glyphs(), textLe
n, it.pos(), | 286 (const char*)it.glyphs(), textLe
n, it.pos(), |
297 1, dfOffset, textRatio, | 287 1, dfOffset); |
298 runPaint); | |
299 break; | 288 break; |
300 } | 289 } |
301 case SkTextBlob::kFull_Positioning: { | 290 case SkTextBlob::kFull_Positioning: { |
302 SkPoint dfOffset = SkPoint::Make(x, y); | 291 SkPoint dfOffset = SkPoint::Make(x, y); |
303 this->internalDrawDFPosText(cacheBlob, run, dfPaint, color,
viewMatrix, | 292 this->internalDrawDFPosText(cacheBlob, run, runPaint, color,
viewMatrix, |
304 (const char*)it.glyphs(), textLe
n, it.pos(), | 293 (const char*)it.glyphs(), textLe
n, it.pos(), |
305 2, dfOffset, textRatio, runPaint
); | 294 2, dfOffset); |
306 break; | 295 break; |
307 } | 296 } |
308 } | 297 } |
309 } else if (SkDraw::ShouldDrawTextAsPaths(runPaint, viewMatrix)) { | 298 } else if (SkDraw::ShouldDrawTextAsPaths(runPaint, viewMatrix)) { |
310 cacheBlob->fRuns[run].fDrawAsPaths = true; | 299 cacheBlob->fRuns[run].fDrawAsPaths = true; |
311 } else { | 300 } else { |
312 cacheBlob->setHasBitmap(); | |
313 switch (it.positioning()) { | 301 switch (it.positioning()) { |
314 case SkTextBlob::kDefault_Positioning: | 302 case SkTextBlob::kDefault_Positioning: |
315 GrTextUtils::DrawBmpText(cacheBlob, run, fContext->getBatchF
ontCache(), | 303 GrTextUtils::DrawBmpText(cacheBlob, run, fContext->getBatchF
ontCache(), |
316 fSurfaceProps, runPaint, color, vie
wMatrix, | 304 fSurfaceProps, runPaint, color, vie
wMatrix, |
317 (const char *)it.glyphs(), textLen, | 305 (const char *)it.glyphs(), textLen, |
318 x + offset.x(), y + offset.y()); | 306 x + offset.x(), y + offset.y()); |
319 break; | 307 break; |
320 case SkTextBlob::kHorizontal_Positioning: | 308 case SkTextBlob::kHorizontal_Positioning: |
321 GrTextUtils::DrawBmpPosText(cacheBlob, run, fContext->getBat
chFontCache(), | 309 GrTextUtils::DrawBmpPosText(cacheBlob, run, fContext->getBat
chFontCache(), |
322 fSurfaceProps, runPaint, color,
viewMatrix, | 310 fSurfaceProps, runPaint, color,
viewMatrix, |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
396 inline void GrAtlasTextContext::fallbackDrawPosText(GrAtlasTextBlob* blob, | 384 inline void GrAtlasTextContext::fallbackDrawPosText(GrAtlasTextBlob* blob, |
397 int runIndex, | 385 int runIndex, |
398 GrColor color, | 386 GrColor color, |
399 const SkPaint& skPaint, | 387 const SkPaint& skPaint, |
400 const SkMatrix& viewMatrix, | 388 const SkMatrix& viewMatrix, |
401 const SkTDArray<char>& fallb
ackTxt, | 389 const SkTDArray<char>& fallb
ackTxt, |
402 const SkTDArray<SkScalar>& f
allbackPos, | 390 const SkTDArray<SkScalar>& f
allbackPos, |
403 int scalarsPerPosition, | 391 int scalarsPerPosition, |
404 const SkPoint& offset) { | 392 const SkPoint& offset) { |
405 SkASSERT(fallbackTxt.count()); | 393 SkASSERT(fallbackTxt.count()); |
406 blob->setHasBitmap(); | |
407 Run& run = blob->fRuns[runIndex]; | 394 Run& run = blob->fRuns[runIndex]; |
408 // Push back a new subrun to fill and set the override descriptor | 395 // Push back a new subrun to fill and set the override descriptor |
409 run.push_back(); | 396 run.push_back(); |
410 run.fOverrideDescriptor.reset(new SkAutoDescriptor); | 397 run.fOverrideDescriptor.reset(new SkAutoDescriptor); |
411 GrTextUtils::DrawBmpPosText(blob, runIndex, fContext->getBatchFontCache(), f
SurfaceProps, | 398 GrTextUtils::DrawBmpPosText(blob, runIndex, fContext->getBatchFontCache(), f
SurfaceProps, |
412 skPaint, color, viewMatrix, fallbackTxt.begin(),
fallbackTxt.count(), | 399 skPaint, color, viewMatrix, fallbackTxt.begin(),
fallbackTxt.count(), |
413 fallbackPos.begin(), scalarsPerPosition, offset)
; | 400 fallbackPos.begin(), scalarsPerPosition, offset)
; |
414 } | 401 } |
415 | 402 |
416 inline GrAtlasTextBlob* | 403 inline GrAtlasTextBlob* |
417 GrAtlasTextContext::setupDFBlob(int glyphCount, const SkPaint& origPaint, | |
418 const SkMatrix& viewMatrix, SkPaint* dfPaint, | |
419 SkScalar* textRatio) { | |
420 GrAtlasTextBlob* blob = fCache->createBlob(glyphCount, 1, GrAtlasTextBlob::k
GrayTextVASize); | |
421 | |
422 *dfPaint = origPaint; | |
423 this->initDistanceFieldPaint(blob, dfPaint, textRatio, viewMatrix); | |
424 blob->fViewMatrix = viewMatrix; | |
425 Run& run = blob->fRuns[0]; | |
426 PerSubRunInfo& subRun = run.fSubRunInfo.back(); | |
427 subRun.setUseLCDText(origPaint.isLCDRenderText()); | |
428 subRun.setDrawAsDistanceFields(); | |
429 | |
430 return blob; | |
431 } | |
432 | |
433 inline GrAtlasTextBlob* | |
434 GrAtlasTextContext::createDrawTextBlob(const GrPaint& paint, const SkPaint& skPa
int, | 404 GrAtlasTextContext::createDrawTextBlob(const GrPaint& paint, const SkPaint& skPa
int, |
435 const SkMatrix& viewMatrix, | 405 const SkMatrix& viewMatrix, |
436 const char text[], size_t byteLength, | 406 const char text[], size_t byteLength, |
437 SkScalar x, SkScalar y) { | 407 SkScalar x, SkScalar y) { |
438 int glyphCount = skPaint.countText(text, byteLength); | 408 int glyphCount = skPaint.countText(text, byteLength); |
439 | 409 |
440 GrAtlasTextBlob* blob; | 410 GrAtlasTextBlob* blob = fCache->createBlob(glyphCount, 1, GrAtlasTextBlob::k
GrayTextVASize); |
| 411 blob->fViewMatrix = viewMatrix; |
| 412 |
441 if (this->canDrawAsDistanceFields(skPaint, viewMatrix)) { | 413 if (this->canDrawAsDistanceFields(skPaint, viewMatrix)) { |
442 SkPaint dfPaint; | 414 this->internalDrawDFText(blob, 0, skPaint, paint.getColor(), viewMatrix,
text, |
443 SkScalar textRatio; | 415 byteLength, x, y); |
444 blob = this->setupDFBlob(glyphCount, skPaint, viewMatrix, &dfPaint, &tex
tRatio); | |
445 | |
446 this->internalDrawDFText(blob, 0, dfPaint, paint.getColor(), viewMatrix,
text, | |
447 byteLength, x, y, textRatio, skPaint); | |
448 } else { | 416 } else { |
449 blob = fCache->createBlob(glyphCount, 1, GrAtlasTextBlob::kGrayTextVASiz
e); | |
450 blob->fViewMatrix = viewMatrix; | |
451 | |
452 GrTextUtils::DrawBmpText(blob, 0, fContext->getBatchFontCache(), fSurfac
eProps, skPaint, | 417 GrTextUtils::DrawBmpText(blob, 0, fContext->getBatchFontCache(), fSurfac
eProps, skPaint, |
453 paint.getColor(), viewMatrix, text, byteLength,
x, y); | 418 paint.getColor(), viewMatrix, text, byteLength,
x, y); |
454 } | 419 } |
455 return blob; | 420 return blob; |
456 } | 421 } |
457 | 422 |
458 inline GrAtlasTextBlob* | 423 inline GrAtlasTextBlob* |
459 GrAtlasTextContext::createDrawPosTextBlob(const GrPaint& paint, const SkPaint& s
kPaint, | 424 GrAtlasTextContext::createDrawPosTextBlob(const GrPaint& paint, const SkPaint& s
kPaint, |
460 const SkMatrix& viewMatrix, | 425 const SkMatrix& viewMatrix, |
461 const char text[], size_t byteLength, | 426 const char text[], size_t byteLength, |
462 const SkScalar pos[], int scalarsPerPo
sition, | 427 const SkScalar pos[], int scalarsPerPo
sition, |
463 const SkPoint& offset) { | 428 const SkPoint& offset) { |
464 int glyphCount = skPaint.countText(text, byteLength); | 429 int glyphCount = skPaint.countText(text, byteLength); |
465 | 430 |
466 GrAtlasTextBlob* blob; | 431 GrAtlasTextBlob* blob = fCache->createBlob(glyphCount, 1, GrAtlasTextBlob::k
GrayTextVASize); |
| 432 blob->fViewMatrix = viewMatrix; |
| 433 |
467 if (this->canDrawAsDistanceFields(skPaint, viewMatrix)) { | 434 if (this->canDrawAsDistanceFields(skPaint, viewMatrix)) { |
468 SkPaint dfPaint; | 435 this->internalDrawDFPosText(blob, 0, skPaint, paint.getColor(), viewMatr
ix, text, |
469 SkScalar textRatio; | 436 byteLength, pos, scalarsPerPosition, offset)
; |
470 blob = this->setupDFBlob(glyphCount, skPaint, viewMatrix, &dfPaint, &tex
tRatio); | |
471 | |
472 this->internalDrawDFPosText(blob, 0, dfPaint, paint.getColor(), viewMatr
ix, text, | |
473 byteLength, pos, scalarsPerPosition, offset,
textRatio, | |
474 skPaint); | |
475 } else { | 437 } else { |
476 blob = fCache->createBlob(glyphCount, 1, GrAtlasTextBlob::kGrayTextVASiz
e); | |
477 blob->fViewMatrix = viewMatrix; | |
478 GrTextUtils::DrawBmpPosText(blob, 0, fContext->getBatchFontCache(), fSur
faceProps, skPaint, | 438 GrTextUtils::DrawBmpPosText(blob, 0, fContext->getBatchFontCache(), fSur
faceProps, skPaint, |
479 paint.getColor(), viewMatrix, text, | 439 paint.getColor(), viewMatrix, text, |
480 byteLength, pos, scalarsPerPosition, offset)
; | 440 byteLength, pos, scalarsPerPosition, offset)
; |
481 } | 441 } |
482 return blob; | 442 return blob; |
483 } | 443 } |
484 | 444 |
485 void GrAtlasTextContext::onDrawText(GrDrawContext* dc, | 445 void GrAtlasTextContext::onDrawText(GrDrawContext* dc, |
486 const GrClip& clip, | 446 const GrClip& clip, |
487 const GrPaint& paint, const SkPaint& skPaint
, | 447 const GrPaint& paint, const SkPaint& skPaint
, |
(...skipping 20 matching lines...) Expand all Loading... |
508 offset)); | 468 offset)); |
509 | 469 |
510 blob->flushThrowaway(fContext, dc, fSurfaceProps, fDistanceAdjustTable, skPa
int, paint, clip, | 470 blob->flushThrowaway(fContext, dc, fSurfaceProps, fDistanceAdjustTable, skPa
int, paint, clip, |
511 regionClipBounds); | 471 regionClipBounds); |
512 } | 472 } |
513 | 473 |
514 void GrAtlasTextContext::internalDrawDFText(GrAtlasTextBlob* blob, int runIndex, | 474 void GrAtlasTextContext::internalDrawDFText(GrAtlasTextBlob* blob, int runIndex, |
515 const SkPaint& skPaint, GrColor colo
r, | 475 const SkPaint& skPaint, GrColor colo
r, |
516 const SkMatrix& viewMatrix, | 476 const SkMatrix& viewMatrix, |
517 const char text[], size_t byteLength
, | 477 const char text[], size_t byteLength
, |
518 SkScalar x, SkScalar y, | 478 SkScalar x, SkScalar y) { |
519 SkScalar textRatio, | |
520 const SkPaint& origPaint) { | |
521 SkASSERT(byteLength == 0 || text != nullptr); | 479 SkASSERT(byteLength == 0 || text != nullptr); |
522 | 480 |
523 // nothing to draw | 481 // nothing to draw |
524 if (text == nullptr || byteLength == 0) { | 482 if (text == nullptr || byteLength == 0) { |
525 return; | 483 return; |
526 } | 484 } |
527 | 485 |
528 SkDrawCacheProc glyphCacheProc = origPaint.getDrawCacheProc(); | 486 SkDrawCacheProc glyphCacheProc = skPaint.getDrawCacheProc(); |
529 SkAutoDescriptor desc; | 487 SkAutoDescriptor desc; |
530 origPaint.getScalerContextDescriptor(&desc, fSurfaceProps, nullptr, true); | 488 skPaint.getScalerContextDescriptor(&desc, fSurfaceProps, nullptr, true); |
531 SkGlyphCache* origPaintCache = SkGlyphCache::DetachCache(origPaint.getTypefa
ce(), | 489 SkGlyphCache* origPaintCache = SkGlyphCache::DetachCache(skPaint.getTypeface
(), |
532 desc.getDesc()); | 490 desc.getDesc()); |
533 | 491 |
534 SkTArray<SkScalar> positions; | 492 SkTArray<SkScalar> positions; |
535 | 493 |
536 const char* textPtr = text; | 494 const char* textPtr = text; |
537 SkFixed stopX = 0; | 495 SkFixed stopX = 0; |
538 SkFixed stopY = 0; | 496 SkFixed stopY = 0; |
539 SkFixed origin = 0; | 497 SkFixed origin = 0; |
540 switch (origPaint.getTextAlign()) { | 498 switch (skPaint.getTextAlign()) { |
541 case SkPaint::kRight_Align: origin = SK_Fixed1; break; | 499 case SkPaint::kRight_Align: origin = SK_Fixed1; break; |
542 case SkPaint::kCenter_Align: origin = SK_FixedHalf; break; | 500 case SkPaint::kCenter_Align: origin = SK_FixedHalf; break; |
543 case SkPaint::kLeft_Align: origin = 0; break; | 501 case SkPaint::kLeft_Align: origin = 0; break; |
544 } | 502 } |
545 | 503 |
546 SkAutoKern autokern; | 504 SkAutoKern autokern; |
547 const char* stop = text + byteLength; | 505 const char* stop = text + byteLength; |
548 while (textPtr < stop) { | 506 while (textPtr < stop) { |
549 // don't need x, y here, since all subpixel variants will have the | 507 // don't need x, y here, since all subpixel variants will have the |
550 // same advance | 508 // same advance |
551 const SkGlyph& glyph = glyphCacheProc(origPaintCache, &textPtr, 0, 0); | 509 const SkGlyph& glyph = glyphCacheProc(origPaintCache, &textPtr, 0, 0); |
552 | 510 |
553 SkFixed width = glyph.fAdvanceX + autokern.adjust(glyph); | 511 SkFixed width = glyph.fAdvanceX + autokern.adjust(glyph); |
554 positions.push_back(SkFixedToScalar(stopX + SkFixedMul(origin, width))); | 512 positions.push_back(SkFixedToScalar(stopX + SkFixedMul(origin, width))); |
555 | 513 |
556 SkFixed height = glyph.fAdvanceY; | 514 SkFixed height = glyph.fAdvanceY; |
557 positions.push_back(SkFixedToScalar(stopY + SkFixedMul(origin, height)))
; | 515 positions.push_back(SkFixedToScalar(stopY + SkFixedMul(origin, height)))
; |
558 | 516 |
559 stopX += width; | 517 stopX += width; |
560 stopY += height; | 518 stopY += height; |
561 } | 519 } |
562 SkASSERT(textPtr == stop); | 520 SkASSERT(textPtr == stop); |
563 | 521 |
564 SkGlyphCache::AttachCache(origPaintCache); | 522 SkGlyphCache::AttachCache(origPaintCache); |
565 | 523 |
566 // now adjust starting point depending on alignment | 524 // now adjust starting point depending on alignment |
567 SkScalar alignX = SkFixedToScalar(stopX); | 525 SkScalar alignX = SkFixedToScalar(stopX); |
568 SkScalar alignY = SkFixedToScalar(stopY); | 526 SkScalar alignY = SkFixedToScalar(stopY); |
569 if (origPaint.getTextAlign() == SkPaint::kCenter_Align) { | 527 if (skPaint.getTextAlign() == SkPaint::kCenter_Align) { |
570 alignX = SkScalarHalf(alignX); | 528 alignX = SkScalarHalf(alignX); |
571 alignY = SkScalarHalf(alignY); | 529 alignY = SkScalarHalf(alignY); |
572 } else if (origPaint.getTextAlign() == SkPaint::kLeft_Align) { | 530 } else if (skPaint.getTextAlign() == SkPaint::kLeft_Align) { |
573 alignX = 0; | 531 alignX = 0; |
574 alignY = 0; | 532 alignY = 0; |
575 } | 533 } |
576 x -= alignX; | 534 x -= alignX; |
577 y -= alignY; | 535 y -= alignY; |
578 SkPoint offset = SkPoint::Make(x, y); | 536 SkPoint offset = SkPoint::Make(x, y); |
579 | 537 |
580 this->internalDrawDFPosText(blob, runIndex, skPaint, color, viewMatrix, text
, byteLength, | 538 this->internalDrawDFPosText(blob, runIndex, skPaint, color, viewMatrix, text
, byteLength, |
581 positions.begin(), 2, offset, textRatio, origPai
nt); | 539 positions.begin(), 2, offset); |
582 } | 540 } |
583 | 541 |
584 void GrAtlasTextContext::internalDrawDFPosText(GrAtlasTextBlob* blob, int runInd
ex, | 542 void GrAtlasTextContext::internalDrawDFPosText(GrAtlasTextBlob* blob, int runInd
ex, |
585 const SkPaint& skPaint, | 543 const SkPaint& origPaint, |
586 GrColor color, | 544 GrColor color, |
587 const SkMatrix& viewMatrix, | 545 const SkMatrix& viewMatrix, |
588 const char text[], size_t byteLen
gth, | 546 const char text[], size_t byteLen
gth, |
589 const SkScalar pos[], int scalars
PerPosition, | 547 const SkScalar pos[], int scalars
PerPosition, |
590 const SkPoint& offset, | 548 const SkPoint& offset) { |
591 SkScalar textRatio, | |
592 const SkPaint& origPaint) { | |
593 | 549 |
594 SkASSERT(byteLength == 0 || text != nullptr); | 550 SkASSERT(byteLength == 0 || text != nullptr); |
595 SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition); | 551 SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition); |
596 | 552 |
597 // nothing to draw | 553 // nothing to draw |
598 if (text == nullptr || byteLength == 0) { | 554 if (text == nullptr || byteLength == 0) { |
599 return; | 555 return; |
600 } | 556 } |
601 | 557 |
602 SkTDArray<char> fallbackTxt; | 558 SkTDArray<char> fallbackTxt; |
603 SkTDArray<SkScalar> fallbackPos; | 559 SkTDArray<SkScalar> fallbackPos; |
604 | 560 |
| 561 // Setup distance field paint and text ratio |
| 562 SkScalar textRatio; |
| 563 SkPaint dfPaint(origPaint); |
| 564 this->initDistanceFieldPaint(blob, &dfPaint, &textRatio, viewMatrix); |
| 565 blob->setHasDistanceField(); |
| 566 blob->setSubRunHasDistanceFields(runIndex, origPaint.isLCDRenderText()); |
| 567 |
605 fCurrStrike = nullptr; | 568 fCurrStrike = nullptr; |
606 | 569 |
607 SkGlyphCache* cache = blob->setupCache(runIndex, fSurfaceProps, skPaint, nul
lptr, true); | 570 SkGlyphCache* cache = blob->setupCache(runIndex, fSurfaceProps, dfPaint, nul
lptr, true); |
608 SkDrawCacheProc glyphCacheProc = skPaint.getDrawCacheProc(); | 571 SkDrawCacheProc glyphCacheProc = dfPaint.getDrawCacheProc(); |
609 GrFontScaler* fontScaler = GetGrFontScaler(cache); | 572 GrFontScaler* fontScaler = GetGrFontScaler(cache); |
610 | 573 |
611 const char* stop = text + byteLength; | 574 const char* stop = text + byteLength; |
612 | 575 |
613 if (SkPaint::kLeft_Align == skPaint.getTextAlign()) { | 576 if (SkPaint::kLeft_Align == dfPaint.getTextAlign()) { |
614 while (text < stop) { | 577 while (text < stop) { |
615 const char* lastText = text; | 578 const char* lastText = text; |
616 // the last 2 parameters are ignored | 579 // the last 2 parameters are ignored |
617 const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0); | 580 const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0); |
618 | 581 |
619 if (glyph.fWidth) { | 582 if (glyph.fWidth) { |
620 SkScalar x = offset.x() + pos[0]; | 583 SkScalar x = offset.x() + pos[0]; |
621 SkScalar y = offset.y() + (2 == scalarsPerPosition ? pos[1] : 0)
; | 584 SkScalar y = offset.y() + (2 == scalarsPerPosition ? pos[1] : 0)
; |
622 | 585 |
623 if (!this->dfAppendGlyph(blob, | 586 if (!this->dfAppendGlyph(blob, |
624 runIndex, | 587 runIndex, |
625 glyph, | 588 glyph, |
626 x, y, color, fontScaler, | 589 x, y, color, fontScaler, |
627 textRatio, viewMatrix)) { | 590 textRatio, viewMatrix)) { |
628 // couldn't append, send to fallback | 591 // couldn't append, send to fallback |
629 fallbackTxt.append(SkToInt(text-lastText), lastText); | 592 fallbackTxt.append(SkToInt(text-lastText), lastText); |
630 *fallbackPos.append() = pos[0]; | 593 *fallbackPos.append() = pos[0]; |
631 if (2 == scalarsPerPosition) { | 594 if (2 == scalarsPerPosition) { |
632 *fallbackPos.append() = pos[1]; | 595 *fallbackPos.append() = pos[1]; |
633 } | 596 } |
634 } | 597 } |
635 } | 598 } |
636 pos += scalarsPerPosition; | 599 pos += scalarsPerPosition; |
637 } | 600 } |
638 } else { | 601 } else { |
639 SkScalar alignMul = SkPaint::kCenter_Align == skPaint.getTextAlign() ? S
K_ScalarHalf | 602 SkScalar alignMul = SkPaint::kCenter_Align == dfPaint.getTextAlign() ? S
K_ScalarHalf |
640 : S
K_Scalar1; | 603 : S
K_Scalar1; |
641 while (text < stop) { | 604 while (text < stop) { |
642 const char* lastText = text; | 605 const char* lastText = text; |
643 // the last 2 parameters are ignored | 606 // the last 2 parameters are ignored |
644 const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0); | 607 const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0); |
645 | 608 |
646 if (glyph.fWidth) { | 609 if (glyph.fWidth) { |
647 SkScalar x = offset.x() + pos[0]; | 610 SkScalar x = offset.x() + pos[0]; |
648 SkScalar y = offset.y() + (2 == scalarsPerPosition ? pos[1] : 0)
; | 611 SkScalar y = offset.y() + (2 == scalarsPerPosition ? pos[1] : 0)
; |
649 | 612 |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
765 | 728 |
766 SkScalar transX = static_cast<SkScalar>(random->nextU()); | 729 SkScalar transX = static_cast<SkScalar>(random->nextU()); |
767 SkScalar transY = static_cast<SkScalar>(random->nextU()); | 730 SkScalar transY = static_cast<SkScalar>(random->nextU()); |
768 const GrAtlasTextBlob::Run::SubRunInfo& info = blob->fRuns[0].fSubRunInfo[0]
; | 731 const GrAtlasTextBlob::Run::SubRunInfo& info = blob->fRuns[0].fSubRunInfo[0]
; |
769 return blob->createBatch(info, textLen, 0, 0, color, transX, transY, skPaint
, | 732 return blob->createBatch(info, textLen, 0, 0, color, transX, transY, skPaint
, |
770 gSurfaceProps, gTextContext->dfAdjustTable(), | 733 gSurfaceProps, gTextContext->dfAdjustTable(), |
771 context->getBatchFontCache()); | 734 context->getBatchFontCache()); |
772 } | 735 } |
773 | 736 |
774 #endif | 737 #endif |
OLD | NEW |