annotate libass/ass_shaper.c @ 36660:7fd255e0db1b

stream.c: remove pointless NULL check. Since it currently is a fixed-size array it can never be NULL. But even if this was changed, this check has no real value: it should still only be possible in case of an obvious code bug during development and the crash it would cause would be easy enough to debug.
author reimar
date Sun, 26 Jan 2014 18:59:15 +0000
parents c3aaaf17c721
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
34300
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
1 /*
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
2 * Copyright (C) 2011 Grigori Goronzy <greg@chown.ath.cx>
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
3 *
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
4 * This file is part of libass.
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
5 *
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
6 * Permission to use, copy, modify, and distribute this software for any
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
7 * purpose with or without fee is hereby granted, provided that the above
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
8 * copyright notice and this permission notice appear in all copies.
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
9 *
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
17 */
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
18
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
19 #include "config.h"
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
20
34342
575ad51cc996 Allow compiling libass without fribidi again.
reimar
parents: 34300
diff changeset
21 #ifdef CONFIG_FRIBIDI
34300
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
22 #include <fribidi/fribidi.h>
34342
575ad51cc996 Allow compiling libass without fribidi again.
reimar
parents: 34300
diff changeset
23 #endif
34300
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
24
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
25 #include "ass_shaper.h"
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
26 #include "ass_render.h"
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
27 #include "ass_font.h"
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
28 #include "ass_parse.h"
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
29 #include "ass_cache.h"
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
30
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
31 #define MAX_RUNS 50
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
32
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
33 #ifdef CONFIG_HARFBUZZ
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
34 #include <hb-ft.h>
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
35 enum {
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
36 VERT = 0,
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
37 VKNA,
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
38 KERN
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
39 };
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
40 #define NUM_FEATURES 3
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
41 #endif
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
42
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
43 struct ass_shaper {
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
44 ASS_ShapingLevel shaping_level;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
45
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
46 // FriBidi log2vis
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
47 int n_glyphs;
34342
575ad51cc996 Allow compiling libass without fribidi again.
reimar
parents: 34300
diff changeset
48 #ifdef CONFIG_FRIBIDI
34300
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
49 FriBidiChar *event_text;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
50 FriBidiCharType *ctypes;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
51 FriBidiLevel *emblevels;
34342
575ad51cc996 Allow compiling libass without fribidi again.
reimar
parents: 34300
diff changeset
52 #endif
34300
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
53 FriBidiStrIndex *cmap;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
54 FriBidiParType base_direction;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
55
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
56 #ifdef CONFIG_HARFBUZZ
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
57 // OpenType features
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
58 int n_features;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
59 hb_feature_t *features;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
60 hb_language_t language;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
61
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
62 // Glyph metrics cache, to speed up shaping
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
63 Cache *metrics_cache;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
64 #endif
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
65 };
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
66
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
67 #ifdef CONFIG_HARFBUZZ
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
68 struct ass_shaper_metrics_data {
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
69 Cache *metrics_cache;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
70 GlyphMetricsHashKey hash_key;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
71 int vertical;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
72 };
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
73
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
74 struct ass_shaper_font_data {
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
75 hb_font_t *fonts[ASS_FONT_MAX_FACES];
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
76 hb_font_funcs_t *font_funcs[ASS_FONT_MAX_FACES];
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
77 struct ass_shaper_metrics_data *metrics_data[ASS_FONT_MAX_FACES];
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
78 };
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
79 #endif
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
80
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
81 /**
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
82 * \brief Print version information
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
83 */
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
84 void ass_shaper_info(ASS_Library *lib)
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
85 {
34342
575ad51cc996 Allow compiling libass without fribidi again.
reimar
parents: 34300
diff changeset
86 ass_msg(lib, MSGL_V, "Shaper:"
575ad51cc996 Allow compiling libass without fribidi again.
reimar
parents: 34300
diff changeset
87 #ifdef CONFIG_FRIBIDI
575ad51cc996 Allow compiling libass without fribidi again.
reimar
parents: 34300
diff changeset
88 " FriBidi " FRIBIDI_VERSION " (SIMPLE)"
575ad51cc996 Allow compiling libass without fribidi again.
reimar
parents: 34300
diff changeset
89 #endif
34300
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
90 #ifdef CONFIG_HARFBUZZ
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
91 " HarfBuzz-ng %s (COMPLEX)", hb_version_string()
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
92 #endif
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
93 );
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
94 }
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
95
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
96 /**
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
97 * \brief grow arrays, if needed
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
98 * \param new_size requested size
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
99 */
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
100 static void check_allocations(ASS_Shaper *shaper, size_t new_size)
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
101 {
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
102 if (new_size > shaper->n_glyphs) {
34342
575ad51cc996 Allow compiling libass without fribidi again.
reimar
parents: 34300
diff changeset
103 #ifdef CONFIG_FRIBIDI
34300
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
104 shaper->event_text = realloc(shaper->event_text, sizeof(FriBidiChar) * new_size);
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
105 shaper->ctypes = realloc(shaper->ctypes, sizeof(FriBidiCharType) * new_size);
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
106 shaper->emblevels = realloc(shaper->emblevels, sizeof(FriBidiLevel) * new_size);
34342
575ad51cc996 Allow compiling libass without fribidi again.
reimar
parents: 34300
diff changeset
107 #endif
34300
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
108 shaper->cmap = realloc(shaper->cmap, sizeof(FriBidiStrIndex) * new_size);
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
109 }
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
110 }
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
111
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
112 /**
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
113 * \brief Free shaper and related data
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
114 */
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
115 void ass_shaper_free(ASS_Shaper *shaper)
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
116 {
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
117 #ifdef CONFIG_HARFBUZZ
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
118 ass_cache_done(shaper->metrics_cache);
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
119 free(shaper->features);
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
120 #endif
34342
575ad51cc996 Allow compiling libass without fribidi again.
reimar
parents: 34300
diff changeset
121 #ifdef CONFIG_FRIBIDI
34300
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
122 free(shaper->event_text);
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
123 free(shaper->ctypes);
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
124 free(shaper->emblevels);
34342
575ad51cc996 Allow compiling libass without fribidi again.
reimar
parents: 34300
diff changeset
125 #endif
34300
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
126 free(shaper->cmap);
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
127 free(shaper);
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
128 }
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
129
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
130 void ass_shaper_font_data_free(ASS_ShaperFontData *priv)
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
131 {
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
132 #ifdef CONFIG_HARFBUZZ
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
133 int i;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
134 for (i = 0; i < ASS_FONT_MAX_FACES; i++)
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
135 if (priv->fonts[i]) {
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
136 free(priv->metrics_data[i]);
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
137 hb_font_destroy(priv->fonts[i]);
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
138 hb_font_funcs_destroy(priv->font_funcs[i]);
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
139 }
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
140 free(priv);
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
141 #endif
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
142 }
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
143
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
144 #ifdef CONFIG_HARFBUZZ
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
145 /**
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
146 * \brief set up the HarfBuzz OpenType feature list with some
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
147 * standard features.
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
148 */
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
149 static void init_features(ASS_Shaper *shaper)
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
150 {
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
151 shaper->features = calloc(sizeof(hb_feature_t), NUM_FEATURES);
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
152
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
153 shaper->n_features = NUM_FEATURES;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
154 shaper->features[VERT].tag = HB_TAG('v', 'e', 'r', 't');
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
155 shaper->features[VERT].end = INT_MAX;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
156 shaper->features[VKNA].tag = HB_TAG('v', 'k', 'n', 'a');
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
157 shaper->features[VKNA].end = INT_MAX;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
158 shaper->features[KERN].tag = HB_TAG('k', 'e', 'r', 'n');
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
159 shaper->features[KERN].end = INT_MAX;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
160 }
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
161
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
162 /**
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
163 * \brief Set features depending on properties of the run
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
164 */
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
165 static void set_run_features(ASS_Shaper *shaper, GlyphInfo *info)
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
166 {
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
167 // enable vertical substitutions for @font runs
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
168 if (info->font->desc.vertical)
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
169 shaper->features[VERT].value = shaper->features[VKNA].value = 1;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
170 else
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
171 shaper->features[VERT].value = shaper->features[VKNA].value = 0;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
172 }
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
173
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
174 /**
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
175 * \brief Update HarfBuzz's idea of font metrics
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
176 * \param hb_font HarfBuzz font
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
177 * \param face associated FreeType font face
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
178 */
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
179 static void update_hb_size(hb_font_t *hb_font, FT_Face face)
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
180 {
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
181 hb_font_set_scale (hb_font,
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
182 ((uint64_t) face->size->metrics.x_scale * (uint64_t) face->units_per_EM) >> 16,
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
183 ((uint64_t) face->size->metrics.y_scale * (uint64_t) face->units_per_EM) >> 16);
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
184 hb_font_set_ppem (hb_font, face->size->metrics.x_ppem,
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
185 face->size->metrics.y_ppem);
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
186 }
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
187
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
188
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
189 /*
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
190 * Cached glyph metrics getters follow
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
191 *
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
192 * These functions replace HarfBuzz' standard FreeType font functions
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
193 * and provide cached access to essential glyph metrics. This usually
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
194 * speeds up shaping a lot. It also allows us to use custom load flags.
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
195 *
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
196 */
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
197
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
198 GlyphMetricsHashValue *
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
199 get_cached_metrics(struct ass_shaper_metrics_data *metrics, FT_Face face,
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
200 hb_codepoint_t glyph)
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
201 {
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
202 GlyphMetricsHashValue *val;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
203
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
204 metrics->hash_key.glyph_index = glyph;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
205 val = ass_cache_get(metrics->metrics_cache, &metrics->hash_key);
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
206
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
207 if (!val) {
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
208 int load_flags = FT_LOAD_DEFAULT | FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
209 | FT_LOAD_IGNORE_TRANSFORM;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
210 GlyphMetricsHashValue new_val;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
211
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
212 if (FT_Load_Glyph(face, glyph, load_flags))
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
213 return NULL;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
214
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
215 memcpy(&new_val.metrics, &face->glyph->metrics, sizeof(FT_Glyph_Metrics));
36363
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
216
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
217 // if @font rendering is enabled and the glyph should be rotated,
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
218 // make cached_h_advance pick up the right advance later
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
219 if (metrics->vertical && glyph >= VERTICAL_LOWER_BOUND)
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
220 new_val.metrics.horiAdvance = new_val.metrics.vertAdvance;
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
221
34300
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
222 val = ass_cache_put(metrics->metrics_cache, &metrics->hash_key, &new_val);
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
223 }
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
224
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
225 return val;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
226 }
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
227
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
228 static hb_bool_t
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
229 get_glyph(hb_font_t *font, void *font_data, hb_codepoint_t unicode,
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
230 hb_codepoint_t variation, hb_codepoint_t *glyph, void *user_data)
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
231 {
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
232 FT_Face face = font_data;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
233
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
234 if (variation)
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
235 *glyph = FT_Face_GetCharVariantIndex(face, unicode, variation);
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
236 else
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
237 *glyph = FT_Get_Char_Index(face, unicode);
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
238
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
239 return *glyph != 0;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
240 }
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
241
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
242 static hb_position_t
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
243 cached_h_advance(hb_font_t *font, void *font_data, hb_codepoint_t glyph,
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
244 void *user_data)
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
245 {
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
246 FT_Face face = font_data;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
247 struct ass_shaper_metrics_data *metrics_priv = user_data;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
248 GlyphMetricsHashValue *metrics = get_cached_metrics(metrics_priv, face, glyph);
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
249
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
250 if (!metrics)
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
251 return 0;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
252
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
253 return metrics->metrics.horiAdvance;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
254 }
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
255
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
256 static hb_position_t
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
257 cached_v_advance(hb_font_t *font, void *font_data, hb_codepoint_t glyph,
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
258 void *user_data)
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
259 {
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
260 FT_Face face = font_data;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
261 struct ass_shaper_metrics_data *metrics_priv = user_data;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
262 GlyphMetricsHashValue *metrics = get_cached_metrics(metrics_priv, face, glyph);
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
263
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
264 if (!metrics)
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
265 return 0;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
266
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
267 return metrics->metrics.vertAdvance;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
268
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
269 }
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
270
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
271 static hb_bool_t
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
272 cached_h_origin(hb_font_t *font, void *font_data, hb_codepoint_t glyph,
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
273 hb_position_t *x, hb_position_t *y, void *user_data)
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
274 {
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
275 return 1;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
276 }
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
277
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
278 static hb_bool_t
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
279 cached_v_origin(hb_font_t *font, void *font_data, hb_codepoint_t glyph,
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
280 hb_position_t *x, hb_position_t *y, void *user_data)
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
281 {
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
282 FT_Face face = font_data;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
283 struct ass_shaper_metrics_data *metrics_priv = user_data;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
284 GlyphMetricsHashValue *metrics = get_cached_metrics(metrics_priv, face, glyph);
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
285
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
286 if (!metrics)
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
287 return 0;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
288
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
289 *x = metrics->metrics.horiBearingX - metrics->metrics.vertBearingX;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
290 *y = metrics->metrics.horiBearingY - (-metrics->metrics.vertBearingY);
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
291
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
292 return 1;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
293 }
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
294
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
295 static hb_position_t
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
296 get_h_kerning(hb_font_t *font, void *font_data, hb_codepoint_t first,
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
297 hb_codepoint_t second, void *user_data)
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
298 {
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
299 FT_Face face = font_data;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
300 FT_Vector kern;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
301
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
302 if (FT_Get_Kerning (face, first, second, FT_KERNING_DEFAULT, &kern))
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
303 return 0;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
304
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
305 return kern.x;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
306 }
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
307
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
308 static hb_position_t
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
309 get_v_kerning(hb_font_t *font, void *font_data, hb_codepoint_t first,
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
310 hb_codepoint_t second, void *user_data)
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
311 {
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
312 return 0;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
313 }
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
314
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
315 static hb_bool_t
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
316 cached_extents(hb_font_t *font, void *font_data, hb_codepoint_t glyph,
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
317 hb_glyph_extents_t *extents, void *user_data)
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
318 {
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
319 FT_Face face = font_data;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
320 struct ass_shaper_metrics_data *metrics_priv = user_data;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
321 GlyphMetricsHashValue *metrics = get_cached_metrics(metrics_priv, face, glyph);
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
322
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
323 if (!metrics)
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
324 return 0;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
325
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
326 extents->x_bearing = metrics->metrics.horiBearingX;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
327 extents->y_bearing = metrics->metrics.horiBearingY;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
328 extents->width = metrics->metrics.width;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
329 extents->height = metrics->metrics.height;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
330
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
331 return 1;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
332 }
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
333
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
334 static hb_bool_t
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
335 get_contour_point(hb_font_t *font, void *font_data, hb_codepoint_t glyph,
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
336 unsigned int point_index, hb_position_t *x,
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
337 hb_position_t *y, void *user_data)
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
338 {
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
339 FT_Face face = font_data;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
340 int load_flags = FT_LOAD_DEFAULT | FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
341 | FT_LOAD_IGNORE_TRANSFORM;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
342
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
343 if (FT_Load_Glyph(face, glyph, load_flags))
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
344 return 0;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
345
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
346 if (point_index >= (unsigned)face->glyph->outline.n_points)
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
347 return 0;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
348
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
349 *x = face->glyph->outline.points[point_index].x;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
350 *y = face->glyph->outline.points[point_index].y;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
351
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
352 return 1;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
353 }
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
354
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
355 /**
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
356 * \brief Retrieve HarfBuzz font from cache.
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
357 * Create it from FreeType font, if needed.
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
358 * \param info glyph cluster
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
359 * \return HarfBuzz font
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
360 */
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
361 static hb_font_t *get_hb_font(ASS_Shaper *shaper, GlyphInfo *info)
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
362 {
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
363 ASS_Font *font = info->font;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
364 hb_font_t **hb_fonts;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
365
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
366 if (!font->shaper_priv)
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
367 font->shaper_priv = calloc(sizeof(ASS_ShaperFontData), 1);
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
368
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
369
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
370 hb_fonts = font->shaper_priv->fonts;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
371 if (!hb_fonts[info->face_index]) {
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
372 hb_fonts[info->face_index] =
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
373 hb_ft_font_create(font->faces[info->face_index], NULL);
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
374
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
375 // set up cached metrics access
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
376 font->shaper_priv->metrics_data[info->face_index] =
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
377 calloc(sizeof(struct ass_shaper_metrics_data), 1);
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
378 struct ass_shaper_metrics_data *metrics =
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
379 font->shaper_priv->metrics_data[info->face_index];
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
380 metrics->metrics_cache = shaper->metrics_cache;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
381 metrics->vertical = info->font->desc.vertical;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
382
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
383 hb_font_funcs_t *funcs = hb_font_funcs_create();
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
384 font->shaper_priv->font_funcs[info->face_index] = funcs;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
385 hb_font_funcs_set_glyph_func(funcs, get_glyph,
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
386 metrics, NULL);
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
387 hb_font_funcs_set_glyph_h_advance_func(funcs, cached_h_advance,
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
388 metrics, NULL);
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
389 hb_font_funcs_set_glyph_v_advance_func(funcs, cached_v_advance,
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
390 metrics, NULL);
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
391 hb_font_funcs_set_glyph_h_origin_func(funcs, cached_h_origin,
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
392 metrics, NULL);
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
393 hb_font_funcs_set_glyph_v_origin_func(funcs, cached_v_origin,
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
394 metrics, NULL);
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
395 hb_font_funcs_set_glyph_h_kerning_func(funcs, get_h_kerning,
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
396 metrics, NULL);
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
397 hb_font_funcs_set_glyph_v_kerning_func(funcs, get_v_kerning,
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
398 metrics, NULL);
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
399 hb_font_funcs_set_glyph_extents_func(funcs, cached_extents,
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
400 metrics, NULL);
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
401 hb_font_funcs_set_glyph_contour_point_func(funcs, get_contour_point,
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
402 metrics, NULL);
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
403 hb_font_set_funcs(hb_fonts[info->face_index], funcs,
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
404 font->faces[info->face_index], NULL);
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
405 }
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
406
35262
49fc594fda43 Updated libass to 0.10.1
SubJunk
parents: 34342
diff changeset
407 // XXX: this is a rather crude hack
49fc594fda43 Updated libass to 0.10.1
SubJunk
parents: 34342
diff changeset
408 const double ft_size = 256.0;
49fc594fda43 Updated libass to 0.10.1
SubJunk
parents: 34342
diff changeset
409 ass_face_set_size(font->faces[info->face_index], ft_size);
34300
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
410 update_hb_size(hb_fonts[info->face_index], font->faces[info->face_index]);
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
411
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
412 // update hash key for cached metrics
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
413 struct ass_shaper_metrics_data *metrics =
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
414 font->shaper_priv->metrics_data[info->face_index];
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
415 metrics->hash_key.font = info->font;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
416 metrics->hash_key.face_index = info->face_index;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
417 metrics->hash_key.size = info->font_size;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
418 metrics->hash_key.scale_x = double_to_d6(info->scale_x);
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
419 metrics->hash_key.scale_y = double_to_d6(info->scale_y);
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
420
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
421 return hb_fonts[info->face_index];
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
422 }
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
423
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
424 /**
36363
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
425 * \brief Map script to default language.
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
426 *
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
427 * This maps a script to a language, if a script has a representative
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
428 * language it is typically used with. Otherwise, the invalid language
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
429 * is returned.
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
430 *
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
431 * The mapping is similar to Pango's pango-language.c.
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
432 *
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
433 * \param script script tag
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
434 * \return language tag
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
435 */
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
436 static hb_language_t script_to_language(hb_script_t script)
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
437 {
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
438 switch (script) {
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
439 // Unicode 1.1
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
440 case HB_SCRIPT_ARABIC: return hb_language_from_string("ar", -1); break;
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
441 case HB_SCRIPT_ARMENIAN: return hb_language_from_string("hy", -1); break;
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
442 case HB_SCRIPT_BENGALI: return hb_language_from_string("bn", -1); break;
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
443 case HB_SCRIPT_CANADIAN_ABORIGINAL: return hb_language_from_string("iu", -1); break;
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
444 case HB_SCRIPT_CHEROKEE: return hb_language_from_string("chr", -1); break;
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
445 case HB_SCRIPT_COPTIC: return hb_language_from_string("cop", -1); break;
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
446 case HB_SCRIPT_CYRILLIC: return hb_language_from_string("ru", -1); break;
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
447 case HB_SCRIPT_DEVANAGARI: return hb_language_from_string("hi", -1); break;
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
448 case HB_SCRIPT_GEORGIAN: return hb_language_from_string("ka", -1); break;
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
449 case HB_SCRIPT_GREEK: return hb_language_from_string("el", -1); break;
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
450 case HB_SCRIPT_GUJARATI: return hb_language_from_string("gu", -1); break;
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
451 case HB_SCRIPT_GURMUKHI: return hb_language_from_string("pa", -1); break;
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
452 case HB_SCRIPT_HANGUL: return hb_language_from_string("ko", -1); break;
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
453 case HB_SCRIPT_HEBREW: return hb_language_from_string("he", -1); break;
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
454 case HB_SCRIPT_HIRAGANA: return hb_language_from_string("ja", -1); break;
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
455 case HB_SCRIPT_KANNADA: return hb_language_from_string("kn", -1); break;
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
456 case HB_SCRIPT_KATAKANA: return hb_language_from_string("ja", -1); break;
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
457 case HB_SCRIPT_LAO: return hb_language_from_string("lo", -1); break;
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
458 case HB_SCRIPT_LATIN: return hb_language_from_string("en", -1); break;
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
459 case HB_SCRIPT_MALAYALAM: return hb_language_from_string("ml", -1); break;
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
460 case HB_SCRIPT_MONGOLIAN: return hb_language_from_string("mn", -1); break;
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
461 case HB_SCRIPT_ORIYA: return hb_language_from_string("or", -1); break;
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
462 case HB_SCRIPT_SYRIAC: return hb_language_from_string("syr", -1); break;
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
463 case HB_SCRIPT_TAMIL: return hb_language_from_string("ta", -1); break;
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
464 case HB_SCRIPT_TELUGU: return hb_language_from_string("te", -1); break;
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
465 case HB_SCRIPT_THAI: return hb_language_from_string("th", -1); break;
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
466
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
467 // Unicode 2.0
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
468 case HB_SCRIPT_TIBETAN: return hb_language_from_string("bo", -1); break;
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
469
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
470 // Unicode 3.0
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
471 case HB_SCRIPT_ETHIOPIC: return hb_language_from_string("am", -1); break;
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
472 case HB_SCRIPT_KHMER: return hb_language_from_string("km", -1); break;
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
473 case HB_SCRIPT_MYANMAR: return hb_language_from_string("my", -1); break;
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
474 case HB_SCRIPT_SINHALA: return hb_language_from_string("si", -1); break;
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
475 case HB_SCRIPT_THAANA: return hb_language_from_string("dv", -1); break;
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
476
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
477 // Unicode 3.2
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
478 case HB_SCRIPT_BUHID: return hb_language_from_string("bku", -1); break;
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
479 case HB_SCRIPT_HANUNOO: return hb_language_from_string("hnn", -1); break;
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
480 case HB_SCRIPT_TAGALOG: return hb_language_from_string("tl", -1); break;
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
481 case HB_SCRIPT_TAGBANWA: return hb_language_from_string("tbw", -1); break;
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
482
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
483 // Unicode 4.0
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
484 case HB_SCRIPT_UGARITIC: return hb_language_from_string("uga", -1); break;
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
485
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
486 // Unicode 4.1
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
487 case HB_SCRIPT_BUGINESE: return hb_language_from_string("bug", -1); break;
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
488 case HB_SCRIPT_OLD_PERSIAN: return hb_language_from_string("peo", -1); break;
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
489 case HB_SCRIPT_SYLOTI_NAGRI: return hb_language_from_string("syl", -1); break;
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
490
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
491 // Unicode 5.0
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
492 case HB_SCRIPT_NKO: return hb_language_from_string("nko", -1); break;
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
493
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
494 // no representative language exists
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
495 default: return HB_LANGUAGE_INVALID; break;
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
496 }
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
497 }
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
498
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
499 /**
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
500 * \brief Determine language to be used for shaping a run.
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
501 *
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
502 * \param shaper shaper instance
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
503 * \param script script tag associated with run
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
504 * \return language tag
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
505 */
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
506 static hb_language_t
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
507 hb_shaper_get_run_language(ASS_Shaper *shaper, hb_script_t script)
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
508 {
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
509 hb_language_t lang;
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
510
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
511 // override set, use it
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
512 if (shaper->language != HB_LANGUAGE_INVALID)
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
513 return shaper->language;
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
514
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
515 // get default language for given script
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
516 lang = script_to_language(script);
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
517
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
518 // no dice, use system default
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
519 if (lang == HB_LANGUAGE_INVALID)
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
520 lang = hb_language_get_default();
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
521
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
522 return lang;
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
523 }
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
524
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
525 /**
34300
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
526 * \brief Shape event text with HarfBuzz. Full OpenType shaping.
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
527 * \param glyphs glyph clusters
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
528 * \param len number of clusters
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
529 */
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
530 static void shape_harfbuzz(ASS_Shaper *shaper, GlyphInfo *glyphs, size_t len)
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
531 {
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
532 int i, j;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
533 int run = 0;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
534 struct {
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
535 int offset;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
536 int end;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
537 hb_buffer_t *buf;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
538 hb_font_t *font;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
539 } runs[MAX_RUNS];
35262
49fc594fda43 Updated libass to 0.10.1
SubJunk
parents: 34342
diff changeset
540 const double ft_size = 256.0;
34300
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
541
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
542 for (i = 0; i < len && run < MAX_RUNS; i++, run++) {
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
543 // get length and level of the current run
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
544 int k = i;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
545 int level = glyphs[i].shape_run_id;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
546 int direction = shaper->emblevels[k] % 2;
36363
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
547 hb_script_t script = glyphs[i].script;
34300
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
548 while (i < (len - 1) && level == glyphs[i+1].shape_run_id)
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
549 i++;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
550 runs[run].offset = k;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
551 runs[run].end = i;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
552 runs[run].buf = hb_buffer_create();
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
553 runs[run].font = get_hb_font(shaper, glyphs + k);
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
554 set_run_features(shaper, glyphs + k);
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
555 hb_buffer_pre_allocate(runs[run].buf, i - k + 1);
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
556 hb_buffer_set_direction(runs[run].buf, direction ? HB_DIRECTION_RTL :
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
557 HB_DIRECTION_LTR);
36363
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
558 hb_buffer_set_language(runs[run].buf,
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
559 hb_shaper_get_run_language(shaper, script));
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
560 hb_buffer_set_script(runs[run].buf, script);
34300
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
561 hb_buffer_add_utf32(runs[run].buf, shaper->event_text + k, i - k + 1,
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
562 0, i - k + 1);
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
563 hb_shape(runs[run].font, runs[run].buf, shaper->features,
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
564 shaper->n_features);
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
565 }
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
566
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
567 // Initialize: skip all glyphs, this is undone later as needed
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
568 for (i = 0; i < len; i++)
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
569 glyphs[i].skip = 1;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
570
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
571 // Update glyph indexes, positions and advances from the shaped runs
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
572 for (i = 0; i < run; i++) {
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
573 int num_glyphs = hb_buffer_get_length(runs[i].buf);
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
574 hb_glyph_info_t *glyph_info = hb_buffer_get_glyph_infos(runs[i].buf, NULL);
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
575 hb_glyph_position_t *pos = hb_buffer_get_glyph_positions(runs[i].buf, NULL);
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
576
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
577 for (j = 0; j < num_glyphs; j++) {
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
578 int idx = glyph_info[j].cluster + runs[i].offset;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
579 GlyphInfo *info = glyphs + idx;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
580 GlyphInfo *root = info;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
581
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
582 // if we have more than one glyph per cluster, allocate a new one
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
583 // and attach to the root glyph
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
584 if (info->skip == 0) {
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
585 while (info->next)
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
586 info = info->next;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
587 info->next = malloc(sizeof(GlyphInfo));
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
588 memcpy(info->next, info, sizeof(GlyphInfo));
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
589 info = info->next;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
590 info->next = NULL;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
591 }
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
592
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
593 // set position and advance
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
594 info->skip = 0;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
595 info->glyph_index = glyph_info[j].codepoint;
35262
49fc594fda43 Updated libass to 0.10.1
SubJunk
parents: 34342
diff changeset
596 info->offset.x = pos[j].x_offset * info->scale_x * (info->font_size / ft_size);
49fc594fda43 Updated libass to 0.10.1
SubJunk
parents: 34342
diff changeset
597 info->offset.y = -pos[j].y_offset * info->scale_y * (info->font_size / ft_size);
49fc594fda43 Updated libass to 0.10.1
SubJunk
parents: 34342
diff changeset
598 info->advance.x = pos[j].x_advance * info->scale_x * (info->font_size / ft_size);
49fc594fda43 Updated libass to 0.10.1
SubJunk
parents: 34342
diff changeset
599 info->advance.y = -pos[j].y_advance * info->scale_y * (info->font_size / ft_size);
34300
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
600
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
601 // accumulate advance in the root glyph
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
602 root->cluster_advance.x += info->advance.x;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
603 root->cluster_advance.y += info->advance.y;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
604 }
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
605 }
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
606
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
607 // Free runs and associated data
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
608 for (i = 0; i < run; i++) {
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
609 hb_buffer_destroy(runs[i].buf);
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
610 }
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
611
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
612 }
36363
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
613
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
614 /**
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
615 * \brief Determine script property of all characters. Characters of script
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
616 * common and inherited get their script from their context.
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
617 *
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
618 */
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
619 void ass_shaper_determine_script(ASS_Shaper *shaper, GlyphInfo *glyphs,
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
620 size_t len)
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
621 {
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
622 int i;
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
623 int backwards_scan = 0;
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
624 hb_unicode_funcs_t *ufuncs = hb_unicode_funcs_get_default();
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
625 hb_script_t last_script = HB_SCRIPT_UNKNOWN;
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
626
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
627 // determine script (forward scan)
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
628 for (i = 0; i < len; i++) {
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
629 GlyphInfo *info = glyphs + i;
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
630 info->script = hb_unicode_script(ufuncs, info->symbol);
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
631
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
632 // common/inherit codepoints inherit script from context
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
633 if (info->script == HB_SCRIPT_COMMON ||
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
634 info->script == HB_SCRIPT_INHERITED) {
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
635 // unknown is not a valid context
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
636 if (last_script != HB_SCRIPT_UNKNOWN)
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
637 info->script = last_script;
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
638 else
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
639 // do a backwards scan to check if next codepoint
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
640 // contains a valid script for context
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
641 backwards_scan = 1;
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
642 } else {
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
643 last_script = info->script;
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
644 }
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
645 }
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
646
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
647 // determine script (backwards scan, if needed)
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
648 last_script = HB_SCRIPT_UNKNOWN;
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
649 for (i = len - 1; i >= 0 && backwards_scan; i--) {
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
650 GlyphInfo *info = glyphs + i;
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
651
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
652 // common/inherit codepoints inherit script from context
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
653 if (info->script == HB_SCRIPT_COMMON ||
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
654 info->script == HB_SCRIPT_INHERITED) {
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
655 // unknown script is not a valid context
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
656 if (last_script != HB_SCRIPT_UNKNOWN)
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
657 info->script = last_script;
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
658 } else {
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
659 last_script = info->script;
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
660 }
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
661 }
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
662 }
34300
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
663 #endif
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
664
34342
575ad51cc996 Allow compiling libass without fribidi again.
reimar
parents: 34300
diff changeset
665 #ifdef CONFIG_FRIBIDI
34300
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
666 /**
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
667 * \brief Shape event text with FriBidi. Does mirroring and simple
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
668 * Arabic shaping.
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
669 * \param len number of clusters
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
670 */
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
671 static void shape_fribidi(ASS_Shaper *shaper, GlyphInfo *glyphs, size_t len)
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
672 {
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
673 int i;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
674 FriBidiJoiningType *joins = calloc(sizeof(*joins), len);
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
675
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
676 // shape on codepoint level
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
677 fribidi_get_joining_types(shaper->event_text, len, joins);
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
678 fribidi_join_arabic(shaper->ctypes, len, shaper->emblevels, joins);
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
679 fribidi_shape(FRIBIDI_FLAGS_DEFAULT | FRIBIDI_FLAGS_ARABIC,
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
680 shaper->emblevels, len, joins, shaper->event_text);
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
681
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
682 // update indexes
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
683 for (i = 0; i < len; i++) {
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
684 GlyphInfo *info = glyphs + i;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
685 FT_Face face = info->font->faces[info->face_index];
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
686 info->symbol = shaper->event_text[i];
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
687 info->glyph_index = FT_Get_Char_Index(face, shaper->event_text[i]);
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
688 }
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
689
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
690 free(joins);
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
691 }
34342
575ad51cc996 Allow compiling libass without fribidi again.
reimar
parents: 34300
diff changeset
692 #endif
34300
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
693
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
694 /**
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
695 * \brief Toggle kerning for HarfBuzz shaping.
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
696 * NOTE: currently only works with OpenType fonts, the TrueType fallback *always*
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
697 * kerns. It's a bug in HarfBuzz.
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
698 */
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
699 void ass_shaper_set_kerning(ASS_Shaper *shaper, int kern)
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
700 {
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
701 #ifdef CONFIG_HARFBUZZ
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
702 shaper->features[KERN].value = !!kern;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
703 #endif
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
704 }
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
705
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
706 /**
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
707 * \brief Find shape runs according to the event's selected fonts
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
708 */
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
709 void ass_shaper_find_runs(ASS_Shaper *shaper, ASS_Renderer *render_priv,
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
710 GlyphInfo *glyphs, size_t len)
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
711 {
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
712 int i;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
713 int shape_run = 0;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
714
36363
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
715 #ifdef CONFIG_HARFBUZZ
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
716 ass_shaper_determine_script(shaper, glyphs, len);
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
717 #endif
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
718
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
719 // find appropriate fonts for the shape runs
34300
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
720 for (i = 0; i < len; i++) {
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
721 GlyphInfo *last = glyphs + i - 1;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
722 GlyphInfo *info = glyphs + i;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
723 // skip drawings
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
724 if (info->symbol == 0xfffc)
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
725 continue;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
726 // set size and get glyph index
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
727 ass_font_get_index(render_priv->fontconfig_priv, info->font,
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
728 info->symbol, &info->face_index, &info->glyph_index);
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
729 // shape runs share the same font face and size
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
730 if (i > 0 && (last->font != info->font ||
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
731 last->font_size != info->font_size ||
36363
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
732 last->face_index != info->face_index ||
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
733 last->script != info->script))
34300
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
734 shape_run++;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
735 info->shape_run_id = shape_run;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
736 }
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
737 }
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
738
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
739 /**
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
740 * \brief Set base direction (paragraph direction) of the text.
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
741 * \param dir base direction
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
742 */
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
743 void ass_shaper_set_base_direction(ASS_Shaper *shaper, FriBidiParType dir)
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
744 {
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
745 shaper->base_direction = dir;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
746 }
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
747
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
748 /**
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
749 * \brief Set language hint. Some languages have specific character variants,
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
750 * like Serbian Cyrillic.
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
751 * \param lang ISO 639-1 two-letter language code
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
752 */
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
753 void ass_shaper_set_language(ASS_Shaper *shaper, const char *code)
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
754 {
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
755 #ifdef CONFIG_HARFBUZZ
36363
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
756 hb_language_t lang;
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
757
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
758 if (code)
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
759 lang = hb_language_from_string(code, -1);
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
760 else
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
761 lang = HB_LANGUAGE_INVALID;
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
762
c3aaaf17c721 Update libass to latest git version.
reimar
parents: 35274
diff changeset
763 shaper->language = lang;
34300
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
764 #endif
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
765 }
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
766
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
767 /**
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
768 * Set shaping level. Essentially switches between FriBidi and HarfBuzz.
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
769 */
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
770 void ass_shaper_set_level(ASS_Shaper *shaper, ASS_ShapingLevel level)
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
771 {
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
772 shaper->shaping_level = level;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
773 }
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
774
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
775 /**
35262
49fc594fda43 Updated libass to 0.10.1
SubJunk
parents: 34342
diff changeset
776 * \brief Remove all zero-width invisible characters from the text.
49fc594fda43 Updated libass to 0.10.1
SubJunk
parents: 34342
diff changeset
777 * \param text_info text
49fc594fda43 Updated libass to 0.10.1
SubJunk
parents: 34342
diff changeset
778 */
49fc594fda43 Updated libass to 0.10.1
SubJunk
parents: 34342
diff changeset
779 static void ass_shaper_skip_characters(TextInfo *text_info)
49fc594fda43 Updated libass to 0.10.1
SubJunk
parents: 34342
diff changeset
780 {
49fc594fda43 Updated libass to 0.10.1
SubJunk
parents: 34342
diff changeset
781 int i;
49fc594fda43 Updated libass to 0.10.1
SubJunk
parents: 34342
diff changeset
782 GlyphInfo *glyphs = text_info->glyphs;
49fc594fda43 Updated libass to 0.10.1
SubJunk
parents: 34342
diff changeset
783
49fc594fda43 Updated libass to 0.10.1
SubJunk
parents: 34342
diff changeset
784 for (i = 0; i < text_info->length; i++) {
49fc594fda43 Updated libass to 0.10.1
SubJunk
parents: 34342
diff changeset
785 // Skip direction override control characters
49fc594fda43 Updated libass to 0.10.1
SubJunk
parents: 34342
diff changeset
786 if ((glyphs[i].symbol <= 0x202e && glyphs[i].symbol >= 0x202a)
49fc594fda43 Updated libass to 0.10.1
SubJunk
parents: 34342
diff changeset
787 || (glyphs[i].symbol <= 0x200f && glyphs[i].symbol >= 0x200b)
49fc594fda43 Updated libass to 0.10.1
SubJunk
parents: 34342
diff changeset
788 || (glyphs[i].symbol <= 0x2063 && glyphs[i].symbol >= 0x2060)
49fc594fda43 Updated libass to 0.10.1
SubJunk
parents: 34342
diff changeset
789 || glyphs[i].symbol == 0xfeff
49fc594fda43 Updated libass to 0.10.1
SubJunk
parents: 34342
diff changeset
790 || glyphs[i].symbol == 0x00ad
49fc594fda43 Updated libass to 0.10.1
SubJunk
parents: 34342
diff changeset
791 || glyphs[i].symbol == 0x034f) {
49fc594fda43 Updated libass to 0.10.1
SubJunk
parents: 34342
diff changeset
792 glyphs[i].symbol = 0;
49fc594fda43 Updated libass to 0.10.1
SubJunk
parents: 34342
diff changeset
793 glyphs[i].skip++;
49fc594fda43 Updated libass to 0.10.1
SubJunk
parents: 34342
diff changeset
794 }
49fc594fda43 Updated libass to 0.10.1
SubJunk
parents: 34342
diff changeset
795 }
49fc594fda43 Updated libass to 0.10.1
SubJunk
parents: 34342
diff changeset
796 }
49fc594fda43 Updated libass to 0.10.1
SubJunk
parents: 34342
diff changeset
797
49fc594fda43 Updated libass to 0.10.1
SubJunk
parents: 34342
diff changeset
798 /**
34300
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
799 * \brief Shape an event's text. Calculates directional runs and shapes them.
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
800 * \param text_info event's text
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
801 */
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
802 void ass_shaper_shape(ASS_Shaper *shaper, TextInfo *text_info)
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
803 {
34342
575ad51cc996 Allow compiling libass without fribidi again.
reimar
parents: 34300
diff changeset
804 #ifndef CONFIG_FRIBIDI
575ad51cc996 Allow compiling libass without fribidi again.
reimar
parents: 34300
diff changeset
805 check_allocations(shaper, text_info->length);
575ad51cc996 Allow compiling libass without fribidi again.
reimar
parents: 34300
diff changeset
806 #else
34300
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
807 int i, last_break;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
808 FriBidiParType dir;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
809 GlyphInfo *glyphs = text_info->glyphs;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
810
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
811 check_allocations(shaper, text_info->length);
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
812
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
813 // Get bidi character types and embedding levels
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
814 last_break = 0;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
815 for (i = 0; i < text_info->length; i++) {
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
816 shaper->event_text[i] = glyphs[i].symbol;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
817 // embedding levels should be calculated paragraph by paragraph
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
818 if (glyphs[i].symbol == '\n' || i == text_info->length - 1) {
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
819 dir = shaper->base_direction;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
820 fribidi_get_bidi_types(shaper->event_text + last_break,
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
821 i - last_break + 1, shaper->ctypes + last_break);
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
822 fribidi_get_par_embedding_levels(shaper->ctypes + last_break,
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
823 i - last_break + 1, &dir, shaper->emblevels + last_break);
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
824 last_break = i + 1;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
825 }
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
826 }
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
827
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
828 // add embedding levels to shape runs for final runs
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
829 for (i = 0; i < text_info->length; i++) {
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
830 glyphs[i].shape_run_id += shaper->emblevels[i];
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
831 }
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
832
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
833 #ifdef CONFIG_HARFBUZZ
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
834 switch (shaper->shaping_level) {
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
835 case ASS_SHAPING_SIMPLE:
35274
4f4a90b80a9a libass: Fixed RTL languages
SubJunk
parents: 35262
diff changeset
836 shape_fribidi(shaper, glyphs, text_info->length);
35262
49fc594fda43 Updated libass to 0.10.1
SubJunk
parents: 34342
diff changeset
837 ass_shaper_skip_characters(text_info);
34300
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
838 break;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
839 case ASS_SHAPING_COMPLEX:
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
840 shape_harfbuzz(shaper, glyphs, text_info->length);
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
841 break;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
842 }
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
843 #else
35274
4f4a90b80a9a libass: Fixed RTL languages
SubJunk
parents: 35262
diff changeset
844 shape_fribidi(shaper, glyphs, text_info->length);
35262
49fc594fda43 Updated libass to 0.10.1
SubJunk
parents: 34342
diff changeset
845 ass_shaper_skip_characters(text_info);
34300
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
846 #endif
34342
575ad51cc996 Allow compiling libass without fribidi again.
reimar
parents: 34300
diff changeset
847 #endif
34300
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
848 }
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
849
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
850 /**
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
851 * \brief Create a new shaper instance and preallocate data structures
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
852 * \param prealloc preallocation size
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
853 */
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
854 ASS_Shaper *ass_shaper_new(size_t prealloc)
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
855 {
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
856 ASS_Shaper *shaper = calloc(sizeof(*shaper), 1);
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
857
34342
575ad51cc996 Allow compiling libass without fribidi again.
reimar
parents: 34300
diff changeset
858 #ifdef CONFIG_FRIBIDI
34300
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
859 shaper->base_direction = FRIBIDI_PAR_ON;
34342
575ad51cc996 Allow compiling libass without fribidi again.
reimar
parents: 34300
diff changeset
860 #endif
34300
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
861 check_allocations(shaper, prealloc);
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
862
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
863 #ifdef CONFIG_HARFBUZZ
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
864 init_features(shaper);
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
865 shaper->metrics_cache = ass_glyph_metrics_cache_create();
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
866 #endif
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
867
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
868 return shaper;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
869 }
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
870
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
871
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
872 /**
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
873 * \brief clean up additional data temporarily needed for shaping and
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
874 * (e.g. additional glyphs allocated)
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
875 */
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
876 void ass_shaper_cleanup(ASS_Shaper *shaper, TextInfo *text_info)
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
877 {
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
878 int i;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
879
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
880 for (i = 0; i < text_info->length; i++) {
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
881 GlyphInfo *info = text_info->glyphs + i;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
882 info = info->next;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
883 while (info) {
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
884 GlyphInfo *next = info->next;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
885 free(info);
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
886 info = next;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
887 }
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
888 }
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
889 }
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
890
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
891 /**
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
892 * \brief Calculate reorder map to render glyphs in visual order
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
893 */
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
894 FriBidiStrIndex *ass_shaper_reorder(ASS_Shaper *shaper, TextInfo *text_info)
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
895 {
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
896 int i;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
897
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
898 // Initialize reorder map
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
899 for (i = 0; i < text_info->length; i++)
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
900 shaper->cmap[i] = i;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
901
34342
575ad51cc996 Allow compiling libass without fribidi again.
reimar
parents: 34300
diff changeset
902 #ifdef CONFIG_FRIBIDI
34300
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
903 // Create reorder map line-by-line
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
904 for (i = 0; i < text_info->n_lines; i++) {
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
905 LineInfo *line = text_info->lines + i;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
906 int level;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
907 FriBidiParType dir = FRIBIDI_PAR_ON;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
908
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
909 level = fribidi_reorder_line(0,
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
910 shaper->ctypes + line->offset, line->len, 0, dir,
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
911 shaper->emblevels + line->offset, NULL,
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
912 shaper->cmap + line->offset);
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
913 }
34342
575ad51cc996 Allow compiling libass without fribidi again.
reimar
parents: 34300
diff changeset
914 #endif
34300
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
915
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
916 return shaper->cmap;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
917 }
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
918
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
919 /**
35262
49fc594fda43 Updated libass to 0.10.1
SubJunk
parents: 34342
diff changeset
920 * \brief Resolve a Windows font charset number to a suitable
34300
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
921 * base direction. 177 and 178 are Hebrew and Arabic respectively, and
35262
49fc594fda43 Updated libass to 0.10.1
SubJunk
parents: 34342
diff changeset
922 * they map to RTL. Everything else maps to LTR for compatibility
49fc594fda43 Updated libass to 0.10.1
SubJunk
parents: 34342
diff changeset
923 * reasons. The special value -1, which is not a legal Windows font charset
49fc594fda43 Updated libass to 0.10.1
SubJunk
parents: 34342
diff changeset
924 * number, can be used for autodetection.
34300
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
925 * \param enc Windows font encoding
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
926 */
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
927 FriBidiParType resolve_base_direction(int enc)
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
928 {
34342
575ad51cc996 Allow compiling libass without fribidi again.
reimar
parents: 34300
diff changeset
929 #ifdef CONFIG_FRIBIDI
34300
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
930 switch (enc) {
35262
49fc594fda43 Updated libass to 0.10.1
SubJunk
parents: 34342
diff changeset
931 case -1:
34300
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
932 return FRIBIDI_PAR_ON;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
933 case 177:
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
934 case 178:
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
935 return FRIBIDI_PAR_RTL;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
936 default:
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
937 return FRIBIDI_PAR_LTR;
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
938 }
34342
575ad51cc996 Allow compiling libass without fribidi again.
reimar
parents: 34300
diff changeset
939 #else
575ad51cc996 Allow compiling libass without fribidi again.
reimar
parents: 34300
diff changeset
940 return 0;
575ad51cc996 Allow compiling libass without fribidi again.
reimar
parents: 34300
diff changeset
941 #endif
34300
77976b68285b Commit added forgotten in previous commit.
reimar
parents:
diff changeset
942 }