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 "gm.h"
|
||||||
#include "sk_tool_utils.h"
|
#include "sk_tool_utils.h"
|
||||||
#include "SkCanvas.h"
|
#include "SkCanvas.h"
|
||||||
|
#include "SkFont.h"
|
||||||
#include "SkTypeface.h"
|
#include "SkTypeface.h"
|
||||||
|
|
||||||
/* This test tries to define the effect of using hairline strokes on text.
|
/* 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 textScale,
|
||||||
SkScalar strokeWidth,
|
SkScalar strokeWidth,
|
||||||
SkPaint::Style strokeStyle) {
|
SkPaint::Style strokeStyle) {
|
||||||
SkPaint paint;
|
SkPaint paint;
|
||||||
paint.setColor(SK_ColorBLACK);
|
paint.setColor(SK_ColorBLACK);
|
||||||
paint.setAntiAlias(true);
|
paint.setAntiAlias(true);
|
||||||
paint.setTextSize(kTextHeight * textScale);
|
paint.setStrokeWidth(strokeWidth);
|
||||||
sk_tool_utils::set_portable_typeface(&paint);
|
paint.setStyle(strokeStyle);
|
||||||
paint.setStrokeWidth(strokeWidth);
|
|
||||||
paint.setStyle(strokeStyle);
|
|
||||||
|
|
||||||
// This demonstrates that we can not measure the text if
|
SkFont font(sk_tool_utils::create_portable_typeface(), kTextHeight * textScale);
|
||||||
// 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));
|
|
||||||
|
|
||||||
SkRect bounds;
|
// This demonstrates that we can not measure the text if
|
||||||
if (drawRef) {
|
// there's a device transform. The canvas total matrix will
|
||||||
SkScalar advance = paint.measureText(kText, sizeof(kText) - 1, &bounds);
|
// end up being a device transform.
|
||||||
|
bool drawRef = !(canvas->getTotalMatrix().getType() &
|
||||||
|
~(SkMatrix::kIdentity_Mask | SkMatrix::kTranslate_Mask));
|
||||||
|
|
||||||
paint.setStrokeWidth(0.0f);
|
SkRect bounds;
|
||||||
paint.setStyle(SkPaint::kStroke_Style);
|
if (drawRef) {
|
||||||
|
SkScalar advance = font.measureText(kText, sizeof(kText) - 1, kUTF8_SkTextEncoding,
|
||||||
|
&bounds, &paint);
|
||||||
|
|
||||||
// Green box is the measured text bounds.
|
paint.setStrokeWidth(0.0f);
|
||||||
paint.setColor(SK_ColorGREEN);
|
paint.setStyle(SkPaint::kStroke_Style);
|
||||||
canvas->drawRect(bounds, paint);
|
|
||||||
|
|
||||||
// Red line is the measured advance from the 0,0 of the text position.
|
// Green box is the measured text bounds.
|
||||||
paint.setColor(SK_ColorRED);
|
paint.setColor(SK_ColorGREEN);
|
||||||
canvas->drawLine(0.0f, 0.0f, advance, 0.0f, paint);
|
canvas->drawRect(bounds, paint);
|
||||||
}
|
|
||||||
|
// Red line is the measured advance from the 0,0 of the text position.
|
||||||
// Black text is the testcase, eg. the text.
|
paint.setColor(SK_ColorRED);
|
||||||
paint.setColor(SK_ColorBLACK);
|
canvas->drawLine(0.0f, 0.0f, advance, 0.0f, paint);
|
||||||
paint.setStrokeWidth(strokeWidth);
|
}
|
||||||
paint.setStyle(strokeStyle);
|
|
||||||
canvas->drawText(kText, sizeof(kText) - 1, 0.0f, 0.0f, paint);
|
// Black text is the testcase, eg. the text.
|
||||||
|
paint.setColor(SK_ColorBLACK);
|
||||||
if (drawRef) {
|
paint.setStrokeWidth(strokeWidth);
|
||||||
SkScalar widths[sizeof(kText) - 1];
|
paint.setStyle(strokeStyle);
|
||||||
paint.getTextWidths(kText, sizeof(kText) - 1, widths, nullptr);
|
canvas->drawSimpleText(kText, sizeof(kText) - 1, kUTF8_SkTextEncoding, 0.0f, 0.0f, font, paint);
|
||||||
|
|
||||||
paint.setStrokeWidth(0.0f);
|
if (drawRef) {
|
||||||
paint.setStyle(SkPaint::kStroke_Style);
|
const size_t len = sizeof(kText) - 1;
|
||||||
|
SkGlyphID glyphs[len];
|
||||||
// Magenta lines are the positions for the characters.
|
const int count = font.textToGlyphs(kText, len, kUTF8_SkTextEncoding, glyphs, len);
|
||||||
paint.setColor(SK_ColorMAGENTA);
|
SkScalar widths[len]; // len is conservative. we really only need 'count'
|
||||||
SkScalar w = bounds.x();
|
font.getWidthsBounds(glyphs, count, widths, nullptr, &paint);
|
||||||
for (size_t i = 0; i < sizeof(kText) - 1; ++i) {
|
|
||||||
canvas->drawLine(w, 0.0f, w, 5.0f, paint);
|
paint.setStrokeWidth(0.0f);
|
||||||
w += widths[i];
|
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) {
|
DEF_SIMPLE_GM(glyph_pos_h_b, c, 800, 600) {
|
||||||
|
@ -140,23 +140,29 @@ bool SkFont::hasSomeAntiAliasing() const {
|
|||||||
|
|
||||||
class SkCanonicalizeFont {
|
class SkCanonicalizeFont {
|
||||||
public:
|
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() ||
|
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);
|
fScale = f->setupForAsPaths(nullptr);
|
||||||
fFont = f;
|
fFont = f;
|
||||||
|
fPaint.reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const SkFont& getFont() const { return *fFont; }
|
const SkFont& getFont() const { return *fFont; }
|
||||||
|
const SkPaint& getPaint() const { return fPaint; }
|
||||||
SkScalar getScale() const { return fScale; }
|
SkScalar getScale() const { return fScale; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const SkFont* fFont;
|
const SkFont* fFont;
|
||||||
SkTLazy<SkFont> fLazy;
|
SkTLazy<SkFont> fLazyFont;
|
||||||
SkScalar fScale;
|
SkPaint fPaint;
|
||||||
|
SkScalar fScale = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -265,7 +271,7 @@ size_t SkFont::breakText(const void* textD, size_t length, SkTextEncoding encodi
|
|||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
|
||||||
SkCanonicalizeFont canon(*this);
|
SkCanonicalizeFont canon(*this, nullptr);
|
||||||
const SkFont& font = canon.getFont();
|
const SkFont& font = canon.getFont();
|
||||||
SkScalar scale = canon.getScale();
|
SkScalar scale = canon.getScale();
|
||||||
|
|
||||||
@ -322,16 +328,11 @@ SkScalar SkFont::measureText(const void* textD, size_t length, SkTextEncoding en
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
SkCanonicalizeFont canon(*this);
|
SkCanonicalizeFont canon(*this, paint);
|
||||||
const SkFont& font = canon.getFont();
|
const SkFont& font = canon.getFont();
|
||||||
SkScalar scale = canon.getScale();
|
SkScalar scale = canon.getScale();
|
||||||
|
|
||||||
SkPaint defaultPaint;
|
auto cache = SkStrikeCache::FindOrCreateStrikeWithNoDeviceExclusive(font, canon.getPaint());
|
||||||
// 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);
|
|
||||||
|
|
||||||
const char* text = static_cast<const char*>(textD);
|
const char* text = static_cast<const char*>(textD);
|
||||||
const char* stop = text + length;
|
const char* stop = text + length;
|
||||||
@ -381,15 +382,14 @@ void VisitGlyphs(const SkFont& origFont, const SkPaint* paint, const uint16_t gl
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SkCanonicalizeFont canon(origFont);
|
SkCanonicalizeFont canon(origFont, paint);
|
||||||
const SkFont& font = canon.getFont();
|
const SkFont& font = canon.getFont();
|
||||||
SkScalar scale = canon.getScale();
|
SkScalar scale = canon.getScale();
|
||||||
if (!scale) {
|
if (!scale) {
|
||||||
scale = 1;
|
scale = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto cache = SkStrikeCache::FindOrCreateStrikeWithNoDeviceExclusive(font,
|
auto cache = SkStrikeCache::FindOrCreateStrikeWithNoDeviceExclusive(font, canon.getPaint());
|
||||||
paint ? *paint : SkPaint());
|
|
||||||
handler(cache.get(), glyphs, count, scale);
|
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 {
|
SkScalar SkFont::getMetrics(SkFontMetrics* metrics) const {
|
||||||
SkCanonicalizeFont canon(*this);
|
SkCanonicalizeFont canon(*this, nullptr);
|
||||||
const SkFont& font = canon.getFont();
|
const SkFont& font = canon.getFont();
|
||||||
SkScalar scale = canon.getScale();
|
SkScalar scale = canon.getScale();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user