Bug 1403261 - enable native webrender handling of partial ligatures. r?mstange
The clipping code uses gfxContext::GetClipExtents which calls gfxContext::GetDeviceOffset
and DrawTarget::GetSize. The former was previously not being intialized, while the latter
was explicitly unimplemented. This patch fixes both of those facts.
Otherwise, enabling this functionality has been made trivial by several upstream patches
in webrender (the most recent being glenn's work on unifying shadows which eliminated
the buggy text-shadow shader code that was blocking this).
MozReview-Commit-ID: B1AlG3o4XQS
--- a/gfx/thebes/gfxTextRun.cpp
+++ b/gfx/thebes/gfxTextRun.cpp
@@ -467,21 +467,16 @@ gfxTextRun::DrawPartialLigature(gfxFont*
gfx::Point* aPt, PropertyProvider* aProvider,
TextRunDrawParams& aParams,
gfx::ShapedTextFlags aOrientation) const
{
if (aRange.start >= aRange.end) {
return;
}
- if (auto* textDrawer = aParams.context->GetTextDrawer()) {
- textDrawer->FoundUnsupportedFeature();
- return;
- }
-
// Draw partial ligature. We hack this by clipping the ligature.
LigatureData data = ComputeLigatureData(aRange, aProvider);
gfxRect clipExtents = aParams.context->GetClipExtents();
gfxFloat start, end;
if (aParams.isVerticalRun) {
start = clipExtents.Y() * mAppUnitsPerDevUnit;
end = clipExtents.YMost() * mAppUnitsPerDevUnit;
ClipPartialLigature(this, &start, &end, aPt->y, &data);
--- a/layout/generic/TextDrawTarget.h
+++ b/layout/generic/TextDrawTarget.h
@@ -63,16 +63,17 @@ public:
LayoutDeviceRect layoutBoundsRect = LayoutDeviceRect::FromAppUnits(
aBounds, appUnitsPerDevPixel);
LayoutDeviceRect layoutClipRect = layoutBoundsRect;
mBoundsRect = wr::ToRoundedLayoutRect(layoutBoundsRect);
// Add 1 pixel of dirty area around clip rect to allow us to paint
// antialiased pixels beyond the measured text extents.
layoutClipRect.Inflate(1);
+ mSize = IntSize::Ceil(layoutClipRect.Width(), layoutClipRect.Height());
mClipStack.AppendElement(layoutClipRect);
mBackfaceVisible = !aItem->BackfaceIsHidden();
mBuilder.Save();
}
// Prevent this from being copied
@@ -183,16 +184,20 @@ public:
mClipStack.AppendElement(rect);
}
void
PopClip() override {
mClipStack.RemoveLastElement();
}
+ IntSize GetSize() const override {
+ return mSize;
+ }
+
void
AppendShadow(const wr::Shadow& aShadow)
{
mBuilder.PushShadow(mBoundsRect, ClipRect(), mBackfaceVisible, aShadow);
mHasShadows = true;
}
void
@@ -317,16 +322,17 @@ private:
bool mHasShadows = false;
// Things used to push to webrender
wr::DisplayListBuilder& mBuilder;
const layers::StackingContextHelper& mSc;
layers::WebRenderLayerManager* mManager;
// Computed facts
+ IntSize mSize;
wr::LayerRect mBoundsRect;
nsTArray<LayoutDeviceRect> mClipStack;
bool mBackfaceVisible;
wr::FontInstanceFlags mWRGlyphFlags = {0};
// The rest of this is dummy implementations of DrawTarget's API
public:
@@ -347,21 +353,16 @@ public:
}
already_AddRefed<SourceSurface> IntoLuminanceSource(LuminanceType aLuminanceType,
float aOpacity) override {
MOZ_CRASH("TextDrawTarget: Method shouldn't be called");
return nullptr;
}
- IntSize GetSize() const override {
- MOZ_CRASH("TextDrawTarget: Method shouldn't be called");
- return IntSize(1, 1);
- }
-
void Flush() override {
MOZ_CRASH("TextDrawTarget: Method shouldn't be called");
}
void DrawCapturedDT(DrawTargetCapture *aCaptureDT,
const Matrix& aTransform) override {
MOZ_CRASH("TextDrawTarget: Method shouldn't be called");
}
--- a/layout/generic/nsTextFrame.cpp
+++ b/layout/generic/nsTextFrame.cpp
@@ -5096,18 +5096,23 @@ nsDisplayText::CreateWebRenderCommands(m
const StackingContextHelper& aSc,
WebRenderLayerManager* aManager,
nsDisplayListBuilder* aDisplayListBuilder)
{
if (mBounds.IsEmpty()) {
return true;
}
+
+ auto appUnitsPerDevPixel = Frame()->PresContext()->AppUnitsPerDevPixel();
+ gfx::Point deviceOffset = LayoutDevicePoint::FromAppUnits(
+ mBounds.TopLeft(), appUnitsPerDevPixel).ToUnknownPoint();
+
RefPtr<TextDrawTarget> textDrawer = new TextDrawTarget(aBuilder, aSc, aManager, this, mBounds);
- RefPtr<gfxContext> captureCtx = gfxContext::CreateOrNull(textDrawer);
+ RefPtr<gfxContext> captureCtx = gfxContext::CreateOrNull(textDrawer, deviceOffset);
RenderToContext(captureCtx, aDisplayListBuilder, true);
return !textDrawer->HasUnsupportedFeatures();
}
void
nsDisplayText::RenderToContext(gfxContext* aCtx, nsDisplayListBuilder* aBuilder, bool aIsRecording)