Mercurial > mplayer.hg
comparison libass/ass_render.c @ 36363:c3aaaf17c721
Update libass to latest git version.
author | reimar |
---|---|
date | Tue, 24 Sep 2013 20:50:02 +0000 |
parents | c7866af24567 |
children |
comparison
equal
deleted
inserted
replaced
36362:99708d402208 | 36363:c3aaaf17c721 |
---|---|
238 * karaoke effects. This can result in a lot of bitmaps (6 to be exact). | 238 * karaoke effects. This can result in a lot of bitmaps (6 to be exact). |
239 */ | 239 */ |
240 static ASS_Image **render_glyph_i(ASS_Renderer *render_priv, | 240 static ASS_Image **render_glyph_i(ASS_Renderer *render_priv, |
241 Bitmap *bm, int dst_x, int dst_y, | 241 Bitmap *bm, int dst_x, int dst_y, |
242 uint32_t color, uint32_t color2, int brk, | 242 uint32_t color, uint32_t color2, int brk, |
243 ASS_Image **tail) | 243 ASS_Image **tail, unsigned int type) |
244 { | 244 { |
245 int i, j, x0, y0, x1, y1, cx0, cy0, cx1, cy1, sx, sy, zx, zy; | 245 int i, j, x0, y0, x1, y1, cx0, cy0, cx1, cy1, sx, sy, zx, zy; |
246 Rect r[4]; | 246 Rect r[4]; |
247 ASS_Image *img; | 247 ASS_Image *img; |
248 | 248 |
306 if (lbrk > r[j].x1) lbrk = r[j].x1; | 306 if (lbrk > r[j].x1) lbrk = r[j].x1; |
307 img = my_draw_bitmap(bm->buffer + r[j].y0 * bm->stride + r[j].x0, | 307 img = my_draw_bitmap(bm->buffer + r[j].y0 * bm->stride + r[j].x0, |
308 lbrk - r[j].x0, r[j].y1 - r[j].y0, | 308 lbrk - r[j].x0, r[j].y1 - r[j].y0, |
309 bm->stride, dst_x + r[j].x0, dst_y + r[j].y0, color); | 309 bm->stride, dst_x + r[j].x0, dst_y + r[j].y0, color); |
310 if (!img) break; | 310 if (!img) break; |
311 img->type = type; | |
311 *tail = img; | 312 *tail = img; |
312 tail = &img->next; | 313 tail = &img->next; |
313 } | 314 } |
314 if (lbrk < r[j].x1) { | 315 if (lbrk < r[j].x1) { |
315 if (lbrk < r[j].x0) lbrk = r[j].x0; | 316 if (lbrk < r[j].x0) lbrk = r[j].x0; |
316 img = my_draw_bitmap(bm->buffer + r[j].y0 * bm->stride + lbrk, | 317 img = my_draw_bitmap(bm->buffer + r[j].y0 * bm->stride + lbrk, |
317 r[j].x1 - lbrk, r[j].y1 - r[j].y0, | 318 r[j].x1 - lbrk, r[j].y1 - r[j].y0, |
318 bm->stride, dst_x + lbrk, dst_y + r[j].y0, color2); | 319 bm->stride, dst_x + lbrk, dst_y + r[j].y0, color2); |
319 if (!img) break; | 320 if (!img) break; |
321 img->type = type; | |
320 *tail = img; | 322 *tail = img; |
321 tail = &img->next; | 323 tail = &img->next; |
322 } | 324 } |
323 } | 325 } |
324 | 326 |
337 * \return pointer to the new list tail | 339 * \return pointer to the new list tail |
338 * Performs clipping. Uses my_draw_bitmap for actual bitmap convertion. | 340 * Performs clipping. Uses my_draw_bitmap for actual bitmap convertion. |
339 */ | 341 */ |
340 static ASS_Image ** | 342 static ASS_Image ** |
341 render_glyph(ASS_Renderer *render_priv, Bitmap *bm, int dst_x, int dst_y, | 343 render_glyph(ASS_Renderer *render_priv, Bitmap *bm, int dst_x, int dst_y, |
342 uint32_t color, uint32_t color2, int brk, ASS_Image **tail) | 344 uint32_t color, uint32_t color2, int brk, ASS_Image **tail, unsigned int type) |
343 { | 345 { |
344 // Inverse clipping in use? | 346 // Inverse clipping in use? |
345 if (render_priv->state.clip_mode) | 347 if (render_priv->state.clip_mode) |
346 return render_glyph_i(render_priv, bm, dst_x, dst_y, color, color2, | 348 return render_glyph_i(render_priv, bm, dst_x, dst_y, color, color2, |
347 brk, tail); | 349 brk, tail, type); |
348 | 350 |
349 // brk is relative to dst_x | 351 // brk is relative to dst_x |
350 // color = color left of brk | 352 // color = color left of brk |
351 // color2 = color right of brk | 353 // color2 = color right of brk |
352 int b_x0, b_y0, b_x1, b_y1; // visible part of the bitmap | 354 int b_x0, b_y0, b_x1, b_y1; // visible part of the bitmap |
397 brk = b_x1; | 399 brk = b_x1; |
398 img = my_draw_bitmap(bm->buffer + bm->stride * b_y0 + b_x0, | 400 img = my_draw_bitmap(bm->buffer + bm->stride * b_y0 + b_x0, |
399 brk - b_x0, b_y1 - b_y0, bm->stride, | 401 brk - b_x0, b_y1 - b_y0, bm->stride, |
400 dst_x + b_x0, dst_y + b_y0, color); | 402 dst_x + b_x0, dst_y + b_y0, color); |
401 if (!img) return tail; | 403 if (!img) return tail; |
404 img->type = type; | |
402 *tail = img; | 405 *tail = img; |
403 tail = &img->next; | 406 tail = &img->next; |
404 } | 407 } |
405 if (brk < b_x1) { // draw right part | 408 if (brk < b_x1) { // draw right part |
406 if (brk < b_x0) | 409 if (brk < b_x0) |
407 brk = b_x0; | 410 brk = b_x0; |
408 img = my_draw_bitmap(bm->buffer + bm->stride * b_y0 + brk, | 411 img = my_draw_bitmap(bm->buffer + bm->stride * b_y0 + brk, |
409 b_x1 - brk, b_y1 - b_y0, bm->stride, | 412 b_x1 - brk, b_y1 - b_y0, bm->stride, |
410 dst_x + brk, dst_y + b_y0, color2); | 413 dst_x + brk, dst_y + b_y0, color2); |
411 if (!img) return tail; | 414 if (!img) return tail; |
415 img->type = type; | |
412 *tail = img; | 416 *tail = img; |
413 tail = &img->next; | 417 tail = &img->next; |
414 } | 418 } |
415 return tail; | 419 return tail; |
416 } | 420 } |
716 bm = info->bm_s; | 720 bm = info->bm_s; |
717 | 721 |
718 here_tail = tail; | 722 here_tail = tail; |
719 tail = | 723 tail = |
720 render_glyph(render_priv, bm, pen_x, pen_y, info->c[3], 0, | 724 render_glyph(render_priv, bm, pen_x, pen_y, info->c[3], 0, |
721 1000000, tail); | 725 1000000, tail, IMAGE_TYPE_SHADOW); |
722 | 726 |
723 if (last_tail && tail != here_tail && ((info->c[3] & 0xff) > 0)) | 727 if (last_tail && tail != here_tail && ((info->c[3] & 0xff) > 0)) |
724 render_overlap(render_priv, last_tail, here_tail); | 728 render_overlap(render_priv, last_tail, here_tail); |
725 last_tail = here_tail; | 729 last_tail = here_tail; |
726 | 730 |
750 // do nothing | 754 // do nothing |
751 } else { | 755 } else { |
752 here_tail = tail; | 756 here_tail = tail; |
753 tail = | 757 tail = |
754 render_glyph(render_priv, bm, pen_x, pen_y, info->c[2], | 758 render_glyph(render_priv, bm, pen_x, pen_y, info->c[2], |
755 0, 1000000, tail); | 759 0, 1000000, tail, IMAGE_TYPE_OUTLINE); |
756 if (last_tail && tail != here_tail && ((info->c[2] & 0xff) > 0)) | 760 if (last_tail && tail != here_tail && ((info->c[2] & 0xff) > 0)) |
757 render_overlap(render_priv, last_tail, here_tail); | 761 render_overlap(render_priv, last_tail, here_tail); |
758 | 762 |
759 last_tail = here_tail; | 763 last_tail = here_tail; |
760 } | 764 } |
781 if ((info->effect_type == EF_KARAOKE) | 785 if ((info->effect_type == EF_KARAOKE) |
782 || (info->effect_type == EF_KARAOKE_KO)) { | 786 || (info->effect_type == EF_KARAOKE_KO)) { |
783 if (info->effect_timing > (info->bbox.xMax >> 6)) | 787 if (info->effect_timing > (info->bbox.xMax >> 6)) |
784 tail = | 788 tail = |
785 render_glyph(render_priv, bm, pen_x, pen_y, | 789 render_glyph(render_priv, bm, pen_x, pen_y, |
786 info->c[0], 0, 1000000, tail); | 790 info->c[0], 0, 1000000, tail, IMAGE_TYPE_CHARACTER); |
787 else | 791 else |
788 tail = | 792 tail = |
789 render_glyph(render_priv, bm, pen_x, pen_y, | 793 render_glyph(render_priv, bm, pen_x, pen_y, |
790 info->c[1], 0, 1000000, tail); | 794 info->c[1], 0, 1000000, tail, IMAGE_TYPE_CHARACTER); |
791 } else if (info->effect_type == EF_KARAOKE_KF) { | 795 } else if (info->effect_type == EF_KARAOKE_KF) { |
792 tail = | 796 tail = |
793 render_glyph(render_priv, bm, pen_x, pen_y, info->c[0], | 797 render_glyph(render_priv, bm, pen_x, pen_y, info->c[0], |
794 info->c[1], info->effect_timing, tail); | 798 info->c[1], info->effect_timing, tail, IMAGE_TYPE_CHARACTER); |
795 } else | 799 } else |
796 tail = | 800 tail = |
797 render_glyph(render_priv, bm, pen_x, pen_y, info->c[0], | 801 render_glyph(render_priv, bm, pen_x, pen_y, info->c[0], |
798 0, 1000000, tail); | 802 0, 1000000, tail, IMAGE_TYPE_CHARACTER); |
799 info = info->next; | 803 info = info->next; |
800 } | 804 } |
801 } | 805 } |
802 | 806 |
803 *tail = 0; | 807 *tail = 0; |
864 change_border(render_priv, render_priv->state.border_x, render_priv->state.border_y); | 868 change_border(render_priv, render_priv->state.border_x, render_priv->state.border_y); |
865 render_priv->state.scale_x = style->ScaleX; | 869 render_priv->state.scale_x = style->ScaleX; |
866 render_priv->state.scale_y = style->ScaleY; | 870 render_priv->state.scale_y = style->ScaleY; |
867 render_priv->state.hspacing = style->Spacing; | 871 render_priv->state.hspacing = style->Spacing; |
868 render_priv->state.be = 0; | 872 render_priv->state.be = 0; |
869 render_priv->state.blur = 0.0; | 873 render_priv->state.blur = style->Blur; |
870 render_priv->state.shadow_x = style->Shadow; | 874 render_priv->state.shadow_x = style->Shadow; |
871 render_priv->state.shadow_y = style->Shadow; | 875 render_priv->state.shadow_y = style->Shadow; |
872 render_priv->state.frx = render_priv->state.fry = 0.; | 876 render_priv->state.frx = render_priv->state.fry = 0.; |
873 render_priv->state.frz = M_PI * style->Angle / 180.; | 877 render_priv->state.frz = M_PI * style->Angle / 180.; |
874 render_priv->state.fax = render_priv->state.fay = 0.; | 878 render_priv->state.fax = render_priv->state.fay = 0.; |
925 | 929 |
926 /* | 930 /* |
927 * Replace the outline of a glyph by a contour which makes up a simple | 931 * Replace the outline of a glyph by a contour which makes up a simple |
928 * opaque rectangle. | 932 * opaque rectangle. |
929 */ | 933 */ |
930 static void draw_opaque_box(ASS_Renderer *render_priv, int asc, int desc, | 934 static void draw_opaque_box(ASS_Renderer *render_priv, GlyphInfo *info, |
931 FT_Outline *ol, FT_Vector advance, int sx, int sy) | 935 int asc, int desc, FT_Outline *ol, |
936 FT_Vector advance, int sx, int sy) | |
932 { | 937 { |
933 int i; | 938 int i; |
934 int adv = advance.x; | 939 int adv = advance.x; |
935 double scale_y = render_priv->state.scale_y; | 940 double scale_y = info->scale_y; |
936 double scale_x = render_priv->state.scale_x; | 941 double scale_x = info->scale_x; |
937 | 942 |
938 // to avoid gaps | 943 // to avoid gaps |
939 sx = FFMAX(64, sx); | 944 sx = FFMAX(64, sx); |
940 sy = FFMAX(64, sy); | 945 sy = FFMAX(64, sy); |
941 | 946 |
942 // Emulate the WTFish behavior of VSFilter, i.e. double-scale | 947 // Emulate the WTFish behavior of VSFilter, i.e. double-scale |
943 // the sizes of the opaque box. | 948 // the sizes of the opaque box. |
944 adv += double_to_d6(render_priv->state.hspacing * render_priv->font_scale | 949 adv += double_to_d6(info->hspacing * render_priv->font_scale * scale_x); |
945 * scale_x); | |
946 adv *= scale_x; | 950 adv *= scale_x; |
947 sx *= scale_x; | 951 sx *= scale_x; |
948 sy *= scale_y; | 952 sy *= scale_y; |
949 desc *= scale_y; | 953 desc *= scale_y; |
950 desc += asc * (scale_y - 1.0); | 954 desc += asc * (scale_y - 1.0); |
1125 if (!v.outline) | 1129 if (!v.outline) |
1126 return; | 1130 return; |
1127 | 1131 |
1128 FT_Outline_Get_CBox(v.outline, &v.bbox_scaled); | 1132 FT_Outline_Get_CBox(v.outline, &v.bbox_scaled); |
1129 | 1133 |
1130 if (info->border_style == 3 && | 1134 if (info->border_style == 3) { |
1131 (info->border_x > 0 || info->border_y > 0)) { | |
1132 FT_Vector advance; | 1135 FT_Vector advance; |
1133 | 1136 |
1134 v.border = calloc(1, sizeof(FT_Outline)); | 1137 v.border = calloc(1, sizeof(FT_Outline)); |
1135 | 1138 |
1136 if (priv->settings.shaper == ASS_SHAPING_SIMPLE || info->drawing) | 1139 if (priv->settings.shaper == ASS_SHAPING_SIMPLE || info->drawing) |
1137 advance = v.advance; | 1140 advance = v.advance; |
1138 else | 1141 else |
1139 advance = info->advance; | 1142 advance = info->advance; |
1140 | 1143 |
1141 draw_opaque_box(priv, v.asc, v.desc, v.border, advance, | 1144 draw_opaque_box(priv, info, v.asc, v.desc, v.border, advance, |
1142 double_to_d6(info->border_x * priv->border_scale), | 1145 double_to_d6(info->border_x * priv->border_scale), |
1143 double_to_d6(info->border_y * priv->border_scale)); | 1146 double_to_d6(info->border_y * priv->border_scale)); |
1144 | 1147 |
1145 } else if ((info->border_x > 0 || info->border_y > 0) | 1148 } else if ((info->border_x > 0 || info->border_y > 0) |
1146 && double_to_d6(info->scale_x) && double_to_d6(info->scale_y)) { | 1149 && double_to_d6(info->scale_x) && double_to_d6(info->scale_y)) { |
1309 render_priv->synth_priv, | 1312 render_priv->synth_priv, |
1310 render_priv->ftlibrary, | 1313 render_priv->ftlibrary, |
1311 outline, border, | 1314 outline, border, |
1312 &hash_val.bm, &hash_val.bm_o, | 1315 &hash_val.bm, &hash_val.bm_o, |
1313 &hash_val.bm_s, info->be, | 1316 &hash_val.bm_s, info->be, |
1314 info->blur * render_priv->border_scale, | 1317 info->blur * render_priv->blur_scale, |
1315 key->shadow_offset, | 1318 key->shadow_offset, |
1316 info->border_style); | 1319 info->border_style, |
1320 info->border_x || info->border_y); | |
1317 if (error) | 1321 if (error) |
1318 info->symbol = 0; | 1322 info->symbol = 0; |
1319 | 1323 |
1320 val = ass_cache_put(render_priv->cache.bitmap_cache, &info->hash_key, | 1324 val = ass_cache_put(render_priv->cache.bitmap_cache, &info->hash_key, |
1321 &hash_val); | 1325 &hash_val); |
2242 | 2246 |
2243 ass_lazy_track_init(render_priv->library, render_priv->track); | 2247 ass_lazy_track_init(render_priv->library, render_priv->track); |
2244 | 2248 |
2245 render_priv->font_scale = settings_priv->font_size_coeff * | 2249 render_priv->font_scale = settings_priv->font_size_coeff * |
2246 render_priv->orig_height / render_priv->track->PlayResY; | 2250 render_priv->orig_height / render_priv->track->PlayResY; |
2251 if (render_priv->storage_height) | |
2252 render_priv->blur_scale = ((double) render_priv->orig_height) / | |
2253 render_priv->storage_height; | |
2254 else | |
2255 render_priv->blur_scale = 1.; | |
2247 if (render_priv->track->ScaledBorderAndShadow) | 2256 if (render_priv->track->ScaledBorderAndShadow) |
2248 render_priv->border_scale = | 2257 render_priv->border_scale = |
2249 ((double) render_priv->orig_height) / | 2258 ((double) render_priv->orig_height) / |
2250 render_priv->track->PlayResY; | 2259 render_priv->track->PlayResY; |
2251 else | 2260 else |
2252 render_priv->border_scale = 1.; | 2261 render_priv->border_scale = render_priv->blur_scale; |
2262 render_priv->border_scale *= settings_priv->font_size_coeff; | |
2253 | 2263 |
2254 ass_shaper_set_kerning(render_priv->shaper, track->Kerning); | 2264 ass_shaper_set_kerning(render_priv->shaper, track->Kerning); |
2255 if (track->Language) | 2265 ass_shaper_set_language(render_priv->shaper, track->Language); |
2256 ass_shaper_set_language(render_priv->shaper, track->Language); | |
2257 ass_shaper_set_level(render_priv->shaper, render_priv->settings.shaper); | 2266 ass_shaper_set_level(render_priv->shaper, render_priv->settings.shaper); |
2258 | 2267 |
2259 // PAR correction | 2268 // PAR correction |
2260 render_priv->font_scale_x = render_priv->settings.aspect / | 2269 double par = render_priv->settings.par; |
2261 render_priv->settings.storage_aspect; | 2270 if (par == 0.) { |
2271 if (settings_priv->frame_width && settings_priv->frame_height && | |
2272 settings_priv->storage_width && settings_priv->storage_height) { | |
2273 double dar = ((double) settings_priv->frame_width) / | |
2274 settings_priv->frame_height; | |
2275 double sar = ((double) settings_priv->storage_width) / | |
2276 settings_priv->storage_height; | |
2277 par = sar / dar; | |
2278 } else | |
2279 par = 1.0; | |
2280 } | |
2281 render_priv->font_scale_x = par; | |
2262 | 2282 |
2263 render_priv->prev_images_root = render_priv->images_root; | 2283 render_priv->prev_images_root = render_priv->images_root; |
2264 render_priv->images_root = 0; | 2284 render_priv->images_root = 0; |
2265 | 2285 |
2266 check_cache_limits(render_priv, &render_priv->cache); | 2286 check_cache_limits(render_priv, &render_priv->cache); |