summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorParth Wazurkar <parthwazurkar@gmail.com>2018-08-10 00:54:24 +0530
committerParth Wazurkar <parthwazurkar@gmail.com>2018-08-10 00:54:24 +0530
commit7ea68ac9f3bfc20f2c6408f21ae82c880c217ba2 (patch)
tree395929896aa32097c4ade395714e67c4eabae300
parent44d9f10ac8d720ff95765c9785b22795a2ccb2ec (diff)
downloadfreetype2-7ea68ac9f3bfc20f2c6408f21ae82c880c217ba2.tar.gz
[gf] Change logic to load bitmap on demand.
Also load glyphs in the order they appear in the font file by changing the cmap scheme and implementing a proper `gf cmap'.
-rw-r--r--src/gf/gfdrivr.c197
-rw-r--r--src/gf/gfdrivr.h36
-rw-r--r--src/gf/gflib.c234
3 files changed, 291 insertions, 176 deletions
diff --git a/src/gf/gfdrivr.c b/src/gf/gfdrivr.c
index 2994b3bb4..50de121a8 100644
--- a/src/gf/gfdrivr.c
+++ b/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;
+
+
+ mid = ( min + max ) >> 1;
+ code = (FT_ULong)encodings[mid].enc;
+
+ if ( charcode == code )
+ {
+ result = encodings[mid].glyph;
+ break;
+ }
- return gindex;
+ 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 )
- {
- result = cmap->bc;
- gindex = 1;
- }
- else
+ min = 0;
+ max = cmap->num_encodings;
+
+ while ( min < max )
{
- char_code -= cmap->bc;
- if ( char_code < cmap->ec - cmap->bc + 1 )
+ FT_ULong code;
+
+
+ mid = ( min + max ) >> 1;
+ code = (FT_ULong)encodings[mid].enc;
+
+ if ( charcode == code )
{
- result = char_code;
- gindex = (FT_UInt)( char_code );
+ result = encodings[mid].glyph + 1;
+ goto Exit;
}
+
+ if ( charcode < code )
+ max = mid;
+ else
+ min = mid + 1;
}
- *achar_code = result;
- return gindex;
+ 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
+ *acharcode = (FT_UInt32)charcode;
+ return result;
}
@@ -163,7 +207,6 @@
FT_Error error = FT_Err_Ok;
FT_Memory memory = FT_FACE_MEMORY( face );
GF_Glyph go=NULL;
- FT_UInt16 i,count;
TFM_Service tfm;
@@ -197,9 +240,9 @@
face->gf_glyph = go ;
/* sanity check */
- if ( !face->gf_glyph->bm_table )
+ if ( !face->gf_glyph->metrics )
{
- FT_TRACE2(( "glyph bitmaps not allocated\n" ));
+ FT_TRACE2(( "glyph metrics missing\n" ));
error = FT_THROW( Invalid_File_Format );
goto Exit;
}
@@ -230,13 +273,7 @@
*/
gfface->family_name = NULL;
- count=0;
- for (i = 0; i < 256; i++)
- {
- if(go->bm_table[i].bitmap != NULL)
- count++;
- }
- gfface->num_glyphs = (FT_Long)count;
+ gfface->num_glyphs = (FT_Long)face->gf_glyph->nglyphs;
FT_TRACE4(( " number of glyphs: allocated %d\n",gfface->num_glyphs ));
@@ -270,15 +307,36 @@
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 );
@@ -365,10 +423,13 @@
{
GF_Face gf = (GF_Face)FT_SIZE_FACE( size );
FT_Face face = FT_FACE( gf );
+ FT_Stream stream;
FT_Error error = FT_Err_Ok;
FT_Bitmap* bitmap = &slot->bitmap;
- GF_BitmapRec bm;
+ GF_MetricRec metric;
GF_Glyph go;
+ FT_ULong bytes;
+ FT_Byte *bitmp;
go = gf->gf_glyph;
@@ -387,7 +448,7 @@
goto Exit;
}
- FT_TRACE1(( "GF_Glyph_Load: glyph index %d\n", glyph_index ));
+ FT_TRACE1(( "GF_Glyph_Load: glyph index %d and charcode is %d\n", glyph_index, go->metrics[glyph_index].code ));
if ( (FT_Int)glyph_index < 0 )
glyph_index = 0;
@@ -399,44 +460,36 @@
goto Exit;
}
- if ( !go->bm_table )
- {
- FT_TRACE2(( "invalid bitmap table\n" ));
- error = FT_THROW( Invalid_File_Format );
- goto Exit;
- }
+ stream = gf->root.stream;
+ metric = gf->gf_glyph->metrics[glyph_index];
- /* slot, bitmap => freetype, bm => gflib */
- bm = gf->gf_glyph->bm_table[glyph_index];
+ error = gf_read_glyph( stream,
+ &metric );
- bitmap->rows = bm.bbx_height;
- bitmap->width = bm.bbx_width;
+ bitmap->rows = metric.bbx_height;
+ bitmap->width = metric.bbx_width;
bitmap->pixel_mode = FT_PIXEL_MODE_MONO;
- if ( !bm.raster )
- {
- FT_TRACE2(( "invalid bitmap width\n" ));
- error = FT_THROW( Invalid_File_Format );
- goto Exit;
- }
-
- bitmap->pitch = (int)bm.raster ;
+ bitmap->pitch = (int)( metric.raster );
/* note: we don't allocate a new array to hold the bitmap; */
/* we can simply point to it */
- ft_glyphslot_set_bitmap( slot, bm.bitmap );
+ ft_glyphslot_set_bitmap( slot, metric.bitmap );
+
slot->format = FT_GLYPH_FORMAT_BITMAP;
- slot->bitmap_left = bm.off_x ;
- slot->bitmap_top = bm.off_y ;
+ slot->bitmap_left = metric.off_x ;
+ slot->bitmap_top = metric.off_y ;
- slot->metrics.horiAdvance = (FT_Pos) (bm.mv_x ) * 64;
- slot->metrics.horiBearingX = (FT_Pos) (bm.off_x ) * 64;
- slot->metrics.horiBearingY = (FT_Pos) (bm.bbx_height) * 64;
+ slot->metrics.horiAdvance = (FT_Pos) ( metric.mv_x ) * 64;
+ slot->metrics.horiBearingX = (FT_Pos) ( metric.off_x ) * 64;
+ slot->metrics.horiBearingY = (FT_Pos) ( metric.bbx_height) * 64;
slot->metrics.width = (FT_Pos) ( bitmap->width * 64 );
slot->metrics.height = (FT_Pos) ( bitmap->rows * 64 );
- ft_synthesize_vertical_metrics( &slot->metrics, bm.bbx_height * 64 );
+ ft_synthesize_vertical_metrics( &slot->metrics, metric.bbx_height * 64 );
+
+ /* XXX: to do: are there cases that need repadding the bitmap? */
Exit:
return error;
diff --git a/src/gf/gfdrivr.h b/src/gf/gfdrivr.h
index 4fd8d2e27..34145ff45 100644
--- a/src/gf/gfdrivr.h
+++ b/src/gf/gfdrivr.h
@@ -27,25 +27,43 @@
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_
+ typedef struct GF_MetricRec_
{
- FT_Int bbx_width, bbx_height;
- FT_Int off_x, off_y;
- FT_Int mv_x, mv_y;
+ FT_Long bbx_width, bbx_height;
+ FT_Long off_x, off_y;
+ FT_Long mv_x, mv_y;
FT_Byte *bitmap;
FT_UInt raster;
+ FT_Long char_offset;
+ FT_UShort code;
- } GF_BitmapRec, *GF_Bitmap;
-
+ } GF_MetricRec, *GF_Metric;
typedef struct GF_GlyphRec_
{
FT_UInt code_min, code_max;
- GF_Bitmap bm_table;
+
+ FT_ULong nmetrics;
+ GF_Metric metrics;
+ FT_ULong nglyphs;
+ FT_ULong nencodings;
+ GF_Encoding encodings;
+
+ FT_Short defaultChar; /* To be checked */
+
FT_Int ds, hppp, vppp;
- FT_Int font_bbx_w, font_bbx_h;
- FT_Int font_bbx_xoff, font_bbx_yoff;
+ FT_Int font_bbx_w, font_bbx_h;
+ FT_Int font_bbx_xoff, font_bbx_yoff;
+ FT_Int check_sum;
} GF_GlyphRec, *GF_Glyph;
diff --git a/src/gf/gflib.c b/src/gf/gflib.c
index 25bb3b6bb..9e922a34d 100644
--- a/src/gf/gflib.c
+++ b/src/gf/gflib.c
@@ -111,26 +111,116 @@ 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_Glyph go,
+ FT_Memory memory )
+ {
+ FT_Error error;
+ FT_ULong nencoding;
+ FT_UInt i, j;
+ FT_ULong k;
+ GF_Encoding encoding = NULL;
+ GF_Metric metric;
+ FT_Long *tosort;
+
+ nencoding = go->nglyphs;
+ FT_TRACE2(( "gf_set_encodings: Reached here.\n" ));
+
+ if ( FT_NEW_ARRAY( metric, go->code_max - go->code_min + 1 ) )
+ return error;
+
+ 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( go->metrics[i].char_offset >= 0 )
+ tosort[i] = go->metrics[i].char_offset;
+ }
+
+ ft_qsort( (void*)tosort, go->nglyphs, sizeof(FT_Long),
+ (int(*)(const void*, const void*) )compare );
+
+ for( i = 0 ; i < go->nglyphs ; i++ )
+ {
+ /* FT_TRACE2(( "tosort[%d]is %ld\n",i,tosort[i] )); */
+ }
+
+ k = 0;
+ for ( i = 0; i < go->nglyphs; i++ )
+ {
+ for ( j = 0; j < 256; j++ )
+ {
+ if( go->metrics[j].char_offset == tosort[i] )
+ break;
+ }
+ metric[k].char_offset = go->metrics[j].char_offset;
+ metric[k].code = go->metrics[j].code;
+ /* FT_TRACE2(( "metric[%d].char_offset is %ld %ld% ld\n",k,metric[k].char_offset,metric[k].code,k )); */
+ encoding[k].enc = go->metrics[j].code;
+ encoding[k].glyph = k;
+ k++;
+ }
+
+ for( i = 0 ; i < go->nglyphs ; i++ )
+ {
+ go->metrics[i].char_offset = metric[i].char_offset;
+ go->metrics[i].code = metric[i].code;
+ /* FT_TRACE2(( "Hi I am here go->metrics[%d].char_offset is %ld %ld% ld\n",i,
+ go->metrics[i].char_offset,go->metrics[i].code,i )); */
+ }
+
+ FT_FREE(metric);
+
+ go->nencodings = k;
+ go->encodings = encoding;
+
+ return error;
+ }
+
FT_LOCAL_DEF( FT_Error )
gf_read_glyph( FT_Stream stream,
- GF_Bitmap bm,
- FT_Memory memory )
+ GF_MetricRec *metrics )
{
FT_Long m, n;
FT_Int paint_sw;
FT_Int instr,inst;
FT_Long min_m, max_m, min_n, max_n, del_m, del_n;
FT_Long w, h, d;
- FT_Int m_b, k;
- FT_Byte *ptr;
+ FT_Int k;
+ /* FT_Int m_b;
+ FT_Byte *ptr; */
FT_Error error = FT_Err_Ok;
+ if( FT_STREAM_SEEK( metrics->char_offset ) )
+ return 0;
+
+ FT_TRACE2(( "In gf_read_glyph\n" ));
+
for ( ; ; )
{
inst = READ_UINT1( stream );
@@ -203,19 +293,25 @@ FT_Byte bit_table[] = {
return -1;
}
+ /* FT_TRACE2(( "w is %ld\n"
+ "h is %ld\n"
+ "-min_m is %ld\n"
+ "max_n is %ld\n\n", w, h, -min_m, max_n ));
+ */
+
/* allocate and build bitmap */
- if ((bm->bitmap = (FT_Byte*)malloc(h*((w+7)/8))) == NULL)
+ if ((metrics->bitmap = (FT_Byte*)malloc(h*((w+7)/8))) == NULL)
{
error = FT_THROW( Invalid_File_Format );
return -1;
}
- memset(bm->bitmap, 0, h*((w+7)/8));
- bm->raster = (FT_UInt)(w+7)/8;
- bm->bbx_width = w;
- bm->bbx_height = h;
- bm->off_x = -min_m;
- bm->off_y = max_n;
+ memset(metrics->bitmap, 0, h*((w+7)/8));
+ metrics->raster = (FT_UInt)(w+7)/8;
+ metrics->bbx_width = w;
+ metrics->bbx_height = h;
+ metrics->off_x = -min_m;
+ metrics->off_y = max_n;
#if 0
bm->mv_x = -min_m;
bm->mv_y = max_n;
@@ -256,6 +352,7 @@ FT_Byte bit_table[] = {
}
else
{
+ /*
ptr = &bm->bitmap[(max_n - n) * bm->raster + (m - min_m)/8];
m_b = (m - min_m) % 8;
while (d > 0)
@@ -269,6 +366,7 @@ FT_Byte bit_table[] = {
}
d--;
}
+ */
}
paint_sw = 1 - paint_sw;
break;
@@ -299,8 +397,6 @@ FT_Byte bit_table[] = {
case GF_NO_OP:
break;
default:
- FT_FREE(bm->bitmap);
- bm->bitmap = NULL;
error = FT_THROW( Invalid_File_Format );
return -1;
}
@@ -315,12 +411,11 @@ FT_Byte bit_table[] = {
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_Long ptr_post, ptr_p, ptr;
FT_Int bc, ec, nchars, i;
FT_Error error = FT_Err_Ok;
FT_Memory memory = extmemory; /* needed for FT_NEW */
@@ -428,70 +523,29 @@ FT_Byte bit_table[] = {
FT_TRACE5(( "gf_load_font: checksum is %ld\n",check_sum ));
- if( ptr_p < 0 ) /* Defined to use ptr_p */
+ if( ptr_p < 0 )
{
FT_ERROR(( "gf_load_font: invalid pointer in postamble\n" ));
goto Exit;
}
- if( check_sum < 0 ) /* Defined to use check_sum */
+ if( check_sum < 0 )
{
FT_ERROR(( "gf_load_font: invalid check sum value\n" ));
goto Exit;
}
- #if 0
- gptr = ftell(fp);
- #endif
-
- #if 0
- /* read min & max char code */
- bc = 256;
- ec = -1;
- for ( ; ; )
- {
- instr = READ_UINT1(fp);
- if (instr == GF_POST_POST)
- {
- break;
- }
- else if (instr == GF_CHAR_LOC)
- {
- code = READ_UINT1(fp);
- (void)SKIP_N(fp, 16);
- }
- else if (instr == GF_CHAR_LOC0)
- {
- code = READ_UINT1(fp);
- (void)SKIP_N(fp, 9);
- }
- else
- {
- error = FT_THROW( Invalid_File_Format );
- goto Exit;
- }
- if (code < bc)
- bc = code;
- if (code > ec)
- ec = code;
- }
- #else
- bc = 0;
- ec = 255;
- #endif
+
+ bc = 0;
+ ec = 255;
nchars = ec - bc + 1;
if( FT_ALLOC(go, sizeof(GF_GlyphRec)) )
goto Exit;
- if( FT_ALLOC_MULT(go->bm_table, sizeof(GF_BitmapRec), nchars) )
- goto Exit;
-
- FT_TRACE2(( "gf_load_font: Allocated bitmap table\n" ));
-
- for (i = 0; i < nchars; i++)
- go->bm_table[i].bitmap = NULL;
+ FT_TRACE5(( "gf_load_font: Allocated GF_GlyphRec\n" ));
+ go->check_sum = check_sum;
go->ds = (FT_UInt)ds/(1<<20);
go->hppp = (FT_UInt)hppp/(1<<16);
go->vppp = (FT_UInt)vppp/(1<<16);
@@ -502,10 +556,15 @@ 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_NEW_ARRAY( go->metrics, nchars ) )
+ goto Exit;
+
+ FT_TRACE5(( "gf_load_font: Allocated go->metrics array\n" ));
+
+ for( i = 0; i < 256 ; i++)
+ go->metrics[i].char_offset = -1;
for ( ; ; )
{
@@ -533,39 +592,27 @@ 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;
+ go->metrics[code - bc].mv_x = dx;
+ go->metrics[code - bc].mv_y = dy;
+ go->metrics[code - bc].char_offset = (FT_ULong)ptr;
+ go->metrics[code - bc].code = (FT_UShort)code;
+ go->nglyphs += 1;
+ }
- bm = &go->bm_table[code - bc];
- if (gf_read_glyph( stream, bm, memory ) < 0)
- goto Exit;
+ error = gf_set_encodings( go, memory );
+ if( error )
+ goto Exit;
- bm->mv_x = dx;
- bm->mv_y = dy;
- if(FT_STREAM_SEEK( optr ))
- goto Exit;
- }
*goptr = go;
return error;
Exit:
if (go != NULL)
{
- if( go->bm_table )
+ if(go->metrics != NULL)
{
- for (i = 0; i < nchars; i++)
- FT_FREE(go->bm_table[i].bitmap);
+ FT_FREE(go->metrics);
}
- FT_FREE(go->bm_table);
FT_FREE(go);
}
return error;
@@ -577,17 +624,14 @@ FT_Byte bit_table[] = {
{
FT_Memory memory = FT_FACE( face )->memory;
GF_Glyph go = face->gf_glyph;
- FT_UInt nchars = FT_FACE( face )->num_glyphs,i;
if ( !go )
return;
- if( go->bm_table )
+ if(go->metrics != NULL)
{
- for (i = 0; i < nchars; i++)
- FT_FREE(go->bm_table[i].bitmap);
+ FT_FREE(go->metrics);
}
- FT_FREE(go->bm_table);
FT_FREE(go);
}