Changeset 32508 in webkit
- Timestamp:
- Apr 24, 2008 12:09:48 PM (16 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 38 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r32497 r32508 1 2008-04-24 Dan Bernstein <mitz@apple.com> 2 3 Reviewed by Darin Adler. 4 5 - test the visual position of the primary caret in bidirectional text 6 7 * platform/mac/editing/input/caret-primary-bidi-expected.txt: Added. 8 * platform/mac/editing/input/caret-primary-bidi.html: Added. 9 1 10 2008-04-24 Justin Garcia <justin.garcia@apple.com> 2 11 -
trunk/WebCore/ChangeLog
r32504 r32508 1 2008-04-24 Dan Bernstein <mitz@apple.com> 2 3 Reviewed by Darin Adler. 4 5 - preparation for https://bugs.webkit.org/show_bug.cgi?id=3729 6 <rdar://problem/4036353> REGRESSION: arrow keys move insertion bar backwards in RTL text 7 8 The three main changes in this patch are: 9 10 1) Making all inline boxes know their bidi level, instead of just text 11 boxes knowing whether their bidi level is odd or even. This is 12 required for the next change. 13 14 2) Replacing RenderObject::inlineBox() with 15 Position::getInlineBoxAndOffset() in recognition of the fact that the 16 inline box containing the primary caret for a position in a given 17 node may belong to a different node's renderer. 18 19 3) Changing RenderObject::caretRect() to take an InlineBox parameter, 20 and changing callers to call VisiblePosition::caretRect(), which 21 locates the inline box, then calls caretRect() on the renderer for 22 that box. This, combined with the previous change, ensures that the 23 primary caret is rendered at the right place for positions that 24 lie on a directionality boundary. 25 26 Test: platform/mac/editing/input/caret-primary-bidi.html 27 28 * WebCore.base.exp: Added the VisiblePosition(Node*, int, EAffinity) 29 constructor and VisiblePosition::caretRect(), and sorted. 30 31 * dom/Position.cpp: 32 (WebCore::nextRenderedEditable): Adjusted for the removal of 33 RenderObject::inlineBox(). 34 (WebCore::previousRenderedEditable): Ditto. 35 (WebCore::Position::rendersInDifferentPosition): Ditto. 36 (WebCore::Position::getInlineBoxAndOffset): Added. Gets the inline box 37 and the offset within that box at which the primary caret for this 38 position should render. 39 40 * dom/Position.h: 41 42 * editing/DeleteSelectionCommand.cpp: 43 (WebCore::DeleteSelectionCommand::mergeParagraphs): Changed to call 44 VisiblePosition::caretRect() instead of calling the RenderObject method. 45 46 * editing/SelectionController.cpp: 47 (WebCore::caretY): Ditto. 48 (WebCore::SelectionController::xPosForVerticalArrowNavigation): Ditto. 49 (WebCore::SelectionController::layout): Ditto. 50 51 * editing/VisiblePosition.cpp: 52 (WebCore::VisiblePosition::caretRect): Changed to call 53 getInlineBoxAndOffset() to get the correct inline box and call the 54 renderer for that box. 55 56 * editing/VisiblePosition.h: 57 (WebCore::VisiblePosition::getInlineBoxAndOffset): Added convenience 58 methods for getting the inline box and caret offset for a visible 59 position, accounting for its affinity. 60 61 * editing/visible_units.cpp: 62 (WebCore::rootBoxForLine): Changed to use getInlineBoxAndOffset() 63 instead of RenderObject::inlineBox(). 64 (WebCore::startPositionForLine): 65 (WebCore::endPositionForLine): 66 (WebCore::previousLinePosition): Ditto. 67 (WebCore::nextLinePosition): Ditto. 68 69 * page/AccessibilityObject.cpp: 70 (WebCore::updateAXLineStartForVisiblePosition): Ditto. 71 72 * page/Frame.cpp: 73 (WebCore::Frame::firstRectForRange): Ditto. 74 75 * rendering/InlineBox.cpp: 76 (WebCore::InlineBox::caretMinOffset): Changed to forward to the 77 renderer. 78 (WebCore::InlineBox::caretMaxOffset): Ditto. 79 * rendering/InlineBox.h: Replaced the m_reversed bit, intended for use 80 in InlineTextBox only, with six bits of the bidi level of the box, 81 intended for use in all leaf inline boxes. 82 (WebCore::InlineBox::InlineBox): Added missing initializer for 83 m_dirOverride and initialized the bidi level. 84 (WebCore::InlineBox::bidiLevel): Added this accessor. 85 (WebCore::InlineBox::setBidiLevel): Ditto. 86 (WebCore::InlineBox::direction): Ditto. 87 (WebCore::InlineBox::caretLeftmostOffset): Added this convenience 88 method. 89 (WebCore::InlineBox::caretRightmostOffset): Ditto. 90 91 * rendering/InlineTextBox.cpp: Replaced all references to m_reversed 92 with checking of direction(). 93 (WebCore::InlineTextBox::selectionRect): 94 (WebCore::InlineTextBox::placeEllipsisBox): 95 (WebCore::InlineTextBox::paint): 96 (WebCore::InlineTextBox::paintSelection): 97 (WebCore::InlineTextBox::paintCompositionBackground): 98 (WebCore::InlineTextBox::paintSpellingOrGrammarMarker): 99 (WebCore::InlineTextBox::paintTextMatchMarker): 100 (WebCore::InlineTextBox::textPos): 101 (WebCore::InlineTextBox::offsetForPosition): 102 (WebCore::InlineTextBox::positionForOffset): 103 104 * rendering/RenderBR.cpp: Removed inlineBox(). 105 * rendering/RenderBR.h: Ditto. 106 107 * rendering/RenderBox.cpp: 108 (WebCore::RenderBox::caretRect): Changed to take an inline box and 109 account for the direction of the box (or the renderer) in positioning 110 the caret: in right-to-left boxes, the "before" position is to the right 111 while "after" is to the left. 112 * rendering/RenderBox.h: 113 114 * rendering/RenderFlow.cpp: 115 (WebCore::RenderFlow::caretRect): Updated the signature. 116 * rendering/RenderFlow.h: 117 118 * rendering/RenderObject.cpp: 119 (WebCore::RenderObject::caretRect): Updated the signature. 120 (WebCore::RenderObject::caretMaxOffset): Changed to return the child 121 node count (or 1 if there are no children) for replaced elements, such 122 as <select>s. 123 * rendering/RenderObject.h: 124 125 * rendering/RenderReplaced.cpp: Removed caretMinOffset() and 126 caretMaxOffset() because the base class implementation does the right 127 thing for replaced objects now. 128 * rendering/RenderReplaced.h: 129 130 * rendering/RenderSVGInlineText.cpp: 131 (WebCore::RenderSVGInlineText::caretRect): Updated the signature. 132 (WebCore::RenderSVGInlineText::positionForCoordinates): Updated for 133 the change from m_reversed to direction(). 134 * rendering/RenderSVGInlineText.h: 135 136 * rendering/RenderText.cpp: 137 (WebCore::RenderText::caretRect): Changed to take an inline box and 138 removed the code that used to find the inline for the given position. 139 Changed use of m_reversed to use direction(). 140 (WebCore::RenderText::position): Changed use of m_reversed to use 141 direction(). 142 * rendering/RenderText.h: 143 144 * rendering/RenderTextControl.cpp: 145 (WebCore::RenderTextControl::textWithHardLineBreaks): Adjusted for the 146 removal of RenderObject::inlineBox(). 147 148 * rendering/RenderTreeAsText.cpp: 149 (WebCore::writeTextRun): Changed to use direction() instead of 150 m_reversed. 151 152 * rendering/SVGInlineTextBox.cpp: Ditto. 153 (WebCore::SVGInlineTextBox::calculateGlyphBoundaries): 154 (WebCore::SVGInlineTextBoxClosestCharacterToPositionWalker::chunkPortionCallback): 155 (WebCore::SVGInlineTextBox::svgCharacterHitsPosition): 156 157 * rendering/SVGRenderTreeAsText.cpp: Ditto. 158 (WebCore::writeSVGInlineTextBox): 159 160 * rendering/SVGRootInlineBox.cpp: Ditto. 161 (WebCore::svgTextRunForInlineTextBox): 162 (WebCore::cummulatedWidthOrHeightOfTextChunk): 163 (WebCore::SVGRootInlineBox::buildLayoutInformationForTextBox): 164 165 * rendering/bidi.cpp: 166 (WebCore::RenderBlock::constructLine): Made this function set the 167 bidi level on all leaf boxes. 168 169 * svg/SVGTextContentElement.cpp: Changed to use direction() instead of 170 m_reversed. 171 (WebCore::cumulativeCharacterRangeLength): 172 (WebCore::SVGInlineTextBoxQueryWalker::chunkPortionCallback): 173 1 174 2008-04-24 Sam Weinig <sam@webkit.org> 2 175 -
trunk/WebCore/WebCore.base.exp
r32320 r32508 335 335 __ZN7WebCore15StringTruncator14centerTruncateERKNS_6StringEfRKNS_4FontEb 336 336 __ZN7WebCore15StringTruncator5widthERKNS_6StringERKNS_4FontEb 337 __ZN7WebCore15VisiblePositionC1EPNS_4NodeEiNS_9EAffinityE 337 338 __ZN7WebCore15VisiblePositionC1ERKNS_8PositionENS_9EAffinityE 338 339 __ZN7WebCore16FontPlatformDataC1EP6NSFontbb … … 633 634 __ZNK7WebCore11FrameLoader16responseMIMETypeEv 634 635 __ZNK7WebCore11FrameLoader20activeDocumentLoaderEv 636 __ZNK7WebCore11FrameLoader21isQuickRedirectComingEv 635 637 __ZNK7WebCore11FrameLoader25provisionalDocumentLoaderEv 636 __ZNK7WebCore11FrameLoader21isQuickRedirectComingEv637 638 __ZNK7WebCore11FrameLoader27numPendingOrLoadingRequestsEb 638 639 __ZNK7WebCore11FrameLoader6clientEv … … 702 703 __ZNK7WebCore15VisiblePosition4nextEb 703 704 __ZNK7WebCore15VisiblePosition8previousEb 705 __ZNK7WebCore15VisiblePosition9caretRectEv 704 706 __ZNK7WebCore16ResourceResponse13nsURLResponseEv 705 707 __ZNK7WebCore17ResourceErrorBase8lazyInitEv -
trunk/WebCore/dom/Position.cpp
r32438 r32508 51 51 if (!node) 52 52 return 0; 53 if (!node->renderer()) 53 RenderObject* renderer = node->renderer(); 54 if (!renderer) 54 55 continue; 55 if ( node->renderer()->inlineBox(0))56 if (renderer->inlineBoxWrapper() || renderer->isText() && static_cast<RenderText*>(renderer)->firstTextBox()) 56 57 return node; 57 58 } … … 65 66 if (!node) 66 67 return 0; 67 if (!node->renderer()) 68 RenderObject* renderer = node->renderer(); 69 if (!renderer) 68 70 continue; 69 if ( node->renderer()->inlineBox(0))71 if (renderer->inlineBoxWrapper() || renderer->isText() && static_cast<RenderText*>(renderer)->firstTextBox()) 70 72 return node; 71 73 } … … 684 686 return false; 685 687 686 LOG(Editing, "renderer: %p [%p]\n", renderer, renderer ? renderer->inlineBox(offset()) : 0); 688 int ignoredCaretOffset; 689 InlineBox* b1; 690 getInlineBoxAndOffset(DOWNSTREAM, b1, ignoredCaretOffset); 691 InlineBox* b2; 692 pos.getInlineBoxAndOffset(DOWNSTREAM, b2, ignoredCaretOffset); 693 694 LOG(Editing, "renderer: %p [%p]\n", renderer, b1); 687 695 LOG(Editing, "thisRenderedOffset: %d\n", thisRenderedOffset); 688 LOG(Editing, "posRenderer: %p [%p]\n", posRenderer, posRenderer ? posRenderer->inlineBox(offset()) : 0);696 LOG(Editing, "posRenderer: %p [%p]\n", posRenderer, b2); 689 697 LOG(Editing, "posRenderedOffset: %d\n", posRenderedOffset); 690 698 LOG(Editing, "node min/max: %d:%d\n", caretMinOffset(node()), caretMaxRenderedOffset(node())); 691 699 LOG(Editing, "pos node min/max: %d:%d\n", caretMinOffset(pos.node()), caretMaxRenderedOffset(pos.node())); 692 700 LOG(Editing, "----------------------------------------------------------------------\n"); 693 694 InlineBox *b1 = renderer ? renderer->inlineBox(offset()) : 0;695 InlineBox *b2 = posRenderer ? posRenderer->inlineBox(pos.offset()) : 0;696 701 697 702 if (!b1 || !b2) { … … 753 758 754 759 return Position(); 760 } 761 762 void Position::getInlineBoxAndOffset(EAffinity affinity, InlineBox*& inlineBox, int& caretOffset) const 763 { 764 TextDirection primaryDirection = LTR; 765 for (RenderObject* r = node()->renderer(); r; r = r->parent()) { 766 if (r->isBlockFlow()) { 767 primaryDirection = r->style()->direction(); 768 break; 769 } 770 } 771 getInlineBoxAndOffset(affinity, primaryDirection, inlineBox, caretOffset); 772 } 773 774 void Position::getInlineBoxAndOffset(EAffinity affinity, TextDirection primaryDirection, InlineBox*& inlineBox, int& caretOffset) const 775 { 776 caretOffset = offset(); 777 RenderObject* renderer = node()->renderer(); 778 if (!renderer->isText()) { 779 inlineBox = renderer->inlineBoxWrapper(); 780 if (!inlineBox || caretOffset > inlineBox->caretMinOffset() && caretOffset < inlineBox->caretMaxOffset()) 781 return; 782 } else { 783 RenderText* textRenderer = static_cast<RenderText*>(renderer); 784 785 InlineTextBox* box; 786 InlineTextBox* candidate = 0; 787 788 for (box = textRenderer->firstTextBox(); box; box = box->nextTextBox()) { 789 int caretMinOffset = box->caretMinOffset(); 790 int caretMaxOffset = box->caretMaxOffset(); 791 792 if (caretOffset < caretMinOffset || caretOffset > caretMaxOffset) 793 continue; 794 795 if (caretOffset > caretMinOffset && caretOffset < caretMaxOffset) { 796 inlineBox = box; 797 return; 798 } 799 800 if (caretOffset == caretMinOffset ^ affinity == UPSTREAM) 801 break; 802 803 candidate = box; 804 } 805 inlineBox = box ? box : candidate; 806 } 807 808 if (!inlineBox) 809 return; 810 811 unsigned char level = inlineBox->bidiLevel(); 812 813 if (inlineBox->direction() == primaryDirection) { 814 if (caretOffset == inlineBox->caretRightmostOffset()) { 815 InlineBox* nextBox = inlineBox->nextLeafChild(); 816 if (!nextBox || nextBox->bidiLevel() >= level) 817 return; 818 819 level = nextBox->bidiLevel(); 820 InlineBox* prevBox = inlineBox; 821 do { 822 prevBox = prevBox->prevLeafChild(); 823 } while (prevBox && prevBox->bidiLevel() > level); 824 825 if (prevBox && prevBox->bidiLevel() == level) // For example, abc FED 123 ^ CBA 826 return; 827 828 // For example, abc 123 ^ CBA 829 while (InlineBox* nextBox = inlineBox->nextLeafChild()) { 830 if (nextBox->bidiLevel() < level) 831 break; 832 inlineBox = nextBox; 833 } 834 caretOffset = inlineBox->caretRightmostOffset(); 835 } else { 836 InlineBox* prevBox = inlineBox->prevLeafChild(); 837 if (!prevBox || prevBox->bidiLevel() >= level) 838 return; 839 840 level = prevBox->bidiLevel(); 841 InlineBox* nextBox = inlineBox; 842 do { 843 nextBox = nextBox->nextLeafChild(); 844 } while (nextBox && nextBox->bidiLevel() > level); 845 846 if (nextBox && nextBox->bidiLevel() == level) 847 return; 848 849 while (InlineBox* prevBox = inlineBox->prevLeafChild()) { 850 if (prevBox->bidiLevel() < level) 851 break; 852 inlineBox = prevBox; 853 } 854 caretOffset = inlineBox->caretLeftmostOffset(); 855 } 856 return; 857 } 858 859 if (caretOffset == inlineBox->caretLeftmostOffset()) { 860 InlineBox* prevBox = inlineBox->prevLeafChild(); 861 if (!prevBox || prevBox->bidiLevel() < level) { 862 // Left edge of a secondary run. Set to the right edge of the entire run. 863 while (InlineBox* nextBox = inlineBox->nextLeafChild()) { 864 if (nextBox->bidiLevel() < level) 865 break; 866 inlineBox = nextBox; 867 } 868 caretOffset = inlineBox->caretRightmostOffset(); 869 } else if (prevBox->bidiLevel() > level) { 870 // Right edge of a "tertiary" run. Set to the left edge of that run. 871 while (InlineBox* tertiaryBox = inlineBox->prevLeafChild()) { 872 if (tertiaryBox->bidiLevel() <= level) 873 break; 874 inlineBox = tertiaryBox; 875 } 876 caretOffset = !inlineBox->caretLeftmostOffset(); 877 } 878 } else { 879 InlineBox* nextBox = inlineBox->nextLeafChild(); 880 if (!nextBox || nextBox->bidiLevel() < level) { 881 // Right edge of a secondary run. Set to the left edge of the entire run. 882 while (InlineBox* prevBox = inlineBox->prevLeafChild()) { 883 if (prevBox->bidiLevel() < level) 884 break; 885 inlineBox = prevBox; 886 } 887 caretOffset = inlineBox->caretLeftmostOffset(); 888 } else if (nextBox->bidiLevel() > level) { 889 // Left edge of a "tertiary" run. Set to the right edge of that run. 890 while (InlineBox* tertiaryBox = inlineBox->nextLeafChild()) { 891 if (tertiaryBox->bidiLevel() <= level) 892 break; 893 inlineBox = tertiaryBox; 894 } 895 caretOffset = inlineBox->caretRightmostOffset(); 896 } 897 } 755 898 } 756 899 -
trunk/WebCore/dom/Position.h
r31161 r32508 28 28 29 29 #include "TextAffinity.h" 30 #include "TextDirection.h" 30 31 #include <wtf/PassRefPtr.h> 31 32 #include <wtf/RefPtr.h> … … 35 36 class CSSComputedStyleDeclaration; 36 37 class Element; 38 class InlineBox; 37 39 class Node; 38 40 class Range; … … 89 91 bool isRenderedCharacter() const; 90 92 bool rendersInDifferentPosition(const Position&) const; 91 93 94 void getInlineBoxAndOffset(EAffinity, InlineBox*&, int& caretOffset) const; 95 void getInlineBoxAndOffset(EAffinity, TextDirection primaryDirection, InlineBox*&, int& caretOffset) const; 96 92 97 static bool hasRenderedNonAnonymousDescendantsWithHeight(RenderObject*); 93 98 static bool nodeIsUserSelectNone(Node*); -
trunk/WebCore/editing/DeleteSelectionCommand.cpp
r30973 r32508 552 552 // FIXME: Consider RTL. 553 553 // FIXME: handleSpecialCaseBRDelete prevents us from getting here in a case like <ul><li>foo<br><br></li></ul>^foo 554 if (isStartOfParagraph(mergeDestination) && 555 startOfParagraphToMove.deepEquivalent().node()->renderer()->caretRect(startOfParagraphToMove.deepEquivalent().offset()).location().x() > 556 mergeDestination.deepEquivalent().node()->renderer()->caretRect(startOfParagraphToMove.deepEquivalent().offset()).location().x()) { 554 if (isStartOfParagraph(mergeDestination) && startOfParagraphToMove.caretRect().x() > mergeDestination.caretRect().x()) { 557 555 ASSERT(mergeDestination.deepEquivalent().downstream().node()->hasTagName(brTag)); 558 556 removeNodeAndPruneAncestors(mergeDestination.deepEquivalent().downstream().node()); -
trunk/WebCore/editing/SelectionController.cpp
r30564 r32508 496 496 static bool caretY(const VisiblePosition &c, int &y) 497 497 { 498 Position p = c.deepEquivalent(); 499 Node *n = p.node(); 500 if (!n) 501 return false; 502 RenderObject *r = p.node()->renderer(); 503 if (!r) 504 return false; 505 IntRect rect = r->caretRect(p.offset()); 498 IntRect rect = c.caretRect(); 506 499 if (rect.isEmpty()) 507 500 return false; … … 628 621 629 622 if (m_xPosForVerticalArrowNavigation == NoXPosForVerticalArrowNavigation) { 630 pos = VisiblePosition(pos, m_sel.affinity()).deepEquivalent();623 VisiblePosition visiblePosition(pos, m_sel.affinity()); 631 624 // VisiblePosition creation can fail here if a node containing the selection becomes visibility:hidden 632 625 // after the selection is created and before this function is called. 633 x = pos.isNotNull() ? pos.node()->renderer()->caretRect(pos.offset(), m_sel.affinity()).x() : 0;626 x = visiblePosition.isNotNull() ? visiblePosition.caretRect().x() : 0; 634 627 m_xPosForVerticalArrowNavigation = x; 635 628 } … … 684 677 685 678 if (isCaret()) { 686 Position pos = m_sel.start(); 687 pos = VisiblePosition(m_sel.start(), m_sel.affinity()).deepEquivalent(); 679 VisiblePosition pos(m_sel.start(), m_sel.affinity()); 688 680 if (pos.isNotNull()) { 689 ASSERT(pos. node()->renderer());690 m_caretRect = pos. node()->renderer()->caretRect(pos.offset(), m_sel.affinity());691 681 ASSERT(pos.deepEquivalent().node()->renderer()); 682 m_caretRect = pos.caretRect(); 683 692 684 int x, y; 693 pos. node()->renderer()->absolutePositionForContent(x, y);685 pos.deepEquivalent().node()->renderer()->absolutePositionForContent(x, y); 694 686 m_caretPositionOnLayout = IntPoint(x, y); 695 687 } -
trunk/WebCore/editing/VisiblePosition.cpp
r30973 r32508 243 243 IntRect VisiblePosition::caretRect() const 244 244 { 245 if (!m_deepPosition.node() || !m_deepPosition.node()->renderer()) 245 Node* node = m_deepPosition.node(); 246 if (!node) 246 247 return IntRect(); 247 248 248 return m_deepPosition.node()->renderer()->caretRect(m_deepPosition.offset(), m_affinity); 249 RenderObject* renderer = node->renderer(); 250 if (!renderer) 251 return IntRect(); 252 253 InlineBox* inlineBox; 254 int caretOffset; 255 getInlineBoxAndOffset(inlineBox, caretOffset); 256 257 if (inlineBox) 258 renderer = inlineBox->object(); 259 260 return renderer->caretRect(inlineBox, caretOffset); 249 261 } 250 262 -
trunk/WebCore/editing/VisiblePosition.h
r30973 r32508 29 29 #include "Node.h" 30 30 #include "Position.h" 31 #include "TextDirection.h" 31 32 32 33 namespace WebCore { … … 44 45 // position is not at a line break. 45 46 #define VP_UPSTREAM_IF_POSSIBLE UPSTREAM 47 48 class InlineBox; 46 49 47 50 class VisiblePosition { … … 75 78 Element* rootEditableElement() const { return m_deepPosition.isNotNull() ? m_deepPosition.node()->rootEditableElement() : 0; } 76 79 80 void getInlineBoxAndOffset(InlineBox*& inlineBox, int& caretOffset) const 81 { 82 m_deepPosition.getInlineBoxAndOffset(m_affinity, inlineBox, caretOffset); 83 } 84 85 void getInlineBoxAndOffset(TextDirection primaryDirection, InlineBox*& inlineBox, int& caretOffset) const 86 { 87 m_deepPosition.getInlineBoxAndOffset(m_affinity, primaryDirection, inlineBox, caretOffset); 88 } 89 77 90 IntRect caretRect() const; 78 91 … … 85 98 void init(const Position&, EAffinity); 86 99 Position canonicalPosition(const Position&); 87 100 88 101 Position m_deepPosition; 89 102 EAffinity m_affinity; -
trunk/WebCore/editing/visible_units.cpp
r30973 r32508 258 258 if (!renderer) 259 259 return 0; 260 261 InlineBox *box = renderer->inlineBox(p.offset(), c.affinity());262 i f (!box)263 return 0;264 265 return box ->root();260 261 InlineBox* box; 262 int offset; 263 c.getInlineBoxAndOffset(box, offset); 264 265 return box ? box->root() : 0; 266 266 } 267 267 … … 280 280 if (c.isNull()) 281 281 return VisiblePosition(); 282 282 283 283 RootInlineBox *rootBox = rootBoxForLine(c); 284 284 if (!rootBox) { … … 348 348 if (c.isNull()) 349 349 return VisiblePosition(); 350 350 351 351 RootInlineBox *rootBox = rootBoxForLine(c); 352 352 if (!rootBox) { … … 442 442 RenderBlock *containingBlock = 0; 443 443 RootInlineBox *root = 0; 444 InlineBox *box = renderer->inlineBox(p.offset(), visiblePosition.affinity()); 444 InlineBox* box; 445 int ignoredCaretOffset; 446 visiblePosition.getInlineBoxAndOffset(box, ignoredCaretOffset); 445 447 if (box) { 446 448 root = box->root()->prevRootBox(); … … 463 465 if (pos.isCandidate()) { 464 466 ASSERT(n->renderer()); 465 box = n->renderer()->inlineBox(caretMaxOffset(n)); 467 Position maxPos(n, caretMaxOffset(n)); 468 maxPos.getInlineBoxAndOffset(DOWNSTREAM, box, ignoredCaretOffset); 466 469 if (box) { 467 470 // previous root line box found … … 512 515 RenderBlock *containingBlock = 0; 513 516 RootInlineBox *root = 0; 514 InlineBox *box = renderer->inlineBox(p.offset(), visiblePosition.affinity()); 517 InlineBox* box; 518 int ignoredCaretOffset; 519 visiblePosition.getInlineBoxAndOffset(box, ignoredCaretOffset); 515 520 if (box) { 516 521 root = box->root()->nextRootBox(); … … 533 538 if (pos.isCandidate()) { 534 539 ASSERT(n->renderer()); 535 box = n->renderer()->inlineBox(caretMinOffset(n));540 pos.getInlineBoxAndOffset(DOWNSTREAM, box, ignoredCaretOffset); 536 541 if (box) { 537 542 // next root line box found -
trunk/WebCore/page/AccessibilityObject.cpp
r32474 r32508 992 992 break; 993 993 renderer = p.node()->renderer(); 994 if (!renderer || renderer->inlineBox(p.offset(), tempPosition.affinity()) || (renderer->isRenderBlock() && p.offset() == 0)) 994 if (!renderer || renderer->isRenderBlock() && !p.offset()) 995 break; 996 InlineBox* box; 997 int ignoredCaretOffset; 998 p.getInlineBoxAndOffset(tempPosition.affinity(), box, ignoredCaretOffset); 999 if (box) 995 1000 break; 996 1001 startPosition = tempPosition; -
trunk/WebCore/page/Frame.cpp
r32422 r32508 279 279 ASSERT(range->startContainer(ec)); 280 280 ASSERT(range->endContainer(ec)); 281 IntRect startCaretRect = range->startContainer(ec)->renderer()->caretRect(range->startOffset(ec), DOWNSTREAM, &extraWidthToEndOfLine); 282 ASSERT(!ec); 283 IntRect endCaretRect = range->endContainer(ec)->renderer()->caretRect(range->endOffset(ec), UPSTREAM); 284 ASSERT(!ec); 285 281 InlineBox* startInlineBox; 282 int startCaretOffset; 283 range->startPosition().getInlineBoxAndOffset(DOWNSTREAM, startInlineBox, startCaretOffset); 284 IntRect startCaretRect = range->startContainer(ec)->renderer()->caretRect(startInlineBox, startCaretOffset, &extraWidthToEndOfLine); 285 286 InlineBox* endInlineBox; 287 int endCaretOffset; 288 range->endPosition().getInlineBoxAndOffset(UPSTREAM, endInlineBox, endCaretOffset); 289 IntRect endCaretRect = range->endContainer(ec)->renderer()->caretRect(endInlineBox, endCaretOffset); 290 286 291 if (startCaretRect.y() == endCaretRect.y()) { 287 292 // start and end are on the same line -
trunk/WebCore/rendering/InlineBox.cpp
r31200 r32508 87 87 int InlineBox::caretMinOffset() const 88 88 { 89 return 0;89 return m_object->caretMinOffset(); 90 90 } 91 91 92 92 int InlineBox::caretMaxOffset() const 93 93 { 94 return 1;94 return m_object->caretMaxOffset(); 95 95 } 96 96 -
trunk/WebCore/rendering/InlineBox.h
r28962 r32508 23 23 24 24 #include "RenderObject.h" // needed for RenderObject::PaintInfo 25 #include "TextDirection.h" 25 26 26 27 namespace WebCore { … … 47 48 , m_firstLine(false) 48 49 , m_constructed(false) 50 , m_bidiEmbeddingLevel(0) 49 51 , m_dirty(false) 50 52 , m_extracted(false) … … 55 57 , m_hasSelectedChildren(false) 56 58 , m_hasEllipsisBox(false) 57 , m_ reversed(false)59 , m_dirOverride(false) 58 60 , m_treatAsText(true) 59 61 , m_determinedIfNextOnLineExists(false) … … 81 83 , m_firstLine(firstLine) 82 84 , m_constructed(constructed) 85 , m_bidiEmbeddingLevel(0) 83 86 , m_dirty(dirty) 84 87 , m_extracted(extracted) … … 89 92 , m_hasSelectedChildren(false) 90 93 , m_hasEllipsisBox(false) 91 , m_ reversed(false)94 , m_dirOverride(false) 92 95 , m_treatAsText(true) 93 96 , m_determinedIfNextOnLineExists(false) … … 212 215 virtual int caretMaxOffset() const; 213 216 virtual unsigned caretMaxRenderedOffset() const; 214 217 218 unsigned char bidiLevel() const { return m_bidiEmbeddingLevel; } 219 void setBidiLevel(unsigned char level) { m_bidiEmbeddingLevel = level; } 220 TextDirection direction() const { return m_bidiEmbeddingLevel % 2 ? RTL : LTR; } 221 int caretLeftmostOffset() const { return direction() == LTR ? caretMinOffset() : caretMaxOffset(); } 222 int caretRightmostOffset() const { return direction() == LTR ? caretMaxOffset() : caretMinOffset(); } 223 215 224 virtual void clearTruncation() { } 216 225 … … 251 260 private: 252 261 bool m_constructed : 1; 262 unsigned char m_bidiEmbeddingLevel : 6; 253 263 protected: 254 264 bool m_dirty : 1; … … 267 277 // for InlineTextBox 268 278 public: 269 bool m_reversed : 1;270 279 bool m_dirOverride : 1; 271 280 bool m_treatAsText : 1; // Whether or not to treat a <br> as text for the purposes of line height. -
trunk/WebCore/rendering/InlineTextBox.cpp
r31200 r32508 98 98 const Font& f = textObj->style(m_firstLine)->font(); 99 99 100 IntRect r = enclosingIntRect(f.selectionRectForText(TextRun(textObj->text()->characters() + m_start, m_len, textObj->allowTabs(), textPos(), m_toAdd, m_reversed, m_dirOverride),100 IntRect r = enclosingIntRect(f.selectionRectForText(TextRun(textObj->text()->characters() + m_start, m_len, textObj->allowTabs(), textPos(), m_toAdd, direction() == RTL, m_dirOverride), 101 101 IntPoint(tx + m_x, ty + selTop), selHeight, sPos, ePos)); 102 102 if (r.x() > tx + m_x + m_width) … … 148 148 149 149 if (ellipsisX < m_x + m_width) { 150 if ( m_reversed)150 if (direction() == RTL) 151 151 return -1; // FIXME: Support LTR truncation when the last run is RTL someday. 152 152 … … 386 386 if (m_truncation != cNoTruncation) 387 387 endPoint = m_truncation; 388 paintInfo.context->drawText(TextRun(textStr->characters() + m_start, endPoint, textObject()->allowTabs(), textPos(), m_toAdd, m_reversed, m_dirOverride || styleToUse->visuallyOrdered()),388 paintInfo.context->drawText(TextRun(textStr->characters() + m_start, endPoint, textObject()->allowTabs(), textPos(), m_toAdd, direction() == RTL, m_dirOverride || styleToUse->visuallyOrdered()), 389 389 IntPoint(m_x + tx, m_y + ty + m_baseline)); 390 390 } else { … … 394 394 // paint only the text that is not selected 395 395 if (sPos >= ePos) 396 paintInfo.context->drawText(TextRun(textStr->characters() + m_start, m_len, textObject()->allowTabs(), textPos(), m_toAdd, m_reversed, m_dirOverride || styleToUse->visuallyOrdered()),396 paintInfo.context->drawText(TextRun(textStr->characters() + m_start, m_len, textObject()->allowTabs(), textPos(), m_toAdd, direction() == RTL, m_dirOverride || styleToUse->visuallyOrdered()), 397 397 IntPoint(m_x + tx, m_y + ty + m_baseline)); 398 398 else { 399 399 if (sPos - 1 >= 0) 400 paintInfo.context->drawText(TextRun(textStr->characters() + m_start, m_len, textObject()->allowTabs(), textPos(), m_toAdd, m_reversed, m_dirOverride || styleToUse->visuallyOrdered()),400 paintInfo.context->drawText(TextRun(textStr->characters() + m_start, m_len, textObject()->allowTabs(), textPos(), m_toAdd, direction() == RTL, m_dirOverride || styleToUse->visuallyOrdered()), 401 401 IntPoint(m_x + tx, m_y + ty + m_baseline), 0, sPos); 402 402 if (ePos < m_start + m_len) 403 paintInfo.context->drawText(TextRun(textStr->characters() + m_start, m_len, textObject()->allowTabs(), textPos(), m_toAdd, m_reversed, m_dirOverride || styleToUse->visuallyOrdered()),403 paintInfo.context->drawText(TextRun(textStr->characters() + m_start, m_len, textObject()->allowTabs(), textPos(), m_toAdd, direction() == RTL, m_dirOverride || styleToUse->visuallyOrdered()), 404 404 IntPoint(m_x + tx, m_y + ty + m_baseline), ePos); 405 405 } … … 416 416 paintInfo.context->setShadow(IntSize(selectionTextShadow->x, selectionTextShadow->y), 417 417 selectionTextShadow->blur, selectionTextShadow->color); 418 paintInfo.context->drawText(TextRun(textStr->characters() + m_start, m_len, textObject()->allowTabs(), textPos(), m_toAdd, m_reversed, m_dirOverride || styleToUse->visuallyOrdered()),418 paintInfo.context->drawText(TextRun(textStr->characters() + m_start, m_len, textObject()->allowTabs(), textPos(), m_toAdd, direction() == RTL, m_dirOverride || styleToUse->visuallyOrdered()), 419 419 IntPoint(m_x + tx, m_y + ty + m_baseline), sPos, ePos); 420 420 if (selectionTextShadow) … … 509 509 int h = selectionHeight(); 510 510 p->clip(IntRect(m_x + tx, y + ty, m_width, h)); 511 p->drawHighlightForText(TextRun(textObject()->text()->characters() + m_start, m_len, textObject()->allowTabs(), textPos(), m_toAdd, m_reversed, m_dirOverride || style->visuallyOrdered()),511 p->drawHighlightForText(TextRun(textObject()->text()->characters() + m_start, m_len, textObject()->allowTabs(), textPos(), m_toAdd, direction() == RTL, m_dirOverride || style->visuallyOrdered()), 512 512 IntPoint(m_x + tx, y + ty), h, c, sPos, ePos); 513 513 p->restore(); … … 531 531 int y = selectionTop(); 532 532 int h = selectionHeight(); 533 p->drawHighlightForText(TextRun(textObject()->text()->characters() + m_start, m_len, textObject()->allowTabs(), textPos(), m_toAdd, m_reversed, m_dirOverride || style->visuallyOrdered()),533 p->drawHighlightForText(TextRun(textObject()->text()->characters() + m_start, m_len, textObject()->allowTabs(), textPos(), m_toAdd, direction() == RTL, m_dirOverride || style->visuallyOrdered()), 534 534 IntPoint(m_x + tx, y + ty), h, c, sPos, ePos); 535 535 p->restore(); … … 630 630 int startPosition = max(marker.startOffset - m_start, (unsigned)0); 631 631 int endPosition = min(marker.endOffset - m_start, (unsigned)m_len); 632 TextRun run(textObject()->text()->characters() + m_start, m_len, textObject()->allowTabs(), textPos(), m_toAdd, m_reversed, m_dirOverride || style->visuallyOrdered());632 TextRun run(textObject()->text()->characters() + m_start, m_len, textObject()->allowTabs(), textPos(), m_toAdd, direction() == RTL, m_dirOverride || style->visuallyOrdered()); 633 633 IntRect markerRect = enclosingIntRect(f->selectionRectForText(run, startPoint, selectionHeight(), startPosition, endPosition)); 634 634 object()->document()->setRenderedRectForMarker(object()->node(), marker, markerRect); … … 663 663 int sPos = max(marker.startOffset - m_start, (unsigned)0); 664 664 int ePos = min(marker.endOffset - m_start, (unsigned)m_len); 665 TextRun run(textObject()->text()->characters() + m_start, m_len, textObject()->allowTabs(), textPos(), m_toAdd, m_reversed, m_dirOverride || style->visuallyOrdered());665 TextRun run(textObject()->text()->characters() + m_start, m_len, textObject()->allowTabs(), textPos(), m_toAdd, direction() == RTL, m_dirOverride || style->visuallyOrdered()); 666 666 IntPoint startPoint = IntPoint(m_x + tx, y + ty); 667 667 … … 802 802 803 803 RenderBlock *blockElement = object()->containingBlock(); 804 return m_reversed? xPos() - blockElement->borderRight() - blockElement->paddingRight()804 return direction() == RTL ? xPos() - blockElement->borderRight() - blockElement->paddingRight() 805 805 : xPos() - blockElement->borderLeft() - blockElement->paddingLeft(); 806 806 } … … 814 814 RenderStyle *style = text->style(m_firstLine); 815 815 const Font* f = &style->font(); 816 return f->offsetForPosition(TextRun(textObject()->text()->characters() + m_start, m_len, textObject()->allowTabs(), textPos(), m_toAdd, m_reversed, m_dirOverride || style->visuallyOrdered()),816 return f->offsetForPosition(TextRun(textObject()->text()->characters() + m_start, m_len, textObject()->allowTabs(), textPos(), m_toAdd, direction() == RTL, m_dirOverride || style->visuallyOrdered()), 817 817 _x - m_x, includePartialGlyphs); 818 818 } … … 825 825 RenderText* text = static_cast<RenderText*>(m_object); 826 826 const Font& f = text->style(m_firstLine)->font(); 827 int from = m_reversed? offset - m_start : 0;828 int to = m_reversed? m_len : offset - m_start;827 int from = direction() == RTL ? offset - m_start : 0; 828 int to = direction() == RTL ? m_len : offset - m_start; 829 829 // FIXME: Do we need to add rightBearing here? 830 return enclosingIntRect(f.selectionRectForText(TextRun(text->text()->characters() + m_start, m_len, textObject()->allowTabs(), textPos(), m_toAdd, m_reversed, m_dirOverride),830 return enclosingIntRect(f.selectionRectForText(TextRun(text->text()->characters() + m_start, m_len, textObject()->allowTabs(), textPos(), m_toAdd, direction() == RTL, m_dirOverride), 831 831 IntPoint(m_x, 0), 0, from, to)).right(); 832 832 } -
trunk/WebCore/rendering/RenderBR.cpp
r29098 r32508 109 109 } 110 110 111 InlineBox* RenderBR::inlineBox(int /*offset*/, EAffinity /*affinity*/)112 {113 return firstTextBox();114 }115 116 111 } // namespace WebCore -
trunk/WebCore/rendering/RenderBR.h
r25754 r32508 61 61 virtual VisiblePosition positionForCoordinates(int x, int y); 62 62 63 virtual InlineBox* inlineBox(int offset, EAffinity = UPSTREAM);64 65 63 private: 66 64 mutable short m_lineHeight; -
trunk/WebCore/rendering/RenderBox.cpp
r32446 r32508 2523 2523 } 2524 2524 2525 IntRect RenderBox::caretRect( int offset, EAffinity affinity, int* extraWidthToEndOfLine)2525 IntRect RenderBox::caretRect(InlineBox* box, int caretOffset, int* extraWidthToEndOfLine) 2526 2526 { 2527 2527 // VisiblePositions at offsets inside containers either a) refer to the positions before/after … … 2533 2533 const int caretWidth = 1; 2534 2534 IntRect rect(xPos(), yPos(), caretWidth, m_height); 2535 if (offset) 2535 TextDirection direction = box ? box->direction() : style()->direction(); 2536 2537 if ((!caretOffset) ^ (direction == LTR)) 2536 2538 rect.move(IntSize(m_width - caretWidth, 0)); 2537 if (InlineBox* box = inlineBoxWrapper()) { 2539 2540 if (box) { 2538 2541 RootInlineBox* rootBox = box->root(); 2539 2542 int top = rootBox->topOverflow(); -
trunk/WebCore/rendering/RenderBox.h
r32406 r32508 140 140 virtual RenderLayer* layer() const { return m_layer; } 141 141 142 virtual IntRect caretRect( int offset, EAffinity = UPSTREAM, int* extraWidthToEndOfLine = 0);142 virtual IntRect caretRect(InlineBox*, int caretOffset, int* extraWidthToEndOfLine = 0); 143 143 144 144 virtual void paintFillLayerExtended(const PaintInfo&, const Color&, const FillLayer*, int clipY, int clipHeight, -
trunk/WebCore/rendering/RenderFlow.cpp
r32446 r32508 621 621 } 622 622 623 IntRect RenderFlow::caretRect( int offset, EAffinity affinity, int* extraWidthToEndOfLine)623 IntRect RenderFlow::caretRect(InlineBox* inlineBox, int caretOffset, int* extraWidthToEndOfLine) 624 624 { 625 625 // Do the normal calculation in most cases. 626 626 if (firstChild() || style()->display() == INLINE) 627 return RenderContainer::caretRect( offset, affinity, extraWidthToEndOfLine);627 return RenderContainer::caretRect(inlineBox, caretOffset, extraWidthToEndOfLine); 628 628 629 629 // This is a special case: -
trunk/WebCore/rendering/RenderFlow.h
r31127 r32508 94 94 virtual int leftmostPosition(bool includeOverflowInterior = true, bool includeSelf = true) const; 95 95 96 virtual IntRect caretRect( int offset, EAffinity = UPSTREAM, int* extraWidthToEndOfLine = 0);96 virtual IntRect caretRect(InlineBox*, int caretOffset, int* extraWidthToEndOfLine = 0); 97 97 98 98 virtual void addFocusRingRects(GraphicsContext*, int tx, int ty); -
trunk/WebCore/rendering/RenderObject.cpp
r32446 r32508 2345 2345 } 2346 2346 2347 IntRect RenderObject::caretRect( int offset, EAffinity affinity, int* extraWidthToEndOfLine)2347 IntRect RenderObject::caretRect(InlineBox* inlineBox, int caretOffset, int* extraWidthToEndOfLine) 2348 2348 { 2349 2349 if (extraWidthToEndOfLine) … … 2956 2956 int RenderObject::caretMaxOffset() const 2957 2957 { 2958 return isReplaced() ? 1: 0;2958 return isReplaced() ? (element() ? max(1U, element()->childNodeCount()) : 1) : 0; 2959 2959 } 2960 2960 … … 2972 2972 { 2973 2973 return current + 1; 2974 }2975 2976 InlineBox* RenderObject::inlineBox(int offset, EAffinity affinity)2977 {2978 return inlineBoxWrapper();2979 2974 } 2980 2975 -
trunk/WebCore/rendering/RenderObject.h
r32446 r32508 434 434 virtual void deleteLineBoxWrapper(); 435 435 436 virtual InlineBox* inlineBox(int offset = 0, EAffinity = UPSTREAM);437 438 436 // for discussion of lineHeight see CSS2 spec 439 437 virtual short lineHeight(bool firstLine, bool isRootLineBox = false) const; … … 833 831 * useful for character range rect computations 834 832 */ 835 virtual IntRect caretRect( int offset, EAffinity = UPSTREAM, int* extraWidthToEndOfLine = 0);833 virtual IntRect caretRect(InlineBox*, int caretOffset, int* extraWidthToEndOfLine = 0); 836 834 837 835 virtual int lowestPosition(bool /*includeOverflowInterior*/ = true, bool /*includeSelf*/ = true) const { return 0; } -
trunk/WebCore/rendering/RenderReplaced.cpp
r32446 r32508 197 197 } 198 198 199 int RenderReplaced::caretMinOffset() const200 {201 return 0;202 }203 204 // Returns 1 since a replaced element can have the caret positioned205 // at its beginning (0), or at its end (1).206 // NOTE: Yet, "select" elements can have any number of "option" elements207 // as children, so this "0 or 1" idea does not really hold up.208 int RenderReplaced::caretMaxOffset() const209 {210 return 1;211 }212 213 199 unsigned RenderReplaced::caretMaxRenderedOffset() const 214 200 { -
trunk/WebCore/rendering/RenderReplaced.h
r31155 r32508 56 56 virtual IntRect overflowRect(bool includeInterior = true) const; 57 57 58 virtual int caretMinOffset() const;59 virtual int caretMaxOffset() const;60 58 virtual unsigned caretMaxRenderedOffset() const; 61 59 virtual VisiblePosition positionForCoordinates(int x, int y); -
trunk/WebCore/rendering/RenderSVGInlineText.cpp
r29663 r32508 123 123 } 124 124 125 IntRect RenderSVGInlineText::caretRect( int offset, EAffinity affinity, int* extraWidthToEndOfLine)125 IntRect RenderSVGInlineText::caretRect(InlineBox* inlineBox, int caretOffset, int* extraWidthToEndOfLine) 126 126 { 127 127 // SVG doesn't have any editable content where a caret rect would be needed … … 147 147 if (box->svgCharacterHitsPosition(x + object->xPos(), y + object->yPos(), offset)) { 148 148 // If we're not at the end/start of the box, stop looking for other selected boxes. 149 if ( !box->m_reversed) {149 if (box->direction() == LTR) { 150 150 if (offset <= (int) box->end() + 1) 151 151 break; -
trunk/WebCore/rendering/RenderSVGInlineText.h
r29663 r32508 40 40 virtual InlineTextBox* createInlineTextBox(); 41 41 42 virtual IntRect caretRect( int offset, EAffinity, int* extraWidthToEndOfLine = 0);42 virtual IntRect caretRect(InlineBox*, int caretOffset, int* extraWidthToEndOfLine = 0); 43 43 virtual VisiblePosition positionForCoordinates(int x, int y); 44 44 -
trunk/WebCore/rendering/RenderText.cpp
r31945 r32508 325 325 } 326 326 327 static inline bool atLineWrap(InlineTextBox* box, int offset) 328 { 329 return box->nextTextBox() && !box->nextOnLine() && offset == box->m_start + box->m_len; 330 } 331 332 IntRect RenderText::caretRect(int offset, EAffinity affinity, int* extraWidthToEndOfLine) 333 { 334 if (!firstTextBox() || !textLength()) 327 IntRect RenderText::caretRect(InlineBox* inlineBox, int caretOffset, int* extraWidthToEndOfLine) 328 { 329 if (!inlineBox) 335 330 return IntRect(); 336 331 337 // Find the text box for the given offset 338 InlineTextBox* box = 0; 339 for (box = firstTextBox(); box; box = box->nextTextBox()) { 340 if (box->containsCaretOffset(offset)) { 341 // Check if downstream affinity would make us move to the next line. 342 if (atLineWrap(box, offset) && affinity == DOWNSTREAM) { 343 // Use the next text box 344 box = box->nextTextBox(); 345 offset = box->m_start; 346 } else { 347 InlineTextBox* prevBox = box->prevTextBox(); 348 if (offset == box->m_start && affinity == UPSTREAM && prevBox && !box->prevOnLine()) { 349 box = prevBox; 350 offset = box->m_start + box->m_len; 351 } 352 } 353 break; 354 } 355 } 356 357 if (!box) 332 ASSERT(inlineBox->isInlineTextBox()); 333 if (!inlineBox->isInlineTextBox()) 358 334 return IntRect(); 335 336 InlineTextBox* box = static_cast<InlineTextBox*>(inlineBox); 359 337 360 338 int height = box->root()->bottomOverflow() - box->root()->topOverflow(); 361 339 int top = box->root()->topOverflow(); 362 340 363 int left = box->positionForOffset( offset);341 int left = box->positionForOffset(caretOffset); 364 342 365 343 int rootLeft = box->root()->xPos(); … … 377 355 if (style()->autoWrap()) { 378 356 int availableWidth = cb->lineWidth(top); 379 if ( !box->m_reversed)357 if (box->direction() == LTR) 380 358 left = min(left, absx + rootLeft + availableWidth - 1); 381 359 else … … 1006 984 } 1007 985 1008 m_containsReversedText |= s-> m_reversed;986 m_containsReversedText |= s->direction() == RTL; 1009 987 } 1010 988 … … 1172 1150 } 1173 1151 1174 InlineBox* RenderText::inlineBox(int offset, EAffinity affinity)1175 {1176 for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) {1177 if (box->containsCaretOffset(offset)) {1178 if (atLineWrap(box, offset) && affinity == DOWNSTREAM)1179 return box->nextTextBox();1180 return box;1181 }1182 if (offset < box->m_start)1183 // The offset we're looking for is before this node1184 // this means the offset must be in content that is1185 // not rendered.1186 return box->prevTextBox() ? box->prevTextBox() : firstTextBox();1187 }1188 1189 return 0;1190 }1191 1192 1152 #ifndef NDEBUG 1193 1153 -
trunk/WebCore/rendering/RenderText.h
r30412 r32508 106 106 virtual void setSelectionState(SelectionState s); 107 107 virtual IntRect selectionRect(bool clipToVisibleContent = true); 108 virtual IntRect caretRect( int offset, EAffinity, int* extraWidthToEndOfLine = 0);108 virtual IntRect caretRect(InlineBox*, int caretOffset, int* extraWidthToEndOfLine = 0); 109 109 110 110 virtual int marginLeft() const { return style()->marginLeft().calcMinValue(0); } … … 115 115 InlineTextBox* firstTextBox() const { return m_firstTextBox; } 116 116 InlineTextBox* lastTextBox() const { return m_lastTextBox; } 117 118 virtual InlineBox* inlineBox(int offset, EAffinity = UPSTREAM);119 117 120 118 virtual int caretMinOffset() const; -
trunk/WebCore/rendering/RenderTextControl.cpp
r31086 r32508 632 632 return ""; 633 633 634 InlineBox* box = renderer->i nlineBox(0, DOWNSTREAM);634 InlineBox* box = renderer->isText() ? static_cast<RenderText*>(renderer)->firstTextBox() : renderer->inlineBoxWrapper(); 635 635 if (!box) 636 636 return ""; -
trunk/WebCore/rendering/RenderTreeAsText.cpp
r32231 r32508 306 306 { 307 307 ts << "text run at (" << run.m_x << "," << run.m_y << ") width " << run.m_width; 308 if (run. m_reversed|| run.m_dirOverride) {309 ts << (run. m_reversed? " RTL" : " LTR");308 if (run.direction() == RTL || run.m_dirOverride) { 309 ts << (run.direction() == RTL ? " RTL" : " LTR"); 310 310 if (run.m_dirOverride) 311 311 ts << " override"; -
trunk/WebCore/rendering/SVGInlineTextBox.cpp
r31342 r32508 100 100 int charsConsumed; 101 101 String glyphName; 102 if ( !m_reversed)102 if (direction() == LTR) 103 103 glyphWidth = calculateGlyphWidth(style, offset, 0, charsConsumed, glyphName); 104 104 else … … 149 149 // Take RTL text into account and pick right glyph width/height. 150 150 // NOTE: This offset has to be corrected _after_ calling calculateGlyphBoundaries 151 if (textBox-> m_reversed)151 if (textBox->direction() == RTL) 152 152 newOffset = textBox->start() + textBox->end() - newOffset; 153 153 … … 249 249 FloatRect glyphRect = calculateGlyphBoundaries(style, offset, charAtPos); 250 250 251 if ( m_reversed)251 if (direction() == RTL) 252 252 offset++; 253 253 … … 261 261 // Check whether x position hits the current character 262 262 if (x < charAtPos.x) { 263 if (offset > 0 && !m_reversed)263 if (offset > 0 && direction() == LTR) 264 264 return true; 265 else if (offset < (int) end() && m_reversed)265 else if (offset < (int) end() && direction() == RTL) 266 266 return true; 267 267 … … 275 275 // Snap to character at half of it's advance 276 276 if (x >= charAtPos.x + glyphRect.width() / 2.0) 277 offset += m_reversed? -1 : 1;277 offset += direction() == RTL ? -1 : 1; 278 278 279 279 return true; -
trunk/WebCore/rendering/SVGRenderTreeAsText.cpp
r30418 r32508 424 424 ts << " width " << cummulatedWidthOfInlineBoxCharacterRange(range); 425 425 426 if (textBox-> m_reversed|| textBox->m_dirOverride) {427 ts << (textBox-> m_reversed? " RTL" : " LTR");426 if (textBox->direction() == RTL || textBox->m_dirOverride) { 427 ts << (textBox->direction() == RTL ? " RTL" : " LTR"); 428 428 429 429 if (textBox->m_dirOverride) -
trunk/WebCore/rendering/SVGRootInlineBox.cpp
r31600 r32508 649 649 ASSERT(style); 650 650 651 TextRun run(c, len, false, static_cast<int>(xPos), textBox->toAdd(), textBox-> m_reversed, textBox->m_dirOverride || style->visuallyOrdered());651 TextRun run(c, len, false, static_cast<int>(xPos), textBox->toAdd(), textBox->direction() == RTL, textBox->m_dirOverride || style->visuallyOrdered()); 652 652 653 653 #if ENABLE(SVG_FONTS) … … 710 710 SVGChar& currentCharacter = *itSearch; 711 711 712 int offset = box-> m_reversed? box->end() - i - positionOffset + 1 : box->start() + i + positionOffset - 1;712 int offset = box->direction() == RTL ? box->end() - i - positionOffset + 1 : box->start() + i + positionOffset - 1; 713 713 714 714 // FIXME: does this need to change to handle multichar glyphs? … … 1131 1131 String unicodeStr; 1132 1132 String glyphName; 1133 if (textBox-> m_reversed) {1133 if (textBox->direction() == RTL) { 1134 1134 glyphWidth = svgTextBox->calculateGlyphWidth(style, textBox->end() - i, extraCharsAvailable, charsConsumed, glyphName); 1135 1135 glyphHeight = svgTextBox->calculateGlyphHeight(style, textBox->end() - i, extraCharsAvailable); … … 1190 1190 float spacing = font.letterSpacing() + calculateKerning(textBox->object()->element()->renderer()); 1191 1191 1192 const UChar* currentCharacter = text->characters() + (textBox-> m_reversed? textBox->end() - i : textBox->start() + i);1192 const UChar* currentCharacter = text->characters() + (textBox->direction() == RTL ? textBox->end() - i : textBox->start() + i); 1193 1193 const UChar* lastCharacter = 0; 1194 1194 1195 if (textBox-> m_reversed) {1195 if (textBox->direction() == RTL) { 1196 1196 if (i < textBox->end()) 1197 1197 lastCharacter = text->characters() + textBox->end() - i + 1; -
trunk/WebCore/rendering/bidi.cpp
r32402 r32508 519 519 if (runCount == 2 && !r->m_object->isListMarker()) 520 520 isOnlyRun = ((style()->direction() == RTL) ? lastRun : firstRun)->m_object->isListMarker(); 521 r->m_box = r->m_object->createInlineBox(r->m_object->isPositioned(), false, isOnlyRun); 522 523 if (r->m_box) { 521 522 InlineBox* box = r->m_object->createInlineBox(r->m_object->isPositioned(), false, isOnlyRun); 523 r->m_box = box; 524 525 if (box) { 524 526 // If we have no parent box yet, or if the run is not simply a sibling, 525 527 // then we need to construct inline boxes as necessary to properly enclose the … … 530 532 531 533 // Append the inline box to this line. 532 parentBox->addToLine(r->m_box); 533 534 if (r->m_box->isInlineTextBox()) { 535 InlineTextBox* text = static_cast<InlineTextBox*>(r->m_box); 534 parentBox->addToLine(box); 535 536 bool visuallyOrdered = r->m_object->style()->visuallyOrdered(); 537 box->setBidiLevel(visuallyOrdered ? 0 : r->level()); 538 539 if (box->isInlineTextBox()) { 540 InlineTextBox* text = static_cast<InlineTextBox*>(box); 536 541 text->setStart(r->m_start); 537 542 text->setLen(r->m_stop - r->m_start); 538 bool visuallyOrdered = r->m_object->style()->visuallyOrdered();539 text->m_reversed = r->reversed(visuallyOrdered);540 543 text->m_dirOverride = r->dirOverride(visuallyOrdered); 541 544 } -
trunk/WebCore/svg/SVGTextContentElement.cpp
r31857 r32508 75 75 76 76 // Take RTL text into account and pick right glyph width/height. 77 if (textBox-> m_reversed)77 if (textBox->direction() == RTL) 78 78 newOffset = textBox->start() + textBox->end() - newOffset; 79 79 … … 192 192 193 193 // Take RTL text into account and pick right glyph width/height. 194 if (textBox-> m_reversed)194 if (textBox->direction() == RTL) 195 195 newOffset = textBox->start() + textBox->end() - newOffset; 196 196 -
trunk/WebKit/mac/ChangeLog
r32505 r32508 1 2008-04-24 Dan Bernstein <mitz@apple.com> 2 3 Reviewed by Darin Adler. 4 5 - preparation for https://bugs.webkit.org/show_bug.cgi?id=3729 6 <rdar://problem/4036353> REGRESSION: arrow keys move insertion bar backwards in RTL text 7 8 * WebView/WebFrame.mm: 9 (-[WebFrame _caretRectAtNode:offset:affinity:]): Changed to use 10 VisiblePosition::caretRect() instead of the RenderObject method which 11 was removed. 12 1 13 2008-04-24 Brady Eidson <beidson@apple.com> 2 14 -
trunk/WebKit/mac/WebView/WebFrame.mm
r32042 r32508 617 617 - (NSRect)_caretRectAtNode:(DOMNode *)node offset:(int)offset affinity:(NSSelectionAffinity)affinity 618 618 { 619 return [node _node]->renderer()->caretRect(offset, static_cast<EAffinity>(affinity)); 619 VisiblePosition visiblePosition([node _node], offset, static_cast<EAffinity>(affinity)); 620 return visiblePosition.caretRect(); 620 621 } 621 622
Note: See TracChangeset
for help on using the changeset viewer.