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 <vcl/dllapi.h>
24 #include <unx/helper.hxx>
25 #include <vcl/timer.hxx>
26 #include <vcl/vclenum.hxx>
27 #include <com/sun/star/lang/Locale.hpp>
28 #include <sallayout.hxx>
29 #include <unx/fc_fontoptions.hxx>
36 #include <unordered_map>
38 #include <config_gio.h>
41 * some words on metrics: every length returned by PrintFontManager and
42 * friends are PostScript afm style, that is they are 1/1000 font height
46 class FontConfigFontOptions
;
47 class FontSelectPattern
;
48 class GenericUnixSalData
;
56 * the difference between FastPrintFontInfo and PrintFontInfo
57 * is that the information in FastPrintFontInfo can usually
58 * be gathered without opening either the font file, they are
59 * gathered from fonts.dir alone.
60 * if only FastPrintFontInfo is gathered and PrintFontInfo
61 * on demand and for less fonts, then performance in startup
62 * increases considerably
65 struct FastPrintFontInfo
67 fontID m_nID
; // FontID
70 OUString m_aFamilyName
;
71 OUString m_aStyleName
;
72 std::vector
< OUString
> m_aAliases
;
73 FontFamily m_eFamilyStyle
;
78 rtl_TextEncoding m_aEncoding
;
82 , m_eFamilyStyle(FAMILY_DONTKNOW
)
83 , m_eItalic(ITALIC_DONTKNOW
)
84 , m_eWidth(WIDTH_DONTKNOW
)
85 , m_eWeight(WEIGHT_DONTKNOW
)
86 , m_ePitch(PITCH_DONTKNOW
)
87 , m_aEncoding(RTL_TEXTENCODING_DONTKNOW
)
91 struct PrintFontInfo
: public FastPrintFontInfo
103 // a class to manage printable fonts
105 class VCL_PLUGIN_PUBLIC PrintFontManager
108 friend struct PrintFont
;
113 OUString m_aFamilyName
;
114 std::vector
<OUString
> m_aAliases
;
116 OUString m_aStyleName
;
117 FontFamily m_eFamilyStyle
;
118 FontItalic m_eItalic
;
120 FontWeight m_eWeight
;
122 rtl_TextEncoding m_aEncoding
;
126 int m_nXMin
; // font bounding box
131 int m_nDirectory
; // atom containing system dependent path
132 OString m_aFontFile
; // relative to directory
133 int m_nCollectionEntry
; // 0 for regular fonts, 0 to ... for fonts stemming from collections
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
* pFont
) const;
151 std::vector
<std::unique_ptr
<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
* pFont
) 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
) 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( const OUString
& rFamily
);
164 PrintFont
* getFont( fontID nID
) const
166 std::unordered_map
< fontID
, PrintFont
* >::const_iterator it
;
167 it
= m_aFonts
.find( nID
);
168 return it
== m_aFonts
.end() ? nullptr : it
->second
;
170 static void fillPrintFontInfo(PrintFont
* pFont
, FastPrintFontInfo
& rInfo
);
171 void fillPrintFontInfo( PrintFont
* pFont
, PrintFontInfo
& rInfo
) const;
173 OString
getDirectory( int nAtom
) const;
174 int getDirectoryAtom( const OString
& rDirectory
);
176 /* try to initialize fonts from libfontconfig
178 called from <code>initialize()</code>
180 static void initFontconfig();
181 void countFontconfigFonts( std::unordered_map
<OString
, int>& o_rVisitedPaths
);
182 /* deinitialize fontconfig
184 static void deinitFontconfig();
186 /* register an application specific font directory for libfontconfig
188 since fontconfig is asked for font substitutes before OOo will check for font availability
189 and fontconfig will happily substitute fonts it doesn't know (e.g. "Arial Narrow" -> "DejaVu Sans Book"!)
190 it becomes necessary to tell the library about all the hidden font treasures
192 static void addFontconfigDir(const OString
& rDirectory
);
194 std::set
<OString
> m_aPreviousLangSupportRequests
;
195 std::vector
<OUString
> m_aCurrentRequests
;
196 Timer m_aFontInstallerTimer
;
198 DECL_LINK( autoInstallFontLangSupport
, Timer
*, void );
202 friend class ::GenericUnixSalData
;
203 static PrintFontManager
& get(); // one instance only
205 // There may be multiple font ids for font collections
206 std::vector
<fontID
> addFontFile( const OString
& rFileName
);
210 // returns the ids of all managed fonts.
211 void getFontList( std::vector
< fontID
>& rFontIDs
);
213 // get font info for a specific font
214 bool getFontInfo( fontID nFontID
, PrintFontInfo
& rInfo
) const;
215 // get fast font info for a specific font
216 bool getFontFastInfo( fontID nFontID
, FastPrintFontInfo
& rInfo
) const;
218 // routines to get font info in small pieces
220 // get a specific fonts PSName name
221 OUString
getPSName( fontID nFontID
) const;
223 // get a specific fonts italic type
224 FontItalic
getFontItalic( fontID nFontID
) const
226 PrintFont
* pFont
= getFont( nFontID
);
227 return pFont
? pFont
->m_eItalic
: ITALIC_DONTKNOW
;
230 // get a specific fonts weight type
231 FontWeight
getFontWeight( fontID nFontID
) const
233 PrintFont
* pFont
= getFont( nFontID
);
234 return pFont
? pFont
->m_eWeight
: WEIGHT_DONTKNOW
;
237 // get a specific fonts system dependent filename
238 OString
getFontFileSysPath( fontID nFontID
) const
240 return getFontFile( getFont( nFontID
) );
243 // get the ttc face number
244 int getFontFaceNumber( fontID nFontID
) const;
246 // get a specific fonts ascend
247 int getFontAscend( fontID nFontID
) const;
249 // get a specific fonts descent
250 int getFontDescend( fontID nFontID
) const;
252 // get a fonts glyph bounding box
253 void getFontBoundingBox( fontID nFont
, int& xMin
, int& yMin
, int& xMax
, int& yMax
);
255 // creates a new font subset of an existing SFNT font
256 // returns true in case of success, else false
257 // nFont: the font to be subsetted
258 // rOutFile: the file to put the new subset into;
259 // must be a valid osl file URL
260 // pGlyphIDs: input array of glyph ids for new font
261 // pNewEncoding: the corresponding encoding in the new font
262 // pWidths: output array of widths of requested glyphs
263 // nGlyphs: number of glyphs in arrays
264 // pCapHeight:: capital height of the produced font
265 // pXMin, pYMin, pXMax, pYMax: outgoing font bounding box
266 // TODO: callers of this method should use its FontSubsetInfo counterpart directly
267 bool createFontSubset( FontSubsetInfo
&,
269 const OUString
& rOutFile
,
270 const sal_GlyphId
* pGlyphIDs
,
271 const sal_uInt8
* pNewEncoding
,
275 void getGlyphWidths( fontID nFont
,
277 std::vector
< sal_Int32
>& rWidths
,
278 std::map
< sal_Unicode
, sal_uInt32
>& rUnicodeEnc
);
280 // font administration functions
282 /* system dependent font matching
285 <code>matchFont</code> matches a pattern of font characteristics
286 and returns the closest match if possible. If a match was found
287 the <code>FastPrintFontInfo</code> passed in as parameter
288 will be update to the found matching font.
291 implementation note: currently the function is only implemented
296 out of the FastPrintFontInfo structure the following
297 fields will be used for the match:
307 if <code>rLocal</code> contains non empty strings the corresponding
308 locale will be used for font matching also; e.g. "Sans" can result
309 in different fonts in e.g. english and japanese
311 void matchFont( FastPrintFontInfo
& rInfo
, const css::lang::Locale
& rLocale
);
312 static FontConfigFontOptions
* getFontOptions( const FastPrintFontInfo
&, int nSize
);
314 void Substitute( FontSelectPattern
&rPattern
, OUString
& rMissingCodes
);
320 #endif // INCLUDED_VCL_INC_FONTMANAGER_HXX
322 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */