Commit 2479a41d authored by Gildas Bazin's avatar Gildas Bazin

* modules/misc/freetype.c: better outlining algorithm + generate 16 colors...

* modules/misc/freetype.c: better outlining algorithm + generate 16 colors (instead of 256) palettized YUV.
parent 2e384769
...@@ -303,6 +303,10 @@ static void Destroy( vlc_object_t *p_this ) ...@@ -303,6 +303,10 @@ static void Destroy( vlc_object_t *p_this )
static int Render( filter_t *p_filter, subpicture_region_t *p_region, static int Render( filter_t *p_filter, subpicture_region_t *p_region,
line_desc_t *p_line, int i_width, int i_height ) line_desc_t *p_line, int i_width, int i_height )
{ {
static uint8_t pi_gamma[16] =
{0x00, 0x41, 0x52, 0x63, 0x84, 0x85, 0x96, 0xa7, 0xb8, 0xc9,
0xca, 0xdb, 0xdc, 0xed, 0xee, 0xff};
uint8_t *p_dst; uint8_t *p_dst;
video_format_t fmt; video_format_t fmt;
int i, x, y, i_pitch; int i, x, y, i_pitch;
...@@ -314,8 +318,8 @@ static int Render( filter_t *p_filter, subpicture_region_t *p_region, ...@@ -314,8 +318,8 @@ static int Render( filter_t *p_filter, subpicture_region_t *p_region,
memset( &fmt, 0, sizeof(video_format_t) ); memset( &fmt, 0, sizeof(video_format_t) );
fmt.i_chroma = VLC_FOURCC('Y','U','V','P'); fmt.i_chroma = VLC_FOURCC('Y','U','V','P');
fmt.i_aspect = VOUT_ASPECT_FACTOR; fmt.i_aspect = VOUT_ASPECT_FACTOR;
fmt.i_width = fmt.i_visible_width = i_width + 2; fmt.i_width = fmt.i_visible_width = i_width + 4;
fmt.i_height = fmt.i_visible_height = i_height + 2; fmt.i_height = fmt.i_visible_height = i_height + 4;
fmt.i_x_offset = fmt.i_y_offset = 0; fmt.i_x_offset = fmt.i_y_offset = 0;
p_region_tmp = spu_CreateRegion( p_filter, &fmt ); p_region_tmp = spu_CreateRegion( p_filter, &fmt );
if( !p_region_tmp ) if( !p_region_tmp )
...@@ -337,17 +341,16 @@ static int Render( filter_t *p_filter, subpicture_region_t *p_region, ...@@ -337,17 +341,16 @@ static int Render( filter_t *p_filter, subpicture_region_t *p_region,
18 * p_line->i_blue + 128) >> 8) + 128; 18 * p_line->i_blue + 128) >> 8) + 128;
/* Build palette */ /* Build palette */
fmt.p_palette->i_entries = 256; fmt.p_palette->i_entries = 16;
for( i = 0; i < fmt.p_palette->i_entries; i++ ) for( i = 0; i < fmt.p_palette->i_entries; i++ )
{ {
fmt.p_palette->palette[i][0] = i * i_y / 256; fmt.p_palette->palette[i][0] = i * 16 * i_y / 256;
fmt.p_palette->palette[i][1] = i_u; fmt.p_palette->palette[i][1] = i_u;
fmt.p_palette->palette[i][2] = i_v; fmt.p_palette->palette[i][2] = i_v;
fmt.p_palette->palette[i][3] = i + (255 - i) / 16; fmt.p_palette->palette[i][3] = pi_gamma[i];
fmt.p_palette->palette[i][3] = fmt.p_palette->palette[i][3] =
(int)fmt.p_palette->palette[i][3] * (255 - p_line->i_alpha) / 255; (int)fmt.p_palette->palette[i][3] * (255 - p_line->i_alpha) / 255;
} }
fmt.p_palette->palette[0][3] = 0;
p_dst = p_region->picture.Y_PIXELS; p_dst = p_region->picture.Y_PIXELS;
i_pitch = p_region->picture.Y_PITCH; i_pitch = p_region->picture.Y_PITCH;
...@@ -376,54 +379,51 @@ static int Render( filter_t *p_filter, subpicture_region_t *p_region, ...@@ -376,54 +379,51 @@ static int Render( filter_t *p_filter, subpicture_region_t *p_region,
i_align_offset = ( i_width - p_line->i_width ) / 2; i_align_offset = ( i_width - p_line->i_width ) / 2;
} }
} }
for( i = 0; p_line->pp_glyphs[i] != NULL; i++ ) for( i = 0; p_line->pp_glyphs[i] != NULL; i++ )
{ {
FT_BitmapGlyph p_glyph = p_line->pp_glyphs[ i ]; FT_BitmapGlyph p_glyph = p_line->pp_glyphs[ i ];
i_offset = ( p_line->p_glyph_pos[ i ].y + i_offset = ( p_line->p_glyph_pos[ i ].y +
i_glyph_tmax - p_glyph->top + 1 ) * i_glyph_tmax - p_glyph->top + 2 ) *
i_pitch + p_line->p_glyph_pos[ i ].x + p_glyph->left + 1 + i_pitch + p_line->p_glyph_pos[ i ].x + p_glyph->left + 2 +
i_align_offset; i_align_offset;
for( y = 0, i_bitmap_offset = 0; y < p_glyph->bitmap.rows; y++ ) for( y = 0, i_bitmap_offset = 0; y < p_glyph->bitmap.rows; y++ )
{ {
for( x = 0; x < p_glyph->bitmap.width; x++, i_bitmap_offset++ ) for( x = 0; x < p_glyph->bitmap.width; x++, i_bitmap_offset++ )
{ {
if( !p_glyph->bitmap.buffer[i_bitmap_offset] ) if( p_glyph->bitmap.buffer[i_bitmap_offset] )
continue; p_dst[i_offset+x] =
((int)p_glyph->bitmap.buffer[i_bitmap_offset] + 8)/16;
i_offset -= i_pitch;
p_dst[i_offset + x] = ((uint16_t)p_dst[i_offset + x]*2 +
p_glyph->bitmap.buffer[i_bitmap_offset])/3;
i_offset += i_pitch; x--;
p_dst[i_offset + x] = ((uint16_t)p_dst[i_offset + x]*2 +
p_glyph->bitmap.buffer[i_bitmap_offset])/3;
x += 2;
p_dst[i_offset + x] = ((uint16_t)p_dst[i_offset + x]*2 +
p_glyph->bitmap.buffer[i_bitmap_offset])/3;
i_offset += i_pitch; x--;
p_dst[i_offset + x] = ((uint16_t)p_dst[i_offset + x]*2 +
p_glyph->bitmap.buffer[i_bitmap_offset])/3;
i_offset -= i_pitch;
} }
i_offset += i_pitch; i_offset += i_pitch;
} }
}
}
i_offset = ( p_line->p_glyph_pos[ i ].y + /* Outlining (find something better than nearest neighbour filtering ?) */
i_glyph_tmax - p_glyph->top + 1 ) * if( 1 )
i_pitch + p_line->p_glyph_pos[ i ].x + p_glyph->left + 1 + {
i_align_offset; uint8_t *p_dst = p_region->picture.Y_PIXELS;
uint8_t *p_top = p_dst; /* Use 1st line as a cache */
uint8_t left, current;
for( y = 0, i_bitmap_offset = 0; y < p_glyph->bitmap.rows; y++ ) for( y = 1; y < (int)fmt.i_height - 1; y++ )
{
memcpy( p_top, p_dst, fmt.i_width );
p_dst += p_region->picture.Y_PITCH;
left = 0;
for( x = 1; x < (int)fmt.i_width - 1; x++ )
{ {
for( x = 0; x < p_glyph->bitmap.width; x++, i_bitmap_offset++ ) current = p_dst[x];
{ p_dst[x] = ( 4 * (int)p_dst[x] + left + p_top[x] + p_dst[x+1] +
if( p_glyph->bitmap.buffer[i_bitmap_offset] > 16 ) p_dst[x + p_region->picture.Y_PITCH]) / 8;
p_dst[i_offset+x] = p_glyph->bitmap.buffer[i_bitmap_offset]; left = current;
}
i_offset += i_pitch;
} }
} }
memset( p_top, 0, fmt.i_width );
} }
return VLC_SUCCESS; return VLC_SUCCESS;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment