📄 ttgload.c
字号:
/***************************************************************************//* *//* ttgload.c *//* *//* TrueType Glyph Loader (body). *//* *//* Copyright 1996-2000 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 <freetype/internal/ftdebug.h>#include <freetype/internal/ftcalc.h>#include <freetype/internal/ftstream.h>#include <freetype/internal/sfnt.h>#include <freetype/tttags.h>#include <freetype/ftoutln.h>#ifdef FT_FLAT_COMPILE#include "ttgload.h"#else#include <truetype/ttgload.h>#endif /*************************************************************************/ /* */ /* 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_ttgload /*************************************************************************/ /* */ /* Composite font flags. */ /* */#define ARGS_ARE_WORDS 0x001#define ARGS_ARE_XY_VALUES 0x002#define ROUND_XY_TO_GRID 0x004#define WE_HAVE_A_SCALE 0x008/* reserved 0x010 */#define MORE_COMPONENTS 0x020#define WE_HAVE_AN_XY_SCALE 0x040#define WE_HAVE_A_2X2 0x080#define WE_HAVE_INSTR 0x100#define USE_MY_METRICS 0x200 /*************************************************************************/ /* */ /* <Function> */ /* TT_Get_Metrics */ /* */ /* <Description> */ /* Returns the horizontal or vertical metrics in font units for a */ /* given glyph. The metrics are the left side bearing (resp. top */ /* side bearing) and advance width (resp. advance height). */ /* */ /* <Input> */ /* header :: A pointer to either the horizontal or vertical metrics */ /* structure. */ /* */ /* index :: The glyph index. */ /* */ /* <Output> */ /* bearing :: The bearing, either left side or top side. */ /* */ /* advance :: The advance width resp. advance height. */ /* */ /* <Note> */ /* This function will much probably move to another component in the */ /* near future, but I haven't decided which yet. */ /* */ FT_LOCAL_DEF void TT_Get_Metrics( TT_HoriHeader* header, FT_UInt index, FT_Short* bearing, FT_UShort* advance ) { TT_LongMetrics* longs_m; FT_UShort k = header->number_Of_HMetrics; if ( index < (FT_UInt)k ) { longs_m = (TT_LongMetrics*)header->long_metrics + index; *bearing = longs_m->bearing; *advance = longs_m->advance; } else { *bearing = ((TT_ShortMetrics*)header->short_metrics)[index - k]; *advance = ((TT_LongMetrics*)header->long_metrics)[k - 1].advance; } } /*************************************************************************/ /* */ /* Returns the horizontal metrics in font units for a given glyph. If */ /* `check' is true, take care of monospaced fonts by returning the */ /* advance width maximum. */ /* */ static void Get_HMetrics( TT_Face face, FT_UInt index, FT_Bool check, FT_Short* lsb, FT_UShort* aw ) { TT_Get_Metrics( &face->horizontal, index, lsb, aw ); if ( check && face->postscript.isFixedPitch ) *aw = face->horizontal.advance_Width_Max; } /*************************************************************************/ /* */ /* Returns the advance width table for a given pixel size if it is */ /* found in the font's `hdmx' table (if any). */ /* */ static FT_Byte* Get_Advance_Widths( TT_Face face, FT_UShort ppem ) { FT_UShort n; for ( n = 0; n < face->hdmx.num_records; n++ ) if ( face->hdmx.records[n].ppem == ppem ) return face->hdmx.records[n].widths; return NULL; }#define cur_to_org( n, zone ) \ MEM_Copy( (zone)->org, (zone)->cur, n * sizeof ( FT_Vector ) )#define org_to_cur( n, zone ) \ MEM_Copy( (zone)->cur, (zone)->org, n * sizeof ( FT_Vector ) ) /*************************************************************************/ /* */ /* Translates an array of coordinates. */ /* */ static void translate_array( FT_UInt n, FT_Vector* coords, FT_Pos delta_x, FT_Pos delta_y ) { FT_UInt k; if ( delta_x ) for ( k = 0; k < n; k++ ) coords[k].x += delta_x; if ( delta_y ) for ( k = 0; k < n; k++ ) coords[k].y += delta_y; } static void tt_prepare_zone( TT_GlyphZone* zone, FT_GlyphLoad* load, FT_UInt start_point, FT_UInt start_contour ) { zone->n_points = load->outline.n_points - start_point; zone->n_contours = load->outline.n_contours - start_contour; zone->org = load->extra_points + start_point; zone->cur = load->outline.points + start_point; zone->tags = (FT_Byte*)load->outline.tags + start_point; zone->contours = (FT_UShort*)load->outline.contours + start_contour; }#undef IS_HINTED#define IS_HINTED( flags ) ( ( flags & FT_LOAD_NO_HINTING ) == 0 ) /*************************************************************************/ /* */ /* The following functions are used by default with TrueType fonts. */ /* However, they can be replaced by alternatives if we need to support */ /* TrueType-compressed formats (like MicroType) in the future. */ /* */ /*************************************************************************/ FT_CALLBACK_DEF FT_Error TT_Access_Glyph_Frame( TT_Loader* loader, FT_UInt glyph_index, FT_ULong offset, FT_UInt byte_count ) { FT_Error error; FT_Stream stream = loader->stream; /* for non-debug mode */ FT_UNUSED( glyph_index ); FT_TRACE5(( "Glyph %ld\n", glyph_index )); /* the following line sets the `error' variable through macros! */ if ( FILE_Seek( offset ) || ACCESS_Frame( byte_count ) ) return error; return TT_Err_Ok; } FT_CALLBACK_DEF void TT_Forget_Glyph_Frame( TT_Loader* loader ) { FT_Stream stream = loader->stream; FORGET_Frame(); } FT_CALLBACK_DEF FT_Error TT_Load_Glyph_Header( TT_Loader* loader ) { FT_Stream stream = loader->stream; loader->n_contours = GET_Short(); loader->bbox.xMin = GET_Short(); loader->bbox.yMin = GET_Short(); loader->bbox.xMax = GET_Short(); loader->bbox.yMax = GET_Short(); FT_TRACE5(( " # of contours: %d\n", loader->n_contours )); FT_TRACE5(( " xMin: %4d xMax: %4d\n", loader->bbox.xMin, loader->bbox.xMax )); FT_TRACE5(( " yMin: %4d yMax: %4d\n", loader->bbox.yMin, loader->bbox.yMax )); return FT_Err_Ok; } FT_CALLBACK_DEF FT_Error TT_Load_Simple_Glyph( TT_Loader* load ) { FT_Error error; FT_Stream stream = load->stream; FT_GlyphLoader* gloader = load->gloader; FT_Int n_contours = load->n_contours; FT_Outline* outline; TT_Face face = (TT_Face)load->face; TT_GlyphSlot slot = (TT_GlyphSlot)load->glyph; FT_UShort n_ins; FT_Int n, n_points; /* reading the contours endpoints & number of points */ { short* cur = gloader->current.outline.contours; short* limit = cur + n_contours; for ( ; cur < limit; cur++ ) cur[0] = GET_UShort(); n_points = 0; if ( n_contours > 0 ) n_points = cur[-1] + 1; error = FT_GlyphLoader_Check_Points( gloader, n_points + 2, 0 ); if ( error ) goto Fail; outline = &gloader->current.outline; } /* reading the bytecode instructions */ slot->control_len = 0; slot->control_data = 0; n_ins = GET_UShort(); FT_TRACE5(( " Instructions size: %d\n", n_ins )); if ( n_ins > face->max_profile.maxSizeOfInstructions ) { FT_TRACE0(( "ERROR: Too many instructions!\n" )); error = TT_Err_Too_Many_Ins; goto Fail; } if ( stream->cursor + n_ins > stream->limit ) { FT_TRACE0(( "ERROR: Instruction count mismatch!\n" )); error = TT_Err_Too_Many_Ins; goto Fail; }#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER if ( ( load->load_flags & ( FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING ) ) == 0 && load->instructions ) { slot->control_len = n_ins; slot->control_data = load->instructions; MEM_Copy( load->instructions, stream->cursor, n_ins ); }#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ stream->cursor += n_ins; /* reading the point tags */ { FT_Byte* flag = (FT_Byte*)outline->tags; FT_Byte* limit = flag + n_points; FT_Byte c, count; for ( ; flag < limit; flag++ ) { *flag = c = GET_Byte(); if ( c & 8 ) { for ( count = GET_Byte(); count > 0; count-- ) *++flag = c; } } } /* reading the X coordinates */ { FT_Vector* vec = outline->points; FT_Vector* limit = vec + n_points; FT_Byte* flag = (FT_Byte*)outline->tags; FT_Pos x = 0; for ( ; vec < limit; vec++, flag++ ) { FT_Pos y = 0; if ( *flag & 2 ) { y = GET_Byte(); if ( ( *flag & 16 ) == 0 )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -