2000-12-08 03:42:29 +01:00
|
|
|
/***************************************************************************/
|
|
|
|
/* */
|
|
|
|
/* cffdrivr.c */
|
|
|
|
/* */
|
|
|
|
/* OpenType font driver implementation (body). */
|
|
|
|
/* */
|
|
|
|
/* Copyright 1996-2000 by */
|
|
|
|
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
|
|
|
|
/* */
|
|
|
|
/* This file is part of the FreeType project, and may only be used, */
|
|
|
|
/* modified, and distributed under the terms of the FreeType project */
|
|
|
|
/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
|
|
|
|
/* this file you indicate that you have read the license and */
|
|
|
|
/* understand and accept it fully. */
|
|
|
|
/* */
|
|
|
|
/***************************************************************************/
|
|
|
|
|
2000-12-08 17:17:16 +01:00
|
|
|
|
2000-12-08 03:42:29 +01:00
|
|
|
#include <ft2build.h>
|
|
|
|
#include FT_FREETYPE_H
|
|
|
|
#include FT_INTERNAL_DEBUG_H
|
|
|
|
#include FT_INTERNAL_STREAM_H
|
|
|
|
#include FT_INTERNAL_SFNT_H
|
|
|
|
#include FT_TRUETYPE_NAMES_H
|
|
|
|
#include FT_INTERNAL_CFF_ERRORS_H
|
|
|
|
|
2000-12-13 20:55:11 +01:00
|
|
|
#include FT_SOURCE_FILE(cff,cffdrivr.h)
|
2001-01-03 01:21:59 +01:00
|
|
|
#include FT_SOURCE_FILE(cff,cffgload.h)
|
2000-12-08 03:42:29 +01:00
|
|
|
|
2000-12-08 17:17:16 +01:00
|
|
|
|
2000-12-08 03:42:29 +01:00
|
|
|
/*************************************************************************/
|
|
|
|
/* */
|
|
|
|
/* The macro FT_COMPONENT is used in trace mode. It is an implicit */
|
|
|
|
/* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
|
|
|
|
/* messages during execution. */
|
|
|
|
/* */
|
|
|
|
#undef FT_COMPONENT
|
2001-01-03 01:21:59 +01:00
|
|
|
#define FT_COMPONENT trace_cffdriver
|
2000-12-08 03:42:29 +01:00
|
|
|
|
|
|
|
|
|
|
|
/*************************************************************************/
|
|
|
|
/*************************************************************************/
|
|
|
|
/*************************************************************************/
|
|
|
|
/**** ****/
|
|
|
|
/**** ****/
|
|
|
|
/**** F A C E S ****/
|
|
|
|
/**** ****/
|
|
|
|
/**** ****/
|
|
|
|
/*************************************************************************/
|
|
|
|
/*************************************************************************/
|
|
|
|
/*************************************************************************/
|
|
|
|
|
|
|
|
|
|
|
|
#undef PAIR_TAG
|
|
|
|
#define PAIR_TAG( left, right ) ( ( (FT_ULong)left << 16 ) | \
|
|
|
|
(FT_ULong)right )
|
|
|
|
|
|
|
|
|
|
|
|
/*************************************************************************/
|
|
|
|
/* */
|
|
|
|
/* <Function> */
|
|
|
|
/* Get_Kerning */
|
|
|
|
/* */
|
|
|
|
/* <Description> */
|
|
|
|
/* A driver method used to return the kerning vector between two */
|
|
|
|
/* glyphs of the same face. */
|
|
|
|
/* */
|
|
|
|
/* <Input> */
|
|
|
|
/* face :: A handle to the source face object. */
|
|
|
|
/* */
|
|
|
|
/* left_glyph :: The index of the left glyph in the kern pair. */
|
|
|
|
/* */
|
|
|
|
/* right_glyph :: The index of the right glyph in the kern pair. */
|
|
|
|
/* */
|
|
|
|
/* <Output> */
|
|
|
|
/* kerning :: The kerning vector. This is in font units for */
|
|
|
|
/* scalable formats, and in pixels for fixed-sizes */
|
|
|
|
/* formats. */
|
|
|
|
/* */
|
|
|
|
/* <Return> */
|
|
|
|
/* FreeType error code. 0 means success. */
|
|
|
|
/* */
|
|
|
|
/* <Note> */
|
|
|
|
/* Only horizontal layouts (left-to-right & right-to-left) are */
|
|
|
|
/* supported by this function. Other layouts, or more sophisticated */
|
|
|
|
/* kernings, are out of scope of this method (the basic driver */
|
|
|
|
/* interface is meant to be simple). */
|
|
|
|
/* */
|
|
|
|
/* They can be implemented by format-specific interfaces. */
|
|
|
|
/* */
|
|
|
|
static
|
|
|
|
FT_Error Get_Kerning( TT_Face face,
|
|
|
|
FT_UInt left_glyph,
|
|
|
|
FT_UInt right_glyph,
|
|
|
|
FT_Vector* kerning )
|
|
|
|
{
|
|
|
|
TT_Kern_0_Pair* pair;
|
|
|
|
|
|
|
|
|
|
|
|
if ( !face )
|
2001-01-03 01:21:59 +01:00
|
|
|
return CFF_Err_Invalid_Face_Handle;
|
2000-12-08 03:42:29 +01:00
|
|
|
|
|
|
|
kerning->x = 0;
|
|
|
|
kerning->y = 0;
|
|
|
|
|
|
|
|
if ( face->kern_pairs )
|
|
|
|
{
|
|
|
|
/* there are some kerning pairs in this font file! */
|
|
|
|
FT_ULong search_tag = PAIR_TAG( left_glyph, right_glyph );
|
|
|
|
FT_Long left, right;
|
|
|
|
|
|
|
|
|
|
|
|
left = 0;
|
|
|
|
right = face->num_kern_pairs - 1;
|
|
|
|
|
|
|
|
while ( left <= right )
|
|
|
|
{
|
|
|
|
FT_Int middle = left + ( ( right - left ) >> 1 );
|
|
|
|
FT_ULong cur_pair;
|
|
|
|
|
|
|
|
|
|
|
|
pair = face->kern_pairs + middle;
|
|
|
|
cur_pair = PAIR_TAG( pair->left, pair->right );
|
|
|
|
|
|
|
|
if ( cur_pair == search_tag )
|
|
|
|
goto Found;
|
|
|
|
|
|
|
|
if ( cur_pair < search_tag )
|
|
|
|
left = middle + 1;
|
|
|
|
else
|
|
|
|
right = middle - 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Exit:
|
2001-01-03 01:21:59 +01:00
|
|
|
return CFF_Err_Ok;
|
2000-12-08 03:42:29 +01:00
|
|
|
|
|
|
|
Found:
|
|
|
|
kerning->x = pair->value;
|
|
|
|
goto Exit;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#undef PAIR_TAG
|
|
|
|
|
|
|
|
|
|
|
|
/*************************************************************************/
|
|
|
|
/* */
|
|
|
|
/* <Function> */
|
|
|
|
/* Load_Glyph */
|
|
|
|
/* */
|
|
|
|
/* <Description> */
|
|
|
|
/* A driver method used to load a glyph within a given glyph slot. */
|
|
|
|
/* */
|
|
|
|
/* <Input> */
|
|
|
|
/* slot :: A handle to the target slot object where the glyph */
|
|
|
|
/* will be loaded. */
|
|
|
|
/* */
|
|
|
|
/* size :: A handle to the source face size at which the glyph */
|
|
|
|
/* must be scaled, loaded, etc. */
|
|
|
|
/* */
|
|
|
|
/* glyph_index :: The index of the glyph in the font file. */
|
|
|
|
/* */
|
|
|
|
/* load_flags :: A flag indicating what to load for this glyph. The */
|
|
|
|
/* FTLOAD_??? constants can be used to control the */
|
|
|
|
/* glyph loading process (e.g., whether the outline */
|
|
|
|
/* should be scaled, whether to load bitmaps or not, */
|
|
|
|
/* whether to hint the outline, etc). */
|
|
|
|
/* */
|
|
|
|
/* <Return> */
|
|
|
|
/* FreeType error code. 0 means success. */
|
|
|
|
/* */
|
|
|
|
static
|
2001-01-03 01:21:59 +01:00
|
|
|
FT_Error Load_Glyph( CFF_GlyphSlot slot,
|
|
|
|
CFF_Size size,
|
2000-12-08 03:42:29 +01:00
|
|
|
FT_UShort glyph_index,
|
|
|
|
FT_UInt load_flags )
|
|
|
|
{
|
|
|
|
FT_Error error;
|
|
|
|
|
|
|
|
|
|
|
|
if ( !slot )
|
2001-01-03 01:21:59 +01:00
|
|
|
return CFF_Err_Invalid_Glyph_Handle;
|
2000-12-08 03:42:29 +01:00
|
|
|
|
|
|
|
/* check whether we want a scaled outline or bitmap */
|
|
|
|
if ( !size )
|
|
|
|
load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING;
|
|
|
|
|
|
|
|
if ( load_flags & FT_LOAD_NO_SCALE )
|
|
|
|
size = NULL;
|
|
|
|
|
|
|
|
/* reset the size object if necessary */
|
|
|
|
if ( size )
|
|
|
|
{
|
|
|
|
/* these two object must have the same parent */
|
|
|
|
if ( size->face != slot->root.face )
|
2001-01-03 01:21:59 +01:00
|
|
|
return CFF_Err_Invalid_Face_Handle;
|
2000-12-08 03:42:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* now load the glyph outline if necessary */
|
2001-01-03 01:21:59 +01:00
|
|
|
error = CFF_Load_Glyph( slot, size, glyph_index, load_flags );
|
2000-12-08 03:42:29 +01:00
|
|
|
|
|
|
|
/* force drop-out mode to 2 - irrelevant now */
|
|
|
|
/* slot->outline.dropout_mode = 2; */
|
|
|
|
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*************************************************************************/
|
|
|
|
/*************************************************************************/
|
|
|
|
/*************************************************************************/
|
|
|
|
/**** ****/
|
|
|
|
/**** ****/
|
|
|
|
/**** C H A R A C T E R M A P P I N G S ****/
|
|
|
|
/**** ****/
|
|
|
|
/**** ****/
|
|
|
|
/*************************************************************************/
|
|
|
|
/*************************************************************************/
|
|
|
|
/*************************************************************************/
|
|
|
|
|
|
|
|
/*************************************************************************/
|
|
|
|
/* */
|
|
|
|
/* <Function> */
|
|
|
|
/* Get_Char_Index */
|
|
|
|
/* */
|
|
|
|
/* <Description> */
|
|
|
|
/* Uses a charmap to return a given character code's glyph index. */
|
|
|
|
/* */
|
|
|
|
/* <Input> */
|
|
|
|
/* charmap :: A handle to the source charmap object. */
|
|
|
|
/* charcode :: The character code. */
|
|
|
|
/* */
|
|
|
|
/* <Return> */
|
|
|
|
/* Glyph index. 0 means `undefined character code'. */
|
|
|
|
/* */
|
|
|
|
static
|
2001-01-03 01:21:59 +01:00
|
|
|
FT_UInt cff_get_char_index( TT_CharMap charmap,
|
2000-12-08 03:42:29 +01:00
|
|
|
FT_Long charcode )
|
|
|
|
{
|
|
|
|
FT_Error error;
|
2001-01-03 01:21:59 +01:00
|
|
|
CFF_Face face;
|
2000-12-08 03:42:29 +01:00
|
|
|
TT_CMapTable* cmap;
|
|
|
|
|
|
|
|
|
|
|
|
cmap = &charmap->cmap;
|
2001-01-03 01:21:59 +01:00
|
|
|
face = (CFF_Face)charmap->root.face;
|
2000-12-08 03:42:29 +01:00
|
|
|
|
|
|
|
/* Load table if needed */
|
|
|
|
if ( !cmap->loaded )
|
|
|
|
{
|
|
|
|
SFNT_Interface* sfnt = (SFNT_Interface*)face->sfnt;
|
|
|
|
|
|
|
|
|
|
|
|
error = sfnt->load_charmap( face, cmap, face->root.stream );
|
|
|
|
if ( error )
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
cmap->loaded = TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ( cmap->get_index ? cmap->get_index( cmap, charcode ) : 0 );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*************************************************************************/
|
|
|
|
/*************************************************************************/
|
|
|
|
/*************************************************************************/
|
|
|
|
/**** ****/
|
|
|
|
/**** ****/
|
|
|
|
/**** D R I V E R I N T E R F A C E ****/
|
|
|
|
/**** ****/
|
|
|
|
/**** ****/
|
|
|
|
/*************************************************************************/
|
|
|
|
/*************************************************************************/
|
|
|
|
/*************************************************************************/
|
|
|
|
|
|
|
|
|
|
|
|
static
|
2001-01-03 01:21:59 +01:00
|
|
|
FT_Module_Interface cff_get_interface( CFF_Driver driver,
|
2000-12-08 03:42:29 +01:00
|
|
|
const char* interface )
|
|
|
|
{
|
|
|
|
FT_Module sfnt;
|
|
|
|
|
|
|
|
|
|
|
|
/* we simply pass our request to the `sfnt' module */
|
|
|
|
sfnt = FT_Get_Module( driver->root.root.library, "sfnt" );
|
|
|
|
|
|
|
|
return sfnt ? sfnt->clazz->get_interface( sfnt, interface ) : 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* The FT_DriverInterface structure is defined in ftdriver.h. */
|
|
|
|
|
|
|
|
FT_CALLBACK_TABLE_DEF
|
|
|
|
const FT_Driver_Class cff_driver_class =
|
|
|
|
{
|
|
|
|
/* begin with the FT_Module_Class fields */
|
|
|
|
{
|
|
|
|
ft_module_font_driver | ft_module_driver_scalable,
|
2001-01-03 01:21:59 +01:00
|
|
|
sizeof( CFF_DriverRec ),
|
2000-12-08 03:42:29 +01:00
|
|
|
"cff",
|
|
|
|
0x10000L,
|
|
|
|
0x20000L,
|
|
|
|
|
|
|
|
0, /* module-specific interface */
|
|
|
|
|
2001-01-03 01:21:59 +01:00
|
|
|
(FT_Module_Constructor)CFF_Init_Driver,
|
|
|
|
(FT_Module_Destructor) CFF_Done_Driver,
|
|
|
|
(FT_Module_Requester) cff_get_interface,
|
2000-12-08 03:42:29 +01:00
|
|
|
},
|
|
|
|
|
|
|
|
/* now the specific driver fields */
|
|
|
|
sizeof( TT_FaceRec ),
|
|
|
|
sizeof( FT_SizeRec ),
|
2001-01-03 01:21:59 +01:00
|
|
|
sizeof( CFF_GlyphSlotRec ),
|
2000-12-08 03:42:29 +01:00
|
|
|
|
2001-01-03 01:21:59 +01:00
|
|
|
(FTDriver_initFace) CFF_Init_Face,
|
|
|
|
(FTDriver_doneFace) CFF_Done_Face,
|
2000-12-08 03:42:29 +01:00
|
|
|
(FTDriver_initSize) 0,
|
|
|
|
(FTDriver_doneSize) 0,
|
|
|
|
(FTDriver_initGlyphSlot)0,
|
|
|
|
(FTDriver_doneGlyphSlot)0,
|
|
|
|
|
|
|
|
(FTDriver_setCharSizes) 0,
|
|
|
|
(FTDriver_setPixelSizes)0,
|
|
|
|
|
|
|
|
(FTDriver_loadGlyph) Load_Glyph,
|
2001-01-03 01:21:59 +01:00
|
|
|
(FTDriver_getCharIndex) cff_get_char_index,
|
2000-12-08 03:42:29 +01:00
|
|
|
|
|
|
|
(FTDriver_getKerning) Get_Kerning,
|
|
|
|
(FTDriver_attachFile) 0,
|
|
|
|
(FTDriver_getAdvances) 0
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef FT_CONFIG_OPTION_DYNAMIC_DRIVERS
|
|
|
|
|
|
|
|
|
|
|
|
/*************************************************************************/
|
|
|
|
/* */
|
|
|
|
/* <Function> */
|
|
|
|
/* getDriverClass */
|
|
|
|
/* */
|
|
|
|
/* <Description> */
|
|
|
|
/* This function is used when compiling the TrueType driver as a */
|
|
|
|
/* shared library (`.DLL' or `.so'). It will be used by the */
|
|
|
|
/* high-level library of FreeType to retrieve the address of the */
|
|
|
|
/* driver's generic interface. */
|
|
|
|
/* */
|
|
|
|
/* It shouldn't be implemented in a static build, as each driver must */
|
|
|
|
/* have the same function as an exported entry point. */
|
|
|
|
/* */
|
|
|
|
/* <Return> */
|
|
|
|
/* The address of the TrueType's driver generic interface. The */
|
|
|
|
/* format-specific interface can then be retrieved through the method */
|
|
|
|
/* interface->get_format_interface. */
|
|
|
|
/* */
|
|
|
|
FT_EXPORT_DEF( const FT_Driver_Class* ) getDriverClass( void )
|
|
|
|
{
|
|
|
|
return &cff_driver_class;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#endif /* CONFIG_OPTION_DYNAMIC_DRIVERS */
|
|
|
|
|
|
|
|
|
|
|
|
/* END */
|