static QPainterPath getPathStroke(const QPainterPath &path, const RenderObject* object, const RenderStyle* style) { QPainterPathStroker s; s.setWidth(KSVGPainterFactory::cssPrimitiveToLength(object, style->svgStyle()->strokeWidth(), 1.0)); if (style->svgStyle()->capStyle() == ButtCap) s.setCapStyle(Qt::FlatCap); else if (style->svgStyle()->capStyle() == RoundCap) s.setCapStyle(Qt::RoundCap); if (style->svgStyle()->joinStyle() == MiterJoin) { s.setJoinStyle(Qt::MiterJoin); s.setMiterLimit((qreal) style->svgStyle()->strokeMiterLimit()); } else if(style->svgStyle()->joinStyle() == RoundJoin) s.setJoinStyle(Qt::RoundJoin); const KCDashArray& dashes = KSVGPainterFactory::dashArrayFromRenderingStyle(style); double dashOffset = KSVGPainterFactory::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)s.width()); s.setDashPattern(pattern); Q_UNUSED(dashOffset); // TODO: dash-offset, does/will qt4 API allow it? (Rob) } return s.createStroke(path); }
QPainterPath GraphicsUtils::shapeFromPath(const QPainterPath &path, const QPen &pen, double shapeStrokeWidth, bool includeOriginalPath) { // this function mostly copied from QGraphicsItem::qt_graphicsItem_shapeFromPath // We unfortunately need this hack as QPainterPathStroker will set a width of 1.0 // if we pass a value of 0.0 to QPainterPathStroker::setWidth() static const double penWidthZero = double(0.00000001); if (path == QPainterPath()) return path; QPainterPathStroker ps; ps.setCapStyle(pen.capStyle()); //ps.setCapStyle(Qt::FlatCap); if (shapeStrokeWidth <= 0.0) ps.setWidth(penWidthZero); else ps.setWidth(shapeStrokeWidth); ps.setJoinStyle(pen.joinStyle()); ps.setMiterLimit(pen.miterLimit()); QPainterPath p = ps.createStroke(path); if (includeOriginalPath) { p.addPath(path); } return p; }
static QRectF qwtStrokedPathRect( const QPainter *painter, const QPainterPath &path ) { QPainterPathStroker stroker; stroker.setWidth( painter->pen().widthF() ); stroker.setCapStyle( painter->pen().capStyle() ); stroker.setJoinStyle( painter->pen().joinStyle() ); stroker.setMiterLimit( painter->pen().miterLimit() ); QRectF rect; if ( qwtHasScalablePen( painter ) ) { QPainterPath stroke = stroker.createStroke(path); rect = painter->transform().map(stroke).boundingRect(); } else { QPainterPath mappedPath = painter->transform().map(path); mappedPath = stroker.createStroke( mappedPath ); rect = mappedPath.boundingRect(); } return rect; }
QPainterPath QGVEdge::shape() const { QPainterPathStroker ps; ps.setCapStyle(_pen.capStyle()); ps.setWidth(_pen.widthF() + 10); ps.setJoinStyle(_pen.joinStyle()); ps.setMiterLimit(_pen.miterLimit()); return ps.createStroke(_path); }
FloatRect Path::strokeBoundingRect(StrokeStyleApplier* applier) { GraphicsContext* gc = scratchContext(); QPainterPathStroker stroke; if (applier) { applier->strokeStyle(gc); QPen pen = gc->pen(); stroke.setWidth(pen.widthF()); stroke.setCapStyle(pen.capStyle()); stroke.setJoinStyle(pen.joinStyle()); stroke.setMiterLimit(pen.miterLimit()); stroke.setDashPattern(pen.dashPattern()); stroke.setDashOffset(pen.dashOffset()); } return stroke.createStroke(m_path).boundingRect(); }
bool Path::strokeContains(StrokeStyleApplier* applier, const FloatPoint& point) const { ASSERT(applier); QPainterPathStroker stroke; GraphicsContext* gc = scratchContext(); applier->strokeStyle(gc); QPen pen = gc->pen(); stroke.setWidth(pen.widthF()); stroke.setCapStyle(pen.capStyle()); stroke.setJoinStyle(pen.joinStyle()); stroke.setMiterLimit(pen.miterLimit()); stroke.setDashPattern(pen.dashPattern()); stroke.setDashOffset(pen.dashOffset()); return stroke.createStroke(m_path).contains(point); }
void tst_QPainterPath::testStroker() { QFETCH(QPainterPath, path); QFETCH(QPen, pen); QFETCH(QPainterPath, stroke); QPainterPathStroker stroker; stroker.setWidth(pen.widthF()); stroker.setCapStyle(pen.capStyle()); stroker.setJoinStyle(pen.joinStyle()); stroker.setMiterLimit(pen.miterLimit()); stroker.setDashPattern(pen.style()); stroker.setDashOffset(pen.dashOffset()); QPainterPath result = stroker.createStroke(path); // check if stroke == result QVERIFY(result.subtracted(stroke).isEmpty()); QVERIFY(stroke.subtracted(result).isEmpty()); }
FloatRect Path::strokeBoundingRect(StrokeStyleApplier* applier) { // FIXME: We should try to use a 'shared Context' instead of creating a new ImageBuffer // on each call. OwnPtr<ImageBuffer> scratchImage = ImageBuffer::create(IntSize(1, 1)); GraphicsContext* gc = scratchImage->context(); QPainterPathStroker stroke; if (applier) { applier->strokeStyle(gc); QPen pen = gc->pen(); stroke.setWidth(pen.widthF()); stroke.setCapStyle(pen.capStyle()); stroke.setJoinStyle(pen.joinStyle()); stroke.setMiterLimit(pen.miterLimit()); stroke.setDashPattern(pen.dashPattern()); stroke.setDashOffset(pen.dashOffset()); } return stroke.createStroke(m_path).boundingRect(); }
bool Path::strokeContains(StrokeStyleApplier* applier, const FloatPoint& point) const { ASSERT(applier); // FIXME: We should try to use a 'shared Context' instead of creating a new ImageBuffer // on each call. OwnPtr<ImageBuffer> scratchImage = ImageBuffer::create(IntSize(1, 1)); GraphicsContext* gc = scratchImage->context(); QPainterPathStroker stroke; applier->strokeStyle(gc); QPen pen = gc->pen(); stroke.setWidth(pen.widthF()); stroke.setCapStyle(pen.capStyle()); stroke.setJoinStyle(pen.joinStyle()); stroke.setMiterLimit(pen.miterLimit()); stroke.setDashPattern(pen.dashPattern()); stroke.setDashOffset(pen.dashOffset()); return stroke.createStroke(m_path).contains(point); }
QPainterPath Toolbox::shapeFromPath(const QPainterPath& path, const QPen& pen, const QBrush& brush, const UnsignedLength& minWidth) noexcept { // http://code.qt.io/cgit/qt/qtbase.git/tree/src/widgets/graphicsview/qgraphicsitem.cpp // Function: qt_graphicsItem_shapeFromPath() if (path == QPainterPath() || pen == Qt::NoPen) { return path; } else { QPainterPathStroker ps; ps.setCapStyle(pen.capStyle()); ps.setWidth(qMax(qMax(pen.widthF(), qreal(0.00000001)), minWidth->toPx())); ps.setJoinStyle(pen.joinStyle()); ps.setMiterLimit(pen.miterLimit()); QPainterPath p = ps.createStroke(path); if (brush != Qt::NoBrush) { p.addPath(path); } return p; } }
QPainterPath ArrowItem::shape() const { QPainterPath path; path.setFillRule(Qt::WindingFill); if (m_shaftItem &&m_shaftItem->path() != QPainterPath()) { QPainterPathStroker ps; QPen pen = m_shaftItem->pen(); ps.setCapStyle(pen.capStyle()); ps.setJoinStyle(pen.joinStyle()); ps.setMiterLimit(pen.miterLimit()); // overwrite pen width to make selection more lazy ps.setWidth(16.0); QPainterPath p = ps.createStroke(m_shaftItem->path()); path.addPath(p); } if (m_startHeadItem) path.addRect(mapRectFromItem(m_startHeadItem, m_startHeadItem->boundingRect())); if (m_endHeadItem) path.addRect(mapRectFromItem(m_endHeadItem, m_endHeadItem->boundingRect())); return path; }