diff options
author | eugeni <eugeni@b3059339-0415-0410-9bf9-f77b7e298cf2> | 2006-09-16 13:32:46 +0000 |
---|---|---|
committer | eugeni <eugeni@b3059339-0415-0410-9bf9-f77b7e298cf2> | 2006-09-16 13:32:46 +0000 |
commit | 69cbeae8457acc1266d5471c5b7b9fb4dff2d374 (patch) | |
tree | 32732bb00905d13ac0ae90a04155af5cb4c73f2e /libass/ass_bitmap.c | |
parent | b21382fa5b313ab1faa6a7722e77bf3b56f3be2f (diff) | |
download | mpv-69cbeae8457acc1266d5471c5b7b9fb4dff2d374.tar.bz2 mpv-69cbeae8457acc1266d5471c5b7b9fb4dff2d374.tar.xz |
Add \be (blur edges) support to libass.
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@19854 b3059339-0415-0410-9bf9-f77b7e298cf2
Diffstat (limited to 'libass/ass_bitmap.c')
-rw-r--r-- | libass/ass_bitmap.c | 107 |
1 files changed, 104 insertions, 3 deletions
diff --git a/libass/ass_bitmap.c b/libass/ass_bitmap.c index 9d98ec000a..c7d5f786aa 100644 --- a/libass/ass_bitmap.c +++ b/libass/ass_bitmap.c @@ -6,8 +6,97 @@ #include FT_GLYPH_H #include "mp_msg.h" +#include "libvo/font_load.h" // for blur() #include "ass_bitmap.h" +struct ass_synth_priv_s { + int tmp_w, tmp_h; + unsigned short* tmp; + + int g_r; + int g_w; + + unsigned *g; + unsigned *gt2; +}; + +static const unsigned int maxcolor = 255; +static const unsigned base = 256; +static const double blur_radius = 1.5; + +static int generate_tables(ass_synth_priv_t* priv, double radius) +{ + double A = log(1.0/base)/(radius*radius*2); + int mx, i; + double volume_diff, volume_factor = 0; + unsigned volume; + + priv->g_r = ceil(radius); + priv->g_w = 2*priv->g_r+1; + + if (priv->g_r) { + priv->g = malloc(priv->g_w * sizeof(unsigned)); + priv->gt2 = malloc(256 * priv->g_w * sizeof(unsigned)); + if (priv->g==NULL || priv->gt2==NULL) { + return -1; + } + } + + if (priv->g_r) { + // gaussian curve with volume = 256 + for (volume_diff=10000000; volume_diff>0.0000001; volume_diff*=0.5){ + volume_factor+= volume_diff; + volume=0; + for (i = 0; i<priv->g_w; ++i) { + priv->g[i] = (unsigned)(exp(A * (i-priv->g_r)*(i-priv->g_r)) * volume_factor + .5); + volume+= priv->g[i]; + } + if(volume>256) volume_factor-= volume_diff; + } + volume=0; + for (i = 0; i<priv->g_w; ++i) { + priv->g[i] = (unsigned)(exp(A * (i-priv->g_r)*(i-priv->g_r)) * volume_factor + .5); + volume+= priv->g[i]; + } + + // gauss table: + for(mx=0;mx<priv->g_w;mx++){ + for(i=0;i<256;i++){ + priv->gt2[mx+i*priv->g_w] = i*priv->g[mx]; + } + } + } + + return 0; +} + +static void resize_tmp(ass_synth_priv_t* priv, int w, int h) +{ + if (priv->tmp_w >= w && priv->tmp_h >= h) + return; + if (priv->tmp_w == 0) + priv->tmp_w = 64; + if (priv->tmp_h == 0) + priv->tmp_h = 64; + while (priv->tmp_w < w) priv->tmp_w *= 2; + while (priv->tmp_h < h) priv->tmp_h *= 2; + if (priv->tmp) + free(priv->tmp); + priv->tmp = malloc((priv->tmp_w + 1) * priv->tmp_h * sizeof(short)); +} + +ass_synth_priv_t* ass_synth_init() +{ + ass_synth_priv_t* priv = calloc(1, sizeof(ass_synth_priv_t)); + generate_tables(priv, blur_radius); + return priv; +} + +void ass_synth_done(ass_synth_priv_t* priv) +{ + free(priv); +} + static bitmap_t* alloc_bitmap(int w, int h) { bitmap_t* bm; @@ -70,22 +159,34 @@ static bitmap_t* glyph_to_bitmap_internal(FT_Glyph glyph, int bord) return bm; } -int glyph_to_bitmap(FT_Glyph glyph, FT_Glyph outline_glyph, bitmap_t** bm_g, bitmap_t** bm_o) +int glyph_to_bitmap(ass_synth_priv_t* priv, FT_Glyph glyph, FT_Glyph outline_glyph, bitmap_t** bm_g, bitmap_t** bm_o, int be) { + const int bord = ceil(blur_radius); + assert(bm_g); if (glyph) - *bm_g = glyph_to_bitmap_internal(glyph, 0); + *bm_g = glyph_to_bitmap_internal(glyph, bord); if (!*bm_g) return 1; if (outline_glyph && bm_o) { - *bm_o = glyph_to_bitmap_internal(outline_glyph, 0); + *bm_o = glyph_to_bitmap_internal(outline_glyph, bord); if (!*bm_o) { ass_free_bitmap(*bm_g); return 1; } } + if (bm_o) + resize_tmp(priv, (*bm_o)->w, (*bm_o)->h); + resize_tmp(priv, (*bm_g)->w, (*bm_g)->h); + + if (be) { + blur((*bm_g)->buffer, priv->tmp, (*bm_g)->w, (*bm_g)->h, (*bm_g)->w, (int*)priv->gt2, priv->g_r, priv->g_w); + if (bm_o) + blur((*bm_o)->buffer, priv->tmp, (*bm_o)->w, (*bm_o)->h, (*bm_o)->w, (int*)priv->gt2, priv->g_r, priv->g_w); + } + return 0; } |