annotate libass/ass_font.c @ 34114:113156bc1137

Ensure that filename related config will always be loaded. Currently, filename related config will only be loaded if MPlayer knows the filename when it gets called, which isn't the case if either MPlayer is called in slave mode or the GUI is called without file argument. In either case, the file to be played is known only later. If filename related config hasn't yet been read, do it after leaving the idle mode loop.
author ib
date Sat, 15 Oct 2011 11:07:29 +0000
parents 88eebbbbd6a0
children 6e7f60f6f9d4
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
21277
0603972f083c Move fonts-related code to a separate file.
eugeni
parents:
diff changeset
1 /*
26723
0f892cd714b2 Use standard license header.
diego
parents: 25660
diff changeset
2 * Copyright (C) 2006 Evgeniy Stepanov <eugeni.stepanov@gmail.com>
0f892cd714b2 Use standard license header.
diego
parents: 25660
diff changeset
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
0f892cd714b2 Use standard license header.
diego
parents: 25660
diff changeset
5 *
34011
88eebbbbd6a0 Update included libass copy to 0.9.13 release.
reimar
parents: 31875
diff changeset
6 * Permission to use, copy, modify, and distribute this software for any
88eebbbbd6a0 Update included libass copy to 0.9.13 release.
reimar
parents: 31875
diff changeset
7 * purpose with or without fee is hereby granted, provided that the above
88eebbbbd6a0 Update included libass copy to 0.9.13 release.
reimar
parents: 31875
diff changeset
8 * copyright notice and this permission notice appear in all copies.
26723
0f892cd714b2 Use standard license header.
diego
parents: 25660
diff changeset
9 *
34011
88eebbbbd6a0 Update included libass copy to 0.9.13 release.
reimar
parents: 31875
diff changeset
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
88eebbbbd6a0 Update included libass copy to 0.9.13 release.
reimar
parents: 31875
diff changeset
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
88eebbbbd6a0 Update included libass copy to 0.9.13 release.
reimar
parents: 31875
diff changeset
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
88eebbbbd6a0 Update included libass copy to 0.9.13 release.
reimar
parents: 31875
diff changeset
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
88eebbbbd6a0 Update included libass copy to 0.9.13 release.
reimar
parents: 31875
diff changeset
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
88eebbbbd6a0 Update included libass copy to 0.9.13 release.
reimar
parents: 31875
diff changeset
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
88eebbbbd6a0 Update included libass copy to 0.9.13 release.
reimar
parents: 31875
diff changeset
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
26723
0f892cd714b2 Use standard license header.
diego
parents: 25660
diff changeset
17 */
21277
0603972f083c Move fonts-related code to a separate file.
eugeni
parents:
diff changeset
18
0603972f083c Move fonts-related code to a separate file.
eugeni
parents:
diff changeset
19 #include "config.h"
0603972f083c Move fonts-related code to a separate file.
eugeni
parents:
diff changeset
20
0603972f083c Move fonts-related code to a separate file.
eugeni
parents:
diff changeset
21 #include <inttypes.h>
0603972f083c Move fonts-related code to a separate file.
eugeni
parents:
diff changeset
22 #include <ft2build.h>
0603972f083c Move fonts-related code to a separate file.
eugeni
parents:
diff changeset
23 #include FT_FREETYPE_H
0603972f083c Move fonts-related code to a separate file.
eugeni
parents:
diff changeset
24 #include FT_SYNTHESIS_H
0603972f083c Move fonts-related code to a separate file.
eugeni
parents:
diff changeset
25 #include FT_GLYPH_H
23328
99ac5d381aed Correct font size in libass.
eugeni
parents: 23300
diff changeset
26 #include FT_TRUETYPE_TABLES_H
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
27 #include FT_OUTLINE_H
31875
ac6e48baa03d Import libass 0.9.11
greg
parents: 31853
diff changeset
28 #include <strings.h>
21277
0603972f083c Move fonts-related code to a separate file.
eugeni
parents:
diff changeset
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
0603972f083c Move fonts-related code to a separate file.
eugeni
parents:
diff changeset
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
0603972f083c Move fonts-related code to a separate file.
eugeni
parents:
diff changeset
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
0603972f083c Move fonts-related code to a separate file.
eugeni
parents:
diff changeset
37
31853
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
38 #define VERTICAL_LOWER_BOUND 0x02f1
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
39
21277
0603972f083c Move fonts-related code to a separate file.
eugeni
parents:
diff changeset
40 /**
31853
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
41 * Select a good charmap, prefer Microsoft Unicode charmaps.
21277
0603972f083c Move fonts-related code to a separate file.
eugeni
parents:
diff changeset
42 * Otherwise, let FreeType decide.
0603972f083c Move fonts-related code to a separate file.
eugeni
parents:
diff changeset
43 */
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
44 static void charmap_magic(ASS_Library *library, FT_Face face)
21277
0603972f083c Move fonts-related code to a separate file.
eugeni
parents:
diff changeset
45 {
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
46 int i;
31853
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
47 int ms_cmap = -1;
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
48
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
49 // Search for a Microsoft Unicode cmap
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
50 for (i = 0; i < face->num_charmaps; ++i) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
51 FT_CharMap cmap = face->charmaps[i];
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
52 unsigned pid = cmap->platform_id;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
53 unsigned eid = cmap->encoding_id;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
54 if (pid == 3 /*microsoft */
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
55 && (eid == 1 /*unicode bmp */
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
56 || eid == 10 /*full unicode */ )) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
57 FT_Set_Charmap(face, cmap);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
58 return;
31853
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
59 } else if (pid == 3 && ms_cmap < 0)
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
60 ms_cmap = i;
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
61 }
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
62
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
63 // Try the first Microsoft cmap if no Microsoft Unicode cmap was found
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
64 if (ms_cmap >= 0) {
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
65 FT_CharMap cmap = face->charmaps[ms_cmap];
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
66 FT_Set_Charmap(face, cmap);
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
67 return;
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
68 }
22210
4a958bd08920 Select the first charmap in the font, if FreeType did not autoselect any.
eugeni
parents: 21630
diff changeset
69
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
70 if (!face->charmap) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
71 if (face->num_charmaps == 0) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
72 ass_msg(library, MSGL_WARN, "Font face with no charmaps");
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
73 return;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
74 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
75 ass_msg(library, MSGL_WARN,
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
76 "No charmap autodetected, trying the first one");
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
77 FT_Set_Charmap(face, face->charmaps[0]);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
78 return;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
79 }
21277
0603972f083c Move fonts-related code to a separate file.
eugeni
parents:
diff changeset
80 }
0603972f083c Move fonts-related code to a separate file.
eugeni
parents:
diff changeset
81
21630
0d8005d2fe5c Update some comments.
eugeni
parents: 21620
diff changeset
82 /**
0d8005d2fe5c Update some comments.
eugeni
parents: 21620
diff changeset
83 * \brief find a memory font by name
0d8005d2fe5c Update some comments.
eugeni
parents: 21620
diff changeset
84 */
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
85 static int find_font(ASS_Library *library, char *name)
21460
62bd8e0d3a0f Open embedded fonts directly from memory.
eugeni
parents: 21458
diff changeset
86 {
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
87 int i;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
88 for (i = 0; i < library->num_fontdata; ++i)
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
89 if (strcasecmp(name, library->fontdata[i].name) == 0)
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
90 return i;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
91 return -1;
21460
62bd8e0d3a0f Open embedded fonts directly from memory.
eugeni
parents: 21458
diff changeset
92 }
62bd8e0d3a0f Open embedded fonts directly from memory.
eugeni
parents: 21458
diff changeset
93
23981
705628816d98 Factor out common code from ass_font_new and ass_font_reselect.
eugeni
parents: 23980
diff changeset
94 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
95
23982
17b5fa69243c Workaround for fonts with zero ascender/descender in horizontal header.
eugeni
parents: 23981
diff changeset
96 static void buggy_font_workaround(FT_Face face)
17b5fa69243c Workaround for fonts with zero ascender/descender in horizontal header.
eugeni
parents: 23981
diff changeset
97 {
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
98 // Some fonts have zero Ascender/Descender fields in 'hhea' table.
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
99 // In this case, get the information from 'os2' table or, as
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
100 // a last resort, from face.bbox.
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
101 if (face->ascender + face->descender == 0 || face->height == 0) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
102 TT_OS2 *os2 = FT_Get_Sfnt_Table(face, ft_sfnt_os2);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
103 if (os2) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
104 face->ascender = os2->sTypoAscender;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
105 face->descender = os2->sTypoDescender;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
106 face->height = face->ascender - face->descender;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
107 } else {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
108 face->ascender = face->bbox.yMax;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
109 face->descender = face->bbox.yMin;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
110 face->height = face->ascender - face->descender;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
111 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
112 }
23982
17b5fa69243c Workaround for fonts with zero ascender/descender in horizontal header.
eugeni
parents: 23981
diff changeset
113 }
17b5fa69243c Workaround for fonts with zero ascender/descender in horizontal header.
eugeni
parents: 23981
diff changeset
114
23981
705628816d98 Factor out common code from ass_font_new and ass_font_reselect.
eugeni
parents: 23980
diff changeset
115 /**
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
116 * \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
117 * \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
118 */
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
119 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
120 {
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
121 char *path;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
122 int index;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
123 FT_Face face;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
124 int error;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
125 int mem_idx;
29263
0f1b5b68af32 whitespace cosmetics: Remove all trailing whitespace.
diego
parents: 28860
diff changeset
126
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
127 if (font->n_faces == ASS_FONT_MAX_FACES)
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
128 return -1;
29263
0f1b5b68af32 whitespace cosmetics: Remove all trailing whitespace.
diego
parents: 28860
diff changeset
129
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
130 path =
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
131 fontconfig_select(font->library, fc_priv, font->desc.family,
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
132 font->desc.treat_family_as_pattern,
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
133 font->desc.bold, font->desc.italic, &index, ch);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
134 if (!path)
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
135 return -1;
23981
705628816d98 Factor out common code from ass_font_new and ass_font_reselect.
eugeni
parents: 23980
diff changeset
136
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
137 mem_idx = find_font(font->library, path);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
138 if (mem_idx >= 0) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
139 error =
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
140 FT_New_Memory_Face(font->ftlibrary,
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
141 (unsigned char *) font->library->
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
142 fontdata[mem_idx].data,
31853
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
143 font->library->fontdata[mem_idx].size, index,
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
144 &face);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
145 if (error) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
146 ass_msg(font->library, MSGL_WARN,
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
147 "Error opening memory font: '%s'", path);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
148 free(path);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
149 return -1;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
150 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
151 } else {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
152 error = FT_New_Face(font->ftlibrary, path, index, &face);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
153 if (error) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
154 ass_msg(font->library, MSGL_WARN,
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
155 "Error opening font: '%s', %d", path, index);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
156 free(path);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
157 return -1;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
158 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
159 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
160 charmap_magic(font->library, face);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
161 buggy_font_workaround(face);
29263
0f1b5b68af32 whitespace cosmetics: Remove all trailing whitespace.
diego
parents: 28860
diff changeset
162
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
163 font->faces[font->n_faces++] = face;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
164 face_set_size(face, font->size);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
165 free(path);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
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
0d8005d2fe5c Update some comments.
eugeni
parents: 21620
diff changeset
169 /**
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
170 * \brief Create a new ASS_Font according to "desc" argument
21630
0d8005d2fe5c Update some comments.
eugeni
parents: 21620
diff changeset
171 */
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
172 ASS_Font *ass_font_new(void *font_cache, ASS_Library *library,
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
173 FT_Library ftlibrary, void *fc_priv,
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
174 ASS_FontDesc *desc)
21277
0603972f083c Move fonts-related code to a separate file.
eugeni
parents:
diff changeset
175 {
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
176 int error;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
177 ASS_Font *fontp;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
178 ASS_Font font;
21317
dcfd069efd8f Move ass_font_t allocation to ass_font.h.
eugeni
parents: 21314
diff changeset
179
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
180 fontp = ass_font_cache_find((Hashmap *) font_cache, desc);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
181 if (fontp)
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
182 return fontp;
29263
0f1b5b68af32 whitespace cosmetics: Remove all trailing whitespace.
diego
parents: 28860
diff changeset
183
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
184 font.library = library;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
185 font.ftlibrary = ftlibrary;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
186 font.n_faces = 0;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
187 font.desc.family = strdup(desc->family);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
188 font.desc.treat_family_as_pattern = desc->treat_family_as_pattern;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
189 font.desc.bold = desc->bold;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
190 font.desc.italic = desc->italic;
31853
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
191 font.desc.vertical = desc->vertical;
21277
0603972f083c Move fonts-related code to a separate file.
eugeni
parents:
diff changeset
192
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
193 font.scale_x = font.scale_y = 1.;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
194 font.v.x = font.v.y = 0;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
195 font.size = 0.;
21277
0603972f083c Move fonts-related code to a separate file.
eugeni
parents:
diff changeset
196
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
197 error = add_face(fc_priv, &font, 0);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
198 if (error == -1) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
199 free(font.desc.family);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
200 return 0;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
201 } else
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
202 return ass_font_cache_add((Hashmap *) font_cache, &font);
21277
0603972f083c Move fonts-related code to a separate file.
eugeni
parents:
diff changeset
203 }
0603972f083c Move fonts-related code to a separate file.
eugeni
parents:
diff changeset
204
21630
0d8005d2fe5c Update some comments.
eugeni
parents: 21620
diff changeset
205 /**
0d8005d2fe5c Update some comments.
eugeni
parents: 21620
diff changeset
206 * \brief Set font transformation matrix and shift vector
0d8005d2fe5c Update some comments.
eugeni
parents: 21620
diff changeset
207 **/
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
208 void ass_font_set_transform(ASS_Font *font, double scale_x,
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
209 double scale_y, FT_Vector *v)
21277
0603972f083c Move fonts-related code to a separate file.
eugeni
parents:
diff changeset
210 {
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
211 font->scale_x = scale_x;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
212 font->scale_y = scale_y;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
213 if (v) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
214 font->v.x = v->x;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
215 font->v.y = v->y;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
216 }
21277
0603972f083c Move fonts-related code to a separate file.
eugeni
parents:
diff changeset
217 }
0603972f083c Move fonts-related code to a separate file.
eugeni
parents:
diff changeset
218
23328
99ac5d381aed Correct font size in libass.
eugeni
parents: 23300
diff changeset
219 static void face_set_size(FT_Face face, double size)
99ac5d381aed Correct font size in libass.
eugeni
parents: 23300
diff changeset
220 {
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
221 TT_HoriHeader *hori = FT_Get_Sfnt_Table(face, ft_sfnt_hhea);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
222 TT_OS2 *os2 = FT_Get_Sfnt_Table(face, ft_sfnt_os2);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
223 double mscale = 1.;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
224 FT_Size_RequestRec rq;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
225 FT_Size_Metrics *m = &face->size->metrics;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
226 // VSFilter uses metrics from TrueType OS/2 table
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
227 // The idea was borrowed from asa (http://asa.diac24.net)
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
228 if (hori && os2) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
229 int hori_height = hori->Ascender - hori->Descender;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
230 int os2_height = os2->usWinAscent + os2->usWinDescent;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
231 if (hori_height && os2_height)
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
232 mscale = (double) hori_height / os2_height;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
233 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
234 memset(&rq, 0, sizeof(rq));
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
235 rq.type = FT_SIZE_REQUEST_TYPE_REAL_DIM;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
236 rq.width = 0;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
237 rq.height = double_to_d6(size * mscale);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
238 rq.horiResolution = rq.vertResolution = 0;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
239 FT_Request_Size(face, &rq);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
240 m->ascender /= mscale;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
241 m->descender /= mscale;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
242 m->height /= mscale;
23328
99ac5d381aed Correct font size in libass.
eugeni
parents: 23300
diff changeset
243 }
99ac5d381aed Correct font size in libass.
eugeni
parents: 23300
diff changeset
244
21630
0d8005d2fe5c Update some comments.
eugeni
parents: 21620
diff changeset
245 /**
0d8005d2fe5c Update some comments.
eugeni
parents: 21620
diff changeset
246 * \brief Set font size
0d8005d2fe5c Update some comments.
eugeni
parents: 21620
diff changeset
247 **/
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
248 void ass_font_set_size(ASS_Font *font, double size)
21277
0603972f083c Move fonts-related code to a separate file.
eugeni
parents:
diff changeset
249 {
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
250 int i;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
251 if (font->size != size) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
252 font->size = size;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
253 for (i = 0; i < font->n_faces; ++i)
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
254 face_set_size(font->faces[i], size);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
255 }
21277
0603972f083c Move fonts-related code to a separate file.
eugeni
parents:
diff changeset
256 }
0603972f083c Move fonts-related code to a separate file.
eugeni
parents:
diff changeset
257
21630
0d8005d2fe5c Update some comments.
eugeni
parents: 21620
diff changeset
258 /**
0d8005d2fe5c Update some comments.
eugeni
parents: 21620
diff changeset
259 * \brief Get maximal font ascender and descender.
0d8005d2fe5c Update some comments.
eugeni
parents: 21620
diff changeset
260 * \param ch character code
0d8005d2fe5c Update some comments.
eugeni
parents: 21620
diff changeset
261 * The values are extracted from the font face that provides glyphs for the given character
0d8005d2fe5c Update some comments.
eugeni
parents: 21620
diff changeset
262 **/
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
263 void ass_font_get_asc_desc(ASS_Font *font, uint32_t ch, int *asc,
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
264 int *desc)
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
265 {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
266 int i;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
267 for (i = 0; i < font->n_faces; ++i) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
268 FT_Face face = font->faces[i];
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
269 TT_OS2 *os2 = FT_Get_Sfnt_Table(face, ft_sfnt_os2);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
270 if (FT_Get_Char_Index(face, ch)) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
271 int y_scale = face->size->metrics.y_scale;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
272 if (os2) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
273 *asc = FT_MulFix(os2->usWinAscent, y_scale);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
274 *desc = FT_MulFix(os2->usWinDescent, y_scale);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
275 } else {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
276 *asc = FT_MulFix(face->ascender, y_scale);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
277 *desc = FT_MulFix(-face->descender, y_scale);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
278 }
31853
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
279 if (font->desc.vertical && ch >= VERTICAL_LOWER_BOUND) {
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
280 *asc = FT_MulFix(face->max_advance_width, y_scale);
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
281 }
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
282 return;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
283 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
284 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
285
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
286 *asc = *desc = 0;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
287 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
288
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
289 /*
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
290 * Strike a glyph with a horizontal line; it's possible to underline it
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
291 * and/or strike through it. For the line's position and size, truetype
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
292 * tables are consulted. Obviously this relies on the data in the tables
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
293 * being accurate.
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
294 *
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
295 */
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
296 static int ass_strike_outline_glyph(FT_Face face, ASS_Font *font,
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
297 FT_Glyph glyph, int under, int through)
21614
5d2ca7ca18b5 Move ascender, descender, and kerning computation to ass_font.c.
eugeni
parents: 21460
diff changeset
298 {
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
299 TT_OS2 *os2 = FT_Get_Sfnt_Table(face, ft_sfnt_os2);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
300 TT_Postscript *ps = FT_Get_Sfnt_Table(face, ft_sfnt_post);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
301 FT_Outline *ol = &((FT_OutlineGlyph) glyph)->outline;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
302 int bear, advance, y_scale, i, dir;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
303
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
304 if (!under && !through)
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
305 return 0;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
306
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
307 // Grow outline
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
308 i = (under ? 4 : 0) + (through ? 4 : 0);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
309 ol->points = realloc(ol->points, sizeof(FT_Vector) *
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
310 (ol->n_points + i));
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
311 ol->tags = realloc(ol->tags, ol->n_points + i);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
312 i = !!under + !!through;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
313 ol->contours = realloc(ol->contours, sizeof(short) *
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
314 (ol->n_contours + i));
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
315
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
316 // If the bearing is negative, the glyph starts left of the current
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
317 // pen position
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
318 bear = FFMIN(face->glyph->metrics.horiBearingX, 0);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
319 // We're adding half a pixel to avoid small gaps
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
320 advance = d16_to_d6(glyph->advance.x) + 32;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
321 y_scale = face->size->metrics.y_scale;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
322
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
323 // Reverse drawing direction for non-truetype fonts
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
324 dir = FT_Outline_Get_Orientation(ol);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
325
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
326 // Add points to the outline
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
327 if (under && ps) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
328 int pos, size;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
329 pos = FT_MulFix(ps->underlinePosition, y_scale * font->scale_y);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
330 size = FT_MulFix(ps->underlineThickness,
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
331 y_scale * font->scale_y / 2);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
332
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
333 if (pos > 0 || size <= 0)
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
334 return 1;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
335
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
336 FT_Vector points[4] = {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
337 {.x = bear, .y = pos + size},
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
338 {.x = advance, .y = pos + size},
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
339 {.x = advance, .y = pos - size},
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
340 {.x = bear, .y = pos - size},
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
341 };
29263
0f1b5b68af32 whitespace cosmetics: Remove all trailing whitespace.
diego
parents: 28860
diff changeset
342
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
343 if (dir == FT_ORIENTATION_TRUETYPE) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
344 for (i = 0; i < 4; i++) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
345 ol->points[ol->n_points] = points[i];
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
346 ol->tags[ol->n_points++] = 1;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
347 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
348 } else {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
349 for (i = 3; i >= 0; i--) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
350 ol->points[ol->n_points] = points[i];
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
351 ol->tags[ol->n_points++] = 1;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
352 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
353 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
354
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
355 ol->contours[ol->n_contours++] = ol->n_points - 1;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
356 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
357
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
358 if (through && os2) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
359 int pos, size;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
360 pos = FT_MulFix(os2->yStrikeoutPosition, y_scale * font->scale_y);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
361 size = FT_MulFix(os2->yStrikeoutSize, y_scale * font->scale_y / 2);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
362
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
363 if (pos < 0 || size <= 0)
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
364 return 1;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
365
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
366 FT_Vector points[4] = {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
367 {.x = bear, .y = pos + size},
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
368 {.x = advance, .y = pos + size},
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
369 {.x = advance, .y = pos - size},
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
370 {.x = bear, .y = pos - size},
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
371 };
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
372
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
373 if (dir == FT_ORIENTATION_TRUETYPE) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
374 for (i = 0; i < 4; i++) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
375 ol->points[ol->n_points] = points[i];
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
376 ol->tags[ol->n_points++] = 1;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
377 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
378 } else {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
379 for (i = 3; i >= 0; i--) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
380 ol->points[ol->n_points] = points[i];
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
381 ol->tags[ol->n_points++] = 1;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
382 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
383 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
384
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
385 ol->contours[ol->n_contours++] = ol->n_points - 1;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
386 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
387
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
388 return 0;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
389 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
390
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
391 /**
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
392 * Slightly embold a glyph without touching its metrics
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
393 */
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
394 static void ass_glyph_embolden(FT_GlyphSlot slot)
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
395 {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
396 int str;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
397
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
398 if (slot->format != FT_GLYPH_FORMAT_OUTLINE)
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
399 return;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
400
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
401 str = FT_MulFix(slot->face->units_per_EM,
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
402 slot->face->size->metrics.y_scale) / 64;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
403
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
404 FT_Outline_Embolden(&slot->outline, str);
21614
5d2ca7ca18b5 Move ascender, descender, and kerning computation to ass_font.c.
eugeni
parents: 21460
diff changeset
405 }
5d2ca7ca18b5 Move ascender, descender, and kerning computation to ass_font.c.
eugeni
parents: 21460
diff changeset
406
21630
0d8005d2fe5c Update some comments.
eugeni
parents: 21620
diff changeset
407 /**
0d8005d2fe5c Update some comments.
eugeni
parents: 21620
diff changeset
408 * \brief Get a glyph
0d8005d2fe5c Update some comments.
eugeni
parents: 21620
diff changeset
409 * \param ch character code
0d8005d2fe5c Update some comments.
eugeni
parents: 21620
diff changeset
410 **/
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
411 FT_Glyph ass_font_get_glyph(void *fontconfig_priv, ASS_Font *font,
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
412 uint32_t ch, ASS_Hinting hinting, int deco)
21277
0603972f083c Move fonts-related code to a separate file.
eugeni
parents:
diff changeset
413 {
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
414 int error;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
415 int index = 0;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
416 int i;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
417 FT_Glyph glyph;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
418 FT_Face face = 0;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
419 int flags = 0;
31853
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
420 int vertical = font->desc.vertical;
21350
5337cdeec169 Skip glyphs with char code < 0x20.
eugeni
parents: 21349
diff changeset
421
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
422 if (ch < 0x20)
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
423 return 0;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
424 // Handle NBSP like a regular space when rendering the glyph
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
425 if (ch == 0xa0)
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
426 ch = ' ';
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
427 if (font->n_faces == 0)
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
428 return 0;
21619
b4b51eb2904f Keep reselected fonts in an array, adding new ones to the end. Glyph
eugeni
parents: 21618
diff changeset
429
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
430 for (i = 0; i < font->n_faces; ++i) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
431 face = font->faces[i];
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
432 index = FT_Get_Char_Index(face, ch);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
433 if (index)
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
434 break;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
435 }
21619
b4b51eb2904f Keep reselected fonts in an array, adding new ones to the end. Glyph
eugeni
parents: 21618
diff changeset
436
27393
4876c89bafdd Rename font-related preprocessor directives.
diego
parents: 26738
diff changeset
437 #ifdef CONFIG_FONTCONFIG
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
438 if (index == 0) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
439 int face_idx;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
440 ass_msg(font->library, MSGL_INFO,
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
441 "Glyph 0x%X not found, selecting one more "
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
442 "font for (%s, %d, %d)", ch, font->desc.family,
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
443 font->desc.bold, font->desc.italic);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
444 face_idx = add_face(fontconfig_priv, font, ch);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
445 if (face_idx >= 0) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
446 face = font->faces[face_idx];
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
447 index = FT_Get_Char_Index(face, ch);
31853
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
448 if (index == 0 && face->num_charmaps > 0) {
34011
88eebbbbd6a0 Update included libass copy to 0.9.13 release.
reimar
parents: 31875
diff changeset
449 int i;
31853
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
450 ass_msg(font->library, MSGL_WARN,
34011
88eebbbbd6a0 Update included libass copy to 0.9.13 release.
reimar
parents: 31875
diff changeset
451 "Glyph 0x%X not found, broken font? Trying all charmaps", ch);
88eebbbbd6a0 Update included libass copy to 0.9.13 release.
reimar
parents: 31875
diff changeset
452 for (i = 0; i < face->num_charmaps; i++) {
88eebbbbd6a0 Update included libass copy to 0.9.13 release.
reimar
parents: 31875
diff changeset
453 FT_Set_Charmap(face, face->charmaps[i]);
88eebbbbd6a0 Update included libass copy to 0.9.13 release.
reimar
parents: 31875
diff changeset
454 if ((index = FT_Get_Char_Index(face, ch)) != 0) break;
88eebbbbd6a0 Update included libass copy to 0.9.13 release.
reimar
parents: 31875
diff changeset
455 }
31853
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
456 }
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
457 if (index == 0) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
458 ass_msg(font->library, MSGL_ERR,
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
459 "Glyph 0x%X not found in font for (%s, %d, %d)",
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
460 ch, font->desc.family, font->desc.bold,
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
461 font->desc.italic);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
462 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
463 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
464 }
21351
c611dfc4cb85 If a glyph is not found in the current font, switch to another one.
eugeni
parents: 21350
diff changeset
465 #endif
c611dfc4cb85 If a glyph is not found in the current font, switch to another one.
eugeni
parents: 21350
diff changeset
466
31853
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
467 flags = FT_LOAD_NO_BITMAP | FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
468 | FT_LOAD_IGNORE_TRANSFORM;
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
469 switch (hinting) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
470 case ASS_HINTING_NONE:
31853
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
471 flags |= FT_LOAD_NO_HINTING;
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
472 break;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
473 case ASS_HINTING_LIGHT:
31853
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
474 flags |= FT_LOAD_FORCE_AUTOHINT | FT_LOAD_TARGET_LIGHT;
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
475 break;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
476 case ASS_HINTING_NORMAL:
31853
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
477 flags |= FT_LOAD_FORCE_AUTOHINT;
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
478 break;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
479 case ASS_HINTING_NATIVE:
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
480 break;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
481 }
29263
0f1b5b68af32 whitespace cosmetics: Remove all trailing whitespace.
diego
parents: 28860
diff changeset
482
31853
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
483 error = FT_Load_Glyph(face, index, flags);
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
484 if (error) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
485 ass_msg(font->library, MSGL_WARN, "Error loading glyph, index %d",
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
486 index);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
487 return 0;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
488 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
489 if (!(face->style_flags & FT_STYLE_FLAG_ITALIC) &&
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
490 (font->desc.italic > 55)) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
491 FT_GlyphSlot_Oblique(face->glyph);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
492 }
29263
0f1b5b68af32 whitespace cosmetics: Remove all trailing whitespace.
diego
parents: 28860
diff changeset
493
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
494 if (!(face->style_flags & FT_STYLE_FLAG_BOLD) &&
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
495 (font->desc.bold > 80)) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
496 ass_glyph_embolden(face->glyph);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
497 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
498 error = FT_Get_Glyph(face->glyph, &glyph);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
499 if (error) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
500 ass_msg(font->library, MSGL_WARN, "Error loading glyph, index %d",
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
501 index);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
502 return 0;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
503 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
504
31853
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
505 // Rotate glyph, if needed
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
506 if (vertical && ch >= VERTICAL_LOWER_BOUND) {
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
507 FT_Matrix m = { 0, double_to_d16(-1.0), double_to_d16(1.0), 0 };
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
508 FT_Outline_Transform(&((FT_OutlineGlyph) glyph)->outline, &m);
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
509 FT_Outline_Translate(&((FT_OutlineGlyph) glyph)->outline,
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
510 face->glyph->metrics.vertAdvance,
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
511 0);
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
512 glyph->advance.x = face->glyph->linearVertAdvance;
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
513 }
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
514
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
515 // Apply scaling and shift
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
516 FT_Matrix scale = { double_to_d16(font->scale_x), 0, 0,
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
517 double_to_d16(font->scale_y) };
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
518 FT_Outline *outl = &((FT_OutlineGlyph) glyph)->outline;
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
519 FT_Outline_Transform(outl, &scale);
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
520 FT_Outline_Translate(outl, font->v.x, font->v.y);
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
521 glyph->advance.x *= font->scale_x;
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
522
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
523 ass_strike_outline_glyph(face, font, glyph, deco & DECO_UNDERLINE,
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
524 deco & DECO_STRIKETHROUGH);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
525
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
526 return glyph;
21277
0603972f083c Move fonts-related code to a separate file.
eugeni
parents:
diff changeset
527 }
0603972f083c Move fonts-related code to a separate file.
eugeni
parents:
diff changeset
528
21630
0d8005d2fe5c Update some comments.
eugeni
parents: 21620
diff changeset
529 /**
0d8005d2fe5c Update some comments.
eugeni
parents: 21620
diff changeset
530 * \brief Get kerning for the pair of glyphs.
0d8005d2fe5c Update some comments.
eugeni
parents: 21620
diff changeset
531 **/
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
532 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
533 {
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
534 FT_Vector v = { 0, 0 };
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
535 int i;
21619
b4b51eb2904f Keep reselected fonts in an array, adding new ones to the end. Glyph
eugeni
parents: 21618
diff changeset
536
31853
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
537 if (font->desc.vertical)
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
538 return v;
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
539
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
540 for (i = 0; i < font->n_faces; ++i) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
541 FT_Face face = font->faces[i];
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
542 int i1 = FT_Get_Char_Index(face, c1);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
543 int i2 = FT_Get_Char_Index(face, c2);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
544 if (i1 && i2) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
545 if (FT_HAS_KERNING(face))
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
546 FT_Get_Kerning(face, i1, i2, FT_KERNING_DEFAULT, &v);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
547 return v;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
548 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
549 if (i1 || i2) // these glyphs are from different font faces, no kerning information
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
550 return v;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
551 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
552 return v;
21614
5d2ca7ca18b5 Move ascender, descender, and kerning computation to ass_font.c.
eugeni
parents: 21460
diff changeset
553 }
5d2ca7ca18b5 Move ascender, descender, and kerning computation to ass_font.c.
eugeni
parents: 21460
diff changeset
554
21630
0d8005d2fe5c Update some comments.
eugeni
parents: 21620
diff changeset
555 /**
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
556 * \brief Deallocate ASS_Font
21630
0d8005d2fe5c Update some comments.
eugeni
parents: 21620
diff changeset
557 **/
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
558 void ass_font_free(ASS_Font *font)
21277
0603972f083c Move fonts-related code to a separate file.
eugeni
parents:
diff changeset
559 {
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
560 int i;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
561 for (i = 0; i < font->n_faces; ++i)
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
562 if (font->faces[i])
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
563 FT_Done_Face(font->faces[i]);
31875
ac6e48baa03d Import libass 0.9.11
greg
parents: 31853
diff changeset
564 free(font->desc.family);
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
565 free(font);
21277
0603972f083c Move fonts-related code to a separate file.
eugeni
parents:
diff changeset
566 }
31853
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
567
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
568 /**
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
569 * \brief Calculate the cbox of a series of points
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
570 */
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
571 static void
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
572 get_contour_cbox(FT_BBox *box, FT_Vector *points, int start, int end)
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
573 {
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
574 box->xMin = box->yMin = INT_MAX;
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
575 box->xMax = box->yMax = INT_MIN;
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
576 int i;
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
577
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
578 for (i = start; i <= end; i++) {
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
579 box->xMin = (points[i].x < box->xMin) ? points[i].x : box->xMin;
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
580 box->xMax = (points[i].x > box->xMax) ? points[i].x : box->xMax;
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
581 box->yMin = (points[i].y < box->yMin) ? points[i].y : box->yMin;
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
582 box->yMax = (points[i].y > box->yMax) ? points[i].y : box->yMax;
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
583 }
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
584 }
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
585
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
586 /**
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
587 * \brief Determine winding direction of a contour
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
588 * \return direction; 0 = clockwise
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
589 */
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
590 static int get_contour_direction(FT_Vector *points, int start, int end)
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
591 {
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
592 int i;
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
593 long long sum = 0;
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
594 int x = points[start].x;
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
595 int y = points[start].y;
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
596 for (i = start + 1; i <= end; i++) {
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
597 sum += x * (points[i].y - y) - y * (points[i].x - x);
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
598 x = points[i].x;
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
599 y = points[i].y;
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
600 }
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
601 sum += x * (points[start].y - y) - y * (points[start].x - x);
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
602 return sum > 0;
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
603 }
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
604
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
605 /**
34011
88eebbbbd6a0 Update included libass copy to 0.9.13 release.
reimar
parents: 31875
diff changeset
606 * \brief Apply fixups to please the FreeType stroker and improve the
88eebbbbd6a0 Update included libass copy to 0.9.13 release.
reimar
parents: 31875
diff changeset
607 * rendering result, especially in case the outline has some anomalies.
88eebbbbd6a0 Update included libass copy to 0.9.13 release.
reimar
parents: 31875
diff changeset
608 * At the moment, the following fixes are done:
88eebbbbd6a0 Update included libass copy to 0.9.13 release.
reimar
parents: 31875
diff changeset
609 *
88eebbbbd6a0 Update included libass copy to 0.9.13 release.
reimar
parents: 31875
diff changeset
610 * 1. Reverse contours that have "inside" winding direction but are not
88eebbbbd6a0 Update included libass copy to 0.9.13 release.
reimar
parents: 31875
diff changeset
611 * contained in any other contours' cbox.
88eebbbbd6a0 Update included libass copy to 0.9.13 release.
reimar
parents: 31875
diff changeset
612 * 2. Remove "inside" contours depending on border size, so that large
88eebbbbd6a0 Update included libass copy to 0.9.13 release.
reimar
parents: 31875
diff changeset
613 * borders do not reverse the winding direction, which leads to "holes"
88eebbbbd6a0 Update included libass copy to 0.9.13 release.
reimar
parents: 31875
diff changeset
614 * inside the border. The inside will be filled by the border of the
88eebbbbd6a0 Update included libass copy to 0.9.13 release.
reimar
parents: 31875
diff changeset
615 * outside contour anyway in this case.
88eebbbbd6a0 Update included libass copy to 0.9.13 release.
reimar
parents: 31875
diff changeset
616 *
88eebbbbd6a0 Update included libass copy to 0.9.13 release.
reimar
parents: 31875
diff changeset
617 * \param outline FreeType outline, modified in-place
88eebbbbd6a0 Update included libass copy to 0.9.13 release.
reimar
parents: 31875
diff changeset
618 * \param border_x border size, x direction, d6 format
88eebbbbd6a0 Update included libass copy to 0.9.13 release.
reimar
parents: 31875
diff changeset
619 * \param border_x border size, y direction, d6 format
31853
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
620 */
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
621 void fix_freetype_stroker(FT_OutlineGlyph glyph, int border_x, int border_y)
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
622 {
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
623 int nc = glyph->outline.n_contours;
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
624 int begin, stop;
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
625 char modified = 0;
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
626 char *valid_cont = malloc(nc);
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
627 int start = 0;
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
628 int end = -1;
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
629 FT_BBox *boxes = malloc(nc * sizeof(FT_BBox));
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
630 int i, j;
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
631 int inside_direction;
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
632
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
633 inside_direction = FT_Outline_Get_Orientation(&glyph->outline) ==
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
634 FT_ORIENTATION_TRUETYPE;
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
635
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
636 // create a list of cboxes of the contours
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
637 for (i = 0; i < nc; i++) {
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
638 start = end + 1;
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
639 end = glyph->outline.contours[i];
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
640 get_contour_cbox(&boxes[i], glyph->outline.points, start, end);
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
641 }
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
642
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
643 // for each contour, check direction and whether it's "outside"
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
644 // or contained in another contour
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
645 end = -1;
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
646 for (i = 0; i < nc; i++) {
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
647 start = end + 1;
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
648 end = glyph->outline.contours[i];
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
649 int dir = get_contour_direction(glyph->outline.points, start, end);
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
650 valid_cont[i] = 1;
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
651 if (dir == inside_direction) {
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
652 for (j = 0; j < nc; j++) {
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
653 if (i == j)
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
654 continue;
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
655 if (boxes[i].xMin >= boxes[j].xMin &&
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
656 boxes[i].xMax <= boxes[j].xMax &&
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
657 boxes[i].yMin >= boxes[j].yMin &&
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
658 boxes[i].yMax <= boxes[j].yMax)
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
659 goto check_inside;
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
660 }
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
661 /* "inside" contour but we can't find anything it could be
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
662 * inside of - assume the font is buggy and it should be
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
663 * an "outside" contour, and reverse it */
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
664 for (j = 0; j < (end + 1 - start) / 2; j++) {
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
665 FT_Vector temp = glyph->outline.points[start + j];
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
666 char temp2 = glyph->outline.tags[start + j];
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
667 glyph->outline.points[start + j] = glyph->outline.points[end - j];
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
668 glyph->outline.points[end - j] = temp;
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
669 glyph->outline.tags[start + j] = glyph->outline.tags[end - j];
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
670 glyph->outline.tags[end - j] = temp2;
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
671 }
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
672 dir ^= 1;
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
673 }
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
674 check_inside:
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
675 if (dir == inside_direction) {
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
676 FT_BBox box;
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
677 get_contour_cbox(&box, glyph->outline.points, start, end);
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
678 int width = box.xMax - box.xMin;
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
679 int height = box.yMax - box.yMin;
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
680 if (width < border_x * 2 || height < border_y * 2) {
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
681 valid_cont[i] = 0;
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
682 modified = 1;
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
683 }
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
684 }
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
685 }
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
686
34011
88eebbbbd6a0 Update included libass copy to 0.9.13 release.
reimar
parents: 31875
diff changeset
687 // if we need to modify the outline, rewrite it and skip
88eebbbbd6a0 Update included libass copy to 0.9.13 release.
reimar
parents: 31875
diff changeset
688 // the contours that we determined should be removed.
31853
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
689 if (modified) {
34011
88eebbbbd6a0 Update included libass copy to 0.9.13 release.
reimar
parents: 31875
diff changeset
690 FT_Outline *outline = &glyph->outline;
88eebbbbd6a0 Update included libass copy to 0.9.13 release.
reimar
parents: 31875
diff changeset
691 int p = 0, c = 0;
31853
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
692 for (i = 0; i < nc; i++) {
34011
88eebbbbd6a0 Update included libass copy to 0.9.13 release.
reimar
parents: 31875
diff changeset
693 if (!valid_cont[i])
31853
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
694 continue;
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
695 begin = (i == 0) ? 0 : glyph->outline.contours[i - 1] + 1;
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
696 stop = glyph->outline.contours[i];
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
697 for (j = begin; j <= stop; j++) {
34011
88eebbbbd6a0 Update included libass copy to 0.9.13 release.
reimar
parents: 31875
diff changeset
698 outline->points[p].x = outline->points[j].x;
88eebbbbd6a0 Update included libass copy to 0.9.13 release.
reimar
parents: 31875
diff changeset
699 outline->points[p].y = outline->points[j].y;
88eebbbbd6a0 Update included libass copy to 0.9.13 release.
reimar
parents: 31875
diff changeset
700 outline->tags[p] = outline->tags[j];
88eebbbbd6a0 Update included libass copy to 0.9.13 release.
reimar
parents: 31875
diff changeset
701 p++;
31853
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
702 }
34011
88eebbbbd6a0 Update included libass copy to 0.9.13 release.
reimar
parents: 31875
diff changeset
703 outline->contours[c] = p - 1;
88eebbbbd6a0 Update included libass copy to 0.9.13 release.
reimar
parents: 31875
diff changeset
704 c++;
31853
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
705 }
34011
88eebbbbd6a0 Update included libass copy to 0.9.13 release.
reimar
parents: 31875
diff changeset
706 outline->n_points = p;
88eebbbbd6a0 Update included libass copy to 0.9.13 release.
reimar
parents: 31875
diff changeset
707 outline->n_contours = c;
31853
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
708 }
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
709
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
710 free(boxes);
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
711 free(valid_cont);
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
712 }
e64df5862cea Import libass 0.9.10
greg
parents: 30200
diff changeset
713