35 #include <QApplication>
38 #include <QFontMetrics>
59 #include <QMessageBox>
81 : upsidedownLabels( Upright )
88 , mFeaturesToLabel( 0 )
89 , mFeatsSendingToPal( 0 )
103 blendMode = QPainter::CompositionMode_SourceOver;
212 mDataDefinedNames.insert(
Size, QPair<QString, int>(
"Size", 0 ) );
213 mDataDefinedNames.insert(
Bold, QPair<QString, int>(
"Bold", 1 ) );
214 mDataDefinedNames.insert(
Italic, QPair<QString, int>(
"Italic", 2 ) );
215 mDataDefinedNames.insert(
Underline, QPair<QString, int>(
"Underline", 3 ) );
216 mDataDefinedNames.insert(
Color, QPair<QString, int>(
"Color", 4 ) );
217 mDataDefinedNames.insert(
Strikeout, QPair<QString, int>(
"Strikeout", 5 ) );
218 mDataDefinedNames.insert(
Family, QPair<QString, int>(
"Family", 6 ) );
219 mDataDefinedNames.insert(
FontStyle, QPair<QString, int>(
"FontStyle", -1 ) );
220 mDataDefinedNames.insert(
FontSizeUnit, QPair<QString, int>(
"FontSizeUnit", -1 ) );
221 mDataDefinedNames.insert(
FontTransp, QPair<QString, int>(
"FontTransp", 18 ) );
222 mDataDefinedNames.insert(
FontCase, QPair<QString, int>(
"FontCase", -1 ) );
223 mDataDefinedNames.insert(
FontLetterSpacing, QPair<QString, int>(
"FontLetterSpacing", -1 ) );
224 mDataDefinedNames.insert(
FontWordSpacing, QPair<QString, int>(
"FontWordSpacing", -1 ) );
225 mDataDefinedNames.insert(
FontBlendMode, QPair<QString, int>(
"FontBlendMode", -1 ) );
228 mDataDefinedNames.insert(
MultiLineWrapChar, QPair<QString, int>(
"MultiLineWrapChar", -1 ) );
229 mDataDefinedNames.insert(
MultiLineHeight, QPair<QString, int>(
"MultiLineHeight", -1 ) );
230 mDataDefinedNames.insert(
MultiLineAlignment, QPair<QString, int>(
"MultiLineAlignment", -1 ) );
231 mDataDefinedNames.insert(
DirSymbDraw, QPair<QString, int>(
"DirSymbDraw", -1 ) );
232 mDataDefinedNames.insert(
DirSymbLeft, QPair<QString, int>(
"DirSymbLeft", -1 ) );
233 mDataDefinedNames.insert(
DirSymbRight, QPair<QString, int>(
"DirSymbRight", -1 ) );
234 mDataDefinedNames.insert(
DirSymbPlacement, QPair<QString, int>(
"DirSymbPlacement", -1 ) );
235 mDataDefinedNames.insert(
DirSymbReverse, QPair<QString, int>(
"DirSymbReverse", -1 ) );
236 mDataDefinedNames.insert(
NumFormat, QPair<QString, int>(
"NumFormat", -1 ) );
237 mDataDefinedNames.insert(
NumDecimals, QPair<QString, int>(
"NumDecimals", -1 ) );
238 mDataDefinedNames.insert(
NumPlusSign, QPair<QString, int>(
"NumPlusSign", -1 ) );
241 mDataDefinedNames.insert(
BufferDraw, QPair<QString, int>(
"BufferDraw", -1 ) );
242 mDataDefinedNames.insert(
BufferSize, QPair<QString, int>(
"BufferSize", 7 ) );
243 mDataDefinedNames.insert(
BufferUnit, QPair<QString, int>(
"BufferUnit", -1 ) );
244 mDataDefinedNames.insert(
BufferColor, QPair<QString, int>(
"BufferColor", 8 ) );
245 mDataDefinedNames.insert(
BufferTransp, QPair<QString, int>(
"BufferTransp", 19 ) );
246 mDataDefinedNames.insert(
BufferJoinStyle, QPair<QString, int>(
"BufferJoinStyle", -1 ) );
247 mDataDefinedNames.insert(
BufferBlendMode, QPair<QString, int>(
"BufferBlendMode", -1 ) );
250 mDataDefinedNames.insert(
ShapeDraw, QPair<QString, int>(
"ShapeDraw", -1 ) );
251 mDataDefinedNames.insert(
ShapeKind, QPair<QString, int>(
"ShapeKind", -1 ) );
252 mDataDefinedNames.insert(
ShapeSVGFile, QPair<QString, int>(
"ShapeSVGFile", -1 ) );
253 mDataDefinedNames.insert(
ShapeSizeType, QPair<QString, int>(
"ShapeSizeType", -1 ) );
254 mDataDefinedNames.insert(
ShapeSizeX, QPair<QString, int>(
"ShapeSizeX", -1 ) );
255 mDataDefinedNames.insert(
ShapeSizeY, QPair<QString, int>(
"ShapeSizeY", -1 ) );
256 mDataDefinedNames.insert(
ShapeSizeUnits, QPair<QString, int>(
"ShapeSizeUnits", -1 ) );
257 mDataDefinedNames.insert(
ShapeRotationType, QPair<QString, int>(
"ShapeRotationType", -1 ) );
258 mDataDefinedNames.insert(
ShapeRotation, QPair<QString, int>(
"ShapeRotation", -1 ) );
259 mDataDefinedNames.insert(
ShapeOffset, QPair<QString, int>(
"ShapeOffset", -1 ) );
260 mDataDefinedNames.insert(
ShapeOffsetUnits, QPair<QString, int>(
"ShapeOffsetUnits", -1 ) );
261 mDataDefinedNames.insert(
ShapeRadii, QPair<QString, int>(
"ShapeRadii", -1 ) );
262 mDataDefinedNames.insert(
ShapeRadiiUnits, QPair<QString, int>(
"ShapeRadiiUnits", -1 ) );
263 mDataDefinedNames.insert(
ShapeTransparency, QPair<QString, int>(
"ShapeTransparency", -1 ) );
264 mDataDefinedNames.insert(
ShapeBlendMode, QPair<QString, int>(
"ShapeBlendMode", -1 ) );
265 mDataDefinedNames.insert(
ShapeFillColor, QPair<QString, int>(
"ShapeFillColor", -1 ) );
266 mDataDefinedNames.insert(
ShapeBorderColor, QPair<QString, int>(
"ShapeBorderColor", -1 ) );
267 mDataDefinedNames.insert(
ShapeBorderWidth, QPair<QString, int>(
"ShapeBorderWidth", -1 ) );
268 mDataDefinedNames.insert(
ShapeBorderWidthUnits, QPair<QString, int>(
"ShapeBorderWidthUnits", -1 ) );
269 mDataDefinedNames.insert(
ShapeJoinStyle, QPair<QString, int>(
"ShapeJoinStyle", -1 ) );
272 mDataDefinedNames.insert(
ShadowDraw, QPair<QString, int>(
"ShadowDraw", -1 ) );
273 mDataDefinedNames.insert(
ShadowUnder, QPair<QString, int>(
"ShadowUnder", -1 ) );
274 mDataDefinedNames.insert(
ShadowOffsetAngle, QPair<QString, int>(
"ShadowOffsetAngle", -1 ) );
275 mDataDefinedNames.insert(
ShadowOffsetDist, QPair<QString, int>(
"ShadowOffsetDist", -1 ) );
276 mDataDefinedNames.insert(
ShadowOffsetUnits, QPair<QString, int>(
"ShadowOffsetUnits", -1 ) );
277 mDataDefinedNames.insert(
ShadowRadius, QPair<QString, int>(
"ShadowRadius", -1 ) );
278 mDataDefinedNames.insert(
ShadowRadiusUnits, QPair<QString, int>(
"ShadowRadiusUnits", -1 ) );
279 mDataDefinedNames.insert(
ShadowTransparency, QPair<QString, int>(
"ShadowTransparency", -1 ) );
280 mDataDefinedNames.insert(
ShadowScale, QPair<QString, int>(
"ShadowScale", -1 ) );
281 mDataDefinedNames.insert(
ShadowColor, QPair<QString, int>(
"ShadowColor", -1 ) );
282 mDataDefinedNames.insert(
ShadowBlendMode, QPair<QString, int>(
"ShadowBlendMode", -1 ) );
285 mDataDefinedNames.insert(
CentroidWhole, QPair<QString, int>(
"CentroidWhole", -1 ) );
286 mDataDefinedNames.insert(
OffsetQuad, QPair<QString, int>(
"OffsetQuad", -1 ) );
287 mDataDefinedNames.insert(
OffsetXY, QPair<QString, int>(
"OffsetXY", -1 ) );
288 mDataDefinedNames.insert(
OffsetUnits, QPair<QString, int>(
"OffsetUnits", -1 ) );
289 mDataDefinedNames.insert(
LabelDistance, QPair<QString, int>(
"LabelDistance", 13 ) );
290 mDataDefinedNames.insert(
DistanceUnits, QPair<QString, int>(
"DistanceUnits", -1 ) );
291 mDataDefinedNames.insert(
OffsetRotation, QPair<QString, int>(
"OffsetRotation", -1 ) );
292 mDataDefinedNames.insert(
CurvedCharAngleInOut, QPair<QString, int>(
"CurvedCharAngleInOut", -1 ) );
293 mDataDefinedNames.insert(
RepeatDistance, QPair<QString, int>(
"RepeatDistance", -1 ) );
294 mDataDefinedNames.insert(
RepeatDistanceUnit, QPair<QString, int>(
"RepeatDistanceUnit", -1 ) );
296 mDataDefinedNames.insert(
PositionX, QPair<QString, int>(
"PositionX", 9 ) );
297 mDataDefinedNames.insert(
PositionY, QPair<QString, int>(
"PositionY", 10 ) );
298 mDataDefinedNames.insert(
Hali, QPair<QString, int>(
"Hali", 11 ) );
299 mDataDefinedNames.insert(
Vali, QPair<QString, int>(
"Vali", 12 ) );
300 mDataDefinedNames.insert(
Rotation, QPair<QString, int>(
"Rotation", 14 ) );
303 mDataDefinedNames.insert(
ScaleVisibility, QPair<QString, int>(
"ScaleVisibility", -1 ) );
304 mDataDefinedNames.insert(
MinScale, QPair<QString, int>(
"MinScale", 16 ) );
305 mDataDefinedNames.insert(
MaxScale, QPair<QString, int>(
"MaxScale", 17 ) );
306 mDataDefinedNames.insert(
FontLimitPixel, QPair<QString, int>(
"FontLimitPixel", -1 ) );
307 mDataDefinedNames.insert(
FontMinPixel, QPair<QString, int>(
"FontMinPixel", -1 ) );
308 mDataDefinedNames.insert(
FontMaxPixel, QPair<QString, int>(
"FontMaxPixel", -1 ) );
310 mDataDefinedNames.insert(
Show, QPair<QString, int>(
"Show", 15 ) );
311 mDataDefinedNames.insert(
AlwaysShow, QPair<QString, int>(
"AlwaysShow", 20 ) );
325 , mFeaturesToLabel( 0 )
326 , mFeatsSendingToPal( 0 )
328 , showingShadowRects( false )
457 mDataDefinedNames = s.mDataDefinedNames;
488 if ( expression == NULL )
497 int r = layer->
customProperty( property +
"R", QVariant( defaultColor.red() ) ).toInt();
498 int g = layer->
customProperty( property +
"G", QVariant( defaultColor.green() ) ).toInt();
499 int b = layer->
customProperty( property +
"B", QVariant( defaultColor.blue() ) ).toInt();
500 int a = withAlpha ? layer->
customProperty( property +
"A", QVariant( defaultColor.alpha() ) ).toInt() : 255;
501 return QColor( r, g, b, a );
515 if ( str.compare(
"Point", Qt::CaseInsensitive ) == 0
517 if ( str.compare(
"MapUnit", Qt::CaseInsensitive ) == 0
525 if ( str.compare(
"Miter", Qt::CaseInsensitive ) == 0 )
return Qt::MiterJoin;
526 if ( str.compare(
"Round", Qt::CaseInsensitive ) == 0 )
return Qt::RoundJoin;
527 return Qt::BevelJoin;
530 void QgsPalLayerSettings::readDataDefinedPropertyMap(
QgsVectorLayer* layer,
531 QMap < QgsPalLayerSettings::DataDefinedProperties, QgsDataDefined* > & propertyMap )
538 QMapIterator<QgsPalLayerSettings::DataDefinedProperties, QPair<QString, int> > i( mDataDefinedNames );
539 while ( i.hasNext() )
542 readDataDefinedProperty( layer, i.key(), propertyMap );
546 void QgsPalLayerSettings::writeDataDefinedPropertyMap(
QgsVectorLayer* layer,
547 const QMap < QgsPalLayerSettings::DataDefinedProperties, QgsDataDefined* > & propertyMap )
554 QMapIterator<QgsPalLayerSettings::DataDefinedProperties, QPair<QString, int> > i( mDataDefinedNames );
555 while ( i.hasNext() )
558 QString newPropertyName =
"labeling/dataDefined/" + i.value().first;
559 QVariant propertyValue = QVariant();
561 QMap< QgsPalLayerSettings::DataDefinedProperties, QgsDataDefined* >::const_iterator it = propertyMap.find( i.key() );
562 if ( it != propertyMap.constEnd() )
570 QString field = dd->
field();
572 bool defaultVals = ( !active && !useExpr && expr.isEmpty() && field.isEmpty() );
578 values << ( active ?
"1" :
"0" );
579 values << ( useExpr ?
"1" :
"0" );
582 if ( !values.isEmpty() )
584 propertyValue = QVariant( values.join(
"~~" ) );
590 if ( propertyValue.isValid() )
600 if ( layer->
customProperty( newPropertyName, QVariant() ).isValid() && i.value().second > -1 )
603 layer->
removeCustomProperty( QString(
"labeling/dataDefinedProperty" ) + QString::number( i.value().second ) );
608 void QgsPalLayerSettings::readDataDefinedProperty(
QgsVectorLayer* layer,
610 QMap < QgsPalLayerSettings::DataDefinedProperties, QgsDataDefined* > & propertyMap )
612 QString newPropertyName =
"labeling/dataDefined/" + mDataDefinedNames.value( p ).first;
613 QVariant newPropertyField = layer->
customProperty( newPropertyName, QVariant() );
615 QString ddString = QString();
616 if ( newPropertyField.isValid() )
618 ddString = newPropertyField.toString();
622 int oldIndx = mDataDefinedNames.value( p ).second;
629 QString oldPropertyName =
"labeling/dataDefinedProperty" + QString::number( oldIndx );
630 QVariant oldPropertyField = layer->
customProperty( oldPropertyName, QVariant() );
632 if ( !oldPropertyField.isValid() )
639 int indx = oldPropertyField.toInt( &conversionOk );
649 if ( !oldIndicesToNames.isEmpty() )
651 ddString = oldIndicesToNames.value( indx );
656 if ( indx < fields.
size() )
658 ddString = fields.
at( indx ).
name();
663 if ( !ddString.isEmpty() )
676 if ( oldIndx == 16 || oldIndx == 17 )
687 if ( !ddString.isEmpty() && ddString != QString(
"0~~0~~~~" ) )
691 QStringList ddv = newStyleString.split(
"~~" );
694 propertyMap.insert( p, dd );
705 if ( layer->
customProperty(
"labeling" ).toString() != QString(
"pal" ) )
722 QFont appFont = QApplication::font();
734 fontFamily = appFont.family();
737 double fontSize = layer->
customProperty(
"labeling/fontSize" ).toDouble();
741 int fontWeight = layer->
customProperty(
"labeling/fontWeight" ).toInt();
742 bool fontItalic = layer->
customProperty(
"labeling/fontItalic" ).toBool();
743 textFont = QFont( fontFamily, fontSize, fontWeight, fontItalic );
747 textFont.setCapitalization(( QFont::Capitalization )layer->
customProperty(
"labeling/fontCapitals", QVariant( 0 ) ).toUInt() );
750 textFont.setLetterSpacing( QFont::AbsoluteSpacing, layer->
customProperty(
"labeling/fontLetterSpacing", QVariant( 0.0 ) ).toDouble() );
751 textFont.setWordSpacing( layer->
customProperty(
"labeling/fontWordSpacing", QVariant( 0.0 ) ).toDouble() );
773 double bufSize = layer->
customProperty(
"labeling/bufferSize", QVariant( 0.0 ) ).toDouble();
776 QVariant drawBuffer = layer->
customProperty(
"labeling/bufferDraw", QVariant() );
777 if ( drawBuffer.isValid() )
782 else if ( bufSize != 0.0 )
809 layer->
customProperty(
"labeling/shapeSizeY", QVariant( 0.0 ) ).toDouble() );
816 layer->
customProperty(
"labeling/shapeOffsetY", QVariant( 0.0 ) ).toDouble() );
821 layer->
customProperty(
"labeling/shapeRadiiY", QVariant( 0.0 ) ).toDouble() );
882 int scalemn = layer->
customProperty(
"labeling/scaleMin", QVariant( 0 ) ).toInt();
883 int scalemx = layer->
customProperty(
"labeling/scaleMax", QVariant( 0 ) ).toInt();
886 QVariant scalevis = layer->
customProperty(
"labeling/scaleVisibility", QVariant() );
887 if ( scalevis.isValid() )
893 else if ( scalemn > 0 || scalemx > 0 )
1073 bool active,
bool useExpr,
const QString& expr,
const QString& field )
1075 bool defaultVals = ( !active && !useExpr && expr.isEmpty() && field.isEmpty() );
1079 QMap< QgsPalLayerSettings::DataDefinedProperties, QgsDataDefined* >::const_iterator it =
dataDefinedProperties.find( p );
1089 else if ( !defaultVals )
1101 delete( it.value() );
1109 QString newValue = value;
1110 if ( !value.isEmpty() && !value.contains(
"~~" ) )
1117 newValue = values.join(
"~~" );
1125 QMap< QgsPalLayerSettings::DataDefinedProperties, QgsDataDefined* >::const_iterator it =
dataDefinedProperties.find( p );
1135 QMap<QString, QString> map;
1136 QMap< QgsPalLayerSettings::DataDefinedProperties, QgsDataDefined* >::const_iterator it =
dataDefinedProperties.find( p );
1139 return it.value()->toMap();
1152 QMap< DataDefinedProperties, QgsDataDefined* >::const_iterator it =
dataDefinedProperties.find( p );
1168 QVariant result = QVariant();
1170 QString field = dd->
field();
1189 else if ( !useExpression && !field.isEmpty() )
1208 if ( result.isValid() )
1221 bool isActive =
false;
1222 QMap< DataDefinedProperties, QgsDataDefined* >::const_iterator it =
dataDefinedProperties.find( p );
1225 isActive = it.value()->isActive();
1233 bool useExpression =
false;
1234 QMap< DataDefinedProperties, QgsDataDefined* >::const_iterator it =
dataDefinedProperties.find( p );
1237 useExpression = it.value()->useExpression();
1240 return useExpression;
1264 double length = geom->
length();
1265 if ( length >= 0.0 )
1267 return ( length >= ( minSize * mapUnitsPerMM ) );
1272 double area = geom->
area();
1275 return ( sqrt( area ) >= ( minSize * mapUnitsPerMM ) );
1336 if ( exprVal.isValid() )
1338 wrapchr = exprVal.toString();
1342 if ( exprVal.isValid() )
1345 double size = exprVal.toDouble( &ok );
1354 if ( exprVal.isValid() )
1356 addDirSymb = exprVal.toBool();
1363 if ( exprVal.isValid() )
1365 leftDirSymb = exprVal.toString();
1369 if ( exprVal.isValid() )
1371 rightDirSymb = exprVal.toString();
1375 if ( exprVal.isValid() )
1378 int enmint = exprVal.toInt( &ok );
1388 if ( wrapchr.isEmpty() )
1390 wrapchr = QString(
"\n" );
1395 && ( !leftDirSymb.isEmpty() || !rightDirSymb.isEmpty() ) )
1397 QString dirSym = leftDirSymb;
1399 if ( fm->width( rightDirSymb ) > fm->width( dirSym ) )
1400 dirSym = rightDirSymb;
1404 text.append( dirSym );
1408 text.prepend( dirSym + wrapchr );
1412 double w = 0.0, h = 0.0;
1413 QStringList multiLineSplit = text.split( wrapchr );
1414 int lines = multiLineSplit.size();
1416 double labelHeight = fm->ascent() + fm->descent();
1418 h += fm->height() + ( double )(( lines - 1 ) * labelHeight * multilineH );
1421 for (
int i = 0; i < lines; ++i )
1423 double width = fm->width( multiLineSplit.at( i ) );
1433 labelX = qAbs( ptSize.
x() -
ptZero.
x() );
1434 labelY = qAbs( ptSize.
y() -
ptZero.
y() );
1449 dataDefinedValues.clear();
1455 showLabel = exprVal.toBool();
1456 QgsDebugMsgLevel( QString(
"exprVal Show:%1" ).arg( showLabel ?
"true" :
"false" ), 4 );
1467 QgsDebugMsgLevel( QString(
"exprVal ScaleVisibility:%1" ).arg( exprVal.toBool() ?
"true" :
"false" ), 4 );
1468 useScaleVisibility = exprVal.toBool();
1471 if ( useScaleVisibility )
1477 QgsDebugMsgLevel( QString(
"exprVal MinScale:%1" ).arg( exprVal.toDouble() ), 4 );
1479 double mins = exprVal.toDouble( &conversionOk );
1489 minScale = 1 / qAbs( minScale );
1501 QgsDebugMsgLevel( QString(
"exprVal MaxScale:%1" ).arg( exprVal.toDouble() ), 4 );
1503 double maxs = exprVal.toDouble( &conversionOk );
1513 maxScale = 1 / qAbs( maxScale );
1529 QString units = exprVal.toString().trimmed();
1531 if ( !units.isEmpty() )
1538 double fontSize = labelFont.pointSizeF();
1541 QgsDebugMsgLevel( QString(
"exprVal Size:%1" ).arg( exprVal.toDouble() ), 4 );
1543 double size = exprVal.toDouble( &ok );
1549 if ( fontSize <= 0.0 )
1556 if ( fontPixelSize < 1 )
1560 labelFont.setPixelSize( fontPixelSize );
1570 QgsDebugMsgLevel( QString(
"exprVal FontLimitPixel:%1" ).arg( exprVal.toBool() ?
"true" :
"false" ), 4 );
1571 useFontLimitPixelSize = exprVal.toBool();
1574 if ( useFontLimitPixelSize )
1580 int sizeInt = exprVal.toInt( &ok );
1581 QgsDebugMsgLevel( QString(
"exprVal FontMinPixel:%1" ).arg( sizeInt ), 4 );
1584 fontMinPixel = sizeInt;
1592 int sizeInt = exprVal.toInt( &ok );
1593 QgsDebugMsgLevel( QString(
"exprVal FontMaxPixel:%1" ).arg( sizeInt ), 4 );
1596 fontMaxPixel = sizeInt;
1600 if ( fontMinPixel > labelFont.pixelSize() || labelFont.pixelSize() > fontMaxPixel )
1612 parseTextStyle( labelFont, fontunits, context );
1613 parseTextFormatting();
1615 parseShapeBackground();
1631 QVariant result = exp->
evaluate( &f );
1637 labelText = result.isNull() ?
"" : result.toString();
1642 labelText = v.isNull() ?
"" : v.toString();
1649 formatnum = exprVal.toBool();
1650 QgsDebugMsgLevel( QString(
"exprVal NumFormat:%1" ).arg( formatnum ?
"true" :
"false" ), 4 );
1661 int dInt = exprVal.toInt( &ok );
1663 if ( ok && dInt > 0 )
1665 decimalPlaces = dInt;
1673 signPlus = exprVal.toBool();
1674 QgsDebugMsgLevel( QString(
"exprVal NumPlusSign:%1" ).arg( signPlus ?
"true" :
"false" ), 4 );
1677 QVariant textV( labelText );
1679 double d = textV.toDouble( &ok );
1682 QString numberFormat;
1683 if ( d > 0 && signPlus )
1685 numberFormat.append(
"+" );
1687 numberFormat.append(
"%1" );
1688 labelText = numberFormat.arg( d, 0,
'f', decimalPlaces );
1694 QFontMetricsF* labelFontMetrics =
new QFontMetricsF( labelFont );
1695 double labelX, labelY;
1701 double maxcharanglein = 20.0;
1702 double maxcharangleout = -20.0;
1712 QString ptstr = exprVal.toString().trimmed();
1713 QgsDebugMsgLevel( QString(
"exprVal CurvedCharAngleInOut:%1" ).arg( ptstr ), 4 );
1715 if ( !ptstr.isEmpty() )
1718 maxcharanglein = qBound( 20.0, (
double )maxcharanglePt.x(), 60.0 );
1719 maxcharangleout = qBound( 20.0, (
double )maxcharanglePt.y(), 95.0 );
1723 maxcharangleout = -( qAbs( maxcharangleout ) );
1734 QScopedPointer<QgsGeometry> clonedGeometry;
1738 clonedGeometry.reset( geom );
1747 QgsDebugMsgLevel( QString(
"Ignoring feature %1 due transformation exception" ).arg( f.
id() ), 4 );
1766 QString str = exprVal.toString().trimmed();
1769 if ( !str.isEmpty() )
1771 if ( str.compare(
"Visible", Qt::CaseInsensitive ) == 0 )
1773 wholeCentroid =
false;
1775 else if ( str.compare(
"Whole", Qt::CaseInsensitive ) == 0 )
1777 wholeCentroid =
true;
1794 clonedGeometry.reset( geom );
1810 bool do_clip =
false;
1811 if ( !centroidPoly || ( centroidPoly && !wholeCentroid ) )
1822 clonedGeometry.reset( geom );
1826 const GEOSGeometry* geos_geom = geom->
asGeos();
1828 if ( geos_geom == NULL )
1857 GEOSGeometry* geos_geom_clone;
1868 bool dataDefinedPosition =
false;
1869 bool labelIsPinned =
false;
1870 bool layerDefinedRotation =
false;
1871 bool dataDefinedRotation =
false;
1872 double xPos = 0.0, yPos = 0.0,
angle = 0.0;
1873 bool ddXPos =
false, ddYPos =
false;
1874 double quadOffsetX = 0.0, quadOffsetY = 0.0;
1875 double offsetX = 0.0, offsetY = 0.0;
1882 int quadInt = exprVal.toInt( &ok );
1884 if ( ok && 0 <= quadInt && quadInt <= 8 )
1935 QString ptstr = exprVal.toString().trimmed();
1938 if ( !ptstr.isEmpty() )
1950 QString units = exprVal.toString().trimmed();
1952 if ( !units.isEmpty() )
1964 if ( !offinmapunits )
1966 offsetX *= mapUntsPerMM;
1972 if ( !offinmapunits )
1974 offsetY *= mapUntsPerMM;
1982 layerDefinedRotation =
true;
1990 double rotD = exprVal.toDouble( &ok );
1994 dataDefinedRotation =
true;
2004 if ( !exprVal.isNull() )
2005 xPos = exprVal.toDouble( &ddXPos );
2011 if ( !exprVal.isNull() )
2012 yPos = exprVal.toDouble( &ddYPos );
2015 if ( ddXPos && ddYPos )
2017 dataDefinedPosition =
true;
2018 labelIsPinned =
true;
2020 if ( layerDefinedRotation && !dataDefinedRotation )
2032 QString haliString = exprVal.toString();
2034 if ( haliString.compare(
"Center", Qt::CaseInsensitive ) == 0 )
2036 xdiff -= labelX / 2.0;
2038 else if ( haliString.compare(
"Right", Qt::CaseInsensitive ) == 0 )
2047 QString valiString = exprVal.toString();
2050 if ( valiString.compare(
"Bottom", Qt::CaseInsensitive ) != 0 )
2052 if ( valiString.compare(
"Top", Qt::CaseInsensitive ) == 0 )
2058 double descentRatio = labelFontMetrics->descent() / labelFontMetrics->height();
2059 if ( valiString.compare(
"Base", Qt::CaseInsensitive ) == 0 )
2061 ydiff -= labelY * descentRatio;
2065 double capHeightRatio = ( labelFontMetrics->boundingRect(
'H' ).height() + 1 + labelFontMetrics->descent() ) / labelFontMetrics->height();
2066 ydiff -= labelY * capHeightRatio;
2067 if ( valiString.compare(
"Half", Qt::CaseInsensitive ) == 0 )
2069 ydiff += labelY * ( capHeightRatio - descentRatio ) / 2.0;
2076 if ( dataDefinedRotation )
2079 double xd = xdiff * cos(
angle ) - ydiff * sin(
angle );
2080 double yd = xdiff * sin(
angle ) + ydiff * cos(
angle );
2091 ct->transformInPlace( xPos, yPos, z );
2096 QgsDebugMsgLevel( QString(
"Ignoring feature %1 due transformation exception on data-defined position" ).arg( f.
id() ), 4 );
2105 QTransform t = QTransform::fromTranslate( center.
x(), center.
y() );
2107 t.translate( -center.
x(), -center.
y() );
2108 double xPosR, yPosR;
2109 t.map( xPos, yPos, &xPosR, &yPosR );
2110 xPos = xPosR; yPos = yPosR;
2128 bool alwaysShow =
false;
2131 alwaysShow = exprVal.toBool();
2138 labelFont.letterSpacing(),
2139 labelFont.wordSpacing(),
2148 #if QT_VERSION >= 0x040800
2149 QgsDebugMsgLevel( QString(
"PAL font stored definedFont: %1, Style: %2" ).arg( labelFont.toString() ).arg( labelFont.styleName() ), 4 );
2159 double distD = exprVal.toDouble( &ok );
2170 QString units = exprVal.toString().trimmed();
2171 QgsDebugMsgLevel( QString(
"exprVal RepeatDistanceUnits:%1" ).arg( units ), 4 );
2172 if ( !units.isEmpty() )
2178 if ( repeatDist != 0 )
2180 if ( repeatdistinmapunit )
2195 xPos, yPos, dataDefinedPosition,
angle, dataDefinedRotation,
2196 quadOffsetX, quadOffsetY, offsetX, offsetY, alwaysShow, repeatDist ) )
2199 catch ( std::exception &e )
2202 QgsDebugMsgLevel( QString(
"Ignoring feature %1 due PAL exception:" ).arg( f.
id() ) + QString::fromLatin1( e.what() ), 4 );
2210 delete labelFontMetrics;
2215 double distance =
dist;
2219 double distD = exprVal.toDouble( &ok );
2230 QString units = exprVal.toString().trimmed();
2232 if ( !units.isEmpty() )
2238 if ( distance != 0 )
2240 if ( distinmapunit )
2253 QMap< DataDefinedProperties, QVariant >::const_iterator dIt = dataDefinedValues.constBegin();
2254 for ( ; dIt != dataDefinedValues.constEnd(); ++dIt )
2263 bool QgsPalLayerSettings::dataDefinedValEval(
const QString& valType,
2269 QString dbgStr = QString(
"exprVal %1:" ).arg( mDataDefinedNames.value( p ).first ) +
"%1";
2271 if ( valType == QString(
"bool" ) )
2273 bool bol = exprVal.toBool();
2275 dataDefinedValues.insert( p, QVariant( bol ) );
2278 if ( valType == QString(
"int" ) )
2281 int size = exprVal.toInt( &ok );
2286 dataDefinedValues.insert( p, QVariant( size ) );
2290 if ( valType == QString(
"intpos" ) )
2293 int size = exprVal.toInt( &ok );
2296 if ( ok && size > 0 )
2298 dataDefinedValues.insert( p, QVariant( size ) );
2302 if ( valType == QString(
"double" ) )
2305 double size = exprVal.toDouble( &ok );
2310 dataDefinedValues.insert( p, QVariant( size ) );
2314 if ( valType == QString(
"doublepos" ) )
2317 double size = exprVal.toDouble( &ok );
2320 if ( ok && size > 0.0 )
2322 dataDefinedValues.insert( p, QVariant( size ) );
2326 if ( valType == QString(
"rotation180" ) )
2329 double rot = exprVal.toDouble( &ok );
2333 if ( rot < -180.0 && rot >= -360 )
2337 if ( rot > 180.0 && rot <= 360 )
2341 if ( rot >= -180 && rot <= 180 )
2343 dataDefinedValues.insert( p, QVariant( rot ) );
2348 if ( valType == QString(
"transp" ) )
2351 int size = exprVal.toInt( &ok );
2353 if ( ok && size >= 0 && size <= 100 )
2355 dataDefinedValues.insert( p, QVariant( size ) );
2359 if ( valType == QString(
"string" ) )
2361 QString str = exprVal.toString();
2364 dataDefinedValues.insert( p, QVariant( str ) );
2367 if ( valType == QString(
"units" ) )
2369 QString unitstr = exprVal.toString().trimmed();
2372 if ( !unitstr.isEmpty() )
2374 dataDefinedValues.insert( p, QVariant((
int )
_decodeUnits( unitstr ) ) );
2378 if ( valType == QString(
"color" ) )
2380 QString colorstr = exprVal.toString().trimmed();
2384 if ( color.isValid() )
2386 dataDefinedValues.insert( p, QVariant( color ) );
2390 if ( valType == QString(
"joinstyle" ) )
2392 QString joinstr = exprVal.toString().trimmed();
2395 if ( !joinstr.isEmpty() )
2401 if ( valType == QString(
"blendmode" ) )
2403 QString blendstr = exprVal.toString().trimmed();
2406 if ( !blendstr.isEmpty() )
2412 if ( valType == QString(
"pointf" ) )
2414 QString ptstr = exprVal.toString().trimmed();
2417 if ( !ptstr.isEmpty() )
2427 void QgsPalLayerSettings::parseTextStyle( QFont& labelFont,
2440 QString ddFontFamily(
"" );
2443 QString family = exprVal.toString().trimmed();
2446 if ( labelFont.family() != family )
2452 ddFontFamily = family;
2458 QString ddFontStyle(
"" );
2461 QString fontstyle = exprVal.toString().trimmed();
2462 QgsDebugMsgLevel( QString(
"exprVal Font style:%1" ).arg( fontstyle ), 4 );
2463 ddFontStyle = fontstyle;
2467 bool ddBold =
false;
2470 bool bold = exprVal.toBool();
2471 QgsDebugMsgLevel( QString(
"exprVal Font bold:%1" ).arg( bold ?
"true" :
"false" ), 4 );
2476 bool ddItalic =
false;
2479 bool italic = exprVal.toBool();
2480 QgsDebugMsgLevel( QString(
"exprVal Font italic:%1" ).arg( italic ?
"true" :
"false" ), 4 );
2487 QFont appFont = QApplication::font();
2488 bool newFontBuilt =
false;
2489 if ( ddBold || ddItalic )
2492 newFont = QFont( !ddFontFamily.isEmpty() ? ddFontFamily : labelFont.family() );
2493 newFontBuilt =
true;
2494 newFont.setBold( ddBold );
2495 newFont.setItalic( ddItalic );
2497 else if ( !ddFontStyle.isEmpty()
2498 && ddFontStyle.compare(
"Ignore", Qt::CaseInsensitive ) != 0 )
2500 if ( !ddFontFamily.isEmpty() )
2503 QFont styledfont = mFontDB.font( ddFontFamily, ddFontStyle, appFont.pointSize() );
2504 if ( appFont != styledfont )
2506 newFont = styledfont;
2507 newFontBuilt =
true;
2514 else if ( !ddFontFamily.isEmpty() )
2516 if ( ddFontStyle.compare(
"Ignore", Qt::CaseInsensitive ) != 0 )
2519 QFont styledfont = mFontDB.font( ddFontFamily,
textNamedStyle, appFont.pointSize() );
2520 if ( appFont != styledfont )
2522 newFont = styledfont;
2523 newFontBuilt =
true;
2528 newFont = QFont( ddFontFamily );
2529 newFontBuilt =
true;
2537 newFont.setPixelSize( labelFont.pixelSize() );
2538 newFont.setCapitalization( labelFont.capitalization() );
2539 newFont.setUnderline( labelFont.underline() );
2540 newFont.setStrikeOut( labelFont.strikeOut() );
2541 newFont.setWordSpacing( labelFont.wordSpacing() );
2542 newFont.setLetterSpacing( QFont::AbsoluteSpacing, labelFont.letterSpacing() );
2544 labelFont = newFont;
2548 double wordspace = labelFont.wordSpacing();
2552 double wspacing = exprVal.toDouble( &ok );
2553 QgsDebugMsgLevel( QString(
"exprVal FontWordSpacing:%1" ).arg( wspacing ), 4 );
2556 wordspace = wspacing;
2562 double letterspace = labelFont.letterSpacing();
2566 double lspacing = exprVal.toDouble( &ok );
2567 QgsDebugMsgLevel( QString(
"exprVal FontLetterSpacing:%1" ).arg( lspacing ), 4 );
2570 letterspace = lspacing;
2576 QFont::Capitalization fontcaps = labelFont.capitalization();
2579 QString fcase = exprVal.toString().trimmed();
2582 if ( !fcase.isEmpty() )
2584 if ( fcase.compare(
"NoChange", Qt::CaseInsensitive ) == 0 )
2586 fontcaps = QFont::MixedCase;
2588 else if ( fcase.compare(
"Upper", Qt::CaseInsensitive ) == 0 )
2590 fontcaps = QFont::AllUppercase;
2592 else if ( fcase.compare(
"Lower", Qt::CaseInsensitive ) == 0 )
2594 fontcaps = QFont::AllLowercase;
2596 else if ( fcase.compare(
"Capitalize", Qt::CaseInsensitive ) == 0 )
2598 fontcaps = QFont::Capitalize;
2601 if ( fontcaps != labelFont.capitalization() )
2603 labelFont.setCapitalization( fontcaps );
2611 bool strikeout = exprVal.toBool();
2612 QgsDebugMsgLevel( QString(
"exprVal Font strikeout:%1" ).arg( strikeout ?
"true" :
"false" ), 4 );
2613 labelFont.setStrikeOut( strikeout );
2619 bool underline = exprVal.toBool();
2620 QgsDebugMsgLevel( QString(
"exprVal Font underline:%1" ).arg( underline ?
"true" :
"false" ), 4 );
2621 labelFont.setUnderline( underline );
2637 void QgsPalLayerSettings::parseTextBuffer()
2645 drawBuffer = exprVal.toBool();
2657 bufrSize = exprVal.toDouble();
2664 bufTransp = exprVal.toInt();
2667 drawBuffer = ( drawBuffer && bufrSize > 0.0 && bufTransp < 100 );
2690 void QgsPalLayerSettings::parseTextFormatting()
2698 wrapchr = exprVal.toString();
2707 QString str = exprVal.toString().trimmed();
2708 QgsDebugMsgLevel( QString(
"exprVal MultiLineAlignment:%1" ).arg( str ), 4 );
2710 if ( !str.isEmpty() )
2715 if ( str.compare(
"Center", Qt::CaseInsensitive ) == 0 )
2719 else if ( str.compare(
"Right", Qt::CaseInsensitive ) == 0 )
2731 drawDirSymb = exprVal.toBool();
2745 QString str = exprVal.toString().trimmed();
2746 QgsDebugMsgLevel( QString(
"exprVal DirSymbPlacement:%1" ).arg( str ), 4 );
2748 if ( !str.isEmpty() )
2753 if ( str.compare(
"Above", Qt::CaseInsensitive ) == 0 )
2757 else if ( str.compare(
"Below", Qt::CaseInsensitive ) == 0 )
2772 void QgsPalLayerSettings::parseShapeBackground()
2780 drawShape = exprVal.toBool();
2792 shapeTransp = exprVal.toInt();
2795 drawShape = ( drawShape && shapeTransp < 100 );
2808 QString skind = exprVal.toString().trimmed();
2811 if ( !skind.isEmpty() )
2816 if ( skind.compare(
"Square", Qt::CaseInsensitive ) == 0 )
2820 else if ( skind.compare(
"Ellipse", Qt::CaseInsensitive ) == 0 )
2824 else if ( skind.compare(
"Circle", Qt::CaseInsensitive ) == 0 )
2828 else if ( skind.compare(
"SVG", Qt::CaseInsensitive ) == 0 )
2832 shapeKind = shpkind;
2841 QString svgfile = exprVal.toString().trimmed();
2842 QgsDebugMsgLevel( QString(
"exprVal ShapeSVGFile:%1" ).arg( svgfile ), 4 );
2853 QString stype = exprVal.toString().trimmed();
2856 if ( !stype.isEmpty() )
2861 if ( stype.compare(
"Fixed", Qt::CaseInsensitive ) == 0 )
2865 shpSizeType = sizType;
2874 ddShpSizeX = exprVal.toDouble();
2881 ddShpSizeY = exprVal.toDouble();
2887 && ( svgPath.isEmpty()
2888 || ( !svgPath.isEmpty()
2890 && ddShpSizeX == 0.0 ) ) )
2896 && ( ddShpSizeX == 0.0 || ddShpSizeY == 0.0 ) )
2918 QString rotstr = exprVal.toString().trimmed();
2919 QgsDebugMsgLevel( QString(
"exprVal ShapeRotationType:%1" ).arg( rotstr ), 4 );
2921 if ( !rotstr.isEmpty() )
2926 if ( rotstr.compare(
"Offset", Qt::CaseInsensitive ) == 0 )
2930 else if ( rotstr.compare(
"Fixed", Qt::CaseInsensitive ) == 0 )
2973 void QgsPalLayerSettings::parseDropShadow()
2981 drawShadow = exprVal.toBool();
2993 shadowTransp = exprVal.toInt();
3000 shadowOffDist = exprVal.toDouble();
3007 shadowRad = exprVal.toDouble();
3010 drawShadow = ( drawShadow && shadowTransp < 100 && !( shadowOffDist == 0.0 && shadowRad == 0.0 ) );
3024 QString str = exprVal.toString().trimmed();
3027 if ( !str.isEmpty() )
3032 if ( str.compare(
"Text", Qt::CaseInsensitive ) == 0 )
3036 else if ( str.compare(
"Buffer", Qt::CaseInsensitive ) == 0 )
3040 else if ( str.compare(
"Background", Qt::CaseInsensitive ) == 0 )
3080 if ( unit ==
MapUnits && mapUnitsPerPixel > 0.0 )
3086 double ptsTomm = ( unit ==
Points ? 0.352778 : 1 );
3095 : mMapSettings( NULL ), mPal( NULL )
3149 bool enabled =
false;
3150 if ( layer->
customProperty(
"labeling" ).toString() == QString(
"pal" ) )
3151 enabled = layer->
customProperty(
"labeling/enabled", QVariant(
false ) ).toBool();
3159 QHash<QString, QgsPalLayerSettings>::iterator lit;
3172 QMap< QgsPalLayerSettings::DataDefinedProperties, QgsDataDefined* >::iterator it = lyr.
dataDefinedProperties.begin();
3175 delete( it.value() );
3196 if ( lyrTmp.fieldName.isEmpty() )
3201 if ( lyrTmp.isExpression )
3239 attrNames.append( name );
3248 QMap< QgsPalLayerSettings::DataDefinedProperties, QgsDataDefined* >::const_iterator dIt = lyr.
dataDefinedProperties.constBegin();
3260 QMap<QString, QVariant> exprParams;
3269 foreach ( QString name, cols )
3271 attrNames.append( name );
3285 default: Q_ASSERT(
"unsupported placement" && 0 );
return 0;
3289 double priority = 1 - lyr.
priority / 10.0;
3290 double min_scale = -1, max_scale = -1;
3300 min_scale, max_scale, arrangement,
3324 default: Q_ASSERT(
"unsupported upside-down label setting" && 0 );
return 0;
3385 double priority = 1 - s->
priority / 10.0;
3416 QHash<QString, QgsDiagramLayerSettings>::iterator layerIt =
mActiveDiagramLayers.find( layerID );
3426 if ( settingList.size() > 0 )
3428 double minScale = settingList.at( 0 ).minScaleDenominator;
3434 double maxScale = settingList.at( 0 ).maxScaleDenominator;
3447 QScopedPointer<QgsGeometry> clonedGeometry;
3448 if ( layerIt.value().ct )
3451 clonedGeometry.reset( geom );
3455 geom->
transform( *( layerIt.value().ct ) );
3460 QgsDebugMsgLevel( QString(
"Ignoring feature %1 due transformation exception" ).arg( feat.
id() ), 4 );
3465 const GEOSGeometry* geos_geom = geom->
asGeos();
3466 if ( geos_geom == 0 )
3476 layerIt.value().geometries.append( lbl );
3478 double diagramWidth = 0;
3479 double diagramHeight = 0;
3483 if ( diagSize.isValid() )
3485 diagramWidth = diagSize.width();
3486 diagramHeight = diagSize.height();
3494 int ddColX = layerIt.value().xPosColumn;
3495 int ddColY = layerIt.value().yPosColumn;
3496 double ddPosX = 0.0;
3497 double ddPosY = 0.0;
3498 bool ddPos = ( ddColX >= 0 && ddColY >= 0 );
3501 bool posXOk, posYOk;
3503 ddPosX = feat.
attribute( ddColX ).toDouble( &posXOk ) - diagramWidth / 2.0;
3504 ddPosY = feat.
attribute( ddColY ).toDouble( &posYOk ) - diagramHeight / 2.0;
3505 if ( !posXOk || !posYOk )
3522 if ( !layerIt.value().palLayer->registerFeature( lbl->
strId(), lbl, diagramWidth, diagramHeight,
"", ddPosX, ddPosY, ddPos ) )
3527 catch ( std::exception &e )
3530 QgsDebugMsgLevel( QString(
"Ignoring feature %1 due PAL exception:" ).arg( feat.
id() ) + QString::fromLatin1( e.what() ), 4 );
3535 QgsPoint ptZero = layerIt.value().xform->toMapCoordinates( 0, 0 );
3536 QgsPoint ptOne = layerIt.value().xform->toMapCoordinates( 1, 0 );
3537 palFeat->
setDistLabel( qAbs( ptOne.
x() - ptZero.
x() ) * layerIt.value().dist );
3588 QHash<QString, QgsPalLayerSettings>::iterator lit;
3591 if ( lit.key() == layerName )
3600 const QMap< QgsPalLayerSettings::DataDefinedProperties, QVariant >& ddValues )
3606 tmpLyr.
textColor = ddColor.value<QColor>();
3625 const QMap< QgsPalLayerSettings::DataDefinedProperties, QVariant >& ddValues )
3678 const QMap< QgsPalLayerSettings::DataDefinedProperties, QVariant >& ddValues )
3735 const QMap< QgsPalLayerSettings::DataDefinedProperties, QVariant >& ddValues )
3846 const QMap< QgsPalLayerSettings::DataDefinedProperties, QVariant >& ddValues )
3921 QPainter* painter = context.
painter();
3937 std::list<LabelPosition*>* labels;
3943 catch ( std::exception& e )
3946 QgsDebugMsgLevel(
"PAL EXCEPTION :-( " + QString::fromLatin1( e.what() ), 4 );
3971 painter->setPen( QColor( 0, 0, 0, 64 ) );
3972 painter->setBrush( Qt::NoBrush );
3987 QgsDebugMsgLevel( QString(
"LABELING work: %1 ms ... labels# %2" ).arg( t.elapsed() ).arg( labels->size() ), 4 );
3998 painter->setRenderHint( QPainter::Antialiasing );
4001 std::list<LabelPosition*>::iterator it = labels->begin();
4002 for ( ; it != labels->end(); ++it )
4014 QString layerName = QString::fromUtf8(( *it )->getLayerName() );
4022 if ( QString( dit.key() +
"d" ) == layerName )
4024 feature.
setFields( &dit.value().fields );
4025 palGeometry->
feature( feature );
4027 dit.value().renderer->renderDiagram( feature, context, outPt.
toQPointF() );
4035 QString layerId = layerName;
4037 mResults->mLabelSearchTree->
insertLabel( *it, QString( palGeometry->
strId() ).toInt(), QString(
"" ), layerId, QFont(),
true, false );
4050 const QMap< QgsPalLayerSettings::DataDefinedProperties, QVariant >& ddValues = palGeometry->
dataDefinedValues();
4055 #if QT_VERSION >= 0x040800
4057 QgsDebugMsgLevel( QString(
"PAL font definedFont: %1, Style: %2" ).arg( dFont.toString() ).arg( dFont.styleName() ), 4 );
4112 QString labeltext = ((
QgsPalGeometry* )( *it )->getFeaturePart()->getUserGeometry() )->text();
4118 painter->setCompositionMode( QPainter::CompositionMode_SourceOver );
4120 QgsDebugMsgLevel( QString(
"LABELING draw: %1 ms" ).arg( t.elapsed() ), 4 );
4130 QHash<QString, QgsPalLayerSettings>::iterator lit;
4134 for ( QList<QgsPalGeometry*>::iterator git = lyr.
geometries.begin(); git != lyr.
geometries.end(); ++git )
4151 for ( QList<QgsPalGeometry*>::iterator git = dls.
geometries.begin(); git != dls.
geometries.end(); ++git )
4211 #if 0 // TODO: generalize some of this
4214 double cx = lp->
getX() + w / 2.0;
4215 double cy = lp->
getY() + h / 2.0;
4218 double sw = w * scale;
4219 double sh = h * scale;
4220 QRectF rect( -sw / 2, -sh / 2, sw, sh );
4230 painter->rotate( rotation );
4233 painter->translate( rect.bottomLeft() );
4235 painter->translate( -rect.bottomLeft() );
4238 QRectF rect( 0, 0, outPt2.
x() - outPt.
x(), outPt2.
y() - outPt.
y() );
4239 painter->translate( QPointF( outPt.
x(), outPt.
y() ) );
4243 painter->drawRect( rect );
4247 rect.moveTo( outPt.
x(), outPt.
y() );
4258 QPainter* painter = context.
painter();
4287 double xc = outPt2.
x() - outPt.
x();
4288 double yc = outPt2.
y() - outPt.
y();
4291 double xd = xc * cos( angle ) - yc * sin( angle );
4292 double yd = xc * sin( angle ) + yc * cos( angle );
4294 centerPt.
setX( centerPt.
x() + xd );
4295 centerPt.
setY( centerPt.
y() + yd );
4309 QString txt = ( label->
getPartId() == -1 ? text : QString( text[label->
getPartId()] ) );
4312 QString wrapchr = !tmpLyr.
wrapChar.isEmpty() ? tmpLyr.
wrapChar : QString(
"\n" );
4318 bool prependSymb =
false;
4336 prependSymb =
false;
4344 symb = symb + wrapchr;
4348 prependSymb =
false;
4349 symb = wrapchr + symb;
4354 txt.prepend( symb );
4364 QStringList multiLineList = txt.split( wrapchr );
4365 int lines = multiLineList.size();
4367 double labelWidest = 0.0;
4368 for (
int i = 0; i < lines; ++i )
4370 double labelWidth = labelfm->width( multiLineList.at( i ) );
4371 if ( labelWidth > labelWidest )
4373 labelWidest = labelWidth;
4377 double labelHeight = labelfm->ascent() + labelfm->descent();
4381 double ascentOffset = 0.25 * labelfm->ascent();
4383 for (
int i = 0; i < lines; ++i )
4386 #if 0 // TODO: generalize some of this
4390 double cx = lp->
getX() + w / 2.0;
4391 double cy = lp->
getY() + h / 2.0;
4394 double sw = w * scale;
4395 double sh = h * scale;
4396 QRectF rect( -sw / 2, -sh / 2, sw, sh );
4405 painter->rotate( rotation );
4408 painter->translate( rect.bottomLeft() );
4411 painter->translate( QPointF( outPt.
x(), outPt.
y() ) );
4420 double xMultiLineOffset = 0.0;
4421 double labelWidth = labelfm->width( multiLineList.at( i ) );
4424 double labelWidthDiff = labelWidest - labelWidth;
4427 labelWidthDiff /= 2;
4429 xMultiLineOffset = labelWidthDiff;
4433 double yMultiLineOffset = ( lines - 1 - i ) * labelHeight * tmpLyr.
multilineHeight;
4434 painter->translate( QPointF( xMultiLineOffset, - ascentOffset - yMultiLineOffset ) );
4436 component.
setText( multiLineList.at( i ) );
4451 path.addText( 0, 0, tmpLyr.
textFont, component.
text() );
4456 textp.begin( &textPict );
4457 textp.setPen( Qt::NoPen );
4459 textp.drawPath( path );
4479 painter->setCompositionMode( tmpLyr.
blendMode );
4489 painter->drawPicture( 0, 0, textPict );
4494 painter->setFont( tmpLyr.
textFont );
4496 painter->setRenderHint( QPainter::TextAntialiasing );
4497 painter->drawText( 0, 0, component.
text() );
4513 QPainter* p = context.
painter();
4519 path.addText( 0, 0, tmpLyr.
textFont, component.
text() );
4521 pen.setWidthF( penSize );
4527 tmpColor.setAlpha( 0 );
4533 buffp.begin( &buffPict );
4534 buffp.setPen( pen );
4535 buffp.setBrush( tmpColor );
4536 buffp.drawPath( path );
4560 p->drawPicture( 0, 0, buffPict );
4568 QPainter* p = context.
painter();
4569 double labelWidth = component.
size().
x(), labelHeight = component.
size().
y();
4599 double sizeOut = 0.0;
4608 if ( labelWidth >= labelHeight )
4609 sizeOut = labelWidth;
4610 else if ( labelHeight > labelWidth )
4611 sizeOut = labelHeight;
4616 sizeOut /= mmToMapUnits;
4630 map[
"size"] = QString::number( sizeOut );
4633 map[
"angle"] = QString::number( 0.0 );
4661 svgp.begin( &svgPict );
4680 svgShdwM->
renderPoint( QPointF( svgSize / 2, -svgSize / 2 ), svgShdwContext );
4697 p->translate( QPointF( xoff, yoff ) );
4699 p->translate( -svgSize / 2, svgSize / 2 );
4723 p->translate( QPointF( xoff, yoff ) );
4726 p->setCompositionMode( QPainter::CompositionMode_SourceOver );
4760 h = sqrt( pow( w, 2 ) + pow( h, 2 ) );
4766 h = h / sqrt( 2.0 ) * 2;
4767 w = w / sqrt( 2.0 ) * 2;
4779 QRectF rect( -w / 2.0, - h / 2.0, w, h );
4781 if ( rect.isNull() )
4785 p->translate( QPointF( component.
center().
x(), component.
center().
y() ) );
4789 p->translate( QPointF( xoff, yoff ) );
4798 pen.setWidthF( penSize );
4810 shapep.begin( &shapePict );
4811 shapep.setPen( pen );
4819 shapep.drawRoundedRect( rect, tmpLyr.
shapeRadii.x(), tmpLyr.
shapeRadii.y(), Qt::RelativeSize );
4825 shapep.drawRoundedRect( rect, xRadius, yRadius );
4831 shapep.drawEllipse( rect );
4856 p->drawPicture( 0, 0, shapePict );
4869 QPainter* p = context.
painter();
4870 double componentWidth = component.
size().
x(), componentHeight = component.
size().
y();
4871 double xOffset = component.
offset().
x(), yOffset = component.
offset().
y();
4878 radius = ( int )( radius + 0.5 );
4882 double blurBufferClippingScale = 3.75;
4883 int blurbuffer = ( radius > 17 ? 16 : radius ) * blurBufferClippingScale;
4885 QImage blurImg( componentWidth + ( pictbuffer * 2.0 ) + ( blurbuffer * 2.0 ),
4886 componentHeight + ( pictbuffer * 2.0 ) + ( blurbuffer * 2.0 ),
4887 QImage::Format_ARGB32_Premultiplied );
4891 int minBlurImgSize = 1;
4895 int maxBlurImgSize = 40000;
4896 if ( blurImg.isNull()
4897 || ( blurImg.width() < minBlurImgSize || blurImg.height() < minBlurImgSize )
4898 || ( blurImg.width() > maxBlurImgSize || blurImg.height() > maxBlurImgSize ) )
4901 blurImg.fill( QColor( Qt::transparent ).rgba() );
4903 if ( !pictp.begin( &blurImg ) )
4905 pictp.setRenderHints( QPainter::Antialiasing | QPainter::SmoothPixmapTransform );
4906 QPointF imgOffset( blurbuffer + pictbuffer + xOffset,
4907 blurbuffer + pictbuffer + componentHeight + yOffset );
4909 pictp.drawPicture( imgOffset,
4913 pictp.setCompositionMode( QPainter::CompositionMode_SourceIn );
4914 pictp.fillRect( blurImg.rect(), tmpLyr.
shadowColor );
4927 picti.begin( &blurImg );
4928 picti.setBrush( Qt::Dense7Pattern );
4929 QPen imgPen( QColor( 0, 0, 255, 255 ) );
4930 imgPen.setWidth( 1 );
4931 picti.setPen( imgPen );
4932 picti.setOpacity( 0.1 );
4933 picti.drawRect( 0, 0, blurImg.width(), blurImg.height() );
4949 QPointF transPt( -offsetDist * cos( angleRad +
M_PI / 2 ),
4950 -offsetDist * sin( angleRad +
M_PI / 2 ) );
4953 p->setRenderHints( QPainter::Antialiasing | QPainter::SmoothPixmapTransform );
4960 double scale = ( double )tmpLyr.
shadowScale / 100.0;
4962 p->scale( scale, scale );
4967 p->translate( transPt );
4968 p->translate( -imgOffset.x(),
4970 p->drawImage( 0, 0, blurImg );
4978 p->setBrush( Qt::NoBrush );
4979 QPen imgPen( QColor( 255, 0, 0, 10 ) );
4980 imgPen.setWidth( 2 );
4981 imgPen.setStyle( Qt::DashLine );
4982 p->setPen( imgPen );
4983 p->scale( scale, scale );
4988 p->translate( transPt );
4989 p->translate( -imgOffset.x(),
4991 p->drawRect( 0, 0, blurImg.width(), blurImg.height() );
4996 p->setBrush( Qt::NoBrush );
4997 QPen componentRectPen( QColor( 0, 255, 0, 70 ) );
4998 componentRectPen.setWidth( 1 );
5003 p->setPen( componentRectPen );
5004 p->drawRect( QRect( -xOffset, -componentHeight - yOffset, componentWidth, componentHeight ) );
5015 "PAL",
"/SearchMethod", (
int )p.
getSearch(), &saved ) );
5017 "PAL",
"/CandidatesPoint", p.
getPointP(), &saved );
5019 "PAL",
"/CandidatesLine", p.
getLineP(), &saved );
5021 "PAL",
"/CandidatesPolygon", p.
getPolyP(), &saved );
5023 "PAL",
"/ShowingCandidates",
false, &saved );
5025 "PAL",
"/ShowingShadowRects",
false, &saved );
5027 "PAL",
"/ShowingAllLabels",
false, &saved );
5031 "PAL",
"/DrawOutlineLabels",
true, &saved );
5079 delete mLabelSearchTree;
5080 mLabelSearchTree = NULL;
5085 QList<QgsLabelPosition> positions;
5087 QList<QgsLabelPosition*> positionPointers;
5088 if ( mLabelSearchTree )
5090 mLabelSearchTree->
label( p, positionPointers );
5091 QList<QgsLabelPosition*>::const_iterator pointerIt = positionPointers.constBegin();
5092 for ( ; pointerIt != positionPointers.constEnd(); ++pointerIt )
5103 QList<QgsLabelPosition> positions;
5105 QList<QgsLabelPosition*> positionPointers;
5106 if ( mLabelSearchTree )
5109 QList<QgsLabelPosition*>::const_iterator pointerIt = positionPointers.constBegin();
5110 for ( ; pointerIt != positionPointers.constEnd(); ++pointerIt )