Bug 1740530 - patch 5 - Implement support for COLRv1 glyphs represented as acyclic graphs of paint records. r=gfx-reviewers,lsalzman

Depends on D153870

Differential Revision: https://phabricator.services.mozilla.com/D152041
This commit is contained in:
Jonathan Kew 2022-08-16 10:39:52 +00:00
Родитель 6012755291
Коммит 85d0caa7ab
6 изменённых файлов: 2037 добавлений и 73 удалений

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -10,6 +10,7 @@
struct hb_blob_t;
struct hb_face_t;
struct hb_font_t;
namespace mozilla {
@ -18,21 +19,44 @@ class TextDrawTarget;
}
namespace gfx {
struct COLRBaseGlyphRecord;
class COLRFonts {
public:
// for color layer from glyph using COLR and CPAL tables
static bool ValidateColorGlyphs(hb_blob_t* aCOLR, hb_blob_t* aCPAL);
static const COLRBaseGlyphRecord* GetGlyphLayers(hb_blob_t* aCOLR,
uint32_t aGlyphId);
// COLRv0: color glyph is represented as a simple list of colored layers.
struct GlyphLayers;
static const GlyphLayers* GetGlyphLayers(hb_blob_t* aCOLR, uint32_t aGlyphId);
static bool PaintGlyphLayers(
hb_blob_t* aCOLR, hb_face_t* aFace, const COLRBaseGlyphRecord* aLayers,
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);
// COLRv1 support: color glyph is represented by a directed acyclic graph of
// paint records.
struct GlyphPaintGraph;
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 Rect GetColorGlyphBounds(hb_blob_t* aCOLR, hb_font_t* aFont,
uint32_t aGlyphId, DrawTarget* aDrawTarget,
ScaledFont* aScaledFont,
float aFontUnitsToPixels);
static uint16_t GetColrTableVersion(hb_blob_t* aCOLR);
};
} // namespace gfx

Просмотреть файл

@ -2466,7 +2466,7 @@ bool gfxFont::RenderColorGlyph(DrawTarget* aDrawTarget, gfxContext* aContext,
layout::TextDrawTarget* aTextDrawer,
ScaledFont* aScaledFont,
DrawOptions aDrawOptions, const Point& aPoint,
uint32_t aGlyphId) const {
uint32_t aGlyphId) {
auto currentColor = [=]() {
DeviceColor ctxColor;
return aContext->GetDeviceColor(ctxColor)
@ -2474,6 +2474,17 @@ bool gfxFont::RenderColorGlyph(DrawTarget* aDrawTarget, gfxContext* aContext,
: sRGBColor::OpaqueBlack();
};
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);
}
}
if (const auto* layers =
COLRFonts::GetGlyphLayers(GetFontEntry()->GetCOLR(), aGlyphId)) {
auto face(GetFontEntry()->GetHBFace());
@ -2509,7 +2520,8 @@ bool gfxFont::HasColorGlyphFor(uint32_t aCh, uint32_t aNextCh) {
}
// Check if there is a COLR/CPAL or SVG glyph for this ID.
if (fe->TryGetColorGlyphs() &&
COLRFonts::GetGlyphLayers(fe->GetCOLR(), gid)) {
(COLRFonts::GetGlyphPaintGraph(fe->GetCOLR(), gid) ||
COLRFonts::GetGlyphLayers(fe->GetCOLR(), gid))) {
return true;
}
if (fe->TryGetSVGData(this) && fe->HasSVGGlyph(gid)) {
@ -3613,6 +3625,24 @@ void gfxFont::SetupGlyphExtents(DrawTarget* aDrawTarget, uint32_t aGlyphID,
return;
}
if (mFontEntry->TryGetColorGlyphs() && mFontEntry->mCOLR &&
COLRFonts::GetColrTableVersion(mFontEntry->mCOLR) == 1) {
auto* shaper = GetHarfBuzzShaper();
if (shaper && shaper->IsInitialized()) {
RefPtr scaledFont = GetScaledFont(aDrawTarget);
Rect r = COLRFonts::GetColorGlyphBounds(
mFontEntry->mCOLR, shaper->GetHBFont(), aGlyphID, aDrawTarget,
scaledFont, mFUnitsConvFactor);
if (!r.IsEmpty()) {
gfxFloat d2a = aExtents->GetAppUnitsPerDevUnit();
aExtents->SetTightGlyphExtents(
aGlyphID, gfxRect(r.X() * d2a, r.Y() * d2a, r.Width() * d2a,
r.Height() * d2a));
return;
}
}
}
gfxRect bounds;
GetGlyphBounds(aGlyphID, &bounds, mAntialiasOption == kAntialiasNone);

Просмотреть файл

@ -2253,8 +2253,7 @@ class gfxFont {
mozilla::layout::TextDrawTarget* aTextDrawer,
mozilla::gfx::ScaledFont* scaledFont,
mozilla::gfx::DrawOptions drawOptions,
const mozilla::gfx::Point& aPoint,
uint32_t aGlyphId) const;
const mozilla::gfx::Point& aPoint, uint32_t aGlyphId);
// Bug 674909. When synthetic bolding text by drawing twice, need to
// render using a pixel offset in device pixels, otherwise text

Просмотреть файл

@ -100,6 +100,9 @@ class gfxHarfBuzzShaper : public gfxFontShaper {
hb_font_funcs_t* aFontFuncs = nullptr,
FontCallbackData* aCallbackData = nullptr);
hb_font_t* GetHBFont() const { return mHBFont; }
hb_face_t* GetHBFace() const { return hb_font_get_face(mHBFont); }
protected:
nsresult SetGlyphsFromRun(gfxShapedText* aShapedText, uint32_t aOffset,
uint32_t aLength, const char16_t* aText,

Просмотреть файл

@ -5702,6 +5702,11 @@
mirror: always
#endif
- name: gfx.font_rendering.colr_v1.enabled
type: RelaxedAtomicBool
value: false
mirror: always
- name: gfx.font_rendering.opentype_svg.enabled
type: RelaxedAtomicBool
value: true