bool QgsMapToolLabel::rotationPoint( QgsPoint& pos, bool ignoreUpsideDown, bool rotatingUnpinned ) { QVector<QgsPoint> cornerPoints = mCurrentLabelPos.cornerPoints; if ( cornerPoints.size() < 4 ) { return false; } if ( mCurrentLabelPos.upsideDown && !ignoreUpsideDown ) { pos = cornerPoints.at( 2 ); } else { pos = cornerPoints.at( 0 ); } //alignment always center/center and rotation 0 for diagrams if ( mCurrentLabelPos.isDiagram ) { pos.setX( pos.x() + mCurrentLabelPos.labelRect.width() / 2.0 ); pos.setY( pos.y() + mCurrentLabelPos.labelRect.height() / 2.0 ); return true; } //adapt pos depending on data defined alignment QString haliString, valiString; currentAlignment( haliString, valiString ); // rotate unpinned labels (i.e. no hali/vali settings) as if hali/vali was Center/Half if ( rotatingUnpinned ) { haliString = "Center"; valiString = "Half"; } // QFont labelFont = labelFontCurrentFeature(); QFontMetricsF labelFontMetrics( mCurrentLabelPos.labelFont ); // NOTE: this assumes the label corner points comprise a rectangle and that the // CRS supports equidistant measurements to accurately determine hypotenuse QgsPoint cp_0 = cornerPoints.at( 0 ); QgsPoint cp_1 = cornerPoints.at( 1 ); QgsPoint cp_3 = cornerPoints.at( 3 ); // QgsDebugMsg( QString( "cp_0: x=%1, y=%2" ).arg( cp_0.x() ).arg( cp_0.y() ) ); // QgsDebugMsg( QString( "cp_1: x=%1, y=%2" ).arg( cp_1.x() ).arg( cp_1.y() ) ); // QgsDebugMsg( QString( "cp_3: x=%1, y=%2" ).arg( cp_3.x() ).arg( cp_3.y() ) ); double labelSizeX = qSqrt( cp_0.sqrDist( cp_1 ) ); double labelSizeY = qSqrt( cp_0.sqrDist( cp_3 ) ); double xdiff = 0; double ydiff = 0; if ( haliString.compare( "Center", Qt::CaseInsensitive ) == 0 ) { xdiff = labelSizeX / 2.0; } else if ( haliString.compare( "Right", Qt::CaseInsensitive ) == 0 ) { xdiff = labelSizeX; } if ( valiString.compare( "Top", Qt::CaseInsensitive ) == 0 || valiString.compare( "Cap", Qt::CaseInsensitive ) == 0 ) { ydiff = labelSizeY; } else { double descentRatio = 1 / labelFontMetrics.ascent() / labelFontMetrics.height(); if ( valiString.compare( "Base", Qt::CaseInsensitive ) == 0 ) { ydiff = labelSizeY * descentRatio; } else if ( valiString.compare( "Half", Qt::CaseInsensitive ) == 0 ) { ydiff = labelSizeY * 0.5 * ( 1 - descentRatio ); } } double angle = mCurrentLabelPos.rotation; double xd = xdiff * cos( angle ) - ydiff * sin( angle ); double yd = xdiff * sin( angle ) + ydiff * cos( angle ); if ( mCurrentLabelPos.upsideDown && !ignoreUpsideDown ) { pos.setX( pos.x() - xd ); pos.setY( pos.y() - yd ); } else { pos.setX( pos.x() + xd ); pos.setY( pos.y() + yd ); } return true; }
bool QgsMapToolLabel::rotationPoint( QgsPoint& pos, bool ignoreUpsideDown ) { QVector<QgsPoint> cornerPoints = mCurrentLabelPos.cornerPoints; if ( cornerPoints.size() < 4 ) { return false; } if ( mCurrentLabelPos.upsideDown && !ignoreUpsideDown ) { pos = mCurrentLabelPos.cornerPoints.at( 2 ); } else { pos = mCurrentLabelPos.cornerPoints.at( 0 ); } //alignment always center/center and rotation 0 for diagrams if ( mCurrentLabelPos.isDiagram ) { pos.setX( pos.x() + mCurrentLabelPos.labelRect.width() / 2.0 ); pos.setY( pos.y() + mCurrentLabelPos.labelRect.height() / 2.0 ); return true; } //adapt pos depending on data defined alignment QString haliString, valiString; currentAlignment( haliString, valiString ); if ( !mCurrentLabelPos.isPinned ) { haliString = "Center"; valiString = "Half"; } QFont labelFont = labelFontCurrentFeature(); QFontMetricsF labelFontMetrics( labelFont ); //label text? QString labelText = currentLabelText(); bool labelSettingsOk; QgsPalLayerSettings& labelSettings = currentLabelSettings( &labelSettingsOk ); if ( !labelSettingsOk ) { return false; } double labelSizeX, labelSizeY; labelSettings.calculateLabelSize( &labelFontMetrics, labelText, labelSizeX, labelSizeY ); double xdiff = 0; double ydiff = 0; if ( haliString.compare( "Center", Qt::CaseInsensitive ) == 0 ) { xdiff = labelSizeX / 2.0; } else if ( haliString.compare( "Right", Qt::CaseInsensitive ) == 0 ) { xdiff = labelSizeX; } if ( valiString.compare( "Top", Qt::CaseInsensitive ) == 0 || valiString.compare( "Cap", Qt::CaseInsensitive ) == 0 ) { ydiff = labelSizeY; } else { double descentRatio = 1 / labelFontMetrics.ascent() / labelFontMetrics.height(); if ( valiString.compare( "Base", Qt::CaseInsensitive ) == 0 ) { ydiff = labelSizeY * descentRatio; } else if ( valiString.compare( "Half", Qt::CaseInsensitive ) == 0 ) { ydiff = labelSizeY * descentRatio; ydiff = labelSizeY * 0.5 * ( 1 - descentRatio ); } } double angle = mCurrentLabelPos.rotation; double xd = xdiff * cos( angle ) - ydiff * sin( angle ); double yd = xdiff * sin( angle ) + ydiff * cos( angle ); if ( mCurrentLabelPos.upsideDown && !ignoreUpsideDown ) { pos.setX( pos.x() - xd ); pos.setY( pos.y() - yd ); } else { pos.setX( pos.x() + xd ); pos.setY( pos.y() + yd ); } return true; }