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
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 *
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
0f892cd714b2 Use standard license header.
diego
parents: 25660
diff changeset
7 * it under the terms of the GNU General Public License as published by
0f892cd714b2 Use standard license header.
diego
parents: 25660
diff changeset
8 * the Free Software Foundation; either version 2 of the License, or
0f892cd714b2 Use standard license header.
diego
parents: 25660
diff changeset
9 * (at your option) any later version.
0f892cd714b2 Use standard license header.
diego
parents: 25660
diff changeset
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
0f892cd714b2 Use standard license header.
diego
parents: 25660
diff changeset
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
0f892cd714b2 Use standard license header.
diego
parents: 25660
diff changeset
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
0f892cd714b2 Use standard license header.
diego
parents: 25660
diff changeset
14 * GNU General Public License for more details.
0f892cd714b2 Use standard license header.
diego
parents: 25660
diff changeset
15 *
0f892cd714b2 Use standard license header.
diego
parents: 25660
diff changeset
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
0f892cd714b2 Use standard license header.
diego
parents: 25660
diff changeset
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
0f892cd714b2 Use standard license header.
diego
parents: 25660
diff changeset
19 */
21277
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 "config.h"
0603972f083c Move fonts-related code to a separate file.
eugeni
parents:
diff changeset
22
0603972f083c Move fonts-related code to a separate file.
eugeni
parents:
diff changeset
23 #include <inttypes.h>
0603972f083c Move fonts-related code to a separate file.
eugeni
parents:
diff changeset
24 #include <ft2build.h>
0603972f083c Move fonts-related code to a separate file.
eugeni
parents:
diff changeset
25 #include FT_FREETYPE_H
0603972f083c Move fonts-related code to a separate file.
eugeni
parents:
diff changeset
26 #include FT_SYNTHESIS_H
0603972f083c Move fonts-related code to a separate file.
eugeni
parents:
diff changeset
27 #include FT_GLYPH_H
23328
99ac5d381aed Correct font size in libass.
eugeni
parents: 23300
diff changeset
28 #include FT_TRUETYPE_TABLES_H
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
29 #include FT_OUTLINE_H
21277
0603972f083c Move fonts-related code to a separate file.
eugeni
parents:
diff changeset
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
0603972f083c Move fonts-related code to a separate file.
eugeni
parents:
diff changeset
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
0603972f083c Move fonts-related code to a separate file.
eugeni
parents:
diff changeset
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
0603972f083c Move fonts-related code to a separate file.
eugeni
parents:
diff changeset
38
0603972f083c Move fonts-related code to a separate file.
eugeni
parents:
diff changeset
39 /**
0603972f083c Move fonts-related code to a separate file.
eugeni
parents:
diff changeset
40 * Select Microfost Unicode CharMap, if the font has one.
0603972f083c Move fonts-related code to a separate file.
eugeni
parents:
diff changeset
41 * Otherwise, let FreeType decide.
0603972f083c Move fonts-related code to a separate file.
eugeni
parents:
diff changeset
42 */
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
43 static void charmap_magic(ASS_Library *library, FT_Face face)
21277
0603972f083c Move fonts-related code to a separate file.
eugeni
parents:
diff changeset
44 {
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
45 int i;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
46 for (i = 0; i < face->num_charmaps; ++i) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
47 FT_CharMap cmap = face->charmaps[i];
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
48 unsigned pid = cmap->platform_id;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
49 unsigned eid = cmap->encoding_id;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
50 if (pid == 3 /*microsoft */
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
51 && (eid == 1 /*unicode bmp */
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
52 || eid == 10 /*full unicode */ )) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
53 FT_Set_Charmap(face, cmap);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
54 return;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
55 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
56 }
22210
4a958bd08920 Select the first charmap in the font, if FreeType did not autoselect any.
eugeni
parents: 21630
diff changeset
57
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
58 if (!face->charmap) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
59 if (face->num_charmaps == 0) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
60 ass_msg(library, MSGL_WARN, "Font face with no charmaps");
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
61 return;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
62 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
63 ass_msg(library, MSGL_WARN,
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
64 "No charmap autodetected, trying the first one");
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
65 FT_Set_Charmap(face, face->charmaps[0]);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
66 return;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
67 }
21277
0603972f083c Move fonts-related code to a separate file.
eugeni
parents:
diff changeset
68 }
0603972f083c Move fonts-related code to a separate file.
eugeni
parents:
diff changeset
69
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
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
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
72 int i;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
73 FT_Matrix m;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
74 m.xx = double_to_d16(font->scale_x);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
75 m.yy = double_to_d16(font->scale_y);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
76 m.xy = m.yx = 0;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
77 for (i = 0; i < font->n_faces; ++i)
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
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
0d8005d2fe5c Update some comments.
eugeni
parents: 21620
diff changeset
81 /**
0d8005d2fe5c Update some comments.
eugeni
parents: 21620
diff changeset
82 * \brief find a memory font by name
0d8005d2fe5c Update some comments.
eugeni
parents: 21620
diff changeset
83 */
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
84 static int find_font(ASS_Library *library, char *name)
21460
62bd8e0d3a0f Open embedded fonts directly from memory.
eugeni
parents: 21458
diff changeset
85 {
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
86 int i;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
87 for (i = 0; i < library->num_fontdata; ++i)
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
88 if (strcasecmp(name, library->fontdata[i].name) == 0)
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
89 return i;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
90 return -1;
21460
62bd8e0d3a0f Open embedded fonts directly from memory.
eugeni
parents: 21458
diff changeset
91 }
62bd8e0d3a0f Open embedded fonts directly from memory.
eugeni
parents: 21458
diff changeset
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
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
97 // Some fonts have zero Ascender/Descender fields in 'hhea' table.
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
98 // In this case, get the information from 'os2' table or, as
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
99 // a last resort, from face.bbox.
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
100 if (face->ascender + face->descender == 0 || face->height == 0) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
101 TT_OS2 *os2 = FT_Get_Sfnt_Table(face, ft_sfnt_os2);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
102 if (os2) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
103 face->ascender = os2->sTypoAscender;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
104 face->descender = os2->sTypoDescender;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
105 face->height = face->ascender - face->descender;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
106 } else {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
107 face->ascender = face->bbox.yMax;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
108 face->descender = face->bbox.yMin;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
109 face->height = face->ascender - face->descender;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
110 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
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
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
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
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
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
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
120 char *path;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
121 int index;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
122 FT_Face face;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
123 int error;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
124 int mem_idx;
29263
0f1b5b68af32 whitespace cosmetics: Remove all trailing whitespace.
diego
parents: 28860
diff changeset
125
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
126 if (font->n_faces == ASS_FONT_MAX_FACES)
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
127 return -1;
29263
0f1b5b68af32 whitespace cosmetics: Remove all trailing whitespace.
diego
parents: 28860
diff changeset
128
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
129 path =
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
130 fontconfig_select(font->library, fc_priv, font->desc.family,
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
131 font->desc.treat_family_as_pattern,
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
132 font->desc.bold, font->desc.italic, &index, ch);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
133 if (!path)
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
134 return -1;
23981
705628816d98 Factor out common code from ass_font_new and ass_font_reselect.
eugeni
parents: 23980
diff changeset
135
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
136 mem_idx = find_font(font->library, path);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
137 if (mem_idx >= 0) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
138 error =
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
139 FT_New_Memory_Face(font->ftlibrary,
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
140 (unsigned char *) font->library->
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
141 fontdata[mem_idx].data,
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
142 font->library->fontdata[mem_idx].size, 0,
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
143 &face);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
144 if (error) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
145 ass_msg(font->library, MSGL_WARN,
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
146 "Error opening memory font: '%s'", path);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
147 free(path);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
148 return -1;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
149 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
150 } else {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
151 error = FT_New_Face(font->ftlibrary, path, index, &face);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
152 if (error) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
153 ass_msg(font->library, MSGL_WARN,
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
154 "Error opening font: '%s', %d", path, index);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
155 free(path);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
156 return -1;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
157 }
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 charmap_magic(font->library, face);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
160 buggy_font_workaround(face);
29263
0f1b5b68af32 whitespace cosmetics: Remove all trailing whitespace.
diego
parents: 28860
diff changeset
161
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
162 font->faces[font->n_faces++] = face;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
163 update_transform(font);
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;
21277
0603972f083c Move fonts-related code to a separate file.
eugeni
parents:
diff changeset
191
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
192 font.scale_x = font.scale_y = 1.;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
193 font.v.x = font.v.y = 0;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
194 font.size = 0.;
21277
0603972f083c Move fonts-related code to a separate file.
eugeni
parents:
diff changeset
195
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
196 error = add_face(fc_priv, &font, 0);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
197 if (error == -1) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
198 free(font.desc.family);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
199 return 0;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
200 } else
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
201 return ass_font_cache_add((Hashmap *) font_cache, &font);
21277
0603972f083c Move fonts-related code to a separate file.
eugeni
parents:
diff changeset
202 }
0603972f083c Move fonts-related code to a separate file.
eugeni
parents:
diff changeset
203
21630
0d8005d2fe5c Update some comments.
eugeni
parents: 21620
diff changeset
204 /**
0d8005d2fe5c Update some comments.
eugeni
parents: 21620
diff changeset
205 * \brief Set font transformation matrix and shift vector
0d8005d2fe5c Update some comments.
eugeni
parents: 21620
diff changeset
206 **/
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
207 void ass_font_set_transform(ASS_Font *font, double scale_x,
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
208 double scale_y, FT_Vector *v)
21277
0603972f083c Move fonts-related code to a separate file.
eugeni
parents:
diff changeset
209 {
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
210 font->scale_x = scale_x;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
211 font->scale_y = scale_y;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
212 if (v) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
213 font->v.x = v->x;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
214 font->v.y = v->y;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
215 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
216 update_transform(font);
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 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
279 return;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
280 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
281 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
282
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
283 *asc = *desc = 0;
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 /*
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
287 * 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
288 * 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
289 * 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
290 * being accurate.
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
291 *
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
292 */
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
293 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
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
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
296 TT_OS2 *os2 = FT_Get_Sfnt_Table(face, ft_sfnt_os2);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
297 TT_Postscript *ps = FT_Get_Sfnt_Table(face, ft_sfnt_post);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
298 FT_Outline *ol = &((FT_OutlineGlyph) glyph)->outline;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
299 int bear, advance, y_scale, i, dir;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
300
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
301 if (!under && !through)
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
302 return 0;
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 // Grow outline
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
305 i = (under ? 4 : 0) + (through ? 4 : 0);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
306 ol->points = realloc(ol->points, sizeof(FT_Vector) *
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
307 (ol->n_points + i));
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
308 ol->tags = realloc(ol->tags, ol->n_points + i);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
309 i = !!under + !!through;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
310 ol->contours = realloc(ol->contours, sizeof(short) *
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
311 (ol->n_contours + i));
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
312
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
313 // 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
314 // pen position
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
315 bear = FFMIN(face->glyph->metrics.horiBearingX, 0);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
316 // We're adding half a pixel to avoid small gaps
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
317 advance = d16_to_d6(glyph->advance.x) + 32;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
318 y_scale = face->size->metrics.y_scale;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
319
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
320 // Reverse drawing direction for non-truetype fonts
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
321 dir = FT_Outline_Get_Orientation(ol);
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 // Add points to the outline
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
324 if (under && ps) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
325 int pos, size;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
326 pos = FT_MulFix(ps->underlinePosition, y_scale * font->scale_y);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
327 size = FT_MulFix(ps->underlineThickness,
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
328 y_scale * font->scale_y / 2);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
329
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
330 if (pos > 0 || size <= 0)
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
331 return 1;
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 FT_Vector points[4] = {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
334 {.x = bear, .y = pos + size},
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
335 {.x = advance, .y = pos + size},
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
336 {.x = advance, .y = pos - size},
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 };
29263
0f1b5b68af32 whitespace cosmetics: Remove all trailing whitespace.
diego
parents: 28860
diff changeset
339
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
340 if (dir == FT_ORIENTATION_TRUETYPE) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
341 for (i = 0; i < 4; i++) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
342 ol->points[ol->n_points] = points[i];
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
343 ol->tags[ol->n_points++] = 1;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
344 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
345 } else {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
346 for (i = 3; i >= 0; i--) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
347 ol->points[ol->n_points] = points[i];
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
348 ol->tags[ol->n_points++] = 1;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
349 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
350 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
351
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
352 ol->contours[ol->n_contours++] = ol->n_points - 1;
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 if (through && os2) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
356 int pos, size;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
357 pos = FT_MulFix(os2->yStrikeoutPosition, y_scale * font->scale_y);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
358 size = FT_MulFix(os2->yStrikeoutSize, y_scale * font->scale_y / 2);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
359
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
360 if (pos < 0 || size <= 0)
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
361 return 1;
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 FT_Vector points[4] = {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
364 {.x = bear, .y = pos + size},
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
365 {.x = advance, .y = pos + size},
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
366 {.x = advance, .y = pos - size},
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 };
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
369
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
370 if (dir == FT_ORIENTATION_TRUETYPE) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
371 for (i = 0; i < 4; i++) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
372 ol->points[ol->n_points] = points[i];
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
373 ol->tags[ol->n_points++] = 1;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
374 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
375 } else {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
376 for (i = 3; i >= 0; i--) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
377 ol->points[ol->n_points] = points[i];
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
378 ol->tags[ol->n_points++] = 1;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
379 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
380 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
381
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
382 ol->contours[ol->n_contours++] = ol->n_points - 1;
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 return 0;
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 /**
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
389 * Slightly embold a glyph without touching its metrics
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 static void ass_glyph_embolden(FT_GlyphSlot slot)
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
392 {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
393 int str;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
394
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
395 if (slot->format != FT_GLYPH_FORMAT_OUTLINE)
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
396 return;
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 str = FT_MulFix(slot->face->units_per_EM,
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
399 slot->face->size->metrics.y_scale) / 64;
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 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
0d8005d2fe5c Update some comments.
eugeni
parents: 21620
diff changeset
404 /**
0d8005d2fe5c Update some comments.
eugeni
parents: 21620
diff changeset
405 * \brief Get a glyph
0d8005d2fe5c Update some comments.
eugeni
parents: 21620
diff changeset
406 * \param ch character code
0d8005d2fe5c Update some comments.
eugeni
parents: 21620
diff changeset
407 **/
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
408 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
409 uint32_t ch, ASS_Hinting hinting, int deco)
21277
0603972f083c Move fonts-related code to a separate file.
eugeni
parents:
diff changeset
410 {
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
411 int error;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
412 int index = 0;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
413 int i;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
414 FT_Glyph glyph;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
415 FT_Face face = 0;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
416 int flags = 0;
21350
5337cdeec169 Skip glyphs with char code < 0x20.
eugeni
parents: 21349
diff changeset
417
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
418 if (ch < 0x20)
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
419 return 0;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
420 // Handle NBSP like a regular space when rendering the glyph
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
421 if (ch == 0xa0)
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
422 ch = ' ';
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
423 if (font->n_faces == 0)
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
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
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
426 for (i = 0; i < font->n_faces; ++i) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
427 face = font->faces[i];
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
428 index = FT_Get_Char_Index(face, ch);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
429 if (index)
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
430 break;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
431 }
21619
b4b51eb2904f Keep reselected fonts in an array, adding new ones to the end. Glyph
eugeni
parents: 21618
diff changeset
432
27393
4876c89bafdd Rename font-related preprocessor directives.
diego
parents: 26738
diff changeset
433 #ifdef CONFIG_FONTCONFIG
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
434 if (index == 0) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
435 int face_idx;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
436 ass_msg(font->library, MSGL_INFO,
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
437 "Glyph 0x%X not found, selecting one more "
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
438 "font for (%s, %d, %d)", ch, font->desc.family,
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
439 font->desc.bold, font->desc.italic);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
440 face_idx = add_face(fontconfig_priv, font, ch);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
441 if (face_idx >= 0) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
442 face = font->faces[face_idx];
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
443 index = FT_Get_Char_Index(face, ch);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
444 if (index == 0) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
445 ass_msg(font->library, MSGL_ERR,
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
446 "Glyph 0x%X not found in font for (%s, %d, %d)",
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
447 ch, font->desc.family, font->desc.bold,
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
448 font->desc.italic);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
449 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
450 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
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
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
454 switch (hinting) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
455 case ASS_HINTING_NONE:
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
456 flags = FT_LOAD_NO_HINTING;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
457 break;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
458 case ASS_HINTING_LIGHT:
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
459 flags = FT_LOAD_FORCE_AUTOHINT | FT_LOAD_TARGET_LIGHT;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
460 break;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
461 case ASS_HINTING_NORMAL:
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
462 flags = FT_LOAD_FORCE_AUTOHINT;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
463 break;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
464 case ASS_HINTING_NATIVE:
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
465 flags = 0;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
466 break;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
467 }
29263
0f1b5b68af32 whitespace cosmetics: Remove all trailing whitespace.
diego
parents: 28860
diff changeset
468
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
469 error = FT_Load_Glyph(face, index, FT_LOAD_NO_BITMAP | flags);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
470 if (error) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
471 ass_msg(font->library, MSGL_WARN, "Error loading glyph, index %d",
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
472 index);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
473 return 0;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
474 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
475 if (!(face->style_flags & FT_STYLE_FLAG_ITALIC) &&
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
476 (font->desc.italic > 55)) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
477 FT_GlyphSlot_Oblique(face->glyph);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
478 }
29263
0f1b5b68af32 whitespace cosmetics: Remove all trailing whitespace.
diego
parents: 28860
diff changeset
479
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
480 if (!(face->style_flags & FT_STYLE_FLAG_BOLD) &&
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
481 (font->desc.bold > 80)) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
482 ass_glyph_embolden(face->glyph);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
483 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
484 error = FT_Get_Glyph(face->glyph, &glyph);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
485 if (error) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
486 ass_msg(font->library, MSGL_WARN, "Error loading glyph, index %d",
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
487 index);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
488 return 0;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
489 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
490
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
491 ass_strike_outline_glyph(face, font, glyph, deco & DECO_UNDERLINE,
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
492 deco & DECO_STRIKETHROUGH);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
493
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
494 return glyph;
21277
0603972f083c Move fonts-related code to a separate file.
eugeni
parents:
diff changeset
495 }
0603972f083c Move fonts-related code to a separate file.
eugeni
parents:
diff changeset
496
21630
0d8005d2fe5c Update some comments.
eugeni
parents: 21620
diff changeset
497 /**
0d8005d2fe5c Update some comments.
eugeni
parents: 21620
diff changeset
498 * \brief Get kerning for the pair of glyphs.
0d8005d2fe5c Update some comments.
eugeni
parents: 21620
diff changeset
499 **/
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
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
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
502 FT_Vector v = { 0, 0 };
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
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
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
505 for (i = 0; i < font->n_faces; ++i) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
506 FT_Face face = font->faces[i];
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
507 int i1 = FT_Get_Char_Index(face, c1);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
508 int i2 = FT_Get_Char_Index(face, c2);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
509 if (i1 && i2) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
510 if (FT_HAS_KERNING(face))
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
511 FT_Get_Kerning(face, i1, i2, FT_KERNING_DEFAULT, &v);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
512 return v;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
513 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
514 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
515 return v;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
516 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
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
0d8005d2fe5c Update some comments.
eugeni
parents: 21620
diff changeset
520 /**
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
521 * \brief Deallocate ASS_Font
21630
0d8005d2fe5c Update some comments.
eugeni
parents: 21620
diff changeset
522 **/
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
523 void ass_font_free(ASS_Font *font)
21277
0603972f083c Move fonts-related code to a separate file.
eugeni
parents:
diff changeset
524 {
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
525 int i;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
526 for (i = 0; i < font->n_faces; ++i)
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
527 if (font->faces[i])
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
528 FT_Done_Face(font->faces[i]);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
529 if (font->desc.family)
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
530 free(font->desc.family);
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents: 29325
diff changeset
531 free(font);
21277
0603972f083c Move fonts-related code to a separate file.
eugeni
parents:
diff changeset
532 }