24 #include <pal/feature.h>
25 #include <pal/layer.h>
26 #include <pal/palgeometry.h>
27 #include <pal/palexception.h>
28 #include <pal/problem.h>
29 #include <pal/labelposition.h>
35 #include <QApplication>
38 #include <QFontMetrics>
42 #include "diagram/qgsdiagram.h"
59 #include <QMessageBox>
68 qreal ltrSpacing = 0.0, qreal wordSpacing = 0.0,
bool curvedLabeling =
false )
75 , mFontMetrics( NULL )
76 , mLetterSpacing( ltrSpacing )
77 , mWordSpacing( wordSpacing )
78 , mCurvedLabeling( curvedLabeling )
81 mDefinedFont = QFont();
87 GEOSGeom_destroy( mG );
94 const GEOSGeometry* getGeosGeometry()
98 void releaseGeosGeometry(
const GEOSGeometry* )
103 const char* strId() {
return mStrId.data(); }
104 QString text() {
return mText; }
106 pal::LabelInfo* info( QFontMetricsF* fm,
const QgsMapToPixel* xform,
double fontScale,
double maxinangle,
double maxoutangle )
111 mFontMetrics =
new QFontMetricsF( *fm );
114 if ( maxinangle < 20.0 )
116 if ( 60.0 < maxinangle )
118 if ( maxoutangle > -20.0 )
120 if ( -95.0 > maxoutangle )
131 mInfo =
new pal::LabelInfo( mText.count(), ptSize.
y() - ptZero.
y(), maxinangle, maxoutangle );
132 for (
int i = 0; i < mText.count(); i++ )
134 mInfo->char_info[i].chr = mText[i].unicode();
138 charWidth = fm->width( mText[i] );
139 if ( mCurvedLabeling )
141 wordSpaceFix = qreal( 0.0 );
142 if ( mText[i] == QString(
" " )[0] )
146 wordSpaceFix = ( nxt < mText.count() && mText[nxt] != QString(
" " )[0] ) ? mWordSpacing : qreal( 0.0 );
148 if ( fm->width( QString( mText[i] ) ) - fm->width( mText[i] ) - mLetterSpacing != qreal( 0.0 ) )
151 wordSpaceFix -= mWordSpacing;
153 charWidth = fm->width( QString( mText[i] ) ) + wordSpaceFix;
157 mInfo->char_info[i].width = ptSize.
x() - ptZero.
x();
162 const QMap< QgsPalLayerSettings::DataDefinedProperties, QVariant >& dataDefinedValues()
const {
return mDataDefinedValues; }
165 void setIsDiagram(
bool d ) { mIsDiagram = d; }
166 bool isDiagram()
const {
return mIsDiagram; }
168 void setIsPinned(
bool f ) { mIsPinned = f; }
169 bool isPinned()
const {
return mIsPinned; }
171 void setDefinedFont( QFont f ) { mDefinedFont = QFont( f ); }
172 QFont definedFont() {
return mDefinedFont; }
174 QFontMetricsF* getLabelFontMetrics() {
return mFontMetrics; }
176 void setDiagramAttributes(
const QgsAttributes& attrs,
const QgsFields* fields ) { mDiagramAttributes = attrs; mDiagramFields = fields; }
177 const QgsAttributes& diagramAttributes() {
return mDiagramAttributes; }
182 feature.
setFields( mDiagramFields,
false );
196 QFontMetricsF* mFontMetrics;
197 qreal mLetterSpacing;
199 bool mCurvedLabeling;
201 QMap< QgsPalLayerSettings::DataDefinedProperties, QVariant > mDataDefinedValues;
217 , mFeaturesToLabel( 0 )
218 , mFeatsSendingToPal( 0 )
230 blendMode = QPainter::CompositionMode_SourceOver;
588 int r = layer->
customProperty( property +
"R", QVariant( defaultColor.red() ) ).toInt();
589 int g = layer->
customProperty( property +
"G", QVariant( defaultColor.green() ) ).toInt();
590 int b = layer->
customProperty( property +
"B", QVariant( defaultColor.blue() ) ).toInt();
591 int a = withAlpha ? layer->
customProperty( property +
"A", QVariant( defaultColor.alpha() ) ).toInt() : 255;
592 return QColor( r, g, b, a );
606 if ( str.compare(
"Point", Qt::CaseInsensitive ) == 0
608 if ( str.compare(
"MapUnit", Qt::CaseInsensitive ) == 0
616 if ( str.compare(
"Lighten", Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_Lighten;
617 if ( str.compare(
"Screen", Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_Screen;
618 if ( str.compare(
"Dodge", Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_ColorDodge;
619 if ( str.compare(
"Addition", Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_Plus;
620 if ( str.compare(
"Darken", Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_Darken;
621 if ( str.compare(
"Multiply", Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_Multiply;
622 if ( str.compare(
"Burn", Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_ColorBurn;
623 if ( str.compare(
"Overlay", Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_Overlay;
624 if ( str.compare(
"SoftLight", Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_SoftLight;
625 if ( str.compare(
"HardLight", Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_HardLight;
626 if ( str.compare(
"Difference", Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_Difference;
627 if ( str.compare(
"Subtract", Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_Exclusion;
628 return QPainter::CompositionMode_SourceOver;
633 if ( str.compare(
"Miter", Qt::CaseInsensitive ) == 0 )
return Qt::MiterJoin;
634 if ( str.compare(
"Round", Qt::CaseInsensitive ) == 0 )
return Qt::RoundJoin;
635 return Qt::BevelJoin;
639 QMap < QgsPalLayerSettings::DataDefinedProperties, QgsDataDefined* > & propertyMap )
646 QMapIterator<QgsPalLayerSettings::DataDefinedProperties, QPair<QString, int> > i(
mDataDefinedNames );
647 while ( i.hasNext() )
655 const QMap < QgsPalLayerSettings::DataDefinedProperties, QgsDataDefined* > & propertyMap )
662 QMapIterator<QgsPalLayerSettings::DataDefinedProperties, QPair<QString, int> > i(
mDataDefinedNames );
663 while ( i.hasNext() )
666 QString newPropertyName =
"labeling/dataDefined/" + i.value().first;
667 QVariant propertyValue = QVariant();
669 QMap< QgsPalLayerSettings::DataDefinedProperties, QgsDataDefined* >::const_iterator it = propertyMap.find( i.key() );
670 if ( it != propertyMap.constEnd() )
678 QString field = dd->
field();
680 bool defaultVals = ( !active && !useExpr && expr.isEmpty() && field.isEmpty() );
686 values << ( active ?
"1" :
"0" );
687 values << ( useExpr ?
"1" :
"0" );
690 if ( !values.isEmpty() )
692 propertyValue = QVariant( values.join(
"~~" ) );
698 if ( propertyValue.isValid() )
708 if ( layer->
customProperty( newPropertyName, QVariant() ).isValid() && i.value().second > -1 )
711 layer->
removeCustomProperty( QString(
"labeling/dataDefinedProperty" ) + QString::number( i.value().second ) );
718 QMap < QgsPalLayerSettings::DataDefinedProperties, QgsDataDefined* > & propertyMap )
720 QString newPropertyName =
"labeling/dataDefined/" +
mDataDefinedNames.value( p ).first;
721 QVariant newPropertyField = layer->
customProperty( newPropertyName, QVariant() );
723 QString ddString = QString();
724 if ( newPropertyField.isValid() )
726 ddString = newPropertyField.toString();
737 QString oldPropertyName =
"labeling/dataDefinedProperty" + QString::number( oldIndx );
738 QVariant oldPropertyField = layer->
customProperty( oldPropertyName, QVariant() );
740 if ( !oldPropertyField.isValid() )
747 int indx = oldPropertyField.toInt( &conversionOk );
757 if ( !oldIndicesToNames.isEmpty() )
759 ddString = oldIndicesToNames.value( indx );
764 if ( indx < fields.
size() )
766 ddString = fields.
at( indx ).
name();
771 if ( !ddString.isEmpty() )
784 if ( oldIndx == 16 || oldIndx == 17 )
795 if ( !ddString.isEmpty() && ddString != QString(
"0~~0~~~~" ) )
799 QStringList ddv = newStyleString.split(
"~~" );
802 propertyMap.insert( p, dd );
813 if ( layer->
customProperty(
"labeling" ).toString() != QString(
"pal" ) )
823 QFont appFont = QApplication::font();
835 fontFamily = appFont.family();
838 double fontSize = layer->
customProperty(
"labeling/fontSize" ).toDouble();
840 int fontWeight = layer->
customProperty(
"labeling/fontWeight" ).toInt();
841 bool fontItalic = layer->
customProperty(
"labeling/fontItalic" ).toBool();
842 textFont = QFont( fontFamily, fontSize, fontWeight, fontItalic );
846 textFont.setCapitalization(( QFont::Capitalization )layer->
customProperty(
"labeling/fontCapitals", QVariant( 0 ) ).toUInt() );
849 textFont.setLetterSpacing( QFont::AbsoluteSpacing, layer->
customProperty(
"labeling/fontLetterSpacing", QVariant( 0.0 ) ).toDouble() );
850 textFont.setWordSpacing( layer->
customProperty(
"labeling/fontWordSpacing", QVariant( 0.0 ) ).toDouble() );
872 double bufSize = layer->
customProperty(
"labeling/bufferSize", QVariant( 0.0 ) ).toDouble();
875 QVariant drawBuffer = layer->
customProperty(
"labeling/bufferDraw", QVariant() );
876 if ( drawBuffer.isValid() )
881 else if ( bufSize != 0.0 )
906 layer->
customProperty(
"labeling/shapeSizeY", QVariant( 0.0 ) ).toDouble() );
911 layer->
customProperty(
"labeling/shapeOffsetY", QVariant( 0.0 ) ).toDouble() );
914 layer->
customProperty(
"labeling/shapeRadiiY", QVariant( 0.0 ) ).toDouble() );
958 int scalemn = layer->
customProperty(
"labeling/scaleMin", QVariant( 0 ) ).toInt();
959 int scalemx = layer->
customProperty(
"labeling/scaleMax", QVariant( 0 ) ).toInt();
962 QVariant scalevis = layer->
customProperty(
"labeling/scaleVisibility", QVariant() );
963 if ( scalevis.isValid() )
969 else if ( scalemn > 0 || scalemx > 0 )
1124 bool active,
bool useExpr,
const QString& expr,
const QString& field )
1126 bool defaultVals = ( !active && !useExpr && expr.isEmpty() && field.isEmpty() );
1130 QMap< QgsPalLayerSettings::DataDefinedProperties, QgsDataDefined* >::const_iterator it =
dataDefinedProperties.find( p );
1140 else if ( !defaultVals )
1152 delete( it.value() );
1160 QString newValue = value;
1161 if ( !value.isEmpty() && !value.contains(
"~~" ) )
1168 newValue = values.join(
"~~" );
1176 QMap< QgsPalLayerSettings::DataDefinedProperties, QgsDataDefined* >::const_iterator it =
dataDefinedProperties.find( p );
1186 QMap<QString, QString> map;
1187 QMap< QgsPalLayerSettings::DataDefinedProperties, QgsDataDefined* >::const_iterator it =
dataDefinedProperties.find( p );
1190 return it.value()->toMap();
1203 QMap< DataDefinedProperties, QgsDataDefined* >::const_iterator it =
dataDefinedProperties.find( p );
1219 QVariant result = QVariant();
1221 QString field = dd->
field();
1240 else if ( !useExpression && !field.isEmpty() )
1259 if ( result.isValid() )
1272 bool isActive =
false;
1273 QMap< DataDefinedProperties, QgsDataDefined* >::const_iterator it =
dataDefinedProperties.find( p );
1276 isActive = it.value()->isActive();
1284 bool useExpression =
false;
1285 QMap< DataDefinedProperties, QgsDataDefined* >::const_iterator it =
dataDefinedProperties.find( p );
1288 useExpression = it.value()->useExpression();
1291 return useExpression;
1315 double length = geom->
length();
1316 if ( length >= 0.0 )
1318 return ( length >= ( minSize * mapUnitsPerMM ) );
1323 double area = geom->
area();
1326 return ( sqrt( area ) >= ( minSize * mapUnitsPerMM ) );
1387 if ( exprVal.isValid() )
1389 wrapchr = exprVal.toString();
1393 if ( exprVal.isValid() )
1396 double size = exprVal.toDouble( &ok );
1405 if ( exprVal.isValid() )
1407 addDirSymb = exprVal.toBool();
1414 if ( exprVal.isValid() )
1416 leftDirSymb = exprVal.toString();
1420 if ( exprVal.isValid() )
1422 rightDirSymb = exprVal.toString();
1426 if ( exprVal.isValid() )
1429 int enmint = exprVal.toInt( &ok );
1439 if ( wrapchr.isEmpty() )
1441 wrapchr = QString(
"\n" );
1446 && ( !leftDirSymb.isEmpty() || !rightDirSymb.isEmpty() ) )
1448 QString dirSym = leftDirSymb;
1450 if ( fm->width( rightDirSymb ) > fm->width( dirSym ) )
1451 dirSym = rightDirSymb;
1455 text.append( dirSym );
1459 text.prepend( dirSym + wrapchr );
1463 double w = 0.0, h = 0.0;
1464 QStringList multiLineSplit = text.split( wrapchr );
1465 int lines = multiLineSplit.size();
1467 double labelHeight = fm->ascent() + fm->descent();
1469 h += fm->height() + ( double )(( lines - 1 ) * labelHeight * multilineH );
1472 for (
int i = 0; i < lines; ++i )
1474 double width = fm->width( multiLineSplit.at( i ) );
1483 labelX = qAbs( ptSize.
x() - ptZero.
x() );
1484 labelY = qAbs( ptSize.
y() - ptZero.
y() );
1502 QgsDebugMsgLevel( QString(
"exprVal Show:%1" ).arg( exprVal.toBool() ?
"true" :
"false" ), 4 );
1503 if ( !exprVal.toBool() )
1513 QgsDebugMsgLevel( QString(
"exprVal ScaleVisibility:%1" ).arg( exprVal.toBool() ?
"true" :
"false" ), 4 );
1514 useScaleVisibility = exprVal.toBool();
1517 if ( useScaleVisibility )
1523 QgsDebugMsgLevel( QString(
"exprVal MinScale:%1" ).arg( exprVal.toDouble() ), 4 );
1525 double mins = exprVal.toDouble( &conversionOk );
1535 minScale = 1 / qAbs( minScale );
1547 QgsDebugMsgLevel( QString(
"exprVal MaxScale:%1" ).arg( exprVal.toDouble() ), 4 );
1549 double maxs = exprVal.toDouble( &conversionOk );
1559 maxScale = 1 / qAbs( maxScale );
1575 QString units = exprVal.toString().trimmed();
1577 if ( !units.isEmpty() )
1584 double fontSize = labelFont.pointSizeF();
1587 QgsDebugMsgLevel( QString(
"exprVal Size:%1" ).arg( exprVal.toDouble() ), 4 );
1589 double size = exprVal.toDouble( &ok );
1595 if ( fontSize <= 0.0 )
1600 int fontPixelSize =
sizeToPixel( fontSize, context, fontunits,
true );
1602 if ( fontPixelSize < 1 )
1606 labelFont.setPixelSize( fontPixelSize );
1616 QgsDebugMsgLevel( QString(
"exprVal FontLimitPixel:%1" ).arg( exprVal.toBool() ?
"true" :
"false" ), 4 );
1617 useFontLimitPixelSize = exprVal.toBool();
1620 if ( useFontLimitPixelSize )
1626 int sizeInt = exprVal.toInt( &ok );
1627 QgsDebugMsgLevel( QString(
"exprVal FontMinPixel:%1" ).arg( sizeInt ), 4 );
1630 fontMinPixel = sizeInt;
1638 int sizeInt = exprVal.toInt( &ok );
1639 QgsDebugMsgLevel( QString(
"exprVal FontMaxPixel:%1" ).arg( sizeInt ), 4 );
1642 fontMaxPixel = sizeInt;
1646 if ( fontMinPixel > labelFont.pixelSize() || labelFont.pixelSize() > fontMaxPixel )
1677 QVariant result = exp->
evaluate( &f );
1683 labelText = result.toString();
1694 formatnum = exprVal.toBool();
1695 QgsDebugMsgLevel( QString(
"exprVal NumFormat:%1" ).arg( formatnum ?
"true" :
"false" ), 4 );
1706 int dInt = exprVal.toInt( &ok );
1708 if ( ok && dInt > 0 )
1710 decimalPlaces = dInt;
1718 signPlus = exprVal.toBool();
1719 QgsDebugMsgLevel( QString(
"exprVal NumPlusSign:%1" ).arg( signPlus ?
"true" :
"false" ), 4 );
1722 QVariant textV = QVariant( labelText );
1724 double d = textV.toDouble( &ok );
1727 QString numberFormat;
1728 if ( d > 0 && signPlus )
1730 numberFormat.append(
"+" );
1732 numberFormat.append(
"%1" );
1733 labelText = numberFormat.arg( d, 0,
'f', decimalPlaces );
1739 QFontMetricsF* labelFontMetrics =
new QFontMetricsF( labelFont );
1740 double labelX, labelY;
1746 double maxcharanglein = 20.0;
1747 double maxcharangleout = -20.0;
1757 QString ptstr = exprVal.toString().trimmed();
1758 QgsDebugMsgLevel( QString(
"exprVal CurvedCharAngleInOut:%1" ).arg( ptstr ), 4 );
1760 if ( !ptstr.isEmpty() )
1763 maxcharanglein = qBound( 20.0, (
double )maxcharanglePt.x(), 60.0 );
1764 maxcharangleout = qBound( 20.0, (
double )maxcharanglePt.y(), 95.0 );
1768 maxcharangleout = -( qAbs( maxcharangleout ) );
1786 QgsDebugMsgLevel( QString(
"Ignoring feature %1 due transformation exception" ).arg( f.
id() ), 4 );
1805 QString str = exprVal.toString().trimmed();
1808 if ( !str.isEmpty() )
1810 if ( str.compare(
"Visible", Qt::CaseInsensitive ) == 0 )
1812 wholeCentroid =
false;
1814 else if ( str.compare(
"Whole", Qt::CaseInsensitive ) == 0 )
1816 wholeCentroid =
true;
1823 bool do_clip =
false;
1824 if ( !centroidPoly || ( centroidPoly && !wholeCentroid ) )
1837 const GEOSGeometry* geos_geom = geom->
asGeos();
1839 if ( geos_geom == NULL )
1868 GEOSGeometry* geos_geom_clone = GEOSGeom_clone( geos_geom );
1871 bool dataDefinedPosition =
false;
1872 bool labelIsPinned =
false;
1873 bool layerDefinedRotation =
false;
1874 bool dataDefinedRotation =
false;
1875 double xPos = 0.0, yPos = 0.0,
angle = 0.0;
1876 bool ddXPos =
false, ddYPos =
false;
1877 double quadOffsetX = 0.0, quadOffsetY = 0.0;
1878 double offsetX = 0.0, offsetY = 0.0;
1885 int quadInt = exprVal.toInt( &ok );
1887 if ( ok && 0 <= quadInt && quadInt <= 8 )
1938 QString ptstr = exprVal.toString().trimmed();
1941 if ( !ptstr.isEmpty() )
1953 QString units = exprVal.toString().trimmed();
1955 if ( !units.isEmpty() )
1967 if ( !offinmapunits )
1969 offsetX *= mapUntsPerMM;
1975 if ( !offinmapunits )
1977 offsetY *= mapUntsPerMM;
1985 layerDefinedRotation =
true;
1993 double rotD = exprVal.toDouble( &ok );
1997 dataDefinedRotation =
true;
2004 xPos = exprVal.toDouble( &ddXPos );
2010 yPos = exprVal.toDouble( &ddYPos );
2013 if ( ddXPos && ddYPos )
2015 dataDefinedPosition =
true;
2016 labelIsPinned =
true;
2018 if ( layerDefinedRotation && !dataDefinedRotation )
2030 QString haliString = exprVal.toString();
2032 if ( haliString.compare(
"Center", Qt::CaseInsensitive ) == 0 )
2034 xdiff -= labelX / 2.0;
2036 else if ( haliString.compare(
"Right", Qt::CaseInsensitive ) == 0 )
2045 QString valiString = exprVal.toString();
2048 if ( valiString.compare(
"Bottom", Qt::CaseInsensitive ) != 0 )
2050 if ( valiString.compare(
"Top", Qt::CaseInsensitive ) == 0 )
2056 double descentRatio = labelFontMetrics->descent() / labelFontMetrics->height();
2057 if ( valiString.compare(
"Base", Qt::CaseInsensitive ) == 0 )
2059 ydiff -= labelY * descentRatio;
2063 double capHeightRatio = ( labelFontMetrics->boundingRect(
'H' ).height() + 1 + labelFontMetrics->descent() ) / labelFontMetrics->height();
2064 ydiff -= labelY * capHeightRatio;
2065 if ( valiString.compare(
"Half", Qt::CaseInsensitive ) == 0 )
2067 ydiff += labelY * ( capHeightRatio - descentRatio ) / 2.0;
2074 if ( dataDefinedRotation )
2077 double xd = xdiff * cos(
angle ) - ydiff * sin(
angle );
2078 double yd = xdiff * sin(
angle ) + ydiff * cos(
angle );
2094 QgsDebugMsgLevel( QString(
"Ignoring feature %1 due transformation exception on data-defined position" ).arg( f.
id() ), 4 );
2114 bool alwaysShow =
false;
2117 alwaysShow = exprVal.toBool();
2124 labelFont.letterSpacing(),
2125 labelFont.wordSpacing(),
2132 #if QT_VERSION >= 0x040800
2133 QgsDebugMsgLevel( QString(
"PAL font stored definedFont: %1, Style: %2" ).arg( labelFont.toString() ).arg( labelFont.styleName() ), 4 );
2140 if ( !
palLayer->registerFeature( lbl->
strId(), lbl, labelX, labelY, labelText.toUtf8().constData(),
2141 xPos, yPos, dataDefinedPosition,
angle, dataDefinedRotation,
2142 quadOffsetX, quadOffsetY, offsetX, offsetY, alwaysShow ) )
2145 catch ( std::exception &e )
2148 QgsDebugMsgLevel( QString(
"Ignoring feature %1 due PAL exception:" ).arg( f.
id() ) + QString::fromLatin1( e.what() ), 4 );
2156 delete labelFontMetrics;
2161 double distance =
dist;
2165 double distD = exprVal.toDouble( &ok );
2176 QString units = exprVal.toString().trimmed();
2178 if ( !units.isEmpty() )
2184 if ( distance != 0 )
2186 if ( distinmapunit )
2194 feat->setDistLabel( qAbs(
ptOne.
x() - ptZero.
x() )* distance );
2198 QMap< DataDefinedProperties, QVariant >::const_iterator dIt =
dataDefinedValues.constBegin();
2214 QString dbgStr = QString(
"exprVal %1:" ).arg(
mDataDefinedNames.value( p ).first ) +
"%1";
2216 if ( valType == QString(
"bool" ) )
2218 bool bol = exprVal.toBool();
2223 if ( valType == QString(
"int" ) )
2226 int size = exprVal.toInt( &ok );
2235 if ( valType == QString(
"intpos" ) )
2238 int size = exprVal.toInt( &ok );
2241 if ( ok && size > 0 )
2247 if ( valType == QString(
"double" ) )
2250 double size = exprVal.toDouble( &ok );
2259 if ( valType == QString(
"doublepos" ) )
2262 double size = exprVal.toDouble( &ok );
2265 if ( ok && size > 0.0 )
2271 if ( valType == QString(
"rotation180" ) )
2274 double rot = exprVal.toDouble( &ok );
2278 if ( rot < -180.0 && rot >= -360 )
2282 if ( rot > 180.0 && rot <= 360 )
2286 if ( rot >= -180 && rot <= 180 )
2293 if ( valType == QString(
"transp" ) )
2296 int size = exprVal.toInt( &ok );
2298 if ( ok && size >= 0 && size <= 100 )
2304 if ( valType == QString(
"string" ) )
2306 QString str = exprVal.toString();
2312 if ( valType == QString(
"units" ) )
2314 QString unitstr = exprVal.toString().trimmed();
2317 if ( !unitstr.isEmpty() )
2323 if ( valType == QString(
"color" ) )
2325 QString colorstr = exprVal.toString().trimmed();
2329 if ( color.isValid() )
2335 if ( valType == QString(
"joinstyle" ) )
2337 QString joinstr = exprVal.toString().trimmed();
2340 if ( !joinstr.isEmpty() )
2346 if ( valType == QString(
"blendmode" ) )
2348 QString blendstr = exprVal.toString().trimmed();
2351 if ( !blendstr.isEmpty() )
2357 if ( valType == QString(
"pointf" ) )
2359 QString ptstr = exprVal.toString().trimmed();
2362 if ( !ptstr.isEmpty() )
2385 QString ddFontFamily(
"" );
2388 QString family = exprVal.toString().trimmed();
2391 if ( labelFont.family() != family )
2397 ddFontFamily = family;
2403 QString ddFontStyle(
"" );
2406 QString fontstyle = exprVal.toString().trimmed();
2407 QgsDebugMsgLevel( QString(
"exprVal Font style:%1" ).arg( fontstyle ), 4 );
2408 ddFontStyle = fontstyle;
2412 bool ddBold =
false;
2415 bool bold = exprVal.toBool();
2416 QgsDebugMsgLevel( QString(
"exprVal Font bold:%1" ).arg( bold ?
"true" :
"false" ), 4 );
2421 bool ddItalic =
false;
2424 bool italic = exprVal.toBool();
2425 QgsDebugMsgLevel( QString(
"exprVal Font italic:%1" ).arg( italic ?
"true" :
"false" ), 4 );
2432 QFont appFont = QApplication::font();
2433 bool newFontBuilt =
false;
2434 if ( ddBold || ddItalic )
2437 newFont = QFont( !ddFontFamily.isEmpty() ? ddFontFamily : labelFont.family() );
2438 newFontBuilt =
true;
2439 newFont.setBold( ddBold );
2440 newFont.setItalic( ddItalic );
2442 else if ( !ddFontStyle.isEmpty()
2443 && ddFontStyle.compare(
"Ignore", Qt::CaseInsensitive ) != 0 )
2445 if ( !ddFontFamily.isEmpty() )
2448 QFont styledfont =
mFontDB.font( ddFontFamily, ddFontStyle, appFont.pointSize() );
2449 if ( appFont != styledfont )
2451 newFont = styledfont;
2452 newFontBuilt =
true;
2459 else if ( !ddFontFamily.isEmpty() )
2461 if ( ddFontStyle.compare(
"Ignore", Qt::CaseInsensitive ) != 0 )
2465 if ( appFont != styledfont )
2467 newFont = styledfont;
2468 newFontBuilt =
true;
2473 newFont = QFont( ddFontFamily );
2474 newFontBuilt =
true;
2482 newFont.setPixelSize( labelFont.pixelSize() );
2483 newFont.setCapitalization( labelFont.capitalization() );
2484 newFont.setUnderline( labelFont.underline() );
2485 newFont.setStrikeOut( labelFont.strikeOut() );
2486 newFont.setWordSpacing( labelFont.wordSpacing() );
2487 newFont.setLetterSpacing( QFont::AbsoluteSpacing, labelFont.letterSpacing() );
2489 labelFont = newFont;
2493 double wordspace = labelFont.wordSpacing();
2497 double wspacing = exprVal.toDouble( &ok );
2498 QgsDebugMsgLevel( QString(
"exprVal FontWordSpacing:%1" ).arg( wspacing ), 4 );
2501 wordspace = wspacing;
2504 labelFont.setWordSpacing(
sizeToPixel( wordspace, context, fontunits,
false ) );
2507 double letterspace = labelFont.letterSpacing();
2511 double lspacing = exprVal.toDouble( &ok );
2512 QgsDebugMsgLevel( QString(
"exprVal FontLetterSpacing:%1" ).arg( lspacing ), 4 );
2515 letterspace = lspacing;
2518 labelFont.setLetterSpacing( QFont::AbsoluteSpacing,
sizeToPixel( letterspace, context, fontunits,
false ) );
2521 QFont::Capitalization fontcaps = labelFont.capitalization();
2524 QString fcase = exprVal.toString().trimmed();
2527 if ( !fcase.isEmpty() )
2529 if ( fcase.compare(
"NoChange", Qt::CaseInsensitive ) == 0 )
2531 fontcaps = QFont::MixedCase;
2533 else if ( fcase.compare(
"Upper", Qt::CaseInsensitive ) == 0 )
2535 fontcaps = QFont::AllUppercase;
2537 else if ( fcase.compare(
"Lower", Qt::CaseInsensitive ) == 0 )
2539 fontcaps = QFont::AllLowercase;
2541 else if ( fcase.compare(
"Capitalize", Qt::CaseInsensitive ) == 0 )
2543 fontcaps = QFont::Capitalize;
2546 if ( fontcaps != labelFont.capitalization() )
2548 labelFont.setCapitalization( fontcaps );
2556 bool strikeout = exprVal.toBool();
2557 QgsDebugMsgLevel( QString(
"exprVal Font strikeout:%1" ).arg( strikeout ?
"true" :
"false" ), 4 );
2558 labelFont.setStrikeOut( strikeout );
2564 bool underline = exprVal.toBool();
2565 QgsDebugMsgLevel( QString(
"exprVal Font underline:%1" ).arg( underline ?
"true" :
"false" ), 4 );
2566 labelFont.setUnderline( underline );
2590 drawBuffer = exprVal.toBool();
2602 bufrSize = exprVal.toDouble();
2609 bufTransp = exprVal.toInt();
2612 drawBuffer = ( drawBuffer && bufrSize > 0.0 && bufTransp < 100 );
2643 wrapchr = exprVal.toString();
2652 QString str = exprVal.toString().trimmed();
2653 QgsDebugMsgLevel( QString(
"exprVal MultiLineAlignment:%1" ).arg( str ), 4 );
2655 if ( !str.isEmpty() )
2660 if ( str.compare(
"Center", Qt::CaseInsensitive ) == 0 )
2664 else if ( str.compare(
"Right", Qt::CaseInsensitive ) == 0 )
2676 drawDirSymb = exprVal.toBool();
2690 QString str = exprVal.toString().trimmed();
2691 QgsDebugMsgLevel( QString(
"exprVal DirSymbPlacement:%1" ).arg( str ), 4 );
2693 if ( !str.isEmpty() )
2698 if ( str.compare(
"Above", Qt::CaseInsensitive ) == 0 )
2702 else if ( str.compare(
"Below", Qt::CaseInsensitive ) == 0 )
2725 drawShape = exprVal.toBool();
2737 shapeTransp = exprVal.toInt();
2740 drawShape = ( drawShape && shapeTransp < 100 );
2753 QString skind = exprVal.toString().trimmed();
2756 if ( !skind.isEmpty() )
2761 if ( skind.compare(
"Square", Qt::CaseInsensitive ) == 0 )
2765 else if ( skind.compare(
"Ellipse", Qt::CaseInsensitive ) == 0 )
2769 else if ( skind.compare(
"Circle", Qt::CaseInsensitive ) == 0 )
2773 else if ( skind.compare(
"SVG", Qt::CaseInsensitive ) == 0 )
2777 shapeKind = shpkind;
2786 QString svgfile = exprVal.toString().trimmed();
2787 QgsDebugMsgLevel( QString(
"exprVal ShapeSVGFile:%1" ).arg( svgfile ), 4 );
2798 QString stype = exprVal.toString().trimmed();
2801 if ( !stype.isEmpty() )
2806 if ( stype.compare(
"Fixed", Qt::CaseInsensitive ) == 0 )
2810 shpSizeType = sizType;
2819 ddShpSizeX = exprVal.toDouble();
2826 ddShpSizeY = exprVal.toDouble();
2832 && ( svgPath.isEmpty()
2833 || ( !svgPath.isEmpty()
2835 && ddShpSizeX == 0.0 ) ) )
2841 && ( ddShpSizeX == 0.0 || ddShpSizeY == 0.0 ) )
2863 QString rotstr = exprVal.toString().trimmed();
2864 QgsDebugMsgLevel( QString(
"exprVal ShapeRotationType:%1" ).arg( rotstr ), 4 );
2866 if ( !rotstr.isEmpty() )
2871 if ( rotstr.compare(
"Offset", Qt::CaseInsensitive ) == 0 )
2875 else if ( rotstr.compare(
"Fixed", Qt::CaseInsensitive ) == 0 )
2926 drawShadow = exprVal.toBool();
2938 shadowTransp = exprVal.toInt();
2945 shadowOffDist = exprVal.toDouble();
2952 shadowRad = exprVal.toDouble();
2955 drawShadow = ( drawShadow && shadowTransp < 100 && !( shadowOffDist == 0.0 && shadowRad == 0.0 ) );
2969 QString str = exprVal.toString().trimmed();
2972 if ( !str.isEmpty() )
2977 if ( str.compare(
"Text", Qt::CaseInsensitive ) == 0 )
2981 else if ( str.compare(
"Buffer", Qt::CaseInsensitive ) == 0 )
2985 else if ( str.compare(
"Background", Qt::CaseInsensitive ) == 0 )
3025 if ( unit ==
MapUnits && mapUnitsPerPixel > 0.0 )
3031 double ptsTomm = ( unit ==
Points ? 0.352778 : 1 );
3040 : mMapRenderer( NULL ), mPal( NULL )
3049 switch ( p.getSearch() )
3080 bool enabled =
false;
3081 if ( layer->
customProperty(
"labeling" ).toString() == QString(
"pal" ) )
3082 enabled = layer->
customProperty(
"labeling/enabled", QVariant(
false ) ).toBool();
3089 QHash<QgsVectorLayer*, QgsPalLayerSettings>::iterator lit;
3102 QMap< QgsPalLayerSettings::DataDefinedProperties, QgsDataDefined* >::iterator it = lyr.
dataDefinedProperties.begin();
3105 delete( it.value() );
3126 if ( lyrTmp.fieldName.isEmpty() )
3132 if ( lyrTmp.isExpression )
3145 if ( fldIndex == -1 )
3176 if ( fldIndex != -1 )
3178 attrIndices.insert( fldIndex );
3183 QMap< QgsPalLayerSettings::DataDefinedProperties, QgsDataDefined* >::const_iterator dIt = lyr.
dataDefinedProperties.constBegin();
3195 QMap<QString, QVariant> exprParams;
3204 foreach ( QString name, cols )
3211 Arrangement arrangement;
3220 default: Q_ASSERT(
"unsupported placement" && 0 );
return 0;
3224 double priority = 1 - lyr.
priority / 10.0;
3225 double min_scale = -1, max_scale = -1;
3234 Layer* l =
mPal->addLayer( layer->
id().toUtf8().data(),
3235 min_scale, max_scale, arrangement,
3236 METER, priority, lyr.
obstacle,
true,
true,
3243 l->setLabelMode( lyr.
labelPerPart ? Layer::LabelPerFeaturePart : Layer::LabelPerFeature );
3249 Layer::UpsideDownLabels upsdnlabels;
3255 default: Q_ASSERT(
"unsupported upside-down label setting" && 0 );
return 0;
3257 l->setUpsidedownLabels( upsdnlabels );
3322 Layer* l =
mPal->addLayer( layer->
id().append(
"d" ).toUtf8().data(), -1, -1, pal::Arrangement( s->
placement ), METER, s->
priority, s->
obstacle,
true, true );
3349 QHash<QgsVectorLayer*, QgsDiagramLayerSettings>::iterator layerIt =
mActiveDiagramLayers.find( layer );
3360 geom->
transform( *( layerIt.value().ct ) );
3363 const GEOSGeometry* geos_geom = geom->
asGeos();
3364 if ( geos_geom == 0 )
3374 layerIt.value().geometries.append( lbl );
3376 double diagramWidth = 0;
3377 double diagramHeight = 0;
3382 if ( diagSize.isValid() )
3384 diagramWidth = diagSize.width();
3385 diagramHeight = diagSize.height();
3393 int ddColX = layerIt.value().xPosColumn;
3394 int ddColY = layerIt.value().yPosColumn;
3395 double ddPosX = 0.0;
3396 double ddPosY = 0.0;
3397 bool ddPos = ( ddColX >= 0 && ddColY >= 0 );
3400 bool posXOk, posYOk;
3402 ddPosX = feat.
attribute( ddColX ).toDouble( &posXOk ) - diagramWidth / 2.0;
3403 ddPosY = feat.
attribute( ddColY ).toDouble( &posYOk ) - diagramHeight / 2.0;
3404 if ( !posXOk || !posYOk )
3421 if ( !layerIt.value().palLayer->registerFeature( lbl->
strId(), lbl, diagramWidth, diagramHeight,
"", ddPosX, ddPosY, ddPos ) )
3426 catch ( std::exception &e )
3429 QgsDebugMsgLevel( QString(
"Ignoring feature %1 due PAL exception:" ).arg( feat.
id() ) + QString::fromLatin1( e.what() ), 4 );
3433 pal::Feature* palFeat = layerIt.value().palLayer->getFeature( lbl->
strId() );
3434 QgsPoint ptZero = layerIt.value().xform->toMapCoordinates( 0, 0 );
3435 QgsPoint ptOne = layerIt.value().xform->toMapCoordinates( 1, 0 );
3436 palFeat->setDistLabel( qAbs( ptOne.
x() - ptZero.
x() ) * layerIt.value().dist );
3454 case Chain: s = CHAIN;
break;
3458 case Falp: s = FALP;
break;
3460 mPal->setSearch( s );
3482 QHash<QgsVectorLayer*, QgsPalLayerSettings>::iterator lit;
3485 if ( lit.key() && lit.key()->id() == layerName )
3494 const QMap< QgsPalLayerSettings::DataDefinedProperties, QVariant >& ddValues )
3500 tmpLyr.
textColor = ddColor.value<QColor>();
3519 const QMap< QgsPalLayerSettings::DataDefinedProperties, QVariant >& ddValues )
3572 const QMap< QgsPalLayerSettings::DataDefinedProperties, QVariant >& ddValues )
3629 const QMap< QgsPalLayerSettings::DataDefinedProperties, QVariant >& ddValues )
3740 const QMap< QgsPalLayerSettings::DataDefinedProperties, QVariant >& ddValues )
3808 QPainter* painter = context.
painter();
3824 std::list<LabelPosition*>* labels;
3825 pal::Problem* problem;
3828 problem =
mPal->extractProblem( scale, bbox );
3830 catch ( std::exception& e )
3833 QgsDebugMsgLevel(
"PAL EXCEPTION :-( " + QString::fromLatin1( e.what() ), 4 );
3846 painter->setPen( QColor( 0, 0, 0, 64 ) );
3847 painter->setBrush( Qt::NoBrush );
3848 for (
int i = 0; i < problem->getNumFeatures(); i++ )
3850 for (
int j = 0; j < problem->getFeatureCandidateCount( i ); j++ )
3852 pal::LabelPosition* lp = problem->getFeatureCandidate( i, j );
3862 QgsDebugMsgLevel( QString(
"LABELING work: %1 ms ... labels# %2" ).arg( t.elapsed() ).arg( labels->size() ), 4 );
3865 painter->setRenderHint( QPainter::Antialiasing );
3870 localp.begin( &localPict );
3871 double localdpi = ( localp.device()->logicalDpiX() + localp.device()->logicalDpiY() ) / 2;
3872 double contextdpi = ( painter->device()->logicalDpiX() + painter->device()->logicalDpiY() ) / 2;
3873 double dpiRatio = localdpi / contextdpi;
3877 std::list<LabelPosition*>::iterator it = labels->begin();
3878 for ( ; it != labels->end(); ++it )
3887 QString layerName = QString::fromUtf8(( *it )->getLayerName() );
3895 if ( dit.key() && dit.key()->id().append(
"d" ) == layerName )
3897 palGeometry->
feature( feature );
3899 dit.value().renderer->renderDiagram( feature, context, QPointF( outPt.
x(), outPt.
y() ) );
3907 QString layerId = layerName;
3922 const QMap< QgsPalLayerSettings::DataDefinedProperties, QVariant >& ddValues = palGeometry->
dataDefinedValues();
3927 #if QT_VERSION >= 0x040800
3929 QgsDebugMsgLevel( QString(
"PAL font definedFont: %1, Style: %2" ).arg( dFont.toString() ).arg( dFont.styleName() ), 4 );
3984 QString labeltext = ((
QgsPalGeometry* )( *it )->getFeaturePart()->getUserGeometry() )->text();
3990 painter->setCompositionMode( QPainter::CompositionMode_SourceOver );
3992 QgsDebugMsgLevel( QString(
"LABELING draw: %1 ms" ).arg( t.elapsed() ), 4 );
3998 QHash<QgsVectorLayer*, QgsPalLayerSettings>::iterator lit;
4002 for ( QList<QgsPalGeometry*>::iterator git = lyr.
geometries.begin(); git != lyr.
geometries.end(); ++git )
4019 for ( QList<QgsPalGeometry*>::iterator git = dls.
geometries.begin(); git != dls.
geometries.end(); ++git )
4029 QList<QgsLabelPosition> positions;
4031 QList<QgsLabelPosition*> positionPointers;
4035 QList<QgsLabelPosition*>::const_iterator pointerIt = positionPointers.constBegin();
4036 for ( ; pointerIt != positionPointers.constEnd(); ++pointerIt )
4047 QList<QgsLabelPosition> positions;
4049 QList<QgsLabelPosition*> positionPointers;
4053 QList<QgsLabelPosition*>::const_iterator pointerIt = positionPointers.constBegin();
4054 for ( ; pointerIt != positionPointers.constEnd(); ++pointerIt )
4090 QgsPoint outPt2 = xform->
transform( lp->getX() + lp->getWidth(), lp->getY() + lp->getHeight() );
4093 painter->translate( QPointF( outPt.
x(), outPt.
y() ) );
4094 painter->rotate( -lp->getAlpha() * 180 /
M_PI );
4095 QRectF rect( 0, 0, outPt2.
x() - outPt.
x(), outPt2.
y() - outPt.
y() );
4096 painter->drawRect( rect );
4100 rect.moveTo( outPt.
x(), outPt.
y() );
4104 if ( lp->getNextPart() )
4111 QPainter* painter = context.
painter();
4129 label->getY() + label->getHeight() / 2 );
4131 double xc = outPt2.
x() - outPt.
x();
4132 double yc = outPt2.
y() - outPt.
y();
4134 double angle = -label->getAlpha();
4135 double xd = xc * cos( angle ) - yc * sin( angle );
4136 double yd = xc * sin( angle ) + yc * cos( angle );
4138 centerPt.
setX( centerPt.
x() + xd );
4139 centerPt.
setY( centerPt.
y() + yd );
4142 component.
setSize(
QgsPoint( label->getWidth(), label->getHeight() ) );
4152 QString text = ((
QgsPalGeometry* )label->getFeaturePart()->getUserGeometry() )->text();
4153 QString txt = ( label->getPartId() == -1 ? text : QString( text[label->getPartId()] ) );
4154 QFontMetricsF* labelfm = ((
QgsPalGeometry* )label->getFeaturePart()->getUserGeometry() )->getLabelFontMetrics();
4156 QString wrapchr = !tmpLyr.
wrapChar.isEmpty() ? tmpLyr.
wrapChar : QString(
"\n" );
4162 bool prependSymb =
false;
4165 if ( label->getReversed() )
4180 prependSymb =
false;
4188 symb = symb + wrapchr;
4192 prependSymb =
false;
4193 symb = wrapchr + symb;
4198 txt.prepend( symb );
4208 QStringList multiLineList = txt.split( wrapchr );
4209 int lines = multiLineList.size();
4211 double labelWidest = 0.0;
4212 for (
int i = 0; i < lines; ++i )
4214 double labelWidth = labelfm->width( multiLineList.at( i ) );
4215 if ( labelWidth > labelWidest )
4217 labelWidest = labelWidth;
4221 double labelHeight = labelfm->ascent() + labelfm->descent();
4225 double ascentOffset = 0.25 * labelfm->ascent();
4227 for (
int i = 0; i < lines; ++i )
4230 painter->translate( QPointF( outPt.
x(), outPt.
y() ) );
4231 painter->rotate( -label->getAlpha() * 180 /
M_PI );
4238 double xMultiLineOffset = 0.0;
4239 double labelWidth = labelfm->width( multiLineList.at( i ) );
4242 double labelWidthDiff = labelWidest - labelWidth;
4245 labelWidthDiff /= 2;
4247 xMultiLineOffset = labelWidthDiff;
4251 double yMultiLineOffset = ( lines - 1 - i ) * labelHeight * tmpLyr.
multilineHeight;
4252 painter->translate( QPointF( xMultiLineOffset, - ascentOffset - yMultiLineOffset ) );
4254 component.
setText( multiLineList.at( i ) );
4269 path.addText( 0, 0, tmpLyr.
textFont, component.
text() );
4274 textp.begin( &textPict );
4275 textp.setPen( Qt::NoPen );
4277 textp.drawPath( path );
4292 painter->setCompositionMode( tmpLyr.
blendMode );
4300 painter->drawPicture( 0, 0, textPict );
4313 if ( label->getNextPart() )
4314 drawLabel( label->getNextPart(), context, tmpLyr, drawType, dpiRatio );
4321 QPainter* p = context.
painter();
4327 path.addText( 0, 0, tmpLyr.
textFont, component.
text() );
4329 pen.setWidthF( penSize );
4335 tmpColor.setAlpha( 0 );
4341 buffp.begin( &buffPict );
4342 buffp.setPen( pen );
4343 buffp.setBrush( tmpColor );
4344 buffp.drawPath( path );
4367 p->drawPicture( 0, 0, buffPict );
4375 QPainter* p = context.
painter();
4376 double labelWidth = component.
size().
x(), labelHeight = component.
size().
y();
4406 double sizeOut = 0.0;
4415 if ( labelWidth >= labelHeight )
4416 sizeOut = labelWidth;
4417 else if ( labelHeight > labelWidth )
4418 sizeOut = labelHeight;
4423 sizeOut /= mmToMapUnits;
4437 map[
"size"] = QString::number( sizeOut );
4440 map[
"angle"] = QString::number( 0.0 );
4468 svgp.begin( &svgPict );
4487 svgShdwM->
renderPoint( QPointF( svgSize / 2, -svgSize / 2 ), svgShdwContext );
4504 p->translate( QPointF( xoff, yoff ) );
4506 p->translate( -svgSize / 2, svgSize / 2 );
4530 p->translate( QPointF( xoff, yoff ) );
4533 p->setCompositionMode( QPainter::CompositionMode_SourceOver );
4567 h = sqrt( pow( w, 2 ) + pow( h, 2 ) );
4573 h = h / sqrt( 2.0 ) * 2;
4574 w = w / sqrt( 2.0 ) * 2;
4586 QRectF rect( -w / 2.0, - h / 2.0, w, h );
4588 if ( rect.isNull() )
4592 p->translate( QPointF( component.
center().
x(), component.
center().
y() ) );
4596 p->translate( QPointF( xoff, yoff ) );
4605 pen.setWidthF( penSize );
4617 shapep.begin( &shapePict );
4618 shapep.setPen( pen );
4626 shapep.drawRoundedRect( rect, tmpLyr.
shapeRadii.x(), tmpLyr.
shapeRadii.y(), Qt::RelativeSize );
4632 shapep.drawRoundedRect( rect, xRadius, yRadius );
4638 shapep.drawEllipse( rect );
4662 p->drawPicture( 0, 0, shapePict );
4675 QPainter* p = context.
painter();
4676 double componentWidth = component.
size().
x(), componentHeight = component.
size().
y();
4677 double xOffset = component.
offset().
x(), yOffset = component.
offset().
y();
4684 radius = ( int )( radius + 0.5 );
4688 double blurBufferClippingScale = 3.75;
4689 int blurbuffer = ( radius > 17 ? 16 : radius ) * blurBufferClippingScale;
4691 QImage blurImg( componentWidth + ( pictbuffer * 2.0 ) + ( blurbuffer * 2.0 ),
4692 componentHeight + ( pictbuffer * 2.0 ) + ( blurbuffer * 2.0 ),
4693 QImage::Format_ARGB32_Premultiplied );
4697 int minBlurImgSize = 1;
4701 int maxBlurImgSize = 40000;
4702 if ( blurImg.isNull()
4703 || ( blurImg.width() < minBlurImgSize || blurImg.height() < minBlurImgSize )
4704 || ( blurImg.width() > maxBlurImgSize || blurImg.height() > maxBlurImgSize ) )
4707 blurImg.fill( QColor( Qt::transparent ).rgba() );
4709 if ( !pictp.begin( &blurImg ) )
4711 pictp.setRenderHints( QPainter::Antialiasing | QPainter::SmoothPixmapTransform );
4712 QPointF imgOffset( blurbuffer + pictbuffer + xOffset,
4713 blurbuffer + pictbuffer + componentHeight + yOffset );
4715 pictp.drawPicture( imgOffset,
4719 pictp.setCompositionMode( QPainter::CompositionMode_SourceIn );
4720 pictp.fillRect( blurImg.rect(), tmpLyr.
shadowColor );
4733 picti.begin( &blurImg );
4734 picti.setBrush( Qt::Dense7Pattern );
4735 QPen imgPen( QColor( 0, 0, 255, 255 ) );
4736 imgPen.setWidth( 1 );
4737 picti.setPen( imgPen );
4738 picti.setOpacity( 0.1 );
4739 picti.drawRect( 0, 0, blurImg.width(), blurImg.height() );
4755 QPointF transPt( -offsetDist * cos( angleRad +
M_PI / 2 ),
4756 -offsetDist * sin( angleRad +
M_PI / 2 ) );
4759 p->setRenderHints( QPainter::Antialiasing | QPainter::SmoothPixmapTransform );
4766 double scale = ( double )tmpLyr.
shadowScale / 100.0;
4768 p->scale( scale, scale );
4773 p->translate( transPt );
4774 p->translate( -imgOffset.x(),
4776 p->drawImage( 0, 0, blurImg );
4784 p->setBrush( Qt::NoBrush );
4785 QPen imgPen( QColor( 255, 0, 0, 10 ) );
4786 imgPen.setWidth( 2 );
4787 imgPen.setStyle( Qt::DashLine );
4788 p->setPen( imgPen );
4789 p->scale( scale, scale );
4794 p->translate( transPt );
4795 p->translate( -imgOffset.x(),
4797 p->drawRect( 0, 0, blurImg.width(), blurImg.height() );
4802 p->setBrush( Qt::NoBrush );
4803 QPen componentRectPen( QColor( 0, 255, 0, 70 ) );
4804 componentRectPen.setWidth( 1 );
4809 p->setPen( componentRectPen );
4810 p->drawRect( QRect( -xOffset, -componentHeight - yOffset, componentWidth, componentHeight ) );
4821 "PAL",
"/SearchMethod", (
int )p.getSearch(), &saved ) );
4823 "PAL",
"/CandidatesPoint", p.getPointP(), &saved );
4825 "PAL",
"/CandidatesLine", p.getLineP(), &saved );
4827 "PAL",
"/CandidatesPolygon", p.getPolyP(), &saved );
4829 "PAL",
"/ShowingCandidates",
false, &saved );
4831 "PAL",
"/ShowingShadowRects",
false, &saved );
4833 "PAL",
"/ShowingAllLabels",
false, &saved );
4835 "PAL",
"/ShowingPartialsLabels", p.getShowPartial(), &saved );