VectorPath::VectorPath(const QPainterPath &painterPath) { m_isPainterPath = true; nOuter = 1; m_painterPath = painterPath; m_fillRule = painterPath.fillRule(); }
static QPainterPath qwtTransformPath( const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QPainterPath &path, bool doAlign ) { QPainterPath shape; shape.setFillRule( path.fillRule() ); for ( int i = 0; i < path.elementCount(); i++ ) { const QPainterPath::Element &element = path.elementAt( i ); double x = xMap.transform( element.x ); double y = yMap.transform( element.y ); switch( element.type ) { case QPainterPath::MoveToElement: { if ( doAlign ) { x = qRound( x ); y = qRound( y ); } shape.moveTo( x, y ); break; } case QPainterPath::LineToElement: { if ( doAlign ) { x = qRound( x ); y = qRound( y ); } shape.lineTo( x, y ); break; } case QPainterPath::CurveToElement: { const QPainterPath::Element& element1 = path.elementAt( ++i ); const double x1 = xMap.transform( element1.x ); const double y1 = yMap.transform( element1.y ); const QPainterPath::Element& element2 = path.elementAt( ++i ); const double x2 = xMap.transform( element2.x ); const double y2 = yMap.transform( element2.y ); shape.cubicTo( x, y, x1, y1, x2, y2 ); break; } case QPainterPath::CurveToDataElement: { break; } } } return shape; }
/*! Draw the shape item \param painter Painter \param xMap X-Scale Map \param yMap Y-Scale Map \param canvasRect Contents rect of the plot canvas */ void QwtPlotShapeItem::draw( QPainter *painter, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect ) const { if ( d_data->shape.isEmpty() ) return; if ( d_data->pen.style() == Qt::NoPen && d_data->brush.style() == Qt::NoBrush ) { return; } const QRectF cRect = QwtScaleMap::invTransform( xMap, yMap, canvasRect.toRect() ); if ( d_data->boundingRect.intersects( cRect ) ) { const bool doAlign = QwtPainter::roundingAlignment( painter ); QPainterPath path = qwtTransformPath( xMap, yMap, d_data->shape, doAlign ); if ( testPaintAttribute( QwtPlotShapeItem::ClipPolygons ) ) { qreal pw = qMax( qreal( 1.0 ), painter->pen().widthF()); QRectF clipRect = canvasRect.adjusted( -pw, -pw, pw, pw ); QPainterPath clippedPath; clippedPath.setFillRule( path.fillRule() ); const QList<QPolygonF> polygons = path.toSubpathPolygons(); for ( int i = 0; i < polygons.size(); i++ ) { const QPolygonF p = QwtClipper::clipPolygonF( clipRect, polygons[i], true ); clippedPath.addPolygon( p ); } path = clippedPath; } if ( d_data->renderTolerance > 0.0 ) { QwtWeedingCurveFitter fitter( d_data->renderTolerance ); QPainterPath fittedPath; fittedPath.setFillRule( path.fillRule() ); const QList<QPolygonF> polygons = path.toSubpathPolygons(); for ( int i = 0; i < polygons.size(); i++ ) fittedPath.addPolygon( fitter.fitCurve( polygons[ i ] ) ); path = fittedPath; } painter->setPen( d_data->pen ); painter->setBrush( d_data->brush ); painter->drawPath( path ); } }
/*! Draw the shape item \param painter Painter \param xMap X-Scale Map \param yMap Y-Scale Map \param canvasRect Contents rect of the plot canvas */ void QwtPlotShapeItem::draw( QPainter *painter, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect ) const { if ( d_data->shape.isEmpty() ) return; if ( d_data->pen.style() == Qt::NoPen && d_data->brush.style() == Qt::NoBrush ) { return; } const QRectF cr = QwtScaleMap::invTransform( xMap, yMap, canvasRect.toRect() ); const QRectF &br = d_data->boundingRect; if ( ( br.left() > cr.right() ) || ( br.right() < cr.left() ) || ( br.top() > cr.bottom() ) || ( br.bottom() < cr.top() ) ) { // outside the visisble area return; } const bool doAlign = QwtPainter::roundingAlignment( painter ); QPainterPath path = qwtTransformPath( xMap, yMap, d_data->shape, doAlign ); if ( testPaintAttribute( QwtPlotShapeItem::ClipPolygons ) ) { const qreal pw = QwtPainter::effectivePenWidth( painter->pen() ); const QRectF clipRect = canvasRect.adjusted( -pw, -pw, pw, pw ); QPainterPath clippedPath; clippedPath.setFillRule( path.fillRule() ); QList<QPolygonF> polygons = path.toSubpathPolygons(); for ( int i = 0; i < polygons.size(); i++ ) { QwtClipper::clipPolygonF( clipRect, polygons[i], true ); clippedPath.addPolygon( polygons[i] ); } path = clippedPath; } if ( d_data->renderTolerance > 0.0 ) { QwtWeedingCurveFitter fitter( d_data->renderTolerance ); QPainterPath fittedPath; fittedPath.setFillRule( path.fillRule() ); const QList<QPolygonF> polygons = path.toSubpathPolygons(); for ( int i = 0; i < polygons.size(); i++ ) fittedPath.addPolygon( fitter.fitCurve( polygons[ i ] ) ); path = fittedPath; } painter->setPen( d_data->pen ); painter->setBrush( d_data->brush ); painter->drawPath( path ); }
static ComPtr<ID2D1PathGeometry1> painterPathToPathGeometry(const QPainterPath &path) { ComPtr<ID2D1PathGeometry1> geometry; ComPtr<ID2D1GeometrySink> sink; HRESULT hr = factory()->CreatePathGeometry(&geometry); if (FAILED(hr)) { qWarning("%s: Could not create path geometry: %#x", __FUNCTION__, hr); return NULL; } hr = geometry->Open(&sink); if (FAILED(hr)) { qWarning("%s: Could not create geometry sink: %#x", __FUNCTION__, hr); return NULL; } switch (path.fillRule()) { case Qt::WindingFill: sink->SetFillMode(D2D1_FILL_MODE_WINDING); break; case Qt::OddEvenFill: sink->SetFillMode(D2D1_FILL_MODE_ALTERNATE); break; } bool inFigure = false; for (int i = 0; i < path.elementCount(); i++) { const QPainterPath::Element element = path.elementAt(i); switch (element.type) { case QPainterPath::MoveToElement: if (inFigure) sink->EndFigure(D2D1_FIGURE_END_OPEN); sink->BeginFigure(to_d2d_point_2f(element), D2D1_FIGURE_BEGIN_FILLED); inFigure = true; break; case QPainterPath::LineToElement: sink->AddLine(to_d2d_point_2f(element)); break; case QPainterPath::CurveToElement: { const QPainterPath::Element data1 = path.elementAt(++i); const QPainterPath::Element data2 = path.elementAt(++i); Q_ASSERT(i < path.elementCount()); Q_ASSERT(data1.type == QPainterPath::CurveToDataElement); Q_ASSERT(data2.type == QPainterPath::CurveToDataElement); D2D1_BEZIER_SEGMENT segment; segment.point1 = to_d2d_point_2f(element); segment.point2 = to_d2d_point_2f(data1); segment.point3 = to_d2d_point_2f(data2); sink->AddBezier(segment); } break; case QPainterPath::CurveToDataElement: qWarning("%s: Unhandled Curve Data Element", __FUNCTION__); break; } } if (inFigure) sink->EndFigure(D2D1_FIGURE_END_OPEN); sink->Close(); return geometry; }
void QCairoPaintEngine::drawPath(const QPainterPath &path) { if (!cr || !surface) { qDebug()<<"Cairo Error [QCairoPaintEngine::drawPath]: no cairo or no surface!"; return; } if (cbrush.style()==Qt::NoBrush && cpen.style()==Qt::NoPen) { qDebug()<<"Cairo Error [QCairoPaintEngine::drawPath]: no pen and no brush set!"; return; } //qDebug()<<"drawPath n="<<path; bool fill; updatePath(path, fill); /*cairo_new_path(cr); int start = -1, elmCount = path.elementCount(); for (int index = 0; index < elmCount; index++) { const QPainterPath::Element elm = path.elementAt(index); switch (elm.type) { case QPainterPath::MoveToElement: cairo_move_to(cr, elm.x, elm.y); start = index; break; case QPainterPath::LineToElement: cairo_line_to(cr, elm.x, elm.y); break; case QPainterPath::CurveToElement: cairo_curve_to(cr, elm.x, elm.y, path.elementAt(index + 1).x, path.elementAt(index + 1).y, path.elementAt(index + 2).x, path.elementAt(index + 2).y); index += 2; break; default: break; } } bool fill=false; if (start != -1 && start != elmCount - 1 && path.elementAt(start).x == path.elementAt(elmCount - 1).x && path.elementAt(start).y == path.elementAt(elmCount - 1).y){ cairo_close_path(cr); //qDebug()<<"closing path"; fill=cbrush.style()!=Qt::NoBrush; }*/ if (fill) fill=cbrush.style()!=Qt::NoBrush; if (fill) { switch (path.fillRule()) { case Qt::WindingFill: cairo_set_fill_rule(cr, CAIRO_FILL_RULE_WINDING); break; default: case Qt::OddEvenFill: cairo_set_fill_rule(cr, CAIRO_FILL_RULE_EVEN_ODD); break; } updateBrush(); if (cpen.style()!=Qt::NoPen) cairo_fill_preserve(cr); else cairo_fill(cr); } if (cpen.style()!=Qt::NoPen) { updatePen(); cairo_stroke(cr); } else { } }