1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #ifndef INCLUDED_VCL_INC_FONTMANAGER_HXX
21 #define INCLUDED_VCL_INC_FONTMANAGER_HXX
23 #include <config_options.h>
24 #include <tools/fontenum.hxx>
25 #include <vcl/dllapi.h>
26 #include <vcl/glyphitem.hxx>
27 #include <vcl/timer.hxx>
28 #include <com/sun/star/lang/Locale.hpp>
29 #include <unx/fc_fontoptions.hxx>
34 #include <string_view>
36 #include <unordered_map>
39 * some words on metrics: every length returned by PrintFontManager and
40 * friends are PostScript afm style, that is they are 1/1000 font height
45 class FontConfigFontOptions
;
46 class FontSelectPattern
;
47 class GenericUnixSalData
;
55 * the difference between FastPrintFontInfo and PrintFontInfo
56 * is that the information in FastPrintFontInfo can usually
57 * be gathered without opening either the font file, they are
58 * gathered from fonts.dir alone.
59 * if only FastPrintFontInfo is gathered and PrintFontInfo
60 * on demand and for less fonts, then performance in startup
61 * increases considerably
64 struct FastPrintFontInfo
66 fontID m_nID
; // FontID
69 OUString m_aFamilyName
;
70 OUString m_aStyleName
;
71 std::vector
< OUString
> m_aAliases
;
72 FontFamily m_eFamilyStyle
;
77 rtl_TextEncoding m_aEncoding
;
81 , m_eFamilyStyle(FAMILY_DONTKNOW
)
82 , m_eItalic(ITALIC_DONTKNOW
)
83 , m_eWidth(WIDTH_DONTKNOW
)
84 , m_eWeight(WEIGHT_DONTKNOW
)
85 , m_ePitch(PITCH_DONTKNOW
)
86 , m_aEncoding(RTL_TEXTENCODING_DONTKNOW
)
90 struct PrintFontInfo
: public FastPrintFontInfo
102 // a class to manage printable fonts
104 class VCL_PLUGIN_PUBLIC PrintFontManager
107 friend struct PrintFont
;
109 struct VCL_DLLPRIVATE PrintFont
112 OUString m_aFamilyName
;
113 std::vector
<OUString
> m_aAliases
;
115 OUString m_aStyleName
;
116 FontFamily m_eFamilyStyle
;
117 FontItalic m_eItalic
;
119 FontWeight m_eWeight
;
121 rtl_TextEncoding m_aEncoding
;
125 int m_nXMin
; // font bounding box
130 int m_nDirectory
; // atom containing system dependent path
131 OString m_aFontFile
; // relative to directory
132 int m_nCollectionEntry
; // 0 for regular fonts, 0 to ... for fonts stemming from collections
133 int m_nVariationEntry
; // 0 for regular fonts, 0 to ... for fonts stemming from font variations
135 explicit PrintFont();
138 fontID m_nNextFontID
;
139 std::unordered_map
< fontID
, PrintFont
> m_aFonts
;
140 // for speeding up findFontFileID
141 std::unordered_map
< OString
, std::set
< fontID
> >
144 std::unordered_map
< OString
, int >
146 std::unordered_map
< int, OString
> m_aAtomToDir
;
149 OString
getFontFile(const PrintFont
& rFont
) const;
151 std::vector
<PrintFont
> analyzeFontFile(int nDirID
, const OString
& rFileName
, const char *pFormat
=nullptr) const;
152 static OUString
convertSfntName( void* pNameRecord
); // actually a NameRecord* format font subsetting code
153 static void analyzeSfntFamilyName( void const * pTTFont
, std::vector
< OUString
>& rnames
); // actually a TrueTypeFont* from font subsetting code
154 bool analyzeSfntFile(PrintFont
& rFont
) const;
155 // finds the font id for the nFaceIndex face in this font file
156 // There may be multiple font ids for font collections
157 fontID
findFontFileID(int nDirID
, const OString
& rFile
, int nFaceIndex
, int nVariationIndex
) const;
159 // There may be multiple font ids for font collections
160 std::vector
<fontID
> findFontFileIDs( int nDirID
, const OString
& rFile
) const;
162 static FontFamily
matchFamilyName( std::u16string_view rFamily
);
164 const PrintFont
* getFont( fontID nID
) const
166 auto it
= m_aFonts
.find( nID
);
167 return it
== m_aFonts
.end() ? nullptr : &it
->second
;
169 PrintFont
* getFont( fontID nID
)
171 auto it
= m_aFonts
.find( nID
);
172 return it
== m_aFonts
.end() ? nullptr : &it
->second
;
174 static void fillPrintFontInfo(const PrintFont
& rFont
, FastPrintFontInfo
& rInfo
);
175 void fillPrintFontInfo( PrintFont
& rFont
, PrintFontInfo
& rInfo
) const;
177 OString
getDirectory( int nAtom
) const;
178 int getDirectoryAtom( const OString
& rDirectory
);
180 /* try to initialize fonts from libfontconfig
182 called from <code>initialize()</code>
184 static void initFontconfig();
185 void countFontconfigFonts( std::unordered_map
<OString
, int>& o_rVisitedPaths
);
186 /* deinitialize fontconfig
188 static void deinitFontconfig();
190 /* register an application specific font directory for libfontconfig
192 since fontconfig is asked for font substitutes before OOo will check for font availability
193 and fontconfig will happily substitute fonts it doesn't know (e.g. "Arial Narrow" -> "DejaVu Sans Book"!)
194 it becomes necessary to tell the library about all the hidden font treasures
196 static void addFontconfigDir(const OString
& rDirectory
);
198 std::set
<OString
> m_aPreviousLangSupportRequests
;
199 std::vector
<OUString
> m_aCurrentRequests
;
200 Timer m_aFontInstallerTimer
;
202 DECL_LINK( autoInstallFontLangSupport
, Timer
*, void );
206 friend class ::GenericUnixSalData
;
207 static PrintFontManager
& get(); // one instance only
209 // There may be multiple font ids for font collections
210 std::vector
<fontID
> addFontFile( const OUString
& rFileUrl
);
214 // returns the ids of all managed fonts.
215 void getFontList( std::vector
< fontID
>& rFontIDs
);
217 // get font info for a specific font
218 bool getFontInfo( fontID nFontID
, PrintFontInfo
& rInfo
) const;
219 // get fast font info for a specific font
220 bool getFontFastInfo( fontID nFontID
, FastPrintFontInfo
& rInfo
) const;
222 // routines to get font info in small pieces
224 // get a specific fonts PSName name
225 OUString
getPSName( fontID nFontID
);
227 // get a specific fonts italic type
228 FontItalic
getFontItalic( fontID nFontID
) const
230 const PrintFont
* pFont
= getFont( nFontID
);
231 return pFont
? pFont
->m_eItalic
: ITALIC_DONTKNOW
;
234 // get a specific fonts weight type
235 FontWeight
getFontWeight( fontID nFontID
) const
237 const PrintFont
* pFont
= getFont( nFontID
);
238 return pFont
? pFont
->m_eWeight
: WEIGHT_DONTKNOW
;
241 // get a specific fonts system dependent filename
242 OString
getFontFileSysPath( fontID nFontID
) const
244 return getFontFile( *getFont( nFontID
) );
247 // get the ttc face number
248 int getFontFaceNumber( fontID nFontID
) const;
250 // get the ttc face variation
251 int getFontFaceVariation( fontID nFontID
) const;
253 // get a specific fonts ascend
254 int getFontAscend( fontID nFontID
);
256 // get a specific fonts descent
257 int getFontDescend( fontID nFontID
);
259 // get a fonts glyph bounding box
260 void getFontBoundingBox( fontID nFont
, int& xMin
, int& yMin
, int& xMax
, int& yMax
);
262 // creates a new font subset of an existing SFNT font
263 // returns true in case of success, else false
264 // nFont: the font to be subsetted
265 // rOutFile: the file to put the new subset into;
266 // must be a valid osl file URL
267 // pGlyphIDs: input array of glyph ids for new font
268 // pNewEncoding: the corresponding encoding in the new font
269 // pWidths: output array of widths of requested glyphs
270 // nGlyphs: number of glyphs in arrays
271 // pCapHeight:: capital height of the produced font
272 // pXMin, pYMin, pXMax, pYMax: outgoing font bounding box
273 // TODO: callers of this method should use its FontSubsetInfo counterpart directly
274 bool createFontSubset( FontSubsetInfo
&,
276 const OUString
& rOutFile
,
277 const sal_GlyphId
* pGlyphIDs
,
278 const sal_uInt8
* pNewEncoding
,
282 void getGlyphWidths( fontID nFont
,
284 std::vector
< sal_Int32
>& rWidths
,
285 std::map
< sal_Unicode
, sal_uInt32
>& rUnicodeEnc
);
287 // font administration functions
289 /* system dependent font matching
292 <code>matchFont</code> matches a pattern of font characteristics
293 and returns the closest match if possible. If a match was found
294 the <code>FastPrintFontInfo</code> passed in as parameter
295 will be update to the found matching font.
298 implementation note: currently the function is only implemented
303 out of the FastPrintFontInfo structure the following
304 fields will be used for the match:
314 if <code>rLocal</code> contains non empty strings the corresponding
315 locale will be used for font matching also; e.g. "Sans" can result
316 in different fonts in e.g. english and japanese
318 void matchFont( FastPrintFontInfo
& rInfo
, const css::lang::Locale
& rLocale
);
320 static std::unique_ptr
<FontConfigFontOptions
> getFontOptions(const FontAttributes
& rFontAttributes
, int nSize
);
322 void Substitute(FontSelectPattern
&rPattern
, OUString
& rMissingCodes
);
328 #endif // INCLUDED_VCL_INC_FONTMANAGER_HXX
330 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */