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:
parent
1d6ae2e8f5
commit
6cd43b4456
@ -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) {
|
||||
|
@ -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();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user