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 |