aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar jvanverth <jvanverth@google.com>2014-10-08 09:07:27 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2014-10-08 09:07:27 -0700
commit0fedb19812f05fcf18d16f0e96000768f4f76b11 (patch)
tree05282555f6edd1d8ae9957c31769191084a8cdbb /src
parente97d82b6e58f417546c738edba40e7ede4f41ea3 (diff)
Rearrange code in TextContexts to be more consistent and match style guide.
Diffstat (limited to 'src')
-rwxr-xr-xsrc/gpu/GrBitmapTextContext.cpp259
-rw-r--r--src/gpu/GrBitmapTextContext.h18
-rwxr-xr-xsrc/gpu/GrDistanceFieldTextContext.cpp629
-rw-r--r--src/gpu/GrDistanceFieldTextContext.h41
-rw-r--r--src/gpu/GrStencilAndCoverTextContext.cpp48
-rw-r--r--src/gpu/GrStencilAndCoverTextContext.h27
-rw-r--r--src/gpu/GrTextContext.h23
7 files changed, 521 insertions, 524 deletions
diff --git a/src/gpu/GrBitmapTextContext.cpp b/src/gpu/GrBitmapTextContext.cpp
index c9cdf2c23f..9478d0436c 100755
--- a/src/gpu/GrBitmapTextContext.cpp
+++ b/src/gpu/GrBitmapTextContext.cpp
@@ -67,99 +67,13 @@ GrBitmapTextContext::GrBitmapTextContext(GrContext* context,
}
GrBitmapTextContext::~GrBitmapTextContext() {
- this->flushGlyphs();
+ this->flush();
}
bool GrBitmapTextContext::canDraw(const SkPaint& paint) {
return !SkDraw::ShouldDrawTextAsPaths(paint, fContext->getMatrix());
}
-static inline GrColor skcolor_to_grcolor_nopremultiply(SkColor c) {
- unsigned r = SkColorGetR(c);
- unsigned g = SkColorGetG(c);
- unsigned b = SkColorGetB(c);
- return GrColorPackRGBA(r, g, b, 0xff);
-}
-
-void GrBitmapTextContext::flushGlyphs() {
- if (NULL == fDrawTarget) {
- return;
- }
-
- GrDrawState* drawState = fDrawTarget->drawState();
- GrDrawState::AutoRestoreEffects are(drawState);
- drawState->setFromPaint(fPaint, SkMatrix::I(), fContext->getRenderTarget());
-
- if (fCurrVertex > 0) {
- // setup our sampler state for our text texture/atlas
- SkASSERT(SkIsAlign4(fCurrVertex));
- SkASSERT(fCurrTexture);
- GrTextureParams params(SkShader::kRepeat_TileMode, GrTextureParams::kNone_FilterMode);
-
- uint32_t textureUniqueID = fCurrTexture->getUniqueID();
-
- if (textureUniqueID != fEffectTextureUniqueID) {
- fCachedGeometryProcessor.reset(GrCustomCoordsTextureEffect::Create(fCurrTexture,
- params));
- fEffectTextureUniqueID = textureUniqueID;
- }
-
- // This effect could be stored with one of the cache objects (atlas?)
- drawState->setGeometryProcessor(fCachedGeometryProcessor.get());
- SkASSERT(fStrike);
- switch (fStrike->getMaskFormat()) {
- // Color bitmap text
- case kARGB_GrMaskFormat:
- SkASSERT(!drawState->hasColorVertexAttribute());
- drawState->setBlendFunc(fPaint.getSrcBlendCoeff(), fPaint.getDstBlendCoeff());
- drawState->setColor(0xffffffff);
- break;
- // LCD text
- case kA888_GrMaskFormat:
- case kA565_GrMaskFormat: {
- if (kOne_GrBlendCoeff != fPaint.getSrcBlendCoeff() ||
- kISA_GrBlendCoeff != fPaint.getDstBlendCoeff() ||
- fPaint.numColorStages()) {
- GrPrintf("LCD Text will not draw correctly.\n");
- }
- SkASSERT(!drawState->hasColorVertexAttribute());
- // We don't use the GrPaint's color in this case because it's been premultiplied by
- // 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(fSkPaint.getColor());
- // paintAlpha
- drawState->setColor(SkColorSetARGB(a, a, a, a));
- // paintColor
- drawState->setBlendConstant(skcolor_to_grcolor_nopremultiply(fSkPaint.getColor()));
- drawState->setBlendFunc(kConstC_GrBlendCoeff, kISC_GrBlendCoeff);
- break;
- }
- // Grayscale/BW text
- case kA8_GrMaskFormat:
- // set back to normal in case we took LCD path previously.
- drawState->setBlendFunc(fPaint.getSrcBlendCoeff(), fPaint.getDstBlendCoeff());
- // We're using per-vertex color.
- SkASSERT(drawState->hasColorVertexAttribute());
- break;
- default:
- SkFAIL("Unexepected mask format.");
- }
- int nGlyphs = fCurrVertex / 4;
- fDrawTarget->setIndexSourceToBuffer(fContext->getQuadIndexBuffer());
- fDrawTarget->drawIndexedInstances(kTriangles_GrPrimitiveType,
- nGlyphs,
- 4, 6, &fVertexBounds);
-
- fDrawTarget->resetVertexSource();
- fVertices = NULL;
- fMaxVertices = 0;
- fCurrVertex = 0;
- fVertexBounds.setLargestInverted();
- SkSafeSetNull(fCurrTexture);
- }
-}
-
inline void GrBitmapTextContext::init(const GrPaint& paint, const SkPaint& skPaint) {
GrTextContext::init(paint, skPaint);
@@ -172,12 +86,6 @@ inline void GrBitmapTextContext::init(const GrPaint& paint, const SkPaint& skPai
fMaxVertices = 0;
}
-inline void GrBitmapTextContext::finish() {
- this->flushGlyphs();
-
- GrTextContext::finish();
-}
-
void GrBitmapTextContext::drawText(const GrPaint& paint, const SkPaint& skPaint,
const char text[], size_t byteLength,
SkScalar x, SkScalar y) {
@@ -254,12 +162,12 @@ void GrBitmapTextContext::drawText(const GrPaint& paint, const SkPaint& skPaint,
fx += autokern.adjust(glyph);
if (glyph.fWidth) {
- this->drawPackedGlyph(GrGlyph::Pack(glyph.getGlyphID(),
- glyph.getSubXFixed(),
- glyph.getSubYFixed()),
- SkFixedFloorToFixed(fx),
- SkFixedFloorToFixed(fy),
- fontScaler);
+ this->appendGlyph(GrGlyph::Pack(glyph.getGlyphID(),
+ glyph.getSubXFixed(),
+ glyph.getSubYFixed()),
+ SkFixedFloorToFixed(fx),
+ SkFixedFloorToFixed(fy),
+ fontScaler);
}
fx += glyph.fAdvanceX;
@@ -328,12 +236,12 @@ void GrBitmapTextContext::drawPosText(const GrPaint& paint, const SkPaint& skPai
fx & fxMask, fy & fyMask);
if (glyph.fWidth) {
- this->drawPackedGlyph(GrGlyph::Pack(glyph.getGlyphID(),
- glyph.getSubXFixed(),
- glyph.getSubYFixed()),
- SkFixedFloorToFixed(fx),
- SkFixedFloorToFixed(fy),
- fontScaler);
+ this->appendGlyph(GrGlyph::Pack(glyph.getGlyphID(),
+ glyph.getSubXFixed(),
+ glyph.getSubYFixed()),
+ SkFixedFloorToFixed(fx),
+ SkFixedFloorToFixed(fy),
+ fontScaler);
}
pos += scalarsPerPosition;
}
@@ -361,12 +269,12 @@ void GrBitmapTextContext::drawPosText(const GrPaint& paint, const SkPaint& skPai
SkASSERT(prevAdvY == glyph.fAdvanceY);
SkASSERT(glyph.fWidth);
- this->drawPackedGlyph(GrGlyph::Pack(glyph.getGlyphID(),
- glyph.getSubXFixed(),
- glyph.getSubYFixed()),
- SkFixedFloorToFixed(fx),
- SkFixedFloorToFixed(fy),
- fontScaler);
+ this->appendGlyph(GrGlyph::Pack(glyph.getGlyphID(),
+ glyph.getSubXFixed(),
+ glyph.getSubYFixed()),
+ SkFixedFloorToFixed(fx),
+ SkFixedFloorToFixed(fy),
+ fontScaler);
}
pos += scalarsPerPosition;
}
@@ -384,12 +292,12 @@ void GrBitmapTextContext::drawPosText(const GrPaint& paint, const SkPaint& skPai
SkFixed fx = SkScalarToFixed(tmsLoc.fX) + SK_FixedHalf; //halfSampleX;
SkFixed fy = SkScalarToFixed(tmsLoc.fY) + SK_FixedHalf; //halfSampleY;
- this->drawPackedGlyph(GrGlyph::Pack(glyph.getGlyphID(),
- glyph.getSubXFixed(),
- glyph.getSubYFixed()),
- SkFixedFloorToFixed(fx),
- SkFixedFloorToFixed(fy),
- fontScaler);
+ this->appendGlyph(GrGlyph::Pack(glyph.getGlyphID(),
+ glyph.getSubXFixed(),
+ glyph.getSubYFixed()),
+ SkFixedFloorToFixed(fx),
+ SkFixedFloorToFixed(fy),
+ fontScaler);
}
pos += scalarsPerPosition;
}
@@ -407,12 +315,12 @@ void GrBitmapTextContext::drawPosText(const GrPaint& paint, const SkPaint& skPai
SkFixed fx = fixedLoc.fX + SK_FixedHalf; //halfSampleX;
SkFixed fy = fixedLoc.fY + SK_FixedHalf; //halfSampleY;
- this->drawPackedGlyph(GrGlyph::Pack(glyph.getGlyphID(),
- glyph.getSubXFixed(),
- glyph.getSubYFixed()),
- SkFixedFloorToFixed(fx),
- SkFixedFloorToFixed(fy),
- fontScaler);
+ this->appendGlyph(GrGlyph::Pack(glyph.getGlyphID(),
+ glyph.getSubXFixed(),
+ glyph.getSubYFixed()),
+ SkFixedFloorToFixed(fx),
+ SkFixedFloorToFixed(fy),
+ fontScaler);
}
pos += scalarsPerPosition;
}
@@ -422,9 +330,9 @@ void GrBitmapTextContext::drawPosText(const GrPaint& paint, const SkPaint& skPai
this->finish();
}
-void GrBitmapTextContext::drawPackedGlyph(GrGlyph::PackedID packed,
- SkFixed vx, SkFixed vy,
- GrFontScaler* scaler) {
+void GrBitmapTextContext::appendGlyph(GrGlyph::PackedID packed,
+ SkFixed vx, SkFixed vy,
+ GrFontScaler* scaler) {
if (NULL == fDrawTarget) {
return;
}
@@ -474,7 +382,7 @@ void GrBitmapTextContext::drawPackedGlyph(GrGlyph::PackedID packed,
}
// flush any accumulated draws to allow us to free up a plot
- this->flushGlyphs();
+ this->flush();
fContext->flush();
// we should have an unused plot now
@@ -518,7 +426,7 @@ HAS_ATLAS:
SkASSERT(texture);
if (fCurrTexture != texture || fCurrVertex + 4 > fMaxVertices) {
- this->flushGlyphs();
+ this->flush();
fCurrTexture = texture;
fCurrTexture->ref();
}
@@ -538,7 +446,7 @@ HAS_ATLAS:
}
bool flush = fDrawTarget->geometryHints(&fMaxVertices, NULL);
if (flush) {
- this->flushGlyphs();
+ this->flush();
fContext->flush();
if (useColorVerts) {
fDrawTarget->drawState()->setVertexAttribs<gTextVertexWithColorAttribs>(
@@ -607,3 +515,96 @@ HAS_ATLAS:
}
fCurrVertex += 4;
}
+
+static inline GrColor skcolor_to_grcolor_nopremultiply(SkColor c) {
+ unsigned r = SkColorGetR(c);
+ unsigned g = SkColorGetG(c);
+ unsigned b = SkColorGetB(c);
+ return GrColorPackRGBA(r, g, b, 0xff);
+}
+
+void GrBitmapTextContext::flush() {
+ if (NULL == fDrawTarget) {
+ return;
+ }
+
+ GrDrawState* drawState = fDrawTarget->drawState();
+ GrDrawState::AutoRestoreEffects are(drawState);
+ drawState->setFromPaint(fPaint, SkMatrix::I(), fContext->getRenderTarget());
+
+ if (fCurrVertex > 0) {
+ // setup our sampler state for our text texture/atlas
+ SkASSERT(SkIsAlign4(fCurrVertex));
+ SkASSERT(fCurrTexture);
+ GrTextureParams params(SkShader::kRepeat_TileMode, GrTextureParams::kNone_FilterMode);
+
+ uint32_t textureUniqueID = fCurrTexture->getUniqueID();
+
+ if (textureUniqueID != fEffectTextureUniqueID) {
+ fCachedGeometryProcessor.reset(GrCustomCoordsTextureEffect::Create(fCurrTexture,
+ params));
+ fEffectTextureUniqueID = textureUniqueID;
+ }
+
+ // This effect could be stored with one of the cache objects (atlas?)
+ drawState->setGeometryProcessor(fCachedGeometryProcessor.get());
+ SkASSERT(fStrike);
+ switch (fStrike->getMaskFormat()) {
+ // Color bitmap text
+ case kARGB_GrMaskFormat:
+ SkASSERT(!drawState->hasColorVertexAttribute());
+ drawState->setBlendFunc(fPaint.getSrcBlendCoeff(), fPaint.getDstBlendCoeff());
+ drawState->setColor(0xffffffff);
+ break;
+ // LCD text
+ case kA888_GrMaskFormat:
+ case kA565_GrMaskFormat: {
+ if (kOne_GrBlendCoeff != fPaint.getSrcBlendCoeff() ||
+ kISA_GrBlendCoeff != fPaint.getDstBlendCoeff() ||
+ fPaint.numColorStages()) {
+ GrPrintf("LCD Text will not draw correctly.\n");
+ }
+ SkASSERT(!drawState->hasColorVertexAttribute());
+ // We don't use the GrPaint's color in this case because it's been premultiplied by
+ // 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(fSkPaint.getColor());
+ // paintAlpha
+ drawState->setColor(SkColorSetARGB(a, a, a, a));
+ // paintColor
+ drawState->setBlendConstant(skcolor_to_grcolor_nopremultiply(fSkPaint.getColor()));
+ drawState->setBlendFunc(kConstC_GrBlendCoeff, kISC_GrBlendCoeff);
+ break;
+ }
+ // Grayscale/BW text
+ case kA8_GrMaskFormat:
+ // set back to normal in case we took LCD path previously.
+ drawState->setBlendFunc(fPaint.getSrcBlendCoeff(), fPaint.getDstBlendCoeff());
+ // We're using per-vertex color.
+ SkASSERT(drawState->hasColorVertexAttribute());
+ break;
+ default:
+ SkFAIL("Unexepected mask format.");
+ }
+ int nGlyphs = fCurrVertex / 4;
+ fDrawTarget->setIndexSourceToBuffer(fContext->getQuadIndexBuffer());
+ fDrawTarget->drawIndexedInstances(kTriangles_GrPrimitiveType,
+ nGlyphs,
+ 4, 6, &fVertexBounds);
+
+ fDrawTarget->resetVertexSource();
+ fVertices = NULL;
+ fMaxVertices = 0;
+ fCurrVertex = 0;
+ fVertexBounds.setLargestInverted();
+ SkSafeSetNull(fCurrTexture);
+ }
+}
+
+inline void GrBitmapTextContext::finish() {
+ this->flush();
+
+ GrTextContext::finish();
+}
+
diff --git a/src/gpu/GrBitmapTextContext.h b/src/gpu/GrBitmapTextContext.h
index c136270c65..4bff399ade 100644
--- a/src/gpu/GrBitmapTextContext.h
+++ b/src/gpu/GrBitmapTextContext.h
@@ -21,6 +21,8 @@ public:
GrBitmapTextContext(GrContext*, const SkDeviceProperties&);
virtual ~GrBitmapTextContext();
+ virtual bool canDraw(const SkPaint& paint) SK_OVERRIDE;
+
virtual void drawText(const GrPaint&, const SkPaint&, const char text[], size_t byteLength,
SkScalar x, SkScalar y) SK_OVERRIDE;
virtual void drawPosText(const GrPaint&, const SkPaint&,
@@ -28,16 +30,7 @@ public:
const SkScalar pos[], int scalarsPerPosition,
const SkPoint& offset) SK_OVERRIDE;
- virtual bool canDraw(const SkPaint& paint) SK_OVERRIDE;
-
private:
- GrTextStrike* fStrike;
-
- void init(const GrPaint&, const SkPaint&);
- void drawPackedGlyph(GrGlyph::PackedID, SkFixed left, SkFixed top, GrFontScaler*);
- void flushGlyphs(); // automatically called by destructor
- void finish();
-
enum {
kMinRequestedGlyphs = 1,
kDefaultRequestedGlyphs = 64,
@@ -45,6 +38,7 @@ private:
kDefaultRequestedVerts = kDefaultRequestedGlyphs * 4,
};
+ GrTextStrike* fStrike;
void* fVertices;
int32_t fMaxVertices;
GrTexture* fCurrTexture;
@@ -53,6 +47,12 @@ private:
uint32_t fEffectTextureUniqueID;
int fCurrVertex;
SkRect fVertexBounds;
+
+ void init(const GrPaint&, const SkPaint&);
+ void appendGlyph(GrGlyph::PackedID, SkFixed left, SkFixed top, GrFontScaler*);
+ void flush(); // automatically called by destructor
+ void finish();
+
};
#endif
diff --git a/src/gpu/GrDistanceFieldTextContext.cpp b/src/gpu/GrDistanceFieldTextContext.cpp
index b565dd63f8..baba10d570 100755
--- a/src/gpu/GrDistanceFieldTextContext.cpp
+++ b/src/gpu/GrDistanceFieldTextContext.cpp
@@ -81,7 +81,7 @@ GrDistanceFieldTextContext::GrDistanceFieldTextContext(GrContext* context,
}
GrDistanceFieldTextContext::~GrDistanceFieldTextContext() {
- this->flushGlyphs();
+ this->flush();
SkSafeSetNull(fGammaTexture);
}
@@ -114,6 +114,231 @@ bool GrDistanceFieldTextContext::canDraw(const SkPaint& paint) {
return rec.getFormat() != SkMask::kARGB32_Format;
}
+inline void GrDistanceFieldTextContext::init(const GrPaint& paint, const SkPaint& skPaint) {
+ GrTextContext::init(paint, skPaint);
+
+ fStrike = NULL;
+
+ const SkMatrix& ctm = fContext->getMatrix();
+
+ // getMaxScale doesn't support perspective, so neither do we at the moment
+ SkASSERT(!ctm.hasPerspective());
+ SkScalar maxScale = ctm.getMaxScale();
+ SkScalar textSize = fSkPaint.getTextSize();
+ SkScalar scaledTextSize = textSize;
+ // if we have non-unity scale, we need to choose our base text size
+ // based on the SkPaint's text size multiplied by the max scale factor
+ // TODO: do we need to do this if we're scaling down (i.e. maxScale < 1)?
+ if (maxScale > 0 && !SkScalarNearlyEqual(maxScale, SK_Scalar1)) {
+ scaledTextSize *= maxScale;
+ }
+
+ fCurrVertex = 0;
+
+ fVertices = NULL;
+
+ if (scaledTextSize <= kSmallDFFontLimit) {
+ fTextRatio = textSize / kSmallDFFontSize;
+ fSkPaint.setTextSize(SkIntToScalar(kSmallDFFontSize));
+ } else if (scaledTextSize <= kMediumDFFontLimit) {
+ fTextRatio = textSize / kMediumDFFontSize;
+ fSkPaint.setTextSize(SkIntToScalar(kMediumDFFontSize));
+ } else {
+ fTextRatio = textSize / kLargeDFFontSize;
+ fSkPaint.setTextSize(SkIntToScalar(kLargeDFFontSize));
+ }
+
+ fUseLCDText = fSkPaint.isLCDRenderText();
+
+ fSkPaint.setLCDRenderText(false);
+ fSkPaint.setAutohinted(false);
+ fSkPaint.setHinting(SkPaint::kNormal_Hinting);
+ fSkPaint.setSubpixelText(true);
+
+}
+
+static void setup_gamma_texture(GrContext* context, const SkGlyphCache* cache,
+ const SkDeviceProperties& deviceProperties,
+ GrTexture** gammaTexture) {
+ if (NULL == *gammaTexture) {
+ int width, height;
+ size_t size;
+
+#ifdef SK_GAMMA_CONTRAST
+ SkScalar contrast = SK_GAMMA_CONTRAST;
+#else
+ SkScalar contrast = 0.5f;
+#endif
+ SkScalar paintGamma = deviceProperties.getGamma();
+ SkScalar deviceGamma = deviceProperties.getGamma();
+
+ size = SkScalerContext::GetGammaLUTSize(contrast, paintGamma, deviceGamma,
+ &width, &height);
+
+ SkAutoTArray<uint8_t> data((int)size);
+ SkScalerContext::GetGammaLUTData(contrast, paintGamma, deviceGamma, data.get());
+
+ // TODO: Update this to use the cache rather than directly creating a texture.
+ GrTextureDesc desc;
+ desc.fFlags = kDynamicUpdate_GrTextureFlagBit;
+ desc.fWidth = width;
+ desc.fHeight = height;
+ desc.fConfig = kAlpha_8_GrPixelConfig;
+
+ *gammaTexture = context->getGpu()->createTexture(desc, NULL, 0);
+ if (NULL == *gammaTexture) {
+ return;
+ }
+
+ context->writeTexturePixels(*gammaTexture,
+ 0, 0, width, height,
+ (*gammaTexture)->config(), data.get(), 0,
+ GrContext::kDontFlush_PixelOpsFlag);
+ }
+}
+
+void GrDistanceFieldTextContext::drawText(const GrPaint& paint, const SkPaint& skPaint,
+ const char text[], size_t byteLength,
+ SkScalar x, SkScalar y) {
+ SkASSERT(byteLength == 0 || text != NULL);
+
+ // nothing to draw or can't draw
+ if (text == NULL || byteLength == 0 /* no raster clip? || fRC->isEmpty()*/
+ || fSkPaint.getRasterizer()) {
+ return;
+ }
+
+ this->init(paint, skPaint);
+
+ SkScalar sizeRatio = fTextRatio;
+
+ SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc();
+
+ SkAutoGlyphCacheNoGamma autoCache(fSkPaint, &fDeviceProperties, NULL);
+ SkGlyphCache* cache = autoCache.getCache();
+ GrFontScaler* fontScaler = GetGrFontScaler(cache);
+
+ setup_gamma_texture(fContext, cache, fDeviceProperties, &fGammaTexture);
+
+ // 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);
+ SkFixed fy = SkScalarToFixed(y);
+ SkFixed fixedScale = SkScalarToFixed(sizeRatio);
+ while (text < stop) {
+ const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0);
+
+ if (glyph.fWidth) {
+ this->appendGlyph(GrGlyph::Pack(glyph.getGlyphID(),
+ glyph.getSubXFixed(),
+ glyph.getSubYFixed()),
+ fx,
+ fy,
+ fontScaler);
+ }
+
+ fx += SkFixedMul_portable(glyph.fAdvanceX, fixedScale);
+ fy += SkFixedMul_portable(glyph.fAdvanceY, fixedScale);
+ }
+
+ this->finish();
+}
+
+void GrDistanceFieldTextContext::drawPosText(const GrPaint& paint, const SkPaint& skPaint,
+ const char text[], size_t byteLength,
+ const SkScalar pos[], int scalarsPerPosition,
+ const SkPoint& offset) {
+
+ SkASSERT(byteLength == 0 || text != NULL);
+ SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition);
+
+ // nothing to draw
+ if (text == NULL || byteLength == 0 /* no raster clip? || fRC->isEmpty()*/) {
+ return;
+ }
+
+ this->init(paint, skPaint);
+
+ SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc();
+
+ SkAutoGlyphCacheNoGamma autoCache(fSkPaint, &fDeviceProperties, NULL);
+ SkGlyphCache* cache = autoCache.getCache();
+ GrFontScaler* fontScaler = GetGrFontScaler(cache);
+
+ setup_gamma_texture(fContext, cache, fDeviceProperties, &fGammaTexture);
+
+ 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 = offset.x() + pos[0];
+ SkScalar y = offset.y() + (2 == scalarsPerPosition ? pos[1] : 0);
+
+ this->appendGlyph(GrGlyph::Pack(glyph.getGlyphID(),
+ glyph.getSubXFixed(),
+ glyph.getSubYFixed()),
+ SkScalarToFixed(x),
+ SkScalarToFixed(y),
+ 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 = offset.x() + pos[0];
+ SkScalar y = offset.y() + (2 == scalarsPerPosition ? pos[1] : 0);
+
+ this->appendGlyph(GrGlyph::Pack(glyph.getGlyphID(),
+ glyph.getSubXFixed(),
+ glyph.getSubYFixed()),
+ SkScalarToFixed(x) - (glyph.fAdvanceX >> alignShift),
+ SkScalarToFixed(y) - (glyph.fAdvanceY >> alignShift),
+ fontScaler);
+ }
+ pos += scalarsPerPosition;
+ }
+ }
+
+ this->finish();
+}
+
static inline GrColor skcolor_to_grcolor_nopremultiply(SkColor c) {
unsigned r = SkColorGetR(c);
unsigned g = SkColorGetG(c);
@@ -143,24 +368,22 @@ void GrDistanceFieldTextContext::setupCoverageEffect(const SkColor& filteredColo
flags != fEffectFlags) {
if (fUseLCDText) {
GrColor colorNoPreMul = skcolor_to_grcolor_nopremultiply(filteredColor);
- fCachedGeometryProcessor.reset(
- GrDistanceFieldLCDTextureEffect::Create(fCurrTexture,
- params,
- fGammaTexture,
- gammaParams,
- colorNoPreMul,
- flags));
+ fCachedGeometryProcessor.reset(GrDistanceFieldLCDTextureEffect::Create(fCurrTexture,
+ params,
+ fGammaTexture,
+ gammaParams,
+ colorNoPreMul,
+ flags));
} else {
#ifdef SK_GAMMA_APPLY_TO_A8
U8CPU lum = SkColorSpaceLuminance::computeLuminance(fDeviceProperties.getGamma(),
filteredColor);
- fCachedGeometryProcessor.reset(
- GrDistanceFieldTextureEffect::Create(fCurrTexture,
- params,
- fGammaTexture,
- gammaParams,
- lum/255.f,
- flags));
+ fCachedGeometryProcessor.reset(GrDistanceFieldTextureEffect::Create(fCurrTexture,
+ params,
+ fGammaTexture,
+ gammaParams,
+ lum/255.f,
+ flags));
#else
fCachedGeometryProcessor.reset(GrDistanceFieldTextureEffect::Create(fCurrTexture,
params, flags));
@@ -173,83 +396,17 @@ void GrDistanceFieldTextContext::setupCoverageEffect(const SkColor& filteredColo
}
-void GrDistanceFieldTextContext::flushGlyphs() {
+void GrDistanceFieldTextContext::appendGlyph(GrGlyph::PackedID packed,
+ SkFixed vx, SkFixed vy,
+ GrFontScaler* scaler) {
if (NULL == fDrawTarget) {
return;
}
- GrDrawState* drawState = fDrawTarget->drawState();
- GrDrawState::AutoRestoreEffects are(drawState);
-
- drawState->setFromPaint(fPaint, fContext->getMatrix(), fContext->getRenderTarget());
-
- if (fCurrVertex > 0) {
- // setup our sampler state for our text texture/atlas
- SkASSERT(SkIsAlign4(fCurrVertex));
-
- // get our current color
- SkColor filteredColor;
- SkColorFilter* colorFilter = fSkPaint.getColorFilter();
- if (colorFilter) {
- filteredColor = colorFilter->filterColor(fSkPaint.getColor());
- } else {
- filteredColor = fSkPaint.getColor();
- }
- this->setupCoverageEffect(filteredColor);
-
- // Effects could be stored with one of the cache objects (atlas?)
- drawState->setGeometryProcessor(fCachedGeometryProcessor.get());
-
- // Set draw state
- if (fUseLCDText) {
- GrColor colorNoPreMul = skcolor_to_grcolor_nopremultiply(filteredColor);
- if (kOne_GrBlendCoeff != fPaint.getSrcBlendCoeff() ||
- kISA_GrBlendCoeff != fPaint.getDstBlendCoeff() ||
- fPaint.numColorStages()) {
- GrPrintf("LCD Text will not draw correctly.\n");
- }
- SkASSERT(!drawState->hasColorVertexAttribute());
- // We don't use the GrPaint's color in this case because it's been premultiplied by
- // 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(fSkPaint.getColor());
- // paintAlpha
- drawState->setColor(SkColorSetARGB(a, a, a, a));
- // paintColor
- drawState->setBlendConstant(colorNoPreMul);
- drawState->setBlendFunc(kConstC_GrBlendCoeff, kISC_GrBlendCoeff);
- } else {
- // set back to normal in case we took LCD path previously.
- drawState->setBlendFunc(fPaint.getSrcBlendCoeff(), fPaint.getDstBlendCoeff());
- // We're using per-vertex color.
- SkASSERT(drawState->hasColorVertexAttribute());
- }
- int nGlyphs = fCurrVertex / 4;
- fDrawTarget->setIndexSourceToBuffer(fContext->getQuadIndexBuffer());
- fDrawTarget->drawIndexedInstances(kTriangles_GrPrimitiveType,
- nGlyphs,
- 4, 6, &fVertexBounds);
- fDrawTarget->resetVertexSource();
- fVertices = NULL;
- fMaxVertices = 0;
- fCurrVertex = 0;
- SkSafeSetNull(fCurrTexture);
- fVertexBounds.setLargestInverted();
- }
-}
-
-void GrDistanceFieldTextContext::drawPackedGlyph(GrGlyph::PackedID packed,
- SkFixed vx, SkFixed vy,
- GrFontScaler* scaler) {
- if (NULL == fDrawTarget) {
- return;
- }
-
if (NULL == fStrike) {
fStrike = fContext->getFontCache()->getStrike(scaler, true);
}
-
+
GrGlyph* glyph = fStrike->getGlyph(packed, scaler);
if (NULL == glyph || glyph->fBounds.isEmpty()) {
return;
@@ -295,7 +452,7 @@ void GrDistanceFieldTextContext::drawPackedGlyph(GrGlyph::PackedID packed,
}
// before we purge the cache, we must flush any accumulated draws
- this->flushGlyphs();
+ this->flush();
fContext->flush();
// we should have an unused plot now
@@ -335,38 +492,34 @@ HAS_ATLAS:
SkASSERT(texture);
if (fCurrTexture != texture || fCurrVertex + 4 > fMaxVertices) {
- this->flushGlyphs();
+ this->flush();
fCurrTexture = texture;
fCurrTexture->ref();
}
bool useColorVerts = !fUseLCDText;
-
+
if (NULL == fVertices) {
// If we need to reserve vertices allow the draw target to suggest
// a number of verts to reserve and whether to perform a flush.
fMaxVertices = kMinRequestedVerts;
if (useColorVerts) {
fDrawTarget->drawState()->setVertexAttribs<gTextVertexWithColorAttribs>(
- SK_ARRAY_COUNT(gTextVertexWithColorAttribs),
- kTextVAColorSize);
+ SK_ARRAY_COUNT(gTextVertexWithColorAttribs), kTextVAColorSize);
} else {
fDrawTarget->drawState()->setVertexAttribs<gTextVertexAttribs>(
- SK_ARRAY_COUNT(gTextVertexAttribs),
- kTextVASize);
+ SK_ARRAY_COUNT(gTextVertexAttribs), kTextVASize);
}
bool flush = fDrawTarget->geometryHints(&fMaxVertices, NULL);
if (flush) {
- this->flushGlyphs();
+ this->flush();
fContext->flush();
if (useColorVerts) {
fDrawTarget->drawState()->setVertexAttribs<gTextVertexWithColorAttribs>(
- SK_ARRAY_COUNT(gTextVertexWithColorAttribs),
- kTextVAColorSize);
+ SK_ARRAY_COUNT(gTextVertexWithColorAttribs), kTextVAColorSize);
} else {
fDrawTarget->drawState()->setVertexAttribs<gTextVertexAttribs>(
- SK_ARRAY_COUNT(gTextVertexAttribs),
- kTextVASize);
+ SK_ARRAY_COUNT(gTextVertexAttribs), kTextVASize);
}
}
fMaxVertices = kDefaultRequestedVerts;
@@ -386,7 +539,7 @@ HAS_ATLAS:
NULL);
GrAlwaysAssert(success);
}
-
+
SkScalar dx = SkIntToScalar(glyph->fBounds.fLeft + SK_DistanceFieldInset);
SkScalar dy = SkIntToScalar(glyph->fBounds.fTop + SK_DistanceFieldInset);
SkScalar width = SkIntToScalar(glyph->fBounds.width() - 2*SK_DistanceFieldInset);
@@ -399,7 +552,7 @@ HAS_ATLAS:
sy += dy;
width *= scale;
height *= scale;
-
+
SkFixed tx = SkIntToFixed(glyph->fAtlasLocation.fX + SK_DistanceFieldInset);
SkFixed ty = SkIntToFixed(glyph->fAtlasLocation.fY + SK_DistanceFieldInset);
SkFixed tw = SkIntToFixed(glyph->fBounds.width() - 2*SK_DistanceFieldInset);
@@ -415,16 +568,16 @@ HAS_ATLAS:
size_t vertSize = fUseLCDText ? (2 * sizeof(SkPoint))
: (2 * sizeof(SkPoint) + sizeof(GrColor));
-
+
SkASSERT(vertSize == fDrawTarget->getDrawState().getVertexStride());
SkPoint* positions = reinterpret_cast<SkPoint*>(
- reinterpret_cast<intptr_t>(fVertices) + vertSize * fCurrVertex);
+ reinterpret_cast<intptr_t>(fVertices) + vertSize * fCurrVertex);
positions->setRectFan(r.fLeft, r.fTop, r.fRight, r.fBottom, vertSize);
// The texture coords are last in both the with and without color vertex layouts.
SkPoint* textureCoords = reinterpret_cast<SkPoint*>(
- reinterpret_cast<intptr_t>(positions) + vertSize - sizeof(SkPoint));
+ reinterpret_cast<intptr_t>(positions) + vertSize - sizeof(SkPoint));
textureCoords->setRectFan(SkFixedToFloat(texture->texturePriv().normalizeFixedX(tx)),
SkFixedToFloat(texture->texturePriv().normalizeFixedY(ty)),
SkFixedToFloat(texture->texturePriv().normalizeFixedX(tx + tw)),
@@ -445,233 +598,75 @@ HAS_ATLAS:
fCurrVertex += 4;
}
-inline void GrDistanceFieldTextContext::init(const GrPaint& paint, const SkPaint& skPaint) {
- GrTextContext::init(paint, skPaint);
-
- fStrike = NULL;
-
- const SkMatrix& ctm = fContext->getMatrix();
-
- // getMaxScale doesn't support perspective, so neither do we at the moment
- SkASSERT(!ctm.hasPerspective());
- SkScalar maxScale = ctm.getMaxScale();
- SkScalar textSize = fSkPaint.getTextSize();
- SkScalar scaledTextSize = textSize;
- // if we have non-unity scale, we need to choose our base text size
- // based on the SkPaint's text size multiplied by the max scale factor
- // TODO: do we need to do this if we're scaling down (i.e. maxScale < 1)?
- if (maxScale > 0 && !SkScalarNearlyEqual(maxScale, SK_Scalar1)) {
- scaledTextSize *= maxScale;
- }
-
- fCurrVertex = 0;
-
- fVertices = NULL;
-
- if (scaledTextSize <= kSmallDFFontLimit) {
- fTextRatio = textSize / kSmallDFFontSize;
- fSkPaint.setTextSize(SkIntToScalar(kSmallDFFontSize));
- } else if (scaledTextSize <= kMediumDFFontLimit) {
- fTextRatio = textSize / kMediumDFFontSize;
- fSkPaint.setTextSize(SkIntToScalar(kMediumDFFontSize));
- } else {
- fTextRatio = textSize / kLargeDFFontSize;
- fSkPaint.setTextSize(SkIntToScalar(kLargeDFFontSize));
- }
-
- fUseLCDText = fSkPaint.isLCDRenderText();
-
- fSkPaint.setLCDRenderText(false);
- fSkPaint.setAutohinted(false);
- fSkPaint.setHinting(SkPaint::kNormal_Hinting);
- fSkPaint.setSubpixelText(true);
-
-}
-
-inline void GrDistanceFieldTextContext::finish() {
- this->flushGlyphs();
-
- GrTextContext::finish();
-}
-
-static void setup_gamma_texture(GrContext* context, const SkGlyphCache* cache,
- const SkDeviceProperties& deviceProperties,
- GrTexture** gammaTexture) {
- if (NULL == *gammaTexture) {
- int width, height;
- size_t size;
-
-#ifdef SK_GAMMA_CONTRAST
- SkScalar contrast = SK_GAMMA_CONTRAST;
-#else
- SkScalar contrast = 0.5f;
-#endif
- SkScalar paintGamma = deviceProperties.getGamma();
- SkScalar deviceGamma = deviceProperties.getGamma();
-
- size = SkScalerContext::GetGammaLUTSize(contrast, paintGamma, deviceGamma,
- &width, &height);
-
- SkAutoTArray<uint8_t> data((int)size);
- SkScalerContext::GetGammaLUTData(contrast, paintGamma, deviceGamma, data.get());
-
- // TODO: Update this to use the cache rather than directly creating a texture.
- GrTextureDesc desc;
- desc.fFlags = kDynamicUpdate_GrTextureFlagBit;
- desc.fWidth = width;
- desc.fHeight = height;
- desc.fConfig = kAlpha_8_GrPixelConfig;
-
- *gammaTexture = context->getGpu()->createTexture(desc, NULL, 0);
- if (NULL == *gammaTexture) {
- return;
- }
-
- context->writeTexturePixels(*gammaTexture,
- 0, 0, width, height,
- (*gammaTexture)->config(), data.get(), 0,
- GrContext::kDontFlush_PixelOpsFlag);
- }
-}
-
-void GrDistanceFieldTextContext::drawText(const GrPaint& paint, const SkPaint& skPaint,
- const char text[], size_t byteLength,
- SkScalar x, SkScalar y) {
- SkASSERT(byteLength == 0 || text != NULL);
-
- // nothing to draw or can't draw
- if (text == NULL || byteLength == 0 /* no raster clip? || fRC->isEmpty()*/
- || fSkPaint.getRasterizer()) {
+void GrDistanceFieldTextContext::flush() {
+ if (NULL == fDrawTarget) {
return;
}
- this->init(paint, skPaint);
-
- SkScalar sizeRatio = fTextRatio;
-
- SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc();
-
- SkAutoGlyphCacheNoGamma autoCache(fSkPaint, &fDeviceProperties, NULL);
- SkGlyphCache* cache = autoCache.getCache();
- GrFontScaler* fontScaler = GetGrFontScaler(cache);
-
- setup_gamma_texture(fContext, cache, fDeviceProperties, &fGammaTexture);
-
- // 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);
+ GrDrawState* drawState = fDrawTarget->drawState();
+ GrDrawState::AutoRestoreEffects are(drawState);
- stopX += glyph.fAdvanceX;
- stopY += glyph.fAdvanceY;
- }
- SkASSERT(textPtr == stop);
+ drawState->setFromPaint(fPaint, fContext->getMatrix(), fContext->getRenderTarget());
- SkScalar alignX = SkFixedToScalar(stopX)*sizeRatio;
- SkScalar alignY = SkFixedToScalar(stopY)*sizeRatio;
+ if (fCurrVertex > 0) {
+ // setup our sampler state for our text texture/atlas
+ SkASSERT(SkIsAlign4(fCurrVertex));
- if (fSkPaint.getTextAlign() == SkPaint::kCenter_Align) {
- alignX = SkScalarHalf(alignX);
- alignY = SkScalarHalf(alignY);
+ // get our current color
+ SkColor filteredColor;
+ SkColorFilter* colorFilter = fSkPaint.getColorFilter();
+ if (colorFilter) {
+ filteredColor = colorFilter->filterColor(fSkPaint.getColor());
+ } else {
+ filteredColor = fSkPaint.getColor();
}
+ this->setupCoverageEffect(filteredColor);
- x -= alignX;
- y -= alignY;
- }
-
- SkFixed fx = SkScalarToFixed(x);
- SkFixed fy = SkScalarToFixed(y);
- SkFixed fixedScale = SkScalarToFixed(sizeRatio);
- while (text < stop) {
- const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0);
+ // Effects could be stored with one of the cache objects (atlas?)
+ drawState->setGeometryProcessor(fCachedGeometryProcessor.get());
- if (glyph.fWidth) {
- this->drawPackedGlyph(GrGlyph::Pack(glyph.getGlyphID(),
- glyph.getSubXFixed(),
- glyph.getSubYFixed()),
- fx,
- fy,
- fontScaler);
+ // Set draw state
+ if (fUseLCDText) {
+ GrColor colorNoPreMul = skcolor_to_grcolor_nopremultiply(filteredColor);
+ if (kOne_GrBlendCoeff != fPaint.getSrcBlendCoeff() ||
+ kISA_GrBlendCoeff != fPaint.getDstBlendCoeff() ||
+ fPaint.numColorStages()) {
+ GrPrintf("LCD Text will not draw correctly.\n");
+ }
+ SkASSERT(!drawState->hasColorVertexAttribute());
+ // We don't use the GrPaint's color in this case because it's been premultiplied by
+ // 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(fSkPaint.getColor());
+ // paintAlpha
+ drawState->setColor(SkColorSetARGB(a, a, a, a));
+ // paintColor
+ drawState->setBlendConstant(colorNoPreMul);
+ drawState->setBlendFunc(kConstC_GrBlendCoeff, kISC_GrBlendCoeff);
+ } else {
+ // set back to normal in case we took LCD path previously.
+ drawState->setBlendFunc(fPaint.getSrcBlendCoeff(), fPaint.getDstBlendCoeff());
+ // We're using per-vertex color.
+ SkASSERT(drawState->hasColorVertexAttribute());
}
-
- fx += SkFixedMul_portable(glyph.fAdvanceX, fixedScale);
- fy += SkFixedMul_portable(glyph.fAdvanceY, fixedScale);
+ int nGlyphs = fCurrVertex / 4;
+ fDrawTarget->setIndexSourceToBuffer(fContext->getQuadIndexBuffer());
+ fDrawTarget->drawIndexedInstances(kTriangles_GrPrimitiveType,
+ nGlyphs,
+ 4, 6, &fVertexBounds);
+ fDrawTarget->resetVertexSource();
+ fVertices = NULL;
+ fMaxVertices = 0;
+ fCurrVertex = 0;
+ SkSafeSetNull(fCurrTexture);
+ fVertexBounds.setLargestInverted();
}
-
- this->finish();
}
-void GrDistanceFieldTextContext::drawPosText(const GrPaint& paint, const SkPaint& skPaint,
- const char text[], size_t byteLength,
- const SkScalar pos[], int scalarsPerPosition,
- const SkPoint& offset) {
-
- SkASSERT(byteLength == 0 || text != NULL);
- SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition);
-
- // nothing to draw
- if (text == NULL || byteLength == 0 /* no raster clip? || fRC->isEmpty()*/) {
- return;
- }
-
- this->init(paint, skPaint);
-
- SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc();
-
- SkAutoGlyphCacheNoGamma autoCache(fSkPaint, &fDeviceProperties, NULL);
- SkGlyphCache* cache = autoCache.getCache();
- GrFontScaler* fontScaler = GetGrFontScaler(cache);
-
- setup_gamma_texture(fContext, cache, fDeviceProperties, &fGammaTexture);
-
- 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 = offset.x() + pos[0];
- SkScalar y = offset.y() + (2 == scalarsPerPosition ? pos[1] : 0);
-
- this->drawPackedGlyph(GrGlyph::Pack(glyph.getGlyphID(),
- glyph.getSubXFixed(),
- glyph.getSubYFixed()),
- SkScalarToFixed(x),
- SkScalarToFixed(y),
- 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 = offset.x() + pos[0];
- SkScalar y = offset.y() + (2 == scalarsPerPosition ? pos[1] : 0);
-
- this->drawPackedGlyph(GrGlyph::Pack(glyph.getGlyphID(),
- glyph.getSubXFixed(),
- glyph.getSubYFixed()),
- SkScalarToFixed(x) - (glyph.fAdvanceX >> alignShift),
- SkScalarToFixed(y) - (glyph.fAdvanceY >> alignShift),
- fontScaler);
- }
- pos += scalarsPerPosition;
- }
- }
+inline void GrDistanceFieldTextContext::finish() {
+ this->flush();
- this->finish();
+ GrTextContext::finish();
}
+
diff --git a/src/gpu/GrDistanceFieldTextContext.h b/src/gpu/GrDistanceFieldTextContext.h
index 0b08b5986c..d628e3e3bd 100644
--- a/src/gpu/GrDistanceFieldTextContext.h
+++ b/src/gpu/GrDistanceFieldTextContext.h
@@ -21,6 +21,8 @@ public:
GrDistanceFieldTextContext(GrContext*, const SkDeviceProperties&, bool enable);
virtual ~GrDistanceFieldTextContext();
+ virtual bool canDraw(const SkPaint& paint) SK_OVERRIDE;
+
virtual void drawText(const GrPaint&, const SkPaint&, const char text[], size_t byteLength,
SkScalar x, SkScalar y) SK_OVERRIDE;
virtual void drawPosText(const GrPaint&, const SkPaint&,
@@ -28,38 +30,35 @@ public:
const SkScalar pos[], int scalarsPerPosition,
const SkPoint& offset) SK_OVERRIDE;
- virtual bool canDraw(const SkPaint& paint) SK_OVERRIDE;
-
private:
+ enum {
+ kMinRequestedGlyphs = 1,
+ kDefaultRequestedGlyphs = 64,
+ kMinRequestedVerts = kMinRequestedGlyphs * 4,
+ kDefaultRequestedVerts = kDefaultRequestedGlyphs * 4,
+ };
+
GrTextStrike* fStrike;
SkScalar fTextRatio;
bool fUseLCDText;
bool fEnableDFRendering;
SkAutoTUnref<GrGeometryProcessor> fCachedGeometryProcessor;
// Used to check whether fCachedEffect is still valid.
- uint32_t fEffectTextureUniqueID;
- SkColor fEffectColor;
- uint32_t fEffectFlags;
- GrTexture* fGammaTexture;
+ uint32_t fEffectTextureUniqueID;
+ SkColor fEffectColor;
+ uint32_t fEffectFlags;
+ GrTexture* fGammaTexture;
+ void* fVertices;
+ int32_t fMaxVertices;
+ GrTexture* fCurrTexture;
+ int fCurrVertex;
+ SkRect fVertexBounds;
void init(const GrPaint&, const SkPaint&);
- void drawPackedGlyph(GrGlyph::PackedID, SkFixed left, SkFixed top, GrFontScaler*);
- void flushGlyphs(); // automatically called by destructor
+ void appendGlyph(GrGlyph::PackedID, SkFixed left, SkFixed top, GrFontScaler*);
void setupCoverageEffect(const SkColor& filteredColor);
+ void flush(); // automatically called by destructor
void finish();
-
- enum {
- kMinRequestedGlyphs = 1,
- kDefaultRequestedGlyphs = 64,
- kMinRequestedVerts = kMinRequestedGlyphs * 4,
- kDefaultRequestedVerts = kDefaultRequestedGlyphs * 4,
- };
-
- void* fVertices;
- int32_t fMaxVertices;
- GrTexture* fCurrTexture;
- int fCurrVertex;
- SkRect fVertexBounds;
};
#endif
diff --git a/src/gpu/GrStencilAndCoverTextContext.cpp b/src/gpu/GrStencilAndCoverTextContext.cpp
index cfcabe923f..1941fa7afc 100644
--- a/src/gpu/GrStencilAndCoverTextContext.cpp
+++ b/src/gpu/GrStencilAndCoverTextContext.cpp
@@ -28,6 +28,30 @@ GrStencilAndCoverTextContext::GrStencilAndCoverTextContext(
GrStencilAndCoverTextContext::~GrStencilAndCoverTextContext() {
}
+bool GrStencilAndCoverTextContext::canDraw(const SkPaint& paint) {
+ if (paint.getRasterizer()) {
+ return false;
+ }
+ if (paint.getMaskFilter()) {
+ return false;
+ }
+ if (paint.getPathEffect()) {
+ return false;
+ }
+
+ // No hairlines unless we can map the 1 px width to the object space.
+ if (paint.getStyle() == SkPaint::kStroke_Style
+ && paint.getStrokeWidth() == 0
+ && fContext->getMatrix().hasPerspective()) {
+ return false;
+ }
+
+ // No color bitmap fonts.
+ SkScalerContext::Rec rec;
+ SkScalerContext::MakeRec(paint, &fDeviceProperties, NULL, &rec);
+ return rec.getFormat() != SkMask::kARGB32_Format;
+}
+
void GrStencilAndCoverTextContext::drawText(const GrPaint& paint,
const SkPaint& skPaint,
const char text[],
@@ -189,30 +213,6 @@ void GrStencilAndCoverTextContext::drawPosText(const GrPaint& paint,
this->finish();
}
-bool GrStencilAndCoverTextContext::canDraw(const SkPaint& paint) {
- if (paint.getRasterizer()) {
- return false;
- }
- if (paint.getMaskFilter()) {
- return false;
- }
- if (paint.getPathEffect()) {
- return false;
- }
-
- // No hairlines unless we can map the 1 px width to the object space.
- if (paint.getStyle() == SkPaint::kStroke_Style
- && paint.getStrokeWidth() == 0
- && fContext->getMatrix().hasPerspective()) {
- return false;
- }
-
- // No color bitmap fonts.
- SkScalerContext::Rec rec;
- SkScalerContext::MakeRec(paint, &fDeviceProperties, NULL, &rec);
- return rec.getFormat() != SkMask::kARGB32_Format;
-}
-
static GrPathRange* get_gr_glyphs(GrContext* ctx,
const SkTypeface* typeface,
const SkDescriptor* desc,
diff --git a/src/gpu/GrStencilAndCoverTextContext.h b/src/gpu/GrStencilAndCoverTextContext.h
index b6e23bdb3f..dc32025501 100644
--- a/src/gpu/GrStencilAndCoverTextContext.h
+++ b/src/gpu/GrStencilAndCoverTextContext.h
@@ -27,6 +27,8 @@ public:
GrStencilAndCoverTextContext(GrContext*, const SkDeviceProperties&);
virtual ~GrStencilAndCoverTextContext();
+ virtual bool canDraw(const SkPaint& paint) SK_OVERRIDE;
+
virtual void drawText(const GrPaint&, const SkPaint&, const char text[],
size_t byteLength,
SkScalar x, SkScalar y) SK_OVERRIDE;
@@ -35,8 +37,6 @@ public:
const SkScalar pos[], int scalarsPerPosition,
const SkPoint& offset) SK_OVERRIDE;
- virtual bool canDraw(const SkPaint& paint) SK_OVERRIDE;
-
private:
static const int kGlyphBufferSize = 1024;
@@ -61,6 +61,18 @@ private:
kMaxPerformance_RenderMode,
};
+ GrDrawState::AutoRestoreEffects fStateRestore;
+ SkScalar fTextRatio;
+ float fTextInverseRatio;
+ SkGlyphCache* fGlyphCache;
+ GrPathRange* fGlyphs;
+ uint32_t fIndexBuffer[kGlyphBufferSize];
+ float fTransformBuffer[2 * kGlyphBufferSize];
+ GrDrawTarget::PathTransformType fTransformType;
+ int fPendingGlyphCount;
+ SkMatrix fContextInitialMatrix;
+ bool fNeedsDeviceSpaceGlyphs;
+
void init(const GrPaint&, const SkPaint&, size_t textByteLength,
RenderMode, const SkPoint& textTranslate);
void initGlyphs(SkGlyphCache* cache);
@@ -69,17 +81,6 @@ private:
void flush();
void finish();
- GrDrawState::AutoRestoreEffects fStateRestore;
- SkScalar fTextRatio;
- float fTextInverseRatio;
- SkGlyphCache* fGlyphCache;
- GrPathRange* fGlyphs;
- uint32_t fIndexBuffer[kGlyphBufferSize];
- float fTransformBuffer[2 * kGlyphBufferSize];
- GrDrawTarget::PathTransformType fTransformType;
- int fPendingGlyphCount;
- SkMatrix fContextInitialMatrix;
- bool fNeedsDeviceSpaceGlyphs;
};
#endif
diff --git a/src/gpu/GrTextContext.h b/src/gpu/GrTextContext.h
index da41c1bb3c..b82a64840b 100644
--- a/src/gpu/GrTextContext.h
+++ b/src/gpu/GrTextContext.h
@@ -24,6 +24,9 @@ class GrFontScaler;
class GrTextContext {
public:
virtual ~GrTextContext() {}
+
+ virtual bool canDraw(const SkPaint& paint) = 0;
+
virtual void drawText(const GrPaint&, const SkPaint&, const char text[], size_t byteLength,
SkScalar x, SkScalar y) = 0;
virtual void drawPosText(const GrPaint&, const SkPaint&,
@@ -31,18 +34,7 @@ public:
const SkScalar pos[], int scalarsPerPosition,
const SkPoint& offset) = 0;
- virtual bool canDraw(const SkPaint& paint) = 0;
-
protected:
- GrTextContext(GrContext*, const SkDeviceProperties&);
-
- static GrFontScaler* GetGrFontScaler(SkGlyphCache* cache);
- static void MeasureText(SkGlyphCache* cache, SkDrawCacheProc glyphCacheProc,
- const char text[], size_t byteLength, SkVector* stopVector);
-
- void init(const GrPaint&, const SkPaint&);
- void finish() { fDrawTarget = NULL; }
-
GrContext* fContext;
SkDeviceProperties fDeviceProperties;
@@ -50,6 +42,15 @@ protected:
SkIRect fClipRect;
GrPaint fPaint;
SkPaint fSkPaint;
+
+ GrTextContext(GrContext*, const SkDeviceProperties&);
+
+ void init(const GrPaint&, const SkPaint&);
+ void finish() { fDrawTarget = NULL; }
+
+ static GrFontScaler* GetGrFontScaler(SkGlyphCache* cache);
+ static void MeasureText(SkGlyphCache* cache, SkDrawCacheProc glyphCacheProc,
+ const char text[], size_t byteLength, SkVector* stopVector);
};
#endif