patch_for_1262.txt

patches QgsMarkerCatalogue - Steven Mizuno, 2008-11-13 06:12 PM

Download (11.9 KB)

 
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