Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(164)

Side by Side Diff: third_party/WebKit/Source/core/editing/VisibleUnits.cpp

Issue 2926823002: Introduce LocalCaretRect for refactoring Local{Caret,Selection}RectPosition() (Closed)
Patch Set: 2017-06-07T19:07:35 Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 1245 matching lines...) Expand 10 before | Expand all | Expand 10 after
1256 primary_direction); 1256 primary_direction);
1257 } 1257 }
1258 1258
1259 InlineBoxPosition ComputeInlineBoxPosition(const PositionInFlatTree& position, 1259 InlineBoxPosition ComputeInlineBoxPosition(const PositionInFlatTree& position,
1260 TextAffinity affinity, 1260 TextAffinity affinity,
1261 TextDirection primary_direction) { 1261 TextDirection primary_direction) {
1262 return ComputeInlineBoxPositionTemplate<EditingInFlatTreeStrategy>( 1262 return ComputeInlineBoxPositionTemplate<EditingInFlatTreeStrategy>(
1263 position, affinity, primary_direction); 1263 position, affinity, primary_direction);
1264 } 1264 }
1265 1265
1266 // TODO(editing-dev): Once we mark |LayoutObject::LocalCaretRect()| |const|,
1267 // we should make this function to take |const LayoutObject&|.
1268 static LocalCaretRect ComputeLocalCaretRect(
1269 LayoutObject* layout_object,
1270 const InlineBoxPosition box_position) {
1271 return LocalCaretRect(
1272 layout_object, layout_object->LocalCaretRect(box_position.inline_box,
1273 box_position.offset_in_box));
1274 }
1275
1266 template <typename Strategy> 1276 template <typename Strategy>
1267 LayoutRect LocalCaretRectOfPositionTemplate( 1277 LocalCaretRect LocalCaretRectOfPositionTemplate(
1268 const PositionWithAffinityTemplate<Strategy>& position, 1278 const PositionWithAffinityTemplate<Strategy>& position) {
1269 LayoutObject*& layout_object) { 1279 if (position.IsNull())
1270 if (position.IsNull()) { 1280 return LocalCaretRect();
1271 layout_object = nullptr; 1281 Node* const node = position.AnchorNode();
1272 return LayoutRect(); 1282 if (!node->GetLayoutObject())
Xiaocheng 2017/06/08 21:00:42 We should store LayoutObject* const layout_object
yosin_UTC9 2017/06/09 06:13:29 Done.
1273 } 1283 return LocalCaretRect();
1274 Node* node = position.AnchorNode();
1275 1284
1276 layout_object = node->GetLayoutObject(); 1285 const InlineBoxPosition& box_position =
1277 if (!layout_object)
1278 return LayoutRect();
1279
1280 InlineBoxPosition box_position =
1281 ComputeInlineBoxPosition(position.GetPosition(), position.Affinity()); 1286 ComputeInlineBoxPosition(position.GetPosition(), position.Affinity());
1282 1287
1283 if (box_position.inline_box) 1288 if (!box_position.inline_box)
1284 layout_object = LineLayoutAPIShim::LayoutObjectFrom( 1289 return ComputeLocalCaretRect(node->GetLayoutObject(), box_position);
Xiaocheng 2017/06/08 21:00:41 We can use early return style without switching th
yosin_UTC9 2017/06/09 06:13:29 Done.
1285 box_position.inline_box->GetLineLayoutItem());
1286 1290
1287 return layout_object->LocalCaretRect(box_position.inline_box, 1291 return ComputeLocalCaretRect(
1288 box_position.offset_in_box); 1292 LineLayoutAPIShim::LayoutObjectFrom(
1293 box_position.inline_box->GetLineLayoutItem()),
1294 box_position);
1289 } 1295 }
1290 1296
1291 // This function was added because the caret rect that is calculated by 1297 // This function was added because the caret rect that is calculated by
1292 // using the line top value instead of the selection top. 1298 // using the line top value instead of the selection top.
1293 template <typename Strategy> 1299 template <typename Strategy>
1294 LayoutRect LocalSelectionRectOfPositionTemplate( 1300 LocalCaretRect LocalSelectionRectOfPositionTemplate(
1295 const PositionWithAffinityTemplate<Strategy>& position, 1301 const PositionWithAffinityTemplate<Strategy>& position) {
1296 LayoutObject*& layout_object) { 1302 if (position.IsNull())
1297 if (position.IsNull()) { 1303 return LocalCaretRect();
1298 layout_object = nullptr; 1304 Node* const node = position.AnchorNode();
1299 return LayoutRect(); 1305 if (!node->GetLayoutObject())
1300 } 1306 return LocalCaretRect();
1301 Node* node = position.AnchorNode();
1302 layout_object = node->GetLayoutObject();
1303 if (!layout_object)
1304 return LayoutRect();
1305 1307
1306 InlineBoxPosition box_position = 1308 const InlineBoxPosition& box_position =
1307 ComputeInlineBoxPosition(position.GetPosition(), position.Affinity()); 1309 ComputeInlineBoxPosition(position.GetPosition(), position.Affinity());
1308 1310
1309 if (!box_position.inline_box) 1311 if (!box_position.inline_box)
1310 return LayoutRect(); 1312 return LocalCaretRect();
Xiaocheng 2017/06/08 21:00:42 The original code returns a non-null LayoutObject.
yosin_UTC9 2017/06/09 06:13:29 I create another patch to return nullptr for layou
1311 1313
1312 layout_object = LineLayoutAPIShim::LayoutObjectFrom( 1314 LayoutObject* const layout_object = LineLayoutAPIShim::LayoutObjectFrom(
1313 box_position.inline_box->GetLineLayoutItem()); 1315 box_position.inline_box->GetLineLayoutItem());
1314 1316
1315 LayoutRect rect = layout_object->LocalCaretRect(box_position.inline_box, 1317 const LayoutRect& rect = layout_object->LocalCaretRect(
1316 box_position.offset_in_box); 1318 box_position.inline_box, box_position.offset_in_box);
1317 1319
1318 if (rect.IsEmpty()) 1320 if (rect.IsEmpty())
1319 return rect; 1321 return LocalCaretRect();
Xiaocheng 2017/06/08 21:00:42 Ditto.
yosin_UTC9 2017/06/09 06:13:29 I create another patch to return nullptr for layou
1320 1322
1321 InlineBox* const box = box_position.inline_box; 1323 InlineBox* const box = box_position.inline_box;
1322 if (layout_object->Style()->IsHorizontalWritingMode()) { 1324 if (layout_object->Style()->IsHorizontalWritingMode()) {
1323 rect.SetY(box->Root().SelectionTop()); 1325 return LocalCaretRect(
1324 rect.SetHeight(box->Root().SelectionHeight()); 1326 layout_object,
1325 return rect; 1327 LayoutRect(LayoutPoint(rect.X(), box->Root().SelectionTop()),
1328 LayoutSize(rect.Width(), box->Root().SelectionHeight())));
1326 } 1329 }
1327 1330
1328 rect.SetX(box->Root().SelectionTop()); 1331 return LocalCaretRect(
1329 rect.SetWidth(box->Root().SelectionHeight()); 1332 layout_object,
1330 return rect; 1333 LayoutRect(LayoutPoint(box->Root().SelectionTop(), rect.Y()),
1334 LayoutSize(box->Root().SelectionHeight(), rect.Height())));
1331 } 1335 }
1332 1336
1333 LayoutRect LocalCaretRectOfPosition(const PositionWithAffinity& position, 1337 LocalCaretRect LocalCaretRectOfPosition(const PositionWithAffinity& position) {
1334 LayoutObject*& layout_object) { 1338 return LocalCaretRectOfPositionTemplate<EditingStrategy>(position);
1335 return LocalCaretRectOfPositionTemplate<EditingStrategy>(position,
1336 layout_object);
1337 } 1339 }
1338 1340
1339 LayoutRect LocalSelectionRectOfPosition(const PositionWithAffinity& position, 1341 static LocalCaretRect LocalSelectionRectOfPosition(
1340 LayoutObject*& layout_object) { 1342 const PositionWithAffinity& position) {
1341 return LocalSelectionRectOfPositionTemplate<EditingStrategy>(position, 1343 return LocalSelectionRectOfPositionTemplate<EditingStrategy>(position);
1342 layout_object);
1343 } 1344 }
1344 1345
1345 LayoutRect LocalCaretRectOfPosition( 1346 LocalCaretRect LocalCaretRectOfPosition(
1346 const PositionInFlatTreeWithAffinity& position, 1347 const PositionInFlatTreeWithAffinity& position) {
1347 LayoutObject*& layout_object) { 1348 return LocalCaretRectOfPositionTemplate<EditingInFlatTreeStrategy>(position);
1348 return LocalCaretRectOfPositionTemplate<EditingInFlatTreeStrategy>(
1349 position, layout_object);
1350 } 1349 }
1351 1350
1352 static LayoutUnit BoundingBoxLogicalHeight(LayoutObject* o, 1351 static LayoutUnit BoundingBoxLogicalHeight(LayoutObject* o,
1353 const LayoutRect& rect) { 1352 const LayoutRect& rect) {
1354 return o->Style()->IsHorizontalWritingMode() ? rect.Height() : rect.Width(); 1353 return o->Style()->IsHorizontalWritingMode() ? rect.Height() : rect.Width();
1355 } 1354 }
1356 1355
1357 bool HasRenderedNonAnonymousDescendantsWithHeight(LayoutObject* layout_object) { 1356 bool HasRenderedNonAnonymousDescendantsWithHeight(LayoutObject* layout_object) {
1358 LayoutObject* stop = layout_object->NextInPreOrderAfterChildren(); 1357 LayoutObject* stop = layout_object->NextInPreOrderAfterChildren();
1359 for (LayoutObject* o = layout_object->SlowFirstChild(); o && o != stop; 1358 for (LayoutObject* o = layout_object->SlowFirstChild(); o && o != stop;
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
1480 return text_offset == text_layout_object->CaretMinOffset() || 1479 return text_offset == text_layout_object->CaretMinOffset() ||
1481 text_offset == NextGraphemeBoundaryOf( 1480 text_offset == NextGraphemeBoundaryOf(
1482 anchor_node, PreviousGraphemeBoundaryOf( 1481 anchor_node, PreviousGraphemeBoundaryOf(
1483 anchor_node, text_offset)); 1482 anchor_node, text_offset));
1484 } 1483 }
1485 } 1484 }
1486 1485
1487 return false; 1486 return false;
1488 } 1487 }
1489 1488
1489 FloatQuad LocalCaretRect::LocalToAbsoluteQuad() const {
1490 return layout_object->LocalToAbsoluteQuad(FloatRect(rect));
1491 }
1492
1490 bool RendersInDifferentPosition(const Position& position1, 1493 bool RendersInDifferentPosition(const Position& position1,
1491 const Position& position2) { 1494 const Position& position2) {
1492 if (position1.IsNull() || position2.IsNull()) 1495 if (position1.IsNull() || position2.IsNull())
1493 return false; 1496 return false;
1494 LayoutObject* layout_object1; 1497 const LocalCaretRect& caret_rect1 =
1495 const LayoutRect& rect1 = 1498 LocalCaretRectOfPosition(PositionWithAffinity(position1));
1496 LocalCaretRectOfPosition(PositionWithAffinity(position1), layout_object1); 1499 const LocalCaretRect& caret_rect2 =
1497 LayoutObject* layout_object2; 1500 LocalCaretRectOfPosition(PositionWithAffinity(position2));
1498 const LayoutRect& rect2 = 1501 if (!caret_rect1.layout_object || !caret_rect2.layout_object)
1499 LocalCaretRectOfPosition(PositionWithAffinity(position2), layout_object2); 1502 return caret_rect1.layout_object != caret_rect2.layout_object;
1500 if (!layout_object1 || !layout_object2) 1503 return caret_rect1.LocalToAbsoluteQuad() != caret_rect2.LocalToAbsoluteQuad();
1501 return layout_object1 != layout_object2;
1502 return layout_object1->LocalToAbsoluteQuad(FloatRect(rect1)) !=
1503 layout_object2->LocalToAbsoluteQuad(FloatRect(rect2));
1504 } 1504 }
1505 1505
1506 static bool IsVisuallyEmpty(const LayoutObject* layout) { 1506 static bool IsVisuallyEmpty(const LayoutObject* layout) {
1507 for (LayoutObject* child = layout->SlowFirstChild(); child; 1507 for (LayoutObject* child = layout->SlowFirstChild(); child;
1508 child = child->NextSibling()) { 1508 child = child->NextSibling()) {
1509 // TODO(xiaochengh): Replace type-based conditioning by virtual function. 1509 // TODO(xiaochengh): Replace type-based conditioning by virtual function.
1510 if (child->IsBox()) { 1510 if (child->IsBox()) {
1511 if (!ToLayoutBox(child)->Size().IsEmpty()) 1511 if (!ToLayoutBox(child)->Size().IsEmpty())
1512 return false; 1512 return false;
1513 } else if (child->IsLayoutInline()) { 1513 } else if (child->IsLayoutInline()) {
(...skipping 493 matching lines...) Expand 10 before | Expand all | Expand 10 after
2007 2007
2008 bool IsVisuallyEquivalentCandidate(const PositionInFlatTree& position) { 2008 bool IsVisuallyEquivalentCandidate(const PositionInFlatTree& position) {
2009 return IsVisuallyEquivalentCandidateAlgorithm<EditingInFlatTreeStrategy>( 2009 return IsVisuallyEquivalentCandidateAlgorithm<EditingInFlatTreeStrategy>(
2010 position); 2010 position);
2011 } 2011 }
2012 2012
2013 template <typename Strategy> 2013 template <typename Strategy>
2014 static IntRect AbsoluteCaretBoundsOfAlgorithm( 2014 static IntRect AbsoluteCaretBoundsOfAlgorithm(
2015 const VisiblePositionTemplate<Strategy>& visible_position) { 2015 const VisiblePositionTemplate<Strategy>& visible_position) {
2016 DCHECK(visible_position.IsValid()) << visible_position; 2016 DCHECK(visible_position.IsValid()) << visible_position;
2017 LayoutObject* layout_object; 2017 const LocalCaretRect& caret_rect =
2018 LayoutRect local_rect = LocalCaretRectOfPosition( 2018 LocalCaretRectOfPosition(visible_position.ToPositionWithAffinity());
2019 visible_position.ToPositionWithAffinity(), layout_object); 2019 if (caret_rect.IsEmpty())
2020 if (local_rect.IsEmpty() || !layout_object)
2021 return IntRect(); 2020 return IntRect();
2022 2021 return caret_rect.LocalToAbsoluteQuad().EnclosingBoundingBox();
2023 return layout_object->LocalToAbsoluteQuad(FloatRect(local_rect))
2024 .EnclosingBoundingBox();
2025 } 2022 }
2026 2023
2027 IntRect AbsoluteCaretBoundsOf(const VisiblePosition& visible_position) { 2024 IntRect AbsoluteCaretBoundsOf(const VisiblePosition& visible_position) {
2028 return AbsoluteCaretBoundsOfAlgorithm<EditingStrategy>(visible_position); 2025 return AbsoluteCaretBoundsOfAlgorithm<EditingStrategy>(visible_position);
2029 } 2026 }
2030 2027
2031 template <typename Strategy> 2028 template <typename Strategy>
2032 static IntRect AbsoluteSelectionBoundsOfAlgorithm( 2029 static IntRect AbsoluteSelectionBoundsOfAlgorithm(
2033 const VisiblePositionTemplate<Strategy>& visible_position) { 2030 const VisiblePositionTemplate<Strategy>& visible_position) {
2034 DCHECK(visible_position.IsValid()) << visible_position; 2031 DCHECK(visible_position.IsValid()) << visible_position;
2035 LayoutObject* layout_object; 2032 const LocalCaretRect& caret_rect =
2036 LayoutRect local_rect = LocalSelectionRectOfPosition( 2033 LocalSelectionRectOfPosition(visible_position.ToPositionWithAffinity());
2037 visible_position.ToPositionWithAffinity(), layout_object); 2034 if (caret_rect.IsEmpty())
2038 if (local_rect.IsEmpty() || !layout_object)
2039 return IntRect(); 2035 return IntRect();
2040 2036 return caret_rect.LocalToAbsoluteQuad().EnclosingBoundingBox();
2041 return layout_object->LocalToAbsoluteQuad(FloatRect(local_rect))
2042 .EnclosingBoundingBox();
2043 } 2037 }
2044 2038
2045 IntRect AbsoluteSelectionBoundsOf(const VisiblePosition& visible_position) { 2039 IntRect AbsoluteSelectionBoundsOf(const VisiblePosition& visible_position) {
2046 return AbsoluteSelectionBoundsOfAlgorithm<EditingStrategy>(visible_position); 2040 return AbsoluteSelectionBoundsOfAlgorithm<EditingStrategy>(visible_position);
2047 } 2041 }
2048 2042
2049 IntRect AbsoluteCaretBoundsOf( 2043 IntRect AbsoluteCaretBoundsOf(
2050 const VisiblePositionInFlatTree& visible_position) { 2044 const VisiblePositionInFlatTree& visible_position) {
2051 return AbsoluteCaretBoundsOfAlgorithm<EditingInFlatTreeStrategy>( 2045 return AbsoluteCaretBoundsOfAlgorithm<EditingInFlatTreeStrategy>(
2052 visible_position); 2046 visible_position);
(...skipping 719 matching lines...) Expand 10 before | Expand all | Expand 10 after
2772 2766
2773 IntRect ComputeTextRect(const EphemeralRangeInFlatTree& range) { 2767 IntRect ComputeTextRect(const EphemeralRangeInFlatTree& range) {
2774 return EnclosingIntRect(ComputeTextRectTemplate(range)); 2768 return EnclosingIntRect(ComputeTextRectTemplate(range));
2775 } 2769 }
2776 2770
2777 FloatRect ComputeTextFloatRect(const EphemeralRange& range) { 2771 FloatRect ComputeTextFloatRect(const EphemeralRange& range) {
2778 return ComputeTextRectTemplate(range); 2772 return ComputeTextRectTemplate(range);
2779 } 2773 }
2780 2774
2781 } // namespace blink 2775 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698