From 9f0a1cde48c2e0ed9365e28291bba1260e5ac7b2 Mon Sep 17 00:00:00 2001 From: reinelt <> Date: Sun, 19 Feb 2006 07:20:54 +0000 Subject: [lcd4linux @ 2006-02-19 07:20:53 by reinelt] image support nearly finished --- drv_generic_graphic.c | 14 ++++++-- lcd4linux.conf.sample | 7 ++-- widget_image.c | 96 ++++++++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 102 insertions(+), 15 deletions(-) diff --git a/drv_generic_graphic.c b/drv_generic_graphic.c index 92b5a45..1836a34 100644 --- a/drv_generic_graphic.c +++ b/drv_generic_graphic.c @@ -23,6 +23,9 @@ * * * $Log: drv_generic_graphic.c,v $ + * Revision 1.21 2006/02/19 07:20:53 reinelt + * image support nearly finished + * * Revision 1.20 2006/02/08 04:55:05 reinelt * moved widget registration to drv_generic_graphic * @@ -536,13 +539,18 @@ int drv_generic_graphic_image_draw(WIDGET * W) col = W->col; width = Image->width; height = Image->height; - + /* sanity check */ if (layer < 0 || layer >= LAYERS) { error("%s: layer %d out of bounds (0..%d)", Driver, layer, LAYERS - 1); return -1; } + /* if no size or no image at all, do nothing */ + if (width <= 0 || height <= 0 || Image->bitmap == NULL) { + return 0; + } + /* maybe grow layout framebuffer */ drv_generic_graphic_resizeFB(row + height, col + width); @@ -550,8 +558,8 @@ int drv_generic_graphic_image_draw(WIDGET * W) for (y = 0; y < height; y++) { for (x = 0; x < width; x++) { int i = (row + y) * LCOLS + col + x; - if (Image->visible && Image->bitmap) { - drv_generic_graphic_FB[layer][i] = Image->bitmap[y*width+x]; + if (Image->visible) { + drv_generic_graphic_FB[layer][i] = Image->bitmap[y * width + x]; } else { drv_generic_graphic_FB[layer][i] = BG_COL; } diff --git a/lcd4linux.conf.sample b/lcd4linux.conf.sample index ba334b9..d6fd9cc 100644 --- a/lcd4linux.conf.sample +++ b/lcd4linux.conf.sample @@ -808,6 +808,7 @@ Widget GPO_Test255 { Widget ImageTest { class 'Image' + file '/home/michi/lcd4linux.png' update 1000 visible 1 } @@ -865,7 +866,7 @@ Layout TestLayer { Col11 'Eth0Bar' } Layer 2 { - X0.Y0 'ImageTest' + X1.Y1 'ImageTest' } } @@ -980,8 +981,8 @@ Layout testMySQL { #Display 'SimpleLCD' #Display 'BA63' #Display 'CT20x4' -Display 'T6963-240x64' -#Display 'XWindow' +#Display 'T6963-240x64' +Display 'XWindow' #Display 'USBLCD' #Display 'BWCT' #Display 'Image' diff --git a/widget_image.c b/widget_image.c index 6c510e7..1cd17f6 100644 --- a/widget_image.c +++ b/widget_image.c @@ -1,4 +1,4 @@ -/* $Id: widget_image.c,v 1.3 2006/02/08 04:55:05 reinelt Exp $ +/* $Id: widget_image.c,v 1.4 2006/02/19 07:20:54 reinelt Exp $ * * image widget handling * @@ -21,6 +21,9 @@ * * * $Log: widget_image.c,v $ + * Revision 1.4 2006/02/19 07:20:54 reinelt + * image support nearly finished + * * Revision 1.3 2006/02/08 04:55:05 reinelt * moved widget registration to drv_generic_graphic * @@ -47,6 +50,7 @@ #include #include #include +#include #include "debug.h" #include "cfg.h" @@ -55,6 +59,7 @@ #include "timer.h" #include "widget.h" #include "widget_image.h" +#include "rgb.h" #ifdef HAVE_GD_GD_H #include @@ -70,13 +75,85 @@ #include #endif -static void widget_image_render (WIDGET_IMAGE *Image) -{ - /* try to open file */ +#ifdef WITH_GD +static void widget_image_render(const char *Name, WIDGET_IMAGE * Image) +{ + int x, y; + FILE *fd; + gdImagePtr gdImage = NULL; + + /* clear bitmap */ + if (Image->bitmap) { + int i; + for (i = 0; i < Image->height * Image->width; i++) { + RGBA empty = { R: 0x00, G: 0x00, B: 0x00, A:0x00 }; + Image->bitmap[i] = empty; + } + } + if (Image->file == NULL || Image->file[0] == '\0') { + error("Warning: Image %s has no file", Name); + return; + } + + fd = fopen(Image->file, "rb"); + if (fd == NULL) { + error("Warning: Image %s: fopen(%s) failed: %s", Name, Image->file, strerror(errno)); + return; + } + + gdImage = gdImageCreateFromPng(fd); + fclose(fd); + + if (fd == NULL) { + error("Warning: Image %s: CreateFromPng(%s) failed!", Name, Image->file); + return; + } + + /* maybe resize bitmap */ + if (gdImage->sx > Image->width) { + Image->width = gdImage->sx; + if (Image->bitmap) + free(Image->bitmap); + Image->bitmap = NULL; + } + if (gdImage->sy > Image->height) { + Image->height = gdImage->sy; + if (Image->bitmap) + free(Image->bitmap); + Image->bitmap = NULL; + } + if (Image->bitmap == NULL && Image->width > 0 && Image->height > 0) { + int i = Image->width * Image->height * sizeof(Image->bitmap[0]); + Image->bitmap = malloc(i); + if (Image->bitmap == NULL) { + error("Warning: Image %s: malloc(%d) failed!", Name, i, strerror(errno)); + return; + } + for (i = 0; i < Image->height * Image->width; i++) { + RGBA empty = { R: 0x00, G: 0x00, B: 0x00, A:0x00 }; + Image->bitmap[i] = empty; + } + } + + /* finally really render it */ + for (x=0; x < gdImage->sx; x++) { + for (y=0; y < gdImage->sy; y++) { + int p = gdImageGetTrueColorPixel (gdImage, x, y); + int a = gdTrueColorGetAlpha(p); + int i = y*Image->width+x; + Image->bitmap[i].R = gdTrueColorGetRed(p); + Image->bitmap[i].G = gdTrueColorGetGreen (p); + Image->bitmap[i].B = gdTrueColorGetBlue(p); + /* GD's alpha is 0 (opaque) to 127 (tranparanet) */ + /* our alpha is 0 (transparent) to 255 (opaque) */ + Image->bitmap[i].A = (a == 127) ? 0 : 255-2*a; + } } } +#endif + static void widget_image_update(void *Self) { @@ -89,7 +166,7 @@ static void widget_image_update(void *Self) /* evaluate expressions */ if (Image->file) { - free (Image->file); + free(Image->file); Image->file = NULL; } if (Image->file_tree != NULL) { @@ -115,12 +192,13 @@ static void widget_image_update(void *Self) Image->visible = 0; DelResult(&result); } - + +#ifdef WITH_GD /* render image into bitmap */ - widget_image_render(Image); - } + widget_image_render(W->name, Image); +#endif - error ("Fixme: We are at image_update"); + } /* finally, draw it! */ if (W->class->draw) -- cgit v1.2.3