| 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 |