aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fb-gui.c56
-rw-r--r--fb-gui.h5
-rw-r--r--fbi.c69
3 files changed, 102 insertions, 28 deletions
diff --git a/fb-gui.c b/fb-gui.c
index 0ff952b..7f87156 100644
--- a/fb-gui.c
+++ b/fb-gui.c
@@ -344,6 +344,17 @@ void shadow_draw_rgbdata(int x, int y, int pixels, unsigned char *rgb)
sdirty[y]++;
}
+void shadow_merge_rgbdata(int x, int y, int pixels, int weight,
+ unsigned char *rgb)
+{
+ unsigned char *dest = shadow[y] + 3*x;
+ int i = 3*pixels;
+
+ while (i-- > 0)
+ *(dest++) += *(rgb++) * weight / 100;
+ sdirty[y]++;
+}
+
void shadow_darkify(int x1, int x2, int y1,int y2, int percent)
{
@@ -354,22 +365,25 @@ void shadow_darkify(int x1, int x2, int y1,int y2, int percent)
h = x2, x2 = x1, x1 = h;
if (y2 < y1)
h = y2, y2 = y1, y1 = h;
+
+ if (x1 < 0)
+ x1 = 0;
+ if (x2 >= swidth)
+ x2 = swidth;
+
+ if (y1 < 0)
+ y1 = 0;
+ if (y2 >= sheight)
+ y2 = sheight;
for (y = y1; y <= y2; y++) {
- if (y < 0)
- continue;
- if (y >= sheight)
- continue;
sdirty[y]++;
ptr = shadow[y];
- for (x = x1; x <= x2; x++) {
- if (x < 0)
- continue;
- if (x >= swidth)
- continue;
- ptr[3*x+0] = ptr[3*x+0] * percent / 100;
- ptr[3*x+1] = ptr[3*x+1] * percent / 100;
- ptr[3*x+2] = ptr[3*x+2] * percent / 100;
+ ptr += 3*x1;
+ x = 3*(x2-x1+1);
+ while (x-- > 0) {
+ *ptr = *ptr * percent / 100;
+ ptr++;
}
}
}
@@ -384,18 +398,20 @@ void shadow_reverse(int x1, int x2, int y1,int y2)
if (y2 < y1)
h = y2, y2 = y1, y1 = h;
+ if (x1 < 0)
+ x1 = 0;
+ if (x2 >= swidth)
+ x2 = swidth;
+
+ if (y1 < 0)
+ y1 = 0;
+ if (y2 >= sheight)
+ y2 = sheight;
+
for (y = y1; y <= y2; y++) {
- if (y < 0)
- continue;
- if (y >= sheight)
- continue;
sdirty[y]++;
ptr = shadow[y];
for (x = x1; x <= x2; x++) {
- if (x < 0)
- continue;
- if (x >= swidth)
- continue;
ptr[3*x+0] = 255-ptr[3*x+0];
ptr[3*x+1] = 255-ptr[3*x+1];
ptr[3*x+2] = 255-ptr[3*x+2];
diff --git a/fb-gui.h b/fb-gui.h
index 351f866..842a511 100644
--- a/fb-gui.h
+++ b/fb-gui.h
@@ -14,7 +14,10 @@ void shadow_fini(void);
void shadow_draw_line(int x1, int x2, int y1,int y2);
void shadow_draw_rect(int x1, int x2, int y1,int y2);
-void shadow_draw_rgbdata(int x, int y, int pixels, unsigned char *rgb);
+void shadow_draw_rgbdata(int x, int y, int pixels,
+ unsigned char *rgb);
+void shadow_merge_rgbdata(int x, int y, int pixels, int weight,
+ unsigned char *rgb);
void shadow_darkify(int x1, int x2, int y1,int y2, int percent);
void shadow_reverse(int x1, int x2, int y1,int y2);
diff --git a/fbi.c b/fbi.c
index ad3b690..40353aa 100644
--- a/fbi.c
+++ b/fbi.c
@@ -336,13 +336,16 @@ static void flist_print_tagged(FILE *fp)
static void
shadow_draw_image(struct ida_image *img, int xoff, int yoff,
- unsigned int first, unsigned int last)
+ unsigned int first, unsigned int last, int weight)
{
unsigned int dwidth = MIN(img->i.width, fb_var.xres);
unsigned int dheight = MIN(img->i.height, fb_var.yres);
unsigned int data, offset, y, xs, ys;
- shadow_clear_lines(first, last);
+ if (100 == weight)
+ shadow_clear_lines(first, last);
+ else
+ shadow_darkify(0, fb_var.xres, first, last, 100 - weight);
/* offset for image data (image > screen, select visible area) */
offset = (yoff * img->i.width + xoff) * 3;
@@ -363,7 +366,12 @@ shadow_draw_image(struct ida_image *img, int xoff, int yoff,
continue;
if (ys+y > last)
continue;
- shadow_draw_rgbdata(xs, ys+y, dwidth, img->data + data + offset);
+ if (100 == weight)
+ shadow_draw_rgbdata(xs, ys+y, dwidth,
+ img->data + data + offset);
+ else
+ shadow_merge_rgbdata(xs, ys+y, dwidth, weight,
+ img->data + data + offset);
}
}
@@ -374,7 +382,7 @@ static void status_prepare(void)
int y2 = fb_var.yres - 1;
if (img) {
- shadow_draw_image(img, fcurrent->left, fcurrent->top, y1, y2);
+ shadow_draw_image(img, fcurrent->left, fcurrent->top, y1, y2, 100);
shadow_darkify(0, fb_var.xres-1, y1, y2, transparency);
} else {
shadow_clear_lines(y1, y2);
@@ -734,8 +742,47 @@ static float auto_scale(struct ida_image *img)
/* ---------------------------------------------------------------------- */
+static void effect_blend(struct flist *f, struct flist *t)
+{
+ static int duration = 300; /* msecs */
+ struct timeval start, now;
+ int msecs, weight = 0;
+
+#if 0
+ char linebuffer[80];
+ int pos = 0;
+#endif
+
+ gettimeofday(&start, NULL);
+ do {
+ gettimeofday(&now, NULL);
+ msecs = (now.tv_sec - start.tv_sec) * 1000;
+ msecs += (now.tv_usec - start.tv_usec) / 1000;
+ weight = msecs * 100 / duration;
+ if (weight > 100)
+ weight = 100;
+ shadow_draw_image(flist_img_get(f), f->left, f->top,
+ 0, fb_var.yres-1, 100);
+ shadow_draw_image(flist_img_get(t), t->left, t->top,
+ 0, fb_var.yres-1, weight);
+
+#if 0
+ pos += snprintf(linebuffer+pos, sizeof(linebuffer)-pos,
+ " %d%%", weight);
+ status_update(linebuffer, NULL);
+#endif
+
+ shadow_render();
+ } while (weight < 100);
+
+#if 0
+ sleep(1);
+#endif
+}
+
static int
-svga_show(struct flist *f, int timeout, char *desc, char *info, int *nr)
+svga_show(struct flist *f, struct flist *prev,
+ int timeout, char *desc, char *info, int *nr)
{
static int paused = 0, skip = KEY_SPACE;
@@ -772,7 +819,12 @@ svga_show(struct flist *f, int timeout, char *desc, char *info, int *nr)
if (f->left + fb_var.xres > img->i.width)
f->left = img->i.width - fb_var.xres;
}
- shadow_draw_image(img, f->left, f->top, 0, fb_var.yres-1);
+ if (prev && prev != f) {
+ effect_blend(prev, f);
+ prev = NULL;
+ } else {
+ shadow_draw_image(img, f->left, f->top, 0, fb_var.yres-1, 100);
+ }
status_update(desc, info);
shadow_render();
@@ -1315,6 +1367,7 @@ main(int argc, char *argv[])
int i, arg, key;
char *info, *desc, *filelist;
char linebuffer[128];
+ struct flist *fprev = NULL;
#if 0
/* debug aid, to attach gdb ... */
@@ -1413,7 +1466,9 @@ main(int argc, char *argv[])
info = make_info(fcurrent->fimg, fcurrent->scale);
}
- switch (key = svga_show(fcurrent, timeout, desc, info, &arg)) {
+ key = svga_show(fcurrent, fprev, timeout, desc, info, &arg);
+ fprev = fcurrent;
+ switch (key) {
case KEY_DELETE:
if (editable) {
struct flist *fdel = fcurrent;