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); }