Mercurial > mplayer.hg
annotate libass/ass_font.c @ 31685:31b6397e3b28
Another try at fixing swscale on win64, as per r31153.
Don't change paramater passing, but instead use casts.
Shouldn't affect asm output on anything other than win64.
libswscale should work on win64 now.
The rest of ffmpeg still isn't win64 compatible due to the issue of xmm
clobbers, but swscale doesn't use any SSE.
Patch by Anton Mitrofanov <BugMaster AT narod DOT ru>.
author | darkshikari |
---|---|
date | Sun, 18 Jul 2010 21:39:57 +0000 |
parents | 48d020c5ceca |
children | e64df5862cea |
rev | line source |
---|---|
21277 | 1 /* |
26723 | 2 * Copyright (C) 2006 Evgeniy Stepanov <eugeni.stepanov@gmail.com> |
3 * | |
26738
588ce97b44f2
Speak of libass instead of MPlayer in the libass license headers.
diego
parents:
26723
diff
changeset
|
4 * This file is part of libass. |
26723 | 5 * |
26738
588ce97b44f2
Speak of libass instead of MPlayer in the libass license headers.
diego
parents:
26723
diff
changeset
|
6 * libass is free software; you can redistribute it and/or modify |
26723 | 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 * | |
26738
588ce97b44f2
Speak of libass instead of MPlayer in the libass license headers.
diego
parents:
26723
diff
changeset
|
11 * libass is distributed in the hope that it will be useful, |
26723 | 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 along | |
26738
588ce97b44f2
Speak of libass instead of MPlayer in the libass license headers.
diego
parents:
26723
diff
changeset
|
17 * with libass; if not, write to the Free Software Foundation, Inc., |
26723 | 18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
19 */ | |
21277 | 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 |
30200 | 29 #include FT_OUTLINE_H |
21277 | 30 |
21458
7af6c25a0cfc
Keep embedded fonts in ass_library_t and perform actual disk write
eugeni
parents:
21351
diff
changeset
|
31 #include "ass.h" |
7af6c25a0cfc
Keep embedded fonts in ass_library_t and perform actual disk write
eugeni
parents:
21351
diff
changeset
|
32 #include "ass_library.h" |
21277 | 33 #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
|
34 #include "ass_bitmap.h" |
7b7627ff1937
Move ass_font_desc_t and ass_font_t declarations to ass_font.h.
eugeni
parents:
21320
diff
changeset
|
35 #include "ass_cache.h" |
21277 | 36 #include "ass_fontconfig.h" |
23299
0ee56ec36a40
Limit ass_font_set_transform to nonrotating transformations.
eugeni
parents:
23212
diff
changeset
|
37 #include "ass_utils.h" |
21277 | 38 |
39 /** | |
40 * Select Microfost Unicode CharMap, if the font has one. | |
41 * Otherwise, let FreeType decide. | |
42 */ | |
30200 | 43 static void charmap_magic(ASS_Library *library, FT_Face face) |
21277 | 44 { |
30200 | 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 */ | |
51 && (eid == 1 /*unicode bmp */ | |
52 || eid == 10 /*full unicode */ )) { | |
53 FT_Set_Charmap(face, cmap); | |
54 return; | |
55 } | |
56 } | |
22210
4a958bd08920
Select the first charmap in the font, if FreeType did not autoselect any.
eugeni
parents:
21630
diff
changeset
|
57 |
30200 | 58 if (!face->charmap) { |
59 if (face->num_charmaps == 0) { | |
60 ass_msg(library, MSGL_WARN, "Font face with no charmaps"); | |
61 return; | |
62 } | |
63 ass_msg(library, MSGL_WARN, | |
64 "No charmap autodetected, trying the first one"); | |
65 FT_Set_Charmap(face, face->charmaps[0]); | |
66 return; | |
67 } | |
21277 | 68 } |
69 | |
30200 | 70 static void update_transform(ASS_Font *font) |
23299
0ee56ec36a40
Limit ass_font_set_transform to nonrotating transformations.
eugeni
parents:
23212
diff
changeset
|
71 { |
30200 | 72 int i; |
73 FT_Matrix m; | |
74 m.xx = double_to_d16(font->scale_x); | |
75 m.yy = double_to_d16(font->scale_y); | |
76 m.xy = m.yx = 0; | |
77 for (i = 0; i < font->n_faces; ++i) | |
78 FT_Set_Transform(font->faces[i], &m, &font->v); | |
23299
0ee56ec36a40
Limit ass_font_set_transform to nonrotating transformations.
eugeni
parents:
23212
diff
changeset
|
79 } |
0ee56ec36a40
Limit ass_font_set_transform to nonrotating transformations.
eugeni
parents:
23212
diff
changeset
|
80 |
21630 | 81 /** |
82 * \brief find a memory font by name | |
83 */ | |
30200 | 84 static int find_font(ASS_Library *library, char *name) |
21460 | 85 { |
30200 | 86 int i; |
87 for (i = 0; i < library->num_fontdata; ++i) | |
88 if (strcasecmp(name, library->fontdata[i].name) == 0) | |
89 return i; | |
90 return -1; | |
21460 | 91 } |
92 | |
23981
705628816d98
Factor out common code from ass_font_new and ass_font_reselect.
eugeni
parents:
23980
diff
changeset
|
93 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
|
94 |
23982
17b5fa69243c
Workaround for fonts with zero ascender/descender in horizontal header.
eugeni
parents:
23981
diff
changeset
|
95 static void buggy_font_workaround(FT_Face face) |
17b5fa69243c
Workaround for fonts with zero ascender/descender in horizontal header.
eugeni
parents:
23981
diff
changeset
|
96 { |
30200 | 97 // Some fonts have zero Ascender/Descender fields in 'hhea' table. |
98 // In this case, get the information from 'os2' table or, as | |
99 // a last resort, from face.bbox. | |
100 if (face->ascender + face->descender == 0 || face->height == 0) { | |
101 TT_OS2 *os2 = FT_Get_Sfnt_Table(face, ft_sfnt_os2); | |
102 if (os2) { | |
103 face->ascender = os2->sTypoAscender; | |
104 face->descender = os2->sTypoDescender; | |
105 face->height = face->ascender - face->descender; | |
106 } else { | |
107 face->ascender = face->bbox.yMax; | |
108 face->descender = face->bbox.yMin; | |
109 face->height = face->ascender - face->descender; | |
110 } | |
111 } | |
23982
17b5fa69243c
Workaround for fonts with zero ascender/descender in horizontal header.
eugeni
parents:
23981
diff
changeset
|
112 } |
17b5fa69243c
Workaround for fonts with zero ascender/descender in horizontal header.
eugeni
parents:
23981
diff
changeset
|
113 |
23981
705628816d98
Factor out common code from ass_font_new and ass_font_reselect.
eugeni
parents:
23980
diff
changeset
|
114 /** |
30200 | 115 * \brief Select a face with the given charcode and add it to ASS_Font |
23981
705628816d98
Factor out common code from ass_font_new and ass_font_reselect.
eugeni
parents:
23980
diff
changeset
|
116 * \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
|
117 */ |
30200 | 118 static int add_face(void *fc_priv, ASS_Font *font, uint32_t ch) |
23981
705628816d98
Factor out common code from ass_font_new and ass_font_reselect.
eugeni
parents:
23980
diff
changeset
|
119 { |
30200 | 120 char *path; |
121 int index; | |
122 FT_Face face; | |
123 int error; | |
124 int mem_idx; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28860
diff
changeset
|
125 |
30200 | 126 if (font->n_faces == ASS_FONT_MAX_FACES) |
127 return -1; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28860
diff
changeset
|
128 |
30200 | 129 path = |
130 fontconfig_select(font->library, fc_priv, font->desc.family, | |
131 font->desc.treat_family_as_pattern, | |
132 font->desc.bold, font->desc.italic, &index, ch); | |
133 if (!path) | |
134 return -1; | |
23981
705628816d98
Factor out common code from ass_font_new and ass_font_reselect.
eugeni
parents:
23980
diff
changeset
|
135 |
30200 | 136 mem_idx = find_font(font->library, path); |
137 if (mem_idx >= 0) { | |
138 error = | |
139 FT_New_Memory_Face(font->ftlibrary, | |
140 (unsigned char *) font->library-> | |
141 fontdata[mem_idx].data, | |
142 font->library->fontdata[mem_idx].size, 0, | |
143 &face); | |
144 if (error) { | |
145 ass_msg(font->library, MSGL_WARN, | |
146 "Error opening memory font: '%s'", path); | |
147 free(path); | |
148 return -1; | |
149 } | |
150 } else { | |
151 error = FT_New_Face(font->ftlibrary, path, index, &face); | |
152 if (error) { | |
153 ass_msg(font->library, MSGL_WARN, | |
154 "Error opening font: '%s', %d", path, index); | |
155 free(path); | |
156 return -1; | |
157 } | |
158 } | |
159 charmap_magic(font->library, face); | |
160 buggy_font_workaround(face); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28860
diff
changeset
|
161 |
30200 | 162 font->faces[font->n_faces++] = face; |
163 update_transform(font); | |
164 face_set_size(face, font->size); | |
165 free(path); | |
166 return font->n_faces - 1; | |
23981
705628816d98
Factor out common code from ass_font_new and ass_font_reselect.
eugeni
parents:
23980
diff
changeset
|
167 } |
705628816d98
Factor out common code from ass_font_new and ass_font_reselect.
eugeni
parents:
23980
diff
changeset
|
168 |
21630 | 169 /** |
30200 | 170 * \brief Create a new ASS_Font according to "desc" argument |
21630 | 171 */ |
30200 | 172 ASS_Font *ass_font_new(void *font_cache, ASS_Library *library, |
173 FT_Library ftlibrary, void *fc_priv, | |
174 ASS_FontDesc *desc) | |
21277 | 175 { |
30200 | 176 int error; |
177 ASS_Font *fontp; | |
178 ASS_Font font; | |
21317 | 179 |
30200 | 180 fontp = ass_font_cache_find((Hashmap *) font_cache, desc); |
181 if (fontp) | |
182 return fontp; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28860
diff
changeset
|
183 |
30200 | 184 font.library = library; |
185 font.ftlibrary = ftlibrary; | |
186 font.n_faces = 0; | |
187 font.desc.family = strdup(desc->family); | |
188 font.desc.treat_family_as_pattern = desc->treat_family_as_pattern; | |
189 font.desc.bold = desc->bold; | |
190 font.desc.italic = desc->italic; | |
21277 | 191 |
30200 | 192 font.scale_x = font.scale_y = 1.; |
193 font.v.x = font.v.y = 0; | |
194 font.size = 0.; | |
21277 | 195 |
30200 | 196 error = add_face(fc_priv, &font, 0); |
197 if (error == -1) { | |
198 free(font.desc.family); | |
199 return 0; | |
200 } else | |
201 return ass_font_cache_add((Hashmap *) font_cache, &font); | |
21277 | 202 } |
203 | |
21630 | 204 /** |
205 * \brief Set font transformation matrix and shift vector | |
206 **/ | |
30200 | 207 void ass_font_set_transform(ASS_Font *font, double scale_x, |
208 double scale_y, FT_Vector *v) | |
21277 | 209 { |
30200 | 210 font->scale_x = scale_x; |
211 font->scale_y = scale_y; | |
212 if (v) { | |
213 font->v.x = v->x; | |
214 font->v.y = v->y; | |
215 } | |
216 update_transform(font); | |
21277 | 217 } |
218 | |
23328 | 219 static void face_set_size(FT_Face face, double size) |
220 { | |
30200 | 221 TT_HoriHeader *hori = FT_Get_Sfnt_Table(face, ft_sfnt_hhea); |
222 TT_OS2 *os2 = FT_Get_Sfnt_Table(face, ft_sfnt_os2); | |
223 double mscale = 1.; | |
224 FT_Size_RequestRec rq; | |
225 FT_Size_Metrics *m = &face->size->metrics; | |
226 // VSFilter uses metrics from TrueType OS/2 table | |
227 // The idea was borrowed from asa (http://asa.diac24.net) | |
228 if (hori && os2) { | |
229 int hori_height = hori->Ascender - hori->Descender; | |
230 int os2_height = os2->usWinAscent + os2->usWinDescent; | |
231 if (hori_height && os2_height) | |
232 mscale = (double) hori_height / os2_height; | |
233 } | |
234 memset(&rq, 0, sizeof(rq)); | |
235 rq.type = FT_SIZE_REQUEST_TYPE_REAL_DIM; | |
236 rq.width = 0; | |
237 rq.height = double_to_d6(size * mscale); | |
238 rq.horiResolution = rq.vertResolution = 0; | |
239 FT_Request_Size(face, &rq); | |
240 m->ascender /= mscale; | |
241 m->descender /= mscale; | |
242 m->height /= mscale; | |
23328 | 243 } |
244 | |
21630 | 245 /** |
246 * \brief Set font size | |
247 **/ | |
30200 | 248 void ass_font_set_size(ASS_Font *font, double size) |
21277 | 249 { |
30200 | 250 int i; |
251 if (font->size != size) { | |
252 font->size = size; | |
253 for (i = 0; i < font->n_faces; ++i) | |
254 face_set_size(font->faces[i], size); | |
255 } | |
21277 | 256 } |
257 | |
21630 | 258 /** |
259 * \brief Get maximal font ascender and descender. | |
260 * \param ch character code | |
261 * The values are extracted from the font face that provides glyphs for the given character | |
262 **/ | |
30200 | 263 void ass_font_get_asc_desc(ASS_Font *font, uint32_t ch, int *asc, |
264 int *desc) | |
265 { | |
266 int i; | |
267 for (i = 0; i < font->n_faces; ++i) { | |
268 FT_Face face = font->faces[i]; | |
269 TT_OS2 *os2 = FT_Get_Sfnt_Table(face, ft_sfnt_os2); | |
270 if (FT_Get_Char_Index(face, ch)) { | |
271 int y_scale = face->size->metrics.y_scale; | |
272 if (os2) { | |
273 *asc = FT_MulFix(os2->usWinAscent, y_scale); | |
274 *desc = FT_MulFix(os2->usWinDescent, y_scale); | |
275 } else { | |
276 *asc = FT_MulFix(face->ascender, y_scale); | |
277 *desc = FT_MulFix(-face->descender, y_scale); | |
278 } | |
279 return; | |
280 } | |
281 } | |
282 | |
283 *asc = *desc = 0; | |
284 } | |
285 | |
286 /* | |
287 * Strike a glyph with a horizontal line; it's possible to underline it | |
288 * and/or strike through it. For the line's position and size, truetype | |
289 * tables are consulted. Obviously this relies on the data in the tables | |
290 * being accurate. | |
291 * | |
292 */ | |
293 static int ass_strike_outline_glyph(FT_Face face, ASS_Font *font, | |
294 FT_Glyph glyph, int under, int through) | |
21614
5d2ca7ca18b5
Move ascender, descender, and kerning computation to ass_font.c.
eugeni
parents:
21460
diff
changeset
|
295 { |
30200 | 296 TT_OS2 *os2 = FT_Get_Sfnt_Table(face, ft_sfnt_os2); |
297 TT_Postscript *ps = FT_Get_Sfnt_Table(face, ft_sfnt_post); | |
298 FT_Outline *ol = &((FT_OutlineGlyph) glyph)->outline; | |
299 int bear, advance, y_scale, i, dir; | |
300 | |
301 if (!under && !through) | |
302 return 0; | |
303 | |
304 // Grow outline | |
305 i = (under ? 4 : 0) + (through ? 4 : 0); | |
306 ol->points = realloc(ol->points, sizeof(FT_Vector) * | |
307 (ol->n_points + i)); | |
308 ol->tags = realloc(ol->tags, ol->n_points + i); | |
309 i = !!under + !!through; | |
310 ol->contours = realloc(ol->contours, sizeof(short) * | |
311 (ol->n_contours + i)); | |
312 | |
313 // If the bearing is negative, the glyph starts left of the current | |
314 // pen position | |
315 bear = FFMIN(face->glyph->metrics.horiBearingX, 0); | |
316 // We're adding half a pixel to avoid small gaps | |
317 advance = d16_to_d6(glyph->advance.x) + 32; | |
318 y_scale = face->size->metrics.y_scale; | |
319 | |
320 // Reverse drawing direction for non-truetype fonts | |
321 dir = FT_Outline_Get_Orientation(ol); | |
322 | |
323 // Add points to the outline | |
324 if (under && ps) { | |
325 int pos, size; | |
326 pos = FT_MulFix(ps->underlinePosition, y_scale * font->scale_y); | |
327 size = FT_MulFix(ps->underlineThickness, | |
328 y_scale * font->scale_y / 2); | |
329 | |
330 if (pos > 0 || size <= 0) | |
331 return 1; | |
332 | |
333 FT_Vector points[4] = { | |
334 {.x = bear, .y = pos + size}, | |
335 {.x = advance, .y = pos + size}, | |
336 {.x = advance, .y = pos - size}, | |
337 {.x = bear, .y = pos - size}, | |
338 }; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28860
diff
changeset
|
339 |
30200 | 340 if (dir == FT_ORIENTATION_TRUETYPE) { |
341 for (i = 0; i < 4; i++) { | |
342 ol->points[ol->n_points] = points[i]; | |
343 ol->tags[ol->n_points++] = 1; | |
344 } | |
345 } else { | |
346 for (i = 3; i >= 0; i--) { | |
347 ol->points[ol->n_points] = points[i]; | |
348 ol->tags[ol->n_points++] = 1; | |
349 } | |
350 } | |
351 | |
352 ol->contours[ol->n_contours++] = ol->n_points - 1; | |
353 } | |
354 | |
355 if (through && os2) { | |
356 int pos, size; | |
357 pos = FT_MulFix(os2->yStrikeoutPosition, y_scale * font->scale_y); | |
358 size = FT_MulFix(os2->yStrikeoutSize, y_scale * font->scale_y / 2); | |
359 | |
360 if (pos < 0 || size <= 0) | |
361 return 1; | |
362 | |
363 FT_Vector points[4] = { | |
364 {.x = bear, .y = pos + size}, | |
365 {.x = advance, .y = pos + size}, | |
366 {.x = advance, .y = pos - size}, | |
367 {.x = bear, .y = pos - size}, | |
368 }; | |
369 | |
370 if (dir == FT_ORIENTATION_TRUETYPE) { | |
371 for (i = 0; i < 4; i++) { | |
372 ol->points[ol->n_points] = points[i]; | |
373 ol->tags[ol->n_points++] = 1; | |
374 } | |
375 } else { | |
376 for (i = 3; i >= 0; i--) { | |
377 ol->points[ol->n_points] = points[i]; | |
378 ol->tags[ol->n_points++] = 1; | |
379 } | |
380 } | |
381 | |
382 ol->contours[ol->n_contours++] = ol->n_points - 1; | |
383 } | |
384 | |
385 return 0; | |
386 } | |
387 | |
388 /** | |
389 * Slightly embold a glyph without touching its metrics | |
390 */ | |
391 static void ass_glyph_embolden(FT_GlyphSlot slot) | |
392 { | |
393 int str; | |
394 | |
395 if (slot->format != FT_GLYPH_FORMAT_OUTLINE) | |
396 return; | |
397 | |
398 str = FT_MulFix(slot->face->units_per_EM, | |
399 slot->face->size->metrics.y_scale) / 64; | |
400 | |
401 FT_Outline_Embolden(&slot->outline, str); | |
21614
5d2ca7ca18b5
Move ascender, descender, and kerning computation to ass_font.c.
eugeni
parents:
21460
diff
changeset
|
402 } |
5d2ca7ca18b5
Move ascender, descender, and kerning computation to ass_font.c.
eugeni
parents:
21460
diff
changeset
|
403 |
21630 | 404 /** |
405 * \brief Get a glyph | |
406 * \param ch character code | |
407 **/ | |
30200 | 408 FT_Glyph ass_font_get_glyph(void *fontconfig_priv, ASS_Font *font, |
409 uint32_t ch, ASS_Hinting hinting, int deco) | |
21277 | 410 { |
30200 | 411 int error; |
412 int index = 0; | |
413 int i; | |
414 FT_Glyph glyph; | |
415 FT_Face face = 0; | |
416 int flags = 0; | |
21350 | 417 |
30200 | 418 if (ch < 0x20) |
419 return 0; | |
420 // Handle NBSP like a regular space when rendering the glyph | |
421 if (ch == 0xa0) | |
422 ch = ' '; | |
423 if (font->n_faces == 0) | |
424 return 0; | |
21619
b4b51eb2904f
Keep reselected fonts in an array, adding new ones to the end. Glyph
eugeni
parents:
21618
diff
changeset
|
425 |
30200 | 426 for (i = 0; i < font->n_faces; ++i) { |
427 face = font->faces[i]; | |
428 index = FT_Get_Char_Index(face, ch); | |
429 if (index) | |
430 break; | |
431 } | |
21619
b4b51eb2904f
Keep reselected fonts in an array, adding new ones to the end. Glyph
eugeni
parents:
21618
diff
changeset
|
432 |
27393 | 433 #ifdef CONFIG_FONTCONFIG |
30200 | 434 if (index == 0) { |
435 int face_idx; | |
436 ass_msg(font->library, MSGL_INFO, | |
437 "Glyph 0x%X not found, selecting one more " | |
438 "font for (%s, %d, %d)", ch, font->desc.family, | |
439 font->desc.bold, font->desc.italic); | |
440 face_idx = add_face(fontconfig_priv, font, ch); | |
441 if (face_idx >= 0) { | |
442 face = font->faces[face_idx]; | |
443 index = FT_Get_Char_Index(face, ch); | |
444 if (index == 0) { | |
445 ass_msg(font->library, MSGL_ERR, | |
446 "Glyph 0x%X not found in font for (%s, %d, %d)", | |
447 ch, font->desc.family, font->desc.bold, | |
448 font->desc.italic); | |
449 } | |
450 } | |
451 } | |
21351
c611dfc4cb85
If a glyph is not found in the current font, switch to another one.
eugeni
parents:
21350
diff
changeset
|
452 #endif |
c611dfc4cb85
If a glyph is not found in the current font, switch to another one.
eugeni
parents:
21350
diff
changeset
|
453 |
30200 | 454 switch (hinting) { |
455 case ASS_HINTING_NONE: | |
456 flags = FT_LOAD_NO_HINTING; | |
457 break; | |
458 case ASS_HINTING_LIGHT: | |
459 flags = FT_LOAD_FORCE_AUTOHINT | FT_LOAD_TARGET_LIGHT; | |
460 break; | |
461 case ASS_HINTING_NORMAL: | |
462 flags = FT_LOAD_FORCE_AUTOHINT; | |
463 break; | |
464 case ASS_HINTING_NATIVE: | |
465 flags = 0; | |
466 break; | |
467 } | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28860
diff
changeset
|
468 |
30200 | 469 error = FT_Load_Glyph(face, index, FT_LOAD_NO_BITMAP | flags); |
470 if (error) { | |
471 ass_msg(font->library, MSGL_WARN, "Error loading glyph, index %d", | |
472 index); | |
473 return 0; | |
474 } | |
475 if (!(face->style_flags & FT_STYLE_FLAG_ITALIC) && | |
476 (font->desc.italic > 55)) { | |
477 FT_GlyphSlot_Oblique(face->glyph); | |
478 } | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28860
diff
changeset
|
479 |
30200 | 480 if (!(face->style_flags & FT_STYLE_FLAG_BOLD) && |
481 (font->desc.bold > 80)) { | |
482 ass_glyph_embolden(face->glyph); | |
483 } | |
484 error = FT_Get_Glyph(face->glyph, &glyph); | |
485 if (error) { | |
486 ass_msg(font->library, MSGL_WARN, "Error loading glyph, index %d", | |
487 index); | |
488 return 0; | |
489 } | |
490 | |
491 ass_strike_outline_glyph(face, font, glyph, deco & DECO_UNDERLINE, | |
492 deco & DECO_STRIKETHROUGH); | |
493 | |
494 return glyph; | |
21277 | 495 } |
496 | |
21630 | 497 /** |
498 * \brief Get kerning for the pair of glyphs. | |
499 **/ | |
30200 | 500 FT_Vector ass_font_get_kerning(ASS_Font *font, uint32_t c1, uint32_t c2) |
21614
5d2ca7ca18b5
Move ascender, descender, and kerning computation to ass_font.c.
eugeni
parents:
21460
diff
changeset
|
501 { |
30200 | 502 FT_Vector v = { 0, 0 }; |
503 int i; | |
21619
b4b51eb2904f
Keep reselected fonts in an array, adding new ones to the end. Glyph
eugeni
parents:
21618
diff
changeset
|
504 |
30200 | 505 for (i = 0; i < font->n_faces; ++i) { |
506 FT_Face face = font->faces[i]; | |
507 int i1 = FT_Get_Char_Index(face, c1); | |
508 int i2 = FT_Get_Char_Index(face, c2); | |
509 if (i1 && i2) { | |
510 if (FT_HAS_KERNING(face)) | |
511 FT_Get_Kerning(face, i1, i2, FT_KERNING_DEFAULT, &v); | |
512 return v; | |
513 } | |
514 if (i1 || i2) // these glyphs are from different font faces, no kerning information | |
515 return v; | |
516 } | |
517 return v; | |
21614
5d2ca7ca18b5
Move ascender, descender, and kerning computation to ass_font.c.
eugeni
parents:
21460
diff
changeset
|
518 } |
5d2ca7ca18b5
Move ascender, descender, and kerning computation to ass_font.c.
eugeni
parents:
21460
diff
changeset
|
519 |
21630 | 520 /** |
30200 | 521 * \brief Deallocate ASS_Font |
21630 | 522 **/ |
30200 | 523 void ass_font_free(ASS_Font *font) |
21277 | 524 { |
30200 | 525 int i; |
526 for (i = 0; i < font->n_faces; ++i) | |
527 if (font->faces[i]) | |
528 FT_Done_Face(font->faces[i]); | |
529 if (font->desc.family) | |
530 free(font->desc.family); | |
531 free(font); | |
21277 | 532 } |