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 FontSubsetInfo;
45 class FontSelectPattern;
46 class GenericUnixSalData;
47 
48 namespace psp {
49 class PPDParser;
50 
51 typedef int fontID;
52 
53 /*
54  * the difference between FastPrintFontInfo and PrintFontInfo
55  * is that the information in FastPrintFontInfo can usually
56  * be gathered without opening either the font file, they are
57  * gathered from fonts.dir alone.
58  * if only FastPrintFontInfo is gathered and PrintFontInfo
59  * on demand and for less fonts, then performance in startup
60  * increases considerably
61  */
62 
64 {
65  fontID m_nID; // FontID
66 
67  // font attributes
68  OUString m_aFamilyName;
69  OUString m_aStyleName;
70  std::vector< OUString > m_aAliases;
76  rtl_TextEncoding m_aEncoding;
77 
79  : m_nID(0)
80  , m_eFamilyStyle(FAMILY_DONTKNOW)
81  , m_eItalic(ITALIC_DONTKNOW)
82  , m_eWidth(WIDTH_DONTKNOW)
83  , m_eWeight(WEIGHT_DONTKNOW)
84  , m_ePitch(PITCH_DONTKNOW)
85  , m_aEncoding(RTL_TEXTENCODING_DONTKNOW)
86  {}
87 };
88 
90 {
91  int m_nAscend;
93 
96  m_nAscend( 0 ),
97  m_nDescend( 0 )
98  {}
99 };
100 
101 // a class to manage printable fonts
102 
104 {
105  struct PrintFont;
106  friend struct PrintFont;
107 
109  {
110  // font attributes
111  OUString m_aFamilyName;
112  std::vector<OUString> m_aAliases;
113  OUString m_aPSName;
114  OUString m_aStyleName;
120  rtl_TextEncoding m_aEncoding;
124  int m_nXMin; // font bounding box
125  int m_nYMin;
126  int m_nXMax;
127  int m_nYMax;
128 
129  int m_nDirectory; // atom containing system dependent path
130  OString m_aFontFile; // relative to directory
131  int m_nCollectionEntry; // 0 for regular fonts, 0 to ... for fonts stemming from collections
132  int m_nVariationEntry; // 0 for regular fonts, 0 to ... for fonts stemming from font variations
133 
134  explicit PrintFont();
135  };
136 
138  std::unordered_map< fontID, std::unique_ptr<PrintFont> > m_aFonts;
139  // for speeding up findFontFileID
140  std::unordered_map< OString, std::set< fontID > >
142 
143  std::unordered_map< OString, int >
145  std::unordered_map< int, OString > m_aAtomToDir;
147 
148  OString getFontFile(const PrintFont* pFont) const;
149 
150  std::vector<std::unique_ptr<PrintFont>> analyzeFontFile(int nDirID, const OString& rFileName, const char *pFormat=nullptr) const;
151  static OUString convertSfntName( void* pNameRecord ); // actually a NameRecord* format font subsetting code
152  static void analyzeSfntFamilyName( void const * pTTFont, std::vector< OUString >& rnames ); // actually a TrueTypeFont* from font subsetting code
153  bool analyzeSfntFile(PrintFont* pFont) const;
154  // finds the font id for the nFaceIndex face in this font file
155  // There may be multiple font ids for font collections
156  fontID findFontFileID(int nDirID, const OString& rFile, int nFaceIndex, int nVariationIndex) const;
157 
158  // There may be multiple font ids for font collections
159  std::vector<fontID> findFontFileIDs( int nDirID, const OString& rFile ) const;
160 
161  static FontFamily matchFamilyName( std::u16string_view rFamily );
162 
163  PrintFont* getFont( fontID nID ) const
164  {
165  auto it = m_aFonts.find( nID );
166  return it == m_aFonts.end() ? nullptr : it->second.get();
167  }
168  static void fillPrintFontInfo(PrintFont* pFont, FastPrintFontInfo& rInfo);
169  void fillPrintFontInfo( PrintFont* pFont, PrintFontInfo& rInfo ) const;
170 
171  OString getDirectory( int nAtom ) const;
172  int getDirectoryAtom( const OString& rDirectory );
173 
174  /* try to initialize fonts from libfontconfig
175 
176  called from <code>initialize()</code>
177  */
178  static void initFontconfig();
179  void countFontconfigFonts( std::unordered_map<OString, int>& o_rVisitedPaths );
180  /* deinitialize fontconfig
181  */
182  static void deinitFontconfig();
183 
184  /* register an application specific font directory for libfontconfig
185 
186  since fontconfig is asked for font substitutes before OOo will check for font availability
187  and fontconfig will happily substitute fonts it doesn't know (e.g. "Arial Narrow" -> "DejaVu Sans Book"!)
188  it becomes necessary to tell the library about all the hidden font treasures
189  */
190  static void addFontconfigDir(const OString& rDirectory);
191 
193  std::vector<OUString> m_aCurrentRequests;
195 
196  DECL_LINK( autoInstallFontLangSupport, Timer*, void );
198 public:
199  ~PrintFontManager();
200  friend class ::GenericUnixSalData;
201  static PrintFontManager& get(); // one instance only
202 
203  // There may be multiple font ids for font collections
204  std::vector<fontID> addFontFile( const OUString& rFileUrl );
205 
206  void initialize();
207 
208  // returns the ids of all managed fonts.
209  void getFontList( std::vector< fontID >& rFontIDs );
210 
211  // get font info for a specific font
212  bool getFontInfo( fontID nFontID, PrintFontInfo& rInfo ) const;
213  // get fast font info for a specific font
214  bool getFontFastInfo( fontID nFontID, FastPrintFontInfo& rInfo ) const;
215 
216  // routines to get font info in small pieces
217 
218  // get a specific fonts PSName name
219  OUString getPSName( fontID nFontID ) const;
220 
221  // get a specific fonts italic type
222  FontItalic getFontItalic( fontID nFontID ) const
223  {
224  PrintFont* pFont = getFont( nFontID );
225  return pFont ? pFont->m_eItalic : ITALIC_DONTKNOW;
226  }
227 
228  // get a specific fonts weight type
229  FontWeight getFontWeight( fontID nFontID ) const
230  {
231  PrintFont* pFont = getFont( nFontID );
232  return pFont ? pFont->m_eWeight : WEIGHT_DONTKNOW;
233  }
234 
235  // get a specific fonts system dependent filename
236  OString getFontFileSysPath( fontID nFontID ) const
237  {
238  return getFontFile( getFont( nFontID ) );
239  }
240 
241  // get the ttc face number
242  int getFontFaceNumber( fontID nFontID ) const;
243 
244  // get the ttc face variation
245  int getFontFaceVariation( fontID nFontID ) const;
246 
247  // get a specific fonts ascend
248  int getFontAscend( fontID nFontID ) const;
249 
250  // get a specific fonts descent
251  int getFontDescend( fontID nFontID ) const;
252 
253  // get a fonts glyph bounding box
254  void getFontBoundingBox( fontID nFont, int& xMin, int& yMin, int& xMax, int& yMax );
255 
256  // creates a new font subset of an existing SFNT font
257  // returns true in case of success, else false
258  // nFont: the font to be subsetted
259  // rOutFile: the file to put the new subset into;
260  // must be a valid osl file URL
261  // pGlyphIDs: input array of glyph ids for new font
262  // pNewEncoding: the corresponding encoding in the new font
263  // pWidths: output array of widths of requested glyphs
264  // nGlyphs: number of glyphs in arrays
265  // pCapHeight:: capital height of the produced font
266  // pXMin, pYMin, pXMax, pYMax: outgoing font bounding box
267  // TODO: callers of this method should use its FontSubsetInfo counterpart directly
268  bool createFontSubset( FontSubsetInfo&,
269  fontID nFont,
270  const OUString& rOutFile,
271  const sal_GlyphId* pGlyphIDs,
272  const sal_uInt8* pNewEncoding,
273  sal_Int32* pWidths,
274  int nGlyphs
275  );
276  void getGlyphWidths( fontID nFont,
277  bool bVertical,
278  std::vector< sal_Int32 >& rWidths,
279  std::map< sal_Unicode, sal_uInt32 >& rUnicodeEnc );
280 
281  // font administration functions
282 
283  /* system dependent font matching
284 
285  <p>
286  <code>matchFont</code> matches a pattern of font characteristics
287  and returns the closest match if possible. If a match was found
288  the <code>FastPrintFontInfo</code> passed in as parameter
289  will be update to the found matching font.
290  </p>
291  <p>
292  implementation note: currently the function is only implemented
293  for fontconfig.
294  </p>
295 
296  @param rInfo
297  out of the FastPrintFontInfo structure the following
298  fields will be used for the match:
299  <ul>
300  <li>family name</li>
301  <li>italic</li>
302  <li>width</li>
303  <li>weight</li>
304  <li>pitch</li>
305  </ul>
306 
307  @param rLocale
308  if <code>rLocal</code> contains non empty strings the corresponding
309  locale will be used for font matching also; e.g. "Sans" can result
310  in different fonts in e.g. english and japanese
311  */
312  void matchFont( FastPrintFontInfo& rInfo, const css::lang::Locale& rLocale );
313  static std::unique_ptr<FontConfigFontOptions> getFontOptions( const FastPrintFontInfo&, int nSize);
314 
315  void Substitute(FontSelectPattern &rPattern, OUString& rMissingCodes);
316 
317 };
318 
319 } // namespace
320 
321 #endif // INCLUDED_VCL_INC_FONTMANAGER_HXX
322 
323 /* 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:76
std::unordered_map< OString, int > m_aDirToAtom
FontWeight getFontWeight(fontID nFontID) const
FontWidth
FAMILY_DONTKNOW
std::unordered_map< fontID, std::unique_ptr< PrintFont > > m_aFonts
std::vector< OUString > m_aCurrentRequests
sal_uInt16 sal_GlyphId
Definition: glyphitem.hxx:26
WEIGHT_DONTKNOW
FontItalic getFontItalic(fontID nFontID) const
PITCH_DONTKNOW
std::set< OString > m_aPreviousLangSupportRequests
FontPitch
#define VCL_PLUGIN_PUBLIC
Definition: dllapi.h:40
FontFamily
PrintFont * getFont(fontID nID) const
FontWeight
unsigned char sal_uInt8
WIDTH_DONTKNOW
ITALIC_DONTKNOW
std::vector< OUString > m_aAliases
Definition: fontmanager.hxx:70
#define VCL_DLLPRIVATE
Definition: dllapi.h:31
std::unordered_map< OString, std::set< fontID > > m_aFontFileToFontID
int fontID
Definition: fontmanager.hxx:49
Definition: timer.hxx:26
FontItalic