@@ -187,6 +187,8 @@ QgsPalLayerSettings::QgsPalLayerSettings()
187
187
labelOffsetInMapUnits = true ;
188
188
distInMapUnits = false ;
189
189
wrapChar = " " ;
190
+ multilineHeight = 1.0 ;
191
+ multilineAlign = MultiLeft;
190
192
preserveRotation = true ;
191
193
}
192
194
@@ -235,6 +237,8 @@ QgsPalLayerSettings::QgsPalLayerSettings( const QgsPalLayerSettings& s )
235
237
distInMapUnits = s.distInMapUnits ;
236
238
labelOffsetInMapUnits = s.labelOffsetInMapUnits ;
237
239
wrapChar = s.wrapChar ;
240
+ multilineHeight = s.multilineHeight ;
241
+ multilineAlign = s.multilineAlign ;
238
242
preserveRotation = s.preserveRotation ;
239
243
240
244
dataDefinedProperties = s.dataDefinedProperties ;
@@ -416,6 +420,8 @@ void QgsPalLayerSettings::readFromLayer( QgsVectorLayer* layer )
416
420
distInMapUnits = layer->customProperty ( " labeling/distInMapUnits" ).toBool ();
417
421
labelOffsetInMapUnits = layer->customProperty ( " labeling/labelOffsetInMapUnits" , QVariant ( true ) ).toBool ();
418
422
wrapChar = layer->customProperty ( " labeling/wrapChar" ).toString ();
423
+ multilineHeight = layer->customProperty ( " labeling/multilineHeight" , QVariant ( 1.0 ) ).toDouble ();
424
+ multilineAlign = ( MultiLineAlign ) layer->customProperty ( " labeling/multilineAlign" , QVariant ( MultiLeft ) ).toUInt ();
419
425
preserveRotation = layer->customProperty ( " labeling/preserveRotation" , QVariant ( true ) ).toBool ();
420
426
_readDataDefinedPropertyMap ( layer, dataDefinedProperties );
421
427
}
@@ -475,6 +481,8 @@ void QgsPalLayerSettings::writeToLayer( QgsVectorLayer* layer )
475
481
layer->setCustomProperty ( " labeling/distInMapUnits" , distInMapUnits );
476
482
layer->setCustomProperty ( " labeling/labelOffsetInMapUnits" , labelOffsetInMapUnits );
477
483
layer->setCustomProperty ( " labeling/wrapChar" , wrapChar );
484
+ layer->setCustomProperty ( " labeling/multilineHeight" , multilineHeight );
485
+ layer->setCustomProperty ( " labeling/multilineAlign" , ( unsigned int )multilineAlign );
478
486
layer->setCustomProperty ( " labeling/preserveRotation" , preserveRotation );
479
487
_writeDataDefinedPropertyMap ( layer, dataDefinedProperties );
480
488
}
@@ -540,16 +548,20 @@ void QgsPalLayerSettings::calculateLabelSize( const QFontMetricsF* fm, QString t
540
548
text.append ( " >" );
541
549
}
542
550
543
- double w, h;
551
+ double w = 0.0 , h = 0.0 ;
544
552
QStringList multiLineSplit;
545
553
if ( !wrapChar.isEmpty () )
546
554
multiLineSplit = text.split ( wrapChar );
547
555
else
548
556
multiLineSplit = text.split ( " \n " );
557
+ int lines = multiLineSplit.size ();
549
558
550
- h = fm->height () * multiLineSplit.size () / rasterCompressFactor;
551
- w = 0 ;
552
- for ( int i = 0 ; i < multiLineSplit.size (); ++i )
559
+ double labelHeight = fm->ascent () + fm->descent (); // ignore +1 for baseline
560
+
561
+ h += fm->height () + ( double )(( lines - 1 ) * labelHeight * multilineHeight );
562
+ h /= rasterCompressFactor;
563
+
564
+ for ( int i = 0 ; i < lines; ++i )
553
565
{
554
566
double width = fm->width ( multiLineSplit.at ( i ) );
555
567
if ( width > w )
@@ -1661,7 +1673,24 @@ void QgsPalLabeling::drawLabel( pal::LabelPosition* label, QPainter* painter, co
1661
1673
else
1662
1674
multiLineList = txt.split ( " \n " );
1663
1675
1664
- for ( int i = 0 ; i < multiLineList.size (); ++i )
1676
+ int lines = multiLineList.size ();
1677
+
1678
+ double labelWidest = 0.0 ;
1679
+ for ( int i = 0 ; i < lines; ++i )
1680
+ {
1681
+ double labelWidth = labelfm->width ( multiLineList.at ( i ) );
1682
+ if ( labelWidth > labelWidest )
1683
+ {
1684
+ labelWidest = labelWidth;
1685
+ }
1686
+ }
1687
+
1688
+ double labelHeight = labelfm->ascent () + labelfm->descent (); // ignore +1 for baseline
1689
+
1690
+ // needed to move bottom of text's descender to within bottom edge of label
1691
+ double ascentOffset = 0.25 * labelfm->ascent (); // labelfm->descent() is not enough
1692
+
1693
+ for ( int i = 0 ; i < lines; ++i )
1665
1694
{
1666
1695
painter->save ();
1667
1696
painter->translate ( QPointF ( outPt.x (), outPt.y () ) );
@@ -1671,10 +1700,22 @@ void QgsPalLabeling::drawLabel( pal::LabelPosition* label, QPainter* painter, co
1671
1700
// to workaround a Qt font scaling bug with small font sizes
1672
1701
painter->scale ( 1.0 / lyr.rasterCompressFactor , 1.0 / lyr.rasterCompressFactor );
1673
1702
1674
- double yMultiLineOffset = ( multiLineList.size () - 1 - i ) * labelfm->height ();
1675
- double ascentOffset = 0.0 ;
1676
- ascentOffset = labelfm->height () * 0.25 * labelfm->ascent () / labelfm->height ();
1677
- painter->translate ( QPointF ( 0 , - ascentOffset - yMultiLineOffset ) );
1703
+ // figure x offset for horizontal alignment of multiple lines
1704
+ double xMultiLineOffset = 0.0 ;
1705
+ if ( lines > 1 && lyr.multilineAlign != QgsPalLayerSettings::MultiLeft )
1706
+ {
1707
+ double labelWidth = labelfm->width ( multiLineList.at ( i ) );
1708
+ double labelWidthDiff = labelWidest - labelWidth;
1709
+ if ( lyr.multilineAlign == QgsPalLayerSettings::MultiCenter )
1710
+ {
1711
+ labelWidthDiff /= 2 ;
1712
+ }
1713
+ xMultiLineOffset = labelWidthDiff * lyr.rasterCompressFactor ;
1714
+ QgsDebugMsg ( QString ( " xMultiLineOffset: %0" ).arg ( xMultiLineOffset ) );
1715
+ }
1716
+
1717
+ double yMultiLineOffset = ( lines - 1 - i ) * labelHeight * lyr.multilineHeight ;
1718
+ painter->translate ( QPointF ( xMultiLineOffset, - ascentOffset - yMultiLineOffset ) );
1678
1719
1679
1720
if ( drawBuffer )
1680
1721
{
0 commit comments