Subversion Repositories Kolibri OS

Rev

Rev 6264 | 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--; //http://board.kolibrios.org/viewtopic.php?f=44&t=973&start=645
  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; //e rus with dots (yo)
  182.         ELSE IF(s==240)s=168; //E rus with dots (yo)
  183.         ELSE IF(s==242)s='E'; //E urk (ye)
  184.         ELSE IF(s==243)s=186; //e urk (ye)
  185.         ELSE IF(s==244)s='I'; //I urk (yi)
  186.         ELSE IF(s==245)s=191; //i urk (yi)
  187.         return s;
  188. }
  189.  
  190. :byte LABEL::init(dword font_path)
  191. {
  192.         lib_init_fs();
  193.         IF(font)free(font);
  194.         IF(!fs.read(font_path)) {
  195.                 debug("Error while loading font: ");
  196.                 debugln(font_path);
  197.                 //io.run("/sys/@notify","'Error: Font is not loaded.' -E");
  198.                 return false;
  199.         }
  200.         font_begin = font = EAX;
  201.         EBX = font_begin + ECX;
  202.         height = DSBYTE[EBX-1];
  203.         width = DSBYTE[EBX-2];
  204.         block = math.ceil(height*width/32);
  205.         smooth = true;
  206.         return true;
  207. }
  208.  
  209.  
  210. /*=====================================================================================
  211. ===========================                                 ===========================
  212. ===========================               RAW               ===========================
  213. ===========================                                 ===========================
  214. =====================================================================================*/
  215.  
  216.  
  217. inline fastcall dword b24(EAX) { return DSDWORD[EAX] & 0x00FFFFFF; }
  218. :void LABEL::apply_smooth()
  219. {
  220.         dword i,line_w,to,dark_background;
  221.         line_w = size.width * 3;
  222.         to = size.height - 1 * line_w + raw - 3;
  223.         for(i=raw; i < to; i+=3)
  224.         {
  225.                 if(i-raw%line_w +3 == line_w) continue;
  226.                 // pixels position, where b - black, w - write
  227.                 // bw
  228.                 // wb
  229.                 if(b24(i)!=background) && (b24(i+3)==background) && (b24(i+line_w)==background) && (b24(i+3+line_w)!=background)
  230.                 {
  231.                         dark_background = MixColors(background,b24(i),210);
  232.                         DSDWORD[i+3] = DSDWORD[i+3] & 0xFF000000 | dark_background;
  233.                         DSDWORD[i+line_w] = DSDWORD[i+line_w] & 0xFF000000 | dark_background;                  
  234.                 }
  235.                 // wb
  236.                 // bw
  237.                 else if(b24(i)==background) && (b24(i+3)!=background) && (b24(i+line_w)!=background) && (b24(i+3+line_w)==background)
  238.                 {
  239.                         dark_background = MixColors(background,b24(i+3),210);
  240.                         DSDWORD[i] = DSDWORD[i] & 0xFF000000 | dark_background;
  241.                         DSDWORD[i+3+line_w] = DSDWORD[i+3+line_w] & 0xFF000000 | dark_background;
  242.                 }
  243.         }
  244. }
  245.  
  246. :int LABEL::write_center(dword x,y,w,h; dword _background, _color; byte fontSizePoints; dword txt)
  247. {
  248.         size.pt = fontSizePoints;
  249.         getsize(txt);
  250.         return write(w-size.width/2+x,y, _background, _color, fontSizePoints, txt);
  251. }
  252.  
  253. :int LABEL::write(int x,y; dword _background, _color; byte fontSizePoints; dword text1)
  254. {
  255.         signed len=0;
  256.         IF(!text1)return false;
  257.         IF(size.pt)IF(!changeSIZE())return false;
  258.         size.pt = fontSizePoints;
  259.         getsize(text1);
  260.         color = _color;
  261.         background = _background;
  262.         y -= size.offset_y;
  263.         EDX = size.width*size.height*3;
  264.         IF(!raw_size)
  265.         {
  266.                 raw_size = EDX;
  267.                 raw = malloc(raw_size);
  268.         }
  269.         ELSE IF(raw_size<EDX)
  270.         {
  271.                 raw_size = EDX;
  272.                 raw = realloc(raw,raw_size);
  273.         }
  274.         // Fill background color {
  275.         EBX = background;
  276.         EAX = raw_size+raw;
  277.         for (EDI=raw; EDI<EAX; EDI+=3) ESDWORD[EDI] = EBX;
  278.         // }
  279.         len = size.offset_x;
  280.         WHILE(DSBYTE[text1])
  281.         {
  282.                 //IF(DSBYTE[text1]=='_') len--; //http://board.kolibrios.org/viewtopic.php?f=44&t=973&start=645
  283.                 len+=symbol(len,0,DSBYTE[text1], raw);
  284.                 IF(bold)len+=math.ceil(size.pt/17);
  285.                 text1++;
  286.         }
  287.         IF (smooth) apply_smooth();
  288.         show_buf(x,y);
  289.         return len;
  290. }
  291.  
  292. :void LABEL::write_buf(int x,y,w,h; dword _background, _color; byte fontSizePoints; dword text1)
  293. {
  294.         dword new_raw_size;
  295.         IF(!text1)return;
  296.         IF(size.pt)IF(!changeSIZE())return;
  297.        
  298.         if (size.pt != fontSizePoints) {
  299.                 size.pt = fontSizePoints;
  300.                 getsize(text1);
  301.                 y -= size.offset_y;
  302.         }
  303.         color = _color;
  304.         background = _background;
  305.  
  306.         size.width = w;
  307.         size.height = h;
  308.  
  309.         new_raw_size = w*h*3;
  310.         IF(raw_size != new_raw_size)
  311.         {
  312.                 raw_size = new_raw_size;
  313.                 free(raw);
  314.                 raw = malloc(raw_size);
  315.                 // Fill background color
  316.                 EBX = background;
  317.                 EAX = raw_size+raw;
  318.                 for (EDI=raw; EDI<EAX; EDI+=3) ESDWORD[EDI] = EBX;
  319.         }
  320.         WHILE(DSBYTE[text1])
  321.         {
  322.                 x+=symbol(x,y,DSBYTE[text1], raw);
  323.                 IF(bold)x+=math.ceil(size.pt/17);
  324.                 text1++;
  325.         }
  326.         return;
  327. }
  328.  
  329. :void LABEL::show_buf(dword x, y){
  330.         _PutImage(x, y, size.width, size.height, raw);
  331. }
  332.  
  333.  
  334.  
  335. #endif