@@ -57,14 +57,18 @@ using namespace pal;
57
57
class QgsPalGeometry : public PalGeometry
58
58
{
59
59
public:
60
- QgsPalGeometry ( QgsFeatureId id, QString text, GEOSGeometry* g )
60
+ QgsPalGeometry ( QgsFeatureId id, QString text, GEOSGeometry* g,
61
+ qreal ltrSpacing = 0.0 , qreal wordSpacing = 0.0 , bool curvedLabeling = false )
61
62
: mG ( g )
62
63
, mText ( text )
63
64
, mId ( id )
64
65
, mInfo ( NULL )
65
66
, mIsDiagram ( false )
66
67
, mIsPinned ( false )
67
68
, mFontMetrics ( NULL )
69
+ , mLetterSpacing ( ltrSpacing )
70
+ , mWordSpacing ( wordSpacing )
71
+ , mCurvedLabeling ( curvedLabeling )
68
72
{
69
73
mStrId = FID_TO_STRING ( id ).toAscii ();
70
74
}
@@ -102,11 +106,36 @@ class QgsPalGeometry : public PalGeometry
102
106
QgsPoint ptZero = xform->toMapCoordinates ( 0 , 0 );
103
107
QgsPoint ptSize = xform->toMapCoordinatesF ( 0.0 , -fm->height () / fontScale );
104
108
109
+ // mLetterSpacing/mWordSpacing = 0.0 is default for non-curved labels
110
+ // (non-curved spacings handled by Qt in QgsPalLayerSettings/QgsPalLabeling)
111
+ qreal charWidth;
112
+ qreal wordSpaceFix;
105
113
mInfo = new pal::LabelInfo ( mText .count (), ptSize.y () - ptZero.y () );
106
114
for ( int i = 0 ; i < mText .count (); i++ )
107
115
{
108
116
mInfo ->char_info [i].chr = mText [i].unicode ();
109
- ptSize = xform->toMapCoordinatesF ( fm->width ( mText [i] ) / fontScale , 0.0 );
117
+
118
+ // reconstruct how Qt creates word spacing, then adjust per individual stored character
119
+ // this will allow PAL to create each candidate width = character width + correct spacing
120
+ charWidth = fm->width ( mText [i] );
121
+ if ( mCurvedLabeling )
122
+ {
123
+ wordSpaceFix = qreal ( 0.0 );
124
+ if ( mText [i] == QString ( " " )[0 ] )
125
+ {
126
+ // word spacing only gets added once at end of consecutive run of spaces, see QTextEngine::shapeText()
127
+ int nxt = i + 1 ;
128
+ wordSpaceFix = ( nxt < mText .count () && mText [nxt] != QString ( " " )[0 ] ) ? mWordSpacing : qreal ( 0.0 );
129
+ }
130
+ if ( fm->width ( QString ( mText [i] ) ) - fm->width ( mText [i] ) - mLetterSpacing != qreal ( 0.0 ) )
131
+ {
132
+ // word spacing applied when it shouldn't be
133
+ wordSpaceFix -= mWordSpacing ;
134
+ }
135
+ charWidth = fm->width ( QString ( mText [i] ) ) + wordSpaceFix;
136
+ }
137
+
138
+ ptSize = xform->toMapCoordinatesF ((( double ) charWidth ) / fontScale , 0.0 );
110
139
mInfo ->char_info [i].width = ptSize.x () - ptZero.x ();
111
140
}
112
141
return mInfo ;
@@ -135,6 +164,9 @@ class QgsPalGeometry : public PalGeometry
135
164
bool mIsDiagram ;
136
165
bool mIsPinned ;
137
166
QFontMetricsF* mFontMetrics ;
167
+ qreal mLetterSpacing ; // for use with curved labels
168
+ qreal mWordSpacing ; // for use with curved labels
169
+ bool mCurvedLabeling ; // whether the geometry is to be used for curved labeling placement
138
170
/* *Stores attribute values for data defined properties*/
139
171
QMap< QgsPalLayerSettings::DataDefinedProperties, QVariant > mDataDefinedValues ;
140
172
@@ -881,7 +913,13 @@ void QgsPalLayerSettings::registerFeature( QgsVectorLayer* layer, QgsFeature& f
881
913
}
882
914
}
883
915
884
- QgsPalGeometry* lbl = new QgsPalGeometry ( f.id (), labelText, geos_geom_clone );
916
+ QgsPalGeometry* lbl = new QgsPalGeometry (
917
+ f.id (),
918
+ labelText,
919
+ geos_geom_clone,
920
+ labelFont.letterSpacing (),
921
+ labelFont.wordSpacing (),
922
+ placement == QgsPalLayerSettings::Curved );
885
923
886
924
// record the created geometry - it will be deleted at the end.
887
925
geometries.append ( lbl );
0 commit comments