Subversion Repositories Kolibri OS

Rev

Rev 6803 | Rev 6806 | Go to most recent revision | Blame | Compare with Previous | 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 ShowBuffer();
  45. } label;
  46.  
  47. :bool LABEL::changeSIZE()
  48. {
  49.         dword file_size;
  50.         dword ofs;
  51.         if(size.pt<9) size.pt = 9;
  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(byte fontSizePoints, dword text1)
  63. {
  64.         size.height = size.width = 0;
  65.         size.offset_x = size.offset_y = -1;
  66.         size.pt = fontSizePoints;
  67.         if(size.pt)if(!changeSIZE())return 0;
  68.         WHILE(DSBYTE[text1])
  69.         {
  70.                 symbol_size(DSBYTE[text1]);
  71.                 text1++;
  72.         }
  73.         $neg size.offset_y
  74.         $neg size.offset_x
  75.         size.height += size.offset_y+1;
  76.         size.width += size.offset_x+1;
  77.         return size.width;
  78. }
  79. :byte LABEL::symbol_size(byte s)
  80. {
  81.         //return symbol_size(s);
  82.         dword xi,yi;
  83.         dword tmp,_;
  84.         dword iii = 0;
  85.         byte rw=0;
  86.         byte X;
  87.         if(bold) size.width+=math.ceil(size.pt/17);
  88.         if(s==32)
  89.         {
  90.                 size.width += width/4;
  91.                 return;
  92.         }
  93.         if(s==9)
  94.         {
  95.                 size.width += width;
  96.                 return;
  97.         }
  98.         s = Cp866ToAnsi(s);
  99.         tmp = block*s << 2 + font;
  100.         for(yi=0; yi<height; yi++)
  101.         {
  102.                 for(xi=0; xi<width; xi++)
  103.                 {
  104.                         if(iii%32) _ >>= 1;
  105.                         else
  106.                         {
  107.                                 tmp += 4;
  108.                                 _ = DSDWORD[tmp];
  109.                         }
  110.                         if(_&1)
  111.                         {
  112.                                 if(xi>rw)rw=xi;
  113.                                 if(size.height<yi)size.height = yi;
  114.                                 if(size.offset_y<0)size.offset_y = yi;
  115.                                 else if(yi<size.offset_y)size.offset_y = yi;
  116.                                 if(!X) X = xi;
  117.                                 else if(X>xi)X = xi;
  118.                         }
  119.                         iii++;
  120.                 }
  121.         }
  122.         size.width += rw;
  123.         if(size.offset_x<0)size.offset_x = X;
  124. }
  125. :byte LABEL::symbol(signed x,y; byte s; dword image_raw)
  126. {
  127.         dword xi,yi;
  128.         dword iii = 0;
  129.         dword offs;
  130.         byte rw=0;
  131.         if(s==32)return width/4;
  132.         if(s==9)return width;
  133.         s = Cp866ToAnsi(s);
  134.         EBX = block*s << 2 + font;
  135.         for(yi=0; yi<height; yi++)
  136.         {
  137.                 EDI = size.offset_y + yi + y * size.width * 3 + image_raw;
  138.                 for(xi=0; xi<width; xi++)
  139.                 {
  140.                         if(iii%32) $shr ecx,1
  141.                         else
  142.                         {
  143.                                         EBX += 4;
  144.                                         ECX = DSDWORD[EBX];
  145.                         }
  146.                         if(ECX&true)
  147.                         {
  148.                                         if(xi>rw)rw=xi;
  149.                                         offs = x + xi *3 + EDI;
  150.                                         DSDWORD[offs] = DSDWORD[offs] & 0xFF000000 | color;
  151.                                         if(bold) DSDWORD[offs+3] = DSDWORD[offs+3] & 0xFF000000 | color;
  152.                         }
  153.                         iii++;
  154.                 }
  155.         }
  156.         return rw;
  157. }
  158.  
  159. inline fastcall Cp866ToAnsi(AL) {
  160.         if (AL>=128)&&(AL<=175) return AL+64;
  161.         if (AL>=224)&&(AL<=239) return AL+16;
  162.         if (AL==241) return 184; //e ruAL with dotAL (yo)
  163.         if (AL==240) return 168; //E ruAL with dotAL (yo)
  164.         if (AL==242) return 'E'; //E ukr (ye)
  165.         if (AL==243) return 186; //e ukr (ye)
  166.         if (AL==244) return 'I'; //I ukr (yi)
  167.         if (AL==245) return 191; //i ukr (yi)
  168.         return AL;
  169. }
  170.  
  171. :byte LABEL::init(dword font_path)
  172. {
  173.         IO label_io;
  174.         if(font)free(font);
  175.         label_io.read(font_path);
  176.         if(!EAX) {
  177.                 debugln(font_path);
  178.                 label_io.run("/sys/@notify", "'Error: KFONT is not loaded.' -E");
  179.                 return false;
  180.         }
  181.         font_begin = label_io.buffer_data;
  182.         changeSIZE();
  183.         smooth = true;
  184.         return true;
  185. }
  186.  
  187.  
  188. /*=====================================================================================
  189. ===========================                                 ===========================
  190. ===========================               RAW               ===========================
  191. ===========================                                 ===========================
  192. =====================================================================================*/
  193.  
  194.  
  195. inline fastcall dword b24(EAX) { return DSDWORD[EAX] & 0x00FFFFFF; }
  196. :void LABEL::ApplySmooth()
  197. {
  198.         dword i,line_w,to,dark_background;
  199.         line_w = size.width * 3;
  200.         to = size.height - 1 * line_w + raw - 3;
  201.         for(i=raw; i < to; i+=3)
  202.         {
  203.                 if(i-raw%line_w +3 == line_w) continue;
  204.                 // pixels position, where b - black, w - write
  205.                 // bw
  206.                 // wb
  207.                 if(b24(i)!=background) && (b24(i+3)==background) && (b24(i+line_w)==background) && (b24(i+3+line_w)!=background)
  208.                 {
  209.                         dark_background = MixColors(background,b24(i),210);
  210.                         DSDWORD[i+3] = DSDWORD[i+3] & 0xFF000000 | dark_background;
  211.                         DSDWORD[i+line_w] = DSDWORD[i+line_w] & 0xFF000000 | dark_background;                  
  212.                 }
  213.                 // wb
  214.                 // bw
  215.                 else if(b24(i)==background) && (b24(i+3)!=background) && (b24(i+line_w)!=background) && (b24(i+3+line_w)==background)
  216.                 {
  217.                         dark_background = MixColors(background,b24(i+3),210);
  218.                         DSDWORD[i] = DSDWORD[i] & 0xFF000000 | dark_background;
  219.                         DSDWORD[i+3+line_w] = DSDWORD[i+3+line_w] & 0xFF000000 | dark_background;
  220.                 }
  221.         }
  222. }
  223.  
  224. :void LABEL::WriteIntoBuffer(int x,y,w,h; dword _background, _color; byte fontSizePoints; dword text1)
  225. {
  226.         dword new_raw_size;
  227.         if(!text1)return;
  228.         if(size.pt)if(!changeSIZE())return;
  229.        
  230.         if (size.pt != fontSizePoints) {
  231.                 getsize(fontSizePoints, text1);
  232.                 y -= size.offset_y;
  233.         }
  234.         color = _color;
  235.         background = _background;
  236.  
  237.         size.width = w;
  238.         size.height = h;
  239.  
  240.         new_raw_size = w*h*3;
  241.         if(raw_size != new_raw_size)
  242.         {
  243.                 raw_size = new_raw_size;
  244.                 free(raw);
  245.                 raw = malloc(raw_size);
  246.                 // Fill background color
  247.                 EBX = background;
  248.                 EAX = raw_size+raw;
  249.                 for (EDI=raw; EDI<EAX; EDI+=3) ESDWORD[EDI] = EBX;
  250.         }
  251.         WHILE(DSBYTE[text1])
  252.         {
  253.                 x+=symbol(x,y,DSBYTE[text1], raw);
  254.                 if(bold)x+=math.ceil(size.pt/17);
  255.                 text1++;
  256.         }
  257.         return;
  258. }
  259.  
  260. :int LABEL::WriteIntoWindow(int x,y; dword _background, _color; byte fontSizePoints; dword text1)
  261. {
  262.         if(!text1)return 0;
  263.         getsize(fontSizePoints, text1);
  264.         raw_size = NULL;
  265.         WriteIntoBuffer(0, -size.offset_y, size.width-size.offset_x,
  266.                 size.height-size.offset_y, _background, _color, fontSizePoints, text1);
  267.         if (smooth) ApplySmooth();
  268.         ShowBuffer(x,y);
  269.         return size.offset_x + size.width;
  270. }
  271.  
  272. :int LABEL::WriteIntoWindowCenter(dword x,y,w,h; dword _background, _color; byte fontSizePoints; dword text1)
  273. {
  274.         getsize(fontSizePoints, text1);
  275.         return WriteIntoWindow(w-size.width/2+x,y, _background, _color, fontSizePoints, text1);
  276. }
  277.  
  278. :void LABEL::ShowBuffer(dword x, y){
  279.         _PutImage(x, y, size.width, size.height, raw);
  280. }
  281.  
  282.  
  283.  
  284. #endif