Example #1
0
void SVGPaintServer::setPenProperties(const RenderObject* object, const RenderStyle* style, QPen& pen) const
{
    pen.setWidthF(SVGRenderStyle::cssPrimitiveToLength(object, style->svgStyle()->strokeWidth(), 1.0));

    if (style->svgStyle()->capStyle() == ButtCap)
        pen.setCapStyle(Qt::FlatCap);
    else if (style->svgStyle()->capStyle() == RoundCap)
        pen.setCapStyle(Qt::RoundCap);

    if (style->svgStyle()->joinStyle() == MiterJoin) {
        pen.setJoinStyle(Qt::MiterJoin);
        pen.setMiterLimit((qreal) style->svgStyle()->strokeMiterLimit());
    } else if(style->svgStyle()->joinStyle() == RoundJoin)
        pen.setJoinStyle(Qt::RoundJoin);

    const DashArray& dashes = WebCore::dashArrayFromRenderingStyle(style);
    double dashOffset = SVGRenderStyle::cssPrimitiveToLength(object, style->svgStyle()->strokeDashOffset(), 0.0);

    unsigned int dashLength = !dashes.isEmpty() ? dashes.size() : 0;
    if(dashLength) {
        QVector<qreal> pattern;
        unsigned int count = (dashLength % 2) == 0 ? dashLength : dashLength * 2;

        for(unsigned int i = 0; i < count; i++)
            pattern.append(dashes[i % dashLength] / (float)pen.widthF());

        pen.setDashPattern(pattern);

        Q_UNUSED(dashOffset);
        // TODO: dash-offset, does/will qt4 API allow it? (Rob)
    }
}
void Context2D::setupPainter()
{
    m_painter.setRenderHint(QPainter::Antialiasing, true);
    if ((m_state.flags & DirtyClippingRegion) && !m_state.clipPath.isEmpty())
        m_painter.setClipPath(m_state.clipPath);
    if (m_state.flags & DirtyFillStyle)
        m_painter.setBrush(m_state.fillStyle);
    if (m_state.flags & DirtyGlobalAlpha)
        m_painter.setOpacity(m_state.globalAlpha);
    if (m_state.flags & DirtyGlobalCompositeOperation)
        m_painter.setCompositionMode(m_state.globalCompositeOperation);
    if (m_state.flags & MDirtyPen) {
        QPen pen = m_painter.pen();
        if (m_state.flags & DirtyStrokeStyle)
            pen.setBrush(m_state.strokeStyle);
        if (m_state.flags & DirtyLineWidth)
            pen.setWidthF(m_state.lineWidth);
        if (m_state.flags & DirtyLineCap)
            pen.setCapStyle(m_state.lineCap);
        if (m_state.flags & DirtyLineJoin)
            pen.setJoinStyle(m_state.lineJoin);
        if (m_state.flags & DirtyMiterLimit)
            pen.setMiterLimit(m_state.miterLimit);
        m_painter.setPen(pen);
    }
}
Example #3
0
// ********************************************************
ImageBufferData::ImageBufferData(const IntSize& size, bool accelerated)
{
    QPainter* painter = new QPainter;
    m_painter = adoptPtr(painter);

#if ENABLE(ACCELERATED_2D_CANVAS)
    if (accelerated) {
        m_impl = adoptPtr(new ImageBufferDataPrivateAccelerated(size));
    } else
#endif
        m_impl = adoptPtr(new ImageBufferDataPrivateUnaccelerated(size));

    if (!m_impl->paintDevice())
        return;
    if (!painter->begin(m_impl->paintDevice()))
        return;

    painter->setRenderHints(QPainter::Antialiasing | QPainter::HighQualityAntialiasing);
    QPen pen = painter->pen();
    pen.setColor(Qt::black);
    pen.setWidth(1);
    pen.setCapStyle(Qt::FlatCap);
    pen.setJoinStyle(Qt::SvgMiterJoin);
    pen.setMiterLimit(10);
    painter->setPen(pen);
    QBrush brush = painter->brush();
    brush.setColor(Qt::black);
    painter->setBrush(brush);
    painter->setCompositionMode(QPainter::CompositionMode_SourceOver);
}
Example #4
0
ImageBufferData::ImageBufferData(const IntSize& size)
    : m_pixmap(size)
{
    if (m_pixmap.isNull())
        return;

    m_pixmap.fill(QColor(Qt::transparent));

    QPainter* painter = new QPainter;
    m_painter = adoptPtr(painter);

    if (!painter->begin(&m_pixmap))
        return;

    // Since ImageBuffer is used mainly for Canvas, explicitly initialize
    // its painter's pen and brush with the corresponding canvas defaults
    // NOTE: keep in sync with CanvasRenderingContext2D::State
    QPen pen = painter->pen();
    pen.setColor(Qt::black);
    pen.setWidth(1);
    pen.setCapStyle(Qt::FlatCap);
    pen.setJoinStyle(Qt::SvgMiterJoin);
    pen.setMiterLimit(10);
    painter->setPen(pen);
    QBrush brush = painter->brush();
    brush.setColor(Qt::black);
    painter->setBrush(brush);
    painter->setCompositionMode(QPainter::CompositionMode_SourceOver);
    
    m_image = StillImage::createForRendering(&m_pixmap);
}
void GraphicsContext::setMiterLimit(float limit)
{
    if (paintingDisabled())
        return;

    QPen nPen = m_data->p().pen();
    nPen.setMiterLimit(limit);
    m_data->p().setPen(nPen);
}
Example #6
0
void Context2D::beginPainting()
{
    if (!m_painter.isActive()) {
        m_painter.begin(&m_image);
        m_painter.setRenderHint(QPainter::Antialiasing);
        if (!m_state.clipPath.isEmpty())
            m_painter.setClipPath(m_state.clipPath);
        m_painter.setBrush(m_state.fillStyle);
        m_painter.setOpacity(m_state.globalAlpha);
        QPen pen;
        pen.setBrush(m_state.strokeStyle);
        if (pen.style() == Qt::NoPen)
            pen.setStyle(Qt::SolidLine);
        pen.setCapStyle(m_state.lineCap);
        pen.setJoinStyle(m_state.lineJoin);
        pen.setWidthF(m_state.lineWidth);
        pen.setMiterLimit(m_state.miterLimit);
        m_painter.setPen(pen);
    } else {
        if ((m_state.flags & DirtyClippingRegion) && !m_state.clipPath.isEmpty())
            m_painter.setClipPath(m_state.clipPath);
        if (m_state.flags & DirtyFillStyle)
            m_painter.setBrush(m_state.fillStyle);
        if (m_state.flags & DirtyGlobalAlpha)
            m_painter.setOpacity(m_state.globalAlpha);
        if (m_state.flags & DirtyGlobalCompositeOperation)
            m_painter.setCompositionMode(m_state.globalCompositeOperation);
        if (m_state.flags & MDirtyPen) {
            QPen pen = m_painter.pen();
            if (m_state.flags & DirtyStrokeStyle)
                pen.setBrush(m_state.strokeStyle);
            if (m_state.flags & DirtyLineWidth)
                pen.setWidthF(m_state.lineWidth);
            if (m_state.flags & DirtyLineCap)
                pen.setCapStyle(m_state.lineCap);
            if (m_state.flags & DirtyLineJoin)
                pen.setJoinStyle(m_state.lineJoin);
            if (m_state.flags & DirtyMiterLimit)
                pen.setMiterLimit(m_state.miterLimit);
            m_painter.setPen(pen);
        }
        m_state.flags = 0;
    }
}
Example #7
0
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    QString filepath = QFileDialog::getSaveFileName(nullptr, "Save File", "",
                                                    "PDF files (*.pdf)");
    if (filepath.isEmpty())
        return 1;
    QPdfWriter writer(filepath);
    writer.setPageSize(QPageSize(QPageSize::A4));
    writer.setResolution(300);

    QPainterPath path;
    path.moveTo(0,0);
    path.lineTo(1000,0);
    path.lineTo(1000,1000);
    path.lineTo(0,800);
    path.lineTo(500,100);
    path.lineTo(800,900);
    path.lineTo(300,600);

    QPen pen;
    pen.setWidth(30);
    pen.setJoinStyle(Qt::MiterJoin);

    // The black path on the first page must always be visible in the PDF viewer.
    QPainter p(&writer);
    pen.setMiterLimit(6.0);
    p.setPen(pen);
    p.drawPath(path);

    // If a miter limit below 1.0 is written to the PDF,
    // broken PDF viewers may not show the red path on the second page.
    writer.newPage();
    pen.setMiterLimit(0.6);
    pen.setColor(Qt::red);
    p.setPen(pen);
    p.drawPath(path);

    p.end();
    return 0;
}
Example #8
0
void Context2D::beginPainting()
{
    if (m_width <= 0 || m_height <=0)
        return;

    if (m_pixmap.width() != m_width || m_pixmap.height() != m_height) {
        if (m_painter.isActive())
            m_painter.end();
        m_pixmap = QPixmap(m_width, m_height);
        m_pixmap.fill(parent()->property("color").value<QColor>());
    }

    if (m_state.shadowBlur > 0 && m_painter.device() != &m_shadowbuffer) {
        if (m_painter.isActive())
            m_painter.end();
        updateShadowBuffer();
        m_painter.begin(&m_shadowbuffer);
        m_painter.setViewport(m_state.shadowOffsetX,
                              m_state.shadowOffsetY,
                              m_shadowbuffer.width(),
                              m_shadowbuffer.height());
        m_shadowbuffer.fill(Qt::transparent);
    }

    if (!m_painter.isActive()) {
        m_painter.begin(&m_pixmap);
        m_painter.setRenderHint(QPainter::Antialiasing);
        if (!m_state.clipPath.isEmpty())
            m_painter.setClipPath(m_state.clipPath);
        m_painter.setBrush(m_state.fillStyle);
        m_painter.setOpacity(m_state.globalAlpha);
        QPen pen;
        pen.setBrush(m_state.strokeStyle);
        if (pen.style() == Qt::NoPen)
            pen.setStyle(Qt::SolidLine);
        pen.setCapStyle(m_state.lineCap);
        pen.setJoinStyle(m_state.lineJoin);
        pen.setWidthF(m_state.lineWidth);
        pen.setMiterLimit(m_state.miterLimit);
        m_painter.setPen(pen);
    } else {
        setupPainter();
        m_state.flags = 0;
    }
}
void ImageBufferData::initPainter()
{
    m_painter->setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);

    // Since ImageBuffer is used mainly for Canvas, explicitly initialize
    // its painter's pen and brush with the corresponding canvas defaults
    // NOTE: keep in sync with CanvasRenderingContext2D::State
    QPen pen = m_painter->pen();
    pen.setColor(Qt::black);
    pen.setWidth(1);
    pen.setCapStyle(Qt::FlatCap);
    pen.setJoinStyle(Qt::SvgMiterJoin);
    pen.setMiterLimit(10);
    m_painter->setPen(pen);
    QBrush brush = m_painter->brush();
    brush.setColor(Qt::black);
    m_painter->setBrush(brush);
    m_painter->setCompositionMode(QPainter::CompositionMode_SourceOver);
}
Example #10
0
void QSvgStrokeStyle::apply(QPainter *p, const QSvgNode *, QSvgExtraStates &states)
{
    m_oldStroke = p->pen();
    m_oldStrokeOpacity = states.strokeOpacity;
    m_oldStrokeDashOffset = states.strokeDashOffset;
    m_oldVectorEffect = states.vectorEffect;

    QPen pen = p->pen();

    qreal oldWidth = pen.widthF();
    qreal width = m_stroke.widthF();
    if (oldWidth == 0)
        oldWidth = 1;
    if (width == 0)
        width = 1;
    qreal scale = oldWidth / width;

    if (m_strokeOpacitySet)
        states.strokeOpacity = m_strokeOpacity;

    if (m_vectorEffectSet)
        states.vectorEffect = m_vectorEffect;

    if (m_strokeSet) {
        if (m_style)
            pen.setBrush(m_style->brush(p, states));
        else
            pen.setBrush(m_stroke.brush());
    }

    if (m_strokeWidthSet)
        pen.setWidthF(m_stroke.widthF());

    bool setDashOffsetNeeded = false;

    if (m_strokeDashOffsetSet) {
        states.strokeDashOffset = m_strokeDashOffset;
        setDashOffsetNeeded = true;
    }

    if (m_strokeDashArraySet) {
        if (m_stroke.style() == Qt::SolidLine) {
            pen.setStyle(Qt::SolidLine);
        } else if (m_strokeWidthSet || oldWidth == 1) {
            // If both width and dash array was set, the dash array is already scaled correctly.
            pen.setDashPattern(m_stroke.dashPattern());
            setDashOffsetNeeded = true;
        } else {
            // If dash array was set, but not the width, the dash array has to be scaled with respect to the old width.
            QVector<qreal> dashes = m_stroke.dashPattern();
            for (int i = 0; i < dashes.size(); ++i)
                dashes[i] /= oldWidth;
            pen.setDashPattern(dashes);
            setDashOffsetNeeded = true;
        }
    } else if (m_strokeWidthSet && pen.style() != Qt::SolidLine && scale != 1) {
        // If the width was set, but not the dash array, the old dash array must be scaled with respect to the new width.
        QVector<qreal> dashes = pen.dashPattern();
        for (int i = 0; i < dashes.size(); ++i)
            dashes[i] *= scale;
        pen.setDashPattern(dashes);
        setDashOffsetNeeded = true;
    }

    if (m_strokeLineCapSet)
        pen.setCapStyle(m_stroke.capStyle());
    if (m_strokeLineJoinSet)
        pen.setJoinStyle(m_stroke.joinStyle());
    if (m_strokeMiterLimitSet)
        pen.setMiterLimit(m_stroke.miterLimit());

    // You can have dash offset on solid strokes in SVG files, but not in Qt.
    // QPen::setDashOffset() will set the pen style to Qt::CustomDashLine,
    // so don't call the method if the pen is solid.
    if (setDashOffsetNeeded && pen.style() != Qt::SolidLine) {
        qreal currentWidth = pen.widthF();
        if (currentWidth == 0)
            currentWidth = 1;
        pen.setDashOffset(states.strokeDashOffset / currentWidth);
    }

    pen.setCosmetic(states.vectorEffect);

    p->setPen(pen);
}