From 75b11e43c284ff80bf49a3c1a0980353b942ff89 Mon Sep 17 00:00:00 2001 From: Lei Zhang Date: Wed, 29 Mar 2017 14:15:52 -0700 Subject: Erase unused freetype files. Change-Id: I024573f341cba48d9f5d2bc38683a016639b14e2 Reviewed-on: https://pdfium-review.googlesource.com/3119 Reviewed-by: dsinclair Commit-Queue: Lei Zhang --- third_party/freetype/src/truetype/Jamfile | 37 - third_party/freetype/src/truetype/ttgxvar.c | 2074 --------------------------- third_party/freetype/src/truetype/ttgxvar.h | 182 --- 3 files changed, 2293 deletions(-) delete mode 100644 third_party/freetype/src/truetype/Jamfile delete mode 100644 third_party/freetype/src/truetype/ttgxvar.c delete mode 100644 third_party/freetype/src/truetype/ttgxvar.h (limited to 'third_party/freetype/src/truetype') diff --git a/third_party/freetype/src/truetype/Jamfile b/third_party/freetype/src/truetype/Jamfile deleted file mode 100644 index 88cc26f2b1..0000000000 --- a/third_party/freetype/src/truetype/Jamfile +++ /dev/null @@ -1,37 +0,0 @@ -# FreeType 2 src/truetype Jamfile -# -# Copyright 2001-2015 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. - -SubDir FT2_TOP $(FT2_SRC_DIR) truetype ; - -{ - local _sources ; - - if $(FT2_MULTI) - { - _sources = ttdriver - ttgload - ttgxvar - ttinterp - ttobjs - ttpic - ttpload - ttsubpix - ; - } - else - { - _sources = truetype ; - } - - Library $(FT2_LIB) : $(_sources).c ; -} - -# end of src/truetype Jamfile diff --git a/third_party/freetype/src/truetype/ttgxvar.c b/third_party/freetype/src/truetype/ttgxvar.c deleted file mode 100644 index dd9e250c94..0000000000 --- a/third_party/freetype/src/truetype/ttgxvar.c +++ /dev/null @@ -1,2074 +0,0 @@ -/***************************************************************************/ -/* */ -/* ttgxvar.c */ -/* */ -/* TrueType GX Font Variation loader */ -/* */ -/* Copyright 2004-2015 by */ -/* David Turner, Robert Wilhelm, Werner Lemberg, and George Williams. */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* Apple documents the `fvar', `gvar', `cvar', and `avar' tables at */ - /* */ - /* https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6[fgca]var.html */ - /* */ - /* The documentation for `fvar' is inconsistent. At one point it says */ - /* that `countSizePairs' should be 3, at another point 2. It should */ - /* be 2. */ - /* */ - /* The documentation for `gvar' is not intelligible; `cvar' refers you */ - /* to `gvar' and is thus also incomprehensible. */ - /* */ - /* The documentation for `avar' appears correct, but Apple has no fonts */ - /* with an `avar' table, so it is hard to test. */ - /* */ - /* Many thanks to John Jenkins (at Apple) in figuring this out. */ - /* */ - /* */ - /* Apple's `kern' table has some references to tuple indices, but as */ - /* there is no indication where these indices are defined, nor how to */ - /* interpolate the kerning values (different tuples have different */ - /* classes) this issue is ignored. */ - /* */ - /*************************************************************************/ - - -#include -#include FT_INTERNAL_DEBUG_H -#include FT_CONFIG_CONFIG_H -#include FT_INTERNAL_STREAM_H -#include FT_INTERNAL_SFNT_H -#include FT_TRUETYPE_TAGS_H -#include FT_MULTIPLE_MASTERS_H - -#include "ttpload.h" -#include "ttgxvar.h" - -#include "tterrors.h" - - -#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT - - -#define FT_Stream_FTell( stream ) \ - (FT_ULong)( (stream)->cursor - (stream)->base ) -#define FT_Stream_SeekSet( stream, off ) \ - ( (stream)->cursor = (stream)->base + (off) ) - - - /*************************************************************************/ - /* */ - /* 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_ttgxvar - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** Internal Routines *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* The macro ALL_POINTS is used in `ft_var_readpackedpoints'. It */ - /* indicates that there is a delta for every point without needing to */ - /* enumerate all of them. */ - /* */ - - /* ensure that value `0' has the same width as a pointer */ -#define ALL_POINTS (FT_UShort*)~(FT_PtrDist)0 - - -#define GX_PT_POINTS_ARE_WORDS 0x80U -#define GX_PT_POINT_RUN_COUNT_MASK 0x7FU - - - /*************************************************************************/ - /* */ - /* */ - /* ft_var_readpackedpoints */ - /* */ - /* */ - /* Read a set of points to which the following deltas will apply. */ - /* Points are packed with a run length encoding. */ - /* */ - /* */ - /* stream :: The data stream. */ - /* */ - /* */ - /* point_cnt :: The number of points read. A zero value means that */ - /* all points in the glyph will be affected, without */ - /* enumerating them individually. */ - /* */ - /* */ - /* An array of FT_UShort containing the affected points or the */ - /* special value ALL_POINTS. */ - /* */ - static FT_UShort* - ft_var_readpackedpoints( FT_Stream stream, - FT_UInt *point_cnt ) - { - FT_UShort *points = NULL; - FT_UInt n; - FT_UInt runcnt; - FT_UInt i, j; - FT_UShort first; - FT_Memory memory = stream->memory; - FT_Error error = FT_Err_Ok; - - FT_UNUSED( error ); - - - *point_cnt = 0; - - n = FT_GET_BYTE(); - if ( n == 0 ) - return ALL_POINTS; - - if ( n & GX_PT_POINTS_ARE_WORDS ) - { - n &= GX_PT_POINT_RUN_COUNT_MASK; - n <<= 8; - n |= FT_GET_BYTE(); - } - - if ( FT_NEW_ARRAY( points, n ) ) - return NULL; - - *point_cnt = n; - - i = 0; - while ( i < n ) - { - runcnt = FT_GET_BYTE(); - if ( runcnt & GX_PT_POINTS_ARE_WORDS ) - { - runcnt &= GX_PT_POINT_RUN_COUNT_MASK; - first = FT_GET_USHORT(); - points[i++] = first; - - if ( runcnt < 1 || i + runcnt > n ) - goto Exit; - - /* first point not included in run count */ - for ( j = 0; j < runcnt; j++ ) - { - first += FT_GET_USHORT(); - points[i++] = first; - } - } - else - { - first = FT_GET_BYTE(); - points[i++] = first; - - if ( runcnt < 1 || i + runcnt > n ) - goto Exit; - - for ( j = 0; j < runcnt; j++ ) - { - first += FT_GET_BYTE(); - points[i++] = first; - } - } - } - - Exit: - return points; - } - - -#define GX_DT_DELTAS_ARE_ZERO 0x80U -#define GX_DT_DELTAS_ARE_WORDS 0x40U -#define GX_DT_DELTA_RUN_COUNT_MASK 0x3FU - - - /*************************************************************************/ - /* */ - /* */ - /* ft_var_readpackeddeltas */ - /* */ - /* */ - /* Read a set of deltas. These are packed slightly differently than */ - /* points. In particular there is no overall count. */ - /* */ - /* */ - /* stream :: The data stream. */ - /* */ - /* delta_cnt :: The number of deltas to be read. */ - /* */ - /* */ - /* An array of FT_Short containing the deltas for the affected */ - /* points. (This only gets the deltas for one dimension. It will */ - /* generally be called twice, once for x, once for y. When used in */ - /* cvt table, it will only be called once.) */ - /* */ - static FT_Short* - ft_var_readpackeddeltas( FT_Stream stream, - FT_UInt delta_cnt ) - { - FT_Short *deltas = NULL; - FT_UInt runcnt, cnt; - FT_UInt i, j; - FT_Memory memory = stream->memory; - FT_Error error = FT_Err_Ok; - - FT_UNUSED( error ); - - - if ( FT_NEW_ARRAY( deltas, delta_cnt ) ) - return NULL; - - i = 0; - while ( i < delta_cnt ) - { - runcnt = FT_GET_BYTE(); - cnt = runcnt & GX_DT_DELTA_RUN_COUNT_MASK; - - if ( runcnt & GX_DT_DELTAS_ARE_ZERO ) - { - /* `runcnt' zeroes get added */ - for ( j = 0; j <= cnt && i < delta_cnt; j++ ) - deltas[i++] = 0; - } - else if ( runcnt & GX_DT_DELTAS_ARE_WORDS ) - { - /* `runcnt' shorts from the stack */ - for ( j = 0; j <= cnt && i < delta_cnt; j++ ) - deltas[i++] = FT_GET_SHORT(); - } - else - { - /* `runcnt' signed bytes from the stack */ - for ( j = 0; j <= cnt && i < delta_cnt; j++ ) - deltas[i++] = FT_GET_CHAR(); - } - - if ( j <= cnt ) - { - /* bad format */ - FT_FREE( deltas ); - return NULL; - } - } - - return deltas; - } - - - /*************************************************************************/ - /* */ - /* */ - /* ft_var_load_avar */ - /* */ - /* */ - /* Parse the `avar' table if present. It need not be, so we return */ - /* nothing. */ - /* */ - /* */ - /* face :: The font face. */ - /* */ - static void - ft_var_load_avar( TT_Face face ) - { - FT_Stream stream = FT_FACE_STREAM( face ); - FT_Memory memory = stream->memory; - GX_Blend blend = face->blend; - GX_AVarSegment segment; - FT_Error error = FT_Err_Ok; - FT_Long version; - FT_Long axisCount; - FT_Int i, j; - FT_ULong table_len; - - FT_UNUSED( error ); - - - FT_TRACE2(( "AVAR " )); - - blend->avar_checked = TRUE; - error = face->goto_table( face, TTAG_avar, stream, &table_len ); - if ( error ) - { - FT_TRACE2(( "is missing\n" )); - return; - } - - if ( FT_FRAME_ENTER( table_len ) ) - return; - - version = FT_GET_LONG(); - axisCount = FT_GET_LONG(); - - if ( version != 0x00010000L ) - { - FT_TRACE2(( "bad table version\n" )); - goto Exit; - } - - FT_TRACE2(( "loaded\n" )); - - if ( axisCount != (FT_Long)blend->mmvar->num_axis ) - { - FT_TRACE2(( "ft_var_load_avar: number of axes in `avar' and `cvar'\n" - " table are different\n" )); - goto Exit; - } - - if ( FT_NEW_ARRAY( blend->avar_segment, axisCount ) ) - goto Exit; - - segment = &blend->avar_segment[0]; - for ( i = 0; i < axisCount; i++, segment++ ) - { - FT_TRACE5(( " axis %d:\n", i )); - - segment->pairCount = FT_GET_USHORT(); - if ( FT_NEW_ARRAY( segment->correspondence, segment->pairCount ) ) - { - /* Failure. Free everything we have done so far. We must do */ - /* it right now since loading the `avar' table is optional. */ - - for ( j = i - 1; j >= 0; j-- ) - FT_FREE( blend->avar_segment[j].correspondence ); - - FT_FREE( blend->avar_segment ); - blend->avar_segment = NULL; - goto Exit; - } - - for ( j = 0; j < segment->pairCount; j++ ) - { - /* convert to Fixed */ - segment->correspondence[j].fromCoord = FT_GET_SHORT() * 4; - segment->correspondence[j].toCoord = FT_GET_SHORT() * 4; - - FT_TRACE5(( " mapping %.4f to %.4f\n", - segment->correspondence[j].fromCoord / 65536.0, - segment->correspondence[j].toCoord / 65536.0 )); - } - - FT_TRACE5(( "\n" )); - } - - Exit: - FT_FRAME_EXIT(); - } - - - typedef struct GX_GVar_Head_ - { - FT_Long version; - FT_UShort axisCount; - FT_UShort globalCoordCount; - FT_ULong offsetToCoord; - FT_UShort glyphCount; - FT_UShort flags; - FT_ULong offsetToData; - - } GX_GVar_Head; - - - /*************************************************************************/ - /* */ - /* */ - /* ft_var_load_gvar */ - /* */ - /* */ - /* Parse the `gvar' table if present. If `fvar' is there, `gvar' had */ - /* better be there too. */ - /* */ - /* */ - /* face :: The font face. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - static FT_Error - ft_var_load_gvar( TT_Face face ) - { - FT_Stream stream = FT_FACE_STREAM( face ); - FT_Memory memory = stream->memory; - GX_Blend blend = face->blend; - FT_Error error; - FT_UInt i, j; - FT_ULong table_len; - FT_ULong gvar_start; - FT_ULong offsetToData; - GX_GVar_Head gvar_head; - - static const FT_Frame_Field gvar_fields[] = - { - -#undef FT_STRUCTURE -#define FT_STRUCTURE GX_GVar_Head - - FT_FRAME_START( 20 ), - FT_FRAME_LONG ( version ), - FT_FRAME_USHORT( axisCount ), - FT_FRAME_USHORT( globalCoordCount ), - FT_FRAME_ULONG ( offsetToCoord ), - FT_FRAME_USHORT( glyphCount ), - FT_FRAME_USHORT( flags ), - FT_FRAME_ULONG ( offsetToData ), - FT_FRAME_END - }; - - - FT_TRACE2(( "GVAR " )); - - if ( ( error = face->goto_table( face, - TTAG_gvar, - stream, - &table_len ) ) != 0 ) - { - FT_TRACE2(( "is missing\n" )); - goto Exit; - } - - gvar_start = FT_STREAM_POS( ); - if ( FT_STREAM_READ_FIELDS( gvar_fields, &gvar_head ) ) - goto Exit; - - blend->tuplecount = gvar_head.globalCoordCount; - blend->gv_glyphcnt = gvar_head.glyphCount; - offsetToData = gvar_start + gvar_head.offsetToData; - - if ( gvar_head.version != 0x00010000L ) - { - FT_TRACE1(( "bad table version\n" )); - error = FT_THROW( Invalid_Table ); - goto Exit; - } - - FT_TRACE2(( "loaded\n" )); - - if ( gvar_head.axisCount != (FT_UShort)blend->mmvar->num_axis ) - { - FT_TRACE1(( "ft_var_load_gvar: number of axes in `gvar' and `cvar'\n" - " table are different\n" )); - error = FT_THROW( Invalid_Table ); - goto Exit; - } - - FT_TRACE5(( "gvar: there are %d shared coordinates:\n", - blend->tuplecount )); - - if ( FT_NEW_ARRAY( blend->glyphoffsets, blend->gv_glyphcnt + 1 ) ) - goto Exit; - - if ( gvar_head.flags & 1 ) - { - /* long offsets (one more offset than glyphs, to mark size of last) */ - if ( FT_FRAME_ENTER( ( blend->gv_glyphcnt + 1 ) * 4L ) ) - goto Exit; - - for ( i = 0; i <= blend->gv_glyphcnt; i++ ) - blend->glyphoffsets[i] = offsetToData + FT_GET_ULONG(); - - FT_FRAME_EXIT(); - } - else - { - /* short offsets (one more offset than glyphs, to mark size of last) */ - if ( FT_FRAME_ENTER( ( blend->gv_glyphcnt + 1 ) * 2L ) ) - goto Exit; - - for ( i = 0; i <= blend->gv_glyphcnt; i++ ) - blend->glyphoffsets[i] = offsetToData + FT_GET_USHORT() * 2; - /* XXX: Undocumented: `*2'! */ - - FT_FRAME_EXIT(); - } - - if ( blend->tuplecount != 0 ) - { - if ( FT_NEW_ARRAY( blend->tuplecoords, - gvar_head.axisCount * blend->tuplecount ) ) - goto Exit; - - if ( FT_STREAM_SEEK( gvar_start + gvar_head.offsetToCoord ) || - FT_FRAME_ENTER( blend->tuplecount * gvar_head.axisCount * 2L ) ) - goto Exit; - - for ( i = 0; i < blend->tuplecount; i++ ) - { - FT_TRACE5(( " [ " )); - for ( j = 0 ; j < (FT_UInt)gvar_head.axisCount; j++ ) - { - blend->tuplecoords[i * gvar_head.axisCount + j] = - FT_GET_SHORT() * 4; /* convert to FT_Fixed */ - FT_TRACE5(( "%.4f ", - blend->tuplecoords[i * gvar_head.axisCount + j] / 65536.0 )); - } - FT_TRACE5(( "]\n" )); - } - - FT_TRACE5(( "\n" )); - - FT_FRAME_EXIT(); - } - - Exit: - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* ft_var_apply_tuple */ - /* */ - /* */ - /* Figure out whether a given tuple (design) applies to the current */ - /* blend, and if so, what is the scaling factor. */ - /* */ - /* */ - /* blend :: The current blend of the font. */ - /* */ - /* tupleIndex :: A flag saying whether this is an intermediate */ - /* tuple or not. */ - /* */ - /* tuple_coords :: The coordinates of the tuple in normalized axis */ - /* units. */ - /* */ - /* im_start_coords :: The initial coordinates where this tuple starts */ - /* to apply (for intermediate coordinates). */ - /* */ - /* im_end_coords :: The final coordinates after which this tuple no */ - /* longer applies (for intermediate coordinates). */ - /* */ - /* */ - /* An FT_Fixed value containing the scaling factor. */ - /* */ - static FT_Fixed - ft_var_apply_tuple( GX_Blend blend, - FT_UShort tupleIndex, - FT_Fixed* tuple_coords, - FT_Fixed* im_start_coords, - FT_Fixed* im_end_coords ) - { - FT_UInt i; - FT_Fixed apply = 0x10000L; - - - for ( i = 0; i < blend->num_axis; i++ ) - { - FT_TRACE6(( " axis coordinate %d (%.4f):\n", - i, blend->normalizedcoords[i] / 65536.0 )); - - /* It's not clear why (for intermediate tuples) we don't need */ - /* to check against start/end -- the documentation says we don't. */ - /* Similarly, it's unclear why we don't need to scale along the */ - /* axis. */ - - if ( tuple_coords[i] == 0 ) - { - FT_TRACE6(( " tuple coordinate is zero, ignored\n", i )); - continue; - } - - else if ( blend->normalizedcoords[i] == 0 ) - { - FT_TRACE6(( " axis coordinate is zero, stop\n" )); - apply = 0; - break; - } - - else if ( ( blend->normalizedcoords[i] < 0 && tuple_coords[i] > 0 ) || - ( blend->normalizedcoords[i] > 0 && tuple_coords[i] < 0 ) ) - { - FT_TRACE6(( " tuple coordinate value %.4f is exceeded, stop\n", - tuple_coords[i] / 65536.0 )); - apply = 0; - break; - } - - else if ( !( tupleIndex & GX_TI_INTERMEDIATE_TUPLE ) ) - { - FT_TRACE6(( " tuple coordinate value %.4f fits\n", - tuple_coords[i] / 65536.0 )); - /* not an intermediate tuple */ - apply = FT_MulFix( apply, - blend->normalizedcoords[i] > 0 - ? blend->normalizedcoords[i] - : -blend->normalizedcoords[i] ); - } - - else if ( blend->normalizedcoords[i] < im_start_coords[i] || - blend->normalizedcoords[i] > im_end_coords[i] ) - { - FT_TRACE6(( " intermediate tuple range [%.4f;%.4f] is exceeded," - " stop\n", - im_start_coords[i] / 65536.0, - im_end_coords[i] / 65536.0 )); - apply = 0; - break; - } - - else if ( blend->normalizedcoords[i] < tuple_coords[i] ) - { - FT_TRACE6(( " intermediate tuple range [%.4f;%.4f] fits\n", - im_start_coords[i] / 65536.0, - im_end_coords[i] / 65536.0 )); - apply = FT_MulDiv( apply, - blend->normalizedcoords[i] - im_start_coords[i], - tuple_coords[i] - im_start_coords[i] ); - } - - else - { - FT_TRACE6(( " intermediate tuple range [%.4f;%.4f] fits\n", - im_start_coords[i] / 65536.0, - im_end_coords[i] / 65536.0 )); - apply = FT_MulDiv( apply, - im_end_coords[i] - blend->normalizedcoords[i], - im_end_coords[i] - tuple_coords[i] ); - } - } - - FT_TRACE6(( " apply factor is %.4f\n", apply / 65536.0 )); - - return apply; - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** MULTIPLE MASTERS SERVICE FUNCTIONS *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - - typedef struct GX_FVar_Head_ - { - FT_Long version; - FT_UShort offsetToData; - FT_UShort countSizePairs; - FT_UShort axisCount; - FT_UShort axisSize; - FT_UShort instanceCount; - FT_UShort instanceSize; - - } GX_FVar_Head; - - - typedef struct fvar_axis_ - { - FT_ULong axisTag; - FT_Fixed minValue; - FT_Fixed defaultValue; - FT_Fixed maxValue; - FT_UShort flags; - FT_UShort nameID; - - } GX_FVar_Axis; - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Get_MM_Var */ - /* */ - /* */ - /* Check that the font's `fvar' table is valid, parse it, and return */ - /* those data. */ - /* */ - /* */ - /* face :: The font face. */ - /* TT_Get_MM_Var initializes the blend structure. */ - /* */ - /* */ - /* master :: The `fvar' data (must be freed by caller). Can be NULL, */ - /* which makes this function simply load MM support. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - FT_LOCAL_DEF( FT_Error ) - TT_Get_MM_Var( TT_Face face, - FT_MM_Var* *master ) - { - FT_Stream stream = face->root.stream; - FT_Memory memory = face->root.memory; - FT_ULong table_len; - FT_Error error = FT_Err_Ok; - FT_ULong fvar_start; - FT_Int i, j; - FT_MM_Var* mmvar = NULL; - FT_Fixed* next_coords; - FT_String* next_name; - FT_Var_Axis* a; - FT_Var_Named_Style* ns; - GX_FVar_Head fvar_head; - - static const FT_Frame_Field fvar_fields[] = - { - -#undef FT_STRUCTURE -#define FT_STRUCTURE GX_FVar_Head - - FT_FRAME_START( 16 ), - FT_FRAME_LONG ( version ), - FT_FRAME_USHORT( offsetToData ), - FT_FRAME_USHORT( countSizePairs ), - FT_FRAME_USHORT( axisCount ), - FT_FRAME_USHORT( axisSize ), - FT_FRAME_USHORT( instanceCount ), - FT_FRAME_USHORT( instanceSize ), - FT_FRAME_END - }; - - static const FT_Frame_Field fvaraxis_fields[] = - { - -#undef FT_STRUCTURE -#define FT_STRUCTURE GX_FVar_Axis - - FT_FRAME_START( 20 ), - FT_FRAME_ULONG ( axisTag ), - FT_FRAME_LONG ( minValue ), - FT_FRAME_LONG ( defaultValue ), - FT_FRAME_LONG ( maxValue ), - FT_FRAME_USHORT( flags ), - FT_FRAME_USHORT( nameID ), - FT_FRAME_END - }; - - - /* read the font data and set up the internal representation */ - /* if not already done */ - - if ( face->blend == NULL ) - { - FT_TRACE2(( "FVAR " )); - - /* both `fvar' and `gvar' must be present */ - if ( ( error = face->goto_table( face, TTAG_gvar, - stream, &table_len ) ) != 0 ) - { - FT_TRACE1(( "\n" - "TT_Get_MM_Var: `gvar' table is missing\n" )); - goto Exit; - } - - if ( ( error = face->goto_table( face, TTAG_fvar, - stream, &table_len ) ) != 0 ) - { - FT_TRACE1(( "is missing\n" )); - goto Exit; - } - - fvar_start = FT_STREAM_POS( ); - - if ( FT_STREAM_READ_FIELDS( fvar_fields, &fvar_head ) ) - goto Exit; - - if ( fvar_head.version != (FT_Long)0x00010000L || -#if 0 - /* fonts like `JamRegular.ttf' have an incorrect value for */ - /* `countSizePairs'; since value 2 is hard-coded in `fvar' */ - /* version 1.0, we simply ignore it */ - fvar_head.countSizePairs != 2 || -#endif - fvar_head.axisSize != 20 || - /* axisCount limit implied by 16-bit instanceSize */ - fvar_head.axisCount > 0x3FFE || - fvar_head.instanceSize != 4 + 4 * fvar_head.axisCount || - /* instanceCount limit implied by limited range of name IDs */ - fvar_head.instanceCount > 0x7EFF || - fvar_head.offsetToData + fvar_head.axisCount * 20U + - fvar_head.instanceCount * fvar_head.instanceSize > table_len ) - { - FT_TRACE1(( "\n" - "TT_Get_MM_Var: invalid `fvar' header\n" )); - error = FT_THROW( Invalid_Table ); - goto Exit; - } - - FT_TRACE2(( "loaded\n" )); - - FT_TRACE5(( "number of GX style axes: %d\n", fvar_head.axisCount )); - - if ( FT_NEW( face->blend ) ) - goto Exit; - - /* cannot overflow 32-bit arithmetic because of limits above */ - face->blend->mmvar_len = - sizeof ( FT_MM_Var ) + - fvar_head.axisCount * sizeof ( FT_Var_Axis ) + - fvar_head.instanceCount * sizeof ( FT_Var_Named_Style ) + - fvar_head.instanceCount * fvar_head.axisCount * sizeof ( FT_Fixed ) + - 5 * fvar_head.axisCount; - - if ( FT_ALLOC( mmvar, face->blend->mmvar_len ) ) - goto Exit; - face->blend->mmvar = mmvar; - - /* set up pointers and offsets into the `mmvar' array; */ - /* the data gets filled in later on */ - - mmvar->num_axis = - fvar_head.axisCount; - mmvar->num_designs = - ~0U; /* meaningless in this context; each glyph */ - /* may have a different number of designs */ - /* (or tuples, as called by Apple) */ - mmvar->num_namedstyles = - fvar_head.instanceCount; - mmvar->axis = - (FT_Var_Axis*)&( mmvar[1] ); - mmvar->namedstyle = - (FT_Var_Named_Style*)&( mmvar->axis[fvar_head.axisCount] ); - - next_coords = - (FT_Fixed*)&( mmvar->namedstyle[fvar_head.instanceCount] ); - for ( i = 0; i < fvar_head.instanceCount; i++ ) - { - mmvar->namedstyle[i].coords = next_coords; - next_coords += fvar_head.axisCount; - } - - next_name = (FT_String*)next_coords; - for ( i = 0; i < fvar_head.axisCount; i++ ) - { - mmvar->axis[i].name = next_name; - next_name += 5; - } - - /* now fill in the data */ - - if ( FT_STREAM_SEEK( fvar_start + fvar_head.offsetToData ) ) - goto Exit; - - a = mmvar->axis; - for ( i = 0; i < fvar_head.axisCount; i++ ) - { - GX_FVar_Axis axis_rec; - - - if ( FT_STREAM_READ_FIELDS( fvaraxis_fields, &axis_rec ) ) - goto Exit; - a->tag = axis_rec.axisTag; - a->minimum = axis_rec.minValue; - a->def = axis_rec.defaultValue; - a->maximum = axis_rec.maxValue; - a->strid = axis_rec.nameID; - - a->name[0] = (FT_String)( a->tag >> 24 ); - a->name[1] = (FT_String)( ( a->tag >> 16 ) & 0xFF ); - a->name[2] = (FT_String)( ( a->tag >> 8 ) & 0xFF ); - a->name[3] = (FT_String)( ( a->tag ) & 0xFF ); - a->name[4] = '\0'; - - FT_TRACE5(( " \"%s\": minimum=%.4f, default=%.4f, maximum=%.4f\n", - a->name, - a->minimum / 65536.0, - a->def / 65536.0, - a->maximum / 65536.0 )); - - a++; - } - - FT_TRACE5(( "\n" )); - - ns = mmvar->namedstyle; - for ( i = 0; i < fvar_head.instanceCount; i++, ns++ ) - { - if ( FT_FRAME_ENTER( 4L + 4L * fvar_head.axisCount ) ) - goto Exit; - - ns->strid = FT_GET_USHORT(); - (void) /* flags = */ FT_GET_USHORT(); - - for ( j = 0; j < fvar_head.axisCount; j++ ) - ns->coords[j] = FT_GET_LONG(); - - FT_FRAME_EXIT(); - } - } - - /* fill the output array if requested */ - - if ( master != NULL ) - { - FT_UInt n; - - - if ( FT_ALLOC( mmvar, face->blend->mmvar_len ) ) - goto Exit; - FT_MEM_COPY( mmvar, face->blend->mmvar, face->blend->mmvar_len ); - - mmvar->axis = - (FT_Var_Axis*)&( mmvar[1] ); - mmvar->namedstyle = - (FT_Var_Named_Style*)&( mmvar->axis[mmvar->num_axis] ); - next_coords = - (FT_Fixed*)&( mmvar->namedstyle[mmvar->num_namedstyles] ); - - for ( n = 0; n < mmvar->num_namedstyles; n++ ) - { - mmvar->namedstyle[n].coords = next_coords; - next_coords += mmvar->num_axis; - } - - a = mmvar->axis; - next_name = (FT_String*)next_coords; - for ( n = 0; n < mmvar->num_axis; n++ ) - { - a->name = next_name; - - /* standard PostScript names for some standard apple tags */ - if ( a->tag == TTAG_wght ) - a->name = (char*)"Weight"; - else if ( a->tag == TTAG_wdth ) - a->name = (char*)"Width"; - else if ( a->tag == TTAG_opsz ) - a->name = (char*)"OpticalSize"; - else if ( a->tag == TTAG_slnt ) - a->name = (char*)"Slant"; - - next_name += 5; - a++; - } - - *master = mmvar; - } - - Exit: - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Set_MM_Blend */ - /* */ - /* */ - /* Set the blend (normalized) coordinates for this instance of the */ - /* font. Check that the `gvar' table is reasonable and does some */ - /* initial preparation. */ - /* */ - /* */ - /* face :: The font. */ - /* Initialize the blend structure with `gvar' data. */ - /* */ - /* */ - /* num_coords :: The number of available coordinates. If it is */ - /* larger than the number of axes, ignore the excess */ - /* values. If it is smaller than the number of axes, */ - /* use the default value (0) for the remaining axes. */ - /* */ - /* coords :: An array of `num_coords', each between [-1,1]. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - FT_LOCAL_DEF( FT_Error ) - TT_Set_MM_Blend( TT_Face face, - FT_UInt num_coords, - FT_Fixed* coords ) - { - FT_Error error = FT_Err_Ok; - GX_Blend blend; - FT_MM_Var* mmvar; - FT_UInt i; - FT_Memory memory = face->root.memory; - - enum - { - mcvt_retain, - mcvt_modify, - mcvt_load - - } manageCvt; - - - face->doblend = FALSE; - - if ( face->blend == NULL ) - { - if ( ( error = TT_Get_MM_Var( face, NULL ) ) != 0 ) - goto Exit; - } - - blend = face->blend; - mmvar = blend->mmvar; - - if ( num_coords > mmvar->num_axis ) - { - FT_TRACE2(( "TT_Set_MM_Blend: only using first %d of %d coordinates\n", - mmvar->num_axis, num_coords )); - num_coords = mmvar->num_axis; - } - - FT_TRACE5(( "normalized design coordinates:\n" )); - - for ( i = 0; i < num_coords; i++ ) - { - FT_TRACE5(( " %.4f\n", coords[i] / 65536.0 )); - if ( coords[i] < -0x00010000L || coords[i] > 0x00010000L ) - { - FT_TRACE1(( "TT_Set_MM_Blend: normalized design coordinate %.4f\n" - " is out of range [-1;1]\n", - coords[i] / 65536.0 )); - error = FT_THROW( Invalid_Argument ); - goto Exit; - } - } - - FT_TRACE5(( "\n" )); - - if ( blend->glyphoffsets == NULL ) - if ( ( error = ft_var_load_gvar( face ) ) != 0 ) - goto Exit; - - if ( blend->normalizedcoords == NULL ) - { - if ( FT_NEW_ARRAY( blend->normalizedcoords, mmvar->num_axis ) ) - goto Exit; - - manageCvt = mcvt_modify; - - /* If we have not set the blend coordinates before this, then the */ - /* cvt table will still be what we read from the `cvt ' table and */ - /* we don't need to reload it. We may need to change it though... */ - } - else - { - manageCvt = mcvt_retain; - - for ( i = 0; i < num_coords; i++ ) - { - if ( blend->normalizedcoords[i] != coords[i] ) - { - manageCvt = mcvt_load; - break; - } - } - - for ( ; i < mmvar->num_axis; i++ ) - { - if ( blend->normalizedcoords[i] != 0 ) - { - manageCvt = mcvt_load; - break; - } - } - - /* If we don't change the blend coords then we don't need to do */ - /* anything to the cvt table. It will be correct. Otherwise we */ - /* no longer have the original cvt (it was modified when we set */ - /* the blend last time), so we must reload and then modify it. */ - } - - blend->num_axis = mmvar->num_axis; - FT_MEM_COPY( blend->normalizedcoords, - coords, - num_coords * sizeof ( FT_Fixed ) ); - - face->doblend = TRUE; - - if ( face->cvt != NULL ) - { - switch ( manageCvt ) - { - case mcvt_load: - /* The cvt table has been loaded already; every time we change the */ - /* blend we may need to reload and remodify the cvt table. */ - FT_FREE( face->cvt ); - face->cvt = NULL; - - error = tt_face_load_cvt( face, face->root.stream ); - break; - - case mcvt_modify: - /* The original cvt table is in memory. All we need to do is */ - /* apply the `cvar' table (if any). */ - error = tt_face_vary_cvt( face, face->root.stream ); - break; - - case mcvt_retain: - /* The cvt table is correct for this set of coordinates. */ - break; - } - } - - Exit: - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Set_Var_Design */ - /* */ - /* */ - /* Set the coordinates for the instance, measured in the user */ - /* coordinate system. Parse the `avar' table (if present) to convert */ - /* from user to normalized coordinates. */ - /* */ - /* */ - /* face :: The font face. */ - /* Initialize the blend struct with `gvar' data. */ - /* */ - /* */ - /* num_coords :: The number of available coordinates. If it is */ - /* larger than the number of axes, ignore the excess */ - /* values. If it is smaller than the number of axes, */ - /* use the default values for the remaining axes. */ - /* */ - /* coords :: A coordinate array with `num_coords' elements. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - FT_LOCAL_DEF( FT_Error ) - TT_Set_Var_Design( TT_Face face, - FT_UInt num_coords, - FT_Fixed* coords ) - { - FT_Error error = FT_Err_Ok; - FT_Fixed* normalized = NULL; - GX_Blend blend; - FT_MM_Var* mmvar; - FT_UInt i, j; - FT_Var_Axis* a; - GX_AVarSegment av; - FT_Memory memory = face->root.memory; - - - if ( face->blend == NULL ) - { - if ( ( error = TT_Get_MM_Var( face, NULL ) ) != 0 ) - goto Exit; - } - - blend = face->blend; - mmvar = blend->mmvar; - - if ( num_coords > mmvar->num_axis ) - { - FT_TRACE2(( "TT_Set_Var_Design:" - " only using first %d of %d coordinates\n", - mmvar->num_axis, num_coords )); - num_coords = mmvar->num_axis; - } - - /* Axis normalization is a two stage process. First we normalize */ - /* based on the [min,def,max] values for the axis to be [-1,0,1]. */ - /* Then, if there's an `avar' table, we renormalize this range. */ - - if ( FT_NEW_ARRAY( normalized, mmvar->num_axis ) ) - goto Exit; - - FT_TRACE5(( "design coordinates:\n" )); - - a = mmvar->axis; - for ( i = 0; i < num_coords; i++, a++ ) - { - FT_TRACE5(( " %.4f\n", coords[i] / 65536.0 )); - if ( coords[i] > a->maximum || coords[i] < a->minimum ) - { - FT_TRACE1(( "TT_Set_Var_Design: normalized design coordinate %.4f\n" - " is out of range [%.4f;%.4f]\n", - coords[i] / 65536.0, - a->minimum / 65536.0, - a->maximum / 65536.0 )); - error = FT_THROW( Invalid_Argument ); - goto Exit; - } - - if ( coords[i] < a->def ) - normalized[i] = -FT_DivFix( coords[i] - a->def, - a->minimum - a->def ); - else if ( a->maximum == a->def ) - normalized[i] = 0; - else - normalized[i] = FT_DivFix( coords[i] - a->def, - a->maximum - a->def ); - } - - FT_TRACE5(( "\n" )); - - for ( ; i < mmvar->num_axis; i++ ) - normalized[i] = 0; - - if ( !blend->avar_checked ) - ft_var_load_avar( face ); - - if ( blend->avar_segment != NULL ) - { - FT_TRACE5(( "normalized design coordinates" - " before applying `avar' data:\n" )); - - av = blend->avar_segment; - for ( i = 0; i < mmvar->num_axis; i++, av++ ) - { - for ( j = 1; j < (FT_UInt)av->pairCount; j++ ) - { - FT_TRACE5(( " %.4f\n", normalized[i] / 65536.0 )); - if ( normalized[i] < av->correspondence[j].fromCoord ) - { - normalized[i] = - FT_MulDiv( normalized[i] - av->correspondence[j - 1].fromCoord, - av->correspondence[j].toCoord - - av->correspondence[j - 1].toCoord, - av->correspondence[j].fromCoord - - av->correspondence[j - 1].fromCoord ) + - av->correspondence[j - 1].toCoord; - break; - } - } - } - } - - error = TT_Set_MM_Blend( face, mmvar->num_axis, normalized ); - - Exit: - FT_FREE( normalized ); - return error; - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** GX VAR PARSING ROUTINES *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* tt_face_vary_cvt */ - /* */ - /* */ - /* Modify the loaded cvt table according to the `cvar' table and the */ - /* font's blend. */ - /* */ - /* */ - /* face :: A handle to the target face object. */ - /* */ - /* */ - /* stream :: A handle to the input stream. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* Most errors are ignored. It is perfectly valid not to have a */ - /* `cvar' table even if there is a `gvar' and `fvar' table. */ - /* */ - FT_LOCAL_DEF( FT_Error ) - tt_face_vary_cvt( TT_Face face, - FT_Stream stream ) - { - FT_Error error; - FT_Memory memory = stream->memory; - FT_ULong table_start; - FT_ULong table_len; - FT_UInt tupleCount; - FT_ULong offsetToData; - FT_ULong here; - FT_UInt i, j; - FT_Fixed* tuple_coords = NULL; - FT_Fixed* im_start_coords = NULL; - FT_Fixed* im_end_coords = NULL; - GX_Blend blend = face->blend; - FT_UInt point_count; - FT_UShort* localpoints; - FT_Short* deltas; - - - FT_TRACE2(( "CVAR " )); - - if ( blend == NULL ) - { - FT_TRACE2(( "\n" - "tt_face_vary_cvt: no blend specified\n" )); - error = FT_Err_Ok; - goto Exit; - } - - if ( face->cvt == NULL ) - { - FT_TRACE2(( "\n" - "tt_face_vary_cvt: no `cvt ' table\n" )); - error = FT_Err_Ok; - goto Exit; - } - - error = face->goto_table( face, TTAG_cvar, stream, &table_len ); - if ( error ) - { - FT_TRACE2(( "is missing\n" )); - - error = FT_Err_Ok; - goto Exit; - } - - if ( FT_FRAME_ENTER( table_len ) ) - { - error = FT_Err_Ok; - goto Exit; - } - - table_start = FT_Stream_FTell( stream ); - if ( FT_GET_LONG() != 0x00010000L ) - { - FT_TRACE2(( "bad table version\n" )); - - error = FT_Err_Ok; - goto FExit; - } - - FT_TRACE2(( "loaded\n" )); - - if ( FT_NEW_ARRAY( tuple_coords, blend->num_axis ) || - FT_NEW_ARRAY( im_start_coords, blend->num_axis ) || - FT_NEW_ARRAY( im_end_coords, blend->num_axis ) ) - goto FExit; - - tupleCount = FT_GET_USHORT(); - offsetToData = table_start + FT_GET_USHORT(); - - /* The documentation implies there are flags packed into the */ - /* tuplecount, but John Jenkins says that shared points don't apply */ - /* to `cvar', and no other flags are defined. */ - - FT_TRACE5(( "cvar: there are %d tuples:\n", tupleCount )); - - for ( i = 0; i < ( tupleCount & 0xFFF ); i++ ) - { - FT_UInt tupleDataSize; - FT_UInt tupleIndex; - FT_Fixed apply; - - - FT_TRACE6(( " tuple %d:\n", i )); - - tupleDataSize = FT_GET_USHORT(); - tupleIndex = FT_GET_USHORT(); - - /* There is no provision here for a global tuple coordinate section, */ - /* so John says. There are no tuple indices, just embedded tuples. */ - - if ( tupleIndex & GX_TI_EMBEDDED_TUPLE_COORD ) - { - for ( j = 0; j < blend->num_axis; j++ ) - tuple_coords[j] = FT_GET_SHORT() * 4; /* convert from */ - /* short frac to fixed */ - } - else - { - /* skip this tuple; it makes no sense */ - - if ( tupleIndex & GX_TI_INTERMEDIATE_TUPLE ) - for ( j = 0; j < 2 * blend->num_axis; j++ ) - (void)FT_GET_SHORT(); - - offsetToData += tupleDataSize; - continue; - } - - if ( tupleIndex & GX_TI_INTERMEDIATE_TUPLE ) - { - for ( j = 0; j < blend->num_axis; j++ ) - im_start_coords[j] = FT_GET_SHORT() * 4; - for ( j = 0; j < blend->num_axis; j++ ) - im_end_coords[j] = FT_GET_SHORT() * 4; - } - - apply = ft_var_apply_tuple( blend, - (FT_UShort)tupleIndex, - tuple_coords, - im_start_coords, - im_end_coords ); - if ( /* tuple isn't active for our blend */ - apply == 0 || - /* global points not allowed, */ - /* if they aren't local, makes no sense */ - !( tupleIndex & GX_TI_PRIVATE_POINT_NUMBERS ) ) - { - offsetToData += tupleDataSize; - continue; - } - - here = FT_Stream_FTell( stream ); - - FT_Stream_SeekSet( stream, offsetToData ); - - localpoints = ft_var_readpackedpoints( stream, &point_count ); - deltas = ft_var_readpackeddeltas( stream, - point_count == 0 ? face->cvt_size - : point_count ); - if ( localpoints == NULL || deltas == NULL ) - ; /* failure, ignore it */ - - else if ( localpoints == ALL_POINTS ) - { -#ifdef FT_DEBUG_LEVEL_TRACE - int count = 0; -#endif - - - FT_TRACE7(( " CVT deltas:\n" )); - - /* this means that there are deltas for every entry in cvt */ - for ( j = 0; j < face->cvt_size; j++ ) - { - FT_Long orig_cvt = face->cvt[j]; - - - face->cvt[j] = (FT_Short)( orig_cvt + - FT_MulFix( deltas[j], apply ) ); - -#ifdef FT_DEBUG_LEVEL_TRACE - if ( orig_cvt != face->cvt[j] ) - { - FT_TRACE7(( " %d: %d -> %d\n", - j, orig_cvt, face->cvt[j] )); - count++; - } -#endif - } - -#ifdef FT_DEBUG_LEVEL_TRACE - if ( !count ) - FT_TRACE7(( " none\n" )); -#endif - } - - else - { -#ifdef FT_DEBUG_LEVEL_TRACE - int count = 0; -#endif - - - FT_TRACE7(( " CVT deltas:\n" )); - - for ( j = 0; j < point_count; j++ ) - { - int pindex = localpoints[j]; - FT_Long orig_cvt = face->cvt[pindex]; - - - face->cvt[pindex] = (FT_Short)( orig_cvt + - FT_MulFix( deltas[j], apply ) ); - -#ifdef FT_DEBUG_LEVEL_TRACE - if ( orig_cvt != face->cvt[pindex] ) - { - FT_TRACE7(( " %d: %d -> %d\n", - pindex, orig_cvt, face->cvt[pindex] )); - count++; - } -#endif - } - -#ifdef FT_DEBUG_LEVEL_TRACE - if ( !count ) - FT_TRACE7(( " none\n" )); -#endif - } - - if ( localpoints != ALL_POINTS ) - FT_FREE( localpoints ); - FT_FREE( deltas ); - - offsetToData += tupleDataSize; - - FT_Stream_SeekSet( stream, here ); - } - - FT_TRACE5(( "\n" )); - - FExit: - FT_FRAME_EXIT(); - - Exit: - FT_FREE( tuple_coords ); - FT_FREE( im_start_coords ); - FT_FREE( im_end_coords ); - - return error; - } - - - /* Shift the original coordinates of all points between indices `p1' */ - /* and `p2', using the same difference as given by index `ref'. */ - - /* modeled after `af_iup_shift' */ - - static void - tt_delta_shift( int p1, - int p2, - int ref, - FT_Vector* in_points, - FT_Vector* out_points ) - { - int p; - FT_Vector delta; - - - delta.x = out_points[ref].x - in_points[ref].x; - delta.y = out_points[ref].y - in_points[ref].y; - - if ( delta.x == 0 && delta.y == 0 ) - return; - - for ( p = p1; p < ref; p++ ) - { - out_points[p].x += delta.x; - out_points[p].y += delta.y; - } - - for ( p = ref + 1; p <= p2; p++ ) - { - out_points[p].x += delta.x; - out_points[p].y += delta.y; - } - } - - - /* Interpolate the original coordinates of all points with indices */ - /* between `p1' and `p2', using `ref1' and `ref2' as the reference */ - /* point indices. */ - - /* modeled after `af_iup_interp', `_iup_worker_interpolate', and */ - /* `Ins_IUP' */ - - static void - tt_delta_interpolate( int p1, - int p2, - int ref1, - int ref2, - FT_Vector* in_points, - FT_Vector* out_points ) - { - int p, i; - - FT_Pos out, in1, in2, out1, out2, d1, d2; - - - if ( p1 > p2 ) - return; - - /* handle both horizontal and vertical coordinates */ - for ( i = 0; i <= 1; i++ ) - { - /* shift array pointers so that we can access `foo.y' as `foo.x' */ - in_points = (FT_Vector*)( (FT_Pos*)in_points + i ); - out_points = (FT_Vector*)( (FT_Pos*)out_points + i ); - - if ( in_points[ref1].x > in_points[ref2].x ) - { - p = ref1; - ref1 = ref2; - ref2 = p; - } - - in1 = in_points[ref1].x; - in2 = in_points[ref2].x; - out1 = out_points[ref1].x; - out2 = out_points[ref2].x; - d1 = out1 - in1; - d2 = out2 - in2; - - if ( out1 == out2 || in1 == in2 ) - { - for ( p = p1; p <= p2; p++ ) - { - out = in_points[p].x; - - if ( out <= in1 ) - out += d1; - else if ( out >= in2 ) - out += d2; - else - out = out1; - - out_points[p].x = out; - } - } - else - { - FT_Fixed scale = FT_DivFix( out2 - out1, in2 - in1 ); - - - for ( p = p1; p <= p2; p++ ) - { - out = in_points[p].x; - - if ( out <= in1 ) - out += d1; - else if ( out >= in2 ) - out += d2; - else - out = out1 + FT_MulFix( out - in1, scale ); - - out_points[p].x = out; - } - } - } - } - - - /* Interpolate points without delta values, similar to */ - /* the `IUP' hinting instruction. */ - - /* modeled after `Ins_IUP */ - - static void - tt_handle_deltas( FT_Outline* outline, - FT_Vector* in_points, - FT_Bool* has_delta ) - { - FT_Vector* out_points; - - FT_Int first_point; - FT_Int end_point; - - FT_Int first_delta; - FT_Int cur_delta; - - FT_Int point; - FT_Short contour; - - - /* ignore empty outlines */ - if ( !outline->n_contours ) - return; - - out_points = outline->points; - - contour = 0; - point = 0; - - do - { - end_point = outline->contours[contour]; - first_point = point; - - /* search first point that has a delta */ - while ( point <= end_point && !has_delta[point] ) - point++; - - if ( point <= end_point ) - { - first_delta = point; - cur_delta = point; - - point++; - - while ( point <= end_point ) - { - /* search next point that has a delta */ - /* and interpolate intermediate points */ - if ( has_delta[point] ) - { - tt_delta_interpolate( cur_delta + 1, - point - 1, - cur_delta, - point, - in_points, - out_points ); - cur_delta = point; - } - - point++; - } - - /* shift contour if we only have a single delta */ - if ( cur_delta == first_delta ) - tt_delta_shift( first_point, - end_point, - cur_delta, - in_points, - out_points ); - else - { - /* otherwise handle remaining points */ - /* at the end and beginning of the contour */ - tt_delta_interpolate( cur_delta + 1, - end_point, - cur_delta, - first_delta, - in_points, - out_points ); - - if ( first_delta > 0 ) - tt_delta_interpolate( first_point, - first_delta - 1, - cur_delta, - first_delta, - in_points, - out_points ); - } - } - contour++; - - } while ( contour < outline->n_contours ); - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Vary_Apply_Glyph_Deltas */ - /* */ - /* */ - /* Apply the appropriate deltas to the current glyph. */ - /* */ - /* */ - /* face :: A handle to the target face object. */ - /* */ - /* glyph_index :: The index of the glyph being modified. */ - /* */ - /* n_points :: The number of the points in the glyph, including */ - /* phantom points. */ - /* */ - /* */ - /* outline :: The outline to change. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - FT_LOCAL_DEF( FT_Error ) - TT_Vary_Apply_Glyph_Deltas( TT_Face face, - FT_UInt glyph_index, - FT_Outline* outline, - FT_UInt n_points ) - { - FT_Stream stream = face->root.stream; - FT_Memory memory = stream->memory; - GX_Blend blend = face->blend; - - FT_Vector* points_org = NULL; - FT_Bool* has_delta = NULL; - - FT_Error error; - FT_ULong glyph_start; - FT_UInt tupleCount; - FT_ULong offsetToData; - FT_ULong here; - FT_UInt i, j; - FT_Fixed* tuple_coords = NULL; - FT_Fixed* im_start_coords = NULL; - FT_Fixed* im_end_coords = NULL; - FT_UInt point_count, spoint_count = 0; - FT_UShort* sharedpoints = NULL; - FT_UShort* localpoints = NULL; - FT_UShort* points; - FT_Short *deltas_x, *deltas_y; - - - if ( !face->doblend || blend == NULL ) - return FT_THROW( Invalid_Argument ); - - if ( glyph_index >= blend->gv_glyphcnt || - blend->glyphoffsets[glyph_index] == - blend->glyphoffsets[glyph_index + 1] ) - { - FT_TRACE2(( "TT_Vary_Apply_Glyph_Deltas:" - " no variation data for this glyph\n" )); - return FT_Err_Ok; - } - - if ( FT_NEW_ARRAY( points_org, n_points ) || - FT_NEW_ARRAY( has_delta, n_points ) ) - goto Fail1; - - if ( FT_STREAM_SEEK( blend->glyphoffsets[glyph_index] ) || - FT_FRAME_ENTER( blend->glyphoffsets[glyph_index + 1] - - blend->glyphoffsets[glyph_index] ) ) - goto Fail1; - - glyph_start = FT_Stream_FTell( stream ); - - /* each set of glyph variation data is formatted similarly to `cvar' */ - /* (except we get shared points and global tuples) */ - - if ( FT_NEW_ARRAY( tuple_coords, blend->num_axis ) || - FT_NEW_ARRAY( im_start_coords, blend->num_axis ) || - FT_NEW_ARRAY( im_end_coords, blend->num_axis ) ) - goto Fail2; - - tupleCount = FT_GET_USHORT(); - offsetToData = glyph_start + FT_GET_USHORT(); - - if ( tupleCount & GX_TC_TUPLES_SHARE_POINT_NUMBERS ) - { - here = FT_Stream_FTell( stream ); - - FT_Stream_SeekSet( stream, offsetToData ); - - sharedpoints = ft_var_readpackedpoints( stream, &spoint_count ); - offsetToData = FT_Stream_FTell( stream ); - - FT_Stream_SeekSet( stream, here ); - } - - FT_TRACE5(( "gvar: there are %d tuples:\n", tupleCount )); - - for ( i = 0; i < ( tupleCount & GX_TC_TUPLE_COUNT_MASK ); i++ ) - { - FT_UInt tupleDataSize; - FT_UInt tupleIndex; - FT_Fixed apply; - - - FT_TRACE6(( " tuple %d:\n", i )); - - tupleDataSize = FT_GET_USHORT(); - tupleIndex = FT_GET_USHORT(); - - if ( tupleIndex & GX_TI_EMBEDDED_TUPLE_COORD ) - { - for ( j = 0; j < blend->num_axis; j++ ) - tuple_coords[j] = FT_GET_SHORT() * 4; /* convert from */ - /* short frac to fixed */ - } - else if ( ( tupleIndex & GX_TI_TUPLE_INDEX_MASK ) >= blend->tuplecount ) - { - error = FT_THROW( Invalid_Table ); - goto Fail2; - } - else - FT_MEM_COPY( - tuple_coords, - &blend->tuplecoords[( tupleIndex & 0xFFF ) * blend->num_axis], - blend->num_axis * sizeof ( FT_Fixed ) ); - - if ( tupleIndex & GX_TI_INTERMEDIATE_TUPLE ) - { - for ( j = 0; j < blend->num_axis; j++ ) - im_start_coords[j] = FT_GET_SHORT() * 4; - for ( j = 0; j < blend->num_axis; j++ ) - im_end_coords[j] = FT_GET_SHORT() * 4; - } - - apply = ft_var_apply_tuple( blend, - (FT_UShort)tupleIndex, - tuple_coords, - im_start_coords, - im_end_coords ); - - if ( apply == 0 ) /* tuple isn't active for our blend */ - { - offsetToData += tupleDataSize; - continue; - } - - here = FT_Stream_FTell( stream ); - - if ( tupleIndex & GX_TI_PRIVATE_POINT_NUMBERS ) - { - FT_Stream_SeekSet( stream, offsetToData ); - - localpoints = ft_var_readpackedpoints( stream, &point_count ); - points = localpoints; - } - else - { - points = sharedpoints; - point_count = spoint_count; - } - - deltas_x = ft_var_readpackeddeltas( stream, - point_count == 0 ? n_points - : point_count ); - deltas_y = ft_var_readpackeddeltas( stream, - point_count == 0 ? n_points - : point_count ); - - if ( points == NULL || deltas_y == NULL || deltas_x == NULL ) - ; /* failure, ignore it */ - - else if ( points == ALL_POINTS ) - { -#ifdef FT_DEBUG_LEVEL_TRACE - int count = 0; -#endif - - - FT_TRACE7(( " point deltas:\n" )); - - /* this means that there are deltas for every point in the glyph */ - for ( j = 0; j < n_points; j++ ) - { -#ifdef FT_DEBUG_LEVEL_TRACE - FT_Vector point_org = outline->points[j]; -#endif - - - outline->points[j].x += FT_MulFix( deltas_x[j], apply ); - outline->points[j].y += FT_MulFix( deltas_y[j], apply ); - -#ifdef FT_DEBUG_LEVEL_TRACE - if ( ( point_org.x != outline->points[j].x ) || - ( point_org.y != outline->points[j].y ) ) - { - FT_TRACE7(( " %d: (%d, %d) -> (%d, %d)\n", - j, - point_org.x, - point_org.y, - outline->points[j].x, - outline->points[j].y )); - count++; - } -#endif - } - -#ifdef FT_DEBUG_LEVEL_TRACE - if ( !count ) - FT_TRACE7(( " none\n" )); -#endif - } - - else - { -#ifdef FT_DEBUG_LEVEL_TRACE - int count = 0; -#endif - - - /* we have to interpolate the missing deltas similar to the */ - /* IUP bytecode instruction */ - for ( j = 0; j < n_points; j++ ) - { - points_org[j] = outline->points[j]; - has_delta[j] = FALSE; - } - - for ( j = 0; j < point_count; j++ ) - { - FT_UShort idx = localpoints[j]; - - - if ( idx >= n_points ) - continue; - - has_delta[idx] = TRUE; - - outline->points[idx].x += FT_MulFix( deltas_x[j], apply ); - outline->points[idx].y += FT_MulFix( deltas_y[j], apply ); - } - - /* no need to handle phantom points here, */ - /* since solitary points can't be interpolated */ - tt_handle_deltas( outline, - points_org, - has_delta ); - -#ifdef FT_DEBUG_LEVEL_TRACE - FT_TRACE7(( " point deltas:\n" )); - - for ( j = 0; j < n_points; j++) - { - if ( ( points_org[j].x != outline->points[j].x ) || - ( points_org[j].y != outline->points[j].y ) ) - { - FT_TRACE7(( " %d: (%d, %d) -> (%d, %d)\n", - j, - points_org[j].x, - points_org[j].y, - outline->points[j].x, - outline->points[j].y )); - count++; - } - } - - if ( !count ) - FT_TRACE7(( " none\n" )); -#endif - } - - if ( localpoints != ALL_POINTS ) - FT_FREE( localpoints ); - FT_FREE( deltas_x ); - FT_FREE( deltas_y ); - - offsetToData += tupleDataSize; - - FT_Stream_SeekSet( stream, here ); - } - - FT_TRACE5(( "\n" )); - - Fail2: - FT_FREE( tuple_coords ); - FT_FREE( im_start_coords ); - FT_FREE( im_end_coords ); - - FT_FRAME_EXIT(); - - Fail1: - FT_FREE( points_org ); - FT_FREE( has_delta ); - - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* tt_done_blend */ - /* */ - /* */ - /* Free the blend internal data structure. */ - /* */ - FT_LOCAL_DEF( void ) - tt_done_blend( FT_Memory memory, - GX_Blend blend ) - { - if ( blend != NULL ) - { - FT_UInt i; - - - FT_FREE( blend->normalizedcoords ); - FT_FREE( blend->mmvar ); - - if ( blend->avar_segment != NULL ) - { - for ( i = 0; i < blend->num_axis; i++ ) - FT_FREE( blend->avar_segment[i].correspondence ); - FT_FREE( blend->avar_segment ); - } - - FT_FREE( blend->tuplecoords ); - FT_FREE( blend->glyphoffsets ); - FT_FREE( blend ); - } - } - -#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */ - - -/* END */ diff --git a/third_party/freetype/src/truetype/ttgxvar.h b/third_party/freetype/src/truetype/ttgxvar.h deleted file mode 100644 index 060d4d60ea..0000000000 --- a/third_party/freetype/src/truetype/ttgxvar.h +++ /dev/null @@ -1,182 +0,0 @@ -/***************************************************************************/ -/* */ -/* ttgxvar.h */ -/* */ -/* TrueType GX Font Variation loader (specification) */ -/* */ -/* Copyright 2004-2015 by */ -/* David Turner, Robert Wilhelm, Werner Lemberg and George Williams. */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ - - -#ifndef __TTGXVAR_H__ -#define __TTGXVAR_H__ - - -#include -#include "ttobjs.h" - - -FT_BEGIN_HEADER - - - /*************************************************************************/ - /* */ - /* */ - /* GX_AVarCorrespondenceRec */ - /* */ - /* */ - /* A data structure representing `shortFracCorrespondence' in `avar' */ - /* table according to the specifications from Apple. */ - /* */ - typedef struct GX_AVarCorrespondenceRec_ - { - FT_Fixed fromCoord; - FT_Fixed toCoord; - - } GX_AVarCorrespondenceRec_, *GX_AVarCorrespondence; - - - /*************************************************************************/ - /* */ - /* */ - /* GX_AVarRec */ - /* */ - /* */ - /* Data from the segment field of `avar' table. */ - /* There is one of these for each axis. */ - /* */ - typedef struct GX_AVarSegmentRec_ - { - FT_UShort pairCount; - GX_AVarCorrespondence correspondence; /* array with pairCount entries */ - - } GX_AVarSegmentRec, *GX_AVarSegment; - - - /*************************************************************************/ - /* */ - /* */ - /* GX_BlendRec */ - /* */ - /* */ - /* Data for interpolating a font from a distortable font specified */ - /* by the GX *var tables ([fgca]var). */ - /* */ - /* */ - /* num_axis :: The number of axes along which interpolation */ - /* may happen */ - /* */ - /* normalizedcoords :: A normalized value (between [-1,1]) indicating */ - /* the contribution along each axis to the final */ - /* interpolated font. */ - /* */ - typedef struct GX_BlendRec_ - { - FT_UInt num_axis; - FT_Fixed* normalizedcoords; - - FT_MM_Var* mmvar; - FT_Offset mmvar_len; - - FT_Bool avar_checked; - GX_AVarSegment avar_segment; - - FT_UInt tuplecount; /* shared tuples in `gvar' */ - FT_Fixed* tuplecoords; /* tuplecoords[tuplecount][num_axis] */ - - FT_UInt gv_glyphcnt; - FT_ULong* glyphoffsets; - - } GX_BlendRec; - - - /*************************************************************************/ - /* */ - /* */ - /* GX_TupleCountFlags */ - /* */ - /* */ - /* Flags used within the `TupleCount' field of the `gvar' table. */ - /* */ - typedef enum GX_TupleCountFlags_ - { - GX_TC_TUPLES_SHARE_POINT_NUMBERS = 0x8000, - GX_TC_RESERVED_TUPLE_FLAGS = 0x7000, - GX_TC_TUPLE_COUNT_MASK = 0x0FFF - - } GX_TupleCountFlags; - - - /*************************************************************************/ - /* */ - /* */ - /* GX_TupleIndexFlags */ - /* */ - /* */ - /* Flags used within the `TupleIndex' field of the `gvar' and `cvar' */ - /* tables. */ - /* */ - typedef enum GX_TupleIndexFlags_ - { - GX_TI_EMBEDDED_TUPLE_COORD = 0x8000, - GX_TI_INTERMEDIATE_TUPLE = 0x4000, - GX_TI_PRIVATE_POINT_NUMBERS = 0x2000, - GX_TI_RESERVED_TUPLE_FLAG = 0x1000, - GX_TI_TUPLE_INDEX_MASK = 0x0FFF - - } GX_TupleIndexFlags; - - -#define TTAG_wght FT_MAKE_TAG( 'w', 'g', 'h', 't' ) -#define TTAG_wdth FT_MAKE_TAG( 'w', 'd', 't', 'h' ) -#define TTAG_opsz FT_MAKE_TAG( 'o', 'p', 's', 'z' ) -#define TTAG_slnt FT_MAKE_TAG( 's', 'l', 'n', 't' ) - - - FT_LOCAL( FT_Error ) - TT_Set_MM_Blend( TT_Face face, - FT_UInt num_coords, - FT_Fixed* coords ); - - FT_LOCAL( FT_Error ) - TT_Set_Var_Design( TT_Face face, - FT_UInt num_coords, - FT_Fixed* coords ); - - FT_LOCAL( FT_Error ) - TT_Get_MM_Var( TT_Face face, - FT_MM_Var* *master ); - - - FT_LOCAL( FT_Error ) - tt_face_vary_cvt( TT_Face face, - FT_Stream stream ); - - - FT_LOCAL( FT_Error ) - TT_Vary_Apply_Glyph_Deltas( TT_Face face, - FT_UInt glyph_index, - FT_Outline* outline, - FT_UInt n_points ); - - - FT_LOCAL( void ) - tt_done_blend( FT_Memory memory, - GX_Blend blend ); - - -FT_END_HEADER - - -#endif /* __TTGXVAR_H__ */ - - -/* END */ -- cgit v1.2.3