Subversion Repositories Kolibri OS

Rev

Rev 5988 | 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. #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 pt;
  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.                 s = Cp866ToAnsi(s);
  147.                 EBX = block*s << 2 + font;
  148.                 for(yi=0; yi<height; yi++)
  149.                 {
  150.                         EDI = size.offset_y + yi + y * size.width * 3 + image_raw;
  151.                         for(xi=0; xi<width; xi++)
  152.                         {
  153.                                 IF(iii%32) $shr ecx,1
  154.                                 ELSE
  155.                                 {
  156.                                                 EBX += 4;
  157.                                                 ECX = DSDWORD[EBX];
  158.                                 }
  159.                                 IF(ECX&true)
  160.                                 {
  161.                                                 IF(xi>rw)rw=xi;
  162.                                                 ___x = x+xi;
  163.                                                 IF(italic)___x+=math.ceil(ital);
  164.                                                 offs = ___x*3 + EDI;
  165.                                                 DSDWORD[offs] = DSDWORD[offs] & 0xFF000000 | color;
  166.                                                 IF(bold) DSDWORD[offs+3] = DSDWORD[offs+3] & 0xFF000000 | color;
  167.                                 }
  168.                                 iii++;
  169.                         }
  170.                         if (italic) ital-=size.offset_i;
  171.                 }
  172.                 return rw;
  173. }
  174.  
  175. byte Cp866ToAnsi(byte s) {
  176.         IF(s>=128)&&(s<=175)s+=64;
  177.         ELSE IF(s>=224)&&(s<=239)s+=16;
  178.         ELSE IF(s==241)s=184; //yo
  179.         ELSE IF(s==240)s=168; //YO
  180.         return s;
  181. }
  182.  
  183. :byte LABEL::init(dword font_path)
  184. {
  185.         lib_init_fs();
  186.         IF(font)free(font);
  187.         IF(!fs.read(font_path)) {
  188.                 debug("Error while loading font: ");
  189.                 debugln(font_path);
  190.                 //io.run("/sys/@notify","'Error: Font is not loaded.' -E");
  191.                 return false;
  192.         }
  193.         font_begin = font = EAX;
  194.         EBX = font_begin + ECX;
  195.         height = DSBYTE[EBX-1];
  196.         width = DSBYTE[EBX-2];
  197.         block = math.ceil(height*width/32);
  198.         smooth = true;
  199.         return true;
  200. }
  201.  
  202.  
  203. /*=====================================================================================
  204. ===========================                                 ===========================
  205. ===========================               RAW               ===========================
  206. ===========================                                 ===========================
  207. =====================================================================================*/
  208.  
  209.  
  210. inline fastcall dword b24(EBX) { return DSDWORD[EBX] << 8; }
  211. :void LABEL::apply_smooth()
  212. {
  213.         dword i,line_w,to;
  214.         line_w = size.width * 3;
  215.         to = size.height - 1 * line_w + raw - 3;
  216.         for(i=raw; i < to; i+=3)
  217.         {
  218.                 IF(i-raw%line_w +3 == line_w) continue;
  219.                 IF(b24(i)==0x000000) && (b24(i+3)!=0x000000) && (b24(i+line_w)!=0x000000) && (b24(i+3+line_w)==0x000000)
  220.                 {
  221.                         ShadowPixel(i+3, 2);
  222.                         ShadowPixel(i+line_w, 2);
  223.                 }
  224.                 ELSE IF(b24(i)!=0x000000) && (b24(i+3)==0x000000) && (b24(i+line_w)==0x000000) && (b24(i+3+line_w)!=0x000000)
  225.                 {
  226.                         ShadowPixel(i, 2);
  227.                         ShadowPixel(i+3+line_w, 2);
  228.                 }
  229.         }
  230. }
  231.  
  232. :int LABEL::write_center(dword x,y,w,h; dword background, color1; byte fontSizePoints; dword txt)
  233. {
  234.         size.pt = fontSizePoints;
  235.         getsize(txt);
  236.         return write(w-size.width/2+x,y, background, color1, fontSizePoints, txt);
  237. }
  238.  
  239. :int LABEL::write(int x,y; dword background, color1; byte fontSizePoints; dword text1)
  240. {
  241.         signed len=0;
  242.         IF(!text1)return false;
  243.         IF(size.pt)IF(!changeSIZE())return false;
  244.         size.pt = fontSizePoints;
  245.         getsize(text1);
  246.         color = color1;
  247.         y -= size.offset_y;
  248.         EDX = size.width*size.height*3;
  249.         IF(!raw_size)
  250.         {
  251.                 raw_size = EDX;
  252.                 raw = malloc(raw_size);
  253.         }
  254.         ELSE IF(raw_size<EDX)
  255.         {
  256.                 raw_size = EDX;
  257.                 raw = realloc(raw,raw_size);
  258.         }
  259.         // Fill background color {
  260.         EBX = background;
  261.         EAX = raw_size+raw;
  262.         for (EDI=raw; EDI<EAX; EDI+=3) ESDWORD[EDI] = EBX;
  263.         // }
  264.         len = size.offset_x;
  265.         WHILE(DSBYTE[text1])
  266.         {
  267.                 IF(DSBYTE[text1]=='_') len--;
  268.                 len+=symbol(len,0,DSBYTE[text1], raw);
  269.                 IF(bold)len+=math.ceil(size.pt/17);
  270.                 text1++;
  271.         }
  272.         IF (smooth) apply_smooth();
  273.         show_buf(x,y);
  274.         return len;
  275. }
  276.  
  277. :void LABEL::write_buf(int x,y,w,h; dword background, color1; byte fontSizePoints; dword text1)
  278. {
  279.         dword new_raw_size;
  280.         IF(!text1)return;
  281.         IF(size.pt)IF(!changeSIZE())return;
  282.        
  283.         size.pt = fontSizePoints;
  284.         getsize(text1);
  285.         y -= size.offset_y;
  286.         color = color1;
  287.  
  288.         size.width = w;
  289.         size.height = h;
  290.  
  291.         new_raw_size = w*h*3;
  292.         IF(raw_size != new_raw_size)
  293.         {
  294.                 raw_size = new_raw_size;
  295.                 free(raw);
  296.                 raw = malloc(raw_size);
  297.                 // Fill background color
  298.                 EBX = background;
  299.                 EAX = raw_size+raw;
  300.                 for (EDI=raw; EDI<EAX; EDI+=3) ESDWORD[EDI] = EBX;
  301.         }
  302.         WHILE(DSBYTE[text1])
  303.         {
  304.                 x+=symbol(x,y,DSBYTE[text1], raw);
  305.                 IF(bold)x+=math.ceil(size.pt/17);
  306.                 text1++;
  307.         }
  308.         return;
  309. }
  310.  
  311. :void LABEL::show_buf(dword x, y){
  312.         _PutImage(x, y, size.width, size.height, raw);
  313. }
  314.  
  315.  
  316.  
  317. #endif