added a CID-keyed font driver in "src/cid"

fixed two bugs in the smooth renderer
This commit is contained in:
David Turner 2000-06-01 03:27:48 +00:00
parent 3581d06464
commit 04aa800ce9
31 changed files with 5475 additions and 48 deletions

View File

@ -1,5 +1,12 @@
LATEST_CHANGES
- added the CID-keyed Type 1 driver in "src/cid". Works pretty well for
only 13 Kb of code ;-) Doesn't read AFM files though, nor the really
useful CMAP files..
- fixed two bugs in the smooth renderer (src/base/ftgrays.c). Thanks to
Boris Letocha for spotting them and providing a fix..
- fixed potential "divide by zero" bugs in ftcalc.c.. my god..
- added source code for the OpenType/CFF driver (still incomplete though..)

View File

@ -81,6 +81,20 @@
for ( file_index = 2; file_index < argc; file_index++ )
{
fname = argv[file_index];
/* try to open the file with no extra extension first */
error = FT_New_Face( library, fname, 0, &face );
if (!error) goto Success;
if ( error == FT_Err_Unknown_File_Format )
{
printf( "unknown format\n" );
continue;
}
/* ok, we could not load the file, try to add an extension to */
/* its name if possible.. */
i = strlen( fname );
while ( i > 0 && fname[i] != '\\' && fname[i] != '/' )
{
@ -124,7 +138,7 @@
error = FT_New_Face( library, filename, 0, &face );
if (error)
{
if (error == FT_Err_Invalid_File_Format)
if (error == FT_Err_Unknown_File_Format)
printf( "unknown format\n" );
else
printf( "could not find/open file (error: %d)\n", error );
@ -132,6 +146,7 @@
}
if (error) Panic( "Could not open file" );
Success:
num_glyphs = face->num_glyphs;
error = FT_Set_Char_Size( face, ptsize << 6, ptsize << 6, 72, 72 );

View File

@ -59,9 +59,9 @@
static grColor fore_color = { 255 };
static int graph_init = 0;
static int graph_init = 0;
static int render_mode = 1;
static int use_grays = 0;
static int use_grays = 1;
/* the standard raster's interface */
static FT_Raster_Funcs std_raster;

View File

@ -74,7 +74,7 @@ $\243^\250*\265\371%!\247:/;.,?<>";
int graph_init = 0;
int render_mode = 1;
int use_grays = 0;
int use_grays = 1;
/* the standard raster's interface */
FT_Raster_Funcs std_raster;
@ -618,6 +618,16 @@ $\243^\250*\265\371%!\247:/;.,?<>";
hinted = 1;
file_loaded = 0;
filename[128] = '\0';
alt_filename[128] = '\0';
strncpy( filename, argv[file], 128 );
strncpy( alt_filename, argv[file], 128 );
/* try to load the file name as is, first */
error = FT_New_Face( library, argv[file], 0, &face );
if (!error) goto Success;
#ifndef macintosh
i = strlen( argv[file] );
while ( i > 0 && argv[file][i] != '\\' && argv[file][i] != '/' )
@ -628,12 +638,6 @@ $\243^\250*\265\371%!\247:/;.,?<>";
}
#endif
filename[128] = '\0';
alt_filename[128] = '\0';
strncpy( filename, argv[file], 128 );
strncpy( alt_filename, argv[file], 128 );
#ifndef macintosh
if ( i >= 0 )
{
@ -647,6 +651,7 @@ $\243^\250*\265\371%!\247:/;.,?<>";
error = FT_New_Face( library, filename, 0, &face );
if (error) goto Display_Font;
Success:
file_loaded++;
error = Reset_Scale( ptsize );

View File

@ -1,4 +1,5 @@
FT_DRIVER(cff_driver_interface)
FT_DRIVER(t1cid_driver_interface)
FT_DRIVER(psnames_driver_interface)
FT_DRIVER(sfnt_driver_interface)
FT_DRIVER(tt_driver_interface)

View File

@ -394,6 +394,12 @@
/* */
#undef T1_CONFIG_OPTION_NO_AFM
/*******************************************************************/
/* Define this configuration macro if you want to prevent the */
/* compilation of the multiple-masters support in the Type 1 driver*/
/* AFM files into an existing face. Note that when set, the T1 */
/* driver will be unable to produce kerning distances.. */
/* */
#undef T1_CONFIG_OPTION_NO_MM_SUPPORT
#endif /* FTOPTION_H */

View File

@ -612,6 +612,7 @@
FT_CharMap charmap;
FT_ListRec sizes_list;
void* autohint_globals;
void* extensions;
FT_UShort max_points;
@ -934,11 +935,15 @@
/* FT_Load_Glyph() API function) and can be expressed */
/* either in 26.6 fractional pixels or font units. */
/* */
/* metrics2 :: This field can be used to return alternate glyph */
/* metrics after a single load. It can contain either */
/* the glyph's metrics in font units, or the scaled but */
/* unhinted ones. See the load flags that apply when */
/* calling the API function FT_Load_Glyph(). */
/* metrics2 :: This field is used to return alternate glyph metrics */
/* for scalable formats. Only four fields in it are */
/* valid: horiBearingX, horiAdvance, vertBearingY and */
/* vertAdvance. All other fields should be ignored. */
/* By default, it contains the glyph metrics expressed */
/* in font units. However, when FT_Load_Glyph() is called */
/* with FT_LOAD_LINEAR set, the metrics are expressed */
/* in 16.16 unhinted pixel values.. This can be useful */
/* to perform WYSIWYG glyph layout.. */
/* */
/* generic :: A typeless pointer which is unused by the FreeType */
/* library or any of its drivers. It can be used by */
@ -955,7 +960,6 @@
/* loaded glyph can be retrieved through the result value */
/* returned by FT_Load_Glyph(). */
/* */
/* */
enum
{

View File

@ -344,6 +344,13 @@
} T1_Font;
typedef struct CID_Subrs_
{
FT_UInt num_subrs;
FT_Byte** code;
} CID_Subrs;
/*************************************************************************/
/*************************************************************************/
@ -372,7 +379,7 @@
typedef struct T1_FaceRec_* T1_Face;
typedef struct CID_FaceRec_* CID_Face;
/***************************************************/
/* */
@ -397,4 +404,13 @@
} T1_FaceRec;
typedef struct CID_FaceRec_
{
FT_FaceRec root;
void* psnames;
CID_Info cid;
CID_Subrs* subrs;
} CID_FaceRec;
#endif /* T1TYPES_H */

View File

@ -69,7 +69,7 @@
FT_Int unique_id;
FT_Int lenIV;
FT_Byte num_blues;
FT_Byte num_blue_values;
FT_Byte num_other_blues;
FT_Byte num_family_blues;
FT_Byte num_family_other_blues;
@ -92,8 +92,8 @@
FT_Bool force_bold;
FT_Bool round_stem_up;
FT_Short stem_snap_widths [13]; /* reserve one place for the std */
FT_Short stem_snap_heights[13]; /* reserve one place for the std */
FT_Short snap_widths [13]; /* reserve one place for the std */
FT_Short snap_heights[13]; /* reserve one place for the std */
FT_Long language_group;
FT_Long password;
@ -181,9 +181,17 @@
typedef struct CID_FontDict_
{
T1_FontInfo font_info;
T1_Private private_dict;
FT_UInt len_buildchar;
FT_Fixed forcebold_threshold;
FT_Pos stroke_width;
FT_Fixed expansion_factor;
FT_Byte paint_type;
FT_Byte font_type;
FT_Matrix font_matrix;
FT_UInt num_subrs;
FT_ULong subrmap_offset;
FT_Int sd_bytes;
@ -201,6 +209,8 @@
FT_String* ordering;
FT_Int supplement;
T1_FontInfo font_info;
FT_BBox font_bbox;
FT_ULong uid_base;
FT_Int num_xuid;
@ -212,9 +222,11 @@
FT_Int gd_bytes;
FT_ULong cid_count;
FT_Int num_font_dicts;
FT_Int num_dicts;
CID_FontDict* font_dicts;
FT_ULong data_offset;
} CID_Info;

View File

@ -300,7 +300,7 @@
/* in during the render phase. This means that: */
/* */
/* . the new vertical position must be within min_ey..max_ey - 1. */
/* . the new horizontal position must be strictly less than max_ey */
/* . the new horizontal position must be strictly less than max_ex */
/* */
/* Note that if a cell is to the left of the clipping region, it is */
/* actually set to the (min_ex-1) horizontal position. */
@ -1198,7 +1198,7 @@
coverage = -coverage;
while ( coverage >= 512 )
coverage -= 512;
coverage = 512-coverage;
if ( coverage > 256 )
coverage = 0;
@ -1216,6 +1216,7 @@
}
y += ras.min_ey;
x += ras.min_ex;
if ( coverage )
{
@ -1330,9 +1331,9 @@
else
{
/* draw a gray span until the end of the clipping region */
if ( cover && x < ras.max_ex )
if ( cover && x < ras.max_ex - ras.min_ex )
grays_hline( RAS_VAR_ x, y,
cover * ( ONE_PIXEL * 2 ), ras.max_ex - x );
cover * ( ONE_PIXEL * 2 ), ras.max_ex - x - ras.min_ex );
cover = 0;
}

228
src/cid/cidafm.c Normal file
View File

@ -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;
}

49
src/cid/cidafm.h Normal file
View File

@ -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 */

1484
src/cid/cidgload.c Normal file

File diff suppressed because it is too large Load Diff

188
src/cid/cidgload.h Normal file
View File

@ -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 */

503
src/cid/cidload.c Normal file
View File

@ -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;
}

54
src/cid/cidload.h Normal file
View File

@ -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 */

473
src/cid/cidobjs.c Normal file
View File

@ -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 */

304
src/cid/cidobjs.h Normal file
View File

@ -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 */

936
src/cid/cidparse.c Normal file
View File

@ -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 );
}
}

347
src/cid/cidparse.h Normal file
View File

@ -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 */

428
src/cid/cidriver.c Normal file
View File

@ -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 */

27
src/cid/cidriver.h Normal file
View File

@ -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 */

94
src/cid/cidtokens.h Normal file
View File

@ -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 )

6
src/cid/module.mk Normal file
View File

@ -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

97
src/cid/rules.mk Normal file
View File

@ -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

75
src/cid/t1errors.h Normal file
View File

@ -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 */

41
src/cid/type1cid.c Normal file
View File

@ -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

View File

@ -993,13 +993,12 @@
for ( u = 0; u < num_points + 2; u++ )
{
glyph->outline.points[u] = loader->base.cur[u];
glyph->outline.tags [u] = loader->base.tags[u];
glyph->outline.tags [u] = loader->base.tags[u];
}
for ( u = 0; u < num_contours; u++ )
glyph->outline.contours[u] = loader->base.contours[u];
/* glyph->outline.second_pass = TRUE; */
glyph->outline.flags &= ~ft_outline_single_pass;
glyph->outline.n_points = num_points;
glyph->outline.n_contours = num_contours;
@ -1029,6 +1028,8 @@
{
TT_Pos left_bearing;
TT_Pos advance;
TT_Pos lsb2, adv2;
left_bearing = loader->left_bearing;
advance = loader->advance;
@ -1042,14 +1043,22 @@
(loader->load_flags & FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH) == 0 )
advance = face->horizontal.advance_Width_Max;
if ( !(loader->load_flags & FT_LOAD_NO_SCALE) )
lsb2 = left_bearing;
adv2 = advance;
/* if necessary, scale the horizontal left bearing and advance */
/* to get their values in 16.16 format.. */
if ( !(loader->load_flags & FT_LOAD_NO_SCALE) &&
loader->load_flags & FT_LOAD_LINEAR )
{
left_bearing = FT_MulFix( left_bearing, x_scale );
advance = FT_MulFix( advance, x_scale );
FT_Pos em_size = face->root.units_per_EM;
FT_Pos pixel_size = (FT_Pos)face->root.size->metrics.x_ppem << 16;
lsb2 = FT_MulDiv( lsb2, pixel_size, em_size );
adv2 = FT_MulDiv( adv2, pixel_size, em_size );
}
glyph->metrics2.horiBearingX = left_bearing;
glyph->metrics2.horiAdvance = advance;
glyph->metrics2.horiBearingX = lsb2;
glyph->metrics2.horiAdvance = adv2;
}
glyph->metrics.horiBearingX = bbox.xMin;
@ -1131,8 +1140,25 @@
advance = advance_height;
}
glyph->metrics2.vertBearingY = Top;
glyph->metrics2.vertAdvance = advance;
/* compute metrics2 fields */
{
FT_Pos vtb2 = top_bearing;
FT_Pos adv2 = advance_height;
/* scale to 16.16 format if required */
if ( !(loader->load_flags & FT_LOAD_NO_SCALE) &&
loader->load_flags & FT_LOAD_LINEAR )
{
FT_Pos em_size = face->root.units_per_EM;
FT_Pos pixel_size = face->root.size->metrics.y_ppem;
vtb2 = FT_MulDiv( vtb2, pixel_size, em_size );
adv2 = FT_MulDiv( adv2, pixel_size, em_size );
}
glyph->metrics2.vertBearingY = vtb2;
glyph->metrics2.vertAdvance = adv2;
}
/* XXX: for now, we have no better algorithm for the lsb, but it */
/* should work fine. */
@ -1306,7 +1332,7 @@
/* clear all outline flags, except the "owner" one */
glyph->outline.flags &= ft_outline_owner;
if (size && size->root.metrics.y_ppem < 24 )
if ( size && size->root.metrics.y_ppem < 24 )
glyph->outline.flags |= ft_outline_high_precision;
/************************************************************************/

View File

@ -127,7 +127,7 @@
/* First of all, check the sizes of the /BlueValues and /OtherBlues */
/* tables. They all must contain an even number of arguments */
if ( priv->num_other_blues & 1 ||
priv->num_blues & 1 )
priv->num_blue_values & 1 )
{
FT_ERROR(( "T1.Copy_Blues : odd number of blue values\n" ));
return T1_Err_Syntax_Error;
@ -141,7 +141,7 @@
blues[n] = priv->other_blues[n];
/* Add the first blue zone in /BlueValues to the table */
num_top = priv->num_blues - 2;
num_top = priv->num_blue_values - 2;
if ( num_top >= 0 )
{
blues[ num_bottom ] = priv->blue_values[0];
@ -294,7 +294,7 @@
standard_width = priv->standard_width[0];
n_zones = priv->num_snap_widths;
base_zone = hints->snap_widths;
orgs = priv->stem_snap_widths;
orgs = priv->snap_widths;
scale = size->root.metrics.x_scale;
while (direction < 2)
@ -461,7 +461,7 @@
standard_width = priv->standard_height[0];
n_zones = priv->num_snap_heights;
base_zone = hints->snap_heights;
orgs = priv->stem_snap_heights;
orgs = priv->snap_heights;
scale = size->root.metrics.y_scale;
}

View File

@ -428,7 +428,7 @@
case imm_BlueValues:
CopyArray( parser, &priv->num_blues,
CopyArray( parser, &priv->num_blue_values,
priv->blue_values, 14 );
break;
@ -478,13 +478,13 @@
case imm_StemSnapH:
CopyArray( parser, &priv->num_snap_widths,
priv->stem_snap_widths, 12 );
priv->snap_widths, 12 );
break;
case imm_StemSnapV:
CopyArray( parser, &priv->num_snap_heights,
priv->stem_snap_heights, 12 );
priv->snap_heights, 12 );
break;

View File

@ -43,7 +43,7 @@
T1_PRIVATE_NUM ( "BlueShift", blue_shift )
T1_PRIVATE_NUM ( "BlueFuzz", blue_fuzz )
T1_PRIVATE_NUM_TABLE( "BlueValues", blue_values, 14, num_blues )
T1_PRIVATE_NUM_TABLE( "BlueValues", blue_values, 14, num_blue_values )
T1_PRIVATE_NUM_TABLE( "OtherBlues", other_blues, 10, num_other_blues )
T1_PRIVATE_NUM_TABLE( "FamilyBlues", family_blues, 14, num_family_blues )
T1_PRIVATE_NUM_TABLE( "FamilyOtherBlues", family_other_blues, 10, num_family_other_blues )
@ -52,8 +52,8 @@
T1_PRIVATE_NUM_TABLE2( "StdVW", standard_height, 1 )
T1_PRIVATE_NUM_TABLE2( "MinFeature", min_feature, 2 )
T1_PRIVATE_NUM_TABLE ( "StemSnapH", stem_snap_widths, 12, num_snap_widths )
T1_PRIVATE_NUM_TABLE ( "StemSnapV", stem_snap_heights, 12, num_snap_heights )
T1_PRIVATE_NUM_TABLE ( "StemSnapH", snap_widths, 12, num_snap_widths )
T1_PRIVATE_NUM_TABLE ( "StemSnapV", snap_heights, 12, num_snap_heights )
#undef T1TYPE
#define T1TYPE T1_Font