diff --git a/gfx/tests/fuzz/TestCOLRv1.cpp b/gfx/tests/fuzz/TestCOLRv1.cpp index 4e44778586b2..7fad4b9d228f 100644 --- a/gfx/tests/fuzz/TestCOLRv1.cpp +++ b/gfx/tests/fuzz/TestCOLRv1.cpp @@ -43,7 +43,7 @@ static int FuzzingRunCOLRv1(const uint8_t* data, size_t size) { Float f2p = kPixelSize / hb_face_get_upem(hb_data_face); auto colorPalette = - MakeUnique>(COLRFonts::CreateColorPalette( + MakeUnique>(COLRFonts::CreateColorPalette( hb_data_face, nullptr, nullptr, "dummy"_ns)); for (unsigned i = 0; i <= glyph_count; ++i) { diff --git a/gfx/thebes/COLRFonts.cpp b/gfx/thebes/COLRFonts.cpp index f17d6a8b1568..a43c86346d19 100644 --- a/gfx/thebes/COLRFonts.cpp +++ b/gfx/thebes/COLRFonts.cpp @@ -11,7 +11,6 @@ #include "gfxFontUtils.h" #include "gfxUtils.h" #include "harfbuzz/hb-ot.h" -#include "harfbuzz/hb.h" #include "mozilla/ScopeExit.h" #include "mozilla/StaticPrefs_gfx.h" #include "mozilla/gfx/Helpers.h" @@ -147,7 +146,7 @@ struct PaintState { const COLRHeader* v0; const COLRv1Header* v1; } mHeader; - const sRGBColor* mPalette; + const hb_color_t* mPalette; DrawTarget* mDrawTarget; ScaledFont* mScaledFont; const int* mCoords; @@ -177,7 +176,11 @@ constexpr uint32_t kPaintRecursionLimit = 256; DeviceColor PaintState::GetColor(uint16_t aPaletteIndex, float aAlpha) const { sRGBColor color; if (aPaletteIndex < mNumColors) { - color = mPalette[uint16_t(aPaletteIndex)]; + hb_color_t c = mPalette[uint16_t(aPaletteIndex)]; + // Explicitly get the components from the hb_color_t, rather than assuming + // anything about its packing. + color = sRGBColor::FromU8(hb_color_get_red(c), hb_color_get_green(c), + hb_color_get_blue(c), hb_color_get_alpha(c)); } else if (aPaletteIndex == 0xffff) { color = mCurrentColor; } else { // Palette index out of range! Return transparent black. @@ -2464,7 +2467,7 @@ bool COLRFonts::PaintGlyphLayers( hb_blob_t* aCOLR, hb_face_t* aFace, const GlyphLayers* aLayers, DrawTarget* aDrawTarget, layout::TextDrawTarget* aTextDrawer, ScaledFont* aScaledFont, DrawOptions aDrawOptions, const Point& aPoint, - const sRGBColor& aCurrentColor, const nsTArray* aColors) { + const sRGBColor& aCurrentColor, const nsTArray* aColors) { const auto* glyphRecord = reinterpret_cast(aLayers); // Default to opaque rendering (non-webrender applies alpha with a layer) float alpha = 1.0; @@ -2530,7 +2533,7 @@ bool COLRFonts::PaintGlyphGraph( hb_blob_t* aCOLR, hb_font_t* aFont, const GlyphPaintGraph* aPaintGraph, DrawTarget* aDrawTarget, layout::TextDrawTarget* aTextDrawer, ScaledFont* aScaledFont, DrawOptions aDrawOptions, const Point& aPoint, - const sRGBColor& aCurrentColor, const nsTArray* aColors, + const sRGBColor& aCurrentColor, const nsTArray* aColors, uint32_t aGlyphId, float aFontUnitsToPixels) { if (aTextDrawer) { // Currently we always punt to a blob for COLRv1 glyphs. @@ -2612,7 +2615,7 @@ uint16_t COLRFonts::GetColrTableVersion(hb_blob_t* aCOLR) { return colr->version; } -nsTArray COLRFonts::CreateColorPalette( +nsTArray COLRFonts::CreateColorPalette( hb_face_t* aFace, const FontPaletteValueSet* aPaletteValueSet, nsAtom* aFontPalette, const nsACString& aFamilyName) { // Find the base color palette to use, if there are multiple available; @@ -2659,27 +2662,24 @@ nsTArray COLRFonts::CreateColorPalette( } } - // Collect the palette colors and convert them to sRGBColor values. + // Collect the palette colors. count = hb_ot_color_palette_get_colors(aFace, paletteIndex, 0, nullptr, nullptr); - nsTArray colors; - colors.SetLength(count); + nsTArray palette; + palette.SetLength(count); hb_ot_color_palette_get_colors(aFace, paletteIndex, 0, &count, - colors.Elements()); - - nsTArray palette; - palette.SetCapacity(count); - for (const auto c : colors) { - palette.AppendElement( - sRGBColor(hb_color_get_red(c) / 255.0, hb_color_get_green(c) / 255.0, - hb_color_get_blue(c) / 255.0, hb_color_get_alpha(c) / 255.0)); - } + palette.Elements()); // Apply @font-palette-values overrides, if present. if (fpv) { for (const auto overrideColor : fpv->mOverrides) { if (overrideColor.mIndex < palette.Length()) { - palette[overrideColor.mIndex] = overrideColor.mColor; + // Override colors contain nscolor, but the palette uses hb_color_t. + // They have different byte packing orders, so we have to explicitly + // map the components, not just assign as a 32-bit value. + nscolor c = overrideColor.mColor; + palette[overrideColor.mIndex] = + HB_COLOR(NS_GET_B(c), NS_GET_G(c), NS_GET_R(c), NS_GET_A(c)); } } } diff --git a/gfx/thebes/COLRFonts.h b/gfx/thebes/COLRFonts.h index aeecb081da3e..580bc6e9e618 100644 --- a/gfx/thebes/COLRFonts.h +++ b/gfx/thebes/COLRFonts.h @@ -5,15 +5,13 @@ #ifndef COLR_FONTS_H #define COLR_FONTS_H +#include "harfbuzz/hb.h" #include "mozilla/gfx/2D.h" #include "nsAtom.h" +#include "nsColor.h" #include "nsTArray.h" #include "nsTHashtable.h" -struct hb_blob_t; -struct hb_face_t; -struct hb_font_t; - namespace mozilla { namespace layout { @@ -28,7 +26,7 @@ class FontPaletteValueSet { struct OverrideColor { uint32_t mIndex = 0; - sRGBColor mColor; + nscolor mColor; }; struct PaletteValues { @@ -100,7 +98,7 @@ class COLRFonts { hb_blob_t* aCOLR, hb_face_t* aFace, const GlyphLayers* aLayers, DrawTarget* aDrawTarget, layout::TextDrawTarget* aTextDrawer, ScaledFont* aScaledFont, DrawOptions aDrawOptions, const Point& aPoint, - const sRGBColor& aCurrentColor, const nsTArray* aColors); + const sRGBColor& aCurrentColor, const nsTArray* aColors); // COLRv1 support: color glyph is represented by a directed acyclic graph of // paint records. @@ -114,7 +112,7 @@ class COLRFonts { hb_blob_t* aCOLR, hb_font_t* aFont, const GlyphPaintGraph* aPaintGraph, DrawTarget* aDrawTarget, layout::TextDrawTarget* aTextDrawer, ScaledFont* aScaledFont, DrawOptions aDrawOptions, const Point& aPoint, - const sRGBColor& aCurrentColor, const nsTArray* aColors, + const sRGBColor& aCurrentColor, const nsTArray* aColors, uint32_t aGlyphId, float aFontUnitsToPixels); static Rect GetColorGlyphBounds(hb_blob_t* aCOLR, hb_font_t* aFont, @@ -124,7 +122,7 @@ class COLRFonts { static uint16_t GetColrTableVersion(hb_blob_t* aCOLR); - static nsTArray CreateColorPalette( + static nsTArray CreateColorPalette( hb_face_t* aFace, const FontPaletteValueSet* aPaletteValueSet, nsAtom* aFontPalette, const nsACString& aFamilyName); }; diff --git a/gfx/thebes/FontPaletteCache.h b/gfx/thebes/FontPaletteCache.h index 816119227ea9..3e477b9158b4 100644 --- a/gfx/thebes/FontPaletteCache.h +++ b/gfx/thebes/FontPaletteCache.h @@ -7,6 +7,7 @@ #include +#include "harfbuzz/hb.h" #include "mozilla/HashFunctions.h" #include "mozilla/MruCache.h" #include "mozilla/RefPtr.h" @@ -26,15 +27,15 @@ class FontPalette { public: FontPalette() = default; - explicit FontPalette(nsTArray&& aColors) + explicit FontPalette(nsTArray&& aColors) : mColors(std::move(aColors)) {} - const nsTArray* Colors() const { return &mColors; } + const nsTArray* Colors() const { return &mColors; } private: ~FontPalette() = default; - nsTArray mColors; + nsTArray mColors; }; // MRU cache used for resolved color-font palettes, to avoid reconstructing diff --git a/layout/style/GeckoBindings.cpp b/layout/style/GeckoBindings.cpp index e78e60f5f289..ca5a323d4ca2 100644 --- a/layout/style/GeckoBindings.cpp +++ b/layout/style/GeckoBindings.cpp @@ -1030,7 +1030,7 @@ void Gecko_SetFontPaletteOverride( return; } aValues->mOverrides.AppendElement(gfx::FontPaletteValueSet::OverrideColor{ - uint32_t(aIndex), gfx::sRGBColor::FromABGR(aColor->ToColor())}); + uint32_t(aIndex), aColor->ToColor()}); } void Gecko_EnsureImageLayersLength(nsStyleImageLayers* aLayers, size_t aLen,