Bug 1403261 - enable native webrender handling of partial ligatures. r?mstange draft
authorAlexis Beingessner <a.beingessner@gmail.com>
Mon, 16 Apr 2018 23:05:48 -0400
changeset 784098 d2417021f6bc67787fb3eb3482e0685eed4170c5
parent 782366 e96685584bf7d3c1d7a4c1861716da89fd650c51
child 784370 29172dea87ecb71554e196cdcace3b9cf9a70efb
push id106854
push userbmo:a.beingessner@gmail.com
push dateWed, 18 Apr 2018 05:19:34 +0000
reviewersmstange
bugs1403261
milestone61.0a1
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
gfx/thebes/gfxTextRun.cpp
layout/generic/TextDrawTarget.h
layout/generic/nsTextFrame.cpp
--- 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)