 Chromium Code Reviews
 Chromium Code Reviews Issue 2926823002:
  Introduce LocalCaretRect for refactoring Local{Caret,Selection}RectPosition()  (Closed)
    
  
    Issue 2926823002:
  Introduce LocalCaretRect for refactoring Local{Caret,Selection}RectPosition()  (Closed) 
  | 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 959 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 970 primary_direction); | 970 primary_direction); | 
| 971 } | 971 } | 
| 972 | 972 | 
| 973 InlineBoxPosition ComputeInlineBoxPosition(const PositionInFlatTree& position, | 973 InlineBoxPosition ComputeInlineBoxPosition(const PositionInFlatTree& position, | 
| 974 TextAffinity affinity, | 974 TextAffinity affinity, | 
| 975 TextDirection primary_direction) { | 975 TextDirection primary_direction) { | 
| 976 return ComputeInlineBoxPositionTemplate<EditingInFlatTreeStrategy>( | 976 return ComputeInlineBoxPositionTemplate<EditingInFlatTreeStrategy>( | 
| 977 position, affinity, primary_direction); | 977 position, affinity, primary_direction); | 
| 978 } | 978 } | 
| 979 | 979 | 
| 980 // TODO(editing-dev): Once we mark |LayoutObject::LocalCaretRect()| |const|, | |
| 981 // we should make this function to take |const LayoutObject&|. | |
| 982 static LocalCaretRect ComputeLocalCaretRect( | |
| 983 LayoutObject* layout_object, | |
| 984 const InlineBoxPosition box_position) { | |
| 985 return LocalCaretRect( | |
| 986 layout_object, layout_object->LocalCaretRect(box_position.inline_box, | |
| 987 box_position.offset_in_box)); | |
| 988 } | |
| 989 | |
| 980 template <typename Strategy> | 990 template <typename Strategy> | 
| 981 LayoutRect LocalCaretRectOfPositionTemplate( | 991 LocalCaretRect LocalCaretRectOfPositionTemplate( | 
| 982 const PositionWithAffinityTemplate<Strategy>& position, | 992 const PositionWithAffinityTemplate<Strategy>& position) { | 
| 983 LayoutObject*& layout_object) { | 993 if (position.IsNull()) | 
| 984 if (position.IsNull()) { | 994 return LocalCaretRect(); | 
| 985 layout_object = nullptr; | 995 Node* const node = position.AnchorNode(); | 
| 986 return LayoutRect(); | 996 LayoutObject* const layout_object = node->GetLayoutObject(); | 
| 987 } | 997 if (!layout_object) | 
| 988 Node* node = position.AnchorNode(); | 998 return LocalCaretRect(); | 
| 989 | 999 | 
| 990 layout_object = node->GetLayoutObject(); | 1000 const InlineBoxPosition& box_position = | 
| 991 if (!layout_object) | |
| 992 return LayoutRect(); | |
| 993 | |
| 994 InlineBoxPosition box_position = | |
| 995 ComputeInlineBoxPosition(position.GetPosition(), position.Affinity()); | 1001 ComputeInlineBoxPosition(position.GetPosition(), position.Affinity()); | 
| 996 | 1002 | 
| 997 if (box_position.inline_box) | 1003 if (box_position.inline_box) { | 
| 998 layout_object = LineLayoutAPIShim::LayoutObjectFrom( | 1004 return ComputeLocalCaretRect( | 
| 999 box_position.inline_box->GetLineLayoutItem()); | 1005 LineLayoutAPIShim::LayoutObjectFrom( | 
| 1000 | 1006 box_position.inline_box->GetLineLayoutItem()), | 
| 1001 return layout_object->LocalCaretRect(box_position.inline_box, | 1007 box_position); | 
| 1002 box_position.offset_in_box); | 1008 } | 
| 1009 return ComputeLocalCaretRect(node->GetLayoutObject(), box_position); | |
| 
Xiaocheng
2017/06/09 05:58:38
nit: s/node->GetLayoutObject()/layout_object/
 
yosin_UTC9
2017/06/09 06:13:29
Done.
 | |
| 1003 } | 1010 } | 
| 1004 | 1011 | 
| 1005 // This function was added because the caret rect that is calculated by | 1012 // This function was added because the caret rect that is calculated by | 
| 1006 // using the line top value instead of the selection top. | 1013 // using the line top value instead of the selection top. | 
| 1007 template <typename Strategy> | 1014 template <typename Strategy> | 
| 1008 LayoutRect LocalSelectionRectOfPositionTemplate( | 1015 LocalCaretRect LocalSelectionRectOfPositionTemplate( | 
| 1009 const PositionWithAffinityTemplate<Strategy>& position, | 1016 const PositionWithAffinityTemplate<Strategy>& position) { | 
| 1010 LayoutObject*& layout_object) { | 1017 if (position.IsNull()) | 
| 1011 if (position.IsNull()) { | 1018 return LocalCaretRect(); | 
| 1012 layout_object = nullptr; | 1019 Node* const node = position.AnchorNode(); | 
| 1013 return LayoutRect(); | 1020 if (!node->GetLayoutObject()) | 
| 1014 } | 1021 return LocalCaretRect(); | 
| 1015 Node* node = position.AnchorNode(); | |
| 1016 layout_object = node->GetLayoutObject(); | |
| 1017 if (!layout_object) | |
| 1018 return LayoutRect(); | |
| 1019 | 1022 | 
| 1020 InlineBoxPosition box_position = | 1023 const InlineBoxPosition& box_position = | 
| 1021 ComputeInlineBoxPosition(position.GetPosition(), position.Affinity()); | 1024 ComputeInlineBoxPosition(position.GetPosition(), position.Affinity()); | 
| 1022 | 1025 | 
| 1023 if (!box_position.inline_box) | 1026 if (!box_position.inline_box) | 
| 1024 return LayoutRect(); | 1027 return LocalCaretRect(); | 
| 1025 | 1028 | 
| 1026 layout_object = LineLayoutAPIShim::LayoutObjectFrom( | 1029 LayoutObject* const layout_object = LineLayoutAPIShim::LayoutObjectFrom( | 
| 1027 box_position.inline_box->GetLineLayoutItem()); | 1030 box_position.inline_box->GetLineLayoutItem()); | 
| 1028 | 1031 | 
| 1029 LayoutRect rect = layout_object->LocalCaretRect(box_position.inline_box, | 1032 const LayoutRect& rect = layout_object->LocalCaretRect( | 
| 1030 box_position.offset_in_box); | 1033 box_position.inline_box, box_position.offset_in_box); | 
| 1031 | 1034 | 
| 1032 if (rect.IsEmpty()) | 1035 if (rect.IsEmpty()) | 
| 1033 return rect; | 1036 return LocalCaretRect(); | 
| 1034 | 1037 | 
| 1035 InlineBox* const box = box_position.inline_box; | 1038 InlineBox* const box = box_position.inline_box; | 
| 1036 if (layout_object->Style()->IsHorizontalWritingMode()) { | 1039 if (layout_object->Style()->IsHorizontalWritingMode()) { | 
| 1037 rect.SetY(box->Root().SelectionTop()); | 1040 return LocalCaretRect( | 
| 1038 rect.SetHeight(box->Root().SelectionHeight()); | 1041 layout_object, | 
| 1039 return rect; | 1042 LayoutRect(LayoutPoint(rect.X(), box->Root().SelectionTop()), | 
| 1043 LayoutSize(rect.Width(), box->Root().SelectionHeight()))); | |
| 1040 } | 1044 } | 
| 1041 | 1045 | 
| 1042 rect.SetX(box->Root().SelectionTop()); | 1046 return LocalCaretRect( | 
| 1043 rect.SetWidth(box->Root().SelectionHeight()); | 1047 layout_object, | 
| 1044 return rect; | 1048 LayoutRect(LayoutPoint(box->Root().SelectionTop(), rect.Y()), | 
| 1049 LayoutSize(box->Root().SelectionHeight(), rect.Height()))); | |
| 1045 } | 1050 } | 
| 1046 | 1051 | 
| 1047 LayoutRect LocalCaretRectOfPosition(const PositionWithAffinity& position, | 1052 LocalCaretRect LocalCaretRectOfPosition(const PositionWithAffinity& position) { | 
| 1048 LayoutObject*& layout_object) { | 1053 return LocalCaretRectOfPositionTemplate<EditingStrategy>(position); | 
| 1049 return LocalCaretRectOfPositionTemplate<EditingStrategy>(position, | |
| 1050 layout_object); | |
| 1051 } | 1054 } | 
| 1052 | 1055 | 
| 1053 LayoutRect LocalSelectionRectOfPosition(const PositionWithAffinity& position, | 1056 static LocalCaretRect LocalSelectionRectOfPosition( | 
| 1054 LayoutObject*& layout_object) { | 1057 const PositionWithAffinity& position) { | 
| 1055 return LocalSelectionRectOfPositionTemplate<EditingStrategy>(position, | 1058 return LocalSelectionRectOfPositionTemplate<EditingStrategy>(position); | 
| 1056 layout_object); | |
| 1057 } | 1059 } | 
| 1058 | 1060 | 
| 1059 LayoutRect LocalCaretRectOfPosition( | 1061 LocalCaretRect LocalCaretRectOfPosition( | 
| 1060 const PositionInFlatTreeWithAffinity& position, | 1062 const PositionInFlatTreeWithAffinity& position) { | 
| 1061 LayoutObject*& layout_object) { | 1063 return LocalCaretRectOfPositionTemplate<EditingInFlatTreeStrategy>(position); | 
| 1062 return LocalCaretRectOfPositionTemplate<EditingInFlatTreeStrategy>( | |
| 1063 position, layout_object); | |
| 1064 } | 1064 } | 
| 1065 | 1065 | 
| 1066 static LayoutUnit BoundingBoxLogicalHeight(LayoutObject* o, | 1066 static LayoutUnit BoundingBoxLogicalHeight(LayoutObject* o, | 
| 1067 const LayoutRect& rect) { | 1067 const LayoutRect& rect) { | 
| 1068 return o->Style()->IsHorizontalWritingMode() ? rect.Height() : rect.Width(); | 1068 return o->Style()->IsHorizontalWritingMode() ? rect.Height() : rect.Width(); | 
| 1069 } | 1069 } | 
| 1070 | 1070 | 
| 1071 bool HasRenderedNonAnonymousDescendantsWithHeight(LayoutObject* layout_object) { | 1071 bool HasRenderedNonAnonymousDescendantsWithHeight(LayoutObject* layout_object) { | 
| 1072 LayoutObject* stop = layout_object->NextInPreOrderAfterChildren(); | 1072 LayoutObject* stop = layout_object->NextInPreOrderAfterChildren(); | 
| 1073 for (LayoutObject* o = layout_object->SlowFirstChild(); o && o != stop; | 1073 for (LayoutObject* o = layout_object->SlowFirstChild(); o && o != stop; | 
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1193 return text_offset == text_layout_object->CaretMinOffset() || | 1193 return text_offset == text_layout_object->CaretMinOffset() || | 
| 1194 text_offset == NextGraphemeBoundaryOf( | 1194 text_offset == NextGraphemeBoundaryOf( | 
| 1195 anchor_node, PreviousGraphemeBoundaryOf( | 1195 anchor_node, PreviousGraphemeBoundaryOf( | 
| 1196 anchor_node, text_offset)); | 1196 anchor_node, text_offset)); | 
| 1197 } | 1197 } | 
| 1198 } | 1198 } | 
| 1199 | 1199 | 
| 1200 return false; | 1200 return false; | 
| 1201 } | 1201 } | 
| 1202 | 1202 | 
| 1203 static FloatQuad LocalToAbsoluteQuadOf(const LocalCaretRect& caret_rect) { | |
| 1204 return caret_rect.layout_object->LocalToAbsoluteQuad( | |
| 1205 FloatRect(caret_rect.rect)); | |
| 1206 } | |
| 1207 | |
| 1203 bool RendersInDifferentPosition(const Position& position1, | 1208 bool RendersInDifferentPosition(const Position& position1, | 
| 1204 const Position& position2) { | 1209 const Position& position2) { | 
| 1205 if (position1.IsNull() || position2.IsNull()) | 1210 if (position1.IsNull() || position2.IsNull()) | 
| 1206 return false; | 1211 return false; | 
| 1207 LayoutObject* layout_object1; | 1212 const LocalCaretRect& caret_rect1 = | 
| 1208 const LayoutRect& rect1 = | 1213 LocalCaretRectOfPosition(PositionWithAffinity(position1)); | 
| 1209 LocalCaretRectOfPosition(PositionWithAffinity(position1), layout_object1); | 1214 const LocalCaretRect& caret_rect2 = | 
| 1210 LayoutObject* layout_object2; | 1215 LocalCaretRectOfPosition(PositionWithAffinity(position2)); | 
| 1211 const LayoutRect& rect2 = | 1216 if (!caret_rect1.layout_object || !caret_rect2.layout_object) | 
| 1212 LocalCaretRectOfPosition(PositionWithAffinity(position2), layout_object2); | 1217 return caret_rect1.layout_object != caret_rect2.layout_object; | 
| 1213 if (!layout_object1 || !layout_object2) | 1218 return LocalToAbsoluteQuadOf(caret_rect1) != | 
| 1214 return layout_object1 != layout_object2; | 1219 LocalToAbsoluteQuadOf(caret_rect2); | 
| 1215 return layout_object1->LocalToAbsoluteQuad(FloatRect(rect1)) != | |
| 1216 layout_object2->LocalToAbsoluteQuad(FloatRect(rect2)); | |
| 1217 } | 1220 } | 
| 1218 | 1221 | 
| 1219 static bool IsVisuallyEmpty(const LayoutObject* layout) { | 1222 static bool IsVisuallyEmpty(const LayoutObject* layout) { | 
| 1220 for (LayoutObject* child = layout->SlowFirstChild(); child; | 1223 for (LayoutObject* child = layout->SlowFirstChild(); child; | 
| 1221 child = child->NextSibling()) { | 1224 child = child->NextSibling()) { | 
| 1222 // TODO(xiaochengh): Replace type-based conditioning by virtual function. | 1225 // TODO(xiaochengh): Replace type-based conditioning by virtual function. | 
| 1223 if (child->IsBox()) { | 1226 if (child->IsBox()) { | 
| 1224 if (!ToLayoutBox(child)->Size().IsEmpty()) | 1227 if (!ToLayoutBox(child)->Size().IsEmpty()) | 
| 1225 return false; | 1228 return false; | 
| 1226 } else if (child->IsLayoutInline()) { | 1229 } else if (child->IsLayoutInline()) { | 
| (...skipping 491 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1718 | 1721 | 
| 1719 bool IsVisuallyEquivalentCandidate(const PositionInFlatTree& position) { | 1722 bool IsVisuallyEquivalentCandidate(const PositionInFlatTree& position) { | 
| 1720 return IsVisuallyEquivalentCandidateAlgorithm<EditingInFlatTreeStrategy>( | 1723 return IsVisuallyEquivalentCandidateAlgorithm<EditingInFlatTreeStrategy>( | 
| 1721 position); | 1724 position); | 
| 1722 } | 1725 } | 
| 1723 | 1726 | 
| 1724 template <typename Strategy> | 1727 template <typename Strategy> | 
| 1725 static IntRect AbsoluteCaretBoundsOfAlgorithm( | 1728 static IntRect AbsoluteCaretBoundsOfAlgorithm( | 
| 1726 const VisiblePositionTemplate<Strategy>& visible_position) { | 1729 const VisiblePositionTemplate<Strategy>& visible_position) { | 
| 1727 DCHECK(visible_position.IsValid()) << visible_position; | 1730 DCHECK(visible_position.IsValid()) << visible_position; | 
| 1728 LayoutObject* layout_object; | 1731 const LocalCaretRect& caret_rect = | 
| 1729 LayoutRect local_rect = LocalCaretRectOfPosition( | 1732 LocalCaretRectOfPosition(visible_position.ToPositionWithAffinity()); | 
| 1730 visible_position.ToPositionWithAffinity(), layout_object); | 1733 if (caret_rect.IsEmpty()) | 
| 1731 if (local_rect.IsEmpty() || !layout_object) | |
| 1732 return IntRect(); | 1734 return IntRect(); | 
| 1733 | 1735 return LocalToAbsoluteQuadOf(caret_rect).EnclosingBoundingBox(); | 
| 1734 return layout_object->LocalToAbsoluteQuad(FloatRect(local_rect)) | |
| 1735 .EnclosingBoundingBox(); | |
| 1736 } | 1736 } | 
| 1737 | 1737 | 
| 1738 IntRect AbsoluteCaretBoundsOf(const VisiblePosition& visible_position) { | 1738 IntRect AbsoluteCaretBoundsOf(const VisiblePosition& visible_position) { | 
| 1739 return AbsoluteCaretBoundsOfAlgorithm<EditingStrategy>(visible_position); | 1739 return AbsoluteCaretBoundsOfAlgorithm<EditingStrategy>(visible_position); | 
| 1740 } | 1740 } | 
| 1741 | 1741 | 
| 1742 template <typename Strategy> | 1742 template <typename Strategy> | 
| 1743 static IntRect AbsoluteSelectionBoundsOfAlgorithm( | 1743 static IntRect AbsoluteSelectionBoundsOfAlgorithm( | 
| 1744 const VisiblePositionTemplate<Strategy>& visible_position) { | 1744 const VisiblePositionTemplate<Strategy>& visible_position) { | 
| 1745 DCHECK(visible_position.IsValid()) << visible_position; | 1745 DCHECK(visible_position.IsValid()) << visible_position; | 
| 1746 LayoutObject* layout_object; | 1746 const LocalCaretRect& caret_rect = | 
| 1747 LayoutRect local_rect = LocalSelectionRectOfPosition( | 1747 LocalSelectionRectOfPosition(visible_position.ToPositionWithAffinity()); | 
| 1748 visible_position.ToPositionWithAffinity(), layout_object); | 1748 if (caret_rect.IsEmpty()) | 
| 1749 if (local_rect.IsEmpty() || !layout_object) | |
| 1750 return IntRect(); | 1749 return IntRect(); | 
| 1751 | 1750 return LocalToAbsoluteQuadOf(caret_rect).EnclosingBoundingBox(); | 
| 1752 return layout_object->LocalToAbsoluteQuad(FloatRect(local_rect)) | |
| 1753 .EnclosingBoundingBox(); | |
| 1754 } | 1751 } | 
| 1755 | 1752 | 
| 1756 IntRect AbsoluteSelectionBoundsOf(const VisiblePosition& visible_position) { | 1753 IntRect AbsoluteSelectionBoundsOf(const VisiblePosition& visible_position) { | 
| 1757 return AbsoluteSelectionBoundsOfAlgorithm<EditingStrategy>(visible_position); | 1754 return AbsoluteSelectionBoundsOfAlgorithm<EditingStrategy>(visible_position); | 
| 1758 } | 1755 } | 
| 1759 | 1756 | 
| 1760 IntRect AbsoluteCaretBoundsOf( | 1757 IntRect AbsoluteCaretBoundsOf( | 
| 1761 const VisiblePositionInFlatTree& visible_position) { | 1758 const VisiblePositionInFlatTree& visible_position) { | 
| 1762 return AbsoluteCaretBoundsOfAlgorithm<EditingInFlatTreeStrategy>( | 1759 return AbsoluteCaretBoundsOfAlgorithm<EditingInFlatTreeStrategy>( | 
| 1763 visible_position); | 1760 visible_position); | 
| (...skipping 719 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2483 | 2480 | 
| 2484 IntRect ComputeTextRect(const EphemeralRangeInFlatTree& range) { | 2481 IntRect ComputeTextRect(const EphemeralRangeInFlatTree& range) { | 
| 2485 return EnclosingIntRect(ComputeTextRectTemplate(range)); | 2482 return EnclosingIntRect(ComputeTextRectTemplate(range)); | 
| 2486 } | 2483 } | 
| 2487 | 2484 | 
| 2488 FloatRect ComputeTextFloatRect(const EphemeralRange& range) { | 2485 FloatRect ComputeTextFloatRect(const EphemeralRange& range) { | 
| 2489 return ComputeTextRectTemplate(range); | 2486 return ComputeTextRectTemplate(range); | 
| 2490 } | 2487 } | 
| 2491 | 2488 | 
| 2492 } // namespace blink | 2489 } // namespace blink | 
| OLD | NEW |