Changeset 3730 in project


Ignore:
Timestamp:
04/03/07 17:11:00 (14 years ago)
Author:
thu
Message:

beginning of unicode support -- code need to be cleaned

Location:
gl-font
Files:
1 added
3 edited

Legend:

Unmodified
Added
Removed
  • gl-font/gl-font.scm

    r3620 r3730  
    1414    gl-font:create
    1515    gl-font:create-from-path
     16    gl-font:create-from-path/ascii
    1617    gl-font:print
    17     gl-font:print-escapes
     18    gl-font:print/ansi
     19    gl-font:print/ascii
    1820
    1921    textured-square-xy
     
    2830  (foreign-lambda void "create_font"))
    2931(define gl-font:create-from-path
    30   (foreign-lambda void "create_font_from_path" c-string))
    31 (define gl-font:print
    32   (foreign-lambda void "gl_print" c-string))
    33 (define gl-font:print-escapes
    34   (foreign-lambda void "gl_print_escapes" c-string))
     32  (foreign-lambda c-pointer "create_font_from_path" c-string))
     33(define gl-font:create-from-path/ascii
     34  (foreign-lambda void "create_font_from_path_ascii" c-string))
     35(define gl-font:print/ascii                                    ; ascii
     36  (foreign-lambda void "gl_print_ascii" c-string))
     37(define gl-font:print/ansi                                     ; ascii with ansi escape codes
     38  (foreign-lambda void "gl_print_ansi" c-string))
     39(define gl-font:print                                          ; unicode with ansi escape codes
     40  (foreign-lambda void "gl_print" c-pointer c-string))
    3541
    3642;
  • gl-font/gl_font.c

    r3620 r3730  
    1212#include <string.h>
    1313#include <math.h>
    14 
    15 
    16 #include <ft2build.h>
    17 #include FT_FREETYPE_H
    18 #include FT_GLYPH_H
     14#include <wchar.h>
     15#include <locale.h>
     16
    1917
    2018#include "gl_font.h"
     
    2220#define WIDTH   512
    2321#define HEIGHT  512
     22
     23static FT_Library ft_library;
     24static int ft_library_initialized_flag = 0;
    2425
    2526/* The image is stored upside-down: the first byte is the
     
    4142}
    4243
    43 /* glyph_info_t holds information
    44  * about glyph's position in the glyphs buffer.
    45  * Stolen from fltk.
    46  */
    47 typedef struct glyph_info_s
    48 {
    49   int x, y, w, h;   /* location of the pixmap in memory */
    50   int left, bottom; /* corner of the pixmap relative to glyph origin */
    51   float advance;    /* x advance value */
    52 } glyph_info_t;
    5344
    5445void
     
    137128    y = glyph_info->y = cury;
    138129    curx += w + 1;
     130
     131    /* copy the pixmap */
     132    for (j = 0; j < h; j++)
     133     for (i = 0; i < w; i++)
     134       image[(y+j) * WIDTH + x + i] = bitmap->buffer[(h-j-1) * bitmap->pitch + i];
     135//       image[(y+j) * WIDTH + x + i] = bitmap->buffer[(j) * bitmap->pitch + i];
     136
     137    glyph_info->left   = face->glyph->bitmap_left;
     138    glyph_info->bottom = face->glyph->bitmap_top - h;
     139  }
     140}
     141
     142void
     143render_glyph_to_image( FT_Face face, unsigned char * image, glyph_info_t * glyph_info, wchar_t code )
     144{
     145  // lower-left corner of next bitmap:
     146  int curx = 1;
     147  int cury = 1;
     148  // when a new row is started it goes here:
     149  int maxy = 1;
     150
     151  int char_code = code; /* TODO use directly code */
     152  {
     153    FT_Bitmap * bitmap;
     154    int w;
     155    int h;
     156    int i, j, x, y;
     157   
     158    FT_Load_Char( face, code, FT_LOAD_RENDER );
     159
     160    glyph_info->advance = face->glyph->advance.x >> 6; 
     161
     162    if ( face->glyph->format != FT_GLYPH_FORMAT_BITMAP ) /* TODO draw something else */
     163    {
     164      glyph_info->w = 0;
     165      glyph_info->h = 0;
     166    }
     167   
     168    bitmap = &face->glyph->bitmap;
     169
     170    w = glyph_info->w = bitmap->width;
     171    h = glyph_info->h = bitmap->rows;
     172
     173    // Skip blank bitmaps
     174    if (w < 1 || h < 1)
     175    {
     176    }
     177   
     178    // figure out where we will put the bitmap
     179    if ( curx + w + 1 > WIDTH ) // start a new row
     180    {
     181      curx = 1;
     182      cury = maxy+1;
     183    }
     184     
     185    // figure out where next row must start
     186    if ( cury + h > maxy )
     187    {
     188      maxy = cury+h;
     189    }
     190     
     191    x = glyph_info->x = curx;
     192    y = glyph_info->y = cury;
    139193
    140194    /* copy the pixmap */
     
    195249  umul = 1.0f/width;
    196250  vmul = 1.0f/height;
    197   for (char_code = 0; char_code < 256; char_code++) {
     251  for (char_code = 0; char_code < 256; char_code++)
     252  {
    198253    glyph_info_t * t = &glyphs_info[char_code];
    199254
     
    202257
    203258    // Draw a texturemapped rectangle:
    204     if (t->w > 0 && t->h > 0) {
     259    if (t->w > 0 && t->h > 0)
     260    {
    205261      glBegin( GL_QUADS );
    206262      glTexCoord2f( t->x * umul, t->y * vmul);
     
    224280}
    225281
     282void
     283draw_glyph( unsigned char * image, font_unicode_t * font, glyph_info_t * glyph_info, int maxy, wchar_t char_code )
     284{
     285  int width;
     286  int height;
     287  float umul;
     288  float vmul;
     289  glPushAttrib(GL_TEXTURE_BIT);
     290  glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT);
     291  glyph_info_t * t = glyph_info;
     292
     293  // generate the OpenGL texture map we will use:
     294
     295  height = next_pow2( maxy );
     296  width = WIDTH;
     297
     298  glBindTexture( GL_TEXTURE_2D, font->texture_id );
     299  glPixelStorei( GL_UNPACK_ALIGNMENT,   1 );
     300  glPixelStorei( GL_UNPACK_ROW_LENGTH,  0 );
     301  glPixelStorei( GL_UNPACK_SKIP_PIXELS, 0 );
     302  glPixelStorei( GL_UNPACK_SKIP_ROWS,   0 );
     303  glTexImage2D( GL_TEXTURE_2D, 0, GL_INTENSITY8, width, height, 0,
     304                GL_LUMINANCE, GL_UNSIGNED_BYTE, image );
     305  glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
     306  glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
     307  glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,     GL_CLAMP );
     308  glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,     GL_CLAMP );
     309
     310  umul = 1.0f/width;
     311  vmul = 1.0f/height;
     312 
     313  // Draw a texturemapped rectangle:
     314  if (t->w > 0 && t->h > 0)
     315  {
     316    glBegin( GL_QUADS );
     317    glTexCoord2f( t->x * umul, t->y * vmul);
     318    glVertex2i(   t->left, t->bottom);
     319    glTexCoord2f((t->x + t->w) * umul, t->y * vmul);
     320    glVertex2i(   t->left + t->w, t->bottom);
     321    glTexCoord2f((t->x + t->w) * umul, (t->y + t->h) * vmul);
     322    glVertex2i(   t->left +t->w,t->bottom + t->h);
     323    glTexCoord2f( t->x * umul, (t->y + t->h) * vmul);
     324    glVertex2i(   t->left, t->bottom + t->h);
     325    glEnd();
     326  }
     327  // move the origin:
     328  glTranslatef(t->advance, 0, 0);
     329
     330  glPopClientAttrib();
     331  glPopAttrib();
     332}
     333
    226334/* version of gl_print that handles ANSI escape sequences */
    227335void
    228 gl_print_escapes( char * text )
     336gl_print_ansi( char * text )
    229337{
    230338  char * c;
     
    268376
    269377void
    270 gl_print( char * text )
     378gl_print_ascii( char * text )
    271379{
    272380  int len; /* length of the current line ('till the next \n). */
     
    311419}
    312420
     421void
     422gl_print( font_unicode_t * font, char * text )
     423{
     424  static unsigned char image[WIDTH * HEIGHT];
     425  wchar_t wtext[512]; /* TODO make it depends on text length */
     426  int i;
     427  wchar_t * c;
     428  if (!setlocale(LC_CTYPE, ""))
     429  {
     430    fprintf(stderr, "Can't set the specified locale! "
     431        "Check LANG, LC_CTYPE, LC_ALL.\n");
     432    return;
     433  }
     434  mbstowcs( wtext, text, 512 );
     435  glPushMatrix();
     436  glEnable( GL_TEXTURE_2D );
     437  glBindTexture( GL_TEXTURE_2D, texture );
     438  for ( c = wtext ; *c ; c++ )
     439  {
     440    switch ( *c )
     441    {
     442      case 0x1b :
     443              ++c;
     444              if ( 0 == wcsncmp( c, L"[1;33m", 6 ) ) /* yellow */
     445              {
     446                glColor3f( 1.0f, 1.0f, 0.0f );
     447                c += 5;
     448                break;
     449              }
     450              if ( 0 == wcsncmp( c, L"[0m", 3 ) )    /* nothing */
     451              {
     452                glColor3f( 1.0f, 1.0f, 1.0f ); /* TODO default */
     453                c += 2;
     454                break;
     455              }
     456      case '\n' :
     457              glPopMatrix();
     458              glTranslatef(0, -18, 0); /* TODO 18 depends on the font... */
     459              glPushMatrix();
     460              break;
     461      default:
     462              render_glyph_to_image( font->face, image, &font->glyph_info, *c ); /* remove glyph_info from the struct */
     463              draw_glyph( image, font, &font->glyph_info, 64, 0 ); /* TODO where does 64 come from ?, remove the 0 */
     464              render_glyph_to_image( font->face, image, &font->glyph_info, L'ù' );
     465              printf("-- %lc\n", *c);
     466              draw_glyph( image, font, &font->glyph_info, 64, 0 );
     467    }
     468  }
     469  glDisable( GL_TEXTURE_2D );
     470  glPopMatrix();
     471}
     472
    313473#define FONT_PATH "/usr/share/fonts/truetype/ttf-dejavu/DejaVuSansMono.ttf"
    314474
    315475void
    316 create_font_from_path( char * font_path )
     476create_font_from_path_ascii( char * font_path )
    317477{
    318478  FT_Library library;
     
    354514}
    355515
     516font_unicode_t *
     517create_font_from_path( char * font_path )
     518{
     519  font_unicode_t * font = (font_unicode_t *)malloc( sizeof(font_unicode_t) );
     520
     521  if ( !ft_library_initialized_flag )
     522  {
     523    if ( FT_Init_FreeType( &ft_library ) )
     524    {
     525      fprintf( stderr, "error when setting char size\n" );
     526      exit( 1 );
     527    }
     528    ft_library_initialized_flag = 1;
     529  }
     530
     531  if ( FT_New_Face( ft_library, font_path, 0, &font->face ) )
     532  {
     533    fprintf( stderr, "error when reading new face\n" );
     534    exit( 1 );
     535  }
     536
     537  /* use 16pt at 72dpi */
     538  if ( FT_Set_Char_Size( font->face, 16 * 64, 0, 72, 72 ) )
     539  {
     540    fprintf( stderr, "error when setting char size\n" );
     541    exit( 1 );
     542  }
     543 
     544  alloc_image( &font->image, WIDTH, HEIGHT ); /* TODO no need for that much here. */
     545 
     546  /* free_image( &font->image ); TODO when writing code for freeing ressource
     547
     548  FT_Done_Face( font->face );
     549  FT_Done_FreeType( ft_library );
     550  ft_library_initialized_flag = 0;
     551  */
     552
     553  glGenTextures( 1, &font->texture_id ); /* TODO release it */
     554  return font;
     555}
     556
    356557/* TODO Use Xft here */
    357558void
    358559create_font( void )
    359560{
    360   create_font_from_path( FONT_PATH );
    361 }
    362 
     561  create_font_from_path_ascii( FONT_PATH );
     562}
     563
  • gl-font/gl_font.h

    r3308 r3730  
    33
    44#include <GL/gl.h>
     5#include <ft2build.h>
     6#include FT_FREETYPE_H
     7#include FT_GLYPH_H
    58
     9
     10/* opengl memory-kept texture font */
    611typedef struct font_s
    712{
     
    1015} font_t;
    1116
    12 void gl_print( char * text );
    13 void create_font_from_path( char * font_path );
     17/* glyph_info_t holds information
     18 * about glyph's position in the glyphs buffer.
     19 * Stolen from fltk.
     20 */
     21typedef struct glyph_info_s
     22{
     23  int x, y, w, h;   /* location of the pixmap in memory */
     24  int left, bottom; /* corner of the pixmap relative to glyph origin */
     25  float advance;    /* x advance value */
     26} glyph_info_t;
     27
     28/* on-the-fly texture generation for unicode support;
     29 * no caching (I guess it should have some caching). */
     30typedef struct font_unicode_s
     31{
     32  FT_Face         face;
     33  unsigned char   * image;
     34  int             width;
     35  int             height;
     36  glyph_info_t    glyph_info;
     37  GLuint          texture_id;
     38} font_unicode_t;
     39
     40void gl_print_ascii( char * text );
     41void gl_print_ansi( char * text );
     42void gl_print( font_unicode_t * font, char * text );
     43void create_font_from_path_ascii( char * font_path );
     44font_unicode_t * create_font_from_path( char * font_path );
    1445void create_font( void );
    1546
Note: See TracChangeset for help on using the changeset viewer.