Subversion Repositories Kolibri OS

Rev

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