Merge pull request #30511 from akien-mga/freetype-2.10.1

freetype: Update to upstream version 2.10.1
This commit is contained in:
Rémi Verschelde 2019-07-11 13:44:52 +02:00 committed by GitHub
commit af5c02def8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
82 changed files with 1943 additions and 1409 deletions

View file

@ -165,7 +165,7 @@ License: Expat and Bitstream Vera Fonts Copyright
Files: ./thirdparty/freetype/
Comment: The FreeType Project
Copyright: 1996-2018, David Turner, Robert Wilhelm, and Werner Lemberg.
Copyright: 1996-2019, David Turner, Robert Wilhelm, and Werner Lemberg.
License: FTL
Files: ./thirdparty/glad/

View file

@ -122,13 +122,13 @@ Use UI font variant if available, because it has tight vertical metrics and good
## freetype
- Upstream: https://www.freetype.org
- Version: 2.10.0
- Version: 2.10.1
- License: FreeType License (BSD-like)
Files extracted from upstream source:
- the src/ folder, stripped of the `Jamfile` files
- the include/ folder
- the `src/` folder, stripped of the `Jamfile` files and the `tools` subfolder
- the `include/` folder
- `docs/{FTL.TXT,LICENSE.TXT}`

View file

@ -645,7 +645,7 @@ FT_BEGIN_HEADER
* FT_ENCODING_MS_SYMBOL ::
* Microsoft Symbol encoding, used to encode mathematical symbols and
* wingdings. For more information, see
* 'https://www.microsoft.com/typography/otspec/recom.htm',
* 'https://www.microsoft.com/typography/otspec/recom.htm#non-standard-symbol-fonts',
* 'http://www.kostis.net/charsets/symbol.htm', and
* 'http://www.kostis.net/charsets/wingding.htm'.
*
@ -1766,6 +1766,13 @@ FT_BEGIN_HEADER
* transformed, distorted, emboldened, etc. However, it must not be
* freed.
*
* [Since 2.10.1] If @FT_LOAD_NO_SCALE is set, outline coordinates of
* OpenType variation fonts for a selected instance are internally
* handled as 26.6 fractional font units but returned as (rounded)
* integers, as expected. To get unrounded font units, don't use
* @FT_LOAD_NO_SCALE but load the glyph with @FT_LOAD_NO_HINTING and
* scale it, using the font's `units_per_EM` value as the ppem.
*
* num_subglyphs ::
* The number of subglyphs in a composite glyph. This field is only
* valid for the composite glyph format that should normally only be
@ -3932,8 +3939,8 @@ FT_BEGIN_HEADER
* The glyph index. 0~means 'undefined character code'.
*/
FT_EXPORT( FT_UInt )
FT_Get_Name_Index( FT_Face face,
FT_String* glyph_name );
FT_Get_Name_Index( FT_Face face,
const FT_String* glyph_name );
/**************************************************************************
@ -4774,7 +4781,7 @@ FT_BEGIN_HEADER
*/
#define FREETYPE_MAJOR 2
#define FREETYPE_MINOR 10
#define FREETYPE_PATCH 0
#define FREETYPE_PATCH 1
/**************************************************************************

View file

@ -244,6 +244,8 @@
#define FT_ERR_PROTOS_DEFINED
FT_BEGIN_HEADER
/**************************************************************************
*
* @function:
@ -274,6 +276,8 @@
FT_EXPORT( const char* )
FT_Error_String( FT_Error error_code );
FT_END_HEADER
#endif /* FT_ERR_PROTOS_DEFINED */

View file

@ -210,7 +210,7 @@ FT_BEGIN_HEADER
*
* As the outline is extracted from a glyph slot, its coordinates are
* expressed normally in 26.6 pixels, unless the flag @FT_LOAD_NO_SCALE
* was used in @FT_Load_Glyph() or @FT_Load_Char().
* was used in @FT_Load_Glyph or @FT_Load_Char.
*
* The outline's tables are always owned by the object and are destroyed
* with it.

View file

@ -869,7 +869,7 @@ FT_BEGIN_HEADER
*
* @input:
* y ::
* The scanline's y~coordinate.
* The scanline's upward y~coordinate.
*
* count ::
* The number of spans to draw on this scanline.
@ -945,19 +945,16 @@ FT_BEGIN_HEADER
* This flag is set to indicate direct rendering. In this mode, client
* applications must provide their own span callback. This lets them
* directly draw or compose over an existing bitmap. If this bit is
* not set, the target pixmap's buffer _must_ be zeroed before
* rendering.
* _not_ set, the target pixmap's buffer _must_ be zeroed before
* rendering and the output will be clipped to its size.
*
* Direct rendering is only possible with anti-aliased glyphs.
*
* FT_RASTER_FLAG_CLIP ::
* This flag is only used in direct rendering mode. If set, the output
* will be clipped to a box specified in the `clip_box` field of the
* @FT_Raster_Params structure.
*
* Note that by default, the glyph bitmap is clipped to the target
* pixmap, except in direct rendering mode where all spans are
* generated if no clipping box is set.
* @FT_Raster_Params structure. Otherwise, the `clip_box` is
* effectively set to the bounding box and all spans are generated.
*/
#define FT_RASTER_FLAG_DEFAULT 0x0
#define FT_RASTER_FLAG_AA 0x1
@ -978,7 +975,8 @@ FT_BEGIN_HEADER
* FT_Raster_Params
*
* @description:
* A structure to hold the arguments used by a raster's render function.
* A structure to hold the parameters used by a raster's render function,
* passed as an argument to @FT_Outline_Render.
*
* @fields:
* target ::

View file

@ -623,7 +623,7 @@ FT_BEGIN_HEADER
* it is bytecode interpreter's execution context, `TT_ExecContext`,
* which is declared in FreeType's internal header file `tttypes.h`.
*/
typedef void
typedef FT_Error
(*FT_DebugHook_Func)( void* arg );

View file

@ -466,8 +466,6 @@ FT_BEGIN_HEADER
*
* @description:
* Render an outline within a bitmap using the current scan-convert.
* This function uses an @FT_Raster_Params structure as an argument,
* allowing advanced features like direct composition, translucency, etc.
*
* @input:
* library ::
@ -485,8 +483,10 @@ FT_BEGIN_HEADER
* FreeType error code. 0~means success.
*
* @note:
* You should know what you are doing and how @FT_Raster_Params works to
* use this function.
* This advanced function uses @FT_Raster_Params as an argument,
* allowing FreeType rasterizer to be used for direct composition,
* translucency, etc. You should know how to set up @FT_Raster_Params
* for this function to work.
*
* The field `params.source` will be set to `outline` before the scan
* converter is called, which means that the value you give to it is

View file

@ -58,7 +58,7 @@ FT_BEGIN_HEADER
* @description:
* A list of valid values for the `charset` byte in @FT_WinFNT_HeaderRec.
* Exact mapping tables for the various 'cpXXXX' encodings (except for
* 'cp1361') can be found at 'ftp://ftp.unicode.org/Public' in the
* 'cp1361') can be found at 'ftp://ftp.unicode.org/Public/' in the
* `MAPPINGS/VENDORS/MICSFT/WINDOWS` subdirectory. 'cp1361' is roughly a
* superset of `MAPPINGS/OBSOLETE/EASTASIA/KSC/JOHAB.TXT`.
*

View file

@ -378,6 +378,7 @@ FT_BEGIN_HEADER
#if FT_SIZEOF_INT == 4
#include <intrin.h>
#pragma intrinsic( _BitScanReverse )
static __inline FT_Int32
FT_MSB_i386( FT_UInt32 x )
@ -385,7 +386,6 @@ FT_BEGIN_HEADER
unsigned long where;
/* not available in older VC versions */
_BitScanReverse( &where, x );
return (FT_Int32)where;

View file

@ -278,14 +278,12 @@ FT_BEGIN_HEADER
#ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
typedef void (*FT_Bitmap_LcdFilterFunc)( FT_Bitmap* bitmap,
FT_Render_Mode render_mode,
FT_Byte* weights );
/* This is the default LCD filter, an in-place, 5-tap FIR filter. */
FT_BASE( void )
ft_lcd_filter_fir( FT_Bitmap* bitmap,
FT_Render_Mode mode,
FT_LcdFiveTapFilter weights );
#endif /* FT_CONFIG_OPTION_SUBPIXEL_RENDERING */
@ -941,8 +939,8 @@ FT_BEGIN_HEADER
FT_UInt buffer_max );
typedef FT_UInt
(*FT_Face_GetGlyphNameIndexFunc)( FT_Face face,
FT_String* glyph_name );
(*FT_Face_GetGlyphNameIndexFunc)( FT_Face face,
const FT_String* glyph_name );
#ifndef FT_CONFIG_OPTION_NO_DEFAULT_SYSTEM

View file

@ -165,6 +165,17 @@ FT_BEGIN_HEADER
#define FT_BYTE_U32( p, i, s ) ( FT_UINT32( FT_BYTE_( p, i ) ) << (s) )
/*
* function acts on increases does range for emits
* pointer checking frames error
* -------------------------------------------------------------------
* FT_PEEK_XXX buffer pointer no no no no
* FT_NEXT_XXX buffer pointer yes no no no
* FT_GET_XXX stream->cursor yes yes yes no
* FT_READ_XXX stream->pos yes yes no yes
*/
/*
* `FT_PEEK_XXX' are generic macros to get data from a buffer position. No
* safety checks are performed.

View file

@ -48,6 +48,7 @@ FT_TRACE_DEF( cache ) /* cache sub-system (ftcache.c, etc.) */
/* SFNT driver components */
FT_TRACE_DEF( sfdriver ) /* SFNT font driver (sfdriver.c) */
FT_TRACE_DEF( sfobjs ) /* SFNT object handler (sfobjs.c) */
FT_TRACE_DEF( sfwoff ) /* WOFF format handler (sfwoff.c) */
FT_TRACE_DEF( ttbdf ) /* TrueType embedded BDF (ttbdf.c) */
FT_TRACE_DEF( ttcmap ) /* charmap handler (ttcmap.c) */
FT_TRACE_DEF( ttcolr ) /* glyph layer table (ttcolr.c) */

View file

@ -40,6 +40,7 @@
#define FT_INTERNAL_TRUETYPE_TYPES_H <freetype/internal/tttypes.h>
#define FT_INTERNAL_TYPE1_TYPES_H <freetype/internal/t1types.h>
#define FT_INTERNAL_WOFF_TYPES_H <freetype/internal/wofftypes.h>
#define FT_INTERNAL_POSTSCRIPT_AUX_H <freetype/internal/psaux.h>
#define FT_INTERNAL_POSTSCRIPT_HINTS_H <freetype/internal/pshints.h>

View file

@ -96,10 +96,10 @@ FT_BEGIN_HEADER
(*done)( PS_Table table );
FT_Error
(*add)( PS_Table table,
FT_Int idx,
void* object,
FT_UInt length );
(*add)( PS_Table table,
FT_Int idx,
const void* object,
FT_UInt length );
void
(*release)( PS_Table table );

View file

@ -41,8 +41,8 @@ FT_BEGIN_HEADER
FT_UInt buffer_max );
typedef FT_UInt
(*FT_GlyphDict_NameIndexFunc)( FT_Face face,
FT_String* glyph_name );
(*FT_GlyphDict_NameIndexFunc)( FT_Face face,
const FT_String* glyph_name );
FT_DEFINE_SERVICE( GlyphDict )

View file

@ -23,6 +23,7 @@
#include <ft2build.h>
#include FT_INTERNAL_DRIVER_H
#include FT_INTERNAL_TRUETYPE_TYPES_H
#include FT_INTERNAL_WOFF_TYPES_H
FT_BEGIN_HEADER

View file

@ -76,8 +76,8 @@ FT_BEGIN_HEADER
FT_Int code_first;
FT_Int code_last;
FT_UShort* char_index;
FT_String** char_name;
FT_UShort* char_index;
const FT_String** char_name;
} T1_EncodingRec, *T1_Encoding;

View file

@ -150,81 +150,6 @@ FT_BEGIN_HEADER
} TT_TableRec, *TT_Table;
/**************************************************************************
*
* @struct:
* WOFF_HeaderRec
*
* @description:
* WOFF file format header.
*
* @fields:
* See
*
* https://www.w3.org/TR/WOFF/#WOFFHeader
*/
typedef struct WOFF_HeaderRec_
{
FT_ULong signature;
FT_ULong flavor;
FT_ULong length;
FT_UShort num_tables;
FT_UShort reserved;
FT_ULong totalSfntSize;
FT_UShort majorVersion;
FT_UShort minorVersion;
FT_ULong metaOffset;
FT_ULong metaLength;
FT_ULong metaOrigLength;
FT_ULong privOffset;
FT_ULong privLength;
} WOFF_HeaderRec, *WOFF_Header;
/**************************************************************************
*
* @struct:
* WOFF_TableRec
*
* @description:
* This structure describes a given table of a WOFF font.
*
* @fields:
* Tag ::
* A four-bytes tag describing the table.
*
* Offset ::
* The offset of the table from the start of the WOFF font in its
* resource.
*
* CompLength ::
* Compressed table length (in bytes).
*
* OrigLength ::
* Uncompressed table length (in bytes).
*
* CheckSum ::
* The table checksum. This value can be ignored.
*
* OrigOffset ::
* The uncompressed table file offset. This value gets computed while
* constructing the (uncompressed) SFNT header. It is not contained in
* the WOFF file.
*/
typedef struct WOFF_TableRec_
{
FT_ULong Tag; /* table ID */
FT_ULong Offset; /* table file offset */
FT_ULong CompLength; /* compressed table length */
FT_ULong OrigLength; /* uncompressed table length */
FT_ULong CheckSum; /* uncompressed checksum */
FT_ULong OrigOffset; /* uncompressed table file offset */
/* (not in the WOFF file) */
} WOFF_TableRec, *WOFF_Table;
/**************************************************************************
*
* @struct:
@ -1395,8 +1320,10 @@ FT_BEGIN_HEADER
*
* cvt ::
* The face's original control value table. Coordinates are expressed
* in unscaled font units. Comes from the 'cvt~' table. Ignored for
* Type 2 fonts.
* in unscaled font units (in 26.6 format). Comes from the 'cvt~'
* table. Ignored for Type 2 fonts.
*
* If varied by the `CVAR' table, non-integer values are possible.
*
* interpreter ::
* A pointer to the TrueType bytecode interpreters field is also used
@ -1633,7 +1560,7 @@ FT_BEGIN_HEADER
/* the original, unscaled, control value table */
FT_ULong cvt_size;
FT_Short* cvt;
FT_Int32* cvt;
/* A pointer to the bytecode interpreter to use. This is also */
/* used to hook the debugger for the `ttdebug' utility. */

View file

@ -0,0 +1,112 @@
/****************************************************************************
*
* wofftypes.h
*
* Basic WOFF/WOFF2 type definitions and interface (specification
* only).
*
* Copyright (C) 1996-2019 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.
*
*/
#ifndef WOFFTYPES_H_
#define WOFFTYPES_H_
#include <ft2build.h>
#include FT_TRUETYPE_TABLES_H
#include FT_INTERNAL_OBJECTS_H
FT_BEGIN_HEADER
/**************************************************************************
*
* @struct:
* WOFF_HeaderRec
*
* @description:
* WOFF file format header.
*
* @fields:
* See
*
* https://www.w3.org/TR/WOFF/#WOFFHeader
*/
typedef struct WOFF_HeaderRec_
{
FT_ULong signature;
FT_ULong flavor;
FT_ULong length;
FT_UShort num_tables;
FT_UShort reserved;
FT_ULong totalSfntSize;
FT_UShort majorVersion;
FT_UShort minorVersion;
FT_ULong metaOffset;
FT_ULong metaLength;
FT_ULong metaOrigLength;
FT_ULong privOffset;
FT_ULong privLength;
} WOFF_HeaderRec, *WOFF_Header;
/**************************************************************************
*
* @struct:
* WOFF_TableRec
*
* @description:
* This structure describes a given table of a WOFF font.
*
* @fields:
* Tag ::
* A four-bytes tag describing the table.
*
* Offset ::
* The offset of the table from the start of the WOFF font in its
* resource.
*
* CompLength ::
* Compressed table length (in bytes).
*
* OrigLength ::
* Uncompressed table length (in bytes).
*
* CheckSum ::
* The table checksum. This value can be ignored.
*
* OrigOffset ::
* The uncompressed table file offset. This value gets computed while
* constructing the (uncompressed) SFNT header. It is not contained in
* the WOFF file.
*/
typedef struct WOFF_TableRec_
{
FT_ULong Tag; /* table ID */
FT_ULong Offset; /* table file offset */
FT_ULong CompLength; /* compressed table length */
FT_ULong OrigLength; /* uncompressed table length */
FT_ULong CheckSum; /* uncompressed checksum */
FT_ULong OrigOffset; /* uncompressed table file offset */
/* (not in the WOFF file) */
} WOFF_TableRec, *WOFF_Table;
FT_END_HEADER
#endif /* WOFFTYPES_H_ */
/* END */

View file

@ -296,6 +296,10 @@
'\0',
'\xE0', '\xB4', '\x9F', ' ', '\xE0', '\xB4', '\xA0', ' ', '\xE0', '\xB4', '\xA7', ' ', '\xE0', '\xB4', '\xB6', ' ', '\xE0', '\xB4', '\x98', ' ', '\xE0', '\xB4', '\x9A', ' ', '\xE0', '\xB4', '\xA5', ' ', '\xE0', '\xB4', '\xB2', /* ട ധ ശ ഘ ച ഥ ല */
'\0',
'\xE1', '\xA0', '\xB3', ' ', '\xE1', '\xA0', '\xB4', ' ', '\xE1', '\xA0', '\xB6', ' ', '\xE1', '\xA0', '\xBD', ' ', '\xE1', '\xA1', '\x82', ' ', '\xE1', '\xA1', '\x8A', ' ', '\xE2', '\x80', '\x8D', '\xE1', '\xA1', '\xA1', '\xE2', '\x80', '\x8D', ' ', '\xE2', '\x80', '\x8D', '\xE1', '\xA1', '\xB3', '\xE2', '\x80', '\x8D', /* ᠳ ᠴ ᠶ ᠽ ᡂ ᡊ ‍ᡡ‍ ‍ᡳ‍ */
'\0',
'\xE1', '\xA1', '\x83', /* ᡃ */
'\0',
'\xE1', '\x80', '\x81', ' ', '\xE1', '\x80', '\x82', ' ', '\xE1', '\x80', '\x84', ' ', '\xE1', '\x80', '\x92', ' ', '\xE1', '\x80', '\x9D', ' ', '\xE1', '\x81', '\xA5', ' ', '\xE1', '\x81', '\x8A', ' ', '\xE1', '\x81', '\x8B', /* ခ ဂ င ဒ ၥ ၊ ။ */
'\0',
'\xE1', '\x80', '\x84', ' ', '\xE1', '\x80', '\x8E', ' ', '\xE1', '\x80', '\x92', ' ', '\xE1', '\x80', '\x95', ' ', '\xE1', '\x80', '\x97', ' ', '\xE1', '\x80', '\x9D', ' ', '\xE1', '\x81', '\x8A', ' ', '\xE1', '\x81', '\x8B', /* င ဎ ဒ ပ ဗ ၊ ။ */
@ -649,6 +653,9 @@
{ AF_BLUE_STRING_MALAYALAM_TOP, AF_BLUE_PROPERTY_LATIN_TOP },
{ AF_BLUE_STRING_MALAYALAM_BOTTOM, 0 },
{ AF_BLUE_STRING_MAX, 0 },
{ AF_BLUE_STRING_MONGOLIAN_TOP_BASE, AF_BLUE_PROPERTY_LATIN_TOP },
{ AF_BLUE_STRING_MONGOLIAN_BOTTOM_BASE, 0 },
{ AF_BLUE_STRING_MAX, 0 },
{ AF_BLUE_STRING_MYANMAR_TOP, AF_BLUE_PROPERTY_LATIN_TOP |
AF_BLUE_PROPERTY_LATIN_X_HEIGHT },
{ AF_BLUE_STRING_MYANMAR_BOTTOM, 0 },

View file

@ -392,6 +392,11 @@ AF_BLUE_STRING_ENUM AF_BLUE_STRINGS_ARRAY AF_BLUE_STRING_MAX_LEN:
AF_BLUE_STRING_MALAYALAM_BOTTOM
"ട ധ ശ ഘ ച ഥ ല"
AF_BLUE_STRING_MONGOLIAN_TOP_BASE
"ᠳ ᠴ ᠶ ᠽ ᡂ ᡊ ‍ᡡ‍ ‍ᡳ‍"
AF_BLUE_STRING_MONGOLIAN_BOTTOM_BASE
"ᡃ"
AF_BLUE_STRING_MYANMAR_TOP
"ခ ဂ င ဒ ၥ ၊ ။"
AF_BLUE_STRING_MYANMAR_BOTTOM
@ -947,6 +952,11 @@ AF_BLUE_STRINGSET_ENUM AF_BLUE_STRINGSETS_ARRAY AF_BLUE_STRINGSET_MAX_LEN:
{ AF_BLUE_STRING_MALAYALAM_BOTTOM, 0 }
{ AF_BLUE_STRING_MAX, 0 }
AF_BLUE_STRINGSET_MONG
{ AF_BLUE_STRING_MONGOLIAN_TOP_BASE, AF_BLUE_PROPERTY_LATIN_TOP }
{ AF_BLUE_STRING_MONGOLIAN_BOTTOM_BASE, 0 }
{ AF_BLUE_STRING_MAX, 0 }
AF_BLUE_STRINGSET_MYMR
{ AF_BLUE_STRING_MYANMAR_TOP, AF_BLUE_PROPERTY_LATIN_TOP |
AF_BLUE_PROPERTY_LATIN_X_HEIGHT }

View file

@ -212,56 +212,58 @@ FT_BEGIN_HEADER
AF_BLUE_STRING_LISU_BOTTOM = 3506,
AF_BLUE_STRING_MALAYALAM_TOP = 3538,
AF_BLUE_STRING_MALAYALAM_BOTTOM = 3582,
AF_BLUE_STRING_MYANMAR_TOP = 3614,
AF_BLUE_STRING_MYANMAR_BOTTOM = 3646,
AF_BLUE_STRING_MYANMAR_ASCENDER = 3678,
AF_BLUE_STRING_MYANMAR_DESCENDER = 3706,
AF_BLUE_STRING_NKO_TOP = 3738,
AF_BLUE_STRING_NKO_BOTTOM = 3762,
AF_BLUE_STRING_NKO_SMALL_TOP = 3777,
AF_BLUE_STRING_NKO_SMALL_BOTTOM = 3786,
AF_BLUE_STRING_OL_CHIKI = 3798,
AF_BLUE_STRING_OLD_TURKIC_TOP = 3822,
AF_BLUE_STRING_OLD_TURKIC_BOTTOM = 3837,
AF_BLUE_STRING_OSAGE_CAPITAL_TOP = 3857,
AF_BLUE_STRING_OSAGE_CAPITAL_BOTTOM = 3897,
AF_BLUE_STRING_OSAGE_CAPITAL_DESCENDER = 3927,
AF_BLUE_STRING_OSAGE_SMALL_TOP = 3942,
AF_BLUE_STRING_OSAGE_SMALL_BOTTOM = 3982,
AF_BLUE_STRING_OSAGE_SMALL_ASCENDER = 4022,
AF_BLUE_STRING_OSAGE_SMALL_DESCENDER = 4047,
AF_BLUE_STRING_OSMANYA_TOP = 4062,
AF_BLUE_STRING_OSMANYA_BOTTOM = 4102,
AF_BLUE_STRING_SAURASHTRA_TOP = 4142,
AF_BLUE_STRING_SAURASHTRA_BOTTOM = 4174,
AF_BLUE_STRING_SHAVIAN_TOP = 4194,
AF_BLUE_STRING_SHAVIAN_BOTTOM = 4204,
AF_BLUE_STRING_SHAVIAN_DESCENDER = 4229,
AF_BLUE_STRING_SHAVIAN_SMALL_TOP = 4239,
AF_BLUE_STRING_SHAVIAN_SMALL_BOTTOM = 4274,
AF_BLUE_STRING_SINHALA_TOP = 4289,
AF_BLUE_STRING_SINHALA_BOTTOM = 4321,
AF_BLUE_STRING_SINHALA_DESCENDER = 4353,
AF_BLUE_STRING_SUNDANESE_TOP = 4397,
AF_BLUE_STRING_SUNDANESE_BOTTOM = 4421,
AF_BLUE_STRING_SUNDANESE_DESCENDER = 4453,
AF_BLUE_STRING_TAI_VIET_TOP = 4461,
AF_BLUE_STRING_TAI_VIET_BOTTOM = 4481,
AF_BLUE_STRING_TAMIL_TOP = 4493,
AF_BLUE_STRING_TAMIL_BOTTOM = 4525,
AF_BLUE_STRING_TELUGU_TOP = 4557,
AF_BLUE_STRING_TELUGU_BOTTOM = 4585,
AF_BLUE_STRING_THAI_TOP = 4613,
AF_BLUE_STRING_THAI_BOTTOM = 4637,
AF_BLUE_STRING_THAI_ASCENDER = 4665,
AF_BLUE_STRING_THAI_LARGE_ASCENDER = 4677,
AF_BLUE_STRING_THAI_DESCENDER = 4689,
AF_BLUE_STRING_THAI_LARGE_DESCENDER = 4705,
AF_BLUE_STRING_THAI_DIGIT_TOP = 4713,
AF_BLUE_STRING_TIFINAGH = 4725,
AF_BLUE_STRING_VAI_TOP = 4757,
AF_BLUE_STRING_VAI_BOTTOM = 4789,
af_blue_1_1 = 4820,
AF_BLUE_STRING_MONGOLIAN_TOP_BASE = 3614,
AF_BLUE_STRING_MONGOLIAN_BOTTOM_BASE = 3658,
AF_BLUE_STRING_MYANMAR_TOP = 3662,
AF_BLUE_STRING_MYANMAR_BOTTOM = 3694,
AF_BLUE_STRING_MYANMAR_ASCENDER = 3726,
AF_BLUE_STRING_MYANMAR_DESCENDER = 3754,
AF_BLUE_STRING_NKO_TOP = 3786,
AF_BLUE_STRING_NKO_BOTTOM = 3810,
AF_BLUE_STRING_NKO_SMALL_TOP = 3825,
AF_BLUE_STRING_NKO_SMALL_BOTTOM = 3834,
AF_BLUE_STRING_OL_CHIKI = 3846,
AF_BLUE_STRING_OLD_TURKIC_TOP = 3870,
AF_BLUE_STRING_OLD_TURKIC_BOTTOM = 3885,
AF_BLUE_STRING_OSAGE_CAPITAL_TOP = 3905,
AF_BLUE_STRING_OSAGE_CAPITAL_BOTTOM = 3945,
AF_BLUE_STRING_OSAGE_CAPITAL_DESCENDER = 3975,
AF_BLUE_STRING_OSAGE_SMALL_TOP = 3990,
AF_BLUE_STRING_OSAGE_SMALL_BOTTOM = 4030,
AF_BLUE_STRING_OSAGE_SMALL_ASCENDER = 4070,
AF_BLUE_STRING_OSAGE_SMALL_DESCENDER = 4095,
AF_BLUE_STRING_OSMANYA_TOP = 4110,
AF_BLUE_STRING_OSMANYA_BOTTOM = 4150,
AF_BLUE_STRING_SAURASHTRA_TOP = 4190,
AF_BLUE_STRING_SAURASHTRA_BOTTOM = 4222,
AF_BLUE_STRING_SHAVIAN_TOP = 4242,
AF_BLUE_STRING_SHAVIAN_BOTTOM = 4252,
AF_BLUE_STRING_SHAVIAN_DESCENDER = 4277,
AF_BLUE_STRING_SHAVIAN_SMALL_TOP = 4287,
AF_BLUE_STRING_SHAVIAN_SMALL_BOTTOM = 4322,
AF_BLUE_STRING_SINHALA_TOP = 4337,
AF_BLUE_STRING_SINHALA_BOTTOM = 4369,
AF_BLUE_STRING_SINHALA_DESCENDER = 4401,
AF_BLUE_STRING_SUNDANESE_TOP = 4445,
AF_BLUE_STRING_SUNDANESE_BOTTOM = 4469,
AF_BLUE_STRING_SUNDANESE_DESCENDER = 4501,
AF_BLUE_STRING_TAI_VIET_TOP = 4509,
AF_BLUE_STRING_TAI_VIET_BOTTOM = 4529,
AF_BLUE_STRING_TAMIL_TOP = 4541,
AF_BLUE_STRING_TAMIL_BOTTOM = 4573,
AF_BLUE_STRING_TELUGU_TOP = 4605,
AF_BLUE_STRING_TELUGU_BOTTOM = 4633,
AF_BLUE_STRING_THAI_TOP = 4661,
AF_BLUE_STRING_THAI_BOTTOM = 4685,
AF_BLUE_STRING_THAI_ASCENDER = 4713,
AF_BLUE_STRING_THAI_LARGE_ASCENDER = 4725,
AF_BLUE_STRING_THAI_DESCENDER = 4737,
AF_BLUE_STRING_THAI_LARGE_DESCENDER = 4753,
AF_BLUE_STRING_THAI_DIGIT_TOP = 4761,
AF_BLUE_STRING_TIFINAGH = 4773,
AF_BLUE_STRING_VAI_TOP = 4805,
AF_BLUE_STRING_VAI_BOTTOM = 4837,
af_blue_1_1 = 4868,
#ifdef AF_CONFIG_OPTION_CJK
AF_BLUE_STRING_CJK_TOP = af_blue_1_1 + 1,
AF_BLUE_STRING_CJK_BOTTOM = af_blue_1_1 + 203,
@ -355,24 +357,25 @@ FT_BEGIN_HEADER
AF_BLUE_STRINGSET_LATP = 166,
AF_BLUE_STRINGSET_LISU = 173,
AF_BLUE_STRINGSET_MLYM = 176,
AF_BLUE_STRINGSET_MYMR = 179,
AF_BLUE_STRINGSET_NKOO = 184,
AF_BLUE_STRINGSET_NONE = 189,
AF_BLUE_STRINGSET_OLCK = 190,
AF_BLUE_STRINGSET_ORKH = 193,
AF_BLUE_STRINGSET_OSGE = 196,
AF_BLUE_STRINGSET_OSMA = 204,
AF_BLUE_STRINGSET_SAUR = 207,
AF_BLUE_STRINGSET_SHAW = 210,
AF_BLUE_STRINGSET_SINH = 216,
AF_BLUE_STRINGSET_SUND = 220,
AF_BLUE_STRINGSET_TAML = 224,
AF_BLUE_STRINGSET_TAVT = 227,
AF_BLUE_STRINGSET_TELU = 230,
AF_BLUE_STRINGSET_TFNG = 233,
AF_BLUE_STRINGSET_THAI = 236,
AF_BLUE_STRINGSET_VAII = 244,
af_blue_2_1 = 247,
AF_BLUE_STRINGSET_MONG = 179,
AF_BLUE_STRINGSET_MYMR = 182,
AF_BLUE_STRINGSET_NKOO = 187,
AF_BLUE_STRINGSET_NONE = 192,
AF_BLUE_STRINGSET_OLCK = 193,
AF_BLUE_STRINGSET_ORKH = 196,
AF_BLUE_STRINGSET_OSGE = 199,
AF_BLUE_STRINGSET_OSMA = 207,
AF_BLUE_STRINGSET_SAUR = 210,
AF_BLUE_STRINGSET_SHAW = 213,
AF_BLUE_STRINGSET_SINH = 219,
AF_BLUE_STRINGSET_SUND = 223,
AF_BLUE_STRINGSET_TAML = 227,
AF_BLUE_STRINGSET_TAVT = 230,
AF_BLUE_STRINGSET_TELU = 233,
AF_BLUE_STRINGSET_TFNG = 236,
AF_BLUE_STRINGSET_THAI = 239,
AF_BLUE_STRINGSET_VAII = 247,
af_blue_2_1 = 250,
#ifdef AF_CONFIG_OPTION_CJK
AF_BLUE_STRINGSET_HANI = af_blue_2_1 + 0,
af_blue_2_1_1 = af_blue_2_1 + 2,

View file

@ -1184,6 +1184,8 @@
seg = edge->first;
if ( !seg )
goto Skip_Loop;
do
{
@ -1239,13 +1241,14 @@
edge2->flags |= AF_EDGE_SERIF;
}
else
edge->link = edge2;
edge->link = edge2;
}
seg = seg->edge_next;
} while ( seg != edge->first );
Skip_Loop:
/* set the round/straight flags */
edge->flags = AF_EDGE_NORMAL;

View file

@ -443,6 +443,7 @@
style = (AF_Style)( globals->glyph_styles[gindex] &
AF_STYLE_UNASSIGNED );
Again:
style_class = af_style_classes[style];
writing_system_class = af_writing_system_classes
[style_class->writing_system];
@ -470,6 +471,16 @@
writing_system_class->style_metrics_done( metrics );
FT_FREE( metrics );
/* internal error code -1 indicates */
/* that no blue zones have been found */
if ( error == -1 )
{
style = (AF_Style)( globals->glyph_styles[gindex] &
AF_STYLE_UNASSIGNED );
goto Again;
}
goto Exit;
}
}

View file

@ -149,7 +149,11 @@
af_shaper_buf_destroy( face, shaper_buf );
if ( !glyph_index )
{
FT_TRACE5(( "standard character missing;"
" using fallback stem widths\n" ));
goto Exit;
}
FT_TRACE5(( "standard character: U+%04lX (glyph index %d)\n",
ch, glyph_index ));
@ -312,7 +316,7 @@
/* Find all blue zones. Flat segments give the reference points, */
/* round segments the overshoot positions. */
static void
static int
af_latin_metrics_init_blues( AF_LatinMetrics metrics,
FT_Face face )
{
@ -981,10 +985,11 @@
af_shaper_buf_destroy( face, shaper_buf );
/* we finally check whether blue zones are ordered; */
/* `ref' and `shoot' values of two blue zones must not overlap */
if ( axis->blue_count )
{
/* we finally check whether blue zones are ordered; */
/* `ref' and `shoot' values of two blue zones must not overlap */
FT_UInt i;
AF_LatinBlue blue_sorted[AF_BLUE_STRINGSET_MAX_LEN + 2];
@ -1033,11 +1038,34 @@
*a ));
}
}
FT_TRACE5(( "\n" ));
return 0;
}
else
{
/* disable hinting for the current style if there are no blue zones */
FT_TRACE5(( "\n" ));
AF_FaceGlobals globals = metrics->root.globals;
FT_UShort* gstyles = globals->glyph_styles;
return;
FT_Long i;
FT_TRACE5(( "no blue zones found:"
" hinting disabled for this style\n" ));
for ( i = 0; i < globals->glyph_count; i++ )
{
if ( ( gstyles[i] & AF_STYLE_MASK ) == sc->style )
gstyles[i] = AF_STYLE_NONE_DFLT;
}
FT_TRACE5(( "\n" ));
return 1;
}
}
@ -1116,6 +1144,8 @@
af_latin_metrics_init( AF_LatinMetrics metrics,
FT_Face face )
{
FT_Error error = FT_Err_Ok;
FT_CharMap oldmap = face->charmap;
@ -1124,12 +1154,18 @@
if ( !FT_Select_Charmap( face, FT_ENCODING_UNICODE ) )
{
af_latin_metrics_init_widths( metrics, face );
af_latin_metrics_init_blues( metrics, face );
if ( af_latin_metrics_init_blues( metrics, face ) )
{
/* use internal error code to indicate missing blue zones */
error = -1;
goto Exit;
}
af_latin_metrics_check_digits( metrics, face );
}
Exit:
FT_Set_Charmap( face, oldmap );
return FT_Err_Ok;
return error;
}
@ -1443,13 +1479,13 @@
nn,
blue->ref.org,
blue->ref.fit / 64.0,
blue->flags & AF_LATIN_BLUE_ACTIVE ? ""
: " (inactive)",
( blue->flags & AF_LATIN_BLUE_ACTIVE ) ? ""
: " (inactive)",
nn,
blue->shoot.org,
blue->shoot.fit / 64.0,
blue->flags & AF_LATIN_BLUE_ACTIVE ? ""
: " (inactive)" ));
( blue->flags & AF_LATIN_BLUE_ACTIVE ) ? ""
: " (inactive)" ));
}
#endif
}

View file

@ -664,6 +664,21 @@
};
const AF_Script_UniRangeRec af_mong_uniranges[] =
{
AF_UNIRANGE_REC( 0x1800, 0x18AF ), /* Mongolian */
AF_UNIRANGE_REC( 0x11660, 0x1167F ), /* Mongolian Supplement */
AF_UNIRANGE_REC( 0, 0 )
};
const AF_Script_UniRangeRec af_mong_nonbase_uniranges[] =
{
AF_UNIRANGE_REC( 0x1885, 0x1886 ),
AF_UNIRANGE_REC( 0x18A9, 0x18A9 ),
AF_UNIRANGE_REC( 0, 0 )
};
const AF_Script_UniRangeRec af_mymr_uniranges[] =
{
AF_UNIRANGE_REC( 0x1000, 0x109F ), /* Myanmar */

View file

@ -243,6 +243,12 @@
HINTING_BOTTOM_TO_TOP,
"\xE0\xB4\xA0 \xE0\xB4\xB1" ) /* റ */
SCRIPT( mong, MONG,
"Mongolian",
HB_SCRIPT_MONGOLIAN,
HINTING_TOP_TO_BOTTOM,
"\xE1\xA1\x82 \xE1\xA0\xAA" ) /* ᡂ ᠪ */
SCRIPT( mymr, MYMR,
"Myanmar",
HB_SCRIPT_MYANMAR,

View file

@ -322,6 +322,13 @@
AF_BLUE_STRINGSET_MLYM,
AF_COVERAGE_DEFAULT )
STYLE( mong_dflt, MONG_DFLT,
"Mongolian default style",
AF_WRITING_SYSTEM_LATIN,
AF_SCRIPT_MONG,
AF_BLUE_STRINGSET_MONG,
AF_COVERAGE_DEFAULT )
STYLE( mymr_dflt, MYMR_DFLT,
"Myanmar default style",
AF_WRITING_SYSTEM_LATIN,

View file

@ -319,9 +319,9 @@
q2 = q2 + q1;
q4 = q4 + q3;
q3 = q3 + q2;
q4 = ( q4 + q3 ) / 8;
q3 = q3 / 4;
q2 = q2 / 2;
q4 = ( q4 + q3 ) >> 3;
q3 = q3 >> 2;
q2 = q2 >> 1;
}
else /* second half */
{
@ -330,9 +330,9 @@
q3 = q3 + q4;
q1 = q1 + q2;
q2 = q2 + q3;
q1 = ( q1 + q2 ) / 8;
q2 = q2 / 4;
q3 = q3 / 2;
q1 = ( q1 + q2 ) >> 3;
q2 = q2 >> 2;
q3 = q3 >> 1;
}
/* check whether either end reached the maximum */

View file

@ -922,12 +922,18 @@
else
FT_TRACE5(( " target bitmap: empty\n" ));
FT_TRACE5(( " final bitmap: (%d, %d) -- (%d, %d); %d x %d\n",
final_llx / 64, final_lly / 64,
final_urx / 64, final_ury / 64,
final_width, final_rows ));
if ( final_width && final_rows )
FT_TRACE5(( " final bitmap: (%d, %d) -- (%d, %d); %d x %d\n",
final_llx / 64, final_lly / 64,
final_urx / 64, final_ury / 64,
final_width, final_rows ));
else
FT_TRACE5(( " final bitmap: empty\n" ));
#endif /* FT_DEBUG_LEVEL_TRACE */
if ( !( final_width && final_rows ) )
return FT_Err_Ok; /* nothing to do */
/* for blending, set offset vector of final bitmap */
/* temporarily to (0,0) */
source_llx -= final_llx;
@ -971,6 +977,7 @@
pitch = target->pitch;
if ( pitch < 0 )
pitch = -pitch;

View file

@ -17,6 +17,7 @@
#include <ft2build.h>
#include FT_INTERNAL_DEBUG_H
#include FT_ERRORS_H

View file

@ -176,6 +176,9 @@
module_name,
property_name,
property_value );
if ( !*p )
break;
}
}

View file

@ -77,13 +77,13 @@
/* FIR filter used by the default and light filters */
FT_BASE_DEF( void )
ft_lcd_filter_fir( FT_Bitmap* bitmap,
FT_Render_Mode mode,
FT_LcdFiveTapFilter weights )
{
FT_UInt width = (FT_UInt)bitmap->width;
FT_UInt height = (FT_UInt)bitmap->rows;
FT_Int pitch = bitmap->pitch;
FT_Byte* origin = bitmap->buffer;
FT_Byte mode = bitmap->pixel_mode;
/* take care of bitmap flow */
@ -91,7 +91,7 @@
origin += pitch * (FT_Int)( height - 1 );
/* horizontal in-place FIR filter */
if ( mode == FT_RENDER_MODE_LCD && width >= 2 )
if ( mode == FT_PIXEL_MODE_LCD && width >= 2 )
{
FT_Byte* line = origin;
@ -134,7 +134,7 @@
}
/* vertical in-place FIR filter */
else if ( mode == FT_RENDER_MODE_LCD_V && height >= 2 )
else if ( mode == FT_PIXEL_MODE_LCD_V && height >= 2 )
{
FT_Byte* column = origin;
@ -183,13 +183,13 @@
/* intra-pixel filter used by the legacy filter */
static void
_ft_lcd_filter_legacy( FT_Bitmap* bitmap,
FT_Render_Mode mode,
FT_Byte* weights )
{
FT_UInt width = (FT_UInt)bitmap->width;
FT_UInt height = (FT_UInt)bitmap->rows;
FT_Int pitch = bitmap->pitch;
FT_Byte* origin = bitmap->buffer;
FT_Byte mode = bitmap->pixel_mode;
static const unsigned int filters[3][3] =
{
@ -206,7 +206,7 @@
origin += pitch * (FT_Int)( height - 1 );
/* horizontal in-place intra-pixel filter */
if ( mode == FT_RENDER_MODE_LCD && width >= 3 )
if ( mode == FT_PIXEL_MODE_LCD && width >= 3 )
{
FT_Byte* line = origin;
@ -243,7 +243,7 @@
}
}
}
else if ( mode == FT_RENDER_MODE_LCD_V && height >= 3 )
else if ( mode == FT_PIXEL_MODE_LCD_V && height >= 3 )
{
FT_Byte* column = origin;

View file

@ -4059,8 +4059,8 @@
/* documentation is in freetype.h */
FT_EXPORT_DEF( FT_UInt )
FT_Get_Name_Index( FT_Face face,
FT_String* glyph_name )
FT_Get_Name_Index( FT_Face face,
const FT_String* glyph_name )
{
FT_UInt result = 0;

View file

@ -46,8 +46,7 @@
void* user )
{
#undef SCALED
#define SCALED( x ) ( ( (x) < 0 ? -( -(x) << shift ) \
: ( (x) << shift ) ) - delta )
#define SCALED( x ) ( (x) * ( 1L << shift ) - delta )
FT_Vector v_last;
FT_Vector v_control;
@ -621,6 +620,16 @@
params->source = (void*)outline;
/* preset clip_box for direct mode */
if ( params->flags & FT_RASTER_FLAG_DIRECT &&
!( params->flags & FT_RASTER_FLAG_CLIP ) )
{
params->clip_box.xMin = cbox.xMin >> 6;
params->clip_box.yMin = cbox.yMin >> 6;
params->clip_box.xMax = ( cbox.xMax + 63 ) >> 6;
params->clip_box.yMax = ( cbox.yMax + 63 ) >> 6;
}
error = FT_ERR( Cannot_Render_Glyph );
while ( renderer )
{

View file

@ -86,16 +86,18 @@
base[4].x = base[2].x;
b = base[1].x;
a = base[3].x = ( base[2].x + b ) / 2;
b = base[1].x = ( base[0].x + b ) / 2;
base[2].x = ( a + b ) / 2;
a = base[0].x + base[1].x;
b = base[1].x + base[2].x;
base[3].x = b >> 1;
base[2].x = ( a + b ) >> 2;
base[1].x = a >> 1;
base[4].y = base[2].y;
b = base[1].y;
a = base[3].y = ( base[2].y + b ) / 2;
b = base[1].y = ( base[0].y + b ) / 2;
base[2].y = ( a + b ) / 2;
a = base[0].y + base[1].y;
b = base[1].y + base[2].y;
base[3].y = b >> 1;
base[2].y = ( a + b ) >> 2;
base[1].y = a >> 1;
}
@ -153,28 +155,32 @@
static void
ft_cubic_split( FT_Vector* base )
{
FT_Pos a, b, c, d;
FT_Pos a, b, c;
base[6].x = base[3].x;
c = base[1].x;
d = base[2].x;
base[1].x = a = ( base[0].x + c ) / 2;
base[5].x = b = ( base[3].x + d ) / 2;
c = ( c + d ) / 2;
base[2].x = a = ( a + c ) / 2;
base[4].x = b = ( b + c ) / 2;
base[3].x = ( a + b ) / 2;
a = base[0].x + base[1].x;
b = base[1].x + base[2].x;
c = base[2].x + base[3].x;
base[5].x = c >> 1;
c += b;
base[4].x = c >> 2;
base[1].x = a >> 1;
a += b;
base[2].x = a >> 2;
base[3].x = ( a + c ) >> 3;
base[6].y = base[3].y;
c = base[1].y;
d = base[2].y;
base[1].y = a = ( base[0].y + c ) / 2;
base[5].y = b = ( base[3].y + d ) / 2;
c = ( c + d ) / 2;
base[2].y = a = ( a + c ) / 2;
base[4].y = b = ( b + c ) / 2;
base[3].y = ( a + b ) / 2;
a = base[0].y + base[1].y;
b = base[1].y + base[2].y;
c = base[2].y + base[3].y;
base[5].y = c >> 1;
c += b;
base[4].y = c >> 2;
base[1].y = a >> 1;
a += b;
base[2].y = a >> 2;
base[3].y = ( a + c ) >> 3;
}

View file

@ -18,8 +18,8 @@
#include<windows.h>
#define FT_VERSION 2,10,0,0
#define FT_VERSION_STR "2.10.0"
#define FT_VERSION 2,10,1,0
#define FT_VERSION_STR "2.10.1"
VS_VERSION_INFO VERSIONINFO
FILEVERSION FT_VERSION

View file

@ -109,9 +109,9 @@ FT_BEGIN_HEADER
/* There are a set of defaults and each font has their own. */
typedef struct bdf_property_t_
{
char* name; /* Name of the property. */
int format; /* Format of the property. */
int builtin; /* A builtin property. */
const char* name; /* Name of the property. */
int format; /* Format of the property. */
int builtin; /* A builtin property. */
union
{
char* atom;

View file

@ -106,7 +106,7 @@ THE SOFTWARE.
FT_ULong code;
if ( mid > max || mid < min )
if ( mid >= max || mid < min )
mid = ( min + max ) >> 1;
code = encodings[mid].enc;
@ -152,7 +152,7 @@ THE SOFTWARE.
FT_ULong code; /* same as BDF_encoding_el.enc */
if ( mid > max || mid < min )
if ( mid >= max || mid < min )
mid = ( min + max ) >> 1;
code = encodings[mid].enc;
@ -216,13 +216,13 @@ THE SOFTWARE.
bdf_font_t* font = bdf->bdffont;
bdf_property_t* prop;
char* strings[4] = { NULL, NULL, NULL, NULL };
size_t nn, len, lengths[4];
const char* strings[4] = { NULL, NULL, NULL, NULL };
size_t lengths[4], nn, len;
face->style_flags = 0;
prop = bdf_get_font_property( font, (char *)"SLANT" );
prop = bdf_get_font_property( font, "SLANT" );
if ( prop && prop->format == BDF_ATOM &&
prop->value.atom &&
( *(prop->value.atom) == 'O' || *(prop->value.atom) == 'o' ||
@ -230,30 +230,30 @@ THE SOFTWARE.
{
face->style_flags |= FT_STYLE_FLAG_ITALIC;
strings[2] = ( *(prop->value.atom) == 'O' || *(prop->value.atom) == 'o' )
? (char *)"Oblique"
: (char *)"Italic";
? "Oblique"
: "Italic";
}
prop = bdf_get_font_property( font, (char *)"WEIGHT_NAME" );
prop = bdf_get_font_property( font, "WEIGHT_NAME" );
if ( prop && prop->format == BDF_ATOM &&
prop->value.atom &&
( *(prop->value.atom) == 'B' || *(prop->value.atom) == 'b' ) )
{
face->style_flags |= FT_STYLE_FLAG_BOLD;
strings[1] = (char *)"Bold";
strings[1] = "Bold";
}
prop = bdf_get_font_property( font, (char *)"SETWIDTH_NAME" );
prop = bdf_get_font_property( font, "SETWIDTH_NAME" );
if ( prop && prop->format == BDF_ATOM &&
prop->value.atom && *(prop->value.atom) &&
!( *(prop->value.atom) == 'N' || *(prop->value.atom) == 'n' ) )
strings[3] = (char *)(prop->value.atom);
strings[3] = (const char *)(prop->value.atom);
prop = bdf_get_font_property( font, (char *)"ADD_STYLE_NAME" );
prop = bdf_get_font_property( font, "ADD_STYLE_NAME" );
if ( prop && prop->format == BDF_ATOM &&
prop->value.atom && *(prop->value.atom) &&
!( *(prop->value.atom) == 'N' || *(prop->value.atom) == 'n' ) )
strings[0] = (char *)(prop->value.atom);
strings[0] = (const char *)(prop->value.atom);
for ( len = 0, nn = 0; nn < 4; nn++ )
{
@ -267,7 +267,7 @@ THE SOFTWARE.
if ( len == 0 )
{
strings[0] = (char *)"Regular";
strings[0] = "Regular";
lengths[0] = ft_strlen( strings[0] );
len = lengths[0] + 1;
}
@ -283,7 +283,7 @@ THE SOFTWARE.
for ( nn = 0; nn < 4; nn++ )
{
char* src = strings[nn];
const char* src = strings[nn];
len = lengths[nn];

View file

@ -79,89 +79,89 @@
static const bdf_property_t _bdf_properties[] =
{
{ (char *)"ADD_STYLE_NAME", BDF_ATOM, 1, { 0 } },
{ (char *)"AVERAGE_WIDTH", BDF_INTEGER, 1, { 0 } },
{ (char *)"AVG_CAPITAL_WIDTH", BDF_INTEGER, 1, { 0 } },
{ (char *)"AVG_LOWERCASE_WIDTH", BDF_INTEGER, 1, { 0 } },
{ (char *)"CAP_HEIGHT", BDF_INTEGER, 1, { 0 } },
{ (char *)"CHARSET_COLLECTIONS", BDF_ATOM, 1, { 0 } },
{ (char *)"CHARSET_ENCODING", BDF_ATOM, 1, { 0 } },
{ (char *)"CHARSET_REGISTRY", BDF_ATOM, 1, { 0 } },
{ (char *)"COMMENT", BDF_ATOM, 1, { 0 } },
{ (char *)"COPYRIGHT", BDF_ATOM, 1, { 0 } },
{ (char *)"DEFAULT_CHAR", BDF_CARDINAL, 1, { 0 } },
{ (char *)"DESTINATION", BDF_CARDINAL, 1, { 0 } },
{ (char *)"DEVICE_FONT_NAME", BDF_ATOM, 1, { 0 } },
{ (char *)"END_SPACE", BDF_INTEGER, 1, { 0 } },
{ (char *)"FACE_NAME", BDF_ATOM, 1, { 0 } },
{ (char *)"FAMILY_NAME", BDF_ATOM, 1, { 0 } },
{ (char *)"FIGURE_WIDTH", BDF_INTEGER, 1, { 0 } },
{ (char *)"FONT", BDF_ATOM, 1, { 0 } },
{ (char *)"FONTNAME_REGISTRY", BDF_ATOM, 1, { 0 } },
{ (char *)"FONT_ASCENT", BDF_INTEGER, 1, { 0 } },
{ (char *)"FONT_DESCENT", BDF_INTEGER, 1, { 0 } },
{ (char *)"FOUNDRY", BDF_ATOM, 1, { 0 } },
{ (char *)"FULL_NAME", BDF_ATOM, 1, { 0 } },
{ (char *)"ITALIC_ANGLE", BDF_INTEGER, 1, { 0 } },
{ (char *)"MAX_SPACE", BDF_INTEGER, 1, { 0 } },
{ (char *)"MIN_SPACE", BDF_INTEGER, 1, { 0 } },
{ (char *)"NORM_SPACE", BDF_INTEGER, 1, { 0 } },
{ (char *)"NOTICE", BDF_ATOM, 1, { 0 } },
{ (char *)"PIXEL_SIZE", BDF_INTEGER, 1, { 0 } },
{ (char *)"POINT_SIZE", BDF_INTEGER, 1, { 0 } },
{ (char *)"QUAD_WIDTH", BDF_INTEGER, 1, { 0 } },
{ (char *)"RAW_ASCENT", BDF_INTEGER, 1, { 0 } },
{ (char *)"RAW_AVERAGE_WIDTH", BDF_INTEGER, 1, { 0 } },
{ (char *)"RAW_AVG_CAPITAL_WIDTH", BDF_INTEGER, 1, { 0 } },
{ (char *)"RAW_AVG_LOWERCASE_WIDTH", BDF_INTEGER, 1, { 0 } },
{ (char *)"RAW_CAP_HEIGHT", BDF_INTEGER, 1, { 0 } },
{ (char *)"RAW_DESCENT", BDF_INTEGER, 1, { 0 } },
{ (char *)"RAW_END_SPACE", BDF_INTEGER, 1, { 0 } },
{ (char *)"RAW_FIGURE_WIDTH", BDF_INTEGER, 1, { 0 } },
{ (char *)"RAW_MAX_SPACE", BDF_INTEGER, 1, { 0 } },
{ (char *)"RAW_MIN_SPACE", BDF_INTEGER, 1, { 0 } },
{ (char *)"RAW_NORM_SPACE", BDF_INTEGER, 1, { 0 } },
{ (char *)"RAW_PIXEL_SIZE", BDF_INTEGER, 1, { 0 } },
{ (char *)"RAW_POINT_SIZE", BDF_INTEGER, 1, { 0 } },
{ (char *)"RAW_PIXELSIZE", BDF_INTEGER, 1, { 0 } },
{ (char *)"RAW_POINTSIZE", BDF_INTEGER, 1, { 0 } },
{ (char *)"RAW_QUAD_WIDTH", BDF_INTEGER, 1, { 0 } },
{ (char *)"RAW_SMALL_CAP_SIZE", BDF_INTEGER, 1, { 0 } },
{ (char *)"RAW_STRIKEOUT_ASCENT", BDF_INTEGER, 1, { 0 } },
{ (char *)"RAW_STRIKEOUT_DESCENT", BDF_INTEGER, 1, { 0 } },
{ (char *)"RAW_SUBSCRIPT_SIZE", BDF_INTEGER, 1, { 0 } },
{ (char *)"RAW_SUBSCRIPT_X", BDF_INTEGER, 1, { 0 } },
{ (char *)"RAW_SUBSCRIPT_Y", BDF_INTEGER, 1, { 0 } },
{ (char *)"RAW_SUPERSCRIPT_SIZE", BDF_INTEGER, 1, { 0 } },
{ (char *)"RAW_SUPERSCRIPT_X", BDF_INTEGER, 1, { 0 } },
{ (char *)"RAW_SUPERSCRIPT_Y", BDF_INTEGER, 1, { 0 } },
{ (char *)"RAW_UNDERLINE_POSITION", BDF_INTEGER, 1, { 0 } },
{ (char *)"RAW_UNDERLINE_THICKNESS", BDF_INTEGER, 1, { 0 } },
{ (char *)"RAW_X_HEIGHT", BDF_INTEGER, 1, { 0 } },
{ (char *)"RELATIVE_SETWIDTH", BDF_CARDINAL, 1, { 0 } },
{ (char *)"RELATIVE_WEIGHT", BDF_CARDINAL, 1, { 0 } },
{ (char *)"RESOLUTION", BDF_INTEGER, 1, { 0 } },
{ (char *)"RESOLUTION_X", BDF_CARDINAL, 1, { 0 } },
{ (char *)"RESOLUTION_Y", BDF_CARDINAL, 1, { 0 } },
{ (char *)"SETWIDTH_NAME", BDF_ATOM, 1, { 0 } },
{ (char *)"SLANT", BDF_ATOM, 1, { 0 } },
{ (char *)"SMALL_CAP_SIZE", BDF_INTEGER, 1, { 0 } },
{ (char *)"SPACING", BDF_ATOM, 1, { 0 } },
{ (char *)"STRIKEOUT_ASCENT", BDF_INTEGER, 1, { 0 } },
{ (char *)"STRIKEOUT_DESCENT", BDF_INTEGER, 1, { 0 } },
{ (char *)"SUBSCRIPT_SIZE", BDF_INTEGER, 1, { 0 } },
{ (char *)"SUBSCRIPT_X", BDF_INTEGER, 1, { 0 } },
{ (char *)"SUBSCRIPT_Y", BDF_INTEGER, 1, { 0 } },
{ (char *)"SUPERSCRIPT_SIZE", BDF_INTEGER, 1, { 0 } },
{ (char *)"SUPERSCRIPT_X", BDF_INTEGER, 1, { 0 } },
{ (char *)"SUPERSCRIPT_Y", BDF_INTEGER, 1, { 0 } },
{ (char *)"UNDERLINE_POSITION", BDF_INTEGER, 1, { 0 } },
{ (char *)"UNDERLINE_THICKNESS", BDF_INTEGER, 1, { 0 } },
{ (char *)"WEIGHT", BDF_CARDINAL, 1, { 0 } },
{ (char *)"WEIGHT_NAME", BDF_ATOM, 1, { 0 } },
{ (char *)"X_HEIGHT", BDF_INTEGER, 1, { 0 } },
{ (char *)"_MULE_BASELINE_OFFSET", BDF_INTEGER, 1, { 0 } },
{ (char *)"_MULE_RELATIVE_COMPOSE", BDF_INTEGER, 1, { 0 } },
{ "ADD_STYLE_NAME", BDF_ATOM, 1, { 0 } },
{ "AVERAGE_WIDTH", BDF_INTEGER, 1, { 0 } },
{ "AVG_CAPITAL_WIDTH", BDF_INTEGER, 1, { 0 } },
{ "AVG_LOWERCASE_WIDTH", BDF_INTEGER, 1, { 0 } },
{ "CAP_HEIGHT", BDF_INTEGER, 1, { 0 } },
{ "CHARSET_COLLECTIONS", BDF_ATOM, 1, { 0 } },
{ "CHARSET_ENCODING", BDF_ATOM, 1, { 0 } },
{ "CHARSET_REGISTRY", BDF_ATOM, 1, { 0 } },
{ "COMMENT", BDF_ATOM, 1, { 0 } },
{ "COPYRIGHT", BDF_ATOM, 1, { 0 } },
{ "DEFAULT_CHAR", BDF_CARDINAL, 1, { 0 } },
{ "DESTINATION", BDF_CARDINAL, 1, { 0 } },
{ "DEVICE_FONT_NAME", BDF_ATOM, 1, { 0 } },
{ "END_SPACE", BDF_INTEGER, 1, { 0 } },
{ "FACE_NAME", BDF_ATOM, 1, { 0 } },
{ "FAMILY_NAME", BDF_ATOM, 1, { 0 } },
{ "FIGURE_WIDTH", BDF_INTEGER, 1, { 0 } },
{ "FONT", BDF_ATOM, 1, { 0 } },
{ "FONTNAME_REGISTRY", BDF_ATOM, 1, { 0 } },
{ "FONT_ASCENT", BDF_INTEGER, 1, { 0 } },
{ "FONT_DESCENT", BDF_INTEGER, 1, { 0 } },
{ "FOUNDRY", BDF_ATOM, 1, { 0 } },
{ "FULL_NAME", BDF_ATOM, 1, { 0 } },
{ "ITALIC_ANGLE", BDF_INTEGER, 1, { 0 } },
{ "MAX_SPACE", BDF_INTEGER, 1, { 0 } },
{ "MIN_SPACE", BDF_INTEGER, 1, { 0 } },
{ "NORM_SPACE", BDF_INTEGER, 1, { 0 } },
{ "NOTICE", BDF_ATOM, 1, { 0 } },
{ "PIXEL_SIZE", BDF_INTEGER, 1, { 0 } },
{ "POINT_SIZE", BDF_INTEGER, 1, { 0 } },
{ "QUAD_WIDTH", BDF_INTEGER, 1, { 0 } },
{ "RAW_ASCENT", BDF_INTEGER, 1, { 0 } },
{ "RAW_AVERAGE_WIDTH", BDF_INTEGER, 1, { 0 } },
{ "RAW_AVG_CAPITAL_WIDTH", BDF_INTEGER, 1, { 0 } },
{ "RAW_AVG_LOWERCASE_WIDTH", BDF_INTEGER, 1, { 0 } },
{ "RAW_CAP_HEIGHT", BDF_INTEGER, 1, { 0 } },
{ "RAW_DESCENT", BDF_INTEGER, 1, { 0 } },
{ "RAW_END_SPACE", BDF_INTEGER, 1, { 0 } },
{ "RAW_FIGURE_WIDTH", BDF_INTEGER, 1, { 0 } },
{ "RAW_MAX_SPACE", BDF_INTEGER, 1, { 0 } },
{ "RAW_MIN_SPACE", BDF_INTEGER, 1, { 0 } },
{ "RAW_NORM_SPACE", BDF_INTEGER, 1, { 0 } },
{ "RAW_PIXEL_SIZE", BDF_INTEGER, 1, { 0 } },
{ "RAW_POINT_SIZE", BDF_INTEGER, 1, { 0 } },
{ "RAW_PIXELSIZE", BDF_INTEGER, 1, { 0 } },
{ "RAW_POINTSIZE", BDF_INTEGER, 1, { 0 } },
{ "RAW_QUAD_WIDTH", BDF_INTEGER, 1, { 0 } },
{ "RAW_SMALL_CAP_SIZE", BDF_INTEGER, 1, { 0 } },
{ "RAW_STRIKEOUT_ASCENT", BDF_INTEGER, 1, { 0 } },
{ "RAW_STRIKEOUT_DESCENT", BDF_INTEGER, 1, { 0 } },
{ "RAW_SUBSCRIPT_SIZE", BDF_INTEGER, 1, { 0 } },
{ "RAW_SUBSCRIPT_X", BDF_INTEGER, 1, { 0 } },
{ "RAW_SUBSCRIPT_Y", BDF_INTEGER, 1, { 0 } },
{ "RAW_SUPERSCRIPT_SIZE", BDF_INTEGER, 1, { 0 } },
{ "RAW_SUPERSCRIPT_X", BDF_INTEGER, 1, { 0 } },
{ "RAW_SUPERSCRIPT_Y", BDF_INTEGER, 1, { 0 } },
{ "RAW_UNDERLINE_POSITION", BDF_INTEGER, 1, { 0 } },
{ "RAW_UNDERLINE_THICKNESS", BDF_INTEGER, 1, { 0 } },
{ "RAW_X_HEIGHT", BDF_INTEGER, 1, { 0 } },
{ "RELATIVE_SETWIDTH", BDF_CARDINAL, 1, { 0 } },
{ "RELATIVE_WEIGHT", BDF_CARDINAL, 1, { 0 } },
{ "RESOLUTION", BDF_INTEGER, 1, { 0 } },
{ "RESOLUTION_X", BDF_CARDINAL, 1, { 0 } },
{ "RESOLUTION_Y", BDF_CARDINAL, 1, { 0 } },
{ "SETWIDTH_NAME", BDF_ATOM, 1, { 0 } },
{ "SLANT", BDF_ATOM, 1, { 0 } },
{ "SMALL_CAP_SIZE", BDF_INTEGER, 1, { 0 } },
{ "SPACING", BDF_ATOM, 1, { 0 } },
{ "STRIKEOUT_ASCENT", BDF_INTEGER, 1, { 0 } },
{ "STRIKEOUT_DESCENT", BDF_INTEGER, 1, { 0 } },
{ "SUBSCRIPT_SIZE", BDF_INTEGER, 1, { 0 } },
{ "SUBSCRIPT_X", BDF_INTEGER, 1, { 0 } },
{ "SUBSCRIPT_Y", BDF_INTEGER, 1, { 0 } },
{ "SUPERSCRIPT_SIZE", BDF_INTEGER, 1, { 0 } },
{ "SUPERSCRIPT_X", BDF_INTEGER, 1, { 0 } },
{ "SUPERSCRIPT_Y", BDF_INTEGER, 1, { 0 } },
{ "UNDERLINE_POSITION", BDF_INTEGER, 1, { 0 } },
{ "UNDERLINE_THICKNESS", BDF_INTEGER, 1, { 0 } },
{ "WEIGHT", BDF_CARDINAL, 1, { 0 } },
{ "WEIGHT_NAME", BDF_ATOM, 1, { 0 } },
{ "X_HEIGHT", BDF_INTEGER, 1, { 0 } },
{ "_MULE_BASELINE_OFFSET", BDF_INTEGER, 1, { 0 } },
{ "_MULE_RELATIVE_COMPOSE", BDF_INTEGER, 1, { 0 } },
};
static const unsigned long
@ -364,7 +364,7 @@
/* An empty string for empty fields. */
static const char empty[1] = { 0 }; /* XXX eliminate this */
static const char empty[] = ""; /* XXX eliminate this */
static char *
@ -407,13 +407,14 @@
static FT_Error
_bdf_list_split( _bdf_list_t* list,
char* separators,
const char* separators,
char* line,
unsigned long linelen )
{
unsigned long final_empty;
int mult;
char *sp, *ep, *end;
const char *sp, *end;
char *ep;
char seps[32];
FT_Error error = FT_Err_Ok;
@ -473,7 +474,7 @@
}
/* Assign the field appropriately. */
list->field[list->used++] = ( ep > sp ) ? sp : (char*)empty;
list->field[list->used++] = ( ep > sp ) ? (char*)sp : (char*)empty;
sp = ep;
@ -692,7 +693,7 @@
/* Routine to convert a decimal ASCII string to an unsigned long integer. */
static unsigned long
_bdf_atoul( char* s )
_bdf_atoul( const char* s )
{
unsigned long v;
@ -717,7 +718,7 @@
/* Routine to convert a decimal ASCII string to a signed long integer. */
static long
_bdf_atol( char* s )
_bdf_atol( const char* s )
{
long v, neg;
@ -750,7 +751,7 @@
/* Routine to convert a decimal ASCII string to an unsigned short integer. */
static unsigned short
_bdf_atous( char* s )
_bdf_atous( const char* s )
{
unsigned short v;
@ -775,7 +776,7 @@
/* Routine to convert a decimal ASCII string to a signed short integer. */
static short
_bdf_atos( char* s )
_bdf_atos( const char* s )
{
short v, neg;
@ -828,7 +829,7 @@
static FT_Error
bdf_create_property( char* name,
bdf_create_property( const char* name,
int format,
bdf_font_t* font )
{
@ -998,7 +999,7 @@
FT_MEM_COPY( name, font->name, len );
error = _bdf_list_split( &list, (char *)"-", name, (unsigned long)len );
error = _bdf_list_split( &list, "-", name, (unsigned long)len );
if ( error )
goto Fail;
@ -1097,7 +1098,7 @@
static FT_Error
_bdf_add_property( bdf_font_t* font,
char* name,
const char* name,
char* value,
unsigned long lineno )
{
@ -1336,7 +1337,7 @@
goto Exit;
}
error = _bdf_list_split( &p->list, (char *)" +", line, linelen );
error = _bdf_list_split( &p->list, " +", line, linelen );
if ( error )
goto Exit;
p->cnt = font->glyphs_size = _bdf_atoul( p->list.field[1] );
@ -1423,7 +1424,7 @@
/* encoding can be checked for an unencoded character. */
FT_FREE( p->glyph_name );
error = _bdf_list_split( &p->list, (char *)" +", line, linelen );
error = _bdf_list_split( &p->list, " +", line, linelen );
if ( error )
goto Exit;
@ -1461,7 +1462,7 @@
goto Exit;
}
error = _bdf_list_split( &p->list, (char *)" +", line, linelen );
error = _bdf_list_split( &p->list, " +", line, linelen );
if ( error )
goto Exit;
@ -1615,7 +1616,7 @@
/* Expect the SWIDTH (scalable width) field next. */
if ( _bdf_strncmp( line, "SWIDTH", 6 ) == 0 )
{
error = _bdf_list_split( &p->list, (char *)" +", line, linelen );
error = _bdf_list_split( &p->list, " +", line, linelen );
if ( error )
goto Exit;
@ -1628,7 +1629,7 @@
/* Expect the DWIDTH (scalable width) field next. */
if ( _bdf_strncmp( line, "DWIDTH", 6 ) == 0 )
{
error = _bdf_list_split( &p->list, (char *)" +", line, linelen );
error = _bdf_list_split( &p->list, " +", line, linelen );
if ( error )
goto Exit;
@ -1653,7 +1654,7 @@
/* Expect the BBX field next. */
if ( _bdf_strncmp( line, "BBX", 3 ) == 0 )
{
error = _bdf_list_split( &p->list, (char *)" +", line, linelen );
error = _bdf_list_split( &p->list, " +", line, linelen );
if ( error )
goto Exit;
@ -1796,7 +1797,7 @@
{
p->font->font_ascent = p->font->bbx.ascent;
ft_sprintf( nbuf, "%hd", p->font->bbx.ascent );
error = _bdf_add_property( p->font, (char *)"FONT_ASCENT",
error = _bdf_add_property( p->font, "FONT_ASCENT",
nbuf, lineno );
if ( error )
goto Exit;
@ -1808,7 +1809,7 @@
{
p->font->font_descent = p->font->bbx.descent;
ft_sprintf( nbuf, "%hd", p->font->bbx.descent );
error = _bdf_add_property( p->font, (char *)"FONT_DESCENT",
error = _bdf_add_property( p->font, "FONT_DESCENT",
nbuf, lineno );
if ( error )
goto Exit;
@ -1846,7 +1847,7 @@
}
else
{
error = _bdf_list_split( &p->list, (char *)" +", line, linelen );
error = _bdf_list_split( &p->list, " +", line, linelen );
if ( error )
goto Exit;
name = p->list.field[0];
@ -1976,7 +1977,7 @@
goto Exit;
}
error = _bdf_list_split( &p->list, (char *)" +", line, linelen );
error = _bdf_list_split( &p->list, " +", line, linelen );
if ( error )
goto Exit;
@ -2015,7 +2016,7 @@
goto Exit;
}
error = _bdf_list_split( &p->list, (char *)" +", line, linelen );
error = _bdf_list_split( &p->list, " +", line, linelen );
if ( error )
goto Exit;
@ -2038,7 +2039,7 @@
/* The next thing to check for is the FONT field. */
if ( _bdf_strncmp( line, "FONT", 4 ) == 0 )
{
error = _bdf_list_split( &p->list, (char *)" +", line, linelen );
error = _bdf_list_split( &p->list, " +", line, linelen );
if ( error )
goto Exit;
_bdf_list_shift( &p->list, 1 );
@ -2081,7 +2082,7 @@
goto Exit;
}
error = _bdf_list_split( &p->list, (char *)" +", line, linelen );
error = _bdf_list_split( &p->list, " +", line, linelen );
if ( error )
goto Exit;
@ -2136,7 +2137,7 @@
/* for compiling fonts. */
p->font->font_ascent = p->font->bbx.ascent;
ft_sprintf( nbuf, "%hd", p->font->bbx.ascent );
error = _bdf_add_property( p->font, (char *)"FONT_ASCENT",
error = _bdf_add_property( p->font, "FONT_ASCENT",
nbuf, lineno );
if ( error )
goto Exit;
@ -2144,7 +2145,7 @@
p->font->font_descent = p->font->bbx.descent;
ft_sprintf( nbuf, "%hd", p->font->bbx.descent );
error = _bdf_add_property( p->font, (char *)"FONT_DESCENT",
error = _bdf_add_property( p->font, "FONT_DESCENT",
nbuf, lineno );
if ( error )
goto Exit;

View file

@ -15,7 +15,7 @@
# Cache driver directory
#
CACHE_DIR := $(SRC_DIR)/cache
CACHE_DIR := $(SRC_DIR)/cache
# compilation flags for the driver

View file

@ -381,8 +381,8 @@
static FT_UInt
cff_get_name_index( CFF_Face face,
FT_String* glyph_name )
cff_get_name_index( CFF_Face face,
const FT_String* glyph_name )
{
CFF_Font cff;
CFF_Charset charset;

View file

@ -962,7 +962,7 @@
cffface->style_name = style_name;
else
/* assume "Regular" style if we don't know better */
cffface->style_name = cff_strcpy( memory, (char *)"Regular" );
cffface->style_name = cff_strcpy( memory, "Regular" );
/********************************************************************
*

View file

@ -77,6 +77,23 @@
}
#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
static void
finalize_t2_strings( FT_Memory memory,
void* data,
void* user )
{
CFF_T2_String t2 = (CFF_T2_String)data;
FT_UNUSED( user );
memory->free( memory, t2->start );
memory->free( memory, data );
}
#endif /* CFF_CONFIG_OPTION_OLD_ENGINE */
FT_LOCAL_DEF( void )
cff_parser_done( CFF_Parser parser )
{
@ -84,13 +101,65 @@
FT_FREE( parser->stack );
#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
FT_List_Finalize( &parser->t2_strings,
finalize_t2_strings,
memory,
NULL );
#endif
}
/* Assuming `first >= last'. */
static FT_Error
cff_parser_within_limits( CFF_Parser parser,
FT_Byte* first,
FT_Byte* last )
{
#ifndef CFF_CONFIG_OPTION_OLD_ENGINE
/* Fast path for regular FreeType builds with the "new" engine; */
/* `first >= parser->start' can be assumed. */
FT_UNUSED( first );
return last < parser->limit ? FT_Err_Ok : FT_THROW( Invalid_Argument );
#else /* CFF_CONFIG_OPTION_OLD_ENGINE */
FT_ListNode node;
if ( first >= parser->start &&
last < parser->limit )
return FT_Err_Ok;
node = parser->t2_strings.head;
while ( node )
{
CFF_T2_String t2 = (CFF_T2_String)node->data;
if ( first >= t2->start &&
last < t2->limit )
return FT_Err_Ok;
node = node->next;
}
return FT_THROW( Invalid_Argument );
#endif /* CFF_CONFIG_OPTION_OLD_ENGINE */
}
/* read an integer */
static FT_Long
cff_parse_integer( FT_Byte* start,
FT_Byte* limit )
cff_parse_integer( CFF_Parser parser,
FT_Byte* start )
{
FT_Byte* p = start;
FT_Int v = *p++;
@ -99,14 +168,14 @@
if ( v == 28 )
{
if ( p + 2 > limit )
if ( cff_parser_within_limits( parser, p, p + 1 ) )
goto Bad;
val = (FT_Short)( ( (FT_UShort)p[0] << 8 ) | p[1] );
}
else if ( v == 29 )
{
if ( p + 4 > limit )
if ( cff_parser_within_limits( parser, p, p + 3 ) )
goto Bad;
val = (FT_Long)( ( (FT_ULong)p[0] << 24 ) |
@ -120,14 +189,14 @@
}
else if ( v < 251 )
{
if ( p + 1 > limit )
if ( cff_parser_within_limits( parser, p, p ) )
goto Bad;
val = ( v - 247 ) * 256 + p[0] + 108;
}
else
{
if ( p + 1 > limit )
if ( cff_parser_within_limits( parser, p, p ) )
goto Bad;
val = -( v - 251 ) * 256 - p[0] - 108;
@ -176,10 +245,10 @@
/* read a real */
static FT_Fixed
cff_parse_real( FT_Byte* start,
FT_Byte* limit,
FT_Long power_ten,
FT_Long* scaling )
cff_parse_real( CFF_Parser parser,
FT_Byte* start,
FT_Long power_ten,
FT_Long* scaling )
{
FT_Byte* p = start;
FT_Int nib;
@ -214,7 +283,7 @@
p++;
/* Make sure we don't read past the end. */
if ( p >= limit )
if ( cff_parser_within_limits( parser, p, p ) )
goto Bad;
}
@ -251,7 +320,7 @@
p++;
/* Make sure we don't read past the end. */
if ( p >= limit )
if ( cff_parser_within_limits( parser, p, p ) )
goto Bad;
}
@ -290,7 +359,7 @@
p++;
/* Make sure we don't read past the end. */
if ( p >= limit )
if ( cff_parser_within_limits( parser, p, p ) )
goto Bad;
}
@ -457,7 +526,7 @@
if ( **d == 30 )
{
/* binary-coded decimal is truncated to integer */
return cff_parse_real( *d, parser->limit, 0, NULL ) >> 16;
return cff_parse_real( parser, *d, 0, NULL ) >> 16;
}
else if ( **d == 255 )
@ -483,7 +552,7 @@
}
else
return cff_parse_integer( *d, parser->limit );
return cff_parse_integer( parser, *d );
}
@ -494,10 +563,10 @@
FT_Long scaling )
{
if ( **d == 30 )
return cff_parse_real( *d, parser->limit, scaling, NULL );
return cff_parse_real( parser, *d, scaling, NULL );
else
{
FT_Long val = cff_parse_integer( *d, parser->limit );
FT_Long val = cff_parse_integer( parser, *d );
if ( scaling )
@ -562,14 +631,14 @@
FT_ASSERT( scaling );
if ( **d == 30 )
return cff_parse_real( *d, parser->limit, 0, scaling );
return cff_parse_real( parser, *d, 0, scaling );
else
{
FT_Long number;
FT_Int integer_length;
number = cff_parse_integer( d[0], d[1] );
number = cff_parse_integer( parser, d[0] );
if ( number > 0x7FFFL )
{
@ -1122,18 +1191,6 @@
#endif /* FT_DEBUG_LEVEL_TRACE */
#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
static void
destruct_t2s_item( FT_Memory memory,
void* data,
void* user )
{
FT_UNUSED( user );
memory->free( memory, data );
}
#endif /* CFF_CONFIG_OPTION_OLD_ENGINE */
FT_LOCAL_DEF( FT_Error )
cff_parser_run( CFF_Parser parser,
FT_Byte* start,
@ -1147,11 +1204,6 @@
FT_Library library = parser->library;
FT_Memory memory = library->memory;
FT_ListRec t2s;
FT_ZERO( &t2s );
#endif
parser->top = parser->stack;
@ -1212,9 +1264,11 @@
FT_Byte* charstring_base;
FT_ULong charstring_len;
FT_Fixed* stack;
FT_ListNode node;
FT_Byte* q;
FT_Fixed* stack;
FT_ListNode node;
CFF_T2_String t2;
size_t t2_size;
FT_Byte* q;
charstring_base = ++p;
@ -1261,16 +1315,26 @@
if ( !node )
goto Out_Of_Memory_Error;
FT_List_Add( &parser->t2_strings, node );
t2 = (CFF_T2_String)memory->alloc( memory,
sizeof ( CFF_T2_StringRec ) );
if ( !t2 )
goto Out_Of_Memory_Error;
node->data = t2;
/* `5' is the conservative upper bound of required bytes per stack */
/* element. */
q = (FT_Byte*)memory->alloc( memory,
5 * ( decoder.top - decoder.stack ) );
t2_size = 5 * ( decoder.top - decoder.stack );
q = (FT_Byte*)memory->alloc( memory, t2_size );
if ( !q )
goto Out_Of_Memory_Error;
node->data = q;
FT_List_Add( &t2s, node );
t2->start = q;
t2->limit = q + t2_size;
stack = decoder.stack;
@ -1531,9 +1595,6 @@
} /* while ( p < limit ) */
Exit:
#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
FT_List_Finalize( &t2s, destruct_t2s_item, memory, NULL );
#endif
return error;
#ifdef CFF_CONFIG_OPTION_OLD_ENGINE

View file

@ -60,6 +60,10 @@ FT_BEGIN_HEADER
FT_Byte** top;
FT_UInt stackSize; /* allocated size */
#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
FT_ListRec t2_strings;
#endif /* CFF_CONFIG_OPTION_OLD_ENGINE */
FT_UInt object_code;
void* object;
@ -130,6 +134,15 @@ FT_BEGIN_HEADER
FT_END_HEADER
#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
typedef struct CFF_T2_String_
{
FT_Byte* start;
FT_Byte* limit;
} CFF_T2_StringRec, *CFF_T2_String;
#endif /* CFF_CONFIG_OPTION_OLD_ENGINE */
#endif /* CFFPARSE_H_ */

View file

@ -746,7 +746,7 @@
stream.zfree = (free_func) ft_gzip_free;
stream.opaque = memory;
err = inflateInit2( &stream, MAX_WBITS );
err = inflateInit2( &stream, MAX_WBITS|32 );
if ( err != Z_OK )
return FT_THROW( Invalid_Argument );

View file

@ -235,6 +235,7 @@ int r )
s->sub.trees.index = 0;
Tracev((stderr, "inflate: table sizes ok\n"));
s->mode = BTREE;
/* fall through */
case BTREE:
while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10))
{
@ -260,6 +261,7 @@ int r )
s->sub.trees.index = 0;
Tracev((stderr, "inflate: bits tree ok\n"));
s->mode = DTREE;
/* fall through */
case DTREE:
while (t = s->sub.trees.table,
s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))
@ -335,6 +337,7 @@ int r )
}
ZFREE(z, s->sub.trees.blens);
s->mode = CODES;
/* fall through */
case CODES:
UPDATE
if ((r = inflate_codes(s, z, r)) != Z_STREAM_END)
@ -351,11 +354,13 @@ int r )
break;
}
s->mode = DRY;
/* fall through */
case DRY:
FLUSH
if (s->read != s->write)
LEAVE
s->mode = DONE;
/* fall through */
case DONE:
r = Z_STREAM_END;
LEAVE

View file

@ -117,6 +117,7 @@ int r )
c->sub.code.need = c->lbits;
c->sub.code.tree = c->ltree;
c->mode = LEN;
/* fall through */
case LEN: /* i: get length/literal/eob next */
j = c->sub.code.need;
NEEDBITS(j)
@ -164,6 +165,7 @@ int r )
c->sub.code.tree = c->dtree;
Tracevv((stderr, "inflate: length %u\n", c->len));
c->mode = DIST;
/* fall through */
case DIST: /* i: get distance next */
j = c->sub.code.need;
NEEDBITS(j)
@ -194,6 +196,7 @@ int r )
DUMPBITS(j)
Tracevv((stderr, "inflate: distance %u\n", c->sub.copy.dist));
c->mode = COPY;
/* fall through */
case COPY: /* o: copying bytes in window, waiting for space */
f = q - c->sub.copy.dist;
while (f < s->window) /* modulo window size-"while" instead */
@ -225,6 +228,7 @@ int r )
if (s->read != s->write)
LEAVE
c->mode = END;
/* fall through */
case END:
r = Z_STREAM_END;
LEAVE

View file

@ -174,6 +174,7 @@ int f )
break;
}
z->state->mode = FLAG;
/* fall through */
case FLAG:
NEEDBYTE
b = NEXTBYTE;
@ -191,18 +192,22 @@ int f )
break;
}
z->state->mode = DICT4;
/* fall through */
case DICT4:
NEEDBYTE
z->state->sub.check.need = (uLong)NEXTBYTE << 24;
z->state->mode = DICT3;
/* fall through */
case DICT3:
NEEDBYTE
z->state->sub.check.need += (uLong)NEXTBYTE << 16;
z->state->mode = DICT2;
/* fall through */
case DICT2:
NEEDBYTE
z->state->sub.check.need += (uLong)NEXTBYTE << 8;
z->state->mode = DICT1;
/* fall through */
case DICT1:
NEEDBYTE
z->state->sub.check.need += (uLong)NEXTBYTE;
@ -234,18 +239,22 @@ int f )
break;
}
z->state->mode = CHECK4;
/* fall through */
case CHECK4:
NEEDBYTE
z->state->sub.check.need = (uLong)NEXTBYTE << 24;
z->state->mode = CHECK3;
/* fall through */
case CHECK3:
NEEDBYTE
z->state->sub.check.need += (uLong)NEXTBYTE << 16;
z->state->mode = CHECK2;
/* fall through */
case CHECK2:
NEEDBYTE
z->state->sub.check.need += (uLong)NEXTBYTE << 8;
z->state->mode = CHECK1;
/* fall through */
case CHECK1:
NEEDBYTE
z->state->sub.check.need += (uLong)NEXTBYTE;
@ -259,6 +268,7 @@ int f )
}
Tracev((stderr, "inflate: zlib check ok\n"));
z->state->mode = DONE;
/* fall through */
case DONE:
return Z_STREAM_END;
case BAD:

View file

@ -99,7 +99,8 @@ FT_BEGIN_HEADER
FT_Short ascent;
FT_Short descent;
FT_Short attributes;
FT_ULong bits;
FT_ULong bits; /* offset into the PCF_BITMAPS table */
} PCF_MetricRec, *PCF_Metric;

View file

@ -122,9 +122,9 @@ THE SOFTWARE.
charcodeCol > enc->lastCol )
return 0;
return (FT_UInt)enc->offset[ ( charcodeRow - enc->firstRow ) *
( enc->lastCol - enc->firstCol + 1 ) +
charcodeCol - enc->firstCol ];
return (FT_UInt)enc->offset[( charcodeRow - enc->firstRow ) *
( enc->lastCol - enc->firstCol + 1 ) +
charcodeCol - enc->firstCol];
}
@ -160,9 +160,9 @@ THE SOFTWARE.
charcode = (FT_UInt32)( charcodeRow * 256 + charcodeCol );
result = (FT_UInt)enc->offset[ ( charcodeRow - enc->firstRow ) *
( enc->lastCol - enc->firstCol + 1 ) +
charcodeCol - enc->firstCol ];
result = (FT_UInt)enc->offset[( charcodeRow - enc->firstRow ) *
( enc->lastCol - enc->firstCol + 1 ) +
charcodeCol - enc->firstCol];
if ( result != 0xFFFFU )
break;
}

View file

@ -743,33 +743,39 @@ THE SOFTWARE.
if ( !orig_nmetrics )
return FT_THROW( Invalid_Table );
/* PCF is a format from ancient times; Unicode was in its */
/* infancy, and widely used two-byte character sets for CJK */
/* scripts (Big 5, GB 2312, JIS X 0208, etc.) did have at most */
/* 15000 characters. Even the more exotic CNS 11643 and CCCII */
/* standards, which were essentially three-byte character sets, */
/* provided less then 65536 assigned characters. */
/* */
/* While technically possible to have a larger number of glyphs */
/* in PCF files, we thus limit the number to 65536. */
if ( orig_nmetrics > 65536 )
/*
* PCF is a format from ancient times; Unicode was in its infancy, and
* widely used two-byte character sets for CJK scripts (Big 5, GB 2312,
* JIS X 0208, etc.) did have at most 15000 characters. Even the more
* exotic CNS 11643 and CCCII standards, which were essentially
* three-byte character sets, provided less then 65536 assigned
* characters.
*
* While technically possible to have a larger number of glyphs in PCF
* files, we thus limit the number to 65535, taking into account that we
* synthesize the metrics of glyph 0 to be a copy of the `default
* character', and that 0xFFFF in the encodings array indicates a
* missing glyph.
*/
if ( orig_nmetrics > 65534 )
{
FT_TRACE0(( "pcf_get_metrics:"
" only loading first 65536 metrics\n" ));
nmetrics = 65536;
" only loading first 65534 metrics\n" ));
nmetrics = 65534;
}
else
nmetrics = orig_nmetrics;
face->nmetrics = nmetrics;
face->nmetrics = nmetrics + 1;
if ( FT_NEW_ARRAY( face->metrics, nmetrics ) )
if ( FT_NEW_ARRAY( face->metrics, face->nmetrics ) )
return error;
metrics = face->metrics;
/* we handle glyph index 0 later on */
metrics = face->metrics + 1;
FT_TRACE4(( "\n" ));
for ( i = 0; i < nmetrics; i++, metrics++ )
for ( i = 1; i < face->nmetrics; i++, metrics++ )
{
FT_TRACE5(( " idx %ld:", i ));
error = pcf_get_metric( stream, format, metrics );
@ -808,12 +814,10 @@ THE SOFTWARE.
pcf_get_bitmaps( FT_Stream stream,
PCF_Face face )
{
FT_Error error;
FT_Memory memory = FT_FACE( face )->memory;
FT_ULong* offsets = NULL;
FT_ULong bitmapSizes[GLYPHPADOPTIONS];
FT_ULong format, size;
FT_ULong nbitmaps, orig_nbitmaps, i, sizebitmaps = 0;
FT_Error error;
FT_ULong bitmapSizes[GLYPHPADOPTIONS];
FT_ULong format, size, pos;
FT_ULong nbitmaps, orig_nbitmaps, i, sizebitmaps = 0;
error = pcf_seek_to_table_type( stream,
@ -859,31 +863,46 @@ THE SOFTWARE.
FT_TRACE4(( " number of bitmaps: %ld\n", orig_nbitmaps ));
/* see comment in `pcf_get_metrics' */
if ( orig_nbitmaps > 65536 )
if ( orig_nbitmaps > 65534 )
{
FT_TRACE0(( "pcf_get_bitmaps:"
" only loading first 65536 bitmaps\n" ));
nbitmaps = 65536;
" only loading first 65534 bitmaps\n" ));
nbitmaps = 65534;
}
else
nbitmaps = orig_nbitmaps;
if ( nbitmaps != face->nmetrics )
/* no extra bitmap for glyph 0 */
if ( nbitmaps != face->nmetrics - 1 )
return FT_THROW( Invalid_File_Format );
if ( FT_NEW_ARRAY( offsets, nbitmaps ) )
return error;
/* start position of bitmap data */
pos = stream->pos + nbitmaps * 4 + 4 * 4;
FT_TRACE5(( "\n" ));
for ( i = 0; i < nbitmaps; i++ )
for ( i = 1; i <= nbitmaps; i++ )
{
FT_ULong offset;
if ( PCF_BYTE_ORDER( format ) == MSBFirst )
(void)FT_READ_ULONG( offsets[i] );
(void)FT_READ_ULONG( offset );
else
(void)FT_READ_ULONG_LE( offsets[i] );
(void)FT_READ_ULONG_LE( offset );
FT_TRACE5(( " bitmap %lu: offset %lu (0x%lX)\n",
i, offsets[i], offsets[i] ));
i, offset, offset ));
/* right now, we only check the offset with a rough estimate; */
/* actual bitmaps are only loaded on demand */
if ( offset > size )
{
FT_TRACE0(( "pcf_get_bitmaps:"
" invalid offset to bitmap data of glyph %lu\n", i ));
face->metrics[i].bits = pos;
}
else
face->metrics[i].bits = pos + offset;
}
if ( error )
goto Bail;
@ -910,24 +929,9 @@ THE SOFTWARE.
FT_UNUSED( sizebitmaps ); /* only used for debugging */
/* right now, we only check the bitmap offsets; */
/* actual bitmaps are only loaded on demand */
for ( i = 0; i < nbitmaps; i++ )
{
/* rough estimate */
if ( offsets[i] > size )
{
FT_TRACE0(( "pcf_get_bitmaps:"
" invalid offset to bitmap data of glyph %lu\n", i ));
}
else
face->metrics[i].bits = stream->pos + offsets[i];
}
face->bitmapsFormat = format;
Bail:
FT_FREE( offsets );
return error;
}
@ -1062,41 +1066,52 @@ THE SOFTWARE.
defaultCharCol = enc->firstCol;
}
/* FreeType mandates that glyph index 0 is the `undefined glyph', */
/* which PCF calls the `default character'. For this reason, we */
/* swap the positions of glyph index 0 and the index corresponding */
/* to `defaultChar' in case they are different. */
/* `stream->cursor' still points at the beginning of the frame; */
/* we can thus easily get the offset to the default character */
/*
* FreeType mandates that glyph index 0 is the `undefined glyph', which
* PCF calls the `default character'. However, FreeType needs glyph
* index 0 to be used for the undefined glyph only, which is is not the
* case for PCF. For this reason, we add one slot for glyph index 0 and
* simply copy the default character to it.
*
* `stream->cursor' still points to the beginning of the frame; we can
* thus easily get the offset to the default character.
*/
pos = stream->cursor +
2 * ( ( defaultCharRow - enc->firstRow ) *
( enc->lastCol - enc->firstCol + 1 ) +
defaultCharCol - enc->firstCol );
( enc->lastCol - enc->firstCol + 1 ) +
defaultCharCol - enc->firstCol );
if ( PCF_BYTE_ORDER( format ) == MSBFirst )
defaultCharEncodingOffset = FT_PEEK_USHORT( pos );
else
defaultCharEncodingOffset = FT_PEEK_USHORT_LE( pos );
if ( defaultCharEncodingOffset >= face->nmetrics )
if ( defaultCharEncodingOffset == 0xFFFF )
{
FT_TRACE0(( "pcf_get_encodings:"
" Invalid glyph index for default character,"
" setting to zero\n" ));
defaultCharEncodingOffset = 0;
" No glyph for default character,\n"
" "
" setting it to the first glyph of the font\n" ));
defaultCharEncodingOffset = 1;
}
if ( defaultCharEncodingOffset )
else
{
/* do the swapping */
PCF_MetricRec tmp = face->metrics[defaultCharEncodingOffset];
defaultCharEncodingOffset++;
face->metrics[defaultCharEncodingOffset] = face->metrics[0];
face->metrics[0] = tmp;
if ( defaultCharEncodingOffset >= face->nmetrics )
{
FT_TRACE0(( "pcf_get_encodings:"
" Invalid glyph index for default character,\n"
" "
" setting it to the first glyph of the font\n" ));
defaultCharEncodingOffset = 1;
}
}
/* copy metrics of default character to index 0 */
face->metrics[0] = face->metrics[defaultCharEncodingOffset];
/* now loop over all values */
offset = enc->offset;
for ( i = enc->firstRow; i <= enc->lastRow; i++ )
{
@ -1111,15 +1126,9 @@ THE SOFTWARE.
else
encodingOffset = FT_GET_USHORT_LE();
if ( encodingOffset != 0xFFFFU )
{
if ( encodingOffset == defaultCharEncodingOffset )
encodingOffset = 0;
else if ( encodingOffset == 0 )
encodingOffset = defaultCharEncodingOffset;
}
*offset++ = encodingOffset;
/* everything is off by 1 due to the artificial glyph 0 */
*offset++ = encodingOffset == 0xFFFF ? 0xFFFF
: encodingOffset + 1;
}
}
FT_Stream_ExitFrame( stream );
@ -1303,9 +1312,8 @@ THE SOFTWARE.
PCF_Property prop;
size_t nn, len;
char* strings[4] = { NULL, NULL, NULL, NULL };
size_t lengths[4];
const char* strings[4] = { NULL, NULL, NULL, NULL };
size_t lengths[4], nn, len;
face->style_flags = 0;
@ -1317,8 +1325,8 @@ THE SOFTWARE.
{
face->style_flags |= FT_STYLE_FLAG_ITALIC;
strings[2] = ( *(prop->value.atom) == 'O' ||
*(prop->value.atom) == 'o' ) ? (char *)"Oblique"
: (char *)"Italic";
*(prop->value.atom) == 'o' ) ? "Oblique"
: "Italic";
}
prop = pcf_find_property( pcf, "WEIGHT_NAME" );
@ -1326,20 +1334,20 @@ THE SOFTWARE.
( *(prop->value.atom) == 'B' || *(prop->value.atom) == 'b' ) )
{
face->style_flags |= FT_STYLE_FLAG_BOLD;
strings[1] = (char*)"Bold";
strings[1] = "Bold";
}
prop = pcf_find_property( pcf, "SETWIDTH_NAME" );
if ( prop && prop->isString &&
*(prop->value.atom) &&
!( *(prop->value.atom) == 'N' || *(prop->value.atom) == 'n' ) )
strings[3] = (char*)( prop->value.atom );
strings[3] = (const char*)( prop->value.atom );
prop = pcf_find_property( pcf, "ADD_STYLE_NAME" );
if ( prop && prop->isString &&
*(prop->value.atom) &&
!( *(prop->value.atom) == 'N' || *(prop->value.atom) == 'n' ) )
strings[0] = (char*)( prop->value.atom );
strings[0] = (const char*)( prop->value.atom );
for ( len = 0, nn = 0; nn < 4; nn++ )
{
@ -1353,7 +1361,7 @@ THE SOFTWARE.
if ( len == 0 )
{
strings[0] = (char*)"Regular";
strings[0] = "Regular";
lengths[0] = ft_strlen( strings[0] );
len = lengths[0] + 1;
}
@ -1369,7 +1377,7 @@ THE SOFTWARE.
for ( nn = 0; nn < 4; nn++ )
{
char* src = strings[nn];
const char* src = strings[nn];
len = lengths[nn];

View file

@ -378,7 +378,7 @@
outline->flags &= ~FT_OUTLINE_OWNER;
outline->flags |= FT_OUTLINE_REVERSE_FILL;
if ( size && pfrsize->metrics.y_ppem < 24 )
if ( pfrsize->metrics.y_ppem < 24 )
outline->flags |= FT_OUTLINE_HIGH_PRECISION;
/* compute the advance vector */

View file

@ -953,7 +953,8 @@
error = afm_parse_kern_data( parser );
if ( error )
goto Fail;
/* fall through since we only support kern data */
/* we only support kern data, so ... */
/* fall through */
case AFM_TOKEN_ENDFONTMETRICS:
return FT_Err_Ok;

View file

@ -72,8 +72,7 @@ FT_BEGIN_HEADER
#define cf2_fixedFraction( x ) \
( (x) - cf2_fixedFloor( x ) )
#define cf2_fracToFixed( x ) \
( (x) < 0 ? -( ( -(x) + 0x2000 ) >> 14 ) \
: ( ( (x) + 0x2000 ) >> 14 ) )
( ( (x) + 0x2000 - ( (x) < 0 ) ) >> 14 )
/* signed numeric types */

View file

@ -274,9 +274,6 @@
if ( !font->isT1 )
{
FT_Service_CFFLoad cffload = (FT_Service_CFFLoad)font->cffload;
/* check for variation vectors */
vstore = cf2_getVStore( decoder );
hasVariations = ( vstore->dataCount != 0 );
@ -284,6 +281,9 @@
if ( hasVariations )
{
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
FT_Service_CFFLoad cffload = (FT_Service_CFFLoad)font->cffload;
/* check whether Private DICT in this subfont needs to be reparsed */
font->error = cf2_getNormalizedVector( decoder,
&lenNormalizedV,

View file

@ -174,10 +174,10 @@
* reallocation fails.
*/
FT_LOCAL_DEF( FT_Error )
ps_table_add( PS_Table table,
FT_Int idx,
void* object,
FT_UInt length )
ps_table_add( PS_Table table,
FT_Int idx,
const void* object,
FT_UInt length )
{
if ( idx < 0 || idx >= table->max_elems )
{

View file

@ -53,10 +53,10 @@ FT_BEGIN_HEADER
FT_Memory memory );
FT_LOCAL( FT_Error )
ps_table_add( PS_Table table,
FT_Int idx,
void* object,
FT_UInt length );
ps_table_add( PS_Table table,
FT_Int idx,
const void* object,
FT_UInt length );
FT_LOCAL( void )
ps_table_done( PS_Table table );

View file

@ -399,7 +399,7 @@
#define RAS_ARGS /* void */
#define RAS_ARG /* void */
#define RAS_ARG void
#define RAS_VARS /* void */
#define RAS_VAR /* void */
@ -546,8 +546,7 @@
#ifdef FT_STATIC_RASTER
static black_TWorker cur_ras;
#define ras cur_ras
static black_TWorker ras;
#else /* !FT_STATIC_RASTER */
@ -661,7 +660,6 @@
return FAILURE;
}
ras.cProfile->flags = 0;
ras.cProfile->start = 0;
ras.cProfile->height = 0;
ras.cProfile->offset = ras.top;
@ -914,16 +912,18 @@
base[4].x = base[2].x;
b = base[1].x;
a = base[3].x = ( base[2].x + b ) / 2;
b = base[1].x = ( base[0].x + b ) / 2;
base[2].x = ( a + b ) / 2;
a = base[0].x + base[1].x;
b = base[1].x + base[2].x;
base[3].x = b >> 1;
base[2].x = ( a + b ) >> 2;
base[1].x = a >> 1;
base[4].y = base[2].y;
b = base[1].y;
a = base[3].y = ( base[2].y + b ) / 2;
b = base[1].y = ( base[0].y + b ) / 2;
base[2].y = ( a + b ) / 2;
a = base[0].y + base[1].y;
b = base[1].y + base[2].y;
base[3].y = b >> 1;
base[2].y = ( a + b ) >> 2;
base[1].y = a >> 1;
/* hand optimized. gcc doesn't seem to be too good at common */
/* expression substitution and instruction scheduling ;-) */
@ -947,28 +947,32 @@
static void
Split_Cubic( TPoint* base )
{
Long a, b, c, d;
Long a, b, c;
base[6].x = base[3].x;
c = base[1].x;
d = base[2].x;
base[1].x = a = ( base[0].x + c + 1 ) >> 1;
base[5].x = b = ( base[3].x + d + 1 ) >> 1;
c = ( c + d + 1 ) >> 1;
base[2].x = a = ( a + c + 1 ) >> 1;
base[4].x = b = ( b + c + 1 ) >> 1;
base[3].x = ( a + b + 1 ) >> 1;
a = base[0].x + base[1].x;
b = base[1].x + base[2].x;
c = base[2].x + base[3].x;
base[5].x = c >> 1;
c += b;
base[4].x = c >> 2;
base[1].x = a >> 1;
a += b;
base[2].x = a >> 2;
base[3].x = ( a + c ) >> 3;
base[6].y = base[3].y;
c = base[1].y;
d = base[2].y;
base[1].y = a = ( base[0].y + c + 1 ) >> 1;
base[5].y = b = ( base[3].y + d + 1 ) >> 1;
c = ( c + d + 1 ) >> 1;
base[2].y = a = ( a + c + 1 ) >> 1;
base[4].y = b = ( b + c + 1 ) >> 1;
base[3].y = ( a + b + 1 ) >> 1;
a = base[0].y + base[1].y;
b = base[1].y + base[2].y;
c = base[2].y + base[3].y;
base[5].y = c >> 1;
c += b;
base[4].y = c >> 2;
base[1].y = a >> 1;
a += b;
base[2].y = a >> 2;
base[3].y = ( a + c ) >> 3;
}
@ -2784,7 +2788,7 @@
P_Left = draw_left;
P_Right = draw_right;
while ( P_Left )
while ( P_Left && P_Right )
{
x1 = P_Left ->X;
x2 = P_Right->X;
@ -2885,7 +2889,7 @@
P_Left = draw_left;
P_Right = draw_right;
while ( P_Left )
while ( P_Left && P_Right )
{
if ( P_Left->countL )
{
@ -3257,7 +3261,9 @@
const FT_Outline* outline = (const FT_Outline*)params->source;
const FT_Bitmap* target_map = params->target;
#ifndef FT_STATIC_RASTER
black_TWorker worker[1];
#endif
Long buffer[FT_MAX_BLACK_POOL];
@ -3299,8 +3305,8 @@
ras.outline = *outline;
ras.target = *target_map;
worker->buff = buffer;
worker->sizeBuff = (&buffer)[1]; /* Points to right after buffer. */
ras.buff = buffer;
ras.sizeBuff = (&buffer)[1]; /* Points to right after buffer. */
return Render_Glyph( RAS_VAR );
}

View file

@ -31,6 +31,7 @@ SFNT_COMPILE := $(CC) $(ANSIFLAGS) \
SFNT_DRV_SRC := $(SFNT_DIR)/pngshim.c \
$(SFNT_DIR)/sfdriver.c \
$(SFNT_DIR)/sfobjs.c \
$(SFNT_DIR)/sfwoff.c \
$(SFNT_DIR)/ttbdf.c \
$(SFNT_DIR)/ttcmap.c \
$(SFNT_DIR)/ttcolr.c \

View file

@ -182,8 +182,8 @@
static FT_UInt
sfnt_get_name_index( FT_Face face,
FT_String* glyph_name )
sfnt_get_name_index( FT_Face face,
const FT_String* glyph_name )
{
TT_Face ttface = (TT_Face)face;
@ -375,47 +375,61 @@
{
case 15:
k4 ^= (FT_UInt32)tail[14] << 16;
/* fall through */
case 14:
k4 ^= (FT_UInt32)tail[13] << 8;
/* fall through */
case 13:
k4 ^= (FT_UInt32)tail[12];
k4 *= c4;
k4 = ROTL32( k4, 18 );
k4 *= c1;
h4 ^= k4;
/* fall through */
case 12:
k3 ^= (FT_UInt32)tail[11] << 24;
/* fall through */
case 11:
k3 ^= (FT_UInt32)tail[10] << 16;
/* fall through */
case 10:
k3 ^= (FT_UInt32)tail[9] << 8;
/* fall through */
case 9:
k3 ^= (FT_UInt32)tail[8];
k3 *= c3;
k3 = ROTL32( k3, 17 );
k3 *= c4;
h3 ^= k3;
/* fall through */
case 8:
k2 ^= (FT_UInt32)tail[7] << 24;
/* fall through */
case 7:
k2 ^= (FT_UInt32)tail[6] << 16;
/* fall through */
case 6:
k2 ^= (FT_UInt32)tail[5] << 8;
/* fall through */
case 5:
k2 ^= (FT_UInt32)tail[4];
k2 *= c2;
k2 = ROTL32( k2, 16 );
k2 *= c3;
h2 ^= k2;
/* fall through */
case 4:
k1 ^= (FT_UInt32)tail[3] << 24;
/* fall through */
case 3:
k1 ^= (FT_UInt32)tail[2] << 16;
/* fall through */
case 2:
k1 ^= (FT_UInt32)tail[1] << 8;
/* fall through */
case 1:
k1 ^= (FT_UInt32)tail[0];
k1 *= c1;

View file

@ -22,6 +22,7 @@
#include "pngshim.c"
#include "sfdriver.c"
#include "sfobjs.c"
#include "sfwoff.c"
#include "ttbdf.c"
#include "ttcmap.c"
#include "ttcolr.c"

View file

@ -21,13 +21,13 @@
#include "ttload.h"
#include "ttcmap.h"
#include "ttkern.h"
#include "sfwoff.h"
#include FT_INTERNAL_SFNT_H
#include FT_INTERNAL_DEBUG_H
#include FT_TRUETYPE_IDS_H
#include FT_TRUETYPE_TAGS_H
#include FT_SERVICE_POSTSCRIPT_CMAPS_H
#include FT_SFNT_NAMES_H
#include FT_GZIP_H
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
#include FT_SERVICE_MULTIPLE_MASTERS_H
@ -337,403 +337,6 @@
}
#define WRITE_USHORT( p, v ) \
do \
{ \
*(p)++ = (FT_Byte)( (v) >> 8 ); \
*(p)++ = (FT_Byte)( (v) >> 0 ); \
\
} while ( 0 )
#define WRITE_ULONG( p, v ) \
do \
{ \
*(p)++ = (FT_Byte)( (v) >> 24 ); \
*(p)++ = (FT_Byte)( (v) >> 16 ); \
*(p)++ = (FT_Byte)( (v) >> 8 ); \
*(p)++ = (FT_Byte)( (v) >> 0 ); \
\
} while ( 0 )
static void
sfnt_stream_close( FT_Stream stream )
{
FT_Memory memory = stream->memory;
FT_FREE( stream->base );
stream->size = 0;
stream->base = NULL;
stream->close = NULL;
}
FT_CALLBACK_DEF( int )
compare_offsets( const void* a,
const void* b )
{
WOFF_Table table1 = *(WOFF_Table*)a;
WOFF_Table table2 = *(WOFF_Table*)b;
FT_ULong offset1 = table1->Offset;
FT_ULong offset2 = table2->Offset;
if ( offset1 > offset2 )
return 1;
else if ( offset1 < offset2 )
return -1;
else
return 0;
}
/* Replace `face->root.stream' with a stream containing the extracted */
/* SFNT of a WOFF font. */
static FT_Error
woff_open_font( FT_Stream stream,
TT_Face face )
{
FT_Memory memory = stream->memory;
FT_Error error = FT_Err_Ok;
WOFF_HeaderRec woff;
WOFF_Table tables = NULL;
WOFF_Table* indices = NULL;
FT_ULong woff_offset;
FT_Byte* sfnt = NULL;
FT_Stream sfnt_stream = NULL;
FT_Byte* sfnt_header;
FT_ULong sfnt_offset;
FT_Int nn;
FT_ULong old_tag = 0;
static const FT_Frame_Field woff_header_fields[] =
{
#undef FT_STRUCTURE
#define FT_STRUCTURE WOFF_HeaderRec
FT_FRAME_START( 44 ),
FT_FRAME_ULONG ( signature ),
FT_FRAME_ULONG ( flavor ),
FT_FRAME_ULONG ( length ),
FT_FRAME_USHORT( num_tables ),
FT_FRAME_USHORT( reserved ),
FT_FRAME_ULONG ( totalSfntSize ),
FT_FRAME_USHORT( majorVersion ),
FT_FRAME_USHORT( minorVersion ),
FT_FRAME_ULONG ( metaOffset ),
FT_FRAME_ULONG ( metaLength ),
FT_FRAME_ULONG ( metaOrigLength ),
FT_FRAME_ULONG ( privOffset ),
FT_FRAME_ULONG ( privLength ),
FT_FRAME_END
};
FT_ASSERT( stream == face->root.stream );
FT_ASSERT( FT_STREAM_POS() == 0 );
if ( FT_STREAM_READ_FIELDS( woff_header_fields, &woff ) )
return error;
/* Make sure we don't recurse back here or hit TTC code. */
if ( woff.flavor == TTAG_wOFF || woff.flavor == TTAG_ttcf )
return FT_THROW( Invalid_Table );
/* Miscellaneous checks. */
if ( woff.length != stream->size ||
woff.num_tables == 0 ||
44 + woff.num_tables * 20UL >= woff.length ||
12 + woff.num_tables * 16UL >= woff.totalSfntSize ||
( woff.totalSfntSize & 3 ) != 0 ||
( woff.metaOffset == 0 && ( woff.metaLength != 0 ||
woff.metaOrigLength != 0 ) ) ||
( woff.metaLength != 0 && woff.metaOrigLength == 0 ) ||
( woff.privOffset == 0 && woff.privLength != 0 ) )
{
FT_ERROR(( "woff_font_open: invalid WOFF header\n" ));
return FT_THROW( Invalid_Table );
}
/* Don't trust `totalSfntSize' before thorough checks. */
if ( FT_ALLOC( sfnt, 12 + woff.num_tables * 16UL ) ||
FT_NEW( sfnt_stream ) )
goto Exit;
sfnt_header = sfnt;
/* Write sfnt header. */
{
FT_UInt searchRange, entrySelector, rangeShift, x;
x = woff.num_tables;
entrySelector = 0;
while ( x )
{
x >>= 1;
entrySelector += 1;
}
entrySelector--;
searchRange = ( 1 << entrySelector ) * 16;
rangeShift = woff.num_tables * 16 - searchRange;
WRITE_ULONG ( sfnt_header, woff.flavor );
WRITE_USHORT( sfnt_header, woff.num_tables );
WRITE_USHORT( sfnt_header, searchRange );
WRITE_USHORT( sfnt_header, entrySelector );
WRITE_USHORT( sfnt_header, rangeShift );
}
/* While the entries in the sfnt header must be sorted by the */
/* tag value, the tables themselves are not. We thus have to */
/* sort them by offset and check that they don't overlap. */
if ( FT_NEW_ARRAY( tables, woff.num_tables ) ||
FT_NEW_ARRAY( indices, woff.num_tables ) )
goto Exit;
FT_TRACE2(( "\n"
" tag offset compLen origLen checksum\n"
" -------------------------------------------\n" ));
if ( FT_FRAME_ENTER( 20L * woff.num_tables ) )
goto Exit;
for ( nn = 0; nn < woff.num_tables; nn++ )
{
WOFF_Table table = tables + nn;
table->Tag = FT_GET_TAG4();
table->Offset = FT_GET_ULONG();
table->CompLength = FT_GET_ULONG();
table->OrigLength = FT_GET_ULONG();
table->CheckSum = FT_GET_ULONG();
FT_TRACE2(( " %c%c%c%c %08lx %08lx %08lx %08lx\n",
(FT_Char)( table->Tag >> 24 ),
(FT_Char)( table->Tag >> 16 ),
(FT_Char)( table->Tag >> 8 ),
(FT_Char)( table->Tag ),
table->Offset,
table->CompLength,
table->OrigLength,
table->CheckSum ));
if ( table->Tag <= old_tag )
{
FT_FRAME_EXIT();
FT_ERROR(( "woff_font_open: table tags are not sorted\n" ));
error = FT_THROW( Invalid_Table );
goto Exit;
}
old_tag = table->Tag;
indices[nn] = table;
}
FT_FRAME_EXIT();
/* Sort by offset. */
ft_qsort( indices,
woff.num_tables,
sizeof ( WOFF_Table ),
compare_offsets );
/* Check offsets and lengths. */
woff_offset = 44 + woff.num_tables * 20L;
sfnt_offset = 12 + woff.num_tables * 16L;
for ( nn = 0; nn < woff.num_tables; nn++ )
{
WOFF_Table table = indices[nn];
if ( table->Offset != woff_offset ||
table->CompLength > woff.length ||
table->Offset > woff.length - table->CompLength ||
table->OrigLength > woff.totalSfntSize ||
sfnt_offset > woff.totalSfntSize - table->OrigLength ||
table->CompLength > table->OrigLength )
{
FT_ERROR(( "woff_font_open: invalid table offsets\n" ));
error = FT_THROW( Invalid_Table );
goto Exit;
}
table->OrigOffset = sfnt_offset;
/* The offsets must be multiples of 4. */
woff_offset += ( table->CompLength + 3 ) & ~3U;
sfnt_offset += ( table->OrigLength + 3 ) & ~3U;
}
/*
* Final checks!
*
* We don't decode and check the metadata block.
* We don't check table checksums either.
* But other than those, I think we implement all
* `MUST' checks from the spec.
*/
if ( woff.metaOffset )
{
if ( woff.metaOffset != woff_offset ||
woff.metaOffset + woff.metaLength > woff.length )
{
FT_ERROR(( "woff_font_open:"
" invalid `metadata' offset or length\n" ));
error = FT_THROW( Invalid_Table );
goto Exit;
}
/* We have padding only ... */
woff_offset += woff.metaLength;
}
if ( woff.privOffset )
{
/* ... if it isn't the last block. */
woff_offset = ( woff_offset + 3 ) & ~3U;
if ( woff.privOffset != woff_offset ||
woff.privOffset + woff.privLength > woff.length )
{
FT_ERROR(( "woff_font_open: invalid `private' offset or length\n" ));
error = FT_THROW( Invalid_Table );
goto Exit;
}
/* No padding for the last block. */
woff_offset += woff.privLength;
}
if ( sfnt_offset != woff.totalSfntSize ||
woff_offset != woff.length )
{
FT_ERROR(( "woff_font_open: invalid `sfnt' table structure\n" ));
error = FT_THROW( Invalid_Table );
goto Exit;
}
/* Now use `totalSfntSize'. */
if ( FT_REALLOC( sfnt,
12 + woff.num_tables * 16UL,
woff.totalSfntSize ) )
goto Exit;
sfnt_header = sfnt + 12;
/* Write the tables. */
for ( nn = 0; nn < woff.num_tables; nn++ )
{
WOFF_Table table = tables + nn;
/* Write SFNT table entry. */
WRITE_ULONG( sfnt_header, table->Tag );
WRITE_ULONG( sfnt_header, table->CheckSum );
WRITE_ULONG( sfnt_header, table->OrigOffset );
WRITE_ULONG( sfnt_header, table->OrigLength );
/* Write table data. */
if ( FT_STREAM_SEEK( table->Offset ) ||
FT_FRAME_ENTER( table->CompLength ) )
goto Exit;
if ( table->CompLength == table->OrigLength )
{
/* Uncompressed data; just copy. */
ft_memcpy( sfnt + table->OrigOffset,
stream->cursor,
table->OrigLength );
}
else
{
#ifdef FT_CONFIG_OPTION_USE_ZLIB
/* Uncompress with zlib. */
FT_ULong output_len = table->OrigLength;
error = FT_Gzip_Uncompress( memory,
sfnt + table->OrigOffset, &output_len,
stream->cursor, table->CompLength );
if ( error )
goto Exit;
if ( output_len != table->OrigLength )
{
FT_ERROR(( "woff_font_open: compressed table length mismatch\n" ));
error = FT_THROW( Invalid_Table );
goto Exit;
}
#else /* !FT_CONFIG_OPTION_USE_ZLIB */
error = FT_THROW( Unimplemented_Feature );
goto Exit;
#endif /* !FT_CONFIG_OPTION_USE_ZLIB */
}
FT_FRAME_EXIT();
/* We don't check whether the padding bytes in the WOFF file are */
/* actually '\0'. For the output, however, we do set them properly. */
sfnt_offset = table->OrigOffset + table->OrigLength;
while ( sfnt_offset & 3 )
{
sfnt[sfnt_offset] = '\0';
sfnt_offset++;
}
}
/* Ok! Finally ready. Swap out stream and return. */
FT_Stream_OpenMemory( sfnt_stream, sfnt, woff.totalSfntSize );
sfnt_stream->memory = stream->memory;
sfnt_stream->close = sfnt_stream_close;
FT_Stream_Free(
face->root.stream,
( face->root.face_flags & FT_FACE_FLAG_EXTERNAL_STREAM ) != 0 );
face->root.stream = sfnt_stream;
face->root.face_flags &= ~FT_FACE_FLAG_EXTERNAL_STREAM;
Exit:
FT_FREE( tables );
FT_FREE( indices );
if ( error )
{
FT_FREE( sfnt );
FT_Stream_Close( sfnt_stream );
FT_FREE( sfnt_stream );
}
return error;
}
#undef WRITE_USHORT
#undef WRITE_ULONG
/* Fill in face->ttc_header. If the font is not a TTC, it is */
/* synthesized into a TTC with one offset table. */
static FT_Error

View file

@ -53,7 +53,7 @@ FT_BEGIN_HEADER
FT_END_HEADER
#endif /* SFDRIVER_H_ */
#endif /* SFOBJS_H_ */
/* END */

434
thirdparty/freetype/src/sfnt/sfwoff.c vendored Normal file
View file

@ -0,0 +1,434 @@
/****************************************************************************
*
* sfwoff.c
*
* WOFF format management (base).
*
* Copyright (C) 1996-2019 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 "sfwoff.h"
#include FT_TRUETYPE_TAGS_H
#include FT_INTERNAL_DEBUG_H
#include FT_INTERNAL_STREAM_H
#include FT_GZIP_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 sfwoff
#define WRITE_USHORT( p, v ) \
do \
{ \
*(p)++ = (FT_Byte)( (v) >> 8 ); \
*(p)++ = (FT_Byte)( (v) >> 0 ); \
\
} while ( 0 )
#define WRITE_ULONG( p, v ) \
do \
{ \
*(p)++ = (FT_Byte)( (v) >> 24 ); \
*(p)++ = (FT_Byte)( (v) >> 16 ); \
*(p)++ = (FT_Byte)( (v) >> 8 ); \
*(p)++ = (FT_Byte)( (v) >> 0 ); \
\
} while ( 0 )
static void
sfnt_stream_close( FT_Stream stream )
{
FT_Memory memory = stream->memory;
FT_FREE( stream->base );
stream->size = 0;
stream->base = NULL;
stream->close = NULL;
}
FT_CALLBACK_DEF( int )
compare_offsets( const void* a,
const void* b )
{
WOFF_Table table1 = *(WOFF_Table*)a;
WOFF_Table table2 = *(WOFF_Table*)b;
FT_ULong offset1 = table1->Offset;
FT_ULong offset2 = table2->Offset;
if ( offset1 > offset2 )
return 1;
else if ( offset1 < offset2 )
return -1;
else
return 0;
}
/* Replace `face->root.stream' with a stream containing the extracted */
/* SFNT of a WOFF font. */
FT_LOCAL_DEF( FT_Error )
woff_open_font( FT_Stream stream,
TT_Face face )
{
FT_Memory memory = stream->memory;
FT_Error error = FT_Err_Ok;
WOFF_HeaderRec woff;
WOFF_Table tables = NULL;
WOFF_Table* indices = NULL;
FT_ULong woff_offset;
FT_Byte* sfnt = NULL;
FT_Stream sfnt_stream = NULL;
FT_Byte* sfnt_header;
FT_ULong sfnt_offset;
FT_Int nn;
FT_ULong old_tag = 0;
static const FT_Frame_Field woff_header_fields[] =
{
#undef FT_STRUCTURE
#define FT_STRUCTURE WOFF_HeaderRec
FT_FRAME_START( 44 ),
FT_FRAME_ULONG ( signature ),
FT_FRAME_ULONG ( flavor ),
FT_FRAME_ULONG ( length ),
FT_FRAME_USHORT( num_tables ),
FT_FRAME_USHORT( reserved ),
FT_FRAME_ULONG ( totalSfntSize ),
FT_FRAME_USHORT( majorVersion ),
FT_FRAME_USHORT( minorVersion ),
FT_FRAME_ULONG ( metaOffset ),
FT_FRAME_ULONG ( metaLength ),
FT_FRAME_ULONG ( metaOrigLength ),
FT_FRAME_ULONG ( privOffset ),
FT_FRAME_ULONG ( privLength ),
FT_FRAME_END
};
FT_ASSERT( stream == face->root.stream );
FT_ASSERT( FT_STREAM_POS() == 0 );
if ( FT_STREAM_READ_FIELDS( woff_header_fields, &woff ) )
return error;
/* Make sure we don't recurse back here or hit TTC code. */
if ( woff.flavor == TTAG_wOFF || woff.flavor == TTAG_ttcf )
return FT_THROW( Invalid_Table );
/* Miscellaneous checks. */
if ( woff.length != stream->size ||
woff.num_tables == 0 ||
44 + woff.num_tables * 20UL >= woff.length ||
12 + woff.num_tables * 16UL >= woff.totalSfntSize ||
( woff.totalSfntSize & 3 ) != 0 ||
( woff.metaOffset == 0 && ( woff.metaLength != 0 ||
woff.metaOrigLength != 0 ) ) ||
( woff.metaLength != 0 && woff.metaOrigLength == 0 ) ||
( woff.privOffset == 0 && woff.privLength != 0 ) )
{
FT_ERROR(( "woff_font_open: invalid WOFF header\n" ));
return FT_THROW( Invalid_Table );
}
/* Don't trust `totalSfntSize' before thorough checks. */
if ( FT_ALLOC( sfnt, 12 + woff.num_tables * 16UL ) ||
FT_NEW( sfnt_stream ) )
goto Exit;
sfnt_header = sfnt;
/* Write sfnt header. */
{
FT_UInt searchRange, entrySelector, rangeShift, x;
x = woff.num_tables;
entrySelector = 0;
while ( x )
{
x >>= 1;
entrySelector += 1;
}
entrySelector--;
searchRange = ( 1 << entrySelector ) * 16;
rangeShift = woff.num_tables * 16 - searchRange;
WRITE_ULONG ( sfnt_header, woff.flavor );
WRITE_USHORT( sfnt_header, woff.num_tables );
WRITE_USHORT( sfnt_header, searchRange );
WRITE_USHORT( sfnt_header, entrySelector );
WRITE_USHORT( sfnt_header, rangeShift );
}
/* While the entries in the sfnt header must be sorted by the */
/* tag value, the tables themselves are not. We thus have to */
/* sort them by offset and check that they don't overlap. */
if ( FT_NEW_ARRAY( tables, woff.num_tables ) ||
FT_NEW_ARRAY( indices, woff.num_tables ) )
goto Exit;
FT_TRACE2(( "\n"
" tag offset compLen origLen checksum\n"
" -------------------------------------------\n" ));
if ( FT_FRAME_ENTER( 20L * woff.num_tables ) )
goto Exit;
for ( nn = 0; nn < woff.num_tables; nn++ )
{
WOFF_Table table = tables + nn;
table->Tag = FT_GET_TAG4();
table->Offset = FT_GET_ULONG();
table->CompLength = FT_GET_ULONG();
table->OrigLength = FT_GET_ULONG();
table->CheckSum = FT_GET_ULONG();
FT_TRACE2(( " %c%c%c%c %08lx %08lx %08lx %08lx\n",
(FT_Char)( table->Tag >> 24 ),
(FT_Char)( table->Tag >> 16 ),
(FT_Char)( table->Tag >> 8 ),
(FT_Char)( table->Tag ),
table->Offset,
table->CompLength,
table->OrigLength,
table->CheckSum ));
if ( table->Tag <= old_tag )
{
FT_FRAME_EXIT();
FT_ERROR(( "woff_font_open: table tags are not sorted\n" ));
error = FT_THROW( Invalid_Table );
goto Exit;
}
old_tag = table->Tag;
indices[nn] = table;
}
FT_FRAME_EXIT();
/* Sort by offset. */
ft_qsort( indices,
woff.num_tables,
sizeof ( WOFF_Table ),
compare_offsets );
/* Check offsets and lengths. */
woff_offset = 44 + woff.num_tables * 20L;
sfnt_offset = 12 + woff.num_tables * 16L;
for ( nn = 0; nn < woff.num_tables; nn++ )
{
WOFF_Table table = indices[nn];
if ( table->Offset != woff_offset ||
table->CompLength > woff.length ||
table->Offset > woff.length - table->CompLength ||
table->OrigLength > woff.totalSfntSize ||
sfnt_offset > woff.totalSfntSize - table->OrigLength ||
table->CompLength > table->OrigLength )
{
FT_ERROR(( "woff_font_open: invalid table offsets\n" ));
error = FT_THROW( Invalid_Table );
goto Exit;
}
table->OrigOffset = sfnt_offset;
/* The offsets must be multiples of 4. */
woff_offset += ( table->CompLength + 3 ) & ~3U;
sfnt_offset += ( table->OrigLength + 3 ) & ~3U;
}
/*
* Final checks!
*
* We don't decode and check the metadata block.
* We don't check table checksums either.
* But other than those, I think we implement all
* `MUST' checks from the spec.
*/
if ( woff.metaOffset )
{
if ( woff.metaOffset != woff_offset ||
woff.metaOffset + woff.metaLength > woff.length )
{
FT_ERROR(( "woff_font_open:"
" invalid `metadata' offset or length\n" ));
error = FT_THROW( Invalid_Table );
goto Exit;
}
/* We have padding only ... */
woff_offset += woff.metaLength;
}
if ( woff.privOffset )
{
/* ... if it isn't the last block. */
woff_offset = ( woff_offset + 3 ) & ~3U;
if ( woff.privOffset != woff_offset ||
woff.privOffset + woff.privLength > woff.length )
{
FT_ERROR(( "woff_font_open: invalid `private' offset or length\n" ));
error = FT_THROW( Invalid_Table );
goto Exit;
}
/* No padding for the last block. */
woff_offset += woff.privLength;
}
if ( sfnt_offset != woff.totalSfntSize ||
woff_offset != woff.length )
{
FT_ERROR(( "woff_font_open: invalid `sfnt' table structure\n" ));
error = FT_THROW( Invalid_Table );
goto Exit;
}
/* Now use `totalSfntSize'. */
if ( FT_REALLOC( sfnt,
12 + woff.num_tables * 16UL,
woff.totalSfntSize ) )
goto Exit;
sfnt_header = sfnt + 12;
/* Write the tables. */
for ( nn = 0; nn < woff.num_tables; nn++ )
{
WOFF_Table table = tables + nn;
/* Write SFNT table entry. */
WRITE_ULONG( sfnt_header, table->Tag );
WRITE_ULONG( sfnt_header, table->CheckSum );
WRITE_ULONG( sfnt_header, table->OrigOffset );
WRITE_ULONG( sfnt_header, table->OrigLength );
/* Write table data. */
if ( FT_STREAM_SEEK( table->Offset ) ||
FT_FRAME_ENTER( table->CompLength ) )
goto Exit;
if ( table->CompLength == table->OrigLength )
{
/* Uncompressed data; just copy. */
ft_memcpy( sfnt + table->OrigOffset,
stream->cursor,
table->OrigLength );
}
else
{
#ifdef FT_CONFIG_OPTION_USE_ZLIB
/* Uncompress with zlib. */
FT_ULong output_len = table->OrigLength;
error = FT_Gzip_Uncompress( memory,
sfnt + table->OrigOffset, &output_len,
stream->cursor, table->CompLength );
if ( error )
goto Exit;
if ( output_len != table->OrigLength )
{
FT_ERROR(( "woff_font_open: compressed table length mismatch\n" ));
error = FT_THROW( Invalid_Table );
goto Exit;
}
#else /* !FT_CONFIG_OPTION_USE_ZLIB */
error = FT_THROW( Unimplemented_Feature );
goto Exit;
#endif /* !FT_CONFIG_OPTION_USE_ZLIB */
}
FT_FRAME_EXIT();
/* We don't check whether the padding bytes in the WOFF file are */
/* actually '\0'. For the output, however, we do set them properly. */
sfnt_offset = table->OrigOffset + table->OrigLength;
while ( sfnt_offset & 3 )
{
sfnt[sfnt_offset] = '\0';
sfnt_offset++;
}
}
/* Ok! Finally ready. Swap out stream and return. */
FT_Stream_OpenMemory( sfnt_stream, sfnt, woff.totalSfntSize );
sfnt_stream->memory = stream->memory;
sfnt_stream->close = sfnt_stream_close;
FT_Stream_Free(
face->root.stream,
( face->root.face_flags & FT_FACE_FLAG_EXTERNAL_STREAM ) != 0 );
face->root.stream = sfnt_stream;
face->root.face_flags &= ~FT_FACE_FLAG_EXTERNAL_STREAM;
Exit:
FT_FREE( tables );
FT_FREE( indices );
if ( error )
{
FT_FREE( sfnt );
FT_Stream_Close( sfnt_stream );
FT_FREE( sfnt_stream );
}
return error;
}
#undef WRITE_USHORT
#undef WRITE_ULONG
/* END */

41
thirdparty/freetype/src/sfnt/sfwoff.h vendored Normal file
View file

@ -0,0 +1,41 @@
/****************************************************************************
*
* sfwoff.h
*
* WOFFF format management (specification).
*
* Copyright (C) 1996-2019 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.
*
*/
#ifndef SFWOFF_H_
#define SFWOFF_H_
#include <ft2build.h>
#include FT_INTERNAL_SFNT_H
#include FT_INTERNAL_OBJECTS_H
FT_BEGIN_HEADER
FT_LOCAL( FT_Error )
woff_open_font( FT_Stream stream,
TT_Face face );
FT_END_HEADER
#endif /* SFWOFF_H_ */
/* END */

View file

@ -2368,10 +2368,7 @@
/* if `gindex' is invalid, the remaining values */
/* in this group are invalid, too */
if ( gindex >= (FT_UInt)face->num_glyphs )
{
gindex = 0;
continue;
}
cmap->cur_charcode = char_code;
cmap->cur_gindex = gindex;
@ -3661,7 +3658,7 @@
tt_get_glyph_name( TT_Face face,
FT_UInt idx )
{
FT_String* PSname;
FT_String* PSname = NULL;
tt_face_get_ps_name( face, idx, &PSname );

View file

@ -280,7 +280,7 @@
else
{
table_pos += 4 * ( k - 1 );
if ( table_pos + 4 > table_end )
if ( table_pos + 2 > table_end )
goto NoData;
if ( FT_STREAM_SEEK( table_pos ) ||
@ -292,7 +292,9 @@
*abearing = 0;
else
{
if ( !FT_STREAM_SEEK( table_pos ) )
if ( FT_STREAM_SEEK( table_pos ) )
*abearing = 0;
else
(void)FT_READ_SHORT( *abearing );
}
}

View file

@ -45,7 +45,7 @@
* This is a new anti-aliasing scan-converter for FreeType 2. The
* algorithm used here is _very_ different from the one in the standard
* `ftraster' module. Actually, `ftgrays' computes the _exact_
* coverage of the outline on each pixel cell.
* coverage of the outline on each pixel cell by straight segments.
*
* It is based on ideas that I initially found in Raph Levien's
* excellent LibArt graphics library (see https://www.levien.com/libart
@ -58,6 +58,14 @@
* different way, and I don't use sorted vector paths. Also, it doesn't
* use floating point values.
*
* Bézier segments are flattened by splitting them until their deviation
* from straight line becomes much smaller than a pixel. Therefore, the
* pixel coverage by a Bézier curve is calculated approximately. To
* estimate the deviation, we use the distance from the control point
* to the conic chord centre or the cubic chord trisection. These
* distances vanish fast after each split. In the conic case, they vanish
* predictably and the number of necessary splits can be calculated.
*
* This renderer has the following advantages:
*
* - It doesn't need an intermediate bitmap. Instead, one can supply a
@ -67,7 +75,7 @@
* callback.
*
* - A perfect anti-aliaser, i.e., it computes the _exact_ coverage on
* each pixel cell.
* each pixel cell by straight segments.
*
* - It performs a single pass on the outline (the `standard' FT2
* renderer makes two passes).
@ -75,7 +83,7 @@
* - It can easily be modified to render to _any_ number of gray levels
* cheaply.
*
* - For small (< 20) pixel sizes, it is faster than the standard
* - For small (< 80) pixel sizes, it is faster than the standard
* renderer.
*
*/
@ -327,17 +335,9 @@ typedef ptrdiff_t FT_PtrDist;
/* must be at least 6 bits! */
#define PIXEL_BITS 8
#undef FLOOR
#undef CEILING
#undef TRUNC
#undef SCALED
#define ONE_PIXEL ( 1 << PIXEL_BITS )
#define TRUNC( x ) ( (TCoord)( (x) >> PIXEL_BITS ) )
#define SUBPIXELS( x ) ( (TPos)(x) * ONE_PIXEL )
#define FLOOR( x ) ( (x) & -ONE_PIXEL )
#define CEILING( x ) ( ( (x) + ONE_PIXEL - 1 ) & -ONE_PIXEL )
#define ROUND( x ) ( ( (x) + ONE_PIXEL / 2 ) & -ONE_PIXEL )
#define TRUNC( x ) (TCoord)( (x) >> PIXEL_BITS )
#define FRACT( x ) (TCoord)( (x) & ( ONE_PIXEL - 1 ) )
#if PIXEL_BITS >= 6
#define UPSCALE( x ) ( (x) * ( ONE_PIXEL >> 6 ) )
@ -388,9 +388,9 @@ typedef ptrdiff_t FT_PtrDist;
#define FT_UDIVPREP( c, b ) \
long b ## _r = c ? (long)( FT_ULONG_MAX >> PIXEL_BITS ) / ( b ) \
: 0
#define FT_UDIV( a, b ) \
( ( (unsigned long)( a ) * (unsigned long)( b ## _r ) ) >> \
( sizeof( long ) * FT_CHAR_BIT - PIXEL_BITS ) )
#define FT_UDIV( a, b ) \
(TCoord)( ( (unsigned long)( a ) * (unsigned long)( b ## _r ) ) >> \
( sizeof( long ) * FT_CHAR_BIT - PIXEL_BITS ) )
/**************************************************************************
@ -432,6 +432,9 @@ typedef ptrdiff_t FT_PtrDist;
#define FT_MAX_GRAY_POOL ( 2048 / sizeof ( TCell ) )
#endif
/* FT_Span buffer size for direct rendering only */
#define FT_MAX_GRAY_SPANS 10
#if defined( _MSC_VER ) /* Visual C++ (and Intel C++) */
/* We disable the warning `structure was padded due to */
@ -465,6 +468,8 @@ typedef ptrdiff_t FT_PtrDist;
FT_Raster_Span_Func render_span;
void* render_span_data;
FT_Span spans[FT_MAX_GRAY_SPANS];
int num_spans;
} gray_TWorker, *gray_PWorker;
@ -516,7 +521,7 @@ typedef ptrdiff_t FT_PtrDist;
/**************************************************************************
*
* Record the current cell in the table.
* Record the current cell in the linked list.
*/
static void
gray_record_cell( RAS_ARG )
@ -526,10 +531,9 @@ typedef ptrdiff_t FT_PtrDist;
pcell = &ras.ycells[ras.ey - ras.min_ey];
for (;;)
while ( ( cell = *pcell ) )
{
cell = *pcell;
if ( !cell || cell->x > x )
if ( cell->x > x )
break;
if ( cell->x == x )
@ -577,16 +581,13 @@ typedef ptrdiff_t FT_PtrDist;
/* Note that if a cell is to the left of the clipping region, it is */
/* actually set to the (min_ex-1) horizontal position. */
if ( ex < ras.min_ex )
ex = ras.min_ex - 1;
/* record the current one if it is valid and substantial */
if ( !ras.invalid && ( ras.area || ras.cover ) )
gray_record_cell( RAS_VAR );
ras.area = 0;
ras.cover = 0;
ras.ex = ex;
ras.ex = FT_MAX( ex, ras.min_ex - 1 );
ras.ey = ey;
ras.invalid = ( ey >= ras.max_ey || ey < ras.min_ey ||
@ -622,8 +623,8 @@ typedef ptrdiff_t FT_PtrDist;
return;
}
fx1 = (TCoord)( x1 - SUBPIXELS( ex1 ) );
fx2 = (TCoord)( x2 - SUBPIXELS( ex2 ) );
fx1 = FRACT( x1 );
fx2 = FRACT( x2 );
/* everything is located in a single cell. That is easy! */
/* */
@ -650,6 +651,9 @@ typedef ptrdiff_t FT_PtrDist;
dx = -dx;
}
/* the fractional part of y-delta is mod/dx. It is essential to */
/* keep track of its accumulation for accurate rendering. */
/* XXX: y-delta and x-delta below should be related. */
FT_DIV_MOD( TCoord, p, dx, delta, mod );
ras.area += (TArea)( ( fx1 + first ) * delta );
@ -715,8 +719,8 @@ typedef ptrdiff_t FT_PtrDist;
( ey1 < ras.min_ey && ey2 < ras.min_ey ) )
goto End;
fy1 = (TCoord)( ras.y - SUBPIXELS( ey1 ) );
fy2 = (TCoord)( to_y - SUBPIXELS( ey2 ) );
fy1 = FRACT( ras.y );
fy2 = FRACT( to_y );
/* everything is on a single scanline */
if ( ey1 == ey2 )
@ -732,7 +736,7 @@ typedef ptrdiff_t FT_PtrDist;
if ( dx == 0 )
{
TCoord ex = TRUNC( ras.x );
TCoord two_fx = (TCoord)( ( ras.x - SUBPIXELS( ex ) ) << 1 );
TCoord two_fx = FRACT( ras.x ) << 1;
TArea area;
@ -787,6 +791,8 @@ typedef ptrdiff_t FT_PtrDist;
dy = -dy;
}
/* the fractional part of x-delta is mod/dy. It is essential to */
/* keep track of its accumulation for accurate rendering. */
FT_DIV_MOD( TCoord, p, dy, delta, mod );
x = ras.x + delta;
@ -843,8 +849,9 @@ typedef ptrdiff_t FT_PtrDist;
gray_render_line( RAS_ARG_ TPos to_x,
TPos to_y )
{
TPos dx, dy, fx1, fy1, fx2, fy2;
TCoord ex1, ex2, ey1, ey2;
TPos dx, dy;
TCoord fx1, fy1, fx2, fy2;
TCoord ex1, ey1, ex2, ey2;
ey1 = TRUNC( ras.y );
@ -858,8 +865,8 @@ typedef ptrdiff_t FT_PtrDist;
ex1 = TRUNC( ras.x );
ex2 = TRUNC( to_x );
fx1 = ras.x - SUBPIXELS( ex1 );
fy1 = ras.y - SUBPIXELS( ey1 );
fx1 = FRACT( ras.x );
fy1 = FRACT( ras.y );
dx = to_x - ras.x;
dy = to_y - ras.y;
@ -868,8 +875,8 @@ typedef ptrdiff_t FT_PtrDist;
;
else if ( dy == 0 ) /* ex1 != ex2 */ /* any horizontal line */
{
ex1 = ex2;
gray_set_cell( RAS_VAR_ ex1, ey1 );
gray_set_cell( RAS_VAR_ ex2, ey2 );
goto End;
}
else if ( dx == 0 )
{
@ -896,7 +903,7 @@ typedef ptrdiff_t FT_PtrDist;
}
else /* any other line */
{
TPos prod = dx * fy1 - dy * fx1;
TPos prod = dx * (TPos)fy1 - dy * (TPos)fx1;
FT_UDIVPREP( ex1 != ex2, dx );
FT_UDIVPREP( ey1 != ey2, dy );
@ -910,7 +917,7 @@ typedef ptrdiff_t FT_PtrDist;
prod - dx * ONE_PIXEL > 0 ) /* left */
{
fx2 = 0;
fy2 = (TPos)FT_UDIV( -prod, -dx );
fy2 = FT_UDIV( -prod, -dx );
prod -= dy * ONE_PIXEL;
ras.cover += ( fy2 - fy1 );
ras.area += ( fy2 - fy1 ) * ( fx1 + fx2 );
@ -922,7 +929,7 @@ typedef ptrdiff_t FT_PtrDist;
prod - dx * ONE_PIXEL + dy * ONE_PIXEL > 0 ) /* up */
{
prod -= dx * ONE_PIXEL;
fx2 = (TPos)FT_UDIV( -prod, dy );
fx2 = FT_UDIV( -prod, dy );
fy2 = ONE_PIXEL;
ras.cover += ( fy2 - fy1 );
ras.area += ( fy2 - fy1 ) * ( fx1 + fx2 );
@ -935,7 +942,7 @@ typedef ptrdiff_t FT_PtrDist;
{
prod += dy * ONE_PIXEL;
fx2 = ONE_PIXEL;
fy2 = (TPos)FT_UDIV( prod, dx );
fy2 = FT_UDIV( prod, dx );
ras.cover += ( fy2 - fy1 );
ras.area += ( fy2 - fy1 ) * ( fx1 + fx2 );
fx1 = 0;
@ -945,7 +952,7 @@ typedef ptrdiff_t FT_PtrDist;
else /* ( prod + dy * ONE_PIXEL < 0 &&
prod > 0 ) down */
{
fx2 = (TPos)FT_UDIV( prod, -dy );
fx2 = FT_UDIV( prod, -dy );
fy2 = 0;
prod += dx * ONE_PIXEL;
ras.cover += ( fy2 - fy1 );
@ -959,8 +966,8 @@ typedef ptrdiff_t FT_PtrDist;
} while ( ex1 != ex2 || ey1 != ey2 );
}
fx2 = to_x - SUBPIXELS( ex2 );
fy2 = to_y - SUBPIXELS( ey2 );
fx2 = FRACT( to_x );
fy2 = FRACT( to_y );
ras.cover += ( fy2 - fy1 );
ras.area += ( fy2 - fy1 ) * ( fx1 + fx2 );
@ -979,16 +986,18 @@ typedef ptrdiff_t FT_PtrDist;
base[4].x = base[2].x;
b = base[1].x;
a = base[3].x = ( base[2].x + b ) / 2;
b = base[1].x = ( base[0].x + b ) / 2;
base[2].x = ( a + b ) / 2;
a = base[0].x + base[1].x;
b = base[1].x + base[2].x;
base[3].x = b >> 1;
base[2].x = ( a + b ) >> 2;
base[1].x = a >> 1;
base[4].y = base[2].y;
b = base[1].y;
a = base[3].y = ( base[2].y + b ) / 2;
b = base[1].y = ( base[0].y + b ) / 2;
base[2].y = ( a + b ) / 2;
a = base[0].y + base[1].y;
b = base[1].y + base[2].y;
base[3].y = b >> 1;
base[2].y = ( a + b ) >> 2;
base[1].y = a >> 1;
}
@ -1042,12 +1051,11 @@ typedef ptrdiff_t FT_PtrDist;
/* many times as there are trailing zeros in the counter. */
do
{
split = 1;
while ( ( draw & split ) == 0 )
split = draw & ( -draw ); /* isolate the rightmost 1-bit */
while ( ( split >>= 1 ) )
{
gray_split_conic( arc );
arc += 2;
split <<= 1;
}
gray_render_line( RAS_VAR_ arc[0].x, arc[0].y );
@ -1060,28 +1068,32 @@ typedef ptrdiff_t FT_PtrDist;
static void
gray_split_cubic( FT_Vector* base )
{
TPos a, b, c, d;
TPos a, b, c;
base[6].x = base[3].x;
c = base[1].x;
d = base[2].x;
base[1].x = a = ( base[0].x + c ) / 2;
base[5].x = b = ( base[3].x + d ) / 2;
c = ( c + d ) / 2;
base[2].x = a = ( a + c ) / 2;
base[4].x = b = ( b + c ) / 2;
base[3].x = ( a + b ) / 2;
a = base[0].x + base[1].x;
b = base[1].x + base[2].x;
c = base[2].x + base[3].x;
base[5].x = c >> 1;
c += b;
base[4].x = c >> 2;
base[1].x = a >> 1;
a += b;
base[2].x = a >> 2;
base[3].x = ( a + c ) >> 3;
base[6].y = base[3].y;
c = base[1].y;
d = base[2].y;
base[1].y = a = ( base[0].y + c ) / 2;
base[5].y = b = ( base[3].y + d ) / 2;
c = ( c + d ) / 2;
base[2].y = a = ( a + c ) / 2;
base[4].y = b = ( b + c ) / 2;
base[3].y = ( a + b ) / 2;
a = base[0].y + base[1].y;
b = base[1].y + base[2].y;
c = base[2].y + base[3].y;
base[5].y = c >> 1;
c += b;
base[4].y = c >> 2;
base[1].y = a >> 1;
a += b;
base[2].y = a >> 2;
base[3].y = ( a + c ) >> 3;
}
@ -1092,9 +1104,6 @@ typedef ptrdiff_t FT_PtrDist;
{
FT_Vector bez_stack[16 * 3 + 1]; /* enough to accommodate bisections */
FT_Vector* arc = bez_stack;
TPos dx, dy, dx_, dy_;
TPos dx1, dy1, dx2, dy2;
TPos L, s, s_limit;
arc[0].x = UPSCALE( to->x );
@ -1123,45 +1132,13 @@ typedef ptrdiff_t FT_PtrDist;
for (;;)
{
/* Decide whether to split or draw. See `Rapid Termination */
/* Evaluation for Recursive Subdivision of Bezier Curves' by Thomas */
/* F. Hain, at */
/* http://www.cis.southalabama.edu/~hain/general/Publications/Bezier/Camera-ready%20CISST02%202.pdf */
/* dx and dy are x and y components of the P0-P3 chord vector. */
dx = dx_ = arc[3].x - arc[0].x;
dy = dy_ = arc[3].y - arc[0].y;
L = FT_HYPOT( dx_, dy_ );
/* Avoid possible arithmetic overflow below by splitting. */
if ( L > 32767 )
goto Split;
/* Max deviation may be as much as (s/L) * 3/4 (if Hain's v = 1). */
s_limit = L * (TPos)( ONE_PIXEL / 6 );
/* s is L * the perpendicular distance from P1 to the line P0-P3. */
dx1 = arc[1].x - arc[0].x;
dy1 = arc[1].y - arc[0].y;
s = FT_ABS( SUB_LONG( MUL_LONG( dy, dx1 ), MUL_LONG( dx, dy1 ) ) );
if ( s > s_limit )
goto Split;
/* s is L * the perpendicular distance from P2 to the line P0-P3. */
dx2 = arc[2].x - arc[0].x;
dy2 = arc[2].y - arc[0].y;
s = FT_ABS( SUB_LONG( MUL_LONG( dy, dx2 ), MUL_LONG( dx, dy2 ) ) );
if ( s > s_limit )
goto Split;
/* Split super curvy segments where the off points are so far
from the chord that the angles P0-P1-P3 or P0-P2-P3 become
acute as detected by appropriate dot products. */
if ( dx1 * ( dx1 - dx ) + dy1 * ( dy1 - dy ) > 0 ||
dx2 * ( dx2 - dx ) + dy2 * ( dy2 - dy ) > 0 )
/* with each split, control points quickly converge towards */
/* chord trisection points and the vanishing distances below */
/* indicate when the segment is flat enough to draw */
if ( FT_ABS( 2 * arc[0].x - 3 * arc[1].x + arc[3].x ) > ONE_PIXEL / 2 ||
FT_ABS( 2 * arc[0].y - 3 * arc[1].y + arc[3].y ) > ONE_PIXEL / 2 ||
FT_ABS( arc[0].x - 3 * arc[2].x + 2 * arc[3].x ) > ONE_PIXEL / 2 ||
FT_ABS( arc[0].y - 3 * arc[2].y + 2 * arc[3].y ) > ONE_PIXEL / 2 )
goto Split;
gray_render_line( RAS_VAR_ arc[0].x, arc[0].y );
@ -1236,8 +1213,6 @@ typedef ptrdiff_t FT_PtrDist;
{
/* scale the coverage from 0..(ONE_PIXEL*ONE_PIXEL*2) to 0..256 */
coverage >>= PIXEL_BITS * 2 + 1 - 8;
if ( coverage < 0 )
coverage = -coverage - 1;
/* compute the line's coverage depending on the outline fill rule */
if ( ras.outline.flags & FT_OUTLINE_EVEN_ODD_FILL )
@ -1247,23 +1222,30 @@ typedef ptrdiff_t FT_PtrDist;
if ( coverage >= 256 )
coverage = 511 - coverage;
}
else
else /* default non-zero winding rule */
{
/* normal non-zero winding rule */
if ( coverage < 0 )
coverage = ~coverage; /* the same as -coverage - 1 */
if ( coverage >= 256 )
coverage = 255;
}
if ( ras.render_span ) /* for FT_RASTER_FLAG_DIRECT only */
if ( ras.num_spans >= 0 ) /* for FT_RASTER_FLAG_DIRECT only */
{
FT_Span span;
FT_Span* span = ras.spans + ras.num_spans++;
span.x = (short)x;
span.len = (unsigned short)acount;
span.coverage = (unsigned char)coverage;
span->x = (short)x;
span->len = (unsigned short)acount;
span->coverage = (unsigned char)coverage;
ras.render_span( y, 1, &span, ras.render_span_data );
if ( ras.num_spans == FT_MAX_GRAY_SPANS )
{
/* flush the span buffer and reset the count */
ras.render_span( y, ras.num_spans, ras.spans, ras.render_span_data );
ras.num_spans = 0;
}
}
else
{
@ -1277,14 +1259,29 @@ typedef ptrdiff_t FT_PtrDist;
*/
switch ( acount )
{
case 7: *q++ = c;
case 6: *q++ = c;
case 5: *q++ = c;
case 4: *q++ = c;
case 3: *q++ = c;
case 2: *q++ = c;
case 1: *q = c;
case 0: break;
case 7:
*q++ = c;
/* fall through */
case 6:
*q++ = c;
/* fall through */
case 5:
*q++ = c;
/* fall through */
case 4:
*q++ = c;
/* fall through */
case 3:
*q++ = c;
/* fall through */
case 2:
*q++ = c;
/* fall through */
case 1:
*q = c;
/* fall through */
case 0:
break;
default:
FT_MEM_SET( q, c, acount );
}
@ -1322,6 +1319,13 @@ typedef ptrdiff_t FT_PtrDist;
if ( cover != 0 )
gray_hline( RAS_VAR_ x, y, cover, ras.max_ex - x );
if ( ras.num_spans > 0 ) /* for FT_RASTER_FLAG_DIRECT only */
{
/* flush the span buffer and reset the count */
ras.render_span( y, ras.num_spans, ras.spans, ras.render_span_data );
ras.num_spans = 0;
}
}
}
@ -1371,7 +1375,7 @@ typedef ptrdiff_t FT_PtrDist;
void* user )
{
#undef SCALED
#define SCALED( x ) ( ( (x) << shift ) - delta )
#define SCALED( x ) ( (x) * ( 1L << shift ) - delta )
FT_Vector v_last;
FT_Vector v_control;
@ -1631,7 +1635,7 @@ typedef ptrdiff_t FT_PtrDist;
gray_convert_glyph_inner( RAS_ARG,
int continued )
{
volatile int error = 0;
int error;
if ( ft_setjmp( ras.jump_buffer ) == 0 )
@ -1755,7 +1759,6 @@ typedef ptrdiff_t FT_PtrDist;
{
const FT_Outline* outline = (const FT_Outline*)params->source;
const FT_Bitmap* target_map = params->target;
FT_BBox clip;
#ifndef FT_STATIC_RASTER
gray_TWorker worker[1];
@ -1792,6 +1795,12 @@ typedef ptrdiff_t FT_PtrDist;
ras.render_span = (FT_Raster_Span_Func)params->gray_spans;
ras.render_span_data = params->user;
ras.num_spans = 0;
ras.min_ex = params->clip_box.xMin;
ras.min_ey = params->clip_box.yMin;
ras.max_ex = params->clip_box.xMax;
ras.max_ey = params->clip_box.yMax;
}
else
{
@ -1816,27 +1825,15 @@ typedef ptrdiff_t FT_PtrDist;
ras.render_span = (FT_Raster_Span_Func)NULL;
ras.render_span_data = NULL;
ras.num_spans = -1; /* invalid */
ras.min_ex = 0;
ras.min_ey = 0;
ras.max_ex = (FT_Pos)target_map->width;
ras.max_ey = (FT_Pos)target_map->rows;
}
/* compute clipping box */
if ( params->flags & FT_RASTER_FLAG_DIRECT &&
params->flags & FT_RASTER_FLAG_CLIP )
clip = params->clip_box;
else
{
/* compute clip box from target pixmap */
clip.xMin = 0;
clip.yMin = 0;
clip.xMax = (FT_Pos)target_map->width;
clip.yMax = (FT_Pos)target_map->rows;
}
/* clip to target bitmap, exit if nothing to do */
ras.min_ex = clip.xMin;
ras.min_ey = clip.yMin;
ras.max_ex = clip.xMax;
ras.max_ey = clip.yMax;
/* exit if nothing to do */
if ( ras.max_ex <= ras.min_ex || ras.max_ey <= ras.min_ey )
return 0;

View file

@ -243,7 +243,7 @@
}
if ( lcd_filter_func )
lcd_filter_func( bitmap, mode, lcd_weights );
lcd_filter_func( bitmap, lcd_weights );
}
#else /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */

View file

@ -82,6 +82,15 @@
#define UNSCALED_COMPONENT_OFFSET 0x1000
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
#define IS_DEFAULT_INSTANCE( _face ) \
( !( FT_IS_NAMED_INSTANCE( _face ) || \
FT_IS_VARIATION( _face ) ) )
#else
#define IS_DEFAULT_INSTANCE( _face ) 1
#endif
/**************************************************************************
*
* Return the horizontal metrics in font units for a given glyph.
@ -927,6 +936,11 @@
FT_Outline* outline;
FT_Int n_points;
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
FT_Memory memory = loader->face->root.memory;
FT_Vector* unrounded = NULL;
#endif
outline = &gloader->current.outline;
n_points = outline->n_points;
@ -947,26 +961,32 @@
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
if ( FT_IS_NAMED_INSTANCE( FT_FACE( loader->face ) ) ||
FT_IS_VARIATION( FT_FACE( loader->face ) ) )
if ( !IS_DEFAULT_INSTANCE( FT_FACE( loader->face ) ) )
{
if ( FT_NEW_ARRAY( unrounded, n_points ) )
goto Exit;
/* Deltas apply to the unscaled data. */
error = TT_Vary_Apply_Glyph_Deltas( loader->face,
loader->glyph_index,
outline,
unrounded,
(FT_UInt)n_points );
/* recalculate linear horizontal and vertical advances */
/* if we don't have HVAR and VVAR, respectively */
/* XXX: change all FreeType modules to store `linear' and `vadvance' */
/* in 26.6 format before the `base' module scales them to 16.16 */
if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) )
loader->linear = outline->points[n_points - 3].x -
outline->points[n_points - 4].x;
loader->linear = FT_PIX_ROUND( unrounded[n_points - 3].x -
unrounded[n_points - 4].x ) / 64;
if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) )
loader->vadvance = outline->points[n_points - 1].x -
outline->points[n_points - 2].x;
loader->vadvance = FT_PIX_ROUND( unrounded[n_points - 1].x -
unrounded[n_points - 2].x ) / 64;
if ( error )
return error;
goto Exit;
}
#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
@ -1021,10 +1041,23 @@
/* compensate for any scaling by de/emboldening; */
/* the amount was determined via experimentation */
if ( x_scale_factor != 1000 && ppem > 11 )
{
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
FT_Vector* orig_points = outline->points;
if ( !IS_DEFAULT_INSTANCE( FT_FACE( loader->face ) ) )
outline->points = unrounded;
#endif
FT_Outline_EmboldenXY( outline,
FT_MulFix( 1280 * ppem,
1000 - x_scale_factor ),
0 );
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
if ( !IS_DEFAULT_INSTANCE( FT_FACE( loader->face ) ) )
outline->points = orig_points;
#endif
}
do_scale = TRUE;
}
}
@ -1045,10 +1078,26 @@
if ( do_scale )
{
for ( ; vec < limit; vec++ )
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
if ( !IS_DEFAULT_INSTANCE( FT_FACE( loader->face ) ) )
{
vec->x = FT_MulFix( vec->x, x_scale );
vec->y = FT_MulFix( vec->y, y_scale );
FT_Vector* u = unrounded;
for ( ; vec < limit; vec++, u++ )
{
vec->x = ( FT_MulFix( u->x, x_scale ) + 32 ) >> 6;
vec->y = ( FT_MulFix( u->y, y_scale ) + 32 ) >> 6;
}
}
else
#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
{
for ( ; vec < limit; vec++ )
{
vec->x = FT_MulFix( vec->x, x_scale );
vec->y = FT_MulFix( vec->y, y_scale );
}
}
}
@ -1080,6 +1129,11 @@
error = TT_Hint_Glyph( loader, 0 );
}
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
Exit:
FT_FREE( unrounded );
#endif
return error;
}
@ -1681,6 +1735,9 @@
short contours[4] = { 0, 1, 2, 3 };
FT_Outline outline;
/* unrounded values */
FT_Vector unrounded[4] = { {0, 0}, {0, 0}, {0, 0}, {0, 0} };
points[0].x = loader->pp1.x;
points[0].y = loader->pp1.y;
@ -1702,6 +1759,7 @@
error = TT_Vary_Apply_Glyph_Deltas( loader->face,
glyph_index,
&outline,
unrounded,
(FT_UInt)outline.n_points );
if ( error )
goto Exit;
@ -1719,9 +1777,11 @@
/* recalculate linear horizontal and vertical advances */
/* if we don't have HVAR and VVAR, respectively */
if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) )
loader->linear = loader->pp2.x - loader->pp1.x;
loader->linear = FT_PIX_ROUND( unrounded[1].x -
unrounded[0].x ) / 64;
if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) )
loader->vadvance = loader->pp4.x - loader->pp3.x;
loader->vadvance = FT_PIX_ROUND( unrounded[3].x -
unrounded[2].x ) / 64;
}
#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
@ -1861,9 +1921,10 @@
FT_SubGlyph subglyph;
FT_Outline outline;
FT_Vector* points = NULL;
char* tags = NULL;
short* contours = NULL;
FT_Vector* points = NULL;
char* tags = NULL;
short* contours = NULL;
FT_Vector* unrounded = NULL;
limit = (short)gloader->current.num_subglyphs;
@ -1877,9 +1938,10 @@
outline.tags = NULL;
outline.contours = NULL;
if ( FT_NEW_ARRAY( points, outline.n_points ) ||
FT_NEW_ARRAY( tags, outline.n_points ) ||
FT_NEW_ARRAY( contours, outline.n_points ) )
if ( FT_NEW_ARRAY( points, outline.n_points ) ||
FT_NEW_ARRAY( tags, outline.n_points ) ||
FT_NEW_ARRAY( contours, outline.n_points ) ||
FT_NEW_ARRAY( unrounded, outline.n_points ) )
goto Exit1;
subglyph = gloader->current.subglyphs;
@ -1928,6 +1990,7 @@
face,
glyph_index,
&outline,
unrounded,
(FT_UInt)outline.n_points ) ) )
goto Exit1;
@ -1955,14 +2018,19 @@
/* recalculate linear horizontal and vertical advances */
/* if we don't have HVAR and VVAR, respectively */
if ( !( face->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) )
loader->linear = loader->pp2.x - loader->pp1.x;
loader->linear =
FT_PIX_ROUND( unrounded[outline.n_points - 3].x -
unrounded[outline.n_points - 4].x ) / 64;
if ( !( face->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) )
loader->vadvance = loader->pp4.x - loader->pp3.x;
loader->vadvance =
FT_PIX_ROUND( unrounded[outline.n_points - 1].x -
unrounded[outline.n_points - 2].x ) / 64;
Exit1:
FT_FREE( outline.points );
FT_FREE( outline.tags );
FT_FREE( outline.contours );
FT_FREE( unrounded );
if ( error )
goto Exit;
@ -2088,6 +2156,7 @@
loader->ins_pos = ins_pos;
if ( IS_HINTED( loader->load_flags ) &&
#ifdef TT_USE_BYTECODE_INTERPRETER
subglyph &&
subglyph->flags & WE_HAVE_INSTR &&
#endif
num_points > start_point )
@ -2611,11 +2680,6 @@
if ( reexecute )
{
FT_UInt i;
for ( i = 0; i < size->cvt_size; i++ )
size->cvt[i] = FT_MulFix( face->cvt[i], size->ttmetrics.scale );
error = tt_size_run_prep( size, pedantic );
if ( error )
return error;
@ -2718,13 +2782,6 @@
FT_Error error;
TT_LoaderRec loader;
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
#define IS_DEFAULT_INSTANCE ( !( FT_IS_NAMED_INSTANCE( glyph->face ) || \
FT_IS_VARIATION( glyph->face ) ) )
#else
#define IS_DEFAULT_INSTANCE 1
#endif
FT_TRACE1(( "TT_Load_Glyph: glyph index %d\n", glyph_index ));
@ -2733,7 +2790,7 @@
/* try to load embedded bitmap (if any) */
if ( size->strike_index != 0xFFFFFFFFUL &&
( load_flags & FT_LOAD_NO_BITMAP ) == 0 &&
IS_DEFAULT_INSTANCE )
IS_DEFAULT_INSTANCE( glyph->face ) )
{
FT_Fixed x_scale = size->root.metrics.x_scale;
FT_Fixed y_scale = size->root.metrics.y_scale;

View file

@ -68,12 +68,16 @@
/* some macros we need */
#define FT_fdot14ToFixed( x ) \
( (FT_Fixed)( (FT_ULong)(x) << 2 ) )
#define FT_intToFixed( i ) \
( (FT_Fixed)( (FT_ULong)(i) << 16 ) )
#define FT_fixedToInt( x ) \
( (FT_Short)( ( (FT_UInt32)(x) + 0x8000U ) >> 16 ) )
#define FT_fdot14ToFixed( x ) \
( (FT_Fixed)( (FT_ULong)(x) << 2 ) )
#define FT_intToFixed( i ) \
( (FT_Fixed)( (FT_ULong)(i) << 16 ) )
#define FT_fdot6ToFixed( i ) \
( (FT_Fixed)( (FT_ULong)(i) << 10 ) )
#define FT_fixedToInt( x ) \
( (FT_Short)( ( (x) + 0x8000U ) >> 16 ) )
#define FT_fixedToFdot6( x ) \
( (FT_Pos)( ( (x) + 0x200 ) >> 10 ) )
/**************************************************************************
@ -397,9 +401,10 @@
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;
segment->correspondence[j].fromCoord =
FT_fdot14ToFixed( FT_GET_SHORT() );
segment->correspondence[j].toCoord =
FT_fdot14ToFixed( FT_GET_SHORT() );
FT_TRACE5(( " mapping %.5f to %.5f\n",
segment->correspondence[j].fromCoord / 65536.0,
@ -1616,7 +1621,7 @@
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_fdot14ToFixed( FT_GET_SHORT() );
FT_TRACE5(( "%.5f ",
blend->tuplecoords[i * gvar_head.axisCount + j] / 65536.0 ));
}
@ -3054,7 +3059,7 @@
if ( instance_index > num_instances )
goto Exit;
if ( instance_index > 0 && mmvar->namedstyle )
if ( instance_index > 0 )
{
FT_Memory memory = face->root.memory;
SFNT_Service sfnt = (SFNT_Service)face->sfnt;
@ -3080,7 +3085,12 @@
mmvar->num_axis,
named_style->coords );
if ( error )
{
/* internal error code -1 means `no change' */
if ( error == -1 )
error = FT_Err_Ok;
goto Exit;
}
}
else
error = TT_Set_Var_Design( face, 0, NULL );
@ -3103,6 +3113,21 @@
/*************************************************************************/
static FT_Error
tt_cvt_ready_iterator( FT_ListNode node,
void* user )
{
TT_Size size = (TT_Size)node->data;
FT_UNUSED( user );
size->cvt_ready = -1;
return FT_Err_Ok;
}
/**************************************************************************
*
* @Function:
@ -3133,6 +3158,8 @@
FT_Error error;
FT_Memory memory = stream->memory;
FT_Face root = &face->root;
FT_ULong table_start;
FT_ULong table_len;
@ -3261,8 +3288,7 @@
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 */
tuple_coords[j] = FT_fdot14ToFixed( FT_GET_SHORT() );
}
else if ( ( tupleIndex & GX_TI_TUPLE_INDEX_MASK ) >= blend->tuplecount )
{
@ -3293,9 +3319,9 @@
if ( tupleIndex & GX_TI_INTERMEDIATE_TUPLE )
{
for ( j = 0; j < blend->num_axis; j++ )
im_start_coords[j] = FT_GET_SHORT() * 4;
im_start_coords[j] = FT_fdot14ToFixed( FT_GET_SHORT() );
for ( j = 0; j < blend->num_axis; j++ )
im_end_coords[j] = FT_GET_SHORT() * 4;
im_end_coords[j] = FT_fdot14ToFixed( FT_GET_SHORT() );
}
apply = ft_var_apply_tuple( blend,
@ -3360,9 +3386,9 @@
{
FT_TRACE7(( " %d: %f -> %f\n",
j,
( FT_intToFixed( face->cvt[j] ) +
( FT_fdot6ToFixed( face->cvt[j] ) +
old_cvt_delta ) / 65536.0,
( FT_intToFixed( face->cvt[j] ) +
( FT_fdot6ToFixed( face->cvt[j] ) +
cvt_deltas[j] ) / 65536.0 ));
count++;
}
@ -3402,9 +3428,9 @@
{
FT_TRACE7(( " %d: %f -> %f\n",
pindex,
( FT_intToFixed( face->cvt[pindex] ) +
( FT_fdot6ToFixed( face->cvt[pindex] ) +
old_cvt_delta ) / 65536.0,
( FT_intToFixed( face->cvt[pindex] ) +
( FT_fdot6ToFixed( face->cvt[pindex] ) +
cvt_deltas[pindex] ) / 65536.0 ));
count++;
}
@ -3429,7 +3455,7 @@
FT_TRACE5(( "\n" ));
for ( i = 0; i < face->cvt_size; i++ )
face->cvt[i] += FT_fixedToInt( cvt_deltas[i] );
face->cvt[i] += FT_fixedToFdot6( cvt_deltas[i] );
FExit:
FT_FRAME_EXIT();
@ -3442,6 +3468,12 @@
FT_FREE( im_end_coords );
FT_FREE( cvt_deltas );
/* iterate over all FT_Size objects and set `cvt_ready' to -1 */
/* to trigger rescaling of all CVT values */
FT_List_Iterate( &root->sizes_list,
tt_cvt_ready_iterator,
NULL );
return error;
}
@ -3669,6 +3701,11 @@
* outline ::
* The outline to change.
*
* @Output:
* unrounded ::
* An array with `n_points' elements that is filled with unrounded
* point coordinates (in 26.6 format).
*
* @Return:
* FreeType error code. 0 means success.
*/
@ -3676,6 +3713,7 @@
TT_Vary_Apply_Glyph_Deltas( TT_Face face,
FT_UInt glyph_index,
FT_Outline* outline,
FT_Vector* unrounded,
FT_UInt n_points )
{
FT_Error error;
@ -3717,6 +3755,12 @@
if ( !face->doblend || !blend )
return FT_THROW( Invalid_Argument );
for ( i = 0; i < n_points; i++ )
{
unrounded[i].x = INT_TO_F26DOT6( outline->points[i].x );
unrounded[i].y = INT_TO_F26DOT6( outline->points[i].y );
}
if ( glyph_index >= blend->gv_glyphcnt ||
blend->glyphoffsets[glyph_index] ==
blend->glyphoffsets[glyph_index + 1] )
@ -3807,8 +3851,7 @@
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 */
tuple_coords[j] = FT_fdot14ToFixed( FT_GET_SHORT() );
}
else if ( ( tupleIndex & GX_TI_TUPLE_INDEX_MASK ) >= blend->tuplecount )
{
@ -3828,9 +3871,9 @@
if ( tupleIndex & GX_TI_INTERMEDIATE_TUPLE )
{
for ( j = 0; j < blend->num_axis; j++ )
im_start_coords[j] = FT_GET_SHORT() * 4;
im_start_coords[j] = FT_fdot14ToFixed( FT_GET_SHORT() );
for ( j = 0; j < blend->num_axis; j++ )
im_end_coords[j] = FT_GET_SHORT() * 4;
im_end_coords[j] = FT_fdot14ToFixed( FT_GET_SHORT() );
}
apply = ft_var_apply_tuple( blend,
@ -4064,6 +4107,9 @@
for ( i = 0; i < n_points; i++ )
{
unrounded[i].x += FT_fixedToFdot6( point_deltas_x[i] );
unrounded[i].y += FT_fixedToFdot6( point_deltas_y[i] );
outline->points[i].x += FT_fixedToInt( point_deltas_x[i] );
outline->points[i].y += FT_fixedToInt( point_deltas_y[i] );
}

View file

@ -416,6 +416,7 @@ FT_BEGIN_HEADER
TT_Vary_Apply_Glyph_Deltas( TT_Face face,
FT_UInt glyph_index,
FT_Outline* outline,
FT_Vector* unrounded,
FT_UInt n_points );
FT_LOCAL( FT_Error )

View file

@ -654,23 +654,25 @@
/* opcodes are gathered in groups of 16 */
/* please keep the spaces as they are */
/* SVTCA y */ PACK( 0, 0 ),
/* SVTCA x */ PACK( 0, 0 ),
/* SPvTCA y */ PACK( 0, 0 ),
/* SPvTCA x */ PACK( 0, 0 ),
/* SFvTCA y */ PACK( 0, 0 ),
/* SFvTCA x */ PACK( 0, 0 ),
/* SPvTL // */ PACK( 2, 0 ),
/* SPvTL + */ PACK( 2, 0 ),
/* SFvTL // */ PACK( 2, 0 ),
/* SFvTL + */ PACK( 2, 0 ),
/* SPvFS */ PACK( 2, 0 ),
/* SFvFS */ PACK( 2, 0 ),
/* GPv */ PACK( 0, 2 ),
/* GFv */ PACK( 0, 2 ),
/* SFvTPv */ PACK( 0, 0 ),
/* 0x00 */
/* SVTCA[0] */ PACK( 0, 0 ),
/* SVTCA[1] */ PACK( 0, 0 ),
/* SPVTCA[0] */ PACK( 0, 0 ),
/* SPVTCA[1] */ PACK( 0, 0 ),
/* SFVTCA[0] */ PACK( 0, 0 ),
/* SFVTCA[1] */ PACK( 0, 0 ),
/* SPVTL[0] */ PACK( 2, 0 ),
/* SPVTL[1] */ PACK( 2, 0 ),
/* SFVTL[0] */ PACK( 2, 0 ),
/* SFVTL[1] */ PACK( 2, 0 ),
/* SPVFS */ PACK( 2, 0 ),
/* SFVFS */ PACK( 2, 0 ),
/* GPV */ PACK( 0, 2 ),
/* GFV */ PACK( 0, 2 ),
/* SFVTPV */ PACK( 0, 0 ),
/* ISECT */ PACK( 5, 0 ),
/* 0x10 */
/* SRP0 */ PACK( 1, 0 ),
/* SRP1 */ PACK( 1, 0 ),
/* SRP2 */ PACK( 1, 0 ),
@ -684,10 +686,11 @@
/* SMD */ PACK( 1, 0 ),
/* ELSE */ PACK( 0, 0 ),
/* JMPR */ PACK( 1, 0 ),
/* SCvTCi */ PACK( 1, 0 ),
/* SSwCi */ PACK( 1, 0 ),
/* SCVTCI */ PACK( 1, 0 ),
/* SSWCI */ PACK( 1, 0 ),
/* SSW */ PACK( 1, 0 ),
/* 0x20 */
/* DUP */ PACK( 1, 2 ),
/* POP */ PACK( 1, 0 ),
/* CLEAR */ PACK( 0, 0 ),
@ -695,7 +698,7 @@
/* DEPTH */ PACK( 0, 1 ),
/* CINDEX */ PACK( 1, 1 ),
/* MINDEX */ PACK( 1, 0 ),
/* AlignPTS */ PACK( 2, 0 ),
/* ALIGNPTS */ PACK( 2, 0 ),
/* INS_$28 */ PACK( 0, 0 ),
/* UTP */ PACK( 1, 0 ),
/* LOOPCALL */ PACK( 2, 0 ),
@ -705,6 +708,7 @@
/* MDAP[0] */ PACK( 1, 0 ),
/* MDAP[1] */ PACK( 1, 0 ),
/* 0x30 */
/* IUP[0] */ PACK( 0, 0 ),
/* IUP[1] */ PACK( 0, 0 ),
/* SHP[0] */ PACK( 0, 0 ), /* loops */
@ -717,17 +721,18 @@
/* IP */ PACK( 0, 0 ), /* loops */
/* MSIRP[0] */ PACK( 2, 0 ),
/* MSIRP[1] */ PACK( 2, 0 ),
/* AlignRP */ PACK( 0, 0 ), /* loops */
/* ALIGNRP */ PACK( 0, 0 ), /* loops */
/* RTDG */ PACK( 0, 0 ),
/* MIAP[0] */ PACK( 2, 0 ),
/* MIAP[1] */ PACK( 2, 0 ),
/* NPushB */ PACK( 0, 0 ),
/* NPushW */ PACK( 0, 0 ),
/* 0x40 */
/* NPUSHB */ PACK( 0, 0 ),
/* NPUSHW */ PACK( 0, 0 ),
/* WS */ PACK( 2, 0 ),
/* RS */ PACK( 1, 1 ),
/* WCvtP */ PACK( 2, 0 ),
/* RCvt */ PACK( 1, 1 ),
/* WCVTP */ PACK( 2, 0 ),
/* RCVT */ PACK( 1, 1 ),
/* GC[0] */ PACK( 1, 1 ),
/* GC[1] */ PACK( 1, 1 ),
/* SCFS */ PACK( 2, 0 ),
@ -735,10 +740,11 @@
/* MD[1] */ PACK( 2, 1 ),
/* MPPEM */ PACK( 0, 1 ),
/* MPS */ PACK( 0, 1 ),
/* FlipON */ PACK( 0, 0 ),
/* FlipOFF */ PACK( 0, 0 ),
/* FLIPON */ PACK( 0, 0 ),
/* FLIPOFF */ PACK( 0, 0 ),
/* DEBUG */ PACK( 1, 0 ),
/* 0x50 */
/* LT */ PACK( 2, 1 ),
/* LTEQ */ PACK( 2, 1 ),
/* GT */ PACK( 2, 1 ),
@ -752,10 +758,11 @@
/* AND */ PACK( 2, 1 ),
/* OR */ PACK( 2, 1 ),
/* NOT */ PACK( 1, 1 ),
/* DeltaP1 */ PACK( 1, 0 ),
/* DELTAP1 */ PACK( 1, 0 ),
/* SDB */ PACK( 1, 0 ),
/* SDS */ PACK( 1, 0 ),
/* 0x60 */
/* ADD */ PACK( 2, 1 ),
/* SUB */ PACK( 2, 1 ),
/* DIV */ PACK( 2, 1 ),
@ -773,14 +780,15 @@
/* NROUND[2] */ PACK( 1, 1 ),
/* NROUND[3] */ PACK( 1, 1 ),
/* WCvtF */ PACK( 2, 0 ),
/* DeltaP2 */ PACK( 1, 0 ),
/* DeltaP3 */ PACK( 1, 0 ),
/* DeltaCn[0] */ PACK( 1, 0 ),
/* DeltaCn[1] */ PACK( 1, 0 ),
/* DeltaCn[2] */ PACK( 1, 0 ),
/* 0x70 */
/* WCVTF */ PACK( 2, 0 ),
/* DELTAP2 */ PACK( 1, 0 ),
/* DELTAP3 */ PACK( 1, 0 ),
/* DELTAC1 */ PACK( 1, 0 ),
/* DELTAC2 */ PACK( 1, 0 ),
/* DELTAC3 */ PACK( 1, 0 ),
/* SROUND */ PACK( 1, 0 ),
/* S45Round */ PACK( 1, 0 ),
/* S45ROUND */ PACK( 1, 0 ),
/* JROT */ PACK( 2, 0 ),
/* JROF */ PACK( 2, 0 ),
/* ROFF */ PACK( 0, 0 ),
@ -790,23 +798,25 @@
/* SANGW */ PACK( 1, 0 ),
/* AA */ PACK( 1, 0 ),
/* FlipPT */ PACK( 0, 0 ), /* loops */
/* FlipRgON */ PACK( 2, 0 ),
/* FlipRgOFF */ PACK( 2, 0 ),
/* 0x80 */
/* FLIPPT */ PACK( 0, 0 ), /* loops */
/* FLIPRGON */ PACK( 2, 0 ),
/* FLIPRGOFF */ PACK( 2, 0 ),
/* INS_$83 */ PACK( 0, 0 ),
/* INS_$84 */ PACK( 0, 0 ),
/* ScanCTRL */ PACK( 1, 0 ),
/* SDPvTL[0] */ PACK( 2, 0 ),
/* SDPvTL[1] */ PACK( 2, 0 ),
/* GetINFO */ PACK( 1, 1 ),
/* SCANCTRL */ PACK( 1, 0 ),
/* SDPVTL[0] */ PACK( 2, 0 ),
/* SDPVTL[1] */ PACK( 2, 0 ),
/* GETINFO */ PACK( 1, 1 ),
/* IDEF */ PACK( 1, 0 ),
/* ROLL */ PACK( 3, 3 ),
/* MAX */ PACK( 2, 1 ),
/* MIN */ PACK( 2, 1 ),
/* ScanTYPE */ PACK( 1, 0 ),
/* InstCTRL */ PACK( 2, 0 ),
/* SCANTYPE */ PACK( 1, 0 ),
/* INSTCTRL */ PACK( 2, 0 ),
/* INS_$8F */ PACK( 0, 0 ),
/* 0x90 */
/* INS_$90 */ PACK( 0, 0 ),
/* GETVAR */ PACK( 0, 0 ), /* will be handled specially */
/* GETDATA */ PACK( 0, 1 ),
@ -824,6 +834,7 @@
/* INS_$9E */ PACK( 0, 0 ),
/* INS_$9F */ PACK( 0, 0 ),
/* 0xA0 */
/* INS_$A0 */ PACK( 0, 0 ),
/* INS_$A1 */ PACK( 0, 0 ),
/* INS_$A2 */ PACK( 0, 0 ),
@ -841,23 +852,25 @@
/* INS_$AE */ PACK( 0, 0 ),
/* INS_$AF */ PACK( 0, 0 ),
/* PushB[0] */ PACK( 0, 1 ),
/* PushB[1] */ PACK( 0, 2 ),
/* PushB[2] */ PACK( 0, 3 ),
/* PushB[3] */ PACK( 0, 4 ),
/* PushB[4] */ PACK( 0, 5 ),
/* PushB[5] */ PACK( 0, 6 ),
/* PushB[6] */ PACK( 0, 7 ),
/* PushB[7] */ PACK( 0, 8 ),
/* PushW[0] */ PACK( 0, 1 ),
/* PushW[1] */ PACK( 0, 2 ),
/* PushW[2] */ PACK( 0, 3 ),
/* PushW[3] */ PACK( 0, 4 ),
/* PushW[4] */ PACK( 0, 5 ),
/* PushW[5] */ PACK( 0, 6 ),
/* PushW[6] */ PACK( 0, 7 ),
/* PushW[7] */ PACK( 0, 8 ),
/* 0xB0 */
/* PUSHB[0] */ PACK( 0, 1 ),
/* PUSHB[1] */ PACK( 0, 2 ),
/* PUSHB[2] */ PACK( 0, 3 ),
/* PUSHB[3] */ PACK( 0, 4 ),
/* PUSHB[4] */ PACK( 0, 5 ),
/* PUSHB[5] */ PACK( 0, 6 ),
/* PUSHB[6] */ PACK( 0, 7 ),
/* PUSHB[7] */ PACK( 0, 8 ),
/* PUSHW[0] */ PACK( 0, 1 ),
/* PUSHW[1] */ PACK( 0, 2 ),
/* PUSHW[2] */ PACK( 0, 3 ),
/* PUSHW[3] */ PACK( 0, 4 ),
/* PUSHW[4] */ PACK( 0, 5 ),
/* PUSHW[5] */ PACK( 0, 6 ),
/* PUSHW[6] */ PACK( 0, 7 ),
/* PUSHW[7] */ PACK( 0, 8 ),
/* 0xC0 */
/* MDRP[00] */ PACK( 1, 0 ),
/* MDRP[01] */ PACK( 1, 0 ),
/* MDRP[02] */ PACK( 1, 0 ),
@ -875,6 +888,7 @@
/* MDRP[14] */ PACK( 1, 0 ),
/* MDRP[15] */ PACK( 1, 0 ),
/* 0xD0 */
/* MDRP[16] */ PACK( 1, 0 ),
/* MDRP[17] */ PACK( 1, 0 ),
/* MDRP[18] */ PACK( 1, 0 ),
@ -892,6 +906,7 @@
/* MDRP[30] */ PACK( 1, 0 ),
/* MDRP[31] */ PACK( 1, 0 ),
/* 0xE0 */
/* MIRP[00] */ PACK( 2, 0 ),
/* MIRP[01] */ PACK( 2, 0 ),
/* MIRP[02] */ PACK( 2, 0 ),
@ -909,6 +924,7 @@
/* MIRP[14] */ PACK( 2, 0 ),
/* MIRP[15] */ PACK( 2, 0 ),
/* 0xF0 */
/* MIRP[16] */ PACK( 2, 0 ),
/* MIRP[17] */ PACK( 2, 0 ),
/* MIRP[18] */ PACK( 2, 0 ),
@ -937,23 +953,25 @@
static
const char* const opcode_name[256] =
{
"7 SVTCA y",
"7 SVTCA x",
"8 SPvTCA y",
"8 SPvTCA x",
"8 SFvTCA y",
"8 SFvTCA x",
"8 SPvTL ||",
"7 SPvTL +",
"8 SFvTL ||",
"7 SFvTL +",
"5 SPvFS",
"5 SFvFS",
"3 GPv",
"3 GFv",
"6 SFvTPv",
/* 0x00 */
"8 SVTCA[y]",
"8 SVTCA[x]",
"9 SPVTCA[y]",
"9 SPVTCA[x]",
"9 SFVTCA[y]",
"9 SFVTCA[x]",
"9 SPVTL[||]",
"8 SPVTL[+]",
"9 SFVTL[||]",
"8 SFVTL[+]",
"5 SPVFS",
"5 SFVFS",
"3 GPV",
"3 GFV",
"6 SFVTPV",
"5 ISECT",
/* 0x10 */
"4 SRP0",
"4 SRP1",
"4 SRP2",
@ -967,10 +985,11 @@
"3 SMD",
"4 ELSE",
"4 JMPR",
"6 SCvTCi",
"5 SSwCi",
"6 SCVTCI",
"5 SSWCI",
"3 SSW",
/* 0x20 */
"3 DUP",
"3 POP",
"5 CLEAR",
@ -978,50 +997,53 @@
"5 DEPTH",
"6 CINDEX",
"6 MINDEX",
"8 AlignPTS",
"8 ALIGNPTS",
"7 INS_$28",
"3 UTP",
"8 LOOPCALL",
"4 CALL",
"4 FDEF",
"4 ENDF",
"7 MDAP[0]",
"7 MDAP[1]",
"6 MDAP[]",
"9 MDAP[rnd]",
"6 IUP[0]",
"6 IUP[1]",
"6 SHP[0]",
"6 SHP[1]",
"6 SHC[0]",
"6 SHC[1]",
"6 SHZ[0]",
"6 SHZ[1]",
/* 0x30 */
"6 IUP[y]",
"6 IUP[x]",
"8 SHP[rp2]",
"8 SHP[rp1]",
"8 SHC[rp2]",
"8 SHC[rp1]",
"8 SHZ[rp2]",
"8 SHZ[rp1]",
"5 SHPIX",
"2 IP",
"8 MSIRP[0]",
"8 MSIRP[1]",
"7 AlignRP",
"7 MSIRP[]",
"A MSIRP[rp0]",
"7 ALIGNRP",
"4 RTDG",
"7 MIAP[0]",
"7 MIAP[1]",
"6 MIAP[]",
"9 MIAP[rnd]",
"6 NPushB",
"6 NPushW",
/* 0x40 */
"6 NPUSHB",
"6 NPUSHW",
"2 WS",
"2 RS",
"5 WCvtP",
"4 RCvt",
"5 GC[0]",
"5 GC[1]",
"5 WCVTP",
"4 RCVT",
"8 GC[curr]",
"8 GC[orig]",
"4 SCFS",
"5 MD[0]",
"5 MD[1]",
"8 MD[curr]",
"8 MD[orig]",
"5 MPPEM",
"3 MPS",
"6 FlipON",
"7 FlipOFF",
"6 FLIPON",
"7 FLIPOFF",
"5 DEBUG",
/* 0x50 */
"2 LT",
"4 LTEQ",
"2 GT",
@ -1035,10 +1057,11 @@
"3 AND",
"2 OR",
"3 NOT",
"7 DeltaP1",
"7 DELTAP1",
"3 SDB",
"3 SDS",
/* 0x60 */
"3 ADD",
"3 SUB",
"3 DIV",
@ -1047,23 +1070,24 @@
"3 NEG",
"5 FLOOR",
"7 CEILING",
"8 ROUND[0]",
"8 ROUND[1]",
"8 ROUND[2]",
"8 ROUND[3]",
"9 NROUND[0]",
"9 NROUND[1]",
"9 NROUND[2]",
"9 NROUND[3]",
"8 ROUND[G]",
"8 ROUND[B]",
"8 ROUND[W]",
"7 ROUND[]",
"9 NROUND[G]",
"9 NROUND[B]",
"9 NROUND[W]",
"8 NROUND[]",
"5 WCvtF",
"7 DeltaP2",
"7 DeltaP3",
"A DeltaCn[0]",
"A DeltaCn[1]",
"A DeltaCn[2]",
/* 0x70 */
"5 WCVTF",
"7 DELTAP2",
"7 DELTAP3",
"7 DELTAC1",
"7 DELTAC2",
"7 DELTAC3",
"6 SROUND",
"8 S45Round",
"8 S45ROUND",
"4 JROT",
"4 JROF",
"4 ROFF",
@ -1073,26 +1097,28 @@
"5 SANGW",
"2 AA",
"6 FlipPT",
"8 FlipRgON",
"9 FlipRgOFF",
/* 0x80 */
"6 FLIPPT",
"8 FLIPRGON",
"9 FLIPRGOFF",
"7 INS_$83",
"7 INS_$84",
"8 ScanCTRL",
"9 SDPvTL[0]",
"9 SDPvTL[1]",
"7 GetINFO",
"8 SCANCTRL",
"A SDPVTL[||]",
"9 SDPVTL[+]",
"7 GETINFO",
"4 IDEF",
"4 ROLL",
"3 MAX",
"3 MIN",
"8 ScanTYPE",
"8 InstCTRL",
"8 SCANTYPE",
"8 INSTCTRL",
"7 INS_$8F",
/* 0x90 */
"7 INS_$90",
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
"6 GETVAR",
"C GETVARIATION",
"7 GETDATA",
#else
"7 INS_$91",
@ -1112,6 +1138,7 @@
"7 INS_$9E",
"7 INS_$9F",
/* 0xA0 */
"7 INS_$A0",
"7 INS_$A1",
"7 INS_$A2",
@ -1129,90 +1156,95 @@
"7 INS_$AE",
"7 INS_$AF",
"8 PushB[0]",
"8 PushB[1]",
"8 PushB[2]",
"8 PushB[3]",
"8 PushB[4]",
"8 PushB[5]",
"8 PushB[6]",
"8 PushB[7]",
"8 PushW[0]",
"8 PushW[1]",
"8 PushW[2]",
"8 PushW[3]",
"8 PushW[4]",
"8 PushW[5]",
"8 PushW[6]",
"8 PushW[7]",
/* 0xB0 */
"8 PUSHB[0]",
"8 PUSHB[1]",
"8 PUSHB[2]",
"8 PUSHB[3]",
"8 PUSHB[4]",
"8 PUSHB[5]",
"8 PUSHB[6]",
"8 PUSHB[7]",
"8 PUSHW[0]",
"8 PUSHW[1]",
"8 PUSHW[2]",
"8 PUSHW[3]",
"8 PUSHW[4]",
"8 PUSHW[5]",
"8 PUSHW[6]",
"8 PUSHW[7]",
/* 0xC0 */
"7 MDRP[G]",
"7 MDRP[B]",
"7 MDRP[W]",
"7 MDRP[?]",
"6 MDRP[]",
"8 MDRP[rG]",
"8 MDRP[rB]",
"8 MDRP[rW]",
"8 MDRP[r?]",
"7 MDRP[r]",
"8 MDRP[mG]",
"8 MDRP[mB]",
"8 MDRP[mW]",
"8 MDRP[m?]",
"7 MDRP[m]",
"9 MDRP[mrG]",
"9 MDRP[mrB]",
"9 MDRP[mrW]",
"9 MDRP[mr?]",
"8 MDRP[mr]",
/* 0xD0 */
"8 MDRP[pG]",
"8 MDRP[pB]",
"8 MDRP[pW]",
"8 MDRP[p?]",
"7 MDRP[p]",
"9 MDRP[prG]",
"9 MDRP[prB]",
"9 MDRP[prW]",
"9 MDRP[pr?]",
"8 MDRP[pr]",
"9 MDRP[pmG]",
"9 MDRP[pmB]",
"9 MDRP[pmW]",
"9 MDRP[pm?]",
"8 MDRP[pm]",
"A MDRP[pmrG]",
"A MDRP[pmrB]",
"A MDRP[pmrW]",
"A MDRP[pmr?]",
"9 MDRP[pmr]",
/* 0xE0 */
"7 MIRP[G]",
"7 MIRP[B]",
"7 MIRP[W]",
"7 MIRP[?]",
"6 MIRP[]",
"8 MIRP[rG]",
"8 MIRP[rB]",
"8 MIRP[rW]",
"8 MIRP[r?]",
"7 MIRP[r]",
"8 MIRP[mG]",
"8 MIRP[mB]",
"8 MIRP[mW]",
"8 MIRP[m?]",
"7 MIRP[m]",
"9 MIRP[mrG]",
"9 MIRP[mrB]",
"9 MIRP[mrW]",
"9 MIRP[mr?]",
"8 MIRP[mr]",
/* 0xF0 */
"8 MIRP[pG]",
"8 MIRP[pB]",
"8 MIRP[pW]",
"8 MIRP[p?]",
"7 MIRP[p]",
"9 MIRP[prG]",
"9 MIRP[prB]",
"9 MIRP[prW]",
"9 MIRP[pr?]",
"8 MIRP[pr]",
"9 MIRP[pmG]",
"9 MIRP[pmB]",
"9 MIRP[pmW]",
"9 MIRP[pm?]",
"8 MIRP[pm]",
"A MIRP[pmrG]",
"A MIRP[pmrB]",
"A MIRP[pmrW]",
"A MIRP[pmr?]"
"9 MIRP[pmr]"
};
#endif /* FT_DEBUG_LEVEL_TRACE */
@ -1662,6 +1694,32 @@
}
/*
*
* Apple's TrueType specification at
*
* https://developer.apple.com/fonts/TrueType-Reference-Manual/RM02/Chap2.html#order
*
* gives the following order of operations in instructions that move
* points.
*
* - check single width cut-in (MIRP, MDRP)
*
* - check control value cut-in (MIRP, MIAP)
*
* - apply engine compensation (MIRP, MDRP)
*
* - round distance (MIRP, MDRP) or value (MIAP, MDAP)
*
* - check minimum distance (MIRP,MDRP)
*
* - move point (MIRP, MDRP, MIAP, MSIRP, MDAP)
*
* For rounding instructions, engine compensation happens before rounding.
*
*/
/**************************************************************************
*
* @Function:
@ -1886,7 +1944,6 @@
zone->org[point].y = ADD_LONG( zone->org[point].y, distance );
}
/**************************************************************************
*
* @Function:
@ -1904,12 +1961,6 @@
*
* @Return:
* The compensated distance.
*
* @Note:
* The TrueType specification says very few about the relationship
* between rounding and engine compensation. However, it seems from
* the description of super round that we should add the compensation
* before rounding.
*/
static FT_F26Dot6
Round_None( TT_ExecContext exc,

View file

@ -148,7 +148,7 @@
/* This list shall be expanded as we find more of them. */
static FT_Bool
tt_check_trickyness_family( FT_String* name )
tt_check_trickyness_family( const FT_String* name )
{
#define TRICK_NAMES_MAX_CHARACTERS 19
@ -937,7 +937,22 @@
TT_Face face = (TT_Face)size->root.face;
TT_ExecContext exec;
FT_Error error;
FT_UInt i;
/* unscaled CVT values are already stored in 26.6 format */
FT_Fixed scale = size->ttmetrics.scale >> 6;
/* Scale the cvt values to the new ppem. */
/* By default, we use the y ppem value for scaling. */
FT_TRACE6(( "CVT values:\n" ));
for ( i = 0; i < size->cvt_size; i++ )
{
size->cvt[i] = FT_MulFix( face->cvt[i], scale );
FT_TRACE6(( " %3d: %f (%f)\n",
i, face->cvt[i] / 64.0, size->cvt[i] / 64.0 ));
}
FT_TRACE6(( "\n" ));
exec = size->context;
@ -1094,11 +1109,17 @@
tt_metrics->rotated = FALSE;
tt_metrics->stretched = FALSE;
/* set default engine compensation */
tt_metrics->compensations[0] = 0; /* gray */
tt_metrics->compensations[1] = 0; /* black */
tt_metrics->compensations[2] = 0; /* white */
tt_metrics->compensations[3] = 0; /* reserved */
/* Set default engine compensation. Value 3 is not described */
/* in the OpenType specification (as of Mai 2019), but Greg */
/* says that MS handles it the same as `gray'. */
/* */
/* The Apple specification says that the compensation for */
/* `gray' is always zero. FreeType doesn't do any */
/* compensation at all. */
tt_metrics->compensations[0] = 0; /* gray */
tt_metrics->compensations[1] = 0; /* black */
tt_metrics->compensations[2] = 0; /* white */
tt_metrics->compensations[3] = 0; /* the same as gray */
}
/* allocate function defs, instruction defs, cvt, and storage area */
@ -1171,20 +1192,8 @@
if ( size->cvt_ready < 0 )
{
FT_UInt i;
TT_Face face = (TT_Face)size->root.face;
/* Scale the cvt values to the new ppem. */
/* By default, we use the y ppem value for scaling. */
FT_TRACE6(( "CVT values:\n" ));
for ( i = 0; i < size->cvt_size; i++ )
{
size->cvt[i] = FT_MulFix( face->cvt[i], size->ttmetrics.scale );
FT_TRACE6(( " %3d: %d (%f)\n",
i, face->cvt[i], size->cvt[i] / 64.0 ));
}
FT_TRACE6(( "\n" ));
/* all twilight points are originally zero */
for ( i = 0; i < (FT_UInt)size->twilight.n_points; i++ )
{

View file

@ -352,12 +352,12 @@
goto Exit;
{
FT_Short* cur = face->cvt;
FT_Short* limit = cur + face->cvt_size;
FT_Int32* cur = face->cvt;
FT_Int32* limit = cur + face->cvt_size;
for ( ; cur < limit; cur++ )
*cur = FT_GET_SHORT();
*cur = FT_GET_SHORT() * 64;
}
FT_FRAME_EXIT();

View file

@ -70,8 +70,8 @@
static FT_UInt
t1_get_name_index( T1_Face face,
FT_String* glyph_name )
t1_get_name_index( T1_Face face,
const FT_String* glyph_name )
{
FT_Int i;

View file

@ -1507,12 +1507,7 @@
/* We need to `zero' out encoding_table.elements */
for ( n = 0; n < array_size; n++ )
{
char* notdef = (char *)".notdef";
(void)T1_Add_Table( char_table, n, notdef, 8 );
}
(void)T1_Add_Table( char_table, n, ".notdef", 8 );
/* Now we need to read records of the form */
/* */
@ -2147,7 +2142,6 @@
/* 0 333 hsbw endchar */
FT_Byte notdef_glyph[] = { 0x8B, 0xF7, 0xE1, 0x0D, 0x0E };
char* notdef_name = (char *)".notdef";
error = T1_Add_Table( swap_table, 0,
@ -2162,7 +2156,7 @@
if ( error )
goto Fail;
error = T1_Add_Table( name_table, 0, notdef_name, 8 );
error = T1_Add_Table( name_table, 0, ".notdef", 8 );
if ( error )
goto Fail;
@ -2633,8 +2627,7 @@
/* we must now build type1.encoding when we have a custom array */
if ( type1->encoding_type == T1_ENCODING_TYPE_ARRAY )
{
FT_Int charcode, idx, min_char, max_char;
FT_Byte* glyph_name;
FT_Int charcode, idx, min_char, max_char;
/* OK, we do the following: for each element in the encoding */
@ -2648,27 +2641,27 @@
charcode = 0;
for ( ; charcode < loader.encoding_table.max_elems; charcode++ )
{
FT_Byte* char_name;
const FT_String* char_name =
(const FT_String*)loader.encoding_table.elements[charcode];
type1->encoding.char_index[charcode] = 0;
type1->encoding.char_name [charcode] = (char *)".notdef";
type1->encoding.char_name [charcode] = ".notdef";
char_name = loader.encoding_table.elements[charcode];
if ( char_name )
for ( idx = 0; idx < type1->num_glyphs; idx++ )
{
glyph_name = (FT_Byte*)type1->glyph_names[idx];
if ( ft_strcmp( (const char*)char_name,
(const char*)glyph_name ) == 0 )
const FT_String* glyph_name = type1->glyph_names[idx];
if ( ft_strcmp( char_name, glyph_name ) == 0 )
{
type1->encoding.char_index[charcode] = (FT_UShort)idx;
type1->encoding.char_name [charcode] = (char*)glyph_name;
type1->encoding.char_name [charcode] = glyph_name;
/* Change min/max encoded char only if glyph name is */
/* not /.notdef */
if ( ft_strcmp( (const char*)".notdef",
(const char*)glyph_name ) != 0 )
if ( ft_strcmp( ".notdef", glyph_name ) != 0 )
{
if ( charcode < min_char )
min_char = charcode;

View file

@ -69,8 +69,8 @@
static FT_UInt
t42_get_name_index( T42_Face face,
FT_String* glyph_name )
t42_get_name_index( T42_Face face,
const FT_String* glyph_name )
{
FT_Int i;

View file

@ -98,8 +98,7 @@
/* we must now build type1.encoding when we have a custom array */
if ( type1->encoding_type == T1_ENCODING_TYPE_ARRAY )
{
FT_Int charcode, idx, min_char, max_char;
FT_Byte* glyph_name;
FT_Int charcode, idx, min_char, max_char;
/* OK, we do the following: for each element in the encoding */
@ -114,27 +113,27 @@
charcode = 0;
for ( ; charcode < loader.encoding_table.max_elems; charcode++ )
{
FT_Byte* char_name;
const FT_String* char_name =
(const FT_String*)loader.encoding_table.elements[charcode];
type1->encoding.char_index[charcode] = 0;
type1->encoding.char_name [charcode] = (char *)".notdef";
type1->encoding.char_name [charcode] = ".notdef";
char_name = loader.encoding_table.elements[charcode];
if ( char_name )
for ( idx = 0; idx < type1->num_glyphs; idx++ )
{
glyph_name = (FT_Byte*)type1->glyph_names[idx];
if ( ft_strcmp( (const char*)char_name,
(const char*)glyph_name ) == 0 )
const FT_String* glyph_name = type1->glyph_names[idx];
if ( ft_strcmp( char_name, glyph_name ) == 0 )
{
type1->encoding.char_index[charcode] = (FT_UShort)idx;
type1->encoding.char_name [charcode] = (char*)glyph_name;
type1->encoding.char_name [charcode] = glyph_name;
/* Change min/max encoded char only if glyph name is */
/* not /.notdef */
if ( ft_strcmp( (const char*)".notdef",
(const char*)glyph_name ) != 0 )
if ( ft_strcmp( ".notdef", glyph_name ) != 0 )
{
if ( charcode < min_char )
min_char = charcode;

View file

@ -226,7 +226,8 @@
if ( !parser->in_memory )
FT_FREE( parser->base_dict );
parser->root.funcs.done( &parser->root );
if ( parser->root.funcs.done )
parser->root.funcs.done( &parser->root );
}
@ -373,12 +374,7 @@
/* We need to `zero' out encoding_table.elements */
for ( n = 0; n < count; n++ )
{
char* notdef = (char *)".notdef";
(void)T1_Add_Table( char_table, n, notdef, 8 );
}
(void)T1_Add_Table( char_table, n, ".notdef", 8 );
/* Now we need to read records of the form */
/* */
@ -1021,8 +1017,7 @@
}
/* if /.notdef does not occupy index 0, do our magic. */
if ( ft_strcmp( (const char*)".notdef",
(const char*)name_table->elements[0] ) )
if ( ft_strcmp( ".notdef", (const char*)name_table->elements[0] ) )
{
/* Swap glyph in index 0 with /.notdef glyph. First, add index 0 */
/* name and code entries to swap_table. Then place notdef_index */