Subversion Repositories Kolibri OS

Rev

Rev 5783 | Blame | Last modification | View Log | Download | RSS feed

  1. #ifndef INCLUDE_FONT_H
  2. #define INCLUDE_FONT_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. :struct __SIZE
  13. {
  14.         word width,height;
  15.         signed offset_x,offset_y;
  16.         float offset_i,w_italic;
  17.         byte text;
  18.         byte TMP_WEIGHT;
  19. };
  20. :struct FONT
  21. {
  22.         __SIZE size;
  23.         byte r,g,b,weight,italic, smooth;
  24.         byte width,height;
  25.         byte encoding;
  26.         dword color;
  27.         dword file_size;
  28.         dword buffer;
  29.         dword buffer_size;
  30.         word block;
  31.         dword data;
  32.         dword begin;
  33.         byte load(...);
  34.         byte symbol(word x,y;byte s;dword c);
  35.         byte symbol_size(byte s);
  36.         dword prepare(word x,y;dword text1);
  37.         void prepare_buf(word x,y,w,h;dword text1);
  38.         void show(word x,y);
  39.         byte textcenter(word x,y,w,h;dword txt);
  40.         dword getsize(dword text1);
  41.         byte changeSIZE();
  42.         void PixelRGB(word x,y);
  43.         //dword GetPixel(word x,y);
  44.         byte no_bg_copy;
  45.         dword bg_color;
  46. };
  47. FONT font = 0;
  48. /*
  49. :dword FONT::GetPixel(word x,y)
  50. {
  51.         dword tmp = y*size.width*3;
  52.         tmp += x*3 + buffer;
  53.         r = DSBYTE[tmp]; tmp++;
  54.         g = DSBYTE[tmp]; tmp++;
  55.         b = DSBYTE[tmp];
  56. }*/
  57. :void FONT::PixelRGB(dword x,y)
  58. {
  59.         $push ebx
  60.         EBX = y*size.width+x*3 + buffer;
  61.         DSBYTE[EBX] = r; EBX++;
  62.         DSBYTE[EBX] = g; EBX++;
  63.         DSBYTE[EBX] = b;
  64.         $pop ebx
  65. }
  66. :byte FONT::changeSIZE()
  67. {
  68.         dword TMP_DATA;
  69.         dword ofs;
  70.         IF(size.text<9) size.text = 8;
  71.         TMP_DATA = data = begin;
  72.         TMP_DATA +=size.text-8*4;
  73.         ofs = DSDWORD[TMP_DATA];
  74.         IF(ofs==-1)return false;
  75.         data += ofs + 156;
  76.         TMP_DATA = data;
  77.         file_size = DSDWORD[TMP_DATA];
  78.         TMP_DATA = data + file_size;
  79.         height = DSBYTE[TMP_DATA - 1];
  80.         width =  DSBYTE[TMP_DATA - 2];
  81.         block = math.ceil(height*width/32);
  82.         return true;
  83. }
  84. :byte FONT::textcenter(word x,y,w,h;dword txt)
  85. {
  86.         getsize(txt);
  87.         EDX = w/2;
  88.         ECX = size.width/2;
  89.         EDX -= ECX;
  90.         x += EDX;
  91.         return text(x,y,txt);
  92. }
  93. :dword FONT::getsize(dword text1)
  94. {
  95.         size.height = size.width = 0;
  96.         size.offset_x = size.offset_y = -1;
  97.         IF(size.text)IF(!changeSIZE())return 0;
  98.         WHILE(DSBYTE[text1])
  99.         {
  100.                 symbol_size(DSBYTE[text1]);
  101.                 text1++;
  102.         }
  103.         $neg size.offset_y
  104.         $neg size.offset_x
  105.         size.height += size.offset_y; size.height++;
  106.         size.width += size.offset_x; size.width++;
  107.         IF(italic)
  108.         {
  109.                 size.w_italic = size.height/3;
  110.                 size.offset_i = size.w_italic/size.height;
  111.                 size.width += size.w_italic;
  112.                 size.w_italic = -size.w_italic;
  113.         }
  114.         return size.width;
  115. }
  116. :byte FONT::symbol_size(byte s)
  117. {
  118.         dword xi,yi;
  119.         dword tmp,_;
  120.         dword iii;
  121.         byte rw=0;
  122.                 byte X;
  123.                 size.TMP_WEIGHT = math.ceil(size.text/17);
  124.         IF(s==32)
  125.                 {
  126.                         size.width += width/4;
  127.                         IF(weight) size.width+=size.TMP_WEIGHT;
  128.                         return;
  129.                 }
  130.                 IF(s==9)
  131.                 {
  132.                         size.width += width;
  133.                         IF(weight) size.width+=size.TMP_WEIGHT;
  134.                         return;
  135.                 }
  136.                 IF(!encoding){
  137.                         IF(s>=128)&&(s<=175)s+=64;
  138.                         ELSE IF(s>=224)&&(s<=239)s+=16;
  139.                         ELSE IF(s==241)s=184; //yo
  140.                         ELSE IF(s==240)s=168; //YO
  141.                 }
  142.         iii = 0;
  143.         tmp = 4*block*s + data;
  144.         for(yi=0; yi<height; yi++)
  145.         {
  146.             for(xi=0; xi<width; xi++)
  147.             {
  148.                 IF(iii%32) _ >>= 1;
  149.                                 ELSE
  150.                                 {
  151.                         tmp += 4;
  152.                         _ = DSDWORD[tmp];
  153.                 }
  154.                 IF(_&1)
  155.                                 {
  156.                                         IF(xi>rw)rw=xi;
  157.                                         IF(size.height<yi)size.height = yi;
  158.                                         IF(size.offset_y<0)size.offset_y = yi;
  159.                                         ELSE IF(yi<size.offset_y)size.offset_y = yi;
  160.                                         IF(!X) X = xi;
  161.                                         ELSE IF(X>xi)X = xi;
  162.                                 }
  163.                 iii++;
  164.             }
  165.         }
  166.                 size.width += rw;
  167.                 IF(weight) size.width+=size.TMP_WEIGHT;
  168.                 IF(s=='_') size.width--;
  169.                 IF(size.offset_x<0)size.offset_x = X;
  170. }
  171. :dword FONT::prepare(word x,y;dword text1)
  172. {
  173.         signed len=0;
  174.         proc_info Form_SELF_FONTS;
  175.         dword c;
  176.         c = color;
  177.         IF(!text1)return false;
  178.         IF(size.text)IF(!changeSIZE())return false;
  179.         AX = c; r = AL; g = AH; c>>=16; AX = c; b = AL;
  180.         getsize(text1);
  181.         y -= size.offset_y;
  182.        
  183.         EDX = size.width*size.height*3;
  184.         IF(!buffer_size)
  185.         {
  186.                 buffer_size = EDX;
  187.                 buffer = malloc(buffer_size);
  188.         }
  189.         ELSE IF(buffer_size<EDX)
  190.         {
  191.                 buffer_size = EDX;
  192.                 buffer = realloc(buffer,buffer_size);
  193.         }
  194.         IF (no_bg_copy)
  195.         {
  196.                 EBX = bg_color;
  197.                 EDI = buffer;
  198.                 EAX = buffer_size+EDI;
  199.                 WHILE (EDI<EAX)
  200.                 {
  201.                         ESDWORD[EDI] = EBX;
  202.                         $add edi,3
  203.                 }
  204.         }
  205.         ELSE
  206.         {
  207.                 GetProcessInfo(#Form_SELF_FONTS, SelfInfo);
  208.                 CopyScreen(buffer,x+Form_SELF_FONTS.left+5,y+Form_SELF_FONTS.top+GetSkinHeight(),size.width,size.height);
  209.         }
  210.         len = size.offset_x;
  211.         WHILE(DSBYTE[text1])
  212.         {
  213.                 IF(DSBYTE[text1]=='_') len--;
  214.                 len+=symbol(len,0,DSBYTE[text1]);
  215.                 IF(weight)len+=math.ceil(size.text/17);
  216.                 text1++;
  217.         }
  218.         IF (no_bg_copy) && (!color) SmoothFont(buffer, size.width, size.height);
  219.         return len;
  220. }
  221. :void FONT::show(word x,y)
  222. {
  223.         _PutImage(x,y,size.width,size.height,buffer);
  224. }
  225. inline fastcall dword b24(EBX) { return DSDWORD[EBX] << 8; }
  226. :void SmoothFont(dword image, w, h)
  227. {
  228.         byte rr,gg,bb;
  229.         dword i,line_w,to, pixel;
  230.         line_w = w * 3;
  231.         to = w*h*3 + image - line_w - 3;
  232.         for (i = image; i < to; i+=3)   {
  233.                 if (i-image%line_w +3 == line_w) continue;
  234.                 if (b24(i)==0x000000) && (b24(i+3)!=0x000000) && (b24(i+line_w)!=0x000000) && (b24(i+3+line_w)==0x000000)
  235.                 {
  236.                         ShadowImage(i+3, 1, 1, 2);
  237.                         ShadowImage(i+line_w, 1, 1, 2);
  238.                 }
  239.                 else if (b24(i)!=0x000000) && (b24(i+3)==0x000000) && (b24(i+line_w)==0x000000) && (b24(i+3+line_w)!=0x000000)
  240.                 {
  241.                         ShadowImage(i, 1, 1, 2);
  242.                         ShadowImage(i+3+line_w, 1, 1, 2);
  243.                 }
  244.         }
  245. }
  246. :byte FONT::symbol(signed x,y;byte s)
  247. {
  248.         dword xi,yi;
  249.         dword tmp,_;
  250.         dword iii;
  251.                 float ital = -size.w_italic;
  252.                 dword ___x;
  253.                 word TMP;
  254.                 byte _TMP_WEIGHT;
  255.         byte rw=0;
  256.         IF(s==32)return width/4;
  257.                 IF(s==9)return width;
  258.                 IF(!encoding)
  259.                 {
  260.                         IF(s>=128)&&(s<=175)s+=64;
  261.                         ELSE IF(s>=224)&&(s<=239)s+=16;
  262.                         ELSE IF(s==241)s=184; //yo
  263.                         ELSE IF(s==240)s=168; //YO
  264.                 }
  265.         iii = 0;
  266.         tmp = 4*block*s + data;
  267.         for(yi=0; yi<height; yi++)
  268.         {
  269.                         TMP = size.offset_y+yi+y;
  270.             for(xi=0; xi<width; xi++)
  271.             {
  272.                                 IF(iii%32) _ >>= 1;
  273.                                 ELSE
  274.                                 {
  275.                                                 tmp += 4;
  276.                                                 _ = DSDWORD[tmp];
  277.                                 }
  278.                                 if(_&1)
  279.                                 {
  280.                                                 IF(xi>rw)rw=xi;
  281.                                                 ___x = x+xi;
  282.                                                 IF(italic)___x+=math.ceil(ital);
  283.                                                 PixelRGB(___x,TMP);
  284.                                                 for(_TMP_WEIGHT=size.TMP_WEIGHT; _TMP_WEIGHT; _TMP_WEIGHT--)
  285.                                                 {
  286.                                                         IF(weight) PixelRGB(___x+_TMP_WEIGHT,TMP);
  287.                                                 }
  288.                                 }
  289.                                 iii++;
  290.             }
  291.                         IF(italic) ital-=size.offset_i;
  292.         }
  293.         return rw;
  294. }
  295. :byte FONT::load(dword path)
  296. {
  297.         buffer_size = 0;
  298.         IF(data)free(data);
  299.         if (!io.readKPACK(path)) { debug("Error while loading font: "); debugln(path); return false; }
  300.         begin = data = io.buffer_data;
  301.         EBX = begin + io.FILES_SIZE;
  302.         height = DSBYTE[EBX - 1];
  303.         width = DSBYTE[EBX - 2];
  304.         block = math.ceil(height*width/32);
  305.         return true;
  306. }
  307.  
  308. :void FONT::prepare_buf(word x,y,w,h; dword text1)
  309. {
  310.         dword c;
  311.         c = color;
  312.         IF(!text1)return;
  313.         IF(size.text)IF(!changeSIZE())return;
  314.         AX = c; r = AL; g = AH; c>>=16; AX = c; b = AL;
  315.         getsize(text1);
  316.         y -= size.offset_y;
  317.        
  318.         size.width = w;
  319.         size.height = h;
  320.  
  321.         EDX = size.width*size.height*3;
  322.         if(buffer_size!=EDX)
  323.         {
  324.                 buffer_size = EDX;
  325.                 free(buffer);
  326.                 buffer = malloc(buffer_size);
  327.                 EBX = font.bg_color;
  328.                 EDI = font.buffer;
  329.                 EAX = font.buffer_size+font.buffer;
  330.                 WHILE (EDI<EAX)
  331.                 {
  332.                         ESDWORD[EDI] = EBX;
  333.                         $add edi,3
  334.                 }
  335.         }
  336.         WHILE(DSBYTE[text1])
  337.         {
  338.                 x+=symbol(x,y,DSBYTE[text1]);
  339.                 IF(weight)x+=math.ceil(size.text/17);
  340.                 text1++;
  341.         }
  342.         return;
  343. }
  344.  
  345. #endif