QGIS API Documentation  3.10.0-A Coruña (6c816b4204)
qgslayoutitempolyline.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgslayoutitempolyline.cpp
3  begin : March 2016
4  copyright : (C) 2016 Paul Blottiere, Oslandia
5  email : paul dot blottiere at oslandia dot com
6  ***************************************************************************/
7 
8 /***************************************************************************
9  * *
10  * This program is free software; you can redistribute it and/or modify *
11  * it under the terms of the GNU General Public License as published by *
12  * the Free Software Foundation; either version 2 of the License, or *
13  * (at your option) any later version. *
14  * *
15  ***************************************************************************/
16 
17 #include "qgslayoutitempolyline.h"
18 #include "qgslayoutitemregistry.h"
19 #include "qgssymbollayerutils.h"
20 #include "qgssymbol.h"
21 #include "qgslayout.h"
22 #include "qgsmapsettings.h"
23 #include "qgslayoututils.h"
24 #include "qgsreadwritecontext.h"
25 #include "qgssvgcache.h"
26 #include "qgsstyleentityvisitor.h"
27 #include <QSvgRenderer>
28 #include <limits>
29 #include <QGraphicsPathItem>
30 #include <QVector2D>
31 
33  : QgsLayoutNodesItem( layout )
34 {
35  createDefaultPolylineStyleSymbol();
36 }
37 
39  : QgsLayoutNodesItem( polyline, layout )
40 {
41  createDefaultPolylineStyleSymbol();
42 }
43 
45 {
46  return new QgsLayoutItemPolyline( layout );
47 }
48 
50 {
52 }
53 
55 {
56  return QgsApplication::getThemeIcon( QStringLiteral( "/mLayoutItemPolyline.svg" ) );
57 }
58 
59 bool QgsLayoutItemPolyline::_addNode( const int indexPoint,
60  QPointF newPoint,
61  const double radius )
62 {
63  const double distStart = computeDistance( newPoint, mPolygon[0] );
64  const double distEnd = computeDistance( newPoint, mPolygon[mPolygon.size() - 1] );
65 
66  if ( indexPoint == ( mPolygon.size() - 1 ) )
67  {
68  if ( distEnd < radius )
69  mPolygon.append( newPoint );
70  else if ( distStart < radius )
71  mPolygon.insert( 0, newPoint );
72  }
73  else
74  mPolygon.insert( indexPoint + 1, newPoint );
75 
76  return true;
77 }
78 
79 bool QgsLayoutItemPolyline::_removeNode( const int index )
80 {
81  if ( index < 0 || index >= mPolygon.size() )
82  return false;
83 
84  mPolygon.remove( index );
85 
86  if ( mPolygon.size() < 2 )
87  mPolygon.clear();
88  else
89  {
90  int newSelectNode = index;
91  if ( index >= mPolygon.size() )
92  newSelectNode = mPolygon.size() - 1;
93  setSelectedNode( newSelectNode );
94  }
95 
96  return true;
97 }
98 
99 void QgsLayoutItemPolyline::createDefaultPolylineStyleSymbol()
100 {
101  QgsStringMap properties;
102  properties.insert( QStringLiteral( "color" ), QStringLiteral( "0,0,0,255" ) );
103  properties.insert( QStringLiteral( "width" ), QStringLiteral( "0.3" ) );
104  properties.insert( QStringLiteral( "capstyle" ), QStringLiteral( "square" ) );
105 
106  mPolylineStyleSymbol.reset( QgsLineSymbol::createSimple( properties ) );
107  refreshSymbol();
108 }
109 
110 void QgsLayoutItemPolyline::refreshSymbol()
111 {
112  if ( layout() )
113  {
114  QgsRenderContext rc = QgsLayoutUtils::createRenderContextForLayout( layout(), nullptr, layout()->renderContext().dpi() );
115  mMaxSymbolBleed = ( 25.4 / layout()->renderContext().dpi() ) * QgsSymbolLayerUtils::estimateMaxSymbolBleed( mPolylineStyleSymbol.get(), rc );
116  }
117 
118  updateSceneRect();
119 
120  emit frameChanged();
121 }
122 
123 void QgsLayoutItemPolyline::drawStartMarker( QPainter *painter )
124 {
125  if ( mPolygon.size() < 2 )
126  return;
127 
128  switch ( mStartMarker )
129  {
130  case MarkerMode::NoMarker:
131  break;
132 
133  case MarkerMode::ArrowHead:
134  {
135  // calculate angle at start of line
136  QLineF startLine( mPolygon.at( 0 ), mPolygon.at( 1 ) );
137  double angle = startLine.angle();
138  drawArrow( painter, mPolygon.at( 0 ), angle );
139  break;
140  }
141 
142  case MarkerMode::SvgMarker:
143  {
144  // calculate angle at start of line
145  QLineF startLine( mPolygon.at( 0 ), mPolygon.at( 1 ) );
146  double angle = startLine.angle();
147  drawSvgMarker( painter, mPolygon.at( 0 ), angle, mStartMarkerFile, mStartArrowHeadHeight );
148  break;
149  }
150  }
151 
152 }
153 
154 void QgsLayoutItemPolyline::drawEndMarker( QPainter *painter )
155 {
156  if ( mPolygon.size() < 2 )
157  return;
158 
159  switch ( mEndMarker )
160  {
161  case MarkerMode::NoMarker:
162  break;
163 
164  case MarkerMode::ArrowHead:
165  {
166  // calculate angle at end of line
167  QLineF endLine( mPolygon.at( mPolygon.count() - 2 ), mPolygon.at( mPolygon.count() - 1 ) );
168  double angle = endLine.angle();
169 
170  //move end point depending on arrow width
171  QVector2D dir = QVector2D( endLine.dx(), endLine.dy() ).normalized();
172  QPointF endPoint = endLine.p2();
173  endPoint += ( dir * 0.5 * mArrowHeadWidth ).toPointF();
174 
175  drawArrow( painter, endPoint, angle );
176  break;
177  }
178  case MarkerMode::SvgMarker:
179  {
180  // calculate angle at end of line
181  QLineF endLine( mPolygon.at( mPolygon.count() - 2 ), mPolygon.at( mPolygon.count() - 1 ) );
182  double angle = endLine.angle();
183  drawSvgMarker( painter, endLine.p2(), angle, mEndMarkerFile, mEndArrowHeadHeight );
184  break;
185  }
186  }
187 }
188 
189 void QgsLayoutItemPolyline::drawArrow( QPainter *painter, QPointF center, double angle )
190 {
191  // translate angle from ccw from axis to cw from north
192  angle = 90 - angle;
193  QPen p;
194  p.setColor( mArrowHeadStrokeColor );
195  p.setWidthF( mArrowHeadStrokeWidth );
196  painter->setPen( p );
197  QBrush b;
198  b.setColor( mArrowHeadFillColor );
199  painter->setBrush( b );
200 
201  drawArrowHead( painter, center.x(), center.y(), angle, mArrowHeadWidth );
202 }
203 
204 void QgsLayoutItemPolyline::updateMarkerSvgSizes()
205 {
206  setStartSvgMarkerPath( mStartMarkerFile );
207  setEndSvgMarkerPath( mEndMarkerFile );
208 }
209 
210 void QgsLayoutItemPolyline::drawArrowHead( QPainter *p, const double x, const double y, const double angle, const double arrowHeadWidth )
211 {
212  if ( !p )
213  return;
214 
215  double angleRad = angle / 180.0 * M_PI;
216  QPointF middlePoint( x, y );
217 
218  //rotate both arrow points
219  QPointF p1 = QPointF( -arrowHeadWidth / 2.0, arrowHeadWidth );
220  QPointF p2 = QPointF( arrowHeadWidth / 2.0, arrowHeadWidth );
221 
222  QPointF p1Rotated, p2Rotated;
223  p1Rotated.setX( p1.x() * std::cos( angleRad ) + p1.y() * -std::sin( angleRad ) );
224  p1Rotated.setY( p1.x() * std::sin( angleRad ) + p1.y() * std::cos( angleRad ) );
225  p2Rotated.setX( p2.x() * std::cos( angleRad ) + p2.y() * -std::sin( angleRad ) );
226  p2Rotated.setY( p2.x() * std::sin( angleRad ) + p2.y() * std::cos( angleRad ) );
227 
228  QPolygonF arrowHeadPoly;
229  arrowHeadPoly << middlePoint;
230  arrowHeadPoly << QPointF( middlePoint.x() + p1Rotated.x(), middlePoint.y() + p1Rotated.y() );
231  arrowHeadPoly << QPointF( middlePoint.x() + p2Rotated.x(), middlePoint.y() + p2Rotated.y() );
232  QPen arrowPen = p->pen();
233  arrowPen.setJoinStyle( Qt::RoundJoin );
234  QBrush arrowBrush = p->brush();
235  arrowBrush.setStyle( Qt::SolidPattern );
236  p->setPen( arrowPen );
237  p->setBrush( arrowBrush );
238  arrowBrush.setStyle( Qt::SolidPattern );
239  p->drawPolygon( arrowHeadPoly );
240 }
241 
242 void QgsLayoutItemPolyline::drawSvgMarker( QPainter *p, QPointF point, double angle, const QString &markerPath, double height ) const
243 {
244  // translate angle from ccw from axis to cw from north
245  angle = 90 - angle;
246 
247  if ( mArrowHeadWidth <= 0 || height <= 0 )
248  {
249  //bad image size
250  return;
251  }
252 
253  if ( markerPath.isEmpty() )
254  return;
255 
256  QSvgRenderer r;
257  const QByteArray &svgContent = QgsApplication::svgCache()->svgContent( markerPath, mArrowHeadWidth, mArrowHeadFillColor, mArrowHeadStrokeColor, mArrowHeadStrokeWidth,
258  1.0 );
259  r.load( svgContent );
260 
261  p->save();
262  p->translate( point.x(), point.y() );
263  p->rotate( angle );
264  p->translate( -mArrowHeadWidth / 2.0, -height / 2.0 );
265  r.render( p, QRectF( 0, 0, mArrowHeadWidth, height ) );
266  p->restore();
267 }
268 
270 {
271  if ( !id().isEmpty() )
272  return id();
273 
274  return tr( "<Polyline>" );
275 }
276 
277 void QgsLayoutItemPolyline::_draw( QgsLayoutItemRenderContext &context, const QStyleOptionGraphicsItem * )
278 {
279  context.renderContext().painter()->save();
280  //setup painter scaling to dots so that raster symbology is drawn to scale
282  QTransform t = QTransform::fromScale( scale, scale );
283 
284  mPolylineStyleSymbol->startRender( context.renderContext() );
285  mPolylineStyleSymbol->renderPolyline( t.map( mPolygon ), nullptr, context.renderContext() );
286  mPolylineStyleSymbol->stopRender( context.renderContext() );
287 
288  // painter is scaled to dots, so scale back to layout units
289  context.renderContext().painter()->scale( context.renderContext().scaleFactor(), context.renderContext().scaleFactor() );
290 
291  drawStartMarker( context.renderContext().painter() );
292  drawEndMarker( context.renderContext().painter() );
293  context.renderContext().painter()->restore();
294 }
295 
296 void QgsLayoutItemPolyline::_readXmlStyle( const QDomElement &elmt, const QgsReadWriteContext &context )
297 {
298  mPolylineStyleSymbol.reset( QgsSymbolLayerUtils::loadSymbol<QgsLineSymbol>( elmt, context ) );
299 }
300 
302 {
303  mPolylineStyleSymbol.reset( static_cast<QgsLineSymbol *>( symbol->clone() ) );
304  refreshSymbol();
305 }
306 
308 {
309  mStartMarker = mode;
310  update();
311 }
312 
314 {
315  mEndMarker = mode;
316  update();
317 }
318 
320 {
321  mArrowHeadWidth = width;
322  updateMarkerSvgSizes();
323  update();
324 }
325 
326 QPainterPath QgsLayoutItemPolyline::shape() const
327 {
328  QPainterPath path;
329  path.addPolygon( mPolygon );
330 
331  QPainterPathStroker ps;
332 
333  ps.setWidth( 2 * mMaxSymbolBleed );
334  QPainterPath strokedOutline = ps.createStroke( path );
335 
336  return strokedOutline;
337 }
338 
340 {
341  QSvgRenderer r;
342  mStartMarkerFile = path;
343  if ( path.isEmpty() || !r.load( path ) )
344  {
345  mStartArrowHeadHeight = 0;
346  }
347  else
348  {
349  //calculate mArrowHeadHeight from svg file and mArrowHeadWidth
350  QRect viewBox = r.viewBox();
351  mStartArrowHeadHeight = mArrowHeadWidth / viewBox.width() * viewBox.height();
352  }
354 }
355 
357 {
358  QSvgRenderer r;
359  mEndMarkerFile = path;
360  if ( path.isEmpty() || !r.load( path ) )
361  {
362  mEndArrowHeadHeight = 0;
363  }
364  else
365  {
366  //calculate mArrowHeadHeight from svg file and mArrowHeadWidth
367  QRect viewBox = r.viewBox();
368  mEndArrowHeadHeight = mArrowHeadWidth / viewBox.width() * viewBox.height();
369  }
371 }
372 
374 {
375  mArrowHeadStrokeColor = color;
376  update();
377 }
378 
380 {
381  mArrowHeadFillColor = color;
382  update();
383 }
384 
386 {
387  mArrowHeadStrokeWidth = width;
389  update();
390 }
391 
393 {
394  if ( mPolylineStyleSymbol )
395  {
396  QgsStyleSymbolEntity entity( mPolylineStyleSymbol.get() );
397  if ( !visitor->visit( QgsStyleEntityVisitorInterface::StyleLeaf( &entity, uuid(), displayName() ) ) )
398  return false;
399  }
400 
401  return true;
402 }
403 
404 void QgsLayoutItemPolyline::_writeXmlStyle( QDomDocument &doc, QDomElement &elmt, const QgsReadWriteContext &context ) const
405 {
406  const QDomElement pe = QgsSymbolLayerUtils::saveSymbol( QString(),
407  mPolylineStyleSymbol.get(),
408  doc,
409  context );
410  elmt.appendChild( pe );
411 }
412 
413 bool QgsLayoutItemPolyline::writePropertiesToElement( QDomElement &elmt, QDomDocument &doc, const QgsReadWriteContext &context ) const
414 {
415  QgsLayoutNodesItem::writePropertiesToElement( elmt, doc, context );
416 
417  // absolute paths to relative
418  QString startMarkerPath = QgsSymbolLayerUtils::svgSymbolPathToName( mStartMarkerFile, context.pathResolver() );
419  QString endMarkerPath = QgsSymbolLayerUtils::svgSymbolPathToName( mEndMarkerFile, context.pathResolver() );
420 
421  elmt.setAttribute( QStringLiteral( "arrowHeadWidth" ), QString::number( mArrowHeadWidth ) );
422  elmt.setAttribute( QStringLiteral( "arrowHeadFillColor" ), QgsSymbolLayerUtils::encodeColor( mArrowHeadFillColor ) );
423  elmt.setAttribute( QStringLiteral( "arrowHeadOutlineColor" ), QgsSymbolLayerUtils::encodeColor( mArrowHeadStrokeColor ) );
424  elmt.setAttribute( QStringLiteral( "outlineWidth" ), QString::number( mArrowHeadStrokeWidth ) );
425  elmt.setAttribute( QStringLiteral( "markerMode" ), mEndMarker );
426  elmt.setAttribute( QStringLiteral( "startMarkerMode" ), mStartMarker );
427  elmt.setAttribute( QStringLiteral( "startMarkerFile" ), startMarkerPath );
428  elmt.setAttribute( QStringLiteral( "endMarkerFile" ), endMarkerPath );
429 
430  return true;
431 }
432 
433 bool QgsLayoutItemPolyline::readPropertiesFromElement( const QDomElement &elmt, const QDomDocument &doc, const QgsReadWriteContext &context )
434 {
435  mArrowHeadWidth = elmt.attribute( QStringLiteral( "arrowHeadWidth" ), QStringLiteral( "2.0" ) ).toDouble();
436  mArrowHeadFillColor = QgsSymbolLayerUtils::decodeColor( elmt.attribute( QStringLiteral( "arrowHeadFillColor" ), QStringLiteral( "0,0,0,255" ) ) );
437  mArrowHeadStrokeColor = QgsSymbolLayerUtils::decodeColor( elmt.attribute( QStringLiteral( "arrowHeadOutlineColor" ), QStringLiteral( "0,0,0,255" ) ) );
438  mArrowHeadStrokeWidth = elmt.attribute( QStringLiteral( "outlineWidth" ), QStringLiteral( "1.0" ) ).toDouble();
439  // relative paths to absolute
440  QString startMarkerPath = elmt.attribute( QStringLiteral( "startMarkerFile" ), QString() );
441  QString endMarkerPath = elmt.attribute( QStringLiteral( "endMarkerFile" ), QString() );
444  mEndMarker = static_cast< QgsLayoutItemPolyline::MarkerMode >( elmt.attribute( QStringLiteral( "markerMode" ), QStringLiteral( "0" ) ).toInt() );
445  mStartMarker = static_cast< QgsLayoutItemPolyline::MarkerMode >( elmt.attribute( QStringLiteral( "startMarkerMode" ), QStringLiteral( "0" ) ).toInt() );
446 
447  QgsLayoutNodesItem::readPropertiesFromElement( elmt, doc, context );
448 
450  return true;
451 }
452 
454 {
455  QRectF br = rect();
456 
457  double margin = std::max( mMaxSymbolBleed, computeMarkerMargin() );
458  if ( mEndMarker == ArrowHead )
459  {
460  margin += 0.5 * mArrowHeadWidth;
461  }
462  br.adjust( -margin, -margin, margin, margin );
463  mCurrentRectangle = br;
464 
465  // update
466  prepareGeometryChange();
467  update();
468 }
469 
470 
471 double QgsLayoutItemPolyline::computeMarkerMargin() const
472 {
473  double margin = 0;
474 
475  if ( mStartMarker == ArrowHead || mEndMarker == ArrowHead )
476  {
477  margin = mArrowHeadStrokeWidth / 2.0 + mArrowHeadWidth * M_SQRT2;
478  }
479 
480  if ( mStartMarker == SvgMarker )
481  {
482  double startMarkerMargin = std::sqrt( 0.25 * ( mStartArrowHeadHeight * mStartArrowHeadHeight + mArrowHeadWidth * mArrowHeadWidth ) );
483  margin = std::max( startMarkerMargin, margin );
484  }
485 
486  if ( mEndMarker == SvgMarker )
487  {
488  double endMarkerMargin = std::sqrt( 0.25 * ( mEndArrowHeadHeight * mEndArrowHeadHeight + mArrowHeadWidth * mArrowHeadWidth ) );
489  margin = std::max( endMarkerMargin, margin );
490  }
491 
492  return margin;
493 }
double arrowHeadWidth() const
Returns the width of line arrow heads in mm.
double computeDistance(QPointF pt1, QPointF pt2) const
Compute an euclidian distance between 2 nodes.
The class is used as a container of context for various read/write operations on other objects...
static QgsSvgCache * svgCache()
Returns the application&#39;s SVG cache, used for caching SVG images and handling parameter replacement w...
void setStartMarker(MarkerMode mode)
Sets the start marker mode, which controls what marker is drawn at the start of the line...
void updateSceneRect()
Update the current scene rectangle for this item.
A symbol entity for QgsStyle databases.
Definition: qgsstyle.h:971
bool _removeNode(int nodeIndex) override
Method called in removeNode.
bool readPropertiesFromElement(const QDomElement &element, const QDomDocument &document, const QgsReadWriteContext &context) override
Sets item state from a DOM element.
void setArrowHeadWidth(double width)
Sets the width of line arrow heads in mm.
void _writeXmlStyle(QDomDocument &doc, QDomElement &elmt, const QgsReadWriteContext &context) const override
Method called in writeXml.
QRectF mCurrentRectangle
Current bounding rectangle of shape.
void setArrowHeadFillColor(const QColor &color)
Sets the color used to fill the arrow head.
static QgsLineSymbol * createSimple(const QgsStringMap &properties)
Create a line symbol with one symbol layer: SimpleLine with specified properties. ...
Definition: qgssymbol.cpp:1240
void setStartSvgMarkerPath(const QString &path)
Sets the path to a SVG marker to draw at the start of the line.
MarkerMode
Vertex marker mode.
An abstract layout item that provides generic methods for node based shapes such as polygon or polyli...
QString displayName() const override
Gets item display name.
double mMaxSymbolBleed
Max symbol bleed.
QPainterPath shape() const override
void setEndSvgMarkerPath(const QString &path)
Sets the path to a SVG marker to draw at the end of the line.
bool writePropertiesToElement(QDomElement &element, QDomDocument &document, const QgsReadWriteContext &context) const override
Stores item state within an XML DOM element.
static QIcon getThemeIcon(const QString &name)
Helper to get a theme icon.
static QDomElement saveSymbol(const QString &symbolName, const QgsSymbol *symbol, QDomDocument &doc, const QgsReadWriteContext &context)
Writes a symbol definition to XML.
QPolygonF mPolygon
Shape&#39;s nodes.
An interface for classes which can visit style entity (e.g.
QByteArray svgContent(const QString &path, double size, const QColor &fill, const QColor &stroke, double strokeWidth, double widthScaleFactor, double fixedAspectRatio=0, bool blocking=false)
Gets SVG content.
QgsLayoutRenderContext & renderContext()
Returns a reference to the layout&#39;s render context, which stores information relating to the current ...
Definition: qgslayout.cpp:358
QMap< QString, QString > QgsStringMap
Definition: qgis.h:612
bool _addNode(int indexPoint, QPointF newPoint, double radius) override
Method called in addNode.
double ANALYSIS_EXPORT angle(QgsPoint *p1, QgsPoint *p2, QgsPoint *p3, QgsPoint *p4)
Calculates the angle between two segments (in 2 dimension, z-values are ignored)
Definition: MathUtils.cpp:786
void setSymbol(QgsLineSymbol *symbol)
Sets the symbol used to draw the shape.
A line symbol type, for rendering LineString and MultiLineString geometries.
Definition: qgssymbol.h:1060
virtual bool visit(const QgsStyleEntityVisitorInterface::StyleLeaf &entity)
Called when the visitor will visit a style entity.
static QString encodeColor(const QColor &color)
int type() const override
QgsLineSymbol * symbol()
Returns the line symbol used to draw the shape.
void _readXmlStyle(const QDomElement &elmt, const QgsReadWriteContext &context) override
Method called in readXml.
void setArrowHeadStrokeColor(const QColor &color)
Sets the color used to draw the stroke around the arrow head.
void setEndMarker(MarkerMode mode)
Sets the end marker mode, which controls what marker is drawn at the end of the line.
void frameChanged()
Emitted if the item&#39;s frame style changes.
static QString svgSymbolPathToName(const QString &path, const QgsPathResolver &pathResolver)
Determines an SVG symbol&#39;s name from its path.
void setArrowHeadStrokeWidth(double width)
Sets the pen width in millimeters for the stroke of the arrow head.
Layout item for node based polyline shapes.
QIcon icon() const override
Returns the item&#39;s icon.
const QgsLayout * layout() const
Returns the layout the object is attached to.
double dpi() const
Returns the dpi for outputting the layout.
QgsRenderContext & renderContext()
Returns a reference to the context&#39;s render context.
Definition: qgslayoutitem.h:72
bool readPropertiesFromElement(const QDomElement &element, const QDomDocument &document, const QgsReadWriteContext &context) override
Sets item state from a DOM element.
static QgsRenderContext createRenderContextForLayout(QgsLayout *layout, QPainter *painter, double dpi=-1)
Creates a render context suitable for the specified layout and painter destination.
static double estimateMaxSymbolBleed(QgsSymbol *symbol, const QgsRenderContext &context)
Returns the maximum estimated bleed for the symbol.
QString id() const
Returns the item&#39;s ID name.
Base class for layouts, which can contain items such as maps, labels, scalebars, etc.
Definition: qgslayout.h:49
void _draw(QgsLayoutItemRenderContext &context, const QStyleOptionGraphicsItem *itemStyle=nullptr) override
Method called in paint.
static QgsLayoutItemPolyline * create(QgsLayout *layout)
Returns a new polyline item for the specified layout.
bool setSelectedNode(int index)
Selects a node by index.
Contains settings and helpers relating to a render of a QgsLayoutItem.
Definition: qgslayoutitem.h:44
const QgsPathResolver & pathResolver() const
Returns path resolver for conversion between relative and absolute paths.
bool accept(QgsStyleEntityVisitorInterface *visitor) const override
Accepts the specified style entity visitor, causing it to visit all style entities associated with th...
Contains information about the context of a rendering operation.
double convertToPainterUnits(double size, QgsUnitTypes::RenderUnit unit, const QgsMapUnitScale &scale=QgsMapUnitScale()) const
Converts a size from the specified units to painter units (pixels).
QPainter * painter()
Returns the destination QPainter for the render operation.
virtual QString uuid() const
Returns the item identification string.
QgsLayoutItemPolyline(QgsLayout *layout)
Constructor for QgsLayoutItemPolyline for the specified layout.
static QString svgSymbolNameToPath(const QString &name, const QgsPathResolver &pathResolver)
Determines an SVG symbol&#39;s path from its name.
double scaleFactor() const
Returns the scaling factor for the render to convert painter units to physical sizes.
bool writePropertiesToElement(QDomElement &element, QDomDocument &document, const QgsReadWriteContext &context) const override
Stores item state within an XML DOM element.
Contains information relating to the style entity currently being visited.
static QColor decodeColor(const QString &str)
QgsLineSymbol * clone() const override
Returns a deep copy of this symbol.
Definition: qgssymbol.cpp:1951