Package: libfreetype6
Version: 2.2.1-2
Severity: normal

When making a call to FT_Load_Char with the FT_LOAD_TARGET_MONO or 
FT_LOAD_MONOCHROME
load flags certain character codes cause a return of error code 6 (invalid 
argument).
The character code causing the error seems to depend on the font file used.
For example:

/usr/share/fonts/truetype/msttcorefonts/Arial.ttf fails on character code 32 
(space character)
/usr/share/fonts/truetype/freefont/FreeSans.ttf fails on characher code 13

Downgrading to 2.1.7 of libfreetype removes the problem.

See the attached file for an example of C code that exhibits the bug.


-- System Information:
Debian Release: 3.1
  APT prefers testing
  APT policy: (990, 'testing'), (500, 'unstable'), (500, 'stable'), (1, 
'experimental')
Architecture: i386 (i686)
Shell:  /bin/sh linked to /bin/bash
Kernel: Linux 2.6.14-2-k7
Locale: LANG=en_GB.UTF-8, LC_CTYPE=en_GB.UTF-8 (charmap=UTF-8)

Versions of packages libfreetype6 depends on:
ii  libc6                         2.3.6-7    GNU C Library: Shared libraries
ii  zlib1g                        1:1.2.2-4  compression library - runtime

libfreetype6 recommends no packages.

-- no debconf information
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include <ft2build.h>
#include FT_FREETYPE_H


static void
dump_bitmap( uint8_t char_num, const char *font_name,
	     FT_Bitmap *bitmap, FT_Glyph_Metrics *metrics,
	     FT_Int left, FT_Int top) {
  /*printf( "row %d, width %d, pitch %d, num_grays %d, pixel_mode %d, palette_mode %d\n",
	  bitmap->rows, bitmap->width, bitmap->pitch, bitmap->num_grays, bitmap->pixel_mode,
	  bitmap->palette_mode);*/

  /*printf( "metrics:\n"
	  "width %d, height %d, bearing x %d, bearing y %d, "
	  "advance %d\n",
	  metrics->width, metrics->height, metrics->horiBearingX,
	  metrics->horiBearingY, metrics->horiAdvance);*/

  /*printf( "left %d, top %d\n", left, top);*/

  if ( isprint( char_num)) {
    printf( "/* '%c' 0x%x\n", (char)char_num, char_num);
  }
  else {
    printf( "/* 0x%x\n", char_num);
  }
  printf( " *\n");

  if ( bitmap->pixel_mode == FT_PIXEL_MODE_MONO) {
    int y;

    for ( y = 0; y < bitmap->rows; y++) {
      uint8_t *bitmap_row = &bitmap->buffer[ y * bitmap->pitch];
      int x;

      printf(" * ");

      for ( x = 0; x < bitmap->width; x++) {
	int bits_index = x / 8;
	uint8_t bits = bitmap_row[bits_index];
	uint8_t mask = 0x80 >> ( x % 8);

	if ( bits & mask)
	  printf("*");
	else
	  printf("-");
      }
      printf("\n");
    }
  }

  if ( bitmap->pixel_mode == FT_PIXEL_MODE_MONO) {
    int y;

    printf( " */\n");
    printf( "static unsigned char\n");
    printf( "%s_%d_bitmap[] = {\n", font_name, char_num);
    printf( "\t%d, %d", bitmap->width, bitmap->rows);

    for ( y = 0; y < bitmap->rows; y++) {
      uint8_t *bitmap_row = &bitmap->buffer[ y * bitmap->pitch];
      int x;

      printf( ",\n\t");

      for ( x = 0; x < (bitmap->width + 7) / 8; x++) {
	uint8_t bits = bitmap_row[x];

	if ( x != 0)
	  printf( ", ");

	printf( "0x%x", bits);
      }
    }
    printf("\n");


    printf( "};\n");

    printf( "static struct font_glyph\n");
    printf( "%s_%d_font_glyph = {\n", font_name, char_num);
    printf( "\t%s_%d_bitmap,\n", font_name, char_num);
    printf( "\t%d, /* top */\n", top);
    printf( "\t%d, /* left */\n", left);
    printf( "\t%d /* advance */\n", metrics->horiAdvance >> 6);
    printf( "};\n\n");
  }
}


#define NUM_CHARS 128


int
main( int argc, char *argv[]) {
  int pixel_size;
  int max_top = 0;
  FT_Error error;
  FT_Library library;
  FT_Face face;
  int i;
  int max_size = 0;

  char font_name[50];
  char filename[200];
  const char *post_name;

  if ( argc != 3) {
    fprintf( stderr, "USAGE: %s <font_file> <bitmap_height>\n", argv[0]);
    exit( EXIT_FAILURE);
  }

  pixel_size = atoi( argv[2]);

  error = FT_Init_FreeType( &library);

  if ( error) {
    fprintf( stderr, "Failed to init freetype lib (%d)\n", error);
    exit( EXIT_FAILURE);
  }

  error = FT_New_Face( library, argv[1], 0, &face);

  if ( error) {
    fprintf( stderr, "Failed to create face (%d) from font file %s\n",
	     error, argv[1]);
    FT_Done_FreeType( library);
    exit( EXIT_FAILURE);
  }

  error = FT_Set_Pixel_Sizes( face, 0, pixel_size);
  if ( error) {
    fprintf( stderr, "Failed (%d) to set pixel size to %d\n",
	     error, pixel_size);
    FT_Done_FreeType( library);
    exit( EXIT_FAILURE);
  }

  post_name = FT_Get_Postscript_Name( face);
  for ( i = 0; i < strlen(post_name); i++) {
    font_name[i] = toupper( post_name[i]);
  }
  font_name[i] = '\0';

  fprintf( stderr, "Dumping font file \"%s\" as %d bitmap characters\n",
	   argv[1], pixel_size);
  fprintf( stderr, "Face name is \"%s\"\n", post_name);


  printf("#ifndef _FONT_%s_%d_H_\n", font_name, pixel_size);
  printf("#define _FONT_%s_%d_H_ 1\n\n", font_name, pixel_size);

  FT_Int major, minor, patch;
  FT_Library_Version( library, &major, &minor, &patch);

  printf("/*\n");
  printf(" * Bitmap font create from font %s character size %d\n", post_name, pixel_size);
  printf(" * created using %s using FreeType library %d.%d.%d\n", argv[0], major, minor, patch);
  printf(" */\n\n");

  printf("#include \"font_structs.h\"\n\n");

  /*
   * Load and render the glyph
   */
  for ( i = 0; i < NUM_CHARS; i++) {
    error = FT_Load_Char( face, i,
			  FT_LOAD_RENDER | FT_LOAD_TARGET_MONO);

    if ( error) {
      if ( isprint( i)) {
	fprintf( stderr, "Failed (%d) to load character '%c' (%d)\n",
		 error, (char)i, i);
      }
      else {
	fprintf( stderr, "Failed (%d) to load character %d\n",
		 error, i);
      }
      FT_Done_FreeType( library);
      exit( EXIT_FAILURE);
    }

    /* dump the bitmap */
    dump_bitmap( i, post_name, &face->glyph->bitmap, &face->glyph->metrics,
		 face->glyph->bitmap_left, face->glyph->bitmap_top);

    if ( face->glyph->bitmap_top > max_top) {
      max_top = face->glyph->bitmap_top;
    }
    if ( face->glyph->bitmap.rows > max_size) {
      max_size = face->glyph->bitmap.rows;
    }
  }

  /*
   * collect all the glyphs together in an array
   */
  printf("static struct font_glyph *\n");
  printf("font_%s_%d_glyphs[%d] = {\n",
	 post_name, pixel_size, NUM_CHARS);
  for ( i = 0; i < NUM_CHARS; i++) {
    if ( i != 0)
      printf(",\n");

    printf("\t&%s_%d_font_glyph", post_name, i);
  }
  printf("\n};\n\n");

  /*
   * Create the font structure
   */
  printf( "struct bitmap_font\n");
  printf( "font_%s_%d = {\n", post_name, pixel_size);
  printf( "\t/* font glyphs */\n");
  printf( "\tfont_%s_%d_glyphs,\n", post_name, pixel_size);
  printf( "\t/* requested glyph size */\n");
  printf( "\t%d,\n", pixel_size);
  printf( "\t/* actual glyph size */\n");
  printf( "\t%d,\n", max_size);
  printf( "\t/* number of glyphs in font */\n");
  printf( "\t%d,\n", NUM_CHARS);
  printf( "\t/* the max top value in font */\n");
  printf( "\t%d\n", max_top);
  printf("};\n\n");


  printf("\n#endif /* End of _FONT_%s_%d_H_ */\n", font_name, pixel_size);

  FT_Done_FreeType( library);
}

Reply via email to