Index: python/core/qgslabel.sip =================================================================== --- python/core/qgslabel.sip (revision 12310) +++ python/core/qgslabel.sip (working copy) @@ -30,7 +30,8 @@ YOffset, Angle, Alignment, - BufferEnabled, + BufferType, + BufferArrowType, BufferSize, BufferColor, BufferBrush, @@ -62,7 +63,8 @@ * \param classAttributes attributes to use for labeling * \note added in 1.2 */ - void renderLabel ( QgsRenderContext &renderContext, QgsFeature &feature, bool selected, QgsLabelAttributes *classAttributes=0); + void renderLabel ( QgsRenderContext &renderContext, QgsFeature &feature, + bool selected, QgsLabelAttributes *classAttributes=0); /** Reads the renderer configuration from an XML file @param rnode the Dom node to read Index: src/app/qgslabeldialog.cpp =================================================================== --- src/app/qgslabeldialog.cpp (revision 12310) +++ src/app/qgslabeldialog.cpp (working copy) @@ -44,7 +44,7 @@ connect( btnDefaultFont, SIGNAL( clicked() ), this, SLOT( changeFont() ) ); - connect( pbnDefaultBufferColor_2, SIGNAL( clicked() ), + connect( pbnBufferColor, SIGNAL( clicked() ), this, SLOT( changeBufferColor() ) ); connect( pbnDefaultFontColor, SIGNAL( clicked() ), this, SLOT( changeFontColor() ) ); @@ -258,7 +258,8 @@ //set the state of the multiline enabled checkbox chkUseMultiline->setChecked( myLabelAttributes->multilineEnabled() ); //set the state of the buffer enabled checkbox - chkUseBuffer->setChecked( myLabelAttributes->bufferEnabled() ); + cboBufferType->setCurrentIndex( myLabelAttributes->bufferType() ); + //cboBufferArrowType->setCurrentIndex( myLabelAttributes->bufferArrowType() ); //NOTE: do we need this line too? TS spinBufferSize->setValue( myLabelAttributes->bufferSize() ); @@ -366,6 +367,8 @@ { myTypeInt = QgsLabelAttributes::MapUnits; } + + myLabelAttributes->setOffset( spinXOffset->value(), spinYOffset->value(), myTypeInt ); myLabelAttributes->setAutoAngle( spinAngle->value() == -1 ); myLabelAttributes->setAngle( spinAngle->value() ); @@ -384,7 +387,8 @@ if ( radioOver->isChecked() ) myLabelAttributes->setAlignment( Qt::AlignCenter ); myLabelAttributes->setMultilineEnabled( chkUseMultiline->isChecked() ); - myLabelAttributes->setBufferEnabled( chkUseBuffer->isChecked() ); + myLabelAttributes->setBufferType( cboBufferType->currentIndex() ); + //myLabelAttributes->setBufferArrowType( cboBufferArrowType->currentIndex() ); myLabelAttributes->setBufferColor( mBufferColor ); myTypeInt = 0; if ( radioBufferUnitsPoints->isChecked() ) @@ -395,6 +399,7 @@ { myTypeInt = QgsLabelAttributes::MapUnits; } + myLabelAttributes->setBufferSize( spinBufferSize->value(), myTypeInt ); //TODO - transparency attributes for buffers Index: src/core/qgslabelattributes.cpp =================================================================== --- src/core/qgslabelattributes.cpp (revision 12310) +++ src/core/qgslabelattributes.cpp (working copy) @@ -44,7 +44,6 @@ mAngleIsAuto( false ), mAlignment( 0 ), mAlignmentIsSet( false ), - mBufferEnabledFlag( false ), mBufferSizeType( 0 ), mBufferSize( 0.0 ), mBufferSizeIsSet( false ), @@ -288,14 +287,35 @@ } /* Buffer */ +/** @note since v1.4 this just tests to see if + buffer type is font and returns true if it is */ bool QgsLabelAttributes::bufferEnabled() const { - return mBufferEnabledFlag; + return false; //FIXME! } +/** @note since v1.4 this just returns true if + buffer type is font */ void QgsLabelAttributes::setBufferEnabled( bool useBufferFlag ) { - mBufferEnabledFlag = useBufferFlag; + return ; // FIXME! } +void QgsLabelAttributes::setBufferArrowType( int BufferArrowType ) +{ + mBufferArrowType = BufferArrowType; +} +int QgsLabelAttributes::bufferType() +{ + return mBufferType; +} +int QgsLabelAttributes::bufferArrowType() +{ + return mBufferArrowType; +} +void QgsLabelAttributes::setBufferType( int BufferType ) +{ + mBufferType = BufferType; +} + void QgsLabelAttributes::setBufferSize( double size, int type ) { mBufferSizeType = type; Index: src/core/qgslabel.cpp =================================================================== --- src/core/qgslabel.cpp (revision 12310) +++ src/core/qgslabel.cpp (working copy) @@ -250,6 +250,7 @@ int dx = 0; int dy = 0; + int labeltype = -1; value = fieldValue( Alignment, feature ); if ( value.isEmpty() ) @@ -275,6 +276,22 @@ alignment |= Qt::AlignTop; else alignment |= Qt::AlignVCenter; + + labeltype = -1; // not set + if ( value.contains( "plaintext" ) ) + labeltype = 1; + else if ( value.contains( "plainrect" ) ) + labeltype = 2; + else if ( value.contains( "plainroundrect" ) ) + labeltype = 3; + else if ( value.contains( "linerect" ) ) + labeltype = 4; + else if ( value.contains( "lineroundrect" ) ) + labeltype = 5; + else if ( value.contains( "arrowrect" ) ) + labeltype = 6; + else if ( value.contains( "arrowroundrect" ) ) + labeltype = 7; } if ( alignment & Qt::AlignLeft ) @@ -352,19 +369,18 @@ // Work out a suitable position to put the label for the // feature. For multi-geometries, put the same label on each // part. - if ( useOverridePoint ) + std::vector points; + labelPoint( points, feature ); + for ( uint i = 0; i < points.size(); ++i ) { - renderLabel( renderContext, overridePoint, text, font, pen, dx, dy, - xoffset, yoffset, ang, width, height, alignment ); - } - else - { - std::vector points; - labelPoint( points, feature ); - for ( uint i = 0; i < points.size(); ++i ) - { + if ( useOverridePoint ) { + QgsPoint pointtmp01 = renderContext.mapToPixel().transform( points[i].p ); + QgsPoint pointtmp02 = renderContext.mapToPixel().transform( overridePoint ); renderLabel( renderContext, points[i].p, text, font, pen, dx, dy, - xoffset, yoffset, mLabelAttributes->angleIsAuto() ? points[i].angle : ang, width, height, alignment ); + pointtmp02.x()-pointtmp01.x(), pointtmp01.y()-pointtmp02.y(), mLabelAttributes->angleIsAuto() ? points[i].angle : ang, width, height, alignment, labeltype ); + } else { + renderLabel( renderContext, points[i].p, text, font, pen, dx, dy, + xoffset, yoffset, mLabelAttributes->angleIsAuto() ? points[i].angle : ang, width, height, alignment, labeltype ); } } } @@ -375,7 +391,7 @@ int dx, int dy, double xoffset, double yoffset, double ang, - int width, int height, int alignment ) + int width, int height, int alignment, int labeltype ) { QPainter *painter = renderContext.painter(); @@ -415,7 +431,7 @@ // // Draw a buffer behind the text if one is desired // - if ( mLabelAttributes->bufferSizeIsSet() && mLabelAttributes->bufferEnabled() ) + if ( mLabelAttributes->bufferSizeIsSet() && (mLabelAttributes->bufferType() != 0) ) { double myBufferSize = mLabelAttributes->bufferSize() * 0.3527 * renderContext.scaleFactor() * renderContext.rasterScaleFactor(); QPen bufferPen; @@ -439,18 +455,222 @@ bufferStepSize = 1 / renderContext.rasterScaleFactor(); } - for ( double i = dx - myBufferSize; i <= dx + myBufferSize; i += bufferStepSize ) - { - for ( double j = dy - myBufferSize; j <= dy + myBufferSize; j += bufferStepSize ) - { - if ( mLabelAttributes->multilineEnabled() ) - painter->drawText( QRectF( i, j - height, width, height ), alignment, text ); - else - painter->drawText( QPointF( i, j ), text ); - } - } + if (labeltype==-1) { + labeltype = mLabelAttributes->bufferType(); + } + if (labeltype==2) { // plainrect + int lxl = dx - myBufferSize; // label x left + int lxr = dx + myBufferSize + width; // label x right + int lyt = dy - myBufferSize - height; // label y top + int lyb = dy + myBufferSize; // label y bottom + QPainterPath rectPath; + rectPath.moveTo( lxl, lyt ); + rectPath.lineTo( lxr, lyt ); + rectPath.lineTo( lxr, lyb ); + rectPath.lineTo( lxl, lyb ); + rectPath.closeSubpath(); + QColor brushColor = mLabelAttributes->bufferColor(); + brushColor.setAlpha( 50 ); + QBrush symbolBrush = QBrush( brushColor ); + painter->fillPath( rectPath, symbolBrush ); + QColor frameColor = mLabelAttributes->color(); + QPen framePen = QPen( QColor( frameColor ) ); + framePen.setWidth( 2 ); + painter->setPen( framePen ); + painter->drawPath( rectPath ); + } else if (labeltype==3) { // plainroundrect + int lxl = dx - myBufferSize; // label x left + int lxr = dx + myBufferSize + width; // label x right + int lyt = dy - myBufferSize - height; // label y top + int lyb = dy + myBufferSize; // label y bottom + QPainterPath roundRectPath; + roundRectPath.moveTo( lxl, lyt+5 ); + roundRectPath.arcTo( lxl, lyt, 10.0, 10.0, 180.0, -90.0); + roundRectPath.lineTo( lxr-5, lyt ); + roundRectPath.arcTo( lxr-10, lyt, 10.0, 10.0, 90.0, -90.0); + roundRectPath.lineTo( lxr, lyb-5 ); + roundRectPath.arcTo( lxr-10, lyb-10, 10.0, 10.0, 0.0, -90.0); + roundRectPath.lineTo( lxl+5, lyb ); + roundRectPath.arcTo( lxl, lyb-10 , 10.0, 10.0, 270.0, -90.0); + roundRectPath.closeSubpath(); + QColor brushColor = mLabelAttributes->bufferColor(); + brushColor.setAlpha( 50 ); + QBrush symbolBrush = QBrush( brushColor ); + painter->fillPath( roundRectPath, symbolBrush ); + QColor frameColor = mLabelAttributes->color(); + QPen framePen = QPen( QColor( frameColor ) ); + framePen.setWidth( 2 ); + painter->setPen( framePen ); + painter->drawPath( roundRectPath ); + } else if (labeltype==4) { // linerect + int lxl = dx - myBufferSize; // label x left + int lxr = dx + myBufferSize + width; // label x right + int lyt = dy - myBufferSize - height; // label y top + int lyb = dy + myBufferSize; // label y bottom + bool bNeedArrow = !( (lxl<=0-xoffset) and (0-xoffset<=lxr) and (lyt<=0+yoffset) and (0+yoffset<=lyb) ); + QPainterPath rectPath; + rectPath.moveTo( lxl, lyt ); + rectPath.lineTo( lxr, lyt ); + rectPath.lineTo( lxr, lyb ); + rectPath.lineTo( lxl, lyb ); + rectPath.closeSubpath(); + QColor brushColor = mLabelAttributes->bufferColor(); + brushColor.setAlpha( 50 ); + QBrush symbolBrush = QBrush( brushColor ); + painter->fillPath( rectPath, symbolBrush ); + QColor frameColor = mLabelAttributes->color(); + QPen framePen = QPen( QColor( frameColor ) ); + framePen.setWidth( 2 ); + painter->setPen( framePen ); + painter->drawPath( rectPath ); + if (bNeedArrow) { + int llx; + int lly; + if (abs(0-xoffset-lxl)>(abs(0-xoffset-lxr))) { + llx = lxr; + } else { + llx = lxl; + } + if (abs(0+yoffset-lyt)>(abs(0+yoffset-lyb))) { + lly = lyb; + } else { + lly = lyt; + } + painter->drawLine( 0-xoffset,0+yoffset, llx,lly ); + //painter->drawRect( -5,-5, 10,10 ); + } + } else if (labeltype==5) { // lineroundrect + int lxl = dx - myBufferSize; // label x left + int lxr = dx + myBufferSize + width; // label x right + int lyt = dy - myBufferSize - height; // label y top + int lyb = dy + myBufferSize; // label y bottom + bool bNeedArrow = !( (lxl<=0-xoffset) and (0-xoffset<=lxr) and (lyt<=0+yoffset) and (0+yoffset<=lyb) ); + QPainterPath roundRectPath; + roundRectPath.moveTo( lxl, lyt+5 ); + roundRectPath.arcTo( lxl, lyt, 10.0, 10.0, 180.0, -90.0); + roundRectPath.lineTo( lxr-5, lyt ); + roundRectPath.arcTo( lxr-10, lyt, 10.0, 10.0, 90.0, -90.0); + roundRectPath.lineTo( lxr, lyb-5 ); + roundRectPath.arcTo( lxr-10, lyb-10, 10.0, 10.0, 0.0, -90.0); + roundRectPath.lineTo( lxl+5, lyb ); + roundRectPath.arcTo( lxl, lyb-10 , 10.0, 10.0, 270.0, -90.0); + roundRectPath.closeSubpath(); + QColor brushColor = mLabelAttributes->bufferColor(); + brushColor.setAlpha( 50 ); + QBrush symbolBrush = QBrush( brushColor ); + painter->fillPath( roundRectPath, symbolBrush ); + QColor frameColor = mLabelAttributes->color(); + QPen framePen = QPen( QColor( frameColor ) ); + framePen.setWidth( 2 ); + painter->setPen( framePen ); + painter->drawPath( roundRectPath ); + if (bNeedArrow) { + int llx; + int lly; + if (abs(0-xoffset-lxl)>(abs(0-xoffset-lxr))) { + llx = lxr-2; + } else { + llx = lxl+2; + } + if (abs(0+yoffset-lyt)>(abs(0+yoffset-lyb))) { + lly = lyb-2; + } else { + lly = lyt+2; + } + painter->drawLine( 0-xoffset,0+yoffset, llx,lly ); + //painter->drawRect( -5,-5, 10,10 ); + } + } else if (labeltype==6) { // arrowrect (not ready yet) + int lxl = dx - myBufferSize; // label x left + int lxr = dx + myBufferSize + width; // label x right + int lyt = dy - myBufferSize - height; // label y top + int lyb = dy + myBufferSize; // label y bottom + bool bNeedArrow = !( (lxl<=0-xoffset) and (0-xoffset<=lxr) and (lyt<=0+yoffset) and (0+yoffset<=lyb) ); + QPainterPath rectPath; + rectPath.moveTo( lxl, lyt ); + rectPath.lineTo( lxr, lyt ); + rectPath.lineTo( lxr, lyb ); + rectPath.lineTo( lxl, lyb ); + rectPath.closeSubpath(); + QColor brushColor = mLabelAttributes->bufferColor(); + brushColor.setAlpha( 50 ); + QBrush symbolBrush = QBrush( brushColor ); + painter->fillPath( rectPath, symbolBrush ); + QColor frameColor = mLabelAttributes->color(); + QPen framePen = QPen( QColor( frameColor ) ); + framePen.setWidth( 2 ); + painter->setPen( framePen ); + painter->drawPath( rectPath ); + if (bNeedArrow) { + int llx; + int lly; + if (abs(0-xoffset-lxl)>(abs(0-xoffset-lxr))) { + llx = lxr; + } else { + llx = lxl; + } + if (abs(0+yoffset-lyt)>(abs(0+yoffset-lyb))) { + lly = lyb; + } else { + lly = lyt; + } + painter->drawLine( 0-xoffset,0+yoffset, llx,lly ); + //painter->drawRect( -5,-5, 10,10 ); + } + } else if (labeltype==7) { // arrowroundrect (not ready yet) + int lxl = dx - myBufferSize; // label x left + int lxr = dx + myBufferSize + width; // label x right + int lyt = dy - myBufferSize - height; // label y top + int lyb = dy + myBufferSize; // label y bottom + bool bNeedArrow = !( (lxl<=0-xoffset) and (0-xoffset<=lxr) and (lyt<=0+yoffset) and (0+yoffset<=lyb) ); + QPainterPath roundRectPath; + roundRectPath.moveTo( lxl, lyt+5 ); + roundRectPath.arcTo( lxl, lyt, 10.0, 10.0, 180.0, -90.0); + roundRectPath.lineTo( lxr-5, lyt ); + roundRectPath.arcTo( lxr-10, lyt, 10.0, 10.0, 90.0, -90.0); + roundRectPath.lineTo( lxr, lyb-5 ); + roundRectPath.arcTo( lxr-10, lyb-10, 10.0, 10.0, 0.0, -90.0); + roundRectPath.lineTo( lxl+5, lyb ); + roundRectPath.arcTo( lxl, lyb-10 , 10.0, 10.0, 270.0, -90.0); + roundRectPath.closeSubpath(); + QColor brushColor = mLabelAttributes->bufferColor(); + brushColor.setAlpha( 50 ); + QBrush symbolBrush = QBrush( brushColor ); + painter->fillPath( roundRectPath, symbolBrush ); + QColor frameColor = mLabelAttributes->color(); + QPen framePen = QPen( QColor( frameColor ) ); + framePen.setWidth( 2 ); + painter->setPen( framePen ); + painter->drawPath( roundRectPath ); + if (bNeedArrow) { + int llx; + int lly; + if (abs(0-xoffset-lxl)>(abs(0-xoffset-lxr))) { + llx = lxr-2; + } else { + llx = lxl+2; + } + if (abs(0+yoffset-lyt)>(abs(0+yoffset-lyb))) { + lly = lyb-2; + } else { + lly = lyt+2; + } + painter->drawLine( 0-xoffset,0+yoffset, llx,lly ); + //painter->drawRect( -5,-5, 10,10 ); + } + } else { // plaintext + for ( double i = dx - myBufferSize; i <= dx + myBufferSize; i += bufferStepSize ) + { + for ( double j = dy - myBufferSize; j <= dy + myBufferSize; j += bufferStepSize ) + { + if ( mLabelAttributes->multilineEnabled() ) + painter->drawText( QRectF( i, j - height, width, height ), alignment, text ); + else + painter->drawText( QPointF( i, j ), text ); + } + } + }; } - painter->setPen( pen ); if ( mLabelAttributes->multilineEnabled() ) painter->drawText( dx, dy - height, width, height, alignment, text ); @@ -975,8 +1195,8 @@ { el = scratchNode.toElement(); - mLabelAttributes->setBufferEnabled(( bool )el.attribute( "on", "0" ).toInt() ); - readLabelField( el, BufferEnabled ); + mLabelAttributes->setBufferType(( int )el.attribute( "on", "0" ).toInt() ); + readLabelField( el, BufferType ); } scratchNode = node.namedItem( "multilineenabled" ); @@ -1272,12 +1492,12 @@ // buffer enabled QDomElement bufferenabled = document.createElement( "bufferenabled" ); - if ( mLabelAttributes->bufferEnabled() ) + if ( mLabelAttributes->bufferType() != 0 ) { - bufferenabled.setAttribute( "on", mLabelAttributes->bufferEnabled() ); - if ( mLabelFieldIdx[BufferEnabled] != -1 ) + bufferenabled.setAttribute( "on", mLabelAttributes->bufferType() ); + if ( mLabelFieldIdx[BufferType] != 0 ) { - bufferenabled.setAttribute( "fieldname", labelField( BufferEnabled ) ); + bufferenabled.setAttribute( "fieldname", labelField( BufferType ) ); } else { Index: src/core/qgslabel.h =================================================================== --- src/core/qgslabel.h (revision 12310) +++ src/core/qgslabel.h (working copy) @@ -73,7 +73,8 @@ YOffset, Angle, Alignment, - BufferEnabled, + BufferType, + BufferArrowType, BufferSize, BufferColor, BufferBrush, @@ -113,7 +114,10 @@ * \param sizeScale global scale factor for size in pixels, labels in map units are not scaled * \note added in 1.2 */ - void renderLabel( QgsRenderContext &renderContext, QgsFeature &feature, bool selected, QgsLabelAttributes *classAttributes = 0 ); + void renderLabel( QgsRenderContext &renderContext, + QgsFeature &feature, + bool selected, + QgsLabelAttributes *classAttributes = 0 ); /** Reads the renderer configuration from an XML file @param rnode the Dom node to read @@ -181,7 +185,7 @@ int dx, int dy, double xoffset, double yoffset, double ang, - int width, int height, int alignment ); + int width, int height, int alignment, int labeltype ); bool readLabelField( QDomElement &el, int attr, QString prefix ); Index: src/core/qgslabelattributes.h =================================================================== --- src/core/qgslabelattributes.h (revision 12310) +++ src/core/qgslabelattributes.h (working copy) @@ -149,8 +149,16 @@ int alignment( void ) const; /* Buffer */ + /** @note since v1.4 this just tests to see if + buffer type is font and returns true if it is */ bool bufferEnabled() const; + /** @note since v1.4 this just returns true if + buffer type is font */ void setBufferEnabled( bool useBufferFlag ); + void setBufferType( int BufferType ); + void setBufferArrowType( int BufferArrowType ); + int bufferType(); + int bufferArrowType(); void setBufferSize( double size, int type ); bool bufferSizeIsSet( void ) const; int bufferSizeType( void ) const; @@ -217,7 +225,8 @@ bool mAlignmentIsSet; /** Buffer enablement */ - bool mBufferEnabledFlag; + int mBufferType; + int mBufferArrowType; /** Buffer size, size type */ int mBufferSizeType; double mBufferSize; Index: src/ui/qgslabeldialogbase.ui =================================================================== --- src/ui/qgslabeldialogbase.ui (revision 12310) +++ src/ui/qgslabeldialogbase.ui (working copy) @@ -6,8 +6,8 @@ 0 0 - 642 - 516 + 756 + 567 @@ -32,12 +32,12 @@ 0 - -990 - 619 - 1440 + 0 + 733 + 1551 - + @@ -45,7 +45,7 @@ Basic label options - + @@ -56,7 +56,7 @@ - + @@ -76,7 +76,7 @@ - + @@ -100,43 +100,47 @@ - - - Font size - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - spinFontSize - - + + + + + Font size + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + spinFontSize + + + + + + + + 0 + 0 + + + + + 50 + 0 + + + + 6 + + + 1000000.000000000000000 + + + 0.000000000000000 + + + + - - - - - 0 - 0 - - - - - 50 - 0 - - - - 6 - - - 1000000.000000000000000 - - - 0.000000000000000 - - - @@ -151,28 +155,32 @@ - - - Angle (deg) - - - spinAngle - - + + + + + Angle (deg) + + + spinAngle + + + + + + + ° + + + 360 + + + 0 + + + + - - - - ° - - - 360 - - - 0 - - - @@ -189,6 +197,88 @@ + + + Buffer + + + + + + Type + + + + + + + + + + None + + + + + Text buffer + + + + + Plain rectangle + + + + + Rounded rectangle + + + + + Plain rect with arrow + + + + + Rounded rect with arrow + + + + + + + + Color + + + + + + + + + Buffer size + + + + + + + + + + + + Map units + + + + + + + + + Placement @@ -350,7 +440,7 @@ - + Buffer size units @@ -441,7 +531,7 @@ - + Offset units @@ -492,7 +582,7 @@ - + Data defined placement @@ -533,7 +623,7 @@ - + Data defined properties @@ -701,7 +791,7 @@ - + Data defined buffer @@ -761,7 +851,7 @@ - + Data defined position @@ -881,6 +971,10 @@ pbnDefaultFontColor spinAngle chkUseMultiline + cboBufferType + pbnBufferColor + spinBufferSize_2 + chkBufferUnitsMap radioAboveLeft radioAbove radioAboveRight