From: Charlie Brej Date: Wed, 13 May 2009 12:11:36 +0000 (+0100) Subject: [two-step] Add merge-fade as a progress animation transition type X-Git-Tag: 0.7.0~170 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=c03d816ebebaabce9a9958a453d8896a33ff1839;p=thirdparty%2Fplymouth.git [two-step] Add merge-fade as a progress animation transition type The merge fade merges the two frames before drawing them to the framebuffer. This makes a smooth transition between areas with partly transparent pixels or areas in later frames becoming trasparent. This is set as the default on the "glow" theme. --- diff --git a/src/libplybootsplash/ply-progress-animation.c b/src/libplybootsplash/ply-progress-animation.c index 9f3fbf2f..42db34ec 100644 --- a/src/libplybootsplash/ply-progress-animation.c +++ b/src/libplybootsplash/ply-progress-animation.c @@ -147,6 +147,51 @@ draw_background (ply_progress_animation_t *progress_animation) progress_animation->frame_area.height); } +static uint32_t* +image_fade_merge(ply_image_t* frame0, ply_image_t* frame1, float fade, int width, int height) +{ + int frame0_width = ply_image_get_width (frame0); + int frame0_height = ply_image_get_height (frame0); + int frame1_width = ply_image_get_width (frame1); + int frame1_height = ply_image_get_height (frame1); + + uint32_t *frame0_data = ply_image_get_data (frame0); + uint32_t *frame1_data = ply_image_get_data (frame1); + + uint32_t *reply_data = malloc (width * height * sizeof (uint32_t)); + int x, y, i; + + + for (y = 0; y < height; y++) + { + for (x = 0; x < width; x++) + { + uint32_t pixel0, pixel1, pixelout; + + if (y < frame0_height && x < frame0_width) + pixel0 = frame0_data[y*frame0_width+x]; + else + pixel0 = 0; + + if (y < frame1_height && x < frame1_width) + pixel1 = frame1_data[y*frame1_width+x]; + else + pixel1 = 0; + + pixelout = 0; + for (i = 0; i < 4; i++) + { + int subval0 = (pixel0 >> (i * 8)) & 0xFF; + int subval1 = (pixel1 >> (i * 8)) & 0xFF; + int subvalout = subval0 * (1-fade) + subval1 * fade; + pixelout |= (subvalout & 0xFF) << (i * 8); + } + reply_data[y*width+x] = pixelout; + } + } + return reply_data; +} + void ply_progress_animation_draw (ply_progress_animation_t *progress_animation) { @@ -183,8 +228,6 @@ ply_progress_animation_draw (ply_progress_animation_t *progress_animation) progress_animation->frame_area.x = progress_animation->area.x; progress_animation->frame_area.y = progress_animation->area.y; - progress_animation->frame_area.width = ply_image_get_width (frames[frame_number]); - progress_animation->frame_area.height = ply_image_get_height (frames[frame_number]); frame_data = ply_image_get_data (frames[frame_number]); if (progress_animation->is_transitioning) @@ -192,6 +235,8 @@ ply_progress_animation_draw (ply_progress_animation_t *progress_animation) double now; double fade_percentage; double fade_out_opacity; + int width, height; + uint32_t* faded_data; now = ply_get_timestamp (); fade_percentage = (now - progress_animation->transition_start_time) / progress_animation->transition_duration; @@ -201,20 +246,50 @@ ply_progress_animation_draw (ply_progress_animation_t *progress_animation) fade_percentage = CLAMP (fade_percentage, 0.0, 1.0); previous_frame_data = ply_image_get_data (frames[frame_number - 1]); - if (progress_animation->transition == PLY_PROGRESS_ANIMATION_TRANSITION_FADE_OVER) - fade_out_opacity = 1.0; + if (progress_animation->transition == PLY_PROGRESS_ANIMATION_TRANSITION_MERGE_FADE) + { + width = MAX(ply_image_get_width (frames[frame_number]), ply_image_get_width (frames[frame_number - 1])); + height = MAX(ply_image_get_height (frames[frame_number]), ply_image_get_width (frames[frame_number - 1])); + progress_animation->frame_area.width = width; + progress_animation->frame_area.height = height; + + faded_data = image_fade_merge(frames[frame_number - 1], frames[frame_number], fade_percentage, width, height); + + ply_frame_buffer_fill_with_argb32_data_at_opacity (progress_animation->frame_buffer, + &progress_animation->frame_area, 0, 0, + faded_data, 1.0); + free(faded_data); + } else - fade_out_opacity = 1.0 - fade_percentage; - - ply_frame_buffer_fill_with_argb32_data_at_opacity (progress_animation->frame_buffer, - &progress_animation->frame_area, 0, 0, - previous_frame_data, fade_out_opacity); - ply_frame_buffer_fill_with_argb32_data_at_opacity (progress_animation->frame_buffer, - &progress_animation->frame_area, 0, 0, - frame_data, fade_percentage); + { + if (progress_animation->transition == PLY_PROGRESS_ANIMATION_TRANSITION_FADE_OVER) + fade_out_opacity = 1.0; + else + fade_out_opacity = 1.0 - fade_percentage; + + progress_animation->frame_area.width = ply_image_get_width (frames[frame_number - 1]); + progress_animation->frame_area.height = ply_image_get_height (frames[frame_number - 1]); + ply_frame_buffer_fill_with_argb32_data_at_opacity (progress_animation->frame_buffer, + &progress_animation->frame_area, 0, 0, + previous_frame_data, fade_out_opacity); + + progress_animation->frame_area.width = ply_image_get_width (frames[frame_number]); + progress_animation->frame_area.height = ply_image_get_height (frames[frame_number]); + ply_frame_buffer_fill_with_argb32_data_at_opacity (progress_animation->frame_buffer, + &progress_animation->frame_area, 0, 0, + frame_data, fade_percentage); + + width = MAX(ply_image_get_width (frames[frame_number]), ply_image_get_width (frames[frame_number - 1])); + height = MAX(ply_image_get_height (frames[frame_number]), ply_image_get_width (frames[frame_number - 1])); + progress_animation->frame_area.width = width; + progress_animation->frame_area.height = height; + } + } else { + progress_animation->frame_area.width = ply_image_get_width (frames[frame_number]); + progress_animation->frame_area.height = ply_image_get_height (frames[frame_number]); ply_frame_buffer_fill_with_argb32_data (progress_animation->frame_buffer, &progress_animation->frame_area, 0, 0, frame_data); diff --git a/src/libplybootsplash/ply-progress-animation.h b/src/libplybootsplash/ply-progress-animation.h index f199187f..3c51d10f 100644 --- a/src/libplybootsplash/ply-progress-animation.h +++ b/src/libplybootsplash/ply-progress-animation.h @@ -36,6 +36,7 @@ typedef enum PLY_PROGRESS_ANIMATION_TRANSITION_NONE, PLY_PROGRESS_ANIMATION_TRANSITION_FADE_OVER, PLY_PROGRESS_ANIMATION_TRANSITION_CROSS_FADE, + PLY_PROGRESS_ANIMATION_TRANSITION_MERGE_FADE, } ply_progress_animation_transition_t; #ifndef PLY_HIDE_FUNCTION_DECLARATIONS diff --git a/src/plugins/splash/two-step/plugin.c b/src/plugins/splash/two-step/plugin.c index 88f2355a..68d75ad9 100644 --- a/src/plugins/splash/two-step/plugin.c +++ b/src/plugins/splash/two-step/plugin.c @@ -165,6 +165,8 @@ create_plugin (ply_key_file_t *key_file) plugin->transition = PLY_PROGRESS_ANIMATION_TRANSITION_FADE_OVER; else if (strcmp (transition, "cross-fade") == 0) plugin->transition = PLY_PROGRESS_ANIMATION_TRANSITION_CROSS_FADE; + else if (strcmp (transition, "merge-fade") == 0) + plugin->transition = PLY_PROGRESS_ANIMATION_TRANSITION_MERGE_FADE; } free (transition); diff --git a/themes/glow/glow.plymouth.in b/themes/glow/glow.plymouth.in index 73694910..b3c4372c 100644 --- a/themes/glow/glow.plymouth.in +++ b/themes/glow/glow.plymouth.in @@ -7,5 +7,5 @@ ModuleName=two-step ImageDir=@PLYMOUTH_THEME_PATH@/glow HorizontalAlignment=.25 VerticalAlignment=.5 -Transition=fade-over +Transition=merge-fade TransitionDuration=.5