diff options
-rw-r--r-- | vcl/inc/svdata.hxx | 4 | ||||
-rw-r--r-- | vcl/source/app/svmain.cxx | 3 | ||||
-rw-r--r-- | vcl/source/gdi/FileDefinitionWidgetDraw.cxx | 72 |
3 files changed, 61 insertions, 18 deletions
diff --git a/vcl/inc/svdata.hxx b/vcl/inc/svdata.hxx index cb666e718943..c5b3482642a2 100644 --- a/vcl/inc/svdata.hxx +++ b/vcl/inc/svdata.hxx @@ -42,6 +42,7 @@ #include <boost/functional/hash.hpp> #include "ControlCacheKey.hxx" #include "schedulerimpl.hxx" +#include <basegfx/DrawCommands.hxx> struct ImplPostEventData; struct ImplTimerData; @@ -199,6 +200,9 @@ struct ImplSVGDIData long mnAppFontX = 0; // AppFont X-Numenator for 40/tel Width long mnAppFontY = 0; // AppFont Y-Numenator for 80/tel Height bool mbFontSubChanged = false; // true: FontSubstitution was changed between Begin/End + + o3tl::lru_map<OUString, BitmapEx> maThemeImageCache = o3tl::lru_map<OUString, BitmapEx>(10); + o3tl::lru_map<OUString, gfx::DrawRoot> maThemeDrawCommandsCache = o3tl::lru_map<OUString, gfx::DrawRoot>(50); }; struct ImplSVWinData diff --git a/vcl/source/app/svmain.cxx b/vcl/source/app/svmain.cxx index 7f23e366cc67..6319208896ae 100644 --- a/vcl/source/app/svmain.cxx +++ b/vcl/source/app/svmain.cxx @@ -575,6 +575,9 @@ void DeInitVCL() pSVData->maGDIData.maScaleCache.remove_if([](const o3tl::lru_map<SalBitmap*, BitmapEx>::key_value_pair_t&) { return true; }); + pSVData->maGDIData.maThemeDrawCommandsCache.clear(); + pSVData->maGDIData.maThemeImageCache.clear(); + // Deinit Sal if (pSVData->mpDefInst) { diff --git a/vcl/source/gdi/FileDefinitionWidgetDraw.cxx b/vcl/source/gdi/FileDefinitionWidgetDraw.cxx index e321734e9a6e..3c0ad43c99b7 100644 --- a/vcl/source/gdi/FileDefinitionWidgetDraw.cxx +++ b/vcl/source/gdi/FileDefinitionWidgetDraw.cxx @@ -343,9 +343,26 @@ void munchDrawCommands(std::vector<std::shared_ptr<DrawCommand>> const& rDrawCom nScaleFactor = comphelper::LibreOfficeKit::getDPIScale(); auto const& rDrawCommand = static_cast<ImageDrawCommand const&>(*pDrawCommand); - SvFileStream aFileStream(rDrawCommand.msSource, StreamMode::READ); + auto& rCacheImages = ImplGetSVData()->maGDIData.maThemeImageCache; + OUString rCacheKey = rDrawCommand.msSource + "@" + OUString::number(nScaleFactor); + auto& aIterator = rCacheImages.find(rCacheKey); + BitmapEx aBitmap; - vcl::bitmap::loadFromSvg(aFileStream, "", aBitmap, nScaleFactor); + if (aIterator == rCacheImages.end()) + { + SvFileStream aFileStream(rDrawCommand.msSource, StreamMode::READ); + + vcl::bitmap::loadFromSvg(aFileStream, "", aBitmap, nScaleFactor); + if (!!aBitmap) + { + rCacheImages.insert(std::make_pair(rCacheKey, aBitmap)); + } + } + else + { + aBitmap = aIterator->second; + } + long nImageWidth = aBitmap.GetSizePixel().Width(); long nImageHeight = aBitmap.GetSizePixel().Height(); SalTwoRect aTR(0, 0, nImageWidth, nImageHeight, nX, nY, nImageWidth / nScaleFactor, @@ -370,27 +387,46 @@ void munchDrawCommands(std::vector<std::shared_ptr<DrawCommand>> const& rDrawCom case DrawCommandType::EXTERNAL: { auto const& rDrawCommand = static_cast<ImageDrawCommand const&>(*pDrawCommand); - SvFileStream aFileStream(rDrawCommand.msSource, StreamMode::READ); - uno::Reference<uno::XComponentContext> xContext( - comphelper::getProcessComponentContext()); - const uno::Reference<graphic::XSvgParser> xSvgParser - = graphic::SvgTools::create(xContext); + auto& rCacheDrawCommands = ImplGetSVData()->maGDIData.maThemeDrawCommandsCache; - std::size_t nSize = aFileStream.remainingSize(); - std::vector<sal_Int8> aBuffer(nSize + 1); - aFileStream.ReadBytes(aBuffer.data(), nSize); - aBuffer[nSize] = 0; + auto& aIterator = rCacheDrawCommands.find(rDrawCommand.msSource); - uno::Sequence<sal_Int8> aData(aBuffer.data(), nSize + 1); - uno::Reference<io::XInputStream> aInputStream( - new comphelper::SequenceInputStream(aData)); + gfx::DrawRoot aDrawRoot; - uno::Any aAny = xSvgParser->getDrawCommands(aInputStream, ""); - if (aAny.has<sal_uInt64>()) + if (aIterator == rCacheDrawCommands.end()) + { + SvFileStream aFileStream(rDrawCommand.msSource, StreamMode::READ); + + uno::Reference<uno::XComponentContext> xContext( + comphelper::getProcessComponentContext()); + const uno::Reference<graphic::XSvgParser> xSvgParser + = graphic::SvgTools::create(xContext); + + std::size_t nSize = aFileStream.remainingSize(); + std::vector<sal_Int8> aBuffer(nSize + 1); + aFileStream.ReadBytes(aBuffer.data(), nSize); + aBuffer[nSize] = 0; + + uno::Sequence<sal_Int8> aData(aBuffer.data(), nSize + 1); + uno::Reference<io::XInputStream> aInputStream( + new comphelper::SequenceInputStream(aData)); + + uno::Any aAny = xSvgParser->getDrawCommands(aInputStream, ""); + if (aAny.has<sal_uInt64>()) + { + auto* pDrawRoot = reinterpret_cast<gfx::DrawRoot*>(aAny.get<sal_uInt64>()); + if (pDrawRoot) + { + rCacheDrawCommands.insert( + std::make_pair(rDrawCommand.msSource, *pDrawRoot)); + drawFromDrawCommands(*pDrawRoot, rGraphics, nX, nY, nWidth, nHeight); + } + } + } + else { - auto* pDrawRoot = reinterpret_cast<gfx::DrawRoot*>(aAny.get<sal_uInt64>()); - drawFromDrawCommands(*pDrawRoot, rGraphics, nX, nY, nWidth, nHeight); + drawFromDrawCommands(aIterator->second, rGraphics, nX, nY, nWidth, nHeight); } } break; |