?? ttgload.c
字號:
/***************************************************************************//* *//* ttgload.c *//* *//* TrueType Glyph Loader (body). *//* *//* Copyright 1996-2001, 2002 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 <ft2build.h>#include FT_INTERNAL_DEBUG_H#include FT_INTERNAL_CALC_H#include FT_INTERNAL_STREAM_H#include FT_INTERNAL_SFNT_H#include FT_TRUETYPE_TAGS_H#include FT_OUTLINE_H#include "ttgload.h"#include "tterrors.h" /*************************************************************************/ /* */ /* 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. */ /* */ /* idx :: 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 idx, FT_Short* bearing, FT_UShort* advance ) { TT_LongMetrics longs_m; FT_UShort k = header->number_Of_HMetrics; if ( idx < (FT_UInt)k ) { longs_m = (TT_LongMetrics )header->long_metrics + idx; *bearing = longs_m->bearing; *advance = longs_m->advance; } else { *bearing = ((TT_ShortMetrics*)header->short_metrics)[idx - 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 idx, FT_Bool check, FT_Short* lsb, FT_UShort* aw ) { TT_Get_Metrics( &face->horizontal, idx, 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 ) \ FT_MEM_COPY( (zone)->org, (zone)->cur, (n) * sizeof ( FT_Vector ) )#define org_to_cur( n, zone ) \ FT_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 = (FT_UShort)( load->outline.n_points - start_point ); zone->n_contours = (FT_Short) ( 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 ( FT_STREAM_SEEK( offset ) || FT_FRAME_ENTER( byte_count ) ) return error; return TT_Err_Ok; } FT_CALLBACK_DEF( void ) TT_Forget_Glyph_Frame( TT_Loader loader ) { FT_Stream stream = loader->stream; FT_FRAME_EXIT(); } FT_CALLBACK_DEF( FT_Error ) TT_Load_Glyph_Header( TT_Loader loader ) { FT_Stream stream = loader->stream; FT_Int byte_len = loader->byte_len - 10; if ( byte_len < 0 ) return TT_Err_Invalid_Outline; loader->n_contours = FT_GET_SHORT(); loader->bbox.xMin = FT_GET_SHORT(); loader->bbox.yMin = FT_GET_SHORT(); loader->bbox.xMax = FT_GET_SHORT(); loader->bbox.yMax = FT_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 )); loader->byte_len = byte_len; return TT_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; FT_Int byte_len = load->byte_len; /* reading the contours endpoints & number of points */ { short* cur = gloader->current.outline.contours; short* limit = cur + n_contours; /* check space for contours array + instructions count */ byte_len -= 2 * ( n_contours + 1 ); if ( byte_len < 0 ) goto Invalid_Outline; for ( ; cur < limit; cur++ ) cur[0] = FT_GET_USHORT(); n_points = 0; if ( n_contours > 0 ) n_points = cur[-1] + 1; error = FT_GlyphLoader_CheckPoints( gloader, n_points + 2, 0 ); if ( error ) goto Fail; /* we'd better check the contours table right now */ outline = &gloader->current.outline; for ( cur = outline->contours + 1; cur < limit; cur++ ) if ( cur[-1] >= cur[0] ) goto Invalid_Outline; } /* reading the bytecode instructions */ slot->control_len = 0; slot->control_data = 0; n_ins = FT_GET_USHORT(); FT_TRACE5(( " Instructions size: %d\n", n_ins )); if ( n_ins > face->max_profile.maxSizeOfInstructions ) { FT_TRACE0(( "TT_Load_Simple_Glyph: Too many instructions!\n" )); error = TT_Err_Too_Many_Hints; goto Fail; } byte_len -= n_ins; if ( byte_len < 0 ) { FT_TRACE0(( "TT_Load_Simple_Glyph: Instruction count mismatch!\n" )); error = TT_Err_Too_Many_Hints; 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; FT_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; while ( flag < limit ) { if ( --byte_len < 0 ) goto Invalid_Outline; *flag++ = c = FT_GET_BYTE(); if ( c & 8 ) { if ( --byte_len < 0 ) goto Invalid_Outline; count = FT_GET_BYTE(); if ( flag + count > limit ) goto Invalid_Outline; for ( ; count > 0; count-- ) *flag++ = c; } } /* check that there is enough room to load the coordinates */ for ( flag = (FT_Byte*)outline->tags; flag < limit; flag++ ) { if ( *flag & 2 ) byte_len -= 1; else if ( ( *flag & 16 ) == 0 ) byte_len -= 2; if ( *flag & 4 ) byte_len -= 1; else if ( ( *flag & 32 ) == 0 ) byte_len -= 2; } if ( byte_len < 0 ) goto Invalid_Outline; } /* reading the X coordinates */ { FT_Vector* vec = outline->points; FT_Vector* limit = vec + n_points;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -