diff --git a/desktop/CppunitTest_desktop_app.mk b/desktop/CppunitTest_desktop_app.mk index aa5bf0cd53e9..1b1c361c142a 100644 --- a/desktop/CppunitTest_desktop_app.mk +++ b/desktop/CppunitTest_desktop_app.mk @@ -16,6 +16,9 @@ $(eval $(call gb_CppunitTest_add_exception_objects,desktop_app, \ $(eval $(call gb_CppunitTest_use_externals,desktop_app, \ $(if $(ENABLE_BREAKPAD),breakpad) \ dbus \ + icu_headers \ + icui18n \ + icuuc \ )) $(eval $(call gb_CppunitTest_use_libraries,desktop_app, \ @@ -32,6 +35,7 @@ $(eval $(call gb_CppunitTest_use_libraries,desktop_app, \ sb \ sfx \ svl \ + svx \ svxcore \ svt \ tk \ diff --git a/desktop/Library_sofficeapp.mk b/desktop/Library_sofficeapp.mk index 2a3f142cb5b7..816426087e49 100644 --- a/desktop/Library_sofficeapp.mk +++ b/desktop/Library_sofficeapp.mk @@ -28,6 +28,9 @@ $(eval $(call gb_Library_use_externals,sofficeapp, \ $(if $(filter OPENCL,$(BUILD_TYPE)),clew) \ boost_headers \ dbus \ + icu_headers \ + icui18n \ + icuuc \ )) $(eval $(call gb_Library_use_custom_headers,sofficeapp,\ @@ -61,6 +64,7 @@ $(eval $(call gb_Library_use_libraries,sofficeapp,\ sb \ sfx \ svl \ + svx \ svxcore \ svt \ tk \ diff --git a/desktop/qa/desktop_lib/test_desktop_lib.cxx b/desktop/qa/desktop_lib/test_desktop_lib.cxx index 11c8db46ebc5..72009670eb03 100644 --- a/desktop/qa/desktop_lib/test_desktop_lib.cxx +++ b/desktop/qa/desktop_lib/test_desktop_lib.cxx @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -103,6 +104,7 @@ public: void testRedlineCalc(); void testPaintPartTile(); void testWriterCommentInsertCursor(); + void testGetFontSubset(); CPPUNIT_TEST_SUITE(DesktopLOKTest); CPPUNIT_TEST(testGetStyles); @@ -135,6 +137,7 @@ public: CPPUNIT_TEST(testRedlineCalc); CPPUNIT_TEST(testPaintPartTile); CPPUNIT_TEST(testWriterCommentInsertCursor); + CPPUNIT_TEST(testGetFontSubset); CPPUNIT_TEST_SUITE_END(); uno::Reference mxComponent; @@ -1623,6 +1626,30 @@ void DesktopLOKTest::testWriterCommentInsertCursor() comphelper::LibreOfficeKit::setActive(false); } +void DesktopLOKTest::testGetFontSubset() +{ + comphelper::LibreOfficeKit::setActive(); + LibLODocument_Impl* pDocument = loadDoc("blank_text.odt"); + OUString aFontName = rtl::Uri::encode( + OUString("Liberation Sans"), + rtl_UriCharClassRelSegment, + rtl_UriEncodeKeepEscapes, + RTL_TEXTENCODING_UTF8 + ); + OUString aUnoFontSubset(".uno:FontSubset&name="); + OString aCommand = OUStringToOString(aUnoFontSubset + aFontName, RTL_TEXTENCODING_UTF8); + boost::property_tree::ptree aTree; + char* pJSON = pDocument->m_pDocumentClass->getCommandValues(pDocument, aCommand.getStr()); + std::stringstream aStream(pJSON); + boost::property_tree::read_json(aStream, aTree); + CPPUNIT_ASSERT( aTree.size() > 0 ); + CPPUNIT_ASSERT( aTree.get_child("commandName").get_value() == ".uno:FontSubset" ); + boost::property_tree::ptree aValues = aTree.get_child("commandValues"); + CPPUNIT_ASSERT( aValues.size() > 0 ); + free(pJSON); + comphelper::LibreOfficeKit::setActive(false); +} + CPPUNIT_TEST_SUITE_REGISTRATION(DesktopLOKTest); CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx index ea543ed2e3bf..9df6471bf53f 100644 --- a/desktop/source/lib/init.cxx +++ b/desktop/source/lib/init.cxx @@ -65,15 +65,18 @@ #include #include #include +#include #include #include #include #include +#include #include #include #include #include #include +#include #include #include #include @@ -2049,6 +2052,58 @@ static char* getFonts (const char* pCommand) return pJson; } +static char* getFontSubset (const OString& aFontName) +{ + OUString aFoundFont(::rtl::Uri::decode(OStringToOUString(aFontName, RTL_TEXTENCODING_UTF8), rtl_UriDecodeStrict, RTL_TEXTENCODING_UTF8)); + SfxObjectShell* pDocSh = SfxObjectShell::Current(); + const SvxFontListItem* pFonts = static_cast( + pDocSh->GetItem(SID_ATTR_CHAR_FONTLIST)); + const FontList* pList = pFonts ? pFonts->GetFontList() : nullptr; + + boost::property_tree::ptree aTree; + aTree.put("commandName", ".uno:FontSubset"); + boost::property_tree::ptree aValues; + + if ( pList && !aFoundFont.isEmpty() ) + { + sal_uInt16 nFontCount = pList->GetFontNameCount(); + sal_uInt16 nItFont = 0; + for (; nItFont < nFontCount; ++nItFont) + { + if (aFoundFont.equals(pList->GetFontName(nItFont).GetFamilyName())) + { + break; + } + } + + if ( nItFont < nFontCount ) + { + FontCharMapRef xFontCharMap (new FontCharMap()); + auto aDevice(VclPtr::Create(nullptr, Size(1, 1), DeviceFormat::DEFAULT)); + vcl::Font aFont(pList->GetFontName(nItFont)); + + aDevice->SetFont(aFont); + aDevice->GetFontCharMap(xFontCharMap); + SubsetMap aSubMap(xFontCharMap); + + for(const Subset* pItSub = aSubMap.GetNextSubset(true); pItSub; pItSub = aSubMap.GetNextSubset(false)) + { + boost::property_tree::ptree aChild; + aChild.put("", static_cast(ublock_getCode(pItSub->GetRangeMin()))); + aValues.push_back(std::make_pair("", aChild)); + } + } + } + + aTree.add_child("commandValues", aValues); + std::stringstream aStream; + boost::property_tree::write_json(aStream, aTree); + char* pJson = static_cast(malloc(aStream.str().size() + 1)); + strcpy(pJson, aStream.str().c_str()); + pJson[aStream.str().size()] = '\0'; + return pJson; +} + static char* getStyles(LibreOfficeKitDocument* pThis, const char* pCommand) { LibLODocument_Impl* pDocument = static_cast(pThis); @@ -2258,6 +2313,7 @@ static char* doc_getCommandValues(LibreOfficeKitDocument* pThis, const char* pCo OString aCommand(pCommand); static const OString aViewRowColumnHeaders(".uno:ViewRowColumnHeaders"); static const OString aCellCursor(".uno:CellCursor"); + static const OString aFontSubset(".uno:FontSubset&name="); if (!strcmp(pCommand, ".uno:CharFontName")) { @@ -2388,6 +2444,10 @@ static char* doc_getCommandValues(LibreOfficeKitDocument* pThis, const char* pCo strcpy(pMemory, aString.getStr()); return pMemory; } + else if (aCommand.startsWith(aFontSubset)) + { + return getFontSubset(OString(pCommand + aFontSubset.getLength())); + } else { gImpl->maLastExceptionMsg = "Unknown command, no values returned";