X-Git-Url: http://research.m1stereo.tv/gitweb?a=blobdiff_plain;f=mlt%2Fsrc%2Fmodules%2Fgtk2%2Fproducer_pango.c;h=f1952dccc21bbf260e68df51df25e490c3d70a00;hb=8691b6464c35a77ae001b9843891a90dd9fd3d50;hp=d113ce69cf9df99f98fc6070e3971a14eedf91b0;hpb=d8eef875f19feb30549855d3695a91df72c5c60f;p=melted diff --git a/mlt/src/modules/gtk2/producer_pango.c b/mlt/src/modules/gtk2/producer_pango.c index d113ce6..f1952dc 100644 --- a/mlt/src/modules/gtk2/producer_pango.c +++ b/mlt/src/modules/gtk2/producer_pango.c @@ -26,6 +26,22 @@ #include #include +struct producer_pango_s +{ + struct mlt_producer_s parent; + int width; + int height; + uint8_t *image; + uint8_t *alpha; + int fgcolor; + int bgcolor; + int align; + int pad; + char *markup; + char *text; + char *font; +}; + // special color type used by internal pango routines typedef struct { @@ -36,9 +52,10 @@ typedef struct static int producer_get_frame( mlt_producer parent, mlt_frame_ptr frame, int index ); 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, rgba_color fg, rgba_color bg, int pad, int align ); +static GdkPixbuf *pango_get_pixbuf( const char *markup, const char *text, const char *font, + rgba_color fg, rgba_color bg, int pad, int align ); -mlt_producer producer_pango_init( const char *markup ) +mlt_producer producer_pango_init( const char *filename ) { producer_pango this = calloc( sizeof( struct producer_pango_s ), 1 ); if ( this != NULL && mlt_producer_init( &this->parent, this ) == 0 ) @@ -48,7 +65,7 @@ mlt_producer producer_pango_init( const char *markup ) producer->get_frame = producer_get_frame; producer->close = producer_close; - this->markup = strdup( markup ); + // This is required to initialise gdk-pixbuf g_type_init(); // Get the properties interface @@ -60,6 +77,52 @@ mlt_producer producer_pango_init( const char *markup ) mlt_properties_set_int( properties, "bgcolor", 0x00000000 ); mlt_properties_set_int( properties, "align", pango_align_left ); mlt_properties_set_int( properties, "pad", 0 ); + mlt_properties_set( properties, "text", "" ); + mlt_properties_set( properties, "font", "Sans 48" ); + mlt_properties_set_int( properties, "x", 0 ); + mlt_properties_set_int( properties, "y", 0 ); + mlt_properties_set_double( properties, "mix", 1.0 ); + + if ( filename == NULL ) + { + mlt_properties_set( properties, "resource", "pango" ); + mlt_properties_set( properties, "markup", "" ); + } + else + { + FILE *f = fopen( filename, "r" ); + if ( f != NULL ) + { + char line[81]; + char *markup = NULL; + size_t size = 0; + line[80] = '\0'; + + while ( fgets( line, 80, f ) ) + { + size += strlen( line ) + 1; + if ( markup ) + { + realloc( markup, size ); + strcat( markup, line ); + } + else + { + markup = strdup( line ); + } + } + fclose( f ); + mlt_properties_set( properties, "resource", ( char * ) filename ); + mlt_properties_set( properties, "markup", ( char * ) ( markup == NULL ? "" : markup ) ); + if ( markup ) + free( markup ); + } + else + { + mlt_properties_set( properties, "resource", "pango" ); + mlt_properties_set( properties, "markup", "" ); + } + } return producer; } @@ -119,37 +182,54 @@ static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int i // Generate a frame *frame = mlt_frame_init( ); - // Obtain properties of frame + // Obtain properties of frame and producer mlt_properties properties = mlt_frame_properties( *frame ); - - // optimization for subsequent iterations on single picture - if ( this->image != NULL ) + mlt_properties producer_props = mlt_producer_properties( producer ); + + // Get producer properties + int fg = mlt_properties_get_int( producer_props, "fgcolor" ); + int bg = mlt_properties_get_int( producer_props, "bgcolor" ); + int align = mlt_properties_get_int( producer_props, "align" ); + int pad = mlt_properties_get_int( producer_props, "pad" ); + char *markup = mlt_properties_get( producer_props, "markup" ); + char *text = mlt_properties_get( producer_props, "text" ); + char *font = mlt_properties_get( producer_props, "font" ); + + // See if any properties changed + int property_changed = ( fg != this->fgcolor ); + property_changed = property_changed || ( bg != this->bgcolor ); + property_changed = property_changed || ( align != this->align ); + property_changed = property_changed || ( pad != this->pad ); + property_changed = property_changed || ( markup && this->markup && strcmp( markup, this->markup ) ); + property_changed = property_changed || ( text && this->text && strcmp( text, this->text ) ); + property_changed = property_changed || ( font && this->font && strcmp( font, this->font ) ); + + // Save the properties for next comparison + this->fgcolor = fg; + this->bgcolor = bg; + this->align = align; + this->pad = pad; + if ( markup != NULL ) { - // Set width/height - mlt_properties_set_int( properties, "width", this->width ); - mlt_properties_set_int( properties, "height", this->height ); - - // if picture sequence pass the image and alpha data without destructor - mlt_properties_set_data( properties, "image", this->image, 0, NULL, NULL ); - mlt_properties_set_data( properties, "alpha", this->alpha, 0, NULL, NULL ); - - // Set alpha mask call back - ( *frame )->get_alpha_mask = producer_get_alpha_mask; - - // Stack the get image callback - mlt_frame_push_get_image( *frame, producer_get_image ); - + if ( this->markup != NULL ) + free( this->markup ); + this->markup = strdup( markup ); } - else + if ( text != NULL ) + { + if ( this->text != NULL ) + free( this->text ); + this->text = strdup( text ); + } + if ( font != NULL ) + { + if ( this->font != NULL ) + free( this->font ); + this->font = strdup( font ); + } + + if ( property_changed ) { - // Obtain properties of producer - mlt_properties props = mlt_producer_properties( producer ); - - // Get properties - int fg = mlt_properties_get_int( props, "fgcolor" ); - int bg = mlt_properties_get_int( props, "bgcolor" ); - int align = mlt_properties_get_int( props, "align" ); - int pad = mlt_properties_get_int( props, "pad" ); rgba_color fgcolor = { ( fg & 0xff000000 ) >> 24, @@ -164,9 +244,9 @@ static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int i ( bg & 0x0000ff00 ) >> 8, ( bg & 0x000000ff ) }; - + // Render the title - pixbuf = pango_get_pixbuf( this->markup, fgcolor, bgcolor, pad, align ); + pixbuf = pango_get_pixbuf( markup, text, font, fgcolor, bgcolor, pad, align ); } // If we have a pixbuf @@ -223,28 +303,44 @@ static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int i // Finished with pixbuf now g_object_unref( pixbuf ); + + // if single picture, reference the image and alpha in the producer + if ( this->image != NULL ) + free( this->image ); + this->image = image; + if ( this->alpha != NULL ) + free( this->alpha ); + this->alpha = alpha; - // Set width/height of frame + } + + if ( this->image != NULL ) + { + // Set width/height mlt_properties_set_int( properties, "width", this->width ); mlt_properties_set_int( properties, "height", this->height ); - // if single picture, reference the image and alpha in the producer - this->image = image; - this->alpha = alpha; + // Set the compositing properties + if ( mlt_properties_get( producer_props, "x" ) != NULL ) + mlt_properties_set_int( properties, "x", mlt_properties_get_int( producer_props, "x" ) ); + if ( mlt_properties_get( producer_props, "y" ) != NULL ) + mlt_properties_set_int( properties, "y", mlt_properties_get_int( producer_props, "y" ) ); + if ( mlt_properties_get( producer_props, "mix" ) != NULL ) + mlt_properties_set_double( properties, "image.mix", mlt_properties_get_double( producer_props, "mix" ) ); - // pass the image and alpha data without destructor - mlt_properties_set_data( properties, "image", image, 0, NULL, NULL ); - mlt_properties_set_data( properties, "alpha", alpha, 0, NULL, NULL ); + // if picture sequence pass the image and alpha data without destructor + mlt_properties_set_data( properties, "image", this->image, this->width * this->height * 2, NULL, NULL ); + mlt_properties_set_data( properties, "alpha", this->alpha, this->width * this->height, NULL, NULL ); - // Set alpha call back + // Set alpha mask call back ( *frame )->get_alpha_mask = producer_get_alpha_mask; - // Push the get_image method + // Stack the get image callback mlt_frame_push_get_image( *frame, producer_get_image ); } // Update timecode on the frame we're creating - mlt_frame_set_timecode( *frame, mlt_producer_position( producer ) ); + mlt_frame_set_position( *frame, mlt_producer_position( producer ) ); // Calculate the next timecode mlt_producer_prepare_next( producer ); @@ -255,12 +351,16 @@ static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int i static void producer_close( mlt_producer parent ) { producer_pango this = parent->child; - if ( this->markup ) - free( this->markup ); - if ( this->image ) + if ( this->image != NULL ) free( this->image ); - if ( this->alpha ) + if ( this->alpha != NULL ) free( this->alpha ); + if ( this->markup != NULL ) + free( this->markup ); + if ( this->text != NULL ) + free( this->text ); + if ( this->font != NULL ) + free( this->font ); parent->close = NULL; mlt_producer_close( parent ); free( this ); @@ -285,12 +385,11 @@ static void pango_draw_background( GdkPixbuf *pixbuf, rgba_color bg ) } } -static GdkPixbuf *pango_get_pixbuf( const char *markup, rgba_color fg, rgba_color bg, int pad, int align ) +static GdkPixbuf *pango_get_pixbuf( const char *markup, const char *text, const char *font, rgba_color fg, rgba_color bg, int pad, int align ) { PangoFT2FontMap *fontmap = (PangoFT2FontMap*) pango_ft2_font_map_new(); PangoContext *context = pango_ft2_font_map_create_context( fontmap ); PangoLayout *layout = pango_layout_new( context ); -// PangoFontDescription *font; int w, h, x; int i, j; GdkPixbuf *pixbuf = NULL; @@ -301,10 +400,15 @@ static GdkPixbuf *pango_get_pixbuf( const char *markup, rgba_color fg, rgba_colo pango_ft2_font_map_set_resolution( fontmap, 72, 72 ); pango_layout_set_width( layout, -1 ); // set wrapping constraints -// pango_layout_set_font_description( layout, "Sans 48" ); + pango_layout_set_font_description( layout, pango_font_description_from_string( font ) ); // pango_layout_set_spacing( layout, space ); pango_layout_set_alignment( layout, ( PangoAlignment ) align ); - pango_layout_set_markup( layout, markup, (markup == NULL ? 0 : strlen( markup ) ) ); + if ( markup != NULL && strcmp( markup, "" ) != 0 ) + pango_layout_set_markup( layout, markup, strlen( markup ) ); + else if ( text != NULL && strcmp( text, "" ) != 0 ) + pango_layout_set_text( layout, text, strlen( text ) ); + else + return NULL; pango_layout_get_pixel_size( layout, &w, &h ); pixbuf = gdk_pixbuf_new( GDK_COLORSPACE_RGB, TRUE /* has alpha */, 8, w + 2 * pad, h + 2 * pad );