Example #1
0
void QSvgTinyDocument::draw(QPainter *p, const QRectF &bounds)
{
    if (m_time.isNull()) {
        m_time.start();
    }

    if (m_viewBox.isNull()) {
        QMatrix matx = QMatrix();
        m_viewBox = transformedBounds(matx);
    }

    p->save();

    //sets default style on the painter
    //### not the most optimal way
    adjustWindowBounds(p, bounds, m_viewBox);
    p->setPen(Qt::NoPen);
    p->setBrush(Qt::black);
    p->setRenderHint(QPainter::Antialiasing);
    p->setRenderHint(QPainter::SmoothPixmapTransform);
    QList<QSvgNode*>::iterator itr = m_renderers.begin();
    applyStyle(p);
    while (itr != m_renderers.end()) {
        QSvgNode *node = *itr;
        if (node->isVisible())
            node->draw(p);
        ++itr;
    }
    revertStyle(p);
    p->restore();
}
Example #2
0
void QSvgPath::draw(QPainter *p, QSvgExtraStates &states)
{
    applyStyle(p, states);
    m_path.setFillRule(states.fillRule);
    QT_SVG_DRAW_SHAPE(p->drawPath(m_path));
    revertStyle(p, states);
}
Example #3
0
QRectF QSvgNode::transformedBounds(QPainter *p, QSvgExtraStates &states) const
{
    applyStyle(p, states);
    QRectF rect = bounds(p, states);
    revertStyle(p, states);
    return rect;
}
Example #4
0
void QSvgTinyDocument::draw(QPainter *p, const QRectF &bounds)
{
    if (m_time.isNull()) {
        m_time.start();
    }

    if (displayMode() == QSvgNode::NoneMode)
        return;

    p->save();
    //sets default style on the painter
    //### not the most optimal way
    mapSourceToTarget(p, bounds);
    QPen pen(Qt::NoBrush, 1, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
    pen.setMiterLimit(4);
    p->setPen(pen);
    p->setBrush(Qt::black);
    p->setRenderHint(QPainter::Antialiasing);
    p->setRenderHint(QPainter::SmoothPixmapTransform);
    QList<QSvgNode*>::iterator itr = m_renderers.begin();
    applyStyle(p, m_states);
    while (itr != m_renderers.end()) {
        QSvgNode *node = *itr;
        if ((node->isVisible()) && (node->displayMode() != QSvgNode::NoneMode))
            node->draw(p, m_states);
        ++itr;
    }
    revertStyle(p, m_states);
    p->restore();
}
Example #5
0
void QSvgRect::draw(QPainter *p, QSvgExtraStates &states)
{
    applyStyle(p, states);
    if (m_rx || m_ry) {
        QT_SVG_DRAW_SHAPE(p->drawRoundedRect(m_rect, m_rx, m_ry, Qt::RelativeSize));
    } else {
        QT_SVG_DRAW_SHAPE(p->drawRect(m_rect));
    }
    revertStyle(p, states);
}
Example #6
0
void QSvgLine::draw(QPainter *p, QSvgExtraStates &states)
{
    applyStyle(p, states);
    if (p->pen().widthF() != 0) {
        qreal oldOpacity = p->opacity();
        p->setOpacity(oldOpacity * states.strokeOpacity);
        p->drawLine(m_line);
        p->setOpacity(oldOpacity);
    }
    revertStyle(p, states);
}
Example #7
0
void QSvgPolyline::draw(QPainter *p, QSvgExtraStates &states)
{
    applyStyle(p, states);
    if (p->brush().style() != Qt::NoBrush) {
        QPen save = p->pen();
        p->setPen(QPen(Qt::NoPen));
        p->drawPolygon(m_poly);
        p->setPen(save);
    }
    p->drawPolyline(m_poly);
    revertStyle(p, states);
}
Example #8
0
void QSvgG::draw(QPainter *p, QSvgExtraStates &states)
{
    QList<QSvgNode*>::iterator itr = m_renderers.begin();
    applyStyle(p, states);

    while (itr != m_renderers.end()) {
        QSvgNode *node = *itr;
        if ((node->isVisible()) && (node->displayMode() != QSvgNode::NoneMode))
            node->draw(p, states);
        ++itr;
    }
    revertStyle(p, states);
}
Example #9
0
void QSvgUse::draw(QPainter *p, QSvgExtraStates &states)
{
    applyStyle(p, states);

    if (!m_start.isNull()) {
        p->translate(m_start);
    }
    m_link->draw(p, states);
    if (!m_start.isNull()) {
        p->translate(-m_start);
    }

    revertStyle(p, states);
}
Example #10
0
void QSvgPolyline::draw(QPainter *p, QSvgExtraStates &states)
{
    applyStyle(p, states);
    qreal oldOpacity = p->opacity();
    if (p->brush().style() != Qt::NoBrush) {
        QPen save = p->pen();
        p->setPen(QPen(Qt::NoPen));
        p->setOpacity(oldOpacity * states.fillOpacity);
        p->drawPolygon(m_poly, states.fillRule);
        p->setPen(save);
    }
    if (p->pen().widthF() != 0) {
        p->setOpacity(oldOpacity * states.strokeOpacity);
        p->drawPolyline(m_poly);
    }
    p->setOpacity(oldOpacity);
    revertStyle(p, states);
}
Example #11
0
void QSvgEllipse::draw(QPainter *p, QSvgExtraStates &states)
{
    applyStyle(p, states);
    QT_SVG_DRAW_SHAPE(p->drawEllipse(m_bounds));
    revertStyle(p, states);
}
Example #12
0
void QSvgText::draw(QPainter *p, QSvgExtraStates &states)
{
    applyStyle(p, states);
    qreal oldOpacity = p->opacity();
    p->setOpacity(oldOpacity * states.fillOpacity);

    // Force the font to have a size of 100 pixels to avoid truncation problems
    // when the font is very small.
    qreal scale = 100.0 / p->font().pointSizeF();
    Qt::Alignment alignment = states.textAnchor;

    QTransform oldTransform = p->worldTransform();
    p->scale(1 / scale, 1 / scale);

    qreal y = 0;
    bool initial = true;
    qreal px = m_coord.x() * scale;
    qreal py = m_coord.y() * scale;
    QSizeF scaledSize = m_size * scale;

    if (m_type == TEXTAREA) {
        if (alignment == Qt::AlignHCenter)
            px += scaledSize.width() / 2;
        else if (alignment == Qt::AlignRight)
            px += scaledSize.width();
    }

    QRectF bounds;
    if (m_size.height() != 0)
        bounds = QRectF(0, py, 1, scaledSize.height()); // x and width are not used.

    bool appendSpace = false;
    QVector<QString> paragraphs;
    QStack<QTextCharFormat> formats;
    QVector<QList<QTextLayout::FormatRange> > formatRanges;
    paragraphs.push_back(QString());
    formatRanges.push_back(QList<QTextLayout::FormatRange>());

    for (int i = 0; i < m_tspans.size(); ++i) {
        if (m_tspans[i] == LINEBREAK) {
            if (m_type == TEXTAREA) {
                if (paragraphs.back().isEmpty()) {
                    QFont font = p->font();
                    font.setPixelSize(font.pointSizeF() * scale);

                    QTextLayout::FormatRange range;
                    range.start = 0;
                    range.length = 1;
                    range.format.setFont(font);
                    formatRanges.back().append(range);

                    paragraphs.back().append(QLatin1Char(' '));;
                }
                appendSpace = false;
                paragraphs.push_back(QString());
                formatRanges.push_back(QList<QTextLayout::FormatRange>());
            }
        } else {
            WhitespaceMode mode = m_tspans[i]->whitespaceMode();
            m_tspans[i]->applyStyle(p, states);

            QFont font = p->font();
            font.setPixelSize(font.pointSizeF() * scale);

            QString newText(m_tspans[i]->text());
            newText.replace(QLatin1Char('\t'), QLatin1Char(' '));
            newText.replace(QLatin1Char('\n'), QLatin1Char(' '));

            bool prependSpace = !appendSpace && !m_tspans[i]->isTspan() && (mode == Default) && !paragraphs.back().isEmpty() && newText.startsWith(QLatin1Char(' '));
            if (appendSpace || prependSpace)
                paragraphs.back().append(QLatin1Char(' '));

            bool appendSpaceNext = (!m_tspans[i]->isTspan() && (mode == Default) && newText.endsWith(QLatin1Char(' ')));

            if (mode == Default) {
                newText = newText.simplified();
                if (newText.isEmpty())
                    appendSpaceNext = false;
            }

            QTextLayout::FormatRange range;
            range.start = paragraphs.back().length();
            range.length = newText.length();
            range.format.setFont(font);
            range.format.setTextOutline(p->pen());
            range.format.setForeground(p->brush());

            if (appendSpace) {
                Q_ASSERT(!formatRanges.back().isEmpty());
                ++formatRanges.back().back().length;
            } else if (prependSpace) {
                --range.start;
                ++range.length;
            }
            formatRanges.back().append(range);

            appendSpace = appendSpaceNext;
            paragraphs.back() += newText;

            m_tspans[i]->revertStyle(p, states);
        }
    }

    if (states.svgFont) {
        // SVG fonts not fully supported...
        QString text = paragraphs.front();
        for (int i = 1; i < paragraphs.size(); ++i) {
            text.append(QLatin1Char('\n'));
            text.append(paragraphs[i]);
        }
        states.svgFont->draw(p, m_coord * scale, text, p->font().pointSizeF() * scale, states.textAnchor);
    } else {
        for (int i = 0; i < paragraphs.size(); ++i) {
            QTextLayout tl(paragraphs[i]);
            QTextOption op = tl.textOption();
            op.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere);
            tl.setTextOption(op);
            tl.setAdditionalFormats(formatRanges[i]);
            tl.beginLayout();

            forever {
                QTextLine line = tl.createLine();
                if (!line.isValid())
                    break;
                if (m_size.width() != 0)
                    line.setLineWidth(scaledSize.width());
            }
            tl.endLayout();

            bool endOfBoundsReached = false;
            for (int i = 0; i < tl.lineCount(); ++i) {
                QTextLine line = tl.lineAt(i);

                qreal x = 0;
                if (alignment == Qt::AlignHCenter)
                    x -= 0.5 * line.naturalTextWidth();
                else if (alignment == Qt::AlignRight)
                    x -= line.naturalTextWidth();

                if (initial && m_type == TEXT)
                    y -= line.ascent();
                initial = false;

                line.setPosition(QPointF(x, y));

                // Check if the current line fits into the bounding rectangle.
                if ((m_size.width() != 0 && line.naturalTextWidth() > scaledSize.width())
                    || (m_size.height() != 0 && y + line.height() > scaledSize.height())) {
                    // I need to set the bounds height to 'y-epsilon' to avoid drawing the current
                    // line. Since the font is scaled to 100 units, 1 should be a safe epsilon.
                    bounds.setHeight(y - 1);
                    endOfBoundsReached = true;
                    break;
                }

                y += 1.1 * line.height();
            }
            tl.draw(p, QPointF(px, py), QVector<QTextLayout::FormatRange>(), bounds);

            if (endOfBoundsReached)
                break;
        }
    }

    p->setWorldTransform(oldTransform, false);
    p->setOpacity(oldOpacity);
    revertStyle(p, states);
}
Example #13
0
void QSvgArc::draw(QPainter *p, QSvgExtraStates &states)
{
    applyStyle(p, states);
    p->drawPath(cubic);
    revertStyle(p, states);
}
Example #14
0
void QSvgPolygon::draw(QPainter *p, QSvgExtraStates &states)
{
    applyStyle(p, states);
    QT_SVG_DRAW_SHAPE(p->drawPolygon(m_poly, states.fillRule));
    revertStyle(p, states);
}
Example #15
0
void QSvgLine::draw(QPainter *p, QSvgExtraStates &states)
{
    applyStyle(p, states);
    p->drawLine(m_bounds);
    revertStyle(p, states);
}
Example #16
0
void QSvgText::draw(QPainter *p, QSvgExtraStates &states)
{
    applyStyle(p, states);

    QSvgFontStyle *fontStyle = static_cast<QSvgFontStyle*>(
        styleProperty(QSvgStyleProperty::FONT));
    if (fontStyle && fontStyle->svgFont()) {
        // SVG fonts not fully supported...
        QString text = m_paragraphs.front();
        for (int i = 1; i < m_paragraphs.size(); ++i) {
            text.append(QLatin1Char('\n'));
            text.append(m_paragraphs[i]);
        }
        fontStyle->svgFont()->draw(p, m_coord, text, fontStyle->pointSize(), m_textAlignment);
        revertStyle(p, states);
        return;
    }

    // Scale the font to its correct size.
    QTransform oldTransform = p->worldTransform();
    p->scale(1 / m_scale, 1 / m_scale);

    qreal y = 0;
    bool initial = true;
    qreal px = m_coord.x() * m_scale;
    qreal py = m_coord.y() * m_scale;
    QSizeF scaledSize = m_size * m_scale;

    if (m_type == TEXTAREA) {
        if (m_textAlignment == Qt::AlignHCenter)
            px += scaledSize.width() / 2;
        else if (m_textAlignment == Qt::AlignRight)
            px += scaledSize.width();
    }

    QRectF bounds;
    if (m_size.height() != 0)
        bounds = QRectF(0, 0, 1, scaledSize.height());

    for (int i = 0; i < m_paragraphs.size(); ++i) {
        QTextLayout tl(m_paragraphs[i]);
        QTextOption op = tl.textOption();
        op.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere);
        tl.setTextOption(op);
        tl.setAdditionalFormats(m_formatRanges[i]);
        tl.beginLayout();
        forever {
            QTextLine line = tl.createLine();
            if (!line.isValid())
                break;

            if (m_size.width() != 0)
                line.setLineWidth(scaledSize.width());
        }
        tl.endLayout();

        bool endOfBoundsReached = false;
        for (int i = 0; i < tl.lineCount(); ++i) {
            QTextLine line = tl.lineAt(i);

            qreal x = 0;
            if (m_textAlignment == Qt::AlignHCenter)
                x -= line.naturalTextWidth() / 2;
            else if (m_textAlignment == Qt::AlignRight)
                x -= line.naturalTextWidth();

            if (initial && m_type == TEXT)
                y -= line.ascent();
            initial = false;

            line.setPosition(QPointF(x, y));
            if ((m_size.width() != 0 && line.naturalTextWidth() > scaledSize.width())
                || (m_size.height() != 0 && y + line.height() > scaledSize.height())) {
                bounds.setHeight(y);
                endOfBoundsReached = true;
                break;
            }

            y += 1.1 * line.height();
        }
        tl.draw(p, QPointF(px, py), QVector<QTextLayout::FormatRange>(), bounds);

        if (endOfBoundsReached)
            break;
    }

    p->setWorldTransform(oldTransform, false);
    revertStyle(p, states);
}
Example #17
0
void QSvgVideo::draw(QPainter *p, QSvgExtraStates &states)
{
    applyStyle(p, states);

    revertStyle(p, states);
}
Example #18
0
void QSvgImage::draw(QPainter *p, QSvgExtraStates &states)
{
    applyStyle(p, states);
    p->drawImage(m_bounds, m_image);
    revertStyle(p, states);
}
Example #19
0
void QSvgSwitch::draw(QPainter *p, QSvgExtraStates &states)
{
    QList<QSvgNode*>::iterator itr = m_renderers.begin();
    applyStyle(p, states);

    while (itr != m_renderers.end()) {
        QSvgNode *node = *itr;
        if (node->isVisible() && (node->displayMode() != QSvgNode::NoneMode)) {
            const QStringList &features  = node->requiredFeatures();
            const QStringList &extensions = node->requiredExtensions();
            const QStringList &languages = node->requiredLanguages();
            const QStringList &formats = node->requiredFormats();
            const QStringList &fonts = node->requiredFonts();

            bool okToRender = true;
            if (!features.isEmpty()) {
                QStringList::const_iterator sitr = features.constBegin();
                for (; sitr != features.constEnd(); ++sitr) {
                    if (!isSupportedSvgFeature(*sitr)) {
                        okToRender = false;
                        break;
                    }
                }
            }

            if (okToRender && !extensions.isEmpty()) {
                QStringList::const_iterator sitr = extensions.constBegin();
                for (; sitr != extensions.constEnd(); ++sitr) {
                    if (!isSupportedSvgExtension(*sitr)) {
                        okToRender = false;
                        break;
                    }
                }
            }

            if (okToRender && !languages.isEmpty()) {
                QStringList::const_iterator sitr = languages.constBegin();
                okToRender = false;
                for (; sitr != languages.constEnd(); ++sitr) {
                    if ((*sitr).startsWith(m_systemLanguagePrefix)) {
                        okToRender = true;
                        break;
                    }
                }
            }

            if (okToRender && !formats.isEmpty()) {
                okToRender = false;
            }

            if (okToRender && !fonts.isEmpty()) {
                okToRender = false;
            }

            if (okToRender) {
                node->draw(p, states);
                break;
            }
        }
        ++itr;
    }
    revertStyle(p, states);
}