Subversion Repositories Kolibri OS

Rev

Rev 6786 | Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. #ifndef INCLUDE_LABEL_H
  2. #define INCLUDE_LABEL_H
  3.  
  4. #ifndef INCLUDE_MATH_H
  5. #include "../lib/math.h"
  6. #endif
  7.  
  8. #ifndef INCLUDE_IO_H
  9. #include "../lib/io.h"
  10. #endif
  11.  
  12. #include "../lib/patterns/rgb.h"
  13.  
  14.  
  15. #define DEFAULT_FONT "/sys/fonts/Tahoma.kf"
  16.  
  17. :struct __SIZE
  18. {
  19.         dword width,height;
  20.         signed offset_x, offset_y;
  21.         byte pt;
  22. };
  23. :struct LABEL
  24. {
  25.         __SIZE size;
  26.         int width,height;
  27.         byte bold,smooth;
  28.         dword color, background;
  29.         dword font,font_begin;
  30.         word block;
  31.         dword raw;
  32.         dword raw_size;
  33.  
  34.         byte init();
  35.         bool changeSIZE();
  36.         byte symbol();
  37.         byte symbol_size();
  38.         dword getsize();
  39.  
  40.         void ApplySmooth();
  41.         int WriteIntoWindow();
  42.         int WriteIntoWindowCenter();
  43.         void WriteIntoBuffer();
  44.         void show_buf();
  45. } label;
  46.  
  47. :bool LABEL::changeSIZE()
  48. {
  49.         dword file_size;
  50.         dword ofs;
  51.         if(size.pt<9) size.pt = 8;
  52.         font = font_begin;
  53.         ofs = DSDWORD[calc(size.pt-8<<2+font_begin)];
  54.         if(ofs==-1)return false;
  55.         font += ofs + 156;
  56.         file_size = DSDWORD[calc(font)];
  57.         height = DSBYTE[calc(font+file_size) - 1];
  58.         width =  DSBYTE[calc(font+file_size) - 2];
  59.         block = math.ceil(height*width/32);
  60.         return true;
  61. }
  62. :dword LABEL::getsize(dword text1)
  63. {
  64.         size.height = size.width = 0;
  65.         size.offset_x = size.offset_y = -1;
  66.         if(size.pt)if(!changeSIZE())return 0;
  67.         WHILE(DSBYTE[text1])
  68.         {
  69.                 symbol_size(DSBYTE[text1]);
  70.                 text1++;
  71.         }
  72.         $neg size.offset_y
  73.         $neg size.offset_x
  74.         size.height += size.offset_y+1;
  75.         size.width += size.offset_x+1;
  76.         return size.width;
  77. }
  78. :byte LABEL::symbol_size(byte s)
  79. {
  80.                 dword xi,yi;
  81.                 dword tmp,_;
  82.                 dword iii = 0;
  83.                 byte rw=0;
  84.                 byte X;
  85.                 if(bold) size.width+=math.ceil(size.pt/17);
  86.                 if(s==32)
  87.                 {
  88.                         size.width += width/4;
  89.                         return;
  90.                 }
  91.                 if(s==9)
  92.                 {
  93.                         size.width += width;
  94.                         return;
  95.                 }
  96.                 s = Cp866ToAnsi(s);
  97.                 tmp = block*s << 2 + font;
  98.                 for(yi=0; yi<height; yi++)
  99.                 {
  100.                         for(xi=0; xi<width; xi++)
  101.                         {
  102.                                 if(iii%32) _ >>= 1;
  103.                                 else
  104.                                 {
  105.                                         tmp += 4;
  106.                                         _ = DSDWORD[tmp];
  107.                                 }
  108.                                 if(_&1)
  109.                                 {
  110.                                         if(xi>rw)rw=xi;
  111.                                         if(size.height<yi)size.height = yi;
  112.                                         if(size.offset_y<0)size.offset_y = yi;
  113.                                         else if(yi<size.offset_y)size.offset_y = yi;
  114.                                         if(!X) X = xi;
  115.                                         else if(X>xi)X = xi;
  116.                                 }
  117.                                 iii++;
  118.                         }
  119.                 }
  120.                 size.width += rw;
  121.                 if(size.offset_x<0)size.offset_x = X;
  122. }
  123. :byte LABEL::symbol(signed x,y; byte s; dword image_raw)
  124. {
  125.                 dword xi,yi;
  126.                 dword iii = 0;
  127.                 dword offs;
  128.                 byte rw=0;
  129.                 if(s==32)return width/4;
  130.                 if(s==9)return width;
  131.                 s = Cp866ToAnsi(s);
  132.                 EBX = block*s << 2 + font;
  133.                 for(yi=0; yi<height; yi++)
  134.                 {
  135.                         EDI = size.offset_y + yi + y * size.width * 3 + image_raw;
  136.                         for(xi=0; xi<width; xi++)
  137.                         {
  138.                                 if(iii%32) $shr ecx,1
  139.                                 else
  140.                                 {
  141.                                                 EBX += 4;
  142.                                                 ECX = DSDWORD[EBX];
  143.                                 }
  144.                                 if(ECX&true)
  145.                                 {
  146.                                                 if(xi>rw)rw=xi;
  147.                                                 offs = x + xi *3 + EDI;
  148.                                                 DSDWORD[offs] = DSDWORD[offs] & 0xFF000000 | color;
  149.                                                 if(bold) DSDWORD[offs+3] = DSDWORD[offs+3] & 0xFF000000 | color;
  150.                                 }
  151.                                 iii++;
  152.                         }
  153.                 }
  154.                 return rw;
  155. }
  156.  
  157. inline fastcall Cp866ToAnsi(AL) {
  158.         if (AL>=128)&&(AL<=175) return AL+64;
  159.         if (AL>=224)&&(AL<=239) return AL+16;
  160.         if (AL==241) return 184; //e ruAL with dotAL (yo)
  161.         if (AL==240) return 168; //E ruAL with dotAL (yo)
  162.         if (AL==242) return 'E'; //E ukr (ye)
  163.         if (AL==243) return 186; //e ukr (ye)
  164.         if (AL==244) return 'I'; //I ukr (yi)
  165.         if (AL==245) return 191; //i ukr (yi)
  166.         return AL;
  167. }
  168.  
  169. :byte LABEL::init(dword font_path)
  170. {
  171.         IO label_io;
  172.         if(font)free(font);
  173.         label_io.read(font_path);
  174.         if(!EAX) {
  175.                 debugln(font_path);
  176.                 label_io.run("/sys/@notify", "'Error: KFONT is not loaded.' -E");
  177.                 return false;
  178.         }
  179.         font_begin = label_io.buffer_data;
  180.         size.pt = 9;
  181.         changeSIZE();
  182.         smooth = true;
  183.         return true;
  184. }
  185.  
  186.  
  187. /*=====================================================================================
  188. ===========================                                 ===========================
  189. ===========================               RAW               ===========================
  190. ===========================                                 ===========================
  191. =====================================================================================*/
  192.  
  193.  
  194. inline fastcall dword b24(EAX) { return DSDWORD[EAX] & 0x00FFFFFF; }
  195. :void LABEL::ApplySmooth()
  196. {
  197.         dword i,line_w,to,dark_background;
  198.         line_w = size.width * 3;
  199.         to = size.height - 1 * line_w + raw - 3;
  200.         for(i=raw; i < to; i+=3)
  201.         {
  202.                 if(i-raw%line_w +3 == line_w) continue;
  203.                 // pixels position, where b - black, w - write
  204.                 // bw
  205.                 // wb
  206.                 if(b24(i)!=background) && (b24(i+3)==background) && (b24(i+line_w)==background) && (b24(i+3+line_w)!=background)
  207.                 {
  208.                         dark_background = MixColors(background,b24(i),210);
  209.                         DSDWORD[i+3] = DSDWORD[i+3] & 0xFF000000 | dark_background;
  210.                         DSDWORD[i+line_w] = DSDWORD[i+line_w] & 0xFF000000 | dark_background;                  
  211.                 }
  212.                 // wb
  213.                 // bw
  214.                 else if(b24(i)==background) && (b24(i+3)!=background) && (b24(i+line_w)!=background) && (b24(i+3+line_w)==background)
  215.                 {
  216.                         dark_background = MixColors(background,b24(i+3),210);
  217.                         DSDWORD[i] = DSDWORD[i] & 0xFF000000 | dark_background;
  218.                         DSDWORD[i+3+line_w] = DSDWORD[i+3+line_w] & 0xFF000000 | dark_background;
  219.                 }
  220.         }
  221. }
  222.  
  223. :int LABEL::WriteIntoWindowCenter(dword x,y,w,h; dword _background, _color; byte fontSizePoints; dword txt)
  224. {
  225.         size.pt = fontSizePoints;
  226.         getsize(txt);
  227.         return WriteIntoWindow(w-size.width/2+x,y, _background, _color, fontSizePoints, txt);
  228. }
  229.  
  230. :int LABEL::WriteIntoWindow(int x,y; dword _background, _color; byte fontSizePoints; dword text1)
  231. {
  232.         signed len=0;
  233.         if(!text1)return false;
  234.         if(size.pt)if(!changeSIZE())return false;
  235.         size.pt = fontSizePoints;
  236.         getsize(text1);
  237.         color = _color;
  238.         background = _background;
  239.         y -= size.offset_y;
  240.         EDX = size.width*size.height*3;
  241.         if(!raw_size)
  242.         {
  243.                 raw_size = EDX;
  244.                 raw = malloc(raw_size);
  245.         }
  246.         else if(raw_size<EDX)
  247.         {
  248.                 raw_size = EDX;
  249.                 raw = realloc(raw,raw_size);
  250.         }
  251.         // Fill background color {
  252.         EBX = background;
  253.         EAX = raw_size+raw;
  254.         for (EDI=raw; EDI<EAX; EDI+=3) ESDWORD[EDI] = EBX;
  255.         // }
  256.         len = size.offset_x;
  257.         WHILE(DSBYTE[text1])
  258.         {
  259.                 len+=symbol(len,0,DSBYTE[text1], raw);
  260.                 if(bold)len+=math.ceil(size.pt/17);
  261.                 text1++;
  262.         }
  263.         IF (smooth) ApplySmooth();
  264.         show_buf(x,y);
  265.         return len;
  266. }
  267.  
  268. :void LABEL::WriteIntoBuffer(int x,y,w,h; dword _background, _color; byte fontSizePoints; dword text1)
  269. {
  270.         dword new_raw_size;
  271.         if(!text1)return;
  272.         if(size.pt)if(!changeSIZE())return;
  273.        
  274.         if (size.pt != fontSizePoints) {
  275.                 size.pt = fontSizePoints;
  276.                 getsize(text1);
  277.                 y -= size.offset_y;
  278.         }
  279.         color = _color;
  280.         background = _background;
  281.  
  282.         size.width = w;
  283.         size.height = h;
  284.  
  285.         new_raw_size = w*h*3;
  286.         if(raw_size != new_raw_size)
  287.         {
  288.                 raw_size = new_raw_size;
  289.                 free(raw);
  290.                 raw = malloc(raw_size);
  291.                 // Fill background color
  292.                 EBX = background;
  293.                 EAX = raw_size+raw;
  294.                 for (EDI=raw; EDI<EAX; EDI+=3) ESDWORD[EDI] = EBX;
  295.         }
  296.         WHILE(DSBYTE[text1])
  297.         {
  298.                 x+=symbol(x,y,DSBYTE[text1], raw);
  299.                 if(bold)x+=math.ceil(size.pt/17);
  300.                 text1++;
  301.         }
  302.         return;
  303. }
  304.  
  305. :void LABEL::show_buf(dword x, y){
  306.         _PutImage(x, y, size.width, size.height, raw);
  307. }
  308.  
  309.  
  310.  
  311. #endif