@@ -756,11 +756,12 @@ void QgsLayoutItemMap::paint( QPainter *painter, const QStyleOptionGraphicsItem
756
756
if ( thisPaintRect.width () == 0 || thisPaintRect.height () == 0 )
757
757
return ;
758
758
759
- painter->save ();
760
- painter->setClipRect ( thisPaintRect );
759
+ // TODO - try to reduce the amount of duplicate code here!
761
760
762
761
if ( mLayout ->context ().isPreviewRender () )
763
762
{
763
+ painter->save ();
764
+ painter->setClipRect ( thisPaintRect );
764
765
if ( !mCacheFinalImage || mCacheFinalImage ->isNull () )
765
766
{
766
767
// No initial render available - so draw some preview text alerting user
@@ -800,6 +801,23 @@ void QgsLayoutItemMap::paint( QPainter *painter, const QStyleOptionGraphicsItem
800
801
// restore rotation
801
802
painter->restore ();
802
803
}
804
+
805
+ painter->setClipRect ( thisPaintRect, Qt::NoClip );
806
+
807
+ if ( shouldDrawPart ( OverviewMapExtent ) )
808
+ {
809
+ mOverviewStack ->drawItems ( painter );
810
+ }
811
+ if ( shouldDrawPart ( Grid ) )
812
+ {
813
+ mGridStack ->drawItems ( painter );
814
+ }
815
+ drawAnnotations ( painter );
816
+ if ( shouldDrawPart ( Frame ) )
817
+ {
818
+ drawMapFrame ( painter );
819
+ }
820
+ painter->restore ();
803
821
}
804
822
else
805
823
{
@@ -811,42 +829,73 @@ void QgsLayoutItemMap::paint( QPainter *painter, const QStyleOptionGraphicsItem
811
829
if ( !paintDevice )
812
830
return ;
813
831
814
- // Fill with background color
815
- if ( shouldDrawPart ( Background ) )
816
- {
817
- drawMapBackground ( painter );
818
- }
819
-
820
832
QgsRectangle cExtent = extent ();
821
833
QSizeF size ( cExtent.width () * mapUnitsToLayoutUnits (), cExtent.height () * mapUnitsToLayoutUnits () );
822
834
823
835
if ( containsAdvancedEffects () && ( !mLayout || !( mLayout ->context ().flags () & QgsLayoutContext::FlagForceVectorOutput ) ) )
824
836
{
825
837
// rasterise
826
- double destinationDpi = mLayout ? mLayout ->context ().dpi () : style->matrix .m11 () * 25.4 ;
827
-
828
- double layoutUnitsToPixels = mLayout ? mLayout ->convertFromLayoutUnits ( 1 , QgsUnitTypes::LayoutPixels ).length () : destinationDpi / 25.4 ;
829
- double widthInPixels = boundingRect ().width () * layoutUnitsToPixels;
830
- double heightInPixels = boundingRect ().height () * layoutUnitsToPixels;
838
+ double destinationDpi = style->matrix .m11 () * 25.4 ;
839
+ double layoutUnitsInInches = mLayout ? mLayout ->convertFromLayoutUnits ( 1 , QgsUnitTypes::LayoutInches ).length () : 1 ;
840
+ int widthInPixels = std::round ( boundingRect ().width () * layoutUnitsInInches * destinationDpi );
841
+ int heightInPixels = std::round ( boundingRect ().height () * layoutUnitsInInches * destinationDpi );
831
842
QImage image = QImage ( widthInPixels, heightInPixels, QImage::Format_ARGB32 );
832
843
833
844
image.fill ( Qt::transparent );
834
845
image.setDotsPerMeterX ( 1000 * destinationDpi / 25.4 );
835
846
image.setDotsPerMeterY ( 1000 * destinationDpi / 25.4 );
847
+ double dotsPerMM = destinationDpi / 25.4 ;
836
848
QPainter p ( &image );
837
- double dotsPerMM = image.logicalDpiX () / 25.4 ;
838
- drawMap ( &p, cExtent, image.size (), destinationDpi );
839
- p.end ();
840
849
841
- dotsPerMM = paintDevice->logicalDpiX () / 25.4 ;
850
+ QPointF tl = -boundingRect ().topLeft ();
851
+ QRect imagePaintRect ( std::round ( tl.x () * dotsPerMM ),
852
+ std::round ( tl.y () * dotsPerMM ),
853
+ std::round ( thisPaintRect.width () * dotsPerMM ),
854
+ std::round ( thisPaintRect.height () * dotsPerMM ) );
855
+ p.setClipRect ( imagePaintRect );
856
+
857
+ p.translate ( imagePaintRect.topLeft () );
858
+
859
+ // Fill with background color - must be drawn onto the flattened image
860
+ // so that layers with opacity or blend modes can correctly interact with it
861
+ if ( shouldDrawPart ( Background ) )
862
+ {
863
+ p.scale ( dotsPerMM, dotsPerMM );
864
+ drawMapBackground ( &p );
865
+ p.scale ( 1.0 / dotsPerMM, 1.0 / dotsPerMM );
866
+ }
867
+
868
+ drawMap ( &p, cExtent, imagePaintRect.size (), image.logicalDpiX () );
869
+
870
+ // important - all other items, overviews, grids etc must be rendered to the
871
+ // flattened image, in case these have blend modes must need to interact
872
+ // with the map
873
+ p.scale ( dotsPerMM, dotsPerMM );
874
+
875
+ if ( shouldDrawPart ( OverviewMapExtent ) )
876
+ {
877
+ mOverviewStack ->drawItems ( &p );
878
+ }
879
+ if ( shouldDrawPart ( Grid ) )
880
+ {
881
+ mGridStack ->drawItems ( &p );
882
+ }
883
+ drawAnnotations ( &p );
884
+
842
885
painter->save ();
843
886
painter->scale ( 1 / dotsPerMM, 1 / dotsPerMM ); // scale painter from mm to dots
844
- painter->drawImage ( 0 , 0 , image );
845
- painter->restore ();
846
-
887
+ painter->drawImage ( std::round ( -tl.x ()* dotsPerMM ), std::round ( -tl.y () * dotsPerMM ), image );
888
+ painter->scale ( dotsPerMM, dotsPerMM );
847
889
}
848
890
else
849
891
{
892
+ // Fill with background color
893
+ if ( shouldDrawPart ( Background ) )
894
+ {
895
+ drawMapBackground ( painter );
896
+ }
897
+
898
+ painter->setClipRect ( thisPaintRect );
850
899
painter->save ();
851
900
painter->translate ( mXOffset , mYOffset );
852
901
@@ -856,31 +905,28 @@ void QgsLayoutItemMap::paint( QPainter *painter, const QStyleOptionGraphicsItem
856
905
drawMap ( painter, cExtent, size, paintDevice->logicalDpiX () );
857
906
858
907
painter->restore ();
859
- }
860
908
861
- mDrawing = false ;
862
- }
863
-
864
- painter->setClipRect ( thisPaintRect, Qt::NoClip );
909
+ painter->setClipRect ( thisPaintRect, Qt::NoClip );
865
910
866
- if ( shouldDrawPart ( OverviewMapExtent ) )
867
- {
868
- mOverviewStack ->drawItems ( painter );
869
- }
870
- if ( shouldDrawPart ( Grid ) )
871
- {
872
- mGridStack ->drawItems ( painter );
873
- }
911
+ if ( shouldDrawPart ( OverviewMapExtent ) )
912
+ {
913
+ mOverviewStack ->drawItems ( painter );
914
+ }
915
+ if ( shouldDrawPart ( Grid ) )
916
+ {
917
+ mGridStack ->drawItems ( painter );
918
+ }
919
+ drawAnnotations ( painter );
874
920
875
- // draw canvas items
876
- drawAnnotations ( painter );
921
+ }
877
922
878
- if ( shouldDrawPart ( Frame ) )
879
- {
880
- drawMapFrame ( painter );
923
+ if ( shouldDrawPart ( Frame ) )
924
+ {
925
+ drawMapFrame ( painter );
926
+ }
927
+ painter->restore ();
928
+ mDrawing = false ;
881
929
}
882
-
883
- painter->restore ();
884
930
}
885
931
886
932
int QgsLayoutItemMap::numberExportLayers () const
@@ -994,7 +1040,7 @@ void QgsLayoutItemMap::recreateCachedImageInBackground( double viewScaleFactor )
994
1040
mPainterJob ->start ();
995
1041
}
996
1042
997
- QgsMapSettings QgsLayoutItemMap::mapSettings ( const QgsRectangle &extent, QSizeF size, int dpi ) const
1043
+ QgsMapSettings QgsLayoutItemMap::mapSettings ( const QgsRectangle &extent, QSizeF size, double dpi ) const
998
1044
{
999
1045
QgsExpressionContext expressionContext = createExpressionContext ();
1000
1046
QgsCoordinateReferenceSystem renderCrs = crs ();
0 commit comments