fdo#68927: sw: fix painting of SVG page background

There was a fix for a wrong constant resulting in too large image size in
a1a0830d1ac3ffabbe35bd8a0264b64f1f7a9d67, and it turns out that painting
of SVG backgrounds was relying on the wasteful rasterization:  the SVG
is rasterized only once (at the initial zoom level) and then cached, and
now the correct image size for 100% is simply scaled up when zooming in.

Fix that by painting SVGs with the drawing layer primitives instead,
which appears to give better results.

Change-Id: I4be16856fd080290526d4963d8c512beefa85363
diff --git a/sw/source/core/doc/notxtfrm.cxx b/sw/source/core/doc/notxtfrm.cxx
index e59e32e..94a37dd 100644
--- a/sw/source/core/doc/notxtfrm.cxx
+++ b/sw/source/core/doc/notxtfrm.cxx
@@ -735,6 +735,36 @@ bool paintUsingPrimitivesHelper(
    return false;
}


void paintGraphicUsingPrimitivesHelper(OutputDevice & rOutputDevice,
         Graphic const& rGraphic, GraphicAttr const& rGraphicAttr,
         SwRect const& rAlignedGrfArea)
{
    // unify using GraphicPrimitive2D
    // -> the primitive handles all crop and mirror stuff
    // -> the primitive renderer will create the needed pdf export data
    // -> if bitmap content, it will be cached system-dependent
    const basegfx::B2DRange aTargetRange(
        rAlignedGrfArea.Left(), rAlignedGrfArea.Top(),
        rAlignedGrfArea.Right(), rAlignedGrfArea.Bottom());
    const basegfx::B2DHomMatrix aTargetTransform(
        basegfx::tools::createScaleTranslateB2DHomMatrix(
            aTargetRange.getRange(),
            aTargetRange.getMinimum()));
    drawinglayer::primitive2d::Primitive2DSequence aContent(1);

    aContent[0] = new drawinglayer::primitive2d::GraphicPrimitive2D(
        aTargetTransform,
        rGraphic,
        rGraphicAttr);

    paintUsingPrimitivesHelper(
        rOutputDevice,
        aContent,
        aTargetRange,
        aTargetRange);
}

/** Paint the graphic.

    We require either a QuickDraw-Bitmap or a graphic here. If we do not have
@@ -857,30 +887,8 @@ void SwNoTxtFrm::PaintPicture( OutputDevice* pOut, const SwRect &rGrfArea ) cons
                }
                else
                {
                    // unify using GraphicPrimitive2D
                    // -> the primitive handles all crop and mirror stuff
                    // -> the primitive renderer will create the needed pdf export data
                    // -> if bitmap conent, it will be cached system-dependent
                    const basegfx::B2DRange aTargetRange(
                        aAlignedGrfArea.Left(), aAlignedGrfArea.Top(),
                        aAlignedGrfArea.Right(), aAlignedGrfArea.Bottom());
                    const basegfx::B2DHomMatrix aTargetTransform(
                        basegfx::tools::createScaleTranslateB2DHomMatrix(
                            aTargetRange.getRange(),
                            aTargetRange.getMinimum()));
                    drawinglayer::primitive2d::Primitive2DSequence aContent;

                    aContent.realloc(1);
                    aContent[0] = new drawinglayer::primitive2d::GraphicPrimitive2D(
                        aTargetTransform,
                        rGrfObj.GetGraphic(),
                        aGrfAttr);

                    paintUsingPrimitivesHelper(
                        *pOut,
                        aContent,
                        aTargetRange,
                        aTargetRange);
                    paintGraphicUsingPrimitivesHelper(*pOut,
                            rGrfObj.GetGraphic(), aGrfAttr, aAlignedGrfArea);
                }
            }
            else
diff --git a/sw/source/core/inc/frmtool.hxx b/sw/source/core/inc/frmtool.hxx
index e44862c..341af85 100644
--- a/sw/source/core/inc/frmtool.hxx
+++ b/sw/source/core/inc/frmtool.hxx
@@ -41,6 +41,8 @@ class XFillGradientItem;
class SdrMarkList;
class SwNodeIndex;
class OutputDevice;
class Graphic;
class GraphicAttr;
class SwPageDesc;

#define FAR_AWAY LONG_MAX - 20000  // initial position of a Fly
@@ -56,6 +58,11 @@ void DrawGraphic( const SvxBrushItem *, const XFillStyleItem*, const XFillGradie
                  const SwRect &rOrg, const SwRect &rOut, const sal_uInt8 nGrfNum = GRFNUM_NO,
                  const sal_Bool bConsiderBackgroundTransparency = sal_False );

void paintGraphicUsingPrimitivesHelper(
        OutputDevice & rOutputDevice,
        Graphic const& rGraphic, GraphicAttr const& rGraphicAttr,
        SwRect const& rAlignedGrfArea);

// method to align rectangle.
// Created declaration here to avoid <extern> declarations
void SwAlignRect( SwRect &rRect, const SwViewShell *pSh );
diff --git a/sw/source/core/layout/paintfrm.cxx b/sw/source/core/layout/paintfrm.cxx
index 84c5de6..f2d6effc 100644
--- a/sw/source/core/layout/paintfrm.cxx
+++ b/sw/source/core/layout/paintfrm.cxx
@@ -1796,7 +1796,16 @@ static void lcl_DrawGraphic( const SvxBrushItem& rBrush, OutputDevice *pOut,
    /// Because for drawing a graphic left-top-corner and size coordinations are
    /// used, these coordinations have to be determined on pixel level.
    ::SwAlignGrfRect( &aAlignedGrfRect, *pOut );
    pGrf->DrawWithPDFHandling( *pOut, aAlignedGrfRect.Pos(), aAlignedGrfRect.SSize() );

    if (pGrf->GetGraphic().getSvgData().get())
    {   // fdo#68927 - SVGs are rasterized badly by DrawWithPDFHandling
        paintGraphicUsingPrimitivesHelper(*pOut,
                pGrf->GetGraphic(), pGrf->GetAttr(), aAlignedGrfRect);
    }
    else
    {
        pGrf->DrawWithPDFHandling( *pOut, aAlignedGrfRect.Pos(), aAlignedGrfRect.SSize() );
    }

    if ( bNotInside )
        pOut->Pop();