summaryrefslogtreecommitdiff
path: root/filter
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.com>2020-02-25 09:04:10 +0100
committerMiklos Vajna <vmiklos@collabora.com>2020-05-13 09:16:33 +0200
commit4f1cf7a1205485ca7b011c5dd7c2031f498d5c7c (patch)
tree8815207113dbf0ae3ce8eaf269742881e8fc288a /filter
parent39ddb0081def0d4635234f59de4e90adf06308e8 (diff)
svx: cache PNG export of graphic shapes
One scenario where this is useful is: manipulate a JPEG photo in Online's Impress, e.g. resize it multiple times. Each time we generate an SVG preview of the shape, which includes the PNG export of the bitmap itself. This helps with a desktop CPU: debug:9976:9974: SVGFilter::filter finished in 3422 ms debug:9976:9974: SVGFilter::filter finished in 176 ms But it is meant to help on mobile, too, where writing such a bitmap as PNG takes 16-17 seconds without this. (This works because SVG writes the original bitmap, even if it's scaled. If that invariant will be broken in the future, we still emit correct output, but then the cache will be less useful.) (cherry picked from commit 570be56b37e4ff105649e604ff4c8a6c368e2e79) Change-Id: I7204b04efeeb42c6eec67f04dfdb8a4ed50443a9
Diffstat (limited to 'filter')
-rw-r--r--filter/source/svg/svgwriter.cxx58
-rw-r--r--filter/source/svg/svgwriter.hxx2
2 files changed, 50 insertions, 10 deletions
diff --git a/filter/source/svg/svgwriter.cxx b/filter/source/svg/svgwriter.cxx
index 9253bbace5f3..dfb203360b4e 100644
--- a/filter/source/svg/svgwriter.cxx
+++ b/filter/source/svg/svgwriter.cxx
@@ -31,6 +31,8 @@
#include <xmloff/unointerfacetouniqueidentifiermapper.hxx>
#include <sax/tools/converter.hxx>
#include <i18nlangtag/languagetag.hxx>
+#include <svx/unoshape.hxx>
+#include <svx/svdograf.hxx>
#include <memory>
@@ -2673,10 +2675,29 @@ void SVGActionWriter::ImplWriteText( const Point& rPos, const OUString& rText,
}
}
+namespace
+{
+SdrGrafObj* GetSdrGrafObjFromXShape(const css::uno::Reference<css::drawing::XShape>* pShape)
+{
+ if (!pShape)
+ {
+ return nullptr;
+ }
+
+ auto pObject = dynamic_cast<SvxGraphicObject*>(pShape->get());
+ if (!pObject)
+ {
+ return nullptr;
+ }
+
+ return dynamic_cast<SdrGrafObj*>(pObject->GetSdrObject());
+}
+}
void SVGActionWriter::ImplWriteBmp( const BitmapEx& rBmpEx,
const Point& rPt, const Size& rSz,
- const Point& rSrcPt, const Size& rSrcSz )
+ const Point& rSrcPt, const Size& rSrcSz,
+ const css::uno::Reference<css::drawing::XShape>* pShape )
{
if( !!rBmpEx )
{
@@ -2691,8 +2712,27 @@ void SVGActionWriter::ImplWriteBmp( const BitmapEx& rBmpEx,
{
SvMemoryStream aOStm( 65535, 65535 );
- if( GraphicConverter::Export( aOStm, rBmpEx, ConvertDataFormat::PNG ) == ERRCODE_NONE )
+ bool bCached = false;
+ SdrGrafObj* pGrafObj = nullptr;
+ if (pShape)
{
+ pGrafObj = GetSdrGrafObjFromXShape(pShape);
+ if (pGrafObj && pGrafObj->GetPNGPreviewChecksum() == rBmpEx.GetChecksum())
+ {
+ const std::vector<sal_Int8>& rPreviewData = pGrafObj->GetPNGPreviewData();
+ aOStm.WriteBytes(rPreviewData.data(), rPreviewData.size());
+ bCached = true;
+ }
+ }
+
+ if( bCached || GraphicConverter::Export( aOStm, rBmpEx, ConvertDataFormat::PNG ) == ERRCODE_NONE )
+ {
+ if (!bCached && pGrafObj)
+ {
+ pGrafObj->SetPNGPreviewChecksum(rBmpEx.GetChecksum());
+ pGrafObj->SetPNGPreviewData(aOStm);
+ }
+
Point aPt;
Size aSz;
Sequence< sal_Int8 > aSeq( static_cast<sal_Int8 const *>(aOStm.GetData()), aOStm.Tell() );
@@ -3036,7 +3076,7 @@ void SVGActionWriter::ImplWriteActions( const GDIMetaFile& rMtf,
const MetaBmpScaleAction* pBmpScaleAction = static_cast<const MetaBmpScaleAction*>(pSubstAct);
ImplWriteBmp( BitmapEx(pBmpScaleAction->GetBitmap()),
pA->GetPoint(), pA->GetSize(),
- Point(), pBmpScaleAction->GetBitmap().GetSizePixel() );
+ Point(), pBmpScaleAction->GetBitmap().GetSizePixel(), pxShape );
}
}
}
@@ -3419,7 +3459,7 @@ void SVGActionWriter::ImplWriteActions( const GDIMetaFile& rMtf,
ImplWriteBmp( BitmapEx(pA->GetBitmap()),
pA->GetPoint(), mpVDev->PixelToLogic( pA->GetBitmap().GetSizePixel() ),
- Point(), pA->GetBitmap().GetSizePixel() );
+ Point(), pA->GetBitmap().GetSizePixel(), pxShape );
}
}
break;
@@ -3439,7 +3479,7 @@ void SVGActionWriter::ImplWriteActions( const GDIMetaFile& rMtf,
{
ImplWriteBmp( BitmapEx(pA->GetBitmap()),
pA->GetPoint(), pA->GetSize(),
- Point(), pA->GetBitmap().GetSizePixel() );
+ Point(), pA->GetBitmap().GetSizePixel(), pxShape );
}
}
}
@@ -3453,7 +3493,7 @@ void SVGActionWriter::ImplWriteActions( const GDIMetaFile& rMtf,
ImplWriteBmp( BitmapEx(pA->GetBitmap()),
pA->GetDestPoint(), pA->GetDestSize(),
- pA->GetSrcPoint(), pA->GetSrcSize() );
+ pA->GetSrcPoint(), pA->GetSrcSize(), pxShape );
}
}
break;
@@ -3466,7 +3506,7 @@ void SVGActionWriter::ImplWriteActions( const GDIMetaFile& rMtf,
ImplWriteBmp( pA->GetBitmapEx(),
pA->GetPoint(), mpVDev->PixelToLogic( pA->GetBitmapEx().GetSizePixel() ),
- Point(), pA->GetBitmapEx().GetSizePixel() );
+ Point(), pA->GetBitmapEx().GetSizePixel(), pxShape );
}
}
break;
@@ -3486,7 +3526,7 @@ void SVGActionWriter::ImplWriteActions( const GDIMetaFile& rMtf,
{
ImplWriteBmp( pA->GetBitmapEx(),
pA->GetPoint(), pA->GetSize(),
- Point(), pA->GetBitmapEx().GetSizePixel() );
+ Point(), pA->GetBitmapEx().GetSizePixel(), pxShape );
}
}
}
@@ -3500,7 +3540,7 @@ void SVGActionWriter::ImplWriteActions( const GDIMetaFile& rMtf,
ImplWriteBmp( pA->GetBitmapEx(),
pA->GetDestPoint(), pA->GetDestSize(),
- pA->GetSrcPoint(), pA->GetSrcSize() );
+ pA->GetSrcPoint(), pA->GetSrcSize(), pxShape );
}
}
break;
diff --git a/filter/source/svg/svgwriter.hxx b/filter/source/svg/svgwriter.hxx
index f0271ed4090b..1418818b0c16 100644
--- a/filter/source/svg/svgwriter.hxx
+++ b/filter/source/svg/svgwriter.hxx
@@ -360,7 +360,7 @@ private:
void ImplWriteMask( GDIMetaFile& rMtf, const Point& rDestPt, const Size& rDestSize, const Gradient& rGradient, sal_uInt32 nWriteFlags );
void ImplWriteText( const Point& rPos, const OUString& rText, const long* pDXArray, long nWidth );
void ImplWriteText( const Point& rPos, const OUString& rText, const long* pDXArray, long nWidth, Color aTextColor );
- void ImplWriteBmp( const BitmapEx& rBmpEx, const Point& rPt, const Size& rSz, const Point& rSrcPt, const Size& rSrcSz );
+ void ImplWriteBmp( const BitmapEx& rBmpEx, const Point& rPt, const Size& rSz, const Point& rSrcPt, const Size& rSrcSz, const css::uno::Reference<css::drawing::XShape>* pShape);
void ImplWriteActions( const GDIMetaFile& rMtf,
sal_uInt32 nWriteFlags,