зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
6012755291
Коммит
85d0caa7ab
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -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
|
||||
|
|
Загрузка…
Ссылка в новой задаче