Use out-of-band messaging for RenderBox::firstLineBaseline() and RenderBox::inlineBlo...
authormmaxfield@apple.com <mmaxfield@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 11 Mar 2015 18:22:06 +0000 (18:22 +0000)
committermmaxfield@apple.com <mmaxfield@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 11 Mar 2015 18:22:06 +0000 (18:22 +0000)
https://bugs.webkit.org/show_bug.cgi?id=142569

Reviewed by David Hyatt.

Source/WebCore:

Currently, RenderBox::firstLineBaseline() and RenderBox::inlineBlockBaseline() return -1 to mean
that its baseline should be skipped. Instead of using this sentinel value, this patch changes the
return type from int to Optional<int>.

No new tests because there is no behavior change.

* rendering/RenderBlock.cpp:
(WebCore::RenderBlock::baselinePosition):
(WebCore::RenderBlock::firstLineBaseline):
(WebCore::RenderBlock::inlineBlockBaseline):
* rendering/RenderBlock.h:
* rendering/RenderBlockFlow.cpp:
(WebCore::RenderBlockFlow::firstLineBaseline):
(WebCore::RenderBlockFlow::inlineBlockBaseline):
* rendering/RenderBlockFlow.h:
* rendering/RenderBox.h:
(WebCore::RenderBox::firstLineBaseline):
(WebCore::RenderBox::inlineBlockBaseline):
* rendering/RenderDeprecatedFlexibleBox.cpp:
(WebCore::RenderDeprecatedFlexibleBox::layoutHorizontalBox):
* rendering/RenderFlexibleBox.cpp:
(WebCore::RenderFlexibleBox::baselinePosition):
(WebCore::RenderFlexibleBox::firstLineBaseline):
(WebCore::RenderFlexibleBox::inlineBlockBaseline):
(WebCore::RenderFlexibleBox::marginBoxAscentForChild):
* rendering/RenderFlexibleBox.h:
* rendering/RenderMenuList.h:
* rendering/RenderTable.cpp:
(WebCore::RenderTable::cellAbove):
(WebCore::RenderTable::cellBelow):
(WebCore::RenderTable::cellBefore):
(WebCore::RenderTable::cellAfter):
(WebCore::RenderTable::firstLineBlock):
(WebCore::RenderTable::baselinePosition):
(WebCore::RenderTable::inlineBlockBaseline):
(WebCore::RenderTable::firstLineBaseline):
* rendering/RenderTable.h:
* rendering/RenderTableCell.cpp:
(WebCore::RenderTableCell::cellBaselinePosition):
* rendering/RenderTableSection.cpp:
(WebCore::RenderTableSection::firstLineBaseline):
* rendering/RenderTableSection.h:
* rendering/RenderTextControl.h:
* rendering/mathml/RenderMathMLBlock.cpp:
(WebCore::RenderMathMLBlock::baselinePosition):
(WebCore::RenderMathMLTable::firstLineBaseline):
* rendering/mathml/RenderMathMLBlock.h:
* rendering/mathml/RenderMathMLFraction.cpp:
(WebCore::RenderMathMLFraction::firstLineBaseline):
* rendering/mathml/RenderMathMLFraction.h:
* rendering/mathml/RenderMathMLOperator.cpp:
(WebCore::RenderMathMLOperator::firstLineBaseline):
* rendering/mathml/RenderMathMLOperator.h:
* rendering/mathml/RenderMathMLRoot.cpp:
(WebCore::RenderMathMLRoot::firstLineBaseline):
(WebCore::RenderMathMLRoot::layout):
* rendering/mathml/RenderMathMLRoot.h:
* rendering/mathml/RenderMathMLRow.cpp:
(WebCore::RenderMathMLRow::layout):
* rendering/mathml/RenderMathMLScripts.cpp:
(WebCore::RenderMathMLScripts::layout):
(WebCore::RenderMathMLScripts::firstLineBaseline):
* rendering/mathml/RenderMathMLScripts.h:
* rendering/mathml/RenderMathMLSpace.cpp:
(WebCore::RenderMathMLSpace::firstLineBaseline):
* rendering/mathml/RenderMathMLSpace.h:
* rendering/mathml/RenderMathMLUnderOver.cpp:
(WebCore::RenderMathMLUnderOver::firstLineBaseline):
* rendering/mathml/RenderMathMLUnderOver.h:

Source/WTF:

Provide a callback to Optional::valueOrCompute() which is evaluated only if necessary.

* wtf/Optional.h:
(WTF::Optional::valueOrCompute):

Tools:

Test Optional::valueOrCompute().

* TestWebKitAPI/Tests/WTF/Optional.cpp:
(TestWebKitAPI::TEST):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@181398 268f45cc-cd09-0410-ab3c-d52691b4dbfc

35 files changed:
Source/WTF/ChangeLog
Source/WTF/wtf/Optional.h
Source/WebCore/ChangeLog
Source/WebCore/rendering/RenderBlock.cpp
Source/WebCore/rendering/RenderBlock.h
Source/WebCore/rendering/RenderBlockFlow.cpp
Source/WebCore/rendering/RenderBlockFlow.h
Source/WebCore/rendering/RenderBox.h
Source/WebCore/rendering/RenderDeprecatedFlexibleBox.cpp
Source/WebCore/rendering/RenderFlexibleBox.cpp
Source/WebCore/rendering/RenderFlexibleBox.h
Source/WebCore/rendering/RenderMenuList.h
Source/WebCore/rendering/RenderTable.cpp
Source/WebCore/rendering/RenderTable.h
Source/WebCore/rendering/RenderTableCell.cpp
Source/WebCore/rendering/RenderTableSection.cpp
Source/WebCore/rendering/RenderTableSection.h
Source/WebCore/rendering/RenderTextControl.h
Source/WebCore/rendering/mathml/RenderMathMLBlock.cpp
Source/WebCore/rendering/mathml/RenderMathMLBlock.h
Source/WebCore/rendering/mathml/RenderMathMLFraction.cpp
Source/WebCore/rendering/mathml/RenderMathMLFraction.h
Source/WebCore/rendering/mathml/RenderMathMLOperator.cpp
Source/WebCore/rendering/mathml/RenderMathMLOperator.h
Source/WebCore/rendering/mathml/RenderMathMLRoot.cpp
Source/WebCore/rendering/mathml/RenderMathMLRoot.h
Source/WebCore/rendering/mathml/RenderMathMLRow.cpp
Source/WebCore/rendering/mathml/RenderMathMLScripts.cpp
Source/WebCore/rendering/mathml/RenderMathMLScripts.h
Source/WebCore/rendering/mathml/RenderMathMLSpace.cpp
Source/WebCore/rendering/mathml/RenderMathMLSpace.h
Source/WebCore/rendering/mathml/RenderMathMLUnderOver.cpp
Source/WebCore/rendering/mathml/RenderMathMLUnderOver.h
Tools/ChangeLog
Tools/TestWebKitAPI/Tests/WTF/Optional.cpp

index ef0dcb9..e028714 100644 (file)
@@ -1,3 +1,15 @@
+2015-03-11  Myles C. Maxfield  <mmaxfield@apple.com>
+
+        Use out-of-band messaging for RenderBox::firstLineBaseline() and RenderBox::inlineBlockBaseline()
+        https://bugs.webkit.org/show_bug.cgi?id=142569
+
+        Reviewed by David Hyatt.
+
+        Provide a callback to Optional::valueOrCompute() which is evaluated only if necessary.
+
+        * wtf/Optional.h:
+        (WTF::Optional::valueOrCompute):
+
 2015-03-10  Brent Fulgham  <bfulgham@apple.com>
 
         [Win] 17 different JSC tests started to fail in DST
index af84617..8e7dbbe 100644 (file)
@@ -154,6 +154,15 @@ public:
         return std::forward<U>(value);
     }
 
+    template<typename U>
+    T valueOrCompute(U callback) const
+    {
+        if (m_isEngaged)
+            return *asPtr();
+
+        return callback();
+    }
+
 private:
     const T* asPtr() const { return reinterpret_cast<const T*>(&m_value); }
     T* asPtr() { return reinterpret_cast<T*>(&m_value); }
index e726848..d234671 100644 (file)
@@ -1,3 +1,80 @@
+2015-03-11  Myles C. Maxfield  <mmaxfield@apple.com>
+
+        Use out-of-band messaging for RenderBox::firstLineBaseline() and RenderBox::inlineBlockBaseline()
+        https://bugs.webkit.org/show_bug.cgi?id=142569
+
+        Reviewed by David Hyatt.
+
+        Currently, RenderBox::firstLineBaseline() and RenderBox::inlineBlockBaseline() return -1 to mean
+        that its baseline should be skipped. Instead of using this sentinel value, this patch changes the
+        return type from int to Optional<int>.
+
+        No new tests because there is no behavior change.
+
+        * rendering/RenderBlock.cpp:
+        (WebCore::RenderBlock::baselinePosition):
+        (WebCore::RenderBlock::firstLineBaseline):
+        (WebCore::RenderBlock::inlineBlockBaseline):
+        * rendering/RenderBlock.h:
+        * rendering/RenderBlockFlow.cpp:
+        (WebCore::RenderBlockFlow::firstLineBaseline):
+        (WebCore::RenderBlockFlow::inlineBlockBaseline):
+        * rendering/RenderBlockFlow.h:
+        * rendering/RenderBox.h:
+        (WebCore::RenderBox::firstLineBaseline):
+        (WebCore::RenderBox::inlineBlockBaseline):
+        * rendering/RenderDeprecatedFlexibleBox.cpp:
+        (WebCore::RenderDeprecatedFlexibleBox::layoutHorizontalBox):
+        * rendering/RenderFlexibleBox.cpp:
+        (WebCore::RenderFlexibleBox::baselinePosition):
+        (WebCore::RenderFlexibleBox::firstLineBaseline):
+        (WebCore::RenderFlexibleBox::inlineBlockBaseline):
+        (WebCore::RenderFlexibleBox::marginBoxAscentForChild):
+        * rendering/RenderFlexibleBox.h:
+        * rendering/RenderMenuList.h:
+        * rendering/RenderTable.cpp:
+        (WebCore::RenderTable::cellAbove):
+        (WebCore::RenderTable::cellBelow):
+        (WebCore::RenderTable::cellBefore):
+        (WebCore::RenderTable::cellAfter):
+        (WebCore::RenderTable::firstLineBlock):
+        (WebCore::RenderTable::baselinePosition):
+        (WebCore::RenderTable::inlineBlockBaseline):
+        (WebCore::RenderTable::firstLineBaseline):
+        * rendering/RenderTable.h:
+        * rendering/RenderTableCell.cpp:
+        (WebCore::RenderTableCell::cellBaselinePosition):
+        * rendering/RenderTableSection.cpp:
+        (WebCore::RenderTableSection::firstLineBaseline):
+        * rendering/RenderTableSection.h:
+        * rendering/RenderTextControl.h:
+        * rendering/mathml/RenderMathMLBlock.cpp:
+        (WebCore::RenderMathMLBlock::baselinePosition):
+        (WebCore::RenderMathMLTable::firstLineBaseline):
+        * rendering/mathml/RenderMathMLBlock.h:
+        * rendering/mathml/RenderMathMLFraction.cpp:
+        (WebCore::RenderMathMLFraction::firstLineBaseline):
+        * rendering/mathml/RenderMathMLFraction.h:
+        * rendering/mathml/RenderMathMLOperator.cpp:
+        (WebCore::RenderMathMLOperator::firstLineBaseline):
+        * rendering/mathml/RenderMathMLOperator.h:
+        * rendering/mathml/RenderMathMLRoot.cpp:
+        (WebCore::RenderMathMLRoot::firstLineBaseline):
+        (WebCore::RenderMathMLRoot::layout):
+        * rendering/mathml/RenderMathMLRoot.h:
+        * rendering/mathml/RenderMathMLRow.cpp:
+        (WebCore::RenderMathMLRow::layout):
+        * rendering/mathml/RenderMathMLScripts.cpp:
+        (WebCore::RenderMathMLScripts::layout):
+        (WebCore::RenderMathMLScripts::firstLineBaseline):
+        * rendering/mathml/RenderMathMLScripts.h:
+        * rendering/mathml/RenderMathMLSpace.cpp:
+        (WebCore::RenderMathMLSpace::firstLineBaseline):
+        * rendering/mathml/RenderMathMLSpace.h:
+        * rendering/mathml/RenderMathMLUnderOver.cpp:
+        (WebCore::RenderMathMLUnderOver::firstLineBaseline):
+        * rendering/mathml/RenderMathMLUnderOver.h:
+
 2015-03-11  Timothy Horton  <timothy_horton@apple.com>
 
         <attachment>s should be created when dropping files onto contentEditable areas
index ede343f..fa604bf 100644 (file)
@@ -2848,7 +2848,7 @@ int RenderBlock::baselinePosition(FontBaseline baselineType, bool firstLine, Lin
         bool ignoreBaseline = (layer() && (layer()->marquee() || (direction == HorizontalLine ? (layer()->verticalScrollbar() || layer()->scrollYOffset() != 0)
             : (layer()->horizontalScrollbar() || layer()->scrollXOffset() != 0)))) || (isWritingModeRoot() && !isRubyRun());
         
-        int baselinePos = ignoreBaseline ? -1 : inlineBlockBaseline(direction);
+        Optional<int> baselinePos = ignoreBaseline ? Optional<int>() : inlineBlockBaseline(direction);
         
         if (isDeprecatedFlexibleBox()) {
             // Historically, we did this check for all baselines. But we can't
@@ -2857,11 +2857,11 @@ int RenderBlock::baselinePosition(FontBaseline baselineType, bool firstLine, Lin
             // calculate the baseline as if -webkit-line-clamp wasn't used.
             // For simplicity, we use this for all uses of deprecated flexbox.
             LayoutUnit bottomOfContent = direction == HorizontalLine ? borderTop() + paddingTop() + contentHeight() : borderRight() + paddingRight() + contentWidth();
-            if (baselinePos > bottomOfContent)
-                baselinePos = -1;
+            if (baselinePos && baselinePos.value() > bottomOfContent)
+                baselinePos = Optional<int>();
         }
-        if (baselinePos != -1)
-            return direction == HorizontalLine ? marginTop() + baselinePos : marginRight() + baselinePos;
+        if (baselinePos)
+            return direction == HorizontalLine ? marginTop() + baselinePos.value() : marginRight() + baselinePos.value();
 
         return RenderBox::baselinePosition(baselineType, firstLine, direction, linePositionMode);
     }
@@ -2883,45 +2883,43 @@ LayoutUnit RenderBlock::minLineHeightForReplacedRenderer(bool isFirstLine, Layou
     return std::max<LayoutUnit>(replacedHeight, lineHeight(isFirstLine, isHorizontalWritingMode() ? HorizontalLine : VerticalLine, PositionOfInteriorLineBoxes));
 }
 
-int RenderBlock::firstLineBaseline() const
+Optional<int> RenderBlock::firstLineBaseline() const
 {
     if (isWritingModeRoot() && !isRubyRun())
-        return -1;
+        return Optional<int>();
 
     for (RenderBox* curr = firstChildBox(); curr; curr = curr->nextSiblingBox()) {
         if (!curr->isFloatingOrOutOfFlowPositioned()) {
-            int result = curr->firstLineBaseline();
-            if (result != -1)
-                return curr->logicalTop() + result; // Translate to our coordinate space.
+            if (Optional<int> result = curr->firstLineBaseline())
+                return Optional<int>(curr->logicalTop() + result.value()); // Translate to our coordinate space.
         }
     }
 
-    return -1;
+    return Optional<int>();
 }
 
-int RenderBlock::inlineBlockBaseline(LineDirectionMode lineDirection) const
+Optional<int> RenderBlock::inlineBlockBaseline(LineDirectionMode lineDirection) const
 {
     if (isWritingModeRoot() && !isRubyRun())
-        return -1;
+        return Optional<int>();
 
     bool haveNormalFlowChild = false;
     for (auto box = lastChildBox(); box; box = box->previousSiblingBox()) {
         if (box->isFloatingOrOutOfFlowPositioned())
             continue;
         haveNormalFlowChild = true;
-        int result = box->inlineBlockBaseline(lineDirection);
-        if (result != -1)
-            return box->logicalTop() + result; // Translate to our coordinate space.
+        if (Optional<int> result = box->inlineBlockBaseline(lineDirection))
+            return Optional<int>(box->logicalTop() + result.value()); // Translate to our coordinate space.
     }
 
     if (!haveNormalFlowChild && hasLineIfEmpty()) {
         auto& fontMetrics = firstLineStyle().fontMetrics();
-        return fontMetrics.ascent()
-             + (lineHeight(true, lineDirection, PositionOfInteriorLineBoxes) - fontMetrics.height()) / 2
-             + (lineDirection == HorizontalLine ? borderTop() + paddingTop() : borderRight() + paddingRight());
+        return Optional<int>(fontMetrics.ascent()
+            + (lineHeight(true, lineDirection, PositionOfInteriorLineBoxes) - fontMetrics.height()) / 2
+            + (lineDirection == HorizontalLine ? borderTop() + paddingTop() : borderRight() + paddingRight()));
     }
 
-    return -1;
+    return Optional<int>();
 }
 
 static inline bool isRenderBlockFlowOrRenderButton(RenderElement& renderElement)
index 17e5202..3b49182 100644 (file)
@@ -346,8 +346,8 @@ protected:
     virtual void computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const override;
     virtual void computePreferredLogicalWidths() override;
     
-    virtual int firstLineBaseline() const override;
-    virtual int inlineBlockBaseline(LineDirectionMode) const override;
+    virtual Optional<int> firstLineBaseline() const override;
+    virtual Optional<int> inlineBlockBaseline(LineDirectionMode) const override;
 
     // Delay updating scrollbars until endAndCommitUpdateScrollInfoAfterLayoutTransaction() is called. These functions are used
     // when a flexbox is laying out its descendants. If multiple calls are made to beginUpdateScrollInfoAfterLayoutTransaction()
index 075a050..0cdd307 100644 (file)
@@ -2988,42 +2988,45 @@ void RenderBlockFlow::markLinesDirtyInBlockRange(LayoutUnit logicalTop, LayoutUn
     }
 }
 
-int RenderBlockFlow::firstLineBaseline() const
+Optional<int> RenderBlockFlow::firstLineBaseline() const
 {
     if (isWritingModeRoot() && !isRubyRun())
-        return -1;
+        return Optional<int>();
 
     if (!childrenInline())
         return RenderBlock::firstLineBaseline();
 
     if (!hasLines())
-        return -1;
+        return Optional<int>();
 
     if (auto simpleLineLayout = this->simpleLineLayout())
-        return SimpleLineLayout::computeFlowFirstLineBaseline(*this, *simpleLineLayout);
+        return Optional<int>(SimpleLineLayout::computeFlowFirstLineBaseline(*this, *simpleLineLayout));
 
     ASSERT(firstRootBox());
     return firstRootBox()->logicalTop() + firstLineStyle().fontMetrics().ascent(firstRootBox()->baselineType());
 }
 
-int RenderBlockFlow::inlineBlockBaseline(LineDirectionMode lineDirection) const
+Optional<int> RenderBlockFlow::inlineBlockBaseline(LineDirectionMode lineDirection) const
 {
     if (isWritingModeRoot() && !isRubyRun())
-        return -1;
+        return Optional<int>();
 
     // Note that here we only take the left and bottom into consideration. Our caller takes the right and top into consideration.
     float boxHeight = lineDirection == HorizontalLine ? height() + m_marginBox.bottom() : width() + m_marginBox.left();
     float lastBaseline;
-    if (!childrenInline())
-        lastBaseline = RenderBlock::inlineBlockBaseline(lineDirection);
-    else {
+    if (!childrenInline()) {
+        Optional<int> inlineBlockBaseline = RenderBlock::inlineBlockBaseline(lineDirection);
+        if (!inlineBlockBaseline)
+            return inlineBlockBaseline;
+        lastBaseline = inlineBlockBaseline.value();
+    } else {
         if (!hasLines()) {
             if (!hasLineIfEmpty())
-                return -1;
+                return Optional<int>();
             const auto& fontMetrics = firstLineStyle().fontMetrics();
-            return fontMetrics.ascent()
+            return Optional<int>(fontMetrics.ascent()
                 + (lineHeight(true, lineDirection, PositionOfInteriorLineBoxes) - fontMetrics.height()) / 2
-                + (lineDirection == HorizontalLine ? borderTop() + paddingTop() : borderRight() + paddingRight());
+                + (lineDirection == HorizontalLine ? borderTop() + paddingTop() : borderRight() + paddingRight()));
         }
 
         if (auto simpleLineLayout = this->simpleLineLayout())
@@ -3037,7 +3040,7 @@ int RenderBlockFlow::inlineBlockBaseline(LineDirectionMode lineDirection) const
     // According to the CSS spec http://www.w3.org/TR/CSS21/visudet.html, we shouldn't be performing this min, but should
     // instead be returning boxHeight directly. However, we feel that a min here is better behavior (and is consistent
     // enough with the spec to not cause tons of breakages).
-    return style().overflowY() == OVISIBLE ? lastBaseline : std::min(boxHeight, lastBaseline);
+    return Optional<int>(style().overflowY() == OVISIBLE ? lastBaseline : std::min(boxHeight, lastBaseline));
 }
 
 GapRects RenderBlockFlow::inlineSelectionGaps(RenderBlock& rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
index 2adfd70..330fd37 100644 (file)
@@ -444,8 +444,8 @@ protected:
 
     void createFloatingObjects();
 
-    virtual int firstLineBaseline() const override;
-    virtual int inlineBlockBaseline(LineDirectionMode) const override;
+    virtual Optional<int> firstLineBaseline() const override;
+    virtual Optional<int> inlineBlockBaseline(LineDirectionMode) const override;
 
     virtual bool isMultiColumnBlockFlow() const override { return multiColumnFlowThread(); }
     
index 5c7dbab..f24b21a 100644 (file)
@@ -521,8 +521,8 @@ public:
     
     RenderLayer* enclosingFloatPaintingLayer() const;
     
-    virtual int firstLineBaseline() const { return -1; }
-    virtual int inlineBlockBaseline(LineDirectionMode) const { return -1; } // Returns -1 if we should skip this box when computing the baseline of an inline-block.
+    virtual Optional<int> firstLineBaseline() const { return Optional<int>(); }
+    virtual Optional<int> inlineBlockBaseline(LineDirectionMode) const { return Optional<int>(); } // Returns empty if we should skip this box when computing the baseline of an inline-block.
 
     bool shrinkToAvoidFloats() const;
     virtual bool avoidsFloats() const;
index 2c1a507..97e7550 100644 (file)
@@ -433,9 +433,7 @@ void RenderDeprecatedFlexibleBox::layoutHorizontalBox(bool relayoutChildren)
 
             // Update our height and overflow height.
             if (style().boxAlign() == BBASELINE) {
-                LayoutUnit ascent = child->firstLineBaseline();
-                if (ascent == -1)
-                    ascent = child->height() + child->marginBottom();
+                LayoutUnit ascent = child->firstLineBaseline().valueOr(child->height() + child->marginBottom());
                 ascent += child->marginTop();
                 LayoutUnit descent = (child->height() + child->verticalMarginExtent()) - ascent;
 
@@ -510,9 +508,7 @@ void RenderDeprecatedFlexibleBox::layoutHorizontalBox(bool relayoutChildren)
                     childY += child->marginTop() + std::max<LayoutUnit>(0, (contentHeight() - (child->height() + child->verticalMarginExtent())) / 2);
                     break;
                 case BBASELINE: {
-                    LayoutUnit ascent = child->firstLineBaseline();
-                    if (ascent == -1)
-                        ascent = child->height() + child->marginBottom();
+                    LayoutUnit ascent = child->firstLineBaseline().valueOr(child->height() + child->marginBottom());
                     ascent += child->marginTop();
                     childY += child->marginTop() + (maxAscent - ascent);
                     break;
index 5f32e94..e9139b8 100644 (file)
@@ -169,18 +169,16 @@ static int synthesizedBaselineFromContentBox(const RenderBox& box, LineDirection
 
 int RenderFlexibleBox::baselinePosition(FontBaseline, bool, LineDirectionMode direction, LinePositionMode) const
 {
-    int baseline = firstLineBaseline();
-    if (baseline == -1)
-        baseline = synthesizedBaselineFromContentBox(*this, direction);
+    int baseline = firstLineBaseline().valueOr(synthesizedBaselineFromContentBox(*this, direction));
 
     int marginAscent = direction == HorizontalLine ? marginTop() : marginRight();
     return baseline + marginAscent;
 }
 
-int RenderFlexibleBox::firstLineBaseline() const
+Optional<int> RenderFlexibleBox::firstLineBaseline() const
 {
     if (isWritingModeRoot() || m_numberOfInFlowChildrenOnFirstLine <= 0)
-        return -1;
+        return Optional<int>();
     RenderBox* baselineChild = 0;
     int childNumber = 0;
     for (RenderBox* child = m_orderIterator.first(); child; child = m_orderIterator.next()) {
@@ -199,28 +197,27 @@ int RenderFlexibleBox::firstLineBaseline() const
     }
 
     if (!baselineChild)
-        return -1;
+        return Optional<int>();
 
     if (!isColumnFlow() && hasOrthogonalFlow(*baselineChild))
-        return crossAxisExtentForChild(*baselineChild) + baselineChild->logicalTop();
+        return Optional<int>(crossAxisExtentForChild(*baselineChild) + baselineChild->logicalTop());
     if (isColumnFlow() && !hasOrthogonalFlow(*baselineChild))
-        return mainAxisExtentForChild(*baselineChild) + baselineChild->logicalTop();
+        return Optional<int>(mainAxisExtentForChild(*baselineChild) + baselineChild->logicalTop());
 
-    int baseline = baselineChild->firstLineBaseline();
-    if (baseline == -1) {
+    Optional<int> baseline = baselineChild->firstLineBaseline();
+    if (!baseline) {
         // FIXME: We should pass |direction| into firstLineBoxBaseline and stop bailing out if we're a writing mode root.
         // This would also fix some cases where the flexbox is orthogonal to its container.
         LineDirectionMode direction = isHorizontalWritingMode() ? HorizontalLine : VerticalLine;
-        return synthesizedBaselineFromContentBox(*baselineChild, direction) + baselineChild->logicalTop();
+        return Optional<int>(synthesizedBaselineFromContentBox(*baselineChild, direction) + baselineChild->logicalTop());
     }
 
-    return baseline + baselineChild->logicalTop();
+    return Optional<int>(baseline.value() + baselineChild->logicalTop());
 }
 
-int RenderFlexibleBox::inlineBlockBaseline(LineDirectionMode direction) const
+Optional<int> RenderFlexibleBox::inlineBlockBaseline(LineDirectionMode direction) const
 {
-    int baseline = firstLineBaseline();
-    if (baseline != -1)
+    if (Optional<int> baseline = firstLineBaseline())
         return baseline;
 
     int marginAscent = direction == HorizontalLine ? marginTop() : marginRight();
@@ -818,9 +815,7 @@ bool RenderFlexibleBox::updateAutoMarginsInCrossAxis(RenderBox& child, LayoutUni
 
 LayoutUnit RenderFlexibleBox::marginBoxAscentForChild(RenderBox& child)
 {
-    LayoutUnit ascent = child.firstLineBaseline();
-    if (ascent == -1)
-        ascent = crossAxisExtentForChild(child);
+    LayoutUnit ascent = child.firstLineBaseline().valueOr(crossAxisExtentForChild(child));
     return ascent + flowAwareMarginBeforeForChild(child);
 }
 
index 6392573..bbbc3ed 100644 (file)
@@ -49,8 +49,8 @@ public:
     virtual void layoutBlock(bool relayoutChildren, LayoutUnit pageLogicalHeight = 0) override final;
 
     virtual int baselinePosition(FontBaseline, bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const override;
-    virtual int firstLineBaseline() const override;
-    virtual int inlineBlockBaseline(LineDirectionMode) const override;
+    virtual Optional<int> firstLineBaseline() const override;
+    virtual Optional<int> inlineBlockBaseline(LineDirectionMode) const override;
 
     virtual void paintChildren(PaintInfo& forSelf, const LayoutPoint&, PaintInfo& forChild, bool usePrintRect) override;
 
index 400bc7a..713dc2d 100644 (file)
@@ -123,8 +123,8 @@ private:
     {
         return RenderBlock::baselinePosition(baseline, firstLine, direction, position);
     }
-    virtual int firstLineBaseline() const override { return RenderBlock::firstLineBaseline(); }
-    virtual int inlineBlockBaseline(LineDirectionMode direction) const override { return RenderBlock::inlineBlockBaseline(direction); }
+    virtual Optional<int> firstLineBaseline() const override { return RenderBlock::firstLineBaseline(); }
+    virtual Optional<int> inlineBlockBaseline(LineDirectionMode direction) const override { return RenderBlock::inlineBlockBaseline(direction); }
 
     void getItemBackgroundColor(unsigned listIndex, Color&, bool& itemHasCustomBackgroundColor) const;
 
index c00c8d7..58f7828 100644 (file)
@@ -1332,7 +1332,7 @@ RenderTableCell* RenderTable::cellAbove(const RenderTableCell* cell) const
 
     // Find the section and row to look in
     unsigned r = cell->rowIndex();
-    RenderTableSection* section = 0;
+    RenderTableSection* section = nullptr;
     unsigned rAbove = 0;
     if (r > 0) {
         // cell is not in the first row, so use the above row in its own section
@@ -1352,7 +1352,7 @@ RenderTableCell* RenderTable::cellAbove(const RenderTableCell* cell) const
         RenderTableSection::CellStruct& aboveCell = section->cellAt(rAbove, effCol);
         return aboveCell.primaryCell();
     } else
-        return 0;
+        return nullptr;
 }
 
 RenderTableCell* RenderTable::cellBelow(const RenderTableCell* cell) const
@@ -1361,7 +1361,7 @@ RenderTableCell* RenderTable::cellBelow(const RenderTableCell* cell) const
 
     // Find the section and row to look in
     unsigned r = cell->rowIndex() + cell->rowSpan() - 1;
-    RenderTableSection* section = 0;
+    RenderTableSection* section = nullptr;
     unsigned rBelow = 0;
     if (r < cell->section()->numRows() - 1) {
         // The cell is not in the last row, so use the next row in the section.
@@ -1379,7 +1379,7 @@ RenderTableCell* RenderTable::cellBelow(const RenderTableCell* cell) const
         RenderTableSection::CellStruct& belowCell = section->cellAt(rBelow, effCol);
         return belowCell.primaryCell();
     } else
-        return 0;
+        return nullptr;
 }
 
 RenderTableCell* RenderTable::cellBefore(const RenderTableCell* cell) const
@@ -1389,7 +1389,7 @@ RenderTableCell* RenderTable::cellBefore(const RenderTableCell* cell) const
     RenderTableSection* section = cell->section();
     unsigned effCol = colToEffCol(cell->col());
     if (!effCol)
-        return 0;
+        return nullptr;
     
     // If we hit a colspan back up to a real cell.
     RenderTableSection::CellStruct& prevCell = section->cellAt(cell->rowIndex(), effCol - 1);
@@ -1402,13 +1402,13 @@ RenderTableCell* RenderTable::cellAfter(const RenderTableCell* cell) const
 
     unsigned effCol = colToEffCol(cell->col() + cell->colSpan());
     if (effCol >= numEffCols())
-        return 0;
+        return nullptr;
     return cell->section()->primaryCellAt(cell->rowIndex(), effCol);
 }
 
 RenderBlock* RenderTable::firstLineBlock() const
 {
-    return 0;
+    return nullptr;
 }
 
 void RenderTable::updateFirstLetter()
@@ -1417,40 +1417,37 @@ void RenderTable::updateFirstLetter()
 
 int RenderTable::baselinePosition(FontBaseline baselineType, bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const
 {
-    LayoutUnit baseline = firstLineBaseline();
-    if (baseline != -1)
-        return baseline;
-
-    return RenderBox::baselinePosition(baselineType, firstLine, direction, linePositionMode);
+    return firstLineBaseline().valueOrCompute([&] {
+        return RenderBox::baselinePosition(baselineType, firstLine, direction, linePositionMode);
+    });
 }
 
-int RenderTable::inlineBlockBaseline(LineDirectionMode) const
+Optional<int> RenderTable::inlineBlockBaseline(LineDirectionMode) const
 {
     // Tables are skipped when computing an inline-block's baseline.
-    return -1;
+    return Optional<int>();
 }
 
-int RenderTable::firstLineBaseline() const
+Optional<int> RenderTable::firstLineBaseline() const
 {
     // The baseline of a 'table' is the same as the 'inline-table' baseline per CSS 3 Flexbox (CSS 2.1
     // doesn't define the baseline of a 'table' only an 'inline-table').
     // This is also needed to properly determine the baseline of a cell if it has a table child.
 
     if (isWritingModeRoot())
-        return -1;
+        return Optional<int>();
 
     recalcSectionsIfNeeded();
 
     const RenderTableSection* topNonEmptySection = this->topNonEmptySection();
     if (!topNonEmptySection)
-        return -1;
+        return Optional<int>();
 
-    int baseline = topNonEmptySection->firstLineBaseline();
-    if (baseline > 0)
-        return topNonEmptySection->logicalTop() + baseline;
+    if (Optional<int> baseline = topNonEmptySection->firstLineBaseline())
+        return Optional<int>(topNonEmptySection->logicalTop() + baseline.value());
 
     // FIXME: A table row always has a baseline per CSS 2.1. Will this return the right value?
-    return -1;
+    return Optional<int>();
 }
 
 LayoutRect RenderTable::overflowClipRect(const LayoutPoint& location, RenderRegion* region, OverlayScrollbarSizeRelevancy relevancy, PaintPhase phase)
index e16ab93..ef83c21 100644 (file)
@@ -299,8 +299,8 @@ private:
     virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction) override;
 
     virtual int baselinePosition(FontBaseline, bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const override final;
-    virtual int firstLineBaseline() const override;
-    virtual int inlineBlockBaseline(LineDirectionMode) const override final;
+    virtual Optional<int> firstLineBaseline() const override;
+    virtual Optional<int> inlineBlockBaseline(LineDirectionMode) const override final;
 
     RenderTableCol* slowColElement(unsigned col, bool* startEdge, bool* endEdge) const;
 
index 86e9d61..ab7137d 100644 (file)
@@ -393,10 +393,7 @@ LayoutUnit RenderTableCell::cellBaselinePosition() const
     // <http://www.w3.org/TR/2007/CR-CSS21-20070719/tables.html#height-layout>: The baseline of a cell is the baseline of
     // the first in-flow line box in the cell, or the first in-flow table-row in the cell, whichever comes first. If there
     // is no such line box or table-row, the baseline is the bottom of content edge of the cell box.
-    LayoutUnit baseline = firstLineBaseline();
-    if (baseline != -1)
-        return baseline;
-    return borderAndPaddingBefore() + contentLogicalHeight();
+    return firstLineBaseline().valueOr(borderAndPaddingBefore() + contentLogicalHeight());
 }
 
 void RenderTableCell::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
index 016206d..39b189e 100644 (file)
@@ -908,26 +908,28 @@ void RenderTableSection::recalcOuterBorder()
     m_outerBorderEnd = calcOuterBorderEnd();
 }
 
-int RenderTableSection::firstLineBaseline() const
+Optional<int> RenderTableSection::firstLineBaseline() const
 {
     if (!m_grid.size())
-        return -1;
+        return Optional<int>();
 
     int firstLineBaseline = m_grid[0].baseline;
     if (firstLineBaseline)
         return firstLineBaseline + m_rowPos[0];
 
-    firstLineBaseline = -1;
+    Optional<int> result;
     const Row& firstRow = m_grid[0].row;
     for (size_t i = 0; i < firstRow.size(); ++i) {
         const CellStruct& cs = firstRow.at(i);
         const RenderTableCell* cell = cs.primaryCell();
         // Only cells with content have a baseline
-        if (cell && cell->contentLogicalHeight())
-            firstLineBaseline = std::max<int>(firstLineBaseline, cell->logicalTop() + cell->borderAndPaddingBefore() + cell->contentLogicalHeight());
+        if (cell && cell->contentLogicalHeight()) {
+            int candidate = cell->logicalTop() + cell->borderAndPaddingBefore() + cell->contentLogicalHeight();
+            result = std::max(result.valueOr(candidate), candidate);
+        }
     }
 
-    return firstLineBaseline;
+    return result;
 }
 
 void RenderTableSection::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
index 43e7888..2a71619 100644 (file)
@@ -64,7 +64,7 @@ public:
 
     virtual void addChild(RenderObject* child, RenderObject* beforeChild = 0) override;
 
-    virtual int firstLineBaseline() const override;
+    virtual Optional<int> firstLineBaseline() const override;
 
     void addCell(RenderTableCell*, RenderTableRow* row);
 
index 127394a..4bd1930 100644 (file)
@@ -102,8 +102,8 @@ public:
     {
         return RenderBlock::baselinePosition(baseline, firstLine, direction, position);
     }
-    virtual int firstLineBaseline() const override { return RenderBlock::firstLineBaseline(); }
-    virtual int inlineBlockBaseline(LineDirectionMode direction) const override { return RenderBlock::inlineBlockBaseline(direction); }
+    virtual Optional<int> firstLineBaseline() const override { return RenderBlock::firstLineBaseline(); }
+    virtual Optional<int> inlineBlockBaseline(LineDirectionMode direction) const override { return RenderBlock::inlineBlockBaseline(direction); }
 
 };
 
index 657fccc..7aa54fb 100644 (file)
@@ -72,11 +72,10 @@ int RenderMathMLBlock::baselinePosition(FontBaseline baselineType, bool firstLin
     if (linePositionMode == PositionOfInteriorLineBoxes)
         return 0;
     
-    LayoutUnit baseline = firstLineBaseline(); // FIXME: This may be unnecessary after flex baselines are implemented (https://bugs.webkit.org/show_bug.cgi?id=96188).
-    if (baseline != -1)
-        return baseline;
-    
-    return RenderFlexibleBox::baselinePosition(baselineType, firstLine, direction, linePositionMode);
+    // FIXME: This may be unnecessary after flex baselines are implemented (https://bugs.webkit.org/show_bug.cgi?id=96188).
+    return firstLineBaseline().valueOrCompute([&] {
+        return RenderFlexibleBox::baselinePosition(baselineType, firstLine, direction, linePositionMode);
+    });
 }
 
 const char* RenderMathMLBlock::renderName() const
@@ -299,7 +298,7 @@ bool parseMathMLNamedSpace(const String& string, LayoutUnit& lengthValue, const
     return false;
 }
 
-int RenderMathMLTable::firstLineBaseline() const
+Optional<int> RenderMathMLTable::firstLineBaseline() const
 {
     // In legal MathML, we'll have a MathML parent. That RenderFlexibleBox parent will use our firstLineBaseline() for baseline alignment, per
     // http://dev.w3.org/csswg/css3-flexbox/#flex-baselines. We want to vertically center an <mtable>, such as a matrix. Essentially the whole <mtable> element fits on a
index b494017..f2cefe6 100644 (file)
@@ -76,7 +76,7 @@ public:
     {
     }
     
-    virtual int firstLineBaseline() const override;
+    virtual Optional<int> firstLineBaseline() const override;
     
 private:
     virtual bool isRenderMathMLTable() const override { return true; }
index 59ffb07..9756ba6 100644 (file)
@@ -159,10 +159,10 @@ void RenderMathMLFraction::paint(PaintInfo& info, const LayoutPoint& paintOffset
     info.context->drawLine(adjustedPaintOffset, IntPoint(adjustedPaintOffset.x() + denominatorWrapper->pixelSnappedOffsetWidth(), adjustedPaintOffset.y()));
 }
 
-int RenderMathMLFraction::firstLineBaseline() const
+Optional<int> RenderMathMLFraction::firstLineBaseline() const
 {
     if (RenderBox* denominatorWrapper = lastChildBox())
-        return denominatorWrapper->logicalTop() + static_cast<int>(lroundf((m_lineThickness + style().fontMetrics().xHeight()) / 2));
+        return Optional<int>(denominatorWrapper->logicalTop() + static_cast<int>(lroundf((m_lineThickness + style().fontMetrics().xHeight()) / 2)));
     return RenderMathMLBlock::firstLineBaseline();
 }
 
index 36f544a..73c0b6c 100644 (file)
@@ -47,7 +47,7 @@ private:
 
     virtual void addChild(RenderObject* child, RenderObject* beforeChild) override;
     virtual void updateFromElement() override;
-    virtual int firstLineBaseline() const override;
+    virtual Optional<int> firstLineBaseline() const override;
     virtual void paint(PaintInfo&, const LayoutPoint&) override;
     virtual RenderMathMLOperator* unembellishedOperator() override;
     virtual void layout() override;
index cd3d221..938f6bc 100644 (file)
@@ -1737,10 +1737,10 @@ void RenderMathMLOperator::updateStyle()
     }
 }
 
-int RenderMathMLOperator::firstLineBaseline() const
+Optional<int> RenderMathMLOperator::firstLineBaseline() const
 {
     if (m_stretchyData.mode() != DrawNormal)
-        return m_stretchHeightAboveBaseline;
+        return Optional<int>(m_stretchHeightAboveBaseline);
     return RenderMathMLToken::firstLineBaseline();
 }
 
index 38cd830..1a3beba 100644 (file)
@@ -154,7 +154,7 @@ private:
     bool isInvisibleOperator() const { return 0x2061 <= m_textContent && m_textContent <= 0x2064; }
     virtual bool isChildAllowed(const RenderObject&, const RenderStyle&) const override;
 
-    virtual int firstLineBaseline() const override;
+    virtual Optional<int> firstLineBaseline() const override;
     virtual RenderMathMLOperator* unembellishedOperator() override { return this; }
     void rebuildTokenContent(const String& operatorString);
     virtual void updateFromElement() override;
index 3e4aee9..875a6fd 100644 (file)
@@ -250,11 +250,11 @@ void RenderMathMLRoot::updateStyle()
     }
 }
 
-int RenderMathMLRoot::firstLineBaseline() const
+Optional<int> RenderMathMLRoot::firstLineBaseline() const
 {
     if (!isEmpty()) {
         auto base = baseWrapper();
-        return static_cast<int>(lroundf(base->firstLineBaseline() + base->marginTop()));
+        return static_cast<int>(lroundf(base->firstLineBaseline().valueOr(-1) + base->marginTop()));
     }
 
     return RenderMathMLBlock::firstLineBaseline();
@@ -285,9 +285,7 @@ void RenderMathMLRoot::layout()
     if (radical) {
         // We stretch the radical sign to cover the height of the base wrapper.
         float baseHeight = base->logicalHeight();
-        float baseHeightAboveBaseline = base->firstLineBaseline();
-        if (baseHeightAboveBaseline == -1)
-            baseHeightAboveBaseline = baseHeight;
+        float baseHeightAboveBaseline = base->firstLineBaseline().valueOr(baseHeight);
         float baseDepthBelowBaseline = baseHeight - baseHeightAboveBaseline;
         baseHeightAboveBaseline += m_verticalGap;
         radical->stretchTo(baseHeightAboveBaseline, baseDepthBelowBaseline);
index aa4c899..bbf2d9b 100644 (file)
@@ -60,7 +60,7 @@ protected:
 private:
     virtual bool isRenderMathMLRoot() const override final { return true; }
     virtual const char* renderName() const override { return "RenderMathMLRoot"; }
-    virtual int firstLineBaseline() const override;
+    virtual Optional<int> firstLineBaseline() const override;
     void updateStyle();
     void restructureWrappers();
 
index 6693f67..cc7a302 100644 (file)
@@ -81,13 +81,11 @@ void RenderMathMLRow::layout()
         LayoutUnit childHeightAboveBaseline = 0, childDepthBelowBaseline = 0;
         if (is<RenderMathMLBlock>(*child)) {
             RenderMathMLBlock& mathmlChild = downcast<RenderMathMLBlock>(*child);
-            childHeightAboveBaseline = mathmlChild.firstLineBaseline();
-            if (childHeightAboveBaseline == -1)
-                childHeightAboveBaseline = mathmlChild.logicalHeight();
+            childHeightAboveBaseline = mathmlChild.firstLineBaseline().valueOr(mathmlChild.logicalHeight());
             childDepthBelowBaseline = mathmlChild.logicalHeight() - childHeightAboveBaseline;
         } else if (is<RenderMathMLTable>(*child)) {
             RenderMathMLTable& tableChild = downcast<RenderMathMLTable>(*child);
-            childHeightAboveBaseline = tableChild.firstLineBaseline();
+            childHeightAboveBaseline = tableChild.firstLineBaseline().valueOr(-1);
             childDepthBelowBaseline = tableChild.logicalHeight() - childHeightAboveBaseline;
         } else if (is<RenderBox>(*child)) {
             childHeightAboveBaseline = downcast<RenderBox>(*child).logicalHeight();
index 05664d7..d70b6a9 100644 (file)
@@ -280,9 +280,7 @@ void RenderMathMLScripts::layout()
     // below the base's top edge, or the subscript's bottom edge above the base's bottom edge.
 
     LayoutUnit baseHeight = base->logicalHeight();
-    LayoutUnit baseBaseline = base->firstLineBaseline();
-    if (baseBaseline == -1)
-        baseBaseline = baseHeight;
+    LayoutUnit baseBaseline = base->firstLineBaseline().valueOr(baseHeight);
     LayoutUnit axis = style().fontMetrics().xHeight() / 2;
     int fontSize = style().fontSize();
 
@@ -314,9 +312,7 @@ void RenderMathMLScripts::layout()
 
         if (RenderBox* superscript = m_kind == Sub ? 0 : subSupPair->lastChildBox()) {
             LayoutUnit superscriptHeight = superscript->logicalHeight();
-            LayoutUnit superscriptBaseline = superscript->firstLineBaseline();
-            if (superscriptBaseline == -1)
-                superscriptBaseline = superscriptHeight;
+            LayoutUnit superscriptBaseline = superscript->firstLineBaseline().valueOr(superscriptHeight);
             LayoutUnit minBaseline = std::max<LayoutUnit>(fontSize / 3 + 1 + superscriptBaseline, superscriptHeight + axis + superscriptShiftValue);
 
             topPadding = std::max<LayoutUnit>(topPadding, minBaseline - baseBaseline);
@@ -324,9 +320,7 @@ void RenderMathMLScripts::layout()
 
         if (RenderBox* subscript = m_kind == Super ? 0 : subSupPair->firstChildBox()) {
             LayoutUnit subscriptHeight = subscript->logicalHeight();
-            LayoutUnit subscriptBaseline = subscript->firstLineBaseline();
-            if (subscriptBaseline == -1)
-                subscriptBaseline = subscriptHeight;
+            LayoutUnit subscriptBaseline = subscript->firstLineBaseline().valueOr(subscriptHeight);
             LayoutUnit baseExtendUnderBaseline = baseHeight - baseBaseline;
             LayoutUnit subscriptUnderItsBaseline = subscriptHeight - subscriptBaseline;
             LayoutUnit minExtendUnderBaseline = std::max<LayoutUnit>(fontSize / 5 + 1 + subscriptUnderItsBaseline, subscriptHeight + subscriptShiftValue - axis);
@@ -356,11 +350,10 @@ void RenderMathMLScripts::layout()
     RenderMathMLBlock::layout();
 }
 
-int RenderMathMLScripts::firstLineBaseline() const
+Optional<int> RenderMathMLScripts::firstLineBaseline() const
 {
     if (m_baseWrapper) {
-        LayoutUnit baseline = m_baseWrapper->firstLineBaseline();
-        if (baseline != -1)
+        if (Optional<int> baseline = m_baseWrapper->firstLineBaseline())
             return baseline;
     }
     return RenderMathMLBlock::firstLineBaseline();
index a86f17d..5c4b179 100644 (file)
@@ -76,7 +76,7 @@ public:
     virtual void removeChild(RenderObject&) override;
     
     virtual RenderMathMLOperator* unembellishedOperator() override;
-    virtual int firstLineBaseline() const override;
+    virtual Optional<int> firstLineBaseline() const override;
 
 protected:
     virtual void layout() override;
index eba68b8..db37eb2 100644 (file)
@@ -91,9 +91,9 @@ void RenderMathMLSpace::styleDidChange(StyleDifference diff, const RenderStyle*
     updateFromElement();
 }
 
-int RenderMathMLSpace::firstLineBaseline() const
+Optional<int> RenderMathMLSpace::firstLineBaseline() const
 {
-    return m_height;
+    return Optional<int>(m_height);
 }
 
 }
index 64e49f2..812087f 100644 (file)
@@ -45,7 +45,7 @@ private:
     virtual bool isChildAllowed(const RenderObject&, const RenderStyle&) const override { return false; }
     virtual void computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const override;
     virtual void updateFromElement() override;
-    virtual int firstLineBaseline() const override;
+    virtual Optional<int> firstLineBaseline() const override;
     virtual void updateLogicalWidth() override;
     virtual void updateLogicalHeight() override;
 
index 79a732c..d2f005b 100644 (file)
@@ -60,14 +60,14 @@ RenderMathMLOperator* RenderMathMLUnderOver::unembellishedOperator()
     return downcast<RenderMathMLBlock>(*base).unembellishedOperator();
 }
 
-int RenderMathMLUnderOver::firstLineBaseline() const
+Optional<int> RenderMathMLUnderOver::firstLineBaseline() const
 {
     RenderBox* base = firstChildBox();
     if (!base)
-        return -1;
-    LayoutUnit baseline = base->firstLineBaseline();
-    if (baseline != -1)
-        baseline += base->logicalTop();
+        return Optional<int>();
+    Optional<int> baseline = base->firstLineBaseline();
+    if (baseline)
+        baseline.value() += static_cast<int>(base->logicalTop());
     return baseline;
 }
 
index d4694d6..f08829a 100644 (file)
@@ -38,7 +38,7 @@ public:
     
     virtual RenderMathMLOperator* unembellishedOperator() override;
 
-    virtual int firstLineBaseline() const override;
+    virtual Optional<int> firstLineBaseline() const override;
     
 protected:
     virtual void layout() override;
index a571d4e..02b9e85 100644 (file)
@@ -1,3 +1,15 @@
+2015-03-11  Myles C. Maxfield  <mmaxfield@apple.com>
+
+        Use out-of-band messaging for RenderBox::firstLineBaseline() and RenderBox::inlineBlockBaseline()
+        https://bugs.webkit.org/show_bug.cgi?id=142569
+
+        Reviewed by David Hyatt.
+
+        Test Optional::valueOrCompute().
+
+        * TestWebKitAPI/Tests/WTF/Optional.cpp:
+        (TestWebKitAPI::TEST):
+
 2015-03-11  Carlos Garcia Campos  <cgarcia@igalia.com>
 
         [GTK] Add an option to enable MiniBrowser for non developer builds and always install it
index 64d2019..05f413b 100644 (file)
@@ -72,4 +72,25 @@ TEST(WTF_Optional, Destructor)
     EXPECT_TRUE(didCallDestructor);
 }
 
+TEST(WTF_Optional, Callback)
+{
+    bool called = false;
+    Optional<int> a;
+    int result = a.valueOrCompute([&] {
+        called = true;
+        return 300;
+    });
+    EXPECT_TRUE(called);
+    EXPECT_EQ(result, 300);
+
+    a = 250;
+    called = false;
+    result = a.valueOrCompute([&] {
+        called = true;
+        return 300;
+    });
+    EXPECT_FALSE(called);
+    EXPECT_EQ(result, 250);
+}
+
 } // namespace TestWebKitAPI