Bug 1600470 - Reduce the emboldening strength used for synthetic-bold faces with FreeType. r=lsalzman

Differential Revision: https://phabricator.services.mozilla.com/D57246

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Jonathan Kew 2019-12-16 14:40:21 +00:00
parent 23e9c6d856
commit 863bbe2172
8 changed files with 59 additions and 11 deletions

View File

@ -65,6 +65,8 @@
#ifdef MOZ_ENABLE_FREETYPE
# include "ft2build.h"
# include FT_FREETYPE_H
# include FT_OUTLINE_H
# include FT_SYNTHESIS_H
#endif
#include "MainThreadUtils.h"
#include "mozilla/Preferences.h"
@ -195,6 +197,40 @@ void mozilla_LockFTLibrary(FT_Library aFTLibrary) {
void mozilla_UnlockFTLibrary(FT_Library aFTLibrary) {
mozilla::gfx::Factory::UnlockFTLibrary(aFTLibrary);
}
// Custom version of FT_GlyphSlot_Embolden to be less aggressive with outline
// fonts than the default implementation in FreeType.
void mozilla_GlyphSlot_Embolden_Less(FT_GlyphSlot slot) {
if (!slot) {
return;
}
if (slot->format != FT_GLYPH_FORMAT_OUTLINE) {
// For non-outline glyphs, just fall back to FreeType's function.
FT_GlyphSlot_Embolden(slot);
return;
}
FT_Face face = slot->face;
// FT_GlyphSlot_Embolden uses a divisor of 24 here; we'll be only half as
// bold.
FT_Pos strength =
FT_MulFix(face->units_per_EM, face->size->metrics.y_scale) / 48;
FT_Outline_Embolden(&slot->outline, strength);
// Adjust metrics to suit the fattened glyph.
if (slot->advance.x) {
slot->advance.x += strength;
}
if (slot->advance.y) {
slot->advance.y += strength;
}
slot->metrics.width += strength;
slot->metrics.height += strength;
slot->metrics.horiAdvance += strength;
slot->metrics.vertAdvance += strength;
slot->metrics.horiBearingY += strength;
}
}
#endif

View File

@ -72,6 +72,10 @@ if CONFIG['MOZ_ENABLE_SKIA_PDF_SFNTLY']:
if CONFIG['MOZ_TREE_FREETYPE']:
DEFINES['SK_CAN_USE_DLOPEN'] = 0
# Reduce strength of synthetic-emboldening used in the freetype backend
# (see bug 1600470).
DEFINES['SK_OUTLINE_EMBOLDEN_DIVISOR'] = 48
# Suppress warnings in third-party code.
CXXFLAGS += [
'-Wno-deprecated-declarations',

View File

@ -58,7 +58,6 @@ typedef enum FT_LcdFilter_
static bool gFontHintingEnabled = true;
static FT_Error (*gSetLcdFilter)(FT_Library, FT_LcdFilter) = nullptr;
static void (*gGlyphSlotEmbolden)(FT_GlyphSlot) = nullptr;
extern "C"
{
@ -70,6 +69,7 @@ extern "C"
int mozilla_LockSharedFTFace(void* aContext, void* aOwner);
void mozilla_UnlockSharedFTFace(void* aContext);
FT_Error mozilla_LoadFTGlyph(FT_Face aFace, uint32_t aGlyphIndex, int32_t aFlags);
void mozilla_GlyphSlot_Embolden_Less(FT_GlyphSlot slot);
}
void SkInitCairoFT(bool fontHintingEnabled)
@ -77,10 +77,8 @@ void SkInitCairoFT(bool fontHintingEnabled)
gFontHintingEnabled = fontHintingEnabled;
#if SK_CAN_USE_DLOPEN
gSetLcdFilter = (FT_Error (*)(FT_Library, FT_LcdFilter))dlsym(RTLD_DEFAULT, "FT_Library_SetLcdFilter");
gGlyphSlotEmbolden = (void (*)(FT_GlyphSlot))dlsym(RTLD_DEFAULT, "FT_GlyphSlot_Embolden");
#else
gSetLcdFilter = &FT_Library_SetLcdFilter;
gGlyphSlotEmbolden = &FT_GlyphSlot_Embolden;
#endif
// FT_Library_SetLcdFilter may be provided but have no effect if FreeType
// is built without FT_CONFIG_OPTION_SUBPIXEL_RENDERING.
@ -486,9 +484,9 @@ bool SkScalerContext_CairoFT::generateAdvance(SkGlyph* glyph)
void SkScalerContext_CairoFT::prepareGlyph(FT_GlyphSlot glyph)
{
if (fRec.fFlags & SkScalerContext::kEmbolden_Flag &&
gGlyphSlotEmbolden) {
gGlyphSlotEmbolden(glyph);
if (fRec.fFlags & SkScalerContext::kEmbolden_Flag) {
// Not FT_GlyphSlot_Embolden because we want a less extreme effect.
mozilla_GlyphSlot_Embolden_Less(glyph);
}
}

View File

@ -500,6 +500,16 @@ FT_Vector gfxFT2FontBase::GetEmboldenStrength(FT_Face aFace) {
if (!mEmbolden) {
return strength;
}
// If it's an outline glyph, we'll be using GlyphSlot_Embolden_Less,
// so we need to match its strength here.
if (aFace->glyph->format == FT_GLYPH_FORMAT_OUTLINE) {
strength.x =
FT_MulFix(aFace->units_per_EM, aFace->size->metrics.y_scale) / 48;
strength.y = strength.x;
return strength;
}
// This is the embolden "strength" used by FT_GlyphSlot_Embolden.
strength.x =
FT_MulFix(aFace->units_per_EM, aFace->size->metrics.y_scale) / 24;

View File

@ -106,7 +106,7 @@ ft_dyn_fn!(FT_Done_MM_Var(library: FT_Library, desc: *mut FT_MM_Var) -> FT_Error
ft_dyn_fn!(FT_Set_Var_Design_Coordinates(face: FT_Face, num_vals: FT_UInt, vals: *mut FT_Fixed) -> FT_Error);
extern "C" {
fn FT_GlyphSlot_Embolden(slot: FT_GlyphSlot);
fn mozilla_GlyphSlot_Embolden_Less(slot: FT_GlyphSlot);
}
enum FontFile {
@ -495,7 +495,7 @@ impl FontContext {
assert!(slot != ptr::null_mut());
if font.flags.contains(FontInstanceFlags::SYNTHETIC_BOLD) {
unsafe { FT_GlyphSlot_Embolden(slot) };
unsafe { mozilla_GlyphSlot_Embolden_Less(slot) };
}
let format = unsafe { (*slot).format };

View File

@ -1,6 +1,6 @@
== box-decoration-break-1.html box-decoration-break-1-ref.html
fuzzy(0-1,0-20) fuzzy-if(skiaContent,0-1,0-700) == box-decoration-break-with-inset-box-shadow-1.html box-decoration-break-with-inset-box-shadow-1-ref.html
skip-if(verify) fuzzy(0-45,0-460) fuzzy-if(skiaContent,0-57,0-439) fuzzy-if(Android,0-57,0-1330) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == box-decoration-break-with-outset-box-shadow-1.html box-decoration-break-with-outset-box-shadow-1-ref.html # Bug 1386543, bug 1392106
skip-if(verify) fuzzy(0-45,0-460) fuzzy-if(skiaContent,0-57,0-439) fuzzy-if(Android,0-70,0-1330) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == box-decoration-break-with-outset-box-shadow-1.html box-decoration-break-with-outset-box-shadow-1-ref.html # Bug 1386543, bug 1392106
random-if(!gtkWidget||webrender) == box-decoration-break-border-image.html box-decoration-break-border-image-ref.html
== box-decoration-break-block-border-padding.html box-decoration-break-block-border-padding-ref.html
== box-decoration-break-block-margin.html box-decoration-break-block-margin-ref.html

View File

@ -8,7 +8,7 @@
}
p {
font-family: dejavu; /* family with only a single weight */
font: 32px dejavu; /* family with only a single weight */
}
.test {

View File

@ -8,7 +8,7 @@
}
p {
font-family: dejavu; /* family with only a single weight */
font: 32px dejavu; /* family with only a single weight */
}
.test {