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 | 7 |
8 #include "GrDistanceFieldTextContext.h" | 8 #include "GrDistanceFieldTextContext.h" |
9 #include "GrAtlas.h" | 9 #include "GrAtlas.h" |
10 #include "GrBitmapTextContext.h" | 10 #include "GrBitmapTextContext.h" |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
49 | 49 |
50 // position + color + texture coord | 50 // position + color + texture coord |
51 extern const GrVertexAttrib gTextVertexWithColorAttribs[] = { | 51 extern const GrVertexAttrib gTextVertexWithColorAttribs[] = { |
52 {kVec2f_GrVertexAttribType, 0, kPosition_Gr
VertexAttribBinding}, | 52 {kVec2f_GrVertexAttribType, 0, kPosition_Gr
VertexAttribBinding}, |
53 {kVec4ub_GrVertexAttribType, sizeof(SkPoint), kColor_GrVer
texAttribBinding}, | 53 {kVec4ub_GrVertexAttribType, sizeof(SkPoint), kColor_GrVer
texAttribBinding}, |
54 {kVec2f_GrVertexAttribType, sizeof(SkPoint) + sizeof(GrColor), kGeometryPro
cessor_GrVertexAttribBinding} | 54 {kVec2f_GrVertexAttribType, sizeof(SkPoint) + sizeof(GrColor), kGeometryPro
cessor_GrVertexAttribBinding} |
55 }; | 55 }; |
56 | 56 |
57 static const size_t kTextVAColorSize = 2 * sizeof(SkPoint) + sizeof(GrColor); | 57 static const size_t kTextVAColorSize = 2 * sizeof(SkPoint) + sizeof(GrColor); |
58 | 58 |
| 59 static const int kVerticesPerGlyph = 4; |
| 60 static const int kIndicesPerGlyph = 6; |
59 }; | 61 }; |
60 | 62 |
61 GrDistanceFieldTextContext::GrDistanceFieldTextContext(GrContext* context, | 63 GrDistanceFieldTextContext::GrDistanceFieldTextContext(GrContext* context, |
62 const SkDeviceProperties&
properties, | 64 const SkDeviceProperties&
properties, |
63 bool enable) | 65 bool enable) |
64 : GrTextContext(context, pro
perties) { | 66 : GrTextContext(context, pro
perties) { |
65 #if SK_FORCE_DISTANCEFIELD_FONTS | 67 #if SK_FORCE_DISTANCEFIELD_FONTS |
66 fEnableDFRendering = true; | 68 fEnableDFRendering = true; |
67 #else | 69 #else |
68 fEnableDFRendering = enable; | 70 fEnableDFRendering = enable; |
69 #endif | 71 #endif |
70 fStrike = NULL; | 72 fStrike = NULL; |
71 fGammaTexture = NULL; | 73 fGammaTexture = NULL; |
72 | 74 |
73 fCurrTexture = NULL; | |
74 fCurrVertex = 0; | |
75 fEffectTextureUniqueID = SK_InvalidUniqueID; | 75 fEffectTextureUniqueID = SK_InvalidUniqueID; |
76 fEffectColor = GrColor_ILLEGAL; | 76 fEffectColor = GrColor_ILLEGAL; |
77 fEffectFlags = 0; | 77 fEffectFlags = 0; |
78 | 78 |
79 fVertices = NULL; | 79 fVertices = NULL; |
80 fMaxVertices = 0; | 80 fCurrVertex = 0; |
| 81 fAllocVertexCount = 0; |
| 82 fTotalVertexCount = 0; |
| 83 fCurrTexture = NULL; |
81 | 84 |
82 fVertexBounds.setLargestInverted(); | 85 fVertexBounds.setLargestInverted(); |
83 } | 86 } |
84 | 87 |
85 GrDistanceFieldTextContext* GrDistanceFieldTextContext::Create(GrContext* contex
t, | 88 GrDistanceFieldTextContext* GrDistanceFieldTextContext::Create(GrContext* contex
t, |
86 const SkDevicePro
perties& props, | 89 const SkDevicePro
perties& props, |
87 bool enable) { | 90 bool enable) { |
88 GrDistanceFieldTextContext* textContext = SkNEW_ARGS(GrDistanceFieldTextCont
ext, | 91 GrDistanceFieldTextContext* textContext = SkNEW_ARGS(GrDistanceFieldTextCont
ext, |
89 (context, props, enable
)); | 92 (context, props, enable
)); |
90 textContext->fFallbackTextContext = GrBitmapTextContext::Create(context, pro
ps); | 93 textContext->fFallbackTextContext = GrBitmapTextContext::Create(context, pro
ps); |
91 | 94 |
92 return textContext; | 95 return textContext; |
93 } | 96 } |
94 | 97 |
95 GrDistanceFieldTextContext::~GrDistanceFieldTextContext() { | 98 GrDistanceFieldTextContext::~GrDistanceFieldTextContext() { |
96 this->flush(); | 99 this->finish(); |
97 SkSafeSetNull(fGammaTexture); | 100 SkSafeSetNull(fGammaTexture); |
98 } | 101 } |
99 | 102 |
100 bool GrDistanceFieldTextContext::canDraw(const SkPaint& paint) { | 103 bool GrDistanceFieldTextContext::canDraw(const SkPaint& paint) { |
101 if (!fEnableDFRendering && !paint.isDistanceFieldTextTEMP()) { | 104 if (!fEnableDFRendering && !paint.isDistanceFieldTextTEMP()) { |
102 return false; | 105 return false; |
103 } | 106 } |
104 | 107 |
105 // rasterizers and mask filters modify alpha, which doesn't | 108 // rasterizers and mask filters modify alpha, which doesn't |
106 // translate well to distance | 109 // translate well to distance |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
138 SkScalar maxScale = ctm.getMaxScale(); | 141 SkScalar maxScale = ctm.getMaxScale(); |
139 SkScalar textSize = fSkPaint.getTextSize(); | 142 SkScalar textSize = fSkPaint.getTextSize(); |
140 SkScalar scaledTextSize = textSize; | 143 SkScalar scaledTextSize = textSize; |
141 // if we have non-unity scale, we need to choose our base text size | 144 // if we have non-unity scale, we need to choose our base text size |
142 // based on the SkPaint's text size multiplied by the max scale factor | 145 // based on the SkPaint's text size multiplied by the max scale factor |
143 // TODO: do we need to do this if we're scaling down (i.e. maxScale < 1)? | 146 // TODO: do we need to do this if we're scaling down (i.e. maxScale < 1)? |
144 if (maxScale > 0 && !SkScalarNearlyEqual(maxScale, SK_Scalar1)) { | 147 if (maxScale > 0 && !SkScalarNearlyEqual(maxScale, SK_Scalar1)) { |
145 scaledTextSize *= maxScale; | 148 scaledTextSize *= maxScale; |
146 } | 149 } |
147 | 150 |
| 151 fVertices = NULL; |
148 fCurrVertex = 0; | 152 fCurrVertex = 0; |
149 | 153 fAllocVertexCount = 0; |
150 fVertices = NULL; | 154 fTotalVertexCount = 0; |
151 | 155 |
152 if (scaledTextSize <= kSmallDFFontLimit) { | 156 if (scaledTextSize <= kSmallDFFontLimit) { |
153 fTextRatio = textSize / kSmallDFFontSize; | 157 fTextRatio = textSize / kSmallDFFontSize; |
154 fSkPaint.setTextSize(SkIntToScalar(kSmallDFFontSize)); | 158 fSkPaint.setTextSize(SkIntToScalar(kSmallDFFontSize)); |
155 } else if (scaledTextSize <= kMediumDFFontLimit) { | 159 } else if (scaledTextSize <= kMediumDFFontLimit) { |
156 fTextRatio = textSize / kMediumDFFontSize; | 160 fTextRatio = textSize / kMediumDFFontSize; |
157 fSkPaint.setTextSize(SkIntToScalar(kMediumDFFontSize)); | 161 fSkPaint.setTextSize(SkIntToScalar(kMediumDFFontSize)); |
158 } else { | 162 } else { |
159 fTextRatio = textSize / kLargeDFFontSize; | 163 fTextRatio = textSize / kLargeDFFontSize; |
160 fSkPaint.setTextSize(SkIntToScalar(kLargeDFFontSize)); | 164 fSkPaint.setTextSize(SkIntToScalar(kLargeDFFontSize)); |
161 } | 165 } |
162 | 166 |
163 fUseLCDText = fSkPaint.isLCDRenderText(); | 167 fUseLCDText = fSkPaint.isLCDRenderText(); |
164 | 168 |
165 fSkPaint.setLCDRenderText(false); | 169 fSkPaint.setLCDRenderText(false); |
166 fSkPaint.setAutohinted(false); | 170 fSkPaint.setAutohinted(false); |
167 fSkPaint.setHinting(SkPaint::kNormal_Hinting); | 171 fSkPaint.setHinting(SkPaint::kNormal_Hinting); |
168 fSkPaint.setSubpixelText(true); | 172 fSkPaint.setSubpixelText(true); |
169 | |
170 } | 173 } |
171 | 174 |
172 static void setup_gamma_texture(GrContext* context, const SkGlyphCache* cache, | 175 static void setup_gamma_texture(GrContext* context, const SkGlyphCache* cache, |
173 const SkDeviceProperties& deviceProperties, | 176 const SkDeviceProperties& deviceProperties, |
174 GrTexture** gammaTexture) { | 177 GrTexture** gammaTexture) { |
175 if (NULL == *gammaTexture) { | 178 if (NULL == *gammaTexture) { |
176 int width, height; | 179 int width, height; |
177 size_t size; | 180 size_t size; |
178 | 181 |
179 #ifdef SK_GAMMA_CONTRAST | 182 #ifdef SK_GAMMA_CONTRAST |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
286 this->init(paint, skPaint); | 289 this->init(paint, skPaint); |
287 | 290 |
288 SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc(); | 291 SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc(); |
289 | 292 |
290 SkAutoGlyphCacheNoGamma autoCache(fSkPaint, &fDeviceProperties, NULL); | 293 SkAutoGlyphCacheNoGamma autoCache(fSkPaint, &fDeviceProperties, NULL); |
291 SkGlyphCache* cache = autoCache.getCache(); | 294 SkGlyphCache* cache = autoCache.getCache(); |
292 GrFontScaler* fontScaler = GetGrFontScaler(cache); | 295 GrFontScaler* fontScaler = GetGrFontScaler(cache); |
293 | 296 |
294 setup_gamma_texture(fContext, cache, fDeviceProperties, &fGammaTexture); | 297 setup_gamma_texture(fContext, cache, fDeviceProperties, &fGammaTexture); |
295 | 298 |
| 299 int numGlyphs = fSkPaint.textToGlyphs(text, byteLength, NULL); |
| 300 fTotalVertexCount = kVerticesPerGlyph*numGlyphs; |
| 301 |
296 const char* stop = text + byteLength; | 302 const char* stop = text + byteLength; |
297 SkTArray<char> fallbackTxt; | 303 SkTArray<char> fallbackTxt; |
298 SkTArray<SkScalar> fallbackPos; | 304 SkTArray<SkScalar> fallbackPos; |
299 | 305 |
300 if (SkPaint::kLeft_Align == fSkPaint.getTextAlign()) { | 306 if (SkPaint::kLeft_Align == fSkPaint.getTextAlign()) { |
301 while (text < stop) { | 307 while (text < stop) { |
302 const char* lastText = text; | 308 const char* lastText = text; |
303 // the last 2 parameters are ignored | 309 // the last 2 parameters are ignored |
304 const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0); | 310 const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0); |
305 | 311 |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
364 } | 370 } |
365 } | 371 } |
366 | 372 |
367 static inline GrColor skcolor_to_grcolor_nopremultiply(SkColor c) { | 373 static inline GrColor skcolor_to_grcolor_nopremultiply(SkColor c) { |
368 unsigned r = SkColorGetR(c); | 374 unsigned r = SkColorGetR(c); |
369 unsigned g = SkColorGetG(c); | 375 unsigned g = SkColorGetG(c); |
370 unsigned b = SkColorGetB(c); | 376 unsigned b = SkColorGetB(c); |
371 return GrColorPackRGBA(r, g, b, 0xff); | 377 return GrColorPackRGBA(r, g, b, 0xff); |
372 } | 378 } |
373 | 379 |
| 380 static void* alloc_vertices(GrDrawTarget* drawTarget, int numVertices, bool useC
olorVerts) { |
| 381 if (numVertices <= 0) { |
| 382 return NULL; |
| 383 } |
| 384 |
| 385 // set up attributes |
| 386 if (useColorVerts) { |
| 387 drawTarget->drawState()->setVertexAttribs<gTextVertexWithColorAttribs>( |
| 388 SK_ARRAY_COUNT(gTextVertexWithColorAttribs),
kTextVAColorSize); |
| 389 } else { |
| 390 drawTarget->drawState()->setVertexAttribs<gTextVertexAttribs>( |
| 391 SK_ARRAY_COUNT(gTextVertexAttribs), kTextVAS
ize); |
| 392 } |
| 393 void* vertices = NULL; |
| 394 bool success = drawTarget->reserveVertexAndIndexSpace(numVertices, |
| 395 0, |
| 396 &vertices, |
| 397 NULL); |
| 398 GrAlwaysAssert(success); |
| 399 return vertices; |
| 400 } |
| 401 |
374 void GrDistanceFieldTextContext::setupCoverageEffect(const SkColor& filteredColo
r) { | 402 void GrDistanceFieldTextContext::setupCoverageEffect(const SkColor& filteredColo
r) { |
375 GrTextureParams params(SkShader::kRepeat_TileMode, GrTextureParams::kBilerp_
FilterMode); | 403 GrTextureParams params(SkShader::kRepeat_TileMode, GrTextureParams::kBilerp_
FilterMode); |
376 GrTextureParams gammaParams(SkShader::kClamp_TileMode, GrTextureParams::kNon
e_FilterMode); | 404 GrTextureParams gammaParams(SkShader::kClamp_TileMode, GrTextureParams::kNon
e_FilterMode); |
377 | 405 |
378 uint32_t textureUniqueID = fCurrTexture->getUniqueID(); | 406 uint32_t textureUniqueID = fCurrTexture->getUniqueID(); |
379 const SkMatrix& ctm = fContext->getMatrix(); | 407 const SkMatrix& ctm = fContext->getMatrix(); |
380 | 408 |
381 // set up any flags | 409 // set up any flags |
382 uint32_t flags = 0; | 410 uint32_t flags = 0; |
383 flags |= ctm.isSimilarity() ? kSimilarity_DistanceFieldEffectFlag : 0; | 411 flags |= ctm.isSimilarity() ? kSimilarity_DistanceFieldEffectFlag : 0; |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
508 this->flush(); | 536 this->flush(); |
509 | 537 |
510 GrContext::AutoMatrix am; | 538 GrContext::AutoMatrix am; |
511 SkMatrix ctm; | 539 SkMatrix ctm; |
512 ctm.setScale(fTextRatio, fTextRatio); | 540 ctm.setScale(fTextRatio, fTextRatio); |
513 ctm.postTranslate(sx, sy); | 541 ctm.postTranslate(sx, sy); |
514 GrPaint tmpPaint(fPaint); | 542 GrPaint tmpPaint(fPaint); |
515 am.setPreConcat(fContext, ctm, &tmpPaint); | 543 am.setPreConcat(fContext, ctm, &tmpPaint); |
516 GrStrokeInfo strokeInfo(SkStrokeRec::kFill_InitStyle); | 544 GrStrokeInfo strokeInfo(SkStrokeRec::kFill_InitStyle); |
517 fContext->drawPath(tmpPaint, *glyph->fPath, strokeInfo); | 545 fContext->drawPath(tmpPaint, *glyph->fPath, strokeInfo); |
| 546 |
| 547 // remove this glyph from the vertices we need to allocate |
| 548 fTotalVertexCount -= kVerticesPerGlyph; |
518 return true; | 549 return true; |
519 } | 550 } |
520 | 551 |
521 HAS_ATLAS: | 552 HAS_ATLAS: |
522 SkASSERT(glyph->fPlot); | 553 SkASSERT(glyph->fPlot); |
523 GrDrawTarget::DrawToken drawToken = fDrawTarget->getCurrentDrawToken(); | 554 GrDrawTarget::DrawToken drawToken = fDrawTarget->getCurrentDrawToken(); |
524 glyph->fPlot->setDrawToken(drawToken); | 555 glyph->fPlot->setDrawToken(drawToken); |
525 | 556 |
526 GrTexture* texture = glyph->fPlot->texture(); | 557 GrTexture* texture = glyph->fPlot->texture(); |
527 SkASSERT(texture); | 558 SkASSERT(texture); |
528 | 559 |
529 if (fCurrTexture != texture || fCurrVertex + 4 > fMaxVertices) { | 560 if (fCurrTexture != texture || fCurrVertex + kVerticesPerGlyph > fTotalVerte
xCount) { |
530 this->flush(); | 561 this->flush(); |
531 fCurrTexture = texture; | 562 fCurrTexture = texture; |
532 fCurrTexture->ref(); | 563 fCurrTexture->ref(); |
533 } | 564 } |
534 | 565 |
535 bool useColorVerts = !fUseLCDText; | 566 bool useColorVerts = !fUseLCDText; |
536 | 567 |
537 if (NULL == fVertices) { | 568 if (NULL == fVertices) { |
538 // If we need to reserve vertices allow the draw target to suggest | 569 int maxQuadVertices = kVerticesPerGlyph * fContext->getQuadIndexBuffer()
->maxQuads(); |
539 // a number of verts to reserve and whether to perform a flush. | 570 fAllocVertexCount = SkMin32(fTotalVertexCount, maxQuadVertices); |
540 fMaxVertices = kMinRequestedVerts; | 571 fVertices = alloc_vertices(fDrawTarget, fAllocVertexCount, useColorVerts
); |
541 if (useColorVerts) { | |
542 fDrawTarget->drawState()->setVertexAttribs<gTextVertexWithColorAttri
bs>( | |
543 SK_ARRAY_COUNT(gTextVertexWithColorAttribs), kTextVAColorSize); | |
544 } else { | |
545 fDrawTarget->drawState()->setVertexAttribs<gTextVertexAttribs>( | |
546 SK_ARRAY_COUNT(gTextVertexAttribs), kTextVASize); | |
547 } | |
548 bool flush = fDrawTarget->geometryHints(&fMaxVertices, NULL); | |
549 if (flush) { | |
550 this->flush(); | |
551 fContext->flush(); | |
552 if (useColorVerts) { | |
553 fDrawTarget->drawState()->setVertexAttribs<gTextVertexWithColorA
ttribs>( | |
554 SK_ARRAY_COUNT(gTextVertexWithColorAttribs), kTextVAColorSiz
e); | |
555 } else { | |
556 fDrawTarget->drawState()->setVertexAttribs<gTextVertexAttribs>( | |
557 SK_ARRAY_COUNT(gTextVertexAttribs), kTextVASize); | |
558 } | |
559 } | |
560 fMaxVertices = kDefaultRequestedVerts; | |
561 // ignore return, no point in flushing again. | |
562 fDrawTarget->geometryHints(&fMaxVertices, NULL); | |
563 | |
564 int maxQuadVertices = 4 * fContext->getQuadIndexBuffer()->maxQuads(); | |
565 if (fMaxVertices < kMinRequestedVerts) { | |
566 fMaxVertices = kDefaultRequestedVerts; | |
567 } else if (fMaxVertices > maxQuadVertices) { | |
568 // don't exceed the limit of the index buffer | |
569 fMaxVertices = maxQuadVertices; | |
570 } | |
571 bool success = fDrawTarget->reserveVertexAndIndexSpace(fMaxVertices, | |
572 0, | |
573 &fVertices, | |
574 NULL); | |
575 GrAlwaysAssert(success); | |
576 } | 572 } |
577 | 573 |
578 SkScalar dx = SkIntToScalar(glyph->fBounds.fLeft + SK_DistanceFieldInset); | 574 SkScalar dx = SkIntToScalar(glyph->fBounds.fLeft + SK_DistanceFieldInset); |
579 SkScalar dy = SkIntToScalar(glyph->fBounds.fTop + SK_DistanceFieldInset); | 575 SkScalar dy = SkIntToScalar(glyph->fBounds.fTop + SK_DistanceFieldInset); |
580 SkScalar width = SkIntToScalar(glyph->fBounds.width() - 2*SK_DistanceFieldIn
set); | 576 SkScalar width = SkIntToScalar(glyph->fBounds.width() - 2*SK_DistanceFieldIn
set); |
581 SkScalar height = SkIntToScalar(glyph->fBounds.height() - 2*SK_DistanceField
Inset); | 577 SkScalar height = SkIntToScalar(glyph->fBounds.height() - 2*SK_DistanceField
Inset); |
582 | 578 |
583 SkScalar scale = fTextRatio; | 579 SkScalar scale = fTextRatio; |
584 dx *= scale; | 580 dx *= scale; |
585 dy *= scale; | 581 dy *= scale; |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
680 drawState->setColor(SkColorSetARGB(a, a, a, a)); | 676 drawState->setColor(SkColorSetARGB(a, a, a, a)); |
681 // paintColor | 677 // paintColor |
682 drawState->setBlendConstant(colorNoPreMul); | 678 drawState->setBlendConstant(colorNoPreMul); |
683 drawState->setBlendFunc(kConstC_GrBlendCoeff, kISC_GrBlendCoeff); | 679 drawState->setBlendFunc(kConstC_GrBlendCoeff, kISC_GrBlendCoeff); |
684 } else { | 680 } else { |
685 // set back to normal in case we took LCD path previously. | 681 // set back to normal in case we took LCD path previously. |
686 drawState->setBlendFunc(fPaint.getSrcBlendCoeff(), fPaint.getDstBlen
dCoeff()); | 682 drawState->setBlendFunc(fPaint.getSrcBlendCoeff(), fPaint.getDstBlen
dCoeff()); |
687 // We're using per-vertex color. | 683 // We're using per-vertex color. |
688 SkASSERT(drawState->hasColorVertexAttribute()); | 684 SkASSERT(drawState->hasColorVertexAttribute()); |
689 } | 685 } |
690 int nGlyphs = fCurrVertex / 4; | 686 int nGlyphs = fCurrVertex / kVerticesPerGlyph; |
691 fDrawTarget->setIndexSourceToBuffer(fContext->getQuadIndexBuffer()); | 687 fDrawTarget->setIndexSourceToBuffer(fContext->getQuadIndexBuffer()); |
692 fDrawTarget->drawIndexedInstances(kTriangles_GrPrimitiveType, | 688 fDrawTarget->drawIndexedInstances(kTriangles_GrPrimitiveType, |
693 nGlyphs, | 689 nGlyphs, |
694 4, 6, &fVertexBounds); | 690 kVerticesPerGlyph, kIndicesPerGlyph, &
fVertexBounds); |
695 fDrawTarget->resetVertexSource(); | 691 fDrawTarget->resetVertexSource(); |
696 fVertices = NULL; | 692 fVertices = NULL; |
697 fMaxVertices = 0; | 693 fTotalVertexCount -= fCurrVertex; |
698 fCurrVertex = 0; | 694 fCurrVertex = 0; |
699 SkSafeSetNull(fCurrTexture); | 695 SkSafeSetNull(fCurrTexture); |
700 fVertexBounds.setLargestInverted(); | 696 fVertexBounds.setLargestInverted(); |
701 } | 697 } |
702 } | 698 } |
703 | 699 |
704 inline void GrDistanceFieldTextContext::finish() { | 700 inline void GrDistanceFieldTextContext::finish() { |
705 this->flush(); | 701 this->flush(); |
| 702 fTotalVertexCount = 0; |
706 | 703 |
707 GrTextContext::finish(); | 704 GrTextContext::finish(); |
708 } | 705 } |
709 | 706 |
OLD | NEW |