Mercurial > mplayer.hg
annotate libass/ass_font.c @ 25509:1cfa39a320cc
Fix update_subtitles() checking subtitle type for the wrong track.
update_subtitles() uses 'type' field from d_dvdsub even when some other track
is active. For this reason, external vobsub is not displayed when there is at
least one text track from demuxer (type is always 't' or 'a' in this case).
The solution is to check vobsub_id and dvdsub_id instead.
author | eugeni |
---|---|
date | Fri, 28 Dec 2007 20:57:38 +0000 |
parents | 810982c2bfb4 |
children | 3993c96eaa95 |
rev | line source |
---|---|
21277 | 1 // -*- c-basic-offset: 8; indent-tabs-mode: t -*- |
2 // vim:ts=8:sw=8:noet:ai: | |
3 /* | |
4 Copyright (C) 2006 Evgeniy Stepanov <eugeni.stepanov@gmail.com> | |
5 | |
6 This program is free software; you can redistribute it and/or modify | |
7 it under the terms of the GNU General Public License as published by | |
8 the Free Software Foundation; either version 2 of the License, or | |
9 (at your option) any later version. | |
10 | |
11 This program is distributed in the hope that it will be useful, | |
12 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 GNU General Public License for more details. | |
15 | |
16 You should have received a copy of the GNU General Public License | |
17 along with this program; if not, write to the Free Software | |
18 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
19 */ | |
20 | |
21 #include "config.h" | |
22 | |
23 #include <inttypes.h> | |
24 #include <ft2build.h> | |
25 #include FT_FREETYPE_H | |
26 #include FT_SYNTHESIS_H | |
27 #include FT_GLYPH_H | |
23328 | 28 #include FT_TRUETYPE_TABLES_H |
21277 | 29 |
21458
7af6c25a0cfc
Keep embedded fonts in ass_library_t and perform actual disk write
eugeni
parents:
21351
diff
changeset
|
30 #include "ass.h" |
7af6c25a0cfc
Keep embedded fonts in ass_library_t and perform actual disk write
eugeni
parents:
21351
diff
changeset
|
31 #include "ass_library.h" |
21277 | 32 #include "ass_font.h" |
21321
7b7627ff1937
Move ass_font_desc_t and ass_font_t declarations to ass_font.h.
eugeni
parents:
21320
diff
changeset
|
33 #include "ass_bitmap.h" |
7b7627ff1937
Move ass_font_desc_t and ass_font_t declarations to ass_font.h.
eugeni
parents:
21320
diff
changeset
|
34 #include "ass_cache.h" |
21277 | 35 #include "ass_fontconfig.h" |
23299
0ee56ec36a40
Limit ass_font_set_transform to nonrotating transformations.
eugeni
parents:
23212
diff
changeset
|
36 #include "ass_utils.h" |
21277 | 37 #include "mputils.h" |
38 | |
39 /** | |
40 * Select Microfost Unicode CharMap, if the font has one. | |
41 * Otherwise, let FreeType decide. | |
42 */ | |
43 static void charmap_magic(FT_Face face) | |
44 { | |
45 int i; | |
46 for (i = 0; i < face->num_charmaps; ++i) { | |
47 FT_CharMap cmap = face->charmaps[i]; | |
48 unsigned pid = cmap->platform_id; | |
49 unsigned eid = cmap->encoding_id; | |
50 if (pid == 3 /*microsoft*/ && (eid == 1 /*unicode bmp*/ || eid == 10 /*full unicode*/)) { | |
51 FT_Set_Charmap(face, cmap); | |
22210
4a958bd08920
Select the first charmap in the font, if FreeType did not autoselect any.
eugeni
parents:
21630
diff
changeset
|
52 return; |
21277 | 53 } |
54 } | |
22210
4a958bd08920
Select the first charmap in the font, if FreeType did not autoselect any.
eugeni
parents:
21630
diff
changeset
|
55 |
4a958bd08920
Select the first charmap in the font, if FreeType did not autoselect any.
eugeni
parents:
21630
diff
changeset
|
56 if (!face->charmap) { |
4a958bd08920
Select the first charmap in the font, if FreeType did not autoselect any.
eugeni
parents:
21630
diff
changeset
|
57 if (face->num_charmaps == 0) { |
4a958bd08920
Select the first charmap in the font, if FreeType did not autoselect any.
eugeni
parents:
21630
diff
changeset
|
58 mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_NoCharmaps); |
4a958bd08920
Select the first charmap in the font, if FreeType did not autoselect any.
eugeni
parents:
21630
diff
changeset
|
59 return; |
4a958bd08920
Select the first charmap in the font, if FreeType did not autoselect any.
eugeni
parents:
21630
diff
changeset
|
60 } |
4a958bd08920
Select the first charmap in the font, if FreeType did not autoselect any.
eugeni
parents:
21630
diff
changeset
|
61 mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_NoCharmapAutodetected); |
4a958bd08920
Select the first charmap in the font, if FreeType did not autoselect any.
eugeni
parents:
21630
diff
changeset
|
62 FT_Set_Charmap(face, face->charmaps[0]); |
4a958bd08920
Select the first charmap in the font, if FreeType did not autoselect any.
eugeni
parents:
21630
diff
changeset
|
63 return; |
4a958bd08920
Select the first charmap in the font, if FreeType did not autoselect any.
eugeni
parents:
21630
diff
changeset
|
64 } |
21277 | 65 } |
66 | |
23299
0ee56ec36a40
Limit ass_font_set_transform to nonrotating transformations.
eugeni
parents:
23212
diff
changeset
|
67 static void update_transform(ass_font_t* font) |
0ee56ec36a40
Limit ass_font_set_transform to nonrotating transformations.
eugeni
parents:
23212
diff
changeset
|
68 { |
0ee56ec36a40
Limit ass_font_set_transform to nonrotating transformations.
eugeni
parents:
23212
diff
changeset
|
69 int i; |
0ee56ec36a40
Limit ass_font_set_transform to nonrotating transformations.
eugeni
parents:
23212
diff
changeset
|
70 FT_Matrix m; |
23328 | 71 m.xx = double_to_d16(font->scale_x); |
72 m.yy = double_to_d16(font->scale_y); | |
23299
0ee56ec36a40
Limit ass_font_set_transform to nonrotating transformations.
eugeni
parents:
23212
diff
changeset
|
73 m.xy = m.yx = 0; |
0ee56ec36a40
Limit ass_font_set_transform to nonrotating transformations.
eugeni
parents:
23212
diff
changeset
|
74 for (i = 0; i < font->n_faces; ++i) |
0ee56ec36a40
Limit ass_font_set_transform to nonrotating transformations.
eugeni
parents:
23212
diff
changeset
|
75 FT_Set_Transform(font->faces[i], &m, &font->v); |
0ee56ec36a40
Limit ass_font_set_transform to nonrotating transformations.
eugeni
parents:
23212
diff
changeset
|
76 } |
0ee56ec36a40
Limit ass_font_set_transform to nonrotating transformations.
eugeni
parents:
23212
diff
changeset
|
77 |
21630 | 78 /** |
79 * \brief find a memory font by name | |
80 */ | |
21460 | 81 static int find_font(ass_library_t* library, char* name) |
82 { | |
83 int i; | |
84 for (i = 0; i < library->num_fontdata; ++i) | |
85 if (strcasecmp(name, library->fontdata[i].name) == 0) | |
86 return i; | |
87 return -1; | |
88 } | |
89 | |
23981
705628816d98
Factor out common code from ass_font_new and ass_font_reselect.
eugeni
parents:
23980
diff
changeset
|
90 static void face_set_size(FT_Face face, double size); |
705628816d98
Factor out common code from ass_font_new and ass_font_reselect.
eugeni
parents:
23980
diff
changeset
|
91 |
23982
17b5fa69243c
Workaround for fonts with zero ascender/descender in horizontal header.
eugeni
parents:
23981
diff
changeset
|
92 static void buggy_font_workaround(FT_Face face) |
17b5fa69243c
Workaround for fonts with zero ascender/descender in horizontal header.
eugeni
parents:
23981
diff
changeset
|
93 { |
17b5fa69243c
Workaround for fonts with zero ascender/descender in horizontal header.
eugeni
parents:
23981
diff
changeset
|
94 // Some fonts have zero Ascender/Descender fields in 'hhea' table. |
17b5fa69243c
Workaround for fonts with zero ascender/descender in horizontal header.
eugeni
parents:
23981
diff
changeset
|
95 // In this case, get the information from 'os2' table or, as |
17b5fa69243c
Workaround for fonts with zero ascender/descender in horizontal header.
eugeni
parents:
23981
diff
changeset
|
96 // a last resort, from face.bbox. |
17b5fa69243c
Workaround for fonts with zero ascender/descender in horizontal header.
eugeni
parents:
23981
diff
changeset
|
97 if (face->ascender + face->descender == 0 || face->height == 0) { |
17b5fa69243c
Workaround for fonts with zero ascender/descender in horizontal header.
eugeni
parents:
23981
diff
changeset
|
98 TT_OS2 *os2 = FT_Get_Sfnt_Table(face, ft_sfnt_os2); |
17b5fa69243c
Workaround for fonts with zero ascender/descender in horizontal header.
eugeni
parents:
23981
diff
changeset
|
99 if (os2) { |
17b5fa69243c
Workaround for fonts with zero ascender/descender in horizontal header.
eugeni
parents:
23981
diff
changeset
|
100 face->ascender = os2->sTypoAscender; |
17b5fa69243c
Workaround for fonts with zero ascender/descender in horizontal header.
eugeni
parents:
23981
diff
changeset
|
101 face->descender = os2->sTypoDescender; |
17b5fa69243c
Workaround for fonts with zero ascender/descender in horizontal header.
eugeni
parents:
23981
diff
changeset
|
102 face->height = face->ascender - face->descender; |
17b5fa69243c
Workaround for fonts with zero ascender/descender in horizontal header.
eugeni
parents:
23981
diff
changeset
|
103 } else { |
17b5fa69243c
Workaround for fonts with zero ascender/descender in horizontal header.
eugeni
parents:
23981
diff
changeset
|
104 face->ascender = face->bbox.yMax; |
17b5fa69243c
Workaround for fonts with zero ascender/descender in horizontal header.
eugeni
parents:
23981
diff
changeset
|
105 face->descender = face->bbox.yMin; |
17b5fa69243c
Workaround for fonts with zero ascender/descender in horizontal header.
eugeni
parents:
23981
diff
changeset
|
106 face->height = face->ascender - face->descender; |
17b5fa69243c
Workaround for fonts with zero ascender/descender in horizontal header.
eugeni
parents:
23981
diff
changeset
|
107 } |
17b5fa69243c
Workaround for fonts with zero ascender/descender in horizontal header.
eugeni
parents:
23981
diff
changeset
|
108 } |
17b5fa69243c
Workaround for fonts with zero ascender/descender in horizontal header.
eugeni
parents:
23981
diff
changeset
|
109 } |
17b5fa69243c
Workaround for fonts with zero ascender/descender in horizontal header.
eugeni
parents:
23981
diff
changeset
|
110 |
23981
705628816d98
Factor out common code from ass_font_new and ass_font_reselect.
eugeni
parents:
23980
diff
changeset
|
111 /** |
705628816d98
Factor out common code from ass_font_new and ass_font_reselect.
eugeni
parents:
23980
diff
changeset
|
112 * \brief Select a face with the given charcode and add it to ass_font_t |
705628816d98
Factor out common code from ass_font_new and ass_font_reselect.
eugeni
parents:
23980
diff
changeset
|
113 * \return index of the new face in font->faces, -1 if failed |
705628816d98
Factor out common code from ass_font_new and ass_font_reselect.
eugeni
parents:
23980
diff
changeset
|
114 */ |
705628816d98
Factor out common code from ass_font_new and ass_font_reselect.
eugeni
parents:
23980
diff
changeset
|
115 static int add_face(void* fc_priv, ass_font_t* font, uint32_t ch) |
705628816d98
Factor out common code from ass_font_new and ass_font_reselect.
eugeni
parents:
23980
diff
changeset
|
116 { |
705628816d98
Factor out common code from ass_font_new and ass_font_reselect.
eugeni
parents:
23980
diff
changeset
|
117 char* path; |
705628816d98
Factor out common code from ass_font_new and ass_font_reselect.
eugeni
parents:
23980
diff
changeset
|
118 int index; |
705628816d98
Factor out common code from ass_font_new and ass_font_reselect.
eugeni
parents:
23980
diff
changeset
|
119 FT_Face face; |
705628816d98
Factor out common code from ass_font_new and ass_font_reselect.
eugeni
parents:
23980
diff
changeset
|
120 int error; |
705628816d98
Factor out common code from ass_font_new and ass_font_reselect.
eugeni
parents:
23980
diff
changeset
|
121 int mem_idx; |
705628816d98
Factor out common code from ass_font_new and ass_font_reselect.
eugeni
parents:
23980
diff
changeset
|
122 |
705628816d98
Factor out common code from ass_font_new and ass_font_reselect.
eugeni
parents:
23980
diff
changeset
|
123 if (font->n_faces == ASS_FONT_MAX_FACES) |
705628816d98
Factor out common code from ass_font_new and ass_font_reselect.
eugeni
parents:
23980
diff
changeset
|
124 return -1; |
705628816d98
Factor out common code from ass_font_new and ass_font_reselect.
eugeni
parents:
23980
diff
changeset
|
125 |
705628816d98
Factor out common code from ass_font_new and ass_font_reselect.
eugeni
parents:
23980
diff
changeset
|
126 path = fontconfig_select(fc_priv, font->desc.family, font->desc.bold, |
705628816d98
Factor out common code from ass_font_new and ass_font_reselect.
eugeni
parents:
23980
diff
changeset
|
127 font->desc.italic, &index, ch); |
705628816d98
Factor out common code from ass_font_new and ass_font_reselect.
eugeni
parents:
23980
diff
changeset
|
128 |
705628816d98
Factor out common code from ass_font_new and ass_font_reselect.
eugeni
parents:
23980
diff
changeset
|
129 mem_idx = find_font(font->library, path); |
705628816d98
Factor out common code from ass_font_new and ass_font_reselect.
eugeni
parents:
23980
diff
changeset
|
130 if (mem_idx >= 0) { |
705628816d98
Factor out common code from ass_font_new and ass_font_reselect.
eugeni
parents:
23980
diff
changeset
|
131 error = FT_New_Memory_Face(font->ftlibrary, (unsigned char*)font->library->fontdata[mem_idx].data, |
705628816d98
Factor out common code from ass_font_new and ass_font_reselect.
eugeni
parents:
23980
diff
changeset
|
132 font->library->fontdata[mem_idx].size, 0, &face); |
705628816d98
Factor out common code from ass_font_new and ass_font_reselect.
eugeni
parents:
23980
diff
changeset
|
133 if (error) { |
705628816d98
Factor out common code from ass_font_new and ass_font_reselect.
eugeni
parents:
23980
diff
changeset
|
134 mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_ErrorOpeningMemoryFont, path); |
705628816d98
Factor out common code from ass_font_new and ass_font_reselect.
eugeni
parents:
23980
diff
changeset
|
135 return -1; |
705628816d98
Factor out common code from ass_font_new and ass_font_reselect.
eugeni
parents:
23980
diff
changeset
|
136 } |
705628816d98
Factor out common code from ass_font_new and ass_font_reselect.
eugeni
parents:
23980
diff
changeset
|
137 } else { |
705628816d98
Factor out common code from ass_font_new and ass_font_reselect.
eugeni
parents:
23980
diff
changeset
|
138 error = FT_New_Face(font->ftlibrary, path, index, &face); |
705628816d98
Factor out common code from ass_font_new and ass_font_reselect.
eugeni
parents:
23980
diff
changeset
|
139 if (error) { |
705628816d98
Factor out common code from ass_font_new and ass_font_reselect.
eugeni
parents:
23980
diff
changeset
|
140 mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_ErrorOpeningFont, path, index); |
705628816d98
Factor out common code from ass_font_new and ass_font_reselect.
eugeni
parents:
23980
diff
changeset
|
141 return -1; |
705628816d98
Factor out common code from ass_font_new and ass_font_reselect.
eugeni
parents:
23980
diff
changeset
|
142 } |
705628816d98
Factor out common code from ass_font_new and ass_font_reselect.
eugeni
parents:
23980
diff
changeset
|
143 } |
705628816d98
Factor out common code from ass_font_new and ass_font_reselect.
eugeni
parents:
23980
diff
changeset
|
144 charmap_magic(face); |
23982
17b5fa69243c
Workaround for fonts with zero ascender/descender in horizontal header.
eugeni
parents:
23981
diff
changeset
|
145 buggy_font_workaround(face); |
23981
705628816d98
Factor out common code from ass_font_new and ass_font_reselect.
eugeni
parents:
23980
diff
changeset
|
146 |
705628816d98
Factor out common code from ass_font_new and ass_font_reselect.
eugeni
parents:
23980
diff
changeset
|
147 font->faces[font->n_faces++] = face; |
705628816d98
Factor out common code from ass_font_new and ass_font_reselect.
eugeni
parents:
23980
diff
changeset
|
148 update_transform(font); |
705628816d98
Factor out common code from ass_font_new and ass_font_reselect.
eugeni
parents:
23980
diff
changeset
|
149 face_set_size(face, font->size); |
705628816d98
Factor out common code from ass_font_new and ass_font_reselect.
eugeni
parents:
23980
diff
changeset
|
150 return font->n_faces - 1; |
705628816d98
Factor out common code from ass_font_new and ass_font_reselect.
eugeni
parents:
23980
diff
changeset
|
151 } |
705628816d98
Factor out common code from ass_font_new and ass_font_reselect.
eugeni
parents:
23980
diff
changeset
|
152 |
21630 | 153 /** |
154 * \brief Create a new ass_font_t according to "desc" argument | |
155 */ | |
21460 | 156 ass_font_t* ass_font_new(ass_library_t* library, FT_Library ftlibrary, void* fc_priv, ass_font_desc_t* desc) |
21277 | 157 { |
158 int error; | |
23212
c932f521344d
In ass_font_new, allocate temporary ass_font_t on stack and return the pointer
eugeni
parents:
23134
diff
changeset
|
159 ass_font_t* fontp; |
c932f521344d
In ass_font_new, allocate temporary ass_font_t on stack and return the pointer
eugeni
parents:
23134
diff
changeset
|
160 ass_font_t font; |
21317 | 161 |
23212
c932f521344d
In ass_font_new, allocate temporary ass_font_t on stack and return the pointer
eugeni
parents:
23134
diff
changeset
|
162 fontp = ass_font_cache_find(desc); |
c932f521344d
In ass_font_new, allocate temporary ass_font_t on stack and return the pointer
eugeni
parents:
23134
diff
changeset
|
163 if (fontp) |
c932f521344d
In ass_font_new, allocate temporary ass_font_t on stack and return the pointer
eugeni
parents:
23134
diff
changeset
|
164 return fontp; |
21277 | 165 |
23981
705628816d98
Factor out common code from ass_font_new and ass_font_reselect.
eugeni
parents:
23980
diff
changeset
|
166 font.library = library; |
23212
c932f521344d
In ass_font_new, allocate temporary ass_font_t on stack and return the pointer
eugeni
parents:
23134
diff
changeset
|
167 font.ftlibrary = ftlibrary; |
23981
705628816d98
Factor out common code from ass_font_new and ass_font_reselect.
eugeni
parents:
23980
diff
changeset
|
168 font.n_faces = 0; |
23212
c932f521344d
In ass_font_new, allocate temporary ass_font_t on stack and return the pointer
eugeni
parents:
23134
diff
changeset
|
169 font.desc.family = strdup(desc->family); |
c932f521344d
In ass_font_new, allocate temporary ass_font_t on stack and return the pointer
eugeni
parents:
23134
diff
changeset
|
170 font.desc.bold = desc->bold; |
c932f521344d
In ass_font_new, allocate temporary ass_font_t on stack and return the pointer
eugeni
parents:
23134
diff
changeset
|
171 font.desc.italic = desc->italic; |
21277 | 172 |
23299
0ee56ec36a40
Limit ass_font_set_transform to nonrotating transformations.
eugeni
parents:
23212
diff
changeset
|
173 font.scale_x = font.scale_y = 1.; |
23212
c932f521344d
In ass_font_new, allocate temporary ass_font_t on stack and return the pointer
eugeni
parents:
23134
diff
changeset
|
174 font.v.x = font.v.y = 0; |
23300 | 175 font.size = 0.; |
21277 | 176 |
23981
705628816d98
Factor out common code from ass_font_new and ass_font_reselect.
eugeni
parents:
23980
diff
changeset
|
177 error = add_face(fc_priv, &font, 0); |
705628816d98
Factor out common code from ass_font_new and ass_font_reselect.
eugeni
parents:
23980
diff
changeset
|
178 if (error == -1) { |
705628816d98
Factor out common code from ass_font_new and ass_font_reselect.
eugeni
parents:
23980
diff
changeset
|
179 free(font.desc.family); |
705628816d98
Factor out common code from ass_font_new and ass_font_reselect.
eugeni
parents:
23980
diff
changeset
|
180 return 0; |
705628816d98
Factor out common code from ass_font_new and ass_font_reselect.
eugeni
parents:
23980
diff
changeset
|
181 } else |
705628816d98
Factor out common code from ass_font_new and ass_font_reselect.
eugeni
parents:
23980
diff
changeset
|
182 return ass_font_cache_add(&font); |
21277 | 183 } |
184 | |
21630 | 185 /** |
186 * \brief Set font transformation matrix and shift vector | |
187 **/ | |
23299
0ee56ec36a40
Limit ass_font_set_transform to nonrotating transformations.
eugeni
parents:
23212
diff
changeset
|
188 void ass_font_set_transform(ass_font_t* font, double scale_x, double scale_y, FT_Vector* v) |
21277 | 189 { |
23299
0ee56ec36a40
Limit ass_font_set_transform to nonrotating transformations.
eugeni
parents:
23212
diff
changeset
|
190 font->scale_x = scale_x; |
0ee56ec36a40
Limit ass_font_set_transform to nonrotating transformations.
eugeni
parents:
23212
diff
changeset
|
191 font->scale_y = scale_y; |
21616
2704273f398d
FT_Set_Transform is fast enough to be called once for each glyph.
eugeni
parents:
21615
diff
changeset
|
192 font->v.x = v->x; |
2704273f398d
FT_Set_Transform is fast enough to be called once for each glyph.
eugeni
parents:
21615
diff
changeset
|
193 font->v.y = v->y; |
23299
0ee56ec36a40
Limit ass_font_set_transform to nonrotating transformations.
eugeni
parents:
23212
diff
changeset
|
194 update_transform(font); |
21277 | 195 } |
196 | |
23328 | 197 static void face_set_size(FT_Face face, double size) |
198 { | |
23340 | 199 #if (FREETYPE_MAJOR > 2) || ((FREETYPE_MAJOR == 2) && (FREETYPE_MINOR > 1)) |
23328 | 200 TT_HoriHeader *hori = FT_Get_Sfnt_Table(face, ft_sfnt_hhea); |
201 TT_OS2 *os2 = FT_Get_Sfnt_Table(face, ft_sfnt_os2); | |
202 double mscale = 1.; | |
203 FT_Size_RequestRec rq; | |
204 FT_Size_Metrics *m = &face->size->metrics; | |
205 // VSFilter uses metrics from TrueType OS/2 table | |
206 // The idea was borrowed from asa (http://asa.diac24.net) | |
23983
90038c72d69e
Don't apply windows-like font scaling if hhea or os2 tables contain invalid
eugeni
parents:
23982
diff
changeset
|
207 if (hori && os2) { |
90038c72d69e
Don't apply windows-like font scaling if hhea or os2 tables contain invalid
eugeni
parents:
23982
diff
changeset
|
208 int hori_height = hori->Ascender - hori->Descender; |
90038c72d69e
Don't apply windows-like font scaling if hhea or os2 tables contain invalid
eugeni
parents:
23982
diff
changeset
|
209 int os2_height = os2->usWinAscent + os2->usWinDescent; |
90038c72d69e
Don't apply windows-like font scaling if hhea or os2 tables contain invalid
eugeni
parents:
23982
diff
changeset
|
210 if (hori_height && os2_height) |
90038c72d69e
Don't apply windows-like font scaling if hhea or os2 tables contain invalid
eugeni
parents:
23982
diff
changeset
|
211 mscale = (double)hori_height / os2_height; |
90038c72d69e
Don't apply windows-like font scaling if hhea or os2 tables contain invalid
eugeni
parents:
23982
diff
changeset
|
212 } |
23328 | 213 memset(&rq, 0, sizeof(rq)); |
214 rq.type = FT_SIZE_REQUEST_TYPE_REAL_DIM; | |
215 rq.width = 0; | |
216 rq.height = double_to_d6(size * mscale); | |
217 rq.horiResolution = rq.vertResolution = 0; | |
218 FT_Request_Size(face, &rq); | |
219 m->ascender /= mscale; | |
220 m->descender /= mscale; | |
221 m->height /= mscale; | |
23339
95bc9f4905f8
FT_Request_Size does not exist in FreeType 2.1.*. Fallback to FT_Set_Char_Size.
eugeni
parents:
23328
diff
changeset
|
222 #else |
95bc9f4905f8
FT_Request_Size does not exist in FreeType 2.1.*. Fallback to FT_Set_Char_Size.
eugeni
parents:
23328
diff
changeset
|
223 FT_Set_Char_Size(face, 0, double_to_d6(size), 0, 0); |
95bc9f4905f8
FT_Request_Size does not exist in FreeType 2.1.*. Fallback to FT_Set_Char_Size.
eugeni
parents:
23328
diff
changeset
|
224 #endif |
23328 | 225 } |
226 | |
21630 | 227 /** |
228 * \brief Set font size | |
229 **/ | |
23300 | 230 void ass_font_set_size(ass_font_t* font, double size) |
21277 | 231 { |
21619
b4b51eb2904f
Keep reselected fonts in an array, adding new ones to the end. Glyph
eugeni
parents:
21618
diff
changeset
|
232 int i; |
21319
415e2119e91c
Don't call FT_Set_Transform/FT_Set_Pixel_Sizes if values have not changed.
eugeni
parents:
21317
diff
changeset
|
233 if (font->size != size) { |
21320 | 234 font->size = size; |
21619
b4b51eb2904f
Keep reselected fonts in an array, adding new ones to the end. Glyph
eugeni
parents:
21618
diff
changeset
|
235 for (i = 0; i < font->n_faces; ++i) |
23328 | 236 face_set_size(font->faces[i], size); |
21319
415e2119e91c
Don't call FT_Set_Transform/FT_Set_Pixel_Sizes if values have not changed.
eugeni
parents:
21317
diff
changeset
|
237 } |
21277 | 238 } |
239 | |
21630 | 240 /** |
241 * \brief Get maximal font ascender and descender. | |
242 * \param ch character code | |
243 * The values are extracted from the font face that provides glyphs for the given character | |
244 **/ | |
21614
5d2ca7ca18b5
Move ascender, descender, and kerning computation to ass_font.c.
eugeni
parents:
21460
diff
changeset
|
245 void ass_font_get_asc_desc(ass_font_t* font, uint32_t ch, int* asc, int* desc) |
5d2ca7ca18b5
Move ascender, descender, and kerning computation to ass_font.c.
eugeni
parents:
21460
diff
changeset
|
246 { |
21619
b4b51eb2904f
Keep reselected fonts in an array, adding new ones to the end. Glyph
eugeni
parents:
21618
diff
changeset
|
247 int i; |
b4b51eb2904f
Keep reselected fonts in an array, adding new ones to the end. Glyph
eugeni
parents:
21618
diff
changeset
|
248 for (i = 0; i < font->n_faces; ++i) { |
21620 | 249 FT_Face face = font->faces[i]; |
250 if (FT_Get_Char_Index(face, ch)) { | |
251 int v, v2; | |
252 v = face->size->metrics.ascender; | |
253 v2 = FT_MulFix(face->bbox.yMax, face->size->metrics.y_scale); | |
254 *asc = (v > v2 * 0.9) ? v : v2; | |
21614
5d2ca7ca18b5
Move ascender, descender, and kerning computation to ass_font.c.
eugeni
parents:
21460
diff
changeset
|
255 |
21620 | 256 v = - face->size->metrics.descender; |
257 v2 = - FT_MulFix(face->bbox.yMin, face->size->metrics.y_scale); | |
258 *desc = (v > v2 * 0.9) ? v : v2; | |
259 return; | |
21619
b4b51eb2904f
Keep reselected fonts in an array, adding new ones to the end. Glyph
eugeni
parents:
21618
diff
changeset
|
260 } |
21614
5d2ca7ca18b5
Move ascender, descender, and kerning computation to ass_font.c.
eugeni
parents:
21460
diff
changeset
|
261 } |
5d2ca7ca18b5
Move ascender, descender, and kerning computation to ass_font.c.
eugeni
parents:
21460
diff
changeset
|
262 |
5d2ca7ca18b5
Move ascender, descender, and kerning computation to ass_font.c.
eugeni
parents:
21460
diff
changeset
|
263 *asc = *desc = 0; |
5d2ca7ca18b5
Move ascender, descender, and kerning computation to ass_font.c.
eugeni
parents:
21460
diff
changeset
|
264 } |
5d2ca7ca18b5
Move ascender, descender, and kerning computation to ass_font.c.
eugeni
parents:
21460
diff
changeset
|
265 |
21630 | 266 /** |
267 * \brief Get a glyph | |
268 * \param ch character code | |
269 **/ | |
23134
1de2a46a0987
Add -ass-hinting option for setting font hinting method.
eugeni
parents:
22210
diff
changeset
|
270 FT_Glyph ass_font_get_glyph(void* fontconfig_priv, ass_font_t* font, uint32_t ch, ass_hinting_t hinting) |
21277 | 271 { |
272 int error; | |
21619
b4b51eb2904f
Keep reselected fonts in an array, adding new ones to the end. Glyph
eugeni
parents:
21618
diff
changeset
|
273 int index = 0; |
b4b51eb2904f
Keep reselected fonts in an array, adding new ones to the end. Glyph
eugeni
parents:
21618
diff
changeset
|
274 int i; |
21277 | 275 FT_Glyph glyph; |
21619
b4b51eb2904f
Keep reselected fonts in an array, adding new ones to the end. Glyph
eugeni
parents:
21618
diff
changeset
|
276 FT_Face face = 0; |
23134
1de2a46a0987
Add -ass-hinting option for setting font hinting method.
eugeni
parents:
22210
diff
changeset
|
277 int flags = 0; |
21350 | 278 |
279 if (ch < 0x20) | |
280 return 0; | |
21619
b4b51eb2904f
Keep reselected fonts in an array, adding new ones to the end. Glyph
eugeni
parents:
21618
diff
changeset
|
281 if (font->n_faces == 0) |
b4b51eb2904f
Keep reselected fonts in an array, adding new ones to the end. Glyph
eugeni
parents:
21618
diff
changeset
|
282 return 0; |
b4b51eb2904f
Keep reselected fonts in an array, adding new ones to the end. Glyph
eugeni
parents:
21618
diff
changeset
|
283 |
b4b51eb2904f
Keep reselected fonts in an array, adding new ones to the end. Glyph
eugeni
parents:
21618
diff
changeset
|
284 for (i = 0; i < font->n_faces; ++i) { |
b4b51eb2904f
Keep reselected fonts in an array, adding new ones to the end. Glyph
eugeni
parents:
21618
diff
changeset
|
285 face = font->faces[i]; |
b4b51eb2904f
Keep reselected fonts in an array, adding new ones to the end. Glyph
eugeni
parents:
21618
diff
changeset
|
286 index = FT_Get_Char_Index(face, ch); |
b4b51eb2904f
Keep reselected fonts in an array, adding new ones to the end. Glyph
eugeni
parents:
21618
diff
changeset
|
287 if (index) |
b4b51eb2904f
Keep reselected fonts in an array, adding new ones to the end. Glyph
eugeni
parents:
21618
diff
changeset
|
288 break; |
b4b51eb2904f
Keep reselected fonts in an array, adding new ones to the end. Glyph
eugeni
parents:
21618
diff
changeset
|
289 } |
b4b51eb2904f
Keep reselected fonts in an array, adding new ones to the end. Glyph
eugeni
parents:
21618
diff
changeset
|
290 |
21351
c611dfc4cb85
If a glyph is not found in the current font, switch to another one.
eugeni
parents:
21350
diff
changeset
|
291 #ifdef HAVE_FONTCONFIG |
c611dfc4cb85
If a glyph is not found in the current font, switch to another one.
eugeni
parents:
21350
diff
changeset
|
292 if (index == 0) { |
23981
705628816d98
Factor out common code from ass_font_new and ass_font_reselect.
eugeni
parents:
23980
diff
changeset
|
293 int face_idx; |
21351
c611dfc4cb85
If a glyph is not found in the current font, switch to another one.
eugeni
parents:
21350
diff
changeset
|
294 mp_msg(MSGT_ASS, MSGL_INFO, MSGTR_LIBASS_GlyphNotFoundReselectingFont, |
c611dfc4cb85
If a glyph is not found in the current font, switch to another one.
eugeni
parents:
21350
diff
changeset
|
295 ch, font->desc.family, font->desc.bold, font->desc.italic); |
23981
705628816d98
Factor out common code from ass_font_new and ass_font_reselect.
eugeni
parents:
23980
diff
changeset
|
296 face_idx = add_face(fontconfig_priv, font, ch); |
24827 | 297 if (face_idx >= 0) { |
24828 | 298 face = font->faces[face_idx]; |
299 index = FT_Get_Char_Index(face, ch); | |
300 if (index == 0) { | |
301 mp_msg(MSGT_ASS, MSGL_ERR, MSGTR_LIBASS_GlyphNotFound, | |
302 ch, font->desc.family, font->desc.bold, font->desc.italic); | |
303 } | |
24827 | 304 } |
21351
c611dfc4cb85
If a glyph is not found in the current font, switch to another one.
eugeni
parents:
21350
diff
changeset
|
305 } |
c611dfc4cb85
If a glyph is not found in the current font, switch to another one.
eugeni
parents:
21350
diff
changeset
|
306 #endif |
c611dfc4cb85
If a glyph is not found in the current font, switch to another one.
eugeni
parents:
21350
diff
changeset
|
307 |
23134
1de2a46a0987
Add -ass-hinting option for setting font hinting method.
eugeni
parents:
22210
diff
changeset
|
308 switch (hinting) { |
1de2a46a0987
Add -ass-hinting option for setting font hinting method.
eugeni
parents:
22210
diff
changeset
|
309 case ASS_HINTING_NONE: flags = FT_LOAD_NO_HINTING; break; |
1de2a46a0987
Add -ass-hinting option for setting font hinting method.
eugeni
parents:
22210
diff
changeset
|
310 case ASS_HINTING_LIGHT: flags = FT_LOAD_FORCE_AUTOHINT | FT_LOAD_TARGET_LIGHT; break; |
1de2a46a0987
Add -ass-hinting option for setting font hinting method.
eugeni
parents:
22210
diff
changeset
|
311 case ASS_HINTING_NORMAL: flags = FT_LOAD_FORCE_AUTOHINT; break; |
1de2a46a0987
Add -ass-hinting option for setting font hinting method.
eugeni
parents:
22210
diff
changeset
|
312 case ASS_HINTING_NATIVE: flags = 0; break; |
1de2a46a0987
Add -ass-hinting option for setting font hinting method.
eugeni
parents:
22210
diff
changeset
|
313 } |
1de2a46a0987
Add -ass-hinting option for setting font hinting method.
eugeni
parents:
22210
diff
changeset
|
314 |
1de2a46a0987
Add -ass-hinting option for setting font hinting method.
eugeni
parents:
22210
diff
changeset
|
315 error = FT_Load_Glyph(face, index, FT_LOAD_NO_BITMAP | flags); |
21277 | 316 if (error) { |
317 mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_ErrorLoadingGlyph); | |
318 return 0; | |
319 } | |
320 | |
321 #if (FREETYPE_MAJOR > 2) || \ | |
322 ((FREETYPE_MAJOR == 2) && (FREETYPE_MINOR >= 2)) || \ | |
323 ((FREETYPE_MAJOR == 2) && (FREETYPE_MINOR == 1) && (FREETYPE_PATCH >= 10)) | |
324 // FreeType >= 2.1.10 required | |
21619
b4b51eb2904f
Keep reselected fonts in an array, adding new ones to the end. Glyph
eugeni
parents:
21618
diff
changeset
|
325 if (!(face->style_flags & FT_STYLE_FLAG_ITALIC) && |
21277 | 326 (font->desc.italic > 55)) { |
21619
b4b51eb2904f
Keep reselected fonts in an array, adding new ones to the end. Glyph
eugeni
parents:
21618
diff
changeset
|
327 FT_GlyphSlot_Oblique(face->glyph); |
21277 | 328 } |
329 #endif | |
21619
b4b51eb2904f
Keep reselected fonts in an array, adding new ones to the end. Glyph
eugeni
parents:
21618
diff
changeset
|
330 error = FT_Get_Glyph(face->glyph, &glyph); |
21277 | 331 if (error) { |
332 mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_ErrorLoadingGlyph); | |
333 return 0; | |
334 } | |
335 | |
336 return glyph; | |
337 } | |
338 | |
21630 | 339 /** |
340 * \brief Get kerning for the pair of glyphs. | |
341 **/ | |
21614
5d2ca7ca18b5
Move ascender, descender, and kerning computation to ass_font.c.
eugeni
parents:
21460
diff
changeset
|
342 FT_Vector ass_font_get_kerning(ass_font_t* font, uint32_t c1, uint32_t c2) |
5d2ca7ca18b5
Move ascender, descender, and kerning computation to ass_font.c.
eugeni
parents:
21460
diff
changeset
|
343 { |
5d2ca7ca18b5
Move ascender, descender, and kerning computation to ass_font.c.
eugeni
parents:
21460
diff
changeset
|
344 FT_Vector v = {0, 0}; |
21619
b4b51eb2904f
Keep reselected fonts in an array, adding new ones to the end. Glyph
eugeni
parents:
21618
diff
changeset
|
345 int i; |
b4b51eb2904f
Keep reselected fonts in an array, adding new ones to the end. Glyph
eugeni
parents:
21618
diff
changeset
|
346 |
b4b51eb2904f
Keep reselected fonts in an array, adding new ones to the end. Glyph
eugeni
parents:
21618
diff
changeset
|
347 for (i = 0; i < font->n_faces; ++i) { |
b4b51eb2904f
Keep reselected fonts in an array, adding new ones to the end. Glyph
eugeni
parents:
21618
diff
changeset
|
348 FT_Face face = font->faces[i]; |
b4b51eb2904f
Keep reselected fonts in an array, adding new ones to the end. Glyph
eugeni
parents:
21618
diff
changeset
|
349 int i1 = FT_Get_Char_Index(face, c1); |
b4b51eb2904f
Keep reselected fonts in an array, adding new ones to the end. Glyph
eugeni
parents:
21618
diff
changeset
|
350 int i2 = FT_Get_Char_Index(face, c2); |
b4b51eb2904f
Keep reselected fonts in an array, adding new ones to the end. Glyph
eugeni
parents:
21618
diff
changeset
|
351 if (i1 && i2) { |
b4b51eb2904f
Keep reselected fonts in an array, adding new ones to the end. Glyph
eugeni
parents:
21618
diff
changeset
|
352 if (FT_HAS_KERNING(face)) |
b4b51eb2904f
Keep reselected fonts in an array, adding new ones to the end. Glyph
eugeni
parents:
21618
diff
changeset
|
353 FT_Get_Kerning(face, i1, i2, FT_KERNING_DEFAULT, &v); |
b4b51eb2904f
Keep reselected fonts in an array, adding new ones to the end. Glyph
eugeni
parents:
21618
diff
changeset
|
354 return v; |
b4b51eb2904f
Keep reselected fonts in an array, adding new ones to the end. Glyph
eugeni
parents:
21618
diff
changeset
|
355 } |
b4b51eb2904f
Keep reselected fonts in an array, adding new ones to the end. Glyph
eugeni
parents:
21618
diff
changeset
|
356 if (i1 || i2) // these glyphs are from different font faces, no kerning information |
b4b51eb2904f
Keep reselected fonts in an array, adding new ones to the end. Glyph
eugeni
parents:
21618
diff
changeset
|
357 return v; |
b4b51eb2904f
Keep reselected fonts in an array, adding new ones to the end. Glyph
eugeni
parents:
21618
diff
changeset
|
358 } |
21614
5d2ca7ca18b5
Move ascender, descender, and kerning computation to ass_font.c.
eugeni
parents:
21460
diff
changeset
|
359 return v; |
5d2ca7ca18b5
Move ascender, descender, and kerning computation to ass_font.c.
eugeni
parents:
21460
diff
changeset
|
360 } |
5d2ca7ca18b5
Move ascender, descender, and kerning computation to ass_font.c.
eugeni
parents:
21460
diff
changeset
|
361 |
21630 | 362 /** |
363 * \brief Deallocate ass_font_t | |
364 **/ | |
21277 | 365 void ass_font_free(ass_font_t* font) |
366 { | |
21619
b4b51eb2904f
Keep reselected fonts in an array, adding new ones to the end. Glyph
eugeni
parents:
21618
diff
changeset
|
367 int i; |
b4b51eb2904f
Keep reselected fonts in an array, adding new ones to the end. Glyph
eugeni
parents:
21618
diff
changeset
|
368 for (i = 0; i < font->n_faces; ++i) |
b4b51eb2904f
Keep reselected fonts in an array, adding new ones to the end. Glyph
eugeni
parents:
21618
diff
changeset
|
369 if (font->faces[i]) FT_Done_Face(font->faces[i]); |
21277 | 370 if (font->desc.family) free(font->desc.family); |
21317 | 371 free(font); |
21277 | 372 } |