summaryrefslogtreecommitdiff
path: root/vcl
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2012-09-03 13:17:09 +0100
committerCaolán McNamara <caolanm@redhat.com>2012-09-03 17:01:38 +0100
commit92efdaf94bc9aa463ed7c73526fbb55ec51e9ff5 (patch)
tree1fb90acc6ece98620d699e7f186f9064d25cd4de /vcl
parent4b5aa7a0bef61c9f81d2f87a7cef744d27e02309 (diff)
Resolves: #i96826# request font installation on render failure
Use packagekit interface to request font installation when glyph fallback fails Change-Id: Idb6f5cb6971bd156d7cac0a79e240246e9e0f973
Diffstat (limited to 'vcl')
-rw-r--r--vcl/Library_vcl.mk1
-rw-r--r--vcl/generic/fontmanager/fontconfig.cxx131
-rw-r--r--vcl/inc/vcl/fontmanager.hxx2
3 files changed, 127 insertions, 7 deletions
diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk
index d45ee98b7a47..5a1dc36eca2e 100644
--- a/vcl/Library_vcl.mk
+++ b/vcl/Library_vcl.mk
@@ -519,6 +519,7 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\
) \
))
$(eval $(call gb_Library_use_externals,vcl,\
+ dbus \
fontconfig \
freetype \
))
diff --git a/vcl/generic/fontmanager/fontconfig.cxx b/vcl/generic/fontmanager/fontconfig.cxx
index a90ecaf699e3..57a17c94f335 100644
--- a/vcl/generic/fontmanager/fontconfig.cxx
+++ b/vcl/generic/fontmanager/fontconfig.cxx
@@ -29,10 +29,17 @@
#include "fontcache.hxx"
#include "impfont.hxx"
-#include "vcl/fontmanager.hxx"
-#include "vcl/vclenum.hxx"
+#include <vcl/fontmanager.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/sysdata.hxx>
+#include <vcl/vclenum.hxx>
+#include <vcl/wrkwin.hxx>
#include "outfont.hxx"
#include <i18npool/languagetag.hxx>
+#include <i18nutil/unicode.hxx>
+#include <rtl/strbuf.hxx>
+#include <unicode/uchar.h>
+#include <unicode/uscript.h>
using namespace psp;
@@ -75,6 +82,10 @@ using namespace psp;
#define FC_FONTFORMAT "fontformat"
#endif
+#ifdef ENABLE_DBUS
+#include <dbus/dbus-glib.h>
+#endif
+
#include <cstdio>
#include <cstdarg>
@@ -797,15 +808,89 @@ namespace
OString sLang = OUStringToOString(rLangTag.getLanguage(), RTL_TEXTENCODING_UTF8).toAsciiLowerCase();
OString sRegion = OUStringToOString(rLangTag.getCountry(), RTL_TEXTENCODING_UTF8).toAsciiLowerCase();
- sLangAttrib = sLang + OString('-') + sRegion;
- if (FcStrSetMember(pLangSet, (const FcChar8*)sLangAttrib.getStr()))
- return sLangAttrib;
+ if (!sRegion.isEmpty())
+ {
+ sLangAttrib = sLang + OString('-') + sRegion;
+ if (FcStrSetMember(pLangSet, (const FcChar8*)sLangAttrib.getStr()))
+ return sLangAttrib;
+ }
if (FcStrSetMember(pLangSet, (const FcChar8*)sLang.getStr()))
- return sLangAttrib;
+ return sLang;
return OString();
}
+
+#ifdef ENABLE_DBUS
+ LanguageTag getExemplerLangTagForCodePoint(sal_uInt32 currentChar)
+ {
+ int32_t script = u_getIntPropertyValue(currentChar, UCHAR_SCRIPT);
+ UScriptCode eScript = static_cast<UScriptCode>(script);
+ OStringBuffer aBuf(unicode::getExemplerLanguageForUScriptCode(eScript));
+ const char* pScriptCode = uscript_getShortName(eScript);
+ if (pScriptCode)
+ aBuf.append('-').append(pScriptCode);
+ return LanguageTag(OStringToOUString(aBuf.makeStringAndClear(), RTL_TEXTENCODING_UTF8));
+ }
+
+ int autoInstallFontLangSupport(const std::vector<OString> &rNewReqs, guint xid)
+ {
+ GError *error = NULL;
+ /* get the DBUS session connection */
+ DBusGConnection *session_connection = dbus_g_bus_get(DBUS_BUS_SESSION, &error);
+ if (error != NULL)
+ {
+ g_warning ("DBUS cannot connect : %s", error->message);
+ g_error_free (error);
+ return -1;
+ }
+
+ /* get the proxy with gnome-session-manager */
+ DBusGProxy *proxy = dbus_g_proxy_new_for_name(session_connection,
+ "org.freedesktop.PackageKit",
+ "/org/freedesktop/PackageKit",
+ "org.freedesktop.PackageKit.Modify");
+ if (proxy == NULL)
+ {
+ g_warning("Could not get DBUS proxy: org.freedesktop.PackageKit");
+ return -1;
+ }
+
+ gchar **fonts = (gchar**)g_malloc((rNewReqs.size() + 1) * sizeof(gchar*));
+ gchar **font = fonts;
+ for (std::vector<OString>::const_iterator aI = rNewReqs.begin(); aI != rNewReqs.end(); ++aI)
+ *font++ = (gchar*)aI->getStr();
+ *font = NULL;
+ gboolean res = dbus_g_proxy_call(proxy, "InstallFontconfigResources", &error,
+ G_TYPE_UINT, xid, /* xid */
+ G_TYPE_STRV, fonts, /* data */
+ G_TYPE_STRING, "hide-finished", /* interaction */
+ G_TYPE_INVALID,
+ G_TYPE_INVALID);
+ /* check the return value */
+ if (!res)
+ g_warning("InstallFontconfigResources method failed");
+
+ /* check the error value */
+ if (error != NULL)
+ {
+ g_warning("InstallFontconfigResources problem : %s", error->message);
+ g_error_free(error);
+ }
+
+ g_free(fonts);
+ g_object_unref(G_OBJECT (proxy));
+
+ return 0;
+ }
+
+ guint get_xid_for_dbus()
+ {
+ const Window *pTopWindow = Application::IsHeadlessModeEnabled() ? NULL : Application::GetActiveTopWindow();
+ const SystemEnvData* pEnvData = pTopWindow ? pTopWindow->GetSystemData() : NULL;
+ return pEnvData ? pEnvData->aWindow : 0;
+ }
+#endif
}
bool PrintFontManager::Substitute( FontSelectPattern &rPattern, rtl::OUString& rMissingCodes )
@@ -950,7 +1035,39 @@ bool PrintFontManager::Substitute( FontSelectPattern &rPattern, rtl::OUString& r
pRemainingCodes[ nRemainingLen++ ] = nCode;
}
}
- rMissingCodes = OUString( pRemainingCodes, nRemainingLen );
+ OUString sStillMissing(pRemainingCodes, nRemainingLen);
+#ifdef ENABLE_DBUS
+ guint xid = get_xid_for_dbus();
+ if (xid)
+ {
+ std::vector<OString> aNewRequests;
+ if (sStillMissing == rMissingCodes) //replaced nothing
+ {
+ //It'd be better if we could ask packagekit using the
+ //missing codepoints or some such rather than using
+ //"language" as a proxy to how fontconfig considers
+ //scripts to default to a given language.
+ for (sal_Int32 i = 0; i < nRemainingLen; ++i)
+ {
+ LanguageTag aOurTag = getExemplerLangTagForCodePoint(pRemainingCodes[i]);
+ OString sTag = OUStringToOString(aOurTag.getBcp47(), RTL_TEXTENCODING_UTF8);
+ if (m_aPreviousLangSupportRequests.find(sTag) != m_aPreviousLangSupportRequests.end())
+ continue;
+ m_aPreviousLangSupportRequests.insert(sTag);
+ sTag = mapToFontConfigLangTag(aOurTag);
+ if (!sTag.isEmpty() && m_aPreviousLangSupportRequests.find(sTag) == m_aPreviousLangSupportRequests.end())
+ {
+ OString sReq = OString(":lang=") + sTag;
+ aNewRequests.push_back(sReq);
+ m_aPreviousLangSupportRequests.insert(sTag);
+ }
+ }
+ }
+ if (!aNewRequests.empty())
+ autoInstallFontLangSupport(aNewRequests, xid);
+ }
+#endif
+ rMissingCodes = sStillMissing;
}
}
diff --git a/vcl/inc/vcl/fontmanager.hxx b/vcl/inc/vcl/fontmanager.hxx
index 3bdfa484e514..4bd7a4d42264 100644
--- a/vcl/inc/vcl/fontmanager.hxx
+++ b/vcl/inc/vcl/fontmanager.hxx
@@ -353,6 +353,8 @@ class VCL_PLUGIN_PUBLIC PrintFontManager
bool readOverrideMetrics();
+ std::set<OString> m_aPreviousLangSupportRequests;
+
PrintFontManager();
~PrintFontManager();
public: