Use linear metrics flag for linear metrics.
Now that no one is using the linear metrics flag directly, change the meaning from 'no-hinting and subpixel positioning at an odd size when measuring and just no-hinting when drawing' to meaning 'use linear metrics'. This also changes the font hosts to no longer use subpixel positioning as a proxy for this value. This fixes outstanding bugs in Chromium about getting the right metrics for hinted fonts. Change-Id: I033b3d5ad431eba906a89cc0fefc59cd6702a02c Reviewed-on: https://skia-review.googlesource.com/c/skia/+/209174 Commit-Queue: Ben Wagner <bungeman@google.com> Reviewed-by: Mike Reed <reed@google.com> Reviewed-by: Herb Derby <herb@google.com>
This commit is contained in:
parent
f0a5369d0c
commit
f460eeec99
@ -65,6 +65,7 @@ protected:
|
|||||||
}
|
}
|
||||||
canvas->translate(0, SkIntToScalar(360));
|
canvas->translate(0, SkIntToScalar(360));
|
||||||
font.setSubpixel(true);
|
font.setSubpixel(true);
|
||||||
|
font.setLinearMetrics(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,6 +88,7 @@ protected:
|
|||||||
}
|
}
|
||||||
canvas->translate(0, SkIntToScalar(360));
|
canvas->translate(0, SkIntToScalar(360));
|
||||||
font.setSubpixel(true);
|
font.setSubpixel(true);
|
||||||
|
font.setLinearMetrics(true);
|
||||||
}
|
}
|
||||||
return DrawResult::kOk;
|
return DrawResult::kOk;
|
||||||
}
|
}
|
||||||
|
@ -53,6 +53,7 @@ public:
|
|||||||
, fShaper(SkShaper::Make()) {
|
, fShaper(SkShaper::Make()) {
|
||||||
fFont.setHinting(kNo_SkFontHinting);
|
fFont.setHinting(kNo_SkFontHinting);
|
||||||
fFont.setSubpixel(true);
|
fFont.setSubpixel(true);
|
||||||
|
fFont.setLinearMetrics(true);
|
||||||
fFont.setEdging(SkFont::Edging::kAntiAlias);
|
fFont.setEdging(SkFont::Edging::kAntiAlias);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,7 +113,10 @@ SkFont SkFont::makeWithSize(SkScalar newSize) const {
|
|||||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
SkScalar SkFont::setupForAsPaths(SkPaint* paint) {
|
SkScalar SkFont::setupForAsPaths(SkPaint* paint) {
|
||||||
constexpr uint32_t flagsToIgnore = kLinearMetrics_PrivFlag |
|
constexpr uint32_t flagsToIgnore =
|
||||||
|
#ifdef SK_IGNORE_LINEAR_METRICS_FIX
|
||||||
|
kLinearMetrics_PrivFlag |
|
||||||
|
#endif
|
||||||
kEmbeddedBitmaps_PrivFlag |
|
kEmbeddedBitmaps_PrivFlag |
|
||||||
kForceAutoHinting_PrivFlag;
|
kForceAutoHinting_PrivFlag;
|
||||||
|
|
||||||
@ -145,9 +148,11 @@ public:
|
|||||||
if (paint) {
|
if (paint) {
|
||||||
fPaint = *paint;
|
fPaint = *paint;
|
||||||
}
|
}
|
||||||
if (font.isLinearMetrics() ||
|
if (
|
||||||
SkDraw::ShouldDrawTextAsPaths(font, fPaint, SkMatrix::I()))
|
#ifdef SK_IGNORE_LINEAR_METRICS_FIX
|
||||||
{
|
font.isLinearMetrics() ||
|
||||||
|
#endif
|
||||||
|
SkDraw::ShouldDrawTextAsPaths(font, fPaint, SkMatrix::I())) {
|
||||||
SkFont* f = fLazyFont.set(font);
|
SkFont* f = fLazyFont.set(font);
|
||||||
fScale = f->setupForAsPaths(nullptr);
|
fScale = f->setupForAsPaths(nullptr);
|
||||||
fFont = f;
|
fFont = f;
|
||||||
|
@ -1025,18 +1025,27 @@ void SkScalerContext::MakeRecAndEffects(const SkFont& font, const SkPaint& paint
|
|||||||
if (font.isForceAutoHinting()) {
|
if (font.isForceAutoHinting()) {
|
||||||
flags |= SkScalerContext::kForceAutohinting_Flag;
|
flags |= SkScalerContext::kForceAutohinting_Flag;
|
||||||
}
|
}
|
||||||
|
#ifdef SK_IGNORE_LINEAR_METRICS_FIX
|
||||||
|
if (font.isSubpixel()) {
|
||||||
|
#else
|
||||||
|
if (font.isLinearMetrics()) {
|
||||||
|
#endif
|
||||||
|
flags |= SkScalerContext::kLinearMetrics_Flag;
|
||||||
|
}
|
||||||
rec->fFlags = SkToU16(flags);
|
rec->fFlags = SkToU16(flags);
|
||||||
|
|
||||||
|
#ifdef SK_IGNORE_LINEAR_METRICS_FIX
|
||||||
// if linear-text is on, then we force hinting to be off (since that's sort of
|
// if linear-text is on, then we force hinting to be off (since that's sort of
|
||||||
// the point of linear-text.
|
// the point of linear-text.
|
||||||
SkFontHinting hinting = (SkFontHinting)font.getHinting();
|
SkFontHinting hinting = (SkFontHinting)font.getHinting();
|
||||||
if (font.isLinearMetrics()) {
|
if (font.isLinearMetrics()) {
|
||||||
hinting = kNo_SkFontHinting;
|
hinting = kNo_SkFontHinting;
|
||||||
}
|
}
|
||||||
|
rec->setHinting(font.getHinting());
|
||||||
|
#else
|
||||||
// these modify fFlags, so do them after assigning fFlags
|
// these modify fFlags, so do them after assigning fFlags
|
||||||
rec->setHinting(hinting);
|
rec->setHinting(font.getHinting());
|
||||||
|
#endif
|
||||||
rec->setLuminanceColor(SkPaintPriv::ComputeLuminanceColor(paint));
|
rec->setLuminanceColor(SkPaintPriv::ComputeLuminanceColor(paint));
|
||||||
|
|
||||||
// For now always set the paint gamma equal to the device gamma.
|
// For now always set the paint gamma equal to the device gamma.
|
||||||
|
@ -241,6 +241,7 @@ public:
|
|||||||
// Generate A8 from LCD source (for GDI and CoreGraphics).
|
// Generate A8 from LCD source (for GDI and CoreGraphics).
|
||||||
// only meaningful if fMaskFormat is kA8
|
// only meaningful if fMaskFormat is kA8
|
||||||
kGenA8FromLCD_Flag = 0x0800, // could be 0x200 (bit meaning dependent on fMaskFormat)
|
kGenA8FromLCD_Flag = 0x0800, // could be 0x200 (bit meaning dependent on fMaskFormat)
|
||||||
|
kLinearMetrics_Flag = 0x1000,
|
||||||
};
|
};
|
||||||
|
|
||||||
// computed values
|
// computed values
|
||||||
@ -261,6 +262,10 @@ public:
|
|||||||
return SkToBool(fRec.fFlags & kSubpixelPositioning_Flag);
|
return SkToBool(fRec.fFlags & kSubpixelPositioning_Flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isLinearMetrics() const {
|
||||||
|
return SkToBool(fRec.fFlags & kLinearMetrics_Flag);
|
||||||
|
}
|
||||||
|
|
||||||
// DEPRECATED
|
// DEPRECATED
|
||||||
bool isVertical() const { return false; }
|
bool isVertical() const { return false; }
|
||||||
|
|
||||||
|
@ -906,8 +906,6 @@ SkTextBaseIter::SkTextBaseIter(const SkGlyphID glyphs[], int count, const SkFont
|
|||||||
const SkPaint* paint) : fFont(font) {
|
const SkPaint* paint) : fFont(font) {
|
||||||
SkAssertResult(count >= 0);
|
SkAssertResult(count >= 0);
|
||||||
|
|
||||||
fFont.setLinearMetrics(true);
|
|
||||||
|
|
||||||
if (paint) {
|
if (paint) {
|
||||||
fPaint = *paint;
|
fPaint = *paint;
|
||||||
}
|
}
|
||||||
@ -915,6 +913,9 @@ SkTextBaseIter::SkTextBaseIter(const SkGlyphID glyphs[], int count, const SkFont
|
|||||||
|
|
||||||
// can't use our canonical size if we need to apply patheffects
|
// can't use our canonical size if we need to apply patheffects
|
||||||
if (fPaint.getPathEffect() == nullptr) {
|
if (fPaint.getPathEffect() == nullptr) {
|
||||||
|
// If the wrong size is going to be used, don't hint anything.
|
||||||
|
fFont.setHinting(kNo_SkFontHinting);
|
||||||
|
fFont.setSubpixel(true);
|
||||||
fScale = fFont.getSize() / SkFontPriv::kCanonicalTextSizeForPaths;
|
fScale = fFont.getSize() / SkFontPriv::kCanonicalTextSizeForPaths;
|
||||||
fFont.setSize(SkIntToScalar(SkFontPriv::kCanonicalTextSizeForPaths));
|
fFont.setSize(SkIntToScalar(SkFontPriv::kCanonicalTextSizeForPaths));
|
||||||
// Note: fScale can be zero here (even if it wasn't before the divide). It can also
|
// Note: fScale can be zero here (even if it wasn't before the divide). It can also
|
||||||
|
@ -845,7 +845,7 @@ SkScalerContext_FreeType::SkScalerContext_FreeType(sk_sp<SkTypeface> typeface,
|
|||||||
fLCDIsVert = SkToBool(fRec.fFlags & SkScalerContext::kLCD_Vertical_Flag);
|
fLCDIsVert = SkToBool(fRec.fFlags & SkScalerContext::kLCD_Vertical_Flag);
|
||||||
|
|
||||||
// compute the flags we send to Load_Glyph
|
// compute the flags we send to Load_Glyph
|
||||||
bool linearMetrics = this->isSubpixel();
|
bool linearMetrics = this->isLinearMetrics();
|
||||||
{
|
{
|
||||||
FT_Int32 loadFlags = FT_LOAD_DEFAULT;
|
FT_Int32 loadFlags = FT_LOAD_DEFAULT;
|
||||||
|
|
||||||
|
@ -723,7 +723,7 @@ SkScalerContext_GDI::SkScalerContext_GDI(sk_sp<LogFontTypeface> rawTypeface,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create a hires matrix if we need linear metrics.
|
// Create a hires matrix if we need linear metrics.
|
||||||
if (this->isSubpixel()) {
|
if (this->isLinearMetrics()) {
|
||||||
OUTLINETEXTMETRIC otm;
|
OUTLINETEXTMETRIC otm;
|
||||||
UINT success = GetOutlineTextMetrics(fDDC, sizeof(otm), &otm);
|
UINT success = GetOutlineTextMetrics(fDDC, sizeof(otm), &otm);
|
||||||
if (0 == success) {
|
if (0 == success) {
|
||||||
@ -885,7 +885,7 @@ void SkScalerContext_GDI::generateMetrics(SkGlyph* glyph) {
|
|||||||
glyph->fAdvanceX = (float)((int)gm.gmCellIncX);
|
glyph->fAdvanceX = (float)((int)gm.gmCellIncX);
|
||||||
glyph->fAdvanceY = (float)((int)gm.gmCellIncY);
|
glyph->fAdvanceY = (float)((int)gm.gmCellIncY);
|
||||||
|
|
||||||
if (this->isSubpixel()) {
|
if ((fTM.tmPitchAndFamily & TMPF_VECTOR) && this->isLinearMetrics()) {
|
||||||
sk_bzero(&gm, sizeof(gm));
|
sk_bzero(&gm, sizeof(gm));
|
||||||
status = GetGlyphOutlineW(fDDC, glyphId, GGO_METRICS | GGO_GLYPH_INDEX, &gm, 0, nullptr, &fHighResMat22);
|
status = GetGlyphOutlineW(fDDC, glyphId, GGO_METRICS | GGO_GLYPH_INDEX, &gm, 0, nullptr, &fHighResMat22);
|
||||||
if (GDI_ERROR != status) {
|
if (GDI_ERROR != status) {
|
||||||
|
@ -358,7 +358,7 @@ SkScalerContext_DW::SkScalerContext_DW(sk_sp<DWriteFontTypeface> typefaceRef,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->isSubpixel()) {
|
if (this->isLinearMetrics()) {
|
||||||
fTextSizeMeasure = realTextSize;
|
fTextSizeMeasure = realTextSize;
|
||||||
fMeasuringMode = DWRITE_MEASURING_MODE_NATURAL;
|
fMeasuringMode = DWRITE_MEASURING_MODE_NATURAL;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user