#include <vlc_memory.h>
#include <math.h>
-#include <errno.h>
#include <ft2build.h>
+#include <freetype/ftsynth.h>
#include FT_FREETYPE_H
#include FT_GLYPH_H
#define FT_FLOOR(X) ((X & -64) >> 6)
#ifdef HAVE_FONTCONFIG
#define FONT_LONGTEXT N_("Font family for the font you want to use")
#else
-#define FONT_LONGTEXT N_("Fontfile for the font you want to use")
+#define FONT_LONGTEXT N_("Font file for the font you want to use")
#endif
#define FONTSIZE_TEXT N_("Font size in pixels")
#define FONTSIZER_TEXT N_("Relative font size")
#define FONTSIZER_LONGTEXT N_("This is the relative default size of the " \
"fonts that will be rendered on the video. If absolute font size is set, "\
- "relative size will be overriden." )
+ "relative size will be overridden." )
static const int pi_sizes[] = { 20, 18, 16, 12, 6 };
static const char *const ppsz_sizes_text[] = {
uint8_t *p_fg_bg_ratio; /* 0x00=100% FG --> 0x7F=100% BG */
bool b_new_color_mode;
/** underline information -- only supplied if text should be underlined */
- uint16_t *pi_underline_offset;
+ int *pi_underline_offset;
uint16_t *pi_underline_thickness;
int i_height;
bool b_italic;
bool b_bold;
bool b_underline;
+ bool b_through;
char *psz_fontname;
} ft_style_t;
if( asprintf( &psz_fontsize, "%d", p_sys->i_default_font_size ) == -1 )
goto error;
+
+ msg_Dbg( p_filter, "Building font databases.");
+ mtime_t t1, t2;
+ t1 = mdate();
+
#ifdef WIN32
- dialog_progress_bar_t *p_dialog = dialog_ProgressCreate( p_filter,
+ dialog_progress_bar_t *p_dialog = NULL;
+ FcConfig *fcConfig = FcInitLoadConfig();
+
+ p_dialog = dialog_ProgressCreate( p_filter,
_("Building font cache"),
_("Please wait while your font cache is rebuilt.\n"
- "This should take less than few minutes."), NULL );
- char *path = xmalloc( PATH_MAX + 1 );
- /* Fontconfig doesnt seem to know where windows fonts are with
- * current contribs. So just tell default windows font directory
- * is the place to search fonts
- */
- GetWindowsDirectory( path, PATH_MAX + 1 );
- strcat( path, "\\fonts" );
- if( p_dialog )
- dialog_ProgressSet( p_dialog, NULL, 0.4 );
-
- FcConfigAppFontAddDir( NULL , path );
- free(path);
-
+ "This should take less than a few minutes."), NULL );
if( p_dialog )
dialog_ProgressSet( p_dialog, NULL, 0.5 );
#endif
- mtime_t t1, t2;
-
- msg_Dbg( p_filter, "Building font database.");
- t1 = mdate();
- FcConfigBuildFonts( NULL );
+ FcConfigBuildFonts( fcConfig );
t2 = mdate();
-
- msg_Dbg( p_filter, "Finished building font database." );
msg_Dbg( p_filter, "Took %ld microseconds", (long)((t2 - t1)) );
fontpattern = FcPatternCreate();
-
if( !fontpattern )
{
msg_Err( p_filter, "Creating fontpattern failed");
goto error;
}
- msg_Dbg( p_filter, "Using %s as font from file %s", psz_fontfamily, psz_fontfile );
+ msg_Dbg( p_filter, "Using %s as font from file %s", psz_fontfamily,
+ psz_fontfile ? psz_fontfile : "(null)" );
p_sys->psz_fontfamily = strdup( psz_fontfamily );
# ifdef WIN32
if( p_dialog )
{
dialog_ProgressSet( p_dialog, NULL, 1.0 );
dialog_ProgressDestroy( p_dialog );
+ p_dialog = NULL;
}
# endif
if( i_error == FT_Err_Unknown_File_Format )
{
- msg_Err( p_filter, "file %s have unknown format", psz_fontfile );
+ msg_Err( p_filter, "file %s have unknown format",
+ psz_fontfile ? psz_fontfile : "(null)" );
goto error;
}
else if( i_error )
{
- msg_Err( p_filter, "failed to load font file %s", psz_fontfile );
+ msg_Err( p_filter, "failed to load font file %s",
+ psz_fontfile ? psz_fontfile : "(null)" );
goto error;
}
if( fontmatch ) FcPatternDestroy( fontmatch );
if( fontpattern ) FcPatternDestroy( fontpattern );
#endif
+
+#ifdef WIN32
+ if( p_dialog )
+ dialog_ProgressDestroy( p_dialog );
+#endif
+
if( p_sys->p_face ) FT_Done_Face( p_sys->p_face );
if( p_sys->p_library ) FT_Done_FreeType( p_sys->p_library );
free( psz_fontfamily );
p_region->p_picture = picture_NewFromFormat( &fmt );
if( !p_region->p_picture )
return VLC_EGENERIC;
+ fmt.p_palette = p_region->fmt.p_palette ? p_region->fmt.p_palette : malloc(sizeof(*fmt.p_palette));
p_region->fmt = fmt;
/* Calculate text color components */
bool b_ok = true;
/* break the underline around the tails of any glyphs which cross it */
+ /* Strikethrough doesn't get broken */
for( z = x - i_line_thickness;
- z < x + i_line_thickness && b_ok;
+ z < x + i_line_thickness && b_ok && (i_line_offset >= 0);
z++ )
{
if( p_next_glyph && ( z >= i_extra ) )
/* Do bidi conversion line-by-line */
while( pos < i_string_length )
{
- while( pos < i_string_length )
+ while( pos < i_string_length )
{
i_char = psz_unicode[pos];
if (i_char != '\r' && i_char != '\n')
p_region_out->i_x = p_region_in->i_x;
p_region_out->i_y = p_region_in->i_y;
- if( config_GetInt( p_filter, "freetype-yuvp" ) )
+ if( var_InheritBool( p_filter, "freetype-yuvp" ) )
Render( p_filter, p_region_out, p_lines, result.x, result.y );
else
RenderYUVA( p_filter, p_region_out, p_lines, result.x, result.y );
#ifdef HAVE_FONTCONFIG
static ft_style_t *CreateStyle( char *psz_fontname, int i_font_size,
uint32_t i_font_color, uint32_t i_karaoke_bg_color, bool b_bold,
- bool b_italic, bool b_uline )
+ bool b_italic, bool b_uline, bool b_through )
{
ft_style_t *p_style = malloc( sizeof( ft_style_t ));
p_style->b_italic = b_italic;
p_style->b_bold = b_bold;
p_style->b_underline = b_uline;
+ p_style->b_through = b_through;
p_style->psz_fontname = strdup( psz_fontname );
}
if(( s1->i_font_size == s2->i_font_size ) &&
( s1->i_font_color == s2->i_font_color ) &&
( s1->b_italic == s2->b_italic ) &&
+ ( s1->b_through == s2->b_through ) &&
( s1->b_bold == s2->b_bold ) &&
( s1->b_underline == s2->b_underline ) &&
( !strcmp( s1->psz_fontname, s2->psz_fontname )))
static ft_style_t *GetStyleFromFontStack( filter_sys_t *p_sys,
font_stack_t **p_fonts, bool b_bold, bool b_italic,
- bool b_uline )
+ bool b_uline, bool b_through )
{
ft_style_t *p_style = NULL;
&i_font_color, &i_karaoke_bg_color ))
{
p_style = CreateStyle( psz_fontname, i_font_size, i_font_color,
- i_karaoke_bg_color, b_bold, b_italic, b_uline );
+ i_karaoke_bg_color, b_bold, b_italic, b_uline, b_through );
}
return p_style;
}
static int RenderTag( filter_t *p_filter, FT_Face p_face, int i_font_color,
- bool b_uline, int i_karaoke_bgcolor,
+ bool b_uline, bool b_through, bool b_bold,
+ bool b_italic, int i_karaoke_bgcolor,
line_desc_t *p_line, uint32_t *psz_unicode,
int *pi_pen_x, int i_pen_y, int *pi_start,
FT_Vector *p_result )
p_line->pp_glyphs[ i ] = NULL;
return VLC_EGENERIC;
}
+
+ /* Do synthetic styling now that Freetype supports it;
+ * ie. if the font we have loaded is NOT already in the
+ * style that the tags want, then switch it on; if they
+ * are then don't. */
+ if (b_bold && !( p_face->style_flags & FT_STYLE_FLAG_BOLD ))
+ FT_GlyphSlot_Embolden( p_face->glyph );
+ if (b_italic && !( p_face->style_flags & FT_STYLE_FLAG_ITALIC ))
+ FT_GlyphSlot_Oblique( p_face->glyph );
+
i_error = FT_Get_Glyph( p_face->glyph, &tmp_glyph );
if( i_error )
{
FT_Done_Glyph( tmp_glyph );
continue;
}
- if( b_uline )
+ if( b_uline || b_through )
{
float aOffset = FT_FLOOR(FT_MulFix(p_face->underline_position,
p_face->size->metrics.y_scale));
( aOffset < 0 ) ? -aOffset : aOffset;
p_line->pi_underline_thickness[ i ] =
( aSize < 0 ) ? -aSize : aSize;
+ if (b_through)
+ {
+ /* Move the baseline to make it strikethrough instead of
+ * underline. That means that strikethrough takes precedence
+ */
+ float aDescent = FT_FLOOR(FT_MulFix(p_face->descender*2,
+ p_face->size->metrics.y_scale));
+
+ p_line->pi_underline_offset[ i ] -=
+ ( aDescent < 0 ) ? -aDescent : aDescent;
+ }
}
+
p_line->pp_glyphs[ i ] = (FT_BitmapGlyph)tmp_glyph;
p_line->p_fg_rgb[ i ] = i_font_color & 0x00ffffff;
p_line->p_bg_rgb[ i ] = i_karaoke_bgcolor & 0x00ffffff;
if( RenderTag( p_filter, p_face ? p_face : p_sys->p_face,
p_style->i_font_color, p_style->b_underline,
+ p_style->b_through,
+ p_style->b_bold,
+ p_style->b_italic,
p_style->i_karaoke_bg_color,
p_line, psz_unicode, &i_pen_x, i_pen_y, &i_posn,
&tmp_result ) != VLC_SUCCESS )
*/
if(( rv == VLC_SUCCESS ) && ( i_len > 0 ))
{
- if( config_GetInt( p_filter, "freetype-yuvp" ) )
+ if( var_InheritBool( p_filter, "freetype-yuvp" ) )
{
Render( p_filter, p_region_out, p_lines,
result.x, result.y );
static ft_style_t *GetStyleFromFontStack( filter_sys_t *p_sys,
font_stack_t **p_fonts, bool b_bold, bool b_italic,
- bool b_uline )
+ bool b_uline, bool b_through )
{
VLC_UNUSED(p_sys);
VLC_UNUSED(p_fonts);
VLC_UNUSED(b_bold);
VLC_UNUSED(b_italic);
VLC_UNUSED(b_uline);
+ VLC_UNUSED(b_through);
return NULL;
}
#endif
p_line->p_fg_rgb = malloc( sizeof( uint32_t ) * ( i_count + 1 ) );
p_line->p_bg_rgb = malloc( sizeof( uint32_t ) * ( i_count + 1 ) );
p_line->p_fg_bg_ratio = calloc( i_count + 1, sizeof( uint8_t ) );
- p_line->pi_underline_offset = calloc( i_count + 1, sizeof( uint16_t ) );
+ p_line->pi_underline_offset = calloc( i_count + 1, sizeof( int ) );
p_line->pi_underline_thickness = calloc( i_count + 1, sizeof( uint16_t ) );
if( ( p_line->pp_glyphs == NULL ) ||
( p_line->p_glyph_pos == NULL ) ||