summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--desktop/inc/lib/init.hxx2
-rw-r--r--desktop/source/lib/init.cxx60
-rw-r--r--include/LibreOfficeKit/LibreOfficeKitEnums.h23
-rw-r--r--libreofficekit/source/gtk/lokdocview.cxx1
4 files changed, 86 insertions, 0 deletions
diff --git a/desktop/inc/lib/init.hxx b/desktop/inc/lib/init.hxx
index 2b21f6a6d30a..6abf4bebd852 100644
--- a/desktop/inc/lib/init.hxx
+++ b/desktop/inc/lib/init.hxx
@@ -13,6 +13,7 @@
#include <unordered_map>
#include <memory>
#include <mutex>
+#include <set>
#include <string_view>
#include <boost/property_tree/ptree.hpp>
@@ -241,6 +242,7 @@ namespace desktop {
std::shared_ptr< LibreOfficeKitDocumentClass > m_pDocumentClass;
std::map<size_t, std::shared_ptr<CallbackFlushHandler>> mpCallbackFlushHandlers;
const int mnDocumentId;
+ std::set<OUString> maFontsMissing;
explicit LibLODocument_Impl(css::uno::Reference<css::lang::XComponent> xComponent,
int nDocumentId);
diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index 54b72d7ef88f..a987ad548d64 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -2584,6 +2584,8 @@ static LibreOfficeKitDocument* lo_documentLoadWithOptions(LibreOfficeKit* pThis,
aFilterOptions[3].Value <<= nUpdateDoc;
*/
+ OutputDevice::StartTrackingFontMappingUse();
+
const int nThisDocumentId = nDocumentIdCounter++;
SfxViewShell::SetCurrentDocId(ViewShellDocId(nThisDocumentId));
uno::Reference<lang::XComponent> xComponent = xComponentLoader->loadComponentFromURL(
@@ -2607,6 +2609,49 @@ static LibreOfficeKitDocument* lo_documentLoadWithOptions(LibreOfficeKit* pThis,
int nState = doc_getSignatureState(pDocument);
pLib->mpCallback(LOK_CALLBACK_SIGNATURE_STATUS, OString::number(nState).getStr(), pLib->mpCallbackData);
}
+
+ auto aFontMappingUseData = OutputDevice::FinishTrackingFontMappingUse();
+
+ // Filter out font substitutions that actually aren't any substitutions, like "Liberation
+ // Serif" -> "Liberation Serif/Regular". If even one of the "substitutions" of a font is to
+ // the same font, don't count that as a missing font.
+
+ for (std::size_t i = 0; i < aFontMappingUseData.size();)
+ {
+ // If the original font had an empty style and one of its replacement fonts has the same
+ // family name, we assume the font is present. The root problem here is that the code
+ // that collects font substitutions tends to get just empty styles for the font that is
+ // being substituded, as vcl::Font::GetStyleName() tents to return an empty string.
+ // (Italicness is instead indicated by what vcl::Font::GetItalic() returns and boldness
+ // by what vcl::Font::GetWeight() returns.)
+ if (aFontMappingUseData[i].mOriginalFont.indexOf('/') == -1)
+ {
+ bool bSubstitutedByTheSame = false;
+ for (const auto &j : aFontMappingUseData[i].mUsedFonts)
+ {
+ if (j.startsWith(OUStringConcatenation(aFontMappingUseData[i].mOriginalFont + "/")))
+ {
+ bSubstitutedByTheSame = true;
+ break;
+ }
+ }
+
+ if (bSubstitutedByTheSame)
+ aFontMappingUseData.erase(aFontMappingUseData.begin() + i);
+ else
+ i++;
+ }
+ else
+ {
+ i++;
+ }
+ }
+
+ for (std::size_t i = 0; i < aFontMappingUseData.size(); ++i)
+ {
+ pDocument->maFontsMissing.insert(aFontMappingUseData[i].mOriginalFont);
+ }
+
return pDocument;
}
catch (const uno::Exception& exception)
@@ -3801,6 +3846,21 @@ static void doc_registerCallback(LibreOfficeKitDocument* pThis,
pDocument->mpCallbackFlushHandlers[nView]->setViewId(pViewShell->GetViewShellId().get());
pViewShell->setLibreOfficeKitViewCallback(pDocument->mpCallbackFlushHandlers[nView].get());
}
+
+ if (pDocument->maFontsMissing.size() != 0)
+ {
+ std::string sPayload = "{ \"fontsmissing\": [ ";
+ bool bFirst = true;
+ for (const auto &f : pDocument->maFontsMissing)
+ {
+ if (!bFirst)
+ sPayload += ", ";
+ sPayload += "\"" + std::string(f.toUtf8().getStr()) + "\"";
+ }
+ sPayload += " ] }";
+ pCallback(LOK_CALLBACK_FONTS_MISSING, sPayload.c_str(), pData);
+ pDocument->maFontsMissing.clear();
+ }
}
else
{
diff --git a/include/LibreOfficeKit/LibreOfficeKitEnums.h b/include/LibreOfficeKit/LibreOfficeKitEnums.h
index f1b2328510b3..9a591413f2dd 100644
--- a/include/LibreOfficeKit/LibreOfficeKitEnums.h
+++ b/include/LibreOfficeKit/LibreOfficeKitEnums.h
@@ -860,6 +860,27 @@ typedef enum
* [<startColumn>, <startRow>, <endColumn>, <endRow>]
*/
LOK_CALLBACK_PRINT_RANGES = 56,
+
+ /**
+ * Informs the LibreOfficeKit client that a font specified in the
+ * document is missing.
+ *
+ * This callback is emitted right after the document has been loaded.
+ *
+ * Payload example:
+ * {
+ * "fontsmissing": [
+ * "Some Random Font",
+ * "Another Font"
+ * ]
+ * }
+ *
+ * The names are those of the font family. Sadly it is currently
+ * not possible to know the name of the font style that is
+ * missing.
+ *
+ */
+ LOK_CALLBACK_FONTS_MISSING = 57,
}
LibreOfficeKitCallbackType;
@@ -1002,6 +1023,8 @@ static inline const char* lokCallbackTypeToString(int nType)
return "LOK_CALLBACK_CONTENT_CONTROL";
case LOK_CALLBACK_PRINT_RANGES:
return "LOK_CALLBACK_PRINT_RANGES";
+ case LOK_CALLBACK_FONTS_MISSING:
+ return "LOK_CALLBACK_FONTS_MISSING";
}
assert(!"Unknown LibreOfficeKitCallbackType type.");
diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx
index a092a1dbf1ab..4c5dbdd9f595 100644
--- a/libreofficekit/source/gtk/lokdocview.cxx
+++ b/libreofficekit/source/gtk/lokdocview.cxx
@@ -1464,6 +1464,7 @@ callback (gpointer pData)
case LOK_COMMAND_BLOCKED:
case LOK_CALLBACK_SC_FOLLOW_JUMP:
case LOK_CALLBACK_PRINT_RANGES:
+ case LOK_CALLBACK_FONTS_MISSING:
{
// TODO: Implement me
break;