Bug 1400411 - text-layers: fallback if SVG fonts or tofu is found. r?jrmuizel
MozReview-Commit-ID: 9vUK5r5sKWB
--- a/gfx/thebes/gfxFont.cpp
+++ b/gfx/thebes/gfxFont.cpp
@@ -35,16 +35,17 @@
#include "mozilla/Likely.h"
#include "mozilla/MemoryReporting.h"
#include "mozilla/Preferences.h"
#include "mozilla/Services.h"
#include "mozilla/Telemetry.h"
#include "gfxMathTable.h"
#include "gfxSVGGlyphs.h"
#include "gfx2DGlue.h"
+#include "TextDrawTarget.h"
#include "GreekCasing.h"
#include "cairo.h"
#include "harfbuzz/hb.h"
#include "harfbuzz/hb-ot.h"
@@ -1917,16 +1918,20 @@ gfxFont::DrawGlyphs(const gfxShapedText
if (glyphCount > 0) {
const gfxShapedText::DetailedGlyph *details =
aShapedText->GetDetailedGlyphs(aOffset + i);
NS_ASSERTION(details, "detailedGlyph should not be missing!");
for (uint32_t j = 0; j < glyphCount; ++j, ++details) {
double advance = details->mAdvance;
if (glyphData->IsMissing()) {
+ if (auto* textDrawer = aRunParams.context->GetTextDrawer()) {
+ textDrawer->FoundUnsupportedFeature();
+ return false;
+ }
// Default-ignorable chars will have zero advance width;
// we don't have to draw the hexbox for them.
if (aRunParams.drawMode != DrawMode::GLYPH_PATH &&
advance > 0) {
double glyphX = aPt->x;
double glyphY = aPt->y;
if (aRunParams.isRTL) {
if (aFontParams.isVerticalFont) {
@@ -2056,17 +2061,24 @@ gfxFont::Draw(const gfxTextRun *aTextRun
fontParams.drawOptions = *aRunParams.drawOpts;
}
fontParams.scaledFont = GetScaledFont(aRunParams.dt);
if (!fontParams.scaledFont) {
return;
}
+ auto* textDrawer = aRunParams.context->GetTextDrawer();
fontParams.haveSVGGlyphs = GetFontEntry()->TryGetSVGData(this);
+
+ if (fontParams.haveSVGGlyphs && textDrawer) {
+ textDrawer->FoundUnsupportedFeature();
+ return;
+ }
+
fontParams.haveColorGlyphs = GetFontEntry()->TryGetColorGlyphs();
fontParams.contextPaint = aRunParams.runContextPaint;
fontParams.isVerticalFont =
aOrientation == gfx::ShapedTextFlags::TEXT_ORIENT_VERTICAL_UPRIGHT;
bool sideways = false;
gfxContextMatrixAutoSaveRestore matrixRestore;
--- a/layout/generic/TextDrawTarget.h
+++ b/layout/generic/TextDrawTarget.h
@@ -87,28 +87,29 @@ class TextDrawTarget : public DrawTarget
public:
// The different phases of drawing the text we're in
// Each should only happen once, and in the given order.
enum class Phase : uint8_t {
eSelection, eUnderline, eOverline, eGlyphs, eEmphasisMarks, eLineThrough
};
explicit TextDrawTarget()
- : mCurrentlyDrawing(Phase::eSelection)
+ : mCurrentlyDrawing(Phase::eSelection), mHasUnsupportedFeatures(false)
{
mCurrentTarget = gfx::Factory::CreateDrawTarget(gfx::BackendType::SKIA, IntSize(1, 1), gfx::SurfaceFormat::B8G8R8A8);
SetSelectionIndex(0);
}
// Prevent this from being copied
TextDrawTarget(const TextDrawTarget& src) = delete;
TextDrawTarget& operator=(const TextDrawTarget&) = delete;
// Change the phase of text we're drawing.
void StartDrawing(Phase aPhase) { mCurrentlyDrawing = aPhase; }
+ void FoundUnsupportedFeature() { mHasUnsupportedFeatures = true; }
void SetSelectionIndex(size_t i) {
// i should only be accessed if i-1 has already been
MOZ_ASSERT(mParts.Length() <= i);
if (mParts.Length() == i){
mParts.AppendElement();
}
@@ -252,16 +253,20 @@ public:
}
const nsTArray<SelectedTextRunFragment>& GetParts() { return mParts; }
bool
CanSerializeFonts()
{
+ if (mHasUnsupportedFeatures) {
+ return false;
+ }
+
for (const SelectedTextRunFragment& part : GetParts()) {
for (const TextRunFragment& frag : part.text) {
if (!frag.font->CanSerialize()) {
return false;
}
}
}
return true;
@@ -380,16 +385,19 @@ private:
SelectedTextRunFragment* mCurrentPart;
// Chunks of the text, grouped by selection
nsTArray<SelectedTextRunFragment> mParts;
// A dummy to handle parts of the DrawTarget impl we don't care for
RefPtr<DrawTarget> mCurrentTarget;
+ // Whether Tofu or SVG fonts were encountered
+ bool mHasUnsupportedFeatures;
+
// The rest of this is dummy implementations of DrawTarget's API
public:
DrawTargetType GetType() const override {
return DrawTargetType::SOFTWARE_RASTER;
}
BackendType GetBackendType() const override {
return BackendType::WEBRENDER_TEXT;