Example #1
0
PositionWithAffinity RenderReplaced::positionForPoint(const LayoutPoint& point)
{
    // FIXME: This code is buggy if the replaced element is relative positioned.
    InlineBox* box = inlineBoxWrapper();
    RootInlineBox* rootBox = box ? &box->root() : 0;

    LayoutUnit top = rootBox ? rootBox->selectionTop() : logicalTop();
    LayoutUnit bottom = rootBox ? rootBox->selectionBottom() : logicalBottom();

    LayoutUnit blockDirectionPosition = isHorizontalWritingMode() ? point.y() + y() : point.x() + x();
    LayoutUnit lineDirectionPosition = isHorizontalWritingMode() ? point.x() + x() : point.y() + y();

    if (blockDirectionPosition < top)
        return createPositionWithAffinity(caretMinOffset(), DOWNSTREAM); // coordinates are above

    if (blockDirectionPosition >= bottom)
        return createPositionWithAffinity(caretMaxOffset(), DOWNSTREAM); // coordinates are below

    if (node()) {
        if (lineDirectionPosition <= logicalLeft() + (logicalWidth() / 2))
            return createPositionWithAffinity(0, DOWNSTREAM);
        return createPositionWithAffinity(1, DOWNSTREAM);
    }

    return RenderBox::positionForPoint(point);
}
PositionWithAffinity LayoutSVGInlineText::positionForPoint(const LayoutPoint& point)
{
    if (!firstTextBox() || !textLength())
        return createPositionWithAffinity(0, DOWNSTREAM);

    ASSERT(m_scalingFactor);
    float baseline = m_scaledFont.fontMetrics().floatAscent() / m_scalingFactor;

    LayoutBlock* containingBlock = this->containingBlock();
    ASSERT(containingBlock);

    // Map local point to absolute point, as the character origins stored in the text fragments use absolute coordinates.
    FloatPoint absolutePoint(point);
    absolutePoint.moveBy(containingBlock->location());

    float closestDistance = std::numeric_limits<float>::max();
    float closestDistancePosition = 0;
    const SVGTextFragment* closestDistanceFragment = 0;
    SVGInlineTextBox* closestDistanceBox = 0;

    AffineTransform fragmentTransform;
    for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) {
        if (!box->isSVGInlineTextBox())
            continue;

        SVGInlineTextBox* textBox = toSVGInlineTextBox(box);
        Vector<SVGTextFragment>& fragments = textBox->textFragments();

        unsigned textFragmentsSize = fragments.size();
        for (unsigned i = 0; i < textFragmentsSize; ++i) {
            const SVGTextFragment& fragment = fragments.at(i);
            FloatRect fragmentRect(fragment.x, fragment.y - baseline, fragment.width, fragment.height);
            fragment.buildFragmentTransform(fragmentTransform);
            if (!fragmentTransform.isIdentity())
                fragmentRect = fragmentTransform.mapRect(fragmentRect);

            float distance = 0;
            if (!fragmentRect.contains(absolutePoint))
                distance = squaredDistanceToClosestPoint(fragmentRect, absolutePoint);

            if (distance <= closestDistance) {
                closestDistance = distance;
                closestDistanceBox = textBox;
                closestDistanceFragment = &fragment;
                closestDistancePosition = fragmentRect.x();
            }
        }
    }

    if (!closestDistanceFragment)
        return createPositionWithAffinity(0, DOWNSTREAM);

    int offset = closestDistanceBox->offsetForPositionInFragment(*closestDistanceFragment, absolutePoint.x() - closestDistancePosition, true);
    return createPositionWithAffinity(offset + closestDistanceBox->start(), offset > 0 ? VP_UPSTREAM_IF_POSSIBLE : DOWNSTREAM);
}
Example #3
0
PositionWithAffinity RenderSVGText::positionForPoint(const LayoutPoint& pointInContents)
{
    RootInlineBox* rootBox = firstRootBox();
    if (!rootBox)
        return createPositionWithAffinity(0, DOWNSTREAM);

    ASSERT(!rootBox->nextRootBox());
    ASSERT(childrenInline());

    InlineBox* closestBox = toSVGRootInlineBox(rootBox)->closestLeafChildForPosition(pointInContents);
    if (!closestBox)
        return createPositionWithAffinity(0, DOWNSTREAM);

    return closestBox->renderer().positionForPoint(LayoutPoint(pointInContents.x(), closestBox->y()));
}
PositionWithAffinity RenderSVGText::positionForPoint(const LayoutPoint& pointInContents)
{
    RootInlineBox* rootBox = firstRootBox();
    if (!rootBox)
        return createPositionWithAffinity(0, DOWNSTREAM);

    ASSERT_WITH_SECURITY_IMPLICATION(rootBox->isSVGRootInlineBox());
    ASSERT(!rootBox->nextRootBox());
    ASSERT(childrenInline());

    InlineBox* closestBox = static_cast<SVGRootInlineBox*>(rootBox)->closestLeafChildForPosition(pointInContents);
    if (!closestBox)
        return createPositionWithAffinity(0, DOWNSTREAM);

    return closestBox->renderer()->positionForPoint(LayoutPoint(pointInContents.x(), closestBox->y()));
}
Example #5
0
PositionWithAffinity LayoutSVGInlineText::positionForPoint(const LayoutPoint& point)
{
    if (!hasTextBoxes() || !textLength())
        return createPositionWithAffinity(0);

    ASSERT(m_scalingFactor);
    float baseline = m_scaledFont.getFontMetrics().floatAscent() / m_scalingFactor;

    LayoutBlock* containingBlock = this->containingBlock();
    ASSERT(containingBlock);

    // Map local point to absolute point, as the character origins stored in the text fragments use absolute coordinates.
    FloatPoint absolutePoint(point);
    absolutePoint.moveBy(containingBlock->location());

    float closestDistance = std::numeric_limits<float>::max();
    float closestDistancePosition = 0;
    const SVGTextFragment* closestDistanceFragment = nullptr;
    SVGInlineTextBox* closestDistanceBox = nullptr;

    for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) {
        if (!box->isSVGInlineTextBox())
            continue;

        SVGInlineTextBox* textBox = toSVGInlineTextBox(box);
        for (const SVGTextFragment& fragment : textBox->textFragments()) {
            FloatRect fragmentRect = fragment.boundingBox(baseline);

            float distance = 0;
            if (!fragmentRect.contains(absolutePoint))
                distance = fragmentRect.squaredDistanceTo(absolutePoint);

            if (distance <= closestDistance) {
                closestDistance = distance;
                closestDistanceBox = textBox;
                closestDistanceFragment = &fragment;
                closestDistancePosition = fragmentRect.x();
            }
        }
    }

    if (!closestDistanceFragment)
        return createPositionWithAffinity(0);

    int offset = closestDistanceBox->offsetForPositionInFragment(*closestDistanceFragment, LayoutUnit(absolutePoint.x() - closestDistancePosition), true);
    return createPositionWithAffinity(offset + closestDistanceBox->start(), offset > 0 ? VP_UPSTREAM_IF_POSSIBLE : TextAffinity::Downstream);
}
Example #6
0
PositionWithAffinity LayoutBR::positionForPoint(const LayoutPoint&)
{
    return createPositionWithAffinity(0);
}