summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorParth Wazurkar <parthwazurkar@gmail.com>2018-07-12 22:33:12 +0530
committerParth Wazurkar <parthwazurkar@gmail.com>2018-07-30 23:53:07 +0530
commit0d109109dfaf0dfdef997460b95f6ca512203412 (patch)
tree1c2d5bbf292ec04b803debefecd56c8bec39d6df
parent24f39cba3dad4a0709b97c878de695c1f54d9144 (diff)
downloadfreetype2-0d109109dfaf0dfdef997460b95f6ca512203412.tar.gz
[pk] Define `pk' font loader functions.
* src/pk/pk.h: Add `pk' format specific opcodes. * src/pk/pklib.c: Define `pk_font_load', `pk_free_font' and other format specific utility functions.
-rw-r--r--src/pk/pk.h24
-rw-r--r--src/pk/pklib.c490
2 files changed, 511 insertions, 3 deletions
diff --git a/src/pk/pk.h b/src/pk/pk.h
index c0ef30564..92028ca19 100644
--- a/src/pk/pk.h
+++ b/src/pk/pk.h
@@ -27,7 +27,29 @@
FT_BEGIN_HEADER
-/* TO-DO */
+#define FONT_DRIVER_PK 1
+
+#define PK_PRE 247
+#define PK_ID 89
+#define PK_XXX1 240
+#define PK_XXX2 241
+#define PK_XXX3 242
+#define PK_XXX4 243
+#define PK_YYY 244
+#define PK_POST 245
+#define PK_NO_OP 246
+
+/* Temporary TO BE REMOVED */
+
+typedef char INT1;
+typedef unsigned char UINT1;
+typedef int INT2;
+typedef unsigned int UINT2;
+typedef long INT3;
+typedef unsigned long UINT3;
+typedef long INT4;
+typedef unsigned long UINT4;
+
FT_END_HEADER
diff --git a/src/pk/pklib.c b/src/pk/pklib.c
index db4310b59..6274003ed 100644
--- a/src/pk/pklib.c
+++ b/src/pk/pklib.c
@@ -40,13 +40,237 @@
#undef FT_COMPONENT
#define FT_COMPONENT trace_pklib
+unsigned char bit_table[] = {
+ 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
+
+
/**************************************************************************
*
* PK font utility functions.
*
*/
- /* TO-DO */
+ long pk_read_intn(FT_Stream,int);
+ unsigned long pk_read_uintn(FT_Stream,int);
+
+#define READ_UINT1( stream ) (UINT1)pk_read_uintn( stream, 1)
+#define READ_UINTN( stream,n) (UINT4)pk_read_uintn( stream, n)
+#define READ_INT1( stream ) (INT1)pk_read_intn( stream, 1)
+#define READ_INT4( stream ) (INT4)pk_read_intn( stream, 4)
+
+/*
+ * Reading a Number from file
+ */
+ unsigned long
+ pk_read_uintn(FT_Stream stream, int size)
+ {
+ unsigned long v,k;
+ FT_Error error;
+ FT_Byte tp;
+ v = 0L;
+ while (size >= 1)
+ {
+ if ( FT_READ_BYTE(tp) )
+ return 0; /* To be changed */
+ k =(unsigned long)tp;
+ v = v*256L + k;
+ --size;
+ }
+ return v;
+ }
+
+ long
+ pk_read_intn(FT_Stream stream, int size)
+ {
+ long v;
+ FT_Byte tp;
+ FT_Error error;
+ unsigned long z ;
+ if ( FT_READ_BYTE(tp) )
+ return 0;/* To be changed */
+ z= (unsigned long)tp;
+ v = (long)z & 0xffL;
+ if (v & 0x80L)
+ v = v - 256L;
+ --size;
+ while (size >= 1)
+ {
+ if ( FT_READ_BYTE(tp) )
+ return 0;/* To be changed */
+ z= (unsigned long)tp;
+ v = v*256L + z;
+ --size;
+ }
+ return v;
+ }
+
+ int
+ pk_read_14(FT_Stream stream, int dyn_f, int bw, UINT4 rs, PK_Bitmap bm, long cc)
+ {
+ long x, y, x8, xm;
+ unsigned char *bm_ptr;
+ unsigned long bit16_buff;
+ int rest_bit16_buff;
+ static unsigned int mask_table[] =
+ { 0xdead, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xdead };
+
+ if (rs == 0)
+ return 0;
+
+ x8 = bm->bbx_width / 8;
+ xm = bm->bbx_width % 8;
+ bm_ptr = bm->bitmap;
+
+ bit16_buff = READ_UINT1( stream ) << 8;
+ rest_bit16_buff = 8;
+ --rs;
+
+ for(y = 0; y < bm->bbx_height; y++)
+ {
+ for(x = 0; x < x8; x++)
+ {
+ *(bm_ptr++) = bit16_buff >> 8;
+ rest_bit16_buff -= 8;
+ bit16_buff = (bit16_buff << 8) & 0xffff;
+ if (rs > 0)
+ {
+ bit16_buff |= (READ_UINT1( stream ) << (8 - rest_bit16_buff));
+ rest_bit16_buff += 8;
+ --rs;
+ }
+ }
+ if (xm != 0)
+ {
+ *(bm_ptr++) = (bit16_buff >> 8) & mask_table[xm];
+ rest_bit16_buff -= xm;
+ bit16_buff = (bit16_buff << xm) & 0xffff;
+ if (rest_bit16_buff < 8)
+ {
+ if (rs > 0)
+ {
+ bit16_buff |= (READ_UINT1( stream ) << (8 - rest_bit16_buff));
+ rest_bit16_buff += 8;
+ --rs;
+ }
+ }
+ }
+ }
+ return 0;
+ }
+
+ int
+ pk_read_n14(FT_Stream stream, int dyn_f, int bw, UINT4 rs, PK_Bitmap bm, long cc)
+ {
+ long x, y, xx, yy, repeat;
+ int bits, b_p;
+ unsigned char *p, *p0, *p1;
+
+ pk_read_nyble_init(rs);
+ p = bm->bitmap;
+ bw = 1-bw;
+ bits = 0;
+ for (y = 0; y < bm->bbx_height; )
+ {
+ b_p = 0;
+ repeat = 0;
+ p0 = p;
+ for (x = 0; x < bm->bbx_width; x++)
+ {
+ if (bits == 0)
+ {
+ bw = 1-bw;
+ if ((bits = pk_read_packed_number(&repeat, stream, dyn_f)) < 0)
+ return -1;
+ }
+ if (bw == 1)
+ *p = *p | bit_table[b_p];
+ --bits;
+ if (++b_p >= 8)
+ {
+ b_p = 0;
+ p++;
+ }
+ }
+ if (b_p != 0)
+ p++;
+ y++;
+ for (yy = 0; yy < repeat; yy++)
+ {
+ p1 = p0;
+ for (xx = 0; xx < bm->raster; xx++)
+ *(p++) = *(p1++);
+ y++;
+ }
+ }
+ return 0;
+ }
+
+ long
+ pk_read_packed_number(long* repeat, FT_Stream, int dyn_f)
+ {
+ int d, n;
+ long di;
+
+ entry:
+ d = pk_read_nyble( stream );
+ if (d == 0)
+ {
+ n = 0;
+ do
+ {
+ di = pk_read_nyble( stream );
+ n++;
+ }
+ while (di == 0);
+ for ( ; n > 0; n--)
+ di = di*16 + pk_read_nyble( stream );
+ return di - 15 + (13 - dyn_f)*16 + dyn_f;
+ }
+ if (d <= dyn_f)
+ return d;
+ if (d <= 13)
+ return (d - dyn_f - 1)*16 + pk_read_nyble( stream ) + dyn_f + 1;
+ *repeat = 1;
+ if (d == 14)
+ *repeat = pk_read_packed_number(repeat, stream, dyn_f);
+ goto entry;
+ }
+
+ int pk_read_nyble_rest_cnt;
+ int pk_read_nyble_max_bytes;
+
+ void
+ pk_read_nyble_init(int max)
+ {
+ pk_read_nyble_rest_cnt = 0;
+ pk_read_nyble_max_bytes = max;
+ }
+
+ int
+ pk_read_nyble(FT_Stream stream)
+ {
+ static UINT1 d;
+ int v;
+
+ switch (pk_read_nyble_rest_cnt)
+ {
+ case 0:
+ d = READ_UINT1( stream );
+ if (--pk_read_nyble_max_bytes < 0)
+ return -1L;
+ v = d / 0x10;
+ d = d % 0x10;
+ pk_read_nyble_rest_cnt = 1;
+ break;
+ case 1:
+ default:
+ v = d;
+ pk_read_nyble_rest_cnt = 0;
+ break;
+ }
+ return v;
+ }
+
/**************************************************************************
*
@@ -54,6 +278,268 @@
*
*/
- /* TO-DO */
+ FT_LOCAL_DEF( FT_Error )
+ pk_load_font(FT_Stream stream,
+ FT_Memory extmemory,
+ PK_Glyph *goptr )
+ {
+ PK_Glyph go;
+ UINT1 instr;
+ UINT4 ds, check_sum, hppp, vppp, k;
+ unsigned int flag, dny_f, bw, ess, size;
+ UINT4 cc, tfm, dx, dy, dm, w, h, rs;
+ INT4 hoff, voff, mv_x, mv_y;
+ long gptr;
+ int bc, ec, nchars, index, i;
+
+ k = READ_UINT1( stream );
+ if ( FT_STREAM_SKIP( k ) )
+ goto Exit;
+ ds = READ_UINT4( stream );
+ check_sum = READ_UINT4( stream );
+ hppp = READ_UINT4( stream );
+ vppp = READ_UINT4( stream );
+
+ /* gptr = ftell(fp); */
+ gptr = stream->pos;
+
+ #if 0
+ /* read min & max char code */
+ bc = 256;
+ ec = -1;
+ for (;;)
+ {
+ instr = READ_UINT1( stream );
+ if (instr == PK_POST)
+ break;
+ switch ((int) instr)
+ {
+ case PK_XXX1: k = (UINT4)READ_UINT1( stream ); if ( FT_STREAM_SKIP( k ) ) goto Exit; break;
+ case PK_XXX2: k = (UINT4)READ_UINT2( stream ); if ( FT_STREAM_SKIP( k ) ) goto Exit; break;
+ case PK_XXX3: k = (UINT4)READ_UINT3( stream ); if ( FT_STREAM_SKIP( k ) ) goto Exit; break;
+ case PK_XXX4: k = (UINT4)READ_UINT4( stream ); if ( FT_STREAM_SKIP( k ) ) goto Exit; break;
+ case PK_YYY: if ( FT_STREAM_SKIP( 4 ) ) goto Exit; break;
+ case PK_NO_OP: break;
+ default:
+ size = instr & 0x3; instr >>= 2;
+ ess = instr & 0x1;
+ if (ess == 0)
+ { /* short */
+ rs = (UINT4)(size*256) + (UINT4)READ_UINT1( stream );
+ cc = (UINT4)READ_UINT1( stream );
+ }
+ else if ((ess == 1) && (size != 3))
+ { /* extended short */
+ rs = (UINT4)(size*65536) + (UINT4)READ_UINT2( stream );
+ cc = (UINT4)READ_UINT1( stream );
+ }
+ else
+ { /* standard */
+ rs = READ_UINT4( stream );
+ cc = (UINT4)READ_UINT4( stream );
+ }
+ if ( FT_STREAM_SKIP( rs ) )
+ goto Exit;
+ if (cc < bc)
+ bc = cc;
+ if (cc > ec)
+ ec = cc;
+ break;
+ }
+ }
+ #else
+ bc = 0;
+ ec = 255;
+ #endif
+
+ nchars = ec - bc + 1;
+ if( FT_ALLOC(go, sizeof(PK_GlyphRec)) )
+ goto Exit;
+
+ if( FT_ALLOC_MULT(go->bm_table, sizeof(PK_BitmapRec), nchars) )
+ goto Exit;
+
+ for (i = 0; i < nchars; i++)
+ go->bm_table[i].bitmap = NULL;
+
+ go->ds = (double)ds/(1<<20);
+ go->hppp = (double)hppp/(1<<16);
+ go->vppp = (double)vppp/(1<<16);
+ go->font_bbx_w = 0;
+ go->font_bbx_h = 0;
+ go->font_bbx_xoff = 0;
+ go->font_bbx_yoff = 0;
+ go->code_min = bc;
+ go->code_max = ec;
+
+ /* read glyphs */
+ /* fseek(fp, gptr, SEEK_SET); */
+ if( FT_STREAM_SEEK( gptr ) )
+ goto Exit;
+
+ for (;;)
+ {
+ if ((instr = READ_UINT1( stream )) == PK_POST)
+ break;
+ switch ((int)instr)
+ {
+ case PK_XXX1:
+ k = (UINT4)READ_UINT1( stream );
+ if ( FT_STREAM_SKIP( k ) )
+ goto Exit;
+ break;
+ case PK_XXX2:
+ k = (UINT4)READ_UINT2( stream );
+ if ( FT_STREAM_SKIP( k ) )
+ goto Exit;
+ break;
+ case PK_XXX3:
+ k = (UINT4)READ_UINT3( stream );
+ if ( FT_STREAM_SKIP( k ) )
+ goto Exit;
+ break;
+ case PK_XXX4:
+ k = (UINT4)READ_UINT4( stream );
+ if ( FT_STREAM_SKIP( k ) )
+ goto Exit;
+ break;
+ case PK_YYY:
+ if ( FT_STREAM_SKIP( 4 ) )
+ goto Exit;
+ break;
+ case PK_NO_OP:
+ break;
+ default:
+ flag = instr;
+ size = flag % 0x04; flag = flag >> 2;
+ ess = flag % 0x02; flag = flag >> 1;
+ bw = flag % 0x02; flag = flag >> 1;
+ dny_f = flag % 0x10;
+ if (ess == 0)
+ { /* short */
+ rs = (UINT4)(size*256) + (UINT4)READ_UINT1( stream ) - (UINT4)8;
+ cc = (UINT4)READ_UINT1( stream );
+ tfm = (UINT4)READ_UINT3( stream );
+ dm = (UINT4)READ_UINT1( stream );
+ w = (UINT4)READ_UINT1( stream );
+ h = (UINT4)READ_UINT1( stream );
+ hoff = (INT4)READ_INT1( stream );
+ voff = (INT4)READ_INT1( stream );
+ mv_x = dm;
+ mv_y = 0;
+ }
+ else if ((ess == 1) && (size != 3))
+ { /* extended short */
+ rs = (UINT4)(size*65536) + (UINT4)READ_UINT2( stream ) - (UINT4)13;
+ cc = (UINT4)READ_UINT1( stream );
+ tfm = (UINT4)READ_UINT3( stream );
+ dm = (UINT4)READ_UINT2( stream );
+ w = (UINT4)READ_UINT2( stream );
+ h = (UINT4)READ_UINT2( stream );
+ hoff = (INT4)READ_INT2( stream );
+ voff = (INT4)READ_INT2( stream );
+ mv_x = dm;
+ mv_y = 0;
+ }
+ else
+ { /* standard */
+ rs = READ_UINT4( stream ) - (UINT4)28;
+ cc = READ_UINT4( stream );
+ tfm = READ_UINT4( stream );
+ dx = READ_UINT4( stream );
+ dy = READ_UINT4( stream );
+ w = READ_UINT4( stream );
+ h = READ_UINT4( stream );
+ hoff = READ_INT4( stream );
+ voff = READ_INT4( stream );
+ mv_x = (double)dx/(double)(1<<16);
+ mv_y = (double)dy/(double)(1<<16);
+ }
+
+ if ((cc < go->code_min) || (go->code_max < cc))
+ {
+ error = FT_THROW( Invalid_File_Format );
+ goto Exit;
+ }
+ index = cc - go->code_min;
+ go->bm_table[index].bbx_width = w;
+ go->bm_table[index].bbx_height = h;
+ go->bm_table[index].raster = (w+7)/8;
+ go->bm_table[index].off_x = -hoff;
+ go->bm_table[index].off_y = voff;
+ go->bm_table[index].mv_x = mv_x;
+ go->bm_table[index].mv_y = mv_y;
+ go->bm_table[index].bitmap = (unsigned char*)malloc(h*((w+7)/8));
+
+ if (go->bm_table[index].bitmap == NULL)
+ {
+ error = FT_THROW( Invalid_File_Format );
+ goto Exit;
+ }
+
+ memset(go->bm_table[index].bitmap, 0, h*((w+7)/8));
+
+ if (dny_f == 14)
+ {
+ if (pk_read_14(stream, dny_f, bw, rs, &(go->bm_table[index]), cc) < 0)
+ {
+ /* vf_error = VF_ERR_ILL_FONT_FILE; (FOR TRACING) */
+ error = FT_THROW( Invalid_File_Format );
+ goto Exit;
+ }
+ }
+ else
+ {
+ if (pk_read_n14(stream, dny_f, bw, rs, &(go->bm_table[index]), cc) < 0)
+ {
+ /* vf_error = VF_ERR_ILL_FONT_FILE; (FOR TRACING) */
+ error = FT_THROW( Invalid_File_Format );
+ goto Exit;
+ }
+ }
+ if (go->font_bbx_w < w)
+ go->font_bbx_w = w;
+ if (go->font_bbx_h < h)
+ go->font_bbx_h = h;
+ if (go->font_bbx_xoff > -hoff)
+ go->font_bbx_xoff = -hoff;
+ if (go->font_bbx_yoff > (voff - h))
+ go->font_bbx_yoff = (voff - h);
+ }
+ }
+ *goptr = go;
+ return error;
+
+ Exit:
+ for (i = 0; i < nchars; i++)
+ {
+ if (go->bm_table[i].bitmap != NULL)
+ FT_FREE(go->bm_table[i].bitmap);
+ }
+ FT_FREE(go->bm_table);
+ FT_FREE(go);
+ }
+
+ FT_LOCAL_DEF( void )
+ pk_free_font( PK_Face face )
+ {
+ FT_Memory memory = FT_FACE( face )->memory;
+ GF_Glyph go = face->pk_glyph;
+ FT_UInt nchars = FT_FACE( face )->num_glyphs,i;
+
+ if ( !go )
+ return;
+
+ if( go->bm_table )
+ {
+ for (i = 0; i < nchars; i++)
+ {
+ if (go->bm_table[i].bitmap != NULL)
+ FT_FREE(go->bm_table[i].bitmap);
+ }
+ }
+ FT_FREE(go->bm_table);
+ FT_FREE(go);
+ }
/* END */