Subversion Repositories Kolibri OS

Rev

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