Subversion Repositories Kolibri OS

Rev

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