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); } }
// ******************************************************** 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); }
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); }
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; } }
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; }
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); }
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); }