예제 #1
0
Position RenderedPosition::positionAtLeftBoundaryOfBiDiRun() const
{
    ASSERT(atLeftBoundaryOfBidiRun());

    if (atLeftmostOffsetInBox())
        return createLegacyEditingPosition(m_renderer->node(), m_offset);

    return createLegacyEditingPosition(nextLeafChild()->renderer().node(), nextLeafChild()->caretLeftmostOffset());
}
예제 #2
0
Position RenderedPosition::positionAtLeftBoundaryOfBiDiRun() const
{
    ASSERT(atLeftBoundaryOfBidiRun());

    if (atLeftmostOffsetInBox())
        return Position::editingPositionOf(m_layoutObject->node(), m_offset);

    return Position::editingPositionOf(nextLeafChild()->layoutObject().node(), nextLeafChild()->caretLeftmostOffset());
}
예제 #3
0
InlineBox* InlineBox::nextLeafChildIgnoringLineBreak() const
{
    InlineBox* leaf = nextLeafChild();
    if (leaf && leaf->isLineBreak())
        return 0;
    return leaf;
}
예제 #4
0
VisiblePosition RenderTextLineBoxes::positionForPoint(const RenderText& renderer, const LayoutPoint& point) const
{
    if (!m_first || !renderer.textLength())
        return renderer.createVisiblePosition(0, DOWNSTREAM);

    LayoutUnit pointLineDirection = m_first->isHorizontal() ? point.x() : point.y();
    LayoutUnit pointBlockDirection = m_first->isHorizontal() ? point.y() : point.x();
    bool blocksAreFlipped = renderer.style().isFlippedBlocksWritingMode();

    InlineTextBox* lastBox = nullptr;
    for (auto box = m_first; box; box = box->nextTextBox()) {
        if (box->isLineBreak() && !box->prevLeafChild() && box->nextLeafChild() && !box->nextLeafChild()->isLineBreak())
            box = box->nextTextBox();

        auto& rootBox = box->root();
        LayoutUnit top = std::min(rootBox.selectionTop(), rootBox.lineTop());
        if (pointBlockDirection > top || (!blocksAreFlipped && pointBlockDirection == top)) {
            LayoutUnit bottom = rootBox.selectionBottom();
            if (rootBox.nextRootBox())
                bottom = std::min(bottom, rootBox.nextRootBox()->lineTop());

            if (pointBlockDirection < bottom || (blocksAreFlipped && pointBlockDirection == bottom)) {
                ShouldAffinityBeDownstream shouldAffinityBeDownstream;
#if PLATFORM(IOS)
                if (pointLineDirection != box->logicalLeft() && point.x() < box->x() + box->logicalWidth()) {
                    int half = box->x() + box->logicalWidth() / 2;
                    EAffinity affinity = point.x() < half ? DOWNSTREAM : VP_UPSTREAM_IF_POSSIBLE;
                    return renderer.createVisiblePosition(box->offsetForPosition(pointLineDirection) + box->start(), affinity);
                }
#endif
                if (lineDirectionPointFitsInBox(pointLineDirection, *box, shouldAffinityBeDownstream))
                    return createVisiblePositionAfterAdjustingOffsetForBiDi(*box, box->offsetForPosition(pointLineDirection), shouldAffinityBeDownstream);
            }
        }
        lastBox = box;
    }

    if (lastBox) {
        ShouldAffinityBeDownstream shouldAffinityBeDownstream;
        lineDirectionPointFitsInBox(pointLineDirection, *lastBox, shouldAffinityBeDownstream);
        return createVisiblePositionAfterAdjustingOffsetForBiDi(*lastBox, lastBox->offsetForPosition(pointLineDirection) + lastBox->start(), shouldAffinityBeDownstream);
    }
    return renderer.createVisiblePosition(0, DOWNSTREAM);
}
예제 #5
0
bool RenderedPosition::atRightBoundaryOfBidiRun(ShouldMatchBidiLevel shouldMatchBidiLevel, unsigned char bidiLevelOfRun) const
{
    if (!m_inlineBox)
        return false;

    if (atRightmostOffsetInBox()) {
        if (shouldMatchBidiLevel == IgnoreBidiLevel)
            return !nextLeafChild() || nextLeafChild()->bidiLevel() < m_inlineBox->bidiLevel();
        return m_inlineBox->bidiLevel() >= bidiLevelOfRun && (!nextLeafChild() || nextLeafChild()->bidiLevel() < bidiLevelOfRun);
    }

    if (atLeftmostOffsetInBox()) {
        if (shouldMatchBidiLevel == IgnoreBidiLevel)
            return prevLeafChild() && m_inlineBox->bidiLevel() < prevLeafChild()->bidiLevel();
        return prevLeafChild() && m_inlineBox->bidiLevel() < bidiLevelOfRun && prevLeafChild()->bidiLevel() >= bidiLevelOfRun;
    }

    return false;
}
예제 #6
0
unsigned char RenderedPosition::bidiLevelOnRight() const
{
    InlineBox* box = atRightmostOffsetInBox() ? nextLeafChild() : m_inlineBox;
    return box ? box->bidiLevel() : 0;
}
예제 #7
0
bool RenderedPosition::isEquivalent(const RenderedPosition& other) const
{
    return (m_layoutObject == other.m_layoutObject && m_inlineBox == other.m_inlineBox && m_offset == other.m_offset)
        || (atLeftmostOffsetInBox() && other.atRightmostOffsetInBox() && prevLeafChild() == other.m_inlineBox)
        || (atRightmostOffsetInBox() && other.atLeftmostOffsetInBox() && nextLeafChild() == other.m_inlineBox);
}
예제 #8
0
InlineBox* InlineBox::nextLeafChildIgnoringLineBreak() const
{
    InlineBox* leaf = nextLeafChild();
    return (leaf && leaf->isLineBreak()) ? nullptr : leaf;
}