Subversion Repositories Kolibri OS

Rev

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