summaryrefslogtreecommitdiffstats
path: root/libass/ass_render.c
diff options
context:
space:
mode:
authoreugeni <eugeni@b3059339-0415-0410-9bf9-f77b7e298cf2>2006-09-16 13:08:17 +0000
committereugeni <eugeni@b3059339-0415-0410-9bf9-f77b7e298cf2>2006-09-16 13:08:17 +0000
commit867aa92076b8b4264e8e1a3378a1b6ed076da7f0 (patch)
tree67e35551c43ac77b304deb23289c14241c1f6679 /libass/ass_render.c
parent52204b1e9381b7c856be3e16dc795a97b041b068 (diff)
downloadmpv-867aa92076b8b4264e8e1a3378a1b6ed076da7f0.tar.bz2
mpv-867aa92076b8b4264e8e1a3378a1b6ed076da7f0.tar.xz
Store bitmap glyphs in a separate struct, instead of FreeType's internal buffer.
This is required for various bitmap modifications (like blur, outline and shadow). git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@19852 b3059339-0415-0410-9bf9-f77b7e298cf2
Diffstat (limited to 'libass/ass_render.c')
-rw-r--r--libass/ass_render.c104
1 files changed, 44 insertions, 60 deletions
diff --git a/libass/ass_render.c b/libass/ass_render.c
index 6aee3cd8d4..e0096ca219 100644
--- a/libass/ass_render.c
+++ b/libass/ass_render.c
@@ -12,6 +12,7 @@
#include "mp_msg.h"
#include "ass.h"
+#include "ass_bitmap.h"
#include "ass_cache.h"
#include "ass_utils.h"
#include "ass_fontconfig.h"
@@ -51,11 +52,12 @@ typedef struct glyph_info_s {
unsigned symbol;
FT_Glyph glyph;
FT_Glyph outline_glyph;
+ bitmap_t* bm;
+ bitmap_t* bm_o;
FT_BBox bbox;
FT_Vector pos;
char linebreak; // the first (leading) glyph of some line ?
uint32_t c[4]; // colors
- char bitmap; // bool
FT_Vector advance; // 26.6
effect_t effect_type;
int effect_timing; // time duration of current karaoke word
@@ -223,6 +225,7 @@ ass_instance_t* ass_init(void)
fontconfig_done(fc_priv);
goto ass_init_exit;
}
+
priv->library = ft;
priv->fontconfig_priv = fc_priv;
// images_root and related stuff is zero-filled in calloc
@@ -280,7 +283,7 @@ static ass_image_t* my_draw_bitmap(unsigned char* bitmap, int bitmap_w, int bitm
* \return pointer to the new list tail
* Performs clipping. Uses my_draw_bitmap for actual bitmap convertion.
*/
-static ass_image_t** render_glyph(FT_BitmapGlyph bit, int dst_x, int dst_y, uint32_t color, uint32_t color2, int brk, ass_image_t** tail)
+static ass_image_t** render_glyph(bitmap_t* bm, int dst_x, int dst_y, uint32_t color, uint32_t color2, int brk, ass_image_t** tail)
{
// brk is relative to dst_x
// color = color left of brk
@@ -288,19 +291,12 @@ static ass_image_t** render_glyph(FT_BitmapGlyph bit, int dst_x, int dst_y, uint
int b_x0, b_y0, b_x1, b_y1; // visible part of the bitmap
int clip_x0, clip_y0, clip_x1, clip_y1;
int tmp;
- FT_Bitmap* bitmap;
ass_image_t* img;
- bitmap = &(bit->bitmap);
- dst_x += bit->left;
- dst_y -= bit->top;
- brk -= bit->left;
+ dst_x += bm->left;
+ dst_y += bm->top;
+ brk -= bm->left;
- if (bitmap->pixel_mode != FT_PIXEL_MODE_GRAY) {
- mp_msg(MSGT_GLOBAL, MSGL_WARN, "Unsupported pixel mode: %d\n", (int)(bitmap->pixel_mode));
- return tail;
- }
-
// clipping
clip_x0 = render_context.clip_x0;
clip_y0 = render_context.clip_y0;
@@ -308,8 +304,8 @@ static ass_image_t** render_glyph(FT_BitmapGlyph bit, int dst_x, int dst_y, uint
clip_y1 = render_context.clip_y1;
b_x0 = 0;
b_y0 = 0;
- b_x1 = bitmap->width;
- b_y1 = bitmap->rows;
+ b_x1 = bm->w;
+ b_y1 = bm->h;
tmp = dst_x - clip_x0;
if (tmp < 0) {
@@ -321,15 +317,15 @@ static ass_image_t** render_glyph(FT_BitmapGlyph bit, int dst_x, int dst_y, uint
mp_msg(MSGT_GLOBAL, MSGL_DBG2, "clip top\n");
b_y0 = - tmp;
}
- tmp = clip_x1 - dst_x - bitmap->width;
+ tmp = clip_x1 - dst_x - bm->w;
if (tmp < 0) {
mp_msg(MSGT_GLOBAL, MSGL_DBG2, "clip right\n");
- b_x1 = bitmap->width + tmp;
+ b_x1 = bm->w + tmp;
}
- tmp = clip_y1 - dst_y - bitmap->rows;
+ tmp = clip_y1 - dst_y - bm->h;
if (tmp < 0) {
mp_msg(MSGT_GLOBAL, MSGL_DBG2, "clip bottom\n");
- b_y1 = bitmap->rows + tmp;
+ b_y1 = bm->h + tmp;
}
if ((b_y0 >= b_y1) || (b_x0 >= b_x1))
@@ -337,16 +333,16 @@ static ass_image_t** render_glyph(FT_BitmapGlyph bit, int dst_x, int dst_y, uint
if (brk > b_x0) { // draw left part
if (brk > b_x1) brk = b_x1;
- img = my_draw_bitmap(bitmap->buffer + bitmap->pitch * b_y0 + b_x0,
- brk - b_x0, b_y1 - b_y0, bitmap->pitch,
+ img = my_draw_bitmap(bm->buffer + bm->w * b_y0 + b_x0,
+ brk - b_x0, b_y1 - b_y0, bm->w,
dst_x + b_x0, dst_y + b_y0, color);
*tail = img;
tail = &img->next;
}
if (brk < b_x1) { // draw right part
if (brk < b_x0) brk = b_x0;
- img = my_draw_bitmap(bitmap->buffer + bitmap->pitch * b_y0 + brk,
- b_x1 - brk, b_y1 - b_y0, bitmap->pitch,
+ img = my_draw_bitmap(bm->buffer + bm->w * b_y0 + brk,
+ b_x1 - brk, b_y1 - b_y0, bm->w,
dst_x + brk, dst_y + b_y0, color2);
*tail = img;
tail = &img->next;
@@ -361,37 +357,31 @@ static ass_image_t** render_glyph(FT_BitmapGlyph bit, int dst_x, int dst_y, uint
static ass_image_t* render_text(text_info_t* text_info, int dst_x, int dst_y)
{
int pen_x, pen_y;
- int error, error2;
- int i;
- FT_Glyph image;
- FT_BitmapGlyph bit;
+ int i, error;
+ bitmap_t* bm;
glyph_hash_val_t hash_val;
ass_image_t* head;
ass_image_t** tail = &head;
for (i = 0; i < text_info->length; ++i) {
- if (text_info->glyphs[i].bitmap != 1) {
+ if (text_info->glyphs[i].glyph) {
if ((text_info->glyphs[i].symbol == '\n') || (text_info->glyphs[i].symbol == 0))
continue;
- error = FT_Glyph_To_Bitmap( &(text_info->glyphs[i].outline_glyph), FT_RENDER_MODE_NORMAL, 0, 1);
- error2 = FT_Glyph_To_Bitmap( &(text_info->glyphs[i].glyph), FT_RENDER_MODE_NORMAL, 0, 1);
-
- if (error || error2) {
- FT_Done_Glyph(text_info->glyphs[i].outline_glyph);
- FT_Done_Glyph(text_info->glyphs[i].glyph);
- mp_msg(MSGT_GLOBAL, MSGL_WARN, "FT_Glyph_To_Bitmap error %d %d, symbol %d, index %d\n",
- error, error2, text_info->glyphs[i].symbol, text_info->glyphs[i].hash_key.index);
- text_info->glyphs[i].symbol = 0; // do not render
- continue;
- }
+ error = glyph_to_bitmap(text_info->glyphs[i].glyph, text_info->glyphs[i].outline_glyph,
+ &text_info->glyphs[i].bm, &text_info->glyphs[i].bm_o);
+ if (error)
+ text_info->glyphs[i].symbol = 0;
+ FT_Done_Glyph(text_info->glyphs[i].glyph);
+ FT_Done_Glyph(text_info->glyphs[i].outline_glyph);
+
// cache
- text_info->glyphs[i].hash_key.bitmap = 1; // other hash_key fields were set in get_glyph()
hash_val.bbox_scaled = text_info->glyphs[i].bbox;
- hash_val.outline_glyph = text_info->glyphs[i].outline_glyph;
- hash_val.glyph = text_info->glyphs[i].glyph;
+ hash_val.bm_o = text_info->glyphs[i].bm_o;
+ hash_val.bm = text_info->glyphs[i].bm;
hash_val.advance.x = text_info->glyphs[i].advance.x;
hash_val.advance.y = text_info->glyphs[i].advance.y;
cache_add_glyph(&(text_info->glyphs[i].hash_key), &hash_val);
+
}
}
@@ -402,13 +392,12 @@ static ass_image_t* render_text(text_info_t* text_info, int dst_x, int dst_y)
pen_x = dst_x + info->pos.x;
pen_y = dst_y + info->pos.y;
- image = info->outline_glyph;
- bit = (FT_BitmapGlyph)image;
+ bm = info->bm_o;
if ((info->effect_type == EF_KARAOKE_KO) && (info->effect_timing <= info->bbox.xMax)) {
// do nothing
} else
- tail = render_glyph(bit, pen_x, pen_y, info->c[2], 0, 1000000, tail);
+ tail = render_glyph(bm, pen_x, pen_y, info->c[2], 0, 1000000, tail);
}
for (i = 0; i < text_info->length; ++i) {
glyph_info_t* info = text_info->glyphs + i;
@@ -417,18 +406,17 @@ static ass_image_t* render_text(text_info_t* text_info, int dst_x, int dst_y)
pen_x = dst_x + info->pos.x;
pen_y = dst_y + info->pos.y;
- image = info->glyph;
- bit = (FT_BitmapGlyph)image;
+ bm = info->bm;
if ((info->effect_type == EF_KARAOKE) || (info->effect_type == EF_KARAOKE_KO)) {
if (info->effect_timing > info->bbox.xMax)
- tail = render_glyph(bit, pen_x, pen_y, info->c[0], 0, 1000000, tail);
+ tail = render_glyph(bm, pen_x, pen_y, info->c[0], 0, 1000000, tail);
else
- tail = render_glyph(bit, pen_x, pen_y, info->c[1], 0, 1000000, tail);
+ tail = render_glyph(bm, pen_x, pen_y, info->c[1], 0, 1000000, tail);
} else if (info->effect_type == EF_KARAOKE_KF) {
- tail = render_glyph(bit, pen_x, pen_y, info->c[0], info->c[1], info->effect_timing, tail);
+ tail = render_glyph(bm, pen_x, pen_y, info->c[0], info->c[1], info->effect_timing, tail);
} else
- tail = render_glyph(bit, pen_x, pen_y, info->c[0], 0, 1000000, tail);
+ tail = render_glyph(bm, pen_x, pen_y, info->c[0], 0, 1000000, tail);
}
*tail = 0;
@@ -1206,20 +1194,16 @@ static int get_glyph(int index, int symbol, glyph_info_t* info, FT_Vector* advan
key->bold = render_context.bold;
key->italic = render_context.italic;
- key->bitmap = 1; // looking for bitmap glyph
-
-
val = cache_find_glyph(key);
// val = 0;
if (val) {
- // bitmap glyph found, no need for FT_Glyph_Copy
- info->glyph = val->glyph;
- info->outline_glyph = val->outline_glyph;
+ info->glyph = info->outline_glyph = 0;
+ info->bm = val->bm;
+ info->bm_o = val->bm_o;
info->bbox = val->bbox_scaled;
info->advance.x = val->advance.x;
info->advance.y = val->advance.y;
- info->bitmap = 1; // bitmap glyph
return 0;
}
@@ -1258,7 +1242,7 @@ static int get_glyph(int index, int symbol, glyph_info_t* info, FT_Vector* advan
FT_Glyph_Copy(info->glyph, &info->outline_glyph);
}
- info->bitmap = 0; // outline glyph
+ info->bm = info->bm_o = 0;
return 0;
}
@@ -1599,7 +1583,7 @@ static int ass_render_event(ass_event_t* event, event_images_t* event_images)
pen.y += text_info.glyphs[text_info.length].advance.y;
// if it's an outline glyph, we still need to fill the bbox
- if (text_info.glyphs[text_info.length].bitmap != 1) {
+ if (text_info.glyphs[text_info.length].glyph) {
FT_Glyph_Get_CBox( text_info.glyphs[text_info.length].glyph, FT_GLYPH_BBOX_PIXELS, &(text_info.glyphs[text_info.length].bbox) );
}
@@ -1822,7 +1806,7 @@ static int ass_render_event(ass_event_t* event, event_images_t* event_images)
info->pos.y -= start.y >> 6;
// mp_msg(MSGT_GLOBAL, MSGL_DBG2, "shift: %d, %d\n", start.x / 64, start.y / 64);
- if (info->bitmap != 1) {
+ if (info->glyph) {
FT_Glyph_Transform( info->glyph, &matrix_rotate, 0 );
FT_Glyph_Transform( info->outline_glyph, &matrix_rotate, 0 );
}