1 /*****************************************************************************
2  * freetype.c : Put text on the video, using freetype2
3  *****************************************************************************
4  * Copyright (C) 2002 - 2015 VLC authors and VideoLAN
5  * $Id: 848c31a4eb46f67572326b3621f95c542cf35edd $
6  *
7  * Authors: Sigmund Augdal Helberg <dnumgis@videolan.org>
8  *          Gildas Bazin <gbazin@videolan.org>
9  *          Bernie Purcell <bitmap@videolan.org>
10  *          Jean-Baptiste Kempf <jb@videolan.org>
11  *          Felix Paul Kühne <fkuehne@videolan.org>
12  *          Salah-Eddin Shaban <salshaaban@gmail.com>
13  *
14  * This program is free software; you can redistribute it and/or modify it
15  * under the terms of the GNU Lesser General Public License as published by
16  * the Free Software Foundation; either version 2.1 of the License, or
17  * (at your option) any later version.
18  *
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22  * GNU Lesser General Public License for more details.
23  *
24  * You should have received a copy of the GNU Lesser General Public License
25  * along with this program; if not, write to the Free Software Foundation, Inc.,
26  * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
27  *****************************************************************************/
28 
29 /*****************************************************************************
30  * Preamble
31  *****************************************************************************/
32 
33 #ifndef PLATFORM_FONTS_H
34 #define PLATFORM_FONTS_H
35 
36 /** \defgroup freetype_fonts Freetype Fonts management
37  * \ingroup freetype
38  * Freetype text rendering cross platform
39  * @{
40  * \file
41  * Freetype module
42  */
43 
44 #ifdef HAVE_CONFIG_H
45 # include "config.h"
46 #endif
47 
48 #include "freetype.h"
49 
50 #ifdef __cplusplus
51 extern "C" {
52 #endif
53 
54 /* Default fonts */
55 #ifdef __APPLE__
56 # define SYSTEM_DEFAULT_FONT_FILE "/System/Library/Fonts/HelveticaNeue.dfont"
57 # define SYSTEM_DEFAULT_FAMILY "Helvetica Neue"
58 # define SYSTEM_DEFAULT_MONOSPACE_FONT_FILE "/System/Library/Fonts/Monaco.dfont"
59 # define SYSTEM_DEFAULT_MONOSPACE_FAMILY "Monaco"
60 #elif defined( _WIN32 )
61 # define SYSTEM_DEFAULT_FONT_FILE "arial.ttf" /* Default path font found at run-time */
62 # define SYSTEM_DEFAULT_FAMILY "Arial"
63 # define SYSTEM_DEFAULT_MONOSPACE_FONT_FILE "cour.ttf"
64 # define SYSTEM_DEFAULT_MONOSPACE_FAMILY "Courier New"
65 #elif defined( __OS2__ )
66 # define SYSTEM_DEFAULT_FONT_FILE "/psfonts/tnrwt_k.ttf"
67 # define SYSTEM_DEFAULT_FAMILY "Times New Roman WT K"
68 # define SYSTEM_DEFAULT_MONOSPACE_FONT_FILE "/psfonts/mtsansdk.ttf"
69 # define SYSTEM_DEFAULT_MONOSPACE_FAMILY "Monotype Sans Duospace WT K"
70 #elif defined( __ANDROID__ )
71 # define SYSTEM_DEFAULT_FONT_FILE "/system/fonts/Roboto-Regular.ttf"
72 # define SYSTEM_DEFAULT_FAMILY "sans-serif"
73 # define SYSTEM_DEFAULT_MONOSPACE_FONT_FILE "/system/fonts/DroidSansMono.ttf"
74 # define SYSTEM_DEFAULT_MONOSPACE_FAMILY "Monospace"
75 #else
76 # define SYSTEM_DEFAULT_FONT_FILE "/usr/share/fonts/truetype/freefont/FreeSerifBold.ttf"
77 # define SYSTEM_DEFAULT_FAMILY "Serif Bold"
78 # define SYSTEM_DEFAULT_MONOSPACE_FONT_FILE "/usr/share/fonts/truetype/freefont/FreeMono.ttf"
79 # define SYSTEM_DEFAULT_MONOSPACE_FAMILY "Monospace"
80 #endif
81 
82 #ifndef DEFAULT_FONT_FILE
83 # define DEFAULT_FONT_FILE SYSTEM_DEFAULT_FONT_FILE
84 #endif
85 
86 #ifndef DEFAULT_FAMILY
87 # define DEFAULT_FAMILY SYSTEM_DEFAULT_FAMILY
88 #endif
89 
90 #ifndef DEFAULT_MONOSPACE_FONT_FILE
91 # define DEFAULT_MONOSPACE_FONT_FILE SYSTEM_DEFAULT_MONOSPACE_FONT_FILE
92 #endif
93 
94 #ifndef DEFAULT_MONOSPACE_FAMILY
95 # define DEFAULT_MONOSPACE_FAMILY SYSTEM_DEFAULT_MONOSPACE_FAMILY
96 #endif
97 
98 /**
99  * Representation of the fonts (linked-list)
100  */
101 typedef struct vlc_font_t vlc_font_t;
102 struct vlc_font_t
103 {
104     vlc_font_t *p_next;   /**< next font in the chain */
105     /**
106      * path to the font file on disk, or ":/x" for font attachments, where x
107      * is the attachment index within \ref filter_sys_t::pp_font_attachments
108      */
109     char       *psz_fontfile;
110     int         i_index;   /**< index of the font in the font file, starts at 0 */
111     bool        b_bold;    /**< if the font is a bold version */
112     bool        b_italic;  /**< if the font is an italic version */
113     FT_Face     p_face;    /**< the freetype structure for the font */
114 };
115 
116 /**
117  * Representation of font families (linked-list)
118  */
119 struct vlc_family_t
120 {
121     vlc_family_t *p_next; /**< next family in the chain */
122     /**
123      * Human-readable name, usually requested.
124      * Can be fallback-xxxx for font attachments with no family name, and for fallback
125      * fonts in Android.
126      * This field is used only for loading the family fonts, and for debugging.
127      * Apart from that, families are accessed either through the
128      * \ref filter_sys_t::family_map dictionary, or as a member of some fallback list
129      * in \ref filter_sys_t::fallback_map. And this field plays no role in either of
130      * the two cases.
131      */
132     char         *psz_name;
133     vlc_font_t   *p_fonts; /**< fonts matching this family */
134 };
135 
136 #define FB_LIST_ATTACHMENTS "attachments"
137 #define FB_LIST_DEFAULT     "default"
138 #define FB_NAME             "fallback"
139 
140 /***
141  * PLATFORM SPECIFIC SELECTORS
142  **/
143 #ifdef HAVE_FONTCONFIG
144 vlc_family_t *FontConfig_GetFallbacks( filter_t *p_filter, const char *psz_family,
145                                        uni_char_t codepoint );
146 const vlc_family_t *FontConfig_GetFamily( filter_t *p_filter, const char *psz_family );
147 int FontConfig_Prepare( filter_t *p_filter );
148 void FontConfig_Unprepare( void );
149 #endif /* FONTCONFIG */
150 
151 #if defined( _WIN32 )
152 const vlc_family_t *DWrite_GetFamily( filter_t *p_filter, const char *psz_family );
153 vlc_family_t *DWrite_GetFallbacks( filter_t *p_filter, const char *psz_family,
154                                   uni_char_t codepoint );
155 int InitDWrite( filter_t *p_filter );
156 int ReleaseDWrite( filter_t *p_filter );
157 int DWrite_GetFontStream( filter_t *p_filter, int i_index, FT_Stream *pp_stream );
158 #if !VLC_WINSTORE_APP
159 vlc_family_t *Win32_GetFallbacks( filter_t *p_filter, const char *psz_family,
160                                   uni_char_t codepoint );
161 
162 const vlc_family_t *Win32_GetFamily( filter_t *p_filter, const char *psz_family );
163 #endif /* !VLC_WINSTORE_APP */
164 #endif /* _WIN32 */
165 
166 #ifdef __APPLE__
167 vlc_family_t *CoreText_GetFallbacks(filter_t *p_filter, const char *psz_family, uni_char_t codepoint);
168 const vlc_family_t *CoreText_GetFamily(filter_t *p_filter, const char *psz_family);
169 #endif /* __APPLE__ */
170 
171 #ifdef __ANDROID__
172 const vlc_family_t *Android_GetFamily( filter_t *p_filter, const char *psz_family );
173 vlc_family_t *Android_GetFallbacks( filter_t *p_filter, const char *psz_family,
174                                     uni_char_t codepoint );
175 int Android_Prepare( filter_t *p_filter );
176 #endif /* __ANDROID__ */
177 
178 char* Dummy_Select( filter_t *p_filter, const char* family,
179                     bool b_bold, bool b_italic,
180                     int *i_idx, uni_char_t codepoint );
181 
182 #define File_Select(a) Dummy_Select(NULL, a, 0, 0, NULL, 0)
183 
184 char* Generic_Select( filter_t *p_filter, const char* family,
185                       bool b_bold, bool b_italic,
186                       int *i_idx, uni_char_t codepoint );
187 
188 
189 /* ******************
190  * Family and fonts *
191  ********************/
192 
193 /**
194  * Creates a new family.
195  *
196  * \param psz_family the usual font family name, human-readable;
197  *                   if NULL, will use "fallback-xxxx"[IN]
198  * \param pp_list the family list where to append the new family;
199  *        can be NULL if not in a list, or if the family is to be appended to a fallback list
200  *        within \ref filter_sys_t::fallback_map [IN]
201  * \param p_dict dictionary where to insert this family; can be NULL.
202  *        If the dictionary already has an entry for \p psz_key, which is often the case when adding
203  *        a new fallback to a fallback list within \ref filter_sys_t::fallback_map, the new family will be
204  *        appended there [IN]
205  * \param psz_key specific key for the dictionary.
206  *        If NULL will use whatever is used for the family name, whether it is the specified \p psz_family
207  *        or "fallback-xxxx" [IN]
208  *
209  * \return the new family representation
210  */
211 vlc_family_t *NewFamily( filter_t *p_filter, const char *psz_family,
212                          vlc_family_t **pp_list, vlc_dictionary_t *p_dict,
213                          const char *psz_key );
214 
215 /**
216  * Creates a new font.
217  *
218  * \param psz_fontfile font file, or ":/x" for font attachments, where x is the attachment index
219  *        within \ref filter_sys_t::pp_font_attachments [IN]
220  * \param i_index index of the font in the font file [IN]
221  * \param b_bold is a bold font or not [IN]
222  * \param b_bold is an italic or not [IN]
223  * \param p_parent parent family.
224  *                 If not NULL, the font will be associated to this family, and
225  *                 appended to the font list in that family [IN]
226  *
227  * \remark This function takes ownership of \p psz_fontfile
228  * \return the new font
229  */
230 vlc_font_t *NewFont( char *psz_fontfile, int i_index,
231                      bool b_bold, bool b_italic,
232                      vlc_family_t *p_parent );
233 
234 /**
235  * Free families and fonts associated.
236  *
237  * \param p_family the family to free [IN]
238  */
239 void FreeFamiliesAndFonts( vlc_family_t *p_family );
240 
241 /**
242  * Free families, but not the fonts associated.
243  *
244  * \param p_families the families to free [IN]
245  */
246 void FreeFamilies( void *p_families, void *p_obj );
247 
248 /**
249  * Construct the default fallback list
250  *
251  * The default fallback list will be searched when all else fails.
252  * It should contain at least one font for each Unicode script.
253  *
254  * No default list is required with FontConfig because FontConfig returns
255  * comprehensive fallback lists. On Windows a default list is used because
256  * Uniscribe seems less reliable than FontConfig in this regard.
257  *
258  * On Android, all fallback families reside within the default fallback list,
259  * which is populated in Android_ParseFamily(), in the XML_READER_ENDELEM section
260  * of that function, where each family is added to the default list if
261  * its name has "fallback" in it. So InitDefaultList() is not called on Android.
262  *
263  * \param p_filter the freetype module object [IN]
264  * \param ppsz_default the table default fonts [IN]
265  * \param i_size the size of the supplied table [IN]
266  *
267  * \return the default fallback list
268  */
269 vlc_family_t *InitDefaultList( filter_t *p_filter, const char *const *ppsz_default,
270                                int i_size );
271 
272 /* Debug Helpers */
273 void DumpFamily( filter_t *p_filter, const vlc_family_t *p_family,
274                  bool b_dump_fonts, int i_max_families );
275 
276 void DumpDictionary( filter_t *p_filter, const vlc_dictionary_t *p_dict,
277                      bool b_dump_fonts, int i_max_families );
278 
279 /* String helpers */
280 char* ToLower( const char *psz_src );
281 
282 /* Size helper, depending on the scaling factor */
283 int ConvertToLiveSize( filter_t *p_filter, const text_style_t *p_style );
284 
285 
286 /* Only for fonts implementors */
287 vlc_family_t *SearchFallbacks( filter_t *p_filter, vlc_family_t *p_fallbacks,
288                                       uni_char_t codepoint );
289 FT_Face GetFace( filter_t *p_filter, vlc_font_t *p_font );
290 
291 #ifdef __cplusplus
292 }
293 #endif
294 
295 #endif //PLATFORM_FONTS_H
296