Move LineWidth out of RenderBlockLineLayout
authorzoltan@webkit.org <zoltan@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 11 Sep 2013 21:29:37 +0000 (21:29 +0000)
committerzoltan@webkit.org <zoltan@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 11 Sep 2013 21:29:37 +0000 (21:29 +0000)
https://bugs.webkit.org/show_bug.cgi?id=121107

Reviewed by David Hyatt.

Move LineWidth class and related code into LineWidth.{h,cpp}.

No new tests, no behavior change.

* CMakeLists.txt:
* GNUmakefile.list.am:
* Target.pri:
* WebCore.vcxproj/WebCore.vcxproj:
* WebCore.xcodeproj/project.pbxproj:
* rendering/LineWidth.cpp: Added.
(WebCore::LineWidth::applyOverhang):
(WebCore::LineWidth::fitBelowFloats):
* rendering/LineWidth.h: Added.
(WebCore::logicalHeightForLine):
(WebCore::LineWidth::LineWidth):
(WebCore::LineWidth::fitsOnLine):
(WebCore::LineWidth::fitsOnLineIncludingExtraWidth):
(WebCore::LineWidth::fitsOnLineExcludingTrailingWhitespace):
(WebCore::LineWidth::currentWidth):
(WebCore::LineWidth::uncommittedWidth):
(WebCore::LineWidth::committedWidth):
(WebCore::LineWidth::availableWidth):
(WebCore::LineWidth::addUncommittedWidth):
(WebCore::LineWidth::commit):
(WebCore::LineWidth::setTrailingWhitespaceWidth):
(WebCore::LineWidth::shouldIndentText):
(WebCore::LineWidth::computeAvailableWidthFromLeftAndRight):
(WebCore::LineWidth::fitsOnLineExcludingTrailingCollapsedWhitespace):
(WebCore::LineWidth::updateAvailableWidth):
(WebCore::LineWidth::shrinkAvailableWidthForNewFloatIfNeeded):
* rendering/RenderBlockLineLayout.cpp:

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

Source/WebCore/CMakeLists.txt
Source/WebCore/ChangeLog
Source/WebCore/GNUmakefile.list.am
Source/WebCore/Target.pri
Source/WebCore/WebCore.vcxproj/WebCore.vcxproj
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/rendering/LineWidth.cpp [new file with mode: 0644]
Source/WebCore/rendering/LineWidth.h [new file with mode: 0644]
Source/WebCore/rendering/RenderBlockLineLayout.cpp

index 57e1166..1702060 100644 (file)
@@ -2109,6 +2109,7 @@ set(WebCore_SOURCES
     rendering/InlineTextBox.cpp
     rendering/LayoutState.cpp
     rendering/LayoutRepainter.cpp
+    rendering/LineWidth.cpp
     rendering/PointerEventsHitRules.cpp
     rendering/RenderApplet.cpp
     rendering/RenderArena.cpp
index a4fbc1a..af30ae3 100644 (file)
@@ -1,3 +1,42 @@
+2013-09-11  Zoltan Horvath  <zoltan@webkit.org>
+
+        Move LineWidth out of RenderBlockLineLayout
+        https://bugs.webkit.org/show_bug.cgi?id=121107
+
+        Reviewed by David Hyatt.
+
+        Move LineWidth class and related code into LineWidth.{h,cpp}.
+
+        No new tests, no behavior change.
+
+        * CMakeLists.txt:
+        * GNUmakefile.list.am:
+        * Target.pri:
+        * WebCore.vcxproj/WebCore.vcxproj:
+        * WebCore.xcodeproj/project.pbxproj:
+        * rendering/LineWidth.cpp: Added.
+        (WebCore::LineWidth::applyOverhang):
+        (WebCore::LineWidth::fitBelowFloats):
+        * rendering/LineWidth.h: Added.
+        (WebCore::logicalHeightForLine):
+        (WebCore::LineWidth::LineWidth):
+        (WebCore::LineWidth::fitsOnLine):
+        (WebCore::LineWidth::fitsOnLineIncludingExtraWidth):
+        (WebCore::LineWidth::fitsOnLineExcludingTrailingWhitespace):
+        (WebCore::LineWidth::currentWidth):
+        (WebCore::LineWidth::uncommittedWidth):
+        (WebCore::LineWidth::committedWidth):
+        (WebCore::LineWidth::availableWidth):
+        (WebCore::LineWidth::addUncommittedWidth):
+        (WebCore::LineWidth::commit):
+        (WebCore::LineWidth::setTrailingWhitespaceWidth):
+        (WebCore::LineWidth::shouldIndentText):
+        (WebCore::LineWidth::computeAvailableWidthFromLeftAndRight):
+        (WebCore::LineWidth::fitsOnLineExcludingTrailingCollapsedWhitespace):
+        (WebCore::LineWidth::updateAvailableWidth):
+        (WebCore::LineWidth::shrinkAvailableWidthForNewFloatIfNeeded):
+        * rendering/RenderBlockLineLayout.cpp:
+
 2013-09-11  Ryosuke Niwa  <rniwa@webkit.org>
 
         HTMLEntityTable could use char to reduce binary size
index 08e3896..9a49ac6 100644 (file)
@@ -4364,6 +4364,8 @@ webcore_sources += \
        Source/WebCore/rendering/LogicalSelectionOffsetCaches.h \
        Source/WebCore/rendering/LayoutRepainter.h \
        Source/WebCore/rendering/LayoutRepainter.cpp \
+       Source/WebCore/rendering/LineWidth.h \
+       Source/WebCore/rendering/LineWidth.cpp \
        Source/WebCore/rendering/OverlapTestRequestClient.h \
        Source/WebCore/rendering/Pagination.h \
        Source/WebCore/rendering/PaintInfo.h \
index ec53d4d..a968513 100644 (file)
@@ -1150,6 +1150,7 @@ SOURCES += \
     rendering/InlineTextBox.cpp \
     rendering/LayoutState.cpp \
     rendering/LayoutRepainter.cpp \
+    rendering/LineWidth.cpp \
     rendering/RenderApplet.cpp \
     rendering/RenderArena.cpp \
     rendering/RenderBlock.cpp \
@@ -2404,6 +2405,7 @@ HEADERS += \
     rendering/InlineTextBox.h \
     rendering/LayoutRepainter.h \
     rendering/LayoutState.h \
+    rendering/LineWidth.h \
     rendering/LogicalSelectionOffsetCaches.h \
     rendering/mathml/RenderMathMLBlock.h \
     rendering/mathml/RenderMathMLFenced.h \
index 8d51d95..609baaf 100644 (file)
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Production|Win32'">true</ExcludedFromBuild>
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Production|x64'">true</ExcludedFromBuild>
     </ClCompile>
+    <ClCompile Include="..\rendering\LineWidth.cpp" />
     <ClCompile Include="..\rendering\PointerEventsHitRules.cpp">
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
     <ClInclude Include="..\rendering\InlineTextBox.h" />
     <ClInclude Include="..\rendering\LayoutRepainter.h" />
     <ClInclude Include="..\rendering\LayoutState.h" />
+    <ClInclude Include="..\rendering\LineWidth.h" />
     <ClInclude Include="..\rendering\PaintInfo.h" />
     <ClInclude Include="..\rendering\PaintPhase.h" />
     <ClInclude Include="..\rendering\PointerEventsHitRules.h" />
index 266da66..00782a1 100644 (file)
                A07D3356152B630E001B6393 /* JSWebGLShaderPrecisionFormat.h in Headers */ = {isa = PBXBuildFile; fileRef = A07D3354152B630E001B6393 /* JSWebGLShaderPrecisionFormat.h */; };
                A07D3358152B632D001B6393 /* WebGLShaderPrecisionFormat.h in Headers */ = {isa = PBXBuildFile; fileRef = A07D3357152B632D001B6393 /* WebGLShaderPrecisionFormat.h */; };
                A08CF154152B77B3009C5775 /* WebGLShaderPrecisionFormat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A08CF153152B77B3009C5775 /* WebGLShaderPrecisionFormat.cpp */; };
+               A0CB002417DF82660017896B /* LineWidth.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A0CB002317DF81AC0017896B /* LineWidth.cpp */; };
+               A0CB002517DF826C0017896B /* LineWidth.h in Headers */ = {isa = PBXBuildFile; fileRef = A0CB002117DE9CD00017896B /* LineWidth.h */; settings = {ATTRIBUTES = (); }; };
                A0EE0DF5144F825500F80B0D /* WebGLDebugRendererInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A0EE0DF1144F825500F80B0D /* WebGLDebugRendererInfo.cpp */; };
                A0EE0DF6144F825500F80B0D /* WebGLDebugRendererInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = A0EE0DF2144F825500F80B0D /* WebGLDebugRendererInfo.h */; };
                A0EE0DF7144F825500F80B0D /* WebGLDebugShaders.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A0EE0DF3144F825500F80B0D /* WebGLDebugShaders.cpp */; };
                A07D3357152B632D001B6393 /* WebGLShaderPrecisionFormat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WebGLShaderPrecisionFormat.h; path = canvas/WebGLShaderPrecisionFormat.h; sourceTree = "<group>"; };
                A07D3359152B633E001B6393 /* WebGLShaderPrecisionFormat.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = WebGLShaderPrecisionFormat.idl; path = canvas/WebGLShaderPrecisionFormat.idl; sourceTree = "<group>"; };
                A08CF153152B77B3009C5775 /* WebGLShaderPrecisionFormat.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = WebGLShaderPrecisionFormat.cpp; path = canvas/WebGLShaderPrecisionFormat.cpp; sourceTree = "<group>"; };
+               A0CB002117DE9CD00017896B /* LineWidth.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LineWidth.h; sourceTree = "<group>"; };
+               A0CB002317DF81AC0017896B /* LineWidth.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LineWidth.cpp; sourceTree = "<group>"; };
                A0EE0DEF144F823200F80B0D /* WebGLDebugShaders.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = WebGLDebugShaders.idl; path = canvas/WebGLDebugShaders.idl; sourceTree = "<group>"; };
                A0EE0DF0144F824300F80B0D /* WebGLDebugRendererInfo.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = WebGLDebugRendererInfo.idl; path = canvas/WebGLDebugRendererInfo.idl; sourceTree = "<group>"; };
                A0EE0DF1144F825500F80B0D /* WebGLDebugRendererInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = WebGLDebugRendererInfo.cpp; path = canvas/WebGLDebugRendererInfo.cpp; sourceTree = "<group>"; };
                                A120ACA013F9983700FE4AC7 /* LayoutRepainter.h */,
                                2D9066040BE141D400956998 /* LayoutState.cpp */,
                                2D9066050BE141D400956998 /* LayoutState.h */,
+                               A0CB002317DF81AC0017896B /* LineWidth.cpp */,
+                               A0CB002117DE9CD00017896B /* LineWidth.h */,
                                9BA273F3172206BB0097CE47 /* LogicalSelectionOffsetCaches.h */,
                                3774ABA30FA21EB400AD7DE9 /* OverlapTestRequestClient.h */,
                                9377AB9F15DEFEEF0031FD04 /* Pagination.h */,
                                BE16C59317CFE17200852C04 /* InbandGenericTextTrack.h in Headers */,
                                BE16C59517CFE17200852C04 /* InbandWebVTTTextTrack.h in Headers */,
                                BC10D76817D8EE71005E2626 /* RenderBlockFlow.h in Headers */,
+                               A0CB002517DF826C0017896B /* LineWidth.h in Headers */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                BE16C59217CFE17200852C04 /* InbandGenericTextTrack.cpp in Sources */,
                                BE16C59417CFE17200852C04 /* InbandWebVTTTextTrack.cpp in Sources */,
                                BC10D76717D8EE6E005E2626 /* RenderBlockFlow.cpp in Sources */,
+                               A0CB002417DF82660017896B /* LineWidth.cpp in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
diff --git a/Source/WebCore/rendering/LineWidth.cpp b/Source/WebCore/rendering/LineWidth.cpp
new file mode 100644 (file)
index 0000000..51ac9a7
--- /dev/null
@@ -0,0 +1,218 @@
+/*
+ * Copyright (C) 2013 Adobe Systems Incorporated. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above
+ *    copyright notice, this list of conditions and the following
+ *    disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ *    copyright notice, this list of conditions and the following
+ *    disclaimer in the documentation and/or other materials
+ *    provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "LineWidth.h"
+
+namespace WebCore {
+
+LineWidth::LineWidth(RenderBlock& block, bool isFirstLine, IndentTextOrNot shouldIndentText)
+    : m_block(block)
+    , m_uncommittedWidth(0)
+    , m_committedWidth(0)
+    , m_overhangWidth(0)
+    , m_trailingWhitespaceWidth(0)
+    , m_trailingCollapsedWhitespaceWidth(0)
+    , m_left(0)
+    , m_right(0)
+    , m_availableWidth(0)
+#if ENABLE(CSS_SHAPES)
+    , m_segment(0)
+#endif
+    , m_isFirstLine(isFirstLine)
+    , m_shouldIndentText(shouldIndentText)
+{
+    ASSERT(block);
+#if ENABLE(CSS_SHAPES)
+    if (ShapeInsideInfo* shapeInsideInfo = m_block.layoutShapeInsideInfo())
+        m_segment = shapeInsideInfo->currentSegment();
+#endif
+    updateAvailableWidth();
+}
+
+bool LineWidth::fitsOnLine(bool ignoringTrailingSpace) const
+{
+    return ignoringTrailingSpace ? fitsOnLineExcludingTrailingCollapsedWhitespace() : fitsOnLineIncludingExtraWidth(0);
+}
+
+bool LineWidth::fitsOnLineIncludingExtraWidth(float extra) const
+{
+    return currentWidth() + extra <= m_availableWidth;
+}
+
+bool LineWidth::fitsOnLineExcludingTrailingWhitespace(float extra) const
+{
+    return currentWidth() - m_trailingWhitespaceWidth + extra <= m_availableWidth;
+}
+
+void LineWidth::updateAvailableWidth(LayoutUnit replacedHeight)
+{
+    LayoutUnit height = m_block.logicalHeight();
+    LayoutUnit logicalHeight = logicalHeightForLine(&m_block, m_isFirstLine, replacedHeight);
+    m_left = m_block.logicalLeftOffsetForLine(height, shouldIndentText(), logicalHeight);
+    m_right = m_block.logicalRightOffsetForLine(height, shouldIndentText(), logicalHeight);
+
+#if ENABLE(CSS_SHAPES)
+    if (m_segment) {
+        m_left = std::max<float>(m_segment->logicalLeft, m_left);
+        m_right = std::min<float>(m_segment->logicalRight, m_right);
+    }
+#endif
+
+    computeAvailableWidthFromLeftAndRight();
+}
+
+void LineWidth::shrinkAvailableWidthForNewFloatIfNeeded(FloatingObject* newFloat)
+{
+    LayoutUnit height = m_block.logicalHeight();
+    if (height < newFloat->logicalTop(m_block.isHorizontalWritingMode()) || height >= newFloat->logicalBottom(m_block.isHorizontalWritingMode()))
+        return;
+
+#if ENABLE(CSS_SHAPES)
+    // When floats with shape outside are stacked, the floats are positioned based on the margin box of the float,
+    // not the shape's contour. Since we computed the width based on the shape contour when we added the float,
+    // when we add a subsequent float on the same line, we need to undo the shape delta in order to position
+    // based on the margin box. In order to do this, we need to walk back through the floating object list to find
+    // the first previous float that is on the same side as our newFloat.
+    ShapeOutsideInfo* previousShapeOutsideInfo = 0;
+    const FloatingObjectSet& floatingObjectSet = m_block.m_floatingObjects->set();
+    FloatingObjectSetIterator it = floatingObjectSet.end();
+    FloatingObjectSetIterator begin = floatingObjectSet.begin();
+    for (--it; it != begin; --it) {
+        FloatingObject* previousFloat = *it;
+        if (previousFloat != newFloat && previousFloat->type() == newFloat->type()) {
+            previousShapeOutsideInfo = previousFloat->renderer()->shapeOutsideInfo();
+            if (previousShapeOutsideInfo)
+                previousShapeOutsideInfo->computeSegmentsForContainingBlockLine(m_block.logicalHeight(), previousFloat->logicalTop(m_block.isHorizontalWritingMode()), logicalHeightForLine(&m_block, m_isFirstLine));
+            break;
+        }
+    }
+
+    ShapeOutsideInfo* shapeOutsideInfo = newFloat->renderer()->shapeOutsideInfo();
+    if (shapeOutsideInfo)
+        shapeOutsideInfo->computeSegmentsForContainingBlockLine(m_block.logicalHeight(), newFloat->logicalTop(m_block.isHorizontalWritingMode()), logicalHeightForLine(&m_block, m_isFirstLine));
+#endif
+
+    if (newFloat->type() == FloatingObject::FloatLeft) {
+        float newLeft = newFloat->logicalRight(m_block.isHorizontalWritingMode());
+#if ENABLE(CSS_SHAPES)
+        if (previousShapeOutsideInfo)
+            newLeft -= previousShapeOutsideInfo->rightSegmentMarginBoxDelta();
+        if (shapeOutsideInfo)
+            newLeft += shapeOutsideInfo->rightSegmentMarginBoxDelta();
+#endif
+
+        if (shouldIndentText() && m_block.style()->isLeftToRightDirection())
+            newLeft += floorToInt(m_block.textIndentOffset());
+        m_left = std::max<float>(m_left, newLeft);
+    } else {
+        float newRight = newFloat->logicalLeft(m_block.isHorizontalWritingMode());
+#if ENABLE(CSS_SHAPES)
+        if (previousShapeOutsideInfo)
+            newRight -= previousShapeOutsideInfo->leftSegmentMarginBoxDelta();
+        if (shapeOutsideInfo)
+            newRight += shapeOutsideInfo->leftSegmentMarginBoxDelta();
+#endif
+
+        if (shouldIndentText() && !m_block.style()->isLeftToRightDirection())
+            newRight -= floorToInt(m_block.textIndentOffset());
+        m_right = std::min<float>(m_right, newRight);
+    }
+
+    computeAvailableWidthFromLeftAndRight();
+}
+
+void LineWidth::commit()
+{
+    m_committedWidth += m_uncommittedWidth;
+    m_uncommittedWidth = 0;
+}
+
+void LineWidth::applyOverhang(RenderRubyRun* rubyRun, RenderObject* startRenderer, RenderObject* endRenderer)
+{
+    int startOverhang;
+    int endOverhang;
+    rubyRun->getOverhang(m_isFirstLine, startRenderer, endRenderer, startOverhang, endOverhang);
+
+    startOverhang = std::min<int>(startOverhang, m_committedWidth);
+    m_availableWidth += startOverhang;
+
+    endOverhang = std::max(std::min<int>(endOverhang, m_availableWidth - currentWidth()), 0);
+    m_availableWidth += endOverhang;
+    m_overhangWidth += startOverhang + endOverhang;
+}
+
+void LineWidth::fitBelowFloats()
+{
+    ASSERT(!m_committedWidth);
+    ASSERT(!fitsOnLine());
+
+    LayoutUnit floatLogicalBottom;
+    LayoutUnit lastFloatLogicalBottom = m_block.logicalHeight();
+    float newLineWidth = m_availableWidth;
+    float newLineLeft = m_left;
+    float newLineRight = m_right;
+    while (true) {
+        floatLogicalBottom = m_block.nextFloatLogicalBottomBelow(lastFloatLogicalBottom);
+        if (floatLogicalBottom <= lastFloatLogicalBottom)
+            break;
+
+        newLineLeft = m_block.logicalLeftOffsetForLine(floatLogicalBottom, shouldIndentText());
+        newLineRight = m_block.logicalRightOffsetForLine(floatLogicalBottom, shouldIndentText());
+        newLineWidth = max(0.0f, newLineRight - newLineLeft);
+        lastFloatLogicalBottom = floatLogicalBottom;
+        if (newLineWidth >= m_uncommittedWidth)
+            break;
+    }
+
+    if (newLineWidth > m_availableWidth) {
+        m_block.setLogicalHeight(lastFloatLogicalBottom);
+        m_availableWidth = newLineWidth + m_overhangWidth;
+        m_left = newLineLeft;
+        m_right = newLineRight;
+    }
+}
+
+void LineWidth::setTrailingWhitespaceWidth(float collapsedWhitespace, float borderPaddingMargin)
+{
+    m_trailingCollapsedWhitespaceWidth = collapsedWhitespace;
+    m_trailingWhitespaceWidth = collapsedWhitespace + borderPaddingMargin;
+}
+
+void LineWidth::computeAvailableWidthFromLeftAndRight()
+{
+    m_availableWidth = max(0.0f, m_right - m_left) + m_overhangWidth;
+}
+
+bool LineWidth::fitsOnLineExcludingTrailingCollapsedWhitespace() const
+{
+    return currentWidth() - m_trailingCollapsedWhitespaceWidth <= m_availableWidth;
+}
+
+}
diff --git a/Source/WebCore/rendering/LineWidth.h b/Source/WebCore/rendering/LineWidth.h
new file mode 100644 (file)
index 0000000..4bafecf
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2013 Adobe Systems Incorporated. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above
+ *    copyright notice, this list of conditions and the following
+ *    disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ *    copyright notice, this list of conditions and the following
+ *    disclaimer in the documentation and/or other materials
+ *    provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LineWidth_h
+#define LineWidth_h
+
+#include "RenderBlock.h"
+#include "RenderRubyRun.h"
+
+namespace WebCore {
+
+enum IndentTextOrNot { DoNotIndentText, IndentText };
+
+inline LayoutUnit logicalHeightForLine(const RenderBlock* block, bool isFirstLine, LayoutUnit replacedHeight = 0)
+{
+    if (!block->document().inNoQuirksMode() && replacedHeight)
+        return replacedHeight;
+
+    if (!(block->style(isFirstLine)->lineBoxContain() & LineBoxContainBlock))
+        return 0;
+
+    return std::max<LayoutUnit>(replacedHeight, block->lineHeight(isFirstLine, block->isHorizontalWritingMode() ? HorizontalLine : VerticalLine, PositionOfInteriorLineBoxes));
+}
+
+class LineWidth {
+public:
+    LineWidth(RenderBlock&, bool isFirstLine, IndentTextOrNot shouldIndentText);
+
+    bool fitsOnLine(bool ignoringTrailingSpace = false) const;
+    bool fitsOnLineIncludingExtraWidth(float extra) const;
+    bool fitsOnLineExcludingTrailingWhitespace(float extra) const;
+
+    float currentWidth() const { return m_committedWidth + m_uncommittedWidth; }
+    // FIXME: We should eventually replace these three functions by ones that work on a higher abstraction.
+    float uncommittedWidth() const { return m_uncommittedWidth; }
+    float committedWidth() const { return m_committedWidth; }
+    float availableWidth() const { return m_availableWidth; }
+
+    void updateAvailableWidth(LayoutUnit minimumHeight = 0);
+    void shrinkAvailableWidthForNewFloatIfNeeded(FloatingObject*);
+    void addUncommittedWidth(float delta) { m_uncommittedWidth += delta; }
+    void commit();
+    void applyOverhang(RenderRubyRun*, RenderObject* startRenderer, RenderObject* endRenderer);
+    void fitBelowFloats();
+    void setTrailingWhitespaceWidth(float collapsedWhitespace, float borderPaddingMargin = 0);
+
+    bool shouldIndentText() const { return m_shouldIndentText == IndentText; }
+
+private:
+    void computeAvailableWidthFromLeftAndRight();
+    bool fitsOnLineExcludingTrailingCollapsedWhitespace() const;
+
+    RenderBlock& m_block;
+    float m_uncommittedWidth;
+    float m_committedWidth;
+    float m_overhangWidth; // The amount by which |m_availableWidth| has been inflated to account for possible contraction due to ruby overhang.
+    float m_trailingWhitespaceWidth;
+    float m_trailingCollapsedWhitespaceWidth;
+    float m_left;
+    float m_right;
+    float m_availableWidth;
+#if ENABLE(CSS_SHAPES)
+    const LineSegment* m_segment;
+#endif
+    bool m_isFirstLine;
+    IndentTextOrNot m_shouldIndentText;
+};
+
+}
+
+#endif // LineWidth_h
index 9d12ab6..2ea2f5e 100644 (file)
@@ -28,6 +28,7 @@
 #include "Hyphenation.h"
 #include "InlineIterator.h"
 #include "InlineTextBox.h"
+#include "LineWidth.h"
 #include "Logging.h"
 #include "RenderArena.h"
 #include "RenderCombineText.h"
@@ -66,17 +67,6 @@ namespace WebCore {
 // We don't let our line box tree for a single line get any deeper than this.
 const unsigned cMaxLineDepth = 200;
 
-static LayoutUnit logicalHeightForLine(const RenderBlock* block, bool isFirstLine, LayoutUnit replacedHeight = 0)
-{
-    if (!block->document().inNoQuirksMode() && replacedHeight)
-        return replacedHeight;
-
-    if (!(block->style(isFirstLine)->lineBoxContain() & LineBoxContainBlock))
-        return 0;
-
-    return max<LayoutUnit>(replacedHeight, block->lineHeight(isFirstLine, block->isHorizontalWritingMode() ? HorizontalLine : VerticalLine, PositionOfInteriorLineBoxes));
-}
-
 #if ENABLE(CSS_SHAPES)
 ShapeInsideInfo* RenderBlock::layoutShapeInsideInfo() const
 {
@@ -94,208 +84,6 @@ ShapeInsideInfo* RenderBlock::layoutShapeInsideInfo() const
 }
 #endif
 
-enum IndentTextOrNot { DoNotIndentText, IndentText };
-
-class LineWidth {
-public:
-    LineWidth(RenderBlock* block, bool isFirstLine, IndentTextOrNot shouldIndentText)
-        : m_block(block)
-        , m_uncommittedWidth(0)
-        , m_committedWidth(0)
-        , m_overhangWidth(0)
-        , m_trailingWhitespaceWidth(0)
-        , m_trailingCollapsedWhitespaceWidth(0)
-        , m_left(0)
-        , m_right(0)
-        , m_availableWidth(0)
-#if ENABLE(CSS_SHAPES)
-        , m_segment(0)
-#endif
-        , m_isFirstLine(isFirstLine)
-        , m_shouldIndentText(shouldIndentText)
-    {
-        ASSERT(block);
-#if ENABLE(CSS_SHAPES)
-        if (ShapeInsideInfo* shapeInsideInfo = m_block->layoutShapeInsideInfo())
-            m_segment = shapeInsideInfo->currentSegment();
-#endif
-        updateAvailableWidth();
-    }
-    bool fitsOnLine(bool ignoringTrailingSpace = false)
-    {
-        return ignoringTrailingSpace ? fitsOnLineExcludingTrailingCollapsedWhitespace() : fitsOnLineIncludingExtraWidth(0);
-    }
-    bool fitsOnLineIncludingExtraWidth(float extra) const { return currentWidth() + extra <= m_availableWidth; }
-    bool fitsOnLineExcludingTrailingWhitespace(float extra) const { return currentWidth() - m_trailingWhitespaceWidth + extra <= m_availableWidth; }
-
-    float currentWidth() const { return m_committedWidth + m_uncommittedWidth; }
-    // FIXME: We should eventually replace these three functions by ones that work on a higher abstraction.
-    float uncommittedWidth() const { return m_uncommittedWidth; }
-    float committedWidth() const { return m_committedWidth; }
-    float availableWidth() const { return m_availableWidth; }
-
-    void updateAvailableWidth(LayoutUnit minimumHeight = 0);
-    void shrinkAvailableWidthForNewFloatIfNeeded(FloatingObject*);
-    void addUncommittedWidth(float delta) { m_uncommittedWidth += delta; }
-    void commit()
-    {
-        m_committedWidth += m_uncommittedWidth;
-        m_uncommittedWidth = 0;
-    }
-    void applyOverhang(RenderRubyRun*, RenderObject* startRenderer, RenderObject* endRenderer);
-    void fitBelowFloats();
-    void setTrailingWhitespaceWidth(float collapsedWhitespace, float borderPaddingMargin = 0) { m_trailingCollapsedWhitespaceWidth = collapsedWhitespace; m_trailingWhitespaceWidth =  collapsedWhitespace + borderPaddingMargin; }
-
-    bool shouldIndentText() const { return m_shouldIndentText == IndentText; }
-
-private:
-    void computeAvailableWidthFromLeftAndRight()
-    {
-        m_availableWidth = max(0.0f, m_right - m_left) + m_overhangWidth;
-    }
-    bool fitsOnLineExcludingTrailingCollapsedWhitespace() const { return currentWidth() - m_trailingCollapsedWhitespaceWidth <= m_availableWidth; }
-
-private:
-    RenderBlock* m_block;
-    float m_uncommittedWidth;
-    float m_committedWidth;
-    float m_overhangWidth; // The amount by which |m_availableWidth| has been inflated to account for possible contraction due to ruby overhang.
-    float m_trailingWhitespaceWidth;
-    float m_trailingCollapsedWhitespaceWidth;
-    float m_left;
-    float m_right;
-    float m_availableWidth;
-#if ENABLE(CSS_SHAPES)
-    const LineSegment* m_segment;
-#endif
-    bool m_isFirstLine;
-    IndentTextOrNot m_shouldIndentText;
-};
-
-inline void LineWidth::updateAvailableWidth(LayoutUnit replacedHeight)
-{
-    LayoutUnit height = m_block->logicalHeight();
-    LayoutUnit logicalHeight = logicalHeightForLine(m_block, m_isFirstLine, replacedHeight);
-    m_left = m_block->logicalLeftOffsetForLine(height, shouldIndentText(), logicalHeight);
-    m_right = m_block->logicalRightOffsetForLine(height, shouldIndentText(), logicalHeight);
-
-#if ENABLE(CSS_SHAPES)
-    if (m_segment) {
-        m_left = max<float>(m_segment->logicalLeft, m_left);
-        m_right = min<float>(m_segment->logicalRight, m_right);
-    }
-#endif
-
-    computeAvailableWidthFromLeftAndRight();
-}
-
-inline void LineWidth::shrinkAvailableWidthForNewFloatIfNeeded(FloatingObject* newFloat)
-{
-    LayoutUnit height = m_block->logicalHeight();
-    if (height < newFloat->logicalTop(m_block->isHorizontalWritingMode()) || height >= newFloat->logicalBottom(m_block->isHorizontalWritingMode()))
-        return;
-
-#if ENABLE(CSS_SHAPES)
-    // When floats with shape outside are stacked, the floats are positioned based on the margin box of the float,
-    // not the shape's contour. Since we computed the width based on the shape contour when we added the float,
-    // when we add a subsequent float on the same line, we need to undo the shape delta in order to position
-    // based on the margin box. In order to do this, we need to walk back through the floating object list to find
-    // the first previous float that is on the same side as our newFloat.
-    ShapeOutsideInfo* previousShapeOutsideInfo = 0;
-    const FloatingObjectSet& floatingObjectSet = m_block->m_floatingObjects->set();
-    FloatingObjectSetIterator it = floatingObjectSet.end();
-    FloatingObjectSetIterator begin = floatingObjectSet.begin();
-    for (--it; it != begin; --it) {
-        FloatingObject* previousFloat = *it;
-        if (previousFloat != newFloat && previousFloat->type() == newFloat->type()) {
-            previousShapeOutsideInfo = previousFloat->renderer()->shapeOutsideInfo();
-            if (previousShapeOutsideInfo) {
-                previousShapeOutsideInfo->computeSegmentsForContainingBlockLine(m_block->logicalHeight(), previousFloat->logicalTop(m_block->isHorizontalWritingMode()), logicalHeightForLine(m_block, m_isFirstLine));
-            }
-            break;
-        }
-    }
-
-    ShapeOutsideInfo* shapeOutsideInfo = newFloat->renderer()->shapeOutsideInfo();
-    if (shapeOutsideInfo) {
-        shapeOutsideInfo->computeSegmentsForContainingBlockLine(m_block->logicalHeight(), newFloat->logicalTop(m_block->isHorizontalWritingMode()), logicalHeightForLine(m_block, m_isFirstLine));
-    }
-#endif
-
-    if (newFloat->type() == FloatingObject::FloatLeft) {
-        float newLeft = newFloat->logicalRight(m_block->isHorizontalWritingMode());
-#if ENABLE(CSS_SHAPES)
-        if (previousShapeOutsideInfo)
-            newLeft -= previousShapeOutsideInfo->rightSegmentMarginBoxDelta();
-        if (shapeOutsideInfo)
-            newLeft += shapeOutsideInfo->rightSegmentMarginBoxDelta();
-#endif
-
-        if (shouldIndentText() && m_block->style()->isLeftToRightDirection())
-            newLeft += floorToInt(m_block->textIndentOffset());
-        m_left = max<float>(m_left, newLeft);
-    } else {
-        float newRight = newFloat->logicalLeft(m_block->isHorizontalWritingMode());
-#if ENABLE(CSS_SHAPES)
-        if (previousShapeOutsideInfo)
-            newRight -= previousShapeOutsideInfo->leftSegmentMarginBoxDelta();
-        if (shapeOutsideInfo)
-            newRight += shapeOutsideInfo->leftSegmentMarginBoxDelta();
-#endif
-
-        if (shouldIndentText() && !m_block->style()->isLeftToRightDirection())
-            newRight -= floorToInt(m_block->textIndentOffset());
-        m_right = min<float>(m_right, newRight);
-    }
-
-    computeAvailableWidthFromLeftAndRight();
-}
-
-void LineWidth::applyOverhang(RenderRubyRun* rubyRun, RenderObject* startRenderer, RenderObject* endRenderer)
-{
-    int startOverhang;
-    int endOverhang;
-    rubyRun->getOverhang(m_isFirstLine, startRenderer, endRenderer, startOverhang, endOverhang);
-
-    startOverhang = min<int>(startOverhang, m_committedWidth);
-    m_availableWidth += startOverhang;
-
-    endOverhang = max(min<int>(endOverhang, m_availableWidth - currentWidth()), 0);
-    m_availableWidth += endOverhang;
-    m_overhangWidth += startOverhang + endOverhang;
-}
-
-void LineWidth::fitBelowFloats()
-{
-    ASSERT(!m_committedWidth);
-    ASSERT(!fitsOnLine());
-
-    LayoutUnit floatLogicalBottom;
-    LayoutUnit lastFloatLogicalBottom = m_block->logicalHeight();
-    float newLineWidth = m_availableWidth;
-    float newLineLeft = m_left;
-    float newLineRight = m_right;
-    while (true) {
-        floatLogicalBottom = m_block->nextFloatLogicalBottomBelow(lastFloatLogicalBottom);
-        if (floatLogicalBottom <= lastFloatLogicalBottom)
-            break;
-
-        newLineLeft = m_block->logicalLeftOffsetForLine(floatLogicalBottom, shouldIndentText());
-        newLineRight = m_block->logicalRightOffsetForLine(floatLogicalBottom, shouldIndentText());
-        newLineWidth = max(0.0f, newLineRight - newLineLeft);
-        lastFloatLogicalBottom = floatLogicalBottom;
-        if (newLineWidth >= m_uncommittedWidth)
-            break;
-    }
-
-    if (newLineWidth > m_availableWidth) {
-        m_block->setLogicalHeight(lastFloatLogicalBottom);
-        m_availableWidth = newLineWidth + m_overhangWidth;
-        m_left = newLineLeft;
-        m_right = newLineRight;
-    }
-}
-
 class LineInfo {
 public:
     LineInfo()
@@ -2928,7 +2716,7 @@ InlineIterator RenderBlock::LineBreaker::nextSegmentBreak(InlineBidiResolver& re
     bool includeEndWidth = true;
     LineMidpointState& lineMidpointState = resolver.midpointState();
 
-    LineWidth width(m_block, lineInfo.isFirstLine(), requiresIndent(lineInfo.isFirstLine(), lineInfo.previousLineBrokeCleanly(), m_block->style()));
+    LineWidth width(*m_block, lineInfo.isFirstLine(), requiresIndent(lineInfo.isFirstLine(), lineInfo.previousLineBrokeCleanly(), m_block->style()));
 
     skipLeadingWhitespace(resolver, lineInfo, lastFloatFromPreviousLine, width);