Resolves: #i96826# request font installation on render failure
Use packagekit interface to request font installation when glyph fallback fails Change-Id: Idb6f5cb6971bd156d7cac0a79e240246e9e0f973
This commit is contained in:
parent
4b5aa7a0be
commit
92efdaf94b
4 changed files with 128 additions and 8 deletions
|
@ -57,7 +57,7 @@ public:
|
|||
*/
|
||||
explicit LanguageTag( const rtl::OUString& rLanguage, const rtl::OUString& rCountry );
|
||||
|
||||
explicit LanguageTag( const LanguageTag & rLanguageTag );
|
||||
LanguageTag( const LanguageTag & rLanguageTag );
|
||||
~LanguageTag();
|
||||
LanguageTag& operator=( const LanguageTag & rLanguageTag );
|
||||
|
||||
|
|
|
@ -519,6 +519,7 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\
|
|||
) \
|
||||
))
|
||||
$(eval $(call gb_Library_use_externals,vcl,\
|
||||
dbus \
|
||||
fontconfig \
|
||||
freetype \
|
||||
))
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -353,6 +353,8 @@ class VCL_PLUGIN_PUBLIC PrintFontManager
|
|||
|
||||
bool readOverrideMetrics();
|
||||
|
||||
std::set<OString> m_aPreviousLangSupportRequests;
|
||||
|
||||
PrintFontManager();
|
||||
~PrintFontManager();
|
||||
public:
|
||||
|
|
Loading…
Reference in a new issue