summaryrefslogtreecommitdiff
path: root/Source/WebCore/rendering/RenderLineBreak.cpp
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
commit1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch)
tree46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WebCore/rendering/RenderLineBreak.cpp
parent32761a6cee1d0dee366b885b7b9c777e67885688 (diff)
downloadWebKitGtk-tarball-master.tar.gz
Diffstat (limited to 'Source/WebCore/rendering/RenderLineBreak.cpp')
-rw-r--r--Source/WebCore/rendering/RenderLineBreak.cpp117
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