Keep track of documents' embedded fonts, and unregister them on unload

First, not releasing the documents could degrade performance in some
long-running instances.

Also, this will help when we implement support for restricted embedded
fonts, which must not show in font lists, when the document was closed.

EmbeddedFontsHelper now keeps track of all the embedded fonts, using a
static map s_EmbeddedFonts; each font has a refcount, and unregistered
only when its refcount is zero. SfxMedium keeps track of its own fonts;
and in its dtor, it calls EmbeddedFontsHelper::releaseFonts.

Change-Id: I0afe971a785c4709cc54a3fab98953db96dbd05f
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/189320
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
Tested-by: Jenkins
This commit is contained in:
Mike Kaganski
2025-08-12 14:14:38 +02:00
parent 22dbeb3505
commit c77a53433d
28 changed files with 320 additions and 17 deletions
+4 -1
View File
@@ -31,12 +31,12 @@
#include <tools/link.hxx>
#include <tools/stream.hxx>
#include <com/sun/star/beans/StringPair.hpp>
#include <com/sun/star/uno/Sequence.hxx>
#include <mutex>
namespace com::sun::star::beans { struct PropertyValue; }
namespace com::sun::star::beans { struct StringPair; }
namespace com::sun::star::embed { class XStorage; }
namespace com::sun::star::graphic { class XGraphic; }
namespace com::sun::star::io { class XInputStream; }
@@ -105,6 +105,8 @@ public:
bool CheckCanGetLockfile() const;
void SetOriginallyReadOnly(bool val);
void AddEmbeddedFonts(const css::uno::Sequence<css::beans::StringPair>& fonts);
// Transfers the embedded font list to another medium (passing ownership)
void TransferEmbeddedFontsTo(SfxMedium& target);
void AddToCheckEditableWorkerList();
void SetWorkerReloadEvent(ImplSVEvent* pEvent);
ImplSVEvent* GetWorkerReloadEvent() const;
@@ -322,6 +324,7 @@ private:
bool bIsLoading, bool bOwnLock, bool bHandleSysLocked);
enum class MessageDlg { LockFileIgnore, LockFileCorrupt };
bool ShowLockFileProblemDialog(MessageDlg nWhichDlg);
void ReleaseEmbeddedFonts();
};
#endif
+2
View File
@@ -94,6 +94,8 @@ public:
*/
static bool isCommonFont(std::u16string_view aFontName);
static void releaseFonts(const std::vector<std::pair<OUString, OUString>>& fonts);
EmbeddedFontsHelper(const css::uno::Reference<css::frame::XModel>& xModel);
~EmbeddedFontsHelper() COVERITY_NOEXCEPT_FALSE;
};
+1
View File
@@ -1131,6 +1131,7 @@ public:
bool IsFontAvailable( std::u16string_view rFontName ) const;
bool AddTempDevFont( const OUString& rFileURL, const OUString& rFontName );
bool RemoveTempDevFont( const OUString& rFileURL, const OUString& rFontName );
void RefreshFontData( const bool bNewFontLists );
FontMetric GetFontMetric() const;
+29
View File
@@ -30,6 +30,7 @@
#include <com/sun/star/task/XStatusIndicator.hpp>
#include <com/sun/star/uno/Reference.h>
#include <com/sun/star/ucb/XContent.hpp>
#include <com/sun/star/beans/StringPair.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/container/XChild.hpp>
#include <com/sun/star/document/XDocumentRevisionListPersistence.hpp>
@@ -415,6 +416,7 @@ public:
bool m_bODFWholesomeEncryption = false;
/// font family, file URL
std::vector<std::pair<OUString, OUString>> m_aEmbeddedFonts;
std::vector<std::pair<OUString, OUString>> m_aEmbeddedFontsToActivate;
OUString m_aName;
@@ -3736,6 +3738,8 @@ SfxMedium::~SfxMedium()
Close(/*bInDestruction*/true);
ReleaseEmbeddedFonts();
if( !pImpl->bIsTemp || pImpl->m_aName.isEmpty() )
return;
@@ -3752,6 +3756,15 @@ SfxMedium::~SfxMedium()
}
}
void SfxMedium::ReleaseEmbeddedFonts()
{
std::vector<std::pair<OUString, OUString>> toRelease(std::move(pImpl->m_aEmbeddedFonts));
toRelease.insert(toRelease.end(), pImpl->m_aEmbeddedFontsToActivate.begin(),
pImpl->m_aEmbeddedFontsToActivate.end());
pImpl->m_aEmbeddedFontsToActivate.clear();
EmbeddedFontsHelper::releaseFonts(toRelease);
}
const OUString& SfxMedium::GetName() const
{
return pImpl->m_aLogicName;
@@ -4002,6 +4015,18 @@ bool SfxMedium::IsOriginallyLoadedReadOnly() const
return pImpl->m_bOriginallyLoadedReadOnly;
}
void SfxMedium::TransferEmbeddedFontsTo(SfxMedium& target)
{
target.pImpl->m_aEmbeddedFonts.insert(target.pImpl->m_aEmbeddedFonts.end(),
pImpl->m_aEmbeddedFonts.begin(),
pImpl->m_aEmbeddedFonts.end());
pImpl->m_aEmbeddedFonts.clear();
target.pImpl->m_aEmbeddedFontsToActivate.insert(target.pImpl->m_aEmbeddedFontsToActivate.end(),
pImpl->m_aEmbeddedFontsToActivate.begin(),
pImpl->m_aEmbeddedFontsToActivate.end());
pImpl->m_aEmbeddedFontsToActivate.clear();
}
void SfxMedium::AddEmbeddedFonts(
const css::uno::Sequence<css::beans::StringPair>& fonts)
{
@@ -4012,6 +4037,10 @@ void SfxMedium::AddEmbeddedFonts(
void SfxMedium::activateEmbeddedFonts()
{
EmbeddedFontsHelper::activateFonts(pImpl->m_aEmbeddedFontsToActivate);
pImpl->m_aEmbeddedFonts.insert(pImpl->m_aEmbeddedFonts.end(),
pImpl->m_aEmbeddedFontsToActivate.begin(),
pImpl->m_aEmbeddedFontsToActivate.end());
pImpl->m_aEmbeddedFontsToActivate.clear();
}
bool SfxMedium::SetWritableForUserOnly( const OUString& aURL )
+4
View File
@@ -2375,6 +2375,10 @@ bool SfxObjectShell::DoSaveCompleted( SfxMedium* pNewMed, bool bRegisterRecent )
SfxMedium* pOld = pMedium;
if ( bMedChanged )
{
if (pMedium)
{
pMedium->TransferEmbeddedFontsTo(*pNewMed);
}
pMedium = pNewMed;
pMedium->CanDisposeStorage_Impl( true );
}
+5
View File
@@ -59,6 +59,11 @@ bool SvpSalGraphics::AddTempDevFont( vcl::font::PhysicalFontCollection* pFontCol
return m_aTextRenderImpl.AddTempDevFont(pFontCollection, rFileURL, rFontName);
}
bool SvpSalGraphics::RemoveTempDevFont(const OUString& rFileURL, const OUString& rFontName)
{
return m_aTextRenderImpl.RemoveTempDevFont(rFileURL, rFontName);
}
std::unique_ptr<GenericSalLayout> SvpSalGraphics::GetTextLayout(int nFallbackLevel)
{
return m_aTextRenderImpl.GetTextLayout(nFallbackLevel);
+1
View File
@@ -72,6 +72,7 @@ public:
virtual void GetDevFontList( vcl::font::PhysicalFontCollection* ) override;
virtual void ClearDevFontCache() override;
virtual bool AddTempDevFont( vcl::font::PhysicalFontCollection*, const OUString& rFileURL, const OUString& rFontName ) override;
virtual bool RemoveTempDevFont( const OUString& rFileURL, const OUString& rFontName ) override;
virtual std::unique_ptr<GenericSalLayout>
GetTextLayout(int nFallbackLevel) override;
virtual void DrawTextLayout( const GenericSalLayout& ) override;
+1
View File
@@ -218,6 +218,7 @@ public:
virtual void ClearDevFontCache() override;
virtual bool AddTempDevFont(vcl::font::PhysicalFontCollection*, const OUString& rFileURL,
const OUString& rFontName) override;
virtual bool RemoveTempDevFont(const OUString& rFileURL, const OUString& rFontName) override;
virtual std::unique_ptr<GenericSalLayout> GetTextLayout(int nFallbackLevel) override;
virtual void DrawTextLayout(const GenericSalLayout&) override;
+1
View File
@@ -458,6 +458,7 @@ public:
// graphics must drop any cached font info
virtual void ClearDevFontCache() override;
virtual bool AddTempDevFont( vcl::font::PhysicalFontCollection*, const OUString& rFileURL, const OUString& rFontName ) override;
virtual bool RemoveTempDevFont( const OUString& rFileURL, const OUString& rFontName ) override;
virtual std::unique_ptr<GenericSalLayout>
GetTextLayout(int nFallbackLevel) override;
+4
View File
@@ -152,6 +152,10 @@ public:
const OUString& rFileURL,
const OUString& rFontName ) = 0;
// Returns true, when the font was unregistered, and its file can be safely deleted
virtual bool RemoveTempDevFont(const OUString& rFileURL,
const OUString& rFontName) = 0;
virtual std::unique_ptr<GenericSalLayout>
GetTextLayout(int nFallbackLevel) = 0;
virtual void DrawTextLayout( const GenericSalLayout& ) = 0;
+1
View File
@@ -38,6 +38,7 @@ public:
virtual void GetDevFontList( vcl::font::PhysicalFontCollection* ) = 0;
virtual void ClearDevFontCache() = 0;
virtual bool AddTempDevFont( vcl::font::PhysicalFontCollection*, const OUString& rFileURL, const OUString& rFontName ) = 0;
virtual bool RemoveTempDevFont( const OUString& rFileURL, const OUString& rFontName ) = 0;
virtual std::unique_ptr<GenericSalLayout>
GetTextLayout(int nFallbackLevel) = 0;
+8
View File
@@ -117,6 +117,9 @@ class VCL_PLUGIN_PUBLIC PrintFontManager
/* register an application specific font file for libfontconfig */
static void addFontconfigFile(const OString& rFile);
/* deregister an application specific font file from libfontconfig */
static void removeFontconfigFile(std::string_view aFile);
std::set<OString> m_aPreviousLangSupportRequests;
std::vector<OUString> m_aCurrentRequests;
Timer m_aFontInstallerTimer;
@@ -128,9 +131,14 @@ public:
friend class ::GenericUnixSalData;
static PrintFontManager& get(); // one instance only
// There may be multiple font ids for font collections
std::vector<fontID> findFontFileIDs( std::u16string_view rFileUrl ) const;
// There may be multiple font ids for font collections
std::vector<fontID> addFontFile( std::u16string_view rFileUrl );
void removeFontFile( std::u16string_view rFileUrl );
void initialize();
const PrintFont* getFont( fontID nID ) const
+1
View File
@@ -47,6 +47,7 @@ public:
virtual void GetDevFontList( vcl::font::PhysicalFontCollection* ) override;
virtual void ClearDevFontCache() override;
virtual bool AddTempDevFont( vcl::font::PhysicalFontCollection*, const OUString& rFileURL, const OUString& rFontName ) override;
virtual bool RemoveTempDevFont( const OUString& rFileURL, const OUString& rFontName ) override;
virtual std::unique_ptr<GenericSalLayout>
GetTextLayout(int nFallbackLevel) override;
+2
View File
@@ -67,6 +67,8 @@ public:
SAL_DLLPRIVATE virtual bool AddTempDevFont( vcl::font::PhysicalFontCollection*,
const OUString& rFileURL,
const OUString& rFontName ) override;
SAL_DLLPRIVATE virtual bool RemoveTempDevFont(const OUString& rFileURL,
const OUString& rFontName) override;
SAL_DLLPRIVATE virtual std::unique_ptr<GenericSalLayout>
GetTextLayout(int nFallbackLevel) override;
+1
View File
@@ -80,6 +80,7 @@ public:
int nFaceNum, int nVariantNum,
sal_IntPtr nFontId,
const FontAttributes&);
void RemoveFontFile(sal_IntPtr nFontId);
SAL_DLLPRIVATE void AnnounceFonts( vcl::font::PhysicalFontCollection* ) const;
+1
View File
@@ -92,6 +92,7 @@ public:
virtual void GetDevFontList( vcl::font::PhysicalFontCollection* ) override;
virtual void ClearDevFontCache() override;
virtual bool AddTempDevFont( vcl::font::PhysicalFontCollection*, const OUString& rFileURL, const OUString& rFontName ) override;
virtual bool RemoveTempDevFont( const OUString& rFileURL, const OUString& rFontName ) override;
virtual std::unique_ptr<GenericSalLayout>
GetTextLayout(int nFallbackLevel) override;
+1
View File
@@ -176,6 +176,7 @@ public:
// graphics must drop any cached font info
virtual void ClearDevFontCache() override;
virtual bool AddTempDevFont( vcl::font::PhysicalFontCollection*, const OUString& rFileURL, const OUString& rFontName ) override;
virtual bool RemoveTempDevFont(const OUString& rFileURL, const OUString& rFontName) override;
virtual std::unique_ptr<GenericSalLayout>
GetTextLayout(int nFallbackLevel) override;
+5
View File
@@ -135,6 +135,11 @@ bool QtGraphics::AddTempDevFont(vcl::font::PhysicalFontCollection*, const OUStri
return false;
}
bool QtGraphics::RemoveTempDevFont(const OUString& /*rFileURL*/, const OUString& /*rFontName*/)
{
return true; // No fonts registered - no problem to remove
}
namespace
{
class QtCommonSalLayout : public GenericSalLayout
+24
View File
@@ -243,6 +243,25 @@ static bool AddTempDevFont(const OUString& rFontFileURL)
return success;
}
static bool RemoveTempDevFont(const OUString& rFontFileURL)
{
OUString aUSystemPath;
OSL_VERIFY(!osl::FileBase::getSystemPathFromFileURL(rFontFileURL, aUSystemPath));
OString aCFileName = OUStringToOString(aUSystemPath, RTL_TEXTENCODING_UTF8);
CFStringRef rFontPath
= CFStringCreateWithCString(nullptr, aCFileName.getStr(), kCFStringEncodingUTF8);
CFURLRef rFontURL
= CFURLCreateWithFileSystemPath(nullptr, rFontPath, kCFURLPOSIXPathStyle, true);
CTFontManagerUnregisterFontsForURL(rFontURL, kCTFontManagerScopeProcess, nullptr);
CFRelease(rFontPath);
CFRelease(rFontURL);
return true; // Assume that even errors meant that there was nothing to remove
}
static void AddTempFontDir( const OUString &rFontDirUrl )
{
osl::Directory aFontDir( rFontDirUrl );
@@ -322,6 +341,11 @@ bool AquaSalGraphics::AddTempDevFont(vcl::font::PhysicalFontCollection*,
return ::AddTempDevFont(rFontFileURL);
}
bool AquaSalGraphics::RemoveTempDevFont(const OUString& rFontFileURL, const OUString& /*rFontName*/)
{
return ::RemoveTempDevFont(rFontFileURL);
}
void AquaSalGraphics::DrawTextLayout(const GenericSalLayout& rLayout)
{
mpBackend->drawTextLayout(rLayout);
+94 -16
View File
@@ -10,6 +10,8 @@
#include <sal/config.h>
#include <memory>
#include <mutex>
#include <unordered_map>
#include <frozen/bits/defines.h>
#include <frozen/bits/elsa_std.h>
#include <frozen/unordered_set.h>
@@ -62,6 +64,17 @@ const OUString& GetEmbeddedFontsRoot()
return path;
}
struct EmbeddedFontData
{
OUString familyName;
int refcount = 0;
bool isActivated = false;
};
std::mutex s_EmbeddedFontsMutex;
// file URL -> EmbeddedFontData
std::unordered_map<OUString, EmbeddedFontData> s_EmbeddedFonts;
void clearDir( const OUString& path )
{
osl::Directory dir( path );
@@ -97,13 +110,12 @@ OUString fileUrlForTemporaryFont(std::u16string_view name)
RTL_TEXTENCODING_UTF8);
}
// Returns true when the file was written, or exactly same data was existing.
// Returns actual URL (maybe of an already existing file), or empty string on failure.
//
// @param name name of the font file
// @param url returns URL of a new file, or empty string (when the same file already existed).
bool writeFontBytesToFile(const std::vector<char>& bytes, std::u16string_view name, OUString& url)
OUString writeFontBytesToFile(const std::vector<char>& bytes, std::u16string_view name)
{
url = fileUrlForTemporaryFont(name);
OUString url = fileUrlForTemporaryFont(name);
std::optional<osl::File> file(url);
auto rc = file->open(osl_File_OpenFlag_Create | osl_File_OpenFlag_Write);
@@ -126,8 +138,7 @@ bool writeFontBytesToFile(const std::vector<char>& bytes, std::u16string_view na
}
if (rc == osl::File::E_None && bytes2 == bytes)
{
url.clear();
return true; // OK, it's the same bytes
return url; // OK, it's the same bytes
}
}
}
@@ -137,7 +148,7 @@ bool writeFontBytesToFile(const std::vector<char>& bytes, std::u16string_view na
}
if (rc != osl::File::E_None)
return false;
return {};
sal_uInt64 writtenTotal = 0;
while (writtenTotal < bytes.size())
@@ -148,11 +159,11 @@ bool writeFontBytesToFile(const std::vector<char>& bytes, std::u16string_view na
{
file->close();
osl::File::remove(file->getURL());
return false;
return {};
}
writtenTotal += written;
}
return true;
return url;
}
}
@@ -185,7 +196,7 @@ EmbeddedFontsHelper::~EmbeddedFontsHelper() COVERITY_NOEXCEPT_FALSE
}
}
// Failed to transfer the read-only fonts to the document. Activate them here.
// Failed to transfer the fonts to the document. Activate them here.
activateFonts(m_aAccumulatedFonts);
}
@@ -282,11 +293,21 @@ bool EmbeddedFontsHelper::addEmbeddedFont( const uno::Reference< io::XInputStrea
}
}
OUString fileUrl;
if (!writeFontBytesToFile(fontData, Concat2View(fontName + extra), fileUrl))
OUString fileUrl = writeFontBytesToFile(fontData, Concat2View(fontName + extra));
if (fileUrl.isEmpty())
return false;
if (!fileUrl.isEmpty())
m_aAccumulatedFonts.emplace_back(std::make_pair(fontName, fileUrl));
// Register it, and increase its refcount in s_EmbeddedFonts
{
std::unique_lock lock(s_EmbeddedFontsMutex);
auto& rData = s_EmbeddedFonts[fileUrl];
assert(rData.familyName.isEmpty() || rData.familyName == fontName);
rData.familyName = fontName;
++rData.refcount;
}
m_aAccumulatedFonts.emplace_back(fontName, fileUrl);
return true;
}
@@ -310,11 +331,68 @@ void EmbeddedFontsHelper::activateFonts(std::vector<std::pair<OUString, OUString
{
if (fonts.empty())
return;
std::vector<std::pair<OUString, OUString>> temp;
{
std::unique_lock lock(s_EmbeddedFontsMutex);
// Only activate fonts that need activation.
for (const auto& pair : fonts)
{
auto it = s_EmbeddedFonts.find(pair.second);
assert(it != s_EmbeddedFonts.end());
if (!it->second.isActivated)
{
it->second.isActivated = true;
temp.push_back(pair);
}
}
}
if (temp.empty())
return;
UpdateFontsGuard aUpdateFontsGuard;
OutputDevice *pDevice = Application::GetDefaultDevice();
for (const auto& [ fontName, fileUrl ] : fonts)
for (const auto& [ fontName, fileUrl ] : temp)
pDevice->AddTempDevFont(fileUrl, fontName);
fonts.clear();
}
void EmbeddedFontsHelper::releaseFonts(const std::vector<std::pair<OUString, OUString>>& fonts)
{
std::vector<std::pair<OUString, OUString>> unregister;
{
std::unique_lock g(s_EmbeddedFontsMutex);
for (const auto& pair : fonts)
{
auto it = s_EmbeddedFonts.find(pair.second);
if (it == s_EmbeddedFonts.end())
{
SAL_WARN("vcl.fonts", "Trying to release a font that wasn't locked?");
continue;
}
assert(it->second.familyName == pair.first);
--it->second.refcount;
if (it->second.refcount == 0)
{
unregister.emplace_back(pair);
s_EmbeddedFonts.erase(it);
}
}
}
if (unregister.empty())
return;
OutputDevice* pDevice = Application::GetDefaultDevice();
for (const auto& [ family, url ] : unregister)
{
if (pDevice->RemoveTempDevFont(url, family))
osl::File::remove(url);
}
OutputDevice::ImplUpdateAllFontData(true);
}
// Check if it's (legally) allowed to embed the font file into a document
+9
View File
@@ -136,6 +136,15 @@ bool OutputDevice::AddTempDevFont( const OUString& rFileURL, const OUString& rFo
return true;
}
bool OutputDevice::RemoveTempDevFont(const OUString& rFileURL, const OUString& rFontName)
{
if( !mpGraphics && !AcquireGraphics() )
return true; // No graphics -> no fonts used
assert(mpGraphics);
return mpGraphics->RemoveTempDevFont(rFileURL, rFontName);
}
bool OutputDevice::GetFontFeatures(std::vector<vcl::font::Feature>& rFontFeatures) const
{
if (!ImplNewFont())
@@ -52,6 +52,7 @@
#include <osl/process.h>
#include <o3tl/hash_combine.hxx>
#include <set>
#include <utility>
#include <algorithm>
@@ -791,6 +792,39 @@ void PrintFontManager::addFontconfigFile( const OString& rFileName )
rWrapper.addFontSet( FcSetApplication );
}
void PrintFontManager::removeFontconfigFile(std::string_view aFileName)
{
FcFontSet* pOrig = FcConfigGetFonts(FcConfigGetCurrent(), FcSetApplication);
if (!pOrig)
return;
std::set<OString> restoreList;
// filter the font sets to remove the file
for (int i = 0; i < pOrig->nfont; ++i)
{
FcChar8* file = nullptr;
FcResult eFileRes = FcPatternGetString(pOrig->fonts[i], FC_FILE, 0, &file);
if (eFileRes == FcResultMatch)
{
if (std::string_view curFile(reinterpret_cast<char*>(file)); aFileName != curFile)
restoreList.emplace(curFile);
}
}
FcConfigAppFontClear(FcConfigGetCurrent());
// Re-add the rest of files
for (const OString& thisFilename : restoreList)
{
FcConfigAppFontAddFile(FcConfigGetCurrent(),
reinterpret_cast<FcChar8 const*>(thisFilename.getStr()));
}
FontCfgWrapper& rWrapper = FontCfgWrapper::get();
rWrapper.addFontSet( FcSetApplication );
}
static void addtopattern(FcPattern *pPattern,
FontItalic eItalic, FontWeight eWeight, FontWidth eWidth, FontPitch ePitch)
{
@@ -135,6 +135,21 @@ int PrintFontManager::getDirectoryAtom( const OString& rDirectory )
return nAtom;
}
std::vector<fontID> PrintFontManager::findFontFileIDs( std::u16string_view rFileUrl ) const
{
rtl_TextEncoding aEncoding = osl_getThreadTextEncoding();
INetURLObject aPath( rFileUrl );
OString aName(OUStringToOString(aPath.GetLastName(INetURLObject::DecodeMechanism::WithCharset, aEncoding), aEncoding));
OString aDir( OUStringToOString(
INetURLObject::decode( aPath.GetPath(), INetURLObject::DecodeMechanism::WithCharset, aEncoding ), aEncoding ) );
auto dirIt = m_aDirToAtom.find(aDir);
if (dirIt == m_aDirToAtom.end())
return {};
return findFontFileIDs(dirIt->second, aName);
}
std::vector<fontID> PrintFontManager::addFontFile( std::u16string_view rFileUrl )
{
rtl_TextEncoding aEncoding = osl_getThreadTextEncoding();
@@ -161,6 +176,25 @@ std::vector<fontID> PrintFontManager::addFontFile( std::u16string_view rFileUrl
return aFontIds;
}
void PrintFontManager::removeFontFile(std::u16string_view rFileUrl)
{
INetURLObject aPath(rFileUrl);
rtl_TextEncoding aEncoding = osl_getThreadTextEncoding();
if (auto ids = findFontFileIDs(rFileUrl); !ids.empty())
{
OString aName(OUStringToOString(
aPath.GetLastName(INetURLObject::DecodeMechanism::WithCharset, aEncoding), aEncoding));
for (auto nFontID : ids)
{
m_aFonts.erase(nFontID);
m_aFontFileToFontID[aName].erase(nFontID);
}
}
removeFontconfigFile(OUStringToOString(aPath.GetFull(), aEncoding));
}
std::vector<PrintFontManager::PrintFont> PrintFontManager::analyzeFontFile( int nDirID, const OString& rFontFile) const
{
std::vector<PrintFontManager::PrintFont> aNewFonts;
+5
View File
@@ -60,6 +60,11 @@ bool X11SalGraphics::AddTempDevFont( vcl::font::PhysicalFontCollection* pFontCol
return mxTextRenderImpl->AddTempDevFont(pFontCollection, rFileURL, rFontName);
}
bool X11SalGraphics::RemoveTempDevFont(const OUString& rFileURL, const OUString& rFontName)
{
return mxTextRenderImpl->RemoveTempDevFont(rFileURL, rFontName);
}
void X11SalGraphics::ClearDevFontCache()
{
mxTextRenderImpl->ClearDevFontCache();
@@ -128,6 +128,22 @@ bool FreeTypeTextRenderImpl::AddTempDevFont(vcl::font::PhysicalFontCollection* p
return true;
}
bool FreeTypeTextRenderImpl::RemoveTempDevFont(const OUString& rFileURL, const OUString& /*rFontName*/)
{
// inform PSP font manager
psp::PrintFontManager& rMgr = psp::PrintFontManager::get();
std::vector<psp::fontID> aFontIds = rMgr.findFontFileIDs(rFileURL);
if (aFontIds.empty())
return true; // Nothing to remove -> safe to delete the file
FreetypeManager& rFreetypeManager = FreetypeManager::get();
for (auto const& nFontId : aFontIds)
rFreetypeManager.RemoveFontFile(nFontId);
rMgr.removeFontFile(rFileURL);
return true;
}
void FreeTypeTextRenderImpl::ClearDevFontCache()
{
FreetypeManager::get().ClearFontCache();
@@ -277,6 +277,13 @@ void FreetypeManager::AddFontFile(const OString& rNormalizedName,
m_aFontInfoList[ nFontId ].reset(pFontInfo);
}
void FreetypeManager::RemoveFontFile(sal_IntPtr nFontId)
{
auto it = m_aFontInfoList.find(nFontId);
if (it != m_aFontInfoList.end())
m_aFontInfoList.erase(it);
}
void FreetypeManager::AnnounceFonts( vcl::font::PhysicalFontCollection* pToAdd ) const
{
for (auto const& font : m_aFontInfoList)
+5
View File
@@ -118,6 +118,11 @@ bool GenPspGraphics::AddTempDevFont( vcl::font::PhysicalFontCollection* pFontCol
return m_aTextRenderImpl.AddTempDevFont(pFontCollection, rFileURL, rFontName);
}
bool GenPspGraphics::RemoveTempDevFont(const OUString& rFileURL, const OUString& rFontName)
{
return m_aTextRenderImpl.RemoveTempDevFont(rFileURL, rFontName);
}
void GenPspGraphics::GetDevFontList( vcl::font::PhysicalFontCollection *pFontCollection )
{
m_aTextRenderImpl.GetDevFontList(pFontCollection);
+20
View File
@@ -972,6 +972,26 @@ bool WinSalGraphics::AddTempDevFont(vcl::font::PhysicalFontCollection* pFontColl
return true;
}
bool WinSalGraphics::RemoveTempDevFont(const OUString& rFileURL, const OUString& /*rFontName*/)
{
OUString path;
osl::FileBase::getSystemPathFromFileURL(rFileURL, path);
auto pSalData = GetSalData();
for (TempFontItem** pp = &pSalData->mpTempFontItem; *pp; pp = &(*pp)->mpNextItem)
{
if ((*pp)->maFontResourcePath == path)
{
RemoveFontResourceExW(o3tl::toW(path.getStr()), FR_PRIVATE, nullptr);
auto p = *pp;
*pp = p->mpNextItem;
delete p;
return true;
}
}
SAL_WARN("vcl.fonts", "Trying to unregister an embedded font that wasn't registered?");
return true; // It's still safe to delete the font file: we don't use it
}
void WinSalGraphics::GetDevFontList( vcl::font::PhysicalFontCollection* pFontCollection )
{
// make sure all LO shared fonts are registered temporarily