diff --git a/src/tfm/tfm.c b/src/tfm/tfm.c new file mode 100644 index 000000000..055ed5ca0 --- /dev/null +++ b/src/tfm/tfm.c @@ -0,0 +1,25 @@ +/**************************************************************************** + * + * tfm.c + * + * FreeType auxiliary TFM module. + * + * Copyright 1996-2018 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. + * + */ + + +#define FT_MAKE_OPTION_SINGLE_OBJECT +#include + +#include "tfmmod.c" + + +/* END */ diff --git a/src/tfm/tfmobjs.c b/src/tfm/tfmobjs.c new file mode 100644 index 000000000..d725a4d7c --- /dev/null +++ b/src/tfm/tfmobjs.c @@ -0,0 +1,389 @@ +/**************************************************************************** + * + * tfmobjs.c + * + * FreeType auxiliary TFM module. + * + * Copyright 1996-2018 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 +#include "tfmobjs.h" +#include "tfmmod.h" +#include FT_INTERNAL_STREAM_H +#include "tfmerrors.h" + + + /************************************************************************** + * + * 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_tfmobjs + + + /************************************************************************** + * + * TFM font utility functions. + * + */ + + long tfm_read_intn(FT_Stream,int); + unsigned long tfm_read_uintn(FT_Stream,int); + +#define READ_UINT2( stream ) (UINT1)tfm_read_uintn( stream, 2) +#define READ_UINT4( stream ) (UINT1)tfm_read_uintn( stream, 4) +#define READ_INT4( stream ) (INT4)tfm_read_intn( stream, 4) + +/* + * Reading a Number from file + */ + unsigned long + tfm_read_uintn(FT_Stream stream, int size) + { + unsigned long v,k; + FT_Error error = FT_Err_Ok; + 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 + tfm_read_intn(FT_Stream stream, int size) + { + long v; + FT_Byte tp; + FT_Error error= FT_Err_Ok; + 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; + } + + /************************************************************************** + * + * API. + * + */ + + FT_LOCAL_DEF( FT_Error ) + tfm_init( TFM_Parser parser, + FT_Memory memory, + FT_Stream stream ) + { + FT_Error error; + + parser->memory = memory; + parser->stream = stream; + parser->FontInfo = NULL; + parser->user_data = NULL; + + return FT_Err_Ok; + } + + + FT_LOCAL( void ) + tfm_close( TFM_Parser parser ) + { + FT_Memory memory = parser->memory; + + FT_FREE( parser->stream ); + } + + + FT_LOCAL_DEF( FT_Error ) + tfm_parse_metrics( TFM_Parser parser ) + { + FT_Memory memory = parser->memory; + TFM_FontInfo fi = parser->FontInfo; + FT_Error error = FT_ERR( Syntax_Error ); + + FT_ULong lf, lh, nc, nci, err; + FT_ULong offset_header, offset_char_info, offset_param; + FT_ULong nw, nh, nd, ni, nl, nk, neng, np, dir; + + FT_Long *w, *h, *d; + FT_ULong *ci, v; + + FT_ULong i; + FT_Long bbxw, bbxh, xoff, yoff; + + if ( !fi ) + return FT_THROW( Invalid_Argument ); + + fi->width = NULL; + fi->height = NULL; + fi->depth = NULL; + + fi->font_bbx_w = 0.0; + fi->font_bbx_h = 0.0; + fi->font_bbx_xoff = 0.0; + fi->font_bbx_yoff = 0.0; + + err = 0; + /* rewind(fp); */ + if( FT_STREAM_SEEK( 0 ) ) + return error; + + lf = (UINT4)READ_UINT2( stream ); + + #if 0 + if ((lf == 11) || (lf == 9)) + { + /* JFM file of Japanese TeX by ASCII Coop. */ + tfm->type = METRIC_TYPE_JFM; + tfm->type_aux = (lf == 11)?METRIC_TYPE_JFM_AUX_H:METRIC_TYPE_JFM_AUX_V; + tfm->nt = (UINT4)READ_UINT2(fp); + lf = (UINT4)READ_UINT2(fp); + lh = (UINT4)READ_UINT2(fp); + offset_header = 4*7; + offset_char_info = 4*(7+tfm->nt+lh); + } + else if (lf == 0) + { + /* Omega Metric File */ + tfm->type = METRIC_TYPE_OFM; + tfm->type_aux = READ_INT2(fp); /* ofm_level */ + if ((tfm->type_aux < 0) || (1 < tfm->type_aux)) + tfm->type_aux = 0; /* broken, maybe */ + lf = READ_UINT4(fp); + lh = READ_UINT4(fp); + if (tfm->type_aux == 0) + { /* level 0 OFM */ + offset_header = 4*14; + offset_char_info = 4*(14+lh); + } + else + { /* level 1 OFM: *** NOT SUPPORTED YET *** */ + offset_header = 4*29; + offset_char_info = 4*(29+lh); + } + } + else + { } + #endif + /* Traditional TeX Metric File */ + lh = (int)READ_UINT2( stream ); + offset_header = 4*6; + offset_char_info = 4*(6+lh); + + #if 0 + if (tfm->type == METRIC_TYPE_OFM) + { + tfm->begin_char = READ_UINT4(fp); + tfm->end_char = READ_UINT4(fp); + nw = READ_UINT4(fp); + nh = READ_UINT4(fp); + nd = READ_UINT4(fp); + + ni = READ_UINT4(fp); + nl = READ_UINT4(fp); + nk = READ_UINT4(fp); + neng = READ_UINT4(fp); + np = READ_UINT4(fp); + dir = READ_UINT4(fp); + + if (((signed)(tfm->begin_char-1) > (signed)tfm->end_char) || + (tfm->end_char > 65535)) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + } + else + { } + #endif + fi->begin_char = (int)READ_UINT2( stream ); + fi->end_char = (int)READ_UINT2( stream ); + + nw = (UINT4)READ_UINT2( stream ); + nh = (UINT4)READ_UINT2( stream ); + nd = (UINT4)READ_UINT2( stream ); + + ni = (UINT4)READ_UINT2( stream ); + nl = (UINT4)READ_UINT2( stream ); + nk = (UINT4)READ_UINT2( stream ); + neng = (UINT4)READ_UINT2( stream ); + np = (UINT4)READ_UINT2( stream ); + + #if 0 + if (tfm->type == METRIC_TYPE_TFM) + {} + #endif + if (((signed)(fi->begin_char-1) > (signed)fi->end_char) || + (fi->end_char > 255)) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + /* fseek(fp, offset_header, SEEK_SET); */ + if (FT_STREAM_SEEK( offset_header ) ) + goto Exit; + fi->cs = READ_UINT4( stream ); + fi->ds = READ_UINT4( stream ); + fi->design_size = (double)(fi->ds)/(double)(1<<20); + + nc = fi->end_char - fi->begin_char + 1; + nci = nc; + #if 0 + if (tfm->type == METRIC_TYPE_OFM) + nci *= 2; + #endif + ci = (UINT4*)calloc(nci, sizeof(UINT4)); + w = (INT4*)calloc(nw, sizeof(UINT4)); + h = (INT4*)calloc(nh, sizeof(UINT4)); + d = (INT4*)calloc(nd, sizeof(UINT4)); + if ((ci == NULL) || (w == NULL) || (h == NULL) || (d == NULL)) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + /* fseek(fp, offset_char_info, SEEK_SET); */ + if( FT_STREAM_SEEK( offset_char_info ) ) + goto Exit; + for (i = 0; i < nci; i++) + ci[i] = READ_UINT4( stream ); + + /* offset_param = ftell(fp) + 4*(nw + nh + nd + ni + nl + nk + neng); */ + offset_param = stream->pos + 4*(nw + nh + nd + ni + nl + nk + neng); + + for (i = 0; i < nw; i++) + w[i] = READ_INT4( stream ); + for (i = 0; i < nh; i++) + h[i] = READ_INT4( stream ); + for (i = 0; i < nd; i++) + d[i] = READ_INT4( stream ); + + fi->width = (INT4*)calloc(nc, sizeof(INT4)); + fi->height = (INT4*)calloc(nc, sizeof(INT4)); + fi->depth = (INT4*)calloc(nc, sizeof(INT4)); + if ((fi->width == NULL) || (fi->height == NULL) || (fi->depth == NULL)) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + bbxw = 0; + bbxh = 0; + xoff = 0; + yoff = 0; + #if 0 + if (tfm->type == METRIC_TYPE_OFM) + { + for (i = 0; i < nc; i++) + { + v = ci[2*i]; + tfm->depth[i] = d[v & 0xff]; v >>= 8; + tfm->height[i] = h[v & 0xff]; v >>= 8; + tfm->width[i] = w[v & 0xffff]; + if (bbxw < tfm->width[i]) + bbxw = tfm->width[i]; + if (bbxh < (tfm->height[i] + tfm->depth[i])) + bbxh = tfm->height[i] + tfm->depth[i]; + if (yoff > -tfm->depth[i]) + yoff = -tfm->depth[i]; + #if 0 + printf("** %.3f %.3f %.3f\n", + (double)tfm->width[i]/(double)(1<<20), + (double)tfm->height[i]/(double)(1<<20), + (double)tfm->depth[i]/(double)(1<<20)); + #endif + } + } + else + { } + #endif + for (i = 0; i < nc; i++) + { + v = ci[i] / 0x10000L; + fi->depth[i] = d[v & 0xf]; v >>= 4; + fi->height[i] = h[v & 0xf]; v >>= 4; + fi->width[i] = w[v & 0xff]; + if (bbxw < fi->width[i]) + bbxw = fi->width[i]; + if (bbxh < (fi->height[i] + fi->depth[i])) + bbxh = fi->height[i] + fi->depth[i]; + if (yoff > -fi->depth[i]) + yoff = -fi->depth[i]; + #if 0 + printf("** %.3f %.3f\n", + (double)tfm->height[i]/(double)(1<<20), + (double)tfm->depth[i]/(double)(1<<20)); + #endif + } + fi->font_bbx_w = fi->design_size * ((double)bbxw / (double)(1<<20)); + fi->font_bbx_h = fi->design_size * ((double)bbxh / (double)(1<<20)); + fi->font_bbx_xoff = fi->design_size * ((double)xoff / (double)(1<<20)); + fi->font_bbx_yoff = fi->design_size * ((double)yoff / (double)(1<<20)); + + #if 0 + if (tfm->type == METRIC_TYPE_JFM) + { + fseek(fp, 4*(7+lh), SEEK_SET); + tfm->ct_kcode = (unsigned int*)calloc(tfm->nt+1, sizeof(unsigned int)); + tfm->ct_ctype = (unsigned int*)calloc(tfm->nt+1, sizeof(unsigned int)); + if ((tfm->ct_kcode == NULL) || (tfm->ct_ctype == NULL)) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + for (i = 0; i < tfm->nt; i++) + { + v = READ_UINT4(fp); + tfm->ct_kcode[i] = v/0x10000L; + tfm->ct_ctype[i] = v%0x10000L; + } + tfm->ct_kcode[tfm->nt] = 0; /* sentinel */ + tfm->ct_ctype[tfm->nt] = 0; + } + #endif + + /* fseek(fp, offset_param, SEEK_SET); */ + if( FT_STREAM_SEEK( offset_param ) ) + return error; /* To be changed */ + if (FT_READ_ULONG(fi->slant) ) + return error; + fi->slant = (double)fi->slant/(double)(1<<20); + + Exit: + FT_FREE(ci); + FT_FREE(w); + FT_FREE(h); + FT_FREE(d); + return error; + } + + +/* END */ diff --git a/src/tfm/tfmobjs.h b/src/tfm/tfmobjs.h new file mode 100644 index 000000000..be55dc84e --- /dev/null +++ b/src/tfm/tfmobjs.h @@ -0,0 +1,56 @@ +/**************************************************************************** + * + * tfmobjs.h + * + * FreeType auxiliary TFM module. + * + * Copyright 1996-2018 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 TFMOBJS_H_ +#define TFMOBJS_H_ + +#include +#include "tfmmod.h" + +FT_BEGIN_HEADER + + +#include +#include FT_INTERNAL_TFM_H + + +FT_BEGIN_HEADER + + /* Initialise the TFM stream */ + FT_LOCAL( FT_Error ) + tfm_init( TFM_Parser parser, + FT_Memory memory + FT_Stream stream ); + + /* Parse TFM metric data */ + FT_LOCAL( FT_Error ) + tfm_parse_metrics( TFM_Parser parser ); + + FT_LOCAL( FT_Error ) + tfm_parse_kerns( TFM_Parser parser ); + + FT_LOCAL( void ) + tfm_close( TFM_Parser parser ); + + +FT_END_HEADER + +#endif /* TFMOBJS_H_ */ + + +/* END */