30  : QPaintEngine( QPaintEngine::AllFeatures ) 
 
   31  , mUsePathStroker( usePathStroker )
 
 
   37  mStrokedPathsSegments = segments;
 
 
   42  mSimplifyTolerance = tolerance;
 
 
   57  return QPaintEngine::User;
 
 
   62  if ( mUsePathStroker && state.state().testFlag( QPaintEngine::DirtyFlag::DirtyPen ) )
 
 
   71  QgsDebugError( QStringLiteral( 
"QgsGeometryPaintEngine does not support drawImage method" ) );
 
 
   77  QgsDebugError( QStringLiteral( 
"QgsGeometryPaintEngine does not support drawPixmap method" ) );
 
 
   83  QgsDebugError( QStringLiteral( 
"QgsGeometryPaintEngine does not support drawTiledPixmap method" ) );
 
 
   90  if ( transform.isIdentity() )
 
   92    for ( 
int i = 0; i < lineCount; ++i, ++lines )
 
   95                              QVector<double> { 
static_cast< double >( lines->x1() ), 
static_cast< double >( lines->x2() ) },
 
   96                              QVector<double> { 
static_cast< double >( lines->y1() ), 
static_cast< double >( lines->y2() ) } )
 
  102    for ( 
int i = 0; i < lineCount; ++i, ++lines )
 
  104      double x1 = lines->x1();
 
  105      double x2 = lines->x2();
 
  106      double y1 = lines->y1();
 
  107      double y2 = lines->y2();
 
  109      double tx1, tx2, ty1, ty2;
 
  110      transform.map( x1, y1, &tx1, &ty1 );
 
  111      transform.map( x2, y2, &tx2, &ty2 );
 
  114                              QVector<double> { tx1, tx2 },
 
  115                              QVector<double> { ty1, ty2 } )
 
 
  123  if ( mUsePathStroker )
 
  126    QPaintEngine::drawLines( lines, lineCount );
 
  130    const QTransform transform = painter()->combinedTransform();
 
 
  137  if ( mUsePathStroker )
 
  140    QPaintEngine::drawLines( lines, lineCount );
 
  144    const QTransform transform = painter()->combinedTransform();
 
 
  153  if ( transform.isIdentity() )
 
  155    for ( 
int i = 0; i < pointCount; ++i, ++points )
 
  158                                          static_cast< double >( points->y() ) ) );
 
  163    for ( 
int i = 0; i < pointCount; ++i, ++points )
 
  165      double x = points->x();
 
  166      double y = points->y();
 
  169      transform.map( x, y, &tx, &ty );
 
 
  178  const QTransform transform = painter()->combinedTransform();
 
 
  184  const QTransform transform = painter()->combinedTransform();
 
 
  192  if ( transform.isIdentity() )
 
  194    for ( 
int i = 0; i < rectCount; ++i, ++rects )
 
  197        QVector<double> { 
static_cast< double >( rects->left() ),
 
  198                          static_cast< double >( rects->right() ),
 
  199                          static_cast< double >( rects->right() ),
 
  200                          static_cast< double >( rects->left() ),
 
  201                          static_cast< double>( rects->left() )
 
  203        QVector<double> { 
static_cast< double >( rects->bottom() ),
 
  204                          static_cast< double >( rects->bottom() ),
 
  205                          static_cast< double >( rects->top() ),
 
  206                          static_cast< double >( rects->top() ),
 
  207                          static_cast< double >( rects->bottom() )
 
  214    for ( 
int i = 0; i < rectCount; ++i, ++rects )
 
  216      const double left = rects->left();
 
  217      const double right = rects->right();
 
  218      const double top = rects->top();
 
  219      const double bottom = rects->bottom();
 
  221      double bottomLeftX, bottomLeftY, bottomRightX, bottomRightY, topLeftX, topLeftY, topRightX, topRightY;
 
  222      transform.map( left, bottom, &bottomLeftX, &bottomLeftY );
 
  223      transform.map( right, bottom, &bottomRightX, &bottomRightY );
 
  224      transform.map( left, top, &topLeftX, &topLeftY );
 
  225      transform.map( right, top, &topRightX, &topRightY );
 
  228        QVector<double> { bottomLeftX, bottomRightX, topRightX, topLeftX, bottomLeftX  },
 
  229        QVector<double> { bottomLeftY, bottomRightY, topRightY, topLeftY, bottomLeftY } );
 
 
  237  const QTransform transform = painter()->combinedTransform();
 
 
  243  const QTransform transform = painter()->combinedTransform();
 
 
  252  x.resize( pointCount );
 
  253  y.resize( pointCount );
 
  254  double *xData = x.data();
 
  255  double *yData = y.data();
 
  257  if ( transform.isIdentity() )
 
  259    for ( 
int i = 0; i < pointCount; ++i, ++points )
 
  261      *xData++ = points->x();
 
  262      *yData++ = points->y();
 
  267    for ( 
int i = 0; i < pointCount; ++i, ++points )
 
  269      const double x = points->x();
 
  270      const double y = points->y();
 
  272      transform.map( x, y, &tx, &ty );
 
  281    case QPaintEngine::PolylineMode:
 
  282      if ( simplifyTolerance > 0 )
 
  288    case QPaintEngine::OddEvenMode:
 
  289    case QPaintEngine::WindingMode:
 
  290    case QPaintEngine::ConvexMode:
 
  291      if ( simplifyTolerance > 0 )
 
 
  301  if ( mUsePathStroker && mode == PolygonDrawMode::PolylineMode )
 
  304    if ( pointCount > 0 )
 
  307      path.moveTo( *points++ );
 
  308      for ( 
int i = 1; i < pointCount; ++i )
 
  310        path.lineTo( *points++ );
 
  317    const QTransform transform = painter()->combinedTransform();
 
  318    drawPolygonImp( transform, mGeometry, points, pointCount, mode, mSimplifyTolerance );
 
 
  324  if ( mUsePathStroker )
 
  327    if ( pointCount > 0 )
 
  330      path.moveTo( *points++ );
 
  331      for ( 
int i = 1; i < pointCount; ++i )
 
  333        path.lineTo( *points++ );
 
  340    const QTransform transform = painter()->combinedTransform();
 
  341    drawPolygonImp( transform, mGeometry, points, pointCount, mode, mSimplifyTolerance );
 
 
  347  std::unique_ptr< QgsAbstractGeometry > buffered;
 
  348  if ( mSimplifyTolerance > 0 )
 
  355    const double preBufferedSimplificationFactor = mSimplifyTolerance * 0.75;
 
  356    std::unique_ptr< QgsLineString > simplified( line->
simplifyByDistance( preBufferedSimplificationFactor ) );
 
  358    buffered.reset( 
geos.buffer( penWidth / 2, mStrokedPathsSegments, endCapStyle, joinStyle, miterLimit ) );
 
  363    buffered.reset( 
geos.buffer( penWidth / 2, mStrokedPathsSegments, endCapStyle, joinStyle, miterLimit ) );
 
  370    buffered->transform( *matrix );
 
  372  if ( 
QgsGeometryCollection *bufferedCollection = qgsgeometry_cast< QgsGeometryCollection * >( buffered.get() ) )
 
  374    if ( mSimplifyTolerance > 0 )
 
  376      for ( 
auto it = bufferedCollection->const_parts_begin(); it != bufferedCollection->const_parts_end(); ++it )
 
  378        mGeometry.
addGeometry( ( *it )->simplifyByDistance( mSimplifyTolerance ) );
 
  383      mGeometry.
addGeometries( bufferedCollection->takeGeometries() );
 
  388    if ( mSimplifyTolerance > 0 )
 
  390      mGeometry.
addGeometry( buffered->simplifyByDistance( mSimplifyTolerance ) );
 
  400void QgsGeometryPaintEngine::addSubpathGeometries( 
const QPainterPath &path, 
const QTransform &matrix )
 
  402  if ( path.isEmpty() )
 
  405  const bool transformIsIdentity = matrix.isIdentity();
 
  409  const double penWidth = mPen.widthF() <= 0 ? 1 : mPen.widthF();
 
  410  const double miterLimit = mPen.miterLimit();
 
  412  QVector< double > currentX;
 
  413  QVector< double > currentY;
 
  414  const int count = path.elementCount();
 
  417  std::vector< std::unique_ptr< QgsPolygon > > queuedPolygons;
 
  419  for ( 
int i = 0; i < count; ++i )
 
  421    const QPainterPath::Element &e = path.elementAt( i );
 
  424      case QPainterPath::MoveToElement:
 
  426        if ( currentX.size() > 1 )
 
  428          auto line = std::make_unique< QgsLineString >( currentX, currentY );
 
  429          if ( mUsePathStroker )
 
  431            addStrokedLine( line.get(), penWidth, endCapStyle, joinStyle, miterLimit, transformIsIdentity ? 
nullptr : &matrix );
 
  435            if ( !transformIsIdentity )
 
  438            if ( mSimplifyTolerance > 0 )
 
  440              queuedPolygons.emplace_back( std::make_unique< QgsPolygon >( line->
simplifyByDistance( mSimplifyTolerance ) ) );
 
  445              queuedPolygons.emplace_back( std::make_unique< QgsPolygon >( line.release() ) );
 
  450            if ( !transformIsIdentity )
 
  452            if ( mSimplifyTolerance > 0 )
 
  463        currentX.resize( 0 );
 
  464        currentY.resize( 0 );
 
  466        currentX.reserve( 16 );
 
  467        currentY.reserve( 16 );
 
  473      case QPainterPath::LineToElement:
 
  480      case QPainterPath::CurveToElement:
 
  482        Q_ASSERT( path.elementAt( i + 1 ).type == QPainterPath::CurveToDataElement );
 
  483        Q_ASSERT( path.elementAt( i + 2 ).type == QPainterPath::CurveToDataElement );
 
  485        const double x1 = path.elementAt( i - 1 ).x;
 
  486        const double y1 = path.elementAt( i - 1 ).y;
 
  488        const double x3 = path.elementAt( i + 1 ).x;
 
  489        const double y3 = path.elementAt( i + 1 ).y;
 
  491        const double x4 = path.elementAt( i + 2 ).x;
 
  492        const double y4 = path.elementAt( i + 2 ).y;
 
  501        currentX << bezier->xVector();
 
  502        currentY << bezier->yVector();
 
  507      case QPainterPath::CurveToDataElement:
 
  508        Q_ASSERT( !
"addSubpathGeometries(), bad element type" );
 
  513  if ( currentX.size() > 1 )
 
  515    auto line = std::make_unique< QgsLineString >( currentX, currentY );
 
  516    if ( mUsePathStroker )
 
  518      addStrokedLine( line.get(), penWidth, endCapStyle, joinStyle, miterLimit, transformIsIdentity ? 
nullptr : &matrix );
 
  522      if ( !transformIsIdentity )
 
  524      if ( mSimplifyTolerance > 0 )
 
  526        queuedPolygons.emplace_back( std::make_unique< QgsPolygon >( line->
simplifyByDistance( mSimplifyTolerance ) ) );
 
  531        queuedPolygons.emplace_back( std::make_unique< QgsPolygon >( line.release() ) );
 
  536      if ( !transformIsIdentity )
 
  538      if ( mSimplifyTolerance > 0 )
 
  550  if ( queuedPolygons.empty() )
 
  556  tempMultiPolygon.
reserve( 
static_cast< int >( queuedPolygons.size() ) );
 
  557  for ( 
auto &part : queuedPolygons )
 
  563  QgsGeos geosCollection( &tempMultiPolygon );
 
  568  for ( 
auto it = g->const_parts_begin(); it != g->const_parts_end(); ++it )
 
  576  const QTransform transform = painter()->combinedTransform();
 
  577  addSubpathGeometries( path, transform );
 
 
  587  mPaintEngine = std::make_unique<QgsGeometryPaintEngine>( usePathStroker );
 
 
  593    mPaintEngine->setStrokedPathSegments( segments );
 
 
  599    mPaintEngine->setSimplificationTolerance( tolerance );
 
 
  604  return mPaintEngine.get();
 
 
  615      val = 
static_cast< int >( mPaintEngine->geometry().boundingBox().width() );
 
  618      val = 
static_cast< int >( mPaintEngine->geometry().boundingBox().height() );
 
  627    case PdmPhysicalDpiX:
 
  631    case PdmPhysicalDpiY:
 
  640    case PdmDevicePixelRatio:
 
  643    case PdmDevicePixelRatioScaled:
 
  644      val = 
static_cast< int >( 1 * QPaintDevice::devicePixelRatioFScale() );
 
  648      qWarning( 
"QPicture::metric: Invalid metric command" );
 
 
  655  return mPaintEngine->geometry();
 
 
  661  QPainter painter( &device );
 
  662  painter.drawPath( path );
 
 
JoinStyle
Join styles for buffers.
 
EndCapStyle
End cap styles for buffers.
 
@ Linework
Combines all rings into a set of noded lines and then extracts valid polygons from that linework.
 
Abstract base class for all geometries.
 
virtual QgsAbstractGeometry * clone() const =0
Clones the geometry by performing a deep copy.
 
void reserve(int size)
Attempts to allocate memory for at least size geometries.
 
virtual bool addGeometries(const QVector< QgsAbstractGeometry * > &geometries)
Adds a list of geometries to the collection, transferring ownership to the collection.
 
virtual bool addGeometry(QgsAbstractGeometry *g)
Adds a geometry and takes ownership. Returns true in case of success.
 
int numGeometries() const
Returns the number of geometries within the collection.
 
A paint device which converts everything renderer to a QgsGeometry representation of the rendered sha...
 
QgsGeometryPaintDevice(bool usePathStroker=false)
Constructor for QgsGeometryPaintDevice.
 
void setStrokedPathSegments(int segments)
Sets the number of segments to use when drawing stroked paths with a rounded pen.
 
int metric(PaintDeviceMetric metric) const override
 
void setSimplificationTolerance(double tolerance)
Sets a simplification tolerance (in painter units) to use for on-the-fly simplification of geometries...
 
QPaintEngine * paintEngine() const override
 
static QgsGeometry painterPathToGeometry(const QPainterPath &path)
Converts a painter path to a QgsGeometry.
 
const QgsAbstractGeometry & geometry() const
Returns the rendered geometry.
 
void setSimplificationTolerance(double tolerance)
Sets a simplification tolerance (in painter units) to use for on-the-fly simplification of geometries...
 
void drawImage(const QRectF &rectangle, const QImage &image, const QRectF &sr, Qt::ImageConversionFlags flags=Qt::AutoColor) final
 
void drawRects(const QRectF *rects, int rectCount) final
 
void drawPolygon(const QPointF *points, int pointCount, QPaintEngine::PolygonDrawMode mode) final
 
void drawPixmap(const QRectF &, const QPixmap &, const QRectF &) final
 
void drawPoints(const QPointF *points, int pointCount) final
 
bool begin(QPaintDevice *) final
 
QgsGeometryPaintEngine(bool usePathStroker=false)
Constructor for QgsGeometryPaintEngine.
 
void drawLines(const QLineF *lines, int lineCount) final
 
QPaintEngine::Type type() const final
 
void drawTiledPixmap(const QRectF &rect, const QPixmap &pixmap, const QPointF &p) final
 
void updateState(const QPaintEngineState &) final
 
void drawPath(const QPainterPath &path) final
 
void setStrokedPathSegments(int segments)
Sets the number of segments to use when drawing stroked paths with a rounded pen.
 
A geometry is the spatial representation of a feature.
 
Does vector analysis using the GEOS library and handles import, export, and exception handling.
 
Line string geometry type, with support for z-dimension and m-values.
 
static std::unique_ptr< QgsLineString > fromBezierCurve(const QgsPoint &start, const QgsPoint &controlPoint1, const QgsPoint &controlPoint2, const QgsPoint &end, int segments=30)
Returns a new linestring created by segmentizing the bezier curve between start and end,...
 
bool isClosed() const override
Returns true if the curve is closed.
 
QgsLineString * simplifyByDistance(double tolerance) const override
Simplifies the geometry by applying the Douglas Peucker simplification by distance algorithm.
 
void transform(const QgsCoordinateTransform &ct, Qgis::TransformDirection d=Qgis::TransformDirection::Forward, bool transformZ=false) override
Transforms the geometry using a coordinate transform.
 
Multi polygon geometry collection.
 
bool addGeometry(QgsAbstractGeometry *g) override
Adds a geometry and takes ownership. Returns true in case of success.
 
static int qtDefaultDpiY()
Returns the default Qt vertical DPI.
 
static int qtDefaultDpiX()
Returns the default Qt horizontal DPI.
 
Point geometry type, with support for z-dimension and m-values.
 
static Qgis::EndCapStyle penCapStyleToEndCapStyle(Qt::PenCapStyle style)
Converts a Qt pen cap style to a QGIS end cap style.
 
static Qgis::JoinStyle penJoinStyleToJoinStyle(Qt::PenJoinStyle style)
Converts a Qt pen joinstyle to a QGIS join style.
 
Contains geos related utilities and functions.
 
void drawPointsImp(const QTransform &transform, QgsGeometryCollection &geometry, const T *points, int pointCount)
 
void drawRectsImp(const QTransform &transform, QgsGeometryCollection &geometry, const T *rects, int rectCount)
 
void drawLinesImp(const QTransform &transform, QgsGeometryCollection &geometry, const T *lines, int lineCount)
 
void drawPolygonImp(const QTransform &transform, QgsGeometryCollection &geometry, const T *points, int pointCount, QPaintEngine::PolygonDrawMode mode, double simplifyTolerance)
 
#define QgsDebugError(str)