summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--desktop/qa/data/SearchIndexResultTest.odtbin0 -> 126871 bytes
-rw-r--r--desktop/qa/desktop_lib/test_desktop_lib.cxx49
-rw-r--r--desktop/source/lib/init.cxx57
-rw-r--r--include/LibreOfficeKit/LibreOfficeKit.h6
-rw-r--r--include/LibreOfficeKit/LibreOfficeKit.hxx16
-rw-r--r--include/vcl/ITiledRenderable.hxx9
-rw-r--r--sw/inc/unotxdoc.hxx3
-rw-r--r--sw/source/uibase/uno/unotxdoc.cxx25
8 files changed, 164 insertions, 1 deletions
diff --git a/desktop/qa/data/SearchIndexResultTest.odt b/desktop/qa/data/SearchIndexResultTest.odt
new file mode 100644
index 000000000000..58ed3a0f5447
--- /dev/null
+++ b/desktop/qa/data/SearchIndexResultTest.odt
Binary files differ
diff --git a/desktop/qa/desktop_lib/test_desktop_lib.cxx b/desktop/qa/desktop_lib/test_desktop_lib.cxx
index 2a26b04dcfa0..dfbee77167b8 100644
--- a/desktop/qa/desktop_lib/test_desktop_lib.cxx
+++ b/desktop/qa/desktop_lib/test_desktop_lib.cxx
@@ -59,6 +59,8 @@
#include <svx/svxids.hrc>
#include <cppunit/TestAssert.h>
+#include <vcl/BitmapTools.hxx>
+#include <vcl/pngwrite.hxx>
#if USE_TLS_NSS
#include <nss.h>
@@ -205,6 +207,7 @@ public:
void testMetricField();
void testMultiDocuments();
void testJumpCursor();
+ void testRenderSearchResult();
void testABI();
CPPUNIT_TEST_SUITE(DesktopLOKTest);
@@ -268,6 +271,7 @@ public:
CPPUNIT_TEST(testMetricField);
CPPUNIT_TEST(testMultiDocuments);
CPPUNIT_TEST(testJumpCursor);
+ CPPUNIT_TEST(testRenderSearchResult);
CPPUNIT_TEST(testABI);
CPPUNIT_TEST_SUITE_END();
@@ -3103,6 +3107,48 @@ void DesktopLOKTest::testJumpCursor()
comphelper::LibreOfficeKit::setTiledAnnotations(true);
}
+void DesktopLOKTest::testRenderSearchResult()
+{
+ constexpr const bool bDumpBitmap = false;
+
+ LibLODocument_Impl* pDocument = loadDoc("SearchIndexResultTest.odt");
+ pDocument->m_pDocumentClass->initializeForRendering(pDocument, "{}");
+
+ Scheduler::ProcessEventsToIdle();
+
+ unsigned char* pBuffer = nullptr;
+ OString aJSON = "{ \"node_index\" : 19 }";
+
+ int nWidth = 0;
+ int nHeight = 0;
+ size_t nByteSize = 0;
+
+ bool bResult = pDocument->m_pDocumentClass->renderSearchResult(pDocument, aJSON.getStr(), &pBuffer, &nWidth, &nHeight, &nByteSize);
+
+ CPPUNIT_ASSERT(bResult);
+ CPPUNIT_ASSERT(pBuffer);
+
+ Scheduler::ProcessEventsToIdle();
+
+ CPPUNIT_ASSERT_EQUAL(642, nWidth);
+ CPPUNIT_ASSERT_EQUAL(561, nHeight);
+ CPPUNIT_ASSERT_EQUAL(size_t(1440648), nByteSize);
+
+ const sal_uInt8* pD = reinterpret_cast<const sal_uInt8*>(pBuffer);
+ BitmapEx aBitmap = vcl::bitmap::CreateFromData(pD, nWidth, nHeight, nWidth * 4, vcl::PixelFormat::N32_BPP, true, true);
+
+ if (bDumpBitmap)
+ {
+ SvFileStream aStream("~/SearchResultBitmap.png", StreamMode::WRITE | StreamMode::TRUNC);
+ vcl::PNGWriter aPNGWriter(aBitmap);
+ aPNGWriter.Write(aStream);
+ }
+ CPPUNIT_ASSERT_EQUAL(tools::Long(642), aBitmap.GetSizePixel().Width());
+ CPPUNIT_ASSERT_EQUAL(tools::Long(561), aBitmap.GetSizePixel().Height());
+
+ std::free(pBuffer);
+}
+
namespace {
constexpr size_t classOffset(int i)
@@ -3200,10 +3246,11 @@ void DesktopLOKTest::testABI()
CPPUNIT_ASSERT_EQUAL(documentClassOffset(59), offsetof(struct _LibreOfficeKitDocumentClass, completeFunction));
CPPUNIT_ASSERT_EQUAL(documentClassOffset(60), offsetof(struct _LibreOfficeKitDocumentClass, setWindowTextSelection));
CPPUNIT_ASSERT_EQUAL(documentClassOffset(61), offsetof(struct _LibreOfficeKitDocumentClass, sendFormFieldEvent));
+ CPPUNIT_ASSERT_EQUAL(documentClassOffset(62), offsetof(struct _LibreOfficeKitDocumentClass, renderSearchResult));
// Extending is fine, update this, and add new assert for the offsetof the
// new method
- CPPUNIT_ASSERT_EQUAL(documentClassOffset(62), sizeof(struct _LibreOfficeKitDocumentClass));
+ CPPUNIT_ASSERT_EQUAL(documentClassOffset(63), sizeof(struct _LibreOfficeKitDocumentClass));
}
CPPUNIT_TEST_SUITE_REGISTRATION(DesktopLOKTest);
diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index c9778d2b0f81..434b2bda81fa 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -43,6 +43,7 @@
#include <vcl/errinf.hxx>
#include <vcl/lok.hxx>
#include <o3tl/any.hxx>
+#include <o3tl/unit_conversion.hxx>
#include <osl/file.hxx>
#include <osl/process.h>
#include <osl/thread.h>
@@ -1192,6 +1193,11 @@ static void doc_completeFunction(LibreOfficeKitDocument* pThis, const char*);
static void doc_sendFormFieldEvent(LibreOfficeKitDocument* pThis,
const char* pArguments);
+
+static bool doc_renderSearchResult(LibreOfficeKitDocument* pThis,
+ const char* pSearchResult, unsigned char** pBitmapBuffer,
+ int* pWidth, int* pHeight, size_t* pByteSize);
+
} // extern "C"
namespace {
@@ -1331,6 +1337,7 @@ LibLODocument_Impl::LibLODocument_Impl(const uno::Reference <css::lang::XCompone
m_pDocumentClass->completeFunction = doc_completeFunction;
m_pDocumentClass->sendFormFieldEvent = doc_sendFormFieldEvent;
+ m_pDocumentClass->renderSearchResult = doc_renderSearchResult;
gDocumentClass = m_pDocumentClass;
}
@@ -5726,6 +5733,56 @@ static void doc_sendFormFieldEvent(LibreOfficeKitDocument* pThis, const char* pA
pDoc->executeFromFieldEvent(aMap);
}
+static bool doc_renderSearchResult(LibreOfficeKitDocument* pThis,
+ const char* pSearchResult, unsigned char** pBitmapBuffer,
+ int* pWidth, int* pHeight, size_t* pByteSize)
+{
+ if (doc_getDocumentType(pThis) != LOK_DOCTYPE_TEXT)
+ return false;
+
+ if (pBitmapBuffer == nullptr)
+ return false;
+
+ if (!pSearchResult || pSearchResult[0] == '\0')
+ return false;
+
+ ITiledRenderable* pDoc = getTiledRenderable(pThis);
+ if (!pDoc)
+ {
+ SetLastExceptionMsg("Document doesn't support tiled rendering");
+ return false;
+ }
+
+ auto aRectangleVector = pDoc->getSearchResultRectangles(pSearchResult);
+
+ // combine into a rectangle union
+ basegfx::B2DRange aRangeUnion;
+ for (basegfx::B2DRange const & rRange : aRectangleVector)
+ {
+ aRangeUnion.expand(rRange);
+ }
+
+ int aPixelWidth = o3tl::convert(aRangeUnion.getWidth(), o3tl::Length::twip, o3tl::Length::px);
+ int aPixelHeight = o3tl::convert(aRangeUnion.getHeight(), o3tl::Length::twip, o3tl::Length::px);
+
+ size_t nByteSize = aPixelWidth * aPixelHeight * 4;
+
+ *pWidth = aPixelWidth;
+ *pHeight = aPixelHeight;
+ *pByteSize = nByteSize;
+
+ auto* pBuffer = static_cast<unsigned char*>(std::malloc(nByteSize));
+
+ doc_paintTile(pThis, pBuffer,
+ aPixelWidth, aPixelHeight,
+ aRangeUnion.getMinX(), aRangeUnion.getMinY(),
+ aRangeUnion.getWidth(), aRangeUnion.getHeight());
+
+ *pBitmapBuffer = pBuffer;
+
+ return true;
+}
+
static char* lo_getError (LibreOfficeKit *pThis)
{
comphelper::ProfileZone aZone("lo_getError");
diff --git a/include/LibreOfficeKit/LibreOfficeKit.h b/include/LibreOfficeKit/LibreOfficeKit.h
index 82738d65ff93..8c9e0012552e 100644
--- a/include/LibreOfficeKit/LibreOfficeKit.h
+++ b/include/LibreOfficeKit/LibreOfficeKit.h
@@ -458,6 +458,12 @@ struct _LibreOfficeKitDocumentClass
void (*sendFormFieldEvent) (LibreOfficeKitDocument* pThis,
const char* pArguments);
+ /// @see lok::Document::renderSearchResult
+ bool (*renderSearchResult) (LibreOfficeKitDocument* pThis,
+ const char* pSearchResult,
+ unsigned char** pBitmapBuffer,
+ int* pWidth, int* pHeight, size_t* pByteSize);
+
#endif // defined LOK_USE_UNSTABLE_API || defined LIBO_INTERNAL_ONLY
};
diff --git a/include/LibreOfficeKit/LibreOfficeKit.hxx b/include/LibreOfficeKit/LibreOfficeKit.hxx
index 06fe5abc19e2..b1d579849cbd 100644
--- a/include/LibreOfficeKit/LibreOfficeKit.hxx
+++ b/include/LibreOfficeKit/LibreOfficeKit.hxx
@@ -787,6 +787,22 @@ public:
mpDoc->pClass->sendFormFieldEvent(mpDoc, pArguments);
}
+ /**
+ * Render input search result to a bitmap buffer.
+ *
+ * @param pSearchResult payload containing the search result data
+ * @param pBitmapBuffer contains the bitmap; use free to deallocate.
+ * @param nWidth output bitmap width
+ * @param nHeight output bitmap height
+ * @param nByteSize output bitmap byte size
+ * @return true if successful
+ */
+ bool renderSearchResult(const char* pSearchResult, unsigned char** pBitmapBuffer,
+ int* pWidth, int* pHeight, size_t* pByteSize)
+ {
+ return mpDoc->pClass->renderSearchResult(mpDoc, pSearchResult, pBitmapBuffer, pWidth, pHeight, pByteSize);
+ }
+
#endif // defined LOK_USE_UNSTABLE_API || defined LIBO_INTERNAL_ONLY
};
diff --git a/include/vcl/ITiledRenderable.hxx b/include/vcl/ITiledRenderable.hxx
index a1107e8a605a..c40c6f1cfb44 100644
--- a/include/vcl/ITiledRenderable.hxx
+++ b/include/vcl/ITiledRenderable.hxx
@@ -18,6 +18,7 @@
#include <vcl/vclptr.hxx>
#include <map>
#include <com/sun/star/datatransfer/XTransferable.hpp>
+#include <basegfx/range/b2drange.hxx>
namespace com::sun::star::beans { struct PropertyValue; }
namespace com::sun::star::datatransfer::clipboard { class XClipboard; }
@@ -328,6 +329,14 @@ public:
virtual void executeFromFieldEvent(const StringMap&)
{
}
+
+ /**
+ * Returns the rectangles of the input search result JSON
+ */
+ virtual std::vector<basegfx::B2DRange> getSearchResultRectangles(const char* /*pPayload*/)
+ {
+ return std::vector<basegfx::B2DRange>();
+ }
};
} // namespace vcl
diff --git a/sw/inc/unotxdoc.hxx b/sw/inc/unotxdoc.hxx
index 79044005530a..02e2d8efb365 100644
--- a/sw/inc/unotxdoc.hxx
+++ b/sw/inc/unotxdoc.hxx
@@ -443,6 +443,9 @@ public:
/// @see vcl::ITiledRenderable::executeFromFieldEvent().
virtual void executeFromFieldEvent(const StringMap& aArguments) override;
+ /// @see vcl::ITiledRenderable::getSearchResultRectangles().
+ std::vector<basegfx::B2DRange> getSearchResultRectangles(const char* pPayload) override;
+
// css::tiledrendering::XTiledRenderable
virtual void SAL_CALL paintTile( const ::css::uno::Any& Parent, ::sal_Int32 nOutputWidth, ::sal_Int32 nOutputHeight, ::sal_Int32 nTilePosX, ::sal_Int32 nTilePosY, ::sal_Int32 nTileWidth, ::sal_Int32 nTileHeight ) override;
diff --git a/sw/source/uibase/uno/unotxdoc.cxx b/sw/source/uibase/uno/unotxdoc.cxx
index b8f81db2f58b..8ea3697192b4 100644
--- a/sw/source/uibase/uno/unotxdoc.cxx
+++ b/sw/source/uibase/uno/unotxdoc.cxx
@@ -163,6 +163,8 @@
#include <svx/svdpage.hxx>
#include <IDocumentOutlineNodes.hxx>
+#include <SearchResultLocator.hxx>
+#include <boost/property_tree/json_parser.hpp>
#define TWIPS_PER_PIXEL 15
@@ -3390,6 +3392,29 @@ void SwXTextDocument::executeFromFieldEvent(const StringMap& aArguments)
}
}
+std::vector<basegfx::B2DRange>
+SwXTextDocument::getSearchResultRectangles(const char* pPayload)
+{
+ std::vector<basegfx::B2DRange> aRectangles;
+
+ boost::property_tree::ptree aTree;
+ std::stringstream aStream(pPayload);
+ boost::property_tree::read_json(aStream, aTree);
+
+ sw::SearchIndexData aData;
+
+ aData.nNodeIndex = sal_uInt32(aTree.get<int>("node_index"));
+
+ SwDoc* pDoc = m_pDocShell->GetDoc();
+
+ sw::SearchResultLocator aLocator(pDoc);
+ sw::LocationResult aResult = aLocator.find(aData);
+ if (aResult.mbFound)
+ aRectangles = aResult.maRectangles;
+
+ return aRectangles;
+}
+
int SwXTextDocument::getPart()
{
SolarMutexGuard aGuard;