Subversion Repositories Kolibri OS

Rev

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