static bool lineDirectionPointFitsInBox(int pointLineDirection, const InlineTextBox& box, ShouldAffinityBeDownstream& shouldAffinityBeDownstream) { shouldAffinityBeDownstream = AlwaysDownstream; // the x coordinate is equal to the left edge of this box // the affinity must be downstream so the position doesn't jump back to the previous line // except when box is the first box in the line if (pointLineDirection <= box.logicalLeft()) { shouldAffinityBeDownstream = !box.prevLeafChild() ? UpstreamIfPositionIsNotAtStart : AlwaysDownstream; return true; } #if !PLATFORM(IOS) // and the x coordinate is to the left of the right edge of this box // check to see if position goes in this box if (pointLineDirection < box.logicalRight()) { shouldAffinityBeDownstream = UpstreamIfPositionIsNotAtStart; return true; } #endif // box is first on line // and the x coordinate is to the left of the first text box left edge if (!box.prevLeafChildIgnoringLineBreak() && pointLineDirection < box.logicalLeft()) return true; if (!box.nextLeafChildIgnoringLineBreak()) { // box is last on line // and the x coordinate is to the right of the last text box right edge // generate VisiblePosition, use UPSTREAM affinity if possible shouldAffinityBeDownstream = UpstreamIfPositionIsNotAtStart; return true; } return false; }
static VisiblePosition createVisiblePositionAfterAdjustingOffsetForBiDi(const InlineTextBox& box, int offset, ShouldAffinityBeDownstream shouldAffinityBeDownstream) { ASSERT(offset >= 0); if (offset && static_cast<unsigned>(offset) < box.len()) return createVisiblePositionForBox(box, box.start() + offset, shouldAffinityBeDownstream); bool positionIsAtStartOfBox = !offset; if (positionIsAtStartOfBox == box.isLeftToRightDirection()) { // offset is on the left edge const InlineBox* prevBox = box.prevLeafChildIgnoringLineBreak(); if ((prevBox && prevBox->bidiLevel() == box.bidiLevel()) || box.renderer().containingBlock()->style().direction() == box.direction()) // FIXME: left on 12CBA return createVisiblePositionForBox(box, box.caretLeftmostOffset(), shouldAffinityBeDownstream); if (prevBox && prevBox->bidiLevel() > box.bidiLevel()) { // e.g. left of B in aDC12BAb const InlineBox* leftmostBox; do { leftmostBox = prevBox; prevBox = leftmostBox->prevLeafChildIgnoringLineBreak(); } while (prevBox && prevBox->bidiLevel() > box.bidiLevel()); return createVisiblePositionForBox(*leftmostBox, leftmostBox->caretRightmostOffset(), shouldAffinityBeDownstream); } if (!prevBox || prevBox->bidiLevel() < box.bidiLevel()) { // e.g. left of D in aDC12BAb const InlineBox* rightmostBox; const InlineBox* nextBox = &box; do { rightmostBox = nextBox; nextBox = rightmostBox->nextLeafChildIgnoringLineBreak(); } while (nextBox && nextBox->bidiLevel() >= box.bidiLevel()); return createVisiblePositionForBox(*rightmostBox, box.isLeftToRightDirection() ? rightmostBox->caretMaxOffset() : rightmostBox->caretMinOffset(), shouldAffinityBeDownstream); } return createVisiblePositionForBox(box, box.caretRightmostOffset(), shouldAffinityBeDownstream); } const InlineBox* nextBox = box.nextLeafChildIgnoringLineBreak(); if ((nextBox && nextBox->bidiLevel() == box.bidiLevel()) || box.renderer().containingBlock()->style().direction() == box.direction()) return createVisiblePositionForBox(box, box.caretRightmostOffset(), shouldAffinityBeDownstream); // offset is on the right edge if (nextBox && nextBox->bidiLevel() > box.bidiLevel()) { // e.g. right of C in aDC12BAb const InlineBox* rightmostBox; do { rightmostBox = nextBox; nextBox = rightmostBox->nextLeafChildIgnoringLineBreak(); } while (nextBox && nextBox->bidiLevel() > box.bidiLevel()); return createVisiblePositionForBox(*rightmostBox, rightmostBox->caretLeftmostOffset(), shouldAffinityBeDownstream); } if (!nextBox || nextBox->bidiLevel() < box.bidiLevel()) { // e.g. right of A in aDC12BAb const InlineBox* leftmostBox; const InlineBox* prevBox = &box; do { leftmostBox = prevBox; prevBox = leftmostBox->prevLeafChildIgnoringLineBreak(); } while (prevBox && prevBox->bidiLevel() >= box.bidiLevel()); return createVisiblePositionForBox(*leftmostBox, box.isLeftToRightDirection() ? leftmostBox->caretMinOffset() : leftmostBox->caretMaxOffset(), shouldAffinityBeDownstream); } return createVisiblePositionForBox(box, box.caretLeftmostOffset(), shouldAffinityBeDownstream); }