QGIS API Documentation  2.12.0-Lyon
qgspalgeometry.h
Go to the documentation of this file.
1 #ifndef QGSPALGEOMETRY_H
2 #define QGSPALGEOMETRY_H
3 
4 #include "qgsgeometry.h"
5 #include "qgspallabeling.h"
6 #include <pal/feature.h>
7 
8 #include "qgslabelingenginev2.h"
9 
10 using namespace pal;
11 
18 {
19  public:
21  QgsTextLabelFeature( QgsFeatureId id, GEOSGeometry* geometry, const QSizeF& size )
22  : QgsLabelFeature( id, geometry, size )
23  , mFontMetrics( NULL )
24  {
25  mDefinedFont = QFont();
26  }
27 
30  {
31  delete mFontMetrics;
32  }
33 
39  QString text( int partId ) const
40  {
41  if ( partId == -1 )
42  return mLabelText;
43  else
44  return mClusters.at( partId );
45  }
46 
48  void calculateInfo( bool curvedLabeling, QFontMetricsF* fm, const QgsMapToPixel* xform, double fontScale, double maxinangle, double maxoutangle )
49  {
50  if ( mInfo )
51  return;
52 
53  mFontMetrics = new QFontMetricsF( *fm ); // duplicate metrics for when drawing label
54 
55  qreal letterSpacing = mDefinedFont.letterSpacing();
56  qreal wordSpacing = mDefinedFont.wordSpacing();
57 
58  // max angle between curved label characters (20.0/-20.0 was default in QGIS <= 1.8)
59  if ( maxinangle < 20.0 )
60  maxinangle = 20.0;
61  if ( 60.0 < maxinangle )
62  maxinangle = 60.0;
63  if ( maxoutangle > -20.0 )
64  maxoutangle = -20.0;
65  if ( -95.0 > maxoutangle )
66  maxoutangle = -95.0;
67 
68  // create label info!
69  double mapScale = xform->mapUnitsPerPixel();
70  double labelHeight = mapScale * fm->height() / fontScale;
71 
72  // mLetterSpacing/mWordSpacing = 0.0 is default for non-curved labels
73  // (non-curved spacings handled by Qt in QgsPalLayerSettings/QgsPalLabeling)
74  qreal charWidth;
75  qreal wordSpaceFix;
76 
77  //split string by valid grapheme boundaries - required for certain scripts (see #6883)
78  mClusters = QgsPalLabeling::splitToGraphemes( mLabelText );
79 
80  mInfo = new pal::LabelInfo( mClusters.count(), labelHeight, maxinangle, maxoutangle );
81  for ( int i = 0; i < mClusters.count(); i++ )
82  {
83  // reconstruct how Qt creates word spacing, then adjust per individual stored character
84  // this will allow PAL to create each candidate width = character width + correct spacing
85  charWidth = fm->width( mClusters[i] );
86  if ( curvedLabeling )
87  {
88  wordSpaceFix = qreal( 0.0 );
89  if ( mClusters[i] == QLatin1String( " " ) )
90  {
91  // word spacing only gets added once at end of consecutive run of spaces, see QTextEngine::shapeText()
92  int nxt = i + 1;
93  wordSpaceFix = ( nxt < mClusters.count() && mClusters[nxt] != QLatin1String( " " ) ) ? wordSpacing : qreal( 0.0 );
94  }
95  // this workaround only works for clusters with a single character. Not sure how it should be handled
96  // with multi-character clusters.
97  if ( mClusters[i].length() == 1 &&
98  !qgsDoubleNear( fm->width( QString( mClusters[i].at( 0 ) ) ), fm->width( mClusters[i].at( 0 ) ) + letterSpacing ) )
99  {
100  // word spacing applied when it shouldn't be
101  wordSpaceFix -= wordSpacing;
102  }
103 
104  charWidth = fm->width( QString( mClusters[i] ) ) + wordSpaceFix;
105  }
106 
107  double labelWidth = mapScale * charWidth / fontScale;
108  mInfo->char_info[i].width = labelWidth;
109  }
110  }
111 
115  void setDataDefinedValues( const QMap< QgsPalLayerSettings::DataDefinedProperties, QVariant >& values ) { mDataDefinedValues = values; }
116 
118  void setDefinedFont( const QFont& f ) { mDefinedFont = f; }
120  QFont definedFont() { return mDefinedFont; }
121 
123  QFontMetricsF* labelFontMetrics() { return mFontMetrics; }
124 
125  protected:
134 
135 };
136 
137 #endif //QGSPALGEOMETRY_H
QgsTextLabelFeature(QgsFeatureId id, GEOSGeometry *geometry, const QSizeF &size)
Construct text label feature.
QStringList mClusters
List of graphemes (used for curved labels)
~QgsTextLabelFeature()
Clean up.
Class that adds extra information to QgsLabelFeature for text labels.
void setDefinedFont(const QFont &f)
Set font to be used for rendering.
qreal width(const QString &text) const
bool qgsDoubleNear(double a, double b, double epsilon=4 *DBL_EPSILON)
Definition: qgis.h:268
Perform transforms between map coordinates and device coordinates.
Definition: qgsmaptopixel.h:34
QMap< QgsPalLayerSettings::DataDefinedProperties, QVariant > mDataDefinedValues
Stores attribute values for data defined properties.
void setDataDefinedValues(const QMap< QgsPalLayerSettings::DataDefinedProperties, QVariant > &values)
Set data-defined values.
const QMap< QgsPalLayerSettings::DataDefinedProperties, QVariant > & dataDefinedValues() const
Get data-defined values.
Optional additional info about label (for curved labels)
Definition: feature.h:47
void calculateInfo(bool curvedLabeling, QFontMetricsF *fm, const QgsMapToPixel *xform, double fontScale, double maxinangle, double maxoutangle)
calculate data for info(). setDefinedFont() must have been called already.
double mapUnitsPerPixel() const
Return current map units per pixel.
QFontMetricsF * mFontMetrics
Metrics of the font for rendering.
QFont definedFont()
Font to be used for rendering.
QString text(int partId) const
Returns the text component corresponding to a specified label part.
The QgsLabelFeature class describes a feature that should be used within the labeling engine...
const QChar at(int position) const
static QStringList splitToGraphemes(const QString &text)
Splits a text string to a list of graphemes, which are the smallest allowable character divisions in ...
qint64 QgsFeatureId
Definition: qgsfeature.h:31
QFont mDefinedFont
Font for rendering.
QFontMetricsF * labelFontMetrics()
Metrics of the font for rendering.
qreal height() const