diff options
| author | Simon Hausmann <simon.hausmann@nokia.com> | 2012-03-12 14:11:15 +0100 |
|---|---|---|
| committer | Simon Hausmann <simon.hausmann@nokia.com> | 2012-03-12 14:11:15 +0100 |
| commit | dd91e772430dc294e3bf478c119ef8d43c0a3358 (patch) | |
| tree | 6f33ce4d5872a5691e0291eb45bf6ab373a5f567 /Source/WebCore/rendering/RenderText.cpp | |
| parent | ad0d549d4cc13433f77c1ac8f0ab379c83d93f28 (diff) | |
| download | qtwebkit-dd91e772430dc294e3bf478c119ef8d43c0a3358.tar.gz | |
Imported WebKit commit 3db4eb1820ac8fb03065d7ea73a4d9db1e8fea1a (http://svn.webkit.org/repository/webkit/trunk@110422)
This includes build fixes for the latest qtbase/qtdeclarative as well as the final QML2 API.
Diffstat (limited to 'Source/WebCore/rendering/RenderText.cpp')
| -rw-r--r-- | Source/WebCore/rendering/RenderText.cpp | 118 |
1 files changed, 56 insertions, 62 deletions
diff --git a/Source/WebCore/rendering/RenderText.cpp b/Source/WebCore/rendering/RenderText.cpp index f2408dbcc..d497a33d6 100644 --- a/Source/WebCore/rendering/RenderText.cpp +++ b/Source/WebCore/rendering/RenderText.cpp @@ -303,10 +303,10 @@ PassRefPtr<StringImpl> RenderText::originalText() const return (e && e->isTextNode()) ? toText(e)->dataImpl() : 0; } -void RenderText::absoluteRects(Vector<LayoutRect>& rects, const LayoutPoint& accumulatedOffset) const +void RenderText::absoluteRects(Vector<IntRect>& rects, const LayoutPoint& accumulatedOffset) const { for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) - rects.append(enclosingLayoutRect(FloatRect(accumulatedOffset + box->topLeft(), box->size()))); + rects.append(enclosingIntRect(FloatRect(accumulatedOffset + box->topLeft(), box->size()))); } static FloatRect localQuadForTextBox(InlineTextBox* box, unsigned start, unsigned end, bool useSelectionHeight) @@ -330,7 +330,7 @@ static FloatRect localQuadForTextBox(InlineTextBox* box, unsigned start, unsigne return FloatRect(); } -void RenderText::absoluteRectsForRange(Vector<LayoutRect>& rects, unsigned start, unsigned end, bool useSelectionHeight, bool* wasFixed) +void RenderText::absoluteRectsForRange(Vector<IntRect>& rects, unsigned start, unsigned end, bool useSelectionHeight, bool* wasFixed) { // Work around signed/unsigned issues. This function takes unsigneds, and is often passed UINT_MAX // to mean "all the way to the end". InlineTextBox coordinates are unsigneds, so changing this @@ -347,7 +347,6 @@ void RenderText::absoluteRectsForRange(Vector<LayoutRect>& rects, unsigned start if (start <= box->start() && box->end() < end) { FloatRect r = box->calculateBoundaries(); if (useSelectionHeight) { - // FIXME: localSelectionRect should switch to return FloatRect soon with the subpixellayout branch. IntRect selectionRect = box->localSelectionRect(start, end); if (box->isHorizontal()) { r.setHeight(selectionRect.height()); @@ -479,8 +478,11 @@ static bool lineDirectionPointFitsInBox(int pointLineDirection, InlineTextBox* b // the x coordinate is equal to the left edge of this box // the affinity must be downstream so the position doesn't jump back to the previous line - if (pointLineDirection == box->logicalLeft()) + // except when box is the first box in the line + if (pointLineDirection <= box->logicalLeft()) { + shouldAffinityBeDownstream = !box->prevLeafChild() ? UpstreamIfPositionIsNotAtStart : AlwaysDownstream; return true; + } // and the x coordinate is to the left of the right edge of this box // check to see if position goes in this box @@ -491,10 +493,10 @@ static bool lineDirectionPointFitsInBox(int pointLineDirection, InlineTextBox* b // box is first on line // and the x coordinate is to the left of the first text box left edge - if (!box->prevOnLine() && pointLineDirection < box->logicalLeft()) + if (!box->prevLeafChildIgnoringLineBreak() && pointLineDirection < box->logicalLeft()) return true; - if (!box->nextOnLine()) { + if (!box->nextLeafChildIgnoringLineBreak()) { // box is last on line // and the x coordinate is to the right of the last text box right edge // generate VisiblePosition, use UPSTREAM affinity if possible @@ -535,7 +537,7 @@ static VisiblePosition createVisiblePositionAfterAdjustingOffsetForBiDi(const In if (positionIsAtStartOfBox == box->isLeftToRightDirection()) { // offset is on the left edge - const InlineBox* prevBox = box->prevLeafChild(); + const InlineBox* prevBox = box->prevLeafChildIgnoringLineBreak(); if ((prevBox && prevBox->bidiLevel() == box->bidiLevel()) || box->renderer()->containingBlock()->style()->direction() == box->direction()) // FIXME: left on 12CBA return createVisiblePositionForBox(box, box->caretLeftmostOffset(), shouldAffinityBeDownstream); @@ -545,7 +547,7 @@ static VisiblePosition createVisiblePositionAfterAdjustingOffsetForBiDi(const In const InlineBox* leftmostBox; do { leftmostBox = prevBox; - prevBox = leftmostBox->prevLeafChild(); + prevBox = leftmostBox->prevLeafChildIgnoringLineBreak(); } while (prevBox && prevBox->bidiLevel() > box->bidiLevel()); return createVisiblePositionForBox(leftmostBox, leftmostBox->caretRightmostOffset(), shouldAffinityBeDownstream); } @@ -556,7 +558,7 @@ static VisiblePosition createVisiblePositionAfterAdjustingOffsetForBiDi(const In const InlineBox* nextBox = box; do { rightmostBox = nextBox; - nextBox = rightmostBox->nextLeafChild(); + nextBox = rightmostBox->nextLeafChildIgnoringLineBreak(); } while (nextBox && nextBox->bidiLevel() >= box->bidiLevel()); return createVisiblePositionForBox(rightmostBox, box->isLeftToRightDirection() ? rightmostBox->caretMaxOffset() : rightmostBox->caretMinOffset(), shouldAffinityBeDownstream); @@ -565,7 +567,7 @@ static VisiblePosition createVisiblePositionAfterAdjustingOffsetForBiDi(const In return createVisiblePositionForBox(box, box->caretRightmostOffset(), shouldAffinityBeDownstream); } - const InlineBox* nextBox = box->nextLeafChild(); + const InlineBox* nextBox = box->nextLeafChildIgnoringLineBreak(); if ((nextBox && nextBox->bidiLevel() == box->bidiLevel()) || box->renderer()->containingBlock()->style()->direction() == box->direction()) return createVisiblePositionForBox(box, box->caretRightmostOffset(), shouldAffinityBeDownstream); @@ -576,7 +578,7 @@ static VisiblePosition createVisiblePositionAfterAdjustingOffsetForBiDi(const In const InlineBox* rightmostBox; do { rightmostBox = nextBox; - nextBox = rightmostBox->nextLeafChild(); + nextBox = rightmostBox->nextLeafChildIgnoringLineBreak(); } while (nextBox && nextBox->bidiLevel() > box->bidiLevel()); return createVisiblePositionForBox(rightmostBox, rightmostBox->caretLeftmostOffset(), shouldAffinityBeDownstream); } @@ -587,7 +589,7 @@ static VisiblePosition createVisiblePositionAfterAdjustingOffsetForBiDi(const In const InlineBox* prevBox = box; do { leftmostBox = prevBox; - prevBox = leftmostBox->prevLeafChild(); + prevBox = leftmostBox->prevLeafChildIgnoringLineBreak(); } while (prevBox && prevBox->bidiLevel() >= box->bidiLevel()); return createVisiblePositionForBox(leftmostBox, box->isLeftToRightDirection() ? leftmostBox->caretMinOffset() : leftmostBox->caretMaxOffset(), shouldAffinityBeDownstream); @@ -601,28 +603,14 @@ VisiblePosition RenderText::positionForPoint(const LayoutPoint& point) if (!firstTextBox() || textLength() == 0) return createVisiblePosition(0, DOWNSTREAM); - // Get the offset for the position, since this will take rtl text into account. - int offset; - LayoutUnit pointLineDirection = firstTextBox()->isHorizontal() ? point.x() : point.y(); LayoutUnit pointBlockDirection = firstTextBox()->isHorizontal() ? point.y() : point.x(); - - // FIXME: We should be able to roll these special cases into the general cases in the loop below. - if (firstTextBox() && pointBlockDirection < firstTextBox()->root()->selectionBottom() && pointLineDirection < firstTextBox()->logicalLeft()) { - // at the y coordinate of the first line or above - // and the x coordinate is to the left of the first text box left edge - offset = firstTextBox()->offsetForPosition(pointLineDirection); - return createVisiblePositionAfterAdjustingOffsetForBiDi(firstTextBox(), offset, UpstreamIfPositionIsNotAtStart); - } - if (lastTextBox() && pointBlockDirection >= lastTextBox()->root()->selectionTop() && pointLineDirection >= lastTextBox()->logicalRight()) { - // at the y coordinate of the last line or below - // and the x coordinate is to the right of the last text box right edge - offset = lastTextBox()->offsetForPosition(pointLineDirection); - return createVisiblePositionAfterAdjustingOffsetForBiDi(lastTextBox(), offset, AlwaysUpstream); - } - InlineTextBox* lastBoxAbove = 0; + InlineTextBox* lastBox = 0; for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) { + if (box->isLineBreak() && !box->prevLeafChild() && box->nextLeafChild() && !box->nextLeafChild()->isLineBreak()) + box = box->nextTextBox(); + RootInlineBox* rootBox = box->root(); if (pointBlockDirection >= rootBox->selectionTop() || pointBlockDirection >= rootBox->lineTop()) { LayoutUnit bottom = rootBox->selectionBottom(); @@ -631,15 +619,19 @@ VisiblePosition RenderText::positionForPoint(const LayoutPoint& point) if (pointBlockDirection < bottom) { ShouldAffinityBeDownstream shouldAffinityBeDownstream; - offset = box->offsetForPosition(pointLineDirection); if (lineDirectionPointFitsInBox(pointLineDirection, box, shouldAffinityBeDownstream)) - return createVisiblePositionAfterAdjustingOffsetForBiDi(box, offset, shouldAffinityBeDownstream); + return createVisiblePositionAfterAdjustingOffsetForBiDi(box, box->offsetForPosition(pointLineDirection), shouldAffinityBeDownstream); } - lastBoxAbove = box; } + lastBox = box; } - return createVisiblePosition(lastBoxAbove ? lastBoxAbove->start() + lastBoxAbove->len() : 0, DOWNSTREAM); + if (lastBox) { + ShouldAffinityBeDownstream shouldAffinityBeDownstream; + lineDirectionPointFitsInBox(pointLineDirection, lastBox, shouldAffinityBeDownstream); + return createVisiblePositionAfterAdjustingOffsetForBiDi(lastBox, lastBox->offsetForPosition(pointLineDirection) + lastBox->start(), shouldAffinityBeDownstream); + } + return createVisiblePosition(0, DOWNSTREAM); } LayoutRect RenderText::localCaretRect(InlineBox* inlineBox, int caretOffset, LayoutUnit* extraWidthToEndOfLine) @@ -1134,39 +1126,41 @@ float RenderText::firstRunY() const void RenderText::setSelectionState(SelectionState state) { - InlineTextBox* box; - RenderObject::setSelectionState(state); - if (state == SelectionStart || state == SelectionEnd || state == SelectionBoth) { - int startPos, endPos; - selectionStartEnd(startPos, endPos); - if (selectionState() == SelectionStart) { - endPos = textLength(); - // to handle selection from end of text to end of line - if (startPos != 0 && startPos == endPos) - startPos = endPos - 1; - } else if (selectionState() == SelectionEnd) - startPos = 0; - - for (box = firstTextBox(); box; box = box->nextTextBox()) { - if (box->isSelected(startPos, endPos)) { - RootInlineBox* line = box->root(); - if (line) - line->setHasSelectedChildren(true); + if (canUpdateSelectionOnRootLineBoxes()) { + if (state == SelectionStart || state == SelectionEnd || state == SelectionBoth) { + int startPos, endPos; + selectionStartEnd(startPos, endPos); + if (selectionState() == SelectionStart) { + endPos = textLength(); + + // to handle selection from end of text to end of line + if (startPos && startPos == endPos) + startPos = endPos - 1; + } else if (selectionState() == SelectionEnd) + startPos = 0; + + for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) { + if (box->isSelected(startPos, endPos)) { + RootInlineBox* root = box->root(); + if (root) + root->setHasSelectedChildren(true); + } + } + } else { + for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) { + RootInlineBox* root = box->root(); + if (root) + root->setHasSelectedChildren(state == SelectionInside); } - } - } else { - for (box = firstTextBox(); box; box = box->nextTextBox()) { - RootInlineBox* line = box->root(); - if (line) - line->setHasSelectedChildren(state == SelectionInside); } } - // The returned value can be null in case of an orphaned tree. - if (RenderBlock* cb = containingBlock()) - cb->setSelectionState(state); + // The containing block can be null in case of an orphaned tree. + RenderBlock* containingBlock = this->containingBlock(); + if (containingBlock && !containingBlock->isRenderView()) + containingBlock->setSelectionState(state); } void RenderText::setTextWithOffset(PassRefPtr<StringImpl> text, unsigned offset, unsigned len, bool force) |
