LibreOffice Module vcl (master)  1
fontmanager.hxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
20 #ifndef INCLUDED_VCL_INC_FONTMANAGER_HXX
21 #define INCLUDED_VCL_INC_FONTMANAGER_HXX
22 
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>
30 
31 #include <map>
32 #include <set>
33 #include <memory>
34 #include <string_view>
35 #include <vector>
36 #include <unordered_map>
37 
38 /*
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
41  */
42 
43 class FontAttributes;
44 class FontSubsetInfo;
46 class FontSelectPattern;
47 class GenericUnixSalData;
48 
49 namespace psp {
50 class PPDParser;
51 
52 typedef int fontID;
53 
54 /*
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
62  */
63 
65 {
66  fontID m_nID; // FontID
67 
68  // font attributes
69  OUString m_aFamilyName;
70  OUString m_aStyleName;
71  std::vector< OUString > m_aAliases;
77  rtl_TextEncoding m_aEncoding;
78 
80  : m_nID(0)
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)
87  {}
88 };
89 
91 {
92  int m_nAscend;
94 
97  m_nAscend( 0 ),
98  m_nDescend( 0 )
99  {}
100 };
101 
102 // a class to manage printable fonts
103 
105 {
106  struct PrintFont;
107  friend struct PrintFont;
108 
110  {
111  // font attributes
112  OUString m_aFamilyName;
113  std::vector<OUString> m_aAliases;
114  OUString m_aPSName;
115  OUString m_aStyleName;
121  rtl_TextEncoding m_aEncoding;
125  int m_nXMin; // font bounding box
126  int m_nYMin;
127  int m_nXMax;
128  int m_nYMax;
129 
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
134 
135  explicit PrintFont();
136  };
137 
139  std::unordered_map< fontID, PrintFont > m_aFonts;
140  // for speeding up findFontFileID
141  std::unordered_map< OString, std::set< fontID > >
143 
144  std::unordered_map< OString, int >
146  std::unordered_map< int, OString > m_aAtomToDir;
148 
149  OString getFontFile(const PrintFont& rFont) const;
150 
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;
158 
159  // There may be multiple font ids for font collections
160  std::vector<fontID> findFontFileIDs( int nDirID, const OString& rFile ) const;
161 
162  static FontFamily matchFamilyName( std::u16string_view rFamily );
163 
164  const PrintFont* getFont( fontID nID ) const
165  {
166  auto it = m_aFonts.find( nID );
167  return it == m_aFonts.end() ? nullptr : &it->second;
168  }
169  PrintFont* getFont( fontID nID )
170  {
171  auto it = m_aFonts.find( nID );
172  return it == m_aFonts.end() ? nullptr : &it->second;
173  }
174  static void fillPrintFontInfo(const PrintFont& rFont, FastPrintFontInfo& rInfo);
175  void fillPrintFontInfo( PrintFont& rFont, PrintFontInfo& rInfo ) const;
176 
177  OString getDirectory( int nAtom ) const;
178  int getDirectoryAtom( const OString& rDirectory );
179 
180  /* try to initialize fonts from libfontconfig
181 
182  called from <code>initialize()</code>
183  */
184  static void initFontconfig();
185  void countFontconfigFonts( std::unordered_map<OString, int>& o_rVisitedPaths );
186  /* deinitialize fontconfig
187  */
188  static void deinitFontconfig();
189 
190  /* register an application specific font directory for libfontconfig
191 
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
195  */
196  static void addFontconfigDir(const OString& rDirectory);
197 
199  std::vector<OUString> m_aCurrentRequests;
201 
202  DECL_LINK( autoInstallFontLangSupport, Timer*, void );
204 public:
205  ~PrintFontManager();
206  friend class ::GenericUnixSalData;
207  static PrintFontManager& get(); // one instance only
208 
209  // There may be multiple font ids for font collections
210  std::vector<fontID> addFontFile( const OUString& rFileUrl );
211 
212  void initialize();
213 
214  // returns the ids of all managed fonts.
215  void getFontList( std::vector< fontID >& rFontIDs );
216 
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;
221 
222  // routines to get font info in small pieces
223 
224  // get a specific fonts PSName name
225  OUString getPSName( fontID nFontID );
226 
227  // get a specific fonts italic type
228  FontItalic getFontItalic( fontID nFontID ) const
229  {
230  const PrintFont* pFont = getFont( nFontID );
231  return pFont ? pFont->m_eItalic : ITALIC_DONTKNOW;
232  }
233 
234  // get a specific fonts weight type
235  FontWeight getFontWeight( fontID nFontID ) const
236  {
237  const PrintFont* pFont = getFont( nFontID );
238  return pFont ? pFont->m_eWeight : WEIGHT_DONTKNOW;
239  }
240 
241  // get a specific fonts system dependent filename
242  OString getFontFileSysPath( fontID nFontID ) const
243  {
244  return getFontFile( *getFont( nFontID ) );
245  }
246 
247  // get the ttc face number
248  int getFontFaceNumber( fontID nFontID ) const;
249 
250  // get the ttc face variation
251  int getFontFaceVariation( fontID nFontID ) const;
252 
253  // get a specific fonts ascend
254  int getFontAscend( fontID nFontID );
255 
256  // get a specific fonts descent
257  int getFontDescend( fontID nFontID );
258 
259  // get a fonts glyph bounding box
260  void getFontBoundingBox( fontID nFont, int& xMin, int& yMin, int& xMax, int& yMax );
261 
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&,
275  fontID nFont,
276  const OUString& rOutFile,
277  const sal_GlyphId* pGlyphIDs,
278  const sal_uInt8* pNewEncoding,
279  sal_Int32* pWidths,
280  int nGlyphs
281  );
282  void getGlyphWidths( fontID nFont,
283  bool bVertical,
284  std::vector< sal_Int32 >& rWidths,
285  std::map< sal_Unicode, sal_uInt32 >& rUnicodeEnc );
286 
287  // font administration functions
288 
289  /* system dependent font matching
290 
291  <p>
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.
296  </p>
297  <p>
298  implementation note: currently the function is only implemented
299  for fontconfig.
300  </p>
301 
302  @param rInfo
303  out of the FastPrintFontInfo structure the following
304  fields will be used for the match:
305  <ul>
306  <li>family name</li>
307  <li>italic</li>
308  <li>width</li>
309  <li>weight</li>
310  <li>pitch</li>
311  </ul>
312 
313  @param rLocale
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
317  */
318  void matchFont( FastPrintFontInfo& rInfo, const css::lang::Locale& rLocale );
319 
320  static std::unique_ptr<FontConfigFontOptions> getFontOptions(const FontAttributes& rFontAttributes, int nSize);
321 
322  void Substitute(FontSelectPattern &rPattern, OUString& rMissingCodes);
323 
324 };
325 
326 } // namespace
327 
328 #endif // INCLUDED_VCL_INC_FONTMANAGER_HXX
329 
330 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
OString getFontFileSysPath(fontID nFontID) const
std::vector< OUString > m_aAliases
std::unordered_map< int, OString > m_aAtomToDir
rtl_TextEncoding m_aEncoding
Definition: fontmanager.hxx:77
std::unordered_map< OString, int > m_aDirToAtom
FontWeight getFontWeight(fontID nFontID) const
PrintFont * getFont(fontID nID)
FontWidth
FAMILY_DONTKNOW
std::vector< OUString > m_aCurrentRequests
sal_uInt16 sal_GlyphId
Definition: glyphitem.hxx:29
WEIGHT_DONTKNOW
FontItalic getFontItalic(fontID nFontID) const
PITCH_DONTKNOW
std::set< OString > m_aPreviousLangSupportRequests
std::unordered_map< fontID, PrintFont > m_aFonts
FontPitch
#define VCL_PLUGIN_PUBLIC
Definition: dllapi.h:40
FontFamily
FontWeight
unsigned char sal_uInt8
WIDTH_DONTKNOW
ITALIC_DONTKNOW
std::vector< OUString > m_aAliases
Definition: fontmanager.hxx:71
const PrintFont * getFont(fontID nID) const
#define VCL_DLLPRIVATE
Definition: dllapi.h:31
std::unordered_map< OString, std::set< fontID > > m_aFontFileToFontID
int fontID
Definition: fontmanager.hxx:50
Definition: timer.hxx:26
FontItalic