Kaydet (Commit) 805b15ce authored tarafından Tomaž Vajngerl's avatar Tomaž Vajngerl Kaydeden (comit) Tomaž Vajngerl

cache file based widget images and draw commands

It is wasteful to parse svg icons all the time so lets cache the
result when this make sense in a LRU map.

Change-Id: I95cc317c9301138a9e384d270223ba147a123e59
Reviewed-on: https://gerrit.libreoffice.org/69055
Tested-by: Jenkins
Reviewed-by: 's avatarTomaž Vajngerl <quikee@gmail.com>
üst 812316f6
......@@ -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
......
......@@ -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)
{
......
......@@ -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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment