Subversion Repositories Kolibri OS

Rev

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