ttgload.c
来自「一个类似windows」· C语言 代码 · 共 1,925 行 · 第 1/5 页
C
1,925 行
/***************************************************************************/
/* */
/* ttgload.c */
/* */
/* TrueType Glyph Loader (body). */
/* */
/* Copyright 1996-2001, 2002, 2003, 2004, 2005 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 "ttpload.h"
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
#include "ttgxvar.h"
#endif
#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 0x0001
#define ARGS_ARE_XY_VALUES 0x0002
#define ROUND_XY_TO_GRID 0x0004
#define WE_HAVE_A_SCALE 0x0008
/* reserved 0x0010 */
#define MORE_COMPONENTS 0x0020
#define WE_HAVE_AN_XY_SCALE 0x0040
#define WE_HAVE_A_2X2 0x0080
#define WE_HAVE_INSTR 0x0100
#define USE_MY_METRICS 0x0200
#define OVERLAP_COMPOUND 0x0400
#define SCALED_COMPONENT_OFFSET 0x0800
#define UNSCALED_COMPONENT_OFFSET 0x1000
/* Maximum recursion depth we allow for composite glyphs.
* The TrueType spec doesn't say anything about recursion,
* so it isn't clear that recursion is allowed at all. But
* we'll be generous.
*/
#define TT_MAX_COMPOSITE_RECURSE 5
/*************************************************************************/
/* */
/* <Function> */
/* tt_face_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. */
/* */
#ifdef FT_OPTIMIZE_MEMORY
static void
tt_face_get_metrics( TT_Face face,
FT_Bool vertical,
FT_UInt idx,
FT_Short *abearing,
FT_UShort *aadvance )
{
TT_HoriHeader* header;
FT_Byte* p;
FT_Byte* limit;
FT_UShort k;
if ( vertical )
{
header = (TT_HoriHeader*)&face->vertical;
p = face->vert_metrics;
limit = p + face->vert_metrics_size;
}
else
{
header = &face->horizontal;
p = face->horz_metrics;
limit = p + face->horz_metrics_size;
}
k = header->number_Of_HMetrics;
if ( k > 0 )
{
if ( idx < (FT_UInt)k )
{
p += 4 * idx;
if ( p + 4 > limit )
goto NoData;
*aadvance = FT_NEXT_USHORT( p );
*abearing = FT_NEXT_SHORT( p );
}
else
{
p += 4 * ( k - 1 );
if ( p + 4 > limit )
goto NoData;
*aadvance = FT_NEXT_USHORT( p );
p += 2 + 2 * ( idx - k );
if ( p + 2 > limit )
*abearing = 0;
else
*abearing = FT_PEEK_SHORT( p );
}
}
else
{
NoData:
*abearing = 0;
*aadvance = 0;
}
}
#else /* !FT_OPTIMIZE_MEMORY */
static void
tt_face_get_metrics( TT_Face face,
FT_Bool vertical,
FT_UInt idx,
FT_Short *abearing,
FT_UShort *aadvance )
{
TT_HoriHeader* header = vertical ? (TT_HoriHeader*)&face->vertical
: &face->horizontal;
TT_LongMetrics longs_m;
FT_UShort k = header->number_Of_HMetrics;
if ( k == 0 )
{
*abearing = *aadvance = 0;
return;
}
if ( idx < (FT_UInt)k )
{
longs_m = (TT_LongMetrics)header->long_metrics + idx;
*abearing = longs_m->bearing;
*aadvance = longs_m->advance;
}
else
{
*abearing = ((TT_ShortMetrics*)header->short_metrics)[idx - k];
*aadvance = ((TT_LongMetrics)header->long_metrics)[k - 1].advance;
}
}
#endif /* !FT_OPTIMIZE_MEMORY */
/*************************************************************************/
/* */
/* 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_face_get_metrics( face, 0, 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_WidthPtr( TT_Face face,
FT_Int ppem,
FT_UInt gindex )
{
#ifdef FT_OPTIMIZE_MEMORY
FT_UInt nn;
FT_Byte* result = NULL;
FT_ULong record_size = face->hdmx_record_size;
FT_Byte* record = face->hdmx_table + 8;
for ( nn = 0; nn < face->hdmx_record_count; nn++ )
if ( face->hdmx_record_sizes[nn] == ppem )
{
gindex += 2;
if ( gindex < record_size )
result = record + gindex;
break;
}
return result;
#else
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[gindex];
return NULL;
#endif
}
/*************************************************************************/
/* */
/* Returns the vertical metrics in font units for a given glyph. */
/* Greg Hitchcock from Microsoft told us that if there were no `vmtx' */
/* table, typoAscender/Descender from the `OS/2' table would be used */
/* instead, and if there were no `OS/2' table, use ascender/descender */
/* from the `hhea' table. But that is not what Microsoft's rasterizer */
/* apparently does: It uses the ppem value as the advance height, and */
/* sets the top side bearing to be zero. */
/* */
/* The monospace `check' is probably not meaningful here, but we leave */
/* it in for a consistent interface. */
/* */
static void
Get_VMetrics( TT_Face face,
FT_UInt idx,
FT_Bool check,
FT_Short* tsb,
FT_UShort* ah )
{
FT_UNUSED( check );
if ( face->vertical_info )
tt_face_get_metrics( face, 1, idx, tsb, ah );
#if 1 /* Emperically determined, at variance with what MS said */
else
{
*tsb = 0;
*ah = face->root.units_per_EM;
}
#else /* This is what MS said to do. It isn't what they do, however. */
else if ( face->os2.version != 0xFFFFU )
{
*tsb = face->os2.sTypoAscender;
*ah = face->os2.sTypoAscender - face->os2.sTypoDescender;
}
else
{
*tsb = face->horizontal.Ascender;
*ah = face->horizontal.Ascender - face->horizontal.Descender;
}
#endif
}
#define cur_to_org( n, zone ) \
FT_ARRAY_COPY( (zone)->org, (zone)->cur, (n) )
#define org_to_cur( n, zone ) \
FT_ARRAY_COPY( (zone)->cur, (zone)->org, (n) )
/*************************************************************************/
/* */
/* 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 ));
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?