tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit c9704533beb0bcf71ab2ce7cae798cc954632a4f
parent a63a6f3c84a4b0c0eef59caf83bff5034de1a798
Author: Lee Salzman <lsalzman@mozilla.com>
Date:   Wed, 22 Oct 2025 19:16:53 +0000

Bug 1995837 - Fix Moz2D for Skia m142 update. r=aosmond

This mainly fixes the fact that Skia no longer easily supports
changing subpixel geometry for individual typefaces.

Instead, we change to setting the subpixel order for individual
Skia canvases/devices, We need to detect at font list initialization
time the subpixel order from Fontconfig and report it to Moz2D.

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

Diffstat:
Mdom/canvas/DrawTargetWebgl.cpp | 2+-
Mgfx/2d/2D.h | 6+++---
Mgfx/2d/DWriteSettings.cpp | 4+++-
Mgfx/2d/DrawTargetSkia.cpp | 23++++++++++++++++++-----
Mgfx/2d/Factory.cpp | 8+++++---
Mgfx/2d/HelpersSkia.h | 2+-
Mgfx/2d/ScaledFontBase.cpp | 2+-
Mgfx/2d/ScaledFontDWrite.cpp | 2+-
Mgfx/2d/ScaledFontFontconfig.cpp | 9+--------
Mgfx/2d/Types.h | 8++++++++
Mgfx/thebes/gfxFcPlatformFontList.cpp | 25+++++++++++++++++++++++++
11 files changed, 67 insertions(+), 24 deletions(-)

diff --git a/dom/canvas/DrawTargetWebgl.cpp b/dom/canvas/DrawTargetWebgl.cpp @@ -5498,7 +5498,7 @@ void DrawTargetWebgl::Stroke(const Path* aPath, const Pattern& aPattern, bool allowStrokeAlpha = false; if (numVerbs >= 2 && numVerbs <= 3) { uint8_t verbs[3]; - skiaPath.getVerbs(verbs, numVerbs); + skiaPath.getVerbs({verbs, numVerbs}); if (verbs[0] == SkPath::kMove_Verb && verbs[1] == SkPath::kLine_Verb && (numVerbs < 3 || verbs[2] == SkPath::kClose_Verb)) { bool closed = numVerbs >= 3; diff --git a/gfx/2d/2D.h b/gfx/2d/2D.h @@ -2317,11 +2317,11 @@ class GFX2D_API Factory { static bool DoesBackendSupportDataDrawtarget(BackendType aType); - static void SetBGRSubpixelOrder(bool aBGR); - static bool GetBGRSubpixelOrder(); + static void SetSubpixelOrder(SubpixelOrder aOrder); + static SubpixelOrder GetSubpixelOrder(); private: - static bool mBGRSubpixelOrder; + static SubpixelOrder mSubpixelOrder; public: static already_AddRefed<DrawTarget> CreateDrawTargetWithSkCanvas( diff --git a/gfx/2d/DWriteSettings.cpp b/gfx/2d/DWriteSettings.cpp @@ -68,7 +68,9 @@ static void GDIGammaVarUpdated() { static void UpdatePixelGeometry() { sPixelGeometry = static_cast<DWRITE_PIXEL_GEOMETRY>(gfxVars::SystemTextPixelGeometry()); - Factory::SetBGRSubpixelOrder(sPixelGeometry == DWRITE_PIXEL_GEOMETRY_BGR); + Factory::SetSubpixelOrder(sPixelGeometry == DWRITE_PIXEL_GEOMETRY_BGR + ? SubpixelOrder::BGR + : SubpixelOrder::RGB); } static void PixelGeometryVarUpdated() { UpdatePixelGeometry(); diff --git a/gfx/2d/DrawTargetSkia.cpp b/gfx/2d/DrawTargetSkia.cpp @@ -420,7 +420,7 @@ static sk_sp<SkImage> ExtractSubset(sk_sp<SkImage> aImage, return SkImages::RasterFromPixmap(subsetPixmap, ReleaseImage, aImage.release()); } - return aImage->makeSubset(nullptr, subsetRect); + return aImage->makeSubset(nullptr, subsetRect, SkImage::RequiredProperties()); } static void FreeAlphaPixels(void* aBuf, void*) { sk_free(aBuf); } @@ -1329,7 +1329,10 @@ class GlyphMaskShader : public SkEmptyShader { } bool isOpaque() const override { return true; } - bool isConstant() const override { return true; } + bool isConstant(SkColor4f* color) const override { + if (color) *color = SkColor4f{1, 1, 1, 1}; + return true; + } void flatten(SkWriteBuffer& buffer) const override { buffer.writeColor4f(mColor); @@ -1412,7 +1415,8 @@ Maybe<Rect> DrawTargetSkia::GetGlyphLocalBounds( for (uint32_t i = 0; i < batchSize; i++) { glyphs[i] = aBuffer.mGlyphs[offset + i].mIndex; } - font.getBounds(glyphs.begin(), batchSize, rects.begin(), nullptr); + font.getBounds({glyphs.begin(), batchSize}, {rects.begin(), batchSize}, + nullptr); for (uint32_t i = 0; i < batchSize; i++) { bounds = bounds.Union(SkRectToRect(rects[i]) + aBuffer.mGlyphs[offset + i].mPosition); @@ -1778,8 +1782,17 @@ void DrawTargetSkia::CopySurface(SourceSurface* aSurface, } static inline SkPixelGeometry GetSkPixelGeometry() { - return Factory::GetBGRSubpixelOrder() ? kBGR_H_SkPixelGeometry - : kRGB_H_SkPixelGeometry; + switch (Factory::GetSubpixelOrder()) { + case SubpixelOrder::BGR: + return kBGR_H_SkPixelGeometry; + case SubpixelOrder::VBGR: + return kBGR_V_SkPixelGeometry; + case SubpixelOrder::VRGB: + return kRGB_V_SkPixelGeometry; + case SubpixelOrder::RGB: + default: + return kRGB_H_SkPixelGeometry; + } } template <typename T> diff --git a/gfx/2d/Factory.cpp b/gfx/2d/Factory.cpp @@ -240,7 +240,7 @@ StaticMutex Factory::mDeviceLock; StaticMutex Factory::mDTDependencyLock; #endif -bool Factory::mBGRSubpixelOrder = false; +SubpixelOrder Factory::mSubpixelOrder = SubpixelOrder::UNKNOWN; mozilla::gfx::Config* Factory::sConfig = nullptr; @@ -627,9 +627,11 @@ already_AddRefed<ScaledFont> Factory::CreateScaledFontForFreeTypeFont( } #endif -void Factory::SetBGRSubpixelOrder(bool aBGR) { mBGRSubpixelOrder = aBGR; } +void Factory::SetSubpixelOrder(SubpixelOrder aOrder) { + mSubpixelOrder = aOrder; +} -bool Factory::GetBGRSubpixelOrder() { return mBGRSubpixelOrder; } +SubpixelOrder Factory::GetSubpixelOrder() { return mSubpixelOrder; } #ifdef MOZ_ENABLE_FREETYPE SharedFTFace::SharedFTFace(FT_Face aFace, SharedFTFaceData* aData) diff --git a/gfx/2d/HelpersSkia.h b/gfx/2d/HelpersSkia.h @@ -153,7 +153,7 @@ static inline bool StrokeOptionsToPaint(SkPaint& aPaint, SkFloatToScalar(aOptions.mDashPattern[i % aOptions.mDashLength]); } - auto dash = SkDashPathEffect::Make(&pattern.front(), dashCount, + auto dash = SkDashPathEffect::Make({&pattern.front(), dashCount}, SkFloatToScalar(aOptions.mDashOffset)); aPaint.setPathEffect(dash); } diff --git a/gfx/2d/ScaledFontBase.cpp b/gfx/2d/ScaledFontBase.cpp @@ -103,7 +103,7 @@ SkPath ScaledFontBase::GetSkiaPathForGlyphs(const GlyphBuffer& aBuffer) { } ctx = {aBuffer.mGlyphs}; font.getPaths( - indices.data(), indices.size(), + {indices.data(), indices.size()}, [](const SkPath* glyphPath, const SkMatrix& scaleMatrix, void* ctxPtr) { Context& ctx = *reinterpret_cast<Context*>(ctxPtr); if (glyphPath) { diff --git a/gfx/2d/ScaledFontDWrite.cpp b/gfx/2d/ScaledFontDWrite.cpp @@ -496,7 +496,7 @@ bool ScaledFontDWrite::GetWRFontInstanceOptions( default: break; } - if (Factory::GetBGRSubpixelOrder()) { + if (Factory::GetSubpixelOrder() == SubpixelOrder::BGR) { options.flags |= wr::FontInstanceFlags::SUBPIXEL_BGR; } options.synthetic_italics = diff --git a/gfx/2d/ScaledFontFontconfig.cpp b/gfx/2d/ScaledFontFontconfig.cpp @@ -48,14 +48,7 @@ bool ScaledFontFontconfig::UseSubpixelPosition() const { } SkTypeface* ScaledFontFontconfig::CreateSkTypeface() { - SkPixelGeometry geo = mInstanceData.mFlags & InstanceData::SUBPIXEL_BGR - ? (mInstanceData.mFlags & InstanceData::LCD_VERTICAL - ? kBGR_V_SkPixelGeometry - : kBGR_H_SkPixelGeometry) - : (mInstanceData.mFlags & InstanceData::LCD_VERTICAL - ? kRGB_V_SkPixelGeometry - : kRGB_H_SkPixelGeometry); - return SkCreateTypefaceFromCairoFTFont(mFace->GetFace(), mFace.get(), geo, + return SkCreateTypefaceFromCairoFTFont(mFace->GetFace(), mFace.get(), mInstanceData.mLcdFilter); } diff --git a/gfx/2d/Types.h b/gfx/2d/Types.h @@ -122,6 +122,14 @@ enum class SurfaceFormat : int8_t { OS_RGBX = X8R8G8B8_UINT32 }; +enum class SubpixelOrder : uint8_t { + UNKNOWN, + RGB, + BGR, + VRGB, + VBGR, +}; + struct SurfaceFormatInfo { bool hasColor; bool hasAlpha; diff --git a/gfx/thebes/gfxFcPlatformFontList.cpp b/gfx/thebes/gfxFcPlatformFontList.cpp @@ -2967,6 +2967,28 @@ void gfxFcPlatformFontList::ClearSystemFontOptions() { cairo_font_options_destroy(mSystemFontOptions); mSystemFontOptions = nullptr; } + Factory::SetSubpixelOrder(SubpixelOrder::UNKNOWN); +} + +static void SetSubpixelOrderFromCairo(const cairo_font_options_t* aOptions) { + SubpixelOrder subpixelOrder = SubpixelOrder::UNKNOWN; + switch (cairo_font_options_get_subpixel_order(aOptions)) { + case CAIRO_SUBPIXEL_ORDER_RGB: + subpixelOrder = SubpixelOrder::RGB; + break; + case CAIRO_SUBPIXEL_ORDER_BGR: + subpixelOrder = SubpixelOrder::BGR; + break; + case CAIRO_SUBPIXEL_ORDER_VRGB: + subpixelOrder = SubpixelOrder::VRGB; + break; + case CAIRO_SUBPIXEL_ORDER_VBGR: + subpixelOrder = SubpixelOrder::VBGR; + break; + default: + break; + } + Factory::SetSubpixelOrder(subpixelOrder); } bool gfxFcPlatformFontList::UpdateSystemFontOptions() { @@ -3004,6 +3026,8 @@ bool gfxFcPlatformFontList::UpdateSystemFontOptions() { return false; } + SetSubpixelOrderFromCairo(options); + ClearSystemFontOptions(); mSystemFontOptions = newOptions; return true; @@ -3035,6 +3059,7 @@ void gfxFcPlatformFontList::UpdateSystemFontOptionsFromIpc( cairo_font_options_set_subpixel_order( mSystemFontOptions, cairo_subpixel_order_t(aOptions.subpixelOrder())); mFreetypeLcdSetting = aOptions.lcdFilter(); + SetSubpixelOrderFromCairo(mSystemFontOptions); } void gfxFcPlatformFontList::SubstituteSystemFontOptions(FcPattern* aPattern) {