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 "GrAtlas.h" | 9 #include "GrAtlas.h" |
10 #include "GrBatch.h" | 10 #include "GrBatch.h" |
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
253 } | 253 } |
254 | 254 |
255 if (blob.fViewMatrix.hasPerspective() != viewMatrix.hasPerspective()) { | 255 if (blob.fViewMatrix.hasPerspective() != viewMatrix.hasPerspective()) { |
256 return true; | 256 return true; |
257 } | 257 } |
258 | 258 |
259 if (blob.fViewMatrix.hasPerspective() && !blob.fViewMatrix.cheapEqualTo(view Matrix)) { | 259 if (blob.fViewMatrix.hasPerspective() && !blob.fViewMatrix.cheapEqualTo(view Matrix)) { |
260 return true; | 260 return true; |
261 } | 261 } |
262 | 262 |
263 if (blob.fViewMatrix.getScaleX() != viewMatrix.getScaleX() || | |
264 blob.fViewMatrix.getScaleY() != viewMatrix.getScaleY() || | |
265 blob.fViewMatrix.getSkewX() != viewMatrix.getSkewX() || | |
266 blob.fViewMatrix.getSkewY() != viewMatrix.getSkewY()) { | |
267 return true; | |
268 } | |
269 | |
270 // We only cache one masked version | 263 // We only cache one masked version |
271 if (blob.fKey.fHasBlur && | 264 if (blob.fKey.fHasBlur && |
272 (blob.fBlurRec.fSigma != blurRec.fSigma || | 265 (blob.fBlurRec.fSigma != blurRec.fSigma || |
273 blob.fBlurRec.fStyle != blurRec.fStyle || | 266 blob.fBlurRec.fStyle != blurRec.fStyle || |
274 blob.fBlurRec.fQuality != blurRec.fQuality)) { | 267 blob.fBlurRec.fQuality != blurRec.fQuality)) { |
275 return true; | 268 return true; |
276 } | 269 } |
277 | 270 |
278 // Similarly, we only cache one version for each style | 271 // Similarly, we only cache one version for each style |
279 if (blob.fKey.fStyle != SkPaint::kFill_Style && | 272 if (blob.fKey.fStyle != SkPaint::kFill_Style && |
280 (blob.fStrokeInfo.fFrameWidth != paint.getStrokeWidth() || | 273 (blob.fStrokeInfo.fFrameWidth != paint.getStrokeWidth() || |
281 blob.fStrokeInfo.fMiterLimit != paint.getStrokeMiter() || | 274 blob.fStrokeInfo.fMiterLimit != paint.getStrokeMiter() || |
282 blob.fStrokeInfo.fJoin != paint.getStrokeJoin())) { | 275 blob.fStrokeInfo.fJoin != paint.getStrokeJoin())) { |
283 return true; | 276 return true; |
284 } | 277 } |
285 | 278 |
286 // We can update the positions in the cachedtextblobs without regenerating t he whole blob, but | 279 // Identical viewmatrices and we can reuse in all cases |
287 // only for integer translations. | 280 if (blob.fViewMatrix.cheapEqualTo(viewMatrix) && x == blob.fX && y == blob.f Y) { |
288 // This cool bit of math will determine the necessary translation to apply t o the already | 281 return false; |
289 // generated vertex coordinates to move them to the correct position | 282 } |
290 SkScalar transX = viewMatrix.getTranslateX() + | 283 |
291 viewMatrix.getScaleX() * (x - blob.fX) + | 284 // Mixed blobs can't be regenerated at this point |
jvanverth1
2015/04/20 17:54:07
Don't you mean "must be regenerated"? Or "can't be
joshualitt
2015/04/20 18:24:57
Acknowledged.
| |
292 viewMatrix.getSkewX() * (y - blob.fY) - | 285 SkASSERT(blob.fHasBitmap || blob.fHasDistanceField); |
293 blob.fViewMatrix.getTranslateX(); | 286 if (blob.fHasBitmap && blob.fHasDistanceField) { |
294 SkScalar transY = viewMatrix.getTranslateY() + | |
295 viewMatrix.getSkewY() * (x - blob.fX) + | |
296 viewMatrix.getScaleY() * (y - blob.fY) - | |
297 blob.fViewMatrix.getTranslateY(); | |
298 if (SkScalarFraction(transX) > SK_ScalarNearlyZero || | |
299 SkScalarFraction(transY) > SK_ScalarNearlyZero) { | |
300 return true; | 287 return true; |
301 } | 288 } |
302 | 289 |
290 // TODO distance fields can handle many of these conditions | |
291 if (blob.fViewMatrix.getScaleX() != viewMatrix.getScaleX() || | |
292 blob.fViewMatrix.getScaleY() != viewMatrix.getScaleY() || | |
293 blob.fViewMatrix.getSkewX() != viewMatrix.getSkewX() || | |
294 blob.fViewMatrix.getSkewY() != viewMatrix.getSkewY()) { | |
295 return true; | |
296 } | |
297 | |
298 if (blob.fHasBitmap) { | |
299 // We can update the positions in the cachedtextblobs without regenerati ng the whole blob, | |
jvanverth1
2015/04/20 17:54:07
I'd think that this formula would work for distanc
joshualitt
2015/04/20 18:24:57
would it? I thought we just want the raw delta (x
| |
300 // but only for integer translations. | |
301 // This cool bit of math will determine the necessary translation to app ly to the already | |
302 // generated vertex coordinates to move them to the correct position | |
303 SkScalar transX = viewMatrix.getTranslateX() + | |
304 viewMatrix.getScaleX() * (x - blob.fX) + | |
305 viewMatrix.getSkewX() * (y - blob.fY) - | |
306 blob.fViewMatrix.getTranslateX(); | |
307 SkScalar transY = viewMatrix.getTranslateY() + | |
308 viewMatrix.getSkewY() * (x - blob.fX) + | |
309 viewMatrix.getScaleY() * (y - blob.fY) - | |
310 blob.fViewMatrix.getTranslateY(); | |
311 if (SkScalarFraction(transX) > SK_ScalarNearlyZero || | |
312 SkScalarFraction(transY) > SK_ScalarNearlyZero) { | |
313 return true; | |
314 } | |
315 | |
303 #ifdef SK_DEBUG | 316 #ifdef SK_DEBUG |
304 static const SkScalar kMinDiscernableTranslation = 0.0625; | 317 static const SkScalar kMinDiscernableTranslation = 0.0625; |
305 // As a safeguard when debugging, we store the total error across all transl ations and print if | 318 // As a safeguard when debugging, we store the total error across all tr anslations and print |
306 // the error becomes discernable. This is pretty unlikely to occur given th e tight bounds above | 319 // if the error becomes discernable. This is pretty unlikely to occur g iven the tight |
307 // on translation | 320 // bounds above on translation |
308 blob.fTotalXError += SkScalarAbs(SkScalarFraction(transX)); | 321 blob.fTotalXError += SkScalarAbs(SkScalarFraction(transX)); |
309 blob.fTotalYError += SkScalarAbs(SkScalarFraction(transY)); | 322 blob.fTotalYError += SkScalarAbs(SkScalarFraction(transY)); |
310 if (blob.fTotalXError > kMinDiscernableTranslation || | 323 if (blob.fTotalXError > kMinDiscernableTranslation || |
311 blob.fTotalYError > kMinDiscernableTranslation) { | 324 blob.fTotalYError > kMinDiscernableTranslation) { |
312 SkDebugf("Exceeding error threshold for bitmap text translation"); | 325 SkDebugf("Exceeding error threshold for bitmap text translation"); |
326 } | |
327 #endif | |
328 (*outTransX) = transX; | |
329 (*outTransY) = transY; | |
330 } else { | |
331 // blob.fHasDistanceFields | |
332 // TODO figure out the regen formula | |
333 return true; | |
313 } | 334 } |
314 #endif | 335 |
315 (*outTransX) = transX; | |
316 (*outTransY) = transY; | |
317 return false; | 336 return false; |
318 } | 337 } |
319 | 338 |
320 | 339 |
321 inline SkGlyphCache* GrAtlasTextContext::setupCache(BitmapTextBlob::Run* run, | 340 inline SkGlyphCache* GrAtlasTextContext::setupCache(BitmapTextBlob::Run* run, |
322 const SkPaint& skPaint, | 341 const SkPaint& skPaint, |
323 const SkMatrix* viewMatrix, | 342 const SkMatrix* viewMatrix, |
324 bool noGamma) { | 343 bool noGamma) { |
325 skPaint.getScalerContextDescriptor(&run->fDescriptor, &fDeviceProperties, vi ewMatrix, noGamma); | 344 skPaint.getScalerContextDescriptor(&run->fDescriptor, &fDeviceProperties, vi ewMatrix, noGamma); |
326 run->fTypeface.reset(SkSafeRef(skPaint.getTypeface())); | 345 run->fTypeface.reset(SkSafeRef(skPaint.getTypeface())); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
371 | 390 |
372 if (cacheBlob) { | 391 if (cacheBlob) { |
373 if (MustRegenerateBlob(&transX, &transY, *cacheBlob, skPaint, blurRec, v iewMatrix, x, y)) { | 392 if (MustRegenerateBlob(&transX, &transY, *cacheBlob, skPaint, blurRec, v iewMatrix, x, y)) { |
374 // We have to remake the blob because changes may invalidate our mas ks. | 393 // We have to remake the blob because changes may invalidate our mas ks. |
375 // TODO we could probably get away reuse most of the time if the poi nter is unique, | 394 // TODO we could probably get away reuse most of the time if the poi nter is unique, |
376 // but we'd have to clear the subrun information | 395 // but we'd have to clear the subrun information |
377 fCache->remove(cacheBlob); | 396 fCache->remove(cacheBlob); |
378 cacheBlob.reset(SkRef(fCache->createCachedBlob(blob, key, blurRec, s kPaint, | 397 cacheBlob.reset(SkRef(fCache->createCachedBlob(blob, key, blurRec, s kPaint, |
379 kGrayTextVASize))); | 398 kGrayTextVASize))); |
380 this->regenerateTextBlob(cacheBlob, skPaint, grPaint.getColor(), vie wMatrix, blob, x, y, | 399 this->regenerateTextBlob(cacheBlob, skPaint, grPaint.getColor(), vie wMatrix, blob, x, y, |
381 drawFilter, clipRect); | 400 drawFilter, clipRect, rt, clip, grPaint); |
382 } else { | 401 } else { |
383 // If we can reuse the blob, then make sure we update the blob's vie wmatrix, and x/y | 402 // If we can reuse the blob, then make sure we update the blob's vie wmatrix, and x/y |
384 // offsets | 403 // offsets |
385 cacheBlob->fViewMatrix = viewMatrix; | 404 cacheBlob->fViewMatrix = viewMatrix; |
386 cacheBlob->fX = x; | 405 cacheBlob->fX = x; |
387 cacheBlob->fY = y; | 406 cacheBlob->fY = y; |
388 fCache->makeMRU(cacheBlob); | 407 fCache->makeMRU(cacheBlob); |
389 } | 408 } |
390 } else { | 409 } else { |
391 if (canCache) { | 410 if (canCache) { |
392 cacheBlob.reset(SkRef(fCache->createCachedBlob(blob, key, blurRec, s kPaint, | 411 cacheBlob.reset(SkRef(fCache->createCachedBlob(blob, key, blurRec, s kPaint, |
393 kGrayTextVASize))); | 412 kGrayTextVASize))); |
394 } else { | 413 } else { |
395 cacheBlob.reset(fCache->createBlob(blob, kGrayTextVASize)); | 414 cacheBlob.reset(fCache->createBlob(blob, kGrayTextVASize)); |
396 } | 415 } |
397 this->regenerateTextBlob(cacheBlob, skPaint, grPaint.getColor(), viewMat rix, blob, x, y, | 416 this->regenerateTextBlob(cacheBlob, skPaint, grPaint.getColor(), viewMat rix, blob, x, y, |
398 drawFilter, clipRect); | 417 drawFilter, clipRect, rt, clip, grPaint); |
399 } | 418 } |
400 | 419 |
401 cacheBlob->fPaintColor = skPaint.getColor(); | 420 cacheBlob->fPaintColor = skPaint.getColor(); |
402 this->flush(fContext->getTextTarget(), blob, cacheBlob, rt, skPaint, grPaint , drawFilter, | 421 this->flush(fContext->getTextTarget(), blob, cacheBlob, rt, skPaint, grPaint , drawFilter, |
403 clip, viewMatrix, clipBounds, x, y, transX, transY); | 422 clip, viewMatrix, clipBounds, x, y, transX, transY); |
404 } | 423 } |
405 | 424 |
406 inline bool GrAtlasTextContext::canDrawAsDistanceFields(const SkPaint& skPaint, | 425 inline bool GrAtlasTextContext::canDrawAsDistanceFields(const SkPaint& skPaint, |
407 const SkMatrix& viewMatr ix) { | 426 const SkMatrix& viewMatr ix) { |
408 // TODO: support perspective (need getMaxScale replacement) | 427 // TODO: support perspective (need getMaxScale replacement) |
(...skipping 26 matching lines...) Expand all Loading... | |
435 return false; | 454 return false; |
436 } | 455 } |
437 | 456 |
438 return true; | 457 return true; |
439 } | 458 } |
440 | 459 |
441 void GrAtlasTextContext::regenerateTextBlob(BitmapTextBlob* cacheBlob, | 460 void GrAtlasTextContext::regenerateTextBlob(BitmapTextBlob* cacheBlob, |
442 const SkPaint& skPaint, GrColor colo r, | 461 const SkPaint& skPaint, GrColor colo r, |
443 const SkMatrix& viewMatrix, | 462 const SkMatrix& viewMatrix, |
444 const SkTextBlob* blob, SkScalar x, SkScalar y, | 463 const SkTextBlob* blob, SkScalar x, SkScalar y, |
445 SkDrawFilter* drawFilter, const SkIR ect& clipRect) { | 464 SkDrawFilter* drawFilter, const SkIR ect& clipRect, |
465 GrRenderTarget* rt, const GrClip& cl ip, | |
466 const GrPaint& paint) { | |
446 cacheBlob->fViewMatrix = viewMatrix; | 467 cacheBlob->fViewMatrix = viewMatrix; |
447 cacheBlob->fX = x; | 468 cacheBlob->fX = x; |
448 cacheBlob->fY = y; | 469 cacheBlob->fY = y; |
449 | 470 |
450 // Regenerate textblob | 471 // Regenerate textblob |
451 SkPaint runPaint = skPaint; | 472 SkPaint runPaint = skPaint; |
452 SkTextBlob::RunIterator it(blob); | 473 SkTextBlob::RunIterator it(blob); |
453 for (int run = 0; !it.done(); it.next(), run++) { | 474 for (int run = 0; !it.done(); it.next(), run++) { |
454 int glyphCount = it.glyphCount(); | 475 int glyphCount = it.glyphCount(); |
455 size_t textLen = glyphCount * sizeof(uint16_t); | 476 size_t textLen = glyphCount * sizeof(uint16_t); |
456 const SkPoint& offset = it.offset(); | 477 const SkPoint& offset = it.offset(); |
457 // applyFontToPaint() always overwrites the exact same attributes, | 478 // applyFontToPaint() always overwrites the exact same attributes, |
458 // so it is safe to not re-seed the paint for this reason. | 479 // so it is safe to not re-seed the paint for this reason. |
459 it.applyFontToPaint(&runPaint); | 480 it.applyFontToPaint(&runPaint); |
460 | 481 |
461 if (drawFilter && !drawFilter->filter(&runPaint, SkDrawFilter::kText_Typ e)) { | 482 if (drawFilter && !drawFilter->filter(&runPaint, SkDrawFilter::kText_Typ e)) { |
462 // A false return from filter() means we should abort the current dr aw. | 483 // A false return from filter() means we should abort the current dr aw. |
463 runPaint = skPaint; | 484 runPaint = skPaint; |
464 continue; | 485 continue; |
465 } | 486 } |
466 | 487 |
467 runPaint.setFlags(fGpuDevice->filterTextFlags(runPaint)); | 488 runPaint.setFlags(fGpuDevice->filterTextFlags(runPaint)); |
468 | 489 |
469 SkGlyphCache* cache = this->setupCache(&cacheBlob->fRuns[run], runPaint, &viewMatrix, | |
470 false); | |
471 | |
472 // setup vertex / glyphIndex for the new run | 490 // setup vertex / glyphIndex for the new run |
473 if (run > 0) { | 491 if (run > 0) { |
474 PerSubRunInfo& newRun = cacheBlob->fRuns[run].fSubRunInfo.back(); | 492 PerSubRunInfo& newRun = cacheBlob->fRuns[run].fSubRunInfo.back(); |
475 PerSubRunInfo& lastRun = cacheBlob->fRuns[run - 1].fSubRunInfo.back( ); | 493 PerSubRunInfo& lastRun = cacheBlob->fRuns[run - 1].fSubRunInfo.back( ); |
476 | 494 |
477 newRun.fVertexStartIndex = lastRun.fVertexEndIndex; | 495 newRun.fVertexStartIndex = lastRun.fVertexEndIndex; |
478 newRun.fVertexEndIndex = lastRun.fVertexEndIndex; | 496 newRun.fVertexEndIndex = lastRun.fVertexEndIndex; |
479 | 497 |
480 newRun.fGlyphStartIndex = lastRun.fGlyphEndIndex; | 498 newRun.fGlyphStartIndex = lastRun.fGlyphEndIndex; |
481 newRun.fGlyphEndIndex = lastRun.fGlyphEndIndex; | 499 newRun.fGlyphEndIndex = lastRun.fGlyphEndIndex; |
482 } | 500 } |
483 | 501 |
484 if (SkDraw::ShouldDrawTextAsPaths(runPaint, viewMatrix)) { | 502 if (canDrawAsDistanceFields(runPaint, viewMatrix)) { |
503 cacheBlob->fHasDistanceField = true; | |
504 SkPaint dfPaint = runPaint; | |
505 SkScalar textRatio; | |
506 this->initDistanceFieldPaint(&dfPaint, &textRatio, viewMatrix); | |
507 Run& runIdx = cacheBlob->fRuns[run]; | |
508 PerSubRunInfo& subRun = runIdx.fSubRunInfo.back(); | |
509 subRun.fUseLCDText = runPaint.isLCDRenderText(); | |
510 subRun.fDrawAsDistanceFields = true; | |
511 | |
512 SkGlyphCache* cache = this->setupCache(&cacheBlob->fRuns[run], dfPai nt, NULL, true); | |
513 | |
514 SkTDArray<char> fallbackTxt; | |
515 SkTDArray<SkScalar> fallbackPos; | |
516 SkPoint dfOffset; | |
517 int scalarsPerPosition = 2; | |
518 switch (it.positioning()) { | |
519 case SkTextBlob::kDefault_Positioning: { | |
520 this->internalDrawDFText(cacheBlob, run, cache, dfPaint, col or, viewMatrix, | |
521 (const char *)it.glyphs(), textLen, | |
522 x + offset.x(), y + offset.y(), cli pRect, textRatio, | |
523 &fallbackTxt, &fallbackPos, &dfOffs et, runPaint); | |
524 break; | |
525 } | |
526 case SkTextBlob::kHorizontal_Positioning: { | |
527 scalarsPerPosition = 1; | |
528 dfOffset = SkPoint::Make(x, y + offset.y()); | |
529 this->internalDrawDFPosText(cacheBlob, run, cache, dfPaint, color, viewMatrix, | |
530 (const char*)it.glyphs(), textLe n, it.pos(), | |
531 scalarsPerPosition, dfOffset, c lipRect, textRatio, | |
532 &fallbackTxt, &fallbackPos); | |
533 break; | |
534 } | |
535 case SkTextBlob::kFull_Positioning: { | |
536 dfOffset = SkPoint::Make(x, y); | |
537 this->internalDrawDFPosText(cacheBlob, run, cache, dfPaint, color, viewMatrix, | |
538 (const char*)it.glyphs(), textLe n, it.pos(), | |
539 scalarsPerPosition, dfOffset, c lipRect, textRatio, | |
540 &fallbackTxt, &fallbackPos); | |
541 break; | |
542 } | |
543 } | |
544 if (fallbackTxt.count()) { | |
545 this->fallbackDrawPosText(cacheBlob, run, rt, clip, paint, runPa int, viewMatrix, | |
546 fallbackTxt, fallbackPos, scalarsPerPo sition, dfOffset, | |
547 clipRect); | |
548 } | |
549 | |
550 SkGlyphCache::AttachCache(cache); | |
551 } else if (SkDraw::ShouldDrawTextAsPaths(runPaint, viewMatrix)) { | |
485 cacheBlob->fRuns[run].fDrawAsPaths = true; | 552 cacheBlob->fRuns[run].fDrawAsPaths = true; |
486 continue; | 553 } else { |
487 } | 554 cacheBlob->fHasBitmap = true; |
488 cacheBlob->fRuns[run].fDrawAsPaths = false; | 555 SkGlyphCache* cache = this->setupCache(&cacheBlob->fRuns[run], runPa int, &viewMatrix, |
489 | 556 false); |
490 switch (it.positioning()) { | 557 switch (it.positioning()) { |
491 case SkTextBlob::kDefault_Positioning: | 558 case SkTextBlob::kDefault_Positioning: |
492 this->internalDrawBMPText(cacheBlob, run, cache, runPaint, color , viewMatrix, | 559 this->internalDrawBMPText(cacheBlob, run, cache, runPaint, c olor, viewMatrix, |
493 (const char *)it.glyphs(), textLen, | 560 (const char *)it.glyphs(), textLen , |
494 x + offset.x(), y + offset.y(), clipRe ct); | 561 x + offset.x(), y + offset.y(), cl ipRect); |
495 break; | 562 break; |
496 case SkTextBlob::kHorizontal_Positioning: | 563 case SkTextBlob::kHorizontal_Positioning: |
497 this->internalDrawBMPPosText(cacheBlob, run, cache, runPaint, co lor, viewMatrix, | 564 this->internalDrawBMPPosText(cacheBlob, run, cache, runPaint , color, viewMatrix, |
498 (const char*)it.glyphs(), textLen, it.pos(), 1, | 565 (const char*)it.glyphs(), textL en, it.pos(), 1, |
499 SkPoint::Make(x, y + offset.y()), c lipRect); | 566 SkPoint::Make(x, y + offset.y() ), clipRect); |
500 break; | 567 break; |
501 case SkTextBlob::kFull_Positioning: | 568 case SkTextBlob::kFull_Positioning: |
502 this->internalDrawBMPPosText(cacheBlob, run, cache, runPaint, co lor, viewMatrix, | 569 this->internalDrawBMPPosText(cacheBlob, run, cache, runPaint , color, viewMatrix, |
503 (const char*)it.glyphs(), textLen, it.pos(), 2, | 570 (const char*)it.glyphs(), textL en, it.pos(), 2, |
504 SkPoint::Make(x, y), clipRect); | 571 SkPoint::Make(x, y), clipRect); |
505 break; | 572 break; |
573 } | |
574 SkGlyphCache::AttachCache(cache); | |
506 } | 575 } |
507 | 576 |
508 if (drawFilter) { | 577 if (drawFilter) { |
509 // A draw filter may change the paint arbitrarily, so we must re-see d in this case. | 578 // A draw filter may change the paint arbitrarily, so we must re-see d in this case. |
510 runPaint = skPaint; | 579 runPaint = skPaint; |
511 } | 580 } |
512 | |
513 SkGlyphCache::AttachCache(cache); | |
514 } | 581 } |
515 } | 582 } |
516 | 583 |
517 inline void GrAtlasTextContext::initDistanceFieldPaint(SkPaint* skPaint, SkScala r* textRatio, | 584 inline void GrAtlasTextContext::initDistanceFieldPaint(SkPaint* skPaint, SkScala r* textRatio, |
518 const SkMatrix& viewMatri x) { | 585 const SkMatrix& viewMatri x) { |
519 // getMaxScale doesn't support perspective, so neither do we at the moment | 586 // getMaxScale doesn't support perspective, so neither do we at the moment |
520 SkASSERT(!viewMatrix.hasPerspective()); | 587 SkASSERT(!viewMatrix.hasPerspective()); |
521 SkScalar maxScale = viewMatrix.getMaxScale(); | 588 SkScalar maxScale = viewMatrix.getMaxScale(); |
522 SkScalar textSize = skPaint->getTextSize(); | 589 SkScalar textSize = skPaint->getTextSize(); |
523 SkScalar scaledTextSize = textSize; | 590 SkScalar scaledTextSize = textSize; |
(...skipping 15 matching lines...) Expand all Loading... | |
539 skPaint->setTextSize(SkIntToScalar(kLargeDFFontSize)); | 606 skPaint->setTextSize(SkIntToScalar(kLargeDFFontSize)); |
540 } | 607 } |
541 | 608 |
542 skPaint->setLCDRenderText(false); | 609 skPaint->setLCDRenderText(false); |
543 skPaint->setAutohinted(false); | 610 skPaint->setAutohinted(false); |
544 skPaint->setHinting(SkPaint::kNormal_Hinting); | 611 skPaint->setHinting(SkPaint::kNormal_Hinting); |
545 skPaint->setSubpixelText(true); | 612 skPaint->setSubpixelText(true); |
546 } | 613 } |
547 | 614 |
548 inline void GrAtlasTextContext::fallbackDrawPosText(BitmapTextBlob* blob, | 615 inline void GrAtlasTextContext::fallbackDrawPosText(BitmapTextBlob* blob, |
616 int runIndex, | |
549 GrRenderTarget* rt, const Gr Clip& clip, | 617 GrRenderTarget* rt, const Gr Clip& clip, |
550 const GrPaint& paint, | 618 const GrPaint& paint, |
551 const SkPaint& skPaint, | 619 const SkPaint& skPaint, |
552 const SkMatrix& viewMatrix, | 620 const SkMatrix& viewMatrix, |
553 const SkTDArray<char>& fallb ackTxt, | 621 const SkTDArray<char>& fallb ackTxt, |
554 const SkTDArray<SkScalar>& f allbackPos, | 622 const SkTDArray<SkScalar>& f allbackPos, |
555 int scalarsPerPosition, | 623 int scalarsPerPosition, |
556 const SkPoint& offset, | 624 const SkPoint& offset, |
557 const SkIRect& clipRect) { | 625 const SkIRect& clipRect) { |
558 SkASSERT(fallbackTxt.count()); | 626 SkASSERT(fallbackTxt.count()); |
559 Run& run = blob->fRuns[0]; | 627 blob->fHasBitmap = true; |
628 Run& run = blob->fRuns[runIndex]; | |
560 PerSubRunInfo& subRun = run.fSubRunInfo.push_back(); | 629 PerSubRunInfo& subRun = run.fSubRunInfo.push_back(); |
561 subRun.fOverrideDescriptor.reset(SkNEW(SkAutoDescriptor)); | 630 subRun.fOverrideDescriptor.reset(SkNEW(SkAutoDescriptor)); |
562 skPaint.getScalerContextDescriptor(subRun.fOverrideDescriptor, | 631 skPaint.getScalerContextDescriptor(subRun.fOverrideDescriptor, |
563 &fDeviceProperties, &viewMatrix, false); | 632 &fDeviceProperties, &viewMatrix, false); |
564 SkGlyphCache* cache = SkGlyphCache::DetachCache(run.fTypeface, | 633 SkGlyphCache* cache = SkGlyphCache::DetachCache(run.fTypeface, |
565 subRun.fOverrideDescriptor-> getDesc()); | 634 subRun.fOverrideDescriptor-> getDesc()); |
566 this->internalDrawBMPPosText(blob, 0, cache, skPaint, paint.getColor(), view Matrix, | 635 this->internalDrawBMPPosText(blob, runIndex, cache, skPaint, paint.getColor( ), viewMatrix, |
567 fallbackTxt.begin(), fallbackTxt.count(), | 636 fallbackTxt.begin(), fallbackTxt.count(), |
568 fallbackPos.begin(), scalarsPerPosition, offset , clipRect); | 637 fallbackPos.begin(), scalarsPerPosition, offset , clipRect); |
569 SkGlyphCache::AttachCache(cache); | 638 SkGlyphCache::AttachCache(cache); |
570 } | 639 } |
571 | 640 |
572 inline GrAtlasTextContext::BitmapTextBlob* | 641 inline GrAtlasTextContext::BitmapTextBlob* |
573 GrAtlasTextContext::setupDFBlob(int glyphCount, const SkPaint& origPaint, | 642 GrAtlasTextContext::setupDFBlob(int glyphCount, const SkPaint& origPaint, |
574 const SkMatrix& viewMatrix, SkGlyphCache** cache , | 643 const SkMatrix& viewMatrix, SkGlyphCache** cache , |
575 SkPaint* dfPaint, SkScalar* textRatio) { | 644 SkPaint* dfPaint, SkScalar* textRatio) { |
576 BitmapTextBlob* blob = fCache->createBlob(glyphCount, 1, kGrayTextVASize); | 645 BitmapTextBlob* blob = fCache->createBlob(glyphCount, 1, kGrayTextVASize); |
577 | 646 |
578 *dfPaint = origPaint; | 647 *dfPaint = origPaint; |
579 this->initDistanceFieldPaint(dfPaint, textRatio, viewMatrix); | 648 this->initDistanceFieldPaint(dfPaint, textRatio, viewMatrix); |
580 blob->fViewMatrix = viewMatrix; | 649 blob->fViewMatrix = viewMatrix; |
581 blob->fRuns[0].fSubRunInfo.back().fUseLCDText = origPaint.isLCDRenderText(); | 650 Run& run = blob->fRuns[0]; |
582 blob->fRuns[0].fSubRunInfo.back().fDrawAsDistanceFields = true; | 651 PerSubRunInfo& subRun = run.fSubRunInfo.back(); |
652 subRun.fUseLCDText = origPaint.isLCDRenderText(); | |
653 subRun.fDrawAsDistanceFields = true; | |
583 | 654 |
584 *cache = this->setupCache(&blob->fRuns[0], *dfPaint, NULL, true); | 655 *cache = this->setupCache(&blob->fRuns[0], *dfPaint, NULL, true); |
585 return blob; | 656 return blob; |
586 } | 657 } |
587 | 658 |
588 void GrAtlasTextContext::onDrawText(GrRenderTarget* rt, const GrClip& clip, | 659 void GrAtlasTextContext::onDrawText(GrRenderTarget* rt, const GrClip& clip, |
589 const GrPaint& paint, const SkPaint& skPaint , | 660 const GrPaint& paint, const SkPaint& skPaint , |
590 const SkMatrix& viewMatrix, | 661 const SkMatrix& viewMatrix, |
591 const char text[], size_t byteLength, | 662 const char text[], size_t byteLength, |
592 SkScalar x, SkScalar y, const SkIRect& regio nClipBounds) { | 663 SkScalar x, SkScalar y, const SkIRect& regio nClipBounds) { |
(...skipping 10 matching lines...) Expand all Loading... | |
603 &dfPaint, &textRatio )); | 674 &dfPaint, &textRatio )); |
604 | 675 |
605 SkTDArray<char> fallbackTxt; | 676 SkTDArray<char> fallbackTxt; |
606 SkTDArray<SkScalar> fallbackPos; | 677 SkTDArray<SkScalar> fallbackPos; |
607 SkPoint offset; | 678 SkPoint offset; |
608 this->internalDrawDFText(blob, 0, cache, dfPaint, paint.getColor(), view Matrix, text, | 679 this->internalDrawDFText(blob, 0, cache, dfPaint, paint.getColor(), view Matrix, text, |
609 byteLength, x, y, clipRect, textRatio, &fallbac kTxt, &fallbackPos, | 680 byteLength, x, y, clipRect, textRatio, &fallbac kTxt, &fallbackPos, |
610 &offset, skPaint); | 681 &offset, skPaint); |
611 SkGlyphCache::AttachCache(cache); | 682 SkGlyphCache::AttachCache(cache); |
612 if (fallbackTxt.count()) { | 683 if (fallbackTxt.count()) { |
613 this->fallbackDrawPosText(blob, rt, clip, paint, skPaint, viewMatrix , fallbackTxt, | 684 this->fallbackDrawPosText(blob, 0, rt, clip, paint, skPaint, viewMat rix, fallbackTxt, |
614 fallbackPos, 2, offset, clipRect); | 685 fallbackPos, 2, offset, clipRect); |
615 } | 686 } |
616 this->flush(fContext->getTextTarget(), blob, rt, skPaint, paint, clip); | 687 this->flush(fContext->getTextTarget(), blob, rt, skPaint, paint, clip); |
617 } else { | 688 } else { |
618 SkAutoTUnref<BitmapTextBlob> blob(fCache->createBlob(glyphCount, 1, kGra yTextVASize)); | 689 SkAutoTUnref<BitmapTextBlob> blob(fCache->createBlob(glyphCount, 1, kGra yTextVASize)); |
619 blob->fViewMatrix = viewMatrix; | 690 blob->fViewMatrix = viewMatrix; |
620 | 691 |
621 SkGlyphCache* cache = this->setupCache(&blob->fRuns[0], skPaint, &viewMa trix, false); | 692 SkGlyphCache* cache = this->setupCache(&blob->fRuns[0], skPaint, &viewMa trix, false); |
622 this->internalDrawBMPText(blob, 0, cache, skPaint, paint.getColor(), vie wMatrix, text, | 693 this->internalDrawBMPText(blob, 0, cache, skPaint, paint.getColor(), vie wMatrix, text, |
623 byteLength, x, y, clipRect); | 694 byteLength, x, y, clipRect); |
(...skipping 20 matching lines...) Expand all Loading... | |
644 SkAutoTUnref<BitmapTextBlob> blob(this->setupDFBlob(glyphCount, skPaint, viewMatrix, &cache, | 715 SkAutoTUnref<BitmapTextBlob> blob(this->setupDFBlob(glyphCount, skPaint, viewMatrix, &cache, |
645 &dfPaint, &textRatio )); | 716 &dfPaint, &textRatio )); |
646 | 717 |
647 SkTDArray<char> fallbackTxt; | 718 SkTDArray<char> fallbackTxt; |
648 SkTDArray<SkScalar> fallbackPos; | 719 SkTDArray<SkScalar> fallbackPos; |
649 this->internalDrawDFPosText(blob, 0, cache, dfPaint, paint.getColor(), v iewMatrix, text, | 720 this->internalDrawDFPosText(blob, 0, cache, dfPaint, paint.getColor(), v iewMatrix, text, |
650 byteLength, pos, scalarsPerPosition, offset, clipRect, | 721 byteLength, pos, scalarsPerPosition, offset, clipRect, |
651 textRatio, &fallbackTxt, &fallbackPos); | 722 textRatio, &fallbackTxt, &fallbackPos); |
652 SkGlyphCache::AttachCache(cache); | 723 SkGlyphCache::AttachCache(cache); |
653 if (fallbackTxt.count()) { | 724 if (fallbackTxt.count()) { |
654 this->fallbackDrawPosText(blob, rt, clip, paint, skPaint, viewMatrix , fallbackTxt, | 725 this->fallbackDrawPosText(blob, 0, rt, clip, paint, skPaint, viewMat rix, fallbackTxt, |
655 fallbackPos, scalarsPerPosition, offset, c lipRect); | 726 fallbackPos, scalarsPerPosition, offset, c lipRect); |
656 } | 727 } |
657 this->flush(fContext->getTextTarget(), blob, rt, skPaint, paint, clip); | 728 this->flush(fContext->getTextTarget(), blob, rt, skPaint, paint, clip); |
658 } else { | 729 } else { |
659 SkAutoTUnref<BitmapTextBlob> blob(fCache->createBlob(glyphCount, 1, kGra yTextVASize)); | 730 SkAutoTUnref<BitmapTextBlob> blob(fCache->createBlob(glyphCount, 1, kGra yTextVASize)); |
660 blob->fViewMatrix = viewMatrix; | 731 blob->fViewMatrix = viewMatrix; |
661 SkGlyphCache* cache = this->setupCache(&blob->fRuns[0], skPaint, &viewMa trix, false); | 732 SkGlyphCache* cache = this->setupCache(&blob->fRuns[0], skPaint, &viewMa trix, false); |
662 this->internalDrawBMPPosText(blob, 0, cache, skPaint, paint.getColor(), viewMatrix, text, | 733 this->internalDrawBMPPosText(blob, 0, cache, skPaint, paint.getColor(), viewMatrix, text, |
663 byteLength, pos, scalarsPerPosition, offset , clipRect); | 734 byteLength, pos, scalarsPerPosition, offset , clipRect); |
664 SkGlyphCache::AttachCache(cache); | 735 SkGlyphCache::AttachCache(cache); |
(...skipping 771 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1436 for (int i = 0; i < instanceCount; i++) { | 1507 for (int i = 0; i < instanceCount; i++) { |
1437 Geometry& args = fGeoData[i]; | 1508 Geometry& args = fGeoData[i]; |
1438 Blob* blob = args.fBlob; | 1509 Blob* blob = args.fBlob; |
1439 Run& run = blob->fRuns[args.fRun]; | 1510 Run& run = blob->fRuns[args.fRun]; |
1440 TextInfo& info = run.fSubRunInfo[args.fSubRun]; | 1511 TextInfo& info = run.fSubRunInfo[args.fSubRun]; |
1441 | 1512 |
1442 uint64_t currentAtlasGen = fFontCache->atlasGeneration(fMaskFormat); | 1513 uint64_t currentAtlasGen = fFontCache->atlasGeneration(fMaskFormat); |
1443 bool regenerateTextureCoords = info.fAtlasGeneration != currentAtlas Gen; | 1514 bool regenerateTextureCoords = info.fAtlasGeneration != currentAtlas Gen; |
1444 bool regenerateColors; | 1515 bool regenerateColors; |
1445 if (fUseDistanceFields) { | 1516 if (fUseDistanceFields) { |
1446 regenerateColors = fUseLCDText && run.fColor != args.fColor; | 1517 regenerateColors = !fUseLCDText && run.fColor != args.fColor; |
jvanverth1
2015/04/20 17:54:07
Whoops. :)
| |
1447 } else { | 1518 } else { |
1448 regenerateColors = kA8_GrMaskFormat == fMaskFormat && run.fColor != args.fColor; | 1519 regenerateColors = kA8_GrMaskFormat == fMaskFormat && run.fColor != args.fColor; |
1449 } | 1520 } |
1450 bool regeneratePositions = args.fTransX != 0.f || args.fTransY != 0. f; | 1521 bool regeneratePositions = args.fTransX != 0.f || args.fTransY != 0. f; |
1451 int glyphCount = info.fGlyphEndIndex - info.fGlyphStartIndex; | 1522 int glyphCount = info.fGlyphEndIndex - info.fGlyphStartIndex; |
1452 | 1523 |
1453 // We regenerate both texture coords and colors in the blob itself, and update the | 1524 // We regenerate both texture coords and colors in the blob itself, and update the |
1454 // atlas generation. If we don't end up purging any unused plots, w e can avoid | 1525 // atlas generation. If we don't end up purging any unused plots, w e can avoid |
1455 // regenerating the coords. We could take a finer grained approach to updating texture | 1526 // regenerating the coords. We could take a finer grained approach to updating texture |
1456 // coords but its not clear if the extra bookkeeping would offset an y gains. | 1527 // coords but its not clear if the extra bookkeeping would offset an y gains. |
(...skipping 543 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2000 pipelineBuilder.setFromPaint(grPaint, rt, clip); | 2071 pipelineBuilder.setFromPaint(grPaint, rt, clip); |
2001 | 2072 |
2002 GrColor color = grPaint.getColor(); | 2073 GrColor color = grPaint.getColor(); |
2003 for (int run = 0; run < cacheBlob->fRunCount; run++) { | 2074 for (int run = 0; run < cacheBlob->fRunCount; run++) { |
2004 this->flushRun(target, &pipelineBuilder, cacheBlob, run, color, 0, 0, sk Paint); | 2075 this->flushRun(target, &pipelineBuilder, cacheBlob, run, color, 0, 0, sk Paint); |
2005 } | 2076 } |
2006 | 2077 |
2007 // Now flush big glyphs | 2078 // Now flush big glyphs |
2008 this->flushBigGlyphs(cacheBlob, rt, grPaint, clip, 0, 0); | 2079 this->flushBigGlyphs(cacheBlob, rt, grPaint, clip, 0, 0); |
2009 } | 2080 } |
OLD | NEW |