Skip to content

Commit 71b5a99

Browse files
committedJun 24, 2015
Fix broken rendering of curved labels for scripts which use >1 char
graphemes (fix #6883) Cherry-picked from 2dc5d95
1 parent 174943e commit 71b5a99

File tree

3 files changed

+37
-12
lines changed

3 files changed

+37
-12
lines changed
 

‎src/core/dxf/qgsdxfpallabeling.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,7 @@ void QgsDxfPalLabeling::drawLabel( pal::LabelPosition* label, QgsRenderContext&
7979
return;
8080

8181
//label text
82-
QString text = g->text();
83-
QString txt = label->getPartId() == -1 ? text : QString( text[ label->getPartId()] );
82+
QString txt = g->text( label->getPartId() );
8483

8584
//angle
8685
double angle = label->getAlpha() * 180 / M_PI;

‎src/core/qgspalgeometry.h

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include "qgsgeometry.h"
55
#include <pal/feature.h>
66
#include <pal/palgeometry.h>
7+
#include <QTextBoundaryFinder>
78

89
using namespace pal;
910

@@ -49,6 +50,19 @@ class QgsPalGeometry : public PalGeometry
4950
const char* strId() { return mStrId.data(); }
5051
QString text() { return mText; }
5152

53+
/** Returns the text component corresponding to a specified label part
54+
* @param partId. Set to -1 for labels which are not broken into parts (eg, non-curved labels), or the required
55+
* part index for labels which are broken into parts (curved labels)
56+
* @note added in QGIS 2.10
57+
*/
58+
QString text( int partId ) const
59+
{
60+
if ( partId == -1 )
61+
return mText;
62+
else
63+
return mClusters.at( partId );
64+
}
65+
5266
pal::LabelInfo* info( QFontMetricsF* fm, const QgsMapToPixel* xform, double fontScale, double maxinangle, double maxoutangle )
5367
{
5468
if ( mInfo )
@@ -74,29 +88,41 @@ class QgsPalGeometry : public PalGeometry
7488
// (non-curved spacings handled by Qt in QgsPalLayerSettings/QgsPalLabeling)
7589
qreal charWidth;
7690
qreal wordSpaceFix;
77-
mInfo = new pal::LabelInfo( mText.count(), labelHeight, maxinangle, maxoutangle );
78-
for ( int i = 0; i < mText.count(); i++ )
91+
92+
//split string by valid grapheme boundaries - required for certain scripts (see #6883)
93+
QTextBoundaryFinder boundaryFinder( QTextBoundaryFinder::Grapheme, mText );
94+
int currentBoundary = -1;
95+
int previousBoundary = 0;
96+
while (( currentBoundary = boundaryFinder.toNextBoundary() ) > 0 )
97+
{
98+
mClusters << mText.mid( previousBoundary, currentBoundary - previousBoundary );
99+
previousBoundary = currentBoundary;
100+
}
101+
102+
mInfo = new pal::LabelInfo( mClusters.count(), labelHeight, maxinangle, maxoutangle );
103+
for ( int i = 0; i < mClusters.count(); i++ )
79104
{
80-
mInfo->char_info[i].chr = mText[i].unicode();
105+
//doesn't appear to be used anywhere:
106+
//mInfo->char_info[i].chr = textClusters[i].unicode();
81107

82108
// reconstruct how Qt creates word spacing, then adjust per individual stored character
83109
// this will allow PAL to create each candidate width = character width + correct spacing
84-
charWidth = fm->width( mText[i] );
110+
charWidth = fm->width( mClusters[i] );
85111
if ( mCurvedLabeling )
86112
{
87113
wordSpaceFix = qreal( 0.0 );
88-
if ( mText[i] == QString( " " )[0] )
114+
if ( mClusters[i] == QString( " " ) )
89115
{
90116
// word spacing only gets added once at end of consecutive run of spaces, see QTextEngine::shapeText()
91117
int nxt = i + 1;
92-
wordSpaceFix = ( nxt < mText.count() && mText[nxt] != QString( " " )[0] ) ? mWordSpacing : qreal( 0.0 );
118+
wordSpaceFix = ( nxt < mClusters.count() && mClusters[nxt] != QString( " " ) ) ? mWordSpacing : qreal( 0.0 );
93119
}
94-
if ( fm->width( QString( mText[i] ) ) - fm->width( mText[i] ) - mLetterSpacing != qreal( 0.0 ) )
120+
if ( fm->width( QString( mClusters[i] ) ) - fm->width( mClusters[i] ) - mLetterSpacing != qreal( 0.0 ) )
95121
{
96122
// word spacing applied when it shouldn't be
97123
wordSpaceFix -= mWordSpacing;
98124
}
99-
charWidth = fm->width( QString( mText[i] ) ) + wordSpaceFix;
125+
charWidth = fm->width( QString( mClusters[i] ) ) + wordSpaceFix;
100126
}
101127

102128
double labelWidth = mapScale * charWidth / fontScale;
@@ -135,6 +161,7 @@ class QgsPalGeometry : public PalGeometry
135161
protected:
136162
GEOSGeometry* mG;
137163
QString mText;
164+
QStringList mClusters;
138165
QByteArray mStrId;
139166
QgsFeatureId mId;
140167
LabelInfo* mInfo;

‎src/core/qgspallabeling.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4324,8 +4324,7 @@ void QgsPalLabeling::drawLabel( pal::LabelPosition* label, QgsRenderContext& con
43244324
{
43254325

43264326
// TODO: optimize access :)
4327-
QString text = (( QgsPalGeometry* )label->getFeaturePart()->getUserGeometry() )->text();
4328-
QString txt = ( label->getPartId() == -1 ? text : QString( text[label->getPartId()] ) );
4327+
QString txt = (( QgsPalGeometry* )label->getFeaturePart()->getUserGeometry() )->text( label->getPartId() );
43294328
QFontMetricsF* labelfm = (( QgsPalGeometry* )label->getFeaturePart()->getUserGeometry() )->getLabelFontMetrics();
43304329

43314330
//add the direction symbol if needed

0 commit comments

Comments
 (0)
Please sign in to comment.