Commit 2e421319 authored by David Turner's avatar David Turner
Browse files

moved a lot of things from the TrueType driver to the SFNT

module (whose interface has changed, by the way)

This allows even more code re-use between TrueType and
OpenType formats..
parent 2c5f482b
LATEST_CHANGES
- moved a lot of stuff from the TrueType driver to the SFNT module,
this allows greater code re-use between font drivers (e.g. TrueType,
OpenType, Compact-TrueType, etc..)
- added a tiny segment cache to the SFNT Charmap 4 decoder, in order
to minimally speed it up..
- added support for Multiple Master fonts in "type1z". There is also
a new file named <freetype/ftmm.h> which defines functions to
manage them from client applications.
......
......@@ -149,6 +149,24 @@
FT_Face face );
/***********************************************************************
*
* <FuncType>
* FT_AutoHinter_Reset_Func
*
* <Description>
* This function is used to recompute the global metrics in a given
* font. This is useful when global font data changes (e.g. multiple
* masters fonts where blend coordinates change..)
*
* <Input>
* hinter :: handle to source auto-hinter
* face :: handle to the face.
*
*
*/
typedef FT_Error (*FT_AutoHinter_Reset_Func)( FT_AutoHinter hinter,
FT_Face face );
/***********************************************************************
*
......@@ -189,6 +207,7 @@
{
FT_AutoHinter_Init_Func init_autohinter;
FT_AutoHinter_Done_Func done_autohinter;
FT_AutoHinter_Reset_Func reset_face;
FT_AutoHinter_Load_Func load_glyph;
FT_AutoHinter_Get_Global_Func get_global_hints;
......
......@@ -195,7 +195,12 @@ typedef struct FT_Frame_Field_
BASE_DEF(void) FT_Forget_Frame( FT_Stream stream );
BASE_DEF(FT_Error) FT_Extract_Frame( FT_Stream stream,
FT_ULong count,
FT_Byte* *pbytes );
BASE_DEF(void) FT_Release_Frame( FT_Stream stream,
FT_Byte* *pbytes );
BASE_DEF(FT_Char) FT_Get_Char( FT_Stream stream );
......@@ -233,13 +238,14 @@ typedef struct FT_Frame_Field_
#define ACCESS_Frame( size ) \
FT_SET_ERROR( FT_Access_Frame( stream, size ) )
#define ACCESS_Compressed_Frame( size ) \
FT_SET_ERROR( FT_Access_Compressed_Frame( stream, size ) )
#define FORGET_Frame() \
FT_Forget_Frame( stream )
#define EXTRACT_Frame( size, bytes ) \
FT_SET_ERROR( FT_Extract_Frame( stream, size, (FT_Byte**)&(bytes) ) )
#define RELEASE_Frame( bytes ) \
FT_Release_Frame( stream, (FT_Byte**)&(bytes) )
#define FILE_Seek( position ) \
FT_SET_ERROR( FT_Seek_Stream( stream, position ) )
......
......@@ -23,6 +23,96 @@
#include <freetype/internal/tttypes.h>
/*************************************************************************/
/* */
/* <FuncType> */
/* TT_Init_Face_Func */
/* */
/* <Description> */
/* First part of the SFNT face object initialisation. This will */
/* find the face in a SFNT file or collection, and load its */
/* format tag in face->format_tag. */
/* */
/* <Input> */
/* stream :: The input stream. */
/* face :: A handle to the target face object. */
/* faceIndex :: The index of the TrueType font, if we're opening a */
/* collection. */
/* num_params :: number of additional parameters */
/* params :: optional additional parameters */
/* */
/* <Return> */
/* FreeType error code. 0 means success. */
/* */
/* <Note> */
/* The stream cursor must be at the font file's origin */
/* This function recognizes fonts embedded in a "TrueType collection" */
/* */
/* Once the format tag has been validated by the font driver, it */
/* should then call the TT_Load_Face_Func callback to read the rest */
/* of the SFNT tables in the object.. */
/* */
typedef
FT_Error (*TT_Init_Face_Func)( FT_Stream stream,
TT_Face face,
FT_Int face_index,
FT_Int num_params,
FT_Parameter* params );
/*************************************************************************/
/* */
/* <FuncType> */
/* TT_Load_Face_Func */
/* */
/* <Description> */
/* Second part of the SFNT face object initialisation. This will */
/* load the common SFNT tables (head, OS/2, maxp, metrics, etc..) */
/* in the face object.. */
/* */
/* <Input> */
/* stream :: The input stream. */
/* face :: A handle to the target face object. */
/* faceIndex :: The index of the TrueType font, if we're opening a */
/* collection. */
/* num_params :: number of additional parameters */
/* params :: optional additional parameters */
/* */
/* <Return> */
/* FreeType error code. 0 means success. */
/* */
/* <Note> */
/* This function must be called after TT_Init_Face_Func */
/* */
typedef
FT_Error (*TT_Load_Face_Func)( FT_Stream stream,
TT_Face face,
FT_Int face_index,
FT_Int num_params,
FT_Parameter* params );
/*************************************************************************/
/* */
/* <FuncType> */
/* TT_Done_Face_Func */
/* */
/* <Description> */
/* A callback used to delete the common SFNT data from a face. */
/* */
/* <Input> */
/* face :: A handle to the target face object. */
/* */
/* <Note> */
/* This function does NOT destroy the face object.. */
/* */
typedef
void (*TT_Done_Face_Func)( TT_Face face );
typedef
FTDriver_Interface (*SFNT_Get_Interface_Func)( FT_Driver driver,
const char* interface );
/*************************************************************************/
/* */
/* <FuncType> */
......@@ -338,10 +428,17 @@
{
TT_Goto_Table_Func goto_table;
TT_Init_Face_Func init_face;
TT_Load_Face_Func load_face;
TT_Done_Face_Func done_face;
SFNT_Get_Interface_Func get_interface;
TT_Load_Any_Func load_any;
TT_Load_Format_Tag_Func load_format_tag;
TT_Load_Directory_Func load_directory;
/* these functions are called by "load_face" but they can also */
/* be called from external modules, if there is a need to */
TT_Load_Table_Func load_header;
TT_Load_Metrics_Func load_metrics;
TT_Load_Table_Func load_charmaps;
......
This diff is collapsed.
......@@ -121,6 +121,37 @@
}
BASE_FUNC(FT_Error) FT_Extract_Frame( FT_Stream stream,
FT_ULong count,
FT_Byte* *pbytes )
{
FT_Error error;
error = FT_Access_Frame( stream, count );
if (!error)
{
*pbytes = (FT_Byte*)stream->cursor;
/* equivalent to FT_Forget_Frame, with no memory block release */
stream->cursor = 0;
stream->limit = 0;
}
return error;
}
BASE_FUNC(void) FT_Release_Frame( FT_Stream stream,
FT_Byte* *pbytes )
{
if (stream->read)
{
FT_Memory memory = stream->memory;
FREE( *pbytes );
}
*pbytes = 0;
}
BASE_FUNC(FT_Error) FT_Access_Frame( FT_Stream stream,
FT_ULong count )
......@@ -194,7 +225,6 @@
if (stream->read)
{
FT_Memory memory = stream->memory;
FREE( stream->base );
}
stream->cursor = 0;
......
......@@ -38,12 +38,14 @@ ifndef SFNT_INCLUDE
$(SFNT_DIR_)ttcmap.c \
$(SFNT_DIR_)ttsbit.c \
$(SFNT_DIR_)ttpost.c \
$(SFNT_DIR_)sfobjs.c \
$(SFNT_DIR_)sfdriver.c
# driver headers
#
SFNT_DRV_H := $(BASE_H) \
$(SFNT_DIR_)sfobjs.h \
$(SFNT_DIR_)ttload.h \
$(SFNT_DIR_)ttsbit.h \
$(SFNT_DIR_)ttcmap.h \
......
......@@ -5,11 +5,52 @@
#include <ttsbit.h>
#include <ttpost.h>
#include <ttcmap.h>
#include <sfobjs.h>
static
void* get_sfnt_table( TT_Face face, FT_Sfnt_Tag tag )
{
void* table;
switch (tag)
{
case ft_sfnt_head: table = &face->header; break;
case ft_sfnt_hhea: table = &face->horizontal; break;
case ft_sfnt_vhea: table = (face->vertical_info ? &face->vertical : 0 ); break;
case ft_sfnt_os2: table = (face->os2.version == 0xFFFF ? 0 : &face->os2 ); break;
case ft_sfnt_post: table = &face->postscript; break;
case ft_sfnt_maxp: table = &face->max_profile; break;
case ft_sfnt_pclt: table = face->pclt.Version ? &face->pclt : 0 ; break;
default:
table = 0;
}
return table;
}
static
FTDriver_Interface SFNT_Get_Interface( FT_Driver driver,
const char* interface )
{
UNUSED(driver);
if (strcmp(interface,"get_sfnt")==0)
return (FTDriver_Interface)get_sfnt_table;
return 0;
}
static const SFNT_Interface sfnt_interface =
{
TT_Goto_Table,
SFNT_Init_Face,
SFNT_Load_Face,
SFNT_Done_Face,
SFNT_Get_Interface,
TT_Load_Any,
TT_Load_Format_Tag,
TT_Load_Directory,
......
......@@ -2,6 +2,7 @@
#include <ttload.c>
#include <ttcmap.c>
#include <sfobjs.c>
#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
#include <ttsbit.c>
......
......@@ -214,6 +214,8 @@
FORGET_Frame();
cmap->get_index = code_to_index4;
cmap4->last_segment = cmap4->segments;
break;
case 6:
......@@ -438,35 +440,45 @@
seg4 = cmap4->segments;
limit = seg4 + segCount;
for ( ; seg4 < limit; seg4++, segCount-- )
{
if ( charCode <= seg4->endCount )
{
/* the ranges are sorted in increasing order, if we're out of */
/* the range here, the char code isn't in the charmap, so exit */
if ( charCode < seg4->startCount )
break;
/* when the idRangeOffset is 0, we can compute the glyph index */
/* directly.. */
if ( seg4->idRangeOffset == 0 )
result = (charCode + seg4->idDelta) & 0xFFFF;
else
/* otherwise, we must use the glyphIdArray to do it */
{
index1 = seg4->idRangeOffset/2 + (charCode - seg4->startCount)
- segCount;
/* check against the last segment */
seg4 = cmap4->last_segment;
if ( (TT_ULong)(charCode - seg4->startCount) <
(TT_ULong)(seg4->endCount - seg4->startCount) )
goto Found;
if ( index1 < cmap4->numGlyphId &&
cmap4->glyphIdArray[index1] != 0 )
{
result = (cmap4->glyphIdArray[index1] + seg4->idDelta) & 0xFFFF;
}
}
for ( seg4 = cmap4->segments; seg4 < limit; seg4++, segCount-- )
{
/* the ranges are sorted in increasing order, if we're out of */
/* the range here, the char code isn't in the charmap, so exit */
if ( charCode > seg4->endCount )
break;
}
if ( charCode >= seg4->startCount )
goto Found;
}
return 0;
Found:
cmap4->last_segment = seg4;
/* when the idRangeOffset is 0, we can compute the glyph index */
/* directly.. */
if ( seg4->idRangeOffset == 0 )
result = (charCode + seg4->idDelta) & 0xFFFF;
else
/* otherwise, we must use the glyphIdArray to do it */
{
index1 = seg4->idRangeOffset/2 + (charCode - seg4->startCount)
- segCount;
if ( index1 < cmap4->numGlyphId &&
cmap4->glyphIdArray[index1] != 0 )
{
result = (cmap4->glyphIdArray[index1] + seg4->idDelta) & 0xFFFF;
}
}
return result;
}
......
......@@ -43,270 +43,6 @@
/*************************************************************************/
/******************************************************************
*
* <Function>
* find_encoding
*
* <Description>
* return the FT_Encoding corresponding to a given
* (platform_id,encoding_id) pair, as found in TrueType charmaps
*
* <Input>
* platform_id ::
* encoding_id ::
*
* <Return>
* the corresponding FT_Encoding tag. ft_encoding_none by default
*
*****************************************************************/
static
FT_Encoding find_encoding( int platform_id,
int encoding_id )
{
typedef struct TEncoding
{
int platform_id;
int encoding_id;
FT_Encoding encoding;
} TEncoding;
static
const TEncoding tt_encodings[] =
{
{ TT_PLATFORM_ISO, -1, ft_encoding_unicode },
{ TT_PLATFORM_APPLE_UNICODE, -1, ft_encoding_unicode },
{ TT_PLATFORM_MACINTOSH, TT_MAC_ID_ROMAN, ft_encoding_apple_roman },
{ TT_PLATFORM_MICROSOFT, TT_MS_ID_UNICODE_CS, ft_encoding_unicode },
{ TT_PLATFORM_MICROSOFT, TT_MS_ID_SJIS, ft_encoding_sjis },
{ TT_PLATFORM_MICROSOFT, TT_MS_ID_BIG_5, ft_encoding_big5 }
};
const TEncoding *cur, *limit;
cur = tt_encodings;
limit = cur + sizeof(tt_encodings)/sizeof(tt_encodings[0]);
for ( ; cur < limit; cur++ )
{
if (cur->platform_id == platform_id)
{
if (cur->encoding_id == encoding_id ||
cur->encoding_id == -1 )
return cur->encoding;
}
}
return ft_encoding_none;
}
/*************************************************************************/
/* */
/* <Function> */
/* Init_Face */
/* */
/* <Description> */
/* A driver method used to initialize a new TrueType face object. */
/* */
/* <Input> */
/* resource :: A handle to the source resource. */
/* */
/* typeface_index :: An index of the face in the font resource. Used */
/* to access individual faces in font collections. */
/* */
/* <InOut> */
/* face :: A handle to the face object. */
/* */
/* <Return> */
/* FreeType error code. 0 means success. */
/* */
/* <Note> */
/* The `typeface_index' parameter field will be set to -1 if the */
/* engine only wants to test the format of the resource. This means */
/* that font drivers should simply check the font format, then return */
/* immediately with an error code of 0 (meaning success). The field */
/* `num_faces' should be set. */
/* */
/* Done_Face() will be called subsequently, whatever the result was. */
/* */
static
TT_Error Init_Face( FT_Stream stream,
TT_Face face,
FT_Int typeface_index,
FT_Int num_params,
FT_Parameter* params )
{
TT_Error error;
/* initialize the TrueType face object */
error = TT_Init_Face( stream, face, typeface_index, num_params, params );
/* now set up root fields */
if ( !error && typeface_index >= 0 )
{
FT_Face root = &face->root;
FT_Int flags;
TT_CharMap charmap;
TT_Int n;
FT_Memory memory;
memory = root->memory;
/*****************************************************************/
/* */
/* Compute face flags. */
/* */
flags = FT_FACE_FLAG_SCALABLE | /* scalable outlines */
FT_FACE_FLAG_SFNT | /* SFNT file format */
FT_FACE_FLAG_HORIZONTAL; /* horizontal data */
/* fixed width font ? */
if ( face->postscript.isFixedPitch )
flags |= FT_FACE_FLAG_FIXED_WIDTH;
/* vertical information ? */
if ( face->vertical_info )
flags |= FT_FACE_FLAG_VERTICAL;
/* kerning available ? */
if ( face->kern_pairs )
flags |= FT_FACE_FLAG_KERNING;
root->face_flags = flags;
/*****************************************************************/
/* */
/* Compute style flags. */
/* */
flags = 0;
if ( face->os2.version != 0xFFFF )
{
/* We have an OS/2 table, use the `fsSelection' field */
if ( face->os2.fsSelection & 1 )
flags |= FT_STYLE_FLAG_ITALIC;
if ( face->os2.fsSelection & 32 )
flags |= FT_STYLE_FLAG_BOLD;
}
else
{
/* This is an old Mac font, use the header field */
if ( face->header.Mac_Style & 1 )
flags |= FT_STYLE_FLAG_BOLD;
if ( face->header.Mac_Style & 2 )
flags |= FT_STYLE_FLAG_ITALIC;
}
face->root.style_flags = flags;
/*****************************************************************/
/* */
/* Polish the charmaps. */
/* */
/* Try to set the charmap encoding according to the platform & */
/* encoding ID of each charmap. */
/* */
charmap = face->charmaps;
root->num_charmaps = face->num_charmaps;
/* allocate table of pointers */
if ( ALLOC_ARRAY( root->charmaps, root->num_charmaps, FT_CharMap ) )
return error;
for ( n = 0; n < root->num_charmaps; n++, charmap++ )
{
FT_Int platform = charmap->cmap.platformID;
FT_Int encoding = charmap->cmap.platformEncodingID;
charmap->root.face = (FT_Face)face;
charmap->root.platform_id = platform;
charmap->root.encoding_id = encoding;
charmap->root.encoding = find_encoding(platform,encoding);
/* now, set root->charmap with a unicode charmap wherever available */
if (!root->charmap && charmap->root.encoding == ft_encoding_unicode)
root->charmap = (FT_CharMap)charmap;
root->charmaps[n] = (FT_CharMap)charmap;
}
#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
if ( face->num_sbit_strikes )
{
face->root.num_fixed_sizes = face->num_sbit_strikes;
if ( ALLOC_ARRAY( face->root.available_sizes,
face->num_sbit_strikes,
FT_Bitmap_Size ) )
return error;
for ( n = 0 ; n < face->num_sbit_strikes ; n++ )
{
face->root.available_sizes[n].width =
face->sbit_strikes[n].x_ppem;
face->root.available_sizes[n].height =
face->sbit_strikes[n].y_ppem;
}
}
else
#else
{
root->num_fixed_sizes = 0;
root->available_sizes = 0;
}
#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
/*****************************************************************/