parent
ad0472531a
commit
c129cb011d
3 changed files with 5 additions and 351 deletions
@ -1,284 +0,0 @@ |
||||
/***************************************************************************/ |
||||
/* */ |
||||
/* cidafm.c */ |
||||
/* */ |
||||
/* AFM support for CID-keyed fonts (body). */ |
||||
/* */ |
||||
/* Copyright 1996-2000 by */ |
||||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ |
||||
/* */ |
||||
/* This file is part of the FreeType project, and may only be used, */ |
||||
/* modified, and distributed under the terms of the FreeType project */ |
||||
/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ |
||||
/* this file you indicate that you have read the license and */ |
||||
/* understand and accept it fully. */ |
||||
/* */ |
||||
/***************************************************************************/ |
||||
|
||||
|
||||
#include <ft2build.h> |
||||
#include FT_SOURCE_FILE( cid, cidafm.h ) |
||||
#include FT_INTERNAL_STREAM_H |
||||
#include FT_INTERNAL_TYPE1_TYPES_H |
||||
#include FT_INTERNAL_TYPE1_ERRORS_H |
||||
|
||||
#include <stdlib.h> /* for qsort() */ |
||||
#include <string.h> /* for strcmp() */ |
||||
#include <ctype.h> /* for isalnum() */ |
||||
|
||||
|
||||
/*************************************************************************/ |
||||
/* */ |
||||
/* The macro FT_COMPONENT is used in trace mode. It is an implicit */ |
||||
/* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ |
||||
/* messages during execution. */ |
||||
/* */ |
||||
#undef FT_COMPONENT |
||||
#define FT_COMPONENT trace_cidafm |
||||
|
||||
|
||||
FT_LOCAL_DEF |
||||
void CID_Done_AFM( FT_Memory memory, |
||||
CID_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 ) ( isalnum( c ) || \ |
||||
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 && !isdigit( *p ) ) |
||||
{ |
||||
sign = 1; |
||||
if ( *p == '-' ) |
||||
sign = -1; |
||||
|
||||
p++; |
||||
} |
||||
|
||||
while ( p < limit && isdigit( *p ) ) |
||||
{ |
||||
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 ) |
||||
{ |
||||
CID_Kern_Pair* pair1 = (CID_Kern_Pair*)a; |
||||
CID_Kern_Pair* pair2 = (CID_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 */ |
||||
FT_LOCAL_DEF |
||||
FT_Error CID_Read_AFM( FT_Face cid_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; |
||||
CID_Kern_Pair* pair; |
||||
T1_Font* type1 = &((T1_Face)t1_face)->type1; |
||||
CID_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 occurrences 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, CID_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 ( CID_Kern_Pair ), |
||||
compare_kern_pairs ); |
||||
|
||||
Exit: |
||||
if ( error ) |
||||
FREE( afm ); |
||||
|
||||
FORGET_Frame(); |
||||
|
||||
return error; |
||||
} |
||||
|
||||
|
||||
/* find the kerning for a given glyph pair */ |
||||
FT_LOCAL_DEF |
||||
void CID_Get_Kerning( CID_AFM* afm, |
||||
FT_UInt glyph1, |
||||
FT_UInt glyph2, |
||||
FT_Vector* kerning ) |
||||
{ |
||||
CID_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; |
||||
} |
||||
|
||||
|
||||
/* END */ |
@ -1,67 +0,0 @@ |
||||
/***************************************************************************/ |
||||
/* */ |
||||
/* cidafm.h */ |
||||
/* */ |
||||
/* AFM support for CID-keyed fonts (specification). */ |
||||
/* */ |
||||
/* 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 __CIDAFM_H__ |
||||
#define __CIDAFM_H__ |
||||
|
||||
|
||||
#include <ft2build.h> |
||||
#include FT_SOURCE_FILE( cid, cidobjs.h ) |
||||
|
||||
|
||||
FT_BEGIN_HEADER |
||||
|
||||
|
||||
typedef struct CID_Kern_Pair_ |
||||
{ |
||||
FT_UInt glyph1; |
||||
FT_UInt glyph2; |
||||
FT_Vector kerning; |
||||
|
||||
} CID_Kern_Pair; |
||||
|
||||
|
||||
typedef struct CID_AFM_ |
||||
{ |
||||
FT_UInt num_pairs; |
||||
CID_Kern_Pair* kern_pairs; |
||||
|
||||
} CID_AFM; |
||||
|
||||
|
||||
FT_LOCAL |
||||
FT_Error CID_Read_AFM( FT_Face cid_face, |
||||
FT_Stream stream ); |
||||
|
||||
FT_LOCAL |
||||
void CID_Done_AFM( FT_Memory memory, |
||||
CID_AFM* afm ); |
||||
|
||||
FT_LOCAL |
||||
void CID_Get_Kerning( CID_AFM* afm, |
||||
FT_UInt glyph1, |
||||
FT_UInt glyph2, |
||||
FT_Vector* kerning ); |
||||
|
||||
|
||||
FT_END_HEADER |
||||
|
||||
#endif /* __CIDAFM_H__ */ |
||||
|
||||
|
||||
/* END */ |
Loading…
Reference in new issue