예제 #1
0
void i_tt_dump_names(TT_Fonthandle *handle) {
  TT_Face_Properties props;
  int name_count;
  int i;
  TT_UShort platform_id, encoding_id, lang_id, name_id;
  TT_UShort name_len;
  TT_String *name;
  
  TT_Get_Face_Properties(handle->face, &props);
  name_count = props.num_Names;
  for (i = 0; i < name_count; ++i) {
    TT_Get_Name_ID(handle->face, i, &platform_id, &encoding_id, &lang_id, 
                   &name_id);
    TT_Get_Name_String(handle->face, i, &name, &name_len);

    printf("# %d: plat %d enc %d lang %d name %d value ", i, platform_id,
           encoding_id, lang_id, name_id);
    if (platform_id == TT_PLATFORM_APPLE_UNICODE) {
      printf("(unicode)\n");
    }
    else {
      printf("'%s'\n", name);
    }
  }
  fflush(stdout);
}
예제 #2
0
static void ttf_instance_setc(struct image_ttf_face_struct *face_s,
			      struct image_ttf_faceinstance_struct *face_i,
			      int towhat,
			      char *where)
{
   TT_Face_Properties prop;
   TT_Instance_Metrics metr;
   int res;
   int resol;

   if ((res=TT_Get_Face_Properties(face_s->face,&prop)))
      my_tt_error(where,"TT_Get_Face_Properties",res);

   resol=58; /* should be 72, but glyphs fit using this value */
      /*
         (int)((72*(prop.horizontal->Ascender+
		    prop.horizontal->Descender)/
		(float)prop.horizontal->Ascender));
*/

   if ((res=TT_Set_Instance_Resolutions(face_i->instance,
					(TT_UShort)resol, (TT_UShort)resol)))
      my_tt_error("Image.TTF.FaceInstance()",
		  "TT_Set_Instance_Resolutions: ",res);

   if ((res=TT_Get_Instance_Metrics(face_i->instance,&metr)))
      my_tt_error(where,"TT_Get_Instance_Metrics",res);

   if ((res=TT_Set_Instance_CharSize(face_i->instance,towhat)))
      my_tt_error(where,"TT_Set_Instance_CharSize: ",res);

   face_i->baseline=
      DOUBLE_TO_INT(((double)(towhat/64.0+towhat/640.0)*
		     prop.horizontal->Ascender)/
		    (prop.horizontal->Ascender - prop.horizontal->Descender));

   face_i->height= (towhat/64 + towhat/640);

   face_i->trans = ~63 &
      (32 +
       DOUBLE_TO_INT(64*((towhat/64.0+towhat/640.0)*
			 prop.horizontal->Ascender)/
		     (prop.horizontal->Ascender-prop.horizontal->Descender)));
}
예제 #3
0
SWFFont loadSWFFontfromTTF(char *filename)
{
  int i;

  TT_Engine *engine;
  TT_Face face;
  TT_Instance instance;
  TT_Glyph glyph;
  TT_Glyph_Metrics metrics;
  TT_Outline outline;
  TT_CharMap charmap;
  TT_Face_Properties properties;
  TT_UShort pid, eid;

  TT_Init_FreeType(engine);

  error = TT_Open_Face(engine, filename, &face);

  if(error)
    fprintf(stderr, "Could not open face.\n");

  TT_Get_Face_Properties(face, &properties);

  for(i=0; i<properties->num_CharMaps; ++i)
    TT_Get_CharMap_ID(face, i, &pid, &eid);

  TT_Get_CharMap(face, charmapIndex, &charmap);

  TT_New_Instance(face, &instance);

  TT_New_Glyph(face, &glyph);

  for(i=0; i<whatever; ++i)
  {
    TT_Load_Glyph(instance, glyph, TT_Char_Index(charmap, i), loadFlags);

    TT_Get_Glyph_Outline(glyph, &outline);

    TT_Get_Glyph_Metrics(glyph, &metrics);
  }

  TT_Done_FreeType(engine);
}
예제 #4
0
파일: ftsbit.c 프로젝트: DavidGriffith/finx
  int  main( int  argc, char**  argv )
  {
    int    i;
    char   filename[128 + 4];
    char   alt_filename[128 + 4];
    char*  execname;
    char*  fname;


#ifdef HAVE_LIBINTL_H
    setlocale( LC_ALL, "" );
    bindtextdomain( "freetype", LOCALEDIR );
    textdomain( "freetype" );
#endif

    execname = argv[0];

    if ( argc < 3 )
      Usage( execname );

    if ( sscanf( argv[1], "%d", &ptsize ) != 1 )
      Usage( execname );

    /* Initialize engine */
    if ( (error = TT_Init_FreeType( &engine )) )
    {
      fprintf( stderr, gettext( "Error while initializing engine.\n" ) );
      goto Failure;
    }

    if ( (error = TT_Init_SBit_Extension( engine )) )
    {
      fprintf( stderr, gettext(
               "Error while initializing embedded bitmap extension.\n" ) );
      goto Failure;
    }

    /* Now check all files */
    fname = argv[2];
    i     = strlen( fname );
    while ( i > 0 && fname[i] != '\\' && fname[i] != '/' )
    {
      if ( fname[i] == '.' )
        i = 0;
      i--;
    }

    filename[128] = '\0';
    alt_filename[128] = '\0';

    strncpy( filename, fname, 128 );
    strncpy( alt_filename, fname, 128 );

    if ( i >= 0 )
    {
      strncpy( filename + strlen( filename ), ".ttf", 4 );
      strncpy( alt_filename + strlen( alt_filename ), ".ttc", 4 );
    }

    /* Load face */
    error = TT_Open_Face( engine, filename, &face );
    if ( error == TT_Err_Could_Not_Open_File )
    {
      strcpy( filename, alt_filename );
      error = TT_Open_Face( engine, alt_filename, &face );
    }

    i     = strlen( filename );
    fname = filename;

    while ( i >= 0 )
      if ( filename[i] == '/' || filename[i] == '\\' )
      {
        fname = filename + i + 1;
        i = -1;
      }
      else
        i--;

    if ( error )
    {
      fprintf( stderr, gettext( "Could not find or open %s.\n" ),
               filename );
      goto Failure;
    }
    if ( error )
    {
      fprintf( stderr, gettext( "Error while opening %s.\n" ), filename );
      goto Failure;
    }

    /* get face properties */
    TT_Get_Face_Properties( face, &properties );
    num_glyphs = properties.num_Glyphs;

    error = TT_Get_Face_Bitmaps( face, &eblc );
    if ( error == TT_Err_Table_Missing )
    {
      fprintf( stderr, gettext(
               "Could not find embedded bitmaps in this font.\n" ) );
      goto Failure;
    }
    if ( error )
    {
      fprintf( stderr, gettext(
               "Error while loading embedded bitmaps.\n" ) );
      goto Failure;
    }

    /* create instance */
    error = TT_New_Instance( face, &instance );
    if ( error )
    {
      fprintf( stderr, gettext( "Could not create instance.\n" ) );
      goto Failure;
    }

    error = TT_Set_Instance_PixelSizes( instance,
                                        ptsize,
                                        ptsize,
                                        ptsize*3/4 );
    if ( error )
    {
      fprintf( stderr,
               gettext( "Could not set point size to %d.\n" ),
               ptsize );
      goto Failure;
    }

    error = TT_New_SBit_Image( &bitmap );
    if ( error )
    {
      fprintf( stderr, gettext(
               "Could not allocate glyph bitmap container.\n" ) );
      goto Failure;
    }

    for ( i = 3; i < argc; i++ )
    {
      unsigned short  glyph_index;


      /* we use %i to allow the prefixes `0x' and `0' */
      if ( sscanf( argv[i], "%hi", &glyph_index ) != 1 )
        Usage( execname );

      error = TT_Load_Glyph_Bitmap( face, instance, glyph_index, bitmap );

      if ( error == TT_Err_Invalid_Glyph_Index )
      {
        fprintf( stderr, gettext(
                 "  no bitmap for glyph %d.\n" ), glyph_index );
        continue;
      }
      if ( error )
      {
        fprintf( stderr, gettext(
                 "Can't load bitmap for glyph %d.\n" ), glyph_index );
        goto Failure;
      }

      /* Dump the resulting bitmap */
      {
        printf( gettext( "glyph index %d = %dx%d pixels, " ),
                glyph_index, bitmap->map.rows, bitmap->map.width );

        printf( gettext( "advance = %ld, minBearing = [%ld,%ld]\n" ),
                (long)(bitmap->metrics.horiAdvance / 64),
                (long)(bitmap->metrics.horiBearingX / 64),
                (long)(bitmap->metrics.horiBearingY / 64));

        Show_Single_Glyph( &bitmap->map );
      }
    }

    TT_Done_SBit_Image( bitmap );
    TT_Done_FreeType( engine );

    exit( EXIT_SUCCESS );      /* for safety reasons */

    return 0;       /* never reached */

  Failure:
    fprintf( stderr, "  " );
    fprintf( stderr, gettext( "FreeType error message: %s\n" ),
             TT_ErrToString18( error ) );

    exit( EXIT_FAILURE );

    return 0;       /* never reached */
  }
예제 #5
0
  int  main( int  argc, char**  argv )
  {
    int    i, total, mode, base, rendered_glyphs;
    char   filename[128 + 4];
    char   alt_filename[128 + 4];
    char*  execname;

    long   t, t0, tz0;


    execname    = argv[0];

    gray_render = 0;
    visual      = 0;

    while ( argc > 1 && argv[1][0] == '-' )
    {
      switch ( argv[1][1] )
      {
      case 'g':
        gray_render = 1;
        break;

      case 'v':
        visual = 1;
        break;

      default:
        Panic( "Unknown argument '%s'!\n", argv[1] );
      }
      argc--;
      argv++;
    }

    if ( argc != 2 )
    {
      fprintf( stderr, "fttimer: simple performance timer -- part of the FreeType project\n" );
      fprintf( stderr,"-----------------------------------------------------------------\n\n" );
      fprintf( stderr,"Usage: %s [-g] [-v] fontname[.ttf|.ttc]\n\n", execname );
      fprintf( stderr,"  where '-g' asks for gray-levels rendering\n" );
      fprintf( stderr,"        '-v' displays while rendering (slower)\n" );

      exit( EXIT_FAILURE );
    }

    i = strlen( argv[1] );
    while ( i > 0 && argv[1][i] != '\\' )
    {
      if ( argv[1][i] == '.' )
        i = 0;
      i--;
    }

    filename[128] = '\0';
    alt_filename[128] = '\0';

    strncpy( filename, argv[1], 128 );
    strncpy( alt_filename, argv[1], 128 );

    if ( i >= 0 )
    {
      strncpy( filename + strlen( filename ), ".ttf", 4 );
      strncpy( alt_filename + strlen( alt_filename ), ".ttc", 4 );
    }

    /* Initialize engine */

    if ( (error = TT_Init_FreeType( &engine )) )
      Panic( "Error while initializing engine, code = 0x%x.\n", error );

    /* Load face */

    error = TT_Open_Face( engine, filename, &face );

    if ( error == TT_Err_Could_Not_Open_File )
    {
      strcpy( filename, alt_filename );
      error = TT_Open_Face( engine, alt_filename, &face );
    }

    if ( error == TT_Err_Could_Not_Open_File )
      Panic( "Could not find/open %s.\n", filename );
    else if ( error )
      Panic( "Error while opening %s, error code = 0x%x.\n",
             filename, error );

    /* get face properties and allocate preload arrays */

    TT_Get_Face_Properties( face, &properties );

    num_glyphs = properties.num_Glyphs;

    tab_glyphs = MAX_GLYPHS;
    if ( tab_glyphs > num_glyphs )
      tab_glyphs = num_glyphs;

    /* create glyph */

    error = TT_New_Glyph( face, &glyph );
    if ( error )
      Panic( "Could not create glyph container.\n" );

    /* create instance */

    error = TT_New_Instance( face, &instance );
    if ( error )
      Panic( "Could not create instance for %s.\n", filename );

    error = TT_Set_Instance_CharSize( instance, 400*64 );
    if ( error )
      Panic( "Could not reset instance for %s.\n", filename );

    if ( gray_render )
      mode = Graphics_Mode_Gray;
    else
      mode = Graphics_Mode_Mono;

    if ( visual )
    {
      if ( !SetGraphScreen( mode ) )
        Panic( "Could not set graphics mode.\n" );
      TT_Set_Raster_Gray_Palette( engine, gray_palette );
    }
    else
    {
      /* This is the default bitmap size used */
      vio_Width  = 640;
      vio_Height = 450;
    }

    Init_Engine();

    Num  = 0;
    Fail = 0;

    total = num_glyphs;
    base  = 0;

    rendered_glyphs = 0;

    t0 = 0;  /* Initial time */

    tz0 = Get_Time();

    while ( total > 0 )
    {
      /* First, preload 'tab_glyphs' in memory */

      cur_glyph   = 0;
      cur_point   = 0;
      cur_contour = 0;

      printf( "loading %d glyphs", tab_glyphs );

      for ( Num = 0; Num < tab_glyphs; Num++ )
      {
        error = LoadTrueTypeChar( base + Num );
        if ( error )
          Fail++;

        total--;
      }

      base += tab_glyphs;

      if ( tab_glyphs > total )
        tab_glyphs = total;

      printf( ", rendering... " );

      /* Now, render the loaded glyphs */

      t = Get_Time();

      for ( Num = 0; Num < cur_glyph; Num++ )
      {
        if ( (error = ConvertRaster( Num )) )
          Fail++;
        else
        {
          rendered_glyphs ++;

          if ( visual )
          {
            sprintf( Header, "Glyph: %5d", Num );
            Display_Bitmap_On_Screen( Bit.bitmap, Bit.rows, Bit.cols );

            Clear_Buffer();
          }
        }
      }

      t = Get_Time() - t;
      if ( t < 0 )
        t += 100L * 60 * 60;

      printf( " = %f s\n", (double)t / 1000 );
      t0 += t;

      /* Now free all loaded outlines */
      for ( Num = 0; Num < cur_glyph; Num++ )
        TT_Done_Outline( &outlines[Num] );
    }

    tz0 = Get_Time() - tz0;

    if ( visual )
      RestoreScreen();

    TT_Close_Face( face );

    printf( "\n" );
    printf( "rendered glyphs  = %d\n", rendered_glyphs );
    printf( "render time      = %f s\n", (double)t0 / 1000 );
    printf( "fails            = %d\n", Fail );
    printf( "average glyphs/s = %f\n",
             (double)rendered_glyphs / t0 * 1000 );

    printf( "total timing     = %f s\n", (double)tz0 / 1000 );
    printf( "Fails = %d\n", Fail );

    TT_Done_FreeType( engine );

    exit( EXIT_SUCCESS );      /* for safety reasons */

    return 0;       /* never reached */
  }
예제 #6
0
void
TTFopen(char *filename, Font *fnt, int new_dpi, int new_ptsize, Boolean quiet)
{
  unsigned short i, num_cmap;
  unsigned short cmap_plat;
  unsigned short cmap_enc;
  TT_Error error;

  TT_UShort script_index, language_index, feature_index;
  TT_UShort req_feature_index = 0xFFFF;


  dpi = new_dpi;
  ptsize = new_ptsize;

  if ((error = TT_Init_FreeType(&engine)))
    oops("Cannot initialize FreeType engine (error code = 0x%x).", error);

  if (fnt->PSnames)
    if ((error = TT_Init_Post_Extension(engine)))
      oops("Cannot initialize PS name support (error code = 0x%x).", error);

  if (fnt->rotate)
    if ((error = TT_Init_GSUB_Extension(engine)))
      oops("Cannot initialize GSUB support (error code = 0x%x).", error);

  /*
   *   Load face.
   */

  error = TT_Open_Face(engine, filename, &face);
  if (error)
    oops("Cannot open `%s'.", filename);

  /*
   *   Get face properties and allocate preloaded arrays.
   */

  TT_Get_Face_Properties(face, &properties);

  /*
   *   Now we try to open the proper font in a collection.
   */

  if (fnt->fontindex != 0)
  {
    if (properties.num_Faces == 1)
      warning("This isn't a TrueType collection.\n"
              "Parameter `Fontindex' is ignored.");
    else
    {
      TT_Close_Face(face);
      if ((error = TT_Open_Collection(engine, filename,
                                      fnt->fontindex, &face)))
        oops("Cannot open font %lu in TrueType Collection `%s'.",
             fnt->fontindex, filename);
    }
  }

  /*
   *   Create instance.
   */
  
  if ((error = TT_New_Instance(face, &instance)))
    oops("Cannot create instance for `%s' (error code = 0x%x).",
         filename, error);

  if ((error = TT_Set_Instance_Resolutions(instance, dpi, dpi)))
    oops("Cannot set device resolutions (error code = 0x%x).");

  if ((error = TT_Set_Instance_CharSize(instance, ptsize * 64)))
    oops("Cannot set character size (error code = 0x%x).", error);

  ppem = (dpi * ptsize + 36) / 72;

  if (!quiet)
    printf("dpi = %d, ptsize = %d, ppem = %d\n\n", dpi, ptsize, ppem);

  matrix1.xx = (TT_Fixed)(floor(fnt->efactor * 1024) * (1<<16)/1024);
  matrix1.xy = (TT_Fixed)(floor(fnt->slant * 1024) * (1<<16)/1024);
  matrix1.yx = (TT_Fixed)0;
  matrix1.yy = (TT_Fixed)(1<<16);

  if (fnt->rotate)
  {
    matrix2.xx = 0;
    matrix2.yx = 1L << 16;
    matrix2.xy = -matrix2.yx;
    matrix2.yy = matrix2.xx;
  }

  if ((error = TT_Set_Instance_Transform_Flags(
                 instance,
                 fnt->rotate ? 1 : 0,
                 fnt->efactor != 1.0 ? 1 : 0)))
    oops("Cannot set transform flags (error code = 0x%x).", error);

  /*
   *   Create glyph container.
   */

  if ((error = TT_New_Glyph(face, &glyph)))
    oops("Cannot create glyph container (error code = 0x%x).");

  if (fnt->PSnames != Only)
  {
    num_cmap = properties.num_CharMaps;
    for (i = 0; i < num_cmap; i++)
    {
      if ((error = TT_Get_CharMap_ID(face, i, &cmap_plat, &cmap_enc)))
        oops("Cannot query cmap (error code = 0x%x).", error);
      if (cmap_plat == fnt->pid && cmap_enc == fnt->eid)
        break;
    }
    if (i == num_cmap)
      oops("Invalid platform and/or encoding ID.");
  
    if ((error = TT_Get_CharMap(face, i, &char_map)))
      oops("Cannot load cmap (error code = 0x%x).", error);
  }

  if (fnt->PSnames)
  {
    if ((error = TT_Load_PS_Names(face, &post)))
      oops("Cannot load TrueType PS names (error code = 0x%x).", error);
  }
  else if (cmap_plat == Microsoft_platform &&
           cmap_enc == Microsoft_Unicode_encoding)
    set_encoding_scheme(encUnicode, fnt);
  else if (cmap_plat == Macintosh_platform &&
           cmap_enc == Macintosh_encoding)
    set_encoding_scheme(encMac, fnt);
  else
    set_encoding_scheme(encFontSpecific, fnt);

  if (fnt->rotate)
  {
    gsub = &gsub_;

    error = TT_Load_GSUB_Table(face, gsub, NULL);
    if (!error)
      has_gsub = True;
    else if (error != TT_Err_Table_Missing)
      warning("Cannot load GSUB table (error code = 0x%x).", error);
    else
      warning("No GSUB data available "
              "for vertical glyph presentation forms.");

    /* we check for the `vert' feature in Chinese, Japanese, and Korean */

    error = TT_GSUB_Select_Script(gsub,
                                  SCRIPT_kana,
                                  &script_index);
    if (error)
      goto check_hani;
    error = TT_GSUB_Select_Feature(gsub,
                                   FEATURE_vert,
                                   script_index,
                                   0xFFFF,
                                   &feature_index);
    if (error)
    {
      error = TT_GSUB_Select_Language(gsub,
                                      LANGUAGE_JAN,
                                      script_index,
                                      &language_index,
                                      &req_feature_index);
      if (error)
        goto check_hani;
      error = TT_GSUB_Select_Feature(gsub,
                                     FEATURE_vert,
                                     script_index,
                                     language_index,
                                     &feature_index);
      if (error)
        goto check_hani;
      else
        goto Done;
    }
    else
      goto Done;

  check_hani:
    error = TT_GSUB_Select_Script(gsub,
                                  SCRIPT_hani,
                                  &script_index);
    if (error)
      goto check_hang;
    error = TT_GSUB_Select_Feature(gsub,
                                   FEATURE_vert,
                                   script_index,
                                   0xFFFF,
                                   &feature_index);
    if (error)
    {
      error = TT_GSUB_Select_Language(gsub,
                                      LANGUAGE_CHN,
                                      script_index,
                                      &language_index,
                                      &req_feature_index);
      if (error)
        goto check_hang;
      error = TT_GSUB_Select_Feature(gsub,
                                     FEATURE_vert,
                                     script_index,
                                     language_index,
                                     &feature_index);
      if (error)
        goto check_hang;
      else
        goto Done;
    }
    else
      goto Done;

  check_hang:
    error = TT_GSUB_Select_Script(gsub,
                                  SCRIPT_hang,
                                  &script_index);
    if (error)
      goto Done;
    error = TT_GSUB_Select_Feature(gsub,
                                   FEATURE_vert,
                                   script_index,
                                   0xFFFF,
                                   &feature_index);
    if (error)
    {
      error = TT_GSUB_Select_Language(gsub,
                                      LANGUAGE_KOR,
                                      script_index,
                                      &language_index,
                                      &req_feature_index);
      if (error)
        goto Done;
      error = TT_GSUB_Select_Feature(gsub,
                                     FEATURE_vert,
                                     script_index,
                                     language_index,
                                     &feature_index);
    }

  Done:
    if (error)
    {
      warning("There is no data for vertical typesetting in GSUB table.");
      has_gsub = False;
    }

    if (req_feature_index != 0xFFFF)
      TT_GSUB_Add_Feature(gsub, req_feature_index, ALL_GLYPHS);
    TT_GSUB_Add_Feature(gsub, feature_index, ALL_GLYPHS);

    in.length = 1;
    in.pos = 0;
    in.string = in_string;
    in.properties = NULL;

    out.pos = 0;
    out.allocated = 0;
    out.string = NULL;
    out.properties = NULL;
  }
}
예제 #7
0
TTF_Font *TTF_OpenFont(const char *file, int ptsize)
{
	TTF_Font *font;
	TT_Face_Properties properties;
	TT_Instance_Metrics imetrics;
	int i, n;
	TT_UShort platform, encoding;
	TT_Error error;

	font = (TTF_Font *)malloc(sizeof(*font));
	if ( font == NULL ) {
		SDL_SetError("Out of memory");
		return(NULL);
	}
	memset(font, 0, sizeof(*font));

	/* Open the font and create ancillary data */
	error = TT_Open_Face(engine, file, &font->face);
	if ( error ) {
		SDL_SetError("Couldn't load font file");
		free(font);
		return(NULL);
	}
	error = TT_New_Glyph(font->face, &font->glyph);
	if ( error ) {
		SDL_SetError("Couldn't create glyph container");
		TTF_CloseFont(font);
		return(NULL);
	}
	error = TT_New_Instance(font->face, &font->inst);
	if ( error ) {
		SDL_SetError("Couldn't create font instance");
		TTF_CloseFont(font);
		return(NULL);
	}

	/* Set the display resolution */
	error = TT_Set_Instance_Resolutions(font->inst, 72, 72);
	if ( error ) {
		SDL_SetError("Couldn't set font resolution");
		TTF_CloseFont(font);
		return(NULL);
	}
	error = TT_Set_Instance_CharSize(font->inst, ptsize*64);
	if ( error ) {
		SDL_SetError("Couldn't set font size");
		TTF_CloseFont(font);
		return(NULL);
	}

	/* Get a Unicode mapping for this font */
	n = TT_Get_CharMap_Count(font->face);
	for ( i=0; i<n; ++i ) {
		TT_Get_CharMap_ID(font->face, i, &platform, &encoding);
		if ( ((platform == TT_PLATFORM_MICROSOFT) &&
		                  (encoding == TT_MS_ID_UNICODE_CS)) ||
		     ((platform == TT_PLATFORM_APPLE_UNICODE) &&
		                  (encoding == TT_APPLE_ID_DEFAULT)) ) {
			TT_Get_CharMap(font->face, i, &font->map);
			break;
		}
	}
	if ( i == n ) {
		SDL_SetError("Font doesn't have a Unicode mapping");
		TTF_CloseFont(font);
		return(NULL);
	}

	/* Get the font metrics for this font */
	TT_Get_Face_Properties(font->face, &properties );
	TT_Get_Instance_Metrics(font->inst, &imetrics);
	font->pointsize = imetrics.y_ppem;
	font->ascent = (float)properties.horizontal->Ascender /
	                properties.header->Units_Per_EM;
	font->ascent *= font->pointsize;
	font->descent = (float)properties.horizontal->Descender /
	                 properties.header->Units_Per_EM;
	font->descent *= font->pointsize;
	font->lineskip = (float)properties.horizontal->Line_Gap /
	                  properties.header->Units_Per_EM;
	font->lineskip *= font->pointsize;
	font->height = round(font->ascent - font->descent);

	/* Set the default font style */
	font->style = TTF_STYLE_NORMAL;
	font->glyph_overhang = font->pointsize/10;
	/* x offset = cos(((90.0-12)/360)*2*M_PI), or 12 degree angle */
	font->glyph_italics = 0.207;
	font->glyph_italics *= font->height;

	return(font);
}
예제 #8
0
  int
  main( int  argc, char**  argv )
  {
    int    i, orig_ptsize, file;
    char   filename[128 + 4];
    char   alt_filename[128 + 4];
    char*  execname;
    int    option;

    int    ptsize;
    int    num_Faces = 0;
    int    glyph_index = 0;
    int    load_flags = TTLOAD_DEFAULT;

    int    force_sbit = 0;

    TT_Engine    engine;

    TT_Face      face;
    TT_Instance  instance;
    TT_Glyph     glyph;

    TT_Raster_Map  map;

    TT_Big_Glyph_Metrics  metrics;
    TT_Face_Properties    properties;
    TT_Instance_Metrics   imetrics;

    TT_EBLC         eblc;
    TT_SBit_Image*  bitmap = NULL;

    TT_Error  error;


    int res = 72;

#ifdef HAVE_LIBINTL_H
    setlocale( LC_ALL, "" );
    bindtextdomain( "freetype", LOCALEDIR );
    textdomain( "freetype" );
#endif

    execname = ft_basename( argv[0] );

    while ( 1 )
    {
      option = ft_getopt( argc, argv, "c:r:i:B" );

      if ( option == -1 )
        break;

      switch ( option )
      {
      case 'r':
        res = atoi( ft_optarg );
        if ( res < 1 )
          usage( execname );
        break;

      case 'c':
        num_Faces = atoi( ft_optarg );
        if ( num_Faces < 0 )
          usage( execname );
        break;

      case 'i':
        glyph_index = atoi( ft_optarg );
        if ( glyph_index < 0 )
          usage( execname );
        break;

      case 'B':
        force_sbit = 1;
        break;

      default:
        usage( execname );
        break;
      }
    }

    argc -= ft_optind;
    argv += ft_optind;

    if ( argc <= 1 )
      usage( execname );

    if ( sscanf( argv[0], "%d", &orig_ptsize ) != 1 )
      orig_ptsize = 64;

    file = 1;

    ptsize = orig_ptsize;

    i = strlen( argv[file] );
    while ( i > 0 && argv[file][i] != '\\' && argv[file][i] != '/' )
    {
      if ( argv[file][i] == '.' )
        i = 0;
        i--;
    }

    filename[128] = '\0';
    alt_filename[128] = '\0';

    strncpy( filename, argv[file], 128 );
    strncpy( alt_filename, argv[file], 128 );

    if ( i >= 0 )
    {
      strncpy( filename + strlen( filename ), ".ttf", 4 );
      strncpy( alt_filename + strlen( alt_filename ), ".ttc", 4 );
    }

    /* Initialize engine */

    error = TT_Init_FreeType( &engine );
    if ( error )
    {
      fprintf( stderr, gettext( "Error while initializing engine.\n" ) );
      goto Failure;
    }

    error = TT_Init_SBit_Extension( engine );
    if ( error )
    {
      fprintf( stderr, gettext(
               "Error while initializing embedded bitmap extension.\n" ) );
      goto Failure;
    }

    /* Load face */

    error = TT_Open_Face( engine, filename, &face );

    if ( error == TT_Err_Could_Not_Open_File )
    {
      strcpy( filename, alt_filename );
      error = TT_Open_Face( engine, alt_filename, &face );
    }

    if ( error == TT_Err_Could_Not_Open_File )
      Panic( gettext( "Could not find or open %s.\n" ), filename );
    if ( error )
    {
      fprintf( stderr, gettext( "Error while opening %s.\n" ),
               filename );
      goto Failure;
    }

    TT_Get_Face_Properties( face, &properties );

    printf( gettext( "There are %d fonts in this collection.\n" ),
            (int)(properties.num_Faces) );

    if ( num_Faces >= properties.num_Faces )
      Panic( gettext(
             "There is no collection with index %d in this font file.\n" ),
             num_Faces );

    TT_Close_Face( face );

    error = TT_Open_Collection( engine, filename, num_Faces, &face );

    /* get face properties and eblc */

    TT_Get_Face_Properties( face, &properties );
    if ( force_sbit )
    {
      error = TT_Get_Face_Bitmaps( face, &eblc );
      if ( error == TT_Err_Table_Missing )
        Panic( gettext( "There is no embedded bitmap data in the font.\n" ) );
      if ( error )
      {
        fprintf( stderr, gettext(
                 "Error while retrieving embedded bitmaps table.\n" ) );
        goto Failure;
      }
    }

    /* create glyph */

    error = TT_New_Glyph( face, &glyph );
    if ( error )
    {
      fprintf( stderr, gettext( "Could not create glyph container.\n" ) );
      goto Failure;
    }

    /* create instance */

    error = TT_New_Instance( face, &instance );
    if ( error )
    {
      fprintf( stderr, gettext( "Could not create instance.\n" ) );
      goto Failure;
    }

    error = TT_Set_Instance_Resolutions( instance, res, res );
    if ( error )
    {
      fprintf( stderr, gettext( "Could not set device resolutions.\n" ) );
      goto Failure;
    }

    error = TT_Set_Instance_CharSize( instance, ptsize*64 );
    if ( error )
    {
      fprintf( stderr, gettext( "Could not reset instance.\n" ) );
      goto Failure;
    }

    TT_Get_Instance_Metrics( instance, &imetrics );

    printf( gettext( "Instance metrics: ppemX %d, ppemY %d\n" ),
            imetrics.x_ppem,
            imetrics.y_ppem );

    if ( force_sbit )
    {
      error = TT_New_SBit_Image( &bitmap );
      if ( error )
      {
        fprintf( stderr, gettext(
                 "Could not allocate glyph bitmap container.\n" ) );
        goto Failure;
      }

      error = TT_Load_Glyph_Bitmap( face, instance, glyph_index, bitmap );
      if ( error )
      {
        fprintf( stderr, gettext(
                 "Can't load bitmap for glyph %d.\n" ), glyph_index );
        goto Failure;
      }

      Show_Metrics( bitmap->metrics, "SBit's metrics" );

      printf( "SBit glyph:\n" );
      Show_Single_Glyph( &bitmap->map );
    }
    else
    {
      TT_Load_Glyph( instance, glyph, glyph_index, load_flags );
      TT_Get_Glyph_Big_Metrics( glyph, &metrics );

      map.width = ( metrics.bbox.xMax - metrics.bbox.xMin ) / 64;
      map.rows = ( metrics.bbox.yMax - metrics.bbox.yMin ) / 64;
      map.cols = ( map.width + 7 ) / 8;
      map.size = map.cols * map.rows;
      map.bitmap = malloc( map.size );
      map.flow = TT_Flow_Down;

      memset( map.bitmap, 0, map.size );

      error = TT_Get_Glyph_Bitmap( glyph, &map,
                                   -metrics.bbox.xMin,
                                   -metrics.bbox.yMin );

      Show_Metrics( metrics, gettext( "Outline's metrics" ) );

      printf( gettext( "Outline glyph\n" ) );
      Show_Single_Glyph( &map );
    }

    free( map.bitmap );

    if ( bitmap )
      TT_Done_SBit_Image( bitmap );

    TT_Done_Instance( instance );
    TT_Done_Glyph( glyph );
    TT_Done_FreeType( engine );

    exit( EXIT_SUCCESS );      /* for safety reasons */

    return 0;       /* never reached */

  Failure:
    fprintf( stderr, "  " );
    fprintf( stderr, gettext( "FreeType error message: %s\n" ),
             TT_ErrToString18( error ) );

    exit( EXIT_FAILURE );

    return 0;       /* never reached */
  }
예제 #9
0
파일: ftdump.c 프로젝트: DavidGriffith/finx
  int
  main( int  argc, char**  argv )
  {
    int    i;
    char   filename[128 + 4];
    char   alt_filename[128 + 4];
    char*  execname;
    char*  gt;


#ifdef HAVE_LIBINTL_H
    setlocale( LC_ALL, "" );
    bindtextdomain( "freetype", LOCALEDIR );
    textdomain( "freetype" );
#endif

    execname = argv[0];

    if ( argc != 2 )
    {
      gt = gettext( "ftdump: Simple TrueType Dumper -- part of the FreeType project" );
      fprintf( stderr, "%s\n", gt );
      separator_line( stderr, strlen( gt ) );

      fprintf( stderr, gettext( "Usage: %s fontname[.ttf|.ttc]\n\n" ),
               execname );

      exit( EXIT_FAILURE );
    }

    i = strlen( argv[1] );
    while ( i > 0 && argv[1][i] != '\\' )
    {
      if ( argv[1][i] == '.' )
        i = 0;
      i--;
    }

    filename[128] = '\0';
    alt_filename[128] = '\0';

    strncpy( filename, argv[1], 128 );
    strncpy( alt_filename, argv[1], 128 );

    if ( i >= 0 )
    {
      strncpy( filename + strlen( filename ), ".ttf", 4 );
      strncpy( alt_filename + strlen( alt_filename ), ".ttc", 4 );
    }

    /* Initialize engine */

    old_memory = 0;

    if ( (error = TT_Init_FreeType( &engine )) )
    {
      fprintf( stderr, gettext( "Error while initializing engine.\n" ) );
      goto Failure;
    }

    if ( (error = TT_Init_SBit_Extension( engine )) )
    {
      fprintf( stderr, gettext(
               "Error while initializing embedded bitmap extension.\n" ) );
      goto Failure;
    }

    if ( (error = TT_Init_GSUB_Extension( engine )) )
    {
      fprintf( stderr, gettext(
               "Error while initializing GSUB extension.\n" ) );
      goto Failure;
    }

    FOOTPRINT( initial_overhead );

    /* Open and Load face */

    error = TT_Open_Face( engine, filename, &face );
    if ( error == TT_Err_Could_Not_Open_File )
    {
      strcpy( filename, alt_filename );
      error = TT_Open_Face( engine, alt_filename, &face );
    }

    if ( error == TT_Err_Could_Not_Open_File )
      Panic( gettext( "Could not find or open %s.\n" ), filename );
    if ( error )
    {
      fprintf( stderr, gettext( "Error while opening %s.\n" ), filename );
      goto Failure;
    }

    FOOTPRINT( face_object );

    /* get face properties and allocate preload arrays */

    TT_Get_Face_Properties( face, &properties );
    num_glyphs = properties.num_Glyphs;

    /* Now do various dumps */

    if ( flag_names )
      Print_Names();

    if ( flag_encodings )
      Print_Encodings();

    if ( flag_cmap )
      Print_Cmap();

    if ( flag_sbits )
      Print_SBits();

    if ( flag_ttopen )
      Print_GSUB();

#ifndef FREETYPE_DLL  /* the statistics are meaningless if we use a DLL. */
    if ( flag_memory )
      Print_Memory();
#endif

    TT_Close_Face( face );

    TT_Done_FreeType( engine );

    exit( EXIT_SUCCESS );       /* for safety reasons */

    return 0;                   /* never reached */

  Failure:
    fprintf( stderr, "  " );
    Panic( gettext( "FreeType error message: %s\n" ),
           TT_ErrToString18( error ) );

    return 0;                   /* never reached */
}
예제 #10
0
void
readttf(Font *fnt, Boolean quiet, Boolean only_range)
{
  TT_Error error;
  ttfinfo *ti, *Ti;
  long Num, index;
  unsigned int i, j;
  long k, max_k;
  unsigned short num_cmap;
  unsigned short cmap_plat, cmap_enc;
  int index_array[257];

  static Boolean initialized = False;

  TT_UShort in_string[2];
  TTO_GSUB_String in, out;

  TT_UShort script_index, language_index, feature_index;
  TT_UShort req_feature_index = 0xFFFF;


  /*
   *   We allocate a placeholder boundary and the `.notdef' character.
   */

  if (!only_range)
  {
    ti = newchar(fnt);
    ti->charcode = -1;
    ti->adobename = ".notdef";

    ti = newchar(fnt);
    ti->charcode = -1;
    ti->adobename = "||"; /* boundary character name */
  }

  /*
   *   Initialize FreeType engine.
   */

  if (!initialized)
  {
    if ((error = TT_Init_FreeType(&engine)))
      oops("Cannot initialize engine (error code = 0x%x).", error);

    if ((error = TT_Init_Kerning_Extension(engine)))
      oops("Cannot initialize kerning (error code = 0x%x).", error);

    if (fnt->PSnames)
      if ((error = TT_Init_Post_Extension(engine)))
        oops("Cannot initialize PS name support (error code = 0x%x).", error);

    if (fnt->rotate)
      if ((error = TT_Init_GSUB_Extension(engine)))
        oops("Cannot initialize GSUB support (error code = 0x%x).", error);

    /*
     *   Load face.
     */

    real_ttfname = TeX_search_ttf_file(&(fnt->ttfname));
    if (!real_ttfname)
      oops("Cannot find `%s'.", fnt->ttfname);

    if ((error = TT_Open_Face(engine, real_ttfname, &face)))
      oops("Cannot open `%s'.", real_ttfname);

    /*
     *   Get face properties and allocate preload arrays.
     */

    TT_Get_Face_Properties(face, &properties);

    /*
     *   Now we try to open the proper font in a collection.
     */

    if (fnt->fontindex != 0)
    {
      if (properties.num_Faces == 1)
      {
        warning("This isn't a TrueType collection.\n"
                "Parameter `-f' is ignored.");
        fnt->fontindex = 0;
        fnt->fontindexparam = NULL;
      }
      else
      {
        TT_Close_Face(face);
        if ((error = TT_Open_Collection(engine, real_ttfname,
                                        fnt->fontindex, &face)))
          oops("Cannot open font %lu in TrueType Collection `%s'.",
               fnt->fontindex, real_ttfname);
      }
    }

    /*
     *   Create instance.
     */

    if ((error = TT_New_Instance(face, &instance)))
      oops("Cannot create instance for `%s' (error code = 0x%x).",
           real_ttfname, error);

    /*
     *   We use a dummy glyph size of 10pt.
     */

    if ((error = TT_Set_Instance_CharSize(instance, 10 * 64)))
      oops("Cannot set character size (error code = 0x%x).", error);

    matrix1.xx = (TT_Fixed)(floor(fnt->efactor * 1024) * (1L<<16)/1024);
    matrix1.xy = (TT_Fixed)(floor(fnt->slant * 1024) * (1L<<16)/1024);
    matrix1.yx = (TT_Fixed)0;
    matrix1.yy = (TT_Fixed)(1L<<16);

    if (fnt->rotate)
    {
      matrix2.xx = 0;
      matrix2.yx = 1L << 16;
      matrix2.xy = -matrix2.yx;
      matrix2.yy = matrix2.xx;
    }

    if ((error = TT_Set_Instance_Transform_Flags(
                   instance,
                   fnt->rotate ? 1 : 0,
                   fnt->efactor != 1.0 ? 1 : 0)))
      oops("Cannot set transform flags (error code = 0x%x).", error);

    /*
     *   Create glyph container.
     */

    if ((error = TT_New_Glyph(face, &glyph)))
      oops("Cannot create glyph container (error code = 0x%x).", error);

    fnt->units_per_em = properties.header->Units_Per_EM;
    fnt->fixedpitch = properties.postscript->isFixedPitch;
    fnt->italicangle = properties.postscript->italicAngle / 65536.0;

    if (fnt->PSnames != Only)
    {
      num_cmap = properties.num_CharMaps;
      for (i = 0; i < num_cmap; i++)
      {
        if ((error = TT_Get_CharMap_ID(face, i, &cmap_plat, &cmap_enc)))
          oops("Cannot query cmap (error code = 0x%x).", error);
        if (cmap_plat == fnt->pid && cmap_enc == fnt->eid)
          break;
      }
      if (i == num_cmap)
      {
        fprintf(stderr, "%s: ERROR: Invalid platform and/or encoding ID.\n",
                progname);
        if (num_cmap == 1)
          fprintf(stderr, "  The only valid PID/EID pair is");
        else
          fprintf(stderr, "  Valid PID/EID pairs are:\n");
        for (i = 0; i < num_cmap; i++)
        {
          TT_Get_CharMap_ID(face, i, &cmap_plat, &cmap_enc);
          fprintf(stderr, "    (%i,%i)\n", cmap_plat, cmap_enc);
        }
        fprintf(stderr, "\n");
        exit(1);
      }

      if ((error = TT_Get_CharMap(face, i, &char_map)))
        oops("Cannot load cmap (error code = 0x%x).", error);
    }

    if (fnt->PSnames)
    {
      if ((error = TT_Load_PS_Names(face, &post)))
        oops("Cannot load TrueType PS names (error code = 0x%x).", error);
    }
    else if (cmap_plat == Microsoft_platform &&
             cmap_enc == Microsoft_Unicode_encoding)
      set_encoding_scheme(encUnicode, fnt);
    else if (cmap_plat == Macintosh_platform &&
             cmap_enc == Macintosh_encoding)
      set_encoding_scheme(encMac, fnt);
    else
      set_encoding_scheme(encFontSpecific, fnt);

    if (fnt->rotate)
    {
      gsub = &gsub_;

      error = TT_Load_GSUB_Table(face, gsub, NULL);
      if (!error)
        has_gsub = True;
      else if (error != TT_Err_Table_Missing)
        warning("Cannot load GSUB table (error code = 0x%x).", error);
      else
        warning("No GSUB data available "
                "for vertical glyph presentation forms.");

      /* we check for the `vert' feature in Chinese, Japanese, and Korean */

      error = TT_GSUB_Select_Script(gsub,
                                    SCRIPT_kana,
                                    &script_index);
      if (error)
        goto check_hani;
      error = TT_GSUB_Select_Feature(gsub,
                                     FEATURE_vert,
                                     script_index,
                                     0xFFFF,
                                     &feature_index);
      if (error)
      {
        error = TT_GSUB_Select_Language(gsub,
                                        LANGUAGE_JAN,
                                        script_index,
                                        &language_index,
                                        &req_feature_index);
        if (error)
          goto check_hani;
        error = TT_GSUB_Select_Feature(gsub,
                                       FEATURE_vert,
                                       script_index,
                                       language_index,
                                       &feature_index);
        if (error)
          goto check_hani;
        else
          goto Done;
      }
      else
        goto Done;

    check_hani:
      error = TT_GSUB_Select_Script(gsub,
                                    SCRIPT_hani,
                                    &script_index);
      if (error)
        goto check_hang;
      error = TT_GSUB_Select_Feature(gsub,
                                     FEATURE_vert,
                                     script_index,
                                     0xFFFF,
                                     &feature_index);
      if (error)
      {
        error = TT_GSUB_Select_Language(gsub,
                                        LANGUAGE_CHN,
                                        script_index,
                                        &language_index,
                                        &req_feature_index);
        if (error)
          goto check_hang;
        error = TT_GSUB_Select_Feature(gsub,
                                       FEATURE_vert,
                                       script_index,
                                       language_index,
                                       &feature_index);
        if (error)
          goto check_hang;
        else
          goto Done;
      }
      else
        goto Done;

    check_hang:
      error = TT_GSUB_Select_Script(gsub,
                                    SCRIPT_hang,
                                    &script_index);
      if (error)
        goto Done;
      error = TT_GSUB_Select_Feature(gsub,
                                     FEATURE_vert,
                                     script_index,
                                     0xFFFF,
                                     &feature_index);
      if (error)
      {
        error = TT_GSUB_Select_Language(gsub,
                                        LANGUAGE_KOR,
                                        script_index,
                                        &language_index,
                                        &req_feature_index);
        if (error)
          goto Done;
        error = TT_GSUB_Select_Feature(gsub,
                                       FEATURE_vert,
                                       script_index,
                                       language_index,
                                       &feature_index);
      }

    Done:
      if (error)
      {
        warning("There is no data for vertical typesetting in GSUB table.");
        has_gsub = False;
      }

      if (req_feature_index != 0xFFFF)
        TT_GSUB_Add_Feature(gsub, req_feature_index, ALL_GLYPHS);
      TT_GSUB_Add_Feature(gsub, feature_index, ALL_GLYPHS);

      in.length = 1;
      in.pos = 0;
      in.string = in_string;
      in.properties = NULL;

      out.pos = 0;
      out.allocated = 0;
      out.string = NULL;
      out.properties = NULL;
    }

    initialized = True;
  }

  if (!quiet)
  {
    if (only_range)
      printf("\n\n%s:\n", fnt->fullname);
    printf("\n");
    printf("Glyph  Code   Glyph Name                ");
    printf("Width  llx    lly      urx    ury\n");
    printf("---------------------------------------");
    printf("---------------------------------\n");
  }

  /*
   *   We load only glyphs with a valid cmap entry.  Nevertheless, for
   *   the default mapping, we use the first 256 glyphs addressed by
   *   ascending code points, followed by glyphs not in the cmap.
   *
   *   If we compute a range, we take the character codes given in
   *   the fnt->sf_code array.
   *
   *   If the -N flag is set, no cmap is used at all.  Instead, the
   *   first 256 glyphs (with a valid PS name) are used for the default
   *   mapping.
   */

  if (!only_range)
    for (i = 0; i < 257; i++)
      index_array[i] = 0;
  else
    for (i = 0; i < 256; i++)
      fnt->inencptrs[i] = 0;

  j = 0;
  if (fnt->PSnames == Only)
    max_k = properties.num_Glyphs - 1;
  else
    max_k = only_range ? 0xFF : 0x16FFFF;

  for (k = 0; k <= max_k; k++)
  {
    char *an;


    if (fnt->PSnames != Only)
    {
      if (only_range)
      {
        index = fnt->sf_code[k];
        if (index < 0)
          continue;
        j = k;
      }
      else
        index = k;

      Num = TT_Char_Index(char_map, index);

      /* now we try to get a vertical glyph form */

      if (has_gsub)
      {
        in_string[0] = Num;
        error = TT_GSUB_Apply_String(gsub, &in, &out);
        if (error && error != TTO_Err_Not_Covered)
          warning("Cannot get the vertical glyph form for glyph index %d.",
                  Num);
        else
          Num = out.string[0];
      }

      if (Num < 0)
        oops("Failure on cmap mapping from %s.", fnt->ttfname);
      if (Num == 0)
        continue;
      if (!only_range)
        if (Num <= 256)
          index_array[Num] = 1;
    }
    else
    {
      Num = k;
      index = 0;
    }

    error = TT_Load_Glyph(instance, glyph, Num, 0);
    if (!error)
      error = TT_Get_Glyph_Big_Metrics(glyph, &metrics);
    if (!error)
      error = TT_Get_Glyph_Outline(glyph, &outline);
    if (!error)
    {
      if (fnt->efactor != 1.0 || fnt->slant != 0.0 )
        TT_Transform_Outline(&outline, &matrix1);
      if (fnt->rotate)
        TT_Transform_Outline(&outline, &matrix2);
    }
    if (!error)
      error = TT_Get_Outline_BBox(&outline, &bbox); /* we need the non-
                                                       grid-fitted bbox */
    if (!error)
    {
      if (fnt->PSnames)
        (void)TT_Get_PS_Name(face, Num, &an);
      else
        an = code_to_adobename(index);

      /* ignore characters not usable for typesetting with TeX */

      if (strcmp(an, ".notdef") == 0)
        continue;
      if (strcmp(an, ".null") == 0)
        continue;
      if (strcmp(an, "nonmarkingreturn") == 0)
        continue;

      ti = newchar(fnt);
      ti->charcode = index;
      ti->glyphindex = Num;
      ti->adobename = an;
      ti->llx = bbox.xMin * 1000 / fnt->units_per_em;
      ti->lly = bbox.yMin * 1000 / fnt->units_per_em;
      ti->urx = bbox.xMax * 1000 / fnt->units_per_em;
      ti->ury = bbox.yMax * 1000 / fnt->units_per_em;

      /*
       *   We must now shift the rotated character both horizontally
       *   and vertically.  The vertical amount is 25% by default.
       */

      if (fnt->rotate)
      {
        ti->llx += (metrics.vertBearingY - bbox.xMin) *
                     1000 / fnt->units_per_em;
        ti->lly -= 1000 * fnt->y_offset;
        ti->urx += (metrics.vertBearingY - bbox.xMin) *
                     1000 / fnt->units_per_em;
        ti->ury -= 1000 * fnt->y_offset;
      }

      /*
       *   We need to avoid negative heights or depths.  They break accents
       *   in math mode, among other things.
       */

      if (ti->lly > 0)
        ti->lly = 0;
      if (ti->ury < 0)
        ti->ury = 0;
      if (fnt->rotate)
        ti->width = metrics.vertAdvance * 1000 / fnt->units_per_em;
      else
        ti->width = transform(metrics.horiAdvance * 1000 / fnt->units_per_em,
                              0, fnt->efactor, fnt->slant);

      if (!quiet)
        printf("%5ld  %05lx  %-25s %5d  % 5d,% 5d -- % 5d,% 5d\n",
               Num, index, ti->adobename,
               ti->width,
               ti->llx, ti->lly, ti->urx, ti->ury);

      if (j < 256)
      {
        fnt->inencptrs[j] = ti;
        ti->incode = j;
      }
      j++;
    }
  }

  /*
   *   Now we load glyphs without a cmap entry, provided some slots are
   *   still free -- we skip this if we have to compute a range or use
   *   PS names.
   */

  if (!only_range && !fnt->PSnames)
  {
    for (i = 1; i <= properties.num_Glyphs; i++)
    {
      char *an;


      if (index_array[i] == 0)
      {
        error = TT_Load_Glyph(instance, glyph, i, 0);
        if (!error)
          error = TT_Get_Glyph_Big_Metrics(glyph, &metrics);
        if (!error)
          error = TT_Get_Glyph_Outline(glyph, &outline);
        if (!error)
          error = TT_Get_Outline_BBox(&outline, &bbox);
        if (!error)
        {
          an = code_to_adobename(i | 0x1000000);

          ti = newchar(fnt);
          ti->charcode = i | 0x1000000;
          ti->glyphindex = i;
          ti->adobename = an;
          ti->llx = bbox.xMin * 1000 / fnt->units_per_em;
          ti->lly = bbox.yMin * 1000 / fnt->units_per_em;
          ti->urx = bbox.xMax * 1000 / fnt->units_per_em;
          ti->ury = bbox.yMax * 1000 / fnt->units_per_em;

          if (ti->lly > 0)
            ti->lly = 0;
          if (ti->ury < 0)
            ti->ury = 0;
          ti->width = transform(metrics.horiAdvance*1000 / fnt->units_per_em,
                                0, fnt->efactor, fnt->slant);

          if (!quiet)
            printf("%5d         %-25s %5d  % 5d,% 5d -- % 5d,% 5d\n",
                   i, ti->adobename,
                   ti->width,
                   ti->llx, ti->lly, ti->urx, ti->ury);

          if (j < 256)
          {
            fnt->inencptrs[j] = ti;
            ti->incode = j;
          }
          else
            break;
          j++;
        }
      }
    }
  }

  /* Finally, we construct a `Germandbls' glyph if necessary */

  if (!only_range)
  {
    if (NULL == findadobe("Germandbls", fnt->charlist) &&
        NULL != (Ti = findadobe("S", fnt->charlist)))
    {
      pcc *np, *nq;


      ti = newchar(fnt);
      ti->charcode = properties.num_Glyphs | 0x1000000;
      ti->glyphindex = properties.num_Glyphs;
      ti->adobename = "Germandbls";
      ti->width = Ti->width << 1;
      ti->llx = Ti->llx;
      ti->lly = Ti->lly;
      ti->urx = Ti->width + Ti->urx;
      ti->ury = Ti->ury;
      ti->kerns = Ti->kerns;

      np = newpcc();
      np->partname = "S";
      nq = newpcc();
      nq->partname = "S";
      nq->xoffset = Ti->width;
      np->next = nq;
      ti->pccs = np;
      ti->constructed = True;

      if (!quiet)
        printf("*            %-25s %5d  % 5d,% 5d -- % 5d,% 5d\n",
               ti->adobename,
               ti->width,
               ti->llx, ti->lly, ti->urx, ti->ury);
    }
  }

  /* kerning between subfonts isn't available */
  if (!only_range)
    readttf_kern(fnt);
}
예제 #11
0
static void image_ttf_face_properties(INT32 args)
{
   int res;
   TT_Face_Properties prop;

   pop_n_elems(args);

   res=TT_Get_Face_Properties(THISf->face,&prop);
   if (res) my_tt_error("Image.TTF.Face->properties()","",res);

   push_text("num_Glyphs");   push_int(prop.num_Glyphs);
   push_text("max_Points");   push_int(prop.max_Points);
   push_text("max_Contours");   push_int(prop.max_Contours);
   push_text("num_Faces");   push_int(prop.num_Faces);

   push_text("header");
   if (prop.header)
   {
      push_text("Table_Version"); push_int(prop.header->Table_Version);
      push_text("Font_Revision"); push_int(prop.header->Font_Revision);
      push_text("CheckSum_Adjust"); push_int(prop.header->CheckSum_Adjust);
      push_text("Magic_Number"); push_int(prop.header->Magic_Number);
      push_text("Flags"); push_int(prop.header->Flags);
      push_text("Units_Per_EM"); push_int(prop.header->Units_Per_EM);
      push_text("Created");
      push_int(prop.header->Created[0]);
      push_int(prop.header->Created[1]);
      f_aggregate(2);
      push_text("Modified");
      push_int(prop.header->Modified[0]);
      push_int(prop.header->Modified[1]);
      f_aggregate(2);
      push_text("xMin"); push_int(prop.header->xMin);
      push_text("yMin"); push_int(prop.header->yMin);
      push_text("xMax"); push_int(prop.header->xMax);
      push_text("yMax"); push_int(prop.header->yMax);
      push_text("Mac_Style"); push_int(prop.header->Mac_Style);
      push_text("Lowest_Rec_PPEM"); push_int(prop.header->Lowest_Rec_PPEM);
      push_text("Font_Direction"); push_int(prop.header->Font_Direction);
      push_text("Index_To_Loc_Format");
      push_int(prop.header->Index_To_Loc_Format);
      push_text("Glyph_Data_Format");
      push_int(prop.header->Glyph_Data_Format);
      f_aggregate_mapping(17*2);
   }
   else push_int(0);

   push_text("horizontal");
   if (prop.horizontal)
   {
      push_text("Version"); push_int(prop.horizontal->Version);
      push_text("Ascender"); push_int(prop.horizontal->Ascender);
      push_text("Descender"); push_int(prop.horizontal->Descender);
      push_text("Line_Gap"); push_int(prop.horizontal->Line_Gap);
      push_text("advance_Width_Max"); push_int(prop.horizontal->advance_Width_Max);
      push_text("min_Left_Side_Bearing"); push_int(prop.horizontal->min_Left_Side_Bearing);
      push_text("min_Right_Side_Bearing"); push_int(prop.horizontal->min_Right_Side_Bearing);
      push_text("xMax_Extent"); push_int(prop.horizontal->xMax_Extent);
      push_text("caret_Slope_Rise"); push_int(prop.horizontal->caret_Slope_Rise);
      push_text("caret_Slope_Run"); push_int(prop.horizontal->caret_Slope_Run);
      push_text("metric_Data_Format"); push_int(prop.horizontal->metric_Data_Format);
      push_text("number_Of_HMetrics"); push_int(prop.horizontal->number_Of_HMetrics);
      f_aggregate_mapping(13*2);
   }
   else push_int(0);

   push_text("os2");
   if (prop.os2)
   {
      push_text("version"); push_int(prop.os2->version);
      push_text("xAvgCharWidth"); push_int(prop.os2->xAvgCharWidth);
      push_text("usWeightClass"); push_int(prop.os2->usWeightClass);
      push_text("usWidthClass"); push_int(prop.os2->usWidthClass);
      push_text("fsType"); push_int(prop.os2->fsType);
      push_text("ySubscriptXSize"); push_int(prop.os2->ySubscriptXSize);
      push_text("ySubscriptYSize"); push_int(prop.os2->ySubscriptYSize);
      push_text("ySubscriptXOffset"); push_int(prop.os2->ySubscriptXOffset);
      push_text("ySubscriptYOffset"); push_int(prop.os2->ySubscriptYOffset);
      push_text("ySuperscriptXSize"); push_int(prop.os2->ySuperscriptXSize);
      push_text("ySuperscriptYSize"); push_int(prop.os2->ySuperscriptYSize);
      push_text("ySuperscriptXOffset"); push_int(prop.os2->ySuperscriptXOffset);
      push_text("ySuperscriptYOffset"); push_int(prop.os2->ySuperscriptYOffset);
      push_text("yStrikeoutSize"); push_int(prop.os2->yStrikeoutSize);
      push_text("yStrikeoutPosition"); push_int(prop.os2->yStrikeoutPosition);
      push_text("sFamilyClass"); push_int(prop.os2->sFamilyClass);

      push_text("panose");
      push_string(make_shared_binary_string(prop.os2->panose,10));

      push_text("ulUnicodeRange1"); push_int(prop.os2->ulUnicodeRange1);
      push_text("ulUnicodeRange2"); push_int(prop.os2->ulUnicodeRange2);
      push_text("ulUnicodeRange3"); push_int(prop.os2->ulUnicodeRange3);
      push_text("ulUnicodeRange4"); push_int(prop.os2->ulUnicodeRange4);

      push_text("achVendID");
      push_string(make_shared_binary_string(prop.os2->achVendID,4));

      push_text("fsSelection"); push_int(prop.os2->fsSelection);
      push_text("usFirstCharIndex"); push_int(prop.os2->usFirstCharIndex);
      push_text("usLastCharIndex"); push_int(prop.os2->usLastCharIndex);
      push_text("sTypoAscender"); push_int(prop.os2->sTypoAscender);
      push_text("sTypoDescender"); push_int(prop.os2->sTypoDescender);
      push_text("sTypoLineGap"); push_int(prop.os2->sTypoLineGap);
      push_text("usWinAscent"); push_int(prop.os2->usWinAscent);
      push_text("usWinDescent"); push_int(prop.os2->usWinDescent);
      push_text("ulCodePageRange1"); push_int(prop.os2->ulCodePageRange1);
      push_text("ulCodePageRange2"); push_int(prop.os2->ulCodePageRange2);

      f_aggregate_mapping(32*2);
   }
   else push_int(0);

   push_text("postscript");
   if (prop.postscript)
   {
      push_text("FormatType"); push_int(prop.postscript->FormatType);
      push_text("italicAngle"); push_int(prop.postscript->italicAngle);
      push_text("underlinePosition"); push_int(prop.postscript->underlinePosition);
      push_text("underlineThickness"); push_int(prop.postscript->underlineThickness);
      push_text("isFixedPitch"); push_int(prop.postscript->isFixedPitch);
      push_text("minMemType42"); push_int(prop.postscript->minMemType42);
      push_text("maxMemType42"); push_int(prop.postscript->maxMemType42);
      push_text("minMemType1"); push_int(prop.postscript->minMemType1);
      push_text("maxMemType1"); push_int(prop.postscript->maxMemType1);
      f_aggregate_mapping(9*2);
   }
   else push_int(0);

   push_text("hdmx");
   if (prop.hdmx)
   {
      int i;

      push_text("version"); push_int(prop.hdmx->version);
      push_text("num_records"); push_int(prop.hdmx->num_records);
      push_text("records");

      for (i=0; i<prop.hdmx->num_records; i++)
      {
	 push_text("ppem"); push_int(prop.hdmx->records[i].ppem);
	 push_text("max_width"); push_int(prop.hdmx->records[i].max_width);
	 /*	 push_text("widths"); push_int(prop.hdmx->records[i].widths);*/
	 f_aggregate_mapping(2*2);
      }
      f_aggregate(prop.hdmx->num_records);

      f_aggregate_mapping(3*2);
   }
   else push_int(0);

   f_aggregate_mapping(9*2);
}
예제 #12
0
TT_Fonthandle*
i_tt_new(const char *fontname) {
  TT_Error error;
  TT_Fonthandle *handle;
  unsigned short i,n;
  unsigned short platform,encoding;
  i_tt_engine *tteng;

  if ((tteng = i_init_tt()) == NULL) {
    i_push_error(0, "Could not initialize FT1 engine");
    return NULL;
  }

  i_clear_error();
  
  mm_log((1,"i_tt_new(fontname '%s')\n",fontname));
  
  /* allocate memory for the structure */
  
  handle = mymalloc( sizeof(TT_Fonthandle) ); /* checked 5Nov05 tonyc */

  /* load the typeface */
  error = TT_Open_Face( tteng->engine, fontname, &handle->face );
  if ( error ) {
    myfree(handle);
    if ( error == TT_Err_Could_Not_Open_File ) {
      mm_log((1, "Could not find/open %s.\n", fontname ));
    }
    else {
      mm_log((1, "Error while opening %s, error code = 0x%x.\n",fontname, 
              (unsigned)error )); 
    }
    i_tt_push_error(error);
    return NULL;
  }
  
  TT_Get_Face_Properties( handle->face, &(handle->properties) );

  /* First, look for a Unicode charmap */
  n = handle->properties.num_CharMaps;
  USTRCT( handle->char_map )=NULL; /* Invalidate character map */
  
  for ( i = 0; i < n; i++ ) {
    TT_Get_CharMap_ID( handle->face, i, &platform, &encoding );
    if ( (platform == 3 && encoding == 1 ) 
         || (platform == 0 && encoding == 0 ) ) {
      mm_log((2,"i_tt_new - found char map platform %u encoding %u\n", 
              platform, encoding));
      TT_Get_CharMap( handle->face, i, &(handle->char_map) );
      break;
    }
  }
  if (!USTRCT(handle->char_map) && n != 0) {
    /* just use the first one */
    TT_Get_CharMap( handle->face, 0, &(handle->char_map));
  }

  /* Zero the pointsizes - and ordering */
  
  for(i=0;i<TT_CHC;i++) {
    USTRCT(handle->instanceh[i].instance)=NULL;
    handle->instanceh[i].order=i;
    handle->instanceh[i].ptsize=0;
    handle->instanceh[i].smooth=-1;
  }

#ifdef FTXPOST
  handle->loaded_names = 0;
#endif

  mm_log((1,"i_tt_new <- %p\n",handle));
  return handle;
}
예제 #13
0
/*
=item i_tt_face_name(handle, name_buf, name_buf_size)

Retrieve's the font's postscript name.

This is complicated by the need to handle encodings and so on.

=cut
 */
size_t
i_tt_face_name(TT_Fonthandle *handle, char *name_buf, size_t name_buf_size) {
  TT_Face_Properties props;
  int name_count;
  int i;
  TT_UShort platform_id, encoding_id, lang_id, name_id;
  TT_UShort name_len;
  TT_String *name;
  int want_index = -1; /* an acceptable but not perfect name */
  int score = 0;

  i_clear_error();
  
  TT_Get_Face_Properties(handle->face, &props);
  name_count = props.num_Names;
  for (i = 0; i < name_count; ++i) {
    TT_Get_Name_ID(handle->face, i, &platform_id, &encoding_id, &lang_id, 
                   &name_id);

    TT_Get_Name_String(handle->face, i, &name, &name_len);

    if (platform_id != TT_PLATFORM_APPLE_UNICODE && name_len
        && name_id == TT_NAME_ID_PS_NAME) {
      int might_want_index = -1;
      int might_score = 0;
      if ((platform_id == TT_PLATFORM_MACINTOSH && encoding_id == TT_MAC_ID_ROMAN)
          ||
          (platform_id == TT_PLATFORM_MICROSOFT && encoding_id == TT_MS_LANGID_ENGLISH_UNITED_STATES)) {
        /* exactly what we want */
        want_index = i;
        break;
      }
      
      if (platform_id == TT_PLATFORM_MICROSOFT
          && (encoding_id & 0xFF) == TT_MS_LANGID_ENGLISH_GENERAL) {
        /* any english is good */
        might_want_index = i;
        might_score = 9;
      }
      /* there might be something in between */
      else {
        /* anything non-unicode is better than nothing */
        might_want_index = i;
        might_score = 1;
      }
      if (might_score > score) {
        score = might_score;
        want_index = might_want_index;
      }
    }
  }

  if (want_index != -1) {
    TT_Get_Name_String(handle->face, want_index, &name, &name_len);
    
    strncpy(name_buf, name, name_buf_size);
    name_buf[name_buf_size-1] = '\0';

    return strlen(name) + 1;
  }
  else {
    i_push_error(0, "no face name present");
    return 0;
  }
}