| 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 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 116 if (paint.getStyle() != SkPaint::kFill_Style) { | 116 if (paint.getStyle() != SkPaint::kFill_Style) { |
| 117 return false; | 117 return false; |
| 118 } | 118 } |
| 119 | 119 |
| 120 // TODO: choose an appropriate maximum scale for distance fields and | 120 // TODO: choose an appropriate maximum scale for distance fields and |
| 121 // enable perspective | 121 // enable perspective |
| 122 if (SkDraw::ShouldDrawTextAsPaths(paint, fContext->getMatrix())) { | 122 if (SkDraw::ShouldDrawTextAsPaths(paint, fContext->getMatrix())) { |
| 123 return false; | 123 return false; |
| 124 } | 124 } |
| 125 | 125 |
| 126 // distance fields cannot represent color fonts | 126 return true; |
| 127 SkScalerContext::Rec rec; | |
| 128 SkScalerContext::MakeRec(paint, &fDeviceProperties, NULL, &rec); | |
| 129 return rec.getFormat() != SkMask::kARGB32_Format; | |
| 130 } | 127 } |
| 131 | 128 |
| 132 inline void GrDistanceFieldTextContext::init(const GrPaint& paint, const SkPaint
& skPaint) { | 129 inline void GrDistanceFieldTextContext::init(const GrPaint& paint, const SkPaint
& skPaint) { |
| 133 GrTextContext::init(paint, skPaint); | 130 GrTextContext::init(paint, skPaint); |
| 134 | 131 |
| 135 fStrike = NULL; | 132 fStrike = NULL; |
| 136 | 133 |
| 137 const SkMatrix& ctm = fContext->getMatrix(); | 134 const SkMatrix& ctm = fContext->getMatrix(); |
| 138 | 135 |
| 139 // getMaxScale doesn't support perspective, so neither do we at the moment | 136 // getMaxScale doesn't support perspective, so neither do we at the moment |
| (...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 427 #ifdef SK_GAMMA_APPLY_TO_A8 | 424 #ifdef SK_GAMMA_APPLY_TO_A8 |
| 428 U8CPU lum = SkColorSpaceLuminance::computeLuminance(fDevicePropertie
s.gamma(), | 425 U8CPU lum = SkColorSpaceLuminance::computeLuminance(fDevicePropertie
s.gamma(), |
| 429 filteredColor); | 426 filteredColor); |
| 430 fCachedGeometryProcessor.reset(GrDistanceFieldTextureEffect::Create(
fCurrTexture, | 427 fCachedGeometryProcessor.reset(GrDistanceFieldTextureEffect::Create(
fCurrTexture, |
| 431
params, | 428
params, |
| 432
fGammaTexture, | 429
fGammaTexture, |
| 433
gammaParams, | 430
gammaParams, |
| 434
lum/255.f, | 431
lum/255.f, |
| 435
flags)); | 432
flags)); |
| 436 #else | 433 #else |
| 437 fCachedGeometryProcessor.reset(GrDistanceFieldTextureEffect::Create(
fCurrTexture, | 434 fCachedGeometryProcessor.reset(GrDistanceFieldNoGammaTextureEffect::
Create(fCurrTexture, |
| 438
params, flags)); | 435
params, flags)); |
| 439 #endif | 436 #endif |
| 440 } | 437 } |
| 441 fEffectTextureUniqueID = textureUniqueID; | 438 fEffectTextureUniqueID = textureUniqueID; |
| 442 fEffectColor = filteredColor; | 439 fEffectColor = filteredColor; |
| 443 fEffectFlags = flags; | 440 fEffectFlags = flags; |
| 444 } | 441 } |
| 445 | 442 |
| 446 } | 443 } |
| 447 | 444 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 461 GrGlyph* glyph = fStrike->getGlyph(packed, scaler); | 458 GrGlyph* glyph = fStrike->getGlyph(packed, scaler); |
| 462 if (NULL == glyph || glyph->fBounds.isEmpty()) { | 459 if (NULL == glyph || glyph->fBounds.isEmpty()) { |
| 463 return true; | 460 return true; |
| 464 } | 461 } |
| 465 | 462 |
| 466 // fallback to color glyph support | 463 // fallback to color glyph support |
| 467 if (kA8_GrMaskFormat != glyph->fMaskFormat) { | 464 if (kA8_GrMaskFormat != glyph->fMaskFormat) { |
| 468 return false; | 465 return false; |
| 469 } | 466 } |
| 470 | 467 |
| 471 /* | 468 SkScalar dx = SkIntToScalar(glyph->fBounds.fLeft + SK_DistanceFieldInset); |
| 472 // not valid, need to find a different solution for this | 469 SkScalar dy = SkIntToScalar(glyph->fBounds.fTop + SK_DistanceFieldInset); |
| 473 vx += SkIntToFixed(glyph->fBounds.fLeft); | 470 SkScalar width = SkIntToScalar(glyph->fBounds.width() - 2*SK_DistanceFieldIn
set); |
| 474 vy += SkIntToFixed(glyph->fBounds.fTop); | 471 SkScalar height = SkIntToScalar(glyph->fBounds.height() - 2*SK_DistanceField
Inset); |
| 475 | 472 |
| 476 // keep them as ints until we've done the clip-test | 473 SkScalar scale = fTextRatio; |
| 477 GrFixed width = glyph->fBounds.width(); | 474 dx *= scale; |
| 478 GrFixed height = glyph->fBounds.height(); | 475 dy *= scale; |
| 476 sx += dx; |
| 477 sy += dy; |
| 478 width *= scale; |
| 479 height *= scale; |
| 480 SkRect glyphRect = SkRect::MakeXYWH(sx, sy, width, height); |
| 479 | 481 |
| 480 // check if we clipped out | 482 // check if we clipped out |
| 481 if (true || NULL == glyph->fPlot) { | 483 SkRect dstRect; |
| 482 int x = vx >> 16; | 484 const SkMatrix& ctm = fContext->getMatrix(); |
| 483 int y = vy >> 16; | 485 (void) ctm.mapRect(&dstRect, glyphRect); |
| 484 if (fClipRect.quickReject(x, y, x + width, y + height)) { | 486 if (fClipRect.quickReject(SkScalarTruncToInt(dstRect.left()), |
| 487 SkScalarTruncToInt(dstRect.top()), |
| 488 SkScalarTruncToInt(dstRect.right()), |
| 489 SkScalarTruncToInt(dstRect.bottom()))) { |
| 485 // SkCLZ(3); // so we can set a break-point in the debugger | 490 // SkCLZ(3); // so we can set a break-point in the debugger |
| 486 return; | 491 return true; |
| 487 } | |
| 488 } | 492 } |
| 489 */ | 493 |
| 490 if (NULL == glyph->fPlot) { | 494 if (NULL == glyph->fPlot) { |
| 491 if (!fStrike->glyphTooLargeForAtlas(glyph)) { | 495 if (!fStrike->glyphTooLargeForAtlas(glyph)) { |
| 492 if (fStrike->addGlyphToAtlas(glyph, scaler)) { | 496 if (fStrike->addGlyphToAtlas(glyph, scaler)) { |
| 493 goto HAS_ATLAS; | 497 goto HAS_ATLAS; |
| 494 } | 498 } |
| 495 | 499 |
| 496 // try to clear out an unused plot before we flush | 500 // try to clear out an unused plot before we flush |
| 497 if (fContext->getFontCache()->freeUnusedPlot(fStrike, glyph) && | 501 if (fContext->getFontCache()->freeUnusedPlot(fStrike, glyph) && |
| 498 fStrike->addGlyphToAtlas(glyph, scaler)) { | 502 fStrike->addGlyphToAtlas(glyph, scaler)) { |
| 499 goto HAS_ATLAS; | 503 goto HAS_ATLAS; |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 558 } | 562 } |
| 559 | 563 |
| 560 bool useColorVerts = !fUseLCDText; | 564 bool useColorVerts = !fUseLCDText; |
| 561 | 565 |
| 562 if (NULL == fVertices) { | 566 if (NULL == fVertices) { |
| 563 int maxQuadVertices = kVerticesPerGlyph * fContext->getQuadIndexBuffer()
->maxQuads(); | 567 int maxQuadVertices = kVerticesPerGlyph * fContext->getQuadIndexBuffer()
->maxQuads(); |
| 564 fAllocVertexCount = SkMin32(fTotalVertexCount, maxQuadVertices); | 568 fAllocVertexCount = SkMin32(fTotalVertexCount, maxQuadVertices); |
| 565 fVertices = alloc_vertices(fDrawTarget, fAllocVertexCount, useColorVerts
); | 569 fVertices = alloc_vertices(fDrawTarget, fAllocVertexCount, useColorVerts
); |
| 566 } | 570 } |
| 567 | 571 |
| 568 SkScalar dx = SkIntToScalar(glyph->fBounds.fLeft + SK_DistanceFieldInset); | |
| 569 SkScalar dy = SkIntToScalar(glyph->fBounds.fTop + SK_DistanceFieldInset); | |
| 570 SkScalar width = SkIntToScalar(glyph->fBounds.width() - 2*SK_DistanceFieldIn
set); | |
| 571 SkScalar height = SkIntToScalar(glyph->fBounds.height() - 2*SK_DistanceField
Inset); | |
| 572 | |
| 573 SkScalar scale = fTextRatio; | |
| 574 dx *= scale; | |
| 575 dy *= scale; | |
| 576 sx += dx; | |
| 577 sy += dy; | |
| 578 width *= scale; | |
| 579 height *= scale; | |
| 580 | |
| 581 SkFixed tx = SkIntToFixed(glyph->fAtlasLocation.fX + SK_DistanceFieldInset); | 572 SkFixed tx = SkIntToFixed(glyph->fAtlasLocation.fX + SK_DistanceFieldInset); |
| 582 SkFixed ty = SkIntToFixed(glyph->fAtlasLocation.fY + SK_DistanceFieldInset); | 573 SkFixed ty = SkIntToFixed(glyph->fAtlasLocation.fY + SK_DistanceFieldInset); |
| 583 SkFixed tw = SkIntToFixed(glyph->fBounds.width() - 2*SK_DistanceFieldInset); | 574 SkFixed tw = SkIntToFixed(glyph->fBounds.width() - 2*SK_DistanceFieldInset); |
| 584 SkFixed th = SkIntToFixed(glyph->fBounds.height() - 2*SK_DistanceFieldInset)
; | 575 SkFixed th = SkIntToFixed(glyph->fBounds.height() - 2*SK_DistanceFieldInset)
; |
| 585 | 576 |
| 586 SkRect r; | 577 fVertexBounds.joinNonEmptyArg(glyphRect); |
| 587 r.fLeft = sx; | |
| 588 r.fTop = sy; | |
| 589 r.fRight = sx + width; | |
| 590 r.fBottom = sy + height; | |
| 591 | |
| 592 fVertexBounds.joinNonEmptyArg(r); | |
| 593 | 578 |
| 594 size_t vertSize = fUseLCDText ? (2 * sizeof(SkPoint)) | 579 size_t vertSize = fUseLCDText ? (2 * sizeof(SkPoint)) |
| 595 : (2 * sizeof(SkPoint) + sizeof(GrColor)); | 580 : (2 * sizeof(SkPoint) + sizeof(GrColor)); |
| 596 | 581 |
| 597 SkASSERT(vertSize == fDrawTarget->getDrawState().getVertexStride()); | 582 SkASSERT(vertSize == fDrawTarget->getDrawState().getVertexStride()); |
| 598 | 583 |
| 599 SkPoint* positions = reinterpret_cast<SkPoint*>( | 584 SkPoint* positions = reinterpret_cast<SkPoint*>( |
| 600 reinterpret_cast<intptr_t>(fVertices) + vertSize
* fCurrVertex); | 585 reinterpret_cast<intptr_t>(fVertices) + vertSize
* fCurrVertex); |
| 601 positions->setRectFan(r.fLeft, r.fTop, r.fRight, r.fBottom, vertSize); | 586 positions->setRectFan(glyphRect.fLeft, glyphRect.fTop, glyphRect.fRight, gly
phRect.fBottom, |
| 587 vertSize); |
| 602 | 588 |
| 603 // The texture coords are last in both the with and without color vertex lay
outs. | 589 // The texture coords are last in both the with and without color vertex lay
outs. |
| 604 SkPoint* textureCoords = reinterpret_cast<SkPoint*>( | 590 SkPoint* textureCoords = reinterpret_cast<SkPoint*>( |
| 605 reinterpret_cast<intptr_t>(positions) + vertSize
- sizeof(SkPoint)); | 591 reinterpret_cast<intptr_t>(positions) + vertSize
- sizeof(SkPoint)); |
| 606 textureCoords->setRectFan(SkFixedToFloat(texture->texturePriv().normalizeFix
edX(tx)), | 592 textureCoords->setRectFan(SkFixedToFloat(texture->texturePriv().normalizeFix
edX(tx)), |
| 607 SkFixedToFloat(texture->texturePriv().normalizeFix
edY(ty)), | 593 SkFixedToFloat(texture->texturePriv().normalizeFix
edY(ty)), |
| 608 SkFixedToFloat(texture->texturePriv().normalizeFix
edX(tx + tw)), | 594 SkFixedToFloat(texture->texturePriv().normalizeFix
edX(tx + tw)), |
| 609 SkFixedToFloat(texture->texturePriv().normalizeFix
edY(ty + th)), | 595 SkFixedToFloat(texture->texturePriv().normalizeFix
edY(ty + th)), |
| 610 vertSize); | 596 vertSize); |
| 611 if (useColorVerts) { | 597 if (useColorVerts) { |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 691 } | 677 } |
| 692 } | 678 } |
| 693 | 679 |
| 694 inline void GrDistanceFieldTextContext::finish() { | 680 inline void GrDistanceFieldTextContext::finish() { |
| 695 this->flush(); | 681 this->flush(); |
| 696 fTotalVertexCount = 0; | 682 fTotalVertexCount = 0; |
| 697 | 683 |
| 698 GrTextContext::finish(); | 684 GrTextContext::finish(); |
| 699 } | 685 } |
| 700 | 686 |
| OLD | NEW |