desktop/source/lib/init.cxx | 12 +++ include/vcl/unx/freetypemanager.hxx | 98 +++++++++++++++++++++++++ vcl/inc/unx/glyphcache.hxx | 62 --------------- vcl/unx/generic/glyphs/freetype_glyphcache.cxx | 5 + vcl/unx/generic/glyphs/glyphcache.cxx | 5 + 5 files changed, 120 insertions(+), 62 deletions(-)
New commits: commit ba00d997ddd6867c3f2bd4909625a91bf4db590b Author: Tor Lillqvist <[email protected]> AuthorDate: Wed Jul 20 16:31:28 2022 +0300 Commit: Tor Lillqvist <[email protected]> CommitDate: Thu Jul 21 11:43:16 2022 +0200 mmap a "downloaded" font in Collabora Online already in the ForKit process Instead of waiting until it gets used in a Kit process. Change-Id: I8671fd637837d66002bd5645734e4fee2f07d864 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/137266 Tested-by: Jenkins CollaboraOffice <[email protected]> Reviewed-by: Tor Lillqvist <[email protected]> diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx index 07276ebd1eea..5e9d48b75925 100644 --- a/desktop/source/lib/init.cxx +++ b/desktop/source/lib/init.cxx @@ -42,6 +42,9 @@ #include <sal/log.hxx> #include <vcl/errinf.hxx> #include <vcl/lok.hxx> +#ifdef LINUX +#include <vcl/unx/freetypemanager.hxx> +#endif #include <o3tl/any.hxx> #include <o3tl/unit_conversion.hxx> #include <osl/file.hxx> @@ -4149,13 +4152,22 @@ static void lo_setOption(LibreOfficeKit* /*pThis*/, const char *pOption, const c else sal_detail_set_log_selector(pCurrentSalLogOverride); } +#ifdef LINUX else if (strcmp(pOption, "addfont") == 0) { + SAL_INFO("vcl.unx.freetype", "Loading and mapping the font '" << pValue << "'"); OutputDevice *pDevice = Application::GetDefaultDevice(); OutputDevice::ImplClearAllFontData(false); pDevice->AddTempDevFont(OUString::fromUtf8(pValue), ""); OutputDevice::ImplRefreshAllFontData(false); + FreetypeManager &rFTManager = FreetypeManager::get(); + OUString sFontFileName; + osl::FileBase::getSystemPathFromFileURL( OUString::fromUtf8(pValue), sFontFileName ); + FreetypeFontFile *pFTFile = rFTManager.FindFontFile(OUStringToOString(sFontFileName, RTL_TEXTENCODING_UTF8)); + FreetypeManager::MapFontFile(pFTFile); + // Intentionally leak that FreetypeFontFile object } +#endif } static void doc_postUnoCommand(LibreOfficeKitDocument* pThis, const char* pCommand, const char* pArguments, bool bNotifyWhenFinished) diff --git a/include/vcl/unx/freetypemanager.hxx b/include/vcl/unx/freetypemanager.hxx new file mode 100644 index 000000000000..2298ddb1f70c --- /dev/null +++ b/include/vcl/unx/freetypemanager.hxx @@ -0,0 +1,98 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#pragma once + +#include <sal/config.h> + +class FontAttributes; +class FreetypeFont; +class FreetypeFontFile; +class FreetypeFontInfo; +class FreetypeFontInstance; + +namespace vcl +{ +namespace font +{ +class PhysicalFontCollection; +} +} + +/** + * The FreetypeManager caches various aspects of Freetype fonts + * + * It mainly consists of two std::unordered_map lists, which hold the items of the cache. + * + * They form kind of a tree, with FreetypeFontFile as the roots, referenced by multiple FreetypeFontInfo + * entries, which are referenced by the FreetypeFont items. + * + * All of these items have reference counters, but these don't control the items life-cycle, but that of + * the managed resources. + * + * The respective resources are: + * FreetypeFontFile = holds the mmapped font file, as long as it's used by any FreetypeFontInfo. + * FreetypeFontInfo = holds the FT_FaceRec_ object, as long as it's used by any FreetypeFont. + * FreetypeFont = holds the FT_SizeRec_ and is owned by a FreetypeFontInstance + * + * FreetypeFontInfo therefore is embedded in the Freetype subclass of PhysicalFontFace. + * FreetypeFont is owned by FreetypeFontInstance, the Freetype subclass of LogicalFontInstance. + * + * Nowadays there is not really a reason to have separate files for the classes, as the FreetypeManager + * is just about handling of Freetype based fonts, not some abstract glyphs. + **/ +class VCL_DLLPUBLIC FreetypeManager final +{ +public: + ~FreetypeManager(); + + static FreetypeManager& get(); + + void AddFontFile(const OString& rNormalizedName, int nFaceNum, int nVariantNum, + sal_IntPtr nFontId, const FontAttributes&); + + void AnnounceFonts(vcl::font::PhysicalFontCollection*) const; + + void ClearFontCache(); + + FreetypeFont* CreateFont(FreetypeFontInstance* pLogicalFont); + + FreetypeFontFile* FindFontFile(const OString& rNativeFileName); + + static void MapFontFile(FreetypeFontFile* pFontFile); + +private: + // to access the constructor (can't use InitFreetypeManager function, because it's private?!) + friend class GenericUnixSalData; + explicit FreetypeManager(); + + static void InitFreetype(); + + typedef std::unordered_map<sal_IntPtr, std::shared_ptr<FreetypeFontInfo>> FontInfoList; + typedef std::unordered_map<const char*, std::unique_ptr<FreetypeFontFile>, rtl::CStringHash, + rtl::CStringEqual> + FontFileList; + + FontInfoList m_aFontInfoList; + sal_IntPtr m_nMaxFontId; + + FontFileList m_aFontFileList; +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/inc/unx/glyphcache.hxx b/vcl/inc/unx/glyphcache.hxx index b6120e2899ee..a142c7f2b719 100644 --- a/vcl/inc/unx/glyphcache.hxx +++ b/vcl/inc/unx/glyphcache.hxx @@ -31,6 +31,7 @@ #include <unx/gendata.hxx> #include <vcl/dllapi.h> #include <vcl/outdev.hxx> +#include <vcl/unx/freetypemanager.hxx> #include <fontattributes.hxx> #include <fontinstance.hxx> @@ -38,8 +39,6 @@ #include <unordered_map> -class FreetypeFont; -class FreetypeFontFile; class FreetypeFontInstance; class FreetypeFontInfo; class FontConfigFontOptions; @@ -47,69 +46,10 @@ namespace vcl::font { class PhysicalFontCollection; } -class FreetypeFont; -class SvpGcpHelper; namespace basegfx { class B2DPolyPolygon; } namespace vcl { struct FontCapabilities; } - /** - * The FreetypeManager caches various aspects of Freetype fonts - * - * It mainly consists of two std::unordered_map lists, which hold the items of the cache. - * - * They form kind of a tree, with FreetypeFontFile as the roots, referenced by multiple FreetypeFontInfo - * entries, which are referenced by the FreetypeFont items. - * - * All of these items have reference counters, but these don't control the items life-cycle, but that of - * the managed resources. - * - * The respective resources are: - * FreetypeFontFile = holds the mmapped font file, as long as it's used by any FreetypeFontInfo. - * FreetypeFontInfo = holds the FT_FaceRec_ object, as long as it's used by any FreetypeFont. - * FreetypeFont = holds the FT_SizeRec_ and is owned by a FreetypeFontInstance - * - * FreetypeFontInfo therefore is embedded in the Freetype subclass of PhysicalFontFace. - * FreetypeFont is owned by FreetypeFontInstance, the Freetype subclass of LogicalFontInstance. - * - * Nowadays there is not really a reason to have separate files for the classes, as the FreetypeManager - * is just about handling of Freetype based fonts, not some abstract glyphs. - **/ -class VCL_DLLPUBLIC FreetypeManager final -{ -public: - ~FreetypeManager(); - - static FreetypeManager& get(); - - void AddFontFile(const OString& rNormalizedName, - int nFaceNum, int nVariantNum, - sal_IntPtr nFontId, - const FontAttributes&); - - void AnnounceFonts( vcl::font::PhysicalFontCollection* ) const; - - void ClearFontCache(); - - FreetypeFont* CreateFont(FreetypeFontInstance* pLogicalFont); - -private: - // to access the constructor (can't use InitFreetypeManager function, because it's private?!) - friend class GenericUnixSalData; - explicit FreetypeManager(); - - static void InitFreetype(); - FreetypeFontFile* FindFontFile(const OString& rNativeFileName); - - typedef std::unordered_map<sal_IntPtr, std::shared_ptr<FreetypeFontInfo>> FontInfoList; - typedef std::unordered_map<const char*, std::unique_ptr<FreetypeFontFile>, rtl::CStringHash, rtl::CStringEqual> FontFileList; - - FontInfoList m_aFontInfoList; - sal_IntPtr m_nMaxFontId; - - FontFileList m_aFontFileList; -}; - class VCL_DLLPUBLIC FreetypeFont final { public: diff --git a/vcl/unx/generic/glyphs/freetype_glyphcache.cxx b/vcl/unx/generic/glyphs/freetype_glyphcache.cxx index b19b6bb96446..a466316ae071 100644 --- a/vcl/unx/generic/glyphs/freetype_glyphcache.cxx +++ b/vcl/unx/generic/glyphs/freetype_glyphcache.cxx @@ -125,9 +125,11 @@ bool FreetypeFontFile::Map() SAL_WARN("vcl.unx.freetype", "mmap of '" << maNativeFileName << "' failed: " << strerror(errno)); mpFileMap = nullptr; } + SAL_INFO("vcl.unx.freetype", "Successful mmap of '" << maNativeFileName << "'"); close( nFile ); } - + else + SAL_INFO("vcl.unx.freetype", "Already mmapped: '" << maNativeFileName << "' (" << mnRefCount << ")"); return (mpFileMap != nullptr); } @@ -139,6 +141,7 @@ void FreetypeFontFile::Unmap() if (mpFileMap) { munmap(mpFileMap, mnFileSize); + SAL_INFO("vcl.unx.freetype", "Successful munmap of '" << maNativeFileName << "'"); mpFileMap = nullptr; } } diff --git a/vcl/unx/generic/glyphs/glyphcache.cxx b/vcl/unx/generic/glyphs/glyphcache.cxx index 79db2d87bdb0..3a86a5436244 100644 --- a/vcl/unx/generic/glyphs/glyphcache.cxx +++ b/vcl/unx/generic/glyphs/glyphcache.cxx @@ -66,6 +66,11 @@ FreetypeFontFile* FreetypeManager::FindFontFile(const OString& rNativeFileName) return pFontFile; } +void FreetypeManager::MapFontFile(FreetypeFontFile* pFontFile) +{ + pFontFile->Map(); +} + FreetypeFontInstance::FreetypeFontInstance(const vcl::font::PhysicalFontFace& rPFF, const vcl::font::FontSelectPattern& rFSP) : LogicalFontInstance(rPFF, rFSP) , mxFreetypeFont(FreetypeManager::get().CreateFont(this))
