| author | Jonathan Kew <jkew@mozilla.com> |
| Tue, 17 Dec 2019 15:51:57 +0000 | |
| changeset 507408 | f2d54eefdb444abf8a5dc66a8eafec16ba8c59fc |
| parent 507407 | ecccb4f29be8ae8b92c19aff9941c9346e2c2c22 |
| child 507409 | b4cc65a4d11e4569ea64670d24e38ef6c88a075e |
| push id | 36927 |
| push user | aiakab@mozilla.com |
| push date | Wed, 18 Dec 2019 00:51:03 +0000 |
| treeherder | mozilla-central@35af0b925215 [default view] [failures only] |
| perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
| reviewers | lsalzman |
| bugs | 1600470 |
| milestone | 73.0a1 |
| first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
| last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/gfx/skia/generate_mozbuild.py +++ b/gfx/skia/generate_mozbuild.py @@ -67,16 +67,20 @@ elif CONFIG['CPU_ARCH'] == 'aarch64' and DEFINES['SKIA_IMPLEMENTATION'] = 1 if CONFIG['MOZ_ENABLE_SKIA_PDF_SFNTLY']: DEFINES['SK_PDF_USE_SFNTLY'] = 1 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', '-Wno-overloaded-virtual', '-Wno-shadow', '-Wno-sign-compare', '-Wno-unreachable-code', '-Wno-unused-function',
--- a/gfx/skia/skia/src/ports/SkFontHost_cairo.cpp +++ b/gfx/skia/skia/src/ports/SkFontHost_cairo.cpp @@ -53,39 +53,38 @@ typedef enum FT_LcdFilter_ #endif #ifndef SK_FONTHOST_CAIRO_STANDALONE #define SK_FONTHOST_CAIRO_STANDALONE 1 #endif static bool gFontHintingEnabled = true; static FT_Error (*gSetLcdFilter)(FT_Library, FT_LcdFilter) = nullptr; -static void (*gGlyphSlotEmbolden)(FT_GlyphSlot) = nullptr; extern "C" { void mozilla_LockFTLibrary(FT_Library aLibrary); void mozilla_UnlockFTLibrary(FT_Library aLibrary); void mozilla_AddRefSharedFTFace(void* aContext); void mozilla_ReleaseSharedFTFace(void* aContext, void* aOwner); void mozilla_ForgetSharedFTFaceLockOwner(void* aContext, void* aOwner); 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); + // Implemented in webrender: + void mozilla_glyphslot_embolden_less(FT_GlyphSlot slot); } 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. if (gSetLcdFilter && gSetLcdFilter(nullptr, FT_LCD_FILTER_NONE) == FT_Err_Unimplemented_Feature) { gSetLcdFilter = nullptr; } } @@ -481,19 +480,19 @@ unsigned SkScalerContext_CairoFT::genera bool SkScalerContext_CairoFT::generateAdvance(SkGlyph* glyph) { generateMetrics(glyph); return !glyph->isEmpty(); } 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); } } void SkScalerContext_CairoFT::generateMetrics(SkGlyph* glyph) { glyph->fMaskFormat = fRec.fMaskFormat; glyph->zeroMetrics();
--- a/gfx/thebes/gfxFT2FontBase.cpp +++ b/gfx/thebes/gfxFT2FontBase.cpp @@ -495,16 +495,27 @@ bool gfxFT2FontBase::ShouldRoundXOffset( gfx_text_subpixel_position_force_enabled_AtStartup())); } FT_Vector gfxFT2FontBase::GetEmboldenStrength(FT_Face aFace) { FT_Vector strength = {0, 0}; if (!mEmbolden) { return strength; } + + // If it's an outline glyph, we'll be using mozilla_glyphslot_embolden_less + // (see gfx/wr/webrender/src/platform/unix/font.rs), so we need to match its + // emboldening 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; strength.y = strength.x; if (aFace->glyph->format == FT_GLYPH_FORMAT_BITMAP) { strength.x &= -64; if (!strength.x) { strength.x = 64;
--- a/gfx/wr/webrender/src/platform/unix/font.rs +++ b/gfx/wr/webrender/src/platform/unix/font.rs @@ -8,17 +8,17 @@ use api::{FontInstanceFlags, FontVariati use freetype::freetype::{FT_BBox, FT_Outline_Translate, FT_Pixel_Mode, FT_Render_Mode}; use freetype::freetype::{FT_Done_Face, FT_Error, FT_Get_Char_Index, FT_Int32}; use freetype::freetype::{FT_Done_FreeType, FT_Library_SetLcdFilter, FT_Pos}; use freetype::freetype::{FT_F26Dot6, FT_Face, FT_Glyph_Format, FT_Long, FT_UInt}; use freetype::freetype::{FT_GlyphSlot, FT_LcdFilter, FT_New_Face, FT_New_Memory_Face}; use freetype::freetype::{FT_Init_FreeType, FT_Load_Glyph, FT_Render_Glyph}; use freetype::freetype::{FT_Library, FT_Outline_Get_CBox, FT_Set_Char_Size, FT_Select_Size}; use freetype::freetype::{FT_Fixed, FT_Matrix, FT_Set_Transform, FT_String, FT_ULong}; -use freetype::freetype::{FT_Err_Unimplemented_Feature}; +use freetype::freetype::{FT_Err_Unimplemented_Feature, FT_MulFix, FT_Outline_Embolden}; use freetype::freetype::{FT_LOAD_COLOR, FT_LOAD_DEFAULT, FT_LOAD_FORCE_AUTOHINT}; use freetype::freetype::{FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH, FT_LOAD_NO_AUTOHINT}; use freetype::freetype::{FT_LOAD_NO_BITMAP, FT_LOAD_NO_HINTING}; use freetype::freetype::{FT_FACE_FLAG_SCALABLE, FT_FACE_FLAG_FIXED_SIZES}; use freetype::freetype::{FT_FACE_FLAG_MULTIPLE_MASTERS}; use freetype::succeeded; use crate::glyph_rasterizer::{FontInstance, GlyphFormat, GlyphKey}; use crate::glyph_rasterizer::{GlyphRasterError, GlyphRasterResult, RasterizedGlyph}; @@ -104,16 +104,56 @@ macro_rules! ft_dyn_fn { ft_dyn_fn!(FT_Get_MM_Var(face: FT_Face, desc: *mut *mut FT_MM_Var) -> FT_Error); 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); } +// Custom version of FT_GlyphSlot_Embolden to be less aggressive with outline +// fonts than the default implementation in FreeType. +#[no_mangle] +pub extern "C" fn mozilla_glyphslot_embolden_less(slot: FT_GlyphSlot) { + if slot.is_null() { + return; + } + + let slot_ = unsafe { &mut *slot }; + let format = slot_.format; + if format != FT_Glyph_Format::FT_GLYPH_FORMAT_OUTLINE { + // For non-outline glyphs, just fall back to FreeType's function. + unsafe { FT_GlyphSlot_Embolden(slot) }; + return; + } + + let face_ = unsafe { *slot_.face }; + + // FT_GlyphSlot_Embolden uses a divisor of 24 here; we'll be only half as + // bold. + let size_ = unsafe { *face_.size }; + let strength = + unsafe { FT_MulFix(face_.units_per_EM as FT_Long, + size_.metrics.y_scale) / 48 }; + unsafe { FT_Outline_Embolden(&mut slot_.outline, strength) }; + + // Adjust metrics to suit the fattened glyph. + if slot_.advance.x != 0 { + slot_.advance.x += strength; + } + if slot_.advance.y != 0 { + slot_.advance.y += strength; + } + slot_.metrics.width += strength; + slot_.metrics.height += strength; + slot_.metrics.horiAdvance += strength; + slot_.metrics.vertAdvance += strength; + slot_.metrics.horiBearingY += strength; +} + enum FontFile { Pathname(CString), Data(Arc<Vec<u8>>), } struct FontFace { // Raw byte data has to live until the font is deleted, according to // https://www.freetype.org/freetype2/docs/reference/ft2-base_interface.html#FT_New_Memory_Face @@ -490,17 +530,17 @@ impl FontContext { ); return None; } let slot = unsafe { (*face).glyph }; assert!(slot != ptr::null_mut()); if font.flags.contains(FontInstanceFlags::SYNTHETIC_BOLD) { - unsafe { FT_GlyphSlot_Embolden(slot) }; + mozilla_glyphslot_embolden_less(slot); } let format = unsafe { (*slot).format }; match format { FT_Glyph_Format::FT_GLYPH_FORMAT_BITMAP => { let y_size = unsafe { (*(*(*slot).face).size).metrics.y_ppem }; Some((slot, req_size as f32 / y_size as f32)) }
--- a/layout/reftests/css-break/reftest.list +++ b/layout/reftests/css-break/reftest.list @@ -1,11 +1,11 @@ == 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 fuzzy-if(!Android,0-1,0-62) fuzzy-if(Android,0-8,0-6627) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == box-decoration-break-first-letter.html box-decoration-break-first-letter-ref.html #Bug 1313773 # Bug 1392106 == box-decoration-break-with-bidi.html box-decoration-break-with-bidi-ref.html random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == box-decoration-break-bug-1235152.html box-decoration-break-bug-1235152-ref.html # Bug 1392106 random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == box-decoration-break-bug-1249913.html box-decoration-break-bug-1249913-ref.html # Bug 1392106 == vertical-wm-001.html vertical-wm-001-ref.html
--- a/layout/reftests/text/synthetic-bold-metrics-01-notref.html +++ b/layout/reftests/text/synthetic-bold-metrics-01-notref.html @@ -3,17 +3,17 @@ <head> <style type="text/css"> @font-face { font-family: dejavu; src: url(../fonts/dejavu-sans/DejaVuSans.ttf); } p { - font-family: dejavu; /* family with only a single weight */ + font: 32px dejavu; /* family with only a single weight */ } .test { color: white; /* hide the text, we're only comparing metrics */ } </style> </head> <body>
--- a/layout/reftests/text/synthetic-bold-metrics-01.html +++ b/layout/reftests/text/synthetic-bold-metrics-01.html @@ -3,17 +3,17 @@ <head> <style type="text/css"> @font-face { font-family: dejavu; src: url(../fonts/dejavu-sans/DejaVuSans.ttf); } p { - font-family: dejavu; /* family with only a single weight */ + font: 32px dejavu; /* family with only a single weight */ } .test { color: white; /* hide the text, we're only comparing metrics */ font-weight: bold; /* synthetic bold will be used */ } </style> </head>