6
6
#include < QPainter>
7
7
#include < cmath>
8
8
9
- const int RULER_MIN_SIZE = 20 ;
9
+ const int RULER_FONT_SIZE = 8 ;
10
10
const int COUNT_VALID_MULTIPLES = 3 ;
11
11
const int COUNT_VALID_MAGNITUDES = 5 ;
12
12
const int QgsComposerRuler::validScaleMultiples[] = {1 , 2 , 5 };
13
13
const int QgsComposerRuler::validScaleMagnitudes[] = {1 , 10 , 100 , 1000 , 10000 };
14
14
15
- QgsComposerRuler::QgsComposerRuler ( QgsComposerRuler::Direction d ): QWidget( 0 ), mDirection( d ), mComposition( 0 ), mLineSnapItem( 0 )
15
+ QgsComposerRuler::QgsComposerRuler ( QgsComposerRuler::Direction d ) : QWidget( 0 ),
16
+ mDirection( d ),
17
+ mComposition( 0 ),
18
+ mLineSnapItem( 0 ),
19
+ mScaleMinPixelsWidth( 0 )
16
20
{
17
21
setMouseTracking ( true );
22
+
23
+ // calculate minimum size required for ruler text
24
+ mRulerFont = new QFont ();
25
+ mRulerFont ->setPointSize ( RULER_FONT_SIZE );
26
+ mRulerFontMetrics = new QFontMetrics ( *mRulerFont );
27
+
28
+ // calculate ruler sizes and marker seperations
29
+
30
+ // minimum gap required between major ticks is 3 digits * 250%, based on appearance
31
+ mScaleMinPixelsWidth = mRulerFontMetrics ->width ( " 000" ) * 2.5 ;
32
+ // minimum ruler height is twice the font height in pixels
33
+ mRulerMinSize = mRulerFontMetrics ->height () * 1.5 ;
34
+
35
+ mMinPixelsPerDivision = mRulerMinSize / 4 ;
36
+ // each small division must be at least 2 pixels apart
37
+ if ( mMinPixelsPerDivision < 2 )
38
+ mMinPixelsPerDivision = 2 ;
39
+
40
+ mPixelsBetweenLineAndText = mRulerMinSize / 10 ;
41
+ mTextBaseline = mRulerMinSize / 1.667 ;
42
+ mMinSpacingVerticalLabels = mRulerMinSize / 5 ;
18
43
}
19
44
20
45
QgsComposerRuler::~QgsComposerRuler ()
21
46
{
47
+ delete mRulerFontMetrics ;
48
+ delete mRulerFont ;
22
49
}
23
50
24
51
QSize QgsComposerRuler::minimumSizeHint () const
25
52
{
26
- return QSize ( RULER_MIN_SIZE, RULER_MIN_SIZE );
53
+ return QSize ( mRulerMinSize , mRulerMinSize );
27
54
}
28
55
29
56
void QgsComposerRuler::paintEvent ( QPaintEvent* event )
@@ -38,19 +65,13 @@ void QgsComposerRuler::paintEvent( QPaintEvent* event )
38
65
39
66
QTransform t = mTransform .inverted ();
40
67
41
- // calculate minimum size required for ruler text
42
- QFont rulerFont = p.font ();
43
- rulerFont.setPointSize ( 8 );
44
- QFontMetrics rulerFontMetrics ( rulerFont );
45
- // minimum gap required between major ticks is 3 digits * 250%
46
- double minFontPixelsWidth = rulerFontMetrics.width ( " 000" ) * 2.5 ;
47
- p.setFont ( rulerFont );
68
+ p.setFont ( *mRulerFont );
48
69
49
70
// find optimum scale for ruler (size of numbered divisions)
50
71
int magnitude = 1 ;
51
72
int multiple = 1 ;
52
73
int mmDisplay;
53
- mmDisplay = optimumScale ( minFontPixelsWidth , magnitude, multiple );
74
+ mmDisplay = optimumScale ( mScaleMinPixelsWidth , magnitude, multiple );
54
75
55
76
// find optimum number of small divisions
56
77
int numSmallDivisions = optimumNumberDivisions ( mmDisplay, multiple );
@@ -77,8 +98,8 @@ void QgsComposerRuler::paintEvent( QPaintEvent* event )
77
98
double pixelCoord = mTransform .map ( QPointF ( markerPos, 0 ) ).x ();
78
99
79
100
// draw large division and text
80
- p.drawLine ( pixelCoord, 0 , pixelCoord, RULER_MIN_SIZE );
81
- p.drawText ( QPointF ( pixelCoord + 2 , RULER_MIN_SIZE / 2.0 + 2 ), QString::number ( markerPos ) );
101
+ p.drawLine ( pixelCoord, 0 , pixelCoord, mRulerMinSize );
102
+ p.drawText ( QPointF ( pixelCoord + mPixelsBetweenLineAndText , mTextBaseline ), QString::number ( markerPos ) );
82
103
83
104
// draw small divisions
84
105
drawSmallDivisions ( &p, markerPos, numSmallDivisions, mmDisplay, endX );
@@ -110,15 +131,15 @@ void QgsComposerRuler::paintEvent( QPaintEvent* event )
110
131
while ( beforePageCoord > startY )
111
132
{
112
133
double pixelCoord = mTransform .map ( QPointF ( 0 , beforePageCoord ) ).y ();
113
- p.drawLine ( 0 , pixelCoord, RULER_MIN_SIZE , pixelCoord );
134
+ p.drawLine ( 0 , pixelCoord, mRulerMinSize , pixelCoord );
114
135
// calc size of label
115
136
QString label = QString::number ( beforePageCoord );
116
- int labelSize = rulerFontMetrics. width ( label );
137
+ int labelSize = mRulerFontMetrics -> width ( label );
117
138
118
139
// draw label only if it fits in before start of next page
119
140
if ( pixelCoord + labelSize + 8 < firstPageY )
120
141
{
121
- drawRotatedText ( &p, QPointF ( RULER_MIN_SIZE / 2.0 + 2.0 , pixelCoord + 4.0 + labelSize ), label );
142
+ drawRotatedText ( &p, QPointF ( mTextBaseline , pixelCoord + mMinSpacingVerticalLabels + labelSize ), label );
122
143
}
123
144
124
145
// draw small divisions
@@ -163,16 +184,16 @@ void QgsComposerRuler::paintEvent( QPaintEvent* event )
163
184
while (( totalCoord < nextPageStartPos ) || (( nextPageStartPos == 0 ) && ( totalCoord <= endY ) ) )
164
185
{
165
186
double pixelCoord = mTransform .map ( QPointF ( 0 , totalCoord ) ).y ();
166
- p.drawLine ( 0 , pixelCoord, RULER_MIN_SIZE , pixelCoord );
187
+ p.drawLine ( 0 , pixelCoord, mRulerMinSize , pixelCoord );
167
188
// calc size of label
168
189
QString label = QString::number ( pageCoord );
169
- int labelSize = rulerFontMetrics. width ( label );
190
+ int labelSize = mRulerFontMetrics -> width ( label );
170
191
171
192
// draw label only if it fits in before start of next page
172
193
if (( pixelCoord + labelSize + 8 < nextPageStartPixel )
173
194
|| ( nextPageStartPixel == 0 ) )
174
195
{
175
- drawRotatedText ( &p, QPointF ( RULER_MIN_SIZE / 2.0 + 2.0 , pixelCoord + 4.0 + labelSize ), label );
196
+ drawRotatedText ( &p, QPointF ( mTextBaseline , pixelCoord + mMinSpacingVerticalLabels + labelSize ), label );
176
197
}
177
198
178
199
// draw small divisions
@@ -194,11 +215,11 @@ void QgsComposerRuler::drawMarkerPos( QPainter *painter )
194
215
painter->setPen ( QColor ( Qt::red ) );
195
216
if ( mDirection == Horizontal )
196
217
{
197
- painter->drawLine ( mMarkerPos .x (), 0 , mMarkerPos .x (), RULER_MIN_SIZE );
218
+ painter->drawLine ( mMarkerPos .x (), 0 , mMarkerPos .x (), mRulerMinSize );
198
219
}
199
220
else
200
221
{
201
- painter->drawLine ( 0 , mMarkerPos .y (), RULER_MIN_SIZE , mMarkerPos .y () );
222
+ painter->drawLine ( 0 , mMarkerPos .y (), mRulerMinSize , mMarkerPos .y () );
202
223
}
203
224
}
204
225
@@ -245,21 +266,21 @@ void QgsComposerRuler::drawSmallDivisions( QPainter *painter, double startPos, i
245
266
if (( numDivisions == 10 && i == 4 ) || ( numDivisions == 4 && i == 1 ) )
246
267
{
247
268
// if drawing the 5th line of 10 or drawing the 2nd line of 4, then draw it slightly longer
248
- lineSize = RULER_MIN_SIZE / 1.5 ;
269
+ lineSize = mRulerMinSize / 1.5 ;
249
270
}
250
271
else
251
272
{
252
- lineSize = RULER_MIN_SIZE / 1.25 ;
273
+ lineSize = mRulerMinSize / 1.25 ;
253
274
}
254
275
255
276
// draw either horizontal or vertical line depending on ruler direction
256
277
if ( mDirection == Horizontal )
257
278
{
258
- painter->drawLine ( pixelCoord, lineSize, pixelCoord, RULER_MIN_SIZE );
279
+ painter->drawLine ( pixelCoord, lineSize, pixelCoord, mRulerMinSize );
259
280
}
260
281
else
261
282
{
262
- painter->drawLine ( lineSize, pixelCoord, RULER_MIN_SIZE , pixelCoord );
283
+ painter->drawLine ( lineSize, pixelCoord, mRulerMinSize , pixelCoord );
263
284
}
264
285
}
265
286
}
@@ -321,8 +342,8 @@ int QgsComposerRuler::optimumNumberDivisions( double rulerScale, int scaleMultip
321
342
{
322
343
// find pixel size for this small division
323
344
double candidateSize = largeDivisionSize / ( *divisions_it );
324
- // small divisions must be seperated by at least 4 pixels
325
- if ( candidateSize >= 4 )
345
+ // check if this seperation is more then allowed min seperation
346
+ if ( candidateSize >= mMinPixelsPerDivision )
326
347
{
327
348
// found a good candidate, return it
328
349
return ( *divisions_it );
0 commit comments