summaryrefslogtreecommitdiff
path: root/svx
diff options
context:
space:
mode:
authorCaolán McNamara <caolan.mcnamara@collabora.com>2023-06-05 20:15:16 +0100
committerCaolán McNamara <caolan.mcnamara@collabora.com>2023-06-06 18:01:31 +0200
commit4df278b4a98637aa5050abfd752eae0a9081b752 (patch)
tree6e5baa87f2e49daccc7e40403ca9df4733df1267 /svx
parent9b03f778adfb87a10d781860930ed4d09410af9c (diff)
perf: cache the generated json for an iconview image
before: |--13.95%--JSDialogNotifyIdle::Invoke | | | |--13.01%--JSDialogNotifyIdle::generateWidgetUpdate | | | | | |--11.03%--IconView::DumpAsPropertyTree | | | lcl_DumpEntryAndSiblings (inlined) | | | | | | | |--10.94%--extractPngString (inlined) after: |--4.86%--JSDialogNotifyIdle::Invoke ... | |--2.90%--JSDialogNotifyIdle::generateWidgetUpdate | | | | | |--0.76%--IconView::DumpAsPropertyTree | | | IconView::DumpEntryAndSiblings | | | Link<std::tuple<tools::JsonWriter&, rtl::OUString const&, std::basic_string_view<char, std::char_traits<char> > > const&, bool>::Call (inlined) | | | StylesPreviewWindow_Base::DoJsonProperty | | | | | | | |--0.55%--StylesPreviewWindow_Base::GetCachedPreviewJson Change-Id: Id234a84e36710794822945584be3adf028808625 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/152630 Tested-by: Jenkins Reviewed-by: Caolán McNamara <caolan.mcnamara@collabora.com>
Diffstat (limited to 'svx')
-rw-r--r--svx/source/inc/StylesPreviewWindow.hxx2
-rw-r--r--svx/source/tbxctrls/StylesPreviewWindow.cxx67
2 files changed, 68 insertions, 1 deletions
diff --git a/svx/source/inc/StylesPreviewWindow.hxx b/svx/source/inc/StylesPreviewWindow.hxx
index de4984e35968..1d59c574bfbe 100644
--- a/svx/source/inc/StylesPreviewWindow.hxx
+++ b/svx/source/inc/StylesPreviewWindow.hxx
@@ -112,6 +112,7 @@ protected:
DECL_LINK(Selected, weld::IconView&, void);
DECL_LINK(DoubleClick, weld::IconView&, bool);
DECL_LINK(DoCommand, const CommandEvent&, bool);
+ DECL_STATIC_LINK(StylesPreviewWindow_Base, DoJsonProperty, const tools::json_prop_query&, bool);
public:
StylesPreviewWindow_Base(
@@ -122,6 +123,7 @@ public:
void Select(const OUString& rStyleName);
void RequestStylesListUpdate();
static VclPtr<VirtualDevice> GetCachedPreview(const std::pair<OUString, OUString>& rStyle);
+ static OString GetCachedPreviewJson(const OUString& rStyle);
private:
void UpdateStylesList();
diff --git a/svx/source/tbxctrls/StylesPreviewWindow.cxx b/svx/source/tbxctrls/StylesPreviewWindow.cxx
index 3cc669ff98ce..eeca3db49840 100644
--- a/svx/source/tbxctrls/StylesPreviewWindow.cxx
+++ b/svx/source/tbxctrls/StylesPreviewWindow.cxx
@@ -19,6 +19,7 @@
#include <StylesPreviewWindow.hxx>
+#include <comphelper/base64.hxx>
#include <comphelper/propertyvalue.hxx>
#include <utility>
#include <vcl/svapp.hxx>
@@ -28,6 +29,7 @@
#include <sfx2/sfxsids.hrc>
#include <sfx2/tplpitem.hxx>
#include <sfx2/viewsh.hxx>
+#include <vcl/filter/PngImageWriter.hxx>
#include <vcl/glyphitemcache.hxx>
#include <vcl/virdev.hxx>
#include <vcl/settings.hxx>
@@ -59,16 +61,19 @@
#include <com/sun/star/uno/Sequence.hxx>
#include <vcl/commandevent.hxx>
+#include <tools/json_writer.hxx>
namespace
{
class StylePreviewCache
{
static std::map<OUString, VclPtr<VirtualDevice>> gStylePreviewCache;
+ static std::map<OUString, OString> gJsonStylePreviewCache;
static int gStylePreviewCacheClients;
public:
static std::map<OUString, VclPtr<VirtualDevice>>& Get() { return gStylePreviewCache; }
+ static std::map<OUString, OString>& GetJson() { return gJsonStylePreviewCache; }
static void ClearCache()
{
@@ -76,6 +81,7 @@ public:
aPreview.second.disposeAndClear();
gStylePreviewCache.clear();
+ gJsonStylePreviewCache.clear();
}
static void RegisterClient() { gStylePreviewCacheClients++; }
@@ -88,6 +94,7 @@ public:
};
std::map<OUString, VclPtr<VirtualDevice>> StylePreviewCache::gStylePreviewCache;
+std::map<OUString, OString> StylePreviewCache::gJsonStylePreviewCache;
int StylePreviewCache::gStylePreviewCacheClients;
}
@@ -414,6 +421,8 @@ StylesPreviewWindow_Base::StylesPreviewWindow_Base(
m_xStylesView->connect_selection_changed(LINK(this, StylesPreviewWindow_Base, Selected));
m_xStylesView->connect_item_activated(LINK(this, StylesPreviewWindow_Base, DoubleClick));
m_xStylesView->connect_command(LINK(this, StylesPreviewWindow_Base, DoCommand));
+ m_xStylesView->connect_get_property_tree_elem(
+ LINK(this, StylesPreviewWindow_Base, DoJsonProperty));
m_xStatusListener = new StyleStatusListener(this, xDispatchProvider);
@@ -497,6 +506,44 @@ void StylesListUpdateTask::Invoke()
m_rStylesList.UpdateSelection();
}
+static OString extractPngString(const BitmapEx& rBitmap)
+{
+ SvMemoryStream aOStm(65535, 65535);
+ // Use fastest compression "1"
+ css::uno::Sequence<css::beans::PropertyValue> aFilterData{
+ comphelper::makePropertyValue("Compression", sal_Int32(1)),
+ };
+ vcl::PngImageWriter aPNGWriter(aOStm);
+ aPNGWriter.setParameters(aFilterData);
+ if (aPNGWriter.write(rBitmap))
+ {
+ css::uno::Sequence<sal_Int8> aSeq(static_cast<sal_Int8 const*>(aOStm.GetData()),
+ aOStm.Tell());
+ OStringBuffer aBuffer("data:image/png;base64,");
+ ::comphelper::Base64::encode(aBuffer, aSeq);
+ return aBuffer.makeStringAndClear();
+ }
+
+ return "";
+}
+
+// 0: json writer, 1: id, 2: property. returns true if supported
+IMPL_STATIC_LINK(StylesPreviewWindow_Base, DoJsonProperty, const tools::json_prop_query&, rQuery,
+ bool)
+{
+ if (std::get<2>(rQuery) != "image")
+ return false;
+
+ OString sBase64Png(GetCachedPreviewJson(std::get<1>(rQuery)));
+ if (sBase64Png.isEmpty())
+ return false;
+
+ tools::JsonWriter& rJsonWriter = std::get<0>(rQuery);
+ rJsonWriter.put("image", sBase64Png);
+
+ return true;
+}
+
VclPtr<VirtualDevice>
StylesPreviewWindow_Base::GetCachedPreview(const std::pair<OUString, OUString>& rStyle)
{
@@ -517,6 +564,23 @@ StylesPreviewWindow_Base::GetCachedPreview(const std::pair<OUString, OUString>&
}
}
+OString StylesPreviewWindow_Base::GetCachedPreviewJson(const OUString& rStyle)
+{
+ auto aJsonFound = StylePreviewCache::GetJson().find(rStyle);
+ if (aJsonFound != StylePreviewCache::GetJson().end())
+ return StylePreviewCache::GetJson()[rStyle];
+
+ auto aFound = StylePreviewCache::Get().find(rStyle);
+ if (aFound == StylePreviewCache::Get().end())
+ return "";
+
+ VclPtr<VirtualDevice> xDev = aFound->second;
+ BitmapEx aBitmap(xDev->GetBitmapEx(Point(0, 0), xDev->GetOutputSize()));
+ OString sResult = extractPngString(aBitmap);
+ StylePreviewCache::GetJson()[rStyle] = sResult;
+ return sResult;
+}
+
void StylesPreviewWindow_Base::UpdateStylesList()
{
m_aAllStyles = m_aDefaultStyles;
@@ -536,7 +600,8 @@ void StylesPreviewWindow_Base::UpdateStylesList()
while (pStyle)
{
- m_aAllStyles.push_back(std::pair<OUString, OUString>("", pStyle->GetName()));
+ OUString sName(pStyle->GetName());
+ m_aAllStyles.push_back(std::pair<OUString, OUString>(sName, sName));
pStyle = xIter->Next();
}
}