Subversion Repositories Kolibri OS

Rev

Rev 5025 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1.  
  2. #include <stdint.h>
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <math.h>
  6. #include <ft2build.h>
  7. #include FT_FREETYPE_H
  8. #include FT_GLYPH_H
  9. #include <pixlib2.h>
  10.  
  11. typedef struct
  12. {
  13.   int  l;
  14.   int  t;
  15.   int  r;
  16.   int  b;
  17. }rect_t;
  18.  
  19. typedef struct
  20. {
  21.     FT_Face face;
  22.     int     height;
  23.     int     base;
  24.  
  25.     FT_Glyph glyph[256];
  26.  
  27. }font_t;
  28.  
  29. static FT_Face def_face;
  30.  
  31. typedef unsigned int color_t;
  32.  
  33. unsigned int ansi2utf32(unsigned char ch);
  34.  
  35. font_t *create_font(FT_Face face, int size);
  36.  
  37. void my_draw_bitmap(bitmap_t *win, FT_Bitmap *bitmap, int dstx, int dsty, int col)
  38. {
  39.     uint8_t *dst;
  40.     uint8_t *src, *tmpsrc;
  41.  
  42.     uint32_t  *tmpdst;
  43.     int i, j;
  44.  
  45.     dst = win->data + dsty * win->pitch + dstx*4;
  46.     src = bitmap->buffer;
  47.  
  48. //    printf("buffer %x width %d rows %d\n",
  49. //            bitmap->buffer, bitmap->width, bitmap->rows);
  50.  
  51.  
  52.     for( i = 0; i < bitmap->rows; i++ )
  53.     {
  54.         tmpdst = (uint32_t*)dst;
  55.         tmpsrc = src;
  56.  
  57.         dst+= win->pitch;
  58.         src+= bitmap->pitch;
  59.  
  60.         for( j = 0; j < bitmap->width; j++)
  61.         {
  62.             int a = *tmpsrc++;
  63.             int sr, sg, sb;
  64.             int dr, dg, db;
  65.  
  66.             if( a != 0) a++;
  67.  
  68.             db = *tmpdst & 0xFF;
  69.             dg = (*tmpdst >> 8) & 0xFF;
  70.             dr = (*tmpdst >> 16) & 0xFF;
  71.  
  72.             sb = col & 0xFF;
  73.             sg = (col >> 8) & 0xFF;
  74.             sr = (col >> 16) &0xFF;
  75.  
  76.             db = (a*sb + db*(256-a))/256;
  77.             dg = (a*sg + dg*(256-a))/256;
  78.             dr = (a*sr + dr*(256-a))/256;
  79.  
  80.             *tmpdst++ = 0xFF000000|(dr<<16)|(dg<<8)|db;
  81.         };
  82.     }
  83. };
  84.  
  85.  
  86. int draw_text_ext(bitmap_t *winbitmap, font_t *font, char *text, int len, rect_t *rc, int color)
  87. {
  88.     FT_UInt glyph_index;
  89.     FT_Bool use_kerning = 0;
  90.     FT_BitmapGlyph  glyph;
  91.     FT_UInt previous;
  92.  
  93.     int x, y, w;
  94.     int col, ncol;
  95.     unsigned char ch;
  96.     int err = 0;
  97.  
  98.     use_kerning = FT_HAS_KERNING( font->face );
  99.     previous = 0;
  100.     col = 0;
  101.  
  102.     x = rc->l << 6;
  103.     y = rc->b;
  104.  
  105.     w = (rc->r - rc->l) << 6;
  106.  
  107.     while( len-- )
  108.     {
  109.         ch = *text++;
  110.  
  111.         if(ch == '\n' || ch == '\r')
  112.             continue;
  113.  
  114.         if(ch == '\t')
  115.         {
  116.             ncol = (col+4) & ~3;
  117.             if( col < ncol)
  118.             {
  119.                 glyph_index = FT_Get_Char_Index( font->face, ansi2utf32(' ') );
  120.  
  121.                 while( col < ncol)
  122.                 {
  123.                     if ( use_kerning && previous && glyph_index )
  124.                     {
  125.                         FT_Vector delta;
  126.                         FT_Get_Kerning( font->face, previous, glyph_index, FT_KERNING_DEFAULT, &delta );
  127.                         x += delta.x ;
  128.                     }
  129.  
  130.                     if( x + (font->glyph[ch]->advance.x >> 10) > w)
  131.                         break;
  132.  
  133.                     x += font->glyph[ch]->advance.x >> 10;
  134.                     previous = glyph_index;
  135.                     col ++;
  136.                 };
  137.             };
  138.             continue;
  139.         };
  140.  
  141.         glyph_index = FT_Get_Char_Index( font->face, ansi2utf32(ch) );
  142.  
  143.         if ( use_kerning && previous && glyph_index )
  144.         {
  145.             FT_Vector delta;
  146.             FT_Get_Kerning( font->face, previous, glyph_index, FT_KERNING_DEFAULT, &delta );
  147.             x += delta.x ;
  148.         }
  149.  
  150.         if( x + (font->glyph[ch]->advance.x >> 10) > w)
  151.             break;
  152.  
  153.         glyph = (FT_BitmapGlyph)font->glyph[ch];
  154.  
  155.         my_draw_bitmap(winbitmap, &glyph->bitmap, (x >> 6) + glyph->left,
  156.                         y - glyph->top, color);
  157.  
  158.         x += font->glyph[ch]->advance.x >> 10;
  159.         previous = glyph_index;
  160.     };
  161.  
  162.     return err;
  163. };
  164.  
  165.  
  166. int init_fontlib()
  167. {
  168.     static FT_Library library;
  169.     FT_Face face = NULL;
  170.     int err;
  171.  
  172.     err = FT_Init_FreeType( &library );
  173.     if ( err )
  174.     {
  175.         printf("an error occurred during FreeType initialization\n");
  176.         goto done;
  177.     }
  178.  
  179.     err = FT_New_Face( library, "/kolibrios/Fonts/IstokWeb.ttf", 0, &face );
  180. //    err = FT_New_Face( library, "/kolibrios/Fonts/lucon.ttf", 0, &face );
  181.     if ( err == FT_Err_Unknown_File_Format )
  182.     {
  183.         printf("font format is unsupported\n");
  184.         goto done;
  185.  
  186.     }
  187.     else if ( err )
  188.     {
  189.         printf("font file could not be read or broken\n");
  190.         goto done;
  191.  
  192.     }
  193.  
  194.     def_face = face;
  195.  
  196. done:
  197.  
  198.     return err;
  199. };
  200.  
  201.  
  202. unsigned int ansi2utf32(unsigned char ch)
  203. {
  204.     if(ch < 0x80)
  205.         return ch;
  206.  
  207.     if(ch < 0xB0)
  208.         return 0x410-0x80 + ch;
  209.  
  210.     if(ch < 0xE0)
  211.         return 0;
  212.  
  213.     if(ch < 0xF0)
  214.         return 0x440-0xE0 + ch;
  215.  
  216.     if(ch == 0xF0)
  217.         return 0x401;
  218.     else if(ch==0xF1)
  219.         return 0x451;
  220.     else return 0;
  221. }
  222.  
  223.  
  224. font_t *create_font(FT_Face xface, int size)
  225. {
  226.     font_t *font;
  227.     int i, err;
  228.  
  229.     font = malloc(sizeof(*font));
  230.     if(font == NULL)
  231.         return font;
  232.  
  233.     memset(font, 0, sizeof(*font));
  234.  
  235.     font->face = (xface == NULL) ? def_face : xface;
  236.     font->height = size;
  237.  
  238.     err = FT_Set_Pixel_Sizes( font->face, 0, size );
  239.  
  240.     for(i = 0; i < 256; i++)
  241.     {
  242.         FT_UInt glyph_index;
  243.         FT_BitmapGlyph  glyph_bitmap;
  244.  
  245.         glyph_index = FT_Get_Char_Index( font->face, ansi2utf32(i) );
  246.  
  247.         err = FT_Load_Glyph( font->face, glyph_index, FT_LOAD_DEFAULT );
  248.         if ( err )
  249.         {
  250.             font->glyph[i] = font->glyph[0] ;
  251.             continue;
  252.         };
  253.  
  254.         err = FT_Get_Glyph( font->face->glyph, &font->glyph[i] );
  255.         if (err)
  256.         {
  257.             font->glyph[i] = font->glyph[0] ;
  258.             continue;
  259.         };
  260.  
  261.         if ( font->glyph[i]->format != FT_GLYPH_FORMAT_BITMAP )
  262.         {
  263.             err = FT_Glyph_To_Bitmap( &font->glyph[i], FT_RENDER_MODE_NORMAL, 0, 1 );
  264.             if ( err )
  265.                 continue;
  266.  
  267.             glyph_bitmap = (FT_BitmapGlyph)font->glyph[i];
  268.  
  269.             if(glyph_bitmap->top > font->base)
  270.                 font->base = glyph_bitmap->top;
  271.         }
  272.     }
  273.  
  274.     return font;
  275. }
  276.