| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2014 Google Inc. | 2 * Copyright 2014 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 | 7 |
| 8 #include "GrStencilAndCoverTextContext.h" | 8 #include "GrStencilAndCoverTextContext.h" |
| 9 #include "GrAtlasTextContext.h" | 9 #include "GrAtlasTextContext.h" |
| 10 #include "GrContext.h" | 10 #include "GrContext.h" |
| (...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 228 GrPipelineBuilder pipelineBuilder(paint, dc->accessRenderTarget(), clip); | 228 GrPipelineBuilder pipelineBuilder(paint, dc->accessRenderTarget(), clip); |
| 229 | 229 |
| 230 TextBlob::Iter iter(blob); | 230 TextBlob::Iter iter(blob); |
| 231 for (TextRun* run = iter.get(); run; run = iter.next()) { | 231 for (TextRun* run = iter.get(); run; run = iter.next()) { |
| 232 run->draw(context, dc, &pipelineBuilder, paint.getColor(), viewMatrix, p
rops, x, y, | 232 run->draw(context, dc, &pipelineBuilder, paint.getColor(), viewMatrix, p
rops, x, y, |
| 233 clipBounds, fFallbackTextContext, skPaint); | 233 clipBounds, fFallbackTextContext, skPaint); |
| 234 run->releaseGlyphCache(); | 234 run->releaseGlyphCache(); |
| 235 } | 235 } |
| 236 } | 236 } |
| 237 | 237 |
| 238 static inline int style_key_cnt(const GrStyle& style) { | |
| 239 int cnt = GrStyle::KeySize(style, GrStyle::Apply::kPathEffectAndStrokeRec); | |
| 240 // We should be able to make a key because we filtered out arbitrary path ef
fects. | |
| 241 SkASSERT(cnt > 0); | |
| 242 return cnt; | |
| 243 } | |
| 244 | |
| 245 static inline void write_style_key(uint32_t* dst, const GrStyle& style) { | |
| 246 // Pass 1 for the scale since the GPU will apply the style not GrStyle::appl
yToPath(). | |
| 247 GrStyle::WriteKey(dst, style, GrStyle::Apply::kPathEffectAndStrokeRec, SK_Sc
alar1); | |
| 248 } | |
| 249 | |
| 250 const GrStencilAndCoverTextContext::TextBlob& | 238 const GrStencilAndCoverTextContext::TextBlob& |
| 251 GrStencilAndCoverTextContext::findOrCreateTextBlob(const SkTextBlob* skBlob, | 239 GrStencilAndCoverTextContext::findOrCreateTextBlob(const SkTextBlob* skBlob, |
| 252 const SkPaint& skPaint) { | 240 const SkPaint& skPaint) { |
| 253 // The font-related parameters are baked into the text blob and will overrid
e this skPaint, so | 241 // The font-related parameters are baked into the text blob and will overrid
e this skPaint, so |
| 254 // the only remaining properties that can affect a TextBlob are the ones rel
ated to stroke. | 242 // the only remaining properties that can affect a TextBlob are the ones rel
ated to stroke. |
| 255 if (SkPaint::kFill_Style == skPaint.getStyle()) { // Fast path. | 243 if (SkPaint::kFill_Style == skPaint.getStyle()) { // Fast path. |
| 256 if (TextBlob** found = fBlobIdCache.find(skBlob->uniqueID())) { | 244 if (TextBlob** found = fBlobIdCache.find(skBlob->uniqueID())) { |
| 257 fLRUList.remove(*found); | 245 fLRUList.remove(*found); |
| 258 fLRUList.addToTail(*found); | 246 fLRUList.addToTail(*found); |
| 259 return **found; | 247 return **found; |
| 260 } | 248 } |
| 261 TextBlob* blob = new TextBlob(skBlob->uniqueID(), skBlob, skPaint); | 249 TextBlob* blob = new TextBlob(skBlob->uniqueID(), skBlob, skPaint); |
| 262 this->purgeToFit(*blob); | 250 this->purgeToFit(*blob); |
| 263 fBlobIdCache.set(skBlob->uniqueID(), blob); | 251 fBlobIdCache.set(skBlob->uniqueID(), blob); |
| 264 fLRUList.addToTail(blob); | 252 fLRUList.addToTail(blob); |
| 265 fCacheSize += blob->cpuMemorySize(); | 253 fCacheSize += blob->cpuMemorySize(); |
| 266 return *blob; | 254 return *blob; |
| 267 } else { | 255 } else { |
| 268 GrStyle style(skPaint); | 256 GrStrokeInfo stroke(skPaint); |
| 269 SkSTArray<4, uint32_t, true> key; | 257 SkSTArray<4, uint32_t, true> key; |
| 270 key.reset(1 + style_key_cnt(style)); | 258 key.reset(1 + stroke.computeUniqueKeyFragmentData32Cnt()); |
| 271 key[0] = skBlob->uniqueID(); | 259 key[0] = skBlob->uniqueID(); |
| 272 write_style_key(&key[1], style); | 260 stroke.asUniqueKeyFragment(&key[1]); |
| 273 if (TextBlob** found = fBlobKeyCache.find(key)) { | 261 if (TextBlob** found = fBlobKeyCache.find(key)) { |
| 274 fLRUList.remove(*found); | 262 fLRUList.remove(*found); |
| 275 fLRUList.addToTail(*found); | 263 fLRUList.addToTail(*found); |
| 276 return **found; | 264 return **found; |
| 277 } | 265 } |
| 278 TextBlob* blob = new TextBlob(key, skBlob, skPaint); | 266 TextBlob* blob = new TextBlob(key, skBlob, skPaint); |
| 279 this->purgeToFit(*blob); | 267 this->purgeToFit(*blob); |
| 280 fBlobKeyCache.set(blob); | 268 fBlobKeyCache.set(blob); |
| 281 fLRUList.addToTail(blob); | 269 fLRUList.addToTail(blob); |
| 282 fCacheSize += blob->cpuMemorySize(); | 270 fCacheSize += blob->cpuMemorySize(); |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 358 SkPaint fFont; | 346 SkPaint fFont; |
| 359 int fBuffIdx; | 347 int fBuffIdx; |
| 360 int fCount; | 348 int fCount; |
| 361 uint16_t fGlyphIds[kWriteBufferSize]; | 349 uint16_t fGlyphIds[kWriteBufferSize]; |
| 362 SkPoint fPositions[kWriteBufferSize]; | 350 SkPoint fPositions[kWriteBufferSize]; |
| 363 }; | 351 }; |
| 364 | 352 |
| 365 ////////////////////////////////////////////////////////////////////////////////
//////////////////// | 353 ////////////////////////////////////////////////////////////////////////////////
//////////////////// |
| 366 | 354 |
| 367 GrStencilAndCoverTextContext::TextRun::TextRun(const SkPaint& fontAndStroke) | 355 GrStencilAndCoverTextContext::TextRun::TextRun(const SkPaint& fontAndStroke) |
| 368 : fStyle(fontAndStroke), | 356 : fStroke(fontAndStroke), |
| 369 fFont(fontAndStroke), | 357 fFont(fontAndStroke), |
| 370 fTotalGlyphCount(0), | 358 fTotalGlyphCount(0), |
| 371 fFallbackGlyphCount(0), | 359 fFallbackGlyphCount(0), |
| 372 fDetachedGlyphCache(nullptr), | 360 fDetachedGlyphCache(nullptr), |
| 373 fLastDrawnGlyphsID(SK_InvalidUniqueID) { | 361 fLastDrawnGlyphsID(SK_InvalidUniqueID) { |
| 374 SkASSERT(fFont.getTextSize() > 0); | 362 SkASSERT(fFont.getTextSize() > 0); |
| 375 SkASSERT(!fStyle.hasNonDashPathEffect()); // Arbitrary path effects not supp
orted. | 363 SkASSERT(!fStroke.isHairlineStyle()); // Hairlines are not supported. |
| 376 SkASSERT(!fStyle.isSimpleHairline()); // Hairlines are not supported. | |
| 377 | 364 |
| 378 // Setting to "fill" ensures that no strokes get baked into font outlines. (
We use the GPU path | 365 // Setting to "fill" ensures that no strokes get baked into font outlines. (
We use the GPU path |
| 379 // rendering API for stroking). | 366 // rendering API for stroking). |
| 380 fFont.setStyle(SkPaint::kFill_Style); | 367 fFont.setStyle(SkPaint::kFill_Style); |
| 381 | 368 |
| 382 if (fFont.isFakeBoldText() && fStyle.isSimpleFill()) { | 369 if (fFont.isFakeBoldText() && SkStrokeRec::kStroke_Style != fStroke.getStyle
()) { |
| 383 const SkStrokeRec& stroke = fStyle.strokeRec(); | |
| 384 // Instead of letting fake bold get baked into the glyph outlines, do it
with GPU stroke. | 370 // Instead of letting fake bold get baked into the glyph outlines, do it
with GPU stroke. |
| 385 SkScalar fakeBoldScale = SkScalarInterpFunc(fFont.getTextSize(), | 371 SkScalar fakeBoldScale = SkScalarInterpFunc(fFont.getTextSize(), |
| 386 kStdFakeBoldInterpKeys, | 372 kStdFakeBoldInterpKeys, |
| 387 kStdFakeBoldInterpValues, | 373 kStdFakeBoldInterpValues, |
| 388 kStdFakeBoldInterpLength); | 374 kStdFakeBoldInterpLength); |
| 389 SkScalar extra = SkScalarMul(fFont.getTextSize(), fakeBoldScale); | 375 SkScalar extra = SkScalarMul(fFont.getTextSize(), fakeBoldScale); |
| 376 fStroke.setStrokeStyle(fStroke.needToApply() ? fStroke.getWidth() + extr
a : extra, |
| 377 true /*strokeAndFill*/); |
| 390 | 378 |
| 391 SkStrokeRec strokeRec(SkStrokeRec::kFill_InitStyle); | |
| 392 strokeRec.setStrokeStyle(stroke.needToApply() ? stroke.getWidth() + extr
a : extra, | |
| 393 true /*strokeAndFill*/); | |
| 394 fStyle = GrStyle(strokeRec, fStyle.pathEffect()); | |
| 395 fFont.setFakeBoldText(false); | 379 fFont.setFakeBoldText(false); |
| 396 } | 380 } |
| 397 | 381 |
| 398 if (!fFont.getPathEffect() && !fStyle.isDashed()) { | 382 if (!fFont.getPathEffect() && !fStroke.isDashed()) { |
| 399 const SkStrokeRec& stroke = fStyle.strokeRec(); | |
| 400 // We can draw the glyphs from canonically sized paths. | 383 // We can draw the glyphs from canonically sized paths. |
| 401 fTextRatio = fFont.getTextSize() / SkPaint::kCanonicalTextSizeForPaths; | 384 fTextRatio = fFont.getTextSize() / SkPaint::kCanonicalTextSizeForPaths; |
| 402 fTextInverseRatio = SkPaint::kCanonicalTextSizeForPaths / fFont.getTextS
ize(); | 385 fTextInverseRatio = SkPaint::kCanonicalTextSizeForPaths / fFont.getTextS
ize(); |
| 403 | 386 |
| 404 // Compensate for the glyphs being scaled by fTextRatio. | 387 // Compensate for the glyphs being scaled by fTextRatio. |
| 405 if (!fStyle.isSimpleFill()) { | 388 if (!fStroke.isFillStyle()) { |
| 406 SkStrokeRec strokeRec(SkStrokeRec::kFill_InitStyle); | 389 fStroke.setStrokeStyle(fStroke.getWidth() / fTextRatio, |
| 407 strokeRec.setStrokeStyle(stroke.getWidth() / fTextRatio, | 390 SkStrokeRec::kStrokeAndFill_Style == fStroke.
getStyle()); |
| 408 SkStrokeRec::kStrokeAndFill_Style == stroke
.getStyle()); | |
| 409 fStyle = GrStyle(strokeRec, fStyle.pathEffect()); | |
| 410 } | 391 } |
| 411 | 392 |
| 412 fFont.setLinearText(true); | 393 fFont.setLinearText(true); |
| 413 fFont.setLCDRenderText(false); | 394 fFont.setLCDRenderText(false); |
| 414 fFont.setAutohinted(false); | 395 fFont.setAutohinted(false); |
| 415 fFont.setHinting(SkPaint::kNo_Hinting); | 396 fFont.setHinting(SkPaint::kNo_Hinting); |
| 416 fFont.setSubpixelText(true); | 397 fFont.setSubpixelText(true); |
| 417 fFont.setTextSize(SkIntToScalar(SkPaint::kCanonicalTextSizeForPaths)); | 398 fFont.setTextSize(SkIntToScalar(SkPaint::kCanonicalTextSizeForPaths)); |
| 418 | 399 |
| 419 fUsingRawGlyphPaths = SK_Scalar1 == fFont.getTextScaleX() && | 400 fUsingRawGlyphPaths = SK_Scalar1 == fFont.getTextScaleX() && |
| 420 0 == fFont.getTextSkewX() && | 401 0 == fFont.getTextSkewX() && |
| 421 !fFont.isFakeBoldText() && | 402 !fFont.isFakeBoldText() && |
| 422 !fFont.isVerticalText(); | 403 !fFont.isVerticalText(); |
| 423 } else { | 404 } else { |
| 424 fTextRatio = fTextInverseRatio = 1.0f; | 405 fTextRatio = fTextInverseRatio = 1.0f; |
| 425 fUsingRawGlyphPaths = false; | 406 fUsingRawGlyphPaths = false; |
| 426 } | 407 } |
| 427 | 408 |
| 428 // Generate the key that will be used to cache the GPU glyph path objects. | 409 // Generate the key that will be used to cache the GPU glyph path objects. |
| 429 if (fUsingRawGlyphPaths && fStyle.isSimpleFill()) { | 410 if (fUsingRawGlyphPaths && fStroke.isFillStyle()) { |
| 430 static const GrUniqueKey::Domain kRawFillPathGlyphDomain = GrUniqueKey::
GenerateDomain(); | 411 static const GrUniqueKey::Domain kRawFillPathGlyphDomain = GrUniqueKey::
GenerateDomain(); |
| 431 | 412 |
| 432 const SkTypeface* typeface = fFont.getTypeface(); | 413 const SkTypeface* typeface = fFont.getTypeface(); |
| 433 GrUniqueKey::Builder builder(&fGlyphPathsKey, kRawFillPathGlyphDomain, 1
); | 414 GrUniqueKey::Builder builder(&fGlyphPathsKey, kRawFillPathGlyphDomain, 1
); |
| 434 reinterpret_cast<uint32_t&>(builder[0]) = typeface ? typeface->uniqueID(
) : 0; | 415 reinterpret_cast<uint32_t&>(builder[0]) = typeface ? typeface->uniqueID(
) : 0; |
| 435 } else { | 416 } else { |
| 436 static const GrUniqueKey::Domain kPathGlyphDomain = GrUniqueKey::Generat
eDomain(); | 417 static const GrUniqueKey::Domain kPathGlyphDomain = GrUniqueKey::Generat
eDomain(); |
| 437 | 418 |
| 438 int styleDataCount = GrStyle::KeySize(fStyle, GrStyle::Apply::kPathEffec
tAndStrokeRec); | 419 int strokeDataCount = fStroke.computeUniqueKeyFragmentData32Cnt(); |
| 439 // Key should be valid since we opted out of drawing arbitrary path effe
cts. | |
| 440 SkASSERT(styleDataCount >= 0); | |
| 441 if (fUsingRawGlyphPaths) { | 420 if (fUsingRawGlyphPaths) { |
| 442 const SkTypeface* typeface = fFont.getTypeface(); | 421 const SkTypeface* typeface = fFont.getTypeface(); |
| 443 GrUniqueKey::Builder builder(&fGlyphPathsKey, kPathGlyphDomain, 2 +
styleDataCount); | 422 GrUniqueKey::Builder builder(&fGlyphPathsKey, kPathGlyphDomain, 2 +
strokeDataCount); |
| 444 reinterpret_cast<uint32_t&>(builder[0]) = typeface ? typeface->uniqu
eID() : 0; | 423 reinterpret_cast<uint32_t&>(builder[0]) = typeface ? typeface->uniqu
eID() : 0; |
| 445 reinterpret_cast<uint32_t&>(builder[1]) = styleDataCount; | 424 reinterpret_cast<uint32_t&>(builder[1]) = strokeDataCount; |
| 446 if (styleDataCount) { | 425 fStroke.asUniqueKeyFragment(&builder[2]); |
| 447 write_style_key(&builder[2], fStyle); | |
| 448 } | |
| 449 } else { | 426 } else { |
| 450 SkGlyphCache* glyphCache = this->getGlyphCache(); | 427 SkGlyphCache* glyphCache = this->getGlyphCache(); |
| 451 const SkTypeface* typeface = glyphCache->getScalerContext()->getType
face(); | 428 const SkTypeface* typeface = glyphCache->getScalerContext()->getType
face(); |
| 452 const SkDescriptor* desc = &glyphCache->getDescriptor(); | 429 const SkDescriptor* desc = &glyphCache->getDescriptor(); |
| 453 int descDataCount = (desc->getLength() + 3) / 4; | 430 int descDataCount = (desc->getLength() + 3) / 4; |
| 454 GrUniqueKey::Builder builder(&fGlyphPathsKey, kPathGlyphDomain, | 431 GrUniqueKey::Builder builder(&fGlyphPathsKey, kPathGlyphDomain, |
| 455 2 + styleDataCount + descDataCount); | 432 2 + strokeDataCount + descDataCount); |
| 456 reinterpret_cast<uint32_t&>(builder[0]) = typeface ? typeface->uniqu
eID() : 0; | 433 reinterpret_cast<uint32_t&>(builder[0]) = typeface ? typeface->uniqu
eID() : 0; |
| 457 reinterpret_cast<uint32_t&>(builder[1]) = styleDataCount | (descData
Count << 16); | 434 reinterpret_cast<uint32_t&>(builder[1]) = strokeDataCount | (descDat
aCount << 16); |
| 458 if (styleDataCount) { | 435 fStroke.asUniqueKeyFragment(&builder[2]); |
| 459 write_style_key(&builder[2], fStyle); | 436 memcpy(&builder[2 + strokeDataCount], desc, desc->getLength()); |
| 460 } | |
| 461 memcpy(&builder[2 + styleDataCount], desc, desc->getLength()); | |
| 462 } | 437 } |
| 463 } | 438 } |
| 464 } | 439 } |
| 465 | 440 |
| 466 GrStencilAndCoverTextContext::TextRun::~TextRun() { | 441 GrStencilAndCoverTextContext::TextRun::~TextRun() { |
| 467 this->releaseGlyphCache(); | 442 this->releaseGlyphCache(); |
| 468 } | 443 } |
| 469 | 444 |
| 470 void GrStencilAndCoverTextContext::TextRun::setText(const char text[], size_t by
teLength, | 445 void GrStencilAndCoverTextContext::TextRun::setText(const char text[], size_t by
teLength, |
| 471 SkScalar x, SkScalar y) { | 446 SkScalar x, SkScalar y) { |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 559 fFallbackTextBlob.reset(fallback.buildIfNeeded(&fFallbackGlyphCount)); | 534 fFallbackTextBlob.reset(fallback.buildIfNeeded(&fFallbackGlyphCount)); |
| 560 } | 535 } |
| 561 | 536 |
| 562 GrPathRange* GrStencilAndCoverTextContext::TextRun::createGlyphs(GrContext* ctx)
const { | 537 GrPathRange* GrStencilAndCoverTextContext::TextRun::createGlyphs(GrContext* ctx)
const { |
| 563 GrPathRange* glyphs = static_cast<GrPathRange*>( | 538 GrPathRange* glyphs = static_cast<GrPathRange*>( |
| 564 ctx->resourceProvider()->findAndRefResourceByUniqueKey(fGlyphPathsKe
y)); | 539 ctx->resourceProvider()->findAndRefResourceByUniqueKey(fGlyphPathsKe
y)); |
| 565 if (nullptr == glyphs) { | 540 if (nullptr == glyphs) { |
| 566 if (fUsingRawGlyphPaths) { | 541 if (fUsingRawGlyphPaths) { |
| 567 SkScalerContextEffects noeffects; | 542 SkScalerContextEffects noeffects; |
| 568 glyphs = ctx->resourceProvider()->createGlyphs(fFont.getTypeface(),
noeffects, | 543 glyphs = ctx->resourceProvider()->createGlyphs(fFont.getTypeface(),
noeffects, |
| 569 nullptr, fStyle); | 544 nullptr, fStroke); |
| 570 } else { | 545 } else { |
| 571 SkGlyphCache* cache = this->getGlyphCache(); | 546 SkGlyphCache* cache = this->getGlyphCache(); |
| 572 glyphs = ctx->resourceProvider()->createGlyphs(cache->getScalerConte
xt()->getTypeface(), | 547 glyphs = ctx->resourceProvider()->createGlyphs(cache->getScalerConte
xt()->getTypeface(), |
| 573 cache->getScalerConte
xt()->getEffects(), | 548 cache->getScalerConte
xt()->getEffects(), |
| 574 &cache->getDescriptor
(), | 549 &cache->getDescriptor
(), |
| 575 fStyle); | 550 fStroke); |
| 576 } | 551 } |
| 577 ctx->resourceProvider()->assignUniqueKeyToResource(fGlyphPathsKey, glyph
s); | 552 ctx->resourceProvider()->assignUniqueKeyToResource(fGlyphPathsKey, glyph
s); |
| 578 } | 553 } |
| 579 return glyphs; | 554 return glyphs; |
| 580 } | 555 } |
| 581 | 556 |
| 582 inline void GrStencilAndCoverTextContext::TextRun::appendGlyph(const SkGlyph& gl
yph, | 557 inline void GrStencilAndCoverTextContext::TextRun::appendGlyph(const SkGlyph& gl
yph, |
| 583 const SkPoint& po
s, | 558 const SkPoint& po
s, |
| 584 FallbackBlobBuild
er* fallback) { | 559 FallbackBlobBuild
er* fallback) { |
| 585 // Stick the glyphs we can't draw into the fallback text blob. | 560 // Stick the glyphs we can't draw into the fallback text blob. |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 639 GrDrawPathRangeBatch::Create(viewMatrix, fTextRatio, fTextInverseRat
io * x, | 614 GrDrawPathRangeBatch::Create(viewMatrix, fTextRatio, fTextInverseRat
io * x, |
| 640 fTextInverseRatio * y, color, | 615 fTextInverseRatio * y, color, |
| 641 GrPathRendering::kWinding_FillType, gly
phs, fInstanceData, | 616 GrPathRendering::kWinding_FillType, gly
phs, fInstanceData, |
| 642 bounds)); | 617 bounds)); |
| 643 | 618 |
| 644 dc->drawPathBatch(*pipelineBuilder, batch); | 619 dc->drawPathBatch(*pipelineBuilder, batch); |
| 645 } | 620 } |
| 646 | 621 |
| 647 if (fFallbackTextBlob) { | 622 if (fFallbackTextBlob) { |
| 648 SkPaint fallbackSkPaint(originalSkPaint); | 623 SkPaint fallbackSkPaint(originalSkPaint); |
| 649 fStyle.strokeRec().applyToPaint(&fallbackSkPaint); | 624 fStroke.applyToPaint(&fallbackSkPaint); |
| 650 if (!fStyle.isSimpleFill()) { | 625 if (!fStroke.isFillStyle()) { |
| 651 fallbackSkPaint.setStrokeWidth(fStyle.strokeRec().getWidth() * fText
Ratio); | 626 fallbackSkPaint.setStrokeWidth(fStroke.getWidth() * fTextRatio); |
| 652 } | 627 } |
| 653 | 628 |
| 654 fallbackTextContext->drawTextBlob(ctx, dc, pipelineBuilder->clip(), fall
backSkPaint, | 629 fallbackTextContext->drawTextBlob(ctx, dc, pipelineBuilder->clip(), fall
backSkPaint, |
| 655 viewMatrix, props, fFallbackTextBlob,
x, y, nullptr, | 630 viewMatrix, props, fFallbackTextBlob,
x, y, nullptr, |
| 656 clipBounds); | 631 clipBounds); |
| 657 } | 632 } |
| 658 } | 633 } |
| 659 | 634 |
| 660 SkGlyphCache* GrStencilAndCoverTextContext::TextRun::getGlyphCache() const { | 635 SkGlyphCache* GrStencilAndCoverTextContext::TextRun::getGlyphCache() const { |
| 661 if (!fDetachedGlyphCache) { | 636 if (!fDetachedGlyphCache) { |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 728 } | 703 } |
| 729 | 704 |
| 730 const SkTextBlob* GrStencilAndCoverTextContext::FallbackBlobBuilder::buildIfNeed
ed(int *count) { | 705 const SkTextBlob* GrStencilAndCoverTextContext::FallbackBlobBuilder::buildIfNeed
ed(int *count) { |
| 731 *count = fCount; | 706 *count = fCount; |
| 732 if (fCount) { | 707 if (fCount) { |
| 733 this->flush(); | 708 this->flush(); |
| 734 return fBuilder->build(); | 709 return fBuilder->build(); |
| 735 } | 710 } |
| 736 return nullptr; | 711 return nullptr; |
| 737 } | 712 } |
| OLD | NEW |