parent
3581d06464
commit
04aa800ce9
31 changed files with 5475 additions and 48 deletions
@ -0,0 +1,228 @@ |
||||
/***************************************************************************
|
||||
* |
||||
* t1afm.c - support for reading Type 1 AFM files |
||||
* |
||||
* |
||||
***************************************************************************/ |
||||
|
||||
#include <cidafm.h> |
||||
#include <freetype/internal/ftstream.h> |
||||
#include <freetype/internal/t1types.h> |
||||
#include <stdlib.h> /* for qsort */ |
||||
|
||||
LOCAL_FUNC |
||||
void CID_Done_AFM( FT_Memory memory, T1_AFM* afm ) |
||||
{ |
||||
FREE( afm->kern_pairs ); |
||||
afm->num_pairs = 0; |
||||
} |
||||
|
||||
#undef IS_KERN_PAIR |
||||
#define IS_KERN_PAIR(p) ( p[0] == 'K' && p[1] == 'P' ) |
||||
|
||||
#define IS_ALPHANUM(c) ( (c >= 'A' && c <= 'Z') || \ |
||||
(c >= 'a' && c <= 'z') || \
|
||||
(c >= '0' && c <= '9') || \
|
||||
(c == '_' && c == '.') ) |
||||
|
||||
/* read a glyph name and return the equivalent glyph index */ |
||||
static |
||||
FT_UInt afm_atoindex( FT_Byte* *start, FT_Byte* limit, T1_Font* type1 ) |
||||
{ |
||||
FT_Byte* p = *start; |
||||
FT_Int len; |
||||
FT_UInt result = 0; |
||||
char temp[64]; |
||||
|
||||
/* skip whitespace */ |
||||
while ( (*p == ' ' || *p == '\t' || *p == ':' || *p == ';') && p < limit ) |
||||
p++; |
||||
*start = p; |
||||
|
||||
/* now, read glyph name */ |
||||
while ( IS_ALPHANUM(*p) && p < limit ) p++; |
||||
len = p - *start; |
||||
if (len > 0 && len < 64) |
||||
{ |
||||
FT_Int n; |
||||
|
||||
/* copy glyph name to intermediate array */ |
||||
MEM_Copy( temp, *start, len ); |
||||
temp[len] = 0; |
||||
|
||||
/* lookup glyph name in face array */ |
||||
for ( n = 0; n < type1->num_glyphs; n++ ) |
||||
{ |
||||
char* gname = (char*)type1->glyph_names[n]; |
||||
|
||||
if ( gname && gname[0] == temp[0] && strcmp(gname,temp) == 0 ) |
||||
{ |
||||
result = n; |
||||
break; |
||||
} |
||||
} |
||||
} |
||||
*start = p; |
||||
return result; |
||||
} |
||||
|
||||
|
||||
/* read an integer */ |
||||
static |
||||
int afm_atoi( FT_Byte** start, FT_Byte* limit ) |
||||
{ |
||||
FT_Byte* p = *start; |
||||
int sum = 0; |
||||
int sign = 1; |
||||
|
||||
/* skip everything that is not a number */ |
||||
while ( p < limit && (*p < '0' || *p > '9') ) |
||||
{ |
||||
sign = 1; |
||||
if (*p == '-') |
||||
sign = -1; |
||||
|
||||
p++; |
||||
} |
||||
|
||||
while ( p < limit && (*p >= '0' && *p < '9') ) |
||||
{ |
||||
sum = sum*10 + (*p - '0'); |
||||
p++; |
||||
} |
||||
*start = p; |
||||
return sum*sign; |
||||
} |
||||
|
||||
|
||||
#undef KERN_INDEX |
||||
#define KERN_INDEX(g1,g2) (((FT_ULong)g1 << 16) | g2) |
||||
|
||||
/* compare two kerning pairs */ |
||||
static |
||||
int compare_kern_pairs( const void* a, const void* b ) |
||||
{ |
||||
T1_Kern_Pair* pair1 = (T1_Kern_Pair*)a; |
||||
T1_Kern_Pair* pair2 = (T1_Kern_Pair*)b; |
||||
|
||||
FT_ULong index1 = KERN_INDEX(pair1->glyph1,pair1->glyph2); |
||||
FT_ULong index2 = KERN_INDEX(pair2->glyph1,pair2->glyph2); |
||||
|
||||
return ( index1 - index2 ); |
||||
} |
||||
|
||||
|
||||
/* parse an AFM file - for now, only read the kerning pairs */ |
||||
LOCAL_FUNC |
||||
FT_Error CID_Read_AFM( FT_Face t1_face, |
||||
FT_Stream stream ) |
||||
{ |
||||
FT_Error error; |
||||
FT_Memory memory = stream->memory; |
||||
FT_Byte* start; |
||||
FT_Byte* limit; |
||||
FT_Byte* p; |
||||
FT_Int count = 0; |
||||
T1_Kern_Pair* pair; |
||||
T1_Font* type1 = &((T1_Face)t1_face)->type1; |
||||
T1_AFM* afm = 0; |
||||
|
||||
if ( ACCESS_Frame(stream->size) ) |
||||
return error; |
||||
|
||||
start = (FT_Byte*)stream->cursor; |
||||
limit = (FT_Byte*)stream->limit; |
||||
p = start; |
||||
|
||||
/* we are now going to count the occurences of "KP" or "KPX" in */ |
||||
/* the AFM file.. */ |
||||
count = 0; |
||||
for ( p = start; p < limit-3; p++ ) |
||||
{ |
||||
if ( IS_KERN_PAIR(p) ) |
||||
count++; |
||||
} |
||||
|
||||
/* Actually, kerning pairs are simply optional !! */ |
||||
if (count == 0) |
||||
goto Exit; |
||||
|
||||
/* allocate the pairs */ |
||||
if ( ALLOC( afm, sizeof(*afm ) ) || |
||||
ALLOC_ARRAY( afm->kern_pairs, count, T1_Kern_Pair ) ) |
||||
goto Exit; |
||||
|
||||
/* now, read each kern pair */ |
||||
pair = afm->kern_pairs; |
||||
afm->num_pairs = count; |
||||
|
||||
/* save in face object */ |
||||
((T1_Face)t1_face)->afm_data = afm; |
||||
|
||||
for ( p = start; p < limit-3; p++ ) |
||||
{ |
||||
if ( IS_KERN_PAIR(p) ) |
||||
{ |
||||
FT_Byte* q; |
||||
|
||||
/* skip keyword (KP or KPX) */ |
||||
q = p+2; |
||||
if (*q == 'X') q++; |
||||
|
||||
pair->glyph1 = afm_atoindex( &q, limit, type1 ); |
||||
pair->glyph2 = afm_atoindex( &q, limit, type1 ); |
||||
pair->kerning.x = afm_atoi( &q, limit ); |
||||
|
||||
pair->kerning.y = 0; |
||||
if ( p[2] != 'X' ) |
||||
pair->kerning.y = afm_atoi( &q, limit ); |
||||
|
||||
pair++; |
||||
} |
||||
} |
||||
|
||||
/* now, sort the kern pairs according to their glyph indices */ |
||||
qsort( afm->kern_pairs, count, sizeof(T1_Kern_Pair), compare_kern_pairs ); |
||||
|
||||
Exit: |
||||
if (error) |
||||
FREE( afm ); |
||||
|
||||
FORGET_Frame(); |
||||
return error; |
||||
} |
||||
|
||||
|
||||
/* find the kerning for a given glyph pair */ |
||||
LOCAL_FUNC |
||||
void CID_Get_Kerning( T1_AFM* afm, |
||||
FT_UInt glyph1, |
||||
FT_UInt glyph2, |
||||
FT_Vector* kerning ) |
||||
{ |
||||
T1_Kern_Pair *min, *mid, *max; |
||||
FT_ULong index = KERN_INDEX(glyph1,glyph2); |
||||
|
||||
/* simple binary search */ |
||||
min = afm->kern_pairs; |
||||
max = min + afm->num_pairs-1; |
||||
|
||||
while (min <= max) |
||||
{ |
||||
FT_ULong midi; |
||||
|
||||
mid = min + (max-min)/2; |
||||
midi = KERN_INDEX(mid->glyph1,mid->glyph2); |
||||
if ( midi == index ) |
||||
{ |
||||
*kerning = mid->kerning; |
||||
return; |
||||
} |
||||
|
||||
if ( midi < index ) min = mid+1; |
||||
else max = mid-1; |
||||
} |
||||
kerning->x = 0; |
||||
kerning->y = 0; |
||||
} |
||||
|
@ -0,0 +1,49 @@ |
||||
/***************************************************************************
|
||||
* |
||||
* t1afm.h - support for reading Type 1 AFM files |
||||
* |
||||
* |
||||
***************************************************************************/ |
||||
|
||||
#ifndef T1AFM_H |
||||
#define T1AFM_H |
||||
|
||||
#include <freetype/internal/ftobjs.h> |
||||
|
||||
/* In this version, we only read the kerning table from the */ |
||||
/* AFM file. We may add support for ligatures a bit later.. */ |
||||
|
||||
typedef struct T1_Kern_Pair_ |
||||
{ |
||||
FT_UInt glyph1; |
||||
FT_UInt glyph2; |
||||
FT_Vector kerning; |
||||
|
||||
} T1_Kern_Pair; |
||||
|
||||
|
||||
typedef struct T1_AFM_ |
||||
{ |
||||
FT_Int num_pairs; |
||||
T1_Kern_Pair* kern_pairs; |
||||
|
||||
} T1_AFM; |
||||
|
||||
#if 0 |
||||
|
||||
LOCAL_DEF |
||||
FT_Error CID_Read_AFM( FT_Face face, |
||||
FT_Stream stream ); |
||||
|
||||
LOCAL_DEF |
||||
void CID_Done_AFM( FT_Memory memory, |
||||
T1_AFM* afm ); |
||||
|
||||
LOCAL_DEF |
||||
void CID_Get_Kerning( T1_AFM* afm, |
||||
FT_UInt glyph1, |
||||
FT_UInt glyph2, |
||||
FT_Vector* kerning ); |
||||
#endif |
||||
|
||||
#endif /* T1AFM_H */ |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,188 @@ |
||||
/*******************************************************************
|
||||
* |
||||
* cidgload.h 1.0 |
||||
* |
||||
* CID-Keyed Type1 Glyph Loader. |
||||
* |
||||
* Copyright 1996-1998 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. |
||||
* |
||||
* |
||||
* The Type 1 glyph loader uses three distinct objects to build |
||||
* scaled and hinted outlines from a charstrings program. These are : |
||||
* |
||||
* - a glyph builder, CID_Builder, used to store the built outline |
||||
* |
||||
* - a glyph hinter, T1_Hinter, used to record and apply the stem |
||||
* hints |
||||
* |
||||
* - a charstrings interpreter, CID_Decoder, used to parse the |
||||
* Type 1 charstrings stream, manage a stack and call the builder |
||||
* and/or hinter depending on the opcodes. |
||||
* |
||||
* Ideally, a Type 2 glyph loader would only need to have its own |
||||
* T2_Decoder object (assuming the hinter is able to manage all |
||||
* kinds of hints). |
||||
* |
||||
******************************************************************/ |
||||
|
||||
#ifndef CIDGLOAD_H |
||||
#define CIDGLOAD_H |
||||
|
||||
#include <cidobjs.h> |
||||
|
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
|
||||
|
||||
/*************************************************************************/ |
||||
/* */ |
||||
/* <Structure> CID_Builder */ |
||||
/* */ |
||||
/* <Description> */ |
||||
/* a structure used during glyph loading to store its outline. */ |
||||
/* */ |
||||
/* <Fields> */ |
||||
/* system :: current system object */ |
||||
/* face :: current face object */ |
||||
/* glyph :: current glyph slot */ |
||||
/* */ |
||||
/* current :: current glyph outline */ |
||||
/* base :: base glyph outline */ |
||||
/* */ |
||||
/* max_points :: maximum points in builder outline */ |
||||
/* max_contours :: maximum contours in builder outline */ |
||||
/* */ |
||||
/* last :: last point position */ |
||||
/* */ |
||||
/* scale_x :: horizontal scale ( FUnits to sub-pixels ) */ |
||||
/* scale_y :: vertical scale ( FUnits to sub-pixels ) */ |
||||
/* pos_x :: horizontal translation (composite glyphs) */ |
||||
/* pos_y :: vertical translation (composite glyph) */ |
||||
/* */ |
||||
/* left_bearing :: left side bearing point */ |
||||
/* advance :: horizontal advance vector */ |
||||
/* */ |
||||
/* path_begun :: flag, indicates that a new path has begun */ |
||||
/* load_points :: flag, if not set, no points are loaded */ |
||||
/* */ |
||||
/* error :: an error code that is only used to report */ |
||||
/* memory allocation problems.. */ |
||||
/* */ |
||||
/* metrics_only :: a boolean indicating that we only want to */ |
||||
/* compute the metrics of a given glyph, not load */ |
||||
/* all of its points.. */ |
||||
/* */ |
||||
|
||||
typedef struct CID_Builder_ |
||||
{ |
||||
FT_Memory memory; |
||||
CID_Face face; |
||||
T1_GlyphSlot glyph; |
||||
|
||||
FT_Outline current; /* the current glyph outline */ |
||||
FT_Outline base; /* the composite glyph outline */ |
||||
|
||||
FT_Int max_points; /* capacity of base outline in points */ |
||||
FT_Int max_contours; /* capacity of base outline in contours */ |
||||
|
||||
T1_Vector last; |
||||
|
||||
T1_Fixed scale_x; |
||||
T1_Fixed scale_y; |
||||
|
||||
T1_Pos pos_x; |
||||
T1_Pos pos_y; |
||||
|
||||
T1_Vector left_bearing; |
||||
T1_Vector advance; |
||||
|
||||
T1_BBox bbox; /* bounding box */ |
||||
T1_Bool path_begun; |
||||
T1_Bool load_points; |
||||
T1_Bool no_recurse; |
||||
|
||||
FT_Error error; /* only used for memory errors */ |
||||
T1_Bool metrics_only; |
||||
|
||||
} CID_Builder; |
||||
|
||||
|
||||
/* execution context charstring zone */ |
||||
typedef struct CID_Decoder_Zone_ |
||||
{ |
||||
FT_Byte* base; |
||||
FT_Byte* limit; |
||||
FT_Byte* cursor; |
||||
|
||||
} CID_Decoder_Zone; |
||||
|
||||
|
||||
typedef struct CID_Decoder_ |
||||
{ |
||||
CID_Builder builder; |
||||
|
||||
FT_Int stack[ T1_MAX_CHARSTRINGS_OPERANDS ]; |
||||
FT_Int* top; |
||||
|
||||
CID_Decoder_Zone zones[ T1_MAX_SUBRS_CALLS+1 ]; |
||||
CID_Decoder_Zone* zone; |
||||
|
||||
FT_Matrix font_matrix; |
||||
CID_Subrs* subrs; |
||||
FT_UInt lenIV; |
||||
|
||||
FT_Int flex_state; |
||||
FT_Int num_flex_vectors; |
||||
FT_Vector flex_vectors[7]; |
||||
|
||||
} CID_Decoder; |
||||
|
||||
|
||||
|
||||
LOCAL_DEF |
||||
void CID_Init_Builder( CID_Builder* builder, |
||||
CID_Face face, |
||||
T1_Size size, |
||||
T1_GlyphSlot glyph ); |
||||
|
||||
LOCAL_DEF |
||||
void CID_Done_Builder( CID_Builder* builder ); |
||||
|
||||
|
||||
LOCAL_DEF |
||||
void CID_Init_Decoder( CID_Decoder* decoder ); |
||||
|
||||
|
||||
#if 0 |
||||
/* Compute the maximum advance width of a font through quick parsing */ |
||||
LOCAL_DEF |
||||
FT_Error CID_Compute_Max_Advance( CID_Face face, |
||||
FT_Int *max_advance ); |
||||
#endif |
||||
|
||||
/* This function is exported, because it is used by the T1Dump utility */ |
||||
LOCAL_DEF |
||||
FT_Error CID_Parse_CharStrings( CID_Decoder* decoder, |
||||
FT_Byte* charstring_base, |
||||
FT_Int charstring_len ); |
||||
|
||||
LOCAL_DEF |
||||
FT_Error CID_Load_Glyph( T1_GlyphSlot glyph, |
||||
T1_Size size, |
||||
FT_Int glyph_index, |
||||
FT_Int load_flags ); |
||||
|
||||
|
||||
#ifdef __cplusplus |
||||
} |
||||
#endif |
||||
|
||||
#endif /* T1GLOAD_H */ |
@ -0,0 +1,503 @@ |
||||
/*******************************************************************
|
||||
* |
||||
* cidload.h 2.0 |
||||
* |
||||
* CID-keyed foint loader |
||||
* |
||||
* 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. |
||||
* |
||||
* |
||||
* This is the new and improved Type 1 data loader for FreeType 2. |
||||
* The old loader has several problems: it is slow, complex, difficult |
||||
* to maintain, and contains incredible hacks to make it accept some |
||||
* ill-formed Type 1 fonts without hiccup-ing. Moreover, about 5% |
||||
* of the Type 1 fonts on my machine still aren't loaded correctly |
||||
* with it. |
||||
* |
||||
* This version is much simpler, much faster and also easier to |
||||
* read and maintain by a great order of magnitude. The idea behind |
||||
* it is to _not_ try to read the Type 1 token stream with a state |
||||
* machine (i.e. a Postscript-like interpreter) but rather to perform |
||||
* simple pattern-matching. |
||||
* |
||||
* Indeed, nearly all data definitions follow a simple pattern |
||||
* like : |
||||
* |
||||
* ..... /Field <data> .... |
||||
* |
||||
* where <data> can be a number, a boolean, a string, or an |
||||
* array of numbers. There are a few exceptions, namely the |
||||
* encoding, font name, charstrings and subrs and they are |
||||
* handled with a special pattern-matching routine. |
||||
* |
||||
* All other common cases are handled very simply. The matching |
||||
* rules are defined in the file "t1tokens.h" through the use |
||||
* of several macros calls T1_FIELD_XXX |
||||
* |
||||
* The function "parse_dict" simply scans *linearly* a given |
||||
* dictionary (either the top-level or private one) and calls |
||||
* the appropriate callback when it encounters an immediate |
||||
* keyword. |
||||
* |
||||
* This is by far the fastest way one can find to parse and read |
||||
* all data :-) |
||||
* |
||||
* This led to tremendous code size reduction. Note that later, |
||||
* the glyph loader will also be _greatly_ simplified, and the |
||||
* automatic hinter will replace the clumsy "t1hinter".. |
||||
* |
||||
******************************************************************/ |
||||
|
||||
#include <freetype/internal/ftdebug.h> |
||||
#include <freetype/config/ftconfig.h> |
||||
#include <freetype/ftmm.h> |
||||
|
||||
#include <freetype/internal/t1types.h> |
||||
#include <t1errors.h> |
||||
#include <cidload.h> |
||||
#include <stdio.h> |
||||
|
||||
#undef FT_COMPONENT |
||||
#define FT_COMPONENT trace_t1load |
||||
|
||||
/* reads a single offset */ |
||||
LOCAL_FUNC |
||||
FT_Long cid_get_offset( FT_Byte** start, FT_Byte offsize ) |
||||
{ |
||||
FT_Long result; |
||||
FT_Byte* p = *start; |
||||
|
||||
for ( result = 0; offsize > 0; offsize-- ) |
||||
result = (result << 8) | *p++; |
||||
|
||||
*start = p; |
||||
return result; |
||||
} |
||||
|
||||
|
||||
LOCAL_FUNC |
||||
void cid_decrypt( FT_Byte* buffer, |
||||
FT_Int length, |
||||
FT_UShort seed ) |
||||
{ |
||||
while ( length > 0 ) |
||||
{ |
||||
FT_Byte plain; |
||||
|
||||
plain = (*buffer ^ (seed >> 8)); |
||||
seed = (*buffer+seed)*52845+22719; |
||||
*buffer++ = plain; |
||||
length--; |
||||
} |
||||
} |
||||
|
||||
|
||||
|
||||
/***************************************************************************/ |
||||
/***************************************************************************/ |
||||
/***** *****/ |
||||
/***** TYPE 1 SYMBOL PARSING *****/ |
||||
/***** *****/ |
||||
/***************************************************************************/ |
||||
/***************************************************************************/ |
||||
|
||||
|
||||
static FT_Error cid_load_keyword( CID_Face face, |
||||
CID_Loader* loader, |
||||
const T1_Field_Rec* keyword ) |
||||
{ |
||||
FT_Error error; |
||||
CID_Parser* parser = &loader->parser; |
||||
FT_Byte* object; |
||||
CID_Info* cid = &face->cid; |
||||
|
||||
/* if the keyword has a dedicated callback, call it */ |
||||
if (keyword->type == t1_field_callback) |
||||
{ |
||||
error = keyword->reader( face, parser ); |
||||
goto Exit; |
||||
} |
||||
|
||||
/* we must now compute the address of our target object */ |
||||
switch (keyword->location) |
||||
{ |
||||
case t1_field_cid_info: |
||||
object = (FT_Byte*)cid; |
||||
break; |
||||
|
||||
case t1_field_font_info: |
||||
object = (FT_Byte*)&cid->font_info; |
||||
break; |
||||
|
||||
default: |
||||
{ |
||||
CID_FontDict* dict; |
||||
|
||||
if ( parser->num_dict < 0 ) |
||||
{ |
||||
FT_ERROR(( "CID.Load_Keyword: invalid use of '%s' !!\n", keyword->ident )); |
||||
error = T1_Err_Syntax_Error; |
||||
goto Exit; |
||||
} |
||||
|
||||
dict = cid->font_dicts + parser->num_dict; |
||||
switch (keyword->location) |
||||
{ |
||||
case t1_field_private: |
||||
object = (FT_Byte*)&dict->private_dict; |
||||
break; |
||||
|
||||
default: |
||||
object = (FT_Byte*)dict; |
||||
} |
||||
} |
||||
} |
||||
|
||||
/* now, load the keyword data in the object's field(s) */ |
||||
if ( keyword->type == t1_field_integer_array || |
||||
keyword->type == t1_field_fixed_array ) |
||||
error = CID_Load_Field_Table( parser, keyword, object ); |
||||
else |
||||
error = CID_Load_Field( parser, keyword, object ); |
||||
|
||||
Exit: |
||||
return error; |
||||
}
|
||||
|
||||
|
||||
static |
||||
FT_Error parse_font_bbox( CID_Face face, CID_Parser* parser ) |
||||
{ |
||||
FT_Short temp[4]; |
||||
T1_BBox* bbox = &face->cid.font_bbox; |
||||
|
||||
(void)CID_ToCoordArray( parser, 4, temp ); |
||||
bbox->xMin = temp[0]; |
||||
bbox->yMin = temp[1]; |
||||
bbox->xMax = temp[2]; |
||||
bbox->yMax = temp[3]; |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
static |
||||
FT_Error parse_font_matrix( CID_Face face, CID_Parser* parser ) |
||||
{ |
||||
FT_Matrix* matrix; |
||||
CID_FontDict* dict; |
||||
T1_Fixed temp[4]; |
||||
|
||||
if (parser->num_dict >= 0) |
||||
{ |
||||
dict = face->cid.font_dicts + parser->num_dict; |
||||
matrix = &dict->font_matrix; |
||||
|
||||
(void)CID_ToFixedArray( parser, 4, temp, 3 ); |
||||
matrix->xx = temp[0]; |
||||
matrix->yx = temp[1]; |
||||
matrix->xy = temp[2]; |
||||
matrix->yy = temp[3]; |
||||
} |
||||
return 0; |
||||
} |
||||
|
||||
static |
||||
FT_Error parse_fd_array( CID_Face face, CID_Parser* parser ) |
||||
{ |
||||
CID_Info* cid = &face->cid; |
||||
FT_Memory memory = face->root.memory; |
||||
FT_Error error; |
||||
FT_Long num_dicts; |
||||
|
||||
num_dicts = CID_ToInt(parser); |
||||
if ( !cid->font_dicts ) |
||||
{ |
||||
FT_Int n; |
||||
|
||||
if ( ALLOC_ARRAY( cid->font_dicts, num_dicts, CID_FontDict ) ) |
||||
goto Exit; |
||||
|
||||
cid->num_dicts = (FT_UInt)num_dicts; |
||||
|
||||
/* don't forget to set a few defauts !! */ |
||||
for ( n = 0; n < cid->num_dicts; n++ ) |
||||
{ |
||||
CID_FontDict* dict = cid->font_dicts + n; |
||||
|
||||
/* default value for lenIV !! */ |
||||
dict->private_dict.lenIV = 4; |
||||
} |
||||
} |
||||
|
||||
Exit: |
||||
return error; |
||||
} |
||||
|
||||
|
||||
|
||||
static |
||||
const T1_Field_Rec t1_field_records[] =
|
||||
{ |
||||
#include <cidtokens.h> |
||||
{ 0, 0, 0, 0, 0, 0 } |
||||
}; |
||||
|
||||
|
||||
static |
||||
int is_space( char c ) |
||||
{ |
||||
return ( c == ' ' || c == '\t' || c == '\r' || c == '\n' ); |
||||
} |
||||
|
||||
static |
||||
int is_alpha( char c ) |
||||
{ |
||||
return ( (c >= 'A' && c <= 'Z') || |
||||
(c >= 'a' && c <= 'z') || |
||||
(c >= '0' && c <= '9') || |
||||
(c == '.') || |
||||
(c == '_') ); |
||||
} |
||||
|
||||
static |
||||
void skip_whitespace( CID_Parser* parser ) |
||||
{ |
||||
FT_Byte* cur = parser->cursor; |
||||
|
||||
while ( cur < parser->limit && is_space(*cur) ) |
||||
cur++; |
||||
|
||||
parser->cursor = cur; |
||||
} |
||||
|
||||
|
||||
|
||||
static |
||||
FT_Error parse_dict( CID_Face face, |
||||
CID_Loader* loader, |
||||
FT_Byte* base, |
||||
FT_Long size ) |
||||
{ |
||||
CID_Parser* parser = &loader->parser; |
||||
|
||||
parser->cursor = base; |
||||
parser->limit = base + size; |
||||
parser->error = 0; |
||||
|
||||
{ |
||||
FT_Byte* cur = base; |
||||
FT_Byte* limit = cur + size; |
||||
|
||||
for ( ;cur < limit; cur++ ) |
||||
{ |
||||
/* look for %ADOBegin... */ |
||||
if ( *cur == '%' && cur + 20 < limit && |
||||
strncmp( (char*)cur, "%ADOBeginFontDict", 17 ) == 0 ) |
||||
{ |
||||
cur += 17; |
||||
|
||||
/* if /FDArray was found, then cid->num_dicts is > 0, and */ |
||||
/* we can start increasing parser->num_dict */ |
||||
if ( face->cid.num_dicts > 0 ) |
||||
parser->num_dict++; |
||||
} |
||||
/* look for immediates */ |
||||
else if (*cur == '/' && cur+2 < limit) |
||||
{ |
||||
FT_Byte* cur2; |
||||
FT_Int len; |
||||
|
||||
cur ++; |
||||
cur2 = cur; |
||||
while (cur2 < limit && is_alpha(*cur2)) cur2++; |
||||
len = cur2-cur; |
||||
|
||||
if (len > 0 && len < 22) |
||||
{ |
||||
/* now, compare the immediate name to the keyword table */ |
||||
const T1_Field_Rec* keyword = t1_field_records; |
||||
|
||||
for (;;) |
||||
{ |
||||
FT_Byte* name; |
||||
|
||||
name = (FT_Byte*)keyword->ident; |
||||
if (!name) break; |
||||
|
||||
if ( cur[0] == name[0] && |
||||
len == (FT_Int)strlen((const char*)name) ) |
||||
{ |
||||
FT_Int n; |
||||
for ( n = 1; n < len; n++ ) |
||||
if (cur[n] != name[n]) |
||||
break; |
||||
|
||||
if (n >= len) |
||||
{ |
||||
/* we found it - run the parsing callback !! */ |
||||
parser->cursor = cur2; |
||||
skip_whitespace( parser ); |
||||
parser->error = cid_load_keyword( face, loader, keyword ); |
||||
if (parser->error) |
||||
return parser->error; |
||||
|
||||
cur = parser->cursor; |
||||
break; |
||||
} |
||||
} |
||||
keyword++; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
return parser->error; |
||||
} |
||||
|
||||
|
||||
|
||||
/* read the subrmap and the subrs of each font dict */ |
||||
static |
||||
FT_Error cid_read_subrs( CID_Face face ) |
||||
{ |
||||
CID_Info* cid = &face->cid; |
||||
FT_Memory memory = face->root.memory; |
||||
FT_Stream stream = face->root.stream; |
||||
FT_Error error; |
||||
FT_UInt n; |
||||
CID_Subrs* subr; |
||||
FT_UInt max_offsets = 0; |
||||
FT_ULong* offsets = 0; |
||||
|
||||
if ( ALLOC_ARRAY( face->subrs, cid->num_dicts, CID_Subrs ) ) |
||||
goto Exit; |
||||
|
||||
subr = face->subrs; |
||||
for ( n = 0; n < cid->num_dicts; n++, subr++ ) |
||||
{ |
||||
CID_FontDict* dict = cid->font_dicts + n; |
||||
FT_UInt count, num_subrs = dict->num_subrs; |
||||
FT_ULong data_len; |
||||
FT_Byte* p; |
||||
|
||||
/* reallocate offsets array if needed */ |
||||
if ( num_subrs+1 > max_offsets ) |
||||
{ |
||||
FT_UInt new_max = (num_subrs+1+3) & -4; |
||||
if ( REALLOC_ARRAY( offsets, max_offsets, new_max, FT_ULong ) ) |
||||
goto Fail; |
||||
|
||||
max_offsets = new_max; |
||||
} |
||||
|
||||
/* read the subrmap's offsets */ |
||||
if ( FILE_Seek( cid->data_offset + dict->subrmap_offset ) || |
||||
ACCESS_Frame( (num_subrs+1) * dict->sd_bytes ) ) |
||||
goto Fail; |
||||
|
||||
p = (FT_Byte*)stream->cursor; |
||||
for ( count = 0; count <= num_subrs; count++ ) |
||||
offsets[count] = cid_get_offset( &p, dict->sd_bytes ); |
||||
|
||||
FORGET_Frame(); |
||||
|
||||
/* now, compute the size of subrs charstrings, allocate and read them */ |
||||
data_len = offsets[num_subrs] - offsets[0]; |
||||
|
||||
if ( ALLOC_ARRAY( subr->code, num_subrs+1, FT_Byte* ) || |
||||
ALLOC( subr->code[0], data_len ) ) |
||||
goto Fail; |
||||
|
||||
if ( FILE_Seek( cid->data_offset + offsets[0] ) || |
||||
FILE_Read( subr->code[0], data_len ) ) |
||||
goto Exit; |
||||
|
||||
/* set up pointers */ |
||||
for ( count = 1; count <= num_subrs; count++ ) |
||||
{ |
||||
FT_UInt len; |
||||
|
||||
len = offsets[count] - offsets[count-1]; |
||||
subr->code[count] = subr->code[count-1] + len; |
||||
} |
||||
|
||||
/* decrypt subroutines */
|
||||
for ( count = 0; count < num_subrs; count++ ) |
||||
{ |
||||
FT_UInt len; |
||||
|
||||
len = offsets[count+1] - offsets[count]; |
||||
cid_decrypt( subr->code[count], len, 4330 ); |
||||
} |
||||
|
||||
subr->num_subrs = num_subrs; |
||||
} |
||||
|
||||
Exit: |
||||
FREE( offsets ); |
||||
return error; |
||||
|
||||
Fail: |
||||
if (face->subrs) |
||||
{ |
||||
for ( n = 0; n < cid->num_dicts; n++ ) |
||||
{ |
||||
if (face->subrs[n].code) |
||||
FREE( face->subrs[n].code[0] ); |
||||
|
||||
FREE( face->subrs[n].code ); |
||||
} |
||||
FREE( face->subrs ); |
||||
} |
||||
goto Exit; |
||||
} |
||||
|
||||
static |
||||
void t1_init_loader( CID_Loader* loader, CID_Face face ) |
||||
{ |
||||
UNUSED(face); |
||||
|
||||
MEM_Set( loader, 0, sizeof(*loader) ); |
||||
} |
||||
|
||||
static |
||||
void t1_done_loader( CID_Loader* loader ) |
||||
{ |
||||
CID_Parser* parser = &loader->parser; |
||||
|
||||
/* finalize parser */ |
||||
CID_Done_Parser( parser ); |
||||
} |
||||
|
||||
LOCAL_FUNC |
||||
FT_Error T1_Open_Face( CID_Face face ) |
||||
{ |
||||
CID_Loader loader; |
||||
CID_Parser* parser; |
||||
FT_Error error; |
||||
|
||||
t1_init_loader( &loader, face ); |
||||
|
||||
parser = &loader.parser; |
||||
error = CID_New_Parser( parser, face->root.stream, face->root.memory ); |
||||
if (error) goto Exit; |
||||
|
||||
error = parse_dict( face, &loader, |
||||
parser->postscript, |
||||
parser->postscript_len ); |
||||
if (error) goto Exit; |
||||
|
||||
face->cid.data_offset = loader.parser.data_offset; |
||||
error = cid_read_subrs( face ); |
||||
|
||||
Exit: |
||||
t1_done_loader( &loader ); |
||||
return error; |
||||
} |
@ -0,0 +1,54 @@ |
||||
/*******************************************************************
|
||||
* |
||||
* t1load.h 2.0 |
||||
* |
||||
* Type1 Loader. |
||||
* |
||||
* 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. |
||||
* |
||||
******************************************************************/ |
||||
|
||||
#ifndef T1LOAD_H |
||||
#define T1LOAD_H |
||||
|
||||
#include <freetype/internal/ftstream.h> |
||||
#include <cidparse.h> |
||||
|
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
|
||||
typedef struct CID_Loader_ |
||||
{ |
||||
CID_Parser parser; /* parser used to read the stream */ |
||||
|
||||
FT_Int num_chars; /* number of characters in encoding */ |
||||
|
||||
} CID_Loader; |
||||
|
||||
LOCAL_DEF |
||||
FT_Long cid_get_offset( FT_Byte** start, FT_Byte offsize ); |
||||
|
||||
LOCAL_DEF |
||||
void cid_decrypt( FT_Byte* buffer, |
||||
FT_Int length, |
||||
FT_UShort seed ); |
||||
|
||||
LOCAL_DEF |
||||
FT_Error T1_Open_Face( CID_Face face ); |
||||
|
||||
#ifdef __cplusplus |
||||
} |
||||
#endif |
||||
|
||||
#endif /* T1LOAD_H */ |
||||
|
||||
|
||||
/* END */ |
@ -0,0 +1,473 @@ |
||||
/*******************************************************************
|
||||
* |
||||
* t1objs.c 1.0 |
||||
* |
||||
* Type1 Objects manager. |
||||
* |
||||
* Copyright 1996-1998 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. |
||||
* |
||||
******************************************************************/ |
||||
|
||||
#include <freetype/internal/ftdebug.h> |
||||
#include <freetype/internal/ftstream.h> |
||||
|
||||
#include <cidgload.h> |
||||
#include <cidload.h> |
||||
#include <freetype/internal/psnames.h> |
||||
#include <cidafm.h> |
||||
|
||||
/* Required by tracing mode */ |
||||
#undef FT_COMPONENT |
||||
#define FT_COMPONENT trace_t1objs |
||||
|
||||
/*******************************************************************
|
||||
* * |
||||
* SIZE FUNCTIONS * |
||||
* * |
||||
* * |
||||
*******************************************************************/ |
||||
|
||||
/*******************************************************************
|
||||
* |
||||
* <Function> T1_Done_Size |
||||
* |
||||
* <Description> |
||||
* The TrueDoc instance object destructor. Used to discard |
||||
* a given instance object.. |
||||
* |
||||
* <Input> |
||||
* instance :: handle to the target instance object |
||||
* |
||||
* <Return> |
||||
* TrueDoc error code. 0 means success |
||||
* |
||||
******************************************************************/ |
||||
|
||||
LOCAL_FUNC |
||||
void T1_Done_Size( T1_Size size ) |
||||
{ |
||||
UNUSED(size); |
||||
} |
||||
|
||||
|
||||
/*******************************************************************
|
||||
* |
||||
* <Function> T1_Init_Size |
||||
* |
||||
* <Description> |
||||
* The instance object constructor |
||||
* |
||||
* <Input> |
||||
* instance : handle to new instance object |
||||
* face : pointer to parent face object |
||||
* |
||||
* <Return> |
||||
* TrueDoc error code. 0 means success. |
||||
* |
||||
******************************************************************/ |
||||
|
||||
LOCAL_DEF |
||||
FT_Error T1_Init_Size( T1_Size size ) |
||||
{ |
||||
size->valid = 0; |
||||
return T1_Err_Ok; |
||||
} |
||||
|
||||
|
||||
/*******************************************************************
|
||||
* |
||||
* <Function> T1_Reset_Size |
||||
* |
||||
* <Description> |
||||
* Resets an instance to a new pointsize/transform. |
||||
* This function is in charge of resetting the blue zones, |
||||
* As well as the stem snap tables for a given size.. |
||||
* |
||||
* <Input> |
||||
* instance the instance object to destroy |
||||
* |
||||
* <Output> |
||||
* Error code. |
||||
* |
||||
******************************************************************/ |
||||
|
||||
LOCAL_FUNC |
||||
FT_Error T1_Reset_Size( T1_Size size ) |
||||
{ |
||||
UNUSED(size); |
||||
return 0; |
||||
} |
||||
|
||||
|
||||
/*******************************************************************
|
||||
* * |
||||
* FACE FUNCTIONS * |
||||
* * |
||||
* * |
||||
*******************************************************************/ |
||||
|
||||
/*******************************************************************
|
||||
* |
||||
* <Function> T1_Done_Face |
||||
* |
||||
* <Description> |
||||
* The face object destructor. |
||||
* |
||||
* <Input> |
||||
* face :: typeless pointer to the face object to destroy |
||||
* |
||||
* <Return> |
||||
* Error code. |
||||
* |
||||
******************************************************************/ |
||||
|
||||
LOCAL_FUNC |
||||
void T1_Done_Face( CID_Face face ) |
||||
{ |
||||
FT_Memory memory; |
||||
|
||||
if (face) |
||||
{ |
||||
CID_Info* cid = &face->cid; |
||||
T1_FontInfo* info = &cid->font_info; |
||||
|
||||
memory = face->root.memory; |
||||
|
||||
/* release FontInfo strings */ |
||||
FREE( info->version ); |
||||
FREE( info->notice ); |
||||
FREE( info->full_name ); |
||||
FREE( info->family_name ); |
||||
FREE( info->weight ); |
||||
|
||||
/* release font dictionaries */ |
||||
FREE( cid->font_dicts ); |
||||
cid->num_dicts = 0; |
||||
|
||||
/* release other strings */ |
||||
FREE( cid->cid_font_name ); |
||||
FREE( cid->registry ); |
||||
FREE( cid->ordering ); |
||||
|
||||
face->root.family_name = 0; |
||||
face->root.style_name = 0; |
||||
} |
||||
} |
||||
|
||||
/*******************************************************************
|
||||
* |
||||
* <Function> T1_Init_Face |
||||
* |
||||
* <Description> |
||||
* The face object constructor. |
||||
* |
||||
* <Input> |
||||
* face :: face record to build |
||||
* Input :: input stream where to load font data |
||||
* |
||||
* <Return> |
||||
* Error code. |
||||
* |
||||
******************************************************************/ |
||||
|
||||
LOCAL_FUNC |
||||
FT_Error T1_Init_Face( FT_Stream stream, |
||||
CID_Face face, |
||||
FT_Int face_index, |
||||
FT_Int num_params, |
||||
FT_Parameter* params ) |
||||
{ |
||||
FT_Error error; |
||||
PSNames_Interface* psnames; |
||||
|
||||
UNUSED(num_params); |
||||
UNUSED(params); |
||||
UNUSED(face_index); |
||||
UNUSED(stream); |
||||
|
||||
face->root.num_faces = 1; |
||||
|
||||
psnames = (PSNames_Interface*)face->psnames; |
||||
if (!psnames) |
||||
{ |
||||
/* look-up the PSNames driver */ |
||||
FT_Driver psnames_driver; |
||||
|
||||
psnames_driver = FT_Get_Driver( face->root.driver->library, "psnames" ); |
||||
if (psnames_driver) |
||||
face->psnames = (PSNames_Interface*) |
||||
(psnames_driver->interface.format_interface); |
||||
} |
||||
|
||||
/* open the tokenizer, this will also check the font format */ |
||||
if ( FILE_Seek(0) ) |
||||
goto Exit; |
||||
|
||||
error = T1_Open_Face( face ); |
||||
if (error) goto Exit; |
||||
|
||||
/* if we just wanted to check the format, leave successfully now */ |
||||
if (face_index < 0) |
||||
goto Exit; |
||||
|
||||
/* check the face index */ |
||||
if ( face_index != 0 ) |
||||
{ |
||||
FT_ERROR(( "T1.Init_Face : invalid face index\n" )); |
||||
error = T1_Err_Invalid_Argument; |
||||
goto Exit; |
||||
} |
||||
|
||||
/* Now, load the font program into the face object */ |
||||
{ |
||||
/* Init the face object fields */ |
||||
/* Now set up root face fields */ |
||||
{ |
||||
FT_Face root = (FT_Face)&face->root; |
||||
|
||||
root->num_glyphs = face->cid.cid_count; |
||||
root->num_charmaps = 0; |
||||
|
||||
root->face_index = face_index; |
||||
root->face_flags = FT_FACE_FLAG_SCALABLE; |
||||
|
||||
root->face_flags |= FT_FACE_FLAG_HORIZONTAL; |
||||
|
||||
if ( face->cid.font_info.is_fixed_pitch ) |
||||
root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; |
||||
|
||||
/* XXX : TO DO - add kerning with .afm support */ |
||||
|
||||
/* get style name - be careful, some broken fonts only */ |
||||
/* have a /FontName dictionary entry .. !! */ |
||||
root->family_name = face->cid.font_info.family_name; |
||||
if (root->family_name) |
||||
{ |
||||
char* full = face->cid.font_info.full_name; |
||||
char* family = root->family_name; |
||||
|
||||
while ( *family && *full == *family ) |
||||
{ |
||||
family++; |
||||
full++; |
||||
} |
||||
|
||||
root->style_name = ( *full == ' ' ? full+1 : "Regular" ); |
||||
} |
||||
else |
||||
{ |
||||
/* do we have a /FontName ?? */ |
||||
if (face->cid.cid_font_name) |
||||
{ |
||||
root->family_name = face->cid.cid_font_name; |
||||
root->style_name = "Regular"; |
||||
} |
||||
} |
||||
|
||||
/* no embedded bitmap support */ |
||||
root->num_fixed_sizes = 0; |
||||
root->available_sizes = 0; |
||||
|
||||
root->bbox = face->cid.font_bbox; |
||||
root->units_per_EM = 1000; |
||||
root->ascender = (FT_Short)face->cid.font_bbox.yMax; |
||||
root->descender = -(FT_Short)face->cid.font_bbox.yMin; |
||||
root->height = ((root->ascender + root->descender)*12)/10; |
||||
|
||||
#if 0 |
||||
/* now compute the maximum advance width */ |
||||
|
||||
root->max_advance_width = face->type1.private_dict.standard_width[0]; |
||||
|
||||
/* compute max advance width for proportional fonts */ |
||||
if (!face->type1.font_info.is_fixed_pitch) |
||||
{ |
||||
FT_Int max_advance; |
||||
|
||||
error = T1_Compute_Max_Advance( face, &max_advance ); |
||||
|
||||
/* in case of error, keep the standard width */ |
||||
if (!error) |
||||
root->max_advance_width = max_advance; |
||||
else |
||||
error = 0; /* clear error */ |
||||
} |
||||
|
||||
root->max_advance_height = root->height; |
||||
#endif |
||||
root->underline_position = face->cid.font_info.underline_position; |
||||
root->underline_thickness = face->cid.font_info.underline_thickness; |
||||
|
||||
root->max_points = 0; |
||||
root->max_contours = 0; |
||||
} |
||||
} |
||||
|
||||
#if 0 |
||||
/* charmap support - synthetize unicode charmap when possible */ |
||||
{ |
||||
FT_Face root = &face->root; |
||||
FT_CharMap charmap = face->charmaprecs; |
||||
|
||||
/* synthesize a Unicode charmap if there is support in the "psnames" */ |
||||
/* module.. */ |
||||
if (face->psnames) |
||||
{ |
||||
PSNames_Interface* psnames = (PSNames_Interface*)face->psnames; |
||||
if (psnames->unicode_value) |
||||
{ |
||||
error = psnames->build_unicodes( root->memory, |
||||
face->type1.num_glyphs, |
||||
(const char**)face->type1.glyph_names, |
||||
&face->unicode_map ); |
||||
if (!error) |
||||
{ |
||||
root->charmap = charmap; |
||||
charmap->face = (FT_Face)face; |
||||
charmap->encoding = ft_encoding_unicode; |
||||
charmap->platform_id = 3; |
||||
charmap->encoding_id = 1; |
||||
charmap++; |
||||
} |
||||
|
||||
/* simply clear the error in case of failure (which really) */ |
||||
/* means that out of memory or no unicode glyph names */ |
||||
error = 0; |
||||
} |
||||
} |
||||
|
||||
/* now, support either the standard, expert, or custom encodings */ |
||||
charmap->face = (FT_Face)face; |
||||
charmap->platform_id = 7; /* a new platform id for Adobe fonts ?? */ |
||||
|
||||
switch (face->type1.encoding_type) |
||||
{ |
||||
case t1_encoding_standard: |
||||
charmap->encoding = ft_encoding_adobe_standard; |
||||
charmap->encoding_id = 0; |
||||
break; |
||||
|
||||
case t1_encoding_expert: |
||||
charmap->encoding = ft_encoding_adobe_expert; |
||||
charmap->encoding_id = 1; |
||||
break; |
||||
|
||||
default: |
||||
charmap->encoding = ft_encoding_adobe_custom; |
||||
charmap->encoding_id = 2; |
||||
break; |
||||
} |
||||
|
||||
root->charmaps = face->charmaps; |
||||
root->num_charmaps = charmap - face->charmaprecs + 1; |
||||
face->charmaps[0] = &face->charmaprecs[0]; |
||||
face->charmaps[1] = &face->charmaprecs[1]; |
||||
} |
||||
#endif |
||||
Exit: |
||||
return error; |
||||
} |
||||
|
||||
|
||||
/*******************************************************************
|
||||
* |
||||
* Function : Glyph_Destroy |
||||
* |
||||
* Description : The glyph object destructor. |
||||
* |
||||
* Input : _glyph typeless pointer to the glyph record to destroy |
||||
* |
||||
* Output : Error code. |
||||
* |
||||
******************************************************************/ |
||||
|
||||
LOCAL_FUNC |
||||
void T1_Done_GlyphSlot( T1_GlyphSlot glyph ) |
||||
{ |
||||
FT_Memory memory = glyph->root.face->memory; |
||||
FT_Library library = glyph->root.face->driver->library; |
||||
|
||||
/* the bitmaps are created on demand */ |
||||
FREE( glyph->root.bitmap.buffer ); |
||||
FT_Outline_Done( library, &glyph->root.outline ); |
||||
return; |
||||
} |
||||
|
||||
|
||||
/*******************************************************************
|
||||
* |
||||
* Function : Glyph_Create |
||||
* |
||||
* Description : The glyph object constructor. |
||||
* |
||||
* Input : glyph glyph record to build. |
||||
* face the glyph's parent face. |
||||
* |
||||
* Output : Error code. |
||||
* |
||||
******************************************************************/ |
||||
|
||||
LOCAL_FUNC |
||||
FT_Error T1_Init_GlyphSlot( T1_GlyphSlot glyph ) |
||||
{ |
||||
FT_Library library = glyph->root.face->driver->library; |
||||
|
||||
glyph->max_points = 0; |
||||
glyph->max_contours = 0; |
||||
glyph->root.bitmap.buffer = 0; |
||||
|
||||
return FT_Outline_New( library, 0, 0, &glyph->root.outline ); |
||||
} |
||||
|
||||
|
||||
/*******************************************************************
|
||||
* |
||||
* <Function> T1_Init_Driver |
||||
* |
||||
* <Description> |
||||
* Initialise a given Type 1 driver object |
||||
* |
||||
* <Input> |
||||
* driver :: handle to target driver object |
||||
* |
||||
* <Return> |
||||
* Error code. |
||||
* |
||||
******************************************************************/ |
||||
|
||||
LOCAL_FUNC |
||||
FT_Error T1_Init_Driver( T1_Driver driver ) |
||||
{ |
||||
UNUSED(driver); |
||||
return T1_Err_Ok; |
||||
} |
||||
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
* |
||||
* <Function> T1_Done_Driver |
||||
* |
||||
* <Description> |
||||
* finalise a given Type 1 driver |
||||
* |
||||
* <Input> |
||||
* driver :: handle to target Type 1 driver |
||||
* |
||||
******************************************************************/ |
||||
|
||||
LOCAL_DEF |
||||
void T1_Done_Driver( T1_Driver driver ) |
||||
{ |
||||
UNUSED(driver); |
||||
} |
||||
|
||||
|
||||
/* END */ |
@ -0,0 +1,304 @@ |
||||
/*******************************************************************
|
||||
* |
||||
* t1objs.h 1.0 |
||||
* |
||||
* Type1 objects definition. |
||||
* |
||||
* Copyright 1996-1999 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. |
||||
* |
||||
******************************************************************/ |
||||
|
||||
#ifndef T1OBJS_H |
||||
#define T1OBJS_H |
||||
|
||||
#include <freetype/internal/ftobjs.h> |
||||
#include <freetype/config/ftconfig.h> |
||||
#include <t1errors.h> |
||||
#include <freetype/internal/t1types.h> |
||||
|
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
|
||||
/* The following structures must be defined by the hinter */ |
||||
typedef struct T1_Size_Hints_ T1_Size_Hints; |
||||
typedef struct T1_Glyph_Hints_ T1_Glyph_Hints; |
||||
|
||||
/***********************************************************************/ |
||||
/* */ |
||||
/* <Type> T1_Driver */ |
||||
/* */ |
||||
/* <Description> */ |
||||
/* A handle to a Type 1 driver object. */ |
||||
/* */ |
||||
typedef struct T1_DriverRec_ *T1_Driver; |
||||
|
||||
|
||||
/***********************************************************************/ |
||||
/* */ |
||||
/* <Type> T1_Size */ |
||||
/* */ |
||||
/* <Description> */ |
||||
/* A handle to a Type 1 size object. */ |
||||
/* */ |
||||
typedef struct T1_SizeRec_* T1_Size; |
||||
|
||||
|
||||
/***********************************************************************/ |
||||
/* */ |
||||
/* <Type> T1_GlyphSlot */ |
||||
/* */ |
||||
/* <Description> */ |
||||
/* A handle to a Type 1 glyph slot object. */ |
||||
/* */ |
||||
typedef struct T1_GlyphSlotRec_* T1_GlyphSlot; |
||||
|
||||
|
||||
/***********************************************************************/ |
||||
/* */ |
||||
/* <Type> T1_CharMap */ |
||||
/* */ |
||||
/* <Description> */ |
||||
/* A handle to a Type 1 character mapping object. */ |
||||
/* */ |
||||
/* <Note> */ |
||||
/* The Type 1 format doesn't use a charmap but an encoding table. */ |
||||
/* The driver is responsible for making up charmap objects */ |
||||
/* corresponding to these tables.. */ |
||||
/* */ |
||||
typedef struct T1_CharMapRec_* T1_CharMap; |
||||
|
||||
|
||||
|
||||
/**************************************************************************/ |
||||
/* */ |
||||
/* NOW BEGINS THE TYPE1 SPECIFIC STUFF .............................. */ |
||||
/* */ |
||||
/**************************************************************************/ |
||||
|
||||
|
||||
/***************************************************/ |
||||
/* */ |
||||
/* T1_Size : */ |
||||
/* */ |
||||
/* Type 1 size record.. */ |
||||
/* */ |
||||
|
||||
typedef struct T1_SizeRec_ |
||||
{ |
||||
FT_SizeRec root; |
||||
T1_Bool valid; |
||||
T1_Size_Hints* hints; /* defined in the hinter. This allows */ |
||||
/* us to experiment with different */ |
||||
/* hinting schemes without having to */ |
||||
/* change 't1objs' each time.. */ |
||||
} T1_SizeRec; |
||||
|
||||
|
||||
|
||||
/***************************************************/ |
||||
/* */ |
||||
/* T1_GlyphSlot : */ |
||||
/* */ |
||||
/* TrueDoc glyph record.. */ |
||||
/* */ |
||||
|
||||
typedef struct T1_GlyphSlotRec_ |
||||
{ |
||||
FT_GlyphSlotRec root; |
||||
|
||||
T1_Bool hint; |
||||
T1_Bool scaled; |
||||
|
||||
FT_Int max_points; |
||||
FT_Int max_contours; |
||||
|
||||
FT_Fixed x_scale; |
||||
FT_Fixed y_scale; |
||||
|
||||
T1_Glyph_Hints* hints; /* defined in the hinter */ |
||||
|
||||
} T1_GlyphSlotRec; |
||||
|
||||
|
||||
/*******************************************************************
|
||||
* |
||||
* <Function> T1_Init_Face |
||||
* |
||||
* <Description> |
||||
* Initialise a given Type 1 face object |
||||
* |
||||
* <Input> |
||||
* face_index :: index of font face in resource |
||||
* resource :: source font resource |
||||
* face :: face record to build |
||||
* |
||||
* <Return> |
||||
* Error code. |
||||
* |
||||
******************************************************************/ |
||||
|
||||
LOCAL_DEF |
||||
FT_Error T1_Init_Face( FT_Stream stream, |
||||
CID_Face face, |
||||
FT_Int face_index, |
||||
FT_Int num_params, |
||||
FT_Parameter* params ); |
||||
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
* |
||||
* <Function> T1_Done_Face |
||||
* |
||||
* <Description> |
||||
* Finalise a given face object |
||||
* |
||||
* <Input> |
||||
* face :: handle to the face object to destroy |
||||
* |
||||
******************************************************************/ |
||||
|
||||
LOCAL_DEF |
||||
void T1_Done_Face( CID_Face face ); |
||||
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
* |
||||
* <Function> T1_Init_Size |
||||
* |
||||
* <Description> |
||||
* Initialise a new Type 1 size object |
||||
* |
||||
* <Input> |
||||
* size :: handle to size object |
||||
* |
||||
* <Return> |
||||
* Type 1 error code. 0 means success. |
||||
* |
||||
******************************************************************/ |
||||
|
||||
LOCAL_DEF |
||||
FT_Error T1_Init_Size( T1_Size size ); |
||||
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
* |
||||
* <Function> T1_Done_Size |
||||
* |
||||
* <Description> |
||||
* The Type 1 size object finaliser. |
||||
* |
||||
* <Input> |
||||
* size :: handle to the target size object. |
||||
* |
||||
******************************************************************/ |
||||
|
||||
LOCAL_DEF |
||||
void T1_Done_Size( T1_Size size ); |
||||
|
||||
|
||||
/*******************************************************************
|
||||
* |
||||
* <Function> T1_Reset_Size |
||||
* |
||||
* <Description> |
||||
* Reset a Type 1 size when resolutions and character dimensions |
||||
* have been changed.. |
||||
* |
||||
* <Input> |
||||
* size :: handle to the target size object. |
||||
* |
||||
******************************************************************/ |
||||
|
||||
LOCAL_DEF |
||||
FT_Error T1_Reset_Size( T1_Size size ); |
||||
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
* |
||||
* <Function> T1_Init_GlyphSlot |
||||
* |
||||
* <Description> The TrueType glyph slot initialiser |
||||
* |
||||
* <Input> glyph :: glyph record to build. |
||||
* |
||||
* <Output> Error code. |
||||
* |
||||
******************************************************************/ |
||||
|
||||
LOCAL_DEF |
||||
FT_Error T1_Init_GlyphSlot( T1_GlyphSlot slot ); |
||||
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
* |
||||
* <Function> T1_Done_GlyphSlot |
||||
* |
||||
* <Description> The Type 1 glyph slot finaliser |
||||
* |
||||
* <Input> glyph :: handle to glyph slot object |
||||
* |
||||
* <Output> Error code. |
||||
* |
||||
******************************************************************/ |
||||
|
||||
LOCAL_DEF |
||||
void T1_Done_GlyphSlot( T1_GlyphSlot slot ); |
||||
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
* |
||||
* <Function> T1_Init_Driver |
||||
* |
||||
* <Description> |
||||
* Initialise a given Type 1 driver object |
||||
* |
||||
* <Input> |
||||
* driver :: handle to target driver object |
||||
* |
||||
* <Return> |
||||
* Error code. |
||||
* |
||||
******************************************************************/ |
||||
|
||||
LOCAL_DEF |
||||
FT_Error T1_Init_Driver( T1_Driver driver ); |
||||
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
* |
||||
* <Function> T1_Done_Driver |
||||
* |
||||
* <Description> |
||||
* finalise a given Type 1 driver |
||||
* |
||||
* <Input> |
||||
* driver :: handle to target Type 1 driver |
||||
* |
||||
******************************************************************/ |
||||
|
||||
LOCAL_DEF |
||||
void T1_Done_Driver( T1_Driver driver ); |
||||
|
||||
#ifdef __cplusplus |
||||
} |
||||
#endif |
||||
|
||||
#endif /* T1OBJS_H */ |
||||
|
||||
|
||||
/* END */ |
@ -0,0 +1,936 @@ |
||||
/*******************************************************************
|
||||
* |
||||
* cidparse.c 2.0 |
||||
* |
||||
* CID-keyed Type1 parser. |
||||
* |
||||
* Copyright 1996-1998 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. |
||||
* |
||||
* The Type 1 parser is in charge of the following: |
||||
* |
||||
* - provide an implementation of a growing sequence of |
||||
* objects called a T1_Table (used to build various tables |
||||
* needed by the loader). |
||||
* |
||||
* - opening .pfb and .pfa files to extract their top-level |
||||
* and private dictionaries |
||||
* |
||||
* - read numbers, arrays & strings from any dictionary |
||||
* |
||||
* See "t1load.c" to see how data is loaded from the font file |
||||
* |
||||
******************************************************************/ |
||||
|
||||
#include <freetype/internal/ftdebug.h> |
||||
#include <freetype/internal/ftcalc.h> |
||||
#include <freetype/internal/ftobjs.h> |
||||
#include <freetype/internal/ftstream.h> |
||||
#include <t1errors.h> |
||||
#include <cidparse.h> |
||||
|
||||
#undef FT_COMPONENT |
||||
#define FT_COMPONENT trace_t1load |
||||
|
||||
#if 0 |
||||
/*************************************************************************/ |
||||
/*************************************************************************/ |
||||
/*************************************************************************/ |
||||
/***** *****/ |
||||
/***** IMPLEMENTATION OF T1_TABLE OBJECT *****/ |
||||
/***** *****/ |
||||
/***** *****/ |
||||
/*************************************************************************/ |
||||
/*************************************************************************/ |
||||
/*************************************************************************/ |
||||
|
||||
|
||||
/*************************************************************************/ |
||||
/* */ |
||||
/* <Function> T1_New_Table */ |
||||
/* */ |
||||
/* <Description> */ |
||||
/* Initialise a T1_Table. */ |
||||
/* */ |
||||
/* <Input> */ |
||||
/* table :: address of target table */ |
||||
/* count :: table size = maximum number of elements */ |
||||
/* memory :: memory object to use for all subsequent reallocations */ |
||||
/* */ |
||||
/* <Return> */ |
||||
/* Error code. 0 means success */ |
||||
/* */ |
||||
|
||||
LOCAL_FUNC |
||||
FT_Error T1_New_Table( T1_Table* table, |
||||
FT_Int count, |
||||
FT_Memory memory ) |
||||
{ |
||||
FT_Error error; |
||||
|
||||
table->memory = memory; |
||||
if ( ALLOC_ARRAY( table->elements, count, FT_Byte* ) || |
||||
ALLOC_ARRAY( table->lengths, count, FT_Byte* ) ) |
||||
goto Exit; |
||||
|
||||
table->max_elems = count; |
||||
table->init = 0xdeadbeef; |
||||
table->num_elems = 0; |
||||
table->block = 0; |
||||
table->capacity = 0; |
||||
table->cursor = 0; |
||||
|
||||
Exit: |
||||
if (error) FREE(table->elements); |
||||
|
||||
return error; |
||||
} |
||||
|
||||
|
||||
|
||||
/*************************************************************************/ |
||||
/* */ |
||||
/* <Function> T1_Add_Table */ |
||||
/* */ |
||||
/* <Description> */ |
||||
/* Adds an object to a T1_Table, possibly growing its memory block */ |
||||
/* */ |
||||
/* <Input> */ |
||||
/* table :: target table */ |
||||
/* index :: index of object in table */ |
||||
/* object :: address of object to copy in memory */ |
||||
/* length :: length in bytes of source object */ |
||||
/* */ |
||||
/* <Return> */ |
||||
/* Error code. 0 means success. An error is returned when a */ |
||||
/* realloc failed.. */ |
||||
/* */ |
||||
|
||||
|
||||
static void shift_elements( T1_Table* table, FT_Byte* old_base ) |
||||
{ |
||||
FT_Long delta = table->block - old_base; |
||||
FT_Byte** offset = table->elements; |
||||
FT_Byte** limit = offset + table->max_elems; |
||||
|
||||
if (delta) |
||||
for ( ; offset < limit; offset++ ) |
||||
{ |
||||
if (offset[0]) |
||||
offset[0] += delta; |
||||
} |
||||
} |
||||
|
||||
static |
||||
FT_Error reallocate_t1_table( T1_Table* table, |
||||
FT_Int new_size ) |
||||
{ |
||||
FT_Memory memory = table->memory; |
||||
FT_Byte* old_base = table->block; |
||||
FT_Error error; |
||||
|
||||
/* realloc the base block */ |
||||
if ( REALLOC( table->block, table->capacity, new_size ) ) |
||||
return error; |
||||
|
||||
table->capacity = new_size; |
||||
|
||||
/* shift all offsets when needed */ |
||||
if (old_base) |
||||
shift_elements( table, old_base ); |
||||
|
||||
return T1_Err_Ok; |
||||
} |
||||
|
||||
|
||||
|
||||
LOCAL_FUNC |
||||
FT_Error T1_Add_Table( T1_Table* table, |
||||
FT_Int index, |
||||
void* object, |
||||
FT_Int length ) |
||||
{ |
||||
if (index < 0 || index > table->max_elems) |
||||
{ |
||||
FT_ERROR(( "T1.Add_Table: invalid index\n" )); |
||||
return T1_Err_Syntax_Error; |
||||
} |
||||
|
||||
/* grow the base block if needed */ |
||||
if ( table->cursor + length > table->capacity ) |
||||
{ |
||||
FT_Error error; |
||||
FT_Int new_size = table->capacity; |
||||
|
||||
while ( new_size < table->cursor+length ) |
||||
new_size += 1024; |
||||
|
||||
error = reallocate_t1_table( table, new_size ); |
||||
if (error) return error; |
||||
} |
||||
|
||||
/* add the object to the base block and adjust offset */ |
||||
table->elements[ index ] = table->block + table->cursor; |
||||
table->lengths [ index ] = length; |
||||
MEM_Copy( table->block + table->cursor, object, length ); |
||||
|
||||
table->cursor += length; |
||||
return T1_Err_Ok; |
||||
} |
||||
|
||||
|
||||
/*************************************************************************/ |
||||
/* */ |
||||
/* <Function> T1_Done_Table */ |
||||
/* */ |
||||
/* <Description> */ |
||||
/* Finalise a T1_Table. (realloc it to its current cursor). */ |
||||
/* */ |
||||
/* <Input> */ |
||||
/* table :: target table */ |
||||
/* */ |
||||
/* <Note> */ |
||||
/* This function does NOT release the heap's memory block. It is up */ |
||||
/* to the caller to clean it, or reference it in its own structures. */ |
||||
/* */ |
||||
#if 0 |
||||
LOCAL_FUNC |
||||
void T1_Done_Table( T1_Table* table ) |
||||
{ |
||||
FT_Memory memory = table->memory; |
||||
FT_Error error; |
||||
FT_Byte* old_base; |
||||
|
||||
/* should never fail, as rec.cursor <= rec.size */ |
||||
old_base = table->block; |
||||
if (!old_base) |
||||
return; |
||||
|
||||
(void)REALLOC( table->block, table->capacity, table->cursor ); |
||||
table->capacity = table->cursor; |
||||
|
||||
if (old_base != table->block) |
||||
shift_elements( table, old_base ); |
||||
} |
||||
#endif |
||||
|
||||
LOCAL_FUNC |
||||
void T1_Release_Table( T1_Table* table ) |
||||
{ |
||||
FT_Memory memory = table->memory; |
||||
|
||||
if (table->init == (FT_Long)0xdeadbeef) |
||||
{ |
||||
FREE( table->block ); |
||||
FREE( table->elements ); |
||||
FREE( table->lengths ); |
||||
table->init = 0; |
||||
} |
||||
} |
||||
|
||||
#endif |
||||
|
||||
/*************************************************************************/ |
||||
/*************************************************************************/ |
||||
/*************************************************************************/ |
||||
/***** *****/ |
||||
/***** INPUT STREAM PARSER *****/ |
||||
/***** *****/ |
||||
/***** *****/ |
||||
/*************************************************************************/ |
||||
/*************************************************************************/ |
||||
/*************************************************************************/ |
||||
|
||||
#define IS_T1_WHITESPACE(c) ( (c) == ' ' || (c) == '\t' ) |
||||
#define IS_T1_LINESPACE(c) ( (c) == '\r' || (c) == '\n' ) |
||||
|
||||
#define IS_T1_SPACE(c) ( IS_T1_WHITESPACE(c) || IS_T1_LINESPACE(c) ) |
||||
|
||||
LOCAL_FUNC |
||||
void CID_Skip_Spaces( CID_Parser* parser ) |
||||
{ |
||||
FT_Byte* cur = parser->cursor; |
||||
FT_Byte* limit = parser->limit; |
||||
|
||||
while (cur < limit) |
||||
{ |
||||
FT_Byte c = *cur; |
||||
if (!IS_T1_SPACE(c)) |
||||
break; |
||||
cur++; |
||||
} |
||||
parser->cursor = cur; |
||||
} |
||||
|
||||
LOCAL_FUNC |
||||
void CID_ToToken( CID_Parser* parser, |
||||
T1_Token_Rec* token ) |
||||
{ |
||||
FT_Byte* cur; |
||||
FT_Byte* limit; |
||||
FT_Byte starter, ender; |
||||
FT_Int embed; |
||||
|
||||
token->type = t1_token_none; |
||||
token->start = 0; |
||||
token->limit = 0; |
||||
|
||||
/* first of all, skip space */ |
||||
CID_Skip_Spaces(parser); |
||||
|
||||
cur = parser->cursor; |
||||
limit = parser->limit; |
||||
|
||||
if ( cur < limit ) |
||||
{ |
||||
switch (*cur) |
||||
{ |
||||
/************* check for strings ***********************/ |
||||
case '(': |
||||
token->type = t1_token_string; |
||||
ender = ')'; |
||||
goto Lookup_Ender; |
||||
|
||||
/************* check for programs/array ****************/ |
||||
case '{': |
||||
token->type = t1_token_array; |
||||
ender = '}'; |
||||
goto Lookup_Ender; |
||||
|
||||
/************* check for table/array ******************/ |
||||
case '[': |
||||
token->type = t1_token_array; |
||||
ender = ']'; |
||||
|
||||
Lookup_Ender: |
||||
embed = 1; |
||||
starter = *cur++; |
||||
token->start = cur; |
||||
while (cur < limit) |
||||
{ |
||||
if (*cur == starter) |
||||
embed++; |
||||
else if (*cur == ender) |
||||
{ |
||||
embed--; |
||||
if (embed <= 0) |
||||
{ |
||||
token->limit = cur++; |
||||
break; |
||||
} |
||||
} |
||||
cur++; |
||||
} |
||||
break; |
||||
|
||||
/* **************** otherwise, it's any token **********/ |
||||
default: |
||||
token->start = cur++; |
||||
token->type = t1_token_any; |
||||
while (cur < limit && !IS_T1_SPACE(*cur)) |
||||
cur++; |
||||
|
||||
token->limit = cur; |
||||
} |
||||
|
||||
if (!token->limit) |
||||
{ |
||||
token->start = 0; |
||||
token->type = t1_token_none; |
||||
} |
||||
|
||||
parser->cursor = cur; |
||||
} |
||||
} |
||||
|
||||
|
||||
LOCAL_FUNC |
||||
void CID_ToTokenArray( CID_Parser* parser, |
||||
T1_Token_Rec* tokens, |
||||
FT_UInt max_tokens, |
||||
FT_Int *pnum_tokens ) |
||||
{ |
||||
T1_Token_Rec master; |
||||
|
||||
*pnum_tokens = -1; |
||||
|
||||
CID_ToToken( parser, &master ); |
||||
if (master.type == t1_token_array) |
||||
{ |
||||
FT_Byte* old_cursor = parser->cursor; |
||||
FT_Byte* old_limit = parser->limit; |
||||
T1_Token_Rec* cur = tokens; |
||||
T1_Token_Rec* limit = cur + max_tokens; |
||||
|
||||
parser->cursor = master.start; |
||||
parser->limit = master.limit; |
||||
|
||||
while (parser->cursor < parser->limit) |
||||
{ |
||||
T1_Token_Rec token; |
||||
|
||||
CID_ToToken( parser, &token ); |
||||
if (!token.type) |
||||
break; |
||||
|
||||
if (cur < limit) |
||||
*cur = token; |
||||
|
||||
cur++; |
||||
} |
||||
|
||||
*pnum_tokens = cur - tokens; |
||||
|
||||
parser->cursor = old_cursor; |
||||
parser->limit = old_limit; |
||||
} |
||||
} |
||||
|
||||
|
||||
static |
||||
FT_Long t1_toint( FT_Byte* *cursor, |
||||
FT_Byte* limit ) |
||||
{ |
||||
FT_Long result = 0; |
||||
FT_Byte* cur = *cursor; |
||||
FT_Byte c, d; |
||||
|
||||
for (; cur < limit; cur++) |
||||
{ |
||||
c = *cur; |
||||
d = (FT_Byte)(c - '0'); |
||||
if (d < 10) break; |
||||
|
||||
if ( c=='-' ) |
||||
{ |
||||
cur++; |
||||
break; |
||||
} |
||||
} |
||||
|
||||
if (cur < limit) |
||||
{ |
||||
do |
||||
{ |
||||
d = (FT_Byte)(cur[0] - '0'); |
||||
if (d >= 10) |
||||
break; |
||||
|
||||
result = result*10 + d; |
||||
cur++; |
||||
|
||||
} while (cur < limit); |
||||
|
||||
if (c == '-') |
||||
result = -result; |
||||
} |
||||
|
||||
*cursor = cur; |
||||
return result; |
||||
} |
||||
|
||||
|
||||
static |
||||
FT_Long t1_tofixed( FT_Byte* *cursor, |
||||
FT_Byte* limit, |
||||
FT_Long power_ten ) |
||||
{ |
||||
FT_Byte* cur = *cursor; |
||||
FT_Long num, divider, result; |
||||
FT_Int sign = 0; |
||||
FT_Byte d; |
||||
|
||||
if (cur >= limit) return 0; |
||||
|
||||
/* first of all, read the integer part */ |
||||
result = t1_toint( &cur, limit ) << 16; |
||||
num = 0; |
||||
divider = 1; |
||||
|
||||
if (result < 0) |
||||
{ |
||||
sign = 1; |
||||
result = -result; |
||||
} |
||||
if (cur >= limit) goto Exit; |
||||
|
||||
/* read decimal part, if any */ |
||||
if (*cur == '.' && cur+1 < limit) |
||||
{ |
||||
cur++; |
||||
|
||||
for (;;) |
||||
{ |
||||
d = (FT_Byte)(*cur - '0'); |
||||
if (d >= 10) break; |
||||
|
||||
if (divider < 10000000L) |
||||
{ |
||||
num = num*10 + d; |
||||
divider *= 10; |
||||
} |
||||
cur++; |
||||
if (cur >= limit) break; |
||||
} |
||||
} |
||||
|
||||
/* read exponent, if any */ |
||||
if ( cur+1 < limit && (*cur == 'e' || *cur == 'E')) |
||||
{ |
||||
cur++; |
||||
power_ten += t1_toint( &cur, limit ); |
||||
} |
||||
|
||||
Exit: |
||||
/* raise to power of ten if needed */ |
||||
while (power_ten > 0) |
||||
{ |
||||
result = result*10; |
||||
num = num*10; |
||||
power_ten--; |
||||
} |
||||
|
||||
while (power_ten < 0) |
||||
{ |
||||
result = result/10; |
||||
divider = divider*10; |
||||
power_ten++; |
||||
} |
||||
|
||||
if (num) |
||||
result += FT_DivFix( num, divider ); |
||||
|
||||
if (sign) |
||||
result = -result; |
||||
|
||||
*cursor = cur; |
||||
return result; |
||||
} |
||||
|
||||
|
||||
static |
||||
int t1_tobool( FT_Byte* *cursor, FT_Byte* limit ) |
||||
{ |
||||
FT_Byte* cur = *cursor; |
||||
T1_Bool result = 0; |
||||
|
||||
/* return 1 if we find a "true", 0 otherwise */ |
||||
if ( cur+3 < limit && |
||||
cur[0] == 't' && |
||||
cur[1] == 'r' && |
||||
cur[2] == 'u' && |
||||
cur[3] == 'e' ) |
||||
{ |
||||
result = 1; |
||||
cur += 5; |
||||
} |
||||
else if ( cur+4 < limit && |
||||
cur[0] == 'f' && |
||||
cur[1] == 'a' && |
||||
cur[2] == 'l' && |
||||
cur[3] == 's' && |
||||
cur[4] == 'e' ) |
||||
{ |
||||
result = 0; |
||||
cur += 6; |
||||
} |
||||
*cursor = cur; |
||||
return result; |
||||
} |
||||
|
||||
|
||||
static |
||||
FT_Int t1_tocoordarray( FT_Byte* *cursor, |
||||
FT_Byte* limit, |
||||
FT_Int max_coords, |
||||
FT_Short* coords ) |
||||
{ |
||||
FT_Byte* cur = *cursor; |
||||
FT_Int count = 0; |
||||
FT_Byte c, ender; |
||||
|
||||
if (cur >= limit) goto Exit; |
||||
|
||||
/* check for the beginning of an array. If not, only one number will be read */ |
||||
c = *cur; |
||||
ender = 0; |
||||
|
||||
if (c == '[') |
||||
ender = ']'; |
||||
|
||||
if (c == '{') |
||||
ender = '}'; |
||||
|
||||
if (ender) |
||||
cur++; |
||||
|
||||
/* now, read the coordinates */ |
||||
for ( ; cur < limit; ) |
||||
{ |
||||
/* skip whitespace in front of data */ |
||||
for (;;) |
||||
{ |
||||
c = *cur; |
||||
if ( c != ' ' && c != '\t' ) break; |
||||
|
||||
cur++; |
||||
if (cur >= limit) goto Exit; |
||||
} |
||||
|
||||
if (count >= max_coords || c == ender) |
||||
break; |
||||
|
||||
coords[count] = (T1_Short)(t1_tofixed(&cur,limit,0) >> 16); |
||||
count++; |
||||
|
||||
if (!ender) |
||||
break; |
||||
} |
||||
|
||||
Exit: |
||||
*cursor = cur; |
||||
return count; |
||||
} |
||||
|
||||
|
||||
|
||||
static |
||||
FT_Int t1_tofixedarray( FT_Byte* *cursor, |
||||
FT_Byte* limit, |
||||
FT_Int max_values, |
||||
FT_Fixed* values, |
||||
FT_Int power_ten ) |
||||
{ |
||||
FT_Byte* cur = *cursor; |
||||
FT_Int count = 0; |
||||
FT_Byte c, ender; |
||||
|
||||
if (cur >= limit) goto Exit; |
||||
|
||||
/* check for the beginning of an array. If not, only one number will be read */ |
||||
c = *cur; |
||||
ender = 0; |
||||
|
||||
if (c == '[') |
||||
ender = ']'; |
||||
|
||||
if (c == '{') |
||||
ender = '}'; |
||||
|
||||
if (ender) |
||||
cur++; |
||||
|
||||
/* now, read the values */ |
||||
for ( ; cur < limit; ) |
||||
{ |
||||
/* skip whitespace in front of data */ |
||||
for (;;) |
||||
{ |
||||
c = *cur; |
||||
if ( c != ' ' && c != '\t' ) break; |
||||
|
||||
cur++; |
||||
if (cur >= limit) goto Exit; |
||||
} |
||||
|
||||
if (count >= max_values || c == ender) |
||||
break; |
||||
|
||||
values[count] = t1_tofixed(&cur,limit,power_ten); |
||||
count++; |
||||
|
||||
if (!ender) |
||||
break; |
||||
} |
||||
|
||||
Exit: |
||||
*cursor = cur; |
||||
return count; |
||||
} |
||||
|
||||
|
||||
|
||||
/* Loads a simple field (i.e. non-table) into the current list of objects */ |
||||
LOCAL_FUNC |
||||
FT_Error CID_Load_Field( CID_Parser* parser, |
||||
const T1_Field_Rec* field, |
||||
void* object ) |
||||
{ |
||||
T1_Token_Rec token; |
||||
FT_Byte* cur; |
||||
FT_Byte* limit; |
||||
FT_UInt count; |
||||
FT_UInt index; |
||||
FT_Error error; |
||||
|
||||
CID_ToToken( parser, &token ); |
||||
if (!token.type) |
||||
goto Fail; |
||||
|
||||
count = 1; |
||||
index = 0; |
||||
cur = token.start; |
||||
limit = token.limit; |
||||
|
||||
{ |
||||
FT_Byte* q = (FT_Byte*)object + field->offset; |
||||
FT_Long val; |
||||
T1_String* string; |
||||
|
||||
switch (field->type) |
||||
{ |
||||
case t1_field_bool: |
||||
{ |
||||
val = t1_tobool( &cur, limit ); |
||||
goto Store_Integer; |
||||
} |
||||
|
||||
case t1_field_fixed: |
||||
{ |
||||
val = t1_tofixed( &cur, limit, 0 ); |
||||
goto Store_Integer; |
||||
} |
||||
|
||||
case t1_field_integer: |
||||
{ |
||||
val = t1_toint( &cur, limit ); |
||||
Store_Integer: |
||||
switch (field->size) |
||||
{ |
||||
case 1: *(FT_Byte*) q = (FT_Byte)val; break; |
||||
case 2: *(FT_UShort*)q = (FT_UShort)val; break; |
||||
default: *(FT_Long*) q = val; |
||||
} |
||||
} |
||||
break; |
||||
|
||||
case t1_field_string: |
||||
{ |
||||
FT_Memory memory = parser->memory; |
||||
FT_UInt len = limit-cur; |
||||
|
||||
if ( ALLOC( string, len+1 ) ) |
||||
goto Exit; |
||||
|
||||
MEM_Copy( string, cur, len ); |
||||
string[len] = 0;
|
||||
|
||||
*(T1_String**)q = string; |
||||
} |
||||
break; |
||||
|
||||
default: |
||||
/* an error occured */ |
||||
goto Fail; |
||||
} |
||||
} |
||||
error = 0; |
||||
|
||||
Exit: |
||||
return error; |
||||
Fail: |
||||
error = T1_Err_Invalid_File_Format; |
||||
goto Exit; |
||||
} |
||||
|
||||
|
||||
#define CID_MAX_TABLE_ELEMENTS 32 |
||||
|
||||
LOCAL_FUNC |
||||
FT_Error CID_Load_Field_Table( CID_Parser* parser, |
||||
const T1_Field_Rec* field, |
||||
void* object ) |
||||
{ |
||||
T1_Token_Rec elements[CID_MAX_TABLE_ELEMENTS]; |
||||
T1_Token_Rec* token; |
||||
FT_Int num_elements; |
||||
FT_Error error = 0; |
||||
FT_Byte* old_cursor; |
||||
FT_Byte* old_limit; |
||||
T1_Field_Rec fieldrec = *(T1_Field_Rec*)field; |
||||
|
||||
fieldrec.type = t1_field_integer; |
||||
if (field->type == t1_field_fixed_array ) |
||||
fieldrec.type = t1_field_fixed;
|
||||
|
||||
CID_ToTokenArray( parser, elements, 32, &num_elements ); |
||||
if (num_elements < 0) |
||||
goto Fail; |
||||
|
||||
if (num_elements > CID_MAX_TABLE_ELEMENTS) |
||||
num_elements = CID_MAX_TABLE_ELEMENTS; |
||||
|
||||
old_cursor = parser->cursor; |
||||
old_limit = parser->limit; |
||||
|
||||
/* we store the elements count */ |
||||
if (field->count_offset) |
||||
*(FT_Byte*)((FT_Byte*)object + field->count_offset) = num_elements; |
||||
|
||||
/* we now load each element, adjusting the field.offset on each one */ |
||||
token = elements; |
||||
for ( ; num_elements > 0; num_elements--, token++ ) |
||||
{ |
||||
parser->cursor = token->start; |
||||
parser->limit = token->limit; |
||||
CID_Load_Field( parser, &fieldrec, object ); |
||||
fieldrec.offset += fieldrec.size; |
||||
} |
||||
|
||||
parser->cursor = old_cursor; |
||||
parser->limit = old_limit; |
||||
|
||||
Exit: |
||||
return error; |
||||
Fail: |
||||
error = T1_Err_Invalid_File_Format; |
||||
goto Exit; |
||||
} |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
LOCAL_FUNC |
||||
FT_Long CID_ToInt ( CID_Parser* parser ) |
||||
{ |
||||
return t1_toint( &parser->cursor, parser->limit ); |
||||
} |
||||
|
||||
|
||||
LOCAL_FUNC |
||||
FT_Int CID_ToCoordArray( CID_Parser* parser, |
||||
FT_Int max_coords, |
||||
FT_Short* coords ) |
||||
{ |
||||
return t1_tocoordarray( &parser->cursor, parser->limit, max_coords, coords ); |
||||
} |
||||
|
||||
|
||||
LOCAL_FUNC |
||||
FT_Int CID_ToFixedArray( CID_Parser* parser, |
||||
FT_Int max_values, |
||||
FT_Fixed* values, |
||||
FT_Int power_ten ) |
||||
{ |
||||
return t1_tofixedarray( &parser->cursor, parser->limit, max_values, values, power_ten ); |
||||
} |
||||
|
||||
|
||||
#if 0 |
||||
/* return the value of an hexadecimal digit */ |
||||
static |
||||
int hexa_value( char c ) |
||||
{ |
||||
unsigned int d; |
||||
|
||||
d = (unsigned int)(c-'0'); |
||||
if ( d <= 9 ) return (int)d; |
||||
|
||||
d = (unsigned int)(c-'a'); |
||||
if ( d <= 5 ) return (int)(d+10); |
||||
|
||||
d = (unsigned int)(c-'A'); |
||||
if ( d <= 5 ) return (int)(d+10); |
||||
|
||||
return -1; |
||||
} |
||||
#endif |
||||
|
||||
|
||||
LOCAL_FUNC |
||||
FT_Error CID_New_Parser( CID_Parser* parser, |
||||
FT_Stream stream, |
||||
FT_Memory memory ) |
||||
{ |
||||
FT_Error error; |
||||
FT_ULong base_offset, offset, ps_len; |
||||
FT_Byte buffer[ 256 + 10 ]; |
||||
FT_Int buff_len; |
||||
|
||||
MEM_Set( parser, 0, sizeof(*parser ) ); |
||||
parser->stream = stream; |
||||
parser->memory = memory; |
||||
|
||||
base_offset = FILE_Pos(); |
||||
|
||||
/* first of all, check the font format in the header */ |
||||
if ( ACCESS_Frame(31) ) |
||||
goto Exit; |
||||
|
||||
if ( strncmp( stream->cursor, "%!PS-Adobe-3.0 Resource-CIDFont", 31 ) ) |
||||
{ |
||||
FT_ERROR(( "Not a valid CID-keyed font\n" )); |
||||
error = FT_Err_Unknown_File_Format; |
||||
} |
||||
|
||||
FORGET_Frame(); |
||||
if (error) goto Exit; |
||||
|
||||
/* now, read the rest of the file, until we find a "StartData" */ |
||||
buff_len = 256; |
||||
for (;;) |
||||
{ |
||||
FT_Byte *p, *limit = buffer + 256; |
||||
|
||||
/* fill input buffer */ |
||||
buff_len -= 256; |
||||
if (buff_len > 0) |
||||
MEM_Move( buffer, limit, buff_len ); |
||||
|
||||
if ( FILE_Read( buffer, 256+10-buff_len ) ) |
||||
goto Exit; |
||||
|
||||
buff_len = 256+10; |
||||
|
||||
/* look for "StartData" */ |
||||
for ( p = buffer; p < limit; p++ ) |
||||
{ |
||||
if ( p[0] == 'S' && strncmp( (char*)p, "StartData", 9 ) == 0 ) |
||||
{ |
||||
/* save offset of binary data after "StartData" */ |
||||
offset = FILE_Pos() - ( limit-p ) + 10; |
||||
goto Found; |
||||
} |
||||
} |
||||
} |
||||
|
||||
Found: |
||||
/* all right, we found the start of the binary data. We will now rewind */ |
||||
/* and extract the frame of corresponding to the Postscript section */ |
||||
ps_len = offset - base_offset; |
||||
if ( FILE_Seek( base_offset ) || |
||||
EXTRACT_Frame( ps_len, parser->postscript ) ) |
||||
goto Exit; |
||||
|
||||
parser->data_offset = offset; |
||||
parser->postscript_len = ps_len; |
||||
parser->cursor = parser->postscript; |
||||
parser->limit = parser->cursor + ps_len; |
||||
parser->num_dict = -1; |
||||
|
||||
Exit: |
||||
return error;
|
||||
} |
||||
|
||||
|
||||
|
||||
LOCAL_FUNC |
||||
void CID_Done_Parser( CID_Parser* parser ) |
||||
{ |
||||
/* always free the private dictionary */ |
||||
if (parser->postscript) |
||||
{ |
||||
FT_Stream stream = parser->stream; |
||||
RELEASE_Frame( parser->postscript ); |
||||
} |
||||
} |
||||
|
@ -0,0 +1,347 @@ |
||||
/*******************************************************************
|
||||
* |
||||
* cidparse.h 2.0 |
||||
* |
||||
* CID-Keyed Type1 parser. |
||||
* |
||||
* Copyright 1996-1998 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. |
||||
* |
||||
* The Type 1 parser is in charge of the following: |
||||
* |
||||
* - provide an implementation of a growing sequence of |
||||
* objects called a T1_Table (used to build various tables |
||||
* needed by the loader). |
||||
* |
||||
* - opening .pfb and .pfa files to extract their top-level |
||||
* and private dictionaries |
||||
* |
||||
* - read numbers, arrays & strings from any dictionary |
||||
* |
||||
* See "t1load.c" to see how data is loaded from the font file |
||||
* |
||||
******************************************************************/ |
||||
|
||||
#ifndef CIDPARSE_H |
||||
#define CIDPARSE_H |
||||
|
||||
#include <freetype/internal/t1types.h> |
||||
|
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
|
||||
|
||||
|
||||
#if 0 |
||||
/*************************************************************************
|
||||
* |
||||
* <Struct> T1_Table |
||||
* |
||||
* <Description> |
||||
* A T1_Table is a simple object used to store an array of objects |
||||
* in a single memory block. |
||||
* |
||||
* <Fields> |
||||
* block :: address in memory of the growheap's block. This |
||||
* can change between two object adds, due to the use |
||||
* of 'realloc'. |
||||
* |
||||
* cursor :: current top of the grow heap within its block |
||||
* |
||||
* capacity :: current size of the heap block. Increments by 1 Kb |
||||
* |
||||
* init :: boolean. set when the table has been initialized |
||||
* (the table user should set this field) |
||||
* |
||||
* max_elems :: maximum number of elements in table |
||||
* num_elems :: current number of elements in table |
||||
* |
||||
* elements :: table of element addresses within the block |
||||
* lengths :: table of element sizes within the block |
||||
* |
||||
* memory :: memory object used for memory operations (alloc/realloc) |
||||
*/ |
||||
|
||||
typedef struct T1_Table_ |
||||
{ |
||||
FT_Byte* block; /* current memory block */ |
||||
FT_Int cursor; /* current cursor in memory block */ |
||||
FT_Int capacity; /* current size of memory block */ |
||||
FT_Long init; |
||||
|
||||
FT_Int max_elems; |
||||
FT_Int num_elems; |
||||
FT_Byte** elements; /* addresses of table elements */ |
||||
FT_Int* lengths; /* lengths of table elements */ |
||||
|
||||
FT_Memory memory; |
||||
|
||||
} T1_Table; |
||||
|
||||
|
||||
LOCAL_DEF |
||||
FT_Error T1_New_Table( T1_Table* table, |
||||
FT_Int count, |
||||
FT_Memory memory ); |
||||
|
||||
|
||||
LOCAL_DEF |
||||
FT_Error T1_Add_Table( T1_Table* table, |
||||
FT_Int index, |
||||
void* object, |
||||
FT_Int length ); |
||||
|
||||
LOCAL_DEF |
||||
void T1_Release_Table( T1_Table* table ); |
||||
#endif |
||||
|
||||
/*************************************************************************
|
||||
* |
||||
* <Struct> CID_Parser |
||||
* |
||||
* <Description> |
||||
* A CID_Parser is an object used to parse a Type 1 fonts very |
||||
* quickly. |
||||
* |
||||
* <Fields> |
||||
* stream :: current input stream |
||||
* memory :: current memory object |
||||
* |
||||
* base_dict :: pointer to top-level dictionary |
||||
* base_len :: length in bytes of top dict |
||||
* |
||||
* private_dict :: pointer to private dictionary |
||||
* private_len :: length in bytes of private dict |
||||
* |
||||
* in_pfb :: boolean. Indicates that we're in a .pfb file |
||||
* in_memory :: boolean. Indicates a memory-based stream |
||||
* single_block :: boolean. Indicates that the private dict |
||||
* is stored in lieu of the base dict |
||||
* |
||||
* cursor :: current parser cursor |
||||
* limit :: current parser limit (first byte after current |
||||
* dictionary). |
||||
* |
||||
* error :: current parsing error |
||||
*/ |
||||
|
||||
typedef struct CID_Parser_ |
||||
{ |
||||
FT_Stream stream; |
||||
FT_Memory memory; |
||||
|
||||
FT_Byte* postscript; |
||||
FT_Int postscript_len; |
||||
|
||||
FT_ULong data_offset; |
||||
|
||||
FT_Byte* cursor; |
||||
FT_Byte* limit; |
||||
FT_Error error; |
||||
|
||||
CID_Info* cid; |
||||
FT_Int num_dict; |
||||
|
||||
} CID_Parser; |
||||
|
||||
|
||||
LOCAL_DEF |
||||
FT_Error CID_New_Parser( CID_Parser* parser, |
||||
FT_Stream stream, |
||||
FT_Memory memory ); |
||||
|
||||
LOCAL_DEF |
||||
void CID_Done_Parser( CID_Parser* parser ); |
||||
|
||||
|
||||
/*************************************************************************
|
||||
* |
||||
* PARSING ROUTINES |
||||
* |
||||
*************************************************************************/ |
||||
|
||||
LOCAL_DEF |
||||
FT_Long CID_ToInt ( CID_Parser* parser ); |
||||
|
||||
LOCAL_DEF |
||||
FT_Int CID_ToCoordArray( CID_Parser* parser, |
||||
FT_Int max_coords, |
||||
FT_Short* coords ); |
||||
|
||||
LOCAL_DEF |
||||
FT_Int CID_ToFixedArray( CID_Parser* parser, |
||||
FT_Int max_values, |
||||
T1_Fixed* values, |
||||
FT_Int power_ten ); |
||||
|
||||
LOCAL_DEF |
||||
void CID_Skip_Spaces( CID_Parser* parser ); |
||||
|
||||
|
||||
|
||||
/* simple enumeration type used to identify token types */ |
||||
typedef enum T1_Token_Type_ |
||||
{ |
||||
t1_token_none = 0, |
||||
t1_token_any, |
||||
t1_token_string, |
||||
t1_token_array, |
||||
|
||||
/* do not remove */ |
||||
t1_token_max |
||||
|
||||
} T1_Token_Type; |
||||
|
||||
/* a simple structure used to identify tokens */ |
||||
typedef struct T1_Token_Rec_ |
||||
{ |
||||
FT_Byte* start; /* first character of token in input stream */ |
||||
FT_Byte* limit; /* first character after the token */ |
||||
T1_Token_Type type; /* type of token.. */ |
||||
|
||||
} T1_Token_Rec;
|
||||
|
||||
|
||||
LOCAL_DEF |
||||
void CID_ToToken( CID_Parser* parser, |
||||
T1_Token_Rec* token ); |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* enumeration type used to identify object fields */ |
||||
typedef enum T1_Field_Type_ |
||||
{ |
||||
t1_field_none = 0, |
||||
t1_field_bool, |
||||
t1_field_integer, |
||||
t1_field_fixed, |
||||
t1_field_string, |
||||
t1_field_integer_array, |
||||
t1_field_fixed_array, |
||||
t1_field_callback, |
||||
|
||||
/* do not remove */ |
||||
t1_field_max |
||||
|
||||
} T1_Field_Type; |
||||
|
||||
typedef enum T1_Field_Location_ |
||||
{ |
||||
t1_field_cid_info, |
||||
t1_field_font_dict, |
||||
t1_field_font_info, |
||||
t1_field_private, |
||||
|
||||
/* do not remove */ |
||||
t1_field_location_max |
||||
|
||||
} T1_Field_Location; |
||||
|
||||
|
||||
typedef FT_Error (*CID_Field_Parser)( CID_Face face, |
||||
CID_Parser* parser ); |
||||
|
||||
/* structure type used to model object fields */ |
||||
typedef struct T1_Field_Rec_ |
||||
{ |
||||
const char* ident; /* field identifier */ |
||||
T1_Field_Location location; |
||||
T1_Field_Type type; /* type of field */ |
||||
CID_Field_Parser reader; |
||||
T1_UInt offset; /* offset of field in object */ |
||||
FT_UInt size; /* size of field in bytes */ |
||||
FT_UInt array_max; /* maximum number of elements for array */ |
||||
FT_UInt count_offset; /* offset of element count for arrays */ |
||||
|
||||
} T1_Field_Rec; |
||||
|
||||
#define T1_FIELD_REF(s,f) (((s*)0)->f) |
||||
|
||||
#define T1_NEW_SIMPLE_FIELD( _ident, _type, _fname ) \ |
||||
{ _ident, T1CODE, _type, \
|
||||
0, \
|
||||
(FT_UInt)(char*)&T1_FIELD_REF(T1TYPE,_fname), \
|
||||
sizeof(T1_FIELD_REF(T1TYPE,_fname)), \
|
||||
0, 0 }, |
||||
|
||||
#define T1_NEW_CALLBACK_FIELD( _ident, _reader ) \ |
||||
{ _ident, T1CODE, t1_field_callback, \
|
||||
_reader, \
|
||||
0, 0, 0, 0 }, |
||||
|
||||
#define T1_NEW_TABLE_FIELD( _ident, _type, _fname, _max ) \ |
||||
{ _ident, T1CODE, _type, \
|
||||
0, \
|
||||
(FT_UInt)(char*)&T1_FIELD_REF(T1TYPE,_fname), \
|
||||
sizeof(T1_FIELD_REF(T1TYPE,_fname)[0]), \
|
||||
_max, \
|
||||
(FT_UInt)(char*)&T1_FIELD_REF(T1TYPE,num_ ## _fname) }, |
||||
|
||||
#define T1_NEW_TABLE_FIELD2( _ident, _type, _fname, _max ) \ |
||||
{ _ident, T1CODE, _type, \
|
||||
0, \
|
||||
(FT_UInt)(char*)&T1_FIELD_REF(T1TYPE,_fname), \
|
||||
sizeof(T1_FIELD_REF(T1TYPE,_fname)[0]), \
|
||||
_max, 0 }, |
||||
|
||||
|
||||
#define T1_FIELD_BOOL( _ident, _fname ) \ |
||||
T1_NEW_SIMPLE_FIELD( _ident, t1_field_bool, _fname ) |
||||
|
||||
#define T1_FIELD_NUM( _ident, _fname ) \ |
||||
T1_NEW_SIMPLE_FIELD( _ident, t1_field_integer, _fname ) |
||||
|
||||
#define T1_FIELD_FIXED( _ident, _fname ) \ |
||||
T1_NEW_SIMPLE_FIELD( _ident, t1_field_fixed, _fname ) |
||||
|
||||
#define T1_FIELD_STRING( _ident, _fname ) \ |
||||
T1_NEW_SIMPLE_FIELD( _ident, t1_field_string, _fname ) |
||||
|
||||
#define T1_FIELD_NUM_TABLE( _ident, _fname, _fmax ) \ |
||||
T1_NEW_TABLE_FIELD( _ident, t1_field_integer_array, _fname, _fmax ) |
||||
|
||||
#define T1_FIELD_FIXED_TABLE( _ident, _fname, _fmax ) \ |
||||
T1_NEW_TABLE_FIELD( _ident, t1_field_fixed_array, _fname, _fmax ) |
||||
|
||||
#define T1_FIELD_NUM_TABLE2( _ident, _fname, _fmax ) \ |
||||
T1_NEW_TABLE_FIELD2( _ident, t1_field_integer_array, _fname, _fmax ) |
||||
|
||||
#define T1_FIELD_FIXED_TABLE2( _ident, _fname, _fmax ) \ |
||||
T1_NEW_TABLE_FIELD2( _ident, t1_field_fixed_array, _fname, _fmax ) |
||||
|
||||
#define T1_FIELD_CALLBACK( _ident, _name ) \ |
||||
T1_NEW_CALLBACK_FIELD( _ident, parse_ ## _name ) |
||||
|
||||
LOCAL_DEF |
||||
FT_Error CID_Load_Field( CID_Parser* parser, |
||||
const T1_Field_Rec* field, |
||||
void* object ); |
||||
|
||||
LOCAL_DEF |
||||
FT_Error CID_Load_Field_Table( CID_Parser* parser, |
||||
const T1_Field_Rec* field, |
||||
void* object ); |
||||
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus |
||||
} |
||||
#endif |
||||
|
||||
#endif /* CIDPARSE_H */ |
||||
|
||||
|
||||
/* END */ |
||||
|
@ -0,0 +1,428 @@ |
||||
/*******************************************************************
|
||||
* |
||||
* t1driver.c |
||||
* |
||||
* High-level Type1 driver interface for FreeType 2.0 |
||||
* |
||||
* Copyright 1996-1998 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. |
||||
* |
||||
******************************************************************/ |
||||
|
||||
#include <cidriver.h> |
||||
#include <cidgload.h> |
||||
#include <cidafm.h> |
||||
|
||||
#include <freetype/internal/ftdebug.h> |
||||
#include <freetype/internal/ftstream.h> |
||||
#include <freetype/internal/psnames.h> |
||||
|
||||
#undef FT_COMPONENT |
||||
#define FT_COMPONENT trace_t1driver |
||||
|
||||
/*************************************************************************/ |
||||
/* */ |
||||
/* <Function> */ |
||||
/* Get_Interface */ |
||||
/* */ |
||||
/* <Description> */ |
||||
/* Each driver can provide one or more extensions to the base */ |
||||
/* FreeType API. These can be used to access format specific */ |
||||
/* features (e.g., all TrueType/OpenType resources share a common */ |
||||
/* file structure and common tables which can be accessed through the */ |
||||
/* `sfnt' interface), or more simply generic ones (e.g., the */ |
||||
/* `postscript names' interface which can be used to retrieve the */ |
||||
/* PostScript name of a given glyph index). */ |
||||
/* */ |
||||
/* <InOut> */ |
||||
/* driver :: A handle to a driver object. */ |
||||
/* */ |
||||
/* <Input> */ |
||||
/* interface :: A string designing the interface. Examples are */ |
||||
/* `sfnt', `post_names', `charmaps', etc. */ |
||||
/* */ |
||||
/* <Return> */ |
||||
/* A typeless pointer to the extension's interface (normally a table */ |
||||
/* of function pointers). Returns NULL if the requested extension */ |
||||
/* isn't available (i.e., wasn't compiled in the driver at build */ |
||||
/* time). */ |
||||
/* */ |
||||
static |
||||
FTDriver_Interface Get_Interface( FT_Driver driver, |
||||
const FT_String* interface ) |
||||
{ |
||||
UNUSED(driver); |
||||
UNUSED(interface); |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
|
||||
#ifdef xxxT1_CONFIG_OPTION_NO_AFM |
||||
/*************************************************************************/ |
||||
/* */ |
||||
/* <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( T1_Face face, |
||||
FT_UInt left_glyph, |
||||
FT_UInt right_glyph, |
||||
T1_Vector* kerning ) |
||||
{ |
||||
T1_AFM* afm; |
||||
|
||||
kerning->x = 0; |
||||
kerning->y = 0; |
||||
|
||||
afm = (T1_AFM*)face->afm_data; |
||||
if (afm) |
||||
CID_Get_Kerning( afm, left_glyph, right_glyph, kerning ); |
||||
|
||||
return T1_Err_Ok; |
||||
} |
||||
#endif |
||||
|
||||
/******************************************************************/ |
||||
/* */ |
||||
/* <Function> Set_Char_Sizes */ |
||||
/* */ |
||||
/* <Description> */ |
||||
/* A driver method used to reset a size's character sizes */ |
||||
/* (horizontal and vertical) expressed in fractional points. */ |
||||
/* */ |
||||
/* <Input> */ |
||||
/* size :: handle to target size object */ |
||||
/* char_width :: character width expressed in 26.6 points */ |
||||
/* char_height :: character height expressed in 26.6 points */ |
||||
/* */ |
||||
/* <Return> */ |
||||
/* FreeType error code. 0 means success */ |
||||
/* */ |
||||
static |
||||
FT_Error Set_Char_Sizes( T1_Size size, |
||||
T1_F26Dot6 char_width, |
||||
T1_F26Dot6 char_height, |
||||
FT_UInt horz_resolution, |
||||
FT_UInt vert_resolution ) |
||||
{ |
||||
UNUSED(char_width); |
||||
UNUSED(char_height); |
||||
UNUSED(horz_resolution); |
||||
UNUSED(vert_resolution); |
||||
|
||||
size->valid = FALSE; |
||||
return T1_Reset_Size( size ); |
||||
} |
||||
|
||||
|
||||
/******************************************************************/ |
||||
/* */ |
||||
/* <Function> Set_Pixel_Sizes */ |
||||
/* */ |
||||
/* <Description> */ |
||||
/* A driver method used to reset a size's character sizes */ |
||||
/* (horizontal and vertical) expressed in integer pixels. */ |
||||
/* */ |
||||
/* <Input> */ |
||||
/* size :: handle to target size object */ |
||||
/* */ |
||||
/* pixel_width :: character width expressed in 26.6 points */ |
||||
/* */ |
||||
/* pixel_height :: character height expressed in 26.6 points */ |
||||
/* */ |
||||
/* char_size :: the corresponding character size in points */ |
||||
/* This value is only sent to the TrueType */ |
||||
/* bytecode interpreter, even though 99% of */ |
||||
/* glyph programs will simply ignore it. A */ |
||||
/* safe value there is the maximum of the */ |
||||
/* pixel width and height (multiplied by */ |
||||
/* 64 to make it a 26.6 fixed float !) */ |
||||
/* <Return> */ |
||||
/* FreeType error code. 0 means success */ |
||||
/* */ |
||||
static |
||||
FT_Error Set_Pixel_Sizes( T1_Size size, |
||||
FT_Int pixel_width, |
||||
FT_Int pixel_height ) |
||||
{ |
||||
UNUSED(pixel_width); |
||||
UNUSED(pixel_height); |
||||
|
||||
size->valid = FALSE; |
||||
return T1_Reset_Size(size); |
||||
} |
||||
|
||||
/*************************************************************************/ |
||||
/* */ |
||||
/* <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 |
||||
FT_UInt Get_Char_Index( FT_CharMap charmap, |
||||
FT_Long charcode ) |
||||
{ |
||||
T1_Face face; |
||||
FT_UInt result = 0; |
||||
PSNames_Interface* psnames; |
||||
|
||||
face = (T1_Face)charmap->face; |
||||
psnames = (PSNames_Interface*)face->psnames; |
||||
if (psnames) |
||||
switch (charmap->encoding) |
||||
{ |
||||
/********************************************************************/ |
||||
/* */ |
||||
/* Unicode encoding support */ |
||||
/* */ |
||||
case ft_encoding_unicode: |
||||
{ |
||||
/* use the "psnames" module to synthetize the Unicode charmap */ |
||||
result = psnames->lookup_unicode( &face->unicode_map, |
||||
(FT_ULong)charcode ); |
||||
|
||||
/* the function returns 0xFFFF when the Unicode charcode has */ |
||||
/* no corresponding glyph.. */ |
||||
if (result == 0xFFFF) |
||||
result = 0; |
||||
goto Exit; |
||||
} |
||||
|
||||
/********************************************************************/ |
||||
/* */ |
||||
/* Custom Type 1 encoding */ |
||||
/* */ |
||||
case ft_encoding_adobe_custom: |
||||
{ |
||||
T1_Encoding* encoding = &face->type1.encoding; |
||||
if (charcode >= encoding->code_first && |
||||
charcode <= encoding->code_last) |
||||
{ |
||||
result = encoding->char_index[charcode]; |
||||
} |
||||
goto Exit; |
||||
} |
||||
|
||||
/********************************************************************/ |
||||
/* */ |
||||
/* Adobe Standard & Expert encoding support */ |
||||
/* */ |
||||
default: |
||||
if (charcode < 256) |
||||
{ |
||||
FT_UInt code; |
||||
FT_Int n; |
||||
const char* glyph_name; |
||||
|
||||
code = psnames->adobe_std_encoding[charcode]; |
||||
if (charmap->encoding == ft_encoding_adobe_expert) |
||||
code = psnames->adobe_expert_encoding[charcode]; |
||||
|
||||
glyph_name = psnames->adobe_std_strings(code); |
||||
if (!glyph_name) break; |
||||
|
||||
for ( n = 0; n < face->type1.num_glyphs; n++ ) |
||||
{ |
||||
const char* gname = face->type1.glyph_names[n]; |
||||
|
||||
if ( gname && gname[0] == glyph_name[0] && |
||||
strcmp( gname, glyph_name ) == 0 ) |
||||
{ |
||||
result = n; |
||||
break; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
Exit: |
||||
return result; |
||||
} |
||||
|
||||
|
||||
/******************************************************************/ |
||||
/* */ |
||||
/* <Struct> FT_DriverInterface */ |
||||
/* */ |
||||
/* <Description> */ |
||||
/* A structure used to hold a font driver's basic interface */ |
||||
/* used by the high-level parts of FreeType (or other apps) */ |
||||
/* */ |
||||
/* Most scalable drivers provide a specialized interface to */ |
||||
/* access format-specific features. It can be retrieved with */ |
||||
/* a call to the "get_format_interface", and should be defined */ |
||||
/* in each font driver header (e.g. ttdriver.h, t1driver.h,..) */ |
||||
/* */ |
||||
/* All fields are function pointers .. */ |
||||
/* */ |
||||
/* */ |
||||
/* <Fields> */ |
||||
/* */ |
||||
/* new_engine :: */ |
||||
/* used to create and initialise a new driver object */ |
||||
/* */ |
||||
/* done_engine :: */ |
||||
/* used to finalise and destroy a given driver object */ |
||||
/* */ |
||||
/* get_format_interface :: */ |
||||
/* return a typeless pointer to the format-specific */ |
||||
/* driver interface. */ |
||||
/* */ |
||||
/* new_face :: */ |
||||
/* create a new face object from a resource */ |
||||
/* */ |
||||
/* done_face :: */ |
||||
/* discards a face object, as well as all child objects */ |
||||
/* ( sizes, charmaps, glyph slots ) */ |
||||
/* */ |
||||
/* get_face_properties :: */ |
||||
/* return generic face properties */ |
||||
/* */ |
||||
/* get_kerning :: */ |
||||
/* return the kerning vector corresponding to a pair */ |
||||
/* of glyphs, expressed in unscaled font units. */ |
||||
/* */ |
||||
/* new_size :: */ |
||||
/* create and initialise a new scalable size object. */ |
||||
/* */ |
||||
/* new_fixed_size :: */ |
||||
/* create and initialise a new fixed-size object. */ |
||||
/* */ |
||||
/* done_size :: */ |
||||
/* finalize a given face size object. */ |
||||
/* */ |
||||
/* set_size_resolutions :: */ |
||||
/* reset a scalable size object's output resolutions */ |
||||
/* */ |
||||
/* set_size_char_sizes :: */ |
||||
/* reset a scalable size object's character size */ |
||||
/* */ |
||||
/* set_pixel_sizes :: */ |
||||
/* reset a face size object's pixel dimensions. Applies */ |
||||
/* to both scalable and fixed faces. */ |
||||
/* */ |
||||
/* new_glyph_slot :: */ |
||||
/* create and initialise a new glyph slot */ |
||||
/* */ |
||||
/* done_glyph_slot :: */ |
||||
/* discard a given glyph slot */ |
||||
/* */ |
||||
/* load_glyph :: */ |
||||
/* load a given glyph into a given slot */ |
||||
/* */ |
||||
/* get_glyph_metrics :: */ |
||||
/* return a loaded glyph's metrics. */ |
||||
/* */ |
||||
|
||||
const FT_DriverInterface t1cid_driver_interface = |
||||
{ |
||||
sizeof( FT_DriverRec ), |
||||
sizeof( CID_FaceRec ), |
||||
sizeof( T1_SizeRec ), |
||||
sizeof( T1_GlyphSlotRec ), |
||||
|
||||
"type1", |
||||
100, |
||||
200, |
||||
|
||||
0, /* format interface */ |
||||
|
||||
(FTDriver_initDriver) T1_Init_Driver, |
||||
(FTDriver_doneDriver) T1_Done_Driver, |
||||
|
||||
(FTDriver_getInterface) Get_Interface, |
||||
|
||||
(FTDriver_initFace) T1_Init_Face, |
||||
(FTDriver_doneFace) T1_Done_Face, |
||||
|
||||
#ifndef xxxxT1_CONFIG_OPTION_NO_AFM |
||||
(FTDriver_getKerning) 0, |
||||
#else |
||||
(FTDriver_getKerning) Get_Kerning, |
||||
#endif |
||||
|
||||
(FTDriver_initSize) T1_Init_Size, |
||||
(FTDriver_doneSize) T1_Done_Size, |
||||
(FTDriver_setCharSizes) Set_Char_Sizes, |
||||
(FTDriver_setPixelSizes) Set_Pixel_Sizes, |
||||
|
||||
(FTDriver_initGlyphSlot) T1_Init_GlyphSlot, |
||||
(FTDriver_doneGlyphSlot) T1_Done_GlyphSlot, |
||||
(FTDriver_loadGlyph) CID_Load_Glyph, |
||||
|
||||
(FTDriver_getCharIndex) Get_Char_Index, |
||||
}; |
||||
|
||||
|
||||
/******************************************************************/ |
||||
/* */ |
||||
/* <Function> Get_FreeType_Driver_Interface */ |
||||
/* */ |
||||
/* <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> */ |
||||
/* address of TrueType's driver generic interface. The */ |
||||
/* forma-specific interface can then be retrieved through */ |
||||
/* the method interface->get_format_interface.. */ |
||||
/* */ |
||||
|
||||
#ifdef FT_CONFIG_OPTION_DYNAMIC_DRIVERS |
||||
|
||||
EXPORT_FUNC(FT_DriverInterface*) getDriverInterface( void ) |
||||
{ |
||||
return &t1cid_driver_interface; |
||||
} |
||||
|
||||
#endif /* FT_CONFIG_OPTION_DYNAMIC_DRIVERS */ |
||||
|
||||
|
@ -0,0 +1,27 @@ |
||||
/*******************************************************************
|
||||
* |
||||
* t1driver.h |
||||
* |
||||
* High-level Type1 driver interface for FreeType 2.0 |
||||
* |
||||
* Copyright 1996-1998 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. |
||||
* |
||||
******************************************************************/ |
||||
|
||||
#ifndef T1DRIVER_H |
||||
#define T1DRIVER_H |
||||
|
||||
#include <cidobjs.h> |
||||
#include <t1errors.h> |
||||
|
||||
FT_EXPORT_VAR(const FT_DriverInterface) t1cid_driver_interface; |
||||
|
||||
#endif /* T1DRIVER_H */ |
||||
|
@ -0,0 +1,94 @@ |
||||
/*******************************************************************
|
||||
* |
||||
* t1tokens.h |
||||
* |
||||
* Type 1 tokens definition |
||||
* |
||||
* Copyright 2000 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. |
||||
* |
||||
* This file only contains macros that are expanded when compiling |
||||
* the "t1load.c" source file. |
||||
* |
||||
******************************************************************/ |
||||
|
||||
#define T1TYPE CID_Info |
||||
#define T1CODE t1_field_cid_info |
||||
|
||||
T1_FIELD_STRING ( "CIDFontName", cid_font_name ) |
||||
T1_FIELD_NUM ( "CIDFontVersion", cid_version ) |
||||
T1_FIELD_NUM ( "CIDFontType", cid_font_type ) |
||||
T1_FIELD_STRING ( "Registry", registry ) |
||||
T1_FIELD_STRING ( "Ordering", ordering ) |
||||
T1_FIELD_NUM ( "Supplement", supplement ) |
||||
T1_FIELD_CALLBACK( "FontBBox", font_bbox ) |
||||
T1_FIELD_NUM ( "UIDBase", uid_base ) |
||||
T1_FIELD_CALLBACK( "FDArray", fd_array ) |
||||
T1_FIELD_NUM ( "CIDMapOffset", cidmap_offset ) |
||||
T1_FIELD_NUM ( "FDBytes", fd_bytes ) |
||||
T1_FIELD_NUM ( "GDBytes", gd_bytes ) |
||||
T1_FIELD_NUM ( "CIDCount", cid_count ) |
||||
|
||||
#undef T1TYPE |
||||
#undef T1CODE |
||||
#define T1TYPE T1_FontInfo |
||||
#define T1CODE t1_field_font_info |
||||
|
||||
T1_FIELD_STRING( "version", version ) |
||||
T1_FIELD_STRING( "Notice", notice ) |
||||
T1_FIELD_STRING( "FullName", full_name ) |
||||
T1_FIELD_STRING( "FamilyName", family_name ) |
||||
T1_FIELD_STRING( "Weight", weight ) |
||||
T1_FIELD_FIXED ( "ItalicAngle", italic_angle ) |
||||
T1_FIELD_BOOL ( "isFixedPitch", is_fixed_pitch ) |
||||
T1_FIELD_NUM ( "UnderlinePosition", underline_position ) |
||||
T1_FIELD_NUM ( "UnderlineThickness", underline_thickness ) |
||||
|
||||
#undef T1TYPE |
||||
#undef T1CODE |
||||
#define T1TYPE CID_FontDict |
||||
#define T1CODE t1_field_font_dict |
||||
|
||||
T1_FIELD_CALLBACK( "FontMatrix", font_matrix ) |
||||
T1_FIELD_NUM ( "PaintType", paint_type ) |
||||
T1_FIELD_NUM ( "FontType", font_type ) |
||||
T1_FIELD_NUM ( "SubrMapOffset", subrmap_offset ) |
||||
T1_FIELD_NUM ( "SDBytes", sd_bytes ) |
||||
T1_FIELD_NUM ( "SubrCount", num_subrs ) |
||||
T1_FIELD_NUM ( "lenBuildCharArray", len_buildchar ) |
||||
T1_FIELD_FIXED ( "ForceBoldThreshold", forcebold_threshold ) |
||||
T1_FIELD_FIXED ( "ExpansionFactor", expansion_factor ) |
||||
T1_FIELD_NUM ( "StrokeWidth", stroke_width ) |
||||
|
||||
#undef T1TYPE |
||||
#undef T1CODE |
||||
#define T1TYPE T1_Private |
||||
#define T1CODE t1_field_private |
||||
|
||||
T1_FIELD_NUM ( "UniqueID", unique_id ) |
||||
T1_FIELD_NUM ( "lenIV", lenIV ) |
||||
T1_FIELD_NUM ( "LanguageGroup", language_group ) |
||||
T1_FIELD_NUM ( "password", password ) |
||||
|
||||
T1_FIELD_FIXED( "BlueScale", blue_scale ) |
||||
T1_FIELD_NUM ( "BlueShift", blue_shift ) |
||||
T1_FIELD_NUM ( "BlueFuzz", blue_fuzz ) |
||||
|
||||
T1_FIELD_NUM_TABLE( "BlueValues", blue_values, 14 ) |
||||
T1_FIELD_NUM_TABLE( "OtherBlues", other_blues, 10 ) |
||||
T1_FIELD_NUM_TABLE( "FamilyBlues", family_blues, 14 ) |
||||
T1_FIELD_NUM_TABLE( "FamilyOtherBlues", family_other_blues, 10 ) |
||||
|
||||
T1_FIELD_NUM_TABLE2( "StdHW", standard_width, 1 ) |
||||
T1_FIELD_NUM_TABLE2( "StdVW", standard_height, 1 ) |
||||
T1_FIELD_NUM_TABLE2( "MinFeature", min_feature, 2 ) |
||||
|
||||
T1_FIELD_NUM_TABLE ( "StemSnapH", snap_widths, 12 ) |
||||
T1_FIELD_NUM_TABLE ( "StemSnapV", snap_heights, 12 ) |
||||
|
||||
|
@ -0,0 +1,6 @@ |
||||
make_module_list: add_type1cid_driver |
||||
|
||||
add_type1cid_driver: |
||||
$(OPEN_DRIVER)t1cid_driver_interface$(CLOSE_DRIVER)
|
||||
$(ECHO_DRIVER)cid $(ECHO_DRIVER_DESC)Postscript CID-keyed fonts, no known extension$(ECHO_DRIVER_DONE)
|
||||
# EOF
|
@ -0,0 +1,97 @@ |
||||
#
|
||||
# FreeType 2 driver configuration rules
|
||||
#
|
||||
|
||||
|
||||
# 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.
|
||||
|
||||
|
||||
#****************************************************************************
|
||||
#* *
|
||||
#* The "Type1z" driver is an experimental replacement for the current *
|
||||
#* Type 1 driver. It features a very different loading mechanism that *
|
||||
#* is much faster than the one used by the `normal' driver, and also *
|
||||
#* deals nicely with nearly broken Type 1 font files. It is also *
|
||||
#* much smaller... *
|
||||
#* *
|
||||
#* Note that it may become a permanent replacement of the current *
|
||||
#* "src/type1" driver in the future.. *
|
||||
#* *
|
||||
#****************************************************************************
|
||||
|
||||
# Type1z driver directory
|
||||
#
|
||||
CID_DIR := $(SRC_)cid
|
||||
CID_DIR_ := $(CID_DIR)$(SEP)
|
||||
|
||||
|
||||
# additional include flags used when compiling the driver
|
||||
#
|
||||
CID_INCLUDE := $(SHARED) $(CID_DIR)
|
||||
CID_COMPILE := $(FT_COMPILE) $(CID_INCLUDE:%=$I%)
|
||||
|
||||
|
||||
# Type1 driver sources (i.e., C files)
|
||||
#
|
||||
CID_DRV_SRC := $(CID_DIR_)cidparse.c \
|
||||
$(CID_DIR_)cidload.c \
|
||||
$(CID_DIR_)cidriver.c \
|
||||
$(CID_DIR_)cidgload.c \
|
||||
$(CID_DIR_)cidafm.c
|
||||
|
||||
# Type1 driver headers
|
||||
#
|
||||
CID_DRV_H := $(CID_DIR_)t1errors.h \
|
||||
$(CID_DIR_)cidtokens.h \
|
||||
$(T1SHARED_H) \
|
||||
$(CID_DRV_SRC:%.c=%.h)
|
||||
|
||||
|
||||
# driver object(s)
|
||||
#
|
||||
# CID_DRV_OBJ_M is used during `debug' builds
|
||||
# CID_DRV_OBJ_S is used during `release' builds
|
||||
#
|
||||
CID_DRV_OBJ_M := $(CID_DRV_SRC:$(CID_DIR_)%.c=$(OBJ_)%.$O) \
|
||||
$(T1SHARED:$(T1SHARED_DIR_)%.c=$(OBJ_)%.$O)
|
||||
CID_DRV_OBJ_S := $(OBJ_)type1cid.$O
|
||||
|
||||
|
||||
# driver source file(s)
|
||||
#
|
||||
CID_DRV_SRC_M := $(CID_DRV_SRC) $(T1SHARED_SRC)
|
||||
CID_DRV_SRC_S := $(CID_DIR_)type1cid.c
|
||||
|
||||
|
||||
# driver - single object
|
||||
#
|
||||
# the driver is recompiled if any of the header or source files is changed
|
||||
#
|
||||
$(CID_DRV_OBJ_S): $(BASE_H) $(CID_DRV_H) $(CID_DRV_SRC) $(CID_DRV_SRC_S) |
||||
$(CID_COMPILE) $T$@ $(CID_DRV_SRC_S)
|
||||
|
||||
|
||||
# driver - multiple objects
|
||||
#
|
||||
# All objects are recompiled if any of the header files is changed
|
||||
#
|
||||
$(OBJ_)t1%.$O: $(CID_DIR_)t1%.c $(BASE_H) $(CID_DRV_H) |
||||
$(CID_COMPILE) $T$@ $<
|
||||
|
||||
$(OBJ_)t1%.$O: $(T1SHARED_DIR_)t1%.c $(BASE_H) $(T1SHARED_H) |
||||
$(CID_COMPILE) $T$@ $<
|
||||
|
||||
|
||||
# update main driver object lists
|
||||
#
|
||||
DRV_OBJS_S += $(CID_DRV_OBJ_S)
|
||||
DRV_OBJS_M += $(CID_DRV_OBJ_M)
|
||||
|
||||
# EOF
|
@ -0,0 +1,75 @@ |
||||
/*******************************************************************
|
||||
* |
||||
* t1errors.h |
||||
* |
||||
* Type1 Error ID definitions |
||||
* |
||||
* Copyright 1996-1998 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. |
||||
* |
||||
******************************************************************/ |
||||
|
||||
#ifndef T1ERRORS_H |
||||
#define T1ERRORS_H |
||||
|
||||
#include <freetype/fterrors.h> |
||||
|
||||
/************************ error codes declaration **************/ |
||||
|
||||
/* The error codes are grouped in 'classes' used to indicate the */ |
||||
/* 'level' at which the error happened. */ |
||||
/* The class is given by an error code's high byte. */ |
||||
|
||||
|
||||
/* ------------- Success is always 0 -------- */ |
||||
|
||||
#define T1_Err_Ok FT_Err_Ok |
||||
|
||||
/* ----------- high level API errors -------- */ |
||||
|
||||
#define T1_Err_Invalid_File_Format FT_Err_Invalid_File_Format |
||||
#define T1_Err_Invalid_Argument FT_Err_Invalid_Argument |
||||
#define T1_Err_Invalid_Driver_Handle FT_Err_Invalid_Driver_Handle |
||||
#define T1_Err_Invalid_Face_Handle FT_Err_Invalid_Face_Handle |
||||
#define T1_Err_Invalid_Size_Handle FT_Err_Invalid_Size_Handle |
||||
#define T1_Err_Invalid_Glyph_Handle FT_Err_Invalid_Slot_Handle |
||||
#define T1_Err_Invalid_CharMap_Handle FT_Err_Invalid_CharMap_Handle |
||||
#define T1_Err_Invalid_Glyph_Index FT_Err_Invalid_Glyph_Index |
||||
|
||||
#define T1_Err_Unimplemented_Feature FT_Err_Unimplemented_Feature |
||||
#define T1_Err_Unavailable_Outline FT_Err_Unavailable_Outline |
||||
#define T1_Err_Unavailable_Bitmap FT_Err_Unavailable_Bitmap |
||||
#define T1_Err_Unavailable_Pixmap FT_Err_Unavailable_Pixmap |
||||
#define T1_Err_File_Is_Not_Collection FT_Err_File_Is_Not_Collection |
||||
|
||||
#define T1_Err_Invalid_Engine FT_Err_Invalid_Driver_Handle |
||||
|
||||
/* ------------- internal errors ------------ */ |
||||
|
||||
#define T1_Err_Out_Of_Memory FT_Err_Out_Of_Memory |
||||
#define T1_Err_Unlisted_Object FT_Err_Unlisted_Object |
||||
|
||||
/* ------------ general glyph outline errors ------ */ |
||||
|
||||
#define T1_Err_Too_Many_Points FT_Err_Too_Many_Points |
||||
#define T1_Err_Too_Many_Contours FT_Err_Too_Many_Contours |
||||
#define T1_Err_Too_Many_Hints FT_Err_Too_Many_Hints |
||||
#define T1_Err_Invalid_Composite FT_Err_Invalid_Composite |
||||
#define T1_Err_Too_Many_Edges FT_Err_Too_Many_Edges |
||||
#define T1_Err_Too_Many_Strokes FT_Err_Too_Many_Strokes |
||||
|
||||
|
||||
#define T1_Err_Syntax_Error FT_Err_Invalid_File_Format |
||||
#define T1_Err_Stack_Underflow FT_Err_Invalid_File_Format |
||||
#define T1_Err_Stack_Overflow FT_Err_Invalid_File_Format |
||||
|
||||
#endif /* TDERRORS_H */ |
||||
|
||||
|
||||
/* END */ |
@ -0,0 +1,41 @@ |
||||
/***************************************************************************/ |
||||
/* */ |
||||
/* type1.c */ |
||||
/* */ |
||||
/* FreeType Type 1 driver component */ |
||||
/* */ |
||||
/* Copyright 1996-1998 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. */ |
||||
/* */ |
||||
/* */ |
||||
/* This file is used to compile the FreeType Type 1 font driver. */ |
||||
/* It relies on all components included in the "base" layer (see */ |
||||
/* the file "ftbase.c"). Source code is located in "freetype/ttlib" */ |
||||
/* and contains : */ |
||||
/* */ |
||||
/* - a driver interface */ |
||||
/* - an object manager */ |
||||
/* - a table loader */ |
||||
/* - a glyph loader */ |
||||
/* - a glyph hinter */ |
||||
/* */ |
||||
/***************************************************************************/ |
||||
|
||||
#define FT_MAKE_OPTION_SINGLE_OBJECT |
||||
|
||||
#include <cidparse.c> |
||||
#include <cidload.c> |
||||
#include <cidobjs.c> |
||||
#include <cidriver.c> |
||||
#include <cidgload.c> |
||||
|
||||
#if 0 |
||||
#include <cidafm.c> |
||||
#endif |
||||
|
Loading…
Reference in new issue