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

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

Issue 1303173002: Move computeInlineBoxPosition() to VisibleUnits.{cpp,h} from Position.{cpp,h} and VisiblePosition.h (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: 2015-08-21T13:45:14 Created 5 years, 4 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
« no previous file with comments | « Source/core/editing/VisibleUnits.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserv ed. 2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserv ed.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 1. Redistributions of source code must retain the above copyright 7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright 9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
(...skipping 1438 matching lines...) Expand 10 before | Expand all | Expand 10 after
1449 VisiblePosition leftBoundaryOfLine(const VisiblePosition& c, TextDirection direc tion) 1449 VisiblePosition leftBoundaryOfLine(const VisiblePosition& c, TextDirection direc tion)
1450 { 1450 {
1451 return direction == LTR ? logicalStartOfLine(c) : logicalEndOfLine(c); 1451 return direction == LTR ? logicalStartOfLine(c) : logicalEndOfLine(c);
1452 } 1452 }
1453 1453
1454 VisiblePosition rightBoundaryOfLine(const VisiblePosition& c, TextDirection dire ction) 1454 VisiblePosition rightBoundaryOfLine(const VisiblePosition& c, TextDirection dire ction)
1455 { 1455 {
1456 return direction == LTR ? logicalEndOfLine(c) : logicalStartOfLine(c); 1456 return direction == LTR ? logicalEndOfLine(c) : logicalStartOfLine(c);
1457 } 1457 }
1458 1458
1459 static bool isNonTextLeafChild(LayoutObject* object)
1460 {
1461 if (object->slowFirstChild())
1462 return false;
1463 if (object->isText())
1464 return false;
1465 return true;
1466 }
1467
1468 static InlineTextBox* searchAheadForBetterMatch(LayoutObject* layoutObject)
1469 {
1470 LayoutBlock* container = layoutObject->containingBlock();
1471 for (LayoutObject* next = layoutObject->nextInPreOrder(container); next; nex t = next->nextInPreOrder(container)) {
1472 if (next->isLayoutBlock())
1473 return 0;
1474 if (next->isBR())
1475 return 0;
1476 if (isNonTextLeafChild(next))
1477 return 0;
1478 if (next->isText()) {
1479 InlineTextBox* match = 0;
1480 int minOffset = INT_MAX;
1481 for (InlineTextBox* box = toLayoutText(next)->firstTextBox(); box; b ox = box->nextTextBox()) {
1482 int caretMinOffset = box->caretMinOffset();
1483 if (caretMinOffset < minOffset) {
1484 match = box;
1485 minOffset = caretMinOffset;
1486 }
1487 }
1488 if (match)
1489 return match;
1490 }
1491 }
1492 return 0;
1493 }
1494
1495 template <typename Strategy>
1496 PositionAlgorithm<Strategy> downstreamIgnoringEditingBoundaries(PositionAlgorith m<Strategy> position)
1497 {
1498 PositionAlgorithm<Strategy> lastPosition;
1499 while (position != lastPosition) {
1500 lastPosition = position;
1501 position = position.downstream(CanCrossEditingBoundary);
1502 }
1503 return position;
1504 }
1505
1506 template <typename Strategy>
1507 PositionAlgorithm<Strategy> upstreamIgnoringEditingBoundaries(PositionAlgorithm< Strategy> position)
1508 {
1509 PositionAlgorithm<Strategy> lastPosition;
1510 while (position != lastPosition) {
1511 lastPosition = position;
1512 position = position.upstream(CanCrossEditingBoundary);
1513 }
1514 return position;
1515 }
1516
1517 template <typename Strategy>
1518 static InlineBoxPosition computeInlineBoxPositionAlgorithm(const PositionAlgorit hm<Strategy>& position, TextAffinity affinity, TextDirection primaryDirection)
1519 {
1520 InlineBox* inlineBox = nullptr;
1521 int caretOffset = position.computeEditingOffset();
1522 Node* const anchorNode = position.anchorNode();
1523 LayoutObject* layoutObject = anchorNode->isShadowRoot() ? toShadowRoot(ancho rNode)->host()->layoutObject() : anchorNode->layoutObject();
1524
1525 if (!layoutObject->isText()) {
1526 inlineBox = 0;
1527 if (canHaveChildrenForEditing(anchorNode) && layoutObject->isLayoutBlock Flow() && hasRenderedNonAnonymousDescendantsWithHeight(layoutObject)) {
1528 // Try a visually equivalent position with possibly opposite
1529 // editability. This helps in case |this| is in an editable block
1530 // but surrounded by non-editable positions. It acts to negate the
1531 // logic at the beginning of LayoutObject::createVisiblePosition().
1532 PositionAlgorithm<Strategy> equivalent = downstreamIgnoringEditingBo undaries(position);
1533 if (equivalent == position) {
1534 equivalent = upstreamIgnoringEditingBoundaries(position);
1535 if (equivalent == position || downstreamIgnoringEditingBoundarie s(equivalent) == position)
1536 return InlineBoxPosition(inlineBox, caretOffset);
1537 }
1538
1539 return computeInlineBoxPosition(equivalent, TextAffinity::Upstream, primaryDirection);
1540 }
1541 if (layoutObject->isBox()) {
1542 inlineBox = toLayoutBox(layoutObject)->inlineBoxWrapper();
1543 if (!inlineBox || (caretOffset > inlineBox->caretMinOffset() && care tOffset < inlineBox->caretMaxOffset()))
1544 return InlineBoxPosition(inlineBox, caretOffset);
1545 }
1546 } else {
1547 LayoutText* textLayoutObject = toLayoutText(layoutObject);
1548
1549 InlineTextBox* box;
1550 InlineTextBox* candidate = 0;
1551
1552 for (box = textLayoutObject->firstTextBox(); box; box = box->nextTextBox ()) {
1553 int caretMinOffset = box->caretMinOffset();
1554 int caretMaxOffset = box->caretMaxOffset();
1555
1556 if (caretOffset < caretMinOffset || caretOffset > caretMaxOffset || (caretOffset == caretMaxOffset && box->isLineBreak()))
1557 continue;
1558
1559 if (caretOffset > caretMinOffset && caretOffset < caretMaxOffset)
1560 return InlineBoxPosition(box, caretOffset);
1561
1562 if (((caretOffset == caretMaxOffset) ^ (affinity == TextAffinity::Do wnstream))
1563 || ((caretOffset == caretMinOffset) ^ (affinity == TextAffinity: :Upstream))
1564 || (caretOffset == caretMaxOffset && box->nextLeafChild() && box ->nextLeafChild()->isLineBreak()))
1565 break;
1566
1567 candidate = box;
1568 }
1569 if (candidate && candidate == textLayoutObject->lastTextBox() && affinit y == TextAffinity::Downstream) {
1570 box = searchAheadForBetterMatch(textLayoutObject);
1571 if (box)
1572 caretOffset = box->caretMinOffset();
1573 }
1574 inlineBox = box ? box : candidate;
1575 }
1576
1577 if (!inlineBox)
1578 return InlineBoxPosition(inlineBox, caretOffset);
1579
1580 unsigned char level = inlineBox->bidiLevel();
1581
1582 if (inlineBox->direction() == primaryDirection) {
1583 if (caretOffset == inlineBox->caretRightmostOffset()) {
1584 InlineBox* nextBox = inlineBox->nextLeafChild();
1585 if (!nextBox || nextBox->bidiLevel() >= level)
1586 return InlineBoxPosition(inlineBox, caretOffset);
1587
1588 level = nextBox->bidiLevel();
1589 InlineBox* prevBox = inlineBox;
1590 do {
1591 prevBox = prevBox->prevLeafChild();
1592 } while (prevBox && prevBox->bidiLevel() > level);
1593
1594 // For example, abc FED 123 ^ CBA
1595 if (prevBox && prevBox->bidiLevel() == level)
1596 return InlineBoxPosition(inlineBox, caretOffset);
1597
1598 // For example, abc 123 ^ CBA
1599 while (InlineBox* nextBox = inlineBox->nextLeafChild()) {
1600 if (nextBox->bidiLevel() < level)
1601 break;
1602 inlineBox = nextBox;
1603 }
1604 return InlineBoxPosition(inlineBox, inlineBox->caretRightmostOffset( ));
1605 }
1606
1607 InlineBox* prevBox = inlineBox->prevLeafChild();
1608 if (!prevBox || prevBox->bidiLevel() >= level)
1609 return InlineBoxPosition(inlineBox, caretOffset);
1610
1611 level = prevBox->bidiLevel();
1612 InlineBox* nextBox = inlineBox;
1613 do {
1614 nextBox = nextBox->nextLeafChild();
1615 } while (nextBox && nextBox->bidiLevel() > level);
1616
1617 if (nextBox && nextBox->bidiLevel() == level)
1618 return InlineBoxPosition(inlineBox, caretOffset);
1619
1620 while (InlineBox* prevBox = inlineBox->prevLeafChild()) {
1621 if (prevBox->bidiLevel() < level)
1622 break;
1623 inlineBox = prevBox;
1624 }
1625 return InlineBoxPosition(inlineBox, inlineBox->caretLeftmostOffset());
1626 }
1627
1628 if (caretOffset == inlineBox->caretLeftmostOffset()) {
1629 InlineBox* prevBox = inlineBox->prevLeafChildIgnoringLineBreak();
1630 if (!prevBox || prevBox->bidiLevel() < level) {
1631 // Left edge of a secondary run. Set to the right edge of the entire
1632 // run.
1633 while (InlineBox* nextBox = inlineBox->nextLeafChildIgnoringLineBrea k()) {
1634 if (nextBox->bidiLevel() < level)
1635 break;
1636 inlineBox = nextBox;
1637 }
1638 return InlineBoxPosition(inlineBox, inlineBox->caretRightmostOffset( ));
1639 }
1640
1641 if (prevBox->bidiLevel() > level) {
1642 // Right edge of a "tertiary" run. Set to the left edge of that run.
1643 while (InlineBox* tertiaryBox = inlineBox->prevLeafChildIgnoringLine Break()) {
1644 if (tertiaryBox->bidiLevel() <= level)
1645 break;
1646 inlineBox = tertiaryBox;
1647 }
1648 return InlineBoxPosition(inlineBox, inlineBox->caretLeftmostOffset() );
1649 }
1650 return InlineBoxPosition(inlineBox, caretOffset);
1651 }
1652
1653 if (layoutObject && layoutObject->style()->unicodeBidi() == Plaintext) {
1654 if (inlineBox->bidiLevel() < level)
1655 return InlineBoxPosition(inlineBox, inlineBox->caretLeftmostOffset() );
1656 return InlineBoxPosition(inlineBox, inlineBox->caretRightmostOffset());
1657 }
1658
1659 InlineBox* nextBox = inlineBox->nextLeafChildIgnoringLineBreak();
1660 if (!nextBox || nextBox->bidiLevel() < level) {
1661 // Right edge of a secondary run. Set to the left edge of the entire
1662 // run.
1663 while (InlineBox* prevBox = inlineBox->prevLeafChildIgnoringLineBreak()) {
1664 if (prevBox->bidiLevel() < level)
1665 break;
1666 inlineBox = prevBox;
1667 }
1668 return InlineBoxPosition(inlineBox, inlineBox->caretLeftmostOffset());
1669 }
1670
1671 if (nextBox->bidiLevel() <= level)
1672 return InlineBoxPosition(inlineBox, caretOffset);
1673
1674 // Left edge of a "tertiary" run. Set to the right edge of that run.
1675 while (InlineBox* tertiaryBox = inlineBox->nextLeafChildIgnoringLineBreak()) {
1676 if (tertiaryBox->bidiLevel() <= level)
1677 break;
1678 inlineBox = tertiaryBox;
1679 }
1680 return InlineBoxPosition(inlineBox, inlineBox->caretRightmostOffset());
1681 }
1682
1683 template <typename Strategy>
1684 static InlineBoxPosition computeInlineBoxPositionAlgorithm(const PositionAlgorit hm<Strategy>& position, TextAffinity affinity)
1685 {
1686 return computeInlineBoxPositionAlgorithm<Strategy>(position, affinity, prima ryDirectionOf(*position.anchorNode()));
1687 }
1688
1689 InlineBoxPosition computeInlineBoxPosition(const Position& position, TextAffinit y affinity)
1690 {
1691 return computeInlineBoxPositionAlgorithm<EditingStrategy>(position, affinity );
1692 }
1693
1694 InlineBoxPosition computeInlineBoxPosition(const PositionInComposedTree& positio n, TextAffinity affinity)
1695 {
1696 return computeInlineBoxPositionAlgorithm<EditingInComposedTreeStrategy>(posi tion, affinity);
1697 }
1698
1699 InlineBoxPosition computeInlineBoxPosition(const VisiblePosition& position)
1700 {
1701 return computeInlineBoxPosition(position.deepEquivalent(), position.affinity ());
1702 }
1703
1704 InlineBoxPosition computeInlineBoxPosition(const Position& position, TextAffinit y affinity, TextDirection primaryDirection)
1705 {
1706 return computeInlineBoxPositionAlgorithm<EditingStrategy>(position, affinity , primaryDirection);
1707 }
1708
1709 InlineBoxPosition computeInlineBoxPosition(const PositionInComposedTree& positio n, TextAffinity affinity, TextDirection primaryDirection)
1710 {
1711 return computeInlineBoxPositionAlgorithm<EditingInComposedTreeStrategy>(posi tion, affinity, primaryDirection);
1712 }
1713
1459 LayoutRect localCaretRectOfPosition(const PositionWithAffinity& position, Layout Object*& layoutObject) 1714 LayoutRect localCaretRectOfPosition(const PositionWithAffinity& position, Layout Object*& layoutObject)
1460 { 1715 {
1461 if (position.position().isNull()) { 1716 if (position.position().isNull()) {
1462 layoutObject = nullptr; 1717 layoutObject = nullptr;
1463 return LayoutRect(); 1718 return LayoutRect();
1464 } 1719 }
1465 Node* node = position.position().anchorNode(); 1720 Node* node = position.position().anchorNode();
1466 1721
1467 layoutObject = node->layoutObject(); 1722 layoutObject = node->layoutObject();
1468 if (!layoutObject) 1723 if (!layoutObject)
(...skipping 477 matching lines...) Expand 10 before | Expand all | Expand 10 after
1946 { 2201 {
1947 return mostBackwardCaretPosition<EditingStrategy>(position, rule); 2202 return mostBackwardCaretPosition<EditingStrategy>(position, rule);
1948 } 2203 }
1949 2204
1950 PositionInComposedTree mostBackwardCaretPosition(const PositionInComposedTree& p osition, EditingBoundaryCrossingRule rule) 2205 PositionInComposedTree mostBackwardCaretPosition(const PositionInComposedTree& p osition, EditingBoundaryCrossingRule rule)
1951 { 2206 {
1952 return mostBackwardCaretPosition<EditingInComposedTreeStrategy>(position, ru le); 2207 return mostBackwardCaretPosition<EditingInComposedTreeStrategy>(position, ru le);
1953 } 2208 }
1954 2209
1955 } 2210 }
OLDNEW
« no previous file with comments | « Source/core/editing/VisibleUnits.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698