[vlc-devel] [PATCH 3/9] freetype: remove remaining layout code from freetype.c

Salah-Eddin Shaban salshaaban at gmail.com
Sat Apr 18 19:56:15 CEST 2015


---
 modules/text_renderer/freetype.c | 467 ---------------------------------------
 1 file changed, 467 deletions(-)

diff --git a/modules/text_renderer/freetype.c b/modules/text_renderer/freetype.c
index a52b24c..4668f07 100644
--- a/modules/text_renderer/freetype.c
+++ b/modules/text_renderer/freetype.c
@@ -928,473 +928,6 @@ static FT_Face LoadFace( filter_t *p_filter,
     return p_face;
 }
 
-static int ProcessLines( filter_t *p_filter,
-                         line_desc_t **pp_lines,
-                         FT_BBox     *p_bbox,
-                         int         *pi_max_face_height,
-
-                         uni_char_t *psz_text,
-                         text_style_t **pp_styles,
-                         uint32_t *pi_k_dates,
-                         int i_len )
-{
-    filter_sys_t   *p_sys = p_filter->p_sys;
-    uni_char_t     *p_fribidi_string = NULL;
-    text_style_t   **pp_fribidi_styles = NULL;
-    int            *p_new_positions = NULL;
-
-#if defined(HAVE_FRIBIDI)
-    {
-        int    *p_old_positions;
-        int start_pos, pos = 0;
-
-        pp_fribidi_styles = calloc( i_len, sizeof(*pp_fribidi_styles) );
-
-        p_fribidi_string  = malloc( (i_len + 1) * sizeof(*p_fribidi_string) );
-        p_old_positions   = malloc( (i_len + 1) * sizeof(*p_old_positions) );
-        p_new_positions   = malloc( (i_len + 1) * sizeof(*p_new_positions) );
-
-        if( ! pp_fribidi_styles ||
-            ! p_fribidi_string ||
-            ! p_old_positions ||
-            ! p_new_positions )
-        {
-            free( p_old_positions );
-            free( p_new_positions );
-            free( p_fribidi_string );
-            free( pp_fribidi_styles );
-            return VLC_ENOMEM;
-        }
-
-        /* Do bidi conversion line-by-line */
-        while(pos < i_len)
-        {
-            while(pos < i_len) {
-                if (psz_text[pos] != '\n')
-                    break;
-                p_fribidi_string[pos] = psz_text[pos];
-                pp_fribidi_styles[pos] = pp_styles[pos];
-                p_new_positions[pos] = pos;
-                ++pos;
-            }
-            start_pos = pos;
-            while(pos < i_len) {
-                if (psz_text[pos] == '\n')
-                    break;
-                ++pos;
-            }
-            if (pos > start_pos)
-            {
-#if (FRIBIDI_MINOR_VERSION < 19) && (FRIBIDI_MAJOR_VERSION == 0)
-                FriBidiCharType base_dir = FRIBIDI_TYPE_LTR;
-#else
-                FriBidiParType base_dir = FRIBIDI_PAR_LTR;
-#endif
-                fribidi_log2vis((FriBidiChar*)psz_text + start_pos,
-                        pos - start_pos, &base_dir,
-                        (FriBidiChar*)p_fribidi_string + start_pos,
-                        p_new_positions + start_pos,
-                        p_old_positions,
-                        NULL );
-                for( int j = start_pos; j < pos; j++ )
-                {
-                    pp_fribidi_styles[ j ] = pp_styles[ start_pos + p_old_positions[j - start_pos] ];
-                    p_new_positions[ j ] += start_pos;
-                }
-            }
-        }
-        p_fribidi_string[ i_len ] = 0;
-        free( p_old_positions );
-
-        pp_styles = pp_fribidi_styles;
-        psz_text = p_fribidi_string;
-    }
-#endif
-    /* Work out the karaoke */
-    uint8_t *pi_karaoke_bar = NULL;
-    if( pi_k_dates )
-    {
-        pi_karaoke_bar = malloc( i_len * sizeof(*pi_karaoke_bar));
-        if( pi_karaoke_bar )
-        {
-            int64_t i_elapsed  = var_GetTime( p_filter, "spu-elapsed" ) / 1000;
-            for( int i = 0; i < i_len; i++ )
-            {
-                unsigned i_bar = p_new_positions ? p_new_positions[i] : i;
-                pi_karaoke_bar[i_bar] = pi_k_dates[i] >= i_elapsed;
-            }
-        }
-    }
-    free( p_new_positions );
-
-    *pi_max_face_height = 0;
-    *pp_lines = NULL;
-    line_desc_t **pp_line_next = pp_lines;
-
-    FT_BBox bbox = {
-        .xMin = INT_MAX,
-        .yMin = INT_MAX,
-        .xMax = INT_MIN,
-        .yMax = INT_MIN,
-    };
-    int i_face_height_previous = 0;
-    int i_base_line = 0;
-    const text_style_t *p_previous_style = NULL;
-    FT_Face p_face = NULL;
-    for( int i_start = 0; i_start < i_len; )
-    {
-        /* Compute the length of the current text line */
-        int i_length = 0;
-        while( i_start + i_length < i_len && psz_text[i_start + i_length] != '\n' )
-            i_length++;
-
-        /* Render the text line (or the begining if too long) into 0 or 1 glyph line */
-        line_desc_t *p_line = i_length > 0 ? NewLine( i_length ) : NULL;
-        int i_index = i_start;
-        FT_Vector pen = {
-            .x = 0,
-            .y = 0,
-        };
-        int i_face_height = 0;
-        FT_BBox line_bbox = {
-            .xMin = INT_MAX,
-            .yMin = INT_MAX,
-            .xMax = INT_MIN,
-            .yMax = INT_MIN,
-        };
-        int i_ul_offset = 0;
-        int i_ul_thickness = 0;
-        typedef struct {
-            int       i_index;
-            FT_Vector pen;
-            FT_BBox   line_bbox;
-            int i_face_height;
-            int i_ul_offset;
-            int i_ul_thickness;
-        } break_point_t;
-        break_point_t break_point;
-        break_point_t break_point_fallback;
-
-#define SAVE_BP(dst) do { \
-        dst.i_index = i_index; \
-        dst.pen = pen; \
-        dst.line_bbox = line_bbox; \
-        dst.i_face_height = i_face_height; \
-        dst.i_ul_offset = i_ul_offset; \
-        dst.i_ul_thickness = i_ul_thickness; \
-    } while(0)
-
-        SAVE_BP( break_point );
-        SAVE_BP( break_point_fallback );
-
-        while( i_index < i_start + i_length )
-        {
-            /* Split by common FT_Face + Size */
-            const text_style_t *p_current_style = pp_styles[i_index];
-            int i_part_length = 0;
-            while( i_index + i_part_length < i_start + i_length )
-            {
-                const text_style_t *p_style = pp_styles[i_index + i_part_length];
-                if( !FaceStyleEquals( p_style, p_current_style ) ||
-                    p_style->i_font_size != p_current_style->i_font_size )
-                    break;
-                i_part_length++;
-            }
-
-            /* (Re)load/reconfigure the face if needed */
-            if( !FaceStyleEquals( p_current_style, p_previous_style ) )
-            {
-                if( p_face )
-                    FT_Done_Face( p_face );
-                p_previous_style = NULL;
-
-                p_face = LoadFace( p_filter, p_current_style );
-            }
-            FT_Face p_current_face = p_face ? p_face : p_sys->p_face;
-            if( !p_previous_style || p_previous_style->i_font_size != p_current_style->i_font_size ||
-                ((p_previous_style->i_style_flags ^ p_current_style->i_style_flags) & STYLE_HALFWIDTH) )
-
-            {
-                int i_font_width = ( p_current_style->i_style_flags & STYLE_HALFWIDTH )
-                                    ? p_current_style->i_font_size / 2
-                                    : p_current_style->i_font_size;
-                if( FT_Set_Pixel_Sizes( p_current_face,
-                                        i_font_width,
-                                        p_current_style->i_font_size ) )
-                    msg_Err( p_filter, "Failed to set font size to %d", p_current_style->i_font_size );
-                if( p_sys->p_stroker )
-                {
-                    double f_outline_thickness = var_InheritInteger( p_filter, "freetype-outline-thickness" ) / 100.0;
-                    f_outline_thickness = VLC_CLIP( f_outline_thickness, 0.0, 0.5 );
-                    int i_radius = (p_current_style->i_font_size << 6) * f_outline_thickness;
-                    FT_Stroker_Set( p_sys->p_stroker,
-                                    i_radius,
-                                    FT_STROKER_LINECAP_ROUND,
-                                    FT_STROKER_LINEJOIN_ROUND, 0 );
-                }
-            }
-            p_previous_style = p_current_style;
-
-            i_face_height = __MAX(i_face_height, FT_CEIL(FT_MulFix(p_current_face->height,
-                                                                   p_current_face->size->metrics.y_scale)));
-
-            /* Render the part */
-            bool b_break_line = false;
-            int i_glyph_last = 0;
-            FT_Vector advance = {
-                .x = 0,
-                .y = 0,
-            };
-            while( i_part_length > 0 )
-            {
-                const text_style_t *p_glyph_style = pp_styles[i_index];
-                uni_char_t character = psz_text[i_index];
-                int i_glyph_index = FT_Get_Char_Index( p_current_face, character );
-
-                /* If the missing glyph is U+FEFF (ZERO WIDTH NO-BREAK SPACE) */
-                /* we can safely ignore it. Otherwise extra squares show up   */
-                /* in Arabic text.                                            */
-                if( i_glyph_index == 0 && character == 0xFEFF )
-                    goto next;
-
-/* These are the most common Arabic diacritics */
-#define DIACRITIC( a ) ( a >= 0x064B && a <= 0x0653 )
-
-                /* Diacritics should be rendered over the preceding base glyph */
-                if( DIACRITIC( character ) )
-                {
-                    pen.x -= advance.x;
-                    pen.y -= advance.y;
-                }
-
-                /* Get kerning vector */
-                FT_Vector kerning = { .x = 0, .y = 0 };
-                if( FT_HAS_KERNING( p_current_face ) && i_glyph_last != 0 && i_glyph_index != 0 )
-                {
-                    FT_Get_Kerning( p_current_face, i_glyph_last, i_glyph_index, ft_kerning_default, &kerning );
-                }
-                if( p_glyph_style->i_spacing > 0 && i_glyph_last != 0 && i_glyph_index != 0 )
-                {
-                    kerning.x = (p_glyph_style->i_spacing) << 6;
-                }
-
-                /* Get the glyph bitmap and its bounding box and all the associated properties */
-                FT_Vector pen_new = {
-                    .x = pen.x + kerning.x,
-                    .y = pen.y + kerning.y,
-                };
-
-                int i_font_width = ( p_current_style->i_style_flags & STYLE_HALFWIDTH )
-                                    ? p_current_style->i_font_size / 2
-                                    : p_current_style->i_font_size;
-                FT_Vector pen_shadow_new = {
-                    .x = pen_new.x + p_sys->f_shadow_vector_x * (i_font_width << 6),
-                    .y = pen_new.y + p_sys->f_shadow_vector_y * (p_current_style->i_font_size << 6),
-                };
-
-                FT_Glyph glyph;
-                FT_BBox  glyph_bbox;
-                FT_Glyph outline;
-                FT_BBox  outline_bbox;
-                FT_Glyph shadow;
-                FT_BBox  shadow_bbox;
-
-                if( GetGlyph( p_filter,
-                              &glyph, &glyph_bbox,
-                              &outline, &outline_bbox,
-                              &shadow, &shadow_bbox,
-                              p_current_face, i_glyph_index, p_glyph_style->i_style_flags,
-                              &pen_new, &pen_shadow_new ) )
-                    goto next;
-
-                FixGlyph( glyph, &glyph_bbox, p_current_face, &pen_new );
-                if( outline )
-                    FixGlyph( outline, &outline_bbox, p_current_face, &pen_new );
-                if( shadow )
-                    FixGlyph( shadow, &shadow_bbox, p_current_face, &pen_shadow_new );
-
-                /* FIXME and what about outline */
-
-                bool     b_karaoke = pi_karaoke_bar && pi_karaoke_bar[i_index] != 0;
-                uint32_t i_color = b_karaoke ? (p_glyph_style->i_karaoke_background_color |
-                                                (p_glyph_style->i_karaoke_background_alpha << 24))
-                                             : (p_glyph_style->i_font_color |
-                                                (p_glyph_style->i_font_alpha << 24));
-                int i_line_offset    = 0;
-                int i_line_thickness = 0;
-                if( p_glyph_style->i_style_flags & (STYLE_UNDERLINE | STYLE_STRIKEOUT) )
-                {
-                    i_line_offset = abs( FT_FLOOR(FT_MulFix(p_current_face->underline_position,
-                                                            p_current_face->size->metrics.y_scale)) );
-
-                    i_line_thickness = abs( FT_CEIL(FT_MulFix(p_current_face->underline_thickness,
-                                                              p_current_face->size->metrics.y_scale)) );
-
-                    if( p_glyph_style->i_style_flags & STYLE_STRIKEOUT )
-                    {
-                        /* Move the baseline to make it strikethrough instead of
-                         * underline. That means that strikethrough takes precedence
-                         */
-                        i_line_offset -= abs( FT_FLOOR(FT_MulFix(p_current_face->descender*2,
-                                                                 p_current_face->size->metrics.y_scale)) );
-                    }
-                    else if( i_line_thickness > 0 )
-                    {
-                        glyph_bbox.yMin = __MIN( glyph_bbox.yMin, - i_line_offset - i_line_thickness );
-
-                        /* The real underline thickness and position are
-                         * updated once the whole line has been parsed */
-                        i_ul_offset = __MAX( i_ul_offset, i_line_offset );
-                        i_ul_thickness = __MAX( i_ul_thickness, i_line_thickness );
-                        i_line_thickness = -1;
-                    }
-                }
-                FT_BBox line_bbox_new = line_bbox;
-                BBoxEnlarge( &line_bbox_new, &glyph_bbox );
-                if( outline )
-                    BBoxEnlarge( &line_bbox_new, &outline_bbox );
-                if( shadow )
-                    BBoxEnlarge( &line_bbox_new, &shadow_bbox );
-
-                b_break_line = i_index > i_start &&
-                               line_bbox_new.xMax - line_bbox_new.xMin >= (int)p_filter->fmt_out.video.i_visible_width;
-                if( b_break_line )
-                {
-                    FT_Done_Glyph( glyph );
-                    if( outline )
-                        FT_Done_Glyph( outline );
-                    if( shadow )
-                        FT_Done_Glyph( shadow );
-
-                    break_point_t *p_bp = NULL;
-                    if( break_point.i_index > i_start )
-                        p_bp = &break_point;
-                    else if( break_point_fallback.i_index > i_start )
-                        p_bp = &break_point_fallback;
-
-                    if( p_bp )
-                    {
-                        msg_Dbg( p_filter, "Breaking line");
-                        for( int i = p_bp->i_index; i < i_index; i++ )
-                        {
-                            line_character_t *ch = &p_line->p_character[i - i_start];
-                            FT_Done_Glyph( (FT_Glyph)ch->p_glyph );
-                            if( ch->p_outline )
-                                FT_Done_Glyph( (FT_Glyph)ch->p_outline );
-                            if( ch->p_shadow )
-                                FT_Done_Glyph( (FT_Glyph)ch->p_shadow );
-                        }
-                        p_line->i_character_count = p_bp->i_index - i_start;
-
-                        i_index = p_bp->i_index;
-                        pen = p_bp->pen;
-                        line_bbox = p_bp->line_bbox;
-                        i_face_height = p_bp->i_face_height;
-                        i_ul_offset = p_bp->i_ul_offset;
-                        i_ul_thickness = p_bp->i_ul_thickness;
-                    }
-                    else
-                    {
-                        msg_Err( p_filter, "Breaking unbreakable line");
-                    }
-                    break;
-                }
-
-                p_line->p_character[p_line->i_character_count++] = (line_character_t){
-                    .p_glyph = (FT_BitmapGlyph)glyph,
-                    .p_outline = (FT_BitmapGlyph)outline,
-                    .p_shadow = (FT_BitmapGlyph)shadow,
-                    .i_color = i_color,
-                    .i_line_offset = i_line_offset,
-                    .i_line_thickness = i_line_thickness,
-                };
-
-                /* Diacritics do not determine advance values. We use        */
-                /* the advance values from the last encountered base glyph,  */
-                /* since multiple diacritics may follow a single base glyph. */
-                if( !DIACRITIC( character ) )
-                {
-                    advance.x = p_current_face->glyph->advance.x;
-                    advance.y = p_current_face->glyph->advance.y;
-                }
-
-                pen.x = pen_new.x + advance.x;
-                pen.y = pen_new.y + advance.y;
-                line_bbox = line_bbox_new;
-            next:
-                i_glyph_last = i_glyph_index;
-                i_part_length--;
-                i_index++;
-
-                if( character == ' ' || character == '\t' )
-                    SAVE_BP( break_point );
-                else if( character == 160 )
-                    SAVE_BP( break_point_fallback );
-            }
-            if( b_break_line )
-                break;
-        }
-#undef SAVE_BP
-        /* Update our baseline */
-        if( i_face_height_previous > 0 )
-            i_base_line += __MAX(i_face_height, i_face_height_previous);
-        if( i_face_height > 0 )
-            i_face_height_previous = i_face_height;
-
-        /* Update the line bbox with the actual base line */
-        if (line_bbox.yMax > line_bbox.yMin) {
-            line_bbox.yMin -= i_base_line;
-            line_bbox.yMax -= i_base_line;
-        }
-        BBoxEnlarge( &bbox, &line_bbox );
-
-        /* Terminate and append the line */
-        if( p_line )
-        {
-            p_line->i_width  = __MAX(line_bbox.xMax - line_bbox.xMin, 0);
-            p_line->i_base_line = i_base_line;
-            p_line->i_height = __MAX(i_face_height, i_face_height_previous);
-            if( i_ul_thickness > 0 )
-            {
-                for( int i = 0; i < p_line->i_character_count; i++ )
-                {
-                    line_character_t *ch = &p_line->p_character[i];
-                    if( ch->i_line_thickness < 0 )
-                    {
-                        ch->i_line_offset    = i_ul_offset;
-                        ch->i_line_thickness = i_ul_thickness;
-                    }
-                }
-            }
-
-            *pp_line_next = p_line;
-            pp_line_next = &p_line->p_next;
-        }
-
-        *pi_max_face_height = __MAX( *pi_max_face_height, i_face_height );
-
-        /* Skip what we have rendered and the line delimitor if present */
-        i_start = i_index;
-        if( i_start < i_len && psz_text[i_start] == '\n' )
-            i_start++;
-
-        if( bbox.yMax - bbox.yMin >= (int)p_filter->fmt_out.video.i_visible_height )
-        {
-            msg_Err( p_filter, "Truncated too high subtitle" );
-            break;
-        }
-    }
-    if( p_face )
-        FT_Done_Face( p_face );
-
-    free( pp_fribidi_styles );
-    free( p_fribidi_string );
-    free( pi_karaoke_bar );
-
-    *p_bbox = bbox;
-    return VLC_SUCCESS;
-}
-
 static xml_reader_t *GetXMLReader( filter_t *p_filter, stream_t *p_sub )
 {
     xml_reader_t *p_xml_reader = p_filter->p_sys->p_xml;
-- 
1.9.1




More information about the vlc-devel mailing list