Bug 1307402 - use a more precise bounding box for initial letter texts. r=jfkthame
authorJeremy Chen <jeremychen@mozilla.com>
Tue, 04 Oct 2016 22:22:52 +0800
changeset 316406 232fa9688147213a976a7c5e8934a8d4b04bd524
parent 316405 c900a87c5e1f607ec09ef598ecc4e22b7edeed41
child 316407 d8a271c72525309029b952075dcbdb9b2f1a284a
push id30770
push userkwierso@gmail.com
push dateWed, 05 Oct 2016 00:00:48 +0000
treeherdermozilla-central@3470e326025c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjfkthame
bugs1307402
milestone52.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1307402 - use a more precise bounding box for initial letter texts. r=jfkthame MozReview-Commit-ID: 5OIXp0uQisn
layout/generic/nsFirstLetterFrame.cpp
layout/generic/nsTextFrame.cpp
layout/generic/nsTextFrame.h
--- a/layout/generic/nsFirstLetterFrame.cpp
+++ b/layout/generic/nsFirstLetterFrame.cpp
@@ -251,17 +251,23 @@ nsFirstLetterFrame::Reflow(nsPresContext
     ll->ReflowFrame(kid, aReflowStatus, &kidMetrics, pushedFrame);
     NS_ASSERTION(lineWM.IsVertical() == wm.IsVertical(),
                  "we're assuming we can mix sizes between lineWM and wm "
                  "since we shouldn't have orthogonal writing modes within "
                  "a line.");
     aMetrics.ISize(lineWM) = ll->EndSpan(this) + bp.IStartEnd(wm);
     ll->SetInFirstLetter(false);
 
-    nsLayoutUtils::SetBSizeFromFontMetrics(this, aMetrics, bp, lineWM, wm);
+    if (mStyleContext->StyleTextReset()->mInitialLetterSize != 0.0f) {
+      aMetrics.SetBlockStartAscent(kidMetrics.BlockStartAscent() +
+                                   bp.BStart(wm));
+      aMetrics.BSize(lineWM) = kidMetrics.BSize(lineWM) + bp.BStartEnd(wm);
+    } else {
+      nsLayoutUtils::SetBSizeFromFontMetrics(this, aMetrics, bp, lineWM, wm);
+    }
   }
 
   if (!NS_INLINE_IS_BREAK_BEFORE(aReflowStatus)) {
     // Create a continuation or remove existing continuations based on
     // the reflow completion status.
     if (NS_FRAME_IS_COMPLETE(aReflowStatus)) {
       if (aReflowInput.mLineLayout) {
         aReflowInput.mLineLayout->SetFirstLetterStyleOK(false);
--- a/layout/generic/nsTextFrame.cpp
+++ b/layout/generic/nsTextFrame.cpp
@@ -8767,16 +8767,24 @@ nsTextFrame::SetLength(int32_t aLength, 
 bool
 nsTextFrame::IsFloatingFirstLetterChild() const
 {
   nsIFrame* frame = GetParent();
   return frame && frame->IsFloating() &&
          frame->GetType() == nsGkAtoms::letterFrame;
 }
 
+bool
+nsTextFrame::IsInitialLetterChild() const
+{
+  nsIFrame* frame = GetParent();
+  return frame && frame->StyleTextReset()->mInitialLetterSize != 0.0f &&
+         frame->GetType() == nsGkAtoms::letterFrame;
+}
+
 struct NewlineProperty {
   int32_t mStartOffset;
   // The offset of the first \n after mStartOffset, or -1 if there is none
   int32_t mNewlineOffset;
 };
 
 void
 nsTextFrame::Reflow(nsPresContext*           aPresContext,
@@ -9045,19 +9053,20 @@ nsTextFrame::ReflowText(nsLineLayout& aL
     : -1;
   PropertyProvider provider(mTextRun, textStyle, frag, this, iter, length,
       lineContainer, xOffsetForTabs, nsTextFrame::eInflated);
 
   uint32_t transformedOffset = provider.GetStart().GetSkippedOffset();
 
   // The metrics for the text go in here
   gfxTextRun::Metrics textMetrics;
-  gfxFont::BoundingBoxType boundingBoxType = IsFloatingFirstLetterChild() ?
-                                               gfxFont::TIGHT_HINTED_OUTLINE_EXTENTS :
-                                               gfxFont::LOOSE_INK_EXTENTS;
+  gfxFont::BoundingBoxType boundingBoxType =
+    IsFloatingFirstLetterChild() || IsInitialLetterChild()
+    ? gfxFont::TIGHT_HINTED_OUTLINE_EXTENTS
+    : gfxFont::LOOSE_INK_EXTENTS;
   NS_ASSERTION(!(NS_REFLOW_CALC_BOUNDING_METRICS & aMetrics.mFlags),
                "We shouldn't be passed NS_REFLOW_CALC_BOUNDING_METRICS anymore");
 
   int32_t limitLength = length;
   int32_t forceBreak = aLineLayout.GetForcedBreakPosition(this);
   bool forceBreakAfter = false;
   if (forceBreak >= length) {
     forceBreakAfter = forceBreak == length;
--- a/layout/generic/nsTextFrame.h
+++ b/layout/generic/nsTextFrame.h
@@ -582,16 +582,18 @@ public:
 
   // Similar to Reflow(), but for use from nsLineLayout
   void ReflowText(nsLineLayout& aLineLayout, nscoord aAvailableWidth,
                   DrawTarget* aDrawTarget,
                   ReflowOutput& aMetrics, nsReflowStatus& aStatus);
 
   bool IsFloatingFirstLetterChild() const;
 
+  bool IsInitialLetterChild() const;
+
   virtual bool ComputeCustomOverflow(nsOverflowAreas& aOverflowAreas) override;
 
   void AssignJustificationGaps(const mozilla::JustificationAssignment& aAssign);
   mozilla::JustificationAssignment GetJustificationAssignment() const;
 
   uint32_t CountGraphemeClusters() const;
 
 protected: