summaryrefslogtreecommitdiffstats
path: root/libass/ass_bitmap.c
diff options
context:
space:
mode:
authoreugeni <eugeni@b3059339-0415-0410-9bf9-f77b7e298cf2>2006-09-16 13:32:46 +0000
committereugeni <eugeni@b3059339-0415-0410-9bf9-f77b7e298cf2>2006-09-16 13:32:46 +0000
commit69cbeae8457acc1266d5471c5b7b9fb4dff2d374 (patch)
tree32732bb00905d13ac0ae90a04155af5cb4c73f2e /libass/ass_bitmap.c
parentb21382fa5b313ab1faa6a7722e77bf3b56f3be2f (diff)
downloadmpv-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.c107
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;
}