]> git.webhop.me Git - msgbox.git/commitdiff
port code from martii for a smoother rendering & better RC handling
authorGetAway <get-away@t-online.de>
Sat, 26 Nov 2016 11:33:49 +0000 (12:33 +0100)
committersvenhoefer <svenhoefer@svenhoefer.com>
Sat, 26 Nov 2016 11:57:03 +0000 (12:57 +0100)
gfx.c
gfx.h
io.c
io.h
msgbox.c
msgbox.h
text.c
text.h
txtform.c

diff --git a/gfx.c b/gfx.c
index d49bb90ae01c08f2dba1b3ba4d740c2474db10c1..fadbb28b917e32f438fa312f28b9c6b9d3f4d72b 100644 (file)
--- a/gfx.c
+++ b/gfx.c
@@ -4,13 +4,13 @@ void RenderBox(int _sx, int _sy, int _ex, int _ey, int rad, int col)
 {
        int F,R=rad,ssx=startx+_sx,ssy=starty+_sy,dxx=_ex-_sx,dyy=_ey-_sy,rx,ry,wx,wy,count;
 
-       unsigned char *pos=(lbb+(ssx<<2)+fix_screeninfo.line_length*ssy);
-       unsigned char *pos0, *pos1, *pos2, *pos3, *i;
-       unsigned char pix[4]={bl[col],gn[col],rd[col],tr[col]};
+       uint32_t *pos = lbb + ssx + stride * ssy;
+       uint32_t *pos0, *pos1, *pos2, *pos3, *i;
+       uint32_t pix = bgra[col];
                
        if (dxx<0) 
        {
-               printf("[msgbox] RenderBox called with dx < 0 (%d)\n", dxx);
+               printf("msgbox RenderBox called with dx < 0 (%d)\n", dxx);
                dxx=0;
        }
 
@@ -48,10 +48,11 @@ void RenderBox(int _sx, int _sy, int _ex, int _ey, int rad, int col)
                rx=R-ssx;
                ry=R-ssy;
 
-               pos0=pos+((dyy-ry)*fix_screeninfo.line_length);
-               pos1=pos+(ry*fix_screeninfo.line_length);
-               pos2=pos+(rx*fix_screeninfo.line_length);
-               pos3=pos+((dyy-rx)*fix_screeninfo.line_length);
+               pos0=pos+(dyy-ry)*stride;
+               pos1=pos+ry*stride;
+               pos2=pos+rx*stride;
+               pos3=pos+(dyy-rx)*stride;
+
                while (ssx <= ssy)
                {
                        rx=R-ssx;
@@ -59,18 +60,20 @@ void RenderBox(int _sx, int _sy, int _ex, int _ey, int rad, int col)
                        wx=rx<<1;
                        wy=ry<<1;
 
-                       for(i=pos0+(rx<<2); i<pos0+((rx+dxx-wx)<<2);i+=4)
-                               memcpy(i, pix, 4);
-                       for(i=pos1+(rx<<2); i<pos1+((rx+dxx-wx)<<2);i+=4)
-                               memcpy(i, pix, 4);
-                       for(i=pos2+(ry<<2); i<pos2+((ry+dxx-wy)<<2);i+=4)
-                               memcpy(i, pix, 4);
-                       for(i=pos3+(ry<<2); i<pos3+((ry+dxx-wy)<<2);i+=4)
-                               memcpy(i, pix, 4);
+                       for(i=pos0+rx; i<pos0+rx+dxx-wx;i++)
+                               *i = pix;
+                       for(i=pos1+rx; i<pos1+rx+dxx-wx;i++)
+                               *i = pix;
+                       for(i=pos2+ry; i<pos2+ry+dxx-wy;i++)
+                               *i = pix;
+                       for(i=pos3+ry; i<pos3+ry+dxx-wy;i++)
+                               *i = pix;
 
                        ssx++;
-                       pos2-=fix_screeninfo.line_length;
-                       pos3+=fix_screeninfo.line_length;
+
+                       pos2-=stride;
+                       pos3+=stride;
+
                        if (F<0)
                        {
                                F+=(ssx<<1)-1;
@@ -79,19 +82,18 @@ void RenderBox(int _sx, int _sy, int _ex, int _ey, int rad, int col)
                        { 
                                F+=((ssx-ssy)<<1);
                                ssy--;
-                               pos0-=fix_screeninfo.line_length;
-                               pos1+=fix_screeninfo.line_length;
+
+                               pos0-=stride;
+                               pos1+=stride;
                        }
                }
-               pos+=R*fix_screeninfo.line_length;
+               pos+=R*stride;
        }
 
        for (count=R; count<(dyy-R); count++)
        {
-               for(i=pos; i<pos+(dxx<<2);i+=4)
-                       memcpy(i, pix, 4);
-               pos+=fix_screeninfo.line_length;
+               for(i=pos; i<pos+dxx;i++)
+                       *i = pix;
+               pos+=stride;
        }
 }
-
-
diff --git a/gfx.h b/gfx.h
index 7f9fc0e48b1160dd3295fce43bdae9f75b422bb0..e21d91d0039f1e6d8ae4dd1cd5b5de9fd9c0c9b7 100644 (file)
--- a/gfx.h
+++ b/gfx.h
@@ -1,5 +1,4 @@
 #ifndef __GFX_H__
-
 #define __GFX_H__
 
 void RenderBox(int sx, int sy, int ex, int ey, int mode, int color);
diff --git a/io.c b/io.c
index c450459e4882c8c887d636995e39140d5bf660ea..16453479bda4cc2456e9b5f0f8ea6d5c5b489c43 100644 (file)
--- a/io.c
+++ b/io.c
@@ -3,7 +3,6 @@
 #include <errno.h>
 #include <locale.h>
 #include <fcntl.h>
-#include <stdio.h>
 #include <ctype.h>
 #include <time.h>
 #include <stdlib.h>
 #include <sys/dir.h>
 #include <sys/stat.h>
 #include <linux/input.h>
-#include "msgbox.h"
-
+#include <poll.h>
+#include <stdint.h>
 #include "io.h"
+#include "msgbox.h"
 
-#define RC_DEVICE      "/dev/input/nevis_ir"
 
 extern int instance;
 struct input_event ev;
 static unsigned short rccode=-1;
-static int rc = 0;
+static int rc;
 
 int InitRC(void)
 {
-       rc = open(RC_DEVICE, O_RDONLY);
+       rc = open(RC_DEVICE, O_RDONLY | O_CLOEXEC);
        if(rc == -1)
        {
                perror("msgbox <open remote control>");
@@ -60,19 +59,65 @@ int RCKeyPressed(void)
        return 0;
 }
 
+void ClearRC(void)
+{
+       struct pollfd pfd;
+       pfd.fd = rc;
+       pfd.events = POLLIN;
+       pfd.revents = 0;
 
-int GetRCCode(void)
+       do
+               poll(&pfd, 1, 300);
+       while(read(rc, &ev, sizeof(ev)) == sizeof(ev));
+}
+
+int GetRCCode(int timeout_in_ms)
 {
-       int rv;
-       
-       if(!RCKeyPressed() || (get_instance()>instance))
+       int rv = -1;
+
+       if (get_instance()>instance)
        {
-               return -1;
+               return rv;
        }
-       rv=rccode;
-       while(RCKeyPressed());
-       
-       return rv;
-}
 
+       if (timeout_in_ms) {
+               struct pollfd pfd;
+               struct timeval tv;
+               uint64_t ms_now, ms_final;
+
+               pfd.fd = rc;
+               pfd.events = POLLIN;
+               pfd.revents = 0;
+
+               gettimeofday( &tv, NULL );
+               ms_now = tv.tv_usec/1000 + tv.tv_sec * 1000;
+               if (timeout_in_ms > 0)
+                       ms_final = ms_now + timeout_in_ms;
+               else
+                       ms_final = UINT64_MAX;
+               while (ms_final > ms_now) {
+                       switch(poll(&pfd, 1, timeout_in_ms)) {
+                               case -1:
+                                       perror("GetRCCode: poll() failed");
+                               case 0:
+                                       return -1;
+                               default:
+                                       ;
+                       }
+                       if(RCKeyPressed()) {
+                               rv = rccode;
+                               while(RCKeyPressed());
+                               return rv;
+                       }
 
+                       gettimeofday( &tv, NULL );
+                       ms_now = tv.tv_usec/1000 + tv.tv_sec * 1000;
+                       if (timeout_in_ms > 0)
+                               timeout_in_ms = (int)(ms_final - ms_now);
+               }
+       } else if(RCKeyPressed()) {
+               rv = rccode;
+               while(RCKeyPressed());
+       }
+       return rv;
+}
diff --git a/io.h b/io.h
index 1619ae7d013df3b78184e782816612294bbe4b66..2cb93f8d93d55ad582d79db6d098774ccc3ab2f4 100644 (file)
--- a/io.h
+++ b/io.h
@@ -1,5 +1,4 @@
 #ifndef __IO_H__
-
 #define __IO_H__
 
 #define RC_DEVICE      "/dev/input/nevis_ir"
@@ -7,6 +6,7 @@
 int InitRC(void);
 int CloseRC(void);
 int RCKeyPressed(void);
-int GetRCCode(void);
+int GetRCCode(int);
+void ClearRC(void);
 
 #endif
index 81dbc87661e28ea06be85d3447c46f78684cd918..c1cf5f47ecdba0b54c1cb4d4e6c24cb8ea7889de 100644 (file)
--- a/msgbox.c
+++ b/msgbox.c
@@ -8,7 +8,7 @@
 #include "gfx.h"
 #include "txtform.h" 
 
-#define M_VERSION 1.18
+#define M_VERSION 1.20
 
 #define NCF_FILE       "/var/tuxbox/config/neutrino.conf"
 #define HDF_FILE       "/tmp/.msgbox_hidden"
 // if font is not in usual place, we look here:
 #define FONT "/share/fonts/neutrino.ttf"
 
-FT_Error                 error;
-FT_Library               library;
-FTC_Manager              manager;
-FTC_SBitCache            cache;
-FTC_SBit         sbit;
-#if FREETYPE_MAJOR == 2 && FREETYPE_MINOR == 0
-FTC_Image_Desc           desc;
-#else
-FTC_ImageTypeRec desc;
-#endif
-
-FT_Face                  face;
-FT_Bool                  use_kerning;
-FT_UInt                  prev_glyphindex;
-
-char *butmsg[MAX_BUTTONS];
-struct fb_fix_screeninfo fix_screeninfo;
-struct fb_var_screeninfo var_screeninfo;
-int startx, starty, sx, ex, sy, ey, debounce, rblock;
-int fb;
-
 //                                        CMCST,   CMCS,  CMCT,    CMC,    CMCIT,  CMCI,   CMHT,   CMH
 //                                        WHITE,   BLUE0, TRANSP,  CMS,    ORANGE, GREEN,  YELLOW, RED
 
@@ -51,6 +30,8 @@ unsigned char rd[] = {        0x00,   0x00,   0xFF,   0x00,   0xFF,   0x00,   0xFF,   0x00,
 unsigned char tr[] = { 0xFF,   0xFF,   0xFF,   0xA0,   0xFF,   0xA0,   0xFF,   0xFF,
                                                0xFF,   0xFF,   0x00,   0xFF,   0xFF,   0xFF,   0xFF,   0xFF};
 
+uint32_t bgra[20];
+
 void TrimString(char *strg);
 
 // OSD stuff
@@ -59,18 +40,18 @@ static char spres[][5]={"","_crt","_lcd"};
 
 char *line_buffer=NULL, *title=NULL;
 int size=24, type=0, timeout=0, refresh=3, flash=0, selection=0, tbuttons=0, buttons=0, bpline=3, echo=0, absolute=0, mute=1, header=1, cyclic=1;
-int rbutt[16],hide=0,radius=10;
+char *butmsg[16];
+int rbutt[16],hide=0,radius=11;
 
 // Misc
 const char NOMEM[]="msgbox <Out of memory>\n";
 char TMP_FILE[64]="/tmp/msgbox.tmp";
-unsigned char *lfb = 0, *lbb = 0, *obb = 0, *hbb = 0, *ibb = 0;
-unsigned char nstr[BUFSIZE]="";
-unsigned char *trstr;
-unsigned char sc[8]={'a','o','u','A','O','U','z','d'}, tc[8]={0xE4,0xF6,0xFC,0xC4,0xD6,0xDC,0xDF,0xB0};
-unsigned char rc = ' ';
+uint32_t *lfb = NULL, *lbb = NULL, *obb = NULL, *hbb = NULL, *ibb = NULL;
+char nstr[BUFSIZE]={0};
+char *trstr;
 const char INST_FILE[]="/tmp/rc.locked";
 int instance=0;
+int stride;
 
 int get_instance(void)
 {
@@ -87,9 +68,10 @@ int rval=0;
 
 void put_instance(int pval)
 {
+FILE *fh;
+
        if(pval)
        {
-               FILE *fh;
                if((fh=fopen(INST_FILE,"w"))!=NULL)
                {
                        fputc(pval,fh);
@@ -102,21 +84,23 @@ void put_instance(int pval)
        }
 }
 
-static void quit_signal()
+static void quit_signal(int sig)
 {
        put_instance(get_instance()-1);
-       printf("msgbox Version %.2f killed\n",M_VERSION);
+       printf("%s Version %.2f killed, signal %d\n", "msgbox", M_VERSION, sig);
        exit(1);
 }
 
 int Read_Neutrino_Cfg(char *entry)
 {
 FILE *nfh;
+char tstr [512], *cfptr=NULL;
 int rv=-1;
 
        if((nfh=fopen(NCF_FILE,"r"))!=NULL)
        {
-               char tstr [512]={0}, *cfptr=NULL;
+               tstr[0]=0;
+
                while((!feof(nfh)) && ((strstr(tstr,entry)==NULL) || ((cfptr=strchr(tstr,'='))==NULL)))
                {
                        fgets(tstr,500,nfh);
@@ -195,7 +179,11 @@ char *pt1=strdup(sptr),*pt2,*pt3;
                if(strlen(pt2))
                {       
                        rbutt[btn]=tbuttons;
-                       butmsg[btn]=strdup(pt2);
+                       size_t l = strlen(pt2);
+                       char *t = (char *)alloca(l * 4 + 1);
+                       memcpy(t, pt2, l + 1);
+                       TranslateString(t, l * 4);
+                       butmsg[btn]=strdup(t);
                        CatchTabs(butmsg[btn++]);
                }
                if(run)
@@ -221,17 +209,17 @@ static int psx, psy, pxw, pyw, myo=0, buttx=80, butty=30, buttdx=20, buttdy=10,
 int show_txt(int buttonly)
 {
 FILE *tfh;
-int x1,y1,cut,rv=-1,btns=buttons,lbtns=(buttons>bpline)?bpline:buttons,blines=1+((btns-1)/lbtns);
+int i,bx,by,x1,y1,rv=-1,run=1,line=0,action=1,cut,itmp,btns=buttons,lbtns=(buttons>bpline)?bpline:buttons,blines=1+((btns-1)/lbtns);
 
        if(hide)
        {
-               memcpy(lfb, hbb, fix_screeninfo.line_length*var_screeninfo.yres);
+               memcpy(lfb, hbb, var_screeninfo.xres*var_screeninfo.yres*sizeof(uint32_t));
                return 0;
        }
-       yo=40+((header)?FSIZE_MED*5/4:0);
+       yo=20+((header)?FSIZE_MED*5/4:0);
        if(!buttonly)
        {
-               memcpy(lbb, ibb, fix_screeninfo.line_length*var_screeninfo.yres);
+               memcpy(lbb, ibb, var_screeninfo.xres*var_screeninfo.yres*sizeof(uint32_t));
        }
        if((tfh=fopen(TMP_FILE,"r"))!=NULL)
        {
@@ -248,7 +236,6 @@ int x1,y1,cut,rv=-1,btns=buttons,lbtns=(buttons>bpline)?bpline:buttons,blines=1+
                        if(type==1)
                        {
                                myo=blines*(butty+buttdy);
-                               int itmp = 0,i;
                                for(i=0; i<btns; i++)
                                {
                                        itmp=GetStringLen(sx,butmsg[i], 26)+10;
@@ -290,10 +277,10 @@ int x1,y1,cut,rv=-1,btns=buttons,lbtns=(buttons>bpline)?bpline:buttons,blines=1+
                        if(btns)
                        {
                                buttxstart=psx+pxw/2-(((double)lbtns*(double)buttsize+(((lbtns>2)&&(lbtns&1))?((double)buttdx):0.0))/2.0);
-                               buttystart=psy+y1*dy;
+                               buttystart=psy+y1*dy+15;
                        }
                }
-               int bx,by,run=1,line=0,action=1;
+
                while(run)
                {
                        //frame layout
@@ -301,19 +288,18 @@ int x1,y1,cut,rv=-1,btns=buttons,lbtns=(buttons>bpline)?bpline:buttons,blines=1+
                        {
                                if(!buttonly)
                                {
-                                       RenderBox(psx-20, psy-yo, psx+pxw+20, psy+pyw+myo, radius, CMH);
-                                       RenderBox(psx-20+2, psy-yo+2, psx+pxw+20-2, psy+pyw+myo-2, radius, CMC);
+                                       RenderBox(psx-20, psy-yo, psx+pxw+20, psy+pyw+myo+15, radius, CMH);
+                                       RenderBox(psx-20+2, psy-yo+2, psx+pxw+20-2, psy+pyw+myo+15-2, radius, CMC);
                                        if(header)
                                        {
                                                RenderBox(psx-20, psy-yo+2-FSIZE_BIG/2, psx+pxw+20, psy-yo+FSIZE_BIG*3/4, radius, CMH);
                                                RenderString(title, psx, psy-yo+FSIZE_BIG/2, pxw, CENTER, FSIZE_BIG, CMHT);
                                        }
                                }
-                               if(buttonly || !(rv=fh_txt_load(TMP_FILE, psx, pxw, psy, dy, size, line, &cut)))
+                               if(buttonly || !(rv=fh_txt_load(TMP_FILE, psx, pxw, psy+15, dy, size, line, &cut)))
                                {
                                        if(type==1)
                                        {
-                                               int i;
                                                for(i=0; i<btns; i++)
                                                {
                                                        bx=i%lbtns;
@@ -323,7 +309,7 @@ int x1,y1,cut,rv=-1,btns=buttons,lbtns=(buttons>bpline)?bpline:buttons,blines=1+
                                                        RenderString(butmsg[i], buttxstart+bx*(buttsize+buttdx/2), buttystart+by*(butty+buttdy/2)+butty-7, buttsize, CENTER, 26, (i==(selection-1))?CMCST:CMCIT);
                                                }
                                        }
-                                       memcpy(lfb, lbb, fix_screeninfo.line_length*var_screeninfo.yres);
+                                       memcpy(lfb, lbb, var_screeninfo.xres*var_screeninfo.yres*sizeof(uint32_t));
                                }
                        }
                        run=0;
@@ -342,7 +328,7 @@ FILE *xfh;
                if((xfh=fopen(msg,"r"))!=NULL)
                {
                        fclose(xfh);
-                       snprintf(TMP_FILE,sizeof(TMP_FILE),"%s",msg);
+                       strcpy(TMP_FILE,msg);
                }
                else
                {
@@ -351,6 +337,12 @@ FILE *xfh;
        }
        else
        {
+               size_t l = strlen(msg);
+               char *t = (char *)alloca(l * 4 + 1);
+               memcpy(t, msg, l + 1);
+               TranslateString(t, l * 4);
+               msg = t;
+
                if((xfh=fopen(TMP_FILE,"w"))!=NULL)
                {
                        while(*msg)
@@ -408,11 +400,10 @@ void ShowUsage(void)
 
 int main (int argc, char **argv)
 {
-int index=0,tv=0,found=0, spr=0;
-int dloop=1, rcc=-1, cupd=0;
-char rstr[BUFSIZE]={0}, *rptr=NULL, *aptr=NULL;
-time_t tm1=0,tm2=0;
-//clock_t tk1=0;
+int ix,tv,found=0, spr;
+int dloop=1, rcc=-1;
+char rstr[BUFSIZE]={0}, *rptr, *aptr;
+time_t tm1,tm2;
 FILE *fh;
 
                if(argc<2)
@@ -443,8 +434,13 @@ FILE *fh;
                                {
                                        if(strstr(aptr,"title=")!=NULL)
                                        {
-                                               title=strdup(rptr);
+                                               size_t l = strlen(rptr);
+                                               char *t = (char *)alloca(l * 4 + 1);
+                                               memcpy(t, rptr, l + 1);
+                                               TranslateString(t, l * 4);
+                                               title = strdup(t);
                                                CatchTabs(title);
+
                                                if(strcmp(title,"none")==0)
                                                {
                                                        header=0;
@@ -661,27 +657,30 @@ FILE *fh;
                        ey=620;
 
 
-               for(index=CMCST; index<=CMH; index++)
+               for(ix=CMCST; ix<=CMH; ix++)
                {
-                       sprintf(rstr,"menu_%s_alpha",menucoltxt[index]);
+                       sprintf(rstr,"menu_%s_alpha",menucoltxt[ix]);
                        if((tv=Read_Neutrino_Cfg(rstr))>=0)
-                               tr[index]=255-(float)tv*2.55;
+                               tr[ix]=255-(float)tv*2.55;
 
-                       sprintf(rstr,"menu_%s_blue",menucoltxt[index]);
+                       sprintf(rstr,"menu_%s_blue",menucoltxt[ix]);
                        if((tv=Read_Neutrino_Cfg(rstr))>=0)
-                               bl[index]=(float)tv*2.55;
+                               bl[ix]=(float)tv*2.55;
 
-                       sprintf(rstr,"menu_%s_green",menucoltxt[index]);
+                       sprintf(rstr,"menu_%s_green",menucoltxt[ix]);
                        if((tv=Read_Neutrino_Cfg(rstr))>=0)
-                               gn[index]=(float)tv*2.55;
+                               gn[ix]=(float)tv*2.55;
 
-                       sprintf(rstr,"menu_%s_red",menucoltxt[index]);
+                       sprintf(rstr,"menu_%s_red",menucoltxt[ix]);
                        if((tv=Read_Neutrino_Cfg(rstr))>=0)
-                               rd[index]=(float)tv*2.55;
+                               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];
+
 
                if(Read_Neutrino_Cfg("rounded_corners")>0)
-                       radius=10;
+                       radius=11;
                else
                        radius=0;
 
@@ -712,7 +711,8 @@ FILE *fh;
                        perror("msgbox <FBIOGET_VSCREENINFO>\n");
                        return -1;
                }
-               if(!(lfb = (unsigned char*)mmap(0, fix_screeninfo.smem_len, PROT_READ | PROT_WRITE, MAP_SHARED, fb, 0)))
+
+               if(!(lfb = (uint32_t*)mmap(0, fix_screeninfo.smem_len, PROT_READ | PROT_WRITE, MAP_SHARED, fb, 0)))
                {
                        perror("msgbox <mapping of Framebuffer>\n");
                        return -1;
@@ -762,7 +762,7 @@ FILE *fh;
                
                use_kerning = FT_HAS_KERNING(face);
 
-               desc.flags = FT_LOAD_MONOCHROME;
+               desc.flags = FT_LOAD_RENDER | FT_LOAD_FORCE_AUTOHINT;
 
        //init backbuffer
 
@@ -774,6 +774,7 @@ FILE *fh;
                        munmap(lfb, fix_screeninfo.smem_len);
                        return -1;
                }
+               stride = fix_screeninfo.line_length/sizeof(uint32_t);
 
                if(!(obb = malloc(fix_screeninfo.line_length*var_screeninfo.yres)))
                {
@@ -810,27 +811,27 @@ FILE *fh;
 
                if(refresh & 1)
                {
-                       memcpy(ibb, lfb, fix_screeninfo.line_length*var_screeninfo.yres);
+                       memcpy(ibb, lbb, var_screeninfo.xres*var_screeninfo.yres*sizeof(uint32_t));
                }
                else
                {
-                       memset(ibb, TRANSP, fix_screeninfo.line_length*var_screeninfo.yres);
+                       memset(ibb, TRANSP, var_screeninfo.xres*var_screeninfo.yres*sizeof(uint32_t));
                }
                if(mute==2)
                {
-                       memcpy(hbb, lfb, fix_screeninfo.line_length*var_screeninfo.yres);
+                       memcpy(hbb, lbb, var_screeninfo.xres*var_screeninfo.yres*sizeof(uint32_t));
                }
                else
                {
-                       memset(hbb, TRANSP, fix_screeninfo.line_length*var_screeninfo.yres);
+                       memset(hbb, TRANSP, var_screeninfo.xres*var_screeninfo.yres*sizeof(uint32_t));
                }
                if(refresh & 2)
                {
-                       memcpy(obb, lfb, fix_screeninfo.line_length*var_screeninfo.yres);
+                       memcpy(obb, lbb, var_screeninfo.xres*var_screeninfo.yres*sizeof(uint32_t));
                }
                else
                {
-                       memset(obb, TRANSP, fix_screeninfo.line_length*var_screeninfo.yres);
+                       memset(obb, TRANSP, var_screeninfo.xres*var_screeninfo.yres*sizeof(uint32_t));
                }
 
                startx = sx;
@@ -852,13 +853,16 @@ FILE *fh;
        //main loop
        while((rcc!=KEY_EXIT) && (rcc!=KEY_OK) && ((timeout==-1)||((tm2-tm1)<timeout)))
        {
-               rcc=GetRCCode();
+               rcc=GetRCCode(1000);
                if(rcc!=-1)
                {
                        time(&tm1);
                }
                else
                {
+                       if(cyclic)
+                               show_txt(0);
+#if 0
                        if(++cupd>100)
                        {
                                if(cyclic)
@@ -868,13 +872,14 @@ FILE *fh;
                                }
                        }
                        usleep(10000L);
+#endif
                }
                if(mute && rcc==KEY_MUTE)
                {
                        hide^=1;
                        show_txt(0);
-                       usleep(500000L);
-                       while(GetRCCode()!=-1);
+
+                       while(GetRCCode(300)!=-1);
                        if(hide)
                        {
                                if((fh=fopen(HDF_FILE,"w"))!=NULL)
@@ -939,7 +944,7 @@ FILE *fh;
        
        //cleanup
 
-       memcpy(lfb, obb, fix_screeninfo.line_length*var_screeninfo.yres);
+       memcpy(lfb, obb, var_screeninfo.xres*var_screeninfo.yres*sizeof(uint32_t));
        munmap(lfb, fix_screeninfo.smem_len);
        close(fb);
        free(lbb);
index 6198b00c5dbcac1764b6f44d5319c0d80d7e84f1..981df54c8480e682393e52b89cf3109b0e6db539 100644 (file)
--- a/msgbox.h
+++ b/msgbox.h
@@ -1,7 +1,8 @@
 #ifndef __MSGBOX_H__
-
 #define __MSGBOX_H__
 
+#include <config.h>
+#define _FILE_OFFSET_BITS 64
 #include <errno.h>
 #include <fcntl.h>
 #include <signal.h>
@@ -17,6 +18,7 @@
 #include <sys/mman.h>
 #include <sys/socket.h>
 #include <sys/un.h>
+#include <stdint.h>
 
 #include <ft2build.h>
 #include FT_FREETYPE_H
 #define MAX_BUTTONS 16
 #define BUFSIZE        4095
 
-extern unsigned char FONT[64];
-
 enum {LEFT, CENTER, RIGHT};
 
-extern FT_Error                error;
-extern FT_Library              library;
-extern FTC_Manager             manager;
-extern FTC_SBitCache           cache;
-extern FTC_SBit                sbit;
+FT_Error               error;
+FT_Library             library;
+FTC_Manager            manager;
+FTC_SBitCache          cache;
+FTC_SBit               sbit;
 #if FREETYPE_MAJOR == 2 && FREETYPE_MINOR == 0
-extern FTC_Image_Desc          desc;
+FTC_Image_Desc         desc;
 #else
-extern FTC_ImageTypeRec        desc;
+FTC_ImageTypeRec       desc;
 #endif
-extern FT_Face                 face;
-extern FT_UInt                 prev_glyphindex;
-extern FT_Bool                 use_kerning;
+FT_Face                        face;
+FT_UInt                        prev_glyphindex;
+FT_Bool                        use_kerning;
 
 // rc codes
 
@@ -102,7 +102,7 @@ extern FT_Bool                      use_kerning;
 
 //devs
 
-extern int fb;
+int fb;
 
 //framebuffer stuff
 
@@ -116,21 +116,25 @@ extern int FSIZE_MED;
 extern int FSIZE_SMALL;
 extern int TABULATOR;
 
-extern unsigned char *lfb, *lbb, *obb, *hbb;
+extern uint32_t *lfb, *lbb, *obb, *hbb;
 
-extern struct fb_fix_screeninfo fix_screeninfo;
-extern struct fb_var_screeninfo var_screeninfo;
-extern unsigned char rd[],gn[],bl[],tr[];
+struct fb_fix_screeninfo fix_screeninfo;
+struct fb_var_screeninfo var_screeninfo;
+extern uint32_t bgra[];
+extern int stride;
+
+int startx, starty, sx, ex, sy, ey;
+//int debounce, rblock;
 
-extern int startx, starty, sx, ex, sy, ey, debounce, rblock;
-extern unsigned char sc[8], tc[8];
 extern char *butmsg[MAX_BUTTONS];
 extern int buttons,selection;
 extern int instance;
 int get_instance(void);
 void put_instance(int pval);
 
+#ifndef FB_DEVICE
 #define FB_DEVICE      "/dev/fb/0"
+#endif
 
 #endif
 
diff --git a/text.c b/text.c
index d78c2c18ca2d9dbf1c99c525a20c5c1006c54fbe..c223f5110580039aa065a03a14cbccb9030026f7 100644 (file)
--- a/text.c
+++ b/text.c
 #include "text.h"
 #include "gfx.h"
 #include "io.h"
+#include "msgbox.h"
 
 int FSIZE_BIG=28;
 int FSIZE_MED=24;
 int FSIZE_SMALL=20;
 int TABULATOR=72;
 
+static char *sc = "aouAOUzd",
+       *su= "\xA4\xB6\xBC\x84\x96\x9C\x9F",
+       *tc="\xE4\xF6\xFC\xC4\xD6\xDC\xDF\xB0";
+
+// from neutrino/src/driver/fontrenderer.cpp
+int UTF8ToUnicode(char **textp, const int utf8_encoded) // returns -1 on error
+{
+       int unicode_value, i;
+       char *text = *textp;
+       if (utf8_encoded && ((((unsigned char)(*text)) & 0x80) != 0))
+       {
+               int remaining_unicode_length;
+               if ((((unsigned char)(*text)) & 0xf8) == 0xf0) {
+                       unicode_value = ((unsigned char)(*text)) & 0x07;
+                       remaining_unicode_length = 3;
+               } else if ((((unsigned char)(*text)) & 0xf0) == 0xe0) {
+                       unicode_value = ((unsigned char)(*text)) & 0x0f;
+                       remaining_unicode_length = 2;
+               } else if ((((unsigned char)(*text)) & 0xe0) == 0xc0) {
+                       unicode_value = ((unsigned char)(*text)) & 0x1f;
+                       remaining_unicode_length = 1;
+               } else {
+                       (*textp)++;
+                       return -1;
+               }
+
+               *textp += remaining_unicode_length;
+
+               for (i = 0; *text && i < remaining_unicode_length; i++) {
+                       text++;
+                       if (((*text) & 0xc0) != 0x80) {
+                               remaining_unicode_length = -1;
+                               return -1;          // incomplete or corrupted character
+                       }
+                       unicode_value <<= 6;
+                       unicode_value |= ((unsigned char)(*text)) & 0x3f;
+               }
+       } else
+               unicode_value = (unsigned char)(*text);
+
+       (*textp)++;
+       return unicode_value;
+}
+
+void CopyUTF8Char(char **to, char **from)
+{
+       int remaining_unicode_length;
+       if (!((unsigned char)(**from) & 0x80))
+               remaining_unicode_length = 1;
+       else if ((((unsigned char)(**from)) & 0xf8) == 0xf0)
+               remaining_unicode_length = 4;
+       else if ((((unsigned char)(**from)) & 0xf0) == 0xe0)
+               remaining_unicode_length = 3;
+       else if ((((unsigned char)(**from)) & 0xe0) == 0xc0)
+               remaining_unicode_length = 2;
+       else {
+               (*from)++;
+               return;
+       }
+       while (**from && remaining_unicode_length) {
+               **to = **from;
+               (*from)++, (*to)++, remaining_unicode_length--;
+       }
+}
+
+int isValidUTF8(char *text) {
+       while (*text)
+               if (-1 == UTF8ToUnicode(&text, 1))
+                       return 0;
+       return 1;
+}
+
+void TranslateString(char *src, size_t size)
+{
+       char *fptr = src;
+       size_t src_len = strlen(src);
+       char *tptr_start = alloca(src_len * 4 + 1);
+       char *tptr = tptr_start;
+
+       if (isValidUTF8(src)) {
+               strncpy(tptr_start, fptr, src_len + 1);
+       }
+       else {
+               while (*fptr) {
+                       int i;
+                       for (i = 0; tc[i] && (tc[i] != *fptr); i++);
+                       if (tc[i]) {
+                               *tptr++ = 0xC3;
+                               *tptr++ = su[i];
+                               fptr++;
+                       } else if (*fptr & 0x80)
+                               fptr++;
+                       else
+                               *tptr++ = *fptr++;
+               }
+               *tptr = 0;
+       }
+
+       fptr = tptr_start;
+       tptr = src;
+       char *tptr_end = src + size - 4;
+
+       while (*fptr && tptr <= tptr_end) {
+               if (*fptr == '~') {
+                       fptr++;
+                       int i;
+                       for (i = 0; sc[i] && (sc[i] != *fptr); i++);
+                               if (*fptr == 'd') {
+                                       *tptr++ = 0xC2;
+                                       *tptr++ = 0xb0;
+                                       fptr++;
+                               } else if (sc[i]) {
+                                       *tptr++ = 0xC3;
+                                       *tptr++ = su[i];
+                                       fptr++;
+                               } else {
+                                       *tptr++ = '~';
+                               }
+               } else {
+                       CopyUTF8Char(&tptr, &fptr);
+               }
+       }
+       *tptr = 0;
+}
+
 /******************************************************************************
  * MyFaceRequester
  ******************************************************************************/
 
-FT_Error MyFaceRequester(FTC_FaceID face_id, FT_Library _library, FT_Pointer request_data, FT_Face *aface)
+FT_Error MyFaceRequester(FTC_FaceID face_id, FT_Library lib, FT_Pointer request_data __attribute__((unused)), FT_Face *aface)
 {
        FT_Error result;
-       request_data=request_data;//for unused request_data
-       result = FT_New_Face(_library, face_id, 0, aface);
+
+       result = FT_New_Face(lib, face_id, 0, aface);
 
        if(result) printf("msgbox <Font \"%s\" failed>\n", (char*)face_id);
 
@@ -26,72 +152,138 @@ FT_Error MyFaceRequester(FTC_FaceID face_id, FT_Library _library, FT_Pointer req
  * RenderChar
  ******************************************************************************/
 
+struct colors_struct
+{
+       uint32_t fgcolor, bgcolor;
+       uint32_t colors[256];
+};
+
+#define COLORS_LRU_SIZE 16
+static struct colors_struct *colors_lru_array[COLORS_LRU_SIZE] = { NULL };
+
+static uint32_t *lookup_colors(uint32_t fgcolor, uint32_t bgcolor)
+{
+       struct colors_struct *cs;
+       int i = 0, j;
+       for (i = 0; i < COLORS_LRU_SIZE; i++)
+               if (colors_lru_array[i] && colors_lru_array[i]->fgcolor == fgcolor && colors_lru_array[i]->bgcolor == bgcolor) {
+                       cs = colors_lru_array[i];
+                       for (j = i; j > 0; j--)
+                               colors_lru_array[j] = colors_lru_array[j - 1];
+                       colors_lru_array[0] = cs;
+                       return cs->colors;
+               }
+       i--;
+       cs = colors_lru_array[i];
+       if (!cs)
+               cs = (struct colors_struct *) calloc(1, sizeof(struct colors_struct));
+       for (j = i; j > 0; j--)
+               colors_lru_array[j] = colors_lru_array[j - 1];
+       cs->fgcolor = fgcolor;
+       cs->bgcolor = bgcolor;
+
+       int ro = var_screeninfo.red.offset;
+       int go = var_screeninfo.green.offset;
+       int bo = var_screeninfo.blue.offset;
+       int to = var_screeninfo.transp.offset;
+       int rm = (1 << var_screeninfo.red.length) - 1;
+       int gm = (1 << var_screeninfo.green.length) - 1;
+       int bm = (1 << var_screeninfo.blue.length) - 1;
+       int tm = (1 << var_screeninfo.transp.length) - 1;
+       int fgr = ((int)fgcolor >> ro) & rm;
+       int fgg = ((int)fgcolor >> go) & gm;
+       int fgb = ((int)fgcolor >> bo) & bm;
+       int fgt = ((int)fgcolor >> to) & tm;
+       int deltar = (((int)bgcolor >> ro) & rm) - fgr;
+       int deltag = (((int)bgcolor >> go) & gm) - fgg;
+       int deltab = (((int)bgcolor >> bo) & bm) - fgb;
+       int deltat = (((int)bgcolor >> to) & tm) - fgt;
+       for (i = 0; i < 256; i++)
+               cs->colors[255 - i] =
+                       (((fgr + deltar * i / 255) & rm) << ro) |
+                       (((fgg + deltag * i / 255) & gm) << go) |
+                       (((fgb + deltab * i / 255) & bm) << bo) |
+                       (((fgt + deltat * i / 255) & tm) << to);
+
+       colors_lru_array[0] = cs;
+       return cs->colors;
+}
+
 int RenderChar(FT_ULong currentchar, int _sx, int _sy, int _ex, int color)
 {
-//     unsigned char pix[4]={oldcmap.red[col],oldcmap.green[col],oldcmap.blue[col],oldcmap.transp[col]};
-//     unsigned char pix[4]={0x80,0x80,0x80,0x80};
+       int row, pitch;
        FT_UInt glyphindex;
        FT_Vector kerning;
-//     FT_Error _error;
+       FT_Error err;
+
+       if (currentchar == '\r') // display \r in windows edited files
+       {
+               if(color != -1)
+               {
+                       if (_sx + 10 < _ex)
+                               RenderBox(_sx, _sy - 10, _sx + 10, _sy, GRID, color);
+                       else
+                               return -1;
+               }
+               return 10;
+       }
 
-       currentchar=currentchar & 0xFF;
+       if (currentchar == '\t')
+       {
+               /* simulate horizontal TAB */
+               return 15;
+       }
 
        //load char
 
-               if(!(glyphindex = FT_Get_Char_Index(face, (int)currentchar)))
+               if(!(glyphindex = FT_Get_Char_Index(face, currentchar)))
                {
-//                     printf("msgbox <FT_Get_Char_Index for Char \"%c\" failed\n", (int)currentchar);
+                       printf("msgbox <FT_Get_Char_Index for Char \"%c\" failed\n", (int)currentchar);
                        return 0;
                }
 
-
-               if((/*_error =*/ FTC_SBitCache_Lookup(cache, &desc, glyphindex, &sbit, NULL)))
+               if((err = FTC_SBitCache_Lookup(cache, &desc, glyphindex, &sbit, NULL)))
                {
-//                     printf("msgbox <FTC_SBitCache_Lookup for Char \"%c\" failed with Errorcode 0x%.2X>\n", (int)currentchar, _error);
+                       printf("msgbox <FTC_SBitCache_Lookup for Char \"%c\" failed with Errorcode 0x%.2X>\n", (int)currentchar, error);
                        return 0;
                }
 
-// no kerning used
-/*
                if(use_kerning)
                {
                        FT_Get_Kerning(face, prev_glyphindex, glyphindex, ft_kerning_default, &kerning);
 
                        prev_glyphindex = glyphindex;
                        kerning.x >>= 6;
-               }
-               else
-*/
+               } else
                        kerning.x = 0;
 
-       //render char
+               //render char
 
                if(color != -1) /* don't render char, return charwidth only */
                {
-                       if(_sx + sbit->xadvance >= _ex){
+                       if (_sx + sbit->xadvance >= _ex)
                                return -1; /* limit to maxwidth */
-                       }
-                       unsigned char pix[4]={bl[color],gn[color],rd[color],tr[color]};
-                       int row, pitch, bit, x = 0, y = 0;
 
+                       uint32_t bgcolor = *(lbb + (sy + _sy) * stride + (sx + _sx));
+                       uint32_t fgcolor = bgra[color];
+                       uint32_t *colors = lookup_colors(fgcolor, bgcolor);
+                       uint32_t *p = lbb + (sx + _sx + sbit->left + kerning.x) + stride * (sy + _sy - sbit->top);
+                       uint32_t *r = p + (_ex - _sx);  /* end of usable box */
                        for(row = 0; row < sbit->height; row++)
                        {
-                               for(pitch = 0; pitch < sbit->pitch; pitch++)
+                               uint32_t *q = p;
+                               uint8_t *s = sbit->buffer + row * sbit->pitch;
+                               for(pitch = 0; pitch < sbit->width; pitch++)
                                {
-                                       for(bit = 7; bit >= 0; bit--)
-                                       {
-                                               if(pitch*8 + 7-bit >= sbit->width) break; /* render needed bits only */
-
-                                               if((sbit->buffer[row * sbit->pitch + pitch]) & 1<<bit) memcpy(lbb + (startx + _sx + sbit->left + kerning.x + x)*4 + fix_screeninfo.line_length*(starty + _sy - sbit->top + y),pix,4);
-
-                                               x++;
-                                       }
+                                       if (*s)
+                                                       *q = colors[*s];
+                                       q++, s++;
+                                       if (q > r)      /* we are past _ex */
+                                               break;
                                }
-
-                               x = 0;
-                               y++;
+                               p += stride;
+                               r += stride;
                        }
-
                }
 
        //return charwidth
@@ -103,66 +295,39 @@ int RenderChar(FT_ULong currentchar, int _sx, int _sy, int _ex, int color)
  * GetStringLen
  ******************************************************************************/
 
-int GetStringLen(int _sx, char *string, int size)
+int GetStringLen(int _sx, char *string, size_t size)
 {
-unsigned int i = 0;
-int stringlen = 0;
+       int i, stringlen = 0;
 
        //reset kerning
 
-               prev_glyphindex = 0;
+       prev_glyphindex = 0;
 
        //calc len
 
-               if(size)
-               {
-                       desc.width = desc.height = size;
-               }
-               
-               while(*string != '\0')
-               {
-                       if(*string != '~')
-                       {
-                               stringlen += RenderChar(*string, -1, -1, -1, -1);
-                       }
-                       else
-                       {
-                               string++;
-                               if(*string=='t')
-                               {
-                                       stringlen=desc.width+TABULATOR*((int)(stringlen/TABULATOR)+1);
-                               }
-                               else
-                               {
-                                       if(*string=='T')
-                                       {
-                                               if(sscanf(string+1,"%4d",&i)==1)
-                                               {
-                                                       string+=4;
-                                                       stringlen=i-_sx;
-                                               }
-                                       }
-                                       else
-                                       {
-                                               int found=0;
-                                               for(i=0; i<sizeof(sc)/sizeof(sc[0]) && !found; i++)
-                                               {
-                                                       if(*string==sc[i])
-                                                       {
-                                                               stringlen += RenderChar(tc[i], -1, -1, -1, -1);
-                                                               found=1;
-                                                       }
-                                               }
-                                       }
-                               }
-                       }
+       if(size)
+               desc.width = desc.height = size;
+
+       while(*string) {
+               switch(*string) {
+               case '~':
                        string++;
+                       if(*string=='t')
+                               stringlen=desc.width+TABULATOR*((int)(stringlen/TABULATOR)+1);
+                       else if(*string=='T' && sscanf(string+1,"%4d",&i)==1) {
+                               string+=5;
+                               stringlen=i-_sx;
+                       }
+                       break;
+               default:
+                       stringlen += RenderChar(UTF8ToUnicode(&string, 1), -1, -1, -1, -1);
+                       break;
                }
+       }
 
        return stringlen;
 }
 
-
 void CatchTabs(char *text)
 {
        int i;
@@ -184,134 +349,73 @@ void CatchTabs(char *text)
 /******************************************************************************
  * RenderString
  ******************************************************************************/
+
 int RenderString(char *string, int _sx, int _sy, int maxwidth, int layout, int size, int color)
 {
-       int stringlen = 0, _ex = 0, charwidth = 0,found = 0;
-       unsigned int i = 0;
-       char rstr[BUFSIZE]={0}, *rptr=rstr, rc=' ';
+       int stringlen, _ex, charwidth,i;
+       char rstr[BUFSIZE]={0}, *rptr=rstr;
        int varcolor=color;
 
        //set size
-               snprintf(rstr,sizeof(rstr),"%s",string);
 
-               desc.width = desc.height = size;
-               TABULATOR=3*size;
+       strcpy(rstr,string);
+
+       desc.width = desc.height = size;
+       TABULATOR=3*size;
        //set alignment
 
-               stringlen = GetStringLen(_sx, rstr, size);
+       stringlen = GetStringLen(_sx, rstr, size);
 
-               if(layout != LEFT)
+       if(layout != LEFT)
+       {
+               switch(layout)
                {
-                       switch(layout)
-                       {
-                               case CENTER:    if(stringlen < maxwidth) _sx += (maxwidth - stringlen)/2;
-                                               break;
+                       case CENTER:    if(stringlen < maxwidth) _sx += (maxwidth - stringlen)/2;
+                                       break;
 
-                               case RIGHT:     if(stringlen < maxwidth) _sx += maxwidth - stringlen;
-                       }
+                       case RIGHT:     if(stringlen < maxwidth) _sx += maxwidth - stringlen;
                }
+       }
 
        //reset kerning
 
-               prev_glyphindex = 0;
+       prev_glyphindex = 0;
 
        //render string
 
-               _ex = _sx + maxwidth;
+       _ex = _sx + maxwidth;
 
-               while(*rptr != '\0')
+       while(*rptr != '\0')
+       {
+               if(*rptr=='~')
                {
-                       if(*rptr=='~')
-                       {
-                               ++rptr;
-                               rc=*rptr;
-                               found=0;
-                               for(i=0; i< sizeof(sc)/sizeof(sc[0]) && !found; i++)
-                               {
-                                       if(rc==sc[i])
-                                       {
-                                               rc=tc[i];
-                                               found=1;
-                                       }
-                               }
-                               if(found)
-                               {
-                                       if((charwidth = RenderChar(rc, _sx, _sy, _ex, varcolor)) == -1) return _sx; /* string > maxwidth */
-                                       _sx += charwidth;
-                               }
-                               else
-                               {
-                                       switch(*rptr)
-                                       {
-                                               case 'R': varcolor=RED; break;
-                                               case 'G': varcolor=GREEN; break;
-                                               case 'Y': varcolor=YELLOW; break;
-                                               case 'B': varcolor=BLUE1; break;
-                                               case 'S': varcolor=color; break;
-                                               case 't':
-                                                       _sx=TABULATOR*((int)(_sx/TABULATOR)+1);
-                                                       break;
-                                               case 'T':
-                                                       if(sscanf(rptr+1,"%4d",&i)==1)
-                                                       {
-                                                               rptr+=4;
-                                                               _sx=i;
-                                                       }
-                                               break;
-                                       }
-                               }
-                       }
-                       else
+                       ++rptr;
+                       switch(*rptr)
                        {
-                               int uml = 0;
-                               switch(*rptr)    /* skip Umlauts */
-                               {
-                                       case '\xc4':
-                                       case '\xd6':
-                                       case '\xdc':
-                                       case '\xe4':
-                                       case '\xf6':
-                                       case '\xfc':
-                                       case '\xdf': uml=1; break;
-                               }
-                               if (uml == 0)
-                               {
-                                       // UTF8_to_Latin1 encoding
-                                       if (((*rptr) & 0xf0) == 0xf0)      /* skip (can't be encoded in Latin1) */
-                                       {
-                                               rptr++;
-                                               if ((*rptr) == 0)
-                                                       *rptr='\x3f'; // ? question mark
-                                               rptr++;
-                                               if ((*rptr) == 0)
-                                                       *rptr='\x3f';
-                                               rptr++;
-                                               if ((*rptr) == 0)
-                                                       *rptr='\x3f';
-                                       }
-                                       else if (((*rptr) & 0xe0) == 0xe0) /* skip (can't be encoded in Latin1) */
+                               case 'R': varcolor=RED; break;
+                               case 'G': varcolor=GREEN; break;
+                               case 'Y': varcolor=YELLOW; break;
+                               case 'B': varcolor=BLUE1; break;
+                               case 'S': varcolor=color; break;
+                               case 't':
+                                       _sx=TABULATOR*((int)(_sx/TABULATOR)+1);
+                                       break;
+                               case 'T':
+                                       if(sscanf(rptr+1,"%4d",&i)==1)
                                        {
-                                               rptr++;
-                                               if ((*rptr) == 0)
-                                                       *rptr='\x3f';
-                                               rptr++;
-                                               if ((*rptr) == 0)
-                                                       *rptr='\x3f';
+                                               rptr+=4;
+                                               _sx=i;
                                        }
-                                       else if (((*rptr) & 0xc0) == 0xc0)
-                                       {
-                                               char c = (((*rptr) & 3) << 6);
-                                               rptr++;
-                                               if ((*rptr) == 0)
-                                                       *rptr='\x3f';
-                                               *rptr = (c | ((*rptr) & 0x3f));
-                                       }
-                               }
-                               if((charwidth = RenderChar(*rptr, _sx, _sy, _ex, varcolor)) == -1) return _sx; /* string > maxwidth */
-                               _sx += charwidth;
+                               break;
                        }
                        rptr++;
                }
+               else
+               {
+                       if((charwidth = RenderChar(UTF8ToUnicode(&rptr, 1), _sx, _sy, _ex, varcolor)) == -1) return _sx; /* string > maxwidth */
+                       _sx += charwidth;
+               }
+       }
        return stringlen;
 }
 
diff --git a/text.h b/text.h
index a76a0caf4d195cdd139782fd0e9ca3d0c9c3133f..3cfe53c5dec95d37da5f67f98ca5553d4d0e3cd7 100644 (file)
--- a/text.h
+++ b/text.h
@@ -1,12 +1,12 @@
 #ifndef __TEXT_H__
-
 #define __TEXT_H__
 
 #include "msgbox.h"
 
 FT_Error MyFaceRequester(FTC_FaceID face_id, FT_Library library, FT_Pointer request_data, FT_Face *aface);
 int RenderString(char *string, int sx, int sy, int maxwidth, int layout, int size, int color);
-int GetStringLen(int sx, char *string, int size);
+void TranslateString(char *src, size_t size);
+int GetStringLen(int sx, char *string, size_t size);
 void CatchTabs(char *text);
 
 #endif
index 9b183a43a254c206243f3ed95c1375d7cfe4f8f0..b53b3d631c1710e8b239b9a2bddbfe112b61acea 100644 (file)
--- a/txtform.c
+++ b/txtform.c
@@ -59,19 +59,23 @@ int just, color=CMCT;
                if((loop>0) && (ys<(ey-dy)))
                {
                        rstr[j]=0;
+                       char *t = (char *)alloca(j * 4 + 1);
+                       memcpy(t, rstr, j + 1);
+                       TranslateString(t, j * 4);
+
                        if(plot)
                        {
                                if(loop>=line)
                                {
-                                       RenderString(rstr, xs, ys, xw, just, size, color);
+                                       RenderString(t, xs, ys, xw, just, size, color);
                                        ys+=dy;
                                }
                        }
                        else
                        {
-                               if(strlen(rstr))
+                               if(strlen(t))
                                {
-                                       slen=GetStringLen(xs, rstr, size);
+                                       slen=GetStringLen(xs, t, size);
                                        if(slen>*x)
                                        {
                                                *x=slen;
@@ -91,7 +95,8 @@ int just, color=CMCT;
 
 int fh_txt_load(const char *name, int _sx, int wx, int _sy, int dy, int size, int line, int *cut)
 {
-       int dummy;
+int dummy;
+
        return fh_txt_trans(name, _sx, wx, _sy, dy, size, line, cut, &dummy, &dummy, 1);
 }