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

Unified Diff: src/device/xps/SkXPSDevice.cpp

Issue 1471043002: Change XPS to use find and place glyph. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: fix warning Created 5 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/device/xps/SkXPSDevice.cpp
diff --git a/src/device/xps/SkXPSDevice.cpp b/src/device/xps/SkXPSDevice.cpp
index 43c5c6cee63b6a2d5cf16632c2c53ec92a96e3fb..f9715985e0a84cc520f5771eae4287f5d6daa662 100644
--- a/src/device/xps/SkXPSDevice.cpp
+++ b/src/device/xps/SkXPSDevice.cpp
@@ -25,6 +25,7 @@
#include "SkDraw.h"
#include "SkDrawProcs.h"
#include "SkEndian.h"
+#include "SkFindAndPlaceGlyph.h"
#include "SkGeometry.h"
#include "SkGlyphCache.h"
#include "SkHRESULT.h"
@@ -2044,74 +2045,18 @@ HRESULT SkXPSDevice::AddGlyphs(const SkDraw& d,
return S_OK;
}
-struct SkXPSDrawProcs : public SkDrawProcs {
-public:
- /** [in] Advance width and offsets for glyphs measured in
- hundredths of the font em size (XPS Spec 5.1.3). */
- FLOAT centemPerUnit;
- /** [in,out] The accumulated glyphs used in the current typeface. */
- SkBitSet* glyphUse;
- /** [out] The glyphs to draw. */
- SkTDArray<XPS_GLYPH_INDEX> xpsGlyphs;
-};
-
-static void xps_draw_1_glyph(const SkDraw1Glyph& state,
- Sk48Dot16 fx, Sk48Dot16 fy,
- const SkGlyph& skGlyph) {
- SkASSERT(skGlyph.fWidth > 0 && skGlyph.fHeight > 0);
-
- SkXPSDrawProcs* procs = static_cast<SkXPSDrawProcs*>(state.fDraw->fProcs);
-
- //Draw pre-adds half the sampling frequency for floor rounding.
- SkScalar x = Sk48Dot16ToScalar(fx) - state.fHalfSampleX;
- SkScalar y = Sk48Dot16ToScalar(fy) - state.fHalfSampleY;
-
- XPS_GLYPH_INDEX* xpsGlyph = procs->xpsGlyphs.append();
- uint16_t glyphID = skGlyph.getGlyphID();
- procs->glyphUse->setBit(glyphID, true);
- xpsGlyph->index = glyphID;
- if (1 == procs->xpsGlyphs.count()) {
- xpsGlyph->advanceWidth = 0.0f;
- xpsGlyph->horizontalOffset = SkScalarToFloat(x) * procs->centemPerUnit;
- xpsGlyph->verticalOffset = SkScalarToFloat(y) * -procs->centemPerUnit;
- } else {
- const XPS_GLYPH_INDEX& first = procs->xpsGlyphs[0];
- xpsGlyph->advanceWidth = 0.0f;
- xpsGlyph->horizontalOffset = (SkScalarToFloat(x) * procs->centemPerUnit)
- - first.horizontalOffset;
- xpsGlyph->verticalOffset = (SkScalarToFloat(y) * -procs->centemPerUnit)
- - first.verticalOffset;
- }
-}
-
-static void text_draw_init(const SkPaint& paint,
- const void* text, size_t byteLength,
- SkBitSet& glyphsUsed,
- SkDraw& myDraw, SkXPSDrawProcs& procs) {
- procs.fD1GProc = xps_draw_1_glyph;
- int numGlyphGuess;
- switch (paint.getTextEncoding()) {
- case SkPaint::kUTF8_TextEncoding:
- numGlyphGuess = SkUTF8_CountUnichars(
- static_cast<const char *>(text),
- byteLength);
- break;
- case SkPaint::kUTF16_TextEncoding:
- numGlyphGuess = SkUTF16_CountUnichars(
- static_cast<const uint16_t *>(text),
- SkToInt(byteLength));
- break;
- case SkPaint::kGlyphID_TextEncoding:
- numGlyphGuess = SkToInt(byteLength / 2);
- break;
- default:
- SK_ALWAYSBREAK(true);
+static int num_glyph_guess(SkPaint::TextEncoding encoding, const void* text, size_t byteLength) {
+ switch (encoding) {
+ case SkPaint::kUTF8_TextEncoding:
+ return SkUTF8_CountUnichars(static_cast<const char *>(text), byteLength);
+ case SkPaint::kUTF16_TextEncoding:
+ return SkUTF16_CountUnichars(static_cast<const uint16_t *>(text), SkToInt(byteLength));
+ case SkPaint::kGlyphID_TextEncoding:
+ return SkToInt(byteLength / 2);
+ default:
+ SK_ALWAYSBREAK(true);
}
- procs.xpsGlyphs.setReserve(numGlyphGuess);
- procs.glyphUse = &glyphsUsed;
- procs.centemPerUnit = 100.0f / SkScalarToFLOAT(paint.getTextSize());
-
- myDraw.fProcs = &procs;
+ return 0;
}
static bool text_must_be_pathed(const SkPaint& paint, const SkMatrix& matrix) {
@@ -2124,6 +2069,50 @@ static bool text_must_be_pathed(const SkPaint& paint, const SkMatrix& matrix) {
;
}
+typedef SkTDArray<XPS_GLYPH_INDEX> GlyphRun;
+
+class ProcessOneGlyph {
+public:
+ ProcessOneGlyph(FLOAT centemPerUnit, SkBitSet* glyphUse, GlyphRun* xpsGlyphs)
+ : fCentemPerUnit(centemPerUnit)
+ , fGlyphUse(glyphUse)
+ , fXpsGlyphs(xpsGlyphs) { }
+
+ void operator()(const SkGlyph& glyph, SkPoint position, SkPoint) {
+ SkASSERT(glyph.fWidth > 0 && glyph.fHeight > 0);
+
+ SkScalar x = position.fX;
+ SkScalar y = position.fY;
+
+ XPS_GLYPH_INDEX* xpsGlyph = fXpsGlyphs->append();
+ uint16_t glyphID = glyph.getGlyphID();
+ fGlyphUse->setBit(glyphID, true);
+ xpsGlyph->index = glyphID;
+ if (1 == fXpsGlyphs->count()) {
+ xpsGlyph->advanceWidth = 0.0f;
+ xpsGlyph->horizontalOffset = SkScalarToFloat(x) * fCentemPerUnit;
+ xpsGlyph->verticalOffset = SkScalarToFloat(y) * -fCentemPerUnit;
+ }
+ else {
+ const XPS_GLYPH_INDEX& first = (*fXpsGlyphs)[0];
+ xpsGlyph->advanceWidth = 0.0f;
+ xpsGlyph->horizontalOffset = (SkScalarToFloat(x) * fCentemPerUnit)
+ - first.horizontalOffset;
+ xpsGlyph->verticalOffset = (SkScalarToFloat(y) * -fCentemPerUnit)
+ - first.verticalOffset;
+ }
+ }
+
+private:
+ /** [in] Advance width and offsets for glyphs measured in
+ hundredths of the font em size (XPS Spec 5.1.3). */
+ const FLOAT fCentemPerUnit;
+ /** [in,out] The accumulated glyphs used in the current typeface. */
+ SkBitSet* const fGlyphUse;
+ /** [out] The glyphs to draw. */
+ GlyphRun* const fXpsGlyphs;
+};
+
void SkXPSDevice::drawText(const SkDraw& d,
const void* text, size_t byteLen,
SkScalar x, SkScalar y,
@@ -2141,31 +2130,41 @@ void SkXPSDevice::drawText(const SkDraw& d,
TypefaceUse* typeface;
HRV(CreateTypefaceUse(paint, &typeface));
- SkDraw myDraw(d);
- myDraw.fMatrix = &SkMatrix::I();
- SkXPSDrawProcs procs;
- text_draw_init(paint, text, byteLen, *typeface->glyphsUsed, myDraw, procs);
+ const SkMatrix& matrix = SkMatrix::I();
+
+ SkAutoGlyphCache autoCache(paint, &this->surfaceProps(), &matrix);
+ SkGlyphCache* cache = autoCache.getCache();
+
+ // Advance width and offsets for glyphs measured in hundredths of the font em size
+ // (XPS Spec 5.1.3).
+ FLOAT centemPerUnit = 100.0f / SkScalarToFLOAT(paint.getTextSize());
+ GlyphRun xpsGlyphs;
+ xpsGlyphs.setReserve(num_glyph_guess(paint.getTextEncoding(),
+ static_cast<const char*>(text), byteLen));
- myDraw.drawText(static_cast<const char*>(text), byteLen, x, y, paint);
+ ProcessOneGlyph processOneGlyph(centemPerUnit, typeface->glyphsUsed, &xpsGlyphs);
- // SkDraw may have clipped out the glyphs, so we need to check
- if (procs.xpsGlyphs.count() == 0) {
+ SkFindAndPlaceGlyph::ProcessText(
+ paint.getTextEncoding(), static_cast<const char*>(text), byteLen,
+ SkPoint{ x, y }, matrix, paint.getTextAlign(), cache, processOneGlyph);
+
+ if (xpsGlyphs.count() == 0) {
return;
}
XPS_POINT origin = {
- procs.xpsGlyphs[0].horizontalOffset / procs.centemPerUnit,
- procs.xpsGlyphs[0].verticalOffset / -procs.centemPerUnit,
+ xpsGlyphs[0].horizontalOffset / centemPerUnit,
+ xpsGlyphs[0].verticalOffset / -centemPerUnit,
};
- procs.xpsGlyphs[0].horizontalOffset = 0.0f;
- procs.xpsGlyphs[0].verticalOffset = 0.0f;
+ xpsGlyphs[0].horizontalOffset = 0.0f;
+ xpsGlyphs[0].verticalOffset = 0.0f;
HRV(AddGlyphs(d,
this->fXpsFactory.get(),
this->fCurrentXpsCanvas.get(),
typeface,
nullptr,
- procs.xpsGlyphs.begin(), procs.xpsGlyphs.count(),
+ xpsGlyphs.begin(), xpsGlyphs.count(),
&origin,
SkScalarToFLOAT(paint.getTextSize()),
XPS_STYLE_SIMULATION_NONE,
@@ -2191,31 +2190,41 @@ void SkXPSDevice::drawPosText(const SkDraw& d,
TypefaceUse* typeface;
HRV(CreateTypefaceUse(paint, &typeface));
- SkDraw myDraw(d);
- myDraw.fMatrix = &SkMatrix::I();
- SkXPSDrawProcs procs;
- text_draw_init(paint, text, byteLen, *typeface->glyphsUsed, myDraw, procs);
+ const SkMatrix& matrix = SkMatrix::I();
+
+ SkAutoGlyphCache autoCache(paint, &this->surfaceProps(), &matrix);
+ SkGlyphCache* cache = autoCache.getCache();
+
+ // Advance width and offsets for glyphs measured in hundredths of the font em size
+ // (XPS Spec 5.1.3).
+ FLOAT centemPerUnit = 100.0f / SkScalarToFLOAT(paint.getTextSize());
+ GlyphRun xpsGlyphs;
+ xpsGlyphs.setReserve(num_glyph_guess(paint.getTextEncoding(),
+ static_cast<const char*>(text), byteLen));
+
+ ProcessOneGlyph processOneGlyph(centemPerUnit, typeface->glyphsUsed, &xpsGlyphs);
- myDraw.drawPosText(static_cast<const char*>(text), byteLen, pos, scalarsPerPos, offset, paint);
+ SkFindAndPlaceGlyph::ProcessPosText(
+ paint.getTextEncoding(), static_cast<const char*>(text), byteLen,
+ offset, matrix, pos, scalarsPerPos, paint.getTextAlign(), cache, processOneGlyph);
- // SkDraw may have clipped out the glyphs, so we need to check
- if (procs.xpsGlyphs.count() == 0) {
+ if (xpsGlyphs.count() == 0) {
return;
}
XPS_POINT origin = {
- procs.xpsGlyphs[0].horizontalOffset / procs.centemPerUnit,
- procs.xpsGlyphs[0].verticalOffset / -procs.centemPerUnit,
+ xpsGlyphs[0].horizontalOffset / centemPerUnit,
+ xpsGlyphs[0].verticalOffset / -centemPerUnit,
};
- procs.xpsGlyphs[0].horizontalOffset = 0.0f;
- procs.xpsGlyphs[0].verticalOffset = 0.0f;
+ xpsGlyphs[0].horizontalOffset = 0.0f;
+ xpsGlyphs[0].verticalOffset = 0.0f;
HRV(AddGlyphs(d,
this->fXpsFactory.get(),
this->fCurrentXpsCanvas.get(),
typeface,
nullptr,
- procs.xpsGlyphs.begin(), procs.xpsGlyphs.count(),
+ xpsGlyphs.begin(), xpsGlyphs.count(),
&origin,
SkScalarToFLOAT(paint.getTextSize()),
XPS_STYLE_SIMULATION_NONE,
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698