OLD | NEW |
1 /* | 1 /* |
2 * (C) 1999 Lars Knoll (knoll@kde.org) | 2 * (C) 1999 Lars Knoll (knoll@kde.org) |
3 * (C) 2000 Dirk Mueller (mueller@kde.org) | 3 * (C) 2000 Dirk Mueller (mueller@kde.org) |
4 * Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved. | 4 * Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved. |
5 * Copyright (C) 2006 Andrew Wellington (proton@wiretapped.net) | 5 * Copyright (C) 2006 Andrew Wellington (proton@wiretapped.net) |
6 * Copyright (C) 2006 Graham Dennis (graham.dennis@gmail.com) | 6 * Copyright (C) 2006 Graham Dennis (graham.dennis@gmail.com) |
7 * | 7 * |
8 * This library is free software; you can redistribute it and/or | 8 * This library is free software; you can redistribute it and/or |
9 * modify it under the terms of the GNU Library General Public | 9 * modify it under the terms of the GNU Library General Public |
10 * License as published by the Free Software Foundation; either | 10 * License as published by the Free Software Foundation; either |
(...skipping 506 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
517 case AlwaysDownstream: | 517 case AlwaysDownstream: |
518 affinity = TextAffinity::Downstream; | 518 affinity = TextAffinity::Downstream; |
519 break; | 519 break; |
520 case AlwaysUpstream: | 520 case AlwaysUpstream: |
521 affinity = VP_UPSTREAM_IF_POSSIBLE; | 521 affinity = VP_UPSTREAM_IF_POSSIBLE; |
522 break; | 522 break; |
523 case UpstreamIfPositionIsNotAtStart: | 523 case UpstreamIfPositionIsNotAtStart: |
524 affinity = offset > box->caretMinOffset() ? VP_UPSTREAM_IF_POSSIBLE : Te
xtAffinity::Downstream; | 524 affinity = offset > box->caretMinOffset() ? VP_UPSTREAM_IF_POSSIBLE : Te
xtAffinity::Downstream; |
525 break; | 525 break; |
526 } | 526 } |
527 int textStartOffset = box->lineLayoutItem().isText() ? LineLayoutText(box->l
ineLayoutItem()).textStartOffset() : 0; | 527 int textStartOffset = box->getLineLayoutItem().isText() ? LineLayoutText(box
->getLineLayoutItem()).textStartOffset() : 0; |
528 return box->lineLayoutItem().createPositionWithAffinity(offset + textStartOf
fset, affinity); | 528 return box->getLineLayoutItem().createPositionWithAffinity(offset + textStar
tOffset, affinity); |
529 } | 529 } |
530 | 530 |
531 static PositionWithAffinity createPositionWithAffinityForBoxAfterAdjustingOffset
ForBiDi(const InlineTextBox* box, int offset, ShouldAffinityBeDownstream shouldA
ffinityBeDownstream) | 531 static PositionWithAffinity createPositionWithAffinityForBoxAfterAdjustingOffset
ForBiDi(const InlineTextBox* box, int offset, ShouldAffinityBeDownstream shouldA
ffinityBeDownstream) |
532 { | 532 { |
533 ASSERT(box); | 533 ASSERT(box); |
534 ASSERT(offset >= 0); | 534 ASSERT(offset >= 0); |
535 | 535 |
536 if (offset && static_cast<unsigned>(offset) < box->len()) | 536 if (offset && static_cast<unsigned>(offset) < box->len()) |
537 return createPositionWithAffinityForBox(box, box->start() + offset, shou
ldAffinityBeDownstream); | 537 return createPositionWithAffinityForBox(box, box->start() + offset, shou
ldAffinityBeDownstream); |
538 | 538 |
539 bool positionIsAtStartOfBox = !offset; | 539 bool positionIsAtStartOfBox = !offset; |
540 if (positionIsAtStartOfBox == box->isLeftToRightDirection()) { | 540 if (positionIsAtStartOfBox == box->isLeftToRightDirection()) { |
541 // offset is on the left edge | 541 // offset is on the left edge |
542 | 542 |
543 const InlineBox* prevBox = box->prevLeafChildIgnoringLineBreak(); | 543 const InlineBox* prevBox = box->prevLeafChildIgnoringLineBreak(); |
544 if ((prevBox && prevBox->bidiLevel() == box->bidiLevel()) | 544 if ((prevBox && prevBox->bidiLevel() == box->bidiLevel()) |
545 || box->lineLayoutItem().containingBlock().style()->direction() == b
ox->direction()) // FIXME: left on 12CBA | 545 || box->getLineLayoutItem().containingBlock().style()->direction() =
= box->direction()) // FIXME: left on 12CBA |
546 return createPositionWithAffinityForBox(box, box->caretLeftmostOffse
t(), shouldAffinityBeDownstream); | 546 return createPositionWithAffinityForBox(box, box->caretLeftmostOffse
t(), shouldAffinityBeDownstream); |
547 | 547 |
548 if (prevBox && prevBox->bidiLevel() > box->bidiLevel()) { | 548 if (prevBox && prevBox->bidiLevel() > box->bidiLevel()) { |
549 // e.g. left of B in aDC12BAb | 549 // e.g. left of B in aDC12BAb |
550 const InlineBox* leftmostBox; | 550 const InlineBox* leftmostBox; |
551 do { | 551 do { |
552 leftmostBox = prevBox; | 552 leftmostBox = prevBox; |
553 prevBox = leftmostBox->prevLeafChildIgnoringLineBreak(); | 553 prevBox = leftmostBox->prevLeafChildIgnoringLineBreak(); |
554 } while (prevBox && prevBox->bidiLevel() > box->bidiLevel()); | 554 } while (prevBox && prevBox->bidiLevel() > box->bidiLevel()); |
555 return createPositionWithAffinityForBox(leftmostBox, leftmostBox->ca
retRightmostOffset(), shouldAffinityBeDownstream); | 555 return createPositionWithAffinityForBox(leftmostBox, leftmostBox->ca
retRightmostOffset(), shouldAffinityBeDownstream); |
556 } | 556 } |
557 | 557 |
558 if (!prevBox || prevBox->bidiLevel() < box->bidiLevel()) { | 558 if (!prevBox || prevBox->bidiLevel() < box->bidiLevel()) { |
559 // e.g. left of D in aDC12BAb | 559 // e.g. left of D in aDC12BAb |
560 const InlineBox* rightmostBox; | 560 const InlineBox* rightmostBox; |
561 const InlineBox* nextBox = box; | 561 const InlineBox* nextBox = box; |
562 do { | 562 do { |
563 rightmostBox = nextBox; | 563 rightmostBox = nextBox; |
564 nextBox = rightmostBox->nextLeafChildIgnoringLineBreak(); | 564 nextBox = rightmostBox->nextLeafChildIgnoringLineBreak(); |
565 } while (nextBox && nextBox->bidiLevel() >= box->bidiLevel()); | 565 } while (nextBox && nextBox->bidiLevel() >= box->bidiLevel()); |
566 return createPositionWithAffinityForBox(rightmostBox, | 566 return createPositionWithAffinityForBox(rightmostBox, |
567 box->isLeftToRightDirection() ? rightmostBox->caretMaxOffset() :
rightmostBox->caretMinOffset(), shouldAffinityBeDownstream); | 567 box->isLeftToRightDirection() ? rightmostBox->caretMaxOffset() :
rightmostBox->caretMinOffset(), shouldAffinityBeDownstream); |
568 } | 568 } |
569 | 569 |
570 return createPositionWithAffinityForBox(box, box->caretRightmostOffset()
, shouldAffinityBeDownstream); | 570 return createPositionWithAffinityForBox(box, box->caretRightmostOffset()
, shouldAffinityBeDownstream); |
571 } | 571 } |
572 | 572 |
573 const InlineBox* nextBox = box->nextLeafChildIgnoringLineBreak(); | 573 const InlineBox* nextBox = box->nextLeafChildIgnoringLineBreak(); |
574 if ((nextBox && nextBox->bidiLevel() == box->bidiLevel()) | 574 if ((nextBox && nextBox->bidiLevel() == box->bidiLevel()) |
575 || box->lineLayoutItem().containingBlock().style()->direction() == box->
direction()) | 575 || box->getLineLayoutItem().containingBlock().style()->direction() == bo
x->direction()) |
576 return createPositionWithAffinityForBox(box, box->caretRightmostOffset()
, shouldAffinityBeDownstream); | 576 return createPositionWithAffinityForBox(box, box->caretRightmostOffset()
, shouldAffinityBeDownstream); |
577 | 577 |
578 // offset is on the right edge | 578 // offset is on the right edge |
579 if (nextBox && nextBox->bidiLevel() > box->bidiLevel()) { | 579 if (nextBox && nextBox->bidiLevel() > box->bidiLevel()) { |
580 // e.g. right of C in aDC12BAb | 580 // e.g. right of C in aDC12BAb |
581 const InlineBox* rightmostBox; | 581 const InlineBox* rightmostBox; |
582 do { | 582 do { |
583 rightmostBox = nextBox; | 583 rightmostBox = nextBox; |
584 nextBox = rightmostBox->nextLeafChildIgnoringLineBreak(); | 584 nextBox = rightmostBox->nextLeafChildIgnoringLineBreak(); |
585 } while (nextBox && nextBox->bidiLevel() > box->bidiLevel()); | 585 } while (nextBox && nextBox->bidiLevel() > box->bidiLevel()); |
(...skipping 592 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1178 } | 1178 } |
1179 | 1179 |
1180 void LayoutText::setSelectionState(SelectionState state) | 1180 void LayoutText::setSelectionState(SelectionState state) |
1181 { | 1181 { |
1182 LayoutObject::setSelectionState(state); | 1182 LayoutObject::setSelectionState(state); |
1183 | 1183 |
1184 if (canUpdateSelectionOnRootLineBoxes()) { | 1184 if (canUpdateSelectionOnRootLineBoxes()) { |
1185 if (state == SelectionStart || state == SelectionEnd || state == Selecti
onBoth) { | 1185 if (state == SelectionStart || state == SelectionEnd || state == Selecti
onBoth) { |
1186 int startPos, endPos; | 1186 int startPos, endPos; |
1187 selectionStartEnd(startPos, endPos); | 1187 selectionStartEnd(startPos, endPos); |
1188 if (selectionState() == SelectionStart) { | 1188 if (getSelectionState() == SelectionStart) { |
1189 endPos = textLength(); | 1189 endPos = textLength(); |
1190 | 1190 |
1191 // to handle selection from end of text to end of line | 1191 // to handle selection from end of text to end of line |
1192 if (startPos && startPos == endPos) | 1192 if (startPos && startPos == endPos) |
1193 startPos = endPos - 1; | 1193 startPos = endPos - 1; |
1194 } else if (selectionState() == SelectionEnd) { | 1194 } else if (getSelectionState() == SelectionEnd) { |
1195 startPos = 0; | 1195 startPos = 0; |
1196 } | 1196 } |
1197 | 1197 |
1198 for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBo
x()) { | 1198 for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBo
x()) { |
1199 if (box->isSelected(startPos, endPos)) { | 1199 if (box->isSelected(startPos, endPos)) { |
1200 box->root().setHasSelectedChildren(true); | 1200 box->root().setHasSelectedChildren(true); |
1201 } | 1201 } |
1202 } | 1202 } |
1203 } else { | 1203 } else { |
1204 for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBo
x()) { | 1204 for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBo
x()) { |
(...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1580 | 1580 |
1581 LayoutRect paintInvalidationRect(visualOverflowRect()); | 1581 LayoutRect paintInvalidationRect(visualOverflowRect()); |
1582 mapToVisibleRectInAncestorSpace(paintInvalidationContainer, paintInvalidatio
nRect, paintInvalidationState); | 1582 mapToVisibleRectInAncestorSpace(paintInvalidationContainer, paintInvalidatio
nRect, paintInvalidationState); |
1583 return paintInvalidationRect; | 1583 return paintInvalidationRect; |
1584 } | 1584 } |
1585 | 1585 |
1586 LayoutRect LayoutText::selectionRectForPaintInvalidation(const LayoutBoxModelObj
ect* paintInvalidationContainer) const | 1586 LayoutRect LayoutText::selectionRectForPaintInvalidation(const LayoutBoxModelObj
ect* paintInvalidationContainer) const |
1587 { | 1587 { |
1588 ASSERT(!needsLayout()); | 1588 ASSERT(!needsLayout()); |
1589 | 1589 |
1590 if (selectionState() == SelectionNone) | 1590 if (getSelectionState() == SelectionNone) |
1591 return LayoutRect(); | 1591 return LayoutRect(); |
1592 LayoutBlock* cb = containingBlock(); | 1592 LayoutBlock* cb = containingBlock(); |
1593 if (!cb) | 1593 if (!cb) |
1594 return LayoutRect(); | 1594 return LayoutRect(); |
1595 | 1595 |
1596 // Now calculate startPos and endPos for painting selection. | 1596 // Now calculate startPos and endPos for painting selection. |
1597 // We include a selection while endPos > 0 | 1597 // We include a selection while endPos > 0 |
1598 int startPos, endPos; | 1598 int startPos, endPos; |
1599 if (selectionState() == SelectionInside) { | 1599 if (getSelectionState() == SelectionInside) { |
1600 // We are fully selected. | 1600 // We are fully selected. |
1601 startPos = 0; | 1601 startPos = 0; |
1602 endPos = textLength(); | 1602 endPos = textLength(); |
1603 } else { | 1603 } else { |
1604 selectionStartEnd(startPos, endPos); | 1604 selectionStartEnd(startPos, endPos); |
1605 if (selectionState() == SelectionStart) | 1605 if (getSelectionState() == SelectionStart) |
1606 endPos = textLength(); | 1606 endPos = textLength(); |
1607 else if (selectionState() == SelectionEnd) | 1607 else if (getSelectionState() == SelectionEnd) |
1608 startPos = 0; | 1608 startPos = 0; |
1609 } | 1609 } |
1610 | 1610 |
1611 LayoutRect rect; | 1611 LayoutRect rect; |
1612 | 1612 |
1613 if (startPos == endPos) | 1613 if (startPos == endPos) |
1614 return rect; | 1614 return rect; |
1615 | 1615 |
1616 for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) { | 1616 for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) { |
1617 rect.unite(box->localSelectionRect(startPos, endPos)); | 1617 rect.unite(box->localSelectionRect(startPos, endPos)); |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1709 return Character::characterRangeCodePath(characters16(), length()) == Simple
Path; | 1709 return Character::characterRangeCodePath(characters16(), length()) == Simple
Path; |
1710 } | 1710 } |
1711 | 1711 |
1712 #if ENABLE(ASSERT) | 1712 #if ENABLE(ASSERT) |
1713 | 1713 |
1714 void LayoutText::checkConsistency() const | 1714 void LayoutText::checkConsistency() const |
1715 { | 1715 { |
1716 #ifdef CHECK_CONSISTENCY | 1716 #ifdef CHECK_CONSISTENCY |
1717 const InlineTextBox* prev = nullptr; | 1717 const InlineTextBox* prev = nullptr; |
1718 for (const InlineTextBox* child = m_firstTextBox; child; child = child->next
TextBox()) { | 1718 for (const InlineTextBox* child = m_firstTextBox; child; child = child->next
TextBox()) { |
1719 ASSERT(child->lineLayoutItem().isEqual(this)); | 1719 ASSERT(child->getLineLayoutItem().isEqual(this)); |
1720 ASSERT(child->prevTextBox() == prev); | 1720 ASSERT(child->prevTextBox() == prev); |
1721 prev = child; | 1721 prev = child; |
1722 } | 1722 } |
1723 ASSERT(prev == m_lastTextBox); | 1723 ASSERT(prev == m_lastTextBox); |
1724 #endif | 1724 #endif |
1725 } | 1725 } |
1726 | 1726 |
1727 #endif | 1727 #endif |
1728 | 1728 |
1729 void LayoutText::momentarilyRevealLastTypedCharacter(unsigned lastTypedCharacter
Offset) | 1729 void LayoutText::momentarilyRevealLastTypedCharacter(unsigned lastTypedCharacter
Offset) |
(...skipping 21 matching lines...) Expand all Loading... |
1751 for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) { | 1751 for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) { |
1752 paintInvalidationContainer.invalidateDisplayItemClientOnBacking(*box, in
validationReason); | 1752 paintInvalidationContainer.invalidateDisplayItemClientOnBacking(*box, in
validationReason); |
1753 if (box->truncation() != cNoTruncation) { | 1753 if (box->truncation() != cNoTruncation) { |
1754 if (EllipsisBox* ellipsisBox = box->root().ellipsisBox()) | 1754 if (EllipsisBox* ellipsisBox = box->root().ellipsisBox()) |
1755 paintInvalidationContainer.invalidateDisplayItemClientOnBacking(
*ellipsisBox, invalidationReason); | 1755 paintInvalidationContainer.invalidateDisplayItemClientOnBacking(
*ellipsisBox, invalidationReason); |
1756 } | 1756 } |
1757 } | 1757 } |
1758 } | 1758 } |
1759 | 1759 |
1760 } // namespace blink | 1760 } // namespace blink |
OLD | NEW |