Branch libreoffice-5-0-4
[LibreOffice.git] / vcl / inc / fontmanager.hxx
blob13bd05fd162289f0481478bc88bac7386d046d20
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 <list>
24 #include <map>
25 #include <set>
26 #include <unordered_map>
28 #include <vcl/dllapi.h>
29 #include <vcl/helper.hxx>
30 #include <vcl/timer.hxx>
31 #include <vcl/vclenum.hxx>
32 #include <com/sun/star/lang/Locale.hpp>
33 #include "salglyphid.hxx"
35 #include <vector>
37 #define ATOM_FAMILYNAME 2
38 #define ATOM_PSNAME 3
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
45 namespace utl { class MultiAtomProvider; }
47 class FontSubsetInfo;
48 class ImplFontOptions;
49 class FontSelectPattern;
51 namespace psp {
52 class PPDParser;
54 namespace fonttype
56 enum type {
57 Unknown = 0,
58 Type1 = 1,
59 TrueType = 2,
64 * the difference between FastPrintFontInfo and PrintFontInfo
65 * is that the information in FastPrintFontInfo can usually
66 * be gathered without openening either the font file or
67 * an afm metric file. they are gathered from fonts.dir alone.
68 * if only FastPrintFontInfo is gathered and PrintFontInfo
69 * on demand and for less fonts, then performance in startup
70 * increases considerably
73 struct FastPrintFontInfo
75 fontID m_nID; // FontID
76 fonttype::type m_eType;
78 // font attributes
79 OUString m_aFamilyName;
80 OUString m_aStyleName;
81 std::list< OUString > m_aAliases;
82 FontFamily m_eFamilyStyle;
83 FontItalic m_eItalic;
84 FontWidth m_eWidth;
85 FontWeight m_eWeight;
86 FontPitch m_ePitch;
87 rtl_TextEncoding m_aEncoding;
88 bool m_bSubsettable;
89 bool m_bEmbeddable;
91 FastPrintFontInfo()
92 : m_nID(0)
93 , m_eType(fonttype::Unknown)
94 , m_eFamilyStyle(FAMILY_DONTKNOW)
95 , m_eItalic(ITALIC_DONTKNOW)
96 , m_eWidth(WIDTH_DONTKNOW)
97 , m_eWeight(WEIGHT_DONTKNOW)
98 , m_ePitch(PITCH_DONTKNOW)
99 , m_aEncoding(RTL_TEXTENCODING_DONTKNOW)
100 , m_bSubsettable(false)
101 , m_bEmbeddable(false)
105 struct PrintFontInfo : public FastPrintFontInfo
107 int m_nAscend;
108 int m_nDescend;
109 int m_nLeading;
110 int m_nWidth;
112 PrintFontInfo() :
113 FastPrintFontInfo(),
114 m_nAscend( 0 ),
115 m_nDescend( 0 ),
116 m_nLeading( 0 ),
117 m_nWidth( 0 )
121 // the values are per thousand of the font size
122 // note: width, height contain advances, not bounding box
123 struct CharacterMetric
125 short int width, height;
127 CharacterMetric() : width( 0 ), height( 0 ) {}
128 bool operator==( const CharacterMetric& rOther ) const
129 { return rOther.width == width && rOther.height == height; }
130 bool operator!=( const CharacterMetric& rOther ) const
131 { return rOther.width != width || rOther.height != height; }
134 class FontCache;
136 // a class to manage printable fonts
137 // aims are type1 and truetype fonts
139 class FontCache;
141 class VCL_PLUGIN_PUBLIC PrintFontManager
143 struct PrintFont;
144 struct TrueTypeFontFile;
145 struct Type1FontFile;
146 friend struct PrintFont;
147 friend struct TrueTypeFontFile;
148 friend struct Type1FontFile;
149 friend class FontCache;
151 struct PrintFontMetrics
153 // character metrics are stored by the following keys:
154 // lower two bytes contain a sal_Unicode (a UCS2 character)
155 // upper byte contains: 0 for horizontal metric
156 // 1 for vertical metric
157 // highest byte: 0 for now
158 std::unordered_map< int, CharacterMetric > m_aMetrics;
159 // contains the unicode blocks for which metrics were queried
160 // this implies that metrics should be queried in terms of
161 // unicode blocks. here a unicode block is identified
162 // by the upper byte of the UCS2 encoding.
163 // note that the corresponding bit should be set even
164 // if the font does not support a single character of that page
165 // this map shows, which pages were queried already
166 // if (like in AFM metrics) all metrics are queried in
167 // a single pass, then all bits should be set
168 char m_aPages[32];
170 std::unordered_map< sal_Unicode, bool > m_bVerticalSubstitutions;
172 PrintFontMetrics() {}
174 bool isEmpty() const { return m_aMetrics.empty(); }
177 struct PrintFont
179 fonttype::type m_eType;
181 // font attributes
182 int m_nFamilyName; // atom
183 std::list< int > m_aAliases;
184 int m_nPSName; // atom
185 OUString m_aStyleName;
186 FontItalic m_eItalic;
187 FontWidth m_eWidth;
188 FontWeight m_eWeight;
189 FontPitch m_ePitch;
190 rtl_TextEncoding m_aEncoding;
191 bool m_bFontEncodingOnly; // set if font should be only accessed by builtin encoding
192 CharacterMetric m_aGlobalMetricX;
193 CharacterMetric m_aGlobalMetricY;
194 PrintFontMetrics* m_pMetrics;
195 int m_nAscend;
196 int m_nDescend;
197 int m_nLeading;
198 int m_nXMin; // font bounding box
199 int m_nYMin;
200 int m_nXMax;
201 int m_nYMax;
202 bool m_bHaveVerticalSubstitutedGlyphs;
203 bool m_bUserOverride;
205 /// mapping from unicode (well, UCS-2) to font code
206 std::map< sal_Unicode, sal_Int32 > m_aEncodingVector;
207 /// HACK for Type 1 fonts: if multiple UCS-2 codes map to the same
208 /// font code, this set contains the preferred one, i.e., the one that
209 /// is specified explicitly via "C" or "CH" in the AFM file
210 std::set<sal_Unicode> m_aEncodingVectorPriority;
211 std::map< sal_Unicode, OString > m_aNonEncoded;
213 explicit PrintFont( fonttype::type eType );
214 virtual ~PrintFont();
215 virtual bool queryMetricPage( int nPage, utl::MultiAtomProvider* pProvider ) = 0;
217 bool readAfmMetrics( utl::MultiAtomProvider* pProvider, bool bFillEncodingvector, bool bOnlyGlobalAttributes );
220 struct Type1FontFile : public PrintFont
222 int m_nDirectory; // atom containing system dependent path
223 OString m_aFontFile; // relative to directory
224 OString m_aMetricFile; // dito
226 /* note: m_aFontFile and Metric file are not atoms
227 because they should be fairly unique */
229 Type1FontFile() : PrintFont( fonttype::Type1 ), m_nDirectory( 0 ) {}
230 virtual ~Type1FontFile();
231 virtual bool queryMetricPage( int nPage, utl::MultiAtomProvider* pProvider ) SAL_OVERRIDE;
234 struct TrueTypeFontFile : public PrintFont
236 int m_nDirectory; // atom containing system dependent path
237 OString m_aFontFile; // relative to directory
238 int m_nCollectionEntry; // 0 for regular fonts, 0 to ... for fonts stemming from collections
239 unsigned int m_nTypeFlags; // copyright bits and PS-OpenType flag
241 TrueTypeFontFile();
242 virtual ~TrueTypeFontFile();
243 virtual bool queryMetricPage( int nPage, utl::MultiAtomProvider* pProvider ) SAL_OVERRIDE;
246 fontID m_nNextFontID;
247 std::unordered_map< fontID, PrintFont* > m_aFonts;
248 std::unordered_map< int, FontFamily > m_aFamilyTypes;
249 std::list< OUString > m_aPrinterDrivers;
250 std::list< OString > m_aFontDirectories;
251 std::list< int > m_aPrivateFontDirectories;
252 utl::MultiAtomProvider* m_pAtoms;
253 // for speeding up findFontFileID
254 std::unordered_map< OString, std::set< fontID >, OStringHash >
255 m_aFontFileToFontID;
257 std::unordered_map< OString, int, OStringHash >
258 m_aDirToAtom;
259 std::unordered_map< int, OString > m_aAtomToDir;
260 int m_nNextDirAtom;
262 std::unordered_multimap< OString, sal_Unicode, OStringHash >
263 m_aAdobenameToUnicode;
264 std::unordered_multimap< sal_Unicode, OString >
265 m_aUnicodeToAdobename;
266 std::unordered_multimap< sal_Unicode, sal_uInt8 > m_aUnicodeToAdobecode;
267 std::unordered_multimap< sal_uInt8, sal_Unicode > m_aAdobecodeToUnicode;
269 mutable FontCache* m_pFontCache;
271 OString getAfmFile( PrintFont* pFont ) const;
272 OString getFontFile( PrintFont* pFont ) const;
274 bool analyzeFontFile( int nDirID, const OString& rFileName, std::list< PrintFont* >& rNewFonts, const char *pFormat=NULL ) const;
275 static OUString convertTrueTypeName( void* pNameRecord ); // actually a NameRecord* formt font subsetting code
276 static void analyzeTrueTypeFamilyName( void* pTTFont, std::list< OUString >& rnames ); // actually a TrueTypeFont* from font subsetting code
277 bool analyzeTrueTypeFile( PrintFont* pFont ) const;
278 // finds the font id for the nFaceIndex face in this font file
279 // There may be multiple font ids for TrueType collections
280 fontID findFontFileID( int nDirID, const OString& rFile, int nFaceIndex ) const;
282 // There may be multiple font ids for TrueType collections
283 std::vector<fontID> findFontFileIDs( int nDirID, const OString& rFile ) const;
285 bool knownFontFile( int nDirID, const OString& rFile ) const
287 return findFontFileID(nDirID, rFile, 0) != 0;
290 static FontFamily matchFamilyName( const OUString& rFamily );
292 PrintFont* getFont( fontID nID ) const
294 std::unordered_map< fontID, PrintFont* >::const_iterator it;
295 it = m_aFonts.find( nID );
296 return it == m_aFonts.end() ? NULL : it->second;
298 void fillPrintFontInfo( PrintFont* pFont, FastPrintFontInfo& rInfo ) const;
299 void fillPrintFontInfo( PrintFont* pFont, PrintFontInfo& rInfo ) const;
301 OString getDirectory( int nAtom ) const;
302 int getDirectoryAtom( const OString& rDirectory, bool bCreate = false );
304 /* try to initialize fonts from libfontconfig
306 called from <code>initialize()</code>
308 static void initFontconfig();
309 void countFontconfigFonts( std::unordered_map<OString, int, OStringHash>& o_rVisitedPaths );
310 /* deinitialize fontconfig
312 static void deinitFontconfig();
314 /* register an application specific font directory for libfontconfig
316 since fontconfig is asked for font substitutes before OOo will check for font availability
317 and fontconfig will happily substitute fonts it doesn't know (e.g. "Arial Narrow" -> "DejaVu Sans Book"!)
318 it becomes necessary to tell the library about all the hidden font treasures
320 @returns
321 true if libfontconfig accepted the directory
322 false else (e.g. no libfontconfig found)
324 static bool addFontconfigDir(const OString& rDirectory);
326 std::set<OString> m_aPreviousLangSupportRequests;
327 std::vector<OString> m_aCurrentRequests;
328 Timer m_aFontInstallerTimer;
330 DECL_LINK_TYPED( autoInstallFontLangSupport, Timer*, void );
332 PrintFontManager();
333 ~PrintFontManager();
334 public:
335 static PrintFontManager& get(); // one instance only
337 // There may be multiple font ids for TrueType collections
338 std::vector<fontID> addFontFile( const OString& rFileName );
340 void initialize();
342 // returns the number of managed fonts
343 int getFontCount() const { return m_aFonts.size(); }
345 // returns the ids of all managed fonts.
346 void getFontList( std::list< fontID >& rFontIDs );
348 // get font info for a specific font
349 bool getFontInfo( fontID nFontID, PrintFontInfo& rInfo ) const;
350 // get fast font info for a specific font
351 bool getFontFastInfo( fontID nFontID, FastPrintFontInfo& rInfo ) const;
353 // routines to get font info in small pieces
355 // get a specific fonts PSName name
356 const OUString& getPSName( fontID nFontID ) const;
358 // get a specific fonts family name aliases
359 void getFontFamilyAliases( fontID nFontID ) const;
361 // get a specific fonts type
362 fonttype::type getFontType( fontID nFontID ) const
364 PrintFont* pFont = getFont( nFontID );
365 return pFont ? pFont->m_eType : fonttype::Unknown;
368 // get a specific fonts italic type
369 FontItalic getFontItalic( fontID nFontID ) const
371 PrintFont* pFont = getFont( nFontID );
372 return pFont ? pFont->m_eItalic : ITALIC_DONTKNOW;
375 // get a specific fonts width type
376 FontWidth getFontWidth( fontID nFontID ) const
378 PrintFont* pFont = getFont( nFontID );
379 return pFont ? pFont->m_eWidth : WIDTH_DONTKNOW;
382 // get a specific fonts weight type
383 FontWeight getFontWeight( fontID nFontID ) const
385 PrintFont* pFont = getFont( nFontID );
386 return pFont ? pFont->m_eWeight : WEIGHT_DONTKNOW;
389 // get a specific fonts pitch type
390 FontPitch getFontPitch( fontID nFontID ) const
392 PrintFont* pFont = getFont( nFontID );
393 return pFont ? pFont->m_ePitch : PITCH_DONTKNOW;
396 // get a specific fonts encoding
397 rtl_TextEncoding getFontEncoding( fontID nFontID ) const
399 PrintFont* pFont = getFont( nFontID );
400 return pFont ? pFont->m_aEncoding : RTL_TEXTENCODING_DONTKNOW;
403 // should i only use font's builtin encoding ?
404 bool getUseOnlyFontEncoding( fontID nFontID ) const
406 PrintFont* pFont = getFont( nFontID );
407 return pFont && pFont->m_bFontEncodingOnly;
410 // get a specific fonts system dependent filename
411 OString getFontFileSysPath( fontID nFontID ) const
413 return getFontFile( getFont( nFontID ) );
416 // get the ttc face number
417 int getFontFaceNumber( fontID nFontID ) const;
419 // get a specific fonts ascend
420 int getFontAscend( fontID nFontID ) const;
422 // get a specific fonts descent
423 int getFontDescend( fontID nFontID ) const;
425 // get a fonts glyph bounding box
426 bool getFontBoundingBox( fontID nFont, int& xMin, int& yMin, int& xMax, int& yMax );
428 // info whether an array of glyphs has vertical substitutions
429 void hasVerticalSubstitutions( fontID nFontID, const sal_Unicode* pCharacters,
430 int nCharacters, bool* pHasSubst ) const;
432 // get a specific fonts metrics
434 // get metrics for a sal_Unicode range
435 // the user is responsible to allocate pArray large enough
436 bool getMetrics( fontID nFontID, sal_Unicode minCharacter, sal_Unicode maxCharacter, CharacterMetric* pArray, bool bVertical = false ) const;
437 // get metrics for an array of sal_Unicode characters
438 // the user is responsible to allocate pArray large enough
439 bool getMetrics( fontID nFontID, const sal_Unicode* pString, int nLen, CharacterMetric* pArray, bool bVertical = false ) const;
441 // get encoding vector of font, currently only for Type1 fonts
442 // returns NULL if encoding vector is empty or font is not type1;
443 // if ppNonEncoded is set and non encoded type1 glyphs exist
444 // then *ppNonEncoded is set to the mapping for nonencoded glyphs.
445 // the encoding vector contains -1 for non encoded glyphs
446 const std::map< sal_Unicode, sal_Int32 >* getEncodingMap( fontID nFontID, const std::map< sal_Unicode, OString >** ppNonEncoded, std::set<sal_Unicode> const ** ppPriority ) const;
448 // evaluates copyright flags for TrueType fonts for printing/viewing
449 // type1 fonts do not have such a feature, so return for them is true
450 bool isFontDownloadingAllowedForPrinting( fontID nFont ) const;
452 // helper for type 1 fonts
453 std::list< OString > getAdobeNameFromUnicode( sal_Unicode aChar ) const;
455 std::pair< std::unordered_multimap< sal_Unicode, sal_uInt8 >::const_iterator,
456 std::unordered_multimap< sal_Unicode, sal_uInt8 >::const_iterator >
457 getAdobeCodeFromUnicode( sal_Unicode aChar ) const
459 return m_aUnicodeToAdobecode.equal_range( aChar );
461 std::list< sal_Unicode > getUnicodeFromAdobeName( const OString& rName ) const;
462 std::pair< std::unordered_multimap< sal_uInt8, sal_Unicode >::const_iterator,
463 std::unordered_multimap< sal_uInt8, sal_Unicode >::const_iterator >
464 getUnicodeFromAdobeCode( sal_uInt8 aChar ) const
466 return m_aAdobecodeToUnicode.equal_range( aChar );
469 // creates a new font subset of an existing TrueType font
470 // returns true in case of success, else false
471 // nFont: the font to be subsetted
472 // rOutFile: the file to put the new subset into;
473 // must be a valid osl file URL
474 // pGlyphIDs: input array of glyph ids for new font
475 // pNewEncoding: the corresponding encoding in the new font
476 // pWidths: output array of widths of requested glyphs
477 // nGlyphs: number of glyphs in arrays
478 // pCapHeight:: capital height of the produced font
479 // pXMin, pYMin, pXMax, pYMax: outgoing font bounding box
480 // TODO: callers of this method should use its FontSubsetInfo counterpart directly
481 bool createFontSubset( FontSubsetInfo&,
482 fontID nFont,
483 const OUString& rOutFile,
484 const sal_GlyphId* pGlyphIDs,
485 const sal_uInt8* pNewEncoding,
486 sal_Int32* pWidths,
487 int nGlyphs,
488 bool bVertical = false
490 void getGlyphWidths( fontID nFont,
491 bool bVertical,
492 std::vector< sal_Int32 >& rWidths,
493 std::map< sal_Unicode, sal_uInt32 >& rUnicodeEnc );
495 // font administration functions
497 /* system dependendent font matching
500 <code>matchFont</code> matches a pattern of font characteristics
501 and returns the closest match if possibe. If a match was found
502 the <code>FastPrintFontInfo</code> passed in as parameter
503 will be update to the found matching font.
504 </p>
506 implementation note: currently the function is only implemented
507 for fontconfig.
508 </p>
510 @param rInfo
511 out of the FastPrintFontInfo structure the following
512 fields will be used for the match:
513 <ul>
514 <li>family name</li>
515 <li>italic</li>
516 <li>width</li>
517 <li>weight</li>
518 <li>pitch</li>
519 </ul>
521 @param rLocale
522 if <code>rLocal</code> contains non empty strings the corresponding
523 locale will be used for font matching also; e.g. "Sans" can result
524 in different fonts in e.g. english and japanese
526 @returns
527 true if a match was found
528 false else
530 bool matchFont( FastPrintFontInfo& rInfo, const com::sun::star::lang::Locale& rLocale );
531 static ImplFontOptions* getFontOptions( const FastPrintFontInfo&, int nSize, void (*subcallback)(void*));
533 bool Substitute( FontSelectPattern &rPattern, OUString& rMissingCodes );
535 int FreeTypeCharIndex( void *pFace, sal_uInt32 aChar );
538 } // namespace
540 #endif // INCLUDED_VCL_INC_FONTMANAGER_HXX
542 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */