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);