[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:
Parth Wazurkar 2018-08-12 11:36:33 +05:30
parent eba29d801e
commit 743b415ca9
3 changed files with 276 additions and 66 deletions

View File

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

View File

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

View File

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