📄 pcfread.c
字号:
( metrics + i )->descent, ( metrics + i )->attributes )); if ( error ) break; } if ( error ) FT_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_Stream_EnterFrame( stream, 8 ); if ( error ) return error; format = FT_GET_ULONG_LE(); if ( PCF_BYTE_ORDER( format ) == MSBFirst ) nbitmaps = FT_GET_ULONG(); else nbitmaps = FT_GET_ULONG_LE(); FT_Stream_ExitFrame( 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 ( FT_NEW_ARRAY( offsets, nbitmaps ) ) return error; for ( i = 0; i < nbitmaps; i++ ) { if ( PCF_BYTE_ORDER( format ) == MSBFirst ) (void)FT_READ_LONG( offsets[i] ); else (void)FT_READ_LONG_LE( 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)FT_READ_LONG( bitmapSizes[i] ); else (void)FT_READ_LONG_LE( 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 )); FT_UNUSED( sizebitmaps ); /* only used for debugging */ for ( i = 0; i < nbitmaps; i++ ) face->metrics[i].bits = stream->pos + offsets[i]; face->bitmapsFormat = format; FT_FREE ( offsets ); return error; Bail: FT_FREE ( offsets ); FT_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_Stream_EnterFrame( stream, 14 ); if ( error ) return error; format = FT_GET_ULONG_LE(); if ( PCF_BYTE_ORDER( format ) == MSBFirst ) { firstCol = FT_GET_SHORT(); lastCol = FT_GET_SHORT(); firstRow = FT_GET_SHORT(); lastRow = FT_GET_SHORT(); face->defaultChar = FT_GET_SHORT(); } else { firstCol = FT_GET_SHORT_LE(); lastCol = FT_GET_SHORT_LE(); firstRow = FT_GET_SHORT_LE(); lastRow = FT_GET_SHORT_LE(); face->defaultChar = FT_GET_SHORT_LE(); } FT_Stream_ExitFrame( 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 ( FT_NEW_ARRAY( tmpEncoding, nencoding ) ) return PCF_Err_Out_Of_Memory; error = FT_Stream_EnterFrame( stream, 2 * nencoding ); if ( error ) goto Bail; for ( i = 0, j = 0 ; i < nencoding; i++ ) { if ( PCF_BYTE_ORDER( format ) == MSBFirst ) encodingOffset = FT_GET_SHORT(); else encodingOffset = FT_GET_SHORT_LE(); 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_Stream_ExitFrame( stream ); if ( FT_NEW_ARRAY( encoding, j ) ) 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; FT_FREE( tmpEncoding ); return error; Bail: FT_FREE( encoding ); FT_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 = FT_READ_ULONG_LE( 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 ( FT_STREAM_READ_FIELDS( pcf_accel_msb_header, accel ) ) goto Bail; } else { if ( FT_STREAM_READ_FIELDS( pcf_accel_header, accel ) ) goto Bail; } error = pcf_get_metric( stream, format & ( ~PCF_FORMAT_MASK ), &(accel->minbounds) ); if ( error ) goto Bail; error = pcf_get_metric( stream, format & ( ~PCF_FORMAT_MASK ), &(accel->maxbounds) ); if ( error ) goto Bail; if ( PCF_FORMAT_MATCH( format, PCF_ACCEL_W_INKBOUNDS ) ) { error = pcf_get_metric( stream, format & ( ~PCF_FORMAT_MASK ), &(accel->ink_minbounds) ); if ( error ) goto Bail; error = pcf_get_metric( stream, format & ( ~PCF_FORMAT_MASK ), &(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 ) goto Exit; error = pcf_get_properties( stream, face ); if ( error ) goto Exit; /* 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 Exit; } /* metrics */ error = pcf_get_metrics( stream, face ); if ( error ) goto Exit; /* bitmaps */ error = pcf_get_bitmaps( stream, face ); if ( error ) goto Exit; /* encodings */ error = pcf_get_encodings( stream, face ); if ( error ) goto Exit; /* BDF style accelerators (i.e. bounds based on encoded glyphs) */ if ( hasBDFAccelerators ) { error = pcf_get_accel( stream, face, PCF_BDF_ACCELERATORS ); if ( error ) goto Exit; } /* XXX: TO DO: inkmetrics and glyph_names are missing */ /* now construct the face object */ { FT_Face root = FT_FACE( face ); PCF_Property prop; 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) == 'o' ) || ( *(prop->value.atom) == 'I' ) || ( *(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' ) || ( *(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 = ft_strlen( prop->value.atom ) + 1; if ( FT_NEW_ARRAY( root->family_name, l ) ) goto Exit; ft_strcpy( root->family_name, prop->value.atom ); } } else root->family_name = 0; /* Note: We shift all glyph indices by +1 since we must * respect the convention that glyph 0 always corresponds * to the "missing glyph". * * This implies bumping the number of "available" glyphs by 1. */ root->num_glyphs = face->nmetrics + 1; root->num_fixed_sizes = 1; if ( FT_NEW_ARRAY( root->available_sizes, 1 ) ) goto Exit; { FT_Bitmap_Size* bsize = root->available_sizes; FT_MEM_ZERO( bsize, sizeof ( FT_Bitmap_Size ) ); prop = pcf_find_property( face, "PIXEL_SIZE" ); if ( prop != NULL ) bsize->height = (FT_Short)prop->value.integer; prop = pcf_find_property( face, "AVERAGE_WIDTH" ); if ( prop != NULL ) bsize->width = (FT_Short)( ( prop->value.integer + 5 ) / 10 ); prop = pcf_find_property( face, "POINT_SIZE" ); if ( prop != NULL ) /* convert from 722,7 decipoints to 72 points per inch */ bsize->size = (FT_Pos)( ( prop->value.integer * 64 * 7200 + 36135L ) / 72270L ); prop = pcf_find_property( face, "RESOLUTION_X" ); if ( prop != NULL ) bsize->x_ppem = (FT_Pos)( ( prop->value.integer * bsize->size + 36 ) / 72 ); prop = pcf_find_property( face, "RESOLUTION_Y" ); if ( prop != NULL ) bsize->y_ppem = (FT_Pos)( ( prop->value.integer * bsize->size + 36 ) / 72 ); if ( bsize->height == 0 ) bsize->height = (FT_Short)( ( bsize->y_ppem + 32 ) / 64 ); if ( bsize->height == 0 ) bsize->height = 12; } /* set up charset */ { 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 ( FT_NEW_ARRAY( face->charset_encoding, ft_strlen( charset_encoding->value.atom ) + 1 ) ) goto Exit; if ( FT_NEW_ARRAY( face->charset_registry, ft_strlen( charset_registry->value.atom ) + 1 ) ) goto Exit; ft_strcpy( face->charset_registry, charset_registry->value.atom ); ft_strcpy( face->charset_encoding, charset_encoding->value.atom ); } } } } Exit: if ( error ) { /* this is done to respect the behaviour of the original */ /* PCF font driver. */ error = PCF_Err_Invalid_File_Format; } return error; }/* END */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -