mirror of https://github.com/freetype/freetype
[gf] Change `cmap' encoding scheme.
* src/gf/gfdrivr.c(GF_Face_Init): - Change `gf_cmap_class' functions to use new encoding scheme. - Set charmap to `0: synthetic, platform 0, encoding 0 language 0' values. * src/gf/gflib.c(gf_set_encodings, gf_load_font): Modify to set encoding so as to load glyphs in the order they appear in the font file.
This commit is contained in:
parent
eba29d801e
commit
743b415ca9
149
src/gf/gfdrivr.c
149
src/gf/gfdrivr.c
|
@ -43,9 +43,9 @@
|
|||
|
||||
typedef struct GF_CMapRec_
|
||||
{
|
||||
FT_CMapRec cmap;
|
||||
FT_UInt32 bc; /* Beginning Character */
|
||||
FT_UInt32 ec; /* End Character */
|
||||
FT_CMapRec cmap;
|
||||
FT_ULong num_encodings;
|
||||
GF_Encoding encodings;
|
||||
} GF_CMapRec, *GF_CMap;
|
||||
|
||||
|
||||
|
@ -57,8 +57,8 @@
|
|||
GF_Face face = (GF_Face)FT_CMAP_FACE( cmap );
|
||||
FT_UNUSED( init_data );
|
||||
|
||||
cmap->bc = face->gf_glyph->code_min;
|
||||
cmap->ec = face->gf_glyph->code_max;
|
||||
cmap->num_encodings = face->gf_glyph->nencodings;
|
||||
cmap->encodings = face->gf_glyph->encodings;
|
||||
|
||||
return FT_Err_Ok;
|
||||
}
|
||||
|
@ -69,54 +69,98 @@
|
|||
{
|
||||
GF_CMap cmap = (GF_CMap)gfcmap;
|
||||
|
||||
cmap->bc = 0;
|
||||
cmap->ec = -1;
|
||||
cmap->encodings = NULL;
|
||||
cmap->num_encodings = 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( FT_UInt )
|
||||
gf_cmap_char_index( FT_CMap gfcmap,
|
||||
FT_UInt32 char_code )
|
||||
FT_UInt32 charcode )
|
||||
{
|
||||
FT_UInt gindex = 0;
|
||||
GF_CMap cmap = (GF_CMap)gfcmap;
|
||||
GF_CMap cmap = (GF_CMap)gfcmap;
|
||||
GF_Encoding encodings = cmap->encodings;
|
||||
FT_ULong min, max, mid;
|
||||
FT_UInt result = 0;
|
||||
|
||||
char_code -= cmap->bc;
|
||||
min = 0;
|
||||
max = cmap->num_encodings;
|
||||
|
||||
if ( char_code < cmap->ec - cmap->bc + 1 )
|
||||
gindex = (FT_UInt)( char_code );
|
||||
while ( min < max )
|
||||
{
|
||||
FT_ULong code;
|
||||
|
||||
return gindex;
|
||||
|
||||
mid = ( min + max ) >> 1;
|
||||
code = (FT_ULong)encodings[mid].enc;
|
||||
|
||||
if ( charcode == code )
|
||||
{
|
||||
result = encodings[mid].glyph;
|
||||
break;
|
||||
}
|
||||
|
||||
if ( charcode < code )
|
||||
max = mid;
|
||||
else
|
||||
min = mid + 1;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
FT_CALLBACK_DEF( FT_UInt )
|
||||
gf_cmap_char_next( FT_CMap gfcmap,
|
||||
FT_UInt32 *achar_code )
|
||||
FT_UInt32 *acharcode )
|
||||
{
|
||||
GF_CMap cmap = (GF_CMap)gfcmap;
|
||||
FT_UInt gindex = 0;
|
||||
FT_UInt32 result = 0;
|
||||
FT_UInt32 char_code = *achar_code + 1;
|
||||
GF_CMap cmap = (GF_CMap)gfcmap;
|
||||
GF_Encoding encodings = cmap->encodings;
|
||||
FT_ULong min, max, mid;
|
||||
FT_ULong charcode = *acharcode + 1;
|
||||
FT_UInt result = 0;
|
||||
|
||||
|
||||
if ( char_code <= cmap->bc )
|
||||
min = 0;
|
||||
max = cmap->num_encodings;
|
||||
|
||||
while ( min < max )
|
||||
{
|
||||
result = cmap->bc;
|
||||
gindex = 1;
|
||||
FT_ULong code;
|
||||
|
||||
|
||||
mid = ( min + max ) >> 1;
|
||||
code = (FT_ULong)encodings[mid].enc;
|
||||
|
||||
if ( charcode == code )
|
||||
{
|
||||
result = encodings[mid].glyph + 1;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
if ( charcode < code )
|
||||
max = mid;
|
||||
else
|
||||
min = mid + 1;
|
||||
}
|
||||
|
||||
charcode = 0;
|
||||
if ( min < cmap->num_encodings )
|
||||
{
|
||||
charcode = (FT_ULong)encodings[min].enc;
|
||||
result = encodings[min].glyph ;
|
||||
}
|
||||
|
||||
Exit:
|
||||
if ( charcode > 0xFFFFFFFFUL )
|
||||
{
|
||||
FT_TRACE1(( "gf_cmap_char_next: charcode 0x%x > 32bit API" ));
|
||||
*acharcode = 0;
|
||||
/* XXX: result should be changed to indicate an overflow error */
|
||||
}
|
||||
else
|
||||
{
|
||||
char_code -= cmap->bc;
|
||||
if ( char_code < cmap->ec - cmap->bc + 1 )
|
||||
{
|
||||
result = char_code;
|
||||
gindex = (FT_UInt)( char_code );
|
||||
}
|
||||
}
|
||||
|
||||
*achar_code = result;
|
||||
return gindex;
|
||||
*acharcode = (FT_UInt32)charcode;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
@ -145,9 +189,10 @@
|
|||
|
||||
memory = FT_FACE_MEMORY( face );
|
||||
|
||||
gf_free_font( face );
|
||||
|
||||
FT_FREE( gfface->available_sizes );
|
||||
FT_FREE( face->gf_glyph->encodings );
|
||||
|
||||
gf_free_font( face );
|
||||
|
||||
}
|
||||
|
||||
|
@ -270,15 +315,37 @@
|
|||
y_res ); ;
|
||||
}
|
||||
|
||||
/* set up charmap */
|
||||
{
|
||||
/* FT_Bool unicode_charmap ; */
|
||||
|
||||
/*
|
||||
* XXX: TO-DO
|
||||
* Currently the unicode_charmap is set to `0'
|
||||
* The functionality of extracting coding scheme
|
||||
* from `xxx' and `yyy' commands will be used to
|
||||
* set the unicode_charmap.
|
||||
*/
|
||||
}
|
||||
|
||||
/* Charmaps */
|
||||
{
|
||||
FT_CharMapRec charmap;
|
||||
FT_Bool unicode_charmap = 0;
|
||||
|
||||
/* Unicode Charmap */
|
||||
charmap.encoding = FT_ENCODING_UNICODE;
|
||||
charmap.platform_id = TT_PLATFORM_MICROSOFT;
|
||||
charmap.encoding_id = TT_MS_ID_UNICODE_CS;
|
||||
charmap.face = FT_FACE( face );
|
||||
charmap.encoding = FT_ENCODING_NONE;
|
||||
/* initial platform/encoding should indicate unset status? */
|
||||
charmap.platform_id = TT_PLATFORM_APPLE_UNICODE;
|
||||
charmap.encoding_id = TT_APPLE_ID_DEFAULT;
|
||||
|
||||
if( unicode_charmap )
|
||||
{
|
||||
/* Unicode Charmap */
|
||||
charmap.encoding = FT_ENCODING_UNICODE;
|
||||
charmap.platform_id = TT_PLATFORM_MICROSOFT;
|
||||
charmap.encoding_id = TT_MS_ID_UNICODE_CS;
|
||||
}
|
||||
|
||||
error = FT_CMap_New( &gf_cmap_class, NULL, &charmap, NULL );
|
||||
|
||||
|
@ -387,7 +454,7 @@
|
|||
goto Exit;
|
||||
}
|
||||
|
||||
FT_TRACE1(( "GF_Glyph_Load: glyph index %d\n", glyph_index ));
|
||||
FT_TRACE1(( "GF_Glyph_Load: glyph index %d charcode is %d\n", glyph_index, go->bm_table[glyph_index].code ));
|
||||
|
||||
if ( (FT_Int)glyph_index < 0 )
|
||||
glyph_index = 0;
|
||||
|
@ -563,7 +630,7 @@
|
|||
}
|
||||
|
||||
|
||||
FT_CALLBACK_TABLE_DEF
|
||||
FT_CALLBACK_TABLE_DEF
|
||||
const FT_Driver_ClassRec gf_driver_class =
|
||||
{
|
||||
{
|
||||
|
|
|
@ -27,6 +27,14 @@
|
|||
|
||||
FT_BEGIN_HEADER
|
||||
|
||||
|
||||
typedef struct GF_EncodingRec_
|
||||
{
|
||||
FT_Long enc;
|
||||
FT_UShort glyph;
|
||||
|
||||
} GF_EncodingRec, *GF_Encoding;
|
||||
|
||||
/* BitmapRec for GF format specific glyphs */
|
||||
typedef struct GF_BitmapRec_
|
||||
{
|
||||
|
@ -35,6 +43,8 @@ FT_BEGIN_HEADER
|
|||
FT_Long mv_x, mv_y;
|
||||
FT_Byte *bitmap;
|
||||
FT_UInt raster;
|
||||
FT_UShort code;
|
||||
FT_ULong nglyphs;
|
||||
|
||||
} GF_BitmapRec, *GF_Bitmap;
|
||||
|
||||
|
@ -47,6 +57,11 @@ FT_BEGIN_HEADER
|
|||
FT_Int font_bbx_w, font_bbx_h;
|
||||
FT_Int font_bbx_xoff, font_bbx_yoff;
|
||||
|
||||
FT_ULong nencodings;
|
||||
GF_Encoding encodings;
|
||||
|
||||
FT_ULong nglyphs;
|
||||
|
||||
} GF_GlyphRec, *GF_Glyph;
|
||||
|
||||
|
||||
|
|
178
src/gf/gflib.c
178
src/gf/gflib.c
|
@ -43,6 +43,14 @@
|
|||
FT_Byte bit_table[] = {
|
||||
0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
|
||||
|
||||
typedef struct GF_CharOffsetRec_
|
||||
{
|
||||
FT_Long char_offset;
|
||||
FT_UShort code;
|
||||
FT_Short gid;
|
||||
|
||||
} GF_CharOffsetRec, *GF_CharOffset;
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* GF font utility functions.
|
||||
|
@ -111,12 +119,80 @@ FT_Byte bit_table[] = {
|
|||
return v;
|
||||
}
|
||||
|
||||
static int
|
||||
compare( FT_Long* a,
|
||||
FT_Long* b )
|
||||
{
|
||||
if ( *a < *b )
|
||||
return -1;
|
||||
else if ( *a > *b )
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* API.
|
||||
*
|
||||
*/
|
||||
|
||||
static FT_Error
|
||||
gf_set_encodings( GF_CharOffset of,
|
||||
FT_Int ngphs,
|
||||
GF_Glyph go,
|
||||
FT_Memory memory )
|
||||
{
|
||||
FT_Error error;
|
||||
FT_ULong nencoding;
|
||||
FT_Int i, j;
|
||||
FT_ULong k;
|
||||
GF_Encoding encoding = NULL;
|
||||
FT_Long *tosort;
|
||||
|
||||
nencoding = ngphs;
|
||||
FT_TRACE2(( "gf_set_encodings: Reached here.\n" ));
|
||||
|
||||
if ( FT_NEW_ARRAY( encoding, nencoding ) )
|
||||
return error;
|
||||
|
||||
if ( FT_NEW_ARRAY( tosort, nencoding ) )
|
||||
return error;
|
||||
|
||||
|
||||
FT_TRACE2(( "gf_set_encodings: Allocated sufficient memory.\n" ));
|
||||
|
||||
for( i = 0 ; i < 256 ; i++ )
|
||||
{
|
||||
if( of[i].char_offset >= 0 )
|
||||
tosort[i] = of[i].char_offset;
|
||||
}
|
||||
|
||||
ft_qsort( (void*)tosort, ngphs, sizeof(FT_Long),
|
||||
(int(*)(const void*, const void*) )compare );
|
||||
|
||||
k = 0;
|
||||
for ( i = 0; i < ngphs; i++ )
|
||||
{
|
||||
for ( j = 0; j < 256; j++ )
|
||||
{
|
||||
if( of[j].char_offset == tosort[i] )
|
||||
break;
|
||||
}
|
||||
encoding[k].enc = of[j].code;
|
||||
encoding[k].glyph = k;
|
||||
of[j].gid = k;
|
||||
k++;
|
||||
}
|
||||
|
||||
FT_FREE(tosort);
|
||||
|
||||
go->nencodings = k;
|
||||
go->encodings = encoding;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
FT_LOCAL_DEF( FT_Error )
|
||||
gf_read_glyph( FT_Stream stream,
|
||||
GF_Bitmap bm,
|
||||
|
@ -314,16 +390,17 @@ FT_Byte bit_table[] = {
|
|||
FT_Memory extmemory,
|
||||
GF_Glyph *goptr )
|
||||
{
|
||||
GF_Glyph go;
|
||||
GF_Bitmap bm;
|
||||
FT_Byte instr, d, pre, id, k, code;
|
||||
FT_Long ds, check_sum, hppp, vppp;
|
||||
FT_Long min_m, max_m, min_n, max_n, w;
|
||||
FT_UInt dx, dy;
|
||||
FT_Long ptr_post, ptr_p, ptr, optr;
|
||||
FT_Int bc, ec, nchars, i;
|
||||
FT_Error error = FT_Err_Ok;
|
||||
FT_Memory memory = extmemory; /* needed for FT_NEW */
|
||||
GF_Glyph go;
|
||||
GF_Bitmap bm;
|
||||
GF_CharOffset of;
|
||||
FT_Byte instr, d, pre, id, k, code;
|
||||
FT_Long ds, check_sum, hppp, vppp;
|
||||
FT_Long min_m, max_m, min_n, max_n, w;
|
||||
FT_UInt dx, dy;
|
||||
FT_Long ptr_post, ptr_p, ptr, optr, rptr;
|
||||
FT_Int bc, ec, nchars, i, ngphs, idx;
|
||||
FT_Error error = FT_Err_Ok;
|
||||
FT_Memory memory = extmemory; /* needed for FT_NEW */
|
||||
|
||||
go = NULL;
|
||||
nchars = -1;
|
||||
|
@ -502,10 +579,55 @@ FT_Byte bit_table[] = {
|
|||
go->code_min = bc;
|
||||
go->code_max = ec;
|
||||
|
||||
/* read glyph */
|
||||
#if 0
|
||||
fseek(fp, gptr, SEEK_SET);
|
||||
#endif
|
||||
go->nglyphs = 0;
|
||||
|
||||
if( FT_ALLOC_MULT(of, sizeof(GF_CharOffsetRec), nchars) )
|
||||
goto Exit;
|
||||
|
||||
for( i = 0; i < 256 ; i++)
|
||||
of[i].char_offset = -1;
|
||||
|
||||
rptr = stream->pos;
|
||||
i=0; ngphs=0;
|
||||
for ( ; ; )
|
||||
{
|
||||
if ((instr = READ_UINT1( stream )) == GF_POST_POST)
|
||||
break;
|
||||
switch ((FT_Int)instr)
|
||||
{
|
||||
case GF_CHAR_LOC:
|
||||
code = READ_UINT1( stream );
|
||||
dx = (FT_UInt)READ_INT4( stream )/(FT_UInt)(1<<16);
|
||||
dy = (FT_UInt)READ_INT4( stream )/(FT_UInt)(1<<16);
|
||||
w = READ_INT4( stream );
|
||||
ptr = READ_INT4( stream );
|
||||
break;
|
||||
case GF_CHAR_LOC0:
|
||||
code = READ_UINT1( stream );
|
||||
dx = (FT_UInt)READ_INT1( stream );
|
||||
dy = (FT_UInt)0;
|
||||
w = READ_INT4( stream );
|
||||
ptr = READ_INT4( stream );
|
||||
break;
|
||||
default:
|
||||
FT_ERROR(( "gf_load_font: missing character locators in postamble\n" ));
|
||||
error = FT_THROW( Unknown_File_Format );
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
of[i].char_offset = (FT_ULong)ptr;
|
||||
of[i].code = (FT_UShort)code;
|
||||
of[i].gid = -1;
|
||||
ngphs += 1;
|
||||
i++;
|
||||
}
|
||||
|
||||
error = gf_set_encodings( of, ngphs, go, memory );
|
||||
if( error )
|
||||
goto Exit;
|
||||
|
||||
if( FT_STREAM_SEEK( rptr ) )
|
||||
goto Exit;
|
||||
|
||||
for ( ; ; )
|
||||
{
|
||||
|
@ -533,27 +655,33 @@ FT_Byte bit_table[] = {
|
|||
goto Exit;
|
||||
}
|
||||
|
||||
/*
|
||||
if( w > max_m) Defined to use w
|
||||
{
|
||||
FT_ERROR(( "gf_load_font: invalid width in charloc\n" ));
|
||||
goto Exit;
|
||||
}
|
||||
*/
|
||||
|
||||
optr = stream->pos;
|
||||
if( FT_STREAM_SEEK( ptr ) )
|
||||
goto Exit;
|
||||
|
||||
bm = &go->bm_table[code - bc];
|
||||
for ( i = 0; i < 256; i++ )
|
||||
{
|
||||
if( of[i].code == code && of[i].char_offset == ptr )
|
||||
{
|
||||
idx = of[i].gid;
|
||||
break;
|
||||
}
|
||||
}
|
||||
bm = &go->bm_table[idx];
|
||||
|
||||
bm->mv_x = dx;
|
||||
bm->mv_y = dy;
|
||||
bm->code = code;
|
||||
go->nglyphs += 1;
|
||||
|
||||
if (gf_read_glyph( stream, bm, memory ) < 0)
|
||||
goto Exit;
|
||||
|
||||
bm->mv_x = dx;
|
||||
bm->mv_y = dy;
|
||||
if(FT_STREAM_SEEK( optr ))
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
FT_FREE(of);
|
||||
*goptr = go;
|
||||
return error;
|
||||
|
||||
|
|
Loading…
Reference in New Issue