[vlc-devel] [vlc-commits] text_renderer: freetype add support for ruby
Jean-Baptiste Kempf
jb at videolan.org
Fri Feb 16 22:17:59 CET 2018
This (and the following commit) deserve a NEWS entry!
Also, gg!
On Fri, 16 Feb 2018, at 19:38, Francois Cartegnie wrote:
> vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Fri Feb
> 9 00:58:47 2018 +0100| [aa11155a67111520091f70a902b83436396158ee] |
> committer: Francois Cartegnie
>
> text_renderer: freetype add support for ruby
>
> > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=aa11155a67111520091f70a902b83436396158ee
> ---
>
> modules/text_renderer/freetype/freetype.c | 91 +++++++++++-
> modules/text_renderer/freetype/text_layout.c | 214 ++++++++++++++++++++++++++-
> modules/text_renderer/freetype/text_layout.h | 19 ++-
> 3 files changed, 312 insertions(+), 12 deletions(-)
>
> diff --git a/modules/text_renderer/freetype/freetype.c b/modules/
> text_renderer/freetype/freetype.c
> index 1802367349..bf76d49b0c 100644
> --- a/modules/text_renderer/freetype/freetype.c
> +++ b/modules/text_renderer/freetype/freetype.c
> @@ -841,6 +841,17 @@ static void RenderCharAXYZ( filter_t *p_filter,
> break;
> }
>
> + if(ch->p_ruby && ch->p_ruby->p_laid)
> + {
> + RenderCharAXYZ( p_filter,
> + p_picture,
> + ch->p_ruby->p_laid,
> + i_offset_x, i_offset_y,
> + 2,
> + ExtractComponents,
> + BlendPixel );
> + }
> +
> /* Don't render if invisible or not wanted */
> if( i_a == STYLE_ALPHA_TRANSPARENT ||
> (g == 0 && 0 == (ch->p_style->i_style_flags & STYLE_SHADOW) ) ||
> @@ -1001,6 +1012,27 @@ static void FillDefaultStyles( filter_t *p_filter )
> text_style_Merge( p_sys->p_default_style, p_sys->p_forced_style, true );
> }
>
> +static void FreeRubyBlockArray( ruby_block_t **pp_array, size_t
> i_array )
> +{
> + ruby_block_t *p_lyt = NULL;
> + for( size_t i = 0; i< i_array; i++ )
> + {
> + if( p_lyt != pp_array[i] )
> + {
> + p_lyt = pp_array[i];
> + if( p_lyt )
> + {
> + free( p_lyt->p_uchars );
> + text_style_Delete( p_lyt->p_style );
> + if( p_lyt->p_laid )
> + FreeLines( p_lyt->p_laid );
> + free( p_lyt );
> + }
> + }
> + }
> + free( pp_array );
> +}
> +
> static void FreeStylesArray( text_style_t **pp_styles, size_t
> i_styles )
> {
> text_style_t *p_style = NULL;
> @@ -1016,7 +1048,8 @@ static void FreeStylesArray( text_style_t
> **pp_styles, size_t i_styles )
> }
>
> static size_t AddTextAndStyles( filter_sys_t *p_sys,
> - const char *psz_text, const
> text_style_t *p_style,
> + const char *psz_text, const char
> *psz_rt,
> + const text_style_t *p_style,
> layout_text_block_t *p_text_block )
> {
> /* Convert chars to unicode */
> @@ -1046,6 +1079,15 @@ static size_t AddTextAndStyles( filter_sys_t
> *p_sys,
> return 0;
> p_text_block->pp_styles = p_realloc;
>
> + /* Same for ruby text */
> + if( SIZE_MAX / sizeof(text_segment_ruby_t *) < p_text_block-
> >i_count + i_newchars )
> + return 0;
> + i_realloc = (p_text_block->i_count + i_newchars) *
> sizeof(text_segment_ruby_t *);
> + p_realloc = realloc( p_text_block->pp_ruby, i_realloc );
> + if ( unlikely(!p_realloc) )
> + return 0;
> + p_text_block->pp_ruby = p_realloc;
> +
> /* Copy data */
> memcpy( &p_text_block->p_uchars[p_text_block->i_count], p_ucs4,
> i_newchars * 4 );
> free( p_ucs4 );
> @@ -1065,6 +1107,33 @@ static size_t AddTextAndStyles( filter_sys_t
> *p_sys,
> for ( size_t i = 0; i < i_newchars; ++i )
> p_text_block->pp_styles[p_text_block->i_count + i] = p_mgstyle;
>
> + ruby_block_t *p_rubyblock = NULL;
> + if( psz_rt )
> + {
> + p_ucs4 = ToCharset( FREETYPE_TO_UCS, psz_rt, &i_bytes );
> + if( !p_ucs4 )
> + return 0;
> + p_rubyblock = malloc(sizeof(ruby_block_t));
> + if( p_rubyblock )
> + {
> + p_rubyblock->p_style = text_style_Duplicate( p_mgstyle );
> + if( !p_rubyblock->p_style )
> + {
> + free( p_ucs4 );
> + free( p_rubyblock );
> + return 0;
> + }
> + p_rubyblock->p_style->i_font_size *= 0.4;
> + p_rubyblock->p_style->f_font_relsize *= 0.4;
> + p_rubyblock->p_uchars = p_ucs4;
> + p_rubyblock->i_count = i_bytes / 4;
> + p_rubyblock->p_laid = NULL;
> + }
> + else free( p_ucs4 );
> + }
> + for ( size_t i = 0; i < i_newchars; ++i )
> + p_text_block->pp_ruby[p_text_block->i_count + i] = p_rubyblock;
> +
> /* now safe to update total nb */
> p_text_block->i_count += i_newchars;
>
> @@ -1081,8 +1150,22 @@ static size_t SegmentsToTextAndStyles( filter_t
> *p_filter, const text_segment_t
> if( !s->psz_text || !s->psz_text[0] )
> continue;
>
> - i_nb_char += AddTextAndStyles( p_filter->p_sys, s->psz_text,
> - s->style, p_text_block );
> + if( s->p_ruby )
> + {
> + for( const text_segment_ruby_t *p_ruby = s->p_ruby;
> + p_ruby; p_ruby = p_ruby-
> >p_next )
> + {
> + i_nb_char += AddTextAndStyles( p_filter->p_sys,
> + p_ruby->psz_base,
> p_ruby->psz_rt,
> + s->style,
> p_text_block );
> + }
> + }
> + else
> + {
> + i_nb_char += AddTextAndStyles( p_filter->p_sys,
> + s->psz_text, NULL,
> + s->style, p_text_block );
> + }
> }
>
> return i_nb_char;
> @@ -1283,6 +1366,8 @@ static int Render( filter_t *p_filter,
> subpicture_region_t *p_region_out,
>
> free( text_block.p_uchars );
> FreeStylesArray( text_block.pp_styles, text_block.i_count );
> + if( text_block.pp_ruby )
> + FreeRubyBlockArray( text_block.pp_ruby, text_block.i_count );
> free( text_block.pi_k_durations );
>
> return rv;
> diff --git a/modules/text_renderer/freetype/text_layout.c b/modules/
> text_renderer/freetype/text_layout.c
> index ad998b2089..106d6f1ba1 100644
> --- a/modules/text_renderer/freetype/text_layout.c
> +++ b/modules/text_renderer/freetype/text_layout.c
> @@ -137,6 +137,7 @@ typedef struct paragraph_t
> uni_char_t *p_code_points; /**< Unicode code points */
> int *pi_glyph_indices; /**< Glyph index values
> within the run's font face */
> text_style_t **pp_styles;
> + ruby_block_t **pp_ruby;
> FT_Face *pp_faces; /**< Used to determine run
> boundaries when performing font fallback */
> int *pi_run_ids; /**< The run to which each
> glyph belongs */
> glyph_bitmaps_t *p_glyph_bitmaps;
> @@ -171,6 +172,9 @@ static void FreeLine( line_desc_t *p_line )
> FT_Done_Glyph( (FT_Glyph)ch->p_shadow );
> }
>
> +// if( p_line->p_ruby )
> +// FreeLine( p_line->p_ruby );
> +
> free( p_line->p_character );
> free( p_line );
> }
> @@ -210,6 +214,67 @@ line_desc_t *NewLine( int i_count )
> return p_line;
> }
>
> +static void ShiftGlyph( FT_BitmapGlyph g, int x, int y )
> +{
> + if( g )
> + {
> + g->left += x;
> + g->top += y;
> + }
> +}
> +
> +static void ShiftChar( line_character_t *c, int x, int y )
> +{
> + ShiftGlyph( c->p_glyph, x, y );
> + ShiftGlyph( c->p_shadow, x, y );
> + ShiftGlyph( c->p_outline, x, y );
> + c->bbox.yMin += y;
> + c->bbox.yMax += y;
> + c->bbox.xMin += x;
> + c->bbox.xMax += x;
> +}
> +
> +static void ShiftLine( line_desc_t *p_line, int x, int y )
> +{
> + for( int i=0; i<p_line->i_character_count; i++ )
> + ShiftChar( &p_line->p_character[i], x, y );
> + p_line->i_base_line += y;
> + p_line->bbox.yMin += y;
> + p_line->bbox.yMax += y;
> + p_line->bbox.xMin += x;
> + p_line->bbox.xMax += x;
> +}
> +
> +static void MoveLineTo( line_desc_t *p_line, int x, int y )
> +{
> + ShiftLine( p_line, x - p_line->bbox.xMin,
> + y - p_line->bbox.yMax );
> +}
> +
> +static void IndentCharsFrom( line_desc_t *p_line, int i_start, int
> i_count, int w, int h )
> +{
> + for( int i=0; i<i_count; i++ )
> + {
> + line_character_t *p_ch = &p_line->p_character[i_start + i];
> + ShiftChar( p_ch, w, h );
> + BBoxEnlarge( &p_line->bbox, &p_ch->bbox );
> + }
> +}
> +
> +static int RubyBaseAdvance( const line_desc_t *p_line, int i_start, int
> *pi_count )
> +{
> + int i_total = 0;
> + *pi_count = 0;
> + for( int i = i_start; i < p_line->i_character_count; i++ )
> + {
> + if( p_line->p_character[i].p_ruby != p_line-
> >p_character[i_start].p_ruby )
> + break;
> + (*pi_count)++;
> + i_total += (p_line->p_character[i].bbox.xMax - p_line-
> >p_character[i].bbox.xMin);
> + }
> + return i_total;
> +}
> +
> static void FixGlyph( FT_Glyph glyph, FT_BBox *p_bbox,
> FT_Pos i_x_advance, FT_Pos i_y_advance,
> const FT_Vector *p_pen )
> @@ -233,6 +298,7 @@ static paragraph_t *NewParagraph( filter_t
> *p_filter,
> int i_size,
> const uni_char_t *p_code_points,
> text_style_t **pp_styles,
> + ruby_block_t **pp_ruby,
> uint32_t *pi_k_dates,
> int i_runs_size )
> {
> @@ -255,6 +321,8 @@ static paragraph_t *NewParagraph( filter_t
> *p_filter,
> calloc( i_size, sizeof( *p_paragraph->p_glyph_bitmaps ) );
> p_paragraph->pi_karaoke_bar =
> calloc( i_size, sizeof( *p_paragraph->pi_karaoke_bar ) );
> + if( pp_ruby )
> + p_paragraph->pp_ruby = calloc( i_size, sizeof( *p_paragraph-
> >pp_ruby ) );
>
> p_paragraph->p_runs = calloc( i_runs_size, sizeof( run_desc_t ) );
> p_paragraph->i_runs_size = i_runs_size;
> @@ -272,6 +340,9 @@ static paragraph_t *NewParagraph( filter_t *p_filter,
> if( pp_styles )
> memcpy( p_paragraph->pp_styles, pp_styles,
> i_size * sizeof( *pp_styles ) );
> + if( p_paragraph->pp_ruby )
> + memcpy( p_paragraph->pp_ruby, pp_ruby, i_size * sizeof( *pp_ruby ) );
> +
> if( pi_k_dates )
> {
> int64_t i_elapsed = var_GetInteger( p_filter, "spu-elapsed" ) / 1000;
> @@ -315,6 +386,7 @@ error:
> if( p_paragraph->p_code_points ) free( p_paragraph->p_code_points );
> if( p_paragraph->pi_glyph_indices ) free( p_paragraph->pi_glyph_indices );
> if( p_paragraph->pp_styles ) free( p_paragraph->pp_styles );
> + if( p_paragraph->pp_ruby ) free( p_paragraph->pp_ruby );
> if( p_paragraph->pp_faces ) free( p_paragraph->pp_faces );
> if( p_paragraph->pi_run_ids ) free( p_paragraph->pi_run_ids );
> if( p_paragraph->p_glyph_bitmaps ) free( p_paragraph->p_glyph_bitmaps );
> @@ -341,6 +413,7 @@ static void FreeParagraph( paragraph_t *p_paragraph )
> free( p_paragraph->pi_karaoke_bar );
> free( p_paragraph->pi_run_ids );
> free( p_paragraph->pp_faces );
> + free( p_paragraph->pp_ruby );
> free( p_paragraph->pp_styles );
> free( p_paragraph->p_code_points );
>
> @@ -732,13 +805,20 @@ static int ShapeParagraphHarfBuzz( filter_t *p_filter,
> i_total_glyphs += p_run->i_glyph_count;
> }
>
> - p_new_paragraph = NewParagraph( p_filter, i_total_glyphs, 0, 0, 0,
> + p_new_paragraph = NewParagraph( p_filter, i_total_glyphs,
> + NULL, NULL, NULL, NULL,
> p_paragraph->i_runs_size );
> if( !p_new_paragraph )
> {
> i_ret = VLC_ENOMEM;
> goto error;
> }
> + if( p_paragraph->pp_ruby )
> + {
> + p_new_paragraph->pp_ruby = calloc(p_new_paragraph->i_size,
> + sizeof(ruby_block_t *));
> + }
> +
> p_new_paragraph->paragraph_type = p_paragraph->paragraph_type;
>
> int i_index = 0;
> @@ -772,6 +852,9 @@ static int ShapeParagraphHarfBuzz( filter_t
> *p_filter,
> p_paragraph->p_levels[ i_source_index ];
> p_new_paragraph->pp_styles[ i_index ] =
> p_paragraph->pp_styles[ i_source_index ];
> + if( p_new_paragraph->pp_ruby )
> + p_new_paragraph->pp_ruby[ i_index ] =
> + p_paragraph->pp_ruby[ i_source_index ];
> p_new_paragraph->pi_karaoke_bar[ i_index ] =
> p_paragraph->pi_karaoke_bar[ i_source_index ];
> p_new_paragraph->p_glyph_bitmaps[ i_index ].i_x_offset =
> @@ -1056,7 +1139,8 @@ static int LoadGlyphs( filter_t *p_filter,
> paragraph_t *p_paragraph,
> static int LayoutLine( filter_t *p_filter,
> paragraph_t *p_paragraph,
> int i_first_char, int i_last_char,
> - line_desc_t **pp_line, bool b_grid )
> + bool b_grid,
> + line_desc_t **pp_line )
> {
> if( p_paragraph->i_size <= 0 || p_paragraph->i_runs_count <= 0
> || i_first_char < 0 || i_last_char < 0
> @@ -1111,6 +1195,9 @@ static int LayoutLine( filter_t *p_filter,
> line_character_t *p_ch = &p_line->p_character[p_line-
> >i_character_count];
> p_ch->p_style = p_paragraph->pp_styles[ i_paragraph_index ];
>
> + if( p_paragraph->pp_ruby )
> + p_ch->p_ruby = p_paragraph->pp_ruby[ i ];
> +
> glyph_bitmaps_t *p_bitmaps =
> p_paragraph->p_glyph_bitmaps + i_paragraph_index;
>
> @@ -1273,6 +1360,44 @@ static int LayoutLine( filter_t *p_filter,
> p_line->i_character_count++;
> }
>
> + /* Second pass for ruby layout */
> + if( p_paragraph->pp_ruby )
> + {
> + const int i_ruby_baseline = p_line->bbox.yMax;
> + const ruby_block_t *p_prevruby = NULL;
> + for( int i = 0; i < p_line->i_character_count; ++i )
> + {
> + line_character_t *p_ch = &p_line->p_character[i];
> + if( p_ch->p_ruby == p_prevruby || !p_ch->p_glyph )
> + continue;
> + p_prevruby = p_ch->p_ruby;
> + if( !p_ch->p_ruby )
> + continue;
> + line_desc_t *p_rubyline = p_ch->p_ruby->p_laid;
> + if( !p_rubyline )
> + continue;
> +
> + int i_rubyadvance = (p_rubyline->bbox.xMax - p_rubyline-
> >bbox.xMin);
> + int i_rubyheight = (p_rubyline->bbox.yMax - p_rubyline-
> >bbox.yMin);
> + MoveLineTo( p_rubyline, p_ch->bbox.xMin, i_ruby_baseline +
> i_rubyheight );
> + BBoxEnlarge( &p_line->bbox, &p_rubyline->bbox );
> +
> + int i_count;
> + int i_baseadvance = RubyBaseAdvance( p_line, i, &i_count );
> + if( i_baseadvance < i_rubyadvance )
> + {
> + IndentCharsFrom( p_line, i, i_count, (i_rubyadvance -
> i_baseadvance) / 2, 0 );
> + IndentCharsFrom( p_line, i + i_count, p_line-
> >i_character_count - (i + i_count),
> + (i_rubyadvance - i_baseadvance + 1),
> 0 );
> + }
> + else if( i_baseadvance > i_rubyadvance + 1 )
> + {
> + ShiftLine( p_rubyline, (i_baseadvance -
> i_rubyadvance) / 2, 0 );
> + BBoxEnlarge( &p_line->bbox, &p_rubyline->bbox ); /*
> shouldn't be needed */
> + }
> + }
> + }
> +
> p_line->i_width = __MAX( 0, p_line->bbox.xMax - p_line-
> >bbox.xMin );
>
> if( b_grid )
> @@ -1316,7 +1441,8 @@ static inline bool IsWhitespaceAt( paragraph_t
> *p_paragraph, size_t i )
>
> static int LayoutParagraph( filter_t *p_filter, paragraph_t
> *p_paragraph,
> unsigned i_max_width, unsigned
> i_max_advance_x,
> - line_desc_t **pp_lines, bool b_grid, bool
> b_balance )
> + bool b_grid, bool b_balance,
> + line_desc_t **pp_lines )
> {
> if( p_paragraph->i_size <= 0 || p_paragraph->i_runs_count <= 0 )
> {
> @@ -1376,12 +1502,27 @@ static int LayoutParagraph( filter_t *p_filter,
> paragraph_t *p_paragraph,
> {
> if( i_line_start < i )
> if( LayoutLine( p_filter, p_paragraph,
> - i_line_start, i - 1, pp_line,
> b_grid ) )
> + i_line_start, i - 1, b_grid,
> pp_line ) )
> goto error;
>
> break;
> }
>
> + if( p_paragraph->pp_ruby &&
> + p_paragraph->pp_ruby[i] &&
> + p_paragraph->pp_ruby[i]->p_laid )
> + {
> + /* Just forward as non breakable */
> + const ruby_block_t *p_rubyseq = p_paragraph->pp_ruby[i];
> + int i_advance = 0;
> + int i_advanceruby = p_rubyseq->p_laid->i_width;
> + while( i < p_paragraph->i_size && p_rubyseq == p_paragraph-
> >pp_ruby[i] )
> + i_advance += p_paragraph->p_glyph_bitmaps[ i+
> + ].i_x_advance;
> + /* Just forward as non breakable */
> + i_width += (i_advance < i_advanceruby) ? i_advanceruby :
> i_advance;
> + continue;
> + }
> +
> if( IsWhitespaceAt( p_paragraph, i ) )
> {
> if( i_line_start == i )
> @@ -1431,7 +1572,7 @@ static int LayoutParagraph( filter_t *p_filter,
> paragraph_t *p_paragraph,
> i_newline_start = i; /* we break line on last char */
>
> if( LayoutLine( p_filter, p_paragraph, i_line_start,
> - i_newline_start - 1, pp_line, b_grid ) )
> + i_newline_start - 1, b_grid, pp_line ) )
> goto error;
>
> /* Handle early end of renderable content;
> @@ -1480,6 +1621,7 @@ static paragraph_t * BuildParagraph( filter_t *p_filter,
> int i_size,
> const uni_char_t *p_uchars,
> text_style_t **pp_styles,
> + ruby_block_t **pp_ruby,
> uint32_t *pi_k_dates,
> int i_runs_size,
> unsigned *pi_max_advance_x )
> @@ -1487,6 +1629,7 @@ static paragraph_t * BuildParagraph( filter_t *p_filter,
> paragraph_t *p_paragraph = NewParagraph( p_filter, i_size,
> p_uchars,
> pp_styles,
> + pp_ruby,
> pi_k_dates,
> i_runs_size );
> if( !p_paragraph )
> @@ -1520,6 +1663,7 @@ static paragraph_t * BuildParagraph( filter_t *p_filter,
> if( LoadGlyphs( p_filter, p_paragraph, false, true, pi_max_advance_x ) )
> goto error;
> #endif
> +
> return p_paragraph;
>
> error:
> @@ -1529,6 +1673,43 @@ error:
> return NULL;
> }
>
> +static int LayoutRubyText( filter_t *p_filter,
> + const uni_char_t *p_uchars,
> + int i_uchars,
> + text_style_t *p_style,
> + line_desc_t **pp_line )
> +{
> + unsigned int i_max_advance_x;
> +
> + text_style_t **pp_styles = malloc(sizeof(*pp_styles) * i_uchars);
> + for(int i=0;i<i_uchars;i++)
> + pp_styles[i] = p_style;
> +
> + paragraph_t *p_paragraph = BuildParagraph( p_filter, i_uchars,
> + p_uchars, pp_styles,
> + NULL, NULL, 1,
> + &i_max_advance_x );
> + if( !p_paragraph )
> + {
> + free( pp_styles );
> + return VLC_EGENERIC;
> + }
> +
> + if( LayoutLine( p_filter, p_paragraph,
> + 0, i_uchars - 1,
> + false, pp_line ) )
> + {
> + free( pp_styles );
> + FreeParagraph( p_paragraph );
> + return VLC_EGENERIC;
> + }
> +
> + FreeParagraph( p_paragraph );
> + free( pp_styles );
> +
> + return VLC_SUCCESS;
> +}
> +
> int LayoutTextBlock( filter_t *p_filter,
> const layout_text_block_t *p_textblock,
> line_desc_t **pp_lines, FT_BBox *p_bbox,
> @@ -1541,6 +1722,22 @@ int LayoutTextBlock( filter_t *p_filter,
> unsigned i_max_advance_x = 0;
> int i_max_face_height = 0;
>
> + /* Prepare ruby content */
> + if( p_textblock->pp_ruby )
> + {
> + ruby_block_t *p_prev = NULL;
> + for( size_t i=0; i<p_textblock->i_count; i++ )
> + {
> + if( p_textblock->pp_ruby[i] == p_prev )
> + continue;
> + p_prev = p_textblock->pp_ruby[i];
> + if( p_prev )
> + LayoutRubyText( p_filter, p_prev->p_uchars, p_prev-
> >i_count,
> + p_prev->p_style, &p_prev->p_laid );
> + }
> + }
> + /* !Prepare ruby content */
> +
> for( size_t i = 0; i <= p_textblock->i_count; ++i )
> {
> if( i == p_textblock->i_count || p_textblock->p_uchars[ i ] ==
> '\n' )
> @@ -1556,6 +1753,8 @@ int LayoutTextBlock( filter_t *p_filter,
> i - i_paragraph_start,
> &p_textblock-
> >p_uchars[i_paragraph_start],
> &p_textblock-
> >pp_styles[i_paragraph_start],
> + p_textblock->pp_ruby ?
> + &p_textblock-
> >pp_ruby[i_paragraph_start] : NULL,
> p_textblock->pi_k_durations ?
> &p_textblock-
> >pi_k_durations[i_paragraph_start] : NULL,
> 20, &i_max_advance_x );
> @@ -1567,8 +1766,9 @@ int LayoutTextBlock( filter_t *p_filter,
>
> if( LayoutParagraph( p_filter, p_paragraph,
> p_textblock->i_max_width,
> - i_max_advance_x, pp_line,
> - p_textblock->b_grid, p_textblock-
> >b_balanced ) )
> + i_max_advance_x,
> + p_textblock->b_grid, p_textblock-
> >b_balanced,
> + pp_line ) )
> {
> FreeParagraph( p_paragraph );
> if( p_first_line ) FreeLines( p_first_line );
> diff --git a/modules/text_renderer/freetype/text_layout.h b/modules/
> text_renderer/freetype/text_layout.h
> index ea0bca7558..bb31aac1b6 100644
> --- a/modules/text_renderer/freetype/text_layout.h
> +++ b/modules/text_renderer/freetype/text_layout.h
> @@ -33,6 +33,9 @@
>
> #include "freetype.h"
>
> +typedef struct ruby_block_t ruby_block_t;
> +typedef struct line_desc_t line_desc_t;
> +
> typedef struct
> {
> FT_BitmapGlyph p_glyph;
> @@ -40,16 +43,15 @@ typedef struct
> FT_BitmapGlyph p_shadow;
> FT_BBox bbox;
> const text_style_t *p_style;
> + const ruby_block_t *p_ruby;
> int i_line_offset; /* underline/strikethrough offset */
> int i_line_thickness; /* underline/strikethrough thickness */
> bool b_in_karaoke;
> } line_character_t;
>
> -typedef struct line_desc_t line_desc_t;
> struct line_desc_t
> {
> line_desc_t *p_next;
> -
> int i_width;
> int i_height;
> int i_base_line;
> @@ -64,6 +66,18 @@ void FreeLines( line_desc_t *p_lines );
> line_desc_t *NewLine( int i_count );
>
> /**
> + * \struct layout_ruby_t
> + * \brief LayoutText parameters
> + */
> +struct ruby_block_t
> +{
> + uni_char_t *p_uchars; /*!< array of size \p i_count character
> codepoints */
> + size_t i_count; /*!< length of the array */
> + text_style_t *p_style; /*!< own style */
> + line_desc_t *p_laid;
> +};
> +
> +/**
> * \struct layout_text_block_t
> * \brief LayoutText parameters
> */
> @@ -71,6 +85,7 @@ typedef struct
> {
> uni_char_t *p_uchars; /*!< array of size \p i_count character
> codepoints */
> text_style_t **pp_styles; /*!< array of size \p i_count character
> styles */
> + ruby_block_t **pp_ruby; /*!< array of size \p */
> uint32_t *pi_k_durations; /*!< array of size \p i_count karaoke
> timestamps */
> size_t i_count; /*!< length of the arrays */
>
>
> _______________________________________________
> vlc-commits mailing list
> vlc-commits at videolan.org
> https://mailman.videolan.org/listinfo/vlc-commits
--
Jean-Baptiste Kempf - President
+33 672 704 734
More information about the vlc-devel
mailing list