📄 pcfread.c
字号:
FREE( face->metrics ); return error; } static FT_Error pcf_get_bitmaps( FT_Stream stream, PCF_Face face ) { FT_Error error = PCF_Err_Ok; FT_Memory memory = FT_FACE(face)->memory; FT_Long* offsets; FT_Long bitmapSizes[GLYPHPADOPTIONS]; FT_ULong format, size; int nbitmaps, i, sizebitmaps = 0; char* bitmaps; error = pcf_seek_to_table_type( stream, face->toc.tables, face->toc.count, PCF_BITMAPS, &format, &size ); if ( error ) return error; error = FT_Access_Frame( stream, 8 ); if ( error ) return error; format = GET_ULongLE(); if ( PCF_BYTE_ORDER( format ) == MSBFirst ) nbitmaps = GET_ULong(); else nbitmaps = GET_ULongLE(); FT_Forget_Frame( stream ); if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) ) return PCF_Err_Invalid_File_Format; if ( nbitmaps != face->nmetrics ) return PCF_Err_Invalid_File_Format; if ( ALLOC( offsets, nbitmaps * sizeof ( FT_ULong ) ) ) return error; for ( i = 0; i < nbitmaps; i++ ) { if ( PCF_BYTE_ORDER( format ) == MSBFirst ) (void)READ_Long( offsets[i] ); else (void)READ_LongLE( offsets[i] ); FT_TRACE4(( "bitmap %d is at offset %ld\n", i, offsets[i] )); } if ( error ) goto Bail; for ( i = 0; i < GLYPHPADOPTIONS; i++ ) { if ( PCF_BYTE_ORDER( format ) == MSBFirst ) (void)READ_Long( bitmapSizes[i] ); else (void)READ_LongLE( bitmapSizes[i] ); if ( error ) goto Bail; sizebitmaps = bitmapSizes[PCF_GLYPH_PAD_INDEX( format )]; FT_TRACE4(( "padding %d implies a size of %ld\n", i, bitmapSizes[i] )); } FT_TRACE4(( " %d bitmaps, padding index %ld\n", nbitmaps, PCF_GLYPH_PAD_INDEX( format ) )); FT_TRACE4(( "bitmap size = %d\n", sizebitmaps )); for ( i = 0; i < nbitmaps; i++ ) face->metrics[i].bits = stream->pos + offsets[i]; face->bitmapsFormat = format; FREE ( offsets ); return error; Bail: FREE ( offsets ); FREE ( bitmaps ); return error; } static FT_Error pcf_get_encodings( FT_Stream stream, PCF_Face face ) { FT_Error error = PCF_Err_Ok; FT_Memory memory = FT_FACE(face)->memory; FT_ULong format, size; int firstCol, lastCol; int firstRow, lastRow; int nencoding, encodingOffset; int i, j; PCF_Encoding tmpEncoding, encoding = 0; error = pcf_seek_to_table_type( stream, face->toc.tables, face->toc.count, PCF_BDF_ENCODINGS, &format, &size ); if ( error ) return error; error = FT_Access_Frame( stream, 14 ); if ( error ) return error; format = GET_ULongLE(); if ( PCF_BYTE_ORDER( format ) == MSBFirst ) { firstCol = GET_Short(); lastCol = GET_Short(); firstRow = GET_Short(); lastRow = GET_Short(); face->defaultChar = GET_Short(); } else { firstCol = GET_ShortLE(); lastCol = GET_ShortLE(); firstRow = GET_ShortLE(); lastRow = GET_ShortLE(); face->defaultChar = GET_ShortLE(); } FT_Forget_Frame( stream ); if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) ) return PCF_Err_Invalid_File_Format; FT_TRACE4(( "enc: firstCol %d, lastCol %d, firstRow %d, lastRow %d\n", firstCol, lastCol, firstRow, lastRow )); nencoding = ( lastCol - firstCol + 1 ) * ( lastRow - firstRow + 1 ); if ( ALLOC( tmpEncoding, nencoding * sizeof ( PCF_EncodingRec ) ) ) return PCF_Err_Out_Of_Memory; error = FT_Access_Frame( stream, 2 * nencoding ); if ( error ) goto Bail; for ( i = 0, j = 0 ; i < nencoding; i++ ) { if ( PCF_BYTE_ORDER( format ) == MSBFirst ) encodingOffset = GET_Short(); else encodingOffset = GET_ShortLE(); if ( encodingOffset != -1 ) { tmpEncoding[j].enc = ( ( ( i / ( lastCol - firstCol + 1 ) ) + firstRow ) * 256 ) + ( ( i % ( lastCol - firstCol + 1 ) ) + firstCol ); tmpEncoding[j].glyph = (FT_Short)encodingOffset; j++; } FT_TRACE4(( "enc n. %d ; Uni %ld ; Glyph %d\n", i, tmpEncoding[j - 1].enc, encodingOffset )); } FT_Forget_Frame( stream ); if ( ALLOC( encoding, (--j) * sizeof ( PCF_EncodingRec ) ) ) goto Bail; for ( i = 0; i < j; i++ ) { encoding[i].enc = tmpEncoding[i].enc; encoding[i].glyph = tmpEncoding[i].glyph; } face->nencodings = j; face->encodings = encoding; FREE( tmpEncoding ); return error; Bail: FREE( encoding ); FREE( tmpEncoding ); return error; } static const FT_Frame_Field pcf_accel_header[] = {#undef FT_STRUCTURE#define FT_STRUCTURE PCF_AccelRec FT_FRAME_START( 20 ), FT_FRAME_BYTE ( noOverlap ), FT_FRAME_BYTE ( constantMetrics ), FT_FRAME_BYTE ( terminalFont ), FT_FRAME_BYTE ( constantWidth ), FT_FRAME_BYTE ( inkInside ), FT_FRAME_BYTE ( inkMetrics ), FT_FRAME_BYTE ( drawDirection ), FT_FRAME_SKIP_BYTES( 1 ), FT_FRAME_LONG_LE ( fontAscent ), FT_FRAME_LONG_LE ( fontDescent ), FT_FRAME_LONG_LE ( maxOverlap ), FT_FRAME_END }; static const FT_Frame_Field pcf_accel_msb_header[] = {#undef FT_STRUCTURE#define FT_STRUCTURE PCF_AccelRec FT_FRAME_START( 20 ), FT_FRAME_BYTE ( noOverlap ), FT_FRAME_BYTE ( constantMetrics ), FT_FRAME_BYTE ( terminalFont ), FT_FRAME_BYTE ( constantWidth ), FT_FRAME_BYTE ( inkInside ), FT_FRAME_BYTE ( inkMetrics ), FT_FRAME_BYTE ( drawDirection ), FT_FRAME_SKIP_BYTES( 1 ), FT_FRAME_LONG ( fontAscent ), FT_FRAME_LONG ( fontDescent ), FT_FRAME_LONG ( maxOverlap ), FT_FRAME_END }; static FT_Error pcf_get_accel( FT_Stream stream, PCF_Face face, FT_ULong type ) { FT_ULong format, size; FT_Error error = PCF_Err_Ok; PCF_Accel accel = &face->accel; error = pcf_seek_to_table_type( stream, face->toc.tables, face->toc.count, type, &format, &size ); if ( error ) goto Bail; error = READ_ULongLE( format ); if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) && !PCF_FORMAT_MATCH( format, PCF_ACCEL_W_INKBOUNDS ) ) goto Bail; if ( PCF_BYTE_ORDER( format ) == MSBFirst ) { if ( READ_Fields( pcf_accel_msb_header, accel ) ) goto Bail; } else { if ( READ_Fields( pcf_accel_header, accel ) ) goto Bail; } error = pcf_get_metric( stream, format, &(accel->minbounds) ); if ( error ) goto Bail; error = pcf_get_metric( stream, format, &(accel->maxbounds) ); if ( error ) goto Bail; if ( PCF_FORMAT_MATCH( format, PCF_ACCEL_W_INKBOUNDS ) ) { error = pcf_get_metric( stream, format, &(accel->ink_minbounds) ); if ( error ) goto Bail; error = pcf_get_metric( stream, format, &(accel->ink_maxbounds) ); if ( error ) goto Bail; } else { accel->ink_minbounds = accel->minbounds; /* I'm not sure about this */ accel->ink_maxbounds = accel->maxbounds; } return error; Bail: return error; } FT_LOCAL_DEF FT_Error pcf_load_font( FT_Stream stream, PCF_Face face ) { FT_Error error = PCF_Err_Ok; FT_Memory memory = FT_FACE(face)->memory; FT_Bool hasBDFAccelerators; error = pcf_read_TOC( stream, face ); if ( error ) return error; error = pcf_get_properties( stream, face ); if ( error ) return error;; /* Use the old accelerators if no BDF accelerators are in the file. */ hasBDFAccelerators = pcf_has_table_type( face->toc.tables, face->toc.count, PCF_BDF_ACCELERATORS ); if ( !hasBDFAccelerators ) { error = pcf_get_accel( stream, face, PCF_ACCELERATORS ); if ( error ) goto Bail; } /* metrics */ error = pcf_get_metrics( stream, face ); if ( error ) goto Bail; /* bitmaps */ error = pcf_get_bitmaps( stream, face ); if ( error ) goto Bail; /* encodings */ error = pcf_get_encodings( stream, face ); if ( error ) goto Bail; /* BDF style accelerators (i.e. bounds based on encoded glyphs) */ if ( hasBDFAccelerators ) { error = pcf_get_accel( stream, face, PCF_BDF_ACCELERATORS ); if ( error ) goto Bail; } /* XXX: TO DO: inkmetrics and glyph_names are missing */ /* now construct the face object */ { FT_Face root = FT_FACE( face ); PCF_Property prop; int size_set = 0; root->num_faces = 1; root->face_index = 0; root->face_flags = FT_FACE_FLAG_FIXED_SIZES | FT_FACE_FLAG_HORIZONTAL | FT_FACE_FLAG_FAST_GLYPHS; if ( face->accel.constantWidth ) root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; root->style_flags = 0; prop = pcf_find_property( face, "SLANT" ); if ( prop != NULL ) if ( prop->isString ) if ( ( *(prop->value.atom) == 'O' ) || ( *(prop->value.atom) == 'I' ) ) root->style_flags |= FT_STYLE_FLAG_ITALIC; prop = pcf_find_property( face, "WEIGHT_NAME" ); if ( prop != NULL ) if ( prop->isString ) if ( *(prop->value.atom) == 'B' ) root->style_flags |= FT_STYLE_FLAG_BOLD; root->style_name = (char *)"Regular"; if ( root->style_flags & FT_STYLE_FLAG_BOLD ) { if ( root->style_flags & FT_STYLE_FLAG_ITALIC ) root->style_name = (char *)"Bold Italic"; else root->style_name = (char *)"Bold"; } else if ( root->style_flags & FT_STYLE_FLAG_ITALIC ) root->style_name = (char *)"Italic"; prop = pcf_find_property( face, "FAMILY_NAME" ); if ( prop != NULL ) { if ( prop->isString ) { int l = strlen( prop->value.atom ) + 1; if ( ALLOC( root->family_name, l * sizeof ( char ) ) ) goto Bail; strcpy( root->family_name, prop->value.atom ); } } else root->family_name = 0; root->num_glyphs = face->nmetrics; root->num_fixed_sizes = 1; if ( ALLOC_ARRAY( root->available_sizes, 1, FT_Bitmap_Size ) ) goto Bail; prop = pcf_find_property( face, "PIXEL_SIZE" ); if ( prop != NULL ) { root->available_sizes->height = root->available_sizes->width = (FT_Short)( prop->value.integer );#if 0 /* average width property support removed until maturation */ prop = pcf_find_property( face, "AVERAGE_WIDTH" ); if ( prop != NULL ) root->available_sizes->width = (FT_Short)( prop->value.integer / 10 );#endif size_set = 1; } else { prop = pcf_find_property( face, "POINT_SIZE" ); if ( prop != NULL ) { PCF_Property xres, yres, avgw; xres = pcf_find_property( face, "RESOLUTION_X" ); yres = pcf_find_property( face, "RESOLUTION_Y" ); avgw = pcf_find_property( face, "AVERAGE_WIDTH" ); if ( ( yres != NULL ) && ( xres != NULL ) ) { root->available_sizes->height = (FT_Short)( prop->value.integer * yres->value.integer / 720 ); #if 0 /* average width property support removed until maturation */ if ( avgw != NULL ) root->available_sizes->width = (FT_Short)( avgw->value.integer / 10 ); else#endif root->available_sizes->width = (FT_Short)( prop->value.integer * xres->value.integer / 720 ); size_set = 1; } } } if (size_set == 0 ) {#if 0 printf( "PCF Warning: Pixel Size undefined, assuming 12\n");#endif root->available_sizes->width = 12; root->available_sizes->height = 12; } /* XXX: charmaps. For now, report unicode for Unicode and Latin 1 */ root->charmaps = &face->charmap_handle; root->num_charmaps = 1; face->charmap.encoding = ft_encoding_none; face->charmap.platform_id = 0; face->charmap.encoding_id = 0; { PCF_Property charset_registry = 0, charset_encoding = 0; charset_registry = pcf_find_property( face, "CHARSET_REGISTRY" ); charset_encoding = pcf_find_property( face, "CHARSET_ENCODING" ); if ( ( charset_registry != NULL ) && ( charset_encoding != NULL ) ) { if ( ( charset_registry->isString ) && ( charset_encoding->isString ) ) { if ( ALLOC( face->charset_encoding, ( strlen( charset_encoding->value.atom ) + 1 ) * sizeof ( char ) ) ) goto Bail; if ( ALLOC( face->charset_registry, ( strlen( charset_registry->value.atom ) + 1 ) * sizeof ( char ) ) ) goto Bail; strcpy( face->charset_registry, charset_registry->value.atom ); strcpy( face->charset_encoding, charset_encoding->value.atom ); if ( !strcmp( face->charset_registry, "ISO10646" ) || ( !strcmp( face->charset_registry, "ISO8859" ) && !strcmp( face->charset_encoding, "1" ) ) ) { face->charmap.encoding = ft_encoding_unicode; face->charmap.platform_id = 3; face->charmap.encoding_id = 1; } } } } face->charmap.face = root; face->charmap_handle = &face->charmap; root->charmap = face->charmap_handle; } return PCF_Err_Ok; Bail: return PCF_Err_Invalid_File_Format; }/* END */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -