diff options
author | vektor <devnull@localhost> | 2003-07-08 13:56:57 +0000 |
---|---|---|
committer | vektor <devnull@localhost> | 2003-07-08 13:56:57 +0000 |
commit | 2ddd2073034cd32fa9a0ef68d68531cd5623d03f (patch) | |
tree | 29155fc0258fc66c517788111dbbb9582ee0f755 | |
parent | 3efce7e297e87af341fe8779eed271eb0d00e74d (diff) |
08 Jul 2003 Billy Biggs <vektor@dumbterm.net>
* tvtime/src/osdtools.h: Added a list widget with hilighting for
building OSD menus.
* tvtime/src/osdtools.c: Implementation.
* tvtime/src/tvtimeosd.h: Let the OSD have a single master list which
the application can construct and query.
* tvtime/src/tvtimeosd.c: Implementation.
-rw-r--r-- | src/osdtools.c | 292 | ||||
-rw-r--r-- | src/osdtools.h | 44 | ||||
-rw-r--r-- | src/tvtimeosd.c | 73 | ||||
-rw-r--r-- | src/tvtimeosd.h | 8 |
4 files changed, 227 insertions, 190 deletions
diff --git a/src/osdtools.c b/src/osdtools.c index f5953df..820a516 100644 --- a/src/osdtools.c +++ b/src/osdtools.c @@ -498,168 +498,6 @@ void osd_databars_composite_packed422_scanline( osd_databars_t *osdd, } } -/* Shape functions */ -struct osd_shape_s -{ - int type; - int frames_left; - int shape_luma; - int shape_cb; - int shape_cr; - int shape_height; - int shape_width; - int shape_adjusted_width; - int image_width; - int image_height; - double aspect_ratio; - int alpha; - uint8_t *image4444; -}; - -osd_shape_t *osd_shape_new( OSD_Shape shape_type, int video_width, - int video_height, int shape_width, - int shape_height, double aspect, int alpha ) -{ - osd_shape_t *osds = malloc( sizeof( osd_shape_t ) ); - osds->frames_left = 0; - osds->shape_luma = 16; - osds->shape_cb = 128; - osds->shape_cr = 128; - osds->image_width = video_width; - osds->image_height = video_height; - osds->alpha = alpha; - osds->aspect_ratio = aspect / (double)(((double)video_width)/((double)video_height)); - osds->shape_width = shape_width; - osds->shape_height = shape_height; - osds->shape_adjusted_width = shape_width; - osds->type = shape_type; - - osds->image4444 = malloc( video_width * video_height * 4 ); - if( !osds ) { - free( osds ); - return 0; - } - - return osds; -} - -void osd_shape_delete( osd_shape_t *osds ) -{ - free( osds->image4444 ); - free( osds ); -} - -void osd_shape_set_timeout( osd_shape_t *osds, int timeout ) -{ - osds->frames_left = timeout; -} - -void osd_shape_render_image4444( osd_shape_t *osds ) -{ - double radius_sqrd, x0, y0; - int x, y; - int width = osds->shape_width; - int height = osds->shape_height; - - switch( osds->type ) { - case OSD_Rect: - blit_colour_packed4444( osds->image4444, width, - height, osds->image_width * 4, - osds->alpha, osds->shape_luma, osds->shape_cb, - osds->shape_cr ); - break; - - case OSD_Circle: - osds->shape_height = osds->shape_width; - - blit_colour_packed4444( osds->image4444, width, - osds->shape_height, osds->image_width * 4, - 0, 0, 0, 0 ); - - x0 = osds->shape_width / 2.0; - y0 = osds->shape_height / 2.0; - radius_sqrd = x0*x0; - - for( x = 0; x < width; x++ ) { - for( y = 0; y < osds->shape_height; y++ ) { - double curx = x*osds->aspect_ratio; - int xoffset = x*4; - if( ((curx-x0)*(curx-x0) + (y-y0)*(y-y0)) <= radius_sqrd ) { - int offset = y*osds->image_width*4 + xoffset; - osds->image4444[ offset + 0 ] = osds->alpha; - osds->image4444[ offset + 1 ] = osds->shape_luma; - osds->image4444[ offset + 2 ] = osds->shape_cb; - osds->image4444[ offset + 3 ] = osds->shape_cr; - } - } - } - break; - - default: - blit_colour_packed4444( osds->image4444, width, - height, osds->image_width * 4, - 0, 0, 0, 0 ); - - break; - } - - osds->shape_adjusted_width = width; -} - -void osd_shape_set_colour( osd_shape_t *osds, int luma, int cb, int cr ) -{ - osds->shape_luma = luma; - osds->shape_cb = cb; - osds->shape_cr = cr; - osd_shape_render_image4444( osds ); -} - -void osd_shape_show_shape( osd_shape_t *osds, int timeout ) -{ - osds->frames_left = timeout; -} - -int osd_shape_visible( osd_shape_t *osds ) -{ - return (osds->frames_left > 0); -} - -void osd_shape_advance_frame( osd_shape_t *osds ) -{ - if( osds->frames_left > 0 ) { - osds->frames_left--; - } -} - -void osd_shape_composite_packed422_scanline( osd_shape_t *osds, - uint8_t *output, - uint8_t *background, - int width, int xpos, - int scanline ) -{ - if( osds->frames_left ) { - if( scanline < osds->shape_height && xpos < osds->shape_adjusted_width ) { - - if( (xpos+width) > osds->shape_adjusted_width ) { - width = osds->shape_adjusted_width - xpos; - } - - if( osds->frames_left < OSD_FADEOUT_TIME ) { - int alpha; - alpha = (int) (((((double) osds->frames_left) / ((double) OSD_FADEOUT_TIME)) * 256.0) + 0.5); - composite_packed4444_alpha_to_packed422_scanline( output, background, - osds->image4444 + (osds->image_width*4*scanline) + (xpos*4), - width, alpha ); - } else { - composite_packed4444_to_packed422_scanline( output, background, - osds->image4444 + (osds->image_width*4*scanline) + (xpos*4), - width ); - } - } - } -} - - /* Graphic functions */ struct osd_graphic_s { @@ -990,4 +828,134 @@ void osd_animation_composite_packed422_scanline( osd_animation_t *osda, } } +#define OSD_LIST_MAX_LINES 10 + +struct osd_list_s +{ + double aspect; + int numlines; + int hilight; + osd_font_t *font; + osd_string_t *lines[ OSD_LIST_MAX_LINES ]; +}; + +osd_list_t *osd_list_new( double pixel_aspect ) +{ + osd_list_t *osdl = malloc( sizeof( osd_list_t ) ); + int i; + + if( !osdl ) { + return 0; + } + + osdl->hilight = -1; + osdl->numlines = 0; + osdl->font = osd_font_new( "FreeSansBold.ttf", 18, pixel_aspect ); + if( !osdl->font ) { + free( osdl ); + return 0; + } + memset( osdl->lines, 0, sizeof( osdl->lines ) ); + + for( i = 0; i < OSD_LIST_MAX_LINES; i++ ) { + osdl->lines[ i ] = osd_string_new( osdl->font ); + if( !osdl->lines[ i ] ) { + osd_list_delete( osdl ); + return 0; + } + osd_string_show_text( osdl->lines[ i ], "Blank", 100 ); + osd_string_set_colour( osdl->lines[ i ], 200, 128, 128 ); + osd_string_show_border( osdl->lines[ i ], 1 ); + } + + return osdl; +} + +void osd_list_delete( osd_list_t *osdl ) +{ + int i; + + for( i = 0; i < OSD_LIST_MAX_LINES; i++ ) { + if( osdl->lines[ i ] ) osd_string_delete( osdl->lines[ i ] ); + } + free( osdl ); +} + +void osd_list_set_text( osd_list_t *osdl, int line, const char *text ) +{ + if( line < OSD_LIST_MAX_LINES ) { + osd_string_show_text( osdl->lines[ line ], text, 100 ); + } +} + +void osd_list_set_lines( osd_list_t *osdl, int numlines ) +{ + osdl->numlines = numlines; +} + +void osd_list_set_hilight( osd_list_t *osdl, int pos ) +{ + if( pos < OSD_LIST_MAX_LINES ) { + if( osdl->hilight >= 0 ) { + osd_string_set_colour( osdl->lines[ osdl->hilight ], + 200, 128, 128 ); + osd_string_rerender( osdl->lines[ osdl->hilight ] ); + } + osdl->hilight = pos; + if( osdl->hilight >= 0 ) { + osd_string_set_colour_rgb( osdl->lines[ osdl->hilight ], + 255, 255, 0 ); + osd_string_rerender( osdl->lines[ osdl->hilight ] ); + } + } +} + +int osd_list_get_hilight( osd_list_t *osdl ) +{ + return osdl->hilight; +} + +int osd_list_get_numlines( osd_list_t *osdl ) +{ + return osdl->numlines; +} + +void osd_list_set_timeout( osd_list_t *osdl, int timeout ) +{ + int i; + for( i = 0; i < osdl->numlines; i++ ) { + osd_string_set_timeout( osdl->lines[ i ], timeout ); + } +} + +int osd_list_visible( osd_list_t *osdl ) +{ + return (osdl->numlines > 0 && osd_string_visible( osdl->lines[ 0 ] )); +} + +void osd_list_advance_frame( osd_list_t *osdl ) +{ + int i; + for( i = 0; i < osdl->numlines; i++ ) { + osd_string_advance_frame( osdl->lines[ i ] ); + } +} + +void osd_list_composite_packed422_scanline( osd_list_t *osdl, + uint8_t *output, + uint8_t *background, + int width, int xpos, + int scanline ) +{ + int i; + + for( i = 0; i < osdl->numlines && scanline >= 0; i++ ) { + if( scanline < osd_string_get_height( osdl->lines[ i ] ) ) { + osd_string_composite_packed422_scanline( osdl->lines[ i ], + output, background, + width, xpos, scanline ); + } + scanline -= osd_string_get_height( osdl->lines[ i ] ); + } +} diff --git a/src/osdtools.h b/src/osdtools.h index 2bd8ad4..eb002ba 100644 --- a/src/osdtools.h +++ b/src/osdtools.h @@ -39,13 +39,8 @@ typedef struct osd_string_s osd_string_t; typedef struct osd_font_s osd_font_t; typedef struct osd_databars_s osd_databars_t; typedef struct osd_graphic_s osd_graphic_t; -typedef struct osd_shape_s osd_shape_t; typedef struct osd_animation_s osd_animation_t; - -typedef enum OSD_Shapes_e { - OSD_Rect = (1<<0), - OSD_Circle = (1<<1) -} OSD_Shape; +typedef struct osd_list_s osd_list_t; /** * Creates a new string with the given truetype font at the given size. @@ -113,27 +108,6 @@ void osd_databars_composite_packed422_scanline( osd_databars_t *osdd, uint8_t *background, int width ); -osd_shape_t *osd_shape_new( OSD_Shape shape_type, int video_width, - int video_height, int shape_width, - int shape_height, double aspect, int alpha ); - -void osd_shape_delete( osd_shape_t *osds ); -void osd_shape_set_colour( osd_shape_t *osds, int luma, int cb, int cr ); -void osd_shape_show_shape( osd_shape_t *osds, int timeout ); -int osd_shape_visible( osd_shape_t *osds ); -void osd_shape_set_timeout( osd_shape_t *osds, int timeout ); -void osd_shape_advance_frame( osd_shape_t *osds ); -void osd_shape_composite_packed422( osd_shape_t *osds, - uint8_t *output, - int width, int height, int stride, - int xpos, int ypos ); -void osd_shape_composite_packed422_scanline( osd_shape_t *osds, - uint8_t *output, - uint8_t *background, - int width, int xpos, - int scanline ); - - osd_graphic_t *osd_graphic_new( const char *filename, double pixel_aspect, int alpha ); void osd_graphic_delete( osd_graphic_t *osdg ); int osd_graphic_get_width( osd_graphic_t *osdg ); @@ -161,6 +135,22 @@ void osd_animation_composite_packed422_scanline( osd_animation_t *osda, int width, int xpos, int scanline ); +osd_list_t *osd_list_new( double pixel_aspect ); +void osd_list_delete( osd_list_t *osdl ); +int osd_list_get_hilight( osd_list_t *osdl ); +int osd_list_get_numlines( osd_list_t *osdl ); +void osd_list_set_hilight( osd_list_t *osdl, int pos ); +void osd_list_set_text( osd_list_t *osdl, int line, const char *text ); +void osd_list_set_lines( osd_list_t *osdl, int numlines ); +void osd_list_set_timeout( osd_list_t *osdl, int timeout ); +int osd_list_visible( osd_list_t *osdl ); +void osd_list_advance_frame( osd_list_t *osdl ); +void osd_list_composite_packed422_scanline( osd_list_t *osdl, + uint8_t *output, + uint8_t *background, + int width, int xpos, + int scanline ); + #ifdef __cplusplus }; #endif diff --git a/src/tvtimeosd.c b/src/tvtimeosd.c index e2c8a8d..ac5c369 100644 --- a/src/tvtimeosd.c +++ b/src/tvtimeosd.c @@ -64,6 +64,10 @@ struct tvtime_osd_s osd_font_t *bigfont; string_object_t strings[ OSD_MAX_STRING_OBJECTS ]; + osd_list_t *list; + int listpos_x; + int listpos_y; + osd_animation_t *channel_logo; int channel_logo_xpos; int channel_logo_ypos; @@ -114,6 +118,8 @@ tvtime_osd_t *tvtime_osd_new( int width, int height, double pixel_aspect, osd->film_mode = -1; osd->mutestate = 0; osd->hold = 0; + osd->listpos_x = (width * 30) / 100; + osd->listpos_y = (height * 30) / 100; memset( osd->channel_number_text, 0, sizeof( osd->channel_number_text ) ); memset( osd->channel_name_text, 0, sizeof( osd->channel_name_text ) ); @@ -146,6 +152,15 @@ tvtime_osd_t *tvtime_osd_new( int width, int height, double pixel_aspect, return 0; } + osd->list = osd_list_new( pixel_aspect ); + if( !osd->list ) { + osd_font_delete( osd->smallfont ); + osd_font_delete( osd->medfont ); + osd_font_delete( osd->bigfont ); + free( osd ); + return 0; + } + osd->strings[ OSD_CHANNEL_NUM ].rightjustified = 0; osd->strings[ OSD_CHANNEL_NUM ].string = osd_string_new( osd->medfont ); osd->strings[ OSD_CHANNEL_NAME ].rightjustified = 0; @@ -177,7 +192,7 @@ tvtime_osd_t *tvtime_osd_new( int width, int height, double pixel_aspect, osd->strings[ OSD_SHOW_LENGTH ].string = osd_string_new( osd->smallfont ); /* We create the logo, but it's ok if it fails to load. */ - osd->channel_logo = osd_animation_new( logofile, pixel_aspect, 256, 3 ); + osd->channel_logo = osd_animation_new( logofile, pixel_aspect, 256, 4 ); if( !osd->strings[ OSD_CHANNEL_NUM ].string || !osd->strings[ OSD_TIME_STRING ].string || !osd->strings[ OSD_TUNER_INFO ].string || !osd->strings[ OSD_SIGNAL_INFO ].string || @@ -561,6 +576,36 @@ void tvtime_osd_volume_muted( tvtime_osd_t *osd, int mutestate ) osd_string_set_timeout( osd->strings[ OSD_MUTED ].string, osd->mutestate ? 100 : 0 ); } +void tvtime_osd_show_list( tvtime_osd_t *osd, int showlist ) +{ + osd_list_set_timeout( osd->list, OSD_FADE_DELAY ); +} + +int tvtime_osd_list_get_hilight( tvtime_osd_t *osd ) +{ + return osd_list_get_hilight( osd->list ); +} + +int tvtime_osd_list_get_numlines( tvtime_osd_t *osd ) +{ + return osd_list_get_numlines( osd->list ); +} + +void tvtime_osd_list_set_hilight( tvtime_osd_t *osd, int pos ) +{ + osd_list_set_hilight( osd->list, pos ); +} + +void tvtime_osd_list_set_text( tvtime_osd_t *osd, int line, const char *text ) +{ + osd_list_set_text( osd->list, line, text ); +} + +void tvtime_osd_list_set_lines( tvtime_osd_t *osd, int numlines ) +{ + osd_list_set_lines( osd->list, numlines ); +} + void tvtime_osd_advance_frame( tvtime_osd_t *osd ) { char timestamp[ 50 ]; @@ -580,6 +625,8 @@ void tvtime_osd_advance_frame( tvtime_osd_t *osd ) if( osd->channel_logo ) { osd_animation_advance_frame( osd->channel_logo ); } + + osd_list_advance_frame( osd->list ); } void tvtime_osd_composite_packed422_scanline( tvtime_osd_t *osd, @@ -646,5 +693,29 @@ void tvtime_osd_composite_packed422_scanline( tvtime_osd_t *osd, } } } + + if( osd_list_visible( osd->list ) && scanline >= osd->listpos_y ) { + int startx; + int strx = 0; + + startx = osd->listpos_x - xpos; + + if( startx < 0 ) { + strx = -startx; + startx = 0; + } + + /* Make sure we start somewhere even. */ + startx = startx & ~1; + + if( startx < width ) { + osd_list_composite_packed422_scanline( osd->list, + output + (startx*2), + output + (startx*2), + width - startx, + strx, + scanline - osd->listpos_y ); + } + } } diff --git a/src/tvtimeosd.h b/src/tvtimeosd.h index 541282f..3b25685 100644 --- a/src/tvtimeosd.h +++ b/src/tvtimeosd.h @@ -82,6 +82,14 @@ void tvtime_osd_show_data_bar( tvtime_osd_t *osd, const char *barname, int percentage ); void tvtime_osd_show_message( tvtime_osd_t *osd, const char *message ); + +void tvtime_osd_show_list( tvtime_osd_t *osd, int showlist ); +int tvtime_osd_list_get_hilight( tvtime_osd_t *osd ); +int tvtime_osd_list_get_numlines( tvtime_osd_t *osd ); +void tvtime_osd_list_set_hilight( tvtime_osd_t *osd, int pos ); +void tvtime_osd_list_set_text( tvtime_osd_t *osd, int line, const char *text ); +void tvtime_osd_list_set_lines( tvtime_osd_t *osd, int numlines ); + /** * This function must be called every frame to update the state of the OSD. */ |