aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fb-gui.c62
-rw-r--r--fb-gui.h6
-rw-r--r--fbi.c26
-rw-r--r--readers.c2
4 files changed, 38 insertions, 58 deletions
diff --git a/fb-gui.c b/fb-gui.c
index f8447b7..a55026f 100644
--- a/fb-gui.c
+++ b/fb-gui.c
@@ -8,8 +8,11 @@
#include <sys/ioctl.h>
#include <linux/fb.h>
+#include <pixman.h>
+
#include "vt.h"
#include "fbtools.h"
+#include "readers.h"
#include "fb-gui.h"
static int ys = 3;
@@ -25,6 +28,7 @@ static unsigned int *sdirty,swidth,sheight;
static cairo_t *context;
static cairo_surface_t *surface;
+static pixman_image_t *pixman;
static unsigned char *framebuffer;
static cairo_font_extents_t extents;
@@ -106,12 +110,19 @@ void shadow_render(gfxstate *gfx)
void shadow_clear_lines(int first, int last)
{
+#if 0
+ /* FIXME: segfaults */
+ cairo_rectangle(context, 0, first, swidth, last - first + 1);
+ cairo_set_source_rgb(context, 0, 0, 0);
+ cairo_fill(context);
+#else
int i;
for (i = first; i <= last; i++) {
memset(shadow[i],0,4*swidth);
sdirty[i]++;
}
+#endif
}
void shadow_clear(void)
@@ -153,6 +164,9 @@ void shadow_init(gfxstate *gfx)
swidth, sheight,
swidth * 4);
context = cairo_create(surface);
+ pixman = pixman_image_create_bits(PIXMAN_x8r8g8b8, swidth, sheight,
+ (void*)framebuffer, swidth * 4);
+
/* init rendering */
switch (gfx->bits_per_pixel) {
@@ -208,40 +222,28 @@ void shadow_draw_rect(int x1, int x2, int y1, int y2)
shadow_set_dirty_range(y1, (y2 - y1) + 1);
}
-void shadow_draw_rgbdata(int x, int y, int pixels, unsigned char *rgb)
+void shadow_composite_image(struct ida_image *img,
+ int xoff, int yoff, int weight)
{
- unsigned char *dest = shadow[y] + 4*x;
- int i;
-
- for (i = 0; i < pixels; i++) {
- dest[0] = rgb[2];
- dest[1] = rgb[1];
- dest[2] = rgb[0];
- dest += 4;
- rgb += 3;
+ if (weight == 100) {
+ pixman_image_composite(PIXMAN_OP_SRC, img->p, NULL, pixman,
+ 0, 0, 0, 0,
+ xoff, yoff,
+ img->i.width, img->i.height);
+ } else {
+ pixman_color_t color = {
+ .alpha = weight * 0xffff / 100,
+ };
+ pixman_image_t *mask = pixman_image_create_solid_fill(&color);
+
+ pixman_image_composite(PIXMAN_OP_OVER, img->p, mask, pixman,
+ 0, 0, 0, 0,
+ xoff, yoff,
+ img->i.width, img->i.height);
+ pixman_image_unref(mask);
}
- sdirty[y]++;
}
-void shadow_merge_rgbdata(int x, int y, int pixels, int weight,
- unsigned char *rgb)
-{
- unsigned char *dest = shadow[y] + 4*x;
- int i;
-
- weight = weight * 256 / 100;
-
- for (i = 0; i < pixels; i++) {
- dest[0] += rgb[2] * weight >> 8;
- dest[1] += rgb[1] * weight >> 8;
- dest[2] += rgb[0] * weight >> 8;
- dest += 4;
- rgb += 3;
- }
- sdirty[y]++;
-}
-
-
void shadow_darkify(int x1, int x2, int y1,int y2, int percent)
{
cairo_rectangle(context, x1, y1,
diff --git a/fb-gui.h b/fb-gui.h
index 3bb1eba..3d9bd6d 100644
--- a/fb-gui.h
+++ b/fb-gui.h
@@ -12,10 +12,8 @@ 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_merge_rgbdata(int x, int y, int pixels, int weight,
- unsigned char *rgb);
+void shadow_composite_image(struct ida_image *img,
+ int xoff, int yoff, int weight);
void shadow_darkify(int x1, int x2, int y1,int y2, int percent);
int shadow_draw_string(int x, int y, char *str, int align);
diff --git a/fbi.c b/fbi.c
index b40010c..6111641 100644
--- a/fbi.c
+++ b/fbi.c
@@ -365,41 +365,21 @@ static void
shadow_draw_image(struct ida_image *img, int xoff, int yoff,
unsigned int first, unsigned int last, int weight)
{
- unsigned int dwidth = MIN(img->i.width, gfx->hdisplay);
- unsigned int dheight = MIN(img->i.height, gfx->vdisplay);
- unsigned int data, offset, y, xs, ys;
+ unsigned int xs, ys;
if (100 == weight)
shadow_clear_lines(first, last);
else
shadow_darkify(0, gfx->hdisplay-1, first, last, 100 - weight);
- /* offset for image data (image > screen, select visible area) */
- offset = (yoff * img->i.width + xoff) * 3;
-
- /* offset for video memory (image < screen, center image) */
+ /* image < screen: center image */
xs = 0, ys = 0;
if (img->i.width < gfx->hdisplay)
xs += (gfx->hdisplay - img->i.width) / 2;
if (img->i.height < gfx->vdisplay)
ys += (gfx->vdisplay - img->i.height) / 2;
- /* go ! */
- for (data = 0, y = 0;
- data < img->i.width * img->i.height * 3
- && data / img->i.width / 3 < dheight;
- data += img->i.width * 3, y++) {
- if (ys+y < first)
- continue;
- if (ys+y > last)
- continue;
- if (100 == weight)
- shadow_draw_rgbdata(xs, ys+y, dwidth,
- ida_image_scanline(img, y) + offset);
- else
- shadow_merge_rgbdata(xs, ys+y, dwidth, weight,
- ida_image_scanline(img, y) + offset);
- }
+ shadow_composite_image(img, xs - xoff, ys - yoff, weight);
}
static void status_prepare(void)
diff --git a/readers.c b/readers.c
index 4fd09fc..24cb818 100644
--- a/readers.c
+++ b/readers.c
@@ -130,7 +130,7 @@ int load_free_extras(struct ida_image_info *info)
void ida_image_alloc(struct ida_image *img)
{
assert(img->p == NULL);
- img->p = pixman_image_create_bits(PIXMAN_r8g8b8,
+ img->p = pixman_image_create_bits(/* PIXMAN_r8g8b8 */ PIXMAN_b8g8r8,
img->i.width, img->i.height, NULL, 0);
}