added a CID-keyed font driver in "src/cid"
fixed two bugs in the smooth renderer
This commit is contained in:
parent
3581d06464
commit
04aa800ce9
7
CHANGES
7
CHANGES
@ -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..)
|
||||
|
@ -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 );
|
||||
|
@ -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;
|
||||
|
@ -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 );
|
||||
|
@ -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)
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
||||
|
||||
|
@ -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
228
src/cid/cidafm.c
Normal 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
49
src/cid/cidafm.h
Normal 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
1484
src/cid/cidgload.c
Normal file
File diff suppressed because it is too large
Load Diff
188
src/cid/cidgload.h
Normal file
188
src/cid/cidgload.h
Normal 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
503
src/cid/cidload.c
Normal 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
54
src/cid/cidload.h
Normal 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
473
src/cid/cidobjs.c
Normal 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
304
src/cid/cidobjs.h
Normal 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
936
src/cid/cidparse.c
Normal 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
347
src/cid/cidparse.h
Normal 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
428
src/cid/cidriver.c
Normal 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
27
src/cid/cidriver.h
Normal 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
94
src/cid/cidtokens.h
Normal 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
6
src/cid/module.mk
Normal 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
97
src/cid/rules.mk
Normal 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
75
src/cid/t1errors.h
Normal 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
41
src/cid/type1cid.c
Normal 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
|
||||
|
@ -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;
|
||||
|
||||
/************************************************************************/
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user