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