Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(779)

Unified Diff: src/gpu/SkGpuDevice.cpp

Issue 85653004: Move distance field font code into SkGpuDevice (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« src/core/SkDraw.cpp ('K') | « src/device/xps/SkXPSDevice.cpp ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/gpu/SkGpuDevice.cpp
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index c6194e70312a5710891b2317e07f61dae90d8ca9..e36d2c61c59fac20451d74f5c8cf2ad1dbb84925 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -1684,9 +1684,6 @@ SkDrawProcs* SkGpuDevice::initDrawForText(GrTextContext* context) {
fDrawProcs = SkNEW(GrSkDrawProcs);
fDrawProcs->fD1GProc = SkGPU_Draw1Glyph;
fDrawProcs->fContext = fContext;
-#if SK_DISTANCEFIELD_FONTS
- fDrawProcs->fFlags = 0;
-#endif
}
// init our (and GL's) state
@@ -1700,9 +1697,12 @@ void SkGpuDevice::drawText(const SkDraw& draw, const void* text,
const SkPaint& paint) {
CHECK_SHOULD_DRAW(draw, false);
- if (fContext->getMatrix().hasPerspective()) {
- // this guy will just call our drawPath()
- draw.drawText((const char*)text, byteLength, x, y, paint);
+ if (draw.shouldDrawTextAsPaths(paint, fContext->getMatrix())) {
+ draw.drawText_asPaths((const char*)text, byteLength, x, y, paint);
+#if SK_DISTANCEFIELD_FONTS
+ } else if (!paint.getRasterizer()) {
+ drawDFText((const char *)text, byteLength, x, y, paint);
+#endif
} else {
SkDraw myDraw(draw);
@@ -1710,23 +1710,93 @@ void SkGpuDevice::drawText(const SkDraw& draw, const void* text,
if (!skPaint2GrPaintShader(this, paint, true, &grPaint)) {
return;
}
-#if SK_DISTANCEFIELD_FONTS
- if (paint.getRasterizer()) {
-#endif
- GrBitmapTextContext context(fContext, grPaint, paint.getColor());
- myDraw.fProcs = this->initDrawForText(&context);
- this->INHERITED::drawText(myDraw, text, byteLength, x, y, paint);
-#if SK_DISTANCEFIELD_FONTS
- } else {
- GrDistanceFieldTextContext context(fContext, grPaint, paint.getColor(),
- paint.getTextSize()/SkDrawProcs::kBaseDFFontSize);
- myDraw.fProcs = this->initDrawForText(&context);
- fDrawProcs->fFlags |= SkDrawProcs::kSkipBakedGlyphTransform_Flag;
- fDrawProcs->fFlags |= SkDrawProcs::kUseScaledGlyphs_Flag;
- this->INHERITED::drawText(myDraw, text, byteLength, x, y, paint);
- fDrawProcs->fFlags = 0;
- }
-#endif
+
+ GrBitmapTextContext context(fContext, grPaint, paint.getColor());
+ myDraw.fProcs = this->initDrawForText(&context);
+ this->INHERITED::drawText(myDraw, text, byteLength, x, y, paint);
+ }
+}
+
+static const int kBaseDFFontSize = 32;
+
+void SkGpuDevice::drawDFText(const char text[], size_t byteLength,
+ SkScalar x, SkScalar y,
+ const SkPaint& paint) {
+ GrPaint grPaint;
+ if (!skPaint2GrPaintShader(this, paint, true, &grPaint)) {
+ return;
+ }
+
+ SkASSERT(byteLength == 0 || text != NULL);
+
+ SkDEBUGCODE(this->validate();)
+
+ // nothing to draw
+ if (text == NULL || byteLength == 0 /* no raster clip? || fRC->isEmpty()*/) {
+ return;
+ }
+
+ SkScalar sizeRatio = paint.getTextSize()/kBaseDFFontSize;
+ GrDistanceFieldTextContext context(fContext, grPaint, paint.getColor(), sizeRatio);
+
+ SkDrawCacheProc glyphCacheProc = paint.getDrawCacheProc();
+
+ SkPaint paintCopy = paint;
+ paintCopy.setTextSize(SkIntToScalar(kBaseDFFontSize));
+ paintCopy.setLCDRenderText(false);
+ paintCopy.setAutohinted(false);
+ paintCopy.setSubpixelText(false);
+ SkAutoGlyphCache autoCache(paintCopy, &this->fLeakyProperties, NULL);
+ SkGlyphCache* cache = autoCache.getCache();
+
+ // need to measure first
+ // TODO - generate positions and pre-load cache as well?
+ const char* stop = text + byteLength;
+ if (paint.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 (paint.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);
+ GrFontScaler* fontScaler = get_gr_font_scaler(cache);
+ while (text < stop) {
+ const SkGlyph& glyph = glyphCacheProc(cache, &text, fx, fy);
+
+ if (glyph.fWidth) {
+ context.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);
}
}
@@ -1736,10 +1806,14 @@ void SkGpuDevice::drawPosText(const SkDraw& draw, const void* text,
const SkPaint& paint) {
CHECK_SHOULD_DRAW(draw, false);
- if (fContext->getMatrix().hasPerspective()) {
+ if (draw.shouldDrawTextAsPaths(paint, fContext->getMatrix())) {
// this guy will just call our drawPath()
- draw.drawPosText((const char*)text, byteLength, pos, constY,
+ draw.drawPosText_asPaths((const char*)text, byteLength, pos, constY,
scalarsPerPos, paint);
+#if SK_DISTANCEFIELD_FONTS
+ } else if (!paint.getRasterizer()) {
+ drawPosDFText((const char *)text, byteLength, pos, constY, scalarsPerPos, paint);
bsalomon 2013/11/25 20:50:22 this->
+#endif
} else {
SkDraw myDraw(draw);
@@ -1747,25 +1821,86 @@ void SkGpuDevice::drawPosText(const SkDraw& draw, const void* text,
if (!skPaint2GrPaintShader(this, paint, true, &grPaint)) {
return;
}
-#if SK_DISTANCEFIELD_FONTS
- if (paint.getRasterizer()) {
-#endif
- GrBitmapTextContext context(fContext, grPaint, paint.getColor());
- myDraw.fProcs = this->initDrawForText(&context);
- this->INHERITED::drawPosText(myDraw, text, byteLength, pos, constY,
- scalarsPerPos, paint);
-#if SK_DISTANCEFIELD_FONTS
- } else {
- GrDistanceFieldTextContext context(fContext, grPaint, paint.getColor(),
- paint.getTextSize()/SkDrawProcs::kBaseDFFontSize);
- myDraw.fProcs = this->initDrawForText(&context);
- fDrawProcs->fFlags |= SkDrawProcs::kSkipBakedGlyphTransform_Flag;
- fDrawProcs->fFlags |= SkDrawProcs::kUseScaledGlyphs_Flag;
- this->INHERITED::drawPosText(myDraw, text, byteLength, pos, constY,
- scalarsPerPos, paint);
- fDrawProcs->fFlags = 0;
+ GrBitmapTextContext context(fContext, grPaint, paint.getColor());
+ myDraw.fProcs = this->initDrawForText(&context);
+ this->INHERITED::drawPosText(myDraw, text, byteLength, pos, constY,
+ scalarsPerPos, paint);
+ }
+}
+
+void SkGpuDevice::drawPosDFText(const char text[], size_t byteLength,
+ const SkScalar pos[], SkScalar constY, int scalarsPerPosition,
+ const SkPaint& paint) {
+ GrPaint grPaint;
+ if (!skPaint2GrPaintShader(this, paint, true, &grPaint)) {
+ return;
+ }
+
+ SkASSERT(byteLength == 0 || text != NULL);
+ SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition);
+
+ SkDEBUGCODE(this->validate();)
+
+ // nothing to draw
+ if (text == NULL || byteLength == 0 /* no raster clip? || fRC->isEmpty()*/) {
+ return;
+ }
+
+ SkScalar sizeRatio = paint.getTextSize()/kBaseDFFontSize;
+ GrDistanceFieldTextContext context(fContext, grPaint, paint.getColor(), sizeRatio);
+
+ SkDrawCacheProc glyphCacheProc = paint.getDrawCacheProc();
+
+ SkPaint paintCopy = paint;
+ paintCopy.setTextSize(SkIntToScalar(kBaseDFFontSize));
+ paintCopy.setLCDRenderText(false);
+ paintCopy.setAutohinted(false);
+ paintCopy.setSubpixelText(false);
+ SkAutoGlyphCache autoCache(paintCopy, &this->fLeakyProperties, NULL);
+ SkGlyphCache* cache = autoCache.getCache();
+
+ const char* stop = text + byteLength;
+ GrFontScaler* fontScaler = get_gr_font_scaler(cache);
+
+ if (SkPaint::kLeft_Align == paint.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];
+
+ context.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 {
robertphillips 2013/11/25 20:39:44 Is all this duplicate code just for the shift?
+ int alignShift = SkPaint::kCenter_Align == paint.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];
+
+ context.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;
}
-#endif
}
}
« src/core/SkDraw.cpp ('K') | « src/device/xps/SkXPSDevice.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698