Subversion Repositories Kolibri OS

Rev

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