aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/SkPaint.cpp
diff options
context:
space:
mode:
authorGravatar Mike Klein <mtklein@google.com>2018-05-02 13:53:53 +0000
committerGravatar Mike Klein <mtklein@google.com>2018-05-02 13:54:54 +0000
commitc76e26a6bb8af9ac9b0c7226851b2ded12d18687 (patch)
tree368bb3cfb1d09e08cfb59cbf666b3e1769267640 /src/core/SkPaint.cpp
parent78a9aed075ecb342545d913bc92ef9abc6431b49 (diff)
Revert "Remove devKerning"
This reverts commit c86c5c0144b85d0bc8ec791f9609ee2d4e7d835a. Reason for revert: 4 of 5 Original change's description: > Remove devKerning > > Dev kerning is not supported by any scalers. This is > mostly removed. The remaining fields fRsbDelta and > fLsbDelta are kept to keep Android compiling. > > Change-Id: If1a9ee9bb599d4e1bdf4b3751ac0c65246350809 > Reviewed-on: https://skia-review.googlesource.com/124921 > Reviewed-by: Ben Wagner <bungeman@google.com> > Commit-Queue: Herb Derby <herb@google.com> TBR=bungeman@google.com,herb@google.com,reed@google.com Change-Id: If865f702868192a1b72cd811baa996dd1282bbce No-Presubmit: true No-Tree-Checks: true No-Try: true Reviewed-on: https://skia-review.googlesource.com/125263 Reviewed-by: Mike Klein <mtklein@google.com> Commit-Queue: Mike Klein <mtklein@google.com>
Diffstat (limited to 'src/core/SkPaint.cpp')
-rw-r--r--src/core/SkPaint.cpp161
1 files changed, 126 insertions, 35 deletions
diff --git a/src/core/SkPaint.cpp b/src/core/SkPaint.cpp
index ab3e2da9b5..141b60b252 100644
--- a/src/core/SkPaint.cpp
+++ b/src/core/SkPaint.cpp
@@ -7,6 +7,7 @@
#include "SkPaint.h"
#include "SkPaintPriv.h"
+#include "SkAutoKern.h"
#include "SkColorFilter.h"
#include "SkData.h"
#include "SkDraw.h"
@@ -244,6 +245,10 @@ void SkPaint::setFakeBoldText(bool doFakeBold) {
this->setFlags(set_clear_mask(fBitfields.fFlags, doFakeBold, kFakeBoldText_Flag));
}
+void SkPaint::setDevKernText(bool doDevKern) {
+ this->setFlags(set_clear_mask(fBitfields.fFlags, doDevKern, kDevKernText_Flag));
+}
+
void SkPaint::setStyle(Style style) {
if ((unsigned)style < kStyleCount) {
fBitfields.fStyle = style;
@@ -620,7 +625,8 @@ static const SkGlyph& sk_getAdvance_glyph_next(SkGlyphCache* cache,
}
SkPaint::GlyphCacheProc SkPaint::GetGlyphCacheProc(TextEncoding encoding,
- bool needFullMetrics) {
+ bool isDevKern,
+ bool needFullMetrics) {
static const GlyphCacheProc gGlyphCacheProcs[] = {
sk_getMetrics_utf8_next,
sk_getMetrics_utf16_next,
@@ -635,7 +641,7 @@ SkPaint::GlyphCacheProc SkPaint::GetGlyphCacheProc(TextEncoding encoding,
unsigned index = encoding;
- if (!needFullMetrics) {
+ if (!needFullMetrics && !isDevKern) {
index += 4;
}
@@ -646,6 +652,7 @@ SkPaint::GlyphCacheProc SkPaint::GetGlyphCacheProc(TextEncoding encoding,
///////////////////////////////////////////////////////////////////////////////
#define TEXT_AS_PATHS_PAINT_FLAGS_TO_IGNORE ( \
+SkPaint::kDevKernText_Flag | \
SkPaint::kLinearText_Flag | \
SkPaint::kLCDRenderText_Flag | \
SkPaint::kEmbeddedBitmapText_Flag | \
@@ -732,6 +739,7 @@ SkScalar SkPaint::measure_text(SkGlyphCache* cache,
}
GlyphCacheProc glyphCacheProc = SkPaint::GetGlyphCacheProc(this->getTextEncoding(),
+ this->isDevKernText(),
nullptr != bounds);
int xyIndex;
@@ -750,16 +758,33 @@ SkScalar SkPaint::measure_text(SkGlyphCache* cache,
SkScalar x = advance(*g, xyIndex);
if (nullptr == bounds) {
- for (; text < stop; n++) {
- x += advance(glyphCacheProc(cache, &text), xyIndex);
+ if (this->isDevKernText()) {
+ for (; text < stop; n++) {
+ const int rsb = g->fRsbDelta;
+ g = &glyphCacheProc(cache, &text);
+ x += SkAutoKern_Adjust(rsb, g->fLsbDelta) + advance(*g, xyIndex);
+ }
+ } else {
+ for (; text < stop; n++) {
+ x += advance(glyphCacheProc(cache, &text), xyIndex);
+ }
}
} else {
set_bounds(*g, bounds);
-
- for (; text < stop; n++) {
- g = &glyphCacheProc(cache, &text);
- joinBoundsProc(*g, bounds, x);
- x += advance(*g, xyIndex);
+ if (this->isDevKernText()) {
+ for (; text < stop; n++) {
+ const int rsb = g->fRsbDelta;
+ g = &glyphCacheProc(cache, &text);
+ x += SkAutoKern_Adjust(rsb, g->fLsbDelta);
+ joinBoundsProc(*g, bounds, x);
+ x += advance(*g, xyIndex);
+ }
+ } else {
+ for (; text < stop; n++) {
+ g = &glyphCacheProc(cache, &text);
+ joinBoundsProc(*g, bounds, x);
+ x += advance(*g, xyIndex);
+ }
}
}
SkASSERT(text == stop);
@@ -832,17 +857,33 @@ size_t SkPaint::breakText(const void* textD, size_t length, SkScalar maxWidth,
auto cache = SkStrikeCache::FindOrCreateStrikeExclusive(paint);
GlyphCacheProc glyphCacheProc = SkPaint::GetGlyphCacheProc(paint.getTextEncoding(),
+ paint.isDevKernText(),
false);
const int xyIndex = paint.isVerticalText() ? 1 : 0;
SkScalar width = 0;
- while (text < stop) {
- const char* curr = text;
- SkScalar x = advance(glyphCacheProc(cache.get(), &text), xyIndex);
- if ((width += x) > maxWidth) {
- width -= x;
- text = curr;
- break;
+ if (this->isDevKernText()) {
+ int rsb = 0;
+ while (text < stop) {
+ const char* curr = text;
+ const SkGlyph& g = glyphCacheProc(cache.get(), &text);
+ SkScalar x = SkAutoKern_Adjust(rsb, g.fLsbDelta) + advance(g, xyIndex);
+ if ((width += x) > maxWidth) {
+ width -= x;
+ text = curr;
+ break;
+ }
+ rsb = g.fRsbDelta;
+ }
+ } else {
+ while (text < stop) {
+ const char* curr = text;
+ SkScalar x = advance(glyphCacheProc(cache.get(), &text), xyIndex);
+ if ((width += x) > maxWidth) {
+ width -= x;
+ text = curr;
+ break;
+ }
}
}
@@ -920,6 +961,7 @@ int SkPaint::getTextWidths(const void* textData, size_t byteLength,
auto cache = SkStrikeCache::FindOrCreateStrikeExclusive(paint);
GlyphCacheProc glyphCacheProc = SkPaint::GetGlyphCacheProc(paint.getTextEncoding(),
+ paint.isDevKernText(),
nullptr != bounds);
const char* text = (const char*)textData;
@@ -927,27 +969,73 @@ int SkPaint::getTextWidths(const void* textData, size_t byteLength,
int count = 0;
const int xyIndex = paint.isVerticalText() ? 1 : 0;
- if (scale) {
- while (text < stop) {
- const SkGlyph& g = glyphCacheProc(cache.get(), &text);
- if (widths) {
- *widths++ = advance(g, xyIndex) * scale;
+ if (this->isDevKernText()) {
+ // we adjust the widths returned here through auto-kerning
+ SkAutoKern autokern;
+ SkScalar prevWidth = 0;
+
+ if (scale) {
+ while (text < stop) {
+ const SkGlyph& g = glyphCacheProc(cache.get(), &text);
+ if (widths) {
+ SkScalar adjust = autokern.adjust(g);
+
+ if (count > 0) {
+ *widths++ = (prevWidth + adjust) * scale;
+ }
+ prevWidth = advance(g, xyIndex);
+ }
+ if (bounds) {
+ set_bounds(g, bounds++, scale);
+ }
+ ++count;
}
- if (bounds) {
- set_bounds(g, bounds++, scale);
+ if (count > 0 && widths) {
+ *widths = prevWidth * scale;
+ }
+ } else {
+ while (text < stop) {
+ const SkGlyph& g = glyphCacheProc(cache.get(), &text);
+ if (widths) {
+ SkScalar adjust = autokern.adjust(g);
+
+ if (count > 0) {
+ *widths++ = prevWidth + adjust;
+ }
+ prevWidth = advance(g, xyIndex);
+ }
+ if (bounds) {
+ set_bounds(g, bounds++);
+ }
+ ++count;
+ }
+ if (count > 0 && widths) {
+ *widths = prevWidth;
}
- ++count;
}
- } else {
- while (text < stop) {
- const SkGlyph& g = glyphCacheProc(cache.get(), &text);
- if (widths) {
- *widths++ = advance(g, xyIndex);
+ } else { // no devkern
+ if (scale) {
+ while (text < stop) {
+ const SkGlyph& g = glyphCacheProc(cache.get(), &text);
+ if (widths) {
+ *widths++ = advance(g, xyIndex) * scale;
+ }
+ if (bounds) {
+ set_bounds(g, bounds++, scale);
+ }
+ ++count;
}
- if (bounds) {
- set_bounds(g, bounds++);
+ } else {
+ while (text < stop) {
+ const SkGlyph& g = glyphCacheProc(cache.get(), &text);
+ if (widths) {
+ *widths++ = advance(g, xyIndex);
+ }
+ if (bounds) {
+ set_bounds(g, bounds++);
+ }
+ ++count;
}
- ++count;
}
}
@@ -1561,6 +1649,7 @@ void SkPaint::toString(SkString* str) const {
SkAddFlagToString(str, this->isFakeBoldText(), "FakeBoldText", &needSeparator);
SkAddFlagToString(str, this->isLinearText(), "LinearText", &needSeparator);
SkAddFlagToString(str, this->isSubpixelText(), "SubpixelText", &needSeparator);
+ SkAddFlagToString(str, this->isDevKernText(), "DevKernText", &needSeparator);
SkAddFlagToString(str, this->isLCDRenderText(), "LCDRenderText", &needSeparator);
SkAddFlagToString(str, this->isEmbeddedBitmapText(),
"EmbeddedBitmapText", &needSeparator);
@@ -1620,7 +1709,9 @@ SkTextBaseIter::SkTextBaseIter(const char text[], size_t length,
const SkPaint& paint,
bool applyStrokeAndPathEffects)
: fPaint(paint) {
- fGlyphCacheProc = SkPaint::GetGlyphCacheProc(paint.getTextEncoding(), true);
+ fGlyphCacheProc = SkPaint::GetGlyphCacheProc(paint.getTextEncoding(),
+ paint.isDevKernText(),
+ true);
fPaint.setLinearText(true);
fPaint.setMaskFilter(nullptr); // don't want this affecting our path-cache lookup
@@ -1689,7 +1780,7 @@ bool SkTextToPathIter::next(const SkPath** path, SkScalar* xpos) {
if (fText < fStop) {
const SkGlyph& glyph = fGlyphCacheProc(fCache.get(), &fText);
- fXPos += fPrevAdvance * fScale;
+ fXPos += (fPrevAdvance + fAutoKern.adjust(glyph)) * fScale;
fPrevAdvance = advance(glyph, fXYIndex); // + fPaint.getTextTracking();
if (glyph.fWidth) {
@@ -1711,7 +1802,7 @@ bool SkTextToPathIter::next(const SkPath** path, SkScalar* xpos) {
bool SkTextInterceptsIter::next(SkScalar* array, int* count) {
const SkGlyph& glyph = fGlyphCacheProc(fCache.get(), &fText);
- fXPos += fPrevAdvance * fScale;
+ fXPos += (fPrevAdvance + fAutoKern.adjust(glyph)) * fScale;
fPrevAdvance = advance(glyph, fXYIndex); // + fPaint.getTextTracking();
if (fCache->findPath(glyph)) {
fCache->findIntercepts(fBounds, fScale, fXPos, SkToBool(fXYIndex),