void SVGInlineTextBox::paintTextMatchMarker(GraphicsContext* context, const FloatPoint&, DocumentMarker* marker, RenderStyle* style, const Font& font)
{
    // SVG is only interested in the TextMatch markers.
    if (marker->type() != DocumentMarker::TextMatch)
        return;

    RenderSVGInlineText* textRenderer = toRenderSVGInlineText(this->textRenderer());
    ASSERT(textRenderer);

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

        SVGInlineTextBox* textBox = toSVGInlineTextBox(box);

        int markerStartPosition = max<int>(marker->startOffset() - textBox->start(), 0);
        int markerEndPosition = min<int>(marker->endOffset() - textBox->start(), textBox->len());

        if (markerStartPosition >= markerEndPosition)
            continue;

        const Vector<SVGTextFragment>& fragments = textBox->textFragments();
        unsigned textFragmentsSize = fragments.size();
        for (unsigned i = 0; i < textFragmentsSize; ++i) {
            const SVGTextFragment& fragment = fragments.at(i);

            int fragmentStartPosition = markerStartPosition;
            int fragmentEndPosition = markerEndPosition;
            if (!textBox->mapStartEndPositionsIntoFragmentCoordinates(fragment, fragmentStartPosition, fragmentEndPosition))
                continue;

            FloatRect fragmentRect = textBox->selectionRectForTextFragment(fragment, fragmentStartPosition, fragmentEndPosition, style);
            fragment.buildFragmentTransform(fragmentTransform);
            bool fragmentTransformIsIdentity = fragmentTransform.isIdentity();

            // Draw the marker highlight.
            if (renderer()->frame()->editor().markedTextMatchesAreHighlighted()) {
                Color color = marker->activeMatch() ?
                    RenderTheme::theme().platformActiveTextSearchHighlightColor() :
                    RenderTheme::theme().platformInactiveTextSearchHighlightColor();
                GraphicsContextStateSaver stateSaver(*context);
                if (!fragmentTransformIsIdentity)
                    context->concatCTM(fragmentTransform);
                context->setFillColor(color);
                context->fillRect(fragmentRect, color);
            }

            if (!fragmentTransformIsIdentity)
                fragmentRect = fragmentTransform.mapRect(fragmentRect);
            markerRect.unite(fragmentRect);
        }
    }

    toRenderedDocumentMarker(marker)->setRenderedRect(textRenderer->localToAbsoluteQuad(markerRect).enclosingBoundingBox());
}
Ejemplo n.º 2
0
void SVGInlineFlowBox::computeTextMatchMarkerRectForRenderer(RenderSVGInlineText* textRenderer)
{
    ASSERT(textRenderer);

    Node* node = textRenderer->node();
    if (!node || !node->inDocument())
        return;

    RenderStyle* style = textRenderer->style();
    ASSERT(style);

    Document* document = textRenderer->document();
    Vector<DocumentMarker> markers = document->markers()->markersForNode(textRenderer->node());

    Vector<DocumentMarker>::iterator markerEnd = markers.end();
    for (Vector<DocumentMarker>::iterator markerIt = markers.begin(); markerIt != markerEnd; ++markerIt) {
        const DocumentMarker& marker = *markerIt;

        // SVG is only interessted in the TextMatch marker, for now.
        if (marker.type != DocumentMarker::TextMatch)
            continue;

        FloatRect markerRect;
        for (InlineTextBox* box = textRenderer->firstTextBox(); box; box = box->nextTextBox()) {
            ASSERT(box->isSVGInlineTextBox());
            SVGInlineTextBox* textBox = static_cast<SVGInlineTextBox*>(box);

            int markerStartPosition = max<int>(marker.startOffset - textBox->start(), 0);
            int markerEndPosition = min<int>(marker.endOffset - textBox->start(), textBox->len());

            if (markerStartPosition >= markerEndPosition)
                continue;

            int fragmentStartPosition = 0;
            int fragmentEndPosition = 0;

            const Vector<SVGTextFragment>& fragments = textBox->textFragments();
            unsigned textFragmentsSize = fragments.size();
            for (unsigned i = 0; i < textFragmentsSize; ++i) {
                const SVGTextFragment& fragment = fragments.at(i);

                fragmentStartPosition = markerStartPosition;
                fragmentEndPosition = markerEndPosition;
                if (!textBox->mapStartEndPositionsIntoFragmentCoordinates(fragment, fragmentStartPosition, fragmentEndPosition))
                    continue;

                FloatRect fragmentRect = textBox->selectionRectForTextFragment(fragment, fragmentStartPosition, fragmentEndPosition, style);
                if (!fragment.transform.isIdentity())
                    fragmentRect = fragment.transform.mapRect(fragmentRect);

                markerRect.unite(fragmentRect);
            }
        }

        document->markers()->setRenderedRectForMarker(node, marker, textRenderer->localToAbsoluteQuad(markerRect).enclosingBoundingBox());
    }
}
Ejemplo n.º 3
0
static inline void reverseInlineBoxRangeAndValueListsIfNeeded(void* userData, Vector<InlineBox*>::iterator first, Vector<InlineBox*>::iterator last)
{
    ASSERT(userData);
    Vector<SVGTextLayoutAttributes*>& attributes = *reinterpret_cast<Vector<SVGTextLayoutAttributes*>*>(userData);

    // This is a copy of std::reverse(first, last). It additionally assures that the metrics map within the renderers belonging to the InlineBoxes are reordered as well.
    while (true)  {
        if (first == last || first == --last)
            return;

        if (!(*last)->isSVGInlineTextBox() || !(*first)->isSVGInlineTextBox()) {
            InlineBox* temp = *first;
            *first = *last;
            *last = temp;
            ++first;
            continue;
        }

        SVGInlineTextBox* firstTextBox = toSVGInlineTextBox(*first);
        SVGInlineTextBox* lastTextBox = toSVGInlineTextBox(*last);

        // Reordering is only necessary for BiDi text that is _absolutely_ positioned.
        if (firstTextBox->len() == 1 && firstTextBox->len() == lastTextBox->len()) {
            RenderSVGInlineText& firstContext = firstTextBox->renderer();
            RenderSVGInlineText& lastContext = lastTextBox->renderer();

            SVGTextLayoutAttributes* firstAttributes = 0;
            SVGTextLayoutAttributes* lastAttributes = 0;
            findFirstAndLastAttributesInVector(attributes, &firstContext, &lastContext, firstAttributes, lastAttributes);
            swapItemsInLayoutAttributes(firstAttributes, lastAttributes, firstTextBox->start(), lastTextBox->start());
        }

        InlineBox* temp = *first;
        *first = *last;
        *last = temp;

        ++first;
    }
}
Ejemplo n.º 4
0
static inline void dumpTextBoxes(Vector<SVGInlineTextBox*>& boxes)
{
    unsigned boxCount = boxes.size();
    fprintf(stderr, "Dumping all text fragments in text sub tree, %i boxes\n", boxCount);

    for (unsigned boxPosition = 0; boxPosition < boxCount; ++boxPosition) {
        SVGInlineTextBox* textBox = boxes.at(boxPosition);
        Vector<SVGTextFragment>& fragments = textBox->textFragments();
        fprintf(stderr, "-> Box %i: Dumping text fragments for SVGInlineTextBox, textBox=%p, textRenderer=%p\n", boxPosition, textBox, textBox->textRenderer());
        fprintf(stderr, "        textBox properties, start=%i, len=%i, box direction=%i\n", textBox->start(), textBox->len(), textBox->direction());
        fprintf(stderr, "   textRenderer properties, textLength=%i\n", textBox->textRenderer()->textLength());

        const UChar* characters = textBox->textRenderer()->characters();

        unsigned fragmentCount = fragments.size();
        for (unsigned i = 0; i < fragmentCount; ++i) {
            SVGTextFragment& fragment = fragments.at(i);
            String fragmentString(characters + fragment.characterOffset, fragment.length);
            fprintf(stderr, "    -> Fragment %i, x=%lf, y=%lf, width=%lf, height=%lf, characterOffset=%i, length=%i, characters='%s'\n"
                          , i, fragment.x, fragment.y, fragment.width, fragment.height, fragment.characterOffset, fragment.length, fragmentString.utf8().data());
        }
    }
}
void SVGInlineTextBoxPainter::paintTextMatchMarker(GraphicsContext* context, const LayoutPoint&, DocumentMarker* marker, const ComputedStyle& style, const Font& font)
{
    // SVG is only interested in the TextMatch markers.
    if (marker->type() != DocumentMarker::TextMatch)
        return;

    LayoutSVGInlineText& textLayoutObject = toLayoutSVGInlineText(m_svgInlineTextBox.layoutObject());

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

        SVGInlineTextBox* textBox = toSVGInlineTextBox(box);

        int markerStartPosition = std::max<int>(marker->startOffset() - textBox->start(), 0);
        int markerEndPosition = std::min<int>(marker->endOffset() - textBox->start(), textBox->len());

        if (markerStartPosition >= markerEndPosition)
            continue;

        const Vector<SVGTextFragment>& fragments = textBox->textFragments();
        unsigned textFragmentsSize = fragments.size();
        for (unsigned i = 0; i < textFragmentsSize; ++i) {
            const SVGTextFragment& fragment = fragments.at(i);

            int fragmentStartPosition = markerStartPosition;
            int fragmentEndPosition = markerEndPosition;
            if (!textBox->mapStartEndPositionsIntoFragmentCoordinates(fragment, fragmentStartPosition, fragmentEndPosition))
                continue;

            FloatRect fragmentRect = textBox->selectionRectForTextFragment(fragment, fragmentStartPosition, fragmentEndPosition, style);
            fragment.buildFragmentTransform(fragmentTransform);

            // Draw the marker highlight.
            if (m_svgInlineTextBox.layoutObject().frame()->editor().markedTextMatchesAreHighlighted()) {
                Color color = marker->activeMatch() ?
                    LayoutTheme::theme().platformActiveTextSearchHighlightColor() :
                    LayoutTheme::theme().platformInactiveTextSearchHighlightColor();
                GraphicsContextStateSaver stateSaver(*context);
                if (!fragmentTransform.isIdentity())
                    context->concatCTM(fragmentTransform);
                context->setFillColor(color);
                context->fillRect(fragmentRect, color);
            }
        }
    }
}