Subversion Repositories Kolibri OS

Rev

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