📄 winfnt.c
字号:
error = fnt_face_get_dll_font( face, face_index ); if ( error ) { /* this didn't work; try to load a single FNT font */ FNT_Font font; if ( FT_NEW( face->font ) ) goto Exit; face->root.num_faces = 1; font = face->font; font->offset = 0; font->fnt_size = stream->size; error = fnt_font_load( font, stream ); if ( error ) goto Fail; } /* we now need to fill the root FT_Face fields */ /* with relevant information */ { FT_Face root = FT_FACE( face ); FNT_Font font = face->font; FT_PtrDist family_size; root->face_flags = FT_FACE_FLAG_FIXED_SIZES | FT_FACE_FLAG_HORIZONTAL; if ( font->header.avg_width == font->header.max_width ) root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; if ( font->header.italic ) root->style_flags |= FT_STYLE_FLAG_ITALIC; if ( font->header.weight >= 800 ) root->style_flags |= FT_STYLE_FLAG_BOLD; /* set up the `fixed_sizes' array */ if ( FT_NEW_ARRAY( root->available_sizes, 1 ) ) goto Fail; root->num_fixed_sizes = 1; { FT_Bitmap_Size* bsize = root->available_sizes; FT_UShort x_res, y_res; bsize->width = font->header.avg_width; bsize->height = (FT_Short)( font->header.pixel_height + font->header.external_leading ); bsize->size = font->header.nominal_point_size << 6; x_res = font->header.horizontal_resolution; if ( !x_res ) x_res = 72; y_res = font->header.vertical_resolution; if ( !y_res ) y_res = 72; bsize->y_ppem = FT_MulDiv( bsize->size, y_res, 72 ); bsize->y_ppem = FT_PIX_ROUND( bsize->y_ppem ); /* * this reads: * * the nominal height is larger than the bbox's height * * => nominal_point_size contains incorrect value; * use pixel_height as the nominal height */ if ( bsize->y_ppem > font->header.pixel_height << 6 ) { FT_TRACE2(( "use pixel_height as the nominal height\n" )); bsize->y_ppem = font->header.pixel_height << 6; bsize->size = FT_MulDiv( bsize->y_ppem, 72, y_res ); } bsize->x_ppem = FT_MulDiv( bsize->size, x_res, 72 ); bsize->x_ppem = FT_PIX_ROUND( bsize->x_ppem ); } { FT_CharMapRec charmap; charmap.encoding = FT_ENCODING_NONE; charmap.platform_id = 0; charmap.encoding_id = 0; charmap.face = root; if ( font->header.charset == FT_WinFNT_ID_MAC ) { charmap.encoding = FT_ENCODING_APPLE_ROMAN; charmap.platform_id = 1;/* charmap.encoding_id = 0; */ } error = FT_CMap_New( fnt_cmap_class, NULL, &charmap, NULL ); if ( error ) goto Fail; /* Select default charmap */ if ( root->num_charmaps ) root->charmap = root->charmaps[0]; } /* setup remaining flags */ /* reserve one slot for the .notdef glyph at index 0 */ root->num_glyphs = font->header.last_char - font->header.first_char + 1 + 1; /* Some broken fonts don't delimit the face name with a final */ /* NULL byte -- the frame is erroneously one byte too small. */ /* We thus allocate one more byte, setting it explicitly to */ /* zero. */ family_size = font->header.file_size - font->header.face_name_offset; if ( FT_ALLOC( font->family_name, family_size + 1 ) ) goto Fail; FT_MEM_COPY( font->family_name, font->fnt_frame + font->header.face_name_offset, family_size ); font->family_name[family_size] = '\0'; if ( FT_REALLOC( font->family_name, family_size, ft_strlen( font->family_name ) + 1 ) ) goto Fail; root->family_name = font->family_name; 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"; } goto Exit; Fail: FNT_Face_Done( face ); Exit: return error; } static FT_Error FNT_Size_Select( FT_Size size ) { FNT_Face face = (FNT_Face)size->face; FT_WinFNT_Header header = &face->font->header; FT_Select_Metrics( size->face, 0 ); size->metrics.ascender = header->ascent * 64; size->metrics.descender = -( header->pixel_height - header->ascent ) * 64; size->metrics.max_advance = header->max_width * 64; return FNT_Err_Ok; } static FT_Error FNT_Size_Request( FT_Size size, FT_Size_Request req ) { FNT_Face face = (FNT_Face)size->face; FT_WinFNT_Header header = &face->font->header; FT_Bitmap_Size* bsize = size->face->available_sizes; FT_Error error = FNT_Err_Invalid_Pixel_Size; FT_Long height; height = FT_REQUEST_HEIGHT( req ); height = ( height + 32 ) >> 6; switch ( req->type ) { case FT_SIZE_REQUEST_TYPE_NOMINAL: if ( height == ( bsize->y_ppem + 32 ) >> 6 ) error = FNT_Err_Ok; break; case FT_SIZE_REQUEST_TYPE_REAL_DIM: if ( height == header->pixel_height ) error = FNT_Err_Ok; break; default: error = FNT_Err_Unimplemented_Feature; break; } if ( error ) return error; else return FNT_Size_Select( size ); } static FT_Error FNT_Load_Glyph( FT_GlyphSlot slot, FT_Size size, FT_UInt glyph_index, FT_Int32 load_flags ) { FNT_Face face = (FNT_Face)FT_SIZE_FACE( size ); FNT_Font font = face->font; FT_Error error = FNT_Err_Ok; FT_Byte* p; FT_Int len; FT_Bitmap* bitmap = &slot->bitmap; FT_ULong offset; FT_Bool new_format; FT_UNUSED( load_flags ); if ( !face || !font || glyph_index >= (FT_UInt)( FT_FACE( face )->num_glyphs ) ) { error = FNT_Err_Invalid_Argument; goto Exit; } if ( glyph_index > 0 ) glyph_index--; /* revert to real index */ else glyph_index = font->header.default_char; /* the .notdef glyph */ new_format = FT_BOOL( font->header.version == 0x300 ); len = new_format ? 6 : 4; /* jump to glyph entry */ p = font->fnt_frame + ( new_format ? 148 : 118 ) + len * glyph_index; bitmap->width = FT_NEXT_SHORT_LE( p ); if ( new_format ) offset = FT_NEXT_ULONG_LE( p ); else offset = FT_NEXT_USHORT_LE( p ); if ( offset >= font->header.file_size ) { FT_TRACE2(( "invalid FNT offset!\n" )); error = FNT_Err_Invalid_File_Format; goto Exit; } /* jump to glyph data */ p = font->fnt_frame + /* font->header.bits_offset */ + offset; /* allocate and build bitmap */ { FT_Memory memory = FT_FACE_MEMORY( slot->face ); FT_Int pitch = ( bitmap->width + 7 ) >> 3; FT_Byte* column; FT_Byte* write; bitmap->pitch = pitch; bitmap->rows = font->header.pixel_height; bitmap->pixel_mode = FT_PIXEL_MODE_MONO; /* note: since glyphs are stored in columns and not in rows we */ /* can't use ft_glyphslot_set_bitmap */ if ( FT_ALLOC_MULT( bitmap->buffer, pitch, bitmap->rows ) ) goto Exit; column = (FT_Byte*)bitmap->buffer; for ( ; pitch > 0; pitch--, column++ ) { FT_Byte* limit = p + bitmap->rows; for ( write = column; p < limit; p++, write += bitmap->pitch ) *write = *p; } } slot->internal->flags = FT_GLYPH_OWN_BITMAP; slot->bitmap_left = 0; slot->bitmap_top = font->header.ascent; slot->format = FT_GLYPH_FORMAT_BITMAP; /* now set up metrics */ slot->metrics.width = bitmap->width << 6; slot->metrics.height = bitmap->rows << 6; slot->metrics.horiAdvance = bitmap->width << 6; slot->metrics.horiBearingX = 0; slot->metrics.horiBearingY = slot->bitmap_top << 6; ft_synthesize_vertical_metrics( &slot->metrics, bitmap->rows << 6 ); Exit: return error; } static FT_Error winfnt_get_header( FT_Face face, FT_WinFNT_HeaderRec *aheader ) { FNT_Font font = ((FNT_Face)face)->font; *aheader = font->header; return 0; } static const FT_Service_WinFntRec winfnt_service_rec = { winfnt_get_header }; /* * SERVICE LIST * */ static const FT_ServiceDescRec winfnt_services[] = { { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_WINFNT }, { FT_SERVICE_ID_WINFNT, &winfnt_service_rec }, { NULL, NULL } }; static FT_Module_Interface winfnt_get_service( FT_Driver driver, const FT_String* service_id ) { FT_UNUSED( driver ); return ft_service_list_lookup( winfnt_services, service_id ); } FT_CALLBACK_TABLE_DEF const FT_Driver_ClassRec winfnt_driver_class = { { FT_MODULE_FONT_DRIVER | FT_MODULE_DRIVER_NO_OUTLINES, sizeof ( FT_DriverRec ), "winfonts", 0x10000L, 0x20000L, 0, (FT_Module_Constructor)0, (FT_Module_Destructor) 0, (FT_Module_Requester) winfnt_get_service }, sizeof( FNT_FaceRec ), sizeof( FT_SizeRec ), sizeof( FT_GlyphSlotRec ), (FT_Face_InitFunc) FNT_Face_Init, (FT_Face_DoneFunc) FNT_Face_Done, (FT_Size_InitFunc) 0, (FT_Size_DoneFunc) 0, (FT_Slot_InitFunc) 0, (FT_Slot_DoneFunc) 0,#ifdef FT_CONFIG_OPTION_OLD_INTERNALS ft_stub_set_char_sizes, ft_stub_set_pixel_sizes,#endif (FT_Slot_LoadFunc) FNT_Load_Glyph, (FT_Face_GetKerningFunc) 0, (FT_Face_AttachFunc) 0, (FT_Face_GetAdvancesFunc) 0, (FT_Size_RequestFunc) FNT_Size_Request, (FT_Size_SelectFunc) FNT_Size_Select };/* END */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -