зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1571738 - Fallback as late as possible for svg/color fonts. r=jrmuizel
Also includes some documentation gardening for TextDrawTarget on what we don't support. Differential Revision: https://phabricator.services.mozilla.com/D41272 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
a52cd4881c
Коммит
22dbda5b64
|
@ -163,7 +163,7 @@ class WebRenderBridgeChild final : public PWebRenderBridgeChild,
|
|||
|
||||
void SetWebRenderLayerManager(WebRenderLayerManager* aManager);
|
||||
|
||||
ipc::IShmemAllocator* GetShmemAllocator();
|
||||
mozilla::ipc::IShmemAllocator* GetShmemAllocator();
|
||||
|
||||
bool IsThreadSafe() const override { return false; }
|
||||
|
||||
|
|
|
@ -1919,7 +1919,7 @@ void gfxFont::DrawOneGlyph(uint32_t aGlyphID, const gfx::Point& aPt,
|
|||
NS_WARNING_ASSERTION(
|
||||
runParams.drawMode != DrawMode::GLYPH_PATH,
|
||||
"Rendering SVG glyph despite request for glyph path");
|
||||
if (RenderSVGGlyph(runParams.context, devPt, aGlyphID,
|
||||
if (RenderSVGGlyph(runParams.context, textDrawer, devPt, aGlyphID,
|
||||
fontParams.contextPaint, runParams.callbacks,
|
||||
*aEmittedGlyphs)) {
|
||||
return;
|
||||
|
@ -1928,8 +1928,9 @@ void gfxFont::DrawOneGlyph(uint32_t aGlyphID, const gfx::Point& aPt,
|
|||
|
||||
if (fontParams.haveColorGlyphs &&
|
||||
!gfxPlatform::GetPlatform()->HasNativeColrFontSupport() &&
|
||||
RenderColorGlyph(runParams.dt, runParams.context, fontParams.scaledFont,
|
||||
fontParams.drawOptions, devPt, aGlyphID)) {
|
||||
RenderColorGlyph(runParams.dt, runParams.context, textDrawer,
|
||||
fontParams.scaledFont, fontParams.drawOptions, devPt,
|
||||
aGlyphID)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2082,14 +2083,6 @@ void gfxFont::Draw(const gfxTextRun* aTextRun, uint32_t aStart, uint32_t aEnd,
|
|||
fontParams.contextPaint = aRunParams.runContextPaint;
|
||||
|
||||
if (textDrawer) {
|
||||
Color color;
|
||||
if (fontParams.haveSVGGlyphs ||
|
||||
(fontParams.haveColorGlyphs &&
|
||||
aRunParams.context->HasNonOpaqueNonTransparentColor(color))) {
|
||||
textDrawer->FoundUnsupportedFeature();
|
||||
return;
|
||||
}
|
||||
|
||||
fontParams.isVerticalFont = aRunParams.isVerticalRun;
|
||||
} else {
|
||||
fontParams.isVerticalFont =
|
||||
|
@ -2319,13 +2312,21 @@ void gfxFont::Draw(const gfxTextRun* aTextRun, uint32_t aStart, uint32_t aEnd,
|
|||
}
|
||||
}
|
||||
|
||||
bool gfxFont::RenderSVGGlyph(gfxContext* aContext, gfx::Point aPoint,
|
||||
uint32_t aGlyphId,
|
||||
bool gfxFont::RenderSVGGlyph(gfxContext* aContext,
|
||||
layout::TextDrawTarget* aTextDrawer,
|
||||
gfx::Point aPoint, uint32_t aGlyphId,
|
||||
SVGContextPaint* aContextPaint) const {
|
||||
if (!GetFontEntry()->HasSVGGlyph(aGlyphId)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (aTextDrawer) {
|
||||
// WebRender doesn't support SVG Glyphs.
|
||||
// (pretend to succeed, output doesn't matter, we will emit a blob)
|
||||
aTextDrawer->FoundUnsupportedFeature();
|
||||
return true;
|
||||
}
|
||||
|
||||
const gfxFloat devUnitsPerSVGUnit =
|
||||
GetAdjustedSize() / GetFontEntry()->UnitsPerEm();
|
||||
gfxContextMatrixAutoSaveRestore matrixRestore(aContext);
|
||||
|
@ -2341,18 +2342,21 @@ bool gfxFont::RenderSVGGlyph(gfxContext* aContext, gfx::Point aPoint,
|
|||
return true;
|
||||
}
|
||||
|
||||
bool gfxFont::RenderSVGGlyph(gfxContext* aContext, gfx::Point aPoint,
|
||||
uint32_t aGlyphId, SVGContextPaint* aContextPaint,
|
||||
bool gfxFont::RenderSVGGlyph(gfxContext* aContext,
|
||||
layout::TextDrawTarget* aTextDrawer,
|
||||
gfx::Point aPoint, uint32_t aGlyphId,
|
||||
SVGContextPaint* aContextPaint,
|
||||
gfxTextRunDrawCallbacks* aCallbacks,
|
||||
bool& aEmittedGlyphs) const {
|
||||
if (aCallbacks && aEmittedGlyphs) {
|
||||
aCallbacks->NotifyGlyphPathEmitted();
|
||||
aEmittedGlyphs = false;
|
||||
}
|
||||
return RenderSVGGlyph(aContext, aPoint, aGlyphId, aContextPaint);
|
||||
return RenderSVGGlyph(aContext, aTextDrawer, aPoint, aGlyphId, aContextPaint);
|
||||
}
|
||||
|
||||
bool gfxFont::RenderColorGlyph(DrawTarget* aDrawTarget, gfxContext* aContext,
|
||||
layout::TextDrawTarget* aTextDrawer,
|
||||
mozilla::gfx::ScaledFont* scaledFont,
|
||||
mozilla::gfx::DrawOptions aDrawOptions,
|
||||
const mozilla::gfx::Point& aPoint,
|
||||
|
@ -2369,6 +2373,16 @@ bool gfxFont::RenderColorGlyph(DrawTarget* aDrawTarget, gfxContext* aContext,
|
|||
return false;
|
||||
}
|
||||
|
||||
// defaultColor is the one that comes from CSS, so it has transparency info.
|
||||
bool hasTransparency = 0.f < defaultColor.a && defaultColor.a < 1.f;
|
||||
if (aTextDrawer && hasTransparency && layerGlyphs.Length() > 1) {
|
||||
// WebRender doesn't support drawing multi-layer transparent color-glyphs,
|
||||
// as it requires compositing all the layers before applying transparency.
|
||||
// (pretend to succeed, output doesn't matter, we will emit a blob)
|
||||
aTextDrawer->FoundUnsupportedFeature();
|
||||
return true;
|
||||
}
|
||||
|
||||
for (uint32_t layerIndex = 0; layerIndex < layerGlyphs.Length();
|
||||
layerIndex++) {
|
||||
Glyph glyph;
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include "nsColor.h"
|
||||
#include "nsFontMetrics.h"
|
||||
#include "mozilla/ServoUtils.h"
|
||||
#include "TextDrawTarget.h"
|
||||
|
||||
typedef struct _cairo cairo_t;
|
||||
typedef struct _cairo_scaled_font cairo_scaled_font_t;
|
||||
|
@ -2148,14 +2149,19 @@ class gfxFont {
|
|||
// if this font has bad underline offset, aIsBadUnderlineFont should be true.
|
||||
void SanitizeMetrics(Metrics* aMetrics, bool aIsBadUnderlineFont);
|
||||
|
||||
bool RenderSVGGlyph(gfxContext* aContext, mozilla::gfx::Point aPoint,
|
||||
uint32_t aGlyphId, SVGContextPaint* aContextPaint) const;
|
||||
bool RenderSVGGlyph(gfxContext* aContext, mozilla::gfx::Point aPoint,
|
||||
uint32_t aGlyphId, SVGContextPaint* aContextPaint,
|
||||
bool RenderSVGGlyph(gfxContext* aContext,
|
||||
mozilla::layout::TextDrawTarget* aTextDrawer,
|
||||
mozilla::gfx::Point aPoint, uint32_t aGlyphId,
|
||||
SVGContextPaint* aContextPaint) const;
|
||||
bool RenderSVGGlyph(gfxContext* aContext,
|
||||
mozilla::layout::TextDrawTarget* aTextDrawer,
|
||||
mozilla::gfx::Point aPoint, uint32_t aGlyphId,
|
||||
SVGContextPaint* aContextPaint,
|
||||
gfxTextRunDrawCallbacks* aCallbacks,
|
||||
bool& aEmittedGlyphs) const;
|
||||
|
||||
bool RenderColorGlyph(DrawTarget* aDrawTarget, gfxContext* aContext,
|
||||
mozilla::layout::TextDrawTarget* aTextDrawer,
|
||||
mozilla::gfx::ScaledFont* scaledFont,
|
||||
mozilla::gfx::DrawOptions drawOptions,
|
||||
const mozilla::gfx::Point& aPoint,
|
||||
|
|
|
@ -20,7 +20,7 @@ namespace layout {
|
|||
|
||||
using namespace gfx;
|
||||
|
||||
// This class is fake DrawTarget, used to intercept text draw calls, while
|
||||
// This class is a fake DrawTarget, used to intercept text draw calls, while
|
||||
// also collecting up the other aspects of text natively.
|
||||
//
|
||||
// When using advanced-layers in nsDisplayText's constructor, we construct this
|
||||
|
@ -350,15 +350,27 @@ class TextDrawTarget : public DrawTarget {
|
|||
return wr::ToRoundedLayoutRect(mClipStack.LastElement());
|
||||
}
|
||||
LayoutDeviceRect GeckoClipRect() { return mClipStack.LastElement(); }
|
||||
// Whether anything unsupported was encountered. Currently:
|
||||
// Whether anything unsupported was encountered. This will result in this
|
||||
// text being emitted as a blob, which means subpixel-AA can't be used and
|
||||
// that performance will probably be a bit worse. At this point, we've
|
||||
// properly implemented everything that shows up a lot, so you can assume
|
||||
// that the remaining things we don't implement are fairly rare. The complete
|
||||
// set of things that we don't implement are as follows:
|
||||
//
|
||||
// * Synthetic bold/italics
|
||||
// * SVG fonts
|
||||
// * Unserializable fonts
|
||||
// * Tofu glyphs
|
||||
// * Pratial ligatures
|
||||
// * Text writing-mode
|
||||
// * Text stroke
|
||||
// * Unserializable Fonts: WR lives across an IPC boundary
|
||||
// * Text-Combine-Upright Squishing: no one's really bothered to impl it yet
|
||||
// * Text-Stroke: not a real standard (exists for webcompat)
|
||||
// * SVG Glyphs: not a real standard (we got overzealous with svg)
|
||||
// * Color Glyphs (Emoji) With Transparency: requires us to apply transparency
|
||||
// with a composited layer (a single emoji can be many single-color glyphs)
|
||||
//
|
||||
// The transparent colored-glyphs issue is probably the most valuable to fix,
|
||||
// since ideally it would also result in us fixing transparency for all
|
||||
// intersecting glyphs (which currently look bad with or without webrender,
|
||||
// so there's no fallback like with emoji). Specifically, transparency
|
||||
// looks bad for "cursive" fonts where glyphs overlap at the seams. Since
|
||||
// this is more common for non-latin scripts (e.g. मनीष), this amounts to us
|
||||
// treating non-latin scripts poorly... unless they're emoji. Yikes!
|
||||
bool mHasUnsupportedFeatures = false;
|
||||
|
||||
// The caller promises to call Save/Restore on the builder as needed.
|
||||
|
|
|
@ -5,7 +5,7 @@ pref(gfx.font_rendering.opentype_svg.enabled,false) != svg-glyph-positioning.s
|
|||
pref(gfx.font_rendering.opentype_svg.enabled,true) fuzzy-if(skiaContent,0-2,0-350) == svg-glyph-positioning.svg svg-glyph-positioning-ref.svg
|
||||
pref(gfx.font_rendering.opentype_svg.enabled,true) == svg-glyph-html.html svg-glyph-html-ref.svg
|
||||
pref(gfx.font_rendering.opentype_svg.enabled,true) == svg-glyph-direct.svg svg-glyph-direct-ref.svg
|
||||
pref(gfx.font_rendering.opentype_svg.enabled,true) fuzzy-if(webrender&&winWidget,129-138,2188-2461) fuzzy-if(OSX,134-134,2463-2463) == svg-glyph-invalid.html svg-glyph-invalid-ref.html
|
||||
pref(gfx.font_rendering.opentype_svg.enabled,true) fuzzy-if(webrender&&OSX,176-176,2330-2330) fuzzy-if(!webrender&&OSX,134-134,2463-2463) == svg-glyph-invalid.html svg-glyph-invalid-ref.html
|
||||
pref(gfx.font_rendering.opentype_svg.enabled,true) == svg-glyph-objectfill-solid.svg svg-glyph-objectfill-solid-ref.svg
|
||||
pref(gfx.font_rendering.opentype_svg.enabled,true) fuzzy-if(skiaContent,0-2,0-200) == svg-glyph-objectstroke-solid.svg svg-glyph-objectstroke-solid-ref.svg
|
||||
pref(gfx.font_rendering.opentype_svg.enabled,true) fuzzy(0-1,0-7) fuzzy-if(gtkWidget&&/^Linux\x20x86_64/.test(http.oscpu),0-1,0-79) fuzzy-if(skiaContent,0-1,0-300) == svg-glyph-objectgradient.svg svg-glyph-objectgradient-ref.svg # see bug 871961#c5
|
||||
|
|
Загрузка…
Ссылка в новой задаче