From: GetAway Date: Thu, 12 Jan 2017 20:45:16 +0000 (+0100) Subject: input 2.0: add png support X-Git-Url: https://git.webhop.me/?a=commitdiff_plain;h=ef6e1f8206daab7052ad5a9e8b37cb29d1c51a35;p=input.git input 2.0: add png support - add shadow - use neutrino font file - k=1 shows PNG Keyboard-layout, k=2 the old graphic --- diff --git a/fb_display.c b/fb_display.c new file mode 100644 index 0000000..dbf7fca --- /dev/null +++ b/fb_display.c @@ -0,0 +1,159 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * +*/ + +//#include "config.h" +#include +#include +#include "text.h" +#include "io.h" +#include "gfx.h" +#include "fb_display.h" + +extern unsigned int alpha; + +void blit2FB(void *fbbuff, + uint32_t width, uint32_t height, + uint32_t xoffs, uint32_t yoffs, + uint32_t xp, uint32_t yp, + int cpp); + +void fb_display(unsigned char *rgbbuff, int x_size, int y_size, int x_pan, int y_pan, int x_offs, int y_offs, int clearflag, int alpha) +{ + void *fbbuff = NULL; + int bp = 0; + if(rgbbuff==NULL) + return; + + /* correct panning */ + if(x_pan > x_size - (int)var_screeninfo.xres) x_pan = 0; + if(y_pan > y_size - (int)var_screeninfo.yres) y_pan = 0; + /* correct offset */ + if(x_offs + x_size > (int)var_screeninfo.xres) x_offs = 0; + if(y_offs + y_size > (int)var_screeninfo.yres) y_offs = 0; + + /* blit buffer 2 fb */ + fbbuff = convertRGB2FB(rgbbuff, x_size * y_size, var_screeninfo.bits_per_pixel, &bp, alpha); + if(fbbuff==NULL) + return; + /* ClearFB if image is smaller */ + if(clearflag) + clearFB(); + blit2FB(fbbuff, x_size, y_size, x_offs, y_offs, x_pan, y_pan, bp); + free(fbbuff); +} + +void blit2FB(void *fbbuff, + uint32_t width, uint32_t height, + uint32_t xoffs, uint32_t yoffs, + uint32_t xp, uint32_t yp, + int cpp) +{ + int count, count2, xc, yc; + + int ssx=startx+xoffs; + int ssy=starty+yoffs; + + xc = (width > var_screeninfo.xres) ? var_screeninfo.xres : width; + yc = (height > var_screeninfo.yres) ? var_screeninfo.yres : height; + + int xo = (ssx/*xoffs*/ * cpp)/sizeof(uint32_t); + + switch(cpp){ + case 4: + { + uint32_t * data = (uint32_t *) fbbuff; + + uint32_t * d = (uint32_t *)lbb + xo + stride * ssy/*yoffs*/; + uint32_t * d2; + + for (count = 0; count < yc; count++ ) { + uint32_t *pixpos = &data[(count + yp) * width]; + d2 = (uint32_t *) d; + for (count2 = 0; count2 < xc; count2++ ) { + uint32_t pix = *(pixpos + xp); + if ((pix & 0xff000000) == 0xff000000) + *d2 = pix; + else { + uint8_t *in = (uint8_t *)(pixpos + xp); + uint8_t *out = (uint8_t *)d2; + int a = in[3]; /* TODO: big/little endian */ + *out = (*out + ((*in - *out) * a) / 256); + in++; out++; + *out = (*out + ((*in - *out) * a) / 256); + in++; out++; + *out = (*out + ((*in - *out) * a) / 256); + } + d2++; + pixpos++; + } + d += stride; + } + } + break; + } +} + +void clearFB() +{ + memset(lbb, 0, var_screeninfo.xres*var_screeninfo.yres*sizeof(uint32_t)); + memcpy(lfb, lbb, var_screeninfo.xres*var_screeninfo.yres*sizeof(uint32_t)); +} + +void* convertRGB2FB(unsigned char *rgbbuff, unsigned long count, int bpp, int *cpp, int alpha) +{ + unsigned long i; + unsigned int *fbbuff = NULL; + + switch(bpp) + { + case 24: + case 32: + *cpp = 4; + fbbuff = (unsigned int *) malloc(count * sizeof(unsigned int)); + if(fbbuff==NULL) + { + printf("Error: malloc\n"); + return NULL; + } + if(alpha) { + for(i = 0; i < count ; i++) { + fbbuff[i] = ((rgbbuff[i*4+3] << 24) & 0xFF000000) | + ((rgbbuff[i*4] << 16) & 0x00FF0000) | + ((rgbbuff[i*4+1] << 8) & 0x0000FF00) | + ((rgbbuff[i*4+2]) & 0x000000FF); + } + } + else + { + int transp; + for(i = 0; i < count ; i++) { + transp = 0; + if(rgbbuff[i*3] || rgbbuff[i*3+1] || rgbbuff[i*3+2]) + transp = 0xFF; + fbbuff[i] = (transp << 24) | + ((rgbbuff[i*3] << 16) & 0xFF0000) | + ((rgbbuff[i*3+1] << 8) & 0xFF00) | + (rgbbuff[i*3+2] & 0xFF); + } + } + break; + default: + fprintf(stderr, "Unsupported video mode! You've got: %dbpp\n", bpp); + exit(1); + } + return (void *)fbbuff; +} diff --git a/fb_display.h b/fb_display.h new file mode 100644 index 0000000..87ab753 --- /dev/null +++ b/fb_display.h @@ -0,0 +1,26 @@ +/* + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * +*/ + +#ifndef __pictureviewer_fbdisplay__ +#define __pictureviewer_fbdisplay__ + +void* convertRGB2FB(unsigned char *rgbbuff, unsigned long count, int bpp, int *cpp, int alpha); +void fb_display(unsigned char *rgbbuff, int x_size, int y_size, int x_pan, int y_pan, int x_offs, int y_offs, int clearflag, int alpha); +void clearFB(); + +#endif diff --git a/gfx.c b/gfx.c index f84aaf0..1b99266 100644 --- a/gfx.c +++ b/gfx.c @@ -2,31 +2,12 @@ #include "current.h" #include "input.h" +#include "gfx.h" +#include "resize.h" +#include "pngw.h" +#include "fb_display.h" -char circle[] = -{ - 0,0,2,2,2,2,2,2,2,2,2,2,2,2,0,0, - 0,2,1,1,1,1,1,1,1,1,1,1,1,1,2,0, - 2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2, - 2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2, - 2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2, - 2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2, - 2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2, - 2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2, - 2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2, - 2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2, - 2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2, - 2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2, - 2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2, - 2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2, - 0,2,1,1,1,1,1,1,1,1,1,1,1,1,2,0, - 0,0,2,2,2,2,2,2,2,2,2,2,2,2,0,0 -}; - -size_t GetCircleHeight() -{ - return sqrt(sizeof(circle)); -} +extern const char NOMEM[]; void RenderBox(int _sx, int _sy, int _ex, int _ey, int rad, int col) { @@ -124,21 +105,84 @@ void RenderBox(int _sx, int _sy, int _ex, int _ey, int rad, int col) } /****************************************************************************** - * RenderCircle + * PaintIcon ******************************************************************************/ -void RenderCircle(int _sx, int _sy, int col) +int paintIcon(const char *const fname, int xstart, int ystart, int xsize, int ysize, int *iw, int *ih) { - int x, y; - uint32_t pix = bgra[col]; - uint32_t *p = lbb + startx + _sx; - int s = stride * (starty + _sy /*+ y*/); - int h = GetCircleHeight(); - - for(y = 0; y < h * h; y += h, s += stride) - for(x = 0; x < h; x++) - switch(circle[x + y]) { - case 1: *(p + x + s) = pix; break; - case 2: *(p + x + s) = 0xFFFFFFFF; break; - } +FILE *tfh; +int x1, y1, rv=-1, alpha=0, bpp=0; + +int imx,imy,dxo,dyo,dxp,dyp; +unsigned char *buffer=NULL; + + if((tfh=fopen(fname,"r"))!=NULL) + { + if(png_getsize(fname, &x1, &y1)) + { + perror(__plugin__ " \n"); + fclose(tfh); + return -1; + } + // no resize + if (xsize == 0 || ysize ==0) + { + xsize = x1; + ysize = y1; + } + if((buffer=(unsigned char *) malloc(x1*y1*4))==NULL) + { + printf(NOMEM); + fclose(tfh); + return -1; + } + + if(!(rv=png_load(fname, &buffer, &x1, &y1, &bpp))) + { + alpha=(bpp==4)?1:0; + scale_pic(&buffer,x1,y1,xstart,ystart,xsize,ysize,&imx,&imy,&dxp,&dyp,&dxo,&dyo,alpha); + + fb_display(buffer, imx, imy, dxp, dyp, dxo, dyo, 0, alpha); + } + free(buffer); + fclose(tfh); + } + *iw = imx; + *ih = imy; + return (rv)?-1:0; +} + +void scale_pic(unsigned char **buffer, int x1, int y1, int xstart, int ystart, int xsize, int ysize, + int *imx, int *imy, int *dxp, int *dyp, int *dxo, int *dyo, int alpha) +{ + float xfact=0, yfact=0; + int txsize=0, tysize=0; + int txstart =xstart, tystart= ystart; + + if (xsize > (ex-xstart)) txsize= (ex-xstart); + else txsize= xsize; + if (ysize > (ey-ystart)) tysize= (ey-ystart); + else tysize=ysize; + xfact= 1000*txsize/x1; + xfact= xfact/1000; + yfact= 1000*tysize/y1; + yfact= yfact/1000; + + if ( xfact <= yfact) + { + *imx=(int)x1*xfact; + *imy=(int)y1*xfact; + } + else + { + *imx=(int)x1*yfact; + *imy=(int)y1*yfact; + } + if ((x1 != *imx) || (y1 != *imy)) + *buffer=color_average_resize(*buffer,x1,y1,*imx,*imy,alpha); + + *dxp=0; + *dyp=0; + *dxo=txstart; + *dyo=tystart; } diff --git a/gfx.h b/gfx.h index d674c23..24b9e56 100644 --- a/gfx.h +++ b/gfx.h @@ -2,7 +2,8 @@ #define __GFX_H__ void RenderBox(int sx, int sy, int ex, int ey, int rad, int col); -void RenderCircle(int _sx, int _sy, int col); -size_t GetCircleHeight(); +int paintIcon(const char *const fname, int xstart, int ystart, int xsize, int ysize, int *iw, int *ih); +void scale_pic(unsigned char **buffer, int x1, int y1, int xstart, int ystart, int xsize, int ysize, + int *imx, int *imy, int *dxp, int *dyp, int *dxo, int *dyo, int alpha); #endif diff --git a/icons.h b/icons.h new file mode 100644 index 0000000..3a02276 --- /dev/null +++ b/icons.h @@ -0,0 +1,13 @@ +#ifndef __icons_h__ +#define __icons_h__ + + +#define ICON_BUTTON_RED "/share/tuxbox/neutrino/icons/rot.png" +#define ICON_BUTTON_GREEN "/share/tuxbox/neutrino/icons/gruen.png" +#define ICON_BUTTON_YELLOW "/share/tuxbox/neutrino/icons/gelb.png" +#define ICON_BUTTON_BLUE "/share/tuxbox/neutrino/icons/blau.png" + +#define ICON_KEYS "/share/tuxbox/neutrino/icons/hint_keys.png" +#define ICON_NUMERIC_PAD "/share/tuxbox/neutrino/icons/numericpad.png" + +#endif diff --git a/input.c b/input.c index 4ba1790..e11e40a 100644 --- a/input.c +++ b/input.c @@ -12,34 +12,48 @@ #define NCF_FILE "/var/tuxbox/config/neutrino.conf" #define BUFSIZE 1024 -#define I_VERSION 1.42 +#define I_VERSION 2.0 -//#define FONT "/usr/share/fonts/md_khmurabi_10.ttf" -#define FONT2 "/share/fonts/pakenham.ttf" + +char FONT[128]="/share/fonts/neutrino.ttf"; // if font is not in usual place, we look here: -#define FONT "/share/fonts/neutrino.ttf" +#define FONT2 "/share/fonts/pakenham.ttf" // CMCST, CMCS, CMCT, CMC, CMCIT, CMCI, CMHT, CMH // WHITE, BLUE0, TRANSP, CMS, ORANGE, GREEN, YELLOW, RED +// COL_MENUCONTENT_PLUS_0 - 3, COL_SHADOW_PLUS_0 unsigned char bl[] = { 0x00, 0x00, 0xFF, 0x80, 0xFF, 0x80, 0x00, 0x80, - 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00}; + 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00}; unsigned char gn[] = { 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xC0, 0x00, - 0xFF, 0x80, 0x00, 0x80, 0xC0, 0xFF, 0xFF, 0x00}; + 0xFF, 0x80, 0x00, 0x80, 0xC0, 0xFF, 0xFF, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00}; unsigned char rd[] = { 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, - 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF}; + 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00}; unsigned char tr[] = { 0xFF, 0xFF, 0xFF, 0xA0, 0xFF, 0xA0, 0xFF, 0xFF, - 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; -uint32_t bgra[20]; + 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00}; +uint32_t bgra[22]; void TrimString(char *strg); void closedown(void); // OSD stuff -static char menucoltxt[][25]={"Content_Selected_Text","Content_Selected","Content_Text","Content","Content_inactive_Text","Content_inactive","Head_Text","Head"}; -static char spres[][5]={"","_crt","_lcd"}; - -char *buffer=NULL; +static char menucoltxt[][25]={ + "Content_Selected_Text", + "Content_Selected", + "Content_Text", + "Content", + "Content_inactive_Text", + "Content_inactive", + "Head_Text", + "Head" +}; +static char spres[][5]={"", "_crt", "_lcd"}; + +char *line_buffer=NULL; // Misc const char NOMEM[]="input \n"; @@ -106,6 +120,11 @@ int rv=-1; } } } + if((strncmp(entry, tstr, 10) == 0) && (strncmp(entry, "font_file=", 10) == 0)) + { + sscanf(tstr, "font_file=%127s", FONT); + rv = 1; + } // printf("%s\n%s=%s -> %d\n",tstr,entry,cfptr,rv); } fclose(nfh); @@ -330,27 +349,27 @@ char rstr[512]={0}, *title=NULL, *format=NULL, *defstr=NULL, *aptr=NULL, *rptr=N title=strdup(ttl); } - if((buffer=calloc(BUFSIZE+1, sizeof(char)))==NULL) + if((line_buffer=calloc(BUFSIZE+1, sizeof(char)))==NULL) { fprintf(stderr, NOMEM); return 0; } spr=Read_Neutrino_Cfg("screen_preset")+1; - sprintf(buffer,"screen_StartX%s",spres[spr]); - if((sx=Read_Neutrino_Cfg(buffer))<0) + sprintf(line_buffer,"screen_StartX%s",spres[spr]); + if((sx=Read_Neutrino_Cfg(line_buffer))<0) sx=100; - sprintf(buffer,"screen_EndX%s",spres[spr]); - if((ex=Read_Neutrino_Cfg(buffer))<0) + sprintf(line_buffer,"screen_EndX%s",spres[spr]); + if((ex=Read_Neutrino_Cfg(line_buffer))<0) ex=1180; - sprintf(buffer,"screen_StartY%s",spres[spr]); - if((sy=Read_Neutrino_Cfg(buffer))<0) + sprintf(line_buffer,"screen_StartY%s",spres[spr]); + if((sy=Read_Neutrino_Cfg(line_buffer))<0) sy=100; - sprintf(buffer,"screen_EndY%s",spres[spr]); - if((ey=Read_Neutrino_Cfg(buffer))<0) + sprintf(line_buffer,"screen_EndY%s",spres[spr]); + if((ey=Read_Neutrino_Cfg(line_buffer))<0) ey=620; for(ix=CMCST; ix<=CMH; ix++) @@ -371,14 +390,40 @@ char rstr[512]={0}, *title=NULL, *format=NULL, *defstr=NULL, *aptr=NULL, *rptr=N if((tv=Read_Neutrino_Cfg(rstr))>=0) rd[ix]=(float)tv*2.55; } - for (ix = 0; ix <= RED; ix++) - bgra[ix] = (tr[ix] << 24) | (rd[ix] << 16) | (gn[ix] << 8) | bl[ix]; + int cix=CMC; + for(ix=COL_MENUCONTENT_PLUS_0; ix<=COL_MENUCONTENT_PLUS_3; ix++) + { + rd[ix]=rd[cix]+25; + gn[ix]=gn[cix]+25; + bl[ix]=bl[cix]+25; + tr[ix]=tr[cix]; + cix=ix; + } + + sprintf(rstr,"infobar_alpha"); + if((tv=Read_Neutrino_Cfg(rstr))>=0) + tr[COL_SHADOW_PLUS_0]=255-(float)tv*2.55; + + sprintf(rstr,"infobar_blue"); + if((tv=Read_Neutrino_Cfg(rstr))>=0) + bl[COL_SHADOW_PLUS_0]=(float)tv*2.55*0.4; + + sprintf(rstr,"infobar_green"); + if((tv=Read_Neutrino_Cfg(rstr))>=0) + gn[COL_SHADOW_PLUS_0]=(float)tv*2.55*0.4; + + sprintf(rstr,"infobar_red"); + if((tv=Read_Neutrino_Cfg(rstr))>=0) + rd[COL_SHADOW_PLUS_0]=(float)tv*2.55*0.4; + + for (ix = 0; ix <= COL_SHADOW_PLUS_0; ix++) + bgra[ix] = (tr[ix] << 24) | (rd[ix] << 16) | (gn[ix] << 8) | bl[ix]; if(Read_Neutrino_Cfg("rounded_corners")>0) radius=11; else - radius=0; + radius = 0; fb = open(FB_DEVICE, O_RDWR); if(fb == -1) @@ -440,6 +485,7 @@ char rstr[512]={0}, *title=NULL, *format=NULL, *defstr=NULL, *aptr=NULL, *rptr=N return -1; } + Read_Neutrino_Cfg("font_file="); if((error = FTC_Manager_LookupFace(manager, FONT, &face))) { if((error = FTC_Manager_LookupFace(manager, FONT2, &face))) @@ -510,7 +556,7 @@ void closedown(void) memcpy(lfb, obb, var_screeninfo.xres*var_screeninfo.yres*sizeof(uint32_t)); munmap(lfb, fix_screeninfo.smem_len); - free(buffer); + free(line_buffer); FTC_Manager_Done(manager); FT_Done_FreeType(library); diff --git a/input.h b/input.h index 6c1a9ae..c7557b2 100644 --- a/input.h +++ b/input.h @@ -103,9 +103,34 @@ int fb; //framebuffer stuff -enum {FILL, GRID}; - -enum {CMCST, CMCS, CMCT, CMC, CMCIT, CMCI, CMHT, CMH, WHITE, BLUE1, GTRANSP, CMS, ORANGE, GREEN, YELLOW, RED}; +enum { + FILL, + GRID +}; + +enum { + CMCST, + CMCS, + CMCT, + CMC, + CMCIT, + CMCI, + CMHT, + CMH, + WHITE, + BLUE1, + GTRANSP, + CMS, + ORANGE, + GREEN, + YELLOW, + RED, + COL_MENUCONTENT_PLUS_0, + COL_MENUCONTENT_PLUS_1, + COL_MENUCONTENT_PLUS_2, + COL_MENUCONTENT_PLUS_3, + COL_SHADOW_PLUS_0 +}; #define TRANSP 0 extern uint32_t *lfb, *lbb, *obb; diff --git a/inputd.c b/inputd.c index 2109cab..b6d17c8 100644 --- a/inputd.c +++ b/inputd.c @@ -1,10 +1,14 @@ #include #include #include + #include "input.h" +#include "icons.h" #include "text.h" #include "io.h" #include "gfx.h" +#include "pngw.h" + #define xbrd 25 #define ybrd 25 @@ -270,11 +274,12 @@ char *sptr=msg, *tptr=tstr; char *inputd(char *form, char *title, char *defstr, int keys, int frame, int mask, int bhelp, int cols, int tmo) { -int i,j; -int exs,eys,wxs,wxw,wys,wyw,xp,yp; -char trnd[2]={0,0},tch; +int iw, ih, xsize=0, ysize=0, icon_w=0, icon_h=0; +int i, j, tlen; +int exs, eys, wxs, wxw, wys, wyw, xp, yp; +char trnd[2]={0,0}, tch; int act_key=-1, last_key=-1, run=1, ipos=0, count=0; -time_t t1,t2,tm1; +time_t t1, t2, tm1; // only for num block const char knum[12][2]={"1","2","3","4","5","6","7","8","9"," ","0"}; const char kalp[12][5]={"+-*/","abcä","def","ghi","jkl","mnoö","pqrs","tuvü","wxyz","","_,.;"}; @@ -297,7 +302,7 @@ const char kalp[12][5]={"+-*/","abc format=form; estr=strdup(form); cnt=strlen(form); - i=GetStringLen(title, BIG)+10; + tlen=i=GetStringLen(title, BIG)+10; j=((cnt>cols)?cols:cnt)*exsz; if(j>i) { @@ -312,6 +317,7 @@ const char kalp[12][5]={"+-*/","abc } } wxw=i+2*xbrd; + wxw=(keys==1 && wxw < 265) ? 265 : wxw; i=(((cnt-1)/cols)+1)*eysz; if(keys) @@ -354,16 +360,35 @@ const char kalp[12][5]={"+-*/","abc } estr[i]=0; - // title - RenderBox(wxs-2, wys-hsz-2, wxs+wxw+2, wys+wyw+2, radius , CMH); + // icon & title + RenderBox(wxs+6, wys-hsz+6, wxs+wxw+6, wys+wyw+6, radius, COL_SHADOW_PLUS_0); RenderBox(wxs, wys-hsz, wxs+wxw, wys+wyw, radius, CMC); RenderBox(wxs, wys-hsz, wxs+wxw, wys, radius, CMH); - RenderString(title, wxs, wys-7, wxw, CENTER, BIG, CMHT); - if(keys) + + png_getsize(ICON_KEYS, &icon_w, &icon_h); + if(icon_w > 40 || icon_h > 40) + icon_w = icon_h = xsize = ysize = 40; + paintIcon(ICON_KEYS, wxs+8, wys-hsz/2-icon_h/2, xsize, ysize, &iw, &ih); + int tstart, twide; + if(wxs+8+iw >= wxs+wxw-8-iw-tlen ) { + tstart = wxs+8+iw; + twide = wxw-8-iw; + } + else { + tstart = wxs; + twide = wxw; + } + RenderString(title, tstart, wys-7, twide, CENTER, BIG, CMHT); + + int bxs=wxs+(wxw-(3*bxsz))/2; + int bys=((wys+wyw)-2*ybrd)-4*bysz; + if(keys == 1) + { + png_getsize(ICON_NUMERIC_PAD, &icon_w, &icon_h); + paintIcon(ICON_NUMERIC_PAD, wxs+wxw/2-icon_w/2, bys+10, 0, 0, &iw, &ih); + } + if(keys == 2) { - int bxs=wxs+(wxw-(3*bxsz))/2; - int bys=((wys+wyw)-2*ybrd)-4*bysz; - for(i=0; i<11; i++) { if(i!=9) //num fields @@ -372,13 +397,16 @@ const char kalp[12][5]={"+-*/","abc RenderBox(bxs+(i%3)*bxsz+2, bys+(i/3)*bysz+2, bxs+((i%3)+1)*bxsz-2, bys+((i/3)+1)*bysz-2, radius, CMC); RenderString(knum[i], bxs+(i%3)*bxsz, bys+(i/3)*bysz+bysz/2+8, bxsz, CENTER, MED, CMCIT); RenderString(kalp[i], bxs+(i%3)*bxsz, bys+(i/3)*bysz+bysz-2, bxsz, CENTER, SMALL, CMCIT); - } - } - RenderCircle(bxs,wys+wyw-ybrd-11,RED); - RenderString("Groß/Klein",bxs+20,wys+wyw-ybrd+10,3*bxsz,LEFT,SMALL,CMCIT); - RenderCircle(bxs+3*bxsz-GetStringLen("löschen",SMALL)-15,wys+wyw-ybrd-11,YELLOW); - RenderString("löschen",bxs+5,wys+wyw-ybrd+10,3*bxsz,RIGHT,SMALL,CMCIT); + } + } + if(keys) + { + png_getsize(ICON_BUTTON_RED, &icon_w, &icon_h); + paintIcon(ICON_BUTTON_RED, bxs-icon_w/2, wys+wyw-ybrd-2-icon_h/2, 0, 0, &iw, &ih); + RenderString("Groß/Klein", bxs+icon_w/2+5,wys+wyw-ybrd+10, 3*bxsz, LEFT, SMALL, CMCIT); + paintIcon(ICON_BUTTON_YELLOW, bxs+125-icon_w/2, wys+wyw-ybrd-2-icon_h/2, 0, 0, &iw, &ih); + RenderString("löschen", bxs+125+icon_w/2+5,wys+wyw-ybrd+10, 65, LEFT, SMALL, CMCIT); } while(run) diff --git a/png_helper.cpp b/png_helper.cpp new file mode 100644 index 0000000..0ab9468 --- /dev/null +++ b/png_helper.cpp @@ -0,0 +1,21 @@ + +#include "pngw.h" + +int png_load_ext(const char *filename, unsigned char **buffer, int* xp, int* yp, int* bpp); +int fh_png_getsize(const char *filename, int *x, int *y); + +extern "C" +{ + +int png_load(const char *filename, unsigned char **buffer, int* xp, int* yp, int* bpp) +{ + return png_load_ext(filename, buffer, xp, yp, bpp); +} + +int png_getsize(const char *filename, int *x, int *y) +{ + return fh_png_getsize(filename, x, y); +} + +} + diff --git a/pngw.cpp b/pngw.cpp new file mode 100644 index 0000000..85493a6 --- /dev/null +++ b/pngw.cpp @@ -0,0 +1,237 @@ +/* + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * +*/ + +#include +#include +#include +#include +#include + +#include "pngw.h" + +#define FH_ERROR_OK 0 +#define FH_ERROR_FILE 1 /* read/access error */ +#define FH_ERROR_FORMAT 2 /* file format error */ +#define FH_ERROR_MALLOC 3 /* error during malloc */ +#define PNG_BYTES_TO_CHECK 4 +#define min(x,y) ((x) < (y) ? (x) : (y)) + +int fh_png_load(const char *name, unsigned char **buffer, int* xp, int* yp); + +int fh_png_id(const char *name) +{ + int fd; + char id[4]; + fd=open(name,O_RDONLY); if(fd==-1) return(0); + read(fd,id,4); + close(fd); + if(id[1]=='P' && id[2]=='N' && id[3]=='G') return(1); + return(0); +} + +int fh_png_load(const char *name, unsigned char **buffer, int* xp, int* yp); + +int int_png_load(const char *name, unsigned char **buffer, int* xp, int* yp, int* bpp, bool alpha) +{ + static const png_color_16 my_background = {0, 0, 0, 0, 0}; + png_structp png_ptr; + png_infop info_ptr; + png_uint_32 width, height; + unsigned int i; + int bit_depth, color_type, interlace_type, number_passes, pass, int_bpp; + png_byte * fbptr; + FILE * fh; + bool updateInfo_alreadyRead; + + if(!(fh=fopen(name,"rb"))) + return(FH_ERROR_FILE); + png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + if(png_ptr == NULL) { + fclose(fh); + return(FH_ERROR_FORMAT); + } + info_ptr = png_create_info_struct(png_ptr); + if(info_ptr == NULL) + { + png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL); + fclose(fh); + return(FH_ERROR_FORMAT); + } +#if (PNG_LIBPNG_VER < 10500) + if (setjmp(png_ptr->jmpbuf)) +#else + if (setjmp(png_jmpbuf(png_ptr))) +#endif + { + png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); + fclose(fh); + return(FH_ERROR_FORMAT); + } + png_init_io(png_ptr,fh); + png_read_info(png_ptr, info_ptr); + png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, NULL, NULL); + updateInfo_alreadyRead = false; + if (alpha) // 24bit or gray scale PNGs with alpha-channel + { + *bpp = png_get_channels(png_ptr, info_ptr); + if ((*bpp == 2) && (color_type == PNG_COLOR_TYPE_GRAY_ALPHA)) { + if (bit_depth < 8) { + /* Extract multiple pixels with bit depths of 1, 2, and 4 + from a single byte into separate bytes + (useful for paletted and grayscale images). */ + png_set_packing(png_ptr); + /* Expand grayscale images to the full 8 bits + from 1, 2, or 4 bits/pixel */ +#if PNG_LIBPNG_VER_MAJOR == 1 && PNG_LIBPNG_VER_MINOR <= 2 && PNG_LIBPNG_VER_RELEASE < 9 + png_set_gray_1_2_4_to_8(png_ptr); +#else + png_set_expand_gray_1_2_4_to_8(png_ptr); +#endif + } + /* Expand the grayscale to 24-bit RGB if necessary. */ + png_set_gray_to_rgb(png_ptr); + /* Update the users info structure */ + png_read_update_info(png_ptr, info_ptr); + updateInfo_alreadyRead = true; + *bpp = png_get_channels(png_ptr, info_ptr); + if (*bpp != 4) { + /* No 4 channels found + load PNG without alpha channel */ + png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); + fclose(fh); + return fh_png_load(name, buffer, xp, yp); + } + } + else if ((*bpp != 4) || !(color_type & PNG_COLOR_MASK_ALPHA)) { + /* No 4 channels & not an alpha channel found + load PNG without alpha channel */ + png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); + fclose(fh); + return fh_png_load(name, buffer, xp, yp); + } + int_bpp = 4; + + /* Expand paletted or RGB images with transparency + to full alpha channels so the data will + be available as RGBA quartets. */ + if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) + png_set_tRNS_to_alpha(png_ptr); + }else // All other PNGs + { + if (color_type == PNG_COLOR_TYPE_PALETTE) + { + png_set_palette_to_rgb(png_ptr); + png_set_background(png_ptr, (png_color_16*)&my_background, PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0); + /* other possibility for png_set_background: use png_get_bKGD */ + } + if (color_type == PNG_COLOR_TYPE_GRAY || + color_type == PNG_COLOR_TYPE_GRAY_ALPHA) + { + png_set_gray_to_rgb(png_ptr); + png_set_background(png_ptr, (png_color_16*)&my_background, PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0); + } + /* this test does not trigger for 8bit-paletted PNGs with newer libpng (1.2.36 at least), + but the data delivered is with alpha channel anyway, so always strip alpha for now + */ +#if PNG_LIBPNG_VER_MAJOR == 1 && PNG_LIBPNG_VER_MINOR <= 2 && PNG_LIBPNG_VER_RELEASE < 36 + if (color_type & PNG_COLOR_MASK_ALPHA) +#endif + png_set_strip_alpha(png_ptr); + if (bit_depth < 8) + png_set_packing(png_ptr); + int_bpp = 3; + } + if (bit_depth == 16) + png_set_strip_16(png_ptr); + number_passes = png_set_interlace_handling(png_ptr); + /* Update the users info structure */ + if (updateInfo_alreadyRead == 0) + png_read_update_info(png_ptr,info_ptr); + unsigned long rowbytes = png_get_rowbytes(png_ptr, info_ptr); + if (width * int_bpp != rowbytes) + { + printf("[pngw.cpp]: Error processing %s - please report (including image).\n", name); + printf(" width: %lu rowbytes: %lu\n", (unsigned long)width, (unsigned long)rowbytes); + fclose(fh); + return(FH_ERROR_FORMAT); + } + for (pass = 0; pass < number_passes; pass++) + { + fbptr = (png_byte *)(*buffer); + for (i = 0; i < height; i++, fbptr += width * int_bpp) + png_read_row(png_ptr, fbptr, NULL); + } + png_read_end(png_ptr, info_ptr); + png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); + fclose(fh); + return(FH_ERROR_OK); +} + +int png_load_ext(const char *name, unsigned char **buffer, int* xp, int* yp, int* bpp) +{ + return int_png_load(name, buffer, xp, yp, bpp, true); +} + +int fh_png_load(const char *name, unsigned char **buffer, int* xp, int* yp) +{ + return int_png_load(name, buffer, xp, yp, NULL, false); +} + +int fh_png_getsize(const char *name,int *x,int *y) +{ + png_structp png_ptr; + png_infop info_ptr; + png_uint_32 width, height; + int bit_depth, color_type, interlace_type; + FILE *fh; + + if(!(fh=fopen(name,"rb"))) return(FH_ERROR_FILE); + + png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,NULL,NULL,NULL); + if(png_ptr == NULL) { + fclose(fh); + return(FH_ERROR_FORMAT); + } + info_ptr = png_create_info_struct(png_ptr); + if(info_ptr == NULL) + { + png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL); + fclose(fh); + return(FH_ERROR_FORMAT); + } + +#if (PNG_LIBPNG_VER < 10500) + if (setjmp(png_ptr->jmpbuf)) +#else + if (setjmp(png_jmpbuf(png_ptr))) +#endif + { + png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); + fclose(fh); + return(FH_ERROR_FORMAT); + } + + png_init_io(png_ptr,fh); + png_read_info(png_ptr, info_ptr); + png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,&interlace_type, NULL, NULL); + png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); + *x=width; + *y=height; + fclose(fh); + return(FH_ERROR_OK); +} diff --git a/pngw.h b/pngw.h new file mode 100644 index 0000000..a09901a --- /dev/null +++ b/pngw.h @@ -0,0 +1,34 @@ +/* + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * +*/ + +#ifndef __PNGW_H__ +#define __PNGW_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif + +int png_load(const char *filename, unsigned char **buffer, int* xp, int* yp, int* bpp); +int png_getsize(const char *filename, int *x, int *y); + +#ifdef __cplusplus +} +#endif + +#endif // __PNGW_H__ diff --git a/readme.txt b/readme.txt index 878ca9c..61a7902 100644 --- a/readme.txt +++ b/readme.txt @@ -46,9 +46,9 @@ Reihe nach den Eingabefeldern zugewiesen. Der Defaulstring enthält also keine F wie der Formatstring sondern nur die reinen Daten. Keys: -Dieser Parameter kann 0 oder 1 sein. Bei 1 wird im Editorfenster die Tastenbelegung für die -Eingabe von alphanumerischen Zeichen zusätzlich mit angezeigt. Mit 0 wird diese Anzeige un- -terdrückt. Defaultwert ist 0. +Dieser Parameter kann 0, 1 oder 2 sein. Bei 1 wird im Editorfenster die Tastenbelegung für die +Eingabe von alphanumerischen Zeichen zusätzlich als PNG-Grafik mit angezeigt, bei 2 alternativ +gezeichnet. Mit 0 wird diese Anzeige unterdrückt. Defaultwert ist 0. Frames: Dieser Parameter kann 0 oder 1 sein. Bei 1 werden Rahmen um die Eingabefelder gezeichnet, diff --git a/resize.c b/resize.c new file mode 100644 index 0000000..f397c37 --- /dev/null +++ b/resize.c @@ -0,0 +1,95 @@ +/* + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * +*/ + +#include +#include +#include + +unsigned char * color_average_resize(unsigned char * orgin, int ox, int oy, int dx, int dy, int alpha) +{ + unsigned char *cr,*p,*q; + int i,j,k,l,ya,yb; + int sq,r,g,b,a; + cr = (unsigned char*) malloc(dx * dy * ((alpha) ? 4 : 3)); + if(cr==NULL) + { + printf("Error: malloc\n"); + return(orgin); + } + p=cr; + + int xa_v[dx]; + for(i=0;i=ox) + xb_v[i]=ox-1; + } + + if (alpha) + { + for(j=0;j=oy) yb=oy-1; + for(i=0;i=oy) yb=oy-1; + for(i=0;i