diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
commit | 1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch) | |
tree | 46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WebCore/rendering/RenderLineBreak.cpp | |
parent | 32761a6cee1d0dee366b885b7b9c777e67885688 (diff) | |
download | WebKitGtk-tarball-master.tar.gz |
webkitgtk-2.16.5HEADwebkitgtk-2.16.5master
Diffstat (limited to 'Source/WebCore/rendering/RenderLineBreak.cpp')
-rw-r--r-- | Source/WebCore/rendering/RenderLineBreak.cpp | 117 |
1 files changed, 104 insertions, 13 deletions
diff --git a/Source/WebCore/rendering/RenderLineBreak.cpp b/Source/WebCore/rendering/RenderLineBreak.cpp index a831e478c..b8199803c 100644 --- a/Source/WebCore/rendering/RenderLineBreak.cpp +++ b/Source/WebCore/rendering/RenderLineBreak.cpp @@ -24,20 +24,42 @@ #include "Document.h" #include "HTMLElement.h" +#include "HTMLWBRElement.h" #include "InlineElementBox.h" +#include "LogicalSelectionOffsetCaches.h" #include "RenderBlock.h" +#include "RenderView.h" #include "RootInlineBox.h" +#include "SimpleLineLayoutFunctions.h" #include "VisiblePosition.h" +#if PLATFORM(IOS) +#include "SelectionRect.h" +#endif + namespace WebCore { static const int invalidLineHeight = -1; -RenderLineBreak::RenderLineBreak(HTMLElement& element, PassRef<RenderStyle> style) - : RenderBoxModelObject(element, std::move(style), 0) +static const SimpleLineLayout::Layout* simpleLineLayout(const RenderLineBreak& renderer) +{ + if (!is<RenderBlockFlow>(*renderer.parent())) + return nullptr; + return downcast<RenderBlockFlow>(*renderer.parent()).simpleLineLayout(); +} + +static void ensureLineBoxes(const RenderLineBreak& renderer) +{ + if (!is<RenderBlockFlow>(*renderer.parent())) + return; + downcast<RenderBlockFlow>(*renderer.parent()).ensureLineBoxes(); +} + +RenderLineBreak::RenderLineBreak(HTMLElement& element, RenderStyle&& style) + : RenderBoxModelObject(element, WTFMove(style), 0) , m_inlineBoxWrapper(nullptr) , m_cachedLineHeight(invalidLineHeight) - , m_isWBR(element.hasTagName(HTMLNames::wbrTag)) + , m_isWBR(is<HTMLWBRElement>(element)) { setIsLineBreak(); } @@ -49,14 +71,14 @@ RenderLineBreak::~RenderLineBreak() LayoutUnit RenderLineBreak::lineHeight(bool firstLine, LineDirectionMode /*direction*/, LinePositionMode /*linePositionMode*/) const { - if (firstLine && document().styleSheetCollection().usesFirstLineRules()) { + if (firstLine && view().usesFirstLineRules()) { const RenderStyle& firstLineStyle = this->firstLineStyle(); if (&firstLineStyle != &style()) - return firstLineStyle.computedLineHeight(&view()); + return firstLineStyle.computedLineHeight(); } if (m_cachedLineHeight == invalidLineHeight) - m_cachedLineHeight = style().computedLineHeight(&view()); + m_cachedLineHeight = style().computedLineHeight(); return m_cachedLineHeight; } @@ -89,7 +111,7 @@ void RenderLineBreak::deleteInlineBoxWrapper() { if (!m_inlineBoxWrapper) return; - if (!documentBeingDestroyed()) + if (!renderTreeBeingDestroyed()) m_inlineBoxWrapper->removeFromParent(); delete m_inlineBoxWrapper; m_inlineBoxWrapper = nullptr; @@ -107,6 +129,12 @@ void RenderLineBreak::dirtyLineBoxes(bool fullLayout) m_inlineBoxWrapper->dirtyLineBoxes(); } +void RenderLineBreak::deleteLineBoxesBeforeSimpleLineLayout() +{ + delete m_inlineBoxWrapper; + m_inlineBoxWrapper = nullptr; +} + int RenderLineBreak::caretMinOffset() const { return 0; @@ -122,33 +150,38 @@ bool RenderLineBreak::canBeSelectionLeaf() const return true; } -VisiblePosition RenderLineBreak::positionForPoint(const LayoutPoint&) +VisiblePosition RenderLineBreak::positionForPoint(const LayoutPoint&, const RenderRegion*) { + ensureLineBoxes(*this); return createVisiblePosition(0, DOWNSTREAM); } void RenderLineBreak::setSelectionState(SelectionState state) { + if (state != SelectionNone) + ensureLineBoxes(*this); RenderBoxModelObject::setSelectionState(state); if (!m_inlineBoxWrapper) return; m_inlineBoxWrapper->root().setHasSelectedChildren(state != SelectionNone); } -LayoutRect RenderLineBreak::localCaretRect(InlineBox* inlineBox, int caretOffset, LayoutUnit* extraWidthToEndOfLine) +LayoutRect RenderLineBreak::localCaretRect(InlineBox* inlineBox, unsigned caretOffset, LayoutUnit* extraWidthToEndOfLine) { ASSERT_UNUSED(caretOffset, !caretOffset); ASSERT_UNUSED(inlineBox, inlineBox == m_inlineBoxWrapper); if (!inlineBox) return LayoutRect(); - static const unsigned caretWidth = 1; const RootInlineBox& rootBox = inlineBox->root(); return rootBox.computeCaretRect(inlineBox->logicalLeft(), caretWidth, extraWidthToEndOfLine); } IntRect RenderLineBreak::linesBoundingBox() const { + if (auto* layout = simpleLineLayout(*this)) + return SimpleLineLayout::computeBoundingBox(*this, *layout); + if (!m_inlineBoxWrapper) return IntRect(); @@ -166,6 +199,11 @@ IntRect RenderLineBreak::linesBoundingBox() const void RenderLineBreak::absoluteRects(Vector<IntRect>& rects, const LayoutPoint& accumulatedOffset) const { + if (auto* layout = simpleLineLayout(*this)) { + rects.appendVector(SimpleLineLayout::collectAbsoluteRects(*this, *layout, accumulatedOffset)); + return; + } + if (!m_inlineBoxWrapper) return; rects.append(enclosingIntRect(FloatRect(accumulatedOffset + m_inlineBoxWrapper->topLeft(), m_inlineBoxWrapper->size()))); @@ -173,9 +211,13 @@ void RenderLineBreak::absoluteRects(Vector<IntRect>& rects, const LayoutPoint& a void RenderLineBreak::absoluteQuads(Vector<FloatQuad>& quads, bool* wasFixed) const { + if (auto* layout = simpleLineLayout(*this)) { + quads.appendVector(SimpleLineLayout::collectAbsoluteQuads(*this, *layout, wasFixed)); + return; + } if (!m_inlineBoxWrapper) return; - quads.append(localToAbsoluteQuad(FloatRect(m_inlineBoxWrapper->topLeft(), m_inlineBoxWrapper->size()), 0 /* mode */, wasFixed)); + quads.append(localToAbsoluteQuad(FloatRect(m_inlineBoxWrapper->topLeft(), m_inlineBoxWrapper->size()), UseTransforms, wasFixed)); } void RenderLineBreak::updateFromStyle() @@ -183,9 +225,58 @@ void RenderLineBreak::updateFromStyle() m_cachedLineHeight = invalidLineHeight; } -IntRect RenderLineBreak::borderBoundingBox() const +#if PLATFORM(IOS) +void RenderLineBreak::collectSelectionRects(Vector<SelectionRect>& rects, unsigned, unsigned) { - return IntRect(IntPoint(), linesBoundingBox().size()); + ensureLineBoxes(*this); + InlineElementBox* box = m_inlineBoxWrapper; + if (!box) + return; + const RootInlineBox& rootBox = box->root(); + LayoutRect rect = rootBox.computeCaretRect(box->logicalLeft(), 0, nullptr); + if (rootBox.isFirstAfterPageBreak()) { + if (box->isHorizontal()) + rect.shiftYEdgeTo(rootBox.lineTopWithLeading()); + else + rect.shiftXEdgeTo(rootBox.lineTopWithLeading()); + } + + auto* containingBlock = containingBlockForObjectInFlow(); + // Map rect, extended left to leftOffset, and right to rightOffset, through transforms to get minX and maxX. + LogicalSelectionOffsetCaches cache(*containingBlock); + LayoutUnit leftOffset = containingBlock->logicalLeftSelectionOffset(*containingBlock, box->logicalTop(), cache); + LayoutUnit rightOffset = containingBlock->logicalRightSelectionOffset(*containingBlock, box->logicalTop(), cache); + LayoutRect extentsRect = rect; + if (box->isHorizontal()) { + extentsRect.setX(leftOffset); + extentsRect.setWidth(rightOffset - leftOffset); + } else { + extentsRect.setY(leftOffset); + extentsRect.setHeight(rightOffset - leftOffset); + } + extentsRect = localToAbsoluteQuad(FloatRect(extentsRect)).enclosingBoundingBox(); + if (!box->isHorizontal()) + extentsRect = extentsRect.transposedRect(); + bool isFirstOnLine = !box->previousOnLineExists(); + bool isLastOnLine = !box->nextOnLineExists(); + if (containingBlock->isRubyBase() || containingBlock->isRubyText()) + isLastOnLine = !containingBlock->containingBlock()->inlineBoxWrapper()->nextOnLineExists(); + + bool isFixed = false; + IntRect absRect = localToAbsoluteQuad(FloatRect(rect), UseTransforms, &isFixed).enclosingBoundingBox(); + bool boxIsHorizontal = !box->isSVGInlineTextBox() ? box->isHorizontal() : !style().isVerticalWritingMode(); + // If the containing block is an inline element, we want to check the inlineBoxWrapper orientation + // to determine the orientation of the block. In this case we also use the inlineBoxWrapper to + // determine if the element is the last on the line. + if (containingBlock->inlineBoxWrapper()) { + if (containingBlock->inlineBoxWrapper()->isHorizontal() != boxIsHorizontal) { + boxIsHorizontal = containingBlock->inlineBoxWrapper()->isHorizontal(); + isLastOnLine = !containingBlock->inlineBoxWrapper()->nextOnLineExists(); + } + } + + rects.append(SelectionRect(absRect, box->direction(), extentsRect.x(), extentsRect.maxX(), extentsRect.maxY(), 0, box->isLineBreak(), isFirstOnLine, isLastOnLine, false, false, boxIsHorizontal, isFixed, containingBlock->isRubyText(), view().pageNumberForBlockProgressionOffset(absRect.x()))); } +#endif } // namespace WebCore |