Bug 1265715 - Part 3. Use nsLayoutUtils::PaintFrame in ClipBackgroundByText; draft
authorCJKu <cku@mozilla.com>
Tue, 26 Apr 2016 00:26:51 +0800
changeset 356095 6d5d04aaf309a41901bc9b6e0fc6356b9042e9ed
parent 356094 e65845c9dd52d2c8b90e6c6b4bc18876b9a93305
child 356096 166ad560441e1f4439cfcd25b08dd71dfff36171
push id16433
push usercku@mozilla.com
push dateMon, 25 Apr 2016 16:28:06 +0000
bugs1265715
milestone48.0a1
Bug 1265715 - Part 3. Use nsLayoutUtils::PaintFrame in ClipBackgroundByText; MozReview-Commit-ID: LRh54GNT0qW
layout/base/nsDisplayList.cpp
layout/base/nsLayoutUtils.cpp
--- a/layout/base/nsDisplayList.cpp
+++ b/layout/base/nsDisplayList.cpp
@@ -488,58 +488,38 @@ AddAnimationsForProperty(nsIFrame* aFram
 
     AddAnimationForProperty(aFrame, *property, anim, aLayer, aData, aPending);
     effect->SetIsRunningOnCompositor(aProperty, true);
   }
 }
 
 static void
 ClipBackgroundByText(nsIFrame* aFrame, nsRenderingContext* aContext,
-                     const gfxRect& aFillRect)
+                     const nsRect& aFillRect)
 {
   // The main function of enabling background-clip:text property value.
   // When a nsDisplayBackgroundImage detects "text" bg-clip style, it will call
   // this function to
   // 1. Ask every text frame objects in aFrame puts glyph paths into aContext.
-  // 2. Then, clip aContext.
+  // 2. Clip aContext.
   //
   // Then, nsDisplayBackgroundImage paints bg-images into this clipped region,
   // so we get images embedded in text shape!
 
-  nsDisplayListBuilder builder(aFrame, nsDisplayListBuilderMode::GENERATE_GLYPH, false);
-
-  builder.EnterPresShell(aFrame);
-  nsDisplayList list;
-  aFrame->BuildDisplayListForStackingContext(&builder,
-                                      nsRect(nsPoint(0, 0), aFrame->GetSize()),
-                                      &list);
-  builder.LeavePresShell(aFrame);
-
-#ifdef DEBUG
-  // ClipBackgroundByText is called by nsDisplayBackgroundImage::Paint or
-  // nsDisplayBackgroundColor::Paint.
-  // Assert that we do not generate and put nsDisplayBackgroundImage or
-  // nsDisplayBackgroundColor into the list again, which would lead to
-  // infinite recursion.
-  for (nsDisplayItem* i = list.GetBottom(); i; i = i->GetAbove()) {
-    MOZ_ASSERT(nsDisplayItem::TYPE_BACKGROUND != i->GetType() &&
-               nsDisplayItem::TYPE_BACKGROUND_COLOR != i->GetType());
-  }
-#endif
-
   gfxContext* ctx = aContext->ThebesContext();
   gfxContextMatrixAutoSaveRestore save(ctx);
-  ctx->SetMatrix(ctx->CurrentMatrix().Translate(aFillRect.TopLeft()));
+  gfxRect bounds = nsLayoutUtils::RectToGfxRect(aFillRect, aFrame->PresContext()->AppUnitsPerDevPixel());
+  ctx->SetMatrix(ctx->CurrentMatrix().Translate(bounds.TopLeft()));
   ctx->NewPath();
 
-  RefPtr<LayerManager> layerManager =
-    list.PaintRoot(&builder, aContext, nsDisplayList::PAINT_DEFAULT);
+  nsLayoutUtils::PaintFrame(aContext, aFrame, aFrame->GetRect(),
+                            NS_RGB(255, 255, 255),
+                            nsDisplayListBuilderMode::GENERATE_GLYPH, 0);
 
   ctx->Clip();
-  list.DeleteAll();
 }
 
 /* static */ void
 nsDisplayListBuilder::AddAnimationsAndTransitionsToLayer(Layer* aLayer,
                                                          nsDisplayListBuilder* aBuilder,
                                                          nsDisplayItem* aItem,
                                                          nsIFrame* aFrame,
                                                          nsCSSProperty aProperty)
@@ -2936,19 +2916,18 @@ nsDisplayBackgroundImage::PaintInternal(
   uint32_t flags = aBuilder->GetBackgroundPaintFlags();
   CheckForBorderItem(this, flags);
 
   nsRect borderBox = nsRect(ToReferenceFrame(), mFrame->GetSize());
   gfxContext* ctx = aCtx->ThebesContext();
   uint8_t clip = mBackgroundStyle->mImage.mLayers[mLayer].mClip;
 
   if (clip == NS_STYLE_IMAGELAYER_CLIP_TEXT) {
-    gfxRect bounds = nsLayoutUtils::RectToGfxRect(borderBox, mFrame->PresContext()->AppUnitsPerDevPixel());
     ctx->Save();
-    ClipBackgroundByText(mFrame, aCtx, bounds);
+    ClipBackgroundByText(mFrame, aCtx, borderBox);
   }
 
   image::DrawResult result =
     nsCSSRendering::PaintBackground(mFrame->PresContext(), *aCtx, mFrame,
                                     aBounds,
                                     borderBox,
                                     flags, aClipRect, mLayer,
                                     CompositionOp::OP_OVER);
@@ -3367,30 +3346,30 @@ nsDisplayBackgroundColor::Paint(nsDispla
   Rect rect = NSRectToSnappedRect(borderBox,
                                   mFrame->PresContext()->AppUnitsPerDevPixel(),
                                   aDrawTarget);
   ColorPattern color(ToDeviceColor(mColor));
   aDrawTarget.FillRect(rect, color);
 #else
   gfxContext* ctx = aCtx->ThebesContext();
 
-  gfxRect bounds =
-    nsLayoutUtils::RectToGfxRect(borderBox, mFrame->PresContext()->AppUnitsPerDevPixel());
-
   uint8_t clip = mBackgroundStyle->mImage.mLayers[0].mClip;
   if (clip == NS_STYLE_IMAGELAYER_CLIP_TEXT) {
     gfxContextAutoSaveRestore save(ctx);
 
-    ClipBackgroundByText(mFrame, aCtx, bounds);
+    ClipBackgroundByText(mFrame, aCtx, borderBox);
     ctx->SetColor(mColor);
     ctx->Fill();
 
     return;
   }
 
+  gfxRect bounds =
+    nsLayoutUtils::RectToGfxRect(borderBox, mFrame->PresContext()->AppUnitsPerDevPixel());
+
   ctx->SetColor(mColor);
   ctx->NewPath();
   ctx->Rectangle(bounds, true);
   ctx->Fill();
 #endif
 }
 
 nsRegion
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -3437,16 +3437,30 @@ nsLayoutUtils::PaintFrame(nsRenderingCon
 #endif
 
     nsDisplayListBuilder::AutoCurrentScrollParentIdSetter idSetter(&builder, id);
 
     PROFILER_LABEL("nsLayoutUtils", "PaintFrame::BuildDisplayList",
       js::ProfileEntry::Category::GRAPHICS);
 
     aFrame->BuildDisplayListForStackingContext(&builder, dirtyRect, &list);
+#ifdef DEBUG
+    if (builder.IsForGenerateGlyphPath()) {
+      // PaintFrame is called to generate text glyph by
+      // nsDisplayBackgroundImage::Paint or nsDisplayBackgroundColor::Paint.
+      //
+      // Assert that we do not generate and put nsDisplayBackgroundImage or
+      // nsDisplayBackgroundColor into the list again, which would lead to
+      // infinite recursion.
+      for (nsDisplayItem* i = list.GetBottom(); i; i = i->GetAbove()) {
+        MOZ_ASSERT(nsDisplayItem::TYPE_BACKGROUND != i->GetType() &&
+                   nsDisplayItem::TYPE_BACKGROUND_COLOR != i->GetType());
+      }
+    }
+#endif
   }
 
   nsIAtom* frameType = aFrame->GetType();
 
   // For the viewport frame in print preview/page layout we want to paint
   // the grey background behind the page, not the canvas color.
   if (frameType == nsGkAtoms::viewportFrame &&
       nsLayoutUtils::NeedsPrintPreviewBackground(presContext)) {