1
|
Index: src/core/symbology/qgsmarkercatalogue.cpp
|
2
|
===================================================================
|
3
|
--- src/core/symbology/qgsmarkercatalogue.cpp (revision 9611)
|
4
|
+++ src/core/symbology/qgsmarkercatalogue.cpp (working copy)
|
5
|
@@ -14,7 +14,6 @@
|
6
|
* *
|
7
|
***************************************************************************/
|
8
|
#include <cmath>
|
9
|
-#include <iostream>
|
10
|
#include <assert.h>
|
11
|
|
12
|
#include <QPen>
|
13
|
@@ -24,7 +23,8 @@
|
14
|
#include <QString>
|
15
|
#include <QStringList>
|
16
|
#include <QRect>
|
17
|
-#include <QPolygon>
|
18
|
+#include <QPointF>
|
19
|
+#include <QPolygonF>
|
20
|
#include <QDir>
|
21
|
#include <QPicture>
|
22
|
#include <QSvgRenderer>
|
23
|
@@ -34,6 +34,13 @@
|
24
|
#include "qgsmarkercatalogue.h"
|
25
|
#include "qgslogger.h"
|
26
|
|
27
|
+// MSVC compiler doesn't have defined M_PI in math.h
|
28
|
+#ifndef M_PI
|
29
|
+#define M_PI 3.14159265358979323846
|
30
|
+#endif
|
31
|
+
|
32
|
+#define DEG2RAD(x) ((x)*M_PI/180)
|
33
|
+
|
34
|
//#define IMAGEDEBUG
|
35
|
|
36
|
QgsMarkerCatalogue *QgsMarkerCatalogue::mMarkerCatalogue = 0;
|
37
|
@@ -46,10 +53,13 @@
|
38
|
mList.append( "hard:circle" );
|
39
|
mList.append( "hard:rectangle" );
|
40
|
mList.append( "hard:diamond" );
|
41
|
+ mList.append( "hard:pentagon" );
|
42
|
mList.append( "hard:cross" );
|
43
|
mList.append( "hard:cross2" );
|
44
|
mList.append( "hard:triangle" );
|
45
|
+ mList.append( "hard:equilateral_triangle" );
|
46
|
mList.append( "hard:star" );
|
47
|
+ mList.append( "hard:regular_star" );
|
48
|
mList.append( "hard:arrow" );
|
49
|
|
50
|
// SVG
|
51
|
@@ -109,16 +119,20 @@
|
52
|
}
|
53
|
|
54
|
QImage myImage;
|
55
|
+ int imageSize;
|
56
|
if ( fullName.left( 5 ) == "hard:" )
|
57
|
{
|
58
|
- myImage = QImage( size + 1, size + 1, QImage::Format_ARGB32_Premultiplied );
|
59
|
+ int pw = ( ( pen.width()==0 ? 1 : pen.width() ) + 1 ) / 2 * 2; // make even (round up); handle cosmetic pen
|
60
|
+ imageSize = ( (int) size + pw ) / 2 * 2 + 1; // make image width, height odd; account for pen width
|
61
|
+ myImage = QImage( imageSize, imageSize, QImage::Format_ARGB32_Premultiplied );
|
62
|
}
|
63
|
else
|
64
|
{
|
65
|
// TODO Change this logic so width is size and height is same
|
66
|
// proportion of scale factor as in oritignal SVG TS XXX
|
67
|
//QPixmap myPixmap = QPixmap(width,height);
|
68
|
- myImage = QImage( size, size, QImage::Format_ARGB32_Premultiplied );
|
69
|
+ imageSize = ( (int) size ) / 2 * 2 + 1; // make image width, height odd
|
70
|
+ myImage = QImage( imageSize, imageSize, QImage::Format_ARGB32_Premultiplied );
|
71
|
}
|
72
|
|
73
|
// starting with transparent QImage
|
74
|
@@ -134,7 +148,7 @@
|
75
|
|
76
|
if ( fullName.left( 5 ) == "hard:" )
|
77
|
{
|
78
|
- hardMarker( &myPainter, fullName.mid( 5 ), size, pen, brush, qtBug );
|
79
|
+ hardMarker( &myPainter, imageSize, fullName.mid( 5 ), size, pen, brush, qtBug );
|
80
|
#ifdef IMAGEDEBUG
|
81
|
QgsDebugMsg( "*** Saving hard marker to hardMarker.png ***" );
|
82
|
#ifdef QGISDEBUG
|
83
|
@@ -181,7 +195,7 @@
|
84
|
|
85
|
if ( fullName.left( 5 ) == "hard:" )
|
86
|
{
|
87
|
- hardMarker( &myPainter, fullName.mid( 5 ), size, pen, brush, qtBug );
|
88
|
+ hardMarker( &myPainter, (int) size, fullName.mid( 5 ), size, pen, brush, qtBug );
|
89
|
return myPicture;
|
90
|
}
|
91
|
else if ( fullName.left( 4 ) == "svg:" )
|
92
|
@@ -199,30 +213,30 @@
|
93
|
mySVG.render( thepPainter );
|
94
|
}
|
95
|
|
96
|
-void QgsMarkerCatalogue::hardMarker( QPainter * thepPainter, QString name, double s, QPen pen, QBrush brush, bool qtBug )
|
97
|
+void QgsMarkerCatalogue::hardMarker( QPainter * thepPainter, int imageSize, QString name, double s, QPen pen, QBrush brush, bool qtBug )
|
98
|
{
|
99
|
// Size of polygon symbols is calculated so that the boundingbox is circumscribed
|
100
|
// around a circle with diameter mPointSize
|
101
|
|
102
|
- double half = s / 2; // number of points from center
|
103
|
+#if 0
|
104
|
+ s = s - pen.widthF(); // to make the overall size of the symbol at the specified size
|
105
|
+#else
|
106
|
+ // the size of the base symbol is at the specified size; the outline is applied additionally
|
107
|
+#endif
|
108
|
|
109
|
+ // Circle radius, is used for other figures also, when compensating for line
|
110
|
+ // width is necessary.
|
111
|
+ double r = s / 2; // get half the size of the figure to be rendered (the radius)
|
112
|
+
|
113
|
QgsDebugMsg( QString( "Hard marker size %1" ).arg( s ) );
|
114
|
|
115
|
- // Find out center coordinates.
|
116
|
- double x_c = s / 2;
|
117
|
- double y_c = x_c;
|
118
|
+ // Find out center coordinates of the QImage to draw on.
|
119
|
+ double x_c = (double) ( imageSize / 2 ) + 0.5; // add 1/2 pixel for proper rounding when the figure's coordinates are added
|
120
|
+ double y_c = x_c; // is square image
|
121
|
|
122
|
- // Also width must be odd otherwise there are discrepancies visible in canvas!
|
123
|
- double lw = pen.widthF();//(int)(2*floor((double)pen.widthF()/2)+1); // -> lw > 0
|
124
|
- pen.setWidthF( lw );
|
125
|
thepPainter->setPen( pen );
|
126
|
thepPainter->setBrush( brush );
|
127
|
- QRect box;
|
128
|
|
129
|
- // Circle radius, is used for other figures also, when compensating for line
|
130
|
- // width is necessary.
|
131
|
-
|
132
|
- int r = ( s - 2 * lw ) / 2 - 1;
|
133
|
QgsDebugMsg( QString( "Hard marker radius %1" ).arg( r ) );
|
134
|
|
135
|
// If radius is 0, draw a circle, so it wont disappear.
|
136
|
@@ -230,80 +244,106 @@
|
137
|
{
|
138
|
// "A stroked ellipse has a size of rectangle.size() plus the pen width."
|
139
|
// (from Qt doc)
|
140
|
- // It doesn't seem like it is centered, however. Fudge...
|
141
|
- // Is this a Qt bug or feature?
|
142
|
- x_c -= (( lw + 5 ) / 4 );
|
143
|
- y_c -= (( lw + 5 ) / 4 );
|
144
|
|
145
|
- thepPainter->drawEllipse( QRectF( x_c - r, y_c - r, x_c + r, y_c + r ) );
|
146
|
+ thepPainter->drawEllipse( QRectF( x_c - r, y_c - r, s, s ) ); // x,y,w,h
|
147
|
}
|
148
|
else if ( name == "rectangle" )
|
149
|
{
|
150
|
- // Same fudge as for circle...
|
151
|
- x_c -= (( lw + 5 ) / 4 );
|
152
|
- y_c -= (( lw + 5 ) / 4 );
|
153
|
-
|
154
|
- thepPainter->drawRect( x_c - r, y_c - r, x_c + r, y_c + r );
|
155
|
+ thepPainter->drawRect( QRectF( x_c - r, y_c - r, s, s ) ); // x,y,w,h
|
156
|
}
|
157
|
else if ( name == "diamond" )
|
158
|
{
|
159
|
- QPolygon pa( 4 );
|
160
|
- pa.setPoint( 0, x_c - r, y_c );
|
161
|
- pa.setPoint( 1, x_c, y_c + r );
|
162
|
- pa.setPoint( 2, x_c + r, y_c );
|
163
|
- pa.setPoint( 3, x_c, y_c - r );
|
164
|
+ QPolygonF pa;
|
165
|
+ pa << QPointF( x_c - r, y_c )
|
166
|
+ << QPointF( x_c, y_c + r )
|
167
|
+ << QPointF( x_c + r, y_c )
|
168
|
+ << QPointF( x_c, y_c - r );
|
169
|
thepPainter->drawPolygon( pa );
|
170
|
}
|
171
|
+ else if ( name == "pentagon" )
|
172
|
+ {
|
173
|
+ QPolygonF pa;
|
174
|
+ pa << QPointF( x_c + ( r * sin( DEG2RAD( 288.0 ) ) ), y_c - ( r * cos( DEG2RAD( 288.0 ) ) ) )
|
175
|
+ << QPointF( x_c + ( r * sin( DEG2RAD( 216.0 ) ) ), y_c - ( r * cos( DEG2RAD( 216.0 ) ) ) )
|
176
|
+ << QPointF( x_c + ( r * sin( DEG2RAD( 144.0 ) ) ), y_c - ( r * cos( DEG2RAD( 144.0 ) ) ) )
|
177
|
+ << QPointF( x_c + ( r * sin( DEG2RAD( 72.0 ) ) ), y_c - ( r * cos( DEG2RAD( 72.0 ) ) ) )
|
178
|
+ << QPointF( x_c, y_c - r );
|
179
|
+ thepPainter->drawPolygon( pa );
|
180
|
+ }
|
181
|
else if ( name == "cross" )
|
182
|
{
|
183
|
- thepPainter->drawLine( x_c - half, y_c, x_c + half, y_c ); // horizontal
|
184
|
- thepPainter->drawLine( x_c, y_c - half, x_c, y_c + half ); // vertical
|
185
|
+ thepPainter->drawLine( QPointF( x_c - r, y_c ), QPointF( x_c + r, y_c ) ); // horizontal
|
186
|
+ thepPainter->drawLine( QPointF( x_c, y_c - r ), QPointF( x_c, y_c + r ) ); // vertical
|
187
|
}
|
188
|
else if ( name == "cross2" )
|
189
|
{
|
190
|
- thepPainter->drawLine( x_c - half, y_c - half, x_c + half, y_c + half );
|
191
|
- thepPainter->drawLine( x_c - half, y_c + half, x_c + half, y_c - half );
|
192
|
+ thepPainter->drawLine( QPointF( x_c - r, y_c - r ), QPointF( x_c + r, y_c + r ) );
|
193
|
+ thepPainter->drawLine( QPointF( x_c - r, y_c + r ), QPointF( x_c + r, y_c - r ) );
|
194
|
}
|
195
|
else if ( name == "triangle" )
|
196
|
{
|
197
|
- QPolygon pa( 3 );
|
198
|
-
|
199
|
- pa.setPoint( 0, x_c - r, y_c + r );
|
200
|
- pa.setPoint( 1, x_c + r, y_c + r );
|
201
|
- pa.setPoint( 2, x_c, y_c - r );
|
202
|
+ QPolygonF pa;
|
203
|
+ pa << QPointF( x_c - r, y_c + r )
|
204
|
+ << QPointF( x_c + r, y_c + r )
|
205
|
+ << QPointF( x_c, y_c - r );
|
206
|
thepPainter->drawPolygon( pa );
|
207
|
}
|
208
|
+ else if ( name == "equilateral_triangle" )
|
209
|
+ {
|
210
|
+ QPolygonF pa;
|
211
|
+ pa << QPointF( x_c + ( r * sin( DEG2RAD( 240.0 ) ) ), y_c - ( r * cos( DEG2RAD( 240.0 ) ) ) )
|
212
|
+ << QPointF( x_c + ( r * sin( DEG2RAD( 120.0 ) ) ), y_c - ( r * cos( DEG2RAD( 120.0 ) ) ) )
|
213
|
+ << QPointF( x_c, y_c - r ); // 0
|
214
|
+ thepPainter->drawPolygon( pa );
|
215
|
+ }
|
216
|
else if ( name == "star" )
|
217
|
{
|
218
|
- int oneSixth = 2 * r / 6;
|
219
|
+ double oneSixth = 2 * r / 6;
|
220
|
|
221
|
- QPolygon pa( 10 );
|
222
|
- pa.setPoint( 0, x_c, y_c - half );
|
223
|
- pa.setPoint( 1, x_c - oneSixth, y_c - oneSixth );
|
224
|
- pa.setPoint( 2, x_c - half, y_c - oneSixth );
|
225
|
- pa.setPoint( 3, x_c - oneSixth, y_c );
|
226
|
- pa.setPoint( 4, x_c - half, y_c + half );
|
227
|
- pa.setPoint( 5, x_c, y_c + oneSixth );
|
228
|
- pa.setPoint( 6, x_c + half, y_c + half );
|
229
|
- pa.setPoint( 7, x_c + oneSixth, y_c );
|
230
|
- pa.setPoint( 8, x_c + half, y_c - oneSixth );
|
231
|
- pa.setPoint( 9, x_c + oneSixth, y_c - oneSixth );
|
232
|
+ QPolygonF pa;
|
233
|
+ pa << QPointF( x_c, y_c - r )
|
234
|
+ << QPointF( x_c - oneSixth, y_c - oneSixth )
|
235
|
+ << QPointF( x_c - r, y_c - oneSixth )
|
236
|
+ << QPointF( x_c - oneSixth, y_c )
|
237
|
+ << QPointF( x_c - r, y_c + r )
|
238
|
+ << QPointF( x_c, y_c + oneSixth )
|
239
|
+ << QPointF( x_c + r, y_c + r )
|
240
|
+ << QPointF( x_c + oneSixth, y_c )
|
241
|
+ << QPointF( x_c + r, y_c - oneSixth )
|
242
|
+ << QPointF( x_c + oneSixth, y_c - oneSixth );
|
243
|
thepPainter->drawPolygon( pa );
|
244
|
}
|
245
|
+ else if ( name == "regular_star" )
|
246
|
+ {
|
247
|
+ // control the 'fatness' of the star: cos(72)/cos(36) gives the classic star shape
|
248
|
+ double inner_r = r * cos( DEG2RAD( 72.0 ) ) / cos( DEG2RAD( 36.0 ) );
|
249
|
|
250
|
+ QPolygonF pa;
|
251
|
+ pa << QPointF( x_c + ( inner_r * sin( DEG2RAD( 324.0 ) ) ), y_c - ( inner_r * cos( DEG2RAD( 324.0 ) ) ) ) // 324
|
252
|
+ << QPointF( x_c + ( r * sin( DEG2RAD( 288.0 ) ) ), y_c - ( r * cos( DEG2RAD( 288 ) ) ) ) // 288
|
253
|
+ << QPointF( x_c + ( inner_r * sin( DEG2RAD( 252.0 ) ) ), y_c - ( inner_r * cos( DEG2RAD( 252.0 ) ) ) ) // 252
|
254
|
+ << QPointF( x_c + ( r * sin( DEG2RAD( 216.0 ) ) ), y_c - ( r * cos( DEG2RAD( 216.0 ) ) ) ) // 216
|
255
|
+ << QPointF( x_c, y_c + ( inner_r ) ) // 180
|
256
|
+ << QPointF( x_c + ( r * sin( DEG2RAD( 144.0 ) ) ), y_c - ( r * cos( DEG2RAD( 144.0 ) ) ) ) // 144
|
257
|
+ << QPointF( x_c + ( inner_r * sin( DEG2RAD( 108.0 ) ) ), y_c - ( inner_r * cos( DEG2RAD( 108.0 ) ) ) ) // 108
|
258
|
+ << QPointF( x_c + ( r * sin( DEG2RAD( 72.0 ) ) ), y_c - ( r * cos( DEG2RAD( 72.0 ) ) ) ) // 72
|
259
|
+ << QPointF( x_c + ( inner_r * sin( DEG2RAD( 36.0 ) ) ), y_c - ( inner_r * cos( DEG2RAD( 36.0 ) ) ) ) // 36
|
260
|
+ << QPointF( x_c, y_c - r ); // 0
|
261
|
+ thepPainter->drawPolygon( pa );
|
262
|
+ }
|
263
|
else if ( name == "arrow" )
|
264
|
{
|
265
|
- int oneEight = r / 4;
|
266
|
- int quarter = r / 2;
|
267
|
+ double oneEight = r / 4;
|
268
|
+ double quarter = r / 2;
|
269
|
|
270
|
- QPolygon pa( 7 );
|
271
|
- pa.setPoint( 0, x_c, y_c - r );
|
272
|
- pa.setPoint( 1, x_c + quarter, y_c - quarter );
|
273
|
- pa.setPoint( 2, x_c + oneEight, y_c - quarter );
|
274
|
- pa.setPoint( 3, x_c + oneEight, y_c + r );
|
275
|
- pa.setPoint( 4, x_c - oneEight, y_c + r );
|
276
|
- pa.setPoint( 5, x_c - oneEight, y_c - quarter );
|
277
|
- pa.setPoint( 6, x_c - quarter, y_c - quarter );
|
278
|
+ QPolygonF pa;
|
279
|
+ pa << QPointF( x_c, y_c - r )
|
280
|
+ << QPointF( x_c + quarter, y_c - quarter )
|
281
|
+ << QPointF( x_c + oneEight, y_c - quarter )
|
282
|
+ << QPointF( x_c + oneEight, y_c + r )
|
283
|
+ << QPointF( x_c - oneEight, y_c + r )
|
284
|
+ << QPointF( x_c - oneEight, y_c - quarter )
|
285
|
+ << QPointF( x_c - quarter, y_c - quarter );
|
286
|
thepPainter->drawPolygon( pa );
|
287
|
}
|
288
|
thepPainter->end();
|
289
|
Index: src/core/symbology/qgsmarkercatalogue.h
|
290
|
===================================================================
|
291
|
--- src/core/symbology/qgsmarkercatalogue.h (revision 9611)
|
292
|
+++ src/core/symbology/qgsmarkercatalogue.h (working copy)
|
293
|
@@ -64,7 +64,7 @@
|
294
|
QStringList mList;
|
295
|
|
296
|
/** Hard coded */
|
297
|
- void hardMarker( QPainter * thepPainter, QString name, double size, QPen pen, QBrush brush, bool qtBug = true );
|
298
|
+ void hardMarker( QPainter * thepPainter, int imageSize, QString name, double size, QPen pen, QBrush brush, bool qtBug = true );
|
299
|
|
300
|
};
|
301
|
|