| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights | 2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights |
| 3 * reserved. | 3 * reserved. |
| 4 * | 4 * |
| 5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
| 6 * modification, are permitted provided that the following conditions | 6 * modification, are permitted provided that the following conditions |
| 7 * are met: | 7 * are met: |
| 8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
| (...skipping 815 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 826 next = next->NextInPreOrder(container)) { | 826 next = next->NextInPreOrder(container)) { |
| 827 if (next->IsLayoutBlock()) | 827 if (next->IsLayoutBlock()) |
| 828 return 0; | 828 return 0; |
| 829 if (next->IsBR()) | 829 if (next->IsBR()) |
| 830 return 0; | 830 return 0; |
| 831 if (IsNonTextLeafChild(next)) | 831 if (IsNonTextLeafChild(next)) |
| 832 return 0; | 832 return 0; |
| 833 if (next->IsText()) { | 833 if (next->IsText()) { |
| 834 InlineTextBox* match = 0; | 834 InlineTextBox* match = 0; |
| 835 int min_offset = INT_MAX; | 835 int min_offset = INT_MAX; |
| 836 for (InlineTextBox* box = ToLayoutText(next)->FirstTextBox(); box; | 836 for (InlineTextBox* box : InlineTextBoxesOf(*ToLayoutText(next))) { |
| 837 box = box->NextTextBox()) { | |
| 838 int caret_min_offset = box->CaretMinOffset(); | 837 int caret_min_offset = box->CaretMinOffset(); |
| 839 if (caret_min_offset < min_offset) { | 838 if (caret_min_offset < min_offset) { |
| 840 match = box; | 839 match = box; |
| 841 min_offset = caret_min_offset; | 840 min_offset = caret_min_offset; |
| 842 } | 841 } |
| 843 } | 842 } |
| 844 if (match) | 843 if (match) |
| 845 return match; | 844 return match; |
| 846 } | 845 } |
| 847 } | 846 } |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 922 } | 921 } |
| 923 if (layout_object->IsBox()) { | 922 if (layout_object->IsBox()) { |
| 924 inline_box = ToLayoutBox(layout_object)->InlineBoxWrapper(); | 923 inline_box = ToLayoutBox(layout_object)->InlineBoxWrapper(); |
| 925 if (!inline_box || (caret_offset > inline_box->CaretMinOffset() && | 924 if (!inline_box || (caret_offset > inline_box->CaretMinOffset() && |
| 926 caret_offset < inline_box->CaretMaxOffset())) | 925 caret_offset < inline_box->CaretMaxOffset())) |
| 927 return InlineBoxPosition(inline_box, caret_offset); | 926 return InlineBoxPosition(inline_box, caret_offset); |
| 928 } | 927 } |
| 929 } else { | 928 } else { |
| 930 LayoutText* text_layout_object = ToLayoutText(layout_object); | 929 LayoutText* text_layout_object = ToLayoutText(layout_object); |
| 931 | 930 |
| 932 InlineTextBox* box; | 931 InlineTextBox* candidate = nullptr; |
| 933 InlineTextBox* candidate = 0; | |
| 934 | 932 |
| 935 for (box = text_layout_object->FirstTextBox(); box; | 933 for (InlineTextBox* box : InlineTextBoxesOf(*text_layout_object)) { |
| 936 box = box->NextTextBox()) { | |
| 937 int caret_min_offset = box->CaretMinOffset(); | 934 int caret_min_offset = box->CaretMinOffset(); |
| 938 int caret_max_offset = box->CaretMaxOffset(); | 935 int caret_max_offset = box->CaretMaxOffset(); |
| 939 | 936 |
| 940 if (caret_offset < caret_min_offset || caret_offset > caret_max_offset || | 937 if (caret_offset < caret_min_offset || caret_offset > caret_max_offset || |
| 941 (caret_offset == caret_max_offset && box->IsLineBreak())) | 938 (caret_offset == caret_max_offset && box->IsLineBreak())) |
| 942 continue; | 939 continue; |
| 943 | 940 |
| 944 if (caret_offset > caret_min_offset && caret_offset < caret_max_offset) | 941 if (caret_offset > caret_min_offset && caret_offset < caret_max_offset) |
| 945 return InlineBoxPosition(box, caret_offset); | 942 return InlineBoxPosition(box, caret_offset); |
| 946 | 943 |
| 947 if (((caret_offset == caret_max_offset) ^ | 944 if (((caret_offset == caret_max_offset) ^ |
| 948 (affinity == TextAffinity::kDownstream)) || | 945 (affinity == TextAffinity::kDownstream)) || |
| 949 ((caret_offset == caret_min_offset) ^ | 946 ((caret_offset == caret_min_offset) ^ |
| 950 (affinity == TextAffinity::kUpstream)) || | 947 (affinity == TextAffinity::kUpstream)) || |
| 951 (caret_offset == caret_max_offset && box->NextLeafChild() && | 948 (caret_offset == caret_max_offset && box->NextLeafChild() && |
| 952 box->NextLeafChild()->IsLineBreak())) | 949 box->NextLeafChild()->IsLineBreak())) { |
| 950 inline_box = box; |
| 953 break; | 951 break; |
| 952 } |
| 954 | 953 |
| 955 candidate = box; | 954 candidate = box; |
| 956 } | 955 } |
| 957 if (candidate && candidate == text_layout_object->LastTextBox() && | 956 if (candidate && candidate == text_layout_object->LastTextBox() && |
| 958 affinity == TextAffinity::kDownstream) { | 957 affinity == TextAffinity::kDownstream) { |
| 959 box = SearchAheadForBetterMatch(text_layout_object); | 958 inline_box = SearchAheadForBetterMatch(text_layout_object); |
| 960 if (box) | 959 if (inline_box) |
| 961 caret_offset = box->CaretMinOffset(); | 960 caret_offset = inline_box->CaretMinOffset(); |
| 962 } | 961 } |
| 963 inline_box = box ? box : candidate; | 962 if (!inline_box) |
| 963 inline_box = candidate; |
| 964 } | 964 } |
| 965 | 965 |
| 966 if (!inline_box) | 966 if (!inline_box) |
| 967 return InlineBoxPosition(inline_box, caret_offset); | 967 return InlineBoxPosition(inline_box, caret_offset); |
| 968 | 968 |
| 969 unsigned char level = inline_box->BidiLevel(); | 969 unsigned char level = inline_box->BidiLevel(); |
| 970 | 970 |
| 971 if (inline_box->Direction() == primary_direction) { | 971 if (inline_box->Direction() == primary_direction) { |
| 972 if (caret_offset == inline_box->CaretRightmostOffset()) { | 972 if (caret_offset == inline_box->CaretRightmostOffset()) { |
| 973 InlineBox* next_box = inline_box->NextLeafChild(); | 973 InlineBox* next_box = inline_box->NextLeafChild(); |
| (...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1307 | 1307 |
| 1308 const int offset_in_node = position.ComputeEditingOffset(); | 1308 const int offset_in_node = position.ComputeEditingOffset(); |
| 1309 LayoutObject* layout_object = | 1309 LayoutObject* layout_object = |
| 1310 AssociatedLayoutObjectOf(*anchor_node, offset_in_node); | 1310 AssociatedLayoutObjectOf(*anchor_node, offset_in_node); |
| 1311 if (!layout_object) | 1311 if (!layout_object) |
| 1312 return false; | 1312 return false; |
| 1313 | 1313 |
| 1314 LayoutText* text_layout_object = ToLayoutText(layout_object); | 1314 LayoutText* text_layout_object = ToLayoutText(layout_object); |
| 1315 const int text_offset = | 1315 const int text_offset = |
| 1316 offset_in_node - text_layout_object->TextStartOffset(); | 1316 offset_in_node - text_layout_object->TextStartOffset(); |
| 1317 for (InlineTextBox* box = text_layout_object->FirstTextBox(); box; | 1317 for (InlineTextBox* box : InlineTextBoxesOf(*text_layout_object)) { |
| 1318 box = box->NextTextBox()) { | |
| 1319 if (text_offset < static_cast<int>(box->Start()) && | 1318 if (text_offset < static_cast<int>(box->Start()) && |
| 1320 !text_layout_object->ContainsReversedText()) { | 1319 !text_layout_object->ContainsReversedText()) { |
| 1321 // The offset we're looking for is before this node | 1320 // The offset we're looking for is before this node |
| 1322 // this means the offset must be in content that is | 1321 // this means the offset must be in content that is |
| 1323 // not laid out. Return false. | 1322 // not laid out. Return false. |
| 1324 return false; | 1323 return false; |
| 1325 } | 1324 } |
| 1326 if (box->ContainsCaretOffset(text_offset)) { | 1325 if (box->ContainsCaretOffset(text_offset)) { |
| 1327 // Return false for offsets inside composed characters. | 1326 // Return false for offsets inside composed characters. |
| 1328 return text_offset == text_layout_object->CaretMinOffset() || | 1327 return text_offset == text_layout_object->CaretMinOffset() || |
| (...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1561 // TODO(editing-dev): This function is just moved out from | 1560 // TODO(editing-dev): This function is just moved out from |
| 1562 // |MostBackwardCaretPosition()|. We should study this function more and | 1561 // |MostBackwardCaretPosition()|. We should study this function more and |
| 1563 // name it appropriately. See https://trac.webkit.org/changeset/32438/ | 1562 // name it appropriately. See https://trac.webkit.org/changeset/32438/ |
| 1564 // which introduce this. | 1563 // which introduce this. |
| 1565 static bool CanBeBackwardCaretPosition(const LayoutText* text_layout_object, | 1564 static bool CanBeBackwardCaretPosition(const LayoutText* text_layout_object, |
| 1566 int offset_in_node) { | 1565 int offset_in_node) { |
| 1567 const unsigned text_start_offset = text_layout_object->TextStartOffset(); | 1566 const unsigned text_start_offset = text_layout_object->TextStartOffset(); |
| 1568 DCHECK_GE(offset_in_node, static_cast<int>(text_start_offset)); | 1567 DCHECK_GE(offset_in_node, static_cast<int>(text_start_offset)); |
| 1569 const unsigned text_offset = offset_in_node - text_start_offset; | 1568 const unsigned text_offset = offset_in_node - text_start_offset; |
| 1570 InlineTextBox* const last_text_box = text_layout_object->LastTextBox(); | 1569 InlineTextBox* const last_text_box = text_layout_object->LastTextBox(); |
| 1571 for (InlineTextBox* box = text_layout_object->FirstTextBox(); box; | 1570 for (InlineTextBox* box : InlineTextBoxesOf(*text_layout_object)) { |
| 1572 box = box->NextTextBox()) { | |
| 1573 if (text_offset == box->Start()) { | 1571 if (text_offset == box->Start()) { |
| 1574 if (text_layout_object->IsTextFragment() && | 1572 if (text_layout_object->IsTextFragment() && |
| 1575 ToLayoutTextFragment(text_layout_object) | 1573 ToLayoutTextFragment(text_layout_object) |
| 1576 ->IsRemainingTextLayoutObject()) { | 1574 ->IsRemainingTextLayoutObject()) { |
| 1577 // |offset_in_node| is at start of remaining text of | 1575 // |offset_in_node| is at start of remaining text of |
| 1578 // |Text| node with :first-letter. | 1576 // |Text| node with :first-letter. |
| 1579 DCHECK_GE(offset_in_node, 1); | 1577 DCHECK_GE(offset_in_node, 1); |
| 1580 LayoutObject* first_letter_layout_object = | 1578 LayoutObject* first_letter_layout_object = |
| 1581 ToLayoutTextFragment(text_layout_object) | 1579 ToLayoutTextFragment(text_layout_object) |
| 1582 ->GetFirstLetterPseudoElement() | 1580 ->GetFirstLetterPseudoElement() |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1717 // TODO(editing-dev): This function is just moved out from | 1715 // TODO(editing-dev): This function is just moved out from |
| 1718 // |MostForwardCaretPosition()|. We should study this function more and | 1716 // |MostForwardCaretPosition()|. We should study this function more and |
| 1719 // name it appropriately. See https://trac.webkit.org/changeset/32438/ | 1717 // name it appropriately. See https://trac.webkit.org/changeset/32438/ |
| 1720 // which introduce this. | 1718 // which introduce this. |
| 1721 static bool CanBeForwardCaretPosition(const LayoutText* text_layout_object, | 1719 static bool CanBeForwardCaretPosition(const LayoutText* text_layout_object, |
| 1722 int offset_in_node) { | 1720 int offset_in_node) { |
| 1723 const unsigned text_start_offset = text_layout_object->TextStartOffset(); | 1721 const unsigned text_start_offset = text_layout_object->TextStartOffset(); |
| 1724 DCHECK_GE(offset_in_node, static_cast<int>(text_start_offset)); | 1722 DCHECK_GE(offset_in_node, static_cast<int>(text_start_offset)); |
| 1725 const unsigned text_offset = offset_in_node - text_start_offset; | 1723 const unsigned text_offset = offset_in_node - text_start_offset; |
| 1726 InlineTextBox* const last_text_box = text_layout_object->LastTextBox(); | 1724 InlineTextBox* const last_text_box = text_layout_object->LastTextBox(); |
| 1727 for (InlineTextBox* box = text_layout_object->FirstTextBox(); box; | 1725 for (InlineTextBox* box : InlineTextBoxesOf(*text_layout_object)) { |
| 1728 box = box->NextTextBox()) { | |
| 1729 if (text_offset <= box->end()) { | 1726 if (text_offset <= box->end()) { |
| 1730 if (text_offset >= box->Start()) | 1727 if (text_offset >= box->Start()) |
| 1731 return true; | 1728 return true; |
| 1732 continue; | 1729 continue; |
| 1733 } | 1730 } |
| 1734 | 1731 |
| 1735 if (box == last_text_box || text_offset != box->Start() + box->Len()) | 1732 if (box == last_text_box || text_offset != box->Start() + box->Len()) |
| 1736 continue; | 1733 continue; |
| 1737 | 1734 |
| 1738 if (DoesContinueOnNextLine(*text_layout_object, box, text_offset)) | 1735 if (DoesContinueOnNextLine(*text_layout_object, box, text_offset)) |
| (...skipping 881 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2620 | 2617 |
| 2621 IntRect ComputeTextRect(const EphemeralRangeInFlatTree& range) { | 2618 IntRect ComputeTextRect(const EphemeralRangeInFlatTree& range) { |
| 2622 return EnclosingIntRect(ComputeTextRectTemplate(range)); | 2619 return EnclosingIntRect(ComputeTextRectTemplate(range)); |
| 2623 } | 2620 } |
| 2624 | 2621 |
| 2625 FloatRect ComputeTextFloatRect(const EphemeralRange& range) { | 2622 FloatRect ComputeTextFloatRect(const EphemeralRange& range) { |
| 2626 return ComputeTextRectTemplate(range); | 2623 return ComputeTextRectTemplate(range); |
| 2627 } | 2624 } |
| 2628 | 2625 |
| 2629 } // namespace blink | 2626 } // namespace blink |
| OLD | NEW |