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();