Mercurial > mplayer.hg
annotate libass/ass_bitmap.c @ 30811:50e0f6942e43
Implement Win32 mutexes.
Implement Win32 mutexes; they used to just be mapped on top of events, which
is not the same thing at all.
The implementation is pretty much the obvious one, similar to the
current critical section implementation and the semaphore implementation;
a single lock count protected by a pthread mutex, and an event lockers can
sleep on to know when the mutex is available.
Also make CreateMutexA and ReleaseMutex available even if QuickTime codecs
support is not configured.
author | sesse |
---|---|
date | Sat, 06 Mar 2010 10:13:37 +0000 |
parents | 48d020c5ceca |
children | e64df5862cea |
rev | line source |
---|---|
20008
fa122b7c71c6
Add copyright notice and vim/emacs comments to libass and vf_ass.c.
eugeni
parents:
19966
diff
changeset
|
1 /* |
26723 | 2 * Copyright (C) 2006 Evgeniy Stepanov <eugeni.stepanov@gmail.com> |
3 * | |
26738
588ce97b44f2
Speak of libass instead of MPlayer in the libass license headers.
diego
parents:
26723
diff
changeset
|
4 * This file is part of libass. |
26723 | 5 * |
26738
588ce97b44f2
Speak of libass instead of MPlayer in the libass license headers.
diego
parents:
26723
diff
changeset
|
6 * libass is free software; you can redistribute it and/or modify |
26723 | 7 * it under the terms of the GNU General Public License as published by |
8 * the Free Software Foundation; either version 2 of the License, or | |
9 * (at your option) any later version. | |
10 * | |
26738
588ce97b44f2
Speak of libass instead of MPlayer in the libass license headers.
diego
parents:
26723
diff
changeset
|
11 * libass is distributed in the hope that it will be useful, |
26723 | 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 * GNU General Public License for more details. | |
15 * | |
16 * You should have received a copy of the GNU General Public License along | |
26738
588ce97b44f2
Speak of libass instead of MPlayer in the libass license headers.
diego
parents:
26723
diff
changeset
|
17 * with libass; if not, write to the Free Software Foundation, Inc., |
26723 | 18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
19 */ | |
20008
fa122b7c71c6
Add copyright notice and vim/emacs comments to libass and vf_ass.c.
eugeni
parents:
19966
diff
changeset
|
20 |
19846
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
21 #include <stdlib.h> |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
22 #include <string.h> |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
23 #include <math.h> |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
24 #include <assert.h> |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
25 #include <ft2build.h> |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
26 #include FT_GLYPH_H |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
27 |
30200 | 28 #include "ass_utils.h" |
19846
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
29 #include "ass_bitmap.h" |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
30 |
30200 | 31 struct ass_synth_priv { |
32 int tmp_w, tmp_h; | |
33 unsigned short *tmp; | |
19848 | 34 |
30200 | 35 int g_r; |
36 int g_w; | |
19848 | 37 |
30200 | 38 unsigned *g; |
39 unsigned *gt2; | |
28436
12e936031c36
Allow \be with arguments other than 0 or 1. Implement \blur.
eugeni
parents:
27409
diff
changeset
|
40 |
30200 | 41 double radius; |
19848 | 42 }; |
43 | |
44 static const unsigned int maxcolor = 255; | |
45 static const unsigned base = 256; | |
46 | |
30200 | 47 static int generate_tables(ASS_SynthPriv *priv, double radius) |
19848 | 48 { |
30200 | 49 double A = log(1.0 / base) / (radius * radius * 2); |
50 int mx, i; | |
51 double volume_diff, volume_factor = 0; | |
52 unsigned volume; | |
19848 | 53 |
30200 | 54 if (priv->radius == radius) |
55 return 0; | |
56 else | |
57 priv->radius = radius; | |
28436
12e936031c36
Allow \be with arguments other than 0 or 1. Implement \blur.
eugeni
parents:
27409
diff
changeset
|
58 |
30200 | 59 priv->g_r = ceil(radius); |
60 priv->g_w = 2 * priv->g_r + 1; | |
19955
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
61 |
30200 | 62 if (priv->g_r) { |
63 priv->g = realloc(priv->g, priv->g_w * sizeof(unsigned)); | |
64 priv->gt2 = realloc(priv->gt2, 256 * priv->g_w * sizeof(unsigned)); | |
65 if (priv->g == NULL || priv->gt2 == NULL) { | |
66 return -1; | |
67 } | |
68 } | |
19848 | 69 |
30200 | 70 if (priv->g_r) { |
71 // gaussian curve with volume = 256 | |
72 for (volume_diff = 10000000; volume_diff > 0.0000001; | |
73 volume_diff *= 0.5) { | |
74 volume_factor += volume_diff; | |
75 volume = 0; | |
76 for (i = 0; i < priv->g_w; ++i) { | |
77 priv->g[i] = | |
78 (unsigned) (exp(A * (i - priv->g_r) * (i - priv->g_r)) * | |
79 volume_factor + .5); | |
80 volume += priv->g[i]; | |
81 } | |
82 if (volume > 256) | |
83 volume_factor -= volume_diff; | |
84 } | |
85 volume = 0; | |
86 for (i = 0; i < priv->g_w; ++i) { | |
87 priv->g[i] = | |
88 (unsigned) (exp(A * (i - priv->g_r) * (i - priv->g_r)) * | |
89 volume_factor + .5); | |
90 volume += priv->g[i]; | |
91 } | |
19955
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
92 |
30200 | 93 // gauss table: |
94 for (mx = 0; mx < priv->g_w; mx++) { | |
95 for (i = 0; i < 256; i++) { | |
96 priv->gt2[mx + i * priv->g_w] = i * priv->g[mx]; | |
97 } | |
98 } | |
99 } | |
19955
2792de2ca069
Cosmetics. Change indentation of block of code to make it consistent with
eugeni
parents:
19941
diff
changeset
|
100 |
30200 | 101 return 0; |
19848 | 102 } |
103 | |
30200 | 104 static void resize_tmp(ASS_SynthPriv *priv, int w, int h) |
19848 | 105 { |
30200 | 106 if (priv->tmp_w >= w && priv->tmp_h >= h) |
107 return; | |
108 if (priv->tmp_w == 0) | |
109 priv->tmp_w = 64; | |
110 if (priv->tmp_h == 0) | |
111 priv->tmp_h = 64; | |
112 while (priv->tmp_w < w) | |
113 priv->tmp_w *= 2; | |
114 while (priv->tmp_h < h) | |
115 priv->tmp_h *= 2; | |
116 if (priv->tmp) | |
117 free(priv->tmp); | |
118 priv->tmp = malloc((priv->tmp_w + 1) * priv->tmp_h * sizeof(short)); | |
19848 | 119 } |
120 | |
30200 | 121 ASS_SynthPriv *ass_synth_init(double radius) |
19848 | 122 { |
30200 | 123 ASS_SynthPriv *priv = calloc(1, sizeof(ASS_SynthPriv)); |
124 generate_tables(priv, radius); | |
125 return priv; | |
19848 | 126 } |
127 | |
30200 | 128 void ass_synth_done(ASS_SynthPriv *priv) |
19848 | 129 { |
30200 | 130 if (priv->tmp) |
131 free(priv->tmp); | |
132 if (priv->g) | |
133 free(priv->g); | |
134 if (priv->gt2) | |
135 free(priv->gt2); | |
136 free(priv); | |
19848 | 137 } |
138 | |
30200 | 139 static Bitmap *alloc_bitmap(int w, int h) |
19846
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
140 { |
30200 | 141 Bitmap *bm; |
142 bm = calloc(1, sizeof(Bitmap)); | |
143 bm->buffer = malloc(w * h); | |
144 bm->w = w; | |
145 bm->h = h; | |
146 bm->left = bm->top = 0; | |
147 return bm; | |
19846
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
148 } |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
149 |
30200 | 150 void ass_free_bitmap(Bitmap *bm) |
19846
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
151 { |
30200 | 152 if (bm) { |
153 if (bm->buffer) | |
154 free(bm->buffer); | |
155 free(bm); | |
156 } | |
19846
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
157 } |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
158 |
30200 | 159 static Bitmap *copy_bitmap(const Bitmap *src) |
19965 | 160 { |
30200 | 161 Bitmap *dst = alloc_bitmap(src->w, src->h); |
162 dst->left = src->left; | |
163 dst->top = src->top; | |
164 memcpy(dst->buffer, src->buffer, src->w * src->h); | |
165 return dst; | |
19965 | 166 } |
167 | |
30200 | 168 static int check_glyph_area(ASS_Library *library, FT_Glyph glyph) |
26035
501ea0b13962
Check glyph bounding box before rasterizing and complain if it is too large.
eugeni
parents:
22886
diff
changeset
|
169 { |
30200 | 170 FT_BBox bbox; |
171 long long dx, dy; | |
172 FT_Glyph_Get_CBox(glyph, FT_GLYPH_BBOX_TRUNCATE, &bbox); | |
173 dx = bbox.xMax - bbox.xMin; | |
174 dy = bbox.yMax - bbox.yMin; | |
175 if (dx * dy > 8000000) { | |
176 ass_msg(library, MSGL_WARN, "Glyph bounding box too large: %dx%dpx", | |
177 (int) dx, (int) dy); | |
178 return 1; | |
179 } else | |
180 return 0; | |
26035
501ea0b13962
Check glyph bounding box before rasterizing and complain if it is too large.
eugeni
parents:
22886
diff
changeset
|
181 } |
501ea0b13962
Check glyph bounding box before rasterizing and complain if it is too large.
eugeni
parents:
22886
diff
changeset
|
182 |
30200 | 183 static Bitmap *glyph_to_bitmap_internal(ASS_Library *library, |
184 FT_Glyph glyph, int bord) | |
19846
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
185 { |
30200 | 186 FT_BitmapGlyph bg; |
187 FT_Bitmap *bit; | |
188 Bitmap *bm; | |
189 int w, h; | |
190 unsigned char *src; | |
191 unsigned char *dst; | |
192 int i; | |
193 int error; | |
19846
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
194 |
30200 | 195 if (check_glyph_area(library, glyph)) |
196 return 0; | |
197 error = FT_Glyph_To_Bitmap(&glyph, FT_RENDER_MODE_NORMAL, 0, 0); | |
198 if (error) { | |
199 ass_msg(library, MSGL_WARN, "FT_Glyph_To_Bitmap error %d", | |
200 error); | |
201 return 0; | |
202 } | |
19846
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
203 |
30200 | 204 bg = (FT_BitmapGlyph) glyph; |
205 bit = &(bg->bitmap); | |
206 if (bit->pixel_mode != FT_PIXEL_MODE_GRAY) { | |
207 ass_msg(library, MSGL_WARN, "Unsupported pixel mode: %d", | |
208 (int) (bit->pixel_mode)); | |
209 FT_Done_Glyph(glyph); | |
210 return 0; | |
211 } | |
19846
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
212 |
30200 | 213 w = bit->width; |
214 h = bit->rows; | |
215 bm = alloc_bitmap(w + 2 * bord, h + 2 * bord); | |
216 memset(bm->buffer, 0, bm->w * bm->h); | |
217 bm->left = bg->left - bord; | |
218 bm->top = -bg->top - bord; | |
19846
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
219 |
30200 | 220 src = bit->buffer; |
221 dst = bm->buffer + bord + bm->w * bord; | |
222 for (i = 0; i < h; ++i) { | |
223 memcpy(dst, src, w); | |
224 src += bit->pitch; | |
225 dst += bm->w; | |
226 } | |
19846
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
227 |
30200 | 228 FT_Done_Glyph(glyph); |
229 return bm; | |
19846
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
230 } |
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
231 |
19966 | 232 /** |
30200 | 233 * \brief fix outline bitmap |
234 * | |
235 * The glyph bitmap is subtracted from outline bitmap. This way looks much | |
236 * better in some cases. | |
19966 | 237 */ |
30200 | 238 static void fix_outline(Bitmap *bm_g, Bitmap *bm_o) |
239 { | |
240 int x, y; | |
241 const int l = bm_o->left > bm_g->left ? bm_o->left : bm_g->left; | |
242 const int t = bm_o->top > bm_g->top ? bm_o->top : bm_g->top; | |
243 const int r = | |
244 bm_o->left + bm_o->w < | |
245 bm_g->left + bm_g->w ? bm_o->left + bm_o->w : bm_g->left + bm_g->w; | |
246 const int b = | |
247 bm_o->top + bm_o->h < | |
248 bm_g->top + bm_g->h ? bm_o->top + bm_o->h : bm_g->top + bm_g->h; | |
249 | |
250 unsigned char *g = | |
251 bm_g->buffer + (t - bm_g->top) * bm_g->w + (l - bm_g->left); | |
252 unsigned char *o = | |
253 bm_o->buffer + (t - bm_o->top) * bm_o->w + (l - bm_o->left); | |
254 | |
255 for (y = 0; y < b - t; ++y) { | |
256 for (x = 0; x < r - l; ++x) { | |
257 unsigned char c_g, c_o; | |
258 c_g = g[x]; | |
259 c_o = o[x]; | |
260 o[x] = (c_o > c_g) ? c_o - (c_g / 2) : 0; | |
261 } | |
262 g += bm_g->w; | |
263 o += bm_o->w; | |
264 } | |
265 } | |
266 | |
267 /** | |
268 * \brief Shift a bitmap by the fraction of a pixel in x and y direction | |
269 * expressed in 26.6 fixed point | |
270 */ | |
271 static void shift_bitmap(unsigned char *buf, int w, int h, int shift_x, | |
272 int shift_y) | |
19856 | 273 { |
30200 | 274 int x, y, b; |
275 | |
276 // Shift in x direction | |
277 if (shift_x > 0) { | |
278 for (y = 0; y < h; y++) { | |
279 for (x = w - 1; x > 0; x--) { | |
280 b = (buf[x + y * w - 1] * shift_x) >> 6; | |
281 buf[x + y * w - 1] -= b; | |
282 buf[x + y * w] += b; | |
283 } | |
284 } | |
285 } else if (shift_x < 0) { | |
286 shift_x = -shift_x; | |
287 for (y = 0; y < h; y++) { | |
288 for (x = 0; x < w - 1; x++) { | |
289 b = (buf[x + y * w + 1] * shift_x) >> 6; | |
290 buf[x + y * w + 1] -= b; | |
291 buf[x + y * w] += b; | |
292 } | |
293 } | |
294 } | |
19965 | 295 |
30200 | 296 // Shift in y direction |
297 if (shift_y > 0) { | |
298 for (x = 0; x < w; x++) { | |
299 for (y = h - 1; y > 0; y--) { | |
300 b = (buf[x + (y - 1) * w] * shift_y) >> 6; | |
301 buf[x + (y - 1) * w] -= b; | |
302 buf[x + y * w] += b; | |
303 } | |
304 } | |
305 } else if (shift_y < 0) { | |
306 shift_y = -shift_y; | |
307 for (x = 0; x < w; x++) { | |
308 for (y = 0; y < h - 1; y++) { | |
309 b = (buf[x + (y + 1) * w] * shift_y) >> 6; | |
310 buf[x + (y + 1) * w] -= b; | |
311 buf[x + y * w] += b; | |
312 } | |
313 } | |
314 } | |
315 } | |
316 | |
317 /* | |
318 * Gaussian blur. An fast pure C implementation from MPlayer. | |
319 */ | |
320 static void ass_gauss_blur(unsigned char *buffer, unsigned short *tmp2, | |
321 int width, int height, int stride, int *m2, | |
322 int r, int mwidth) | |
323 { | |
324 | |
325 int x, y; | |
326 | |
327 unsigned char *s = buffer; | |
328 unsigned short *t = tmp2 + 1; | |
329 for (y = 0; y < height; y++) { | |
330 memset(t - 1, 0, (width + 1) * sizeof(short)); | |
19965 | 331 |
30200 | 332 for (x = 0; x < r; x++) { |
333 const int src = s[x]; | |
334 if (src) { | |
335 register unsigned short *dstp = t + x - r; | |
336 int mx; | |
337 unsigned *m3 = (unsigned *) (m2 + src * mwidth); | |
338 for (mx = r - x; mx < mwidth; mx++) { | |
339 dstp[mx] += m3[mx]; | |
340 } | |
341 } | |
342 } | |
343 | |
344 for (; x < width - r; x++) { | |
345 const int src = s[x]; | |
346 if (src) { | |
347 register unsigned short *dstp = t + x - r; | |
348 int mx; | |
349 unsigned *m3 = (unsigned *) (m2 + src * mwidth); | |
350 for (mx = 0; mx < mwidth; mx++) { | |
351 dstp[mx] += m3[mx]; | |
352 } | |
353 } | |
354 } | |
355 | |
356 for (; x < width; x++) { | |
357 const int src = s[x]; | |
358 if (src) { | |
359 register unsigned short *dstp = t + x - r; | |
360 int mx; | |
361 const int x2 = r + width - x; | |
362 unsigned *m3 = (unsigned *) (m2 + src * mwidth); | |
363 for (mx = 0; mx < x2; mx++) { | |
364 dstp[mx] += m3[mx]; | |
365 } | |
366 } | |
367 } | |
368 | |
369 s += stride; | |
370 t += width + 1; | |
371 } | |
372 | |
373 t = tmp2; | |
374 for (x = 0; x < width; x++) { | |
375 for (y = 0; y < r; y++) { | |
376 unsigned short *srcp = t + y * (width + 1) + 1; | |
377 int src = *srcp; | |
378 if (src) { | |
379 register unsigned short *dstp = srcp - 1 + width + 1; | |
380 const int src2 = (src + 128) >> 8; | |
381 unsigned *m3 = (unsigned *) (m2 + src2 * mwidth); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28802
diff
changeset
|
382 |
30200 | 383 int mx; |
384 *srcp = 128; | |
385 for (mx = r - 1; mx < mwidth; mx++) { | |
386 *dstp += m3[mx]; | |
387 dstp += width + 1; | |
388 } | |
389 } | |
390 } | |
391 for (; y < height - r; y++) { | |
392 unsigned short *srcp = t + y * (width + 1) + 1; | |
393 int src = *srcp; | |
394 if (src) { | |
395 register unsigned short *dstp = srcp - 1 - r * (width + 1); | |
396 const int src2 = (src + 128) >> 8; | |
397 unsigned *m3 = (unsigned *) (m2 + src2 * mwidth); | |
19965 | 398 |
30200 | 399 int mx; |
400 *srcp = 128; | |
401 for (mx = 0; mx < mwidth; mx++) { | |
402 *dstp += m3[mx]; | |
403 dstp += width + 1; | |
404 } | |
405 } | |
406 } | |
407 for (; y < height; y++) { | |
408 unsigned short *srcp = t + y * (width + 1) + 1; | |
409 int src = *srcp; | |
410 if (src) { | |
411 const int y2 = r + height - y; | |
412 register unsigned short *dstp = srcp - 1 - r * (width + 1); | |
413 const int src2 = (src + 128) >> 8; | |
414 unsigned *m3 = (unsigned *) (m2 + src2 * mwidth); | |
415 | |
416 int mx; | |
417 *srcp = 128; | |
418 for (mx = 0; mx < y2; mx++) { | |
419 *dstp += m3[mx]; | |
420 dstp += width + 1; | |
421 } | |
422 } | |
423 } | |
424 t++; | |
425 } | |
426 | |
427 t = tmp2; | |
428 s = buffer; | |
429 for (y = 0; y < height; y++) { | |
430 for (x = 0; x < width; x++) { | |
431 s[x] = t[x] >> 8; | |
432 } | |
433 s += stride; | |
434 t += width + 1; | |
435 } | |
19856 | 436 } |
437 | |
28799
65b83aee82fb
Use blur with kernel [[1,2,1], [2,4,2], [1,2,1]] for \be.
greg
parents:
28781
diff
changeset
|
438 /** |
65b83aee82fb
Use blur with kernel [[1,2,1], [2,4,2], [1,2,1]] for \be.
greg
parents:
28781
diff
changeset
|
439 * \brief Blur with [[1,2,1]. [2,4,2], [1,2,1]] kernel |
65b83aee82fb
Use blur with kernel [[1,2,1], [2,4,2], [1,2,1]] for \be.
greg
parents:
28781
diff
changeset
|
440 * This blur is the same as the one employed by vsfilter. |
65b83aee82fb
Use blur with kernel [[1,2,1], [2,4,2], [1,2,1]] for \be.
greg
parents:
28781
diff
changeset
|
441 */ |
30200 | 442 static void be_blur(unsigned char *buf, int w, int h) |
443 { | |
444 unsigned int x, y; | |
445 unsigned int old_sum, new_sum; | |
28799
65b83aee82fb
Use blur with kernel [[1,2,1], [2,4,2], [1,2,1]] for \be.
greg
parents:
28781
diff
changeset
|
446 |
30200 | 447 for (y = 0; y < h; y++) { |
448 old_sum = 2 * buf[y * w]; | |
449 for (x = 0; x < w - 1; x++) { | |
450 new_sum = buf[y * w + x] + buf[y * w + x + 1]; | |
451 buf[y * w + x] = (old_sum + new_sum) >> 2; | |
452 old_sum = new_sum; | |
453 } | |
454 } | |
28799
65b83aee82fb
Use blur with kernel [[1,2,1], [2,4,2], [1,2,1]] for \be.
greg
parents:
28781
diff
changeset
|
455 |
30200 | 456 for (x = 0; x < w; x++) { |
457 old_sum = 2 * buf[x]; | |
458 for (y = 0; y < h - 1; y++) { | |
459 new_sum = buf[y * w + x] + buf[(y + 1) * w + x]; | |
460 buf[y * w + x] = (old_sum + new_sum) >> 2; | |
461 old_sum = new_sum; | |
462 } | |
463 } | |
28799
65b83aee82fb
Use blur with kernel [[1,2,1], [2,4,2], [1,2,1]] for \be.
greg
parents:
28781
diff
changeset
|
464 } |
65b83aee82fb
Use blur with kernel [[1,2,1], [2,4,2], [1,2,1]] for \be.
greg
parents:
28781
diff
changeset
|
465 |
30200 | 466 int glyph_to_bitmap(ASS_Library *library, ASS_SynthPriv *priv_blur, |
467 FT_Glyph glyph, FT_Glyph outline_glyph, | |
468 Bitmap **bm_g, Bitmap **bm_o, Bitmap **bm_s, | |
469 int be, double blur_radius, FT_Vector shadow_offset, | |
470 int border_style) | |
19846
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
471 { |
30200 | 472 blur_radius *= 2; |
473 int bbord = be > 0 ? sqrt(2 * be) : 0; | |
474 int gbord = blur_radius > 0.0 ? blur_radius + 1 : 0; | |
475 int bord = FFMAX(bbord, gbord); | |
476 if (bord == 0 && (shadow_offset.x || shadow_offset.y)) | |
477 bord = 1; | |
19848 | 478 |
30200 | 479 assert(bm_g && bm_o && bm_s); |
19965 | 480 |
30200 | 481 *bm_g = *bm_o = *bm_s = 0; |
19846
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
482 |
30200 | 483 if (glyph) |
484 *bm_g = glyph_to_bitmap_internal(library, glyph, bord); | |
485 if (!*bm_g) | |
486 return 1; | |
487 | |
488 if (outline_glyph) { | |
489 *bm_o = glyph_to_bitmap_internal(library, outline_glyph, bord); | |
490 if (!*bm_o) { | |
491 return 1; | |
492 } | |
493 } | |
19965 | 494 |
30200 | 495 // Apply box blur (multiple passes, if requested) |
496 while (be--) { | |
497 if (*bm_o) | |
498 be_blur((*bm_o)->buffer, (*bm_o)->w, (*bm_o)->h); | |
499 else | |
500 be_blur((*bm_g)->buffer, (*bm_g)->w, (*bm_g)->h); | |
501 } | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28802
diff
changeset
|
502 |
30200 | 503 // Apply gaussian blur |
504 if (blur_radius > 0.0) { | |
505 if (*bm_o) | |
506 resize_tmp(priv_blur, (*bm_o)->w, (*bm_o)->h); | |
507 else | |
508 resize_tmp(priv_blur, (*bm_g)->w, (*bm_g)->h); | |
509 generate_tables(priv_blur, blur_radius); | |
510 if (*bm_o) | |
511 ass_gauss_blur((*bm_o)->buffer, priv_blur->tmp, | |
512 (*bm_o)->w, (*bm_o)->h, (*bm_o)->w, | |
513 (int *) priv_blur->gt2, priv_blur->g_r, | |
514 priv_blur->g_w); | |
515 else | |
516 ass_gauss_blur((*bm_g)->buffer, priv_blur->tmp, | |
517 (*bm_g)->w, (*bm_g)->h, (*bm_g)->w, | |
518 (int *) priv_blur->gt2, priv_blur->g_r, | |
519 priv_blur->g_w); | |
520 } | |
19856 | 521 |
30200 | 522 // Create shadow and fix outline as needed |
523 if (*bm_o && border_style != 3) { | |
524 *bm_s = copy_bitmap(*bm_o); | |
525 fix_outline(*bm_g, *bm_o); | |
526 } else if (*bm_o) { | |
527 *bm_s = copy_bitmap(*bm_o); | |
528 } else | |
529 *bm_s = copy_bitmap(*bm_g); | |
530 | |
531 assert(bm_s); | |
532 | |
533 shift_bitmap((*bm_s)->buffer, (*bm_s)->w,(*bm_s)->h, | |
534 shadow_offset.x, shadow_offset.y); | |
535 | |
536 return 0; | |
19846
bcc792bfa431
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
eugeni
parents:
diff
changeset
|
537 } |