/src/libass/libass/ass_render_api.c
Line | Count | Source |
1 | | /* |
2 | | * Copyright (C) 2006 Evgeniy Stepanov <eugeni.stepanov@gmail.com> |
3 | | * Copyright (C) 2010 Grigori Goronzy <greg@geekmind.org> |
4 | | * |
5 | | * This file is part of libass. |
6 | | * |
7 | | * Permission to use, copy, modify, and distribute this software for any |
8 | | * purpose with or without fee is hereby granted, provided that the above |
9 | | * copyright notice and this permission notice appear in all copies. |
10 | | * |
11 | | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
12 | | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
13 | | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
14 | | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
15 | | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
16 | | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
17 | | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
18 | | */ |
19 | | |
20 | | #include "config.h" |
21 | | #include "ass_compat.h" |
22 | | |
23 | | #include <limits.h> |
24 | | #include <stdint.h> |
25 | | |
26 | | #include "ass_render.h" |
27 | | #include "ass_utils.h" |
28 | | |
29 | | static void ass_reconfigure(ASS_Renderer *priv) |
30 | 35.8k | { |
31 | 35.8k | ASS_Settings *settings = &priv->settings; |
32 | | |
33 | 35.8k | priv->render_id++; |
34 | 35.8k | ass_cache_empty(priv->cache.composite_cache); |
35 | 35.8k | ass_cache_empty(priv->cache.bitmap_cache); |
36 | 35.8k | ass_cache_empty(priv->cache.outline_cache); |
37 | | |
38 | 35.8k | priv->width = settings->frame_width; |
39 | 35.8k | priv->height = settings->frame_height; |
40 | 35.8k | priv->frame_content_width = settings->frame_width - settings->left_margin - |
41 | 35.8k | settings->right_margin; |
42 | 35.8k | priv->frame_content_height = settings->frame_height - settings->top_margin - |
43 | 35.8k | settings->bottom_margin; |
44 | 35.8k | priv->fit_width = |
45 | 35.8k | (long long) priv->frame_content_width * priv->height >= |
46 | 35.8k | (long long) priv->frame_content_height * priv->width ? |
47 | 35.8k | priv->width : |
48 | 35.8k | (double) priv->frame_content_width * priv->height / priv->frame_content_height; |
49 | 35.8k | priv->fit_height = |
50 | 35.8k | (long long) priv->frame_content_width * priv->height <= |
51 | 35.8k | (long long) priv->frame_content_height * priv->width ? |
52 | 35.8k | priv->height : |
53 | 35.8k | (double) priv->frame_content_height * priv->width / priv->frame_content_width; |
54 | 35.8k | } |
55 | | |
56 | | void ass_set_frame_size(ASS_Renderer *priv, int w, int h) |
57 | 11.9k | { |
58 | 11.9k | if (w <= 0 || h <= 0 || w > FFMIN(INT_MAX, SIZE_MAX) / h) |
59 | 0 | w = h = 0; |
60 | 11.9k | if (priv->settings.frame_width != w || priv->settings.frame_height != h) { |
61 | 11.9k | priv->settings.frame_width = w; |
62 | 11.9k | priv->settings.frame_height = h; |
63 | 11.9k | ass_reconfigure(priv); |
64 | 11.9k | } |
65 | 11.9k | } |
66 | | |
67 | | void ass_set_storage_size(ASS_Renderer *priv, int w, int h) |
68 | 11.9k | { |
69 | 11.9k | if (w <= 0 || h <= 0 || w > FFMIN(INT_MAX, SIZE_MAX) / h) |
70 | 0 | w = h = 0; |
71 | 11.9k | if (priv->settings.storage_width != w || |
72 | 11.9k | priv->settings.storage_height != h) { |
73 | 11.9k | priv->settings.storage_width = w; |
74 | 11.9k | priv->settings.storage_height = h; |
75 | 11.9k | ass_reconfigure(priv); |
76 | 11.9k | } |
77 | 11.9k | } |
78 | | |
79 | | void ass_set_shaper(ASS_Renderer *priv, ASS_ShapingLevel level) |
80 | 0 | { |
81 | | // select the complex shaper for illegal values |
82 | 0 | if (level == ASS_SHAPING_SIMPLE || level == ASS_SHAPING_COMPLEX) |
83 | 0 | priv->settings.shaper = level; |
84 | 0 | else |
85 | 0 | priv->settings.shaper = ASS_SHAPING_COMPLEX; |
86 | 0 | } |
87 | | |
88 | | void ass_set_margins(ASS_Renderer *priv, int t, int b, int l, int r) |
89 | 0 | { |
90 | 0 | if (priv->settings.left_margin != l || priv->settings.right_margin != r || |
91 | 0 | priv->settings.top_margin != t || priv->settings.bottom_margin != b) { |
92 | 0 | priv->settings.left_margin = l; |
93 | 0 | priv->settings.right_margin = r; |
94 | 0 | priv->settings.top_margin = t; |
95 | 0 | priv->settings.bottom_margin = b; |
96 | 0 | ass_reconfigure(priv); |
97 | 0 | } |
98 | 0 | } |
99 | | |
100 | | void ass_set_use_margins(ASS_Renderer *priv, int use) |
101 | 0 | { |
102 | 0 | priv->settings.use_margins = use; |
103 | 0 | } |
104 | | |
105 | | void ass_set_aspect_ratio(ASS_Renderer *priv, double dar, double sar) |
106 | 0 | { |
107 | 0 | ass_set_pixel_aspect(priv, dar / sar); |
108 | 0 | } |
109 | | |
110 | | void ass_set_pixel_aspect(ASS_Renderer *priv, double par) |
111 | 0 | { |
112 | 0 | if (par < 0) par = 0; |
113 | 0 | if (priv->settings.par != par) { |
114 | 0 | priv->settings.par = par; |
115 | 0 | ass_reconfigure(priv); |
116 | 0 | } |
117 | 0 | } |
118 | | |
119 | | void ass_set_font_scale(ASS_Renderer *priv, double font_scale) |
120 | 0 | { |
121 | 0 | if (priv->settings.font_size_coeff != font_scale) { |
122 | 0 | priv->settings.font_size_coeff = font_scale; |
123 | 0 | ass_reconfigure(priv); |
124 | 0 | } |
125 | 0 | } |
126 | | |
127 | | void ass_set_hinting(ASS_Renderer *priv, ASS_Hinting ht) |
128 | 0 | { |
129 | 0 | if (priv->settings.hinting != ht) { |
130 | 0 | priv->settings.hinting = ht; |
131 | 0 | ass_reconfigure(priv); |
132 | 0 | } |
133 | 0 | } |
134 | | |
135 | | void ass_set_line_spacing(ASS_Renderer *priv, double line_spacing) |
136 | 0 | { |
137 | 0 | priv->settings.line_spacing = line_spacing; |
138 | 0 | } |
139 | | |
140 | | void ass_set_line_position(ASS_Renderer *priv, double line_position) |
141 | 0 | { |
142 | 0 | if (priv->settings.line_position != line_position) { |
143 | 0 | priv->settings.line_position = line_position; |
144 | 0 | ass_reconfigure(priv); |
145 | 0 | } |
146 | 0 | } |
147 | | |
148 | | void ass_set_fonts(ASS_Renderer *priv, const char *default_font, |
149 | | const char *default_family, int dfp, |
150 | | const char *config, int update) |
151 | 11.9k | { |
152 | 11.9k | free(priv->settings.default_font); |
153 | 11.9k | free(priv->settings.default_family); |
154 | 11.9k | priv->settings.default_font = default_font ? strdup(default_font) : 0; |
155 | 11.9k | priv->settings.default_family = |
156 | 11.9k | default_family ? strdup(default_family) : 0; |
157 | | |
158 | 11.9k | ass_reconfigure(priv); |
159 | | |
160 | 11.9k | ass_cache_empty(priv->cache.font_cache); |
161 | 11.9k | ass_cache_empty(priv->cache.metrics_cache); |
162 | | |
163 | 11.9k | if (priv->fontselect) |
164 | 0 | ass_fontselect_free(priv->fontselect); |
165 | 11.9k | priv->fontselect = ass_fontselect_init(priv->library, priv->ftlibrary, |
166 | 11.9k | &priv->num_emfonts, default_family, default_font, config, dfp); |
167 | 11.9k | } |
168 | | |
169 | | void ass_set_selective_style_override_enabled(ASS_Renderer *priv, int bits) |
170 | 0 | { |
171 | 0 | if (priv->settings.selective_style_overrides != bits) { |
172 | 0 | priv->settings.selective_style_overrides = bits; |
173 | 0 | ass_reconfigure(priv); |
174 | 0 | } |
175 | 0 | } |
176 | | |
177 | | void ass_set_selective_style_override(ASS_Renderer *priv, ASS_Style *style) |
178 | 0 | { |
179 | 0 | ASS_Style *user_style = &priv->user_override_style; |
180 | 0 | free(user_style->FontName); |
181 | 0 | *user_style = *style; |
182 | 0 | user_style->FontName = strdup(user_style->FontName); |
183 | 0 | ass_reconfigure(priv); |
184 | 0 | } |
185 | | |
186 | | int ass_fonts_update(ASS_Renderer *render_priv) |
187 | 0 | { |
188 | | // This is just a stub now! |
189 | 0 | return 1; |
190 | 0 | } |
191 | | |
192 | | void ass_set_cache_limits(ASS_Renderer *render_priv, int glyph_max, |
193 | | int bitmap_max) |
194 | 0 | { |
195 | 0 | render_priv->cache.glyph_max = glyph_max ? glyph_max : GLYPH_CACHE_MAX; |
196 | |
|
197 | 0 | size_t bitmap_cache, composite_cache; |
198 | 0 | if (bitmap_max) { |
199 | 0 | bitmap_cache = MEGABYTE * (size_t) bitmap_max; |
200 | 0 | composite_cache = bitmap_cache / (COMPOSITE_CACHE_RATIO + 1); |
201 | 0 | bitmap_cache -= composite_cache; |
202 | 0 | } else { |
203 | 0 | bitmap_cache = BITMAP_CACHE_MAX_SIZE; |
204 | 0 | composite_cache = COMPOSITE_CACHE_MAX_SIZE; |
205 | 0 | } |
206 | 0 | render_priv->cache.bitmap_max_size = bitmap_cache; |
207 | 0 | render_priv->cache.composite_max_size = composite_cache; |
208 | 0 | } |
209 | | |
210 | | ASS_FontProvider * |
211 | | ass_create_font_provider(ASS_Renderer *priv, ASS_FontProviderFuncs *funcs, |
212 | | void *data) |
213 | 0 | { |
214 | 0 | return ass_font_provider_new(priv->fontselect, funcs, data); |
215 | 0 | } |