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:
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) {