📄 ttcmap.c
字号:
/***************************************************************************//* *//* ttcmap.c *//* *//* TrueType character mapping table (cmap) support (body). *//* *//* Copyright 1996-1999 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 <ftdebug.h>#include <ttload.h>#include <ttcmap.h>#include <tterrors.h>/* required by the tracing mode */#undef FT_COMPONENT#define FT_COMPONENT trace_ttcmap static TT_UInt code_to_index0( TT_CMapTable* charmap, TT_ULong char_code ); static TT_UInt code_to_index2( TT_CMapTable* charmap, TT_ULong char_code ); static TT_UInt code_to_index4( TT_CMapTable* charmap, TT_ULong char_code ); static TT_UInt code_to_index6( TT_CMapTable* charmap, TT_ULong char_code ); /*************************************************************************/ /* */ /* <Function> */ /* TT_CharMap_Load */ /* */ /* <Description> */ /* Loads a given TrueType character map into memory. */ /* */ /* <Input> */ /* face :: A handle to the parent face object. */ /* stream :: A handle to the current stream object. */ /* */ /* <InOut> */ /* table :: A pointer to a cmap object. */ /* */ /* <Return> */ /* Error code. 0 means success. */ /* */ /* <Note> */ /* The function assumes that the stream is already in use (i.e., */ /* opened). In case of error, all partially allocated tables are */ /* released. */ /* */ LOCAL_FUNC TT_Error TT_CharMap_Load( TT_Face face, TT_CMapTable* cmap, FT_Stream stream ) { TT_Error error; FT_Memory memory; TT_UShort num_SH, num_Seg, i; TT_UShort u, l; TT_CMap0* cmap0; TT_CMap2* cmap2; TT_CMap4* cmap4; TT_CMap6* cmap6; TT_CMap2SubHeader* cmap2sub; TT_CMap4Segment* segments; if ( cmap->loaded ) return TT_Err_Ok; memory = stream->memory; if ( FILE_Seek( cmap->offset ) ) return error; switch ( cmap->format ) { case 0: cmap0 = &cmap->c.cmap0; if ( ALLOC( cmap0->glyphIdArray, 256L ) || FILE_Read( (void*)cmap0->glyphIdArray, 256L ) ) goto Fail; cmap->get_index = code_to_index0; break; case 2: num_SH = 0; cmap2 = &cmap->c.cmap2; /* allocate subheader keys */ if ( ALLOC_ARRAY( cmap2->subHeaderKeys, 256, TT_UShort ) || ACCESS_Frame( 512L ) ) goto Fail; for ( i = 0; i < 256; i++ ) { u = GET_UShort() / 8; cmap2->subHeaderKeys[i] = u; if ( num_SH < u ) num_SH = u; } FORGET_Frame(); /* load subheaders */ cmap2->numGlyphId = l = ( ( cmap->length - 2L*(256+3) - num_SH*8L ) & 0xffff ) / 2; if ( ALLOC_ARRAY( cmap2->subHeaders, num_SH + 1, TT_CMap2SubHeader ) || ACCESS_Frame( ( num_SH + 1 ) * 8L ) ) goto Fail; cmap2sub = cmap2->subHeaders; for ( i = 0; i <= num_SH; i++ ) { cmap2sub->firstCode = GET_UShort(); cmap2sub->entryCount = GET_UShort(); cmap2sub->idDelta = GET_Short(); /* we apply the location offset immediately */ cmap2sub->idRangeOffset = GET_UShort() - ( num_SH - i ) * 8 - 2; cmap2sub++; } FORGET_Frame(); /* load glyph IDs */ if ( ALLOC_ARRAY( cmap2->glyphIdArray, l, TT_UShort ) || ACCESS_Frame( l * 2L ) ) goto Fail; for ( i = 0; i < l; i++ ) cmap2->glyphIdArray[i] = GET_UShort(); FORGET_Frame(); cmap->get_index = code_to_index2; break; case 4: cmap4 = &cmap->c.cmap4; /* load header */ if ( ACCESS_Frame( 8L ) ) goto Fail; cmap4->segCountX2 = GET_UShort(); cmap4->searchRange = GET_UShort(); cmap4->entrySelector = GET_UShort(); cmap4->rangeShift = GET_UShort(); num_Seg = cmap4->segCountX2 / 2; FORGET_Frame(); /* load segments */ if ( ALLOC_ARRAY( cmap4->segments, num_Seg, TT_CMap4Segment ) || ACCESS_Frame( (num_Seg * 4 + 1) * 2L ) ) goto Fail; segments = cmap4->segments; for ( i = 0; i < num_Seg; i++ ) segments[i].endCount = GET_UShort(); (void)GET_UShort(); for ( i = 0; i < num_Seg; i++ ) segments[i].startCount = GET_UShort(); for ( i = 0; i < num_Seg; i++ ) segments[i].idDelta = GET_Short(); for ( i = 0; i < num_Seg; i++ ) segments[i].idRangeOffset = GET_UShort(); FORGET_Frame(); cmap4->numGlyphId = l = ( ( cmap->length - ( 16L + 8L * num_Seg ) ) & 0xFFFF ) /2; /* load IDs */ if ( ALLOC_ARRAY( cmap4->glyphIdArray, l, TT_UShort ) || ACCESS_Frame( l*2L ) ) goto Fail; for ( i = 0; i < l; i++ ) cmap4->glyphIdArray[i] = GET_UShort(); FORGET_Frame(); cmap->get_index = code_to_index4; break; case 6: cmap6 = &cmap->c.cmap6; if ( ACCESS_Frame( 4L ) ) goto Fail; cmap6->firstCode = GET_UShort(); cmap6->entryCount = GET_UShort(); FORGET_Frame(); l = cmap6->entryCount; if ( ALLOC_ARRAY( cmap6->glyphIdArray, cmap6->entryCount, TT_Short ) || ACCESS_Frame( l * 2L ) ) goto Fail; for ( i = 0; i < l; i++ ) cmap6->glyphIdArray[i] = GET_UShort(); FORGET_Frame(); cmap->get_index = code_to_index6; break; default: /* corrupt character mapping table */ return TT_Err_Invalid_CharMap_Format; } return TT_Err_Ok; Fail: TT_CharMap_Free( face, cmap ); return error; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -