示例#1
0
void SVGRootInlineBox::paint(PaintInfo& paintInfo, const LayoutPoint&, LayoutUnit, LayoutUnit)
{
    ASSERT(paintInfo.phase == PaintPhaseForeground || paintInfo.phase == PaintPhaseSelection);
    ASSERT(!paintInfo.context->paintingDisabled());

    bool isPrinting = renderSVGText().document().printing();
    bool hasSelection = !isPrinting && selectionState() != RenderObject::SelectionNone;

    PaintInfo childPaintInfo(paintInfo);
    if (hasSelection) {
        for (InlineBox* child = firstChild(); child; child = child->nextOnLine()) {
            if (child->isSVGInlineTextBox())
                toSVGInlineTextBox(child)->paintSelectionBackground(childPaintInfo);
            else if (child->isSVGInlineFlowBox())
                toSVGInlineFlowBox(child)->paintSelectionBackground(childPaintInfo);
        }
    }

    SVGRenderingContext renderingContext(renderSVGText(), paintInfo, SVGRenderingContext::SaveGraphicsContext);
    if (renderingContext.isRenderingPrepared()) {
        for (InlineBox* child = firstChild(); child; child = child->nextOnLine()) {
            if (child->isSVGInlineTextBox())
                SVGInlineFlowBox::computeTextMatchMarkerRectForRenderer(&toSVGInlineTextBox(child)->renderer());

            child->paint(paintInfo, LayoutPoint(), 0, 0);
        }
    }
}
示例#2
0
void SVGRootInlineBox::paint(PaintInfo& paintInfo, int, int)
{
    ASSERT(paintInfo.phase == PaintPhaseForeground || paintInfo.phase == PaintPhaseSelection);
    ASSERT(!paintInfo.context->paintingDisabled());

    RenderObject* boxRenderer = renderer();
    ASSERT(boxRenderer);

    bool isPrinting = renderer()->document()->printing();
    bool hasSelection = !isPrinting && selectionState() != RenderObject::SelectionNone;

    PaintInfo childPaintInfo(paintInfo);
    if (hasSelection) {
        for (InlineBox* child = firstChild(); child; child = child->nextOnLine()) {
            if (child->isSVGInlineTextBox())
                static_cast<SVGInlineTextBox*>(child)->paintSelectionBackground(childPaintInfo);
            else if (child->isSVGInlineFlowBox())
                static_cast<SVGInlineFlowBox*>(child)->paintSelectionBackground(childPaintInfo);
        }
    }

    childPaintInfo.context->save();

    if (SVGRenderSupport::prepareToRenderSVGContent(boxRenderer, childPaintInfo)) {
        for (InlineBox* child = firstChild(); child; child = child->nextOnLine()) {
            if (child->isSVGInlineTextBox())
                SVGInlineFlowBox::computeTextMatchMarkerRectForRenderer(toRenderSVGInlineText(static_cast<SVGInlineTextBox*>(child)->textRenderer()));

            child->paint(childPaintInfo, 0, 0);
        }
    }

    SVGRenderSupport::finishRenderSVGContent(boxRenderer, childPaintInfo, paintInfo.context);
    childPaintInfo.context->restore();
}
示例#3
0
void SVGRootInlineBox::layoutCharactersInTextBoxes(InlineFlowBox* start, SVGTextLayoutEngine& characterLayout)
{
    for (InlineBox* child = start->firstChild(); child; child = child->nextOnLine()) {
        if (child->isSVGInlineTextBox()) {
            ASSERT(child->renderer().isSVGInlineText());

            SVGInlineTextBox* textBox = toSVGInlineTextBox(child);
            characterLayout.layoutInlineTextBox(textBox);
        } else {
            // Skip generated content.
            Node* node = child->renderer().node();
            if (!node)
                continue;

            ASSERT_WITH_SECURITY_IMPLICATION(child->isInlineFlowBox());

            SVGInlineFlowBox* flowBox = toSVGInlineFlowBox(child);
            bool isTextPath = node->hasTagName(SVGNames::textPathTag);
            if (isTextPath) {
                // Build text chunks for all <textPath> children, using the line layout algorithm.
                // This is needeed as text-anchor is just an additional startOffset for text paths.
                SVGTextLayoutEngine lineLayout(characterLayout.layoutAttributes());
                layoutCharactersInTextBoxes(flowBox, lineLayout);

                characterLayout.beginTextPathLayout(&child->renderer(), lineLayout);
            }

            layoutCharactersInTextBoxes(flowBox, characterLayout);

            if (isTextPath)
                characterLayout.endTextPathLayout();
        }
    }
}
示例#4
0
void SVGRootInlineBox::layoutChildBoxes(InlineFlowBox* start, FloatRect* childRect)
{
    for (InlineBox* child = start->firstChild(); child; child = child->nextOnLine()) {
        FloatRect boxRect;
        if (child->isSVGInlineTextBox()) {
            ASSERT(child->renderer().isSVGInlineText());

            SVGInlineTextBox* textBox = toSVGInlineTextBox(child);
            boxRect = textBox->calculateBoundaries();
            textBox->setX(boxRect.x());
            textBox->setY(boxRect.y());
            textBox->setLogicalWidth(boxRect.width());
            textBox->setLogicalHeight(boxRect.height());
        } else {
            // Skip generated content.
            if (!child->renderer().node())
                continue;

            ASSERT_WITH_SECURITY_IMPLICATION(child->isInlineFlowBox());

            SVGInlineFlowBox* flowBox = toSVGInlineFlowBox(child);
            layoutChildBoxes(flowBox);

            boxRect = flowBox->calculateBoundaries();
            flowBox->setX(boxRect.x());
            flowBox->setY(boxRect.y());
            flowBox->setLogicalWidth(boxRect.width());
            flowBox->setLogicalHeight(boxRect.height());
        }
        if (childRect)
            childRect->unite(boxRect);
    }
}
示例#5
0
void SVGRootInlineBox::layoutChildBoxes(InlineFlowBox* start)
{
    for (InlineBox* child = start->firstChild(); child; child = child->nextOnLine()) {
        if (child->isSVGInlineTextBox()) {
            ASSERT(child->renderer());
            ASSERT(child->renderer()->isSVGInlineText());

            SVGInlineTextBox* textBox = static_cast<SVGInlineTextBox*>(child);
            IntRect boxRect = textBox->calculateBoundaries();
            textBox->setX(boxRect.x());
            textBox->setY(boxRect.y());
            textBox->setLogicalWidth(boxRect.width());
            textBox->setLogicalHeight(boxRect.height());
        } else {
            ASSERT(child->isInlineFlowBox());

            // Skip generated content.
            if (!child->renderer()->node())
                continue;

            SVGInlineFlowBox* flowBox = static_cast<SVGInlineFlowBox*>(child);
            layoutChildBoxes(flowBox);

            IntRect boxRect = flowBox->calculateBoundaries();
            flowBox->setX(boxRect.x());
            flowBox->setY(boxRect.y());
            flowBox->setLogicalWidth(boxRect.width());
            flowBox->setLogicalHeight(boxRect.height());
        }
    }
}
void SVGTextLayoutEngine::layoutCharactersInTextBoxes(InlineFlowBox* start)
{
    bool textLengthSpacingInEffect = m_textLengthSpacingInEffect || definesTextLengthWithSpacing(start);
    TemporaryChange<bool> textLengthSpacingScope(m_textLengthSpacingInEffect, textLengthSpacingInEffect);

    for (InlineBox* child = start->firstChild(); child; child = child->nextOnLine()) {
        if (child->isSVGInlineTextBox()) {
            ASSERT(child->layoutObject().isSVGInlineText());
            layoutInlineTextBox(toSVGInlineTextBox(child));
        } else {
            // Skip generated content.
            Node* node = child->layoutObject().node();
            if (!node)
                continue;

            SVGInlineFlowBox* flowBox = toSVGInlineFlowBox(child);
            bool isTextPath = isSVGTextPathElement(*node);
            if (isTextPath)
                beginTextPathLayout(flowBox);

            layoutCharactersInTextBoxes(flowBox);

            if (isTextPath)
                endTextPathLayout();
        }
    }
}
void SVGRootInlineBoxPainter::paint(const PaintInfo& paintInfo, const LayoutPoint& paintOffset)
{
    ASSERT(paintInfo.phase == PaintPhaseForeground || paintInfo.phase == PaintPhaseSelection);

    bool hasSelection = !paintInfo.isPrinting() && m_svgRootInlineBox.selectionState() != SelectionNone;

    PaintInfo paintInfoBeforeFiltering(paintInfo);
    if (hasSelection && !LayoutObjectDrawingRecorder::useCachedDrawingIfPossible(*paintInfoBeforeFiltering.context, m_svgRootInlineBox.layoutObject(),
        paintInfoBeforeFiltering.phase, paintOffset)) {
        LayoutObjectDrawingRecorder recorder(*paintInfoBeforeFiltering.context, m_svgRootInlineBox.layoutObject(), paintInfoBeforeFiltering.phase,
            paintInfoBeforeFiltering.cullRect().m_rect, paintOffset);
        for (InlineBox* child = m_svgRootInlineBox.firstChild(); child; child = child->nextOnLine()) {
            if (child->isSVGInlineTextBox())
                SVGInlineTextBoxPainter(*toSVGInlineTextBox(child)).paintSelectionBackground(paintInfoBeforeFiltering);
            else if (child->isSVGInlineFlowBox())
                SVGInlineFlowBoxPainter(*toSVGInlineFlowBox(child)).paintSelectionBackground(paintInfoBeforeFiltering);
        }
    }

    SVGPaintContext paintContext(m_svgRootInlineBox.layoutObject(), paintInfoBeforeFiltering);
    if (paintContext.applyClipMaskAndFilterIfNecessary()) {
        for (InlineBox* child = m_svgRootInlineBox.firstChild(); child; child = child->nextOnLine())
            child->paint(paintContext.paintInfo(), paintOffset, 0, 0);
    }
}
示例#8
0
LayoutRect SVGInlineFlowBox::calculateBoundaries() const
{
    LayoutRect childRect;
    for (InlineBox* child = firstChild(); child; child = child->nextOnLine()) {
        if (!child->isSVGInlineTextBox() && !child->isSVGInlineFlowBox())
            continue;
        childRect.unite(child->calculateBoundaries());
    }
    return childRect;
}
示例#9
0
bool SVGRootInlineBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, LayoutUnit lineTop, LayoutUnit lineBottom, HitTestAction hitTestAction)
{
    for (InlineBox* leaf = firstLeafChild(); leaf; leaf = leaf->nextLeafChild()) {
        if (!leaf->isSVGInlineTextBox())
            continue;
        if (leaf->nodeAtPoint(request, result, locationInContainer, accumulatedOffset, lineTop, lineBottom, hitTestAction))
            return true;
    }

    return false;
}
示例#10
0
void SVGInlineFlowBox::paintSelectionBackground(PaintInfo& paintInfo)
{
    ASSERT(paintInfo.phase == PaintPhaseForeground || paintInfo.phase == PaintPhaseSelection);

    PaintInfo childPaintInfo(paintInfo);
    for (InlineBox* child = firstChild(); child; child = child->nextOnLine()) {
        if (child->isSVGInlineTextBox())
            toSVGInlineTextBox(child)->paintSelectionBackground(childPaintInfo);
        else if (child->isSVGInlineFlowBox())
            toSVGInlineFlowBox(child)->paintSelectionBackground(childPaintInfo);
    }
}
void SVGInlineFlowBoxPainter::paintSelectionBackground(const PaintInfo& paintInfo)
{
    ASSERT(paintInfo.phase == PaintPhaseForeground || paintInfo.phase == PaintPhaseSelection);

    PaintInfo childPaintInfo(paintInfo);
    for (InlineBox* child = m_svgInlineFlowBox.firstChild(); child; child = child->nextOnLine()) {
        if (child->isSVGInlineTextBox())
            SVGInlineTextBoxPainter(*toSVGInlineTextBox(child)).paintSelectionBackground(childPaintInfo);
        else if (child->isSVGInlineFlowBox())
            SVGInlineFlowBoxPainter(*toSVGInlineFlowBox(child)).paintSelectionBackground(childPaintInfo);
    }
}
void SVGInlineFlowBox::paintSelectionBackground(PaintInfo& paintInfo)
{
    ASSERT(paintInfo.phase == PaintPhaseForeground || paintInfo.phase == PaintPhaseSelection);
    ASSERT(!paintInfo.context->paintingDisabled());

    PaintInfo childPaintInfo(paintInfo);
    for (InlineBox* child = firstChild(); child; child = child->nextOnLine()) {
        if (child->isSVGInlineTextBox())
            static_cast<SVGInlineTextBox*>(child)->paintSelectionBackground(childPaintInfo);
        else if (child->isSVGInlineFlowBox())
            static_cast<SVGInlineFlowBox*>(child)->paintSelectionBackground(childPaintInfo);
    }
}
示例#13
0
void SVGInlineFlowBox::paint(PaintInfo& paintInfo, const LayoutPoint&, LayoutUnit, LayoutUnit)
{
    ASSERT(paintInfo.phase == PaintPhaseForeground || paintInfo.phase == PaintPhaseSelection);
    ASSERT(!paintInfo.context->paintingDisabled());

    RenderObject* boxRenderer = renderer();
    ASSERT(boxRenderer);

    SVGRenderingContext renderingContext(boxRenderer, paintInfo, SVGRenderingContext::SaveGraphicsContext);
    if (renderingContext.isRenderingPrepared()) {
        for (InlineBox* child = firstChild(); child; child = child->nextOnLine()) {
            if (child->isSVGInlineTextBox())
                computeTextMatchMarkerRectForRenderer(toRenderSVGInlineText(static_cast<SVGInlineTextBox*>(child)->textRenderer()));

            child->paint(paintInfo, LayoutPoint(), 0, 0);
        }
    }
}
示例#14
0
static void collectTextBoxesInFlowBox(InlineFlowBox* flowBox, Vector<SVGInlineTextBox*>& textBoxes)
{
    if (!flowBox)
        return;

    for (InlineBox* child = flowBox->firstChild(); child; child = child->nextOnLine()) {
        if (child->isInlineFlowBox()) {
            // Skip generated content.
            if (!child->layoutObject().node())
                continue;

            collectTextBoxesInFlowBox(toInlineFlowBox(child), textBoxes);
            continue;
        }

        if (child->isSVGInlineTextBox())
            textBoxes.append(toSVGInlineTextBox(child));
    }
}
示例#15
0
void SVGTextQuery::collectTextBoxesInFlowBox(InlineFlowBox* flowBox)
{
    if (!flowBox)
        return;

    for (InlineBox* child = flowBox->firstChild(); child; child = child->nextOnLine()) {
        if (child->isInlineFlowBox()) {
            // Skip generated content.
            if (!child->renderer()->node())
                continue;

            collectTextBoxesInFlowBox(toInlineFlowBox(child));
            continue;
        }

        if (child->isSVGInlineTextBox())
            m_textBoxes.append(toSVGInlineTextBox(child));
    }
}
void SVGInlineFlowBox::paint(PaintInfo& paintInfo, const LayoutPoint&, LayoutUnit, LayoutUnit)
{
    ASSERT(paintInfo.phase == PaintPhaseForeground || paintInfo.phase == PaintPhaseSelection);
    ASSERT(!paintInfo.context->paintingDisabled());

    RenderObject* boxRenderer = renderer();
    ASSERT(boxRenderer);

    PaintInfo childPaintInfo(paintInfo);
    GraphicsContextStateSaver stateSaver(*childPaintInfo.context);

    if (SVGRenderSupport::prepareToRenderSVGContent(boxRenderer, childPaintInfo)) {
        for (InlineBox* child = firstChild(); child; child = child->nextOnLine()) {
            if (child->isSVGInlineTextBox())
                computeTextMatchMarkerRectForRenderer(toRenderSVGInlineText(static_cast<SVGInlineTextBox*>(child)->textRenderer()));

            child->paint(childPaintInfo, LayoutPoint(), 0, 0);
        }
    }

    SVGRenderSupport::finishRenderSVGContent(boxRenderer, childPaintInfo, paintInfo.context);
}
static void applyTextAnchorToTextChunk(SVGTextChunk& chunk)
{
    // This method is not called for chunks containing chars aligned on a path.
    // -> all characters are visible, no need to check for "isHidden()" anywhere.

    if (chunk.anchor == TA_START)
        return;

    float shift = calculateTextAnchorShiftForTextChunk(chunk, chunk.anchor);

    // Apply correction to chunk
    Vector<SVGChar>::iterator chunkIt = chunk.start;
    for (; chunkIt != chunk.end; ++chunkIt) {
        SVGChar& curChar = *chunkIt;

        if (chunk.isVerticalText)
            curChar.y += shift;
        else
            curChar.x += shift;
    }

    // Move inline boxes
    Vector<SVGInlineBoxCharacterRange>::iterator boxIt = chunk.boxes.begin();
    Vector<SVGInlineBoxCharacterRange>::iterator boxEnd = chunk.boxes.end();

    for (; boxIt != boxEnd; ++boxIt) {
        SVGInlineBoxCharacterRange& range = *boxIt;

        InlineBox* curBox = range.box;
        ASSERT(curBox->isSVGInlineTextBox());

        // Move target box
        if (chunk.isVerticalText)
            curBox->setY(curBox->y() + static_cast<int>(shift));
        else
            curBox->setX(curBox->x() + static_cast<int>(shift));
    }
}
示例#18
0
InlineBox* SVGRootInlineBox::closestLeafChildForPosition(const LayoutPoint& point)
{
    InlineBox* firstLeaf = firstLeafChild();
    InlineBox* lastLeaf = lastLeafChild();
    if (firstLeaf == lastLeaf)
        return firstLeaf;

    // FIXME: Check for vertical text!
    InlineBox* closestLeaf = 0;
    for (InlineBox* leaf = firstLeaf; leaf; leaf = leaf->nextLeafChild()) {
        if (!leaf->isSVGInlineTextBox())
            continue;
        if (point.y() < leaf->y())
            continue;
        if (point.y() > leaf->y() + leaf->virtualLogicalHeight())
            continue;

        closestLeaf = leaf;
        if (point.x() < leaf->left() + leaf->logicalWidth())
            return leaf;
    }

    return closestLeaf ? closestLeaf : lastLeaf;
}