*/}}
Ver código fonte

16 and 7 segment lcd font basics and progresss

YimingWu 2 anos atrás
pai
commit
777eaa4bb0
4 arquivos alterados com 158 adições e 4 exclusões
  1. 2 0
      la_interface.h
  2. 5 3
      la_kernel.c
  3. 2 0
      la_tns.h
  4. 149 1
      la_tns_kernel.c

+ 2 - 0
la_interface.h

@@ -987,6 +987,8 @@ STRUCTURE(laWidget){
 #define LA_UI_FLAGS_NO_SCROLL_INACTIVE (1<<24)
 #define LA_UI_FLAGS_COLOR_SPACE_CLAY (1<<25)
 #define LA_UI_FLAGS_EXIT_WHEN_TRIGGERED LA_UI_FLAGS_COLOR_SPACE_CLAY
+#define LA_TEXT_LCD_16         (1<<27)
+#define LA_TEXT_LCD_7          (1<<28)
 
 #define LA_UI_FLAGS_INT_ICON  (LA_UI_FLAGS_NO_DECAL|LA_UI_FLAGS_NO_EVENT|LA_UI_FLAGS_ICON)
 #define LA_UI_FLAGS_PLAIN     (LA_UI_FLAGS_NO_DECAL|LA_UI_FLAGS_NO_EVENT)

+ 5 - 3
la_kernel.c

@@ -333,8 +333,10 @@ void laShowProgressV(real p1, real p2, char* format, va_list v){
     }
     XClearWindow(MAIN.dpy,MAIN.Progress.w);
     if(p1>=0) MAIN.Progress.p1=p1; if(p2>=0) MAIN.Progress.p2=p2;
-    XFillRectangle(MAIN.dpy,MAIN.Progress.w,MAIN.Progress.gc,0,0,PROGRESSW*MAIN.Progress.p1,LA_RH);
-    XFillRectangle(MAIN.dpy,MAIN.Progress.w,MAIN.Progress.gc,0,LA_RH,PROGRESSW*MAIN.Progress.p2,LA_RH);
+    XFillRectangle(MAIN.dpy,MAIN.Progress.w,MAIN.Progress.gc,LA_RH*2,0,PROGRESSW*MAIN.Progress.p1,LA_RH);
+    XFillRectangle(MAIN.dpy,MAIN.Progress.w,MAIN.Progress.gc,LA_RH*2,LA_RH,PROGRESSW*MAIN.Progress.p2,LA_RH);
+    tnsDrawLCD7_ProgressX11(LA_RH*1.5,0,MAIN.Progress.p1);
+    tnsDrawLCD7_ProgressX11(LA_RH*1.5,LA_RH,MAIN.Progress.p2);
     XFlush(MAIN.dpy); XSync(MAIN.dpy, 0);
 }
 void laShowProgress(real p1, real p2, char* format, ...){
@@ -356,7 +358,7 @@ void laHideProgress(){
 //=======================
 
 void laInitProgressWindow(){
-    MAIN.Progress.w=XCreateSimpleWindow(MAIN.dpy, RootWindow(MAIN.dpy, 0), 0, 0, PROGRESSW, LA_RH*2, 0, BlackPixel(MAIN.dpy, 0), WhitePixel(MAIN.dpy, 0));
+    MAIN.Progress.w=XCreateSimpleWindow(MAIN.dpy, RootWindow(MAIN.dpy, 0), 0, 0, PROGRESSW+LA_RH*2, LA_RH*2, 0, BlackPixel(MAIN.dpy, 0), WhitePixel(MAIN.dpy, 0));
     if(!MAIN.Progress.w) return;
     Atom window_type = XInternAtom(MAIN.dpy, "_NET_WM_WINDOW_TYPE", False); long value = XInternAtom(MAIN.dpy, "_NET_WM_WINDOW_TYPE_DOCK", False);
     XChangeProperty(MAIN.dpy, MAIN.Progress.w, window_type,XA_ATOM, 32, PropModeReplace, (unsigned char *) &value,1 );

+ 2 - 0
la_tns.h

@@ -1314,6 +1314,8 @@ int tnsStringGetDimension(char* content, uint32_t* contentU, int Count, int WLim
 int tnsStringGetWidth(char *content, int Count, int UseMono);
 int tnsStringGetWidthU(uint32_t *contentU, int Count, int UseMono);
 void tnsDrawStringM(char *content, uint32_t* contentU, real Color[4], int L, int R, int T, int Flags);
+int tnsDrawLCD7_ProgressX11(real x, real y, real Percent);
+void tnsDrawStringLCD(char *content, uint32_t* contentU, real Color[4], int L, int R, int T, int Flags);
 void tnsDrawStringAutoM(char *content, uint32_t* contentU, real Color[4], int L, int R, int T, int Flags);
 void tnsDrawStringAuto(char *content, real Color[4], int L, int R, int T, int Flags);
 void tnsDrawStringWithPriority(char *Label, char *MajorContent, real Color[4], int TextAlign, int L, int R, int T, int Flags);

+ 149 - 1
la_tns_kernel.c

@@ -324,6 +324,54 @@ void main(){\n\
     gl_FragColor=vec4(fIdColor,1.);\n\
 }";
 
+#define HF 0.5
+
+//  1  2
+// 7 9 11     13  14
+//  3  4
+// 8 10 12    15  16
+//  5  6
+real TNS_LCD_SEG_16[16][4]={
+    {0,0,HF,0},{HF,0,1,0},{0,0.5,HF,0.5},{HF,0.5,1,0.5},{0,1,HF,1},{HF,1,1,1},
+    {0,0,0,HF},{0,HF,0,1},{0.5,0,0.5,HF},{0.5,HF,0.5,1},{1,0,1,HF},{1,HF,1,1},
+    {0,0,HF,HF},{1,0,HF,HF},{0,1,HF,HF},{1,1,HF,HF},
+};
+char TNS_LCD_MAP_16[][16]={
+    {1,1,0,0,1,1,1,1,0,0,1,1,0,1,1,0},{0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0},//0-9
+    {1,1,1,1,1,1,0,1,0,0,1,0,0,0,0,0},{1,1,1,1,1,1,0,0,0,0,1,1,0,0,0,0},
+    {0,0,1,1,0,0,1,0,1,1,0,0,0,0,0,0},{1,1,1,1,1,1,1,0,0,0,0,1,0,0,0,0},
+    {1,1,1,1,1,1,1,1,0,0,0,1,0,0,0,0},{1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0},
+    {1,1,1,1,1,1,1,1,0,0,1,1,0,0,0,0},{1,1,1,1,1,1,1,0,0,0,1,1,0,0,0,0},
+    {1,1,1,1,0,0,1,1,0,0,1,1,0,0,0,0},{1,1,0,1,1,1,0,0,1,1,1,1,0,0,0,0},//A
+    {1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0},{1,1,0,0,1,1,0,0,1,1,1,1,0,0,0,0},
+    {1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0},{1,1,1,1,0,0,1,1,0,0,0,0,0,0,0,0},
+    {1,1,0,1,1,1,1,1,0,0,0,1,0,0,0,0},{0,0,1,1,0,0,1,1,0,0,1,1,0,0,0,0},
+    {1,1,0,0,1,1,0,0,1,1,0,0,0,0,0,0},{1,1,0,0,1,0,0,0,1,1,0,0,0,0,0,0},
+    {0,0,1,0,0,0,1,1,0,0,0,0,0,1,0,1},{0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0},
+    {0,0,0,0,0,0,1,1,0,0,1,1,1,1,0,0},{0,0,0,0,0,0,1,1,0,0,1,1,1,0,0,1},
+    {1,1,0,0,1,1,1,1,0,0,1,1,0,0,0,0},{1,1,1,1,0,0,1,1,0,0,1,0,0,0,0,0},
+    {1,1,0,0,1,1,1,1,0,0,1,1,0,0,0,1},{1,1,1,1,0,0,1,1,0,0,1,0,0,0,0,1},
+    {1,1,0,1,1,1,0,0,0,0,0,1,1,0,0,0},{1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0},
+    {0,0,0,0,1,1,1,1,0,0,1,1,0,0,0,0},{0,0,0,0,0,0,1,1,0,0,0,0,0,1,1,0},
+    {0,0,0,0,0,0,1,1,0,0,1,1,0,0,1,1},{0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1},
+    {0,0,0,0,0,0,0,0,0,1,0,0,1,1,0,0},{1,1,0,0,1,1,0,0,0,0,0,0,0,1,1,0},
+};
+
+//   1
+// 4   6
+//   2
+// 5   7
+//   3
+real TNS_LCD_SEG_7[7][4]={ {0,0,1,0},{0,0.5,1,0.5},{0,1,1,1},
+    {0,0,0,HF},{0,HF,0,1},{1,0,1,HF},{1,HF,1,1},
+};
+char TNS_LCD_MAP_7[][7]={
+    {1,0,1,1,1,1,1},{0,0,0,0,0,1,1},{1,1,1,0,1,1,0},{1,1,1,0,0,1,1},{0,1,0,1,0,1,1},// 0-4
+    {1,1,1,1,0,0,1},{1,1,1,1,1,0,1},{1,0,0,0,0,1,1},{1,1,1,1,1,1,1},{1,1,1,1,0,1,1},// 6-9
+};
+
+#undef HF
+
 int tKnlAttatchShader(tnsShader *tns);
 tnsShader *tKnlFindShader1i(int CustomIndex);
 void tKnlPushMatrix();
@@ -2778,6 +2826,13 @@ int tnsInvalidateFontCache(){
     int GenHeight=LA_RH*MAIN.FontSize;
     for(int i=0;i<f->NumFaces;i++){
         FT_Set_Char_Size(f->ftface[i], 0, GenHeight << 6, 96, 96);
+        FT_Glyph glyph; int half_adv=0;
+        if(!FT_Get_Advance(f->ftface[i],'a',FT_LOAD_TARGET_NORMAL | FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP, &half_adv)){
+            if (FT_Load_Char(f->ftface[i], 'a', FT_LOAD_TARGET_NORMAL | FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP)||
+                FT_Get_Glyph(f->ftface[i]->glyph, &glyph)){ SEND_PANIC_ERROR("Monospace font doesn't contain character 'a'"); }
+            f->MonoAdvance=(real)f->ftface[i]->glyph->advance.x/64.0;
+            if(glyph) FT_Done_Glyph(glyph);
+        }
     }
     if(f->ftfacemono){
         FT_Set_Char_Size(f->ftfacemono, 0, (GenHeight << 6)*f->MonoScale, 96, 96); FT_Glyph glyph;
@@ -2837,7 +2892,14 @@ int tnsLoadSystemFont(char* from, char* name){
         if (FT_New_Face(f->ftlib, buf, 0, &f->ftface[f->NumFaces])) continue;
         FT_Select_Charmap(f->ftface[f->NumFaces], FT_ENCODING_UNICODE);
         FT_Set_Char_Size(f->ftface[f->NumFaces], 0, GenHeight << 6, 96, 96);
-        f->NumFaces++;
+        f->NumFaces++; FT_Glyph glyph; int half_adv=0;
+        if(!f->MonoAdvance && !FT_Get_Advance(f->ftface[f->NumFaces],'a',FT_LOAD_TARGET_NORMAL | FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP, &half_adv)){
+            FT_Set_Char_Size(f->ftface[f->NumFaces], 0, (GenHeight << 6)*f->MonoScale, 96, 96);
+            if (FT_Load_Char(f->ftface[f->NumFaces], 'a', FT_LOAD_TARGET_NORMAL | FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP)||
+                FT_Get_Glyph(f->ftface[f->NumFaces]->glyph, &glyph)){ SEND_PANIC_ERROR("Monospace font doesn't contain character 'a'"); }
+            f->MonoAdvance=(real)f->ftface[f->NumFaces]->glyph->advance.x/64.0;
+            if(glyph) FT_Done_Glyph(glyph);
+        }
         return 1;
     }
 
@@ -3081,7 +3143,93 @@ int tnsStringGetWidth(char *content, int Count, int UseMono){
 int tnsStringGetWidthU(uint32_t *contentU, int Count, int UseMono){
     return tnsStringGetDimension(0, contentU, Count, 0, 0, UseMono);
 }
+
+int tnsDrawLCD7_ProgressX11(real x, real y, real Percent){
+    real hgap=LA_RH/15; real vgap=LA_RH/5;
+    real MA=FM->UsingFont->MonoAdvance;
+    real w=MA-hgap*2, h=LA_RH-vgap*2; y+=vgap; x+=hgap-MA;
+    TNS_CLAMP(Percent,0,1);
+    char str[10]; sprintf(str,"%d",(int)(Percent*100)); int len=strlen(str);
+    for(int i=len-1;i>=0;i--){
+        int uc=str[i];
+        if(uc>='0' && uc<='9'){ uc-='0'; } 
+        else { continue; }
+        for(int i=0;i<7;i++){
+            if(TNS_LCD_MAP_7[uc][i]){
+                real* seg=TNS_LCD_SEG_7[i];
+                XDrawLine(MAIN.dpy,MAIN.Progress.w,MAIN.Progress.gc,
+                    tnsInterpolate(x,x+w,seg[0]),tnsInterpolate(y,y+h,seg[1]),tnsInterpolate(x,x+w,seg[2]),tnsInterpolate(y,y+h,seg[3]));
+            }
+        }
+        x-=MA;
+    }
+    return 1;
+}
+int tnsMakeLCD7(real x, real y, real w, real h, int ch){
+    int uc=ch;
+    if(ch>='0' && ch<='9'){ uc-='0'; } 
+    else {return 0;}
+    for(int i=0;i<7;i++){
+        if(TNS_LCD_MAP_7[uc][i]){
+            real* seg=TNS_LCD_SEG_7[i];
+            tnsVertex2d(tnsInterpolate(x,x+w,seg[0]),tnsInterpolate(y,y+h,seg[1]));
+            tnsVertex2d(tnsInterpolate(x,x+w,seg[2]),tnsInterpolate(y,y+h,seg[3]));
+        }
+    }
+    return 1;
+}
+int tnsMakeLCD16(real x, real y, real w, real h, int ch){
+    int uc=ch;
+    if(ch>='0' && ch<='9'){ uc-='0'; }
+    elif(ch>='A' && ch<='Z'){ uc-='A'; uc+=10; }
+    else {return 0;}
+    for(int i=0;i<16;i++){
+        if(TNS_LCD_MAP_16[uc][i]){
+            real* seg=TNS_LCD_SEG_16[i];
+            tnsVertex2d(tnsInterpolate(x,x+w,seg[0]),tnsInterpolate(y,y+h,seg[1]));
+            tnsVertex2d(tnsInterpolate(x,x+w,seg[2]),tnsInterpolate(y,y+h,seg[3]));
+        }
+    }
+    return 1;
+}
+void tnsDrawStringLCD(char *content, uint32_t* contentU, real Color[4], int L, int R, int T, int Flags){
+    real MA=FM->UsingFont->MonoAdvance;
+    real sx = L; int sy = T; real dx=MA; real hgap=LA_RH/15; real vgap=LA_RH/5;
+    int i,advance=1;
+    int len = contentU?strlenU(contentU):strlen(content);
+    int RevY=(Flags&LA_TEXT_REVERT_Y);
+    int OneLine=(Flags&LA_TEXT_ONE_LINE);
+    int Use16=(Flags&LA_TEXT_LCD_16);
+
+    tnsFlush();
+    tnsUseNoTexture();
+
+    int any=0, UC=1; int BreakNow=0;
+    for (i = 0; i < len && UC; i+=advance){
+        UC = contentU?contentU[i]:laToUnicode(&content[i], &advance);
+
+        if (UC == L'\n'){ if(!OneLine){sx = L; sy += LA_RH; continue;}else{ UC=' '; } }
+
+        if (sx + dx > R+1){
+            if(Flags&LA_TEXT_LINE_WRAP){ sx=L; sy+=LA_RH; }else{ break; }
+        }
+        
+        if(Use16){
+            if(tnsMakeLCD16(sx+hgap, sy+vgap, dx-hgap*2, LA_RH-vgap*2, UC)) any=1;
+        }else{
+            if(tnsMakeLCD7(sx+hgap, sy+vgap, dx-hgap*2, LA_RH-vgap*2, UC)) any=1;
+        }
+
+        sx += dx;
+        
+        if(BreakNow){ break; }
+    }
+    if(any){ tnsColor4dv(Color); tnsPackAs(GL_LINES); glLineWidth(dx/10); tnsFlush(); glLineWidth(1); }
+}
 void tnsDrawStringM(char *content, uint32_t* contentU, real Color[4], int L, int R, int T, int Flags){
+    if(Flags&(LA_TEXT_LCD_16|LA_TEXT_LCD_7)){
+        tnsDrawStringLCD(content,contentU,Color,L,R,T,Flags); return;
+    }
     real sx = L; int sy = (LA_RH!=LA_RH0)?(((((real)FM->UsingFont->height/LA_RH0-0.5)/MAIN.UiScale)+0.5)*LA_RH + T):(FM->UsingFont->height+T);
     real MA=FM->UsingFont->MonoAdvance;
     int i,advance=1;