Example #1
0
  ftc_basic_family_get_count( FTC_Family   ftcfamily,
                              FTC_Manager  manager )
  {
    FTC_BasicFamily  family = (FTC_BasicFamily)ftcfamily;
    FT_Error         error;
    FT_Face          face;
    FT_UInt          result = 0;


    error = FTC_Manager_LookupFace( manager, family->attrs.scaler.face_id,
                                    &face );

    if ( error || !face )
      return result;

    if ( (FT_ULong)face->num_glyphs > FT_UINT_MAX || 0 > face->num_glyphs )
    {
      FT_TRACE1(( "ftc_basic_family_get_count: too large number of glyphs " ));
      FT_TRACE1(( "in this face, truncated\n", face->num_glyphs ));
    }

    if ( !error )
      result = (FT_UInt)face->num_glyphs;

    return result;
  }
Example #2
0
  FT_Stream_Open( FT_Stream    stream,
                  const char*  filepathname )
  {
    FT_FILE*  file;


    if ( !stream )
      return FT_Err_Invalid_Stream_Handle;

    file = ft_fopen( filepathname, "rb" );
    if ( !file )
    {
      FT_ERROR(( "FT_Stream_Open:"
                 " could not open `%s'\n", filepathname ));

      return FT_Err_Cannot_Open_Resource;
    }

    ft_fseek( file, 0, SEEK_END );
    stream->size = ft_ftell( file );
    ft_fseek( file, 0, SEEK_SET );

    stream->descriptor.pointer = file;
    stream->pathname.pointer   = (char*)filepathname;
    stream->pos                = 0;

    stream->read  = ft_ansi_stream_io;
    stream->close = ft_ansi_stream_close;

    FT_TRACE1(( "FT_Stream_Open:" ));
    FT_TRACE1(( " opened `%s' (%d bytes) successfully\n",
                filepathname, stream->size ));

    return FT_Err_Ok;
  }
Example #3
0
  FT_Stream_Open( FT_Stream    stream,
                  const char*  filepathname )
  {
//  FILE*                  file;
    BPTR                   file; // TetiSoft
    struct FileInfoBlock*  fib;  // TetiSoft


    if ( !stream )
      return FT_Err_Invalid_Stream_Handle;

//  file = fopen( filepathname, "rb" );
    file = Open( filepathname, MODE_OLDFILE );  // TetiSoft
    if ( !file )
    {
      FT_ERROR(( "FT_Stream_Open:" ));
      FT_ERROR(( " could not open `%s'\n", filepathname ));

      return FT_Err_Cannot_Open_Resource;
    }

//  fseek( file, 0, SEEK_END );
//  astream->size = ftell( file );
//  fseek( file, 0, SEEK_SET );
    fib = AllocDosObject( DOS_FIB, NULL );
    if ( !fib )
    {
      Close ( file );
      FT_ERROR(( "FT_Stream_Open:" ));
      FT_ERROR(( " could not open `%s'\n", filepathname ));

      return FT_Err_Cannot_Open_Resource;
    }
    if ( !( ExamineFH( file, fib ) ) )
    {
      FreeDosObject( DOS_FIB, fib );
      Close ( file );
      FT_ERROR(( "FT_Stream_Open:" ));
      FT_ERROR(( " could not open `%s'\n", filepathname ));

      return FT_Err_Cannot_Open_Resource;
    }
    stream->size = fib->fib_Size;
    FreeDosObject( DOS_FIB, fib );

//  stream->descriptor.pointer = file;
    stream->descriptor.pointer = (void *)file;

    stream->pathname.pointer   = (char*)filepathname;
    stream->pos                = 0;

    stream->read  = ft_io_stream;
    stream->close = ft_close_stream;

    FT_TRACE1(( "FT_Stream_Open:" ));
    FT_TRACE1(( " opened `%s' (%d bytes) successfully\n",
                filepathname, stream->size ));

    return FT_Err_Ok;
  }
Example #4
0
  FTC_SBitCache_LookupScaler( FTC_SBitCache  cache,
                              FTC_Scaler     scaler,
                              FT_ULong       load_flags,
                              FT_UInt        gindex,
                              FTC_SBit      *ansbit,
                              FTC_Node      *anode )
  {
    FT_Error           error;
    FTC_BasicQueryRec  query;
    FTC_Node           node = 0; /* make compiler happy */
    FT_UInt32          hash;


    if ( anode )
        *anode = NULL;

    /* other argument checks delayed to FTC_Cache_Lookup */
    if ( !ansbit || !scaler )
        return FTC_Err_Invalid_Argument;

    *ansbit = NULL;

    /* FT_Load_Glyph(), FT_Load_Char() take FT_UInt flags */
    if ( load_flags > FT_UINT_MAX )
    {
      FT_TRACE1(( "FTC_ImageCache_LookupScaler: higher bits in load_flags" ));
      FT_TRACE1(( "0x%x are dropped\n", (load_flags & ~((FT_ULong)FT_UINT_MAX)) ));
    }

    query.attrs.scaler     = scaler[0];
    query.attrs.load_flags = (FT_UInt)load_flags;

    /* beware, the hash must be the same for all glyph ranges! */
    hash = FTC_BASIC_ATTR_HASH( &query.attrs ) +
             gindex / FTC_SBIT_ITEMS_PER_NODE;

    FTC_GCACHE_LOOKUP_CMP( cache,
                           ftc_basic_family_compare,
                           FTC_SNode_Compare,
                           hash, gindex,
                           &query,
                           node,
                           error );
    if ( error )
      goto Exit;

    *ansbit = FTC_SNODE( node )->sbits +
              ( gindex - FTC_GNODE( node )->gindex );

    if ( anode )
    {
      *anode = node;
      node->ref_count++;
    }

  Exit:
    return error;
  }
Example #5
0
  FTC_ImageCache_LookupScaler( FTC_ImageCache  cache,
                               FTC_Scaler      scaler,
                               FT_ULong        load_flags,
                               FT_UInt         gindex,
                               FT_Glyph       *aglyph,
                               FTC_Node       *anode )
  {
    FTC_BasicQueryRec  query;
    FTC_Node           node = 0; /* make compiler happy */
    FT_Error           error;
    FT_UInt32          hash;


    /* some argument checks are delayed to FTC_Cache_Lookup */
    if ( !aglyph || !scaler )
    {
      error = FTC_Err_Invalid_Argument;
      goto Exit;
    }

    *aglyph = NULL;
    if ( anode )
      *anode  = NULL;

    /* FT_Load_Glyph(), FT_Load_Char() take FT_UInt flags */
    if ( load_flags > FT_UINT_MAX )
    {
      FT_TRACE1(( "FTC_ImageCache_LookupScaler: higher bits in load_flags" ));
      FT_TRACE1(( "0x%x are dropped\n", (load_flags & ~((FT_ULong)FT_UINT_MAX)) ));
    }

    query.attrs.scaler     = scaler[0];
    query.attrs.load_flags = (FT_UInt)load_flags;

    hash = FTC_BASIC_ATTR_HASH( &query.attrs ) + gindex;

    FTC_GCACHE_LOOKUP_CMP( cache,
                           ftc_basic_family_compare,
                           FTC_GNode_Compare,
                           hash, gindex,
                           &query,
                           node,
                           error );
    if ( !error )
    {
      *aglyph = FTC_INODE( node )->glyph;

      if ( anode )
      {
        *anode = node;
        node->ref_count++;
      }
    }

  Exit:
    return error;
  }
Example #6
0
  /*
   *  CID INFO SERVICE
   *
   */
  static FT_Error
  cff_get_ros( CFF_Face      face,
               const char*  *registry,
               const char*  *ordering,
               FT_Int       *supplement )
  {
    FT_Error  error = CFF_Err_Ok;
    CFF_Font  cff   = (CFF_Font)face->extra.data;


    if ( cff )
    {
      CFF_FontRecDict  dict = &cff->top_font.font_dict;


      if ( dict->cid_registry == 0xFFFFU )
      {
        error = CFF_Err_Invalid_Argument;
        goto Fail;
      }

      if ( registry )
      {
        if ( cff->registry == NULL )
          cff->registry = cff_index_get_sid_string( cff,
                                                    dict->cid_registry );
        *registry = cff->registry;
      }
      
      if ( ordering )
      {
        if ( cff->ordering == NULL )
          cff->ordering = cff_index_get_sid_string( cff,
                                                    dict->cid_ordering );
        *ordering = cff->ordering;
      }

      /*
       * XXX: According to Adobe TechNote #5176, the supplement in CFF
       *      can be a real number. We truncate it to fit public API
       *      since freetype-2.3.6.
       */
      if ( supplement )
      {
        if ( dict->cid_supplement < FT_INT_MIN ||
             dict->cid_supplement > FT_INT_MAX )
          FT_TRACE1(( "cff_get_ros: too large supplement %d is truncated\n",
                      dict->cid_supplement ));
        *supplement = (FT_Int)dict->cid_supplement;
      }
    }
      
  Fail:
    return error;
  }
Example #7
0
FT_Stream_Open( FT_Stream stream, const char*  filepathname)
{
	Dir *dir;
	int  file;

	if ( !stream )
		return FT_Err_Invalid_Stream_Handle;
	file = kopen( (char*)filepathname, OREAD);
	if ( file < 0) {
		FT_ERROR(( "FT_Stream_Open:" ));
		FT_ERROR(( " could not open `%s'\n", filepathname ));
		return FT_Err_Cannot_Open_Resource;
	}
	dir = kdirfstat(file);
	if (dir == nil) {
		kclose(file);
		FT_ERROR(( "FT_Stream_Open:" ));
		FT_ERROR(( " could not stat `%s'\n", filepathname ));
		return FT_Err_Cannot_Open_Resource;
	}
	stream->size = dir->length;
	free(dir);

	stream->descriptor.pointer = (void*)file;
	stream->pathname.pointer = (char*)filepathname;
	stream->pos = 0;

	stream->read  = ft_ansi_stream_io;
	stream->close = ft_ansi_stream_close;

	FT_TRACE1(( "FT_Stream_Open:" ));
	FT_TRACE1(( " opened `%s' (%d bytes) successfully\n",
		filepathname, stream->size ));

	return FT_Err_Ok;
}
Example #8
0
  T42_GlyphSlot_Load( FT_GlyphSlot  glyph,
                      FT_Size       size,
                      FT_UInt       glyph_index,
                      FT_Int32      load_flags )
  {
    FT_Error         error;
    T42_GlyphSlot    t42slot = (T42_GlyphSlot)glyph;
    T42_Size         t42size = (T42_Size)size;
    T42_Face         t42face = (T42_Face)size->face;
    FT_Driver_Class  ttclazz = ((T42_Driver)glyph->face->driver)->ttclazz;


    FT_TRACE1(( "T42_GlyphSlot_Load: glyph index %d\n", glyph_index ));

    /* map T42 glyph index to embedded TTF's glyph index */
    glyph_index = (FT_UInt)ft_strtol(
                    (const char *)t42face->type1.charstrings[glyph_index],
                    NULL, 10 );

    t42_glyphslot_clear( t42slot->ttslot );
    error = ttclazz->load_glyph( t42slot->ttslot,
                                 t42size->ttsize,
                                 glyph_index,
                                 load_flags | FT_LOAD_NO_BITMAP );

    if ( !error )
    {
      glyph->metrics = t42slot->ttslot->metrics;

      glyph->linearHoriAdvance = t42slot->ttslot->linearHoriAdvance;
      glyph->linearVertAdvance = t42slot->ttslot->linearVertAdvance;

      glyph->format  = t42slot->ttslot->format;
      glyph->outline = t42slot->ttslot->outline;

      glyph->bitmap      = t42slot->ttslot->bitmap;
      glyph->bitmap_left = t42slot->ttslot->bitmap_left;
      glyph->bitmap_top  = t42slot->ttslot->bitmap_top;

      glyph->num_subglyphs = t42slot->ttslot->num_subglyphs;
      glyph->subglyphs     = t42slot->ttslot->subglyphs;

      glyph->control_data  = t42slot->ttslot->control_data;
      glyph->control_len   = t42slot->ttslot->control_len;
    }

    return error;
  }
Example #9
0
FT_EXPORT_FUNC(FT_Error)  FT_Register_Extension(
    FT_Driver driver,
    FT_Extension_Class   *clazz)
{
	FT_Extension_Registry  *registry;


	if(!driver)
	{
		return FT_Err_Invalid_Driver_Handle;
	}

	if(!clazz)
	{
		return FT_Err_Invalid_Argument;
	}

	registry = (FT_Extension_Registry *)driver->extensions;

	if(registry)
	{
		FT_Int n   = registry->num_extensions;
		FT_Extension_Class  *cur = registry->classes + n;


		if(n >= FT_MAX_EXTENSIONS)
		{
			return FT_Err_Too_Many_Extensions;
		}

		*cur = *clazz;

		cur->offset  = registry->cur_offset;

		registry->num_extensions++;
		registry->cur_offset +=
		    (cur->size + FT_ALIGNMENT - 1) & - FT_ALIGNMENT;

		FT_TRACE1(("FT_Register_Extension: `%s' successfully registered\n",
		           cur->id));
	}

	return FT_Err_Ok;
}
Example #10
0
FT_EXPORT_FUNC(void *)  FT_Get_Extension(
    FT_Face face,
    const char  *extension_id,
    void       **extension_interface)
{
	FT_Extension_Registry  *registry;


	if(!face || !extension_id || !extension_interface)
	{
		return 0;
	}

	registry = (FT_Extension_Registry *)face->driver->extensions;

	if(registry && face->extensions)
	{
		FT_Extension_Class  *cur   = registry->classes;
		FT_Extension_Class  *limit = cur + registry->num_extensions;


		for(; cur < limit; cur++)
			if(strcmp(cur->id, extension_id) == 0)
			{
				*extension_interface = cur->interface;

				FT_TRACE1(("FT_Get_Extension: got `%s'\n", extension_id));

				return (void *)((char *)face->extensions + cur->offset);
			}
	}

	/* could not find the extension id */

	FT_ERROR(("FT_Get_Extension: couldn't find `%s'\n", extension_id));

	*extension_interface = 0;

	return 0;
}
Example #11
0
  cff_glyph_load( FT_GlyphSlot  cffslot,      /* CFF_GlyphSlot */
                  FT_Size       cffsize,      /* CFF_Size      */
                  FT_UInt       glyph_index,
                  FT_Int32      load_flags )
  {
    FT_Error       error;
    CFF_GlyphSlot  slot = (CFF_GlyphSlot)cffslot;
    CFF_Size       size = (CFF_Size)cffsize;


    if ( !slot )
      return FT_THROW( Invalid_Slot_Handle );

    FT_TRACE1(( "cff_glyph_load: glyph index %d\n", glyph_index ));

    /* check whether we want a scaled outline or bitmap */
    if ( !size )
      load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING;

    /* reset the size object if necessary */
    if ( load_flags & FT_LOAD_NO_SCALE )
      size = NULL;

    if ( size )
    {
      /* these two objects must have the same parent */
      if ( cffsize->face != cffslot->face )
        return FT_THROW( Invalid_Face_Handle );
    }

    /* now load the glyph outline if necessary */
    error = cff_slot_load( slot, size, glyph_index, load_flags );

    /* force drop-out mode to 2 - irrelevant now */
    /* slot->outline.dropout_mode = 2; */

    return error;
  }
Example #12
0
 /* open a standard stream from a given pathname */
  static void
  ft_std_stream_init( FT_StdStream  stream,
                      const char*   pathname )
  {
    FT_ASSERT( pathname != NULL );

    stream->file = fopen( pathname, "rb" );
    if ( stream->file == NULL )
    {
      FT_ERROR(( "iso.stream.init: could not open '%s'\n", pathname ));
      FT_XTHROW( FT_Err_Stream_Open );
    }
    
    /* compute total size in bytes */
    fseek( file, 0, SEEK_END );
    FT_STREAM__SIZE(stream) = ftell( file );
    fseek( file, 0, SEEK_SET );
    
    stream->pathname = pathname;
    stream->pos      = 0;
    
    FT_TRACE1(( "iso.stream.init: opened '%s' (%ld bytes) succesfully\n",
                 pathname, FT_STREAM__SIZE(stream) ));
  }                 
Example #13
0
  static FT_Error
  otv_validate( FT_Face volatile   face,
                FT_UInt            ot_flags,
                FT_Bytes          *ot_base,
                FT_Bytes          *ot_gdef,
                FT_Bytes          *ot_gpos,
                FT_Bytes          *ot_gsub,
                FT_Bytes          *ot_jstf )
  {
    FT_Error                  error = OTV_Err_Ok;
    FT_Byte* volatile         base;
    FT_Byte* volatile         gdef;
    FT_Byte* volatile         gpos;
    FT_Byte* volatile         gsub;
    FT_Byte* volatile         jstf;
    FT_Byte* volatile         math;
    FT_ULong                  len_base, len_gdef, len_gpos, len_gsub, len_jstf;
    FT_ULong                  len_math;
    FT_UInt                   num_glyphs = (FT_UInt)face->num_glyphs;
    FT_ValidatorRec volatile  valid;


    base     = gdef     = gpos     = gsub     = jstf     = math     = NULL;
    len_base = len_gdef = len_gpos = len_gsub = len_jstf = len_math = 0;

    /*
     * XXX: OpenType tables cannot handle 32-bit glyph index,
     *      although broken TrueType can have 32-bit glyph index.
     */
    if ( face->num_glyphs > 0xFFFFL )
    {
      FT_TRACE1(( "otv_validate: Invalid glyphs index (0x0000FFFF - 0x%08x) ",
                  face->num_glyphs ));
      FT_TRACE1(( "are not handled by OpenType tables\n" ));
      num_glyphs = 0xFFFF;
    }

    /* load tables */

    if ( ot_flags & FT_VALIDATE_BASE )
    {
      error = otv_load_table( face, TTAG_BASE, &base, &len_base );
      if ( error )
        goto Exit;
    }

    if ( ot_flags & FT_VALIDATE_GDEF )
    {
      error = otv_load_table( face, TTAG_GDEF, &gdef, &len_gdef );
      if ( error )
        goto Exit;
    }

    if ( ot_flags & FT_VALIDATE_GPOS )
    {
      error = otv_load_table( face, TTAG_GPOS, &gpos, &len_gpos );
      if ( error )
        goto Exit;
    }

    if ( ot_flags & FT_VALIDATE_GSUB )
    {
      error = otv_load_table( face, TTAG_GSUB, &gsub, &len_gsub );
      if ( error )
        goto Exit;
    }

    if ( ot_flags & FT_VALIDATE_JSTF )
    {
      error = otv_load_table( face, TTAG_JSTF, &jstf, &len_jstf );
      if ( error )
        goto Exit;
    }

    if ( ot_flags & FT_VALIDATE_MATH )
    {
      error = otv_load_table( face, TTAG_MATH, &math, &len_math );
      if ( error )
        goto Exit;
    }

    /* validate tables */

    if ( base )
    {
      ft_validator_init( &valid, base, base + len_base, FT_VALIDATE_DEFAULT );
      if ( ft_setjmp( valid.jump_buffer ) == 0 )
        otv_BASE_validate( base, &valid );
      error = valid.error;
      if ( error )
        goto Exit;
    }

    if ( gpos )
    {
      ft_validator_init( &valid, gpos, gpos + len_gpos, FT_VALIDATE_DEFAULT );
      if ( ft_setjmp( valid.jump_buffer ) == 0 )
        otv_GPOS_validate( gpos, num_glyphs, &valid );
      error = valid.error;
      if ( error )
        goto Exit;
    }

    if ( gsub )
    {
      ft_validator_init( &valid, gsub, gsub + len_gsub, FT_VALIDATE_DEFAULT );
      if ( ft_setjmp( valid.jump_buffer ) == 0 )
        otv_GSUB_validate( gsub, num_glyphs, &valid );
      error = valid.error;
      if ( error )
        goto Exit;
    }

    if ( gdef )
    {
      ft_validator_init( &valid, gdef, gdef + len_gdef, FT_VALIDATE_DEFAULT );
      if ( ft_setjmp( valid.jump_buffer ) == 0 )
        otv_GDEF_validate( gdef, gsub, gpos, num_glyphs, &valid );
      error = valid.error;
      if ( error )
        goto Exit;
    }

    if ( jstf )
    {
      ft_validator_init( &valid, jstf, jstf + len_jstf, FT_VALIDATE_DEFAULT );
      if ( ft_setjmp( valid.jump_buffer ) == 0 )
        otv_JSTF_validate( jstf, gsub, gpos, num_glyphs, &valid );
      error = valid.error;
      if ( error )
        goto Exit;
    }

    if ( math )
    {
      ft_validator_init( &valid, math, math + len_math, FT_VALIDATE_DEFAULT );
      if ( ft_setjmp( valid.jump_buffer ) == 0 )
        otv_MATH_validate( math, num_glyphs, &valid );
      error = valid.error;
      if ( error )
        goto Exit;
    }

    *ot_base = (FT_Bytes)base;
    *ot_gdef = (FT_Bytes)gdef;
    *ot_gpos = (FT_Bytes)gpos;
    *ot_gsub = (FT_Bytes)gsub;
    *ot_jstf = (FT_Bytes)jstf;

  Exit:
    if ( error ) {
      FT_Memory  memory = FT_FACE_MEMORY( face );


      FT_FREE( base );
      FT_FREE( gdef );
      FT_FREE( gpos );
      FT_FREE( gsub );
      FT_FREE( jstf );
    }
    {
      FT_Memory  memory = FT_FACE_MEMORY( face );


      FT_FREE( math );                 /* Can't return this as API is frozen */
    }

    return error;
  }
Example #14
0
  FTC_ImageCache_LookupScaler( FTC_ImageCache  cache,
                               FTC_Scaler      scaler,
                               FT_ULong        load_flags,
                               FT_UInt         gindex,
                               FT_Glyph       *aglyph,
                               FTC_Node       *anode )
  {
    FTC_BasicQueryRec  query;
    FTC_Node           node = 0; /* make compiler happy */
    FT_Error           error;
    FT_Offset          hash;


    /* some argument checks are delayed to `FTC_Cache_Lookup' */
    if ( !aglyph || !scaler )
    {
      error = FT_THROW( Invalid_Argument );
      goto Exit;
    }

    *aglyph = NULL;
    if ( anode )
      *anode  = NULL;

    /*
     * Internal `FTC_BasicAttr->load_flags' is of type `FT_UInt',
     * but public `FT_Face->face_flags' is of type `FT_Long'.
     *
     * On long > int systems, higher bits of load_flags cannot be handled.
     */
#if FT_ULONG_MAX > FT_UINT_MAX
    if ( load_flags > FT_UINT_MAX )
      FT_TRACE1(( "FTC_ImageCache_LookupScaler:"
                  " higher bits in load_flags 0x%x are dropped\n",
                  load_flags & ~((FT_ULong)FT_UINT_MAX) ));
#endif

    query.attrs.scaler     = scaler[0];
    query.attrs.load_flags = (FT_UInt)load_flags;

    hash = FTC_BASIC_ATTR_HASH( &query.attrs ) + gindex;

    FTC_GCACHE_LOOKUP_CMP( cache,
                           ftc_basic_family_compare,
                           FTC_GNode_Compare,
                           hash, gindex,
                           &query,
                           node,
                           error );
    if ( !error )
    {
      *aglyph = FTC_INODE( node )->glyph;

      if ( anode )
      {
        *anode = node;
        node->ref_count++;
      }
    }

  Exit:
    return error;
  }
Example #15
0
  cid_load_glyph( T1_Decoder  decoder,
                  FT_UInt     glyph_index )
  {
    CID_Face       face = (CID_Face)decoder->builder.face;
    CID_FaceInfo   cid  = &face->cid;
    FT_Byte*       p;
    FT_ULong       fd_select;
    FT_Stream      stream       = face->cid_stream;
    FT_Error       error        = FT_Err_Ok;
    FT_Byte*       charstring   = 0;
    FT_Memory      memory       = face->root.memory;
    FT_ULong       glyph_length = 0;
    PSAux_Service  psaux        = (PSAux_Service)face->psaux;

#ifdef FT_CONFIG_OPTION_INCREMENTAL
    FT_Incremental_InterfaceRec *inc =
                                  face->root.internal->incremental_interface;
#endif


    FT_TRACE1(( "cid_load_glyph: glyph index %d\n", glyph_index ));

#ifdef FT_CONFIG_OPTION_INCREMENTAL

    /* For incremental fonts get the character data using */
    /* the callback function.                             */
    if ( inc )
    {
      FT_Data  glyph_data;


      error = inc->funcs->get_glyph_data( inc->object,
                                          glyph_index, &glyph_data );
      if ( error )
        goto Exit;

      p         = (FT_Byte*)glyph_data.pointer;
      fd_select = cid_get_offset( &p, (FT_Byte)cid->fd_bytes );

      if ( glyph_data.length != 0 )
      {
        glyph_length = (FT_ULong)( glyph_data.length - cid->fd_bytes );
        (void)FT_ALLOC( charstring, glyph_length );
        if ( !error )
          ft_memcpy( charstring, glyph_data.pointer + cid->fd_bytes,
                     glyph_length );
      }

      inc->funcs->free_glyph_data( inc->object, &glyph_data );

      if ( error )
        goto Exit;
    }

    else

#endif /* FT_CONFIG_OPTION_INCREMENTAL */

    /* For ordinary fonts read the CID font dictionary index */
    /* and charstring offset from the CIDMap.                */
    {
      FT_UInt   entry_len = (FT_UInt)( cid->fd_bytes + cid->gd_bytes );
      FT_ULong  off1;


      if ( FT_STREAM_SEEK( cid->data_offset + cid->cidmap_offset +
                           glyph_index * entry_len )               ||
           FT_FRAME_ENTER( 2 * entry_len )                         )
        goto Exit;

      p            = (FT_Byte*)stream->cursor;
      fd_select    = cid_get_offset( &p, (FT_Byte)cid->fd_bytes );
      off1         = cid_get_offset( &p, (FT_Byte)cid->gd_bytes );
      p           += cid->fd_bytes;
      glyph_length = cid_get_offset( &p, (FT_Byte)cid->gd_bytes ) - off1;
      FT_FRAME_EXIT();

      if ( fd_select >= (FT_ULong)cid->num_dicts )
      {
        error = FT_THROW( Invalid_Offset );
        goto Exit;
      }
      if ( glyph_length == 0 )
        goto Exit;
      if ( FT_ALLOC( charstring, glyph_length ) )
        goto Exit;
      if ( FT_STREAM_READ_AT( cid->data_offset + off1,
                              charstring, glyph_length ) )
        goto Exit;
    }

    /* Now set up the subrs array and parse the charstrings. */
    {
      CID_FaceDict  dict;
      CID_Subrs     cid_subrs = face->subrs + fd_select;
      FT_UInt       cs_offset;


      /* Set up subrs */
      decoder->num_subrs = cid_subrs->num_subrs;
      decoder->subrs     = cid_subrs->code;
      decoder->subrs_len = 0;

      /* Set up font matrix */
      dict                 = cid->font_dicts + fd_select;

      decoder->font_matrix = dict->font_matrix;
      decoder->font_offset = dict->font_offset;
      decoder->lenIV       = dict->private_dict.lenIV;

      /* Decode the charstring. */

      /* Adjustment for seed bytes. */
      cs_offset = decoder->lenIV >= 0 ? (FT_UInt)decoder->lenIV : 0;

      /* Decrypt only if lenIV >= 0. */
      if ( decoder->lenIV >= 0 )
        psaux->t1_decrypt( charstring, glyph_length, 4330 );

      error = decoder->funcs.parse_charstrings(
                decoder, charstring + cs_offset,
                glyph_length - cs_offset );
    }

    FT_FREE( charstring );

#ifdef FT_CONFIG_OPTION_INCREMENTAL

    /* Incremental fonts can optionally override the metrics. */
    if ( !error && inc && inc->funcs->get_glyph_metrics )
    {
      FT_Incremental_MetricsRec  metrics;


      metrics.bearing_x = FIXED_TO_INT( decoder->builder.left_bearing.x );
      metrics.bearing_y = 0;
      metrics.advance   = FIXED_TO_INT( decoder->builder.advance.x );
      metrics.advance_v = FIXED_TO_INT( decoder->builder.advance.y );

      error = inc->funcs->get_glyph_metrics( inc->object,
                                             glyph_index, FALSE, &metrics );

      decoder->builder.left_bearing.x = INT_TO_FIXED( metrics.bearing_x );
      decoder->builder.advance.x      = INT_TO_FIXED( metrics.advance );
      decoder->builder.advance.y      = INT_TO_FIXED( metrics.advance_v );
    }

#endif /* FT_CONFIG_OPTION_INCREMENTAL */

  Exit:
    return error;
  }
Example #16
0
  FT_Stream_Open( FT_Stream    stream,
                  const char*  filepathname )
  {
    int          file;
    struct stat  stat_buf;


    if ( !stream )
      return FT_THROW( Invalid_Stream_Handle );

    /* open the file */
    file = open( filepathname, O_RDONLY );
    if ( file < 0 )
    {
      FT_ERROR(( "FT_Stream_Open:" ));
      FT_ERROR(( " could not open `%s'\n", filepathname ));
      return FT_THROW( Cannot_Open_Resource );
    }

    /* Here we ensure that a "fork" will _not_ duplicate   */
    /* our opened input streams on Unix.  This is critical */
    /* since it avoids some (possible) access control      */
    /* issues and cleans up the kernel file table a bit.   */
    /*                                                     */
#ifdef F_SETFD
#ifdef FD_CLOEXEC
    (void)fcntl( file, F_SETFD, FD_CLOEXEC );
#else
    (void)fcntl( file, F_SETFD, 1 );
#endif /* FD_CLOEXEC */
#endif /* F_SETFD */

    if ( fstat( file, &stat_buf ) < 0 )
    {
      FT_ERROR(( "FT_Stream_Open:" ));
      FT_ERROR(( " could not `fstat' file `%s'\n", filepathname ));
      goto Fail_Map;
    }

    /* XXX: TODO -- real 64bit platform support                        */
    /*                                                                 */
    /* `stream->size' is typedef'd to unsigned long (in `ftsystem.h'); */
    /* `stat_buf.st_size', however, is usually typedef'd to off_t      */
    /* (in sys/stat.h).                                                */
    /* On some platforms, the former is 32bit and the latter is 64bit. */
    /* To avoid overflow caused by fonts in huge files larger than     */
    /* 2GB, do a test.  Temporary fix proposed by Sean McBride.        */
    /*                                                                 */
    if ( stat_buf.st_size > LONG_MAX )
    {
      FT_ERROR(( "FT_Stream_Open: file is too big\n" ));
      goto Fail_Map;
    }
    else if ( stat_buf.st_size == 0 )
    {
      FT_ERROR(( "FT_Stream_Open: zero-length file\n" ));
      goto Fail_Map;
    }

    /* This cast potentially truncates a 64bit to 32bit! */
    stream->size = (unsigned long)stat_buf.st_size;
    stream->pos  = 0;
    stream->base = (unsigned char *)mmap( NULL,
                                          stream->size,
                                          PROT_READ,
                                          MAP_FILE | MAP_PRIVATE,
                                          file,
                                          0 );

    /* on some RTOS, mmap might return 0 */
    if ( (long)stream->base != -1 && stream->base != NULL )
      stream->close = ft_close_stream_by_munmap;
    else
    {
      ssize_t  total_read_count;


      FT_ERROR(( "FT_Stream_Open:" ));
      FT_ERROR(( " could not `mmap' file `%s'\n", filepathname ));

      stream->base = (unsigned char*)ft_alloc( NULL, stream->size );

      if ( !stream->base )
      {
        FT_ERROR(( "FT_Stream_Open:" ));
        FT_ERROR(( " could not `alloc' memory\n" ));
        goto Fail_Map;
      }

      total_read_count = 0;
      do
      {
        ssize_t  read_count;


        read_count = read( file,
                           stream->base + total_read_count,
                           stream->size - total_read_count );

        if ( read_count <= 0 )
        {
          if ( read_count == -1 && errno == EINTR )
            continue;

          FT_ERROR(( "FT_Stream_Open:" ));
          FT_ERROR(( " error while `read'ing file `%s'\n", filepathname ));
          goto Fail_Read;
        }

        total_read_count += read_count;

      } while ( (unsigned long)total_read_count != stream->size );

      stream->close = ft_close_stream_by_free;
    }

    close( file );

    stream->descriptor.pointer = stream->base;
    stream->pathname.pointer   = (char*)filepathname;

    stream->read = 0;

    FT_TRACE1(( "FT_Stream_Open:" ));
    FT_TRACE1(( " opened `%s' (%d bytes) successfully\n",
                filepathname, stream->size ));

    return FT_Err_Ok;

  Fail_Read:
    ft_free( NULL, stream->base );

  Fail_Map:
    close( file );

    stream->base = NULL;
    stream->size = 0;
    stream->pos  = 0;

    return FT_THROW( Cannot_Open_Stream );
  }
Example #17
0
  FTC_SBitCache_Lookup( FTC_SBitCache  cache,
                        FTC_ImageType  type,
                        FT_UInt        gindex,
                        FTC_SBit      *ansbit,
                        FTC_Node      *anode )
  {
    FT_Error           error;
    FTC_BasicQueryRec  query;
    FTC_Node           node = 0; /* make compiler happy */
    FT_Offset          hash;


    if ( anode )
      *anode = NULL;

    /* other argument checks delayed to `FTC_Cache_Lookup' */
    if ( !ansbit )
      return FT_THROW( Invalid_Argument );

    *ansbit = NULL;

    /*
     * Internal `FTC_BasicAttr->load_flags' is of type `FT_UInt',
     * but public `FT_ImageType->flags' is of type `FT_Int32'.
     *
     * On 16bit systems, higher bits of type->flags cannot be handled.
     */
#if 0xFFFFFFFFUL > FT_UINT_MAX
    if ( (type->flags & (FT_ULong)FT_UINT_MAX) )
      FT_TRACE1(( "FTC_ImageCache_Lookup:"
                  " higher bits in load_flags 0x%x are dropped\n",
                  (FT_ULong)type->flags & ~((FT_ULong)FT_UINT_MAX) ));
#endif

    query.attrs.scaler.face_id = type->face_id;
    query.attrs.scaler.width   = type->width;
    query.attrs.scaler.height  = type->height;
    query.attrs.load_flags     = (FT_UInt)type->flags;

    query.attrs.scaler.pixel = 1;
    query.attrs.scaler.x_res = 0;  /* make compilers happy */
    query.attrs.scaler.y_res = 0;

    /* beware, the hash must be the same for all glyph ranges! */
    hash = FTC_BASIC_ATTR_HASH( &query.attrs ) +
           gindex / FTC_SBIT_ITEMS_PER_NODE;

#if 1  /* inlining is about 50% faster! */
    FTC_GCACHE_LOOKUP_CMP( cache,
                           ftc_basic_family_compare,
                           FTC_SNode_Compare,
                           hash, gindex,
                           &query,
                           node,
                           error );
#else
    error = FTC_GCache_Lookup( FTC_GCACHE( cache ),
                               hash,
                               gindex,
                               FTC_GQUERY( &query ),
                               &node );
#endif
    if ( error )
      goto Exit;

    *ansbit = FTC_SNODE( node )->sbits +
              ( gindex - FTC_GNODE( node )->gindex );

    if ( anode )
    {
      *anode = node;
      node->ref_count++;
    }

  Exit:
    return error;
  }
Example #18
0
  FT_Stream_Open( FT_Stream    stream,
                  const char*  filepathname )
  {
    struct FileInfoBlock*  fib;
    struct SysFile*        sysfile;


    if ( !stream )
      return FT_THROW( Invalid_Stream_Handle );

#ifdef __amigaos4__
    sysfile = AllocMem ( sizeof (struct SysFile ), MEMF_SHARED );
#else
    sysfile = AllocMem ( sizeof (struct SysFile ), MEMF_PUBLIC );
#endif
    if ( !sysfile )
    {
      FT_ERROR(( "FT_Stream_Open:" ));
      FT_ERROR(( " could not open `%s'\n", filepathname ));

      return FT_THROW( Cannot_Open_Resource );
    }
    sysfile->file = Open( (STRPTR)filepathname, MODE_OLDFILE );
    if ( !sysfile->file )
    {
      FreeMem ( sysfile, sizeof ( struct SysFile ));
      FT_ERROR(( "FT_Stream_Open:" ));
      FT_ERROR(( " could not open `%s'\n", filepathname ));

      return FT_THROW( Cannot_Open_Resource );
    }

    fib = AllocDosObject( DOS_FIB, NULL );
    if ( !fib )
    {
      Close ( sysfile->file );
      FreeMem ( sysfile, sizeof ( struct SysFile ));
      FT_ERROR(( "FT_Stream_Open:" ));
      FT_ERROR(( " could not open `%s'\n", filepathname ));

      return FT_THROW( Cannot_Open_Resource );
    }
    if ( !( ExamineFH( sysfile->file, fib ) ) )
    {
      FreeDosObject( DOS_FIB, fib );
      Close ( sysfile->file );
      FreeMem ( sysfile, sizeof ( struct SysFile ));
      FT_ERROR(( "FT_Stream_Open:" ));
      FT_ERROR(( " could not open `%s'\n", filepathname ));

      return FT_THROW( Cannot_Open_Resource );
    }
    stream->size = fib->fib_Size;
    FreeDosObject( DOS_FIB, fib );

    stream->descriptor.pointer = (void *)sysfile;
    stream->pathname.pointer   = (char*)filepathname;
    sysfile->iobuf_start       = 0;
    sysfile->iobuf_end         = 0;
    stream->pos                = 0;

    stream->read  = ft_amiga_stream_io;
    stream->close = ft_amiga_stream_close;

    if ( !stream->size )
    {
      ft_amiga_stream_close( stream );
      FT_ERROR(( "FT_Stream_Open:" ));
      FT_ERROR(( " opened `%s' but zero-sized\n", filepathname ));
      return FT_THROW( Cannot_Open_Stream );
    }

    FT_TRACE1(( "FT_Stream_Open:" ));
    FT_TRACE1(( " opened `%s' (%ld bytes) successfully\n",
                filepathname, stream->size ));

    return FT_Err_Ok;
  }
Example #19
0
  FTC_ImageCache_Lookup( FTC_ImageCache  cache,
                         FTC_ImageType   type,
                         FT_UInt         gindex,
                         FT_Glyph       *aglyph,
                         FTC_Node       *anode )
  {
    FTC_BasicQueryRec  query;
    FTC_Node           node = 0; /* make compiler happy */
    FT_Error           error;
    FT_Offset          hash;


    /* some argument checks are delayed to `FTC_Cache_Lookup' */
    if ( !aglyph )
    {
      error = FT_THROW( Invalid_Argument );
      goto Exit;
    }

    *aglyph = NULL;
    if ( anode )
      *anode  = NULL;

    if ( (FT_ULong)( type->flags - FT_INT_MIN ) > FT_UINT_MAX )
      FT_TRACE1(( "FTC_ImageCache_Lookup:"
                  " higher bits in load_flags 0x%x are dropped\n",
                  (FT_ULong)type->flags & ~((FT_ULong)FT_UINT_MAX) ));

    query.attrs.scaler.face_id = type->face_id;
    query.attrs.scaler.width   = type->width;
    query.attrs.scaler.height  = type->height;
    query.attrs.load_flags     = (FT_UInt)type->flags;

    query.attrs.scaler.pixel = 1;
    query.attrs.scaler.x_res = 0;  /* make compilers happy */
    query.attrs.scaler.y_res = 0;

    hash = FTC_BASIC_ATTR_HASH( &query.attrs ) + gindex;

#if 1  /* inlining is about 50% faster! */
    FTC_GCACHE_LOOKUP_CMP( cache,
                           ftc_basic_family_compare,
                           FTC_GNode_Compare,
                           hash, gindex,
                           &query,
                           node,
                           error );
#else
    error = FTC_GCache_Lookup( FTC_GCACHE( cache ),
                               hash, gindex,
                               FTC_GQUERY( &query ),
                               &node );
#endif
    if ( !error )
    {
      *aglyph = FTC_INODE( node )->glyph;

      if ( anode )
      {
        *anode = node;
        node->ref_count++;
      }
    }

  Exit:
    return error;
  }
Example #20
0
  FTC_SBitCache_LookupScaler( FTC_SBitCache  cache,
                              FTC_Scaler     scaler,
                              FT_ULong       load_flags,
                              FT_UInt        gindex,
                              FTC_SBit      *ansbit,
                              FTC_Node      *anode )
  {
    FT_Error           error;
    FTC_BasicQueryRec  query;
    FTC_Node           node = 0; /* make compiler happy */
    FT_Offset          hash;


    if ( anode )
        *anode = NULL;

    /* other argument checks delayed to `FTC_Cache_Lookup' */
    if ( !ansbit || !scaler )
        return FT_THROW( Invalid_Argument );

    *ansbit = NULL;

    /*
     * Internal `FTC_BasicAttr->load_flags' is of type `FT_UInt',
     * but public `FT_Face->face_flags' is of type `FT_Long'.
     *
     * On long > int systems, higher bits of load_flags cannot be handled.
     */
#if FT_ULONG_MAX > FT_UINT_MAX
    if ( load_flags > FT_UINT_MAX )
      FT_TRACE1(( "FTC_ImageCache_LookupScaler:"
                  " higher bits in load_flags 0x%x are dropped\n",
                  load_flags & ~((FT_ULong)FT_UINT_MAX) ));
#endif

    query.attrs.scaler     = scaler[0];
    query.attrs.load_flags = (FT_UInt)load_flags;

    /* beware, the hash must be the same for all glyph ranges! */
    hash = FTC_BASIC_ATTR_HASH( &query.attrs ) +
             gindex / FTC_SBIT_ITEMS_PER_NODE;

    FTC_GCACHE_LOOKUP_CMP( cache,
                           ftc_basic_family_compare,
                           FTC_SNode_Compare,
                           hash, gindex,
                           &query,
                           node,
                           error );
    if ( error )
      goto Exit;

    *ansbit = FTC_SNODE( node )->sbits +
              ( gindex - FTC_GNODE( node )->gindex );

    if ( anode )
    {
      *anode = node;
      node->ref_count++;
    }

  Exit:
    return error;
  }
Example #21
0
pfr_slot_load( FT_GlyphSlot  pfrslot,         /* PFR_Slot */
               FT_Size       pfrsize,         /* PFR_Size */
               FT_UInt       gindex,
               FT_Int32      load_flags )
{
    PFR_Slot     slot    = (PFR_Slot)pfrslot;
    PFR_Size     size    = (PFR_Size)pfrsize;
    FT_Error     error;
    PFR_Face     face    = (PFR_Face)pfrslot->face;
    PFR_Char     gchar;
    FT_Outline*  outline = &pfrslot->outline;
    FT_ULong     gps_offset;


    FT_TRACE1(( "pfr_slot_load: glyph index %d\n", gindex ));

    if ( gindex > 0 )
        gindex--;

    if ( !face || gindex >= face->phy_font.num_chars )
    {
        error = FT_THROW( Invalid_Argument );
        goto Exit;
    }

    /* try to load an embedded bitmap */
    if ( ( load_flags & ( FT_LOAD_NO_SCALE | FT_LOAD_NO_BITMAP ) ) == 0 )
    {
        error = pfr_slot_load_bitmap( slot, size, gindex );
        if ( error == 0 )
            goto Exit;
    }

    if ( load_flags & FT_LOAD_SBITS_ONLY )
    {
        error = FT_THROW( Invalid_Argument );
        goto Exit;
    }

    gchar               = face->phy_font.chars + gindex;
    pfrslot->format     = FT_GLYPH_FORMAT_OUTLINE;
    outline->n_points   = 0;
    outline->n_contours = 0;
    gps_offset          = face->header.gps_section_offset;

    /* load the glyph outline (FT_LOAD_NO_RECURSE isn't supported) */
    error = pfr_glyph_load( &slot->glyph, face->root.stream,
                            gps_offset, gchar->gps_offset, gchar->gps_size );

    if ( !error )
    {
        FT_BBox            cbox;
        FT_Glyph_Metrics*  metrics = &pfrslot->metrics;
        FT_Pos             advance;
        FT_UInt            em_metrics, em_outline;
        FT_Bool            scaling;


        scaling = FT_BOOL( ( load_flags & FT_LOAD_NO_SCALE ) == 0 );

        /* copy outline data */
        *outline = slot->glyph.loader->base.outline;

        outline->flags &= ~FT_OUTLINE_OWNER;
        outline->flags |= FT_OUTLINE_REVERSE_FILL;

        if ( size && pfrsize->metrics.y_ppem < 24 )
            outline->flags |= FT_OUTLINE_HIGH_PRECISION;

        /* compute the advance vector */
        metrics->horiAdvance = 0;
        metrics->vertAdvance = 0;

        advance    = gchar->advance;
        em_metrics = face->phy_font.metrics_resolution;
        em_outline = face->phy_font.outline_resolution;

        if ( em_metrics != em_outline )
            advance = FT_MulDiv( advance,
                                 (FT_Long)em_outline,
                                 (FT_Long)em_metrics );

        if ( face->phy_font.flags & PFR_PHY_VERTICAL )
            metrics->vertAdvance = advance;
        else
            metrics->horiAdvance = advance;

        pfrslot->linearHoriAdvance = metrics->horiAdvance;
        pfrslot->linearVertAdvance = metrics->vertAdvance;

        /* make-up vertical metrics(?) */
        metrics->vertBearingX = 0;
        metrics->vertBearingY = 0;

#if 0 /* some fonts seem to be broken here! */

        /* Apply the font matrix, if any.                 */
        /* TODO: Test existing fonts with unusual matrix  */
        /* whether we have to adjust Units per EM.        */
        {
            FT_Matrix font_matrix;


            font_matrix.xx = face->log_font.matrix[0] << 8;
            font_matrix.yx = face->log_font.matrix[1] << 8;
            font_matrix.xy = face->log_font.matrix[2] << 8;
            font_matrix.yy = face->log_font.matrix[3] << 8;

            FT_Outline_Transform( outline, &font_matrix );
        }
#endif

        /* scale when needed */
        if ( scaling )
        {
            FT_Int      n;
            FT_Fixed    x_scale = pfrsize->metrics.x_scale;
            FT_Fixed    y_scale = pfrsize->metrics.y_scale;
            FT_Vector*  vec     = outline->points;


            /* scale outline points */
            for ( n = 0; n < outline->n_points; n++, vec++ )
            {
                vec->x = FT_MulFix( vec->x, x_scale );
                vec->y = FT_MulFix( vec->y, y_scale );
            }

            /* scale the advance */
            metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, x_scale );
            metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, y_scale );
        }

        /* compute the rest of the metrics */
        FT_Outline_Get_CBox( outline, &cbox );

        metrics->width        = cbox.xMax - cbox.xMin;
        metrics->height       = cbox.yMax - cbox.yMin;
        metrics->horiBearingX = cbox.xMin;
        metrics->horiBearingY = cbox.yMax - metrics->height;
    }

Exit:
    return error;
}
Example #22
0
  FTC_SBitCache_Lookup( FTC_SBitCache  cache,
                        FTC_ImageType  type,
                        FT_UInt        gindex,
                        FTC_SBit      *ansbit,
                        FTC_Node      *anode )
  {
    FT_Error           error;
    FTC_BasicQueryRec  query;
    FTC_Node           node = 0; /* make compiler happy */
    FT_UInt32          hash;


    if ( anode )
      *anode = NULL;

    /* other argument checks delayed to FTC_Cache_Lookup */
    if ( !ansbit )
      return FTC_Err_Invalid_Argument;

    *ansbit = NULL;

#if defined( FT_CONFIG_OPTION_OLD_INTERNALS ) && ( FT_INT_MAX > 0xFFFFU )

    /*  This one is a major hack used to detect whether we are passed a
     *  regular FTC_ImageType handle, or a legacy FTC_OldImageDesc one.
     */
    if ( (FT_ULong)type->width >= 0x10000L )
    {
      FTC_OldImageDesc  desc = (FTC_OldImageDesc)type;


      query.attrs.scaler.face_id = desc->font.face_id;
      query.attrs.scaler.width   = desc->font.pix_width;
      query.attrs.scaler.height  = desc->font.pix_height;
      query.attrs.load_flags     = desc->flags;
    }
    else

#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */

    {
      if ( (FT_ULong)(type->flags - FT_INT_MIN) > FT_UINT_MAX )
      {
        FT_TRACE1(( "FTC_ImageCache_Lookup: higher bits in load_flags" ));
        FT_TRACE1(( "0x%x are dropped\n", (type->flags & ~((FT_ULong)FT_UINT_MAX)) ));
      }

      query.attrs.scaler.face_id = type->face_id;
      query.attrs.scaler.width   = type->width;
      query.attrs.scaler.height  = type->height;
      query.attrs.load_flags     = (FT_UInt)type->flags;
    }

    query.attrs.scaler.pixel = 1;
    query.attrs.scaler.x_res = 0;  /* make compilers happy */
    query.attrs.scaler.y_res = 0;

    /* beware, the hash must be the same for all glyph ranges! */
    hash = FTC_BASIC_ATTR_HASH( &query.attrs ) +
           gindex / FTC_SBIT_ITEMS_PER_NODE;

#if 1  /* inlining is about 50% faster! */
    FTC_GCACHE_LOOKUP_CMP( cache,
                           ftc_basic_family_compare,
                           FTC_SNode_Compare,
                           hash, gindex,
                           &query,
                           node,
                           error );
#else
    error = FTC_GCache_Lookup( FTC_GCACHE( cache ),
                               hash,
                               gindex,
                               FTC_GQUERY( &query ),
                               &node );
#endif
    if ( error )
      goto Exit;

    *ansbit = FTC_SNODE( node )->sbits +
              ( gindex - FTC_GNODE( node )->gindex );

    if ( anode )
    {
      *anode = node;
      node->ref_count++;
    }

  Exit:
    return error;
  }
Example #23
0
  T1_Read_Metrics( FT_Face    t1_face,
                   FT_Stream  stream )
  {
    PSAux_Service  psaux;
    FT_Memory      memory  = stream->memory;
    AFM_ParserRec  parser;
    AFM_FontInfo   fi      = NULL;
    FT_Error       error   = FT_ERR( Unknown_File_Format );
    T1_Face        face    = (T1_Face)t1_face;
    T1_Font        t1_font = &face->type1;


    if ( face->afm_data )
    {
      FT_TRACE1(( "T1_Read_Metrics:"
                  " Freeing previously attached metrics data.\n" ));
      T1_Done_Metrics( memory, (AFM_FontInfo)face->afm_data );

      face->afm_data = NULL;
    }

    if ( FT_NEW( fi )                   ||
         FT_FRAME_ENTER( stream->size ) )
      goto Exit;

    fi->FontBBox  = t1_font->font_bbox;
    fi->Ascender  = t1_font->font_bbox.yMax;
    fi->Descender = t1_font->font_bbox.yMin;

    psaux = (PSAux_Service)face->psaux;
    if ( psaux->afm_parser_funcs )
    {
      error = psaux->afm_parser_funcs->init( &parser,
                                             stream->memory,
                                             stream->cursor,
                                             stream->limit );

      if ( !error )
      {
        parser.FontInfo  = fi;
        parser.get_index = t1_get_index;
        parser.user_data = t1_font;

        error = psaux->afm_parser_funcs->parse( &parser );
        psaux->afm_parser_funcs->done( &parser );
      }
    }

    if ( FT_ERR_EQ( error, Unknown_File_Format ) )
    {
      FT_Byte*  start = stream->cursor;


      /* MS Windows allows versions up to 0x3FF without complaining */
      if ( stream->size > 6                              &&
           start[1] < 4                                  &&
           FT_PEEK_ULONG_LE( start + 2 ) == stream->size )
        error = T1_Read_PFM( t1_face, stream, fi );
    }

    if ( !error )
    {
      t1_font->font_bbox = fi->FontBBox;

      t1_face->bbox.xMin =   fi->FontBBox.xMin            >> 16;
      t1_face->bbox.yMin =   fi->FontBBox.yMin            >> 16;
      /* no `U' suffix here to 0xFFFF! */
      t1_face->bbox.xMax = ( fi->FontBBox.xMax + 0xFFFF ) >> 16;
      t1_face->bbox.yMax = ( fi->FontBBox.yMax + 0xFFFF ) >> 16;

      /* no `U' suffix here to 0x8000! */
      t1_face->ascender  = (FT_Short)( ( fi->Ascender  + 0x8000 ) >> 16 );
      t1_face->descender = (FT_Short)( ( fi->Descender + 0x8000 ) >> 16 );

      if ( fi->NumKernPair )
      {
        t1_face->face_flags |= FT_FACE_FLAG_KERNING;
        face->afm_data       = fi;
        fi = NULL;
      }
    }
Example #24
0
  T1_Load_Glyph( FT_GlyphSlot  t1glyph,          /* T1_GlyphSlot */
                 FT_Size       t1size,           /* T1_Size      */
                 FT_UInt       glyph_index,
                 FT_Int32      load_flags )
  {
    T1_GlyphSlot            glyph = (T1_GlyphSlot)t1glyph;
    FT_Error                error;
#ifdef __REACTOS__
    T1_DecoderRec *decoder = malloc(sizeof(T1_DecoderRec));
    if (!decoder)
      return FT_THROW( Out_Of_Memory );
/* Ugly but it allows us to reduce the diff */
#define decoder (*decoder)
    {
#else
    T1_DecoderRec           decoder;
#endif
    T1_Face                 face = (T1_Face)t1glyph->face;
    FT_Bool                 hinting;
    FT_Bool                 scaled;
    FT_Bool                 force_scaling = FALSE;
    T1_Font                 type1         = &face->type1;
    PSAux_Service           psaux         = (PSAux_Service)face->psaux;
    const T1_Decoder_Funcs  decoder_funcs = psaux->t1_decoder_funcs;

    FT_Matrix               font_matrix;
    FT_Vector               font_offset;
    FT_Data                 glyph_data;
    FT_Bool                 must_finish_decoder = FALSE;
#ifdef FT_CONFIG_OPTION_INCREMENTAL
    FT_Bool                 glyph_data_loaded = 0;
#endif


#ifdef FT_CONFIG_OPTION_INCREMENTAL
    if ( glyph_index >= (FT_UInt)face->root.num_glyphs &&
         !face->root.internal->incremental_interface   )
#else
    if ( glyph_index >= (FT_UInt)face->root.num_glyphs )
#endif /* FT_CONFIG_OPTION_INCREMENTAL */
    {
      error = FT_THROW( Invalid_Argument );
      goto Exit;
    }

    FT_TRACE1(( "T1_Load_Glyph: glyph index %d\n", glyph_index ));

    FT_ASSERT( ( face->len_buildchar == 0 ) == ( face->buildchar == NULL ) );

    if ( load_flags & FT_LOAD_NO_RECURSE )
      load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING;

    if ( t1size )
    {
      glyph->x_scale = t1size->metrics.x_scale;
      glyph->y_scale = t1size->metrics.y_scale;
    }
    else
    {
      glyph->x_scale = 0x10000L;
      glyph->y_scale = 0x10000L;
    }

    t1glyph->outline.n_points   = 0;
    t1glyph->outline.n_contours = 0;

    hinting = FT_BOOL( ( load_flags & FT_LOAD_NO_SCALE   ) == 0 &&
                       ( load_flags & FT_LOAD_NO_HINTING ) == 0 );
    scaled  = FT_BOOL( ( load_flags & FT_LOAD_NO_SCALE   ) == 0 );

    glyph->hint     = hinting;
    glyph->scaled   = scaled;
    t1glyph->format = FT_GLYPH_FORMAT_OUTLINE;

    error = decoder_funcs->init( &decoder,
                                 t1glyph->face,
                                 t1size,
                                 t1glyph,
                                 (FT_Byte**)type1->glyph_names,
                                 face->blend,
                                 FT_BOOL( hinting ),
                                 FT_LOAD_TARGET_MODE( load_flags ),
                                 T1_Parse_Glyph );
    if ( error )
      goto Exit;

    must_finish_decoder = TRUE;

    decoder.builder.no_recurse = FT_BOOL(
                                   ( load_flags & FT_LOAD_NO_RECURSE ) != 0 );

    decoder.num_subrs     = type1->num_subrs;
    decoder.subrs         = type1->subrs;
    decoder.subrs_len     = type1->subrs_len;
    decoder.subrs_hash    = type1->subrs_hash;

    decoder.buildchar     = face->buildchar;
    decoder.len_buildchar = face->len_buildchar;

    /* now load the unscaled outline */
    error = T1_Parse_Glyph_And_Get_Char_String( &decoder, glyph_index,
                                                &glyph_data,
                                                &force_scaling );
    if ( error )
      goto Exit;
#ifdef FT_CONFIG_OPTION_INCREMENTAL
    glyph_data_loaded = 1;
#endif

    hinting     = glyph->hint;
    font_matrix = decoder.font_matrix;
    font_offset = decoder.font_offset;

    /* save new glyph tables */
    decoder_funcs->done( &decoder );

    must_finish_decoder = FALSE;

    /* now, set the metrics -- this is rather simple, as   */
    /* the left side bearing is the xMin, and the top side */
    /* bearing the yMax                                    */
    if ( !error )
    {
      t1glyph->outline.flags &= FT_OUTLINE_OWNER;
      t1glyph->outline.flags |= FT_OUTLINE_REVERSE_FILL;

      /* for composite glyphs, return only left side bearing and */
      /* advance width                                           */
      if ( load_flags & FT_LOAD_NO_RECURSE )
      {
        FT_Slot_Internal  internal = t1glyph->internal;


        t1glyph->metrics.horiBearingX =
          FIXED_TO_INT( decoder.builder.left_bearing.x );
        t1glyph->metrics.horiAdvance  =
          FIXED_TO_INT( decoder.builder.advance.x );

        internal->glyph_matrix      = font_matrix;
        internal->glyph_delta       = font_offset;
        internal->glyph_transformed = 1;
      }
      else
      {
        FT_BBox            cbox;
        FT_Glyph_Metrics*  metrics = &t1glyph->metrics;


        /* copy the _unscaled_ advance width */
        metrics->horiAdvance =
          FIXED_TO_INT( decoder.builder.advance.x );
        t1glyph->linearHoriAdvance =
          FIXED_TO_INT( decoder.builder.advance.x );
        t1glyph->internal->glyph_transformed = 0;

        if ( load_flags & FT_LOAD_VERTICAL_LAYOUT )
        {
          /* make up vertical ones */
          metrics->vertAdvance = ( face->type1.font_bbox.yMax -
                                   face->type1.font_bbox.yMin ) >> 16;
          t1glyph->linearVertAdvance = metrics->vertAdvance;
        }
        else
        {
          metrics->vertAdvance =
            FIXED_TO_INT( decoder.builder.advance.y );
          t1glyph->linearVertAdvance =
            FIXED_TO_INT( decoder.builder.advance.y );
        }

        t1glyph->format = FT_GLYPH_FORMAT_OUTLINE;

        if ( t1size && t1size->metrics.y_ppem < 24 )
          t1glyph->outline.flags |= FT_OUTLINE_HIGH_PRECISION;

#if 1
        /* apply the font matrix, if any */
        if ( font_matrix.xx != 0x10000L || font_matrix.yy != 0x10000L ||
             font_matrix.xy != 0        || font_matrix.yx != 0        )
        {
          FT_Outline_Transform( &t1glyph->outline, &font_matrix );

          metrics->horiAdvance = FT_MulFix( metrics->horiAdvance,
                                            font_matrix.xx );
          metrics->vertAdvance = FT_MulFix( metrics->vertAdvance,
                                            font_matrix.yy );
        }

        if ( font_offset.x || font_offset.y )
        {
          FT_Outline_Translate( &t1glyph->outline,
                                font_offset.x,
                                font_offset.y );

          metrics->horiAdvance += font_offset.x;
          metrics->vertAdvance += font_offset.y;
        }
#endif

        if ( ( load_flags & FT_LOAD_NO_SCALE ) == 0 || force_scaling )
        {
          /* scale the outline and the metrics */
          FT_Int       n;
          FT_Outline*  cur = decoder.builder.base;
          FT_Vector*   vec = cur->points;
          FT_Fixed     x_scale = glyph->x_scale;
          FT_Fixed     y_scale = glyph->y_scale;


          /* First of all, scale the points, if we are not hinting */
          if ( !hinting || ! decoder.builder.hints_funcs )
            for ( n = cur->n_points; n > 0; n--, vec++ )
            {
              vec->x = FT_MulFix( vec->x, x_scale );
              vec->y = FT_MulFix( vec->y, y_scale );
            }

          /* Then scale the metrics */
          metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, x_scale );
          metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, y_scale );
        }

        /* compute the other metrics */
        FT_Outline_Get_CBox( &t1glyph->outline, &cbox );

        metrics->width  = cbox.xMax - cbox.xMin;
        metrics->height = cbox.yMax - cbox.yMin;

        metrics->horiBearingX = cbox.xMin;
        metrics->horiBearingY = cbox.yMax;

        if ( load_flags & FT_LOAD_VERTICAL_LAYOUT )
        {
          /* make up vertical ones */
          ft_synthesize_vertical_metrics( metrics,
                                          metrics->vertAdvance );
        }
      }
Example #25
0
  T1_Load_Glyph( FT_GlyphSlot  t1glyph,          /* T1_GlyphSlot */
                 FT_Size       t1size,           /* T1_Size      */
                 FT_UInt       glyph_index,
                 FT_Int32      load_flags )
  {
    T1_GlyphSlot            glyph = (T1_GlyphSlot)t1glyph;
    FT_Error                error;
#ifdef __REACTOS__
    T1_DecoderRec *decoder = malloc(sizeof(T1_DecoderRec));
/* Ugly but it allows us to reduce the diff */
#define decoder (*decoder)
#else
    T1_DecoderRec           decoder;
#endif
    T1_Face                 face = (T1_Face)t1glyph->face;
    FT_Bool                 hinting;
    T1_Font                 type1         = &face->type1;
    PSAux_Service           psaux         = (PSAux_Service)face->psaux;
    const T1_Decoder_Funcs  decoder_funcs = psaux->t1_decoder_funcs;

    FT_Matrix               font_matrix;
    FT_Vector               font_offset;
    FT_Data                 glyph_data;
    FT_Bool                 must_finish_decoder = FALSE;
#ifdef FT_CONFIG_OPTION_INCREMENTAL
    FT_Bool                 glyph_data_loaded = 0;
#endif


#ifdef FT_CONFIG_OPTION_INCREMENTAL
    if ( glyph_index >= (FT_UInt)face->root.num_glyphs &&
         !face->root.internal->incremental_interface   )
#else
    if ( glyph_index >= (FT_UInt)face->root.num_glyphs )
#endif /* FT_CONFIG_OPTION_INCREMENTAL */
    {
      error = FT_THROW( Invalid_Argument );
      goto Exit;
    }

    FT_TRACE1(( "T1_Load_Glyph: glyph index %d\n", glyph_index ));

    FT_ASSERT( ( face->len_buildchar == 0 ) == ( face->buildchar == NULL ) );

    if ( load_flags & FT_LOAD_NO_RECURSE )
      load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING;

    if ( t1size )
    {
      glyph->x_scale = t1size->metrics.x_scale;
      glyph->y_scale = t1size->metrics.y_scale;
    }
    else
    {
      glyph->x_scale = 0x10000L;
      glyph->y_scale = 0x10000L;
    }

    t1glyph->outline.n_points   = 0;
    t1glyph->outline.n_contours = 0;

    hinting = FT_BOOL( ( load_flags & FT_LOAD_NO_SCALE   ) == 0 &&
                       ( load_flags & FT_LOAD_NO_HINTING ) == 0 );

    t1glyph->format = FT_GLYPH_FORMAT_OUTLINE;

    error = decoder_funcs->init( &decoder,
                                 t1glyph->face,
                                 t1size,
                                 t1glyph,
                                 (FT_Byte**)type1->glyph_names,
                                 face->blend,
                                 FT_BOOL( hinting ),
                                 FT_LOAD_TARGET_MODE( load_flags ),
                                 T1_Parse_Glyph );
    if ( error )
      goto Exit;

    must_finish_decoder = TRUE;

    decoder.builder.no_recurse = FT_BOOL(
                                   ( load_flags & FT_LOAD_NO_RECURSE ) != 0 );

    decoder.num_subrs     = type1->num_subrs;
    decoder.subrs         = type1->subrs;
    decoder.subrs_len     = type1->subrs_len;

    decoder.buildchar     = face->buildchar;
    decoder.len_buildchar = face->len_buildchar;

    /* now load the unscaled outline */
    error = T1_Parse_Glyph_And_Get_Char_String( &decoder, glyph_index,
                                                &glyph_data );
    if ( error )
      goto Exit;
#ifdef FT_CONFIG_OPTION_INCREMENTAL
    glyph_data_loaded = 1;
#endif

    font_matrix = decoder.font_matrix;
    font_offset = decoder.font_offset;

    /* save new glyph tables */
    decoder_funcs->done( &decoder );

    must_finish_decoder = FALSE;

    /* now, set the metrics -- this is rather simple, as   */
    /* the left side bearing is the xMin, and the top side */
    /* bearing the yMax                                    */
    if ( !error )
    {
      t1glyph->outline.flags &= FT_OUTLINE_OWNER;
      t1glyph->outline.flags |= FT_OUTLINE_REVERSE_FILL;

      /* for composite glyphs, return only left side bearing and */
      /* advance width                                           */
      if ( load_flags & FT_LOAD_NO_RECURSE )
      {
        FT_Slot_Internal  internal = t1glyph->internal;


        t1glyph->metrics.horiBearingX =
          FIXED_TO_INT( decoder.builder.left_bearing.x );
        t1glyph->metrics.horiAdvance  =
          FIXED_TO_INT( decoder.builder.advance.x );

        internal->glyph_matrix      = font_matrix;
        internal->glyph_delta       = font_offset;
        internal->glyph_transformed = 1;
      }
      else
      {
        FT_BBox            cbox;
        FT_Glyph_Metrics*  metrics = &t1glyph->metrics;


        /* copy the _unscaled_ advance width */
        metrics->horiAdvance =
          FIXED_TO_INT( decoder.builder.advance.x );
        t1glyph->linearHoriAdvance =
          FIXED_TO_INT( decoder.builder.advance.x );
        t1glyph->internal->glyph_transformed = 0;

        if ( load_flags & FT_LOAD_VERTICAL_LAYOUT )
        {
          /* make up vertical ones */
          metrics->vertAdvance = ( face->type1.font_bbox.yMax -
                                   face->type1.font_bbox.yMin ) >> 16;
          t1glyph->linearVertAdvance = metrics->vertAdvance;
        }
        else
        {
Example #26
0
File: afshaper.c Project: 93i/godot
  const char*
  af_shaper_get_cluster( const char*      p,
                         AF_StyleMetrics  metrics,
                         void*            buf_,
                         unsigned int*    count )
  {
    AF_StyleClass        style_class;
    const hb_feature_t*  feature;
    FT_Int               upem;
    const char*          q;
    int                  len;

    hb_buffer_t*    buf = (hb_buffer_t*)buf_;
    hb_font_t*      font;
    hb_codepoint_t  dummy;


    upem        = (FT_Int)metrics->globals->face->units_per_EM;
    style_class = metrics->style_class;
    feature     = features[style_class->coverage];

    font = metrics->globals->hb_font;

    /* we shape at a size of units per EM; this means font units */
    hb_font_set_scale( font, upem, upem );

    while ( *p == ' ' )
      p++;

    /* count bytes up to next space (or end of buffer) */
    q = p;
    while ( !( *q == ' ' || *q == '\0' ) )
      GET_UTF8_CHAR( dummy, q );
    len = (int)( q - p );

    /* feed character(s) to the HarfBuzz buffer */
    hb_buffer_clear_contents( buf );
    hb_buffer_add_utf8( buf, p, len, 0, len );

    /* we let HarfBuzz guess the script and writing direction */
    hb_buffer_guess_segment_properties( buf );

    /* shape buffer, which means conversion from character codes to */
    /* glyph indices, possibly applying a feature                   */
    hb_shape( font, buf, feature, feature ? 1 : 0 );

    if ( feature )
    {
      hb_buffer_t*  hb_buf = metrics->globals->hb_buf;

      unsigned int      gcount;
      hb_glyph_info_t*  ginfo;

      unsigned int      hb_gcount;
      hb_glyph_info_t*  hb_ginfo;


      /* we have to check whether applying a feature does actually change */
      /* glyph indices; otherwise the affected glyph or glyphs aren't     */
      /* available at all in the feature                                  */

      hb_buffer_clear_contents( hb_buf );
      hb_buffer_add_utf8( hb_buf, p, len, 0, len );
      hb_buffer_guess_segment_properties( hb_buf );
      hb_shape( font, hb_buf, NULL, 0 );

      ginfo    = hb_buffer_get_glyph_infos( buf, &gcount );
      hb_ginfo = hb_buffer_get_glyph_infos( hb_buf, &hb_gcount );

      if ( gcount == hb_gcount )
      {
        unsigned int  i;


        for (i = 0; i < gcount; i++ )
          if ( ginfo[i].codepoint != hb_ginfo[i].codepoint )
            break;

        if ( i == gcount )
        {
          /* both buffers have identical glyph indices */
          hb_buffer_clear_contents( buf );
        }
      }
    }

    *count = hb_buffer_get_length( buf );

#ifdef FT_DEBUG_LEVEL_TRACE
    if ( feature && *count > 1 )
      FT_TRACE1(( "af_shaper_get_cluster:"
                  " input character mapped to multiple glyphs\n" ));
#endif

    return q;
  }
Example #27
0
  FT_Stream_Open( FT_Stream    stream,
                  const char*  filepathname )
  {
    int          file;
    struct stat  stat_buf;


    if ( !stream )
      return FT_Err_Invalid_Stream_Handle;

    /* open the file */
    file = open( filepathname, O_RDONLY );
    if ( file < 0 )
    {
      FT_ERROR(( "FT_Stream_Open:" ));
      FT_ERROR(( " could not open `%s'\n", filepathname ));
      return FT_Err_Cannot_Open_Resource;
    }

    /* Here we ensure that a "fork" will _not_ duplicate   */
    /* our opened input streams on Unix.  This is critical */
    /* since it avoids some (possible) access control      */
    /* issues and cleans up the kernel file table a bit.   */
    /*                                                     */
#ifdef F_SETFD
#ifdef FD_CLOEXEC
    (void)fcntl( file, F_SETFD, FD_CLOEXEC );
#else
    (void)fcntl( file, F_SETFD, 1 );
#endif /* FD_CLOEXEC */
#endif /* F_SETFD */

    if ( fstat( file, &stat_buf ) < 0 )
    {
      FT_ERROR(( "FT_Stream_Open:" ));
      FT_ERROR(( " could not `fstat' file `%s'\n", filepathname ));
      goto Fail_Map;
    }

    stream->size = stat_buf.st_size;
    stream->pos  = 0;
    stream->base = (unsigned char *)mmap( NULL,
                                          stream->size,
                                          PROT_READ,
                                          MAP_FILE | MAP_PRIVATE,
                                          file,
                                          0 );

    if ( (long)stream->base == -1 )
    {
      FT_ERROR(( "FT_Stream_Open:" ));
      FT_ERROR(( " could not `mmap' file `%s'\n", filepathname ));
      goto Fail_Map;
    }

    close( file );

    stream->descriptor.pointer = stream->base;
    stream->pathname.pointer   = (char*)filepathname;

    stream->close = ft_close_stream;
    stream->read  = 0;

    FT_TRACE1(( "FT_Stream_Open:" ));
    FT_TRACE1(( " opened `%s' (%d bytes) successfully\n",
                filepathname, stream->size ));

    return FT_Err_Ok;

  Fail_Map:
    close( file );

    stream->base = NULL;
    stream->size = 0;
    stream->pos  = 0;

    return FT_Err_Cannot_Open_Stream;
  }
Example #28
0
  FT_Error
  af_get_char_index( AF_StyleMetrics  metrics,
                     FT_ULong         charcode,
                     FT_ULong        *codepoint,
                     FT_Long         *y_offset )
  {
    AF_StyleClass  style_class;

    const hb_feature_t*  feature;

    FT_ULong  in_idx, out_idx;


    if ( !metrics )
      return FT_THROW( Invalid_Argument );

    in_idx = FT_Get_Char_Index( metrics->globals->face, charcode );

    style_class = metrics->style_class;

    feature = features[style_class->coverage];

    if ( feature )
    {
      FT_Int  upem = (FT_Int)metrics->globals->face->units_per_EM;

      hb_font_t*    font = metrics->globals->hb_font;
      hb_buffer_t*  buf  = hb_buffer_create();

      uint32_t  c = (uint32_t)charcode;

      hb_glyph_info_t*      ginfo;
      hb_glyph_position_t*  gpos;
      unsigned int          gcount;


      /* we shape at a size of units per EM; this means font units */
      hb_font_set_scale( font, upem, upem );

      /* XXX: is this sufficient for a single character of any script? */
      hb_buffer_set_direction( buf, HB_DIRECTION_LTR );
      hb_buffer_set_script( buf, scripts[style_class->script] );

      /* we add one character to `buf' ... */
      hb_buffer_add_utf32( buf, &c, 1, 0, 1 );

      /* ... and apply one feature */
      hb_shape( font, buf, feature, 1 );

      ginfo = hb_buffer_get_glyph_infos( buf, &gcount );
      gpos  = hb_buffer_get_glyph_positions( buf, &gcount );

      out_idx = ginfo[0].codepoint;

      /* getting the same index indicates no substitution,         */
      /* which means that the glyph isn't available in the feature */
      if ( in_idx == out_idx )
      {
        *codepoint = 0;
        *y_offset  = 0;
      }
      else
      {
        *codepoint = out_idx;
        *y_offset  = gpos[0].y_offset;
      }

      hb_buffer_destroy( buf );

#ifdef FT_DEBUG_LEVEL_TRACE
      if ( gcount > 1 )
        FT_TRACE1(( "af_get_char_index:"
                    " input character mapped to multiple glyphs\n" ));
#endif
    }
    else
    {
      *codepoint = in_idx;
      *y_offset  = 0;
    }

    return FT_Err_Ok;
  }
Example #29
0
  FT_Stream_Open( FT_Stream    stream,
                  const char*  filepathname )
  {
    int          file;
    struct stat  stat_buf;


    if ( !stream )
      return FT_THROW( Invalid_Stream_Handle );

    /* open the file */
    file = open( filepathname, O_RDONLY );
    if ( file < 0 )
    {
      FT_ERROR(( "FT_Stream_Open:" ));
      FT_ERROR(( " could not open `%s'\n", filepathname ));
      return FT_THROW( Cannot_Open_Resource );
    }

    if ( fstat( file, &stat_buf ) < 0 )
    {
      FT_ERROR(( "FT_Stream_Open:" ));
      FT_ERROR(( " could not `fstat' file `%s'\n", filepathname ));
      goto Fail_Map;
    }

    stream->size = stat_buf.st_size;
    if ( !stream->size )
    {
      FT_ERROR(( "FT_Stream_Open:" ));
      FT_ERROR(( " opened `%s' but zero-sized\n", filepathname ));
      goto Fail_Map;
    }

    stream->pos  = 0;
    stream->base = (unsigned char *)mmap( NULL,
                                          stream->size,
                                          PROT_READ,
                                          MAP_FILE | MAP_PRIVATE,
                                          file,
                                          0 );

    if ( (long)stream->base == -1 )
    {
      FT_ERROR(( "FT_Stream_Open:" ));
      FT_ERROR(( " could not `mmap' file `%s'\n", filepathname ));
      goto Fail_Map;
    }

    close( file );

    stream->descriptor.pointer = stream->base;
    stream->pathname.pointer   = (char*)filepathname;

    stream->close = ft_close_stream;
    stream->read  = 0;

    FT_TRACE1(( "FT_Stream_Open:" ));
    FT_TRACE1(( " opened `%s' (%d bytes) successfully\n",
                filepathname, stream->size ));

    return FT_Err_Ok;

  Fail_Map:
    close( file );

    stream->base = NULL;
    stream->size = 0;
    stream->pos  = 0;

    return FT_THROW( Cannot_Open_Stream );
  }
Example #30
0
  sfnt_init_face( FT_Stream      stream,
                  TT_Face        face,
                  FT_Int         face_index,
                  FT_Int         num_params,
                  FT_Parameter*  params )
  {
    FT_Error         error;
    FT_Library       library = face->root.driver->root.library;
    SFNT_Service     sfnt;
    SFNT_HeaderRec   sfnt_header;

    /* for now, parameters are unused */
    FT_UNUSED( num_params );
    FT_UNUSED( params );


	FT_TRACE1( ( "john1\n" ) );
    sfnt = (SFNT_Service)face->sfnt;
	FT_TRACE1( ( "john2\n" ) );
    if ( !sfnt )
    {
      sfnt = (SFNT_Service)FT_Get_Module_Interface( library, "sfnt" );
	FT_TRACE1( ( "john3\n" ) );
      if ( !sfnt )
      {
        error = SFNT_Err_Invalid_File_Format;
        goto Exit;
      }

      face->sfnt       = sfnt;
      face->goto_table = sfnt->goto_table;
    }

	FT_TRACE1( ( "john4\n" ) );
    FT_FACE_FIND_GLOBAL_SERVICE( face, face->psnames, POSTSCRIPT_CMAPS );

    /* check that we have a valid TrueType file */
    error = sfnt->load_sfnt_header( face, stream, face_index, &sfnt_header );
	FT_TRACE1( ( "john5\n" ) );
    if ( error )
      goto Exit;

    face->format_tag = sfnt_header.format_tag;
    face->num_tables = sfnt_header.num_tables;

    /* Load font directory */
    error = sfnt->load_directory( face, stream, &sfnt_header );
	FT_TRACE1( ( "john6\n" ) );
    if ( error )
      goto Exit;

	FT_TRACE1( ( "john7\n" ) );
    face->root.num_faces = face->ttc_header.count;
	FT_TRACE1( ( "john8\n" ) );
    if ( face->root.num_faces < 1 )
      face->root.num_faces = 1;
	FT_TRACE1( ( "john9\n" ) );

  Exit:
    return error;
  }