Hi, [PATCH 1/2] Implement text cropping and fitting to specified width
this patch implement a feature that prevent very long string to take out of dedicated box. two methods implemented:
*width_crop* just limit target rendered image width *width_fit* scale width to fit specified width if it overflow it range [PATCH 2/2] Scale pango layout according aspect ratio usedthis patch force scaling pango canvas to pixel aspect ratio used. this should avoid scaling filter invoking and as result lowering CPU usage (for dv_pal_wide for example)
-- Maksym Veremeyenko
From 72c6f4680eb8a41ddf20993aab34aaceacaef34f Mon Sep 17 00:00:00 2001 From: Maksym Veremeyenko <ve...@m1.tv> Date: Tue, 26 Jan 2016 21:58:20 +0200 Subject: [PATCH 2/2] Scale pango layout according aspect ratio used --- src/modules/gtk2/producer_pango.c | 67 +++++++++++++++++++++++++++++++++-- src/modules/gtk2/producer_pango.yml | 11 ++++++ 2 files changed, 75 insertions(+), 3 deletions(-) diff --git a/src/modules/gtk2/producer_pango.c b/src/modules/gtk2/producer_pango.c index 6d9d4a6..81d81a6 100644 --- a/src/modules/gtk2/producer_pango.c +++ b/src/modules/gtk2/producer_pango.c @@ -83,6 +83,7 @@ struct producer_pango_s int rotate; int width_crop; int width_fit; + int respect_sample_aspect_num, respect_sample_aspect_den, respect_aspect_ratio; }; static void clean_cached( producer_pango self ) @@ -102,7 +103,8 @@ static void producer_close( mlt_producer parent ); static void pango_draw_background( GdkPixbuf *pixbuf, rgba_color bg ); static GdkPixbuf *pango_get_pixbuf( const char *markup, const char *text, const char *font, rgba_color fg, rgba_color bg, rgba_color ol, int pad, int align, char* family, - int style, int weight, int size, int outline, int rotate, int width_crop, int width_fit ); + int style, int weight, int size, int outline, int rotate, int width_crop, int width_fit, + int respect_sample_aspect_num, int respect_sample_aspect_den, int respect_aspect_ratio ); static void fill_pixbuf( GdkPixbuf* pixbuf, FT_Bitmap* bitmap, int w, int h, int pad, int align, rgba_color fg, rgba_color bg ); static void fill_pixbuf_with_outline( GdkPixbuf* pixbuf, FT_Bitmap* bitmap, int w, int h, int pad, int align, rgba_color fg, rgba_color bg, rgba_color ol, int outline ); @@ -404,6 +406,15 @@ static void refresh_image( mlt_frame frame, int width, int height ) int width_crop = mlt_properties_get_int( producer_props, "width_crop" ); int width_fit = mlt_properties_get_int( producer_props, "width_fit" ); int property_changed = 0; + int respect_sample_aspect_num = 0, respect_sample_aspect_den = 0; + int respect_aspect_ratio = mlt_properties_get_int( producer_props, "respect_aspect_ratio" ); + if ( respect_aspect_ratio ) + { + mlt_profile profile = mlt_service_profile( MLT_PRODUCER_SERVICE( producer ) ); + mlt_properties_set_double( producer_props, "force_aspect_ratio", mlt_profile_sar( profile ) ); + respect_sample_aspect_num = profile->sample_aspect_num; + respect_sample_aspect_den = profile->sample_aspect_den; + } if ( pixbuf == NULL ) { @@ -436,6 +447,9 @@ static void refresh_image( mlt_frame frame, int width, int height ) property_changed = property_changed || ( size != this->size ); property_changed = property_changed || ( width_crop != this->width_crop ); property_changed = property_changed || ( width_fit != this->width_fit ); + property_changed = property_changed || ( respect_sample_aspect_num != this->respect_sample_aspect_num ); + property_changed = property_changed || ( respect_sample_aspect_den != this->respect_sample_aspect_den ); + property_changed = property_changed || ( respect_aspect_ratio != this->respect_aspect_ratio ); // Save the properties for next comparison this->align = align; @@ -454,6 +468,9 @@ static void refresh_image( mlt_frame frame, int width, int height ) this->size = size; this->width_crop = width_crop; this->width_fit = width_fit; + this->respect_sample_aspect_num = respect_sample_aspect_num; + this->respect_sample_aspect_den = respect_sample_aspect_den; + this->respect_aspect_ratio = respect_aspect_ratio; } if ( pixbuf == NULL && property_changed ) @@ -483,7 +500,9 @@ static void refresh_image( mlt_frame frame, int width, int height ) } // Render the title - pixbuf = pango_get_pixbuf( markup, text, font, fgcolor, bgcolor, olcolor, pad, align, family, style, weight, size, outline, rotate, width_crop, width_fit ); + pixbuf = pango_get_pixbuf( markup, text, font, fgcolor, bgcolor, olcolor, pad, align, family, + style, weight, size, outline, rotate, width_crop, width_fit, + respect_sample_aspect_num, respect_sample_aspect_den, respect_aspect_ratio ); if ( pixbuf != NULL ) { @@ -749,7 +768,10 @@ static void pango_draw_background( GdkPixbuf *pixbuf, rgba_color bg ) } } -static GdkPixbuf *pango_get_pixbuf( const char *markup, const char *text, const char *font, rgba_color fg, rgba_color bg, rgba_color ol, int pad, int align, char* family, int style, int weight, int size, int outline, int rotate, int width_crop, int width_fit ) +static GdkPixbuf *pango_get_pixbuf( const char *markup, const char *text, const char *font, + rgba_color fg, rgba_color bg, rgba_color ol, int pad, int align, char* family, + int style, int weight, int size, int outline, int rotate, int width_crop, int width_fit, + int respect_sample_aspect_num, int respect_sample_aspect_den, int respect_aspect_ratio ) { PangoContext *context = pango_ft2_font_map_create_context( fontmap ); PangoLayout *layout = pango_layout_new( context ); @@ -828,6 +850,45 @@ static GdkPixbuf *pango_get_pixbuf( const char *markup, const char *text, const else pango_layout_get_pixel_size( layout, &w, &h ); + // respect aspect ratio + if ( respect_aspect_ratio ) + { + double n_x, n_y; + PangoRectangle rect; + PangoMatrix m_layout = PANGO_MATRIX_INIT, m_offset = PANGO_MATRIX_INIT; + + if ( 1 == respect_aspect_ratio ) + { + pango_matrix_scale( &m_layout, respect_sample_aspect_den / (double)respect_sample_aspect_num, 1.0 ); + pango_matrix_scale( &m_offset, respect_sample_aspect_den / (double)respect_sample_aspect_num, 1.0 ); + } + else + { + pango_matrix_scale( &m_layout, 1.0, respect_sample_aspect_num / (double)respect_sample_aspect_den ); + pango_matrix_scale( &m_offset, 1.0, respect_sample_aspect_num / (double)respect_sample_aspect_den ); + } + + pango_context_set_base_gravity( context, PANGO_GRAVITY_AUTO ); + pango_context_set_matrix( context, &m_layout ); + pango_layout_context_changed( layout ); + pango_layout_get_extents( layout, NULL, &rect ); + pango_matrix_transform_rectangle( pango_context_get_matrix( context ), &rect); + + n_x = -rect.x; + n_y = -rect.y; + pango_matrix_transform_point( &m_offset, &n_x, &n_y ); + rect.x = n_x; + rect.y = n_y; + + pango_extents_to_pixels( &rect, NULL ); + + w = rect.width; + h = rect.height; + + x = rect.x; + y = rect.y; + } + // limit width if ( width_crop && w > width_crop) w = width_crop; diff --git a/src/modules/gtk2/producer_pango.yml b/src/modules/gtk2/producer_pango.yml index 0168a82..20ab078 100644 --- a/src/modules/gtk2/producer_pango.yml +++ b/src/modules/gtk2/producer_pango.yml @@ -253,3 +253,14 @@ parameters: readonly: no mutable: yes widget: spinner + + - identifier: respect_aspect_ratio + title: Scale pango layout according aspect ratio used + type: integer + description: > + Non-zero value enables automatic scaling pango layout to producer profile sar used. + Value 1 scale horizontally, value 2 scales vertially + default: 0 + readonly: no + mutable: yes + widget: spinner -- 1.7.7.6
From 073f4f56456fd5d20d202597d1bb20e609e6a2ab Mon Sep 17 00:00:00 2001 From: Maksym Veremeyenko <ve...@m1.tv> Date: Tue, 26 Jan 2016 20:33:04 +0200 Subject: [PATCH 1/2] Implement text cropping and fitting to specified width --- src/modules/gtk2/producer_pango.c | 48 ++++++++++++++++++++++++++++++++-- src/modules/gtk2/producer_pango.yml | 20 ++++++++++++++ 2 files changed, 65 insertions(+), 3 deletions(-) diff --git a/src/modules/gtk2/producer_pango.c b/src/modules/gtk2/producer_pango.c index baa733a..6d9d4a6 100644 --- a/src/modules/gtk2/producer_pango.c +++ b/src/modules/gtk2/producer_pango.c @@ -81,6 +81,8 @@ struct producer_pango_s int style; int weight; int rotate; + int width_crop; + int width_fit; }; static void clean_cached( producer_pango self ) @@ -99,7 +101,8 @@ static int producer_get_frame( mlt_producer parent, mlt_frame_ptr frame, int ind static void producer_close( mlt_producer parent ); static void pango_draw_background( GdkPixbuf *pixbuf, rgba_color bg ); static GdkPixbuf *pango_get_pixbuf( const char *markup, const char *text, const char *font, - rgba_color fg, rgba_color bg, rgba_color ol, int pad, int align, char* family, int style, int weight, int size, int outline, int rotate ); + rgba_color fg, rgba_color bg, rgba_color ol, int pad, int align, char* family, + int style, int weight, int size, int outline, int rotate, int width_crop, int width_fit ); static void fill_pixbuf( GdkPixbuf* pixbuf, FT_Bitmap* bitmap, int w, int h, int pad, int align, rgba_color fg, rgba_color bg ); static void fill_pixbuf_with_outline( GdkPixbuf* pixbuf, FT_Bitmap* bitmap, int w, int h, int pad, int align, rgba_color fg, rgba_color bg, rgba_color ol, int outline ); @@ -398,6 +401,8 @@ static void refresh_image( mlt_frame frame, int width, int height ) int weight = mlt_properties_get_int( producer_props, "weight" ); int rotate = mlt_properties_get_int( producer_props, "rotate" ); int size = mlt_properties_get_int( producer_props, "size" ); + int width_crop = mlt_properties_get_int( producer_props, "width_crop" ); + int width_fit = mlt_properties_get_int( producer_props, "width_fit" ); int property_changed = 0; if ( pixbuf == NULL ) @@ -429,6 +434,8 @@ static void refresh_image( mlt_frame frame, int width, int height ) property_changed = property_changed || ( rotate != this->rotate ); property_changed = property_changed || ( style != this->style ); property_changed = property_changed || ( size != this->size ); + property_changed = property_changed || ( width_crop != this->width_crop ); + property_changed = property_changed || ( width_fit != this->width_fit ); // Save the properties for next comparison this->align = align; @@ -445,6 +452,8 @@ static void refresh_image( mlt_frame frame, int width, int height ) this->rotate = rotate; this->style = style; this->size = size; + this->width_crop = width_crop; + this->width_fit = width_fit; } if ( pixbuf == NULL && property_changed ) @@ -474,7 +483,7 @@ static void refresh_image( mlt_frame frame, int width, int height ) } // Render the title - pixbuf = pango_get_pixbuf( markup, text, font, fgcolor, bgcolor, olcolor, pad, align, family, style, weight, size, outline, rotate ); + pixbuf = pango_get_pixbuf( markup, text, font, fgcolor, bgcolor, olcolor, pad, align, family, style, weight, size, outline, rotate, width_crop, width_fit ); if ( pixbuf != NULL ) { @@ -740,7 +749,7 @@ static void pango_draw_background( GdkPixbuf *pixbuf, rgba_color bg ) } } -static GdkPixbuf *pango_get_pixbuf( const char *markup, const char *text, const char *font, rgba_color fg, rgba_color bg, rgba_color ol, int pad, int align, char* family, int style, int weight, int size, int outline, int rotate ) +static GdkPixbuf *pango_get_pixbuf( const char *markup, const char *text, const char *font, rgba_color fg, rgba_color bg, rgba_color ol, int pad, int align, char* family, int style, int weight, int size, int outline, int rotate, int width_crop, int width_fit ) { PangoContext *context = pango_ft2_font_map_create_context( fontmap ); PangoLayout *layout = pango_layout_new( context ); @@ -819,6 +828,39 @@ static GdkPixbuf *pango_get_pixbuf( const char *markup, const char *text, const else pango_layout_get_pixel_size( layout, &w, &h ); + // limit width + if ( width_crop && w > width_crop) + w = width_crop; + else if (width_fit && w > width_fit) + { + double n_x, n_y; + PangoRectangle rect; + PangoMatrix m_layout = PANGO_MATRIX_INIT, m_offset = PANGO_MATRIX_INIT; + + pango_matrix_scale( &m_layout, width_fit / (double)w, 1.0 ); + pango_matrix_scale( &m_offset, width_fit / (double)w, 1.0 ); + + pango_context_set_base_gravity( context, PANGO_GRAVITY_AUTO ); + pango_context_set_matrix( context, &m_layout ); + pango_layout_context_changed( layout ); + pango_layout_get_extents( layout, NULL, &rect ); + pango_matrix_transform_rectangle( pango_context_get_matrix( context ), &rect); + + n_x = -rect.x; + n_y = -rect.y; + pango_matrix_transform_point( &m_offset, &n_x, &n_y ); + rect.x = n_x; + rect.y = n_y; + + pango_extents_to_pixels( &rect, NULL ); + + w = rect.width; + h = rect.height; + + x = rect.x; + y = rect.y; + } + if ( pad == 0 ) pad = 1; diff --git a/src/modules/gtk2/producer_pango.yml b/src/modules/gtk2/producer_pango.yml index ce3badf..0168a82 100644 --- a/src/modules/gtk2/producer_pango.yml +++ b/src/modules/gtk2/producer_pango.yml @@ -233,3 +233,23 @@ parameters: readonly: no mutable: yes widget: spinner + + - identifier: width_crop + title: Width to crop + type: integer + description: > + Limit width of rendered image. + default: 0 + readonly: no + mutable: yes + widget: spinner + + - identifier: width_fit + title: Fit width + type: integer + description: > + Scale pango layout to fit specified width if it becode wider. + default: 0 + readonly: no + mutable: yes + widget: spinner -- 1.7.7.6
------------------------------------------------------------------------------ Site24x7 APM Insight: Get Deep Visibility into Application Performance APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month Monitor end-to-end web transactions and take corrective actions now Troubleshoot faster and improve end-user experience. Signup Now! http://pubads.g.doubleclick.net/gampad/clk?id=267308311&iu=/4140
_______________________________________________ Mlt-devel mailing list Mlt-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mlt-devel