42
42
43
43
#define FONT_WORKAROUND_SCALE 10 // scale factor for upscaling fontsize and downscaling painter
44
44
45
+ #ifndef M_DEG2RAD
46
+ #define M_DEG2RAD 0.0174532925
47
+ #endif
48
+
45
49
QgsComposerItem::QgsComposerItem ( QgsComposition* composition, bool manageZValue )
46
50
: QObject( 0 )
47
51
, QGraphicsRectItem( 0 )
@@ -733,6 +737,77 @@ bool QgsComposerItem::imageSizeConsideringRotation( double& width, double& heigh
733
737
return imageSizeConsideringRotation ( width, height, mItemRotation );
734
738
}
735
739
740
+ QRectF QgsComposerItem::largestRotatedRectWithinBounds ( QRectF originalRect, QRectF boundsRect, double rotation ) const
741
+ {
742
+ double originalWidth = originalRect.width ();
743
+ double originalHeight = originalRect.height ();
744
+ double boundsWidth = boundsRect.width ();
745
+ double boundsHeight = boundsRect.height ();
746
+ double ratioBoundsRect = boundsWidth / boundsHeight;
747
+
748
+ // shortcut for some rotation values
749
+ if ( rotation == 0 || rotation == 90 || rotation == 180 || rotation == 270 )
750
+ {
751
+ double originalRatio = originalWidth / originalHeight;
752
+ double rectScale = originalRatio > ratioBoundsRect ? boundsWidth / originalWidth : boundsHeight / originalHeight;
753
+ double rectScaledWidth = rectScale * originalWidth;
754
+ double rectScaledHeight = rectScale * originalHeight;
755
+
756
+ if ( rotation == 0 || rotation == 180 )
757
+ {
758
+ return QRectF (( boundsWidth - rectScaledWidth ) / 2.0 , ( boundsHeight - rectScaledHeight ) / 2.0 , rectScaledWidth, rectScaledHeight );
759
+ }
760
+ else if ( rotation == 0 || rotation == 180 )
761
+ {
762
+ return QRectF (( boundsWidth - rectScaledHeight ) / 2.0 , ( boundsHeight - rectScaledWidth ) / 2.0 , rectScaledHeight, rectScaledWidth );
763
+ }
764
+ }
765
+
766
+ // convert angle to radians and flip
767
+ double angleRad = -rotation * M_DEG2RAD;
768
+ double cosAngle = cos ( angleRad );
769
+ double sinAngle = sin ( angleRad );
770
+
771
+ // calculate size of bounds of rotated rectangle
772
+ double widthBoundsRotatedRect = originalWidth * fabs ( cosAngle ) + originalHeight * fabs ( sinAngle );
773
+ double heightBoundsRotatedRect = originalHeight * fabs ( cosAngle ) + originalWidth * fabs ( sinAngle );
774
+
775
+ // compare ratio of rotated rect with bounds rect and calculate scaling of rotated
776
+ // rect to fit within bounds
777
+ double ratioBoundsRotatedRect = widthBoundsRotatedRect / heightBoundsRotatedRect;
778
+ double rectScale = ratioBoundsRotatedRect > ratioBoundsRect ? boundsWidth / widthBoundsRotatedRect : boundsHeight / heightBoundsRotatedRect;
779
+ double rectScaledWidth = rectScale * originalWidth;
780
+ double rectScaledHeight = rectScale * originalHeight;
781
+
782
+ // now calculate offset so that rotated rectangle is centered within bounds
783
+ // first calculate min x and y coordinates
784
+ double currentCornerX = 0 ;
785
+ double minX = 0 ;
786
+ currentCornerX += rectScaledWidth * cosAngle;
787
+ minX = minX < currentCornerX ? minX : currentCornerX;
788
+ currentCornerX += rectScaledHeight * sinAngle;
789
+ minX = minX < currentCornerX ? minX : currentCornerX;
790
+ currentCornerX -= rectScaledWidth * cosAngle;
791
+ minX = minX < currentCornerX ? minX : currentCornerX;
792
+
793
+ double currentCornerY = 0 ;
794
+ double minY = 0 ;
795
+ currentCornerY -= rectScaledWidth * sinAngle;
796
+ minY = minY < currentCornerY ? minY : currentCornerY;
797
+ currentCornerY += rectScaledHeight * cosAngle;
798
+ minY = minY < currentCornerY ? minY : currentCornerY;
799
+ currentCornerY += rectScaledWidth * sinAngle;
800
+ minY = minY < currentCornerY ? minY : currentCornerY;
801
+
802
+ // now calculate offset position of rotated rectangle
803
+ double offsetX = ratioBoundsRotatedRect > ratioBoundsRect ? 0 : ( boundsWidth - rectScale * widthBoundsRotatedRect ) / 2.0 ;
804
+ offsetX += fabs ( minX );
805
+ double offsetY = ratioBoundsRotatedRect > ratioBoundsRect ? ( boundsHeight - rectScale * heightBoundsRotatedRect ) / 2.0 : 0 ;
806
+ offsetY += fabs ( minY );
807
+
808
+ return QRectF ( offsetX, offsetY, rectScaledWidth, rectScaledHeight );
809
+ }
810
+
736
811
bool QgsComposerItem::imageSizeConsideringRotation ( double & width, double & height, double rotation ) const
737
812
{
738
813
if ( qAbs ( rotation ) <= 0.0 ) // width and height stays the same if there is no rotation
@@ -759,19 +834,19 @@ bool QgsComposerItem::imageSizeConsideringRotation( double& width, double& heigh
759
834
double midX = width / 2.0 ;
760
835
double midY = height / 2.0 ;
761
836
762
- if ( !cornerPointOnRotatedAndScaledRect ( x1, y1 , width, height ) )
837
+ if ( !cornerPointOnRotatedAndScaledRect ( x1, y1 , width, height, rotation ) )
763
838
{
764
839
return false ;
765
840
}
766
- if ( !cornerPointOnRotatedAndScaledRect ( x2, y2, width, height ) )
841
+ if ( !cornerPointOnRotatedAndScaledRect ( x2, y2, width, height, rotation ) )
767
842
{
768
843
return false ;
769
844
}
770
- if ( !cornerPointOnRotatedAndScaledRect ( x3, y3, width, height ) )
845
+ if ( !cornerPointOnRotatedAndScaledRect ( x3, y3, width, height, rotation ) )
771
846
{
772
847
return false ;
773
848
}
774
- if ( !cornerPointOnRotatedAndScaledRect ( x4, y4, width, height ) )
849
+ if ( !cornerPointOnRotatedAndScaledRect ( x4, y4, width, height, rotation ) )
775
850
{
776
851
return false ;
777
852
}
0 commit comments