11 #include <QSvgRenderer>
19 #define M_PI 3.14159265358979323846
22 #define DEG2RAD(x) ((x)*M_PI/180)
28 double c = cos( angle ), s = sin( angle );
29 return QPointF( offset.x() * c - offset.y() * s, offset.x() * s + offset.y() * c );
52 if ( props.contains(
"name" ) )
54 if ( props.contains(
"color" ) )
56 if ( props.contains(
"color_border" ) )
58 if ( props.contains(
"size" ) )
59 size = props[
"size"].toDouble();
60 if ( props.contains(
"angle" ) )
61 angle = props[
"angle"].toDouble();
64 if ( props.contains(
"offset" ) )
72 return "SimpleMarker";
77 QColor brushColor =
mColor;
79 if ( context.
alpha() < 1 )
81 penColor.setAlphaF( context.
alpha() );
82 brushColor.setAlphaF( context.
alpha() );
84 mBrush = QBrush( brushColor );
85 mPen = QPen( penColor );
90 if ( context.
alpha() < 1 )
92 selBrushColor.setAlphaF( context.
alpha() );
93 selPenColor.setAlphaF( context.
alpha() );
116 if (
mName !=
"circle" )
117 mSelPen.setColor( selBrushColor );
129 if ( !hasDataDefinedSize )
134 double half = scaledSize / 2.0;
135 transform.scale( half, half );
139 if ( !hasDataDefinedRotation &&
mAngle != 0 )
141 transform.rotate(
mAngle );
166 double pw = ((
mPen.widthF() == 0 ? 1 :
mPen.widthF() ) + 1 ) / 2 * 2;
167 int imageSize = (( int ) scaledSize + pw ) / 2 * 2 + 1;
169 double center = (( double ) imageSize / 2 ) + 0.5;
171 mCache = QImage( QSize( imageSize, imageSize ), QImage::Format_ARGB32_Premultiplied );
176 p.setRenderHint( QPainter::Antialiasing );
179 p.translate( QPointF( center, center ) );
187 mSelCache = QImage( QSize( imageSize, imageSize ), QImage::Format_ARGB32_Premultiplied );
191 p.setRenderHint( QPainter::Antialiasing );
194 p.translate( QPointF( center, center ) );
205 p.setRenderHint( QPainter::Antialiasing );
206 p.fillRect( 0, 0, imageSize, imageSize, selColor );
209 p.translate( QPointF( center, center ) );
223 if (
mName ==
"rectangle" )
225 mPolygon = QPolygonF( QRectF( QPointF( -1, -1 ), QPointF( 1, 1 ) ) );
228 else if (
mName ==
"diamond" )
230 mPolygon << QPointF( -1, 0 ) << QPointF( 0, 1 )
231 << QPointF( 1, 0 ) << QPointF( 0, -1 );
234 else if (
mName ==
"pentagon" )
243 else if (
mName ==
"triangle" )
245 mPolygon << QPointF( -1, 1 ) << QPointF( 1, 1 ) << QPointF( 0, -1 );
248 else if (
mName ==
"equilateral_triangle" )
255 else if (
mName ==
"star" )
257 double sixth = 1.0 / 3;
260 << QPointF( -sixth, -sixth )
261 << QPointF( -1, -sixth )
262 << QPointF( -sixth, 0 )
264 << QPointF( 0, + sixth )
266 << QPointF( + sixth, 0 )
267 << QPointF( 1, -sixth )
268 << QPointF( + sixth, -sixth );
271 else if (
mName ==
"regular_star" )
277 << QPointF( inner_r * sin(
DEG2RAD( 252.0 ) ), - inner_r * cos(
DEG2RAD( 252.0 ) ) )
279 << QPointF( 0, inner_r )
281 << QPointF( inner_r * sin(
DEG2RAD( 108.0 ) ), - inner_r * cos(
DEG2RAD( 108.0 ) ) )
283 << QPointF( inner_r * sin(
DEG2RAD( 36.0 ) ), - inner_r * cos(
DEG2RAD( 36.0 ) ) )
287 else if (
mName ==
"arrow" )
291 << QPointF( 0.5, -0.5 )
292 << QPointF( 0.25, -0.25 )
293 << QPointF( 0.25, 1 )
294 << QPointF( -0.25, 1 )
295 << QPointF( -0.25, -0.5 )
296 << QPointF( -0.5, -0.5 );
299 else if (
mName ==
"filled_arrowhead" )
301 mPolygon << QPointF( 0, 0 ) << QPointF( -1, 1 ) << QPointF( -1, -1 );
310 mPath = QPainterPath();
312 if (
mName ==
"circle" )
314 mPath.addEllipse( QRectF( -1, -1, 2, 2 ) );
317 else if (
mName ==
"cross" )
319 mPath.moveTo( -1, 0 );
320 mPath.lineTo( 1, 0 );
321 mPath.moveTo( 0, -1 );
322 mPath.lineTo( 0, 1 );
325 else if (
mName ==
"cross2" )
327 mPath.moveTo( -1, -1 );
328 mPath.lineTo( 1, 1 );
329 mPath.moveTo( 1, -1 );
330 mPath.lineTo( -1, 1 );
333 else if (
mName ==
"line" )
335 mPath.moveTo( 0, -1 );
336 mPath.lineTo( 0, 1 );
339 else if (
mName ==
"arrowhead" )
341 mPath.moveTo( 0, 0 );
342 mPath.lineTo( -1, -1 );
343 mPath.moveTo( 0, 0 );
344 mPath.lineTo( -1, 1 );
369 p->drawImage( QRectF( point.x() - s / 2.0 + off.x(),
370 point.y() - s / 2.0 + off.y(),
381 transform.translate( point.x() + off.x(), point.y() + off.y() );
384 if ( hasDataDefinedSize )
387 double half = scaledSize / 2.0;
388 transform.scale( half, half );
394 transform.rotate(
mAngle );
401 p->drawPolygon( transform.map(
mPolygon ) );
403 p->drawPath( transform.map(
mPath ) );
414 map[
"size"] = QString::number(
mSize );
415 map[
"angle"] = QString::number(
mAngle );
435 p->drawPath(
mPath );
458 if ( props.contains(
"name" ) )
459 name = props[
"name"];
460 if ( props.contains(
"size" ) )
461 size = props[
"size"].toDouble();
462 if ( props.contains(
"angle" ) )
463 angle = props[
"angle"].toDouble();
466 if ( props.contains(
"offset" ) )
479 double pictureSize = 0;
491 QRectF rect( QPointF( -pictureSize / 2.0, -pictureSize / 2.0 ), QSizeF( pictureSize, pictureSize ) );
492 QSvgRenderer renderer(
mPath );
494 renderer.render( &painter, rect );
496 selPainter.setRenderHint( QPainter::Antialiasing );
498 selPainter.setPen( Qt::NoPen );
499 selPainter.drawEllipse( QPointF( 0, 0 ), pictureSize*0.6, pictureSize*0.6 );
500 renderer.render( &selPainter, rect );
522 p->translate( point + outputOffset );
534 p->drawPicture( 0, 0, pct );
544 map[
"size"] = QString::number(
mSize );
545 map[
"angle"] = QString::number(
mAngle );
564 for (
int i = 0; i < svgPaths.size(); i++ )
566 QDir dir( svgPaths[i] );
567 foreach( QString item, dir.entryList( QDir::Dirs | QDir::NoDotAndDotDot ) )
569 svgPaths.insert( i + 1, dir.path() +
"/" + item );
572 foreach( QString item, dir.entryList( QStringList(
"*.svg" ), QDir::Files ) )
575 list.append( dir.path() +
"/" + item );
586 if ( QFile( name ).exists() )
587 return QFileInfo( name ).canonicalFilePath();
592 for (
int i = 0; i < svgPaths.size(); i++ )
595 QFileInfo myInfo( name );
596 QString myFileName = myInfo.fileName();
597 QString myLowestDir = myInfo.dir().dirName();
598 QString myLocalPath = svgPaths[i] +
"/" + myLowestDir +
"/" + myFileName;
600 QgsDebugMsg(
"Alternative svg path: " + myLocalPath );
601 if ( QFile( myLocalPath ).exists() )
604 return QFileInfo( myLocalPath ).canonicalFilePath();
606 else if ( myInfo.isRelative() )
609 QString alternatePath = pfi.canonicalPath() + QDir::separator() + name;
610 if ( pfi.exists() && QFile( alternatePath ).exists() )
613 return QFileInfo( alternatePath ).canonicalFilePath();
623 QgsDebugMsg(
"Computed alternate path but no svg there either" );
633 QFileInfo fi( path );
637 path = fi.canonicalFilePath();
641 for (
int i = 0; i < svgPaths.size(); i++ )
643 QString dir = QFileInfo( svgPaths[i] ).canonicalFilePath();
645 if ( !dir.isEmpty() && path.startsWith( dir ) )
647 path = path.mid( dir.size() );
676 if ( props.contains(
"font" ) )
677 fontFamily = props[
"font"];
678 if ( props.contains(
"chr" ) && props[
"chr"].length() > 0 )
679 chr = props[
"chr"].at( 0 );
680 if ( props.contains(
"size" ) )
681 pointSize = props[
"size"].toDouble();
682 if ( props.contains(
"color" ) )
684 if ( props.contains(
"angle" ) )
685 angle = props[
"angle"].toDouble();
688 if ( props.contains(
"offset" ) )
702 QFontMetrics fm(
mFont );
716 penColor.setAlphaF( context.
alpha() );
717 p->setPen( penColor );
725 p->translate( point + outputOffset );
745 props[
"size"] = QString::number(
mSize );
747 props[
"angle"] = QString::number(
mAngle );