Update SkCanonicalizeFont to also update paint

Bug: skia:
Change-Id: I3bf0ecc133778645826f83f7bc54f9c4f88e5e05
Reviewed-on: https://skia-review.googlesource.com/c/177885
Reviewed-by: Mike Reed <reed@google.com>
Commit-Queue: Mike Reed <reed@google.com>
This commit is contained in:
Mike Reed 2018-12-16 15:57:29 -05:00 committed by Skia Commit-Bot
parent 1d6ae2e8f5
commit 6cd43b4456
2 changed files with 68 additions and 63 deletions

View File

@ -8,6 +8,7 @@
#include "gm.h"
#include "sk_tool_utils.h"
#include "SkCanvas.h"
#include "SkFont.h"
#include "SkTypeface.h"
/* This test tries to define the effect of using hairline strokes on text.
@ -80,57 +81,61 @@ static void drawTestCase(SkCanvas* canvas,
SkScalar textScale,
SkScalar strokeWidth,
SkPaint::Style strokeStyle) {
SkPaint paint;
paint.setColor(SK_ColorBLACK);
paint.setAntiAlias(true);
paint.setTextSize(kTextHeight * textScale);
sk_tool_utils::set_portable_typeface(&paint);
paint.setStrokeWidth(strokeWidth);
paint.setStyle(strokeStyle);
SkPaint paint;
paint.setColor(SK_ColorBLACK);
paint.setAntiAlias(true);
paint.setStrokeWidth(strokeWidth);
paint.setStyle(strokeStyle);
// This demonstrates that we can not measure the text if
// there's a device transform. The canvas total matrix will
// end up being a device transform.
bool drawRef = !(canvas->getTotalMatrix().getType() &
~(SkMatrix::kIdentity_Mask | SkMatrix::kTranslate_Mask));
SkFont font(sk_tool_utils::create_portable_typeface(), kTextHeight * textScale);
SkRect bounds;
if (drawRef) {
SkScalar advance = paint.measureText(kText, sizeof(kText) - 1, &bounds);
// This demonstrates that we can not measure the text if
// there's a device transform. The canvas total matrix will
// end up being a device transform.
bool drawRef = !(canvas->getTotalMatrix().getType() &
~(SkMatrix::kIdentity_Mask | SkMatrix::kTranslate_Mask));
paint.setStrokeWidth(0.0f);
paint.setStyle(SkPaint::kStroke_Style);
SkRect bounds;
if (drawRef) {
SkScalar advance = font.measureText(kText, sizeof(kText) - 1, kUTF8_SkTextEncoding,
&bounds, &paint);
// Green box is the measured text bounds.
paint.setColor(SK_ColorGREEN);
canvas->drawRect(bounds, paint);
paint.setStrokeWidth(0.0f);
paint.setStyle(SkPaint::kStroke_Style);
// Red line is the measured advance from the 0,0 of the text position.
paint.setColor(SK_ColorRED);
canvas->drawLine(0.0f, 0.0f, advance, 0.0f, paint);
}
// Black text is the testcase, eg. the text.
paint.setColor(SK_ColorBLACK);
paint.setStrokeWidth(strokeWidth);
paint.setStyle(strokeStyle);
canvas->drawText(kText, sizeof(kText) - 1, 0.0f, 0.0f, paint);
if (drawRef) {
SkScalar widths[sizeof(kText) - 1];
paint.getTextWidths(kText, sizeof(kText) - 1, widths, nullptr);
paint.setStrokeWidth(0.0f);
paint.setStyle(SkPaint::kStroke_Style);
// Magenta lines are the positions for the characters.
paint.setColor(SK_ColorMAGENTA);
SkScalar w = bounds.x();
for (size_t i = 0; i < sizeof(kText) - 1; ++i) {
canvas->drawLine(w, 0.0f, w, 5.0f, paint);
w += widths[i];
}
// Green box is the measured text bounds.
paint.setColor(SK_ColorGREEN);
canvas->drawRect(bounds, paint);
// Red line is the measured advance from the 0,0 of the text position.
paint.setColor(SK_ColorRED);
canvas->drawLine(0.0f, 0.0f, advance, 0.0f, paint);
}
// Black text is the testcase, eg. the text.
paint.setColor(SK_ColorBLACK);
paint.setStrokeWidth(strokeWidth);
paint.setStyle(strokeStyle);
canvas->drawSimpleText(kText, sizeof(kText) - 1, kUTF8_SkTextEncoding, 0.0f, 0.0f, font, paint);
if (drawRef) {
const size_t len = sizeof(kText) - 1;
SkGlyphID glyphs[len];
const int count = font.textToGlyphs(kText, len, kUTF8_SkTextEncoding, glyphs, len);
SkScalar widths[len]; // len is conservative. we really only need 'count'
font.getWidthsBounds(glyphs, count, widths, nullptr, &paint);
paint.setStrokeWidth(0.0f);
paint.setStyle(SkPaint::kStroke_Style);
// Magenta lines are the positions for the characters.
paint.setColor(SK_ColorMAGENTA);
SkScalar w = bounds.x();
for (size_t i = 0; i < sizeof(kText) - 1; ++i) {
canvas->drawLine(w, 0.0f, w, 5.0f, paint);
w += widths[i];
}
}
}
DEF_SIMPLE_GM(glyph_pos_h_b, c, 800, 600) {

View File

@ -140,23 +140,29 @@ bool SkFont::hasSomeAntiAliasing() const {
class SkCanonicalizeFont {
public:
SkCanonicalizeFont(const SkFont& font) : fFont(&font), fScale(0) {
SkCanonicalizeFont(const SkFont& font, const SkPaint* paint) : fFont(&font) {
if (paint) {
fPaint = *paint;
}
if (font.isLinearMetrics() ||
SkDraw::ShouldDrawTextAsPaths(font, SkPaint(), SkMatrix::I()))
SkDraw::ShouldDrawTextAsPaths(font, fPaint, SkMatrix::I()))
{
SkFont* f = fLazy.set(font);
SkFont* f = fLazyFont.set(font);
fScale = f->setupForAsPaths(nullptr);
fFont = f;
fPaint.reset();
}
}
const SkFont& getFont() const { return *fFont; }
const SkPaint& getPaint() const { return fPaint; }
SkScalar getScale() const { return fScale; }
private:
const SkFont* fFont;
SkTLazy<SkFont> fLazy;
SkScalar fScale;
const SkFont* fFont;
SkTLazy<SkFont> fLazyFont;
SkPaint fPaint;
SkScalar fScale = 0;
};
@ -265,7 +271,7 @@ size_t SkFont::breakText(const void* textD, size_t length, SkTextEncoding encodi
return length;
}
SkCanonicalizeFont canon(*this);
SkCanonicalizeFont canon(*this, nullptr);
const SkFont& font = canon.getFont();
SkScalar scale = canon.getScale();
@ -322,16 +328,11 @@ SkScalar SkFont::measureText(const void* textD, size_t length, SkTextEncoding en
return 0;
}
SkCanonicalizeFont canon(*this);
SkCanonicalizeFont canon(*this, paint);
const SkFont& font = canon.getFont();
SkScalar scale = canon.getScale();
SkPaint defaultPaint;
// if we had to cannonicalize the font, then we need to also reset the paint
if (!paint || this != &font) {
paint = &defaultPaint;
}
auto cache = SkStrikeCache::FindOrCreateStrikeWithNoDeviceExclusive(font, *paint);
auto cache = SkStrikeCache::FindOrCreateStrikeWithNoDeviceExclusive(font, canon.getPaint());
const char* text = static_cast<const char*>(textD);
const char* stop = text + length;
@ -381,15 +382,14 @@ void VisitGlyphs(const SkFont& origFont, const SkPaint* paint, const uint16_t gl
return;
}
SkCanonicalizeFont canon(origFont);
SkCanonicalizeFont canon(origFont, paint);
const SkFont& font = canon.getFont();
SkScalar scale = canon.getScale();
if (!scale) {
scale = 1;
}
auto cache = SkStrikeCache::FindOrCreateStrikeWithNoDeviceExclusive(font,
paint ? *paint : SkPaint());
auto cache = SkStrikeCache::FindOrCreateStrikeWithNoDeviceExclusive(font, canon.getPaint());
handler(cache.get(), glyphs, count, scale);
}
@ -468,7 +468,7 @@ bool SkFont::getPath(uint16_t glyphID, SkPath* path) const {
}
SkScalar SkFont::getMetrics(SkFontMetrics* metrics) const {
SkCanonicalizeFont canon(*this);
SkCanonicalizeFont canon(*this, nullptr);
const SkFont& font = canon.getFont();
SkScalar scale = canon.getScale();