mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-27 14:52:16 +00:00
Bug 1791780 - Support custom color font palettes in the COLR-font rendering code. r=gfx-reviewers,lsalzman
This creates the gfx support needed to use alternate palettes, though not yet connected to the CSS rules/properties to define and access them. Differential Revision: https://phabricator.services.mozilla.com/D157958
This commit is contained in:
parent
c2d6d7271f
commit
d811a2820d
@ -43,6 +43,9 @@ static int FuzzingRunCOLRv1(const uint8_t* data, size_t size) {
|
||||
RefPtr sf = new MockScaledFont(uf, hb_data_font);
|
||||
Float f2p = kPixelSize / hb_face_get_upem(hb_data_face);
|
||||
|
||||
UniquePtr<nsTArray<sRGBColor>> colorPalette =
|
||||
COLRFonts::SetupColorPalette(hb_data_face, nullptr, nullptr, "dummy"_ns);
|
||||
|
||||
for (unsigned i = 0; i <= glyph_count; ++i) {
|
||||
if (COLRFonts::GetColrTableVersion(colr) == 1) {
|
||||
Rect bounds =
|
||||
@ -51,15 +54,16 @@ static int FuzzingRunCOLRv1(const uint8_t* data, size_t size) {
|
||||
if (paintGraph) {
|
||||
dt->PushClipRect(bounds);
|
||||
COLRFonts::PaintGlyphGraph(colr, hb_data_font, paintGraph, dt, nullptr,
|
||||
sf, DrawOptions(), sRGBColor(), Point(), i,
|
||||
f2p);
|
||||
sf, DrawOptions(), Point(), sRGBColor(),
|
||||
colorPalette.get(), i, f2p);
|
||||
dt->PopClip();
|
||||
}
|
||||
}
|
||||
const auto* layers = COLRFonts::GetGlyphLayers(colr, i);
|
||||
if (layers) {
|
||||
COLRFonts::PaintGlyphLayers(colr, hb_data_face, layers, dt, nullptr, sf,
|
||||
DrawOptions(), sRGBColor(), Point());
|
||||
DrawOptions(), Point(), sRGBColor(),
|
||||
colorPalette.get());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -146,7 +146,7 @@ struct PaintState {
|
||||
const COLRHeader* v0;
|
||||
const COLRv1Header* v1;
|
||||
} mHeader;
|
||||
const hb_color_t* mPalette;
|
||||
const sRGBColor* mPalette;
|
||||
DrawTarget* mDrawTarget;
|
||||
ScaledFont* mScaledFont;
|
||||
const int* mCoords;
|
||||
@ -174,16 +174,13 @@ struct PaintState {
|
||||
DeviceColor PaintState::GetColor(uint16_t aPaletteIndex, float aAlpha) const {
|
||||
sRGBColor color;
|
||||
if (aPaletteIndex < mNumColors) {
|
||||
const hb_color_t& c = mPalette[uint16_t(aPaletteIndex)];
|
||||
color = 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 * aAlpha);
|
||||
color = mPalette[uint16_t(aPaletteIndex)];
|
||||
} else if (aPaletteIndex == 0xffff) {
|
||||
color = mCurrentColor;
|
||||
color.a *= aAlpha;
|
||||
} else { // Palette index out of range! Return transparent black.
|
||||
color = sRGBColor();
|
||||
}
|
||||
color.a *= aAlpha;
|
||||
return ToDeviceColor(color);
|
||||
}
|
||||
|
||||
@ -2380,8 +2377,8 @@ const COLRFonts::GlyphLayers* COLRFonts::GetGlyphLayers(hb_blob_t* aCOLR,
|
||||
bool COLRFonts::PaintGlyphLayers(
|
||||
hb_blob_t* aCOLR, hb_face_t* aFace, const GlyphLayers* aLayers,
|
||||
DrawTarget* aDrawTarget, layout::TextDrawTarget* aTextDrawer,
|
||||
ScaledFont* aScaledFont, DrawOptions aDrawOptions,
|
||||
const sRGBColor& aCurrentColor, const Point& aPoint) {
|
||||
ScaledFont* aScaledFont, DrawOptions aDrawOptions, const Point& aPoint,
|
||||
const sRGBColor& aCurrentColor, const nsTArray<sRGBColor>* aColors) {
|
||||
const auto* glyphRecord = reinterpret_cast<const BaseGlyphRecord*>(aLayers);
|
||||
// Default to opaque rendering (non-webrender applies alpha with a layer)
|
||||
float alpha = 1.0;
|
||||
@ -2406,19 +2403,11 @@ bool COLRFonts::PaintGlyphLayers(
|
||||
alpha = aCurrentColor.a;
|
||||
}
|
||||
|
||||
// Get the default palette (TODO: hook up CSS font-palette support)
|
||||
unsigned int colorCount = 0;
|
||||
AutoTArray<hb_color_t, 64> colors;
|
||||
colors.SetLength(hb_ot_color_palette_get_colors(aFace, /* paletteIndex */ 0,
|
||||
0, &colorCount, nullptr));
|
||||
colorCount = colors.Length();
|
||||
hb_ot_color_palette_get_colors(aFace, 0, 0, &colorCount, colors.Elements());
|
||||
|
||||
unsigned int length;
|
||||
const COLRHeader* colr =
|
||||
reinterpret_cast<const COLRHeader*>(hb_blob_get_data(aCOLR, &length));
|
||||
PaintState state{{colr},
|
||||
colors.Elements(),
|
||||
aColors->Elements(),
|
||||
aDrawTarget,
|
||||
aScaledFont,
|
||||
nullptr, // variations not needed
|
||||
@ -2426,7 +2415,7 @@ bool COLRFonts::PaintGlyphLayers(
|
||||
length,
|
||||
aCurrentColor,
|
||||
0.0, // fontUnitsToPixels not needed
|
||||
uint16_t(colors.Length()),
|
||||
uint16_t(aColors->Length()),
|
||||
0,
|
||||
nullptr};
|
||||
return glyphRecord->Paint(state, alpha, aPoint);
|
||||
@ -2457,29 +2446,21 @@ const COLRFonts::GlyphPaintGraph* COLRFonts::GetGlyphPaintGraph(
|
||||
bool COLRFonts::PaintGlyphGraph(
|
||||
hb_blob_t* aCOLR, hb_font_t* aFont, const GlyphPaintGraph* aPaintGraph,
|
||||
DrawTarget* aDrawTarget, layout::TextDrawTarget* aTextDrawer,
|
||||
ScaledFont* aScaledFont, DrawOptions aDrawOptions,
|
||||
const sRGBColor& aCurrentColor, const Point& aPoint, uint32_t aGlyphId,
|
||||
float aFontUnitsToPixels) {
|
||||
ScaledFont* aScaledFont, DrawOptions aDrawOptions, const Point& aPoint,
|
||||
const sRGBColor& aCurrentColor, const nsTArray<sRGBColor>* aColors,
|
||||
uint32_t aGlyphId, float aFontUnitsToPixels) {
|
||||
if (aTextDrawer) {
|
||||
// Currently we always punt to a blob for COLRv1 glyphs.
|
||||
aTextDrawer->FoundUnsupportedFeature();
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned int colorCount = 0;
|
||||
AutoTArray<hb_color_t, 64> colors;
|
||||
hb_face_t* face = hb_font_get_face(aFont);
|
||||
colors.SetLength(hb_ot_color_palette_get_colors(face, /* paletteIndex */ 0, 0,
|
||||
&colorCount, nullptr));
|
||||
colorCount = colors.Length();
|
||||
hb_ot_color_palette_get_colors(face, 0, 0, &colorCount, colors.Elements());
|
||||
|
||||
unsigned int coordCount;
|
||||
const int* coords = hb_font_get_var_coords_normalized(aFont, &coordCount);
|
||||
|
||||
AutoTArray<uint32_t, 32> visitedOffsets;
|
||||
PaintState state{{nullptr},
|
||||
colors.Elements(),
|
||||
aColors->Elements(),
|
||||
aDrawTarget,
|
||||
aScaledFont,
|
||||
coords,
|
||||
@ -2487,7 +2468,7 @@ bool COLRFonts::PaintGlyphGraph(
|
||||
hb_blob_get_length(aCOLR),
|
||||
aCurrentColor,
|
||||
aFontUnitsToPixels,
|
||||
uint16_t(colors.Length()),
|
||||
uint16_t(aColors->Length()),
|
||||
uint16_t(coordCount),
|
||||
&visitedOffsets};
|
||||
state.mHeader.v1 =
|
||||
@ -2548,4 +2529,98 @@ uint16_t COLRFonts::GetColrTableVersion(hb_blob_t* aCOLR) {
|
||||
return colr->version;
|
||||
}
|
||||
|
||||
UniquePtr<nsTArray<sRGBColor>> COLRFonts::SetupColorPalette(
|
||||
hb_face_t* aFace, const FontPaletteValueSet* aPaletteValueSet,
|
||||
nsAtom* aFontPalette, const nsACString& aFamilyName) {
|
||||
// Find the base color palette to use, if there are multiple available;
|
||||
// default to first in the font, if nothing matches what is requested.
|
||||
unsigned int paletteIndex = 0;
|
||||
unsigned int count = hb_ot_color_palette_get_count(aFace);
|
||||
MOZ_ASSERT(count > 0, "No palettes? Font should have been rejected!");
|
||||
|
||||
const FontPaletteValueSet::PaletteValues* fpv = nullptr;
|
||||
if (aFontPalette && aFontPalette != nsGkAtoms::normal &&
|
||||
(count > 1 || aPaletteValueSet)) {
|
||||
auto findPalette = [&](hb_ot_color_palette_flags_t flag) -> unsigned int {
|
||||
MOZ_ASSERT(flag != HB_OT_COLOR_PALETTE_FLAG_DEFAULT);
|
||||
for (unsigned int i = 0; i < count; ++i) {
|
||||
if (hb_ot_color_palette_get_flags(aFace, i) & flag) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
if (aFontPalette == nsGkAtoms::light) {
|
||||
paletteIndex =
|
||||
findPalette(HB_OT_COLOR_PALETTE_FLAG_USABLE_WITH_LIGHT_BACKGROUND);
|
||||
} else if (aFontPalette == nsGkAtoms::dark) {
|
||||
paletteIndex =
|
||||
findPalette(HB_OT_COLOR_PALETTE_FLAG_USABLE_WITH_DARK_BACKGROUND);
|
||||
} else {
|
||||
if (aPaletteValueSet) {
|
||||
if ((fpv = aPaletteValueSet->Lookup(aFontPalette, aFamilyName))) {
|
||||
if (fpv->mBasePalette >= 0 && fpv->mBasePalette < int32_t(count)) {
|
||||
paletteIndex = fpv->mBasePalette;
|
||||
} else if (fpv->mBasePalette ==
|
||||
FontPaletteValueSet::PaletteValues::kLight) {
|
||||
paletteIndex = findPalette(
|
||||
HB_OT_COLOR_PALETTE_FLAG_USABLE_WITH_LIGHT_BACKGROUND);
|
||||
} else if (fpv->mBasePalette ==
|
||||
FontPaletteValueSet::PaletteValues::kDark) {
|
||||
paletteIndex = findPalette(
|
||||
HB_OT_COLOR_PALETTE_FLAG_USABLE_WITH_DARK_BACKGROUND);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Collect the palette colors and convert them to sRGBColor values.
|
||||
count =
|
||||
hb_ot_color_palette_get_colors(aFace, paletteIndex, 0, nullptr, nullptr);
|
||||
nsTArray<hb_color_t> colors;
|
||||
colors.SetLength(count);
|
||||
hb_ot_color_palette_get_colors(aFace, paletteIndex, 0, &count,
|
||||
colors.Elements());
|
||||
|
||||
auto palette = MakeUnique<nsTArray<sRGBColor>>();
|
||||
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));
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return palette;
|
||||
}
|
||||
|
||||
const FontPaletteValueSet::PaletteValues* FontPaletteValueSet::Lookup(
|
||||
nsAtom* aName, const nsACString& aFamily) const {
|
||||
nsAutoCString family(aFamily);
|
||||
ToLowerCase(family);
|
||||
if (const HashEntry* entry =
|
||||
mValues.GetEntry(PaletteHashKey(aName, family))) {
|
||||
return &entry->mValue;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
FontPaletteValueSet::PaletteValues* FontPaletteValueSet::Insert(
|
||||
nsAtom* aName, const nsACString& aFamily) {
|
||||
nsAutoCString family(aFamily);
|
||||
ToLowerCase(family);
|
||||
HashEntry* entry = mValues.PutEntry(PaletteHashKey(aName, family));
|
||||
return &entry->mValue;
|
||||
}
|
||||
|
||||
} // end namespace mozilla::gfx
|
||||
|
@ -7,6 +7,10 @@
|
||||
#define COLR_FONTS_H
|
||||
|
||||
#include "mozilla/gfx/2D.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "nsAtom.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsTHashtable.h"
|
||||
|
||||
struct hb_blob_t;
|
||||
struct hb_face_t;
|
||||
@ -20,6 +24,70 @@ class TextDrawTarget;
|
||||
|
||||
namespace gfx {
|
||||
|
||||
class FontPaletteValueSet {
|
||||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(FontPaletteValueSet)
|
||||
|
||||
struct OverrideColor {
|
||||
uint32_t mIndex = 0;
|
||||
sRGBColor mColor;
|
||||
};
|
||||
|
||||
struct PaletteValues {
|
||||
enum { kLight = -1, kDark = -2 };
|
||||
int32_t mBasePalette = 0; // 0-based index, or kLight/kDark constants
|
||||
nsTArray<OverrideColor> mOverrides;
|
||||
};
|
||||
|
||||
const PaletteValues* Lookup(nsAtom* aName, const nsACString& aFamily) const;
|
||||
|
||||
PaletteValues* Insert(nsAtom* aName, const nsACString& aFamily);
|
||||
|
||||
private:
|
||||
~FontPaletteValueSet() = default;
|
||||
|
||||
struct PaletteHashKey {
|
||||
RefPtr<nsAtom> mName;
|
||||
nsCString mFamily;
|
||||
|
||||
PaletteHashKey() = delete;
|
||||
PaletteHashKey(nsAtom* aName, const nsACString& aFamily)
|
||||
: mName(aName), mFamily(aFamily) {}
|
||||
PaletteHashKey(const PaletteHashKey& aKey) = default;
|
||||
};
|
||||
|
||||
class HashEntry : public PLDHashEntryHdr {
|
||||
public:
|
||||
using KeyType = const PaletteHashKey&;
|
||||
using KeyTypePointer = const PaletteHashKey*;
|
||||
|
||||
HashEntry() = delete;
|
||||
explicit HashEntry(KeyTypePointer aKey) : mKey(*aKey) {}
|
||||
HashEntry(HashEntry&& other) noexcept
|
||||
: PLDHashEntryHdr(std::move(other)),
|
||||
mKey(other.mKey),
|
||||
mValue(std::move(other.mValue)) {
|
||||
NS_ERROR("Should not be called");
|
||||
}
|
||||
~HashEntry() = default;
|
||||
|
||||
bool KeyEquals(const KeyTypePointer aKey) const {
|
||||
return mKey.mName == aKey->mName && mKey.mFamily.Equals(aKey->mFamily);
|
||||
}
|
||||
static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; }
|
||||
static PLDHashNumber HashKey(const KeyTypePointer aKey) {
|
||||
return aKey->mName->hash() +
|
||||
HashString(aKey->mFamily.get(), aKey->mFamily.Length());
|
||||
}
|
||||
enum { ALLOW_MEMMOVE = true };
|
||||
|
||||
PaletteHashKey mKey;
|
||||
PaletteValues mValue;
|
||||
};
|
||||
|
||||
nsTHashtable<HashEntry> mValues;
|
||||
};
|
||||
|
||||
class COLRFonts {
|
||||
public:
|
||||
static bool ValidateColorGlyphs(hb_blob_t* aCOLR, hb_blob_t* aCPAL);
|
||||
@ -33,8 +101,8 @@ class COLRFonts {
|
||||
static bool PaintGlyphLayers(
|
||||
hb_blob_t* aCOLR, hb_face_t* aFace, const GlyphLayers* aLayers,
|
||||
DrawTarget* aDrawTarget, layout::TextDrawTarget* aTextDrawer,
|
||||
ScaledFont* aScaledFont, DrawOptions aDrawOptions,
|
||||
const sRGBColor& aCurrentColor, const Point& aPoint);
|
||||
ScaledFont* aScaledFont, DrawOptions aDrawOptions, const Point& aPoint,
|
||||
const sRGBColor& aCurrentColor, const nsTArray<sRGBColor>* aColors);
|
||||
|
||||
// COLRv1 support: color glyph is represented by a directed acyclic graph of
|
||||
// paint records.
|
||||
@ -44,14 +112,12 @@ class COLRFonts {
|
||||
static const GlyphPaintGraph* GetGlyphPaintGraph(hb_blob_t* aCOLR,
|
||||
uint32_t aGlyphId);
|
||||
|
||||
static bool PaintGlyphGraph(hb_blob_t* aCOLR, hb_font_t* aFont,
|
||||
const GlyphPaintGraph* aPaintGraph,
|
||||
DrawTarget* aDrawTarget,
|
||||
layout::TextDrawTarget* aTextDrawer,
|
||||
ScaledFont* aScaledFont, DrawOptions aDrawOptions,
|
||||
const sRGBColor& aCurrentColor,
|
||||
const Point& aPoint, uint32_t aGlyphId,
|
||||
float aFontUnitsToPixels);
|
||||
static bool 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<sRGBColor>* aColors,
|
||||
uint32_t aGlyphId, float aFontUnitsToPixels);
|
||||
|
||||
static Rect GetColorGlyphBounds(hb_blob_t* aCOLR, hb_font_t* aFont,
|
||||
uint32_t aGlyphId, DrawTarget* aDrawTarget,
|
||||
@ -59,6 +125,10 @@ class COLRFonts {
|
||||
float aFontUnitsToPixels);
|
||||
|
||||
static uint16_t GetColrTableVersion(hb_blob_t* aCOLR);
|
||||
|
||||
static UniquePtr<nsTArray<sRGBColor>> SetupColorPalette(
|
||||
hb_face_t* aFace, const FontPaletteValueSet* aPaletteValueSet,
|
||||
nsAtom* aFontPalette, const nsACString& aFamilyName);
|
||||
};
|
||||
|
||||
} // namespace gfx
|
||||
|
@ -2035,8 +2035,7 @@ void gfxFont::DrawOneGlyph(uint32_t aGlyphID, const gfx::Point& aPt,
|
||||
|
||||
if (fontParams.haveColorGlyphs && !UseNativeColrFontSupport() &&
|
||||
RenderColorGlyph(runParams.dt, runParams.context, textDrawer,
|
||||
fontParams.scaledFont, fontParams.drawOptions, devPt,
|
||||
aGlyphID)) {
|
||||
fontParams, devPt, aGlyphID)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2187,6 +2186,17 @@ void gfxFont::Draw(const gfxTextRun* aTextRun, uint32_t aStart, uint32_t aEnd,
|
||||
fontParams.haveColorGlyphs = GetFontEntry()->TryGetColorGlyphs();
|
||||
fontParams.contextPaint = aRunParams.runContextPaint;
|
||||
|
||||
if (fontParams.haveColorGlyphs && !UseNativeColrFontSupport()) {
|
||||
DeviceColor ctxColor;
|
||||
fontParams.currentColor = aRunParams.context->GetDeviceColor(ctxColor)
|
||||
? sRGBColor::FromABGR(ctxColor.ToABGR())
|
||||
: sRGBColor::OpaqueBlack();
|
||||
gfxFontEntry::AutoHBFace face = GetFontEntry()->GetHBFace();
|
||||
fontParams.palette = COLRFonts::SetupColorPalette(
|
||||
face, aRunParams.paletteValueSet, aRunParams.fontPalette,
|
||||
GetFontEntry()->FamilyName());
|
||||
}
|
||||
|
||||
if (textDrawer) {
|
||||
fontParams.isVerticalFont = aRunParams.isVerticalRun;
|
||||
} else {
|
||||
@ -2468,24 +2478,17 @@ bool gfxFont::RenderSVGGlyph(gfxContext* aContext,
|
||||
|
||||
bool gfxFont::RenderColorGlyph(DrawTarget* aDrawTarget, gfxContext* aContext,
|
||||
layout::TextDrawTarget* aTextDrawer,
|
||||
ScaledFont* aScaledFont,
|
||||
DrawOptions aDrawOptions, const Point& aPoint,
|
||||
uint32_t aGlyphId) {
|
||||
auto currentColor = [=]() {
|
||||
DeviceColor ctxColor;
|
||||
return aContext->GetDeviceColor(ctxColor)
|
||||
? sRGBColor::FromABGR(ctxColor.ToABGR())
|
||||
: sRGBColor::OpaqueBlack();
|
||||
};
|
||||
|
||||
const FontDrawParams& aFontParams,
|
||||
const Point& aPoint, uint32_t aGlyphId) {
|
||||
if (const auto* paintGraph =
|
||||
COLRFonts::GetGlyphPaintGraph(GetFontEntry()->GetCOLR(), aGlyphId)) {
|
||||
const auto* hbShaper = GetHarfBuzzShaper();
|
||||
if (hbShaper && hbShaper->IsInitialized()) {
|
||||
return COLRFonts::PaintGlyphGraph(
|
||||
GetFontEntry()->GetCOLR(), hbShaper->GetHBFont(), paintGraph,
|
||||
aDrawTarget, aTextDrawer, aScaledFont, aDrawOptions, currentColor(),
|
||||
aPoint, aGlyphId, mFUnitsConvFactor);
|
||||
aDrawTarget, aTextDrawer, aFontParams.scaledFont,
|
||||
aFontParams.drawOptions, aPoint, aFontParams.currentColor,
|
||||
aFontParams.palette.get(), aGlyphId, mFUnitsConvFactor);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2494,7 +2497,8 @@ bool gfxFont::RenderColorGlyph(DrawTarget* aDrawTarget, gfxContext* aContext,
|
||||
auto face(GetFontEntry()->GetHBFace());
|
||||
bool ok = COLRFonts::PaintGlyphLayers(
|
||||
GetFontEntry()->GetCOLR(), face, layers, aDrawTarget, aTextDrawer,
|
||||
aScaledFont, aDrawOptions, currentColor(), aPoint);
|
||||
aFontParams.scaledFont, aFontParams.drawOptions, aPoint,
|
||||
aFontParams.currentColor, aFontParams.palette.get());
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
@ -2263,10 +2263,12 @@ class gfxFont {
|
||||
|
||||
bool RenderColorGlyph(DrawTarget* aDrawTarget, gfxContext* aContext,
|
||||
mozilla::layout::TextDrawTarget* aTextDrawer,
|
||||
mozilla::gfx::ScaledFont* scaledFont,
|
||||
mozilla::gfx::DrawOptions drawOptions,
|
||||
const FontDrawParams& aFontParams,
|
||||
const mozilla::gfx::Point& aPoint, uint32_t aGlyphId);
|
||||
|
||||
void SetupColorPalette(FontDrawParams* aFontParams,
|
||||
const TextRunDrawParams& aRunParams) const;
|
||||
|
||||
// Subclasses can override to return true if the platform is able to render
|
||||
// COLR-font glyphs directly, instead of us painting the layers explicitly.
|
||||
// (Currently used only for COLR.v0 fonts on macOS.)
|
||||
@ -2301,6 +2303,8 @@ struct MOZ_STACK_CLASS TextRunDrawParams {
|
||||
gfxPattern* textStrokePattern = nullptr;
|
||||
const mozilla::gfx::StrokeOptions* strokeOpts = nullptr;
|
||||
const mozilla::gfx::DrawOptions* drawOpts = nullptr;
|
||||
const mozilla::gfx::FontPaletteValueSet* paletteValueSet = nullptr;
|
||||
nsAtom* fontPalette = nullptr;
|
||||
DrawMode drawMode = DrawMode::GLYPH_FILL;
|
||||
bool isVerticalRun = false;
|
||||
bool isRTL = false;
|
||||
@ -2316,6 +2320,8 @@ struct MOZ_STACK_CLASS FontDrawParams {
|
||||
int32_t extraStrikes;
|
||||
mozilla::gfx::DrawOptions drawOptions;
|
||||
gfxFloat advanceDirection;
|
||||
mozilla::gfx::sRGBColor currentColor;
|
||||
mozilla::UniquePtr<nsTArray<mozilla::gfx::sRGBColor>> palette;
|
||||
bool isVerticalFont;
|
||||
bool haveSVGGlyphs;
|
||||
bool haveColorGlyphs;
|
||||
|
@ -613,12 +613,14 @@ bool gfxMacFont::ShouldRoundXOffset(cairo_t* aCairo) const {
|
||||
}
|
||||
|
||||
bool gfxMacFont::UseNativeColrFontSupport() const {
|
||||
if (nsCocoaFeatures::OnHighSierraOrLater()) {
|
||||
auto* colr = GetFontEntry()->GetCOLR();
|
||||
if (colr && COLRFonts::GetColrTableVersion(colr) == 0) {
|
||||
return true;
|
||||
/*
|
||||
if (nsCocoaFeatures::OnHighSierraOrLater()) {
|
||||
auto* colr = GetFontEntry()->GetCOLR();
|
||||
if (colr && COLRFonts::GetColrTableVersion(colr) == 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1827,7 +1827,6 @@ bool gfxPlatform::IsFontFormatSupported(
|
||||
}
|
||||
StyleFontFaceSourceTechFlags unsupportedTechnologies =
|
||||
StyleFontFaceSourceTechFlags::INCREMENTAL |
|
||||
StyleFontFaceSourceTechFlags::PALETTES |
|
||||
StyleFontFaceSourceTechFlags::COLOR_SBIX;
|
||||
if (!StaticPrefs::gfx_downloadable_fonts_keep_color_bitmaps()) {
|
||||
unsupportedTechnologies |= StyleFontFaceSourceTechFlags::COLOR_CBDT;
|
||||
@ -1835,6 +1834,9 @@ bool gfxPlatform::IsFontFormatSupported(
|
||||
if (!StaticPrefs::gfx_font_rendering_colr_v1_enabled()) {
|
||||
unsupportedTechnologies |= StyleFontFaceSourceTechFlags::COLOR_COLRV1;
|
||||
}
|
||||
if (!StaticPrefs::layout_css_font_palette_enabled()) {
|
||||
unsupportedTechnologies |= StyleFontFaceSourceTechFlags::PALETTES;
|
||||
}
|
||||
if (!StaticPrefs::layout_css_font_variations_enabled()) {
|
||||
unsupportedTechnologies |= StyleFontFaceSourceTechFlags::VARIATIONS;
|
||||
}
|
||||
|
@ -632,6 +632,8 @@ void gfxTextRun::Draw(const Range aRange, const gfx::Point aPt,
|
||||
params.direction = direction;
|
||||
params.strokeOpts = aParams.strokeOpts;
|
||||
params.textStrokeColor = aParams.textStrokeColor;
|
||||
params.fontPalette = aParams.fontPalette;
|
||||
params.paletteValueSet = aParams.paletteValueSet;
|
||||
params.textStrokePattern = aParams.textStrokePattern;
|
||||
params.drawOpts = aParams.drawOpts;
|
||||
params.drawMode = aParams.drawMode;
|
||||
|
@ -252,6 +252,8 @@ class gfxTextRun : public gfxShapedText {
|
||||
gfxContext* context;
|
||||
DrawMode drawMode = DrawMode::GLYPH_FILL;
|
||||
nscolor textStrokeColor = 0;
|
||||
nsAtom* fontPalette = nullptr;
|
||||
mozilla::gfx::FontPaletteValueSet* paletteValueSet = nullptr;
|
||||
gfxPattern* textStrokePattern = nullptr;
|
||||
const mozilla::gfx::StrokeOptions* strokeOpts = nullptr;
|
||||
const mozilla::gfx::DrawOptions* drawOpts = nullptr;
|
||||
|
@ -214,6 +214,7 @@ struct nsTextFrame::DrawTextRunParams {
|
||||
DrawPathCallbacks* callbacks = nullptr;
|
||||
nscolor textColor = NS_RGBA(0, 0, 0, 0);
|
||||
nscolor textStrokeColor = NS_RGBA(0, 0, 0, 0);
|
||||
nsAtom* fontPalette = nullptr;
|
||||
float textStrokeWidth = 0.0f;
|
||||
bool drawSoftHyphen = false;
|
||||
explicit DrawTextRunParams(gfxContext* aContext) : context(aContext) {}
|
||||
@ -6346,6 +6347,7 @@ void nsTextFrame::PaintOneShadow(const PaintShadowParams& aParams,
|
||||
params.textStyle = &textPaintStyle;
|
||||
params.textColor =
|
||||
aParams.context == shadowContext ? shadowColor : NS_RGB(0, 0, 0);
|
||||
params.fontPalette = nsGkAtoms::normal; // XXX fixme
|
||||
params.clipEdges = aParams.clipEdges;
|
||||
params.drawSoftHyphen = HasAnyStateBits(TEXT_HYPHEN_BREAK);
|
||||
// Multi-color shadow is not allowed, so we use the same color of the text
|
||||
@ -6478,6 +6480,7 @@ bool nsTextFrame::PaintTextWithSelectionColors(
|
||||
params.advanceWidth = &advance;
|
||||
params.callbacks = aParams.callbacks;
|
||||
params.glyphRange = aParams.glyphRange;
|
||||
params.fontPalette = StyleFont()->GetFontPaletteAtom();
|
||||
|
||||
PaintShadowParams shadowParams(aParams);
|
||||
shadowParams.provider = aParams.provider;
|
||||
@ -7048,6 +7051,8 @@ void nsTextFrame::PaintText(const PaintTextParams& aParams,
|
||||
params.contextPaint = aParams.contextPaint;
|
||||
params.callbacks = aParams.callbacks;
|
||||
params.glyphRange = range;
|
||||
params.fontPalette = StyleFont()->GetFontPaletteAtom();
|
||||
|
||||
DrawText(range, textBaselinePt, params);
|
||||
}
|
||||
|
||||
@ -7060,6 +7065,7 @@ static void DrawTextRun(const gfxTextRun* aTextRun,
|
||||
params.provider = aParams.provider;
|
||||
params.advanceWidth = aParams.advanceWidth;
|
||||
params.contextPaint = aParams.contextPaint;
|
||||
params.fontPalette = aParams.fontPalette;
|
||||
params.callbacks = aParams.callbacks;
|
||||
if (aParams.callbacks) {
|
||||
aParams.callbacks->NotifyBeforeText(aParams.textColor);
|
||||
|
@ -118,6 +118,8 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleFont {
|
||||
static mozilla::Length ZoomText(const mozilla::dom::Document&,
|
||||
mozilla::Length);
|
||||
|
||||
nsAtom* GetFontPaletteAtom() const { return mFontPalette._0.AsAtom(); }
|
||||
|
||||
nsFont mFont;
|
||||
|
||||
// Our "computed size". Can be different from mFont.size which is our "actual
|
||||
|
Loading…
Reference in New Issue
Block a user