| Index: src/gpu/GrDistanceFieldTextContext.cpp
|
| diff --git a/src/gpu/GrDistanceFieldTextContext.cpp b/src/gpu/GrDistanceFieldTextContext.cpp
|
| index 2f67c4915a5ffa670eddcf5b061e7a6417f1e270..d04e52e7cf83af7aca99f267fd1dcdfc913e6e25 100755
|
| --- a/src/gpu/GrDistanceFieldTextContext.cpp
|
| +++ b/src/gpu/GrDistanceFieldTextContext.cpp
|
| @@ -9,6 +9,7 @@
|
| #include "GrAtlas.h"
|
| #include "GrDrawTarget.h"
|
| #include "GrFontScaler.h"
|
| +#include "SkGlyphCache.h"
|
| #include "GrIndexBuffer.h"
|
| #include "GrTextStrike.h"
|
| #include "GrTextStrike_impl.h"
|
| @@ -19,18 +20,16 @@
|
|
|
| static const int kGlyphCoordsAttributeIndex = 1;
|
|
|
| +static const int kBaseDFFontSize = 32;
|
| +
|
| SK_CONF_DECLARE(bool, c_DumpFontCache, "gpu.dumpFontCache", false,
|
| "Dump the contents of the font cache before every purge.");
|
|
|
| -
|
| GrDistanceFieldTextContext::GrDistanceFieldTextContext(GrContext* context,
|
| - const GrPaint& paint,
|
| - SkColor color,
|
| - SkScalar textRatio)
|
| - : GrTextContext(context, paint)
|
| - , fTextRatio(textRatio) {
|
| - fSkPaintColor = color;
|
| -
|
| + const GrPaint& grPaint,
|
| + const SkPaint& skPaint)
|
| + : GrTextContext(context, grPaint),
|
| + fSkPaint(skPaint) {
|
| fStrike = NULL;
|
|
|
| fCurrTexture = NULL;
|
| @@ -38,6 +37,13 @@ GrDistanceFieldTextContext::GrDistanceFieldTextContext(GrContext* context,
|
|
|
| fVertices = NULL;
|
| fMaxVertices = 0;
|
| +
|
| + fTextRatio = fSkPaint.getTextSize()/kBaseDFFontSize;
|
| +
|
| + fSkPaint.setTextSize(SkIntToScalar(kBaseDFFontSize));
|
| + fSkPaint.setLCDRenderText(false);
|
| + fSkPaint.setAutohinted(false);
|
| + fSkPaint.setSubpixelText(false);
|
| }
|
|
|
| GrDistanceFieldTextContext::~GrDistanceFieldTextContext() {
|
| @@ -81,11 +87,11 @@ void GrDistanceFieldTextContext::flushGlyphs() {
|
| // alpha. Instead we feed in a non-premultiplied color, and multiply its alpha by
|
| // the mask texture color. The end result is that we get
|
| // mask*paintAlpha*paintColor + (1-mask*paintAlpha)*dstColor
|
| - int a = SkColorGetA(fSkPaintColor);
|
| + int a = SkColorGetA(fSkPaint.getColor());
|
| // paintAlpha
|
| drawState->setColor(SkColorSetARGB(a, a, a, a));
|
| // paintColor
|
| - drawState->setBlendConstant(skcolor_to_grcolor_nopremultiply(fSkPaintColor));
|
| + drawState->setBlendConstant(skcolor_to_grcolor_nopremultiply(fSkPaint.getColor()));
|
| drawState->setBlendFunc(kConstC_GrBlendCoeff, kISC_GrBlendCoeff);
|
| } else {
|
| // set back to normal in case we took LCD path previously.
|
| @@ -276,3 +282,127 @@ HAS_ATLAS:
|
| 2 * sizeof(SkPoint));
|
| fCurrVertex += 4;
|
| }
|
| +
|
| +void GrDistanceFieldTextContext::drawText(const char text[], size_t byteLength,
|
| + SkScalar x, SkScalar y, SkGlyphCache* cache,
|
| + GrFontScaler* fontScaler) {
|
| + SkASSERT(byteLength == 0 || text != NULL);
|
| +
|
| + // nothing to draw
|
| + if (text == NULL || byteLength == 0 /* no raster clip? || fRC->isEmpty()*/) {
|
| + return;
|
| + }
|
| +
|
| + SkScalar sizeRatio = fTextRatio;
|
| +
|
| + SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc();
|
| +
|
| + // need to measure first
|
| + // TODO - generate positions and pre-load cache as well?
|
| + const char* stop = text + byteLength;
|
| + if (fSkPaint.getTextAlign() != SkPaint::kLeft_Align) {
|
| + SkFixed stopX = 0;
|
| + SkFixed stopY = 0;
|
| +
|
| + const char* textPtr = text;
|
| + while (textPtr < stop) {
|
| + // don't need x, y here, since all subpixel variants will have the
|
| + // same advance
|
| + const SkGlyph& glyph = glyphCacheProc(cache, &textPtr, 0, 0);
|
| +
|
| + stopX += glyph.fAdvanceX;
|
| + stopY += glyph.fAdvanceY;
|
| + }
|
| + SkASSERT(textPtr == stop);
|
| +
|
| + SkScalar alignX = SkFixedToScalar(stopX)*sizeRatio;
|
| + SkScalar alignY = SkFixedToScalar(stopY)*sizeRatio;
|
| +
|
| + if (fSkPaint.getTextAlign() == SkPaint::kCenter_Align) {
|
| + alignX = SkScalarHalf(alignX);
|
| + alignY = SkScalarHalf(alignY);
|
| + }
|
| +
|
| + x -= alignX;
|
| + y -= alignY;
|
| + }
|
| +
|
| + SkFixed fx = SkScalarToFixed(x) + SK_FixedHalf;
|
| + SkFixed fy = SkScalarToFixed(y) + SK_FixedHalf;
|
| + SkFixed fixedScale = SkScalarToFixed(sizeRatio);
|
| + while (text < stop) {
|
| + const SkGlyph& glyph = glyphCacheProc(cache, &text, fx, fy);
|
| +
|
| + if (glyph.fWidth) {
|
| + this->drawPackedGlyph(GrGlyph::Pack(glyph.getGlyphID(),
|
| + glyph.getSubXFixed(),
|
| + glyph.getSubYFixed()),
|
| + SkFixedFloorToFixed(fx),
|
| + SkFixedFloorToFixed(fy),
|
| + fontScaler);
|
| + }
|
| +
|
| + fx += SkFixedMul_portable(glyph.fAdvanceX, fixedScale);
|
| + fy += SkFixedMul_portable(glyph.fAdvanceY, fixedScale);
|
| + }
|
| +}
|
| +
|
| +void GrDistanceFieldTextContext::drawPosText(const char text[], size_t byteLength,
|
| + const SkScalar pos[], SkScalar constY,
|
| + int scalarsPerPosition,
|
| + SkGlyphCache* cache, GrFontScaler* fontScaler) {
|
| +
|
| + SkASSERT(byteLength == 0 || text != NULL);
|
| + SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition);
|
| +
|
| + // nothing to draw
|
| + if (text == NULL || byteLength == 0 /* no raster clip? || fRC->isEmpty()*/) {
|
| + return;
|
| + }
|
| +
|
| + SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc();
|
| +
|
| + const char* stop = text + byteLength;
|
| +
|
| + if (SkPaint::kLeft_Align == fSkPaint.getTextAlign()) {
|
| + while (text < stop) {
|
| + // the last 2 parameters are ignored
|
| + const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0);
|
| +
|
| + if (glyph.fWidth) {
|
| + SkScalar x = pos[0];
|
| + SkScalar y = scalarsPerPosition == 1 ? constY : pos[1];
|
| +
|
| + this->drawPackedGlyph(GrGlyph::Pack(glyph.getGlyphID(),
|
| + glyph.getSubXFixed(),
|
| + glyph.getSubYFixed()),
|
| + SkScalarToFixed(x) + SK_FixedHalf, //d1g.fHalfSampleX,
|
| + SkScalarToFixed(y) + SK_FixedHalf, //d1g.fHalfSampleY,
|
| + fontScaler);
|
| + }
|
| + pos += scalarsPerPosition;
|
| + }
|
| + } else {
|
| + int alignShift = SkPaint::kCenter_Align == fSkPaint.getTextAlign() ? 1 : 0;
|
| + while (text < stop) {
|
| + // the last 2 parameters are ignored
|
| + const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0);
|
| +
|
| + if (glyph.fWidth) {
|
| + SkScalar x = pos[0];
|
| + SkScalar y = scalarsPerPosition == 1 ? constY : pos[1];
|
| +
|
| + this->drawPackedGlyph(GrGlyph::Pack(glyph.getGlyphID(),
|
| + glyph.getSubXFixed(),
|
| + glyph.getSubYFixed()),
|
| + SkScalarToFixed(x) - (glyph.fAdvanceX >> alignShift)
|
| + + SK_FixedHalf, //d1g.fHalfSampleX,
|
| + SkScalarToFixed(y) - (glyph.fAdvanceY >> alignShift)
|
| + + SK_FixedHalf, //d1g.fHalfSampleY,
|
| + fontScaler);
|
| + }
|
| + pos += scalarsPerPosition;
|
| + }
|
| + }
|
| +}
|
| +
|
|
|