IntRect Editor::firstRectForRange(Range* range) const { LayoutUnit extraWidthToEndOfLine = 0; ASSERT(range->startContainer()); ASSERT(range->endContainer()); IntRect startCaretRect = RenderedPosition(VisiblePosition(range->startPosition()).deepEquivalent(), DOWNSTREAM).absoluteRect(&extraWidthToEndOfLine); if (startCaretRect == LayoutRect()) return IntRect(); IntRect endCaretRect = RenderedPosition(VisiblePosition(range->endPosition()).deepEquivalent(), UPSTREAM).absoluteRect(); if (endCaretRect == LayoutRect()) return IntRect(); if (startCaretRect.y() == endCaretRect.y()) { // start and end are on the same line return IntRect(std::min(startCaretRect.x(), endCaretRect.x()), startCaretRect.y(), abs(endCaretRect.x() - startCaretRect.x()), std::max(startCaretRect.height(), endCaretRect.height())); } // start and end aren't on the same line, so go from start to the end of its line return IntRect(startCaretRect.x(), startCaretRect.y(), startCaretRect.width() + extraWidthToEndOfLine, startCaretRect.height()); }
RenderedPosition RenderedPosition::rightBoundaryOfBidiRun(unsigned char bidiLevelOfRun) { if (!m_inlineBox || bidiLevelOfRun > m_inlineBox->bidiLevel()) return RenderedPosition(); InlineBox* box = m_inlineBox; do { InlineBox* next = box->nextLeafChildIgnoringLineBreak(); if (!next || next->bidiLevel() < bidiLevelOfRun) return RenderedPosition(&box->layoutObject(), box, box->caretRightmostOffset()); box = next; } while (box); ASSERT_NOT_REACHED(); return RenderedPosition(); }
RenderedPosition RenderedPosition::leftBoundaryOfBidiRun(unsigned char bidiLevelOfRun) { if (!m_inlineBox || bidiLevelOfRun > m_inlineBox->bidiLevel()) return RenderedPosition(); InlineBox* box = m_inlineBox; do { InlineBox* prev = box->prevLeafChildIgnoringLineBreak(); if (!prev || prev->bidiLevel() < bidiLevelOfRun) return RenderedPosition(&box->layoutObject(), box, box->caretLeftmostOffset()); box = prev; } while (box); ASSERT_NOT_REACHED(); return RenderedPosition(); }