1 /****************************************************************************\
2  Part of the XeTeX typesetting system
3  Copyright (c) 1994-2008 by SIL International
4  Copyright (c) 2009 by Jonathan Kew
5  Copyright (c) 2012, 2013 by Jiang Jiang
6 
7  SIL Author(s): Jonathan Kew
8 
9 Permission is hereby granted, free of charge, to any person obtaining
10 a copy of this software and associated documentation files (the
11 "Software"), to deal in the Software without restriction, including
12 without limitation the rights to use, copy, modify, merge, publish,
13 distribute, sublicense, and/or sell copies of the Software, and to
14 permit persons to whom the Software is furnished to do so, subject to
15 the following conditions:
16 
17 The above copyright notice and this permission notice shall be
18 included in all copies or substantial portions of the Software.
19 
20 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 NONINFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE
24 FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
25 CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 
28 Except as contained in this notice, the name of the copyright holders
29 shall not be used in advertising or otherwise to promote the sale,
30 use or other dealings in this Software without prior written
31 authorization from the copyright holders.
32 \****************************************************************************/
33 
34 #ifndef __XETEX_FONT_MANAGER_H
35 #define __XETEX_FONT_MANAGER_H
36 
37 #ifdef XETEX_MAC
38 #include <ApplicationServices/ApplicationServices.h>
39 typedef CTFontDescriptorRef PlatformFontRef;
40 #else
41 #include <fontconfig/fontconfig.h>
42 #include <ft2build.h>
43 #include FT_FREETYPE_H
44 typedef FcPattern* PlatformFontRef;
45 #endif
46 
47 #include "XeTeX_ext.h"
48 
49 #include "XeTeXLayoutInterface.h"
50 
51 #ifdef __cplusplus  /* allow inclusion in plain C files just to get the typedefs above */
52 
53 #include <string>
54 #include <map>
55 #include <list>
56 #include <vector>
57 
58 class XeTeXFontMgr
59 {
60 public:
61     static XeTeXFontMgr*            GetFontManager();
62         // returns the global fontmanager (creating it if necessary)
63     static void                     Terminate();
64         // clean up (may be required if using the cocoa implementation)
65 
66     PlatformFontRef                 findFont(const char* name, char* variant, double ptSize);
67         // 1st arg is name as specified by user (C string, UTF-8)
68         // 2nd is /B/I/AAT/OT/ICU/GR/S=## qualifiers
69         // 1. try name given as "full name"
70         // 2. if there's a hyphen, split and try "family-style"
71         // 3. try as PostScript name
72         // 4. try name as family with "Regular/Plain/Normal" style
73         // apply style qualifiers and optical sizing if present
74 
75         // SIDE EFFECT: sets sReqEngine to 'A' or 'O' or 'G' if appropriate,
76         //   else clears it to 0
77 
78         // SIDE EFFECT: updates TeX variables /nameoffile/ and /namelength/,
79         //   to match the actual font found
80 
81         // SIDE EFFECT: edits /variant/ string in-place removing /B or /I
82 
83     const char*                     getFullName(PlatformFontRef font) const;
84         // return the full name of the font, suitable for use in XeTeX source
85         // without requiring style qualifiers
86 
87     double                          getDesignSize(XeTeXFont font);
88 
getReqEngine()89     char                            getReqEngine() const { return sReqEngine; };
90         // return the requested rendering technology for the most recent findFont
91         // or 0 if no specific technology was requested
92 
setReqEngine(char reqEngine)93     void                            setReqEngine(char reqEngine) const { sReqEngine = reqEngine; };
94 
95 protected:
96     static XeTeXFontMgr*            sFontManager;
97     static char                     sReqEngine;
98 
XeTeXFontMgr()99                                     XeTeXFontMgr()
100                                         { }
~XeTeXFontMgr()101     virtual                         ~XeTeXFontMgr()
102                                         { }
103 
104     virtual void                    initialize() = 0;
105     virtual void                    terminate();
106 
107     virtual std::string             getPlatformFontDesc(PlatformFontRef font) const = 0;
108 
109     class Font;
110     class Family;
111 
112     struct OpSizeRec {
113         unsigned int    designSize;
114         unsigned int    subFamilyID;
115         unsigned int    nameCode;
116         unsigned int    minSize;
117         unsigned int    maxSize;
118     };
119 
120     class Font {
121         public:
Font(PlatformFontRef ref)122                             Font(PlatformFontRef ref)
123                                 : m_fullName(NULL), m_psName(NULL), m_familyName(NULL), m_styleName(NULL)
124                                 , parent(NULL)
125                                 , fontRef(ref), weight(0), width(0), slant(0)
126                                 , isReg(false), isBold(false), isItalic(false)
127                                 { opSizeInfo.subFamilyID = 0;
128                                   opSizeInfo.designSize = 100; } /* default to 10bp */
~Font()129                             ~Font()
130                                 { delete m_fullName; delete m_psName; }
131 
132             std::string*    m_fullName;
133             std::string*    m_psName;
134             std::string*    m_familyName; // default family and style names that should locate this font
135             std::string*    m_styleName;
136             Family*         parent;
137             PlatformFontRef fontRef;
138             OpSizeRec       opSizeInfo;
139             uint16_t        weight;
140             uint16_t        width;
141             int16_t         slant;
142             bool            isReg;
143             bool            isBold;
144             bool            isItalic;
145     };
146 
147     class Family {
148         public:
Family()149                                             Family()
150                                                 : minWeight(0), maxWeight(0)
151                                                 , minWidth(0), maxWidth(0)
152                                                 , minSlant(0), maxSlant(0)
153                                                 {
154                                                     styles = new std::map<std::string,Font*>;
155                                                 }
~Family()156                                             ~Family()
157                                                 {
158                                                     delete styles;
159                                                 }
160 
161             std::map<std::string,Font*>*    styles;
162             uint16_t                        minWeight;
163             uint16_t                        maxWeight;
164             uint16_t                        minWidth;
165             uint16_t                        maxWidth;
166             int16_t                         minSlant;
167             int16_t                         maxSlant;
168     };
169 
170     class NameCollection {
171     public:
172         std::list<std::string>  m_familyNames;
173         std::list<std::string>  m_styleNames;
174         std::list<std::string>  m_fullNames;
175         std::string             m_psName;
176         std::string             m_subFamily;
177     };
178 
179     std::map<std::string,Font*>                 m_nameToFont;                     // maps full name (as used in TeX source) to font record
180     std::map<std::string,Family*>               m_nameToFamily;
181     std::map<PlatformFontRef,Font*>             m_platformRefToFont;
182     std::map<std::string,Font*>                 m_psNameToFont;                   // maps PS name (as used in .xdv) to font record
183 
184     int             weightAndWidthDiff(const Font* a, const Font* b) const;
185     int             styleDiff(const Font* a, int wt, int wd, int slant) const;
186     Font*           bestMatchFromFamily(const Family* fam, int wt, int wd, int slant) const;
187     void            appendToList(std::list<std::string>* list, const char* str);
188     void            prependToList(std::list<std::string>* list, const char* str);
189     void            addToMaps(PlatformFontRef platformFont, const NameCollection* names);
190 
191     const OpSizeRec* getOpSize(XeTeXFont font);
192 
193     virtual void    getOpSizeRecAndStyleFlags(Font* theFont);
194     virtual void    searchForHostPlatformFonts(const std::string& name) = 0;
195 
196     virtual NameCollection*     readNames(PlatformFontRef fontRef) = 0;
197 
198     void    die(const char*s, int i) const; /* for fatal internal errors! */
199 };
200 
201 #endif  /* __cplusplus */
202 
203 
204 #endif  /* __XETEX_FONT_MANAGER_H */
205