Mercurial > mplayer.hg
comparison libass/ass_render.c @ 19965:70352570e9ae
Shadow support in libass.
author | eugeni |
---|---|
date | Sun, 24 Sep 2006 16:04:37 +0000 |
parents | fb2063eaa445 |
children | fa122b7c71c6 |
comparison
equal
deleted
inserted
replaced
19964:edee81101156 | 19965:70352570e9ae |
---|---|
51 // glyph_info_t and text_info_t are used for text centering and word-wrapping operations | 51 // glyph_info_t and text_info_t are used for text centering and word-wrapping operations |
52 typedef struct glyph_info_s { | 52 typedef struct glyph_info_s { |
53 unsigned symbol; | 53 unsigned symbol; |
54 FT_Glyph glyph; | 54 FT_Glyph glyph; |
55 FT_Glyph outline_glyph; | 55 FT_Glyph outline_glyph; |
56 bitmap_t* bm; | 56 bitmap_t* bm; // glyph bitmap |
57 bitmap_t* bm_o; | 57 bitmap_t* bm_o; // outline bitmap |
58 bitmap_t* bm_s; // shadow bitmap | |
58 FT_BBox bbox; | 59 FT_BBox bbox; |
59 FT_Vector pos; | 60 FT_Vector pos; |
60 char linebreak; // the first (leading) glyph of some line ? | 61 char linebreak; // the first (leading) glyph of some line ? |
61 uint32_t c[4]; // colors | 62 uint32_t c[4]; // colors |
62 FT_Vector advance; // 26.6 | 63 FT_Vector advance; // 26.6 |
66 // part of the glyph to the left of it is displayed in a different color. | 67 // part of the glyph to the left of it is displayed in a different color. |
67 int effect_skip_timing; // delay after the end of last karaoke word | 68 int effect_skip_timing; // delay after the end of last karaoke word |
68 int asc, desc; // font max ascender and descender | 69 int asc, desc; // font max ascender and descender |
69 // int height; | 70 // int height; |
70 int be; // blur edges | 71 int be; // blur edges |
72 int shadow; | |
71 | 73 |
72 glyph_hash_key_t hash_key; | 74 glyph_hash_key_t hash_key; |
73 } glyph_info_t; | 75 } glyph_info_t; |
74 | 76 |
75 typedef struct line_info_s { | 77 typedef struct line_info_s { |
111 uint32_t c[4]; // colors(Primary, Secondary, so on) in RGBA | 113 uint32_t c[4]; // colors(Primary, Secondary, so on) in RGBA |
112 int clip_x0, clip_y0, clip_x1, clip_y1; | 114 int clip_x0, clip_y0, clip_x1, clip_y1; |
113 char detect_collisions; | 115 char detect_collisions; |
114 uint32_t fade; // alpha from \fad | 116 uint32_t fade; // alpha from \fad |
115 char be; // blur edges | 117 char be; // blur edges |
118 int shadow; | |
116 | 119 |
117 effect_t effect_type; | 120 effect_t effect_type; |
118 int effect_timing; | 121 int effect_timing; |
119 int effect_skip_timing; | 122 int effect_skip_timing; |
120 | 123 |
374 if (text_info->glyphs[i].glyph) { | 377 if (text_info->glyphs[i].glyph) { |
375 if ((text_info->glyphs[i].symbol == '\n') || (text_info->glyphs[i].symbol == 0)) | 378 if ((text_info->glyphs[i].symbol == '\n') || (text_info->glyphs[i].symbol == 0)) |
376 continue; | 379 continue; |
377 error = glyph_to_bitmap(ass_instance->synth_priv, | 380 error = glyph_to_bitmap(ass_instance->synth_priv, |
378 text_info->glyphs[i].glyph, text_info->glyphs[i].outline_glyph, | 381 text_info->glyphs[i].glyph, text_info->glyphs[i].outline_glyph, |
379 &text_info->glyphs[i].bm, &text_info->glyphs[i].bm_o, text_info->glyphs[i].be); | 382 &text_info->glyphs[i].bm, &text_info->glyphs[i].bm_o, |
383 &text_info->glyphs[i].bm_s, text_info->glyphs[i].be); | |
380 if (error) | 384 if (error) |
381 text_info->glyphs[i].symbol = 0; | 385 text_info->glyphs[i].symbol = 0; |
382 FT_Done_Glyph(text_info->glyphs[i].glyph); | 386 FT_Done_Glyph(text_info->glyphs[i].glyph); |
383 if (text_info->glyphs[i].outline_glyph) | 387 if (text_info->glyphs[i].outline_glyph) |
384 FT_Done_Glyph(text_info->glyphs[i].outline_glyph); | 388 FT_Done_Glyph(text_info->glyphs[i].outline_glyph); |
385 | 389 |
386 // cache | 390 // cache |
387 hash_val.bbox_scaled = text_info->glyphs[i].bbox; | 391 hash_val.bbox_scaled = text_info->glyphs[i].bbox; |
388 hash_val.bm_o = text_info->glyphs[i].bm_o; | 392 hash_val.bm_o = text_info->glyphs[i].bm_o; |
389 hash_val.bm = text_info->glyphs[i].bm; | 393 hash_val.bm = text_info->glyphs[i].bm; |
394 hash_val.bm_s = text_info->glyphs[i].bm_s; | |
390 hash_val.advance.x = text_info->glyphs[i].advance.x; | 395 hash_val.advance.x = text_info->glyphs[i].advance.x; |
391 hash_val.advance.y = text_info->glyphs[i].advance.y; | 396 hash_val.advance.y = text_info->glyphs[i].advance.y; |
392 cache_add_glyph(&(text_info->glyphs[i].hash_key), &hash_val); | 397 cache_add_glyph(&(text_info->glyphs[i].hash_key), &hash_val); |
393 | 398 |
394 } | 399 } |
400 } | |
401 | |
402 for (i = 0; i < text_info->length; ++i) { | |
403 glyph_info_t* info = text_info->glyphs + i; | |
404 if ((info->symbol == 0) || (info->symbol == '\n') || !info->bm_s || (info->shadow == 0)) | |
405 continue; | |
406 | |
407 pen_x = dst_x + info->pos.x + info->shadow; | |
408 pen_y = dst_y + info->pos.y + info->shadow; | |
409 bm = info->bm_s; | |
410 | |
411 tail = render_glyph(bm, pen_x, pen_y, info->c[3], 0, 1000000, tail); | |
395 } | 412 } |
396 | 413 |
397 for (i = 0; i < text_info->length; ++i) { | 414 for (i = 0; i < text_info->length; ++i) { |
398 glyph_info_t* info = text_info->glyphs + i; | 415 glyph_info_t* info = text_info->glyphs + i; |
399 if ((info->symbol == 0) || (info->symbol == '\n') || !info->bm_o) | 416 if ((info->symbol == 0) || (info->symbol == '\n') || !info->bm_o) |
990 int val = strtol(p, &p, 10); | 1007 int val = strtol(p, &p, 10); |
991 render_context.effect_type = EF_KARAOKE; | 1008 render_context.effect_type = EF_KARAOKE; |
992 if (render_context.effect_timing) | 1009 if (render_context.effect_timing) |
993 render_context.effect_skip_timing += render_context.effect_timing; | 1010 render_context.effect_skip_timing += render_context.effect_timing; |
994 render_context.effect_timing = val * 10; | 1011 render_context.effect_timing = val * 10; |
1012 } else if (mystrcmp(&p, "shad")) { | |
1013 int val; | |
1014 if (mystrtoi(&p, 10, &val)) | |
1015 render_context.shadow = val; | |
1016 else | |
1017 render_context.shadow = render_context.style->Shadow; | |
995 } | 1018 } |
996 | 1019 |
997 return p; | 1020 return p; |
998 | 1021 |
999 #undef skip | 1022 #undef skip |
1135 change_border(-1.); | 1158 change_border(-1.); |
1136 render_context.scale_x = render_context.style->ScaleX; | 1159 render_context.scale_x = render_context.style->ScaleX; |
1137 render_context.scale_y = render_context.style->ScaleY; | 1160 render_context.scale_y = render_context.style->ScaleY; |
1138 render_context.hspacing = 0; // FIXME | 1161 render_context.hspacing = 0; // FIXME |
1139 render_context.be = 0; | 1162 render_context.be = 0; |
1163 render_context.shadow = render_context.style->Shadow; | |
1140 | 1164 |
1141 // FIXME: does not reset unsupported attributes. | 1165 // FIXME: does not reset unsupported attributes. |
1142 } | 1166 } |
1143 | 1167 |
1144 /** | 1168 /** |
1206 | 1230 |
1207 if (val) { | 1231 if (val) { |
1208 info->glyph = info->outline_glyph = 0; | 1232 info->glyph = info->outline_glyph = 0; |
1209 info->bm = val->bm; | 1233 info->bm = val->bm; |
1210 info->bm_o = val->bm_o; | 1234 info->bm_o = val->bm_o; |
1235 info->bm_s = val->bm_s; | |
1211 info->bbox = val->bbox_scaled; | 1236 info->bbox = val->bbox_scaled; |
1212 info->advance.x = val->advance.x; | 1237 info->advance.x = val->advance.x; |
1213 info->advance.y = val->advance.y; | 1238 info->advance.y = val->advance.y; |
1214 | 1239 |
1215 return 0; | 1240 return 0; |
1250 } | 1275 } |
1251 } else { | 1276 } else { |
1252 info->outline_glyph = 0; | 1277 info->outline_glyph = 0; |
1253 } | 1278 } |
1254 | 1279 |
1255 info->bm = info->bm_o = 0; | 1280 info->bm = info->bm_o = info->bm_s = 0; |
1256 | 1281 |
1257 return 0; | 1282 return 0; |
1258 } | 1283 } |
1259 | 1284 |
1260 /** | 1285 /** |
1623 text_info.glyphs[text_info.length].effect_timing = render_context.effect_timing; | 1648 text_info.glyphs[text_info.length].effect_timing = render_context.effect_timing; |
1624 text_info.glyphs[text_info.length].effect_skip_timing = render_context.effect_skip_timing; | 1649 text_info.glyphs[text_info.length].effect_skip_timing = render_context.effect_skip_timing; |
1625 text_info.glyphs[text_info.length].asc = get_face_ascender(render_context.face); | 1650 text_info.glyphs[text_info.length].asc = get_face_ascender(render_context.face); |
1626 text_info.glyphs[text_info.length].desc = get_face_descender(render_context.face); | 1651 text_info.glyphs[text_info.length].desc = get_face_descender(render_context.face); |
1627 text_info.glyphs[text_info.length].be = render_context.be; | 1652 text_info.glyphs[text_info.length].be = render_context.be; |
1653 text_info.glyphs[text_info.length].shadow = render_context.shadow; | |
1628 | 1654 |
1629 text_info.length++; | 1655 text_info.length++; |
1630 | 1656 |
1631 render_context.effect_type = EF_NONE; | 1657 render_context.effect_type = EF_NONE; |
1632 render_context.effect_timing = 0; | 1658 render_context.effect_timing = 0; |