diff options
author | Lei Zhang <thestig@chromium.org> | 2017-03-29 21:02:13 -0700 |
---|---|---|
committer | Chromium commit bot <commit-bot@chromium.org> | 2017-03-30 04:15:13 +0000 |
commit | 3de5005b3013bc7f9b62bc2153786de90a3cc285 (patch) | |
tree | 20a2514fef275a461ae1ac17a14356406f426a63 /third_party/freetype/src/base | |
parent | 75b11e43c284ff80bf49a3c1a0980353b942ff89 (diff) | |
download | pdfium-3de5005b3013bc7f9b62bc2153786de90a3cc285.tar.xz |
Upgrade to FreeType 2.7.1.
BUG=pdfium:601
Change-Id: I07756cd208cd2221802ff2d331f316b6618a41e0
Reviewed-on: https://pdfium-review.googlesource.com/3120
Commit-Queue: Lei Zhang <thestig@chromium.org>
Reviewed-by: dsinclair <dsinclair@chromium.org>
Diffstat (limited to 'third_party/freetype/src/base')
26 files changed, 1127 insertions, 269 deletions
diff --git a/third_party/freetype/src/base/basepic.c b/third_party/freetype/src/base/basepic.c index 9850ed96a4..57fb8169ad 100644 --- a/third_party/freetype/src/base/basepic.c +++ b/third_party/freetype/src/base/basepic.c @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services for base. */ /* */ -/* Copyright 2009-2015 by */ +/* Copyright 2009-2017 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/third_party/freetype/src/base/basepic.h b/third_party/freetype/src/base/basepic.h index c5d7cbf5ab..258d4ce2ba 100644 --- a/third_party/freetype/src/base/basepic.h +++ b/third_party/freetype/src/base/basepic.h @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services for base. */ /* */ -/* Copyright 2009-2015 by */ +/* Copyright 2009-2017 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __BASEPIC_H__ -#define __BASEPIC_H__ +#ifndef BASEPIC_H_ +#define BASEPIC_H_ #include FT_INTERNAL_PIC_H @@ -85,7 +85,7 @@ FT_END_HEADER /* */ -#endif /* __BASEPIC_H__ */ +#endif /* BASEPIC_H_ */ /* END */ diff --git a/third_party/freetype/src/base/ftadvanc.c b/third_party/freetype/src/base/ftadvanc.c index f12908f518..1557607fc5 100644 --- a/third_party/freetype/src/base/ftadvanc.c +++ b/third_party/freetype/src/base/ftadvanc.c @@ -4,7 +4,7 @@ /* */ /* Quick computation of advance widths (body). */ /* */ -/* Copyright 2008-2015 by */ +/* Copyright 2008-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -36,7 +36,7 @@ if ( flags & FT_LOAD_NO_SCALE ) return FT_Err_Ok; - if ( face->size == NULL ) + if ( !face->size ) return FT_THROW( Invalid_Size_Handle ); if ( flags & FT_LOAD_VERTICAL_LAYOUT ) @@ -60,8 +60,11 @@ /* - unscaled load */ /* - unhinted load */ /* - light-hinted load */ + /* - if a variations font, it must have an `HVAR' or `VVAR' */ + /* table (thus the old MM or GX fonts don't qualify; this */ + /* gets checked by the driver-specific functions) */ -#define LOAD_ADVANCE_FAST_CHECK( flags ) \ +#define LOAD_ADVANCE_FAST_CHECK( face, flags ) \ ( flags & ( FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING ) || \ FT_LOAD_TARGET_MODE( flags ) == FT_RENDER_MODE_LIGHT ) @@ -87,7 +90,7 @@ return FT_THROW( Invalid_Glyph_Index ); func = face->driver->clazz->get_advances; - if ( func && LOAD_ADVANCE_FAST_CHECK( flags ) ) + if ( func && LOAD_ADVANCE_FAST_CHECK( face, flags ) ) { FT_Error error; @@ -133,7 +136,7 @@ return FT_Err_Ok; func = face->driver->clazz->get_advances; - if ( func && LOAD_ADVANCE_FAST_CHECK( flags ) ) + if ( func && LOAD_ADVANCE_FAST_CHECK( face, flags ) ) { error = func( face, start, count, flags, padvances ); if ( !error ) @@ -157,8 +160,8 @@ /* scale from 26.6 to 16.16 */ padvances[nn] = ( flags & FT_LOAD_VERTICAL_LAYOUT ) - ? face->glyph->advance.y << 10 - : face->glyph->advance.x << 10; + ? face->glyph->advance.y * 1024 + : face->glyph->advance.x * 1024; } return error; diff --git a/third_party/freetype/src/base/ftbase.c b/third_party/freetype/src/base/ftbase.c index 253dfb7236..993ac72286 100644 --- a/third_party/freetype/src/base/ftbase.c +++ b/third_party/freetype/src/base/ftbase.c @@ -4,7 +4,7 @@ /* */ /* Single object library component (body only). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -26,6 +26,7 @@ #include "ftcalc.c" #include "ftdbgmem.c" #include "ftgloadr.c" +#include "fthash.c" #include "ftobjs.c" #include "ftoutln.c" #include "ftrfork.c" diff --git a/third_party/freetype/src/base/ftbase.h b/third_party/freetype/src/base/ftbase.h index e37fefa411..2072284f06 100644 --- a/third_party/freetype/src/base/ftbase.h +++ b/third_party/freetype/src/base/ftbase.h @@ -4,7 +4,7 @@ /* */ /* The FreeType private functions used in base module (specification). */ /* */ -/* Copyright 2008-2015 by */ +/* Copyright 2008-2017 by */ /* David Turner, Robert Wilhelm, Werner Lemberg, and suzuki toshiya. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTBASE_H__ -#define __FTBASE_H__ +#ifndef FTBASE_H_ +#define FTBASE_H_ #include <ft2build.h> @@ -68,7 +68,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTBASE_H__ */ +#endif /* FTBASE_H_ */ /* END */ diff --git a/third_party/freetype/src/base/ftbitmap.c b/third_party/freetype/src/base/ftbitmap.c index a54572aaa2..88c88c4c1b 100644 --- a/third_party/freetype/src/base/ftbitmap.c +++ b/third_party/freetype/src/base/ftbitmap.c @@ -4,7 +4,7 @@ /* */ /* FreeType utility functions for bitmaps (body). */ /* */ -/* Copyright 2004-2015 by */ +/* Copyright 2004-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -76,7 +76,7 @@ source_pitch_sign = source->pitch < 0 ? -1 : 1; target_pitch_sign = target->pitch < 0 ? -1 : 1; - if ( source->buffer == NULL ) + if ( !source->buffer ) { *target = *source; if ( source_pitch_sign != target_pitch_sign ) @@ -351,7 +351,7 @@ } /* for each row */ - for ( y = 0; y < bitmap->rows ; y++ ) + for ( y = 0; y < bitmap->rows; y++ ) { /* * Horizontally: diff --git a/third_party/freetype/src/base/ftcalc.c b/third_party/freetype/src/base/ftcalc.c index 619a08b3a0..f0525502f3 100644 --- a/third_party/freetype/src/base/ftcalc.c +++ b/third_party/freetype/src/base/ftcalc.c @@ -4,7 +4,7 @@ /* */ /* Arithmetic computations (body). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -233,7 +233,7 @@ { #ifdef FT_MULFIX_ASSEMBLER - return FT_MULFIX_ASSEMBLER( a_, b_ ); + return FT_MULFIX_ASSEMBLER( (FT_Int32)a_, (FT_Int32)b_ ); #else @@ -449,8 +449,8 @@ FT_Add64( &temp, &temp2, &temp ); /* last attempt to ditch long division */ - a = temp.hi == 0 ? temp.lo / c - : ft_div64by32( temp.hi, temp.lo, c ); + a = ( temp.hi == 0 ) ? temp.lo / c + : ft_div64by32( temp.hi, temp.lo, c ); } a_ = (FT_Long)a; @@ -492,8 +492,8 @@ ft_multo64( a, b, &temp ); /* last attempt to ditch long division */ - a = temp.hi == 0 ? temp.lo / c - : ft_div64by32( temp.hi, temp.lo, c ); + a = ( temp.hi == 0 ) ? temp.lo / c + : ft_div64by32( temp.hi, temp.lo, c ); } a_ = (FT_Long)a; diff --git a/third_party/freetype/src/base/ftdbgmem.c b/third_party/freetype/src/base/ftdbgmem.c index 6f20313b34..242246bfd1 100644 --- a/third_party/freetype/src/base/ftdbgmem.c +++ b/third_party/freetype/src/base/ftdbgmem.c @@ -4,7 +4,7 @@ /* */ /* Memory debugger (body). */ /* */ -/* Copyright 2001-2015 by */ +/* Copyright 2001-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -268,7 +268,7 @@ ft_mem_table_alloc( table, new_size * (FT_Long)sizeof ( FT_MemNode ) ); - if ( new_buckets == NULL ) + if ( !new_buckets ) return; FT_ARRAY_ZERO( new_buckets, new_size ); @@ -309,7 +309,7 @@ table = (FT_MemTable)memory->alloc( memory, sizeof ( *table ) ); - if ( table == NULL ) + if ( !table ) goto Exit; FT_ZERO( table ); @@ -367,7 +367,8 @@ { printf( "leaked memory block at address %p, size %8ld in (%s:%ld)\n", - node->address, node->size, + (void*)node->address, + node->size, FT_FILENAME( node->source->file_name ), node->source->line_no ); @@ -462,10 +463,10 @@ (FT_UInt32)( 5 * _ft_debug_lineno ); pnode = &table->sources[hash % FT_MEM_SOURCE_BUCKETS]; - for ( ;; ) + for (;;) { node = *pnode; - if ( node == NULL ) + if ( !node ) break; if ( node->file_name == _ft_debug_file && @@ -476,7 +477,7 @@ } node = (FT_MemSource)ft_mem_table_alloc( table, sizeof ( *node ) ); - if ( node == NULL ) + if ( !node ) ft_mem_debug_panic( "not enough memory to perform memory debugging\n" ); @@ -544,7 +545,7 @@ /* we need to create a new node in this table */ node = (FT_MemNode)ft_mem_table_alloc( table, sizeof ( *node ) ); - if ( node == NULL ) + if ( !node ) ft_mem_debug_panic( "not enough memory to run memory tests" ); node->address = address; @@ -716,7 +717,7 @@ FT_MemTable table = (FT_MemTable)memory->user; - if ( block == NULL ) + if ( !block ) ft_mem_debug_panic( "trying to free NULL in (%s:%ld)", FT_FILENAME( _ft_debug_file ), _ft_debug_lineno ); @@ -754,7 +755,7 @@ /* the following is valid according to ANSI C */ #if 0 - if ( block == NULL || cur_size == 0 ) + if ( !block || !cur_size ) ft_mem_debug_panic( "trying to reallocate NULL in (%s:%ld)", file_name, line_no ); #endif @@ -798,7 +799,7 @@ return NULL; new_block = (FT_Pointer)ft_mem_table_alloc( table, new_size ); - if ( new_block == NULL ) + if ( !new_block ) return NULL; ft_mem_table_set( table, (FT_Byte*)new_block, new_size, delta ); @@ -839,9 +840,9 @@ memory->free = ft_mem_debug_free; p = getenv( "FT2_ALLOC_TOTAL_MAX" ); - if ( p != NULL ) + if ( p ) { - FT_Long total_max = ft_atol( p ); + FT_Long total_max = ft_strtol( p, NULL, 10 ); if ( total_max > 0 ) @@ -852,9 +853,9 @@ } p = getenv( "FT2_ALLOC_COUNT_MAX" ); - if ( p != NULL ) + if ( p ) { - FT_Long total_count = ft_atol( p ); + FT_Long total_count = ft_strtol( p, NULL, 10 ); if ( total_count > 0 ) @@ -865,9 +866,9 @@ } p = getenv( "FT2_KEEP_ALIVE" ); - if ( p != NULL ) + if ( p ) { - FT_Long keep_alive = ft_atol( p ); + FT_Long keep_alive = ft_strtol( p, NULL, 10 ); if ( keep_alive > 0 ) diff --git a/third_party/freetype/src/base/ftfntfmt.c b/third_party/freetype/src/base/ftfntfmt.c index 98e7431a2b..dcbeba0053 100644 --- a/third_party/freetype/src/base/ftfntfmt.c +++ b/third_party/freetype/src/base/ftfntfmt.c @@ -4,7 +4,7 @@ /* */ /* FreeType utility file for font formats (body). */ /* */ -/* Copyright 2002-2015 by */ +/* Copyright 2002-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/third_party/freetype/src/base/ftfstype.c b/third_party/freetype/src/base/ftfstype.c index cd3458f73e..cec4fb3025 100644 --- a/third_party/freetype/src/base/ftfstype.c +++ b/third_party/freetype/src/base/ftfstype.c @@ -4,7 +4,7 @@ /* */ /* FreeType utility file to access FSType data (body). */ /* */ -/* Copyright 2008-2015 by */ +/* Copyright 2008-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/third_party/freetype/src/base/ftgloadr.c b/third_party/freetype/src/base/ftgloadr.c index 7e28638b27..8134003b4b 100644 --- a/third_party/freetype/src/base/ftgloadr.c +++ b/third_party/freetype/src/base/ftgloadr.c @@ -4,7 +4,7 @@ /* */ /* The FreeType glyph loader (body). */ /* */ -/* Copyright 2002-2015 by */ +/* Copyright 2002-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/third_party/freetype/src/base/ftglyph.c b/third_party/freetype/src/base/ftglyph.c index cb7fc37787..9bfb330508 100644 --- a/third_party/freetype/src/base/ftglyph.c +++ b/third_party/freetype/src/base/ftglyph.c @@ -4,7 +4,7 @@ /* */ /* FreeType convenience functions to handle glyphs (body). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -125,23 +125,25 @@ FT_BitmapGlyph glyph = (FT_BitmapGlyph)bitmap_glyph; - cbox->xMin = glyph->left << 6; - cbox->xMax = cbox->xMin + (FT_Pos)( glyph->bitmap.width << 6 ); - cbox->yMax = glyph->top << 6; - cbox->yMin = cbox->yMax - (FT_Pos)( glyph->bitmap.rows << 6 ); + cbox->xMin = glyph->left * 64; + cbox->xMax = cbox->xMin + (FT_Pos)( glyph->bitmap.width * 64 ); + cbox->yMax = glyph->top * 64; + cbox->yMin = cbox->yMax - (FT_Pos)( glyph->bitmap.rows * 64 ); } - FT_DEFINE_GLYPH(ft_bitmap_glyph_class, + FT_DEFINE_GLYPH( + ft_bitmap_glyph_class, + sizeof ( FT_BitmapGlyphRec ), FT_GLYPH_FORMAT_BITMAP, - ft_bitmap_glyph_init, - ft_bitmap_glyph_done, - ft_bitmap_glyph_copy, - 0, /* FT_Glyph_TransformFunc */ - ft_bitmap_glyph_bbox, - 0 /* FT_Glyph_PrepareFunc */ + ft_bitmap_glyph_init, /* FT_Glyph_InitFunc glyph_init */ + ft_bitmap_glyph_done, /* FT_Glyph_DoneFunc glyph_done */ + ft_bitmap_glyph_copy, /* FT_Glyph_CopyFunc glyph_copy */ + NULL, /* FT_Glyph_TransformFunc glyph_transform */ + ft_bitmap_glyph_bbox, /* FT_Glyph_GetBBoxFunc glyph_bbox */ + NULL /* FT_Glyph_PrepareFunc glyph_prepare */ ) @@ -260,16 +262,18 @@ } - FT_DEFINE_GLYPH( ft_outline_glyph_class, + FT_DEFINE_GLYPH( + ft_outline_glyph_class, + sizeof ( FT_OutlineGlyphRec ), FT_GLYPH_FORMAT_OUTLINE, - ft_outline_glyph_init, - ft_outline_glyph_done, - ft_outline_glyph_copy, - ft_outline_glyph_transform, - ft_outline_glyph_bbox, - ft_outline_glyph_prepare + ft_outline_glyph_init, /* FT_Glyph_InitFunc glyph_init */ + ft_outline_glyph_done, /* FT_Glyph_DoneFunc glyph_done */ + ft_outline_glyph_copy, /* FT_Glyph_CopyFunc glyph_copy */ + ft_outline_glyph_transform, /* FT_Glyph_TransformFunc glyph_transform */ + ft_outline_glyph_bbox, /* FT_Glyph_GetBBoxFunc glyph_bbox */ + ft_outline_glyph_prepare /* FT_Glyph_PrepareFunc glyph_prepare */ ) @@ -403,9 +407,9 @@ if ( error ) goto Exit; - /* copy advance while converting it to 16.16 format */ - glyph->advance.x = slot->advance.x << 10; - glyph->advance.y = slot->advance.y << 10; + /* copy advance while converting 26.6 to 16.16 format */ + glyph->advance.x = slot->advance.x * 1024; + glyph->advance.y = slot->advance.y * 1024; /* now import the image from the glyph slot */ error = clazz->glyph_init( glyph, slot ); @@ -542,8 +546,8 @@ /* we render the glyph into a glyph bitmap using a `dummy' glyph slot */ /* then calling FT_Render_Glyph_Internal() */ - FT_MEM_ZERO( &dummy, sizeof ( dummy ) ); - FT_MEM_ZERO( &dummy_internal, sizeof ( dummy_internal ) ); + FT_ZERO( &dummy ); + FT_ZERO( &dummy_internal ); dummy.internal = &dummy_internal; dummy.library = library; dummy.format = clazz->glyph_format; diff --git a/third_party/freetype/src/base/fthash.c b/third_party/freetype/src/base/fthash.c new file mode 100644 index 0000000000..21bc8dd5b4 --- /dev/null +++ b/third_party/freetype/src/base/fthash.c @@ -0,0 +1,339 @@ +/***************************************************************************/ +/* */ +/* fthash.c */ +/* */ +/* Hashing functions (body). */ +/* */ +/***************************************************************************/ + +/* + * Copyright 2000 Computing Research Labs, New Mexico State University + * Copyright 2001-2015 + * Francesco Zappa Nardelli + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COMPUTING RESEARCH LAB OR NEW MEXICO STATE UNIVERSITY BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT + * OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR + * THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + /*************************************************************************/ + /* */ + /* This file is based on code from bdf.c,v 1.22 2000/03/16 20:08:50 */ + /* */ + /* taken from Mark Leisher's xmbdfed package */ + /* */ + /*************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_HASH_H +#include FT_INTERNAL_MEMORY_H + + +#define INITIAL_HT_SIZE 241 + + + static FT_ULong + hash_str_lookup( FT_Hashkey* key ) + { + const char* kp = key->str; + FT_ULong res = 0; + + + /* Mocklisp hash function. */ + while ( *kp ) + res = ( res << 5 ) - res + (FT_ULong)*kp++; + + return res; + } + + + static FT_ULong + hash_num_lookup( FT_Hashkey* key ) + { + FT_ULong num = (FT_ULong)key->num; + FT_ULong res; + + + /* Mocklisp hash function. */ + res = num & 0xFF; + res = ( res << 5 ) - res + ( ( num >> 8 ) & 0xFF ); + res = ( res << 5 ) - res + ( ( num >> 16 ) & 0xFF ); + res = ( res << 5 ) - res + ( ( num >> 24 ) & 0xFF ); + + return res; + } + + + static FT_Bool + hash_str_compare( FT_Hashkey* a, + FT_Hashkey* b ) + { + if ( a->str[0] == b->str[0] && + ft_strcmp( a->str, b->str ) == 0 ) + return 1; + + return 0; + } + + + static FT_Bool + hash_num_compare( FT_Hashkey* a, + FT_Hashkey* b ) + { + if ( a->num == b->num ) + return 1; + + return 0; + } + + + static FT_Hashnode* + hash_bucket( FT_Hashkey key, + FT_Hash hash ) + { + FT_ULong res = 0; + FT_Hashnode* bp = hash->table; + FT_Hashnode* ndp; + + + res = (hash->lookup)( &key ); + + ndp = bp + ( res % hash->size ); + while ( *ndp ) + { + if ( (hash->compare)( &(*ndp)->key, &key ) ) + break; + + ndp--; + if ( ndp < bp ) + ndp = bp + ( hash->size - 1 ); + } + + return ndp; + } + + + static FT_Error + hash_rehash( FT_Hash hash, + FT_Memory memory ) + { + FT_Hashnode* obp = hash->table; + FT_Hashnode* bp; + FT_Hashnode* nbp; + + FT_UInt i, sz = hash->size; + FT_Error error = FT_Err_Ok; + + + hash->size <<= 1; + hash->limit = hash->size / 3; + + if ( FT_NEW_ARRAY( hash->table, hash->size ) ) + goto Exit; + + for ( i = 0, bp = obp; i < sz; i++, bp++ ) + { + if ( *bp ) + { + nbp = hash_bucket( (*bp)->key, hash ); + *nbp = *bp; + } + } + + FT_FREE( obp ); + + Exit: + return error; + } + + + static FT_Error + hash_init( FT_Hash hash, + FT_Bool is_num, + FT_Memory memory ) + { + FT_UInt sz = INITIAL_HT_SIZE; + FT_Error error; + + + hash->size = sz; + hash->limit = sz / 3; + hash->used = 0; + + if ( is_num ) + { + hash->lookup = hash_num_lookup; + hash->compare = hash_num_compare; + } + else + { + hash->lookup = hash_str_lookup; + hash->compare = hash_str_compare; + } + + FT_MEM_NEW_ARRAY( hash->table, sz ); + + return error; + } + + + FT_Error + ft_hash_str_init( FT_Hash hash, + FT_Memory memory ) + { + return hash_init( hash, 0, memory ); + } + + + FT_Error + ft_hash_num_init( FT_Hash hash, + FT_Memory memory ) + { + return hash_init( hash, 1, memory ); + } + + + void + ft_hash_str_free( FT_Hash hash, + FT_Memory memory ) + { + if ( hash ) + { + FT_UInt sz = hash->size; + FT_Hashnode* bp = hash->table; + FT_UInt i; + + + for ( i = 0; i < sz; i++, bp++ ) + FT_FREE( *bp ); + + FT_FREE( hash->table ); + } + } + + + /* `ft_hash_num_free' is the same as `ft_hash_str_free' */ + + + static FT_Error + hash_insert( FT_Hashkey key, + size_t data, + FT_Hash hash, + FT_Memory memory ) + { + FT_Hashnode nn; + FT_Hashnode* bp = hash_bucket( key, hash ); + FT_Error error = FT_Err_Ok; + + + nn = *bp; + if ( !nn ) + { + if ( FT_NEW( nn ) ) + goto Exit; + *bp = nn; + + nn->key = key; + nn->data = data; + + if ( hash->used >= hash->limit ) + { + error = hash_rehash( hash, memory ); + if ( error ) + goto Exit; + } + + hash->used++; + } + else + nn->data = data; + + Exit: + return error; + } + + + FT_Error + ft_hash_str_insert( const char* key, + size_t data, + FT_Hash hash, + FT_Memory memory ) + { + FT_Hashkey hk; + + + hk.str = key; + + return hash_insert( hk, data, hash, memory ); + } + + + FT_Error + ft_hash_num_insert( FT_Int num, + size_t data, + FT_Hash hash, + FT_Memory memory ) + { + FT_Hashkey hk; + + + hk.num = num; + + return hash_insert( hk, data, hash, memory ); + } + + + static size_t* + hash_lookup( FT_Hashkey key, + FT_Hash hash ) + { + FT_Hashnode* np = hash_bucket( key, hash ); + + + return (*np) ? &(*np)->data + : NULL; + } + + + size_t* + ft_hash_str_lookup( const char* key, + FT_Hash hash ) + { + FT_Hashkey hk; + + + hk.str = key; + + return hash_lookup( hk, hash ); + } + + + size_t* + ft_hash_num_lookup( FT_Int num, + FT_Hash hash ) + { + FT_Hashkey hk; + + + hk.num = num; + + return hash_lookup( hk, hash ); + } + + +/* END */ diff --git a/third_party/freetype/src/base/ftinit.c b/third_party/freetype/src/base/ftinit.c index b65a91d06c..1c4b76f567 100644 --- a/third_party/freetype/src/base/ftinit.c +++ b/third_party/freetype/src/base/ftinit.c @@ -4,7 +4,7 @@ /* */ /* FreeType initialization layer (body). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -226,6 +226,115 @@ } +#ifdef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES + +#define MAX_LENGTH 128 + + /* + * Set default properties derived from the `FREETYPE_PROPERTIES' + * environment variable. + * + * `FREETYPE_PROPERTIES' has the following syntax form (broken here into + * multiple lines for better readability) + * + * <optional whitespace> + * <module-name1> ':' + * <property-name1> '=' <property-value1> + * <whitespace> + * <module-name2> ':' + * <property-name2> '=' <property-value2> + * ... + * + * Example: + * + * FREETYPE_PROPERTIES=truetype:interpreter-version=35 \ + * cff:no-stem-darkening=1 \ + * autofitter:warping=1 + * + */ + + static void + ft_set_default_properties( FT_Library library ) + { + const char* env; + const char* p; + const char* q; + + char module_name[MAX_LENGTH + 1]; + char property_name[MAX_LENGTH + 1]; + char property_value[MAX_LENGTH + 1]; + + int i; + + + env = ft_getenv( "FREETYPE_PROPERTIES" ); + if ( !env ) + return; + + for ( p = env; *p; p++ ) + { + /* skip leading whitespace and separators */ + if ( *p == ' ' || *p == '\t' ) + continue; + + /* read module name, followed by `:' */ + q = p; + for ( i = 0; i < MAX_LENGTH; i++ ) + { + if ( !*p || *p == ':' ) + break; + module_name[i] = *p++; + } + module_name[i] = '\0'; + + if ( !*p || *p != ':' || p == q ) + break; + + /* read property name, followed by `=' */ + q = ++p; + for ( i = 0; i < MAX_LENGTH; i++ ) + { + if ( !*p || *p == '=' ) + break; + property_name[i] = *p++; + } + property_name[i] = '\0'; + + if ( !*p || *p != '=' || p == q ) + break; + + /* read property value, followed by whitespace (if any) */ + q = ++p; + for ( i = 0; i < MAX_LENGTH; i++ ) + { + if ( !*p || *p == ' ' || *p == '\t' ) + break; + property_value[i] = *p++; + } + property_value[i] = '\0'; + + if ( !( *p == '\0' || *p == ' ' || *p == '\t' ) || p == q ) + break; + + /* we completely ignore errors */ + ft_property_string_set( library, + module_name, + property_name, + property_value ); + } + } + +#else + + static void + ft_set_default_properties( FT_Library library ) + { + FT_UNUSED( library ); + } + +#endif + + /* documentation is in freetype.h */ FT_EXPORT_DEF( FT_Error ) @@ -256,6 +365,8 @@ else FT_Add_Default_Modules( *alibrary ); + ft_set_default_properties( *alibrary ); + return error; } diff --git a/third_party/freetype/src/base/ftlcdfil.c b/third_party/freetype/src/base/ftlcdfil.c index ff6f7e98ce..f8e1709e92 100644 --- a/third_party/freetype/src/base/ftlcdfil.c +++ b/third_party/freetype/src/base/ftlcdfil.c @@ -4,7 +4,7 @@ /* */ /* FreeType API for color filtering of subpixel bitmap glyphs (body). */ /* */ -/* Copyright 2006-2015 by */ +/* Copyright 2006-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -296,6 +296,8 @@ return FT_THROW( Invalid_Argument ); ft_memcpy( library->lcd_weights, weights, 5 ); + library->lcd_filter_func = _ft_lcd_filter_fir; + library->lcd_extra = 2; return FT_Err_Ok; } @@ -305,12 +307,10 @@ FT_Library_SetLcdFilter( FT_Library library, FT_LcdFilter filter ) { + static const FT_Byte default_filter[5] = + { 0x08, 0x4d, 0x56, 0x4d, 0x08 }; static const FT_Byte light_filter[5] = { 0x00, 0x55, 0x56, 0x55, 0x00 }; - /* the values here sum up to a value larger than 256, */ - /* providing a cheap gamma correction */ - static const FT_Byte default_filter[5] = - { 0x10, 0x40, 0x70, 0x40, 0x10 }; if ( !library ) @@ -324,25 +324,9 @@ break; case FT_LCD_FILTER_DEFAULT: -#if defined( FT_FORCE_LEGACY_LCD_FILTER ) - - library->lcd_filter_func = _ft_lcd_filter_legacy; - library->lcd_extra = 0; - -#elif defined( FT_FORCE_LIGHT_LCD_FILTER ) - - ft_memcpy( library->lcd_weights, light_filter, 5 ); - library->lcd_filter_func = _ft_lcd_filter_fir; - library->lcd_extra = 2; - -#else - ft_memcpy( library->lcd_weights, default_filter, 5 ); library->lcd_filter_func = _ft_lcd_filter_fir; library->lcd_extra = 2; - -#endif - break; case FT_LCD_FILTER_LIGHT: @@ -354,6 +338,7 @@ #ifdef USE_LEGACY case FT_LCD_FILTER_LEGACY: + case FT_LCD_FILTER_LEGACY1: library->lcd_filter_func = _ft_lcd_filter_legacy; library->lcd_extra = 0; break; diff --git a/third_party/freetype/src/base/ftmm.c b/third_party/freetype/src/base/ftmm.c index 7c012aa438..b8db3c5662 100644 --- a/third_party/freetype/src/base/ftmm.c +++ b/third_party/freetype/src/base/ftmm.c @@ -4,7 +4,7 @@ /* */ /* Multiple Master font support (body). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -22,6 +22,7 @@ #include FT_MULTIPLE_MASTERS_H #include FT_INTERNAL_OBJECTS_H #include FT_SERVICE_MULTIPLE_MASTERS_H +#include FT_SERVICE_METRICS_VARIATIONS_H /*************************************************************************/ @@ -62,6 +63,34 @@ } + static FT_Error + ft_face_get_mvar_service( FT_Face face, + FT_Service_MetricsVariations *aservice ) + { + FT_Error error; + + + *aservice = NULL; + + if ( !face ) + return FT_THROW( Invalid_Face_Handle ); + + error = FT_ERR( Invalid_Argument ); + + if ( FT_HAS_MULTIPLE_MASTERS( face ) ) + { + FT_FACE_LOOKUP_SERVICE( face, + *aservice, + METRICS_VARIATIONS ); + + if ( *aservice ) + error = FT_Err_Ok; + } + + return error; + } + + /* documentation is in ftmm.h */ FT_EXPORT_DEF( FT_Error ) @@ -140,6 +169,13 @@ error = service->set_mm_design( face, num_coords, coords ); } + /* enforce recomputation of auto-hinting data */ + if ( !error && face->autohint.finalizer ) + { + face->autohint.finalizer( face->autohint.data ); + face->autohint.data = NULL; + } + return error; } @@ -151,6 +187,49 @@ FT_UInt num_coords, FT_Fixed* coords ) { + FT_Error error; + FT_Service_MultiMasters service_mm; + FT_Service_MetricsVariations service_mvar; + + + /* check of `face' delayed to `ft_face_get_mm_service' */ + + if ( !coords ) + return FT_THROW( Invalid_Argument ); + + error = ft_face_get_mm_service( face, &service_mm ); + if ( !error ) + { + error = FT_ERR( Invalid_Argument ); + if ( service_mm->set_var_design ) + error = service_mm->set_var_design( face, num_coords, coords ); + } + + error = ft_face_get_mvar_service( face, &service_mvar ); + if ( !error ) + { + if ( service_mvar->metrics_adjust ) + service_mvar->metrics_adjust( face ); + } + + /* enforce recomputation of auto-hinting data */ + if ( !error && face->autohint.finalizer ) + { + face->autohint.finalizer( face->autohint.data ); + face->autohint.data = NULL; + } + + return error; + } + + + /* documentation is in ftmm.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Get_Var_Design_Coordinates( FT_Face face, + FT_UInt num_coords, + FT_Fixed* coords ) + { FT_Error error; FT_Service_MultiMasters service; @@ -164,8 +243,8 @@ if ( !error ) { error = FT_ERR( Invalid_Argument ); - if ( service->set_var_design ) - error = service->set_var_design( face, num_coords, coords ); + if ( service->get_var_design ) + error = service->get_var_design( face, num_coords, coords ); } return error; @@ -179,6 +258,95 @@ FT_UInt num_coords, FT_Fixed* coords ) { + FT_Error error; + FT_Service_MultiMasters service_mm; + FT_Service_MetricsVariations service_mvar; + + + /* check of `face' delayed to `ft_face_get_mm_service' */ + + if ( !coords ) + return FT_THROW( Invalid_Argument ); + + error = ft_face_get_mm_service( face, &service_mm ); + if ( !error ) + { + error = FT_ERR( Invalid_Argument ); + if ( service_mm->set_mm_blend ) + error = service_mm->set_mm_blend( face, num_coords, coords ); + } + + error = ft_face_get_mvar_service( face, &service_mvar ); + if ( !error ) + { + if ( service_mvar->metrics_adjust ) + service_mvar->metrics_adjust( face ); + } + + /* enforce recomputation of auto-hinting data */ + if ( !error && face->autohint.finalizer ) + { + face->autohint.finalizer( face->autohint.data ); + face->autohint.data = NULL; + } + + return error; + } + + + /* documentation is in ftmm.h */ + + /* This is exactly the same as the previous function. It exists for */ + /* orthogonality. */ + + FT_EXPORT_DEF( FT_Error ) + FT_Set_Var_Blend_Coordinates( FT_Face face, + FT_UInt num_coords, + FT_Fixed* coords ) + { + FT_Error error; + FT_Service_MultiMasters service_mm; + FT_Service_MetricsVariations service_mvar; + + + /* check of `face' delayed to `ft_face_get_mm_service' */ + + if ( !coords ) + return FT_THROW( Invalid_Argument ); + + error = ft_face_get_mm_service( face, &service_mm ); + if ( !error ) + { + error = FT_ERR( Invalid_Argument ); + if ( service_mm->set_mm_blend ) + error = service_mm->set_mm_blend( face, num_coords, coords ); + } + + error = ft_face_get_mvar_service( face, &service_mvar ); + if ( !error ) + { + if ( service_mvar->metrics_adjust ) + service_mvar->metrics_adjust( face ); + } + + /* enforce recomputation of auto-hinting data */ + if ( !error && face->autohint.finalizer ) + { + face->autohint.finalizer( face->autohint.data ); + face->autohint.data = NULL; + } + + return error; + } + + + /* documentation is in ftmm.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Get_MM_Blend_Coordinates( FT_Face face, + FT_UInt num_coords, + FT_Fixed* coords ) + { FT_Error error; FT_Service_MultiMasters service; @@ -192,8 +360,8 @@ if ( !error ) { error = FT_ERR( Invalid_Argument ); - if ( service->set_mm_blend ) - error = service->set_mm_blend( face, num_coords, coords ); + if ( service->get_mm_blend ) + error = service->get_mm_blend( face, num_coords, coords ); } return error; @@ -206,7 +374,7 @@ /* orthogonality. */ FT_EXPORT_DEF( FT_Error ) - FT_Set_Var_Blend_Coordinates( FT_Face face, + FT_Get_Var_Blend_Coordinates( FT_Face face, FT_UInt num_coords, FT_Fixed* coords ) { @@ -223,8 +391,8 @@ if ( !error ) { error = FT_ERR( Invalid_Argument ); - if ( service->set_mm_blend ) - error = service->set_mm_blend( face, num_coords, coords ); + if ( service->get_mm_blend ) + error = service->get_mm_blend( face, num_coords, coords ); } return error; diff --git a/third_party/freetype/src/base/ftobjs.c b/third_party/freetype/src/base/ftobjs.c index f0c2e77fcc..59d65e2a69 100644 --- a/third_party/freetype/src/base/ftobjs.c +++ b/third_party/freetype/src/base/ftobjs.c @@ -4,7 +4,7 @@ /* */ /* The FreeType private base classes (body). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -55,7 +55,18 @@ #pragma warning( disable : 4244 ) #endif /* _MSC_VER */ - /* it's easiest to include `md5.c' directly */ + /* It's easiest to include `md5.c' directly. However, since OpenSSL */ + /* also provides the same functions, there might be conflicts if */ + /* both FreeType and OpenSSL are built as static libraries. For */ + /* this reason, we put the MD5 stuff into the `FT_' namespace. */ +#define MD5_u32plus FT_MD5_u32plus +#define MD5_CTX FT_MD5_CTX +#define MD5_Init FT_MD5_Init +#define MD5_Update FT_MD5_Update +#define MD5_Final FT_MD5_Final + +#undef HAVE_OPENSSL + #include "md5.c" #if defined( _MSC_VER ) @@ -68,6 +79,15 @@ #define GRID_FIT_METRICS + /* forward declaration */ + static FT_Error + ft_open_face_internal( FT_Library library, + const FT_Open_Args* args, + FT_Long face_index, + FT_Face *aface, + FT_Bool test_mac_fonts ); + + FT_BASE_DEF( FT_Pointer ) ft_service_list_lookup( FT_ServiceDesc service_descriptors, const char* service_id ) @@ -442,7 +462,8 @@ Exit: - FT_TRACE4(( "FT_New_GlyphSlot: Return %d\n", error )); + FT_TRACE4(( "FT_New_GlyphSlot: Return 0x%x\n", error )); + return error; } @@ -630,6 +651,9 @@ load_flags &= ~FT_LOAD_RENDER; } + if ( load_flags & FT_LOAD_BITMAP_METRICS_ONLY ) + load_flags &= ~FT_LOAD_RENDER; + /* * Determine whether we need to auto-hint or not. * The general rules are: @@ -675,8 +699,8 @@ /* check the size of the `fpgm' and `prep' tables, too -- */ /* the assumption is that there don't exist real TTFs where */ /* both `fpgm' and `prep' tables are missing */ - if ( mode == FT_RENDER_MODE_LIGHT || - face->internal->ignore_unpatented_hinter || + if ( ( mode == FT_RENDER_MODE_LIGHT && + !FT_DRIVER_HINTS_LIGHTLY( driver ) ) || ( FT_IS_SFNT( face ) && ttface->num_locations && ttface->max_profile.maxSizeOfInstructions == 0 && @@ -1091,7 +1115,7 @@ end = first + face->num_charmaps; /* points after the last one */ - for ( cur = first; cur < end; ++cur ) + for ( cur = first; cur < end; cur++ ) { if ( cur[0]->platform_id == TT_PLATFORM_APPLE_UNICODE && cur[0]->encoding_id == TT_APPLE_ID_VARIANT_SELECTOR && @@ -1226,7 +1250,7 @@ args.pathname = (char*)pathname; args.stream = NULL; - return FT_Open_Face( library, &args, face_index, aface ); + return ft_open_face_internal( library, &args, face_index, aface, 1 ); } #endif @@ -1253,7 +1277,7 @@ args.memory_size = file_size; args.stream = NULL; - return FT_Open_Face( library, &args, face_index, aface ); + return ft_open_face_internal( library, &args, face_index, aface, 1 ); } @@ -1288,7 +1312,7 @@ /* Finalizer for a memory stream; gets called by FT_Done_Face(). */ /* It frees the memory it uses. */ - /* From ftmac.c. */ + /* From `ftmac.c'. */ static void memory_stream_close( FT_Stream stream ) { @@ -1304,7 +1328,7 @@ /* Create a new memory stream from a buffer and a size. */ - /* From ftmac.c. */ + /* From `ftmac.c'. */ static FT_Error new_memory_stream( FT_Library library, FT_Byte* base, @@ -1324,7 +1348,7 @@ return FT_THROW( Invalid_Argument ); *astream = NULL; - memory = library->memory; + memory = library->memory; if ( FT_NEW( stream ) ) goto Exit; @@ -1340,7 +1364,7 @@ /* Create a new FT_Face given a buffer and a driver name. */ - /* from ftmac.c */ + /* From `ftmac.c'. */ FT_LOCAL_DEF( FT_Error ) open_face_from_buffer( FT_Library library, FT_Byte* base, @@ -1366,11 +1390,11 @@ return error; } - args.flags = FT_OPEN_STREAM; + args.flags = FT_OPEN_STREAM; args.stream = stream; if ( driver_name ) { - args.flags = args.flags | FT_OPEN_DRIVER; + args.flags = args.flags | FT_OPEN_DRIVER; args.driver = FT_Get_Module( library, driver_name ); } @@ -1384,9 +1408,9 @@ face_index &= 0x7FFF0000L; /* retain GX data */ #endif - error = FT_Open_Face( library, &args, face_index, aface ); + error = ft_open_face_internal( library, &args, face_index, aface, 0 ); - if ( error == FT_Err_Ok ) + if ( !error ) (*aface)->face_flags &= ~FT_FACE_FLAG_EXTERNAL_STREAM; else #ifdef FT_MACINTOSH @@ -1407,7 +1431,7 @@ /* Type 1 and CID-keyed font drivers should recognize sfnt-wrapped */ /* format too. Here, since we can't expect that the TrueType font */ - /* driver is loaded unconditially, we must parse the font by */ + /* driver is loaded unconditionally, we must parse the font by */ /* ourselves. We are only interested in the name of the table and */ /* the offset. */ @@ -1472,6 +1496,7 @@ if ( face_index >= 0 && pstable_index == face_index ) return FT_Err_Ok; } + return FT_THROW( Table_Missing ); } @@ -1509,14 +1534,29 @@ if ( error ) goto Exit; - if ( FT_Stream_Seek( stream, pos + offset ) ) + if ( offset > stream->size ) + { + FT_TRACE2(( "open_face_PS_from_sfnt_stream: invalid table offset\n" )); + error = FT_THROW( Invalid_Table ); + goto Exit; + } + else if ( length > stream->size - offset ) + { + FT_TRACE2(( "open_face_PS_from_sfnt_stream: invalid table length\n" )); + error = FT_THROW( Invalid_Table ); + goto Exit; + } + + error = FT_Stream_Seek( stream, pos + offset ); + if ( error ) goto Exit; if ( FT_ALLOC( sfnt_ps, (FT_Long)length ) ) goto Exit; error = FT_Stream_Read( stream, (FT_Byte *)sfnt_ps, length ); - if ( error ) { + if ( error ) + { FT_FREE( sfnt_ps ); goto Exit; } @@ -1562,6 +1602,7 @@ { FT_Error error = FT_ERR( Cannot_Open_Resource ); FT_Memory memory = library->memory; + FT_Byte* pfb_data = NULL; int i, type, flags; FT_ULong len; @@ -1577,12 +1618,12 @@ /* Find the length of all the POST resources, concatenated. Assume */ /* worst case (each resource in its own section). */ pfb_len = 0; - for ( i = 0; i < resource_cnt; ++i ) + for ( i = 0; i < resource_cnt; i++ ) { error = FT_Stream_Seek( stream, (FT_ULong)offsets[i] ); if ( error ) goto Exit; - if ( FT_READ_ULONG( temp ) ) + if ( FT_READ_ULONG( temp ) ) /* actually LONG */ goto Exit; /* FT2 allocator takes signed long buffer length, @@ -1590,12 +1631,15 @@ */ FT_TRACE4(( " POST fragment #%d: length=0x%08x" " total pfb_len=0x%08x\n", - i, temp, pfb_len + temp + 6)); + i, temp, pfb_len + temp + 6 )); + if ( FT_MAC_RFORK_MAX_LEN < temp || FT_MAC_RFORK_MAX_LEN - temp < pfb_len + 6 ) { FT_TRACE2(( " MacOS resource length cannot exceed" - " 0x%08x\n", FT_MAC_RFORK_MAX_LEN )); + " 0x%08x\n", + FT_MAC_RFORK_MAX_LEN )); + error = FT_THROW( Invalid_Offset ); goto Exit; } @@ -1603,15 +1647,20 @@ pfb_len += temp + 6; } - FT_TRACE2(( " total buffer size to concatenate %d" - " POST fragments: 0x%08x\n", - resource_cnt, pfb_len + 2)); - if ( pfb_len + 2 < 6 ) { + FT_TRACE2(( " total buffer size to concatenate" + " %d POST fragments: 0x%08x\n", + resource_cnt, pfb_len + 2 )); + + if ( pfb_len + 2 < 6 ) + { FT_TRACE2(( " too long fragment length makes" - " pfb_len confused: pfb_len=0x%08x\n", pfb_len )); + " pfb_len confused: pfb_len=0x%08x\n", + pfb_len )); + error = FT_THROW( Array_Too_Large ); goto Exit; } + if ( FT_ALLOC( pfb_data, (FT_Long)pfb_len + 2 ) ) goto Exit; @@ -1624,9 +1673,10 @@ pfb_pos = 6; pfb_lenpos = 2; - len = 0; + len = 0; type = 1; - for ( i = 0; i < resource_cnt; ++i ) + + for ( i = 0; i < resource_cnt; i++ ) { error = FT_Stream_Seek( stream, (FT_ULong)offsets[i] ); if ( error ) @@ -1645,18 +1695,24 @@ if ( FT_READ_USHORT( flags ) ) goto Exit2; - FT_TRACE3(( "POST fragment[%d]: offsets=0x%08x, rlen=0x%08x, flags=0x%04x\n", - i, offsets[i], rlen, flags )); + + FT_TRACE3(( "POST fragment[%d]:" + " offsets=0x%08x, rlen=0x%08x, flags=0x%04x\n", + i, offsets[i], rlen, flags )); error = FT_ERR( Array_Too_Large ); - /* postpone the check of rlen longer than buffer until FT_Stream_Read() */ + + /* postpone the check of `rlen longer than buffer' */ + /* until `FT_Stream_Read' */ + if ( ( flags >> 8 ) == 0 ) /* Comment, should not be loaded */ { - FT_TRACE3(( " Skip POST fragment #%d because it is a comment\n", i )); + FT_TRACE3(( " Skip POST fragment #%d because it is a comment\n", + i )); continue; } - /* the flags are part of the resource, so rlen >= 2. */ + /* the flags are part of the resource, so rlen >= 2, */ /* but some fonts declare rlen = 0 for empty fragment */ if ( rlen > 2 ) rlen -= 2; @@ -1668,9 +1724,12 @@ else { FT_TRACE3(( " Write POST fragment #%d header (4-byte) to buffer" - " %p + 0x%08x\n", i, pfb_data, pfb_lenpos )); + " %p + 0x%08x\n", + i, pfb_data, pfb_lenpos )); + if ( pfb_lenpos + 3 > pfb_len + 2 ) goto Exit2; + pfb_data[pfb_lenpos ] = (FT_Byte)( len ); pfb_data[pfb_lenpos + 1] = (FT_Byte)( len >> 8 ); pfb_data[pfb_lenpos + 2] = (FT_Byte)( len >> 16 ); @@ -1680,13 +1739,16 @@ break; FT_TRACE3(( " Write POST fragment #%d header (6-byte) to buffer" - " %p + 0x%08x\n", i, pfb_data, pfb_pos )); + " %p + 0x%08x\n", + i, pfb_data, pfb_pos )); + if ( pfb_pos + 6 > pfb_len + 2 ) goto Exit2; + pfb_data[pfb_pos++] = 0x80; type = flags >> 8; - len = rlen; + len = rlen; pfb_data[pfb_pos++] = (FT_Byte)type; pfb_lenpos = pfb_pos; @@ -1700,14 +1762,18 @@ goto Exit2; FT_TRACE3(( " Load POST fragment #%d (%d byte) to buffer" - " %p + 0x%08x\n", i, rlen, pfb_data, pfb_pos )); + " %p + 0x%08x\n", + i, rlen, pfb_data, pfb_pos )); + error = FT_Stream_Read( stream, (FT_Byte *)pfb_data + pfb_pos, rlen ); if ( error ) goto Exit2; + pfb_pos += rlen; } error = FT_ERR( Array_Too_Large ); + if ( pfb_pos + 2 > pfb_len + 2 ) goto Exit2; pfb_data[pfb_pos++] = 0x80; @@ -1728,11 +1794,12 @@ aface ); Exit2: - if ( error == FT_ERR( Array_Too_Large ) ) + if ( FT_ERR_EQ( error, Array_Too_Large ) ) FT_TRACE2(( " Abort due to too-short buffer to store" " all POST fragments\n" )); - else if ( error == FT_ERR( Invalid_Offset ) ) + else if ( FT_ERR_EQ( error, Invalid_Offset ) ) FT_TRACE2(( " Abort due to invalid offset in a POST fragment\n" )); + if ( error ) error = FT_ERR( Cannot_Open_Resource ); FT_FREE( pfb_data ); @@ -1764,8 +1831,8 @@ FT_Long face_index_in_resource = 0; - if ( face_index == -1 ) - face_index = 0; + if ( face_index < 0 ) + face_index = -face_index - 1; if ( face_index >= resource_cnt ) return FT_THROW( Cannot_Open_Resource ); @@ -1776,7 +1843,7 @@ if ( FT_READ_LONG( rlen ) ) goto Exit; - if ( rlen == -1 ) + if ( rlen < 1 ) return FT_THROW( Cannot_Open_Resource ); if ( (FT_ULong)rlen > FT_MAC_RFORK_MAX_LEN ) return FT_THROW( Invalid_Offset ); @@ -1790,7 +1857,8 @@ goto Exit; /* rewind sfnt stream before open_face_PS_from_sfnt_stream() */ - if ( FT_Stream_Seek( stream, flag_offset + 4 ) ) + error = FT_Stream_Seek( stream, flag_offset + 4 ); + if ( error ) goto Exit; if ( FT_ALLOC( sfnt_data, rlen ) ) @@ -1828,19 +1896,19 @@ { FT_Memory memory = library->memory; FT_Error error; - FT_Long map_offset, rdara_pos; + FT_Long map_offset, rdata_pos; FT_Long *data_offsets; FT_Long count; error = FT_Raccess_Get_HeaderInfo( library, stream, resource_offset, - &map_offset, &rdara_pos ); + &map_offset, &rdata_pos ); if ( error ) return error; /* POST resources must be sorted to concatenate properly */ error = FT_Raccess_Get_DataOffsets( library, stream, - map_offset, rdara_pos, + map_offset, rdata_pos, TTAG_POST, TRUE, &data_offsets, &count ); if ( !error ) @@ -1857,7 +1925,7 @@ /* sfnt resources should not be sorted to preserve the face order by QuickDraw API */ error = FT_Raccess_Get_DataOffsets( library, stream, - map_offset, rdara_pos, + map_offset, rdata_pos, TTAG_sfnt, FALSE, &data_offsets, &count ); if ( !error ) @@ -1890,7 +1958,7 @@ FT_Long dlen, offset; - if ( NULL == stream ) + if ( !stream ) return FT_THROW( Invalid_Stream_Operation ); error = FT_Stream_Seek( stream, 0 ); @@ -1964,13 +2032,15 @@ { FT_TRACE3(( "Skip rule %d: darwin vfs resource fork" " is already checked and" - " no font is found\n", i )); + " no font is found\n", + i )); continue; } if ( errors[i] ) { - FT_TRACE3(( "Error[%d] has occurred in rule %d\n", errors[i], i )); + FT_TRACE3(( "Error 0x%x has occurred in rule %d\n", + errors[i], i )); continue; } @@ -2080,6 +2150,17 @@ FT_Long face_index, FT_Face *aface ) { + return ft_open_face_internal( library, args, face_index, aface, 1 ); + } + + + static FT_Error + ft_open_face_internal( FT_Library library, + const FT_Open_Args* args, + FT_Long face_index, + FT_Face *aface, + FT_Bool test_mac_fonts ) + { FT_Error error; FT_Driver driver = NULL; FT_Memory memory = NULL; @@ -2090,6 +2171,23 @@ FT_Module* cur; FT_Module* limit; +#ifndef FT_CONFIG_OPTION_MAC_FONTS + FT_UNUSED( test_mac_fonts ); +#endif + + +#ifdef FT_DEBUG_LEVEL_TRACE + FT_TRACE3(( "FT_Open_Face: " )); + if ( face_index < 0 ) + FT_TRACE3(( "Requesting number of faces and named instances\n")); + else + { + FT_TRACE3(( "Requesting face %ld", face_index & 0xFFFFL )); + if ( face_index & 0x7FFF0000L ) + FT_TRACE3(( ", named instance %ld", face_index >> 16 )); + FT_TRACE3(( "\n" )); + } +#endif /* test for valid `library' delayed to `FT_Stream_New' */ @@ -2167,11 +2265,13 @@ goto Success; #ifdef FT_CONFIG_OPTION_MAC_FONTS - if ( ft_strcmp( cur[0]->clazz->module_name, "truetype" ) == 0 && + if ( test_mac_fonts && + ft_strcmp( cur[0]->clazz->module_name, "truetype" ) == 0 && FT_ERR_EQ( error, Table_Missing ) ) { /* TrueType but essential tables are missing */ - if ( FT_Stream_Seek( stream, 0 ) ) + error = FT_Stream_Seek( stream, 0 ); + if ( error ) break; error = open_face_PS_from_sfnt_stream( library, @@ -2203,16 +2303,20 @@ goto Fail2; #if !defined( FT_MACINTOSH ) && defined( FT_CONFIG_OPTION_MAC_FONTS ) - error = load_mac_face( library, stream, face_index, aface, args ); - if ( !error ) + if ( test_mac_fonts ) { - /* We don't want to go to Success here. We've already done that. */ - /* On the other hand, if we succeeded we still need to close this */ - /* stream (we opened a different stream which extracted the */ - /* interesting information out of this stream here. That stream */ - /* will still be open and the face will point to it). */ - FT_Stream_Free( stream, external_stream ); - return error; + error = load_mac_face( library, stream, face_index, aface, args ); + if ( !error ) + { + /* We don't want to go to Success here. We've already done */ + /* that. On the other hand, if we succeeded we still need to */ + /* close this stream (we opened a different stream which */ + /* extracted the interesting information out of this stream */ + /* here. That stream will still be open and the face will */ + /* point to it). */ + FT_Stream_Free( stream, external_stream ); + return error; + } } if ( FT_ERR_NEQ( error, Unknown_File_Format ) ) @@ -2285,11 +2389,24 @@ if ( bsize->height < 0 ) - bsize->height = (FT_Short)-bsize->height; + bsize->height = -bsize->height; if ( bsize->x_ppem < 0 ) - bsize->x_ppem = (FT_Short)-bsize->x_ppem; + bsize->x_ppem = -bsize->x_ppem; if ( bsize->y_ppem < 0 ) bsize->y_ppem = -bsize->y_ppem; + + /* check whether negation actually has worked */ + if ( bsize->height < 0 || bsize->x_ppem < 0 || bsize->y_ppem < 0 ) + { + FT_TRACE0(( "FT_Open_Face:" + " Invalid bitmap dimensions for stroke %d," + " now disabled\n", i )); + bsize->width = 0; + bsize->height = 0; + bsize->size = 0; + bsize->x_ppem = 0; + bsize->y_ppem = 0; + } } } @@ -2323,7 +2440,20 @@ destroy_face( memory, face, driver ); Exit: - FT_TRACE4(( "FT_Open_Face: Return %d\n", error )); +#ifdef FT_DEBUG_LEVEL_TRACE + if ( !error && face_index < 0 ) + { + FT_TRACE3(( "FT_Open_Face: The font has %ld face%s\n" + " and %ld named instance%s for face %ld\n", + face->num_faces, + face->num_faces == 1 ? "" : "s", + face->style_flags >> 16, + ( face->style_flags >> 16 ) == 1 ? "" : "s", + -face_index - 1 )); + } +#endif + + FT_TRACE4(( "FT_Open_Face: Return 0x%x\n", error )); return error; } @@ -2589,6 +2719,9 @@ w = FT_PIX_ROUND( w ); h = FT_PIX_ROUND( h ); + if ( !w || !h ) + return FT_THROW( Invalid_Pixel_Size ); + for ( i = 0; i < face->num_fixed_sizes; i++ ) { FT_Bitmap_Size* bsize = face->available_sizes + i; @@ -2608,6 +2741,8 @@ } } + FT_TRACE3(( "FT_Match_Size: no matching bitmap strike\n" )); + return FT_THROW( Invalid_Pixel_Size ); } @@ -3327,7 +3462,7 @@ FT_CMap cmap = NULL; - if ( clazz == NULL || charmap == NULL || charmap->face == NULL ) + if ( !clazz || !charmap || !charmap->face ) return FT_THROW( Invalid_Argument ); face = charmap->face; @@ -3472,7 +3607,7 @@ FT_CMap ucmap = FT_CMAP( face->charmap ); - if ( charmap != NULL ) + if ( charmap ) { FT_CMap vcmap = FT_CMAP( charmap ); @@ -3513,7 +3648,7 @@ FT_CharMap charmap = find_variant_selector_charmap( face ); - if ( charmap != NULL ) + if ( charmap ) { FT_CMap vcmap = FT_CMAP( charmap ); @@ -3552,7 +3687,7 @@ FT_CharMap charmap = find_variant_selector_charmap( face ); - if ( charmap != NULL ) + if ( charmap ) { FT_CMap vcmap = FT_CMAP( charmap ); FT_Memory memory = FT_FACE_MEMORY( face ); @@ -3580,7 +3715,7 @@ FT_CharMap charmap = find_variant_selector_charmap( face ); - if ( charmap != NULL ) + if ( charmap ) { FT_CMap vcmap = FT_CMAP( charmap ); FT_Memory memory = FT_FACE_MEMORY( face ); @@ -3614,7 +3749,7 @@ FT_CharMap charmap = find_variant_selector_charmap( face ); - if ( charmap != NULL ) + if ( charmap ) { FT_CMap vcmap = FT_CMAP( charmap ); FT_Memory memory = FT_FACE_MEMORY( face ); @@ -3742,7 +3877,7 @@ if ( face && FT_IS_SFNT( face ) ) { FT_FACE_FIND_SERVICE( face, service, SFNT_TABLE ); - if ( service != NULL ) + if ( service ) table = service->get_table( face, tag ); } @@ -3766,7 +3901,7 @@ return FT_THROW( Invalid_Face_Handle ); FT_FACE_FIND_SERVICE( face, service, SFNT_TABLE ); - if ( service == NULL ) + if ( !service ) return FT_THROW( Unimplemented_Feature ); return service->load_table( face, tag, offset, buffer, length ); @@ -3791,7 +3926,7 @@ return FT_THROW( Invalid_Face_Handle ); FT_FACE_FIND_SERVICE( face, service, SFNT_TABLE ); - if ( service == NULL ) + if ( !service ) return FT_THROW( Unimplemented_Feature ); return service->table_info( face, table_index, tag, &offset, length ); @@ -3813,7 +3948,7 @@ face = charmap->face; FT_FACE_FIND_SERVICE( face, service, TT_CMAP ); - if ( service == NULL ) + if ( !service ) return 0; if ( service->get_cmap_info( charmap, &cmap_info )) return 0; @@ -3837,7 +3972,7 @@ face = charmap->face; FT_FACE_FIND_SERVICE( face, service, TT_CMAP ); - if ( service == NULL ) + if ( !service ) return -1; if ( service->get_cmap_info( charmap, &cmap_info )) return -1; @@ -4156,39 +4291,51 @@ #undef FT_COMPONENT #define FT_COMPONENT trace_bitmap - /* we convert to a single bitmap format for computing the checksum */ - if ( !error ) + /* + * Computing the MD5 checksum is expensive, unnecessarily distorting a + * possible profiling of FreeType if compiled with tracing support. For + * this reason, we execute the following code only if explicitly + * requested. + */ + + /* we use FT_TRACE3 in this block */ + if ( ft_trace_levels[trace_bitmap] >= 3 ) { - FT_Bitmap bitmap; - FT_Error err; + /* we convert to a single bitmap format for computing the checksum */ + if ( !error && slot->bitmap.buffer ) + { + FT_Bitmap bitmap; + FT_Error err; - FT_Bitmap_Init( &bitmap ); + FT_Bitmap_Init( &bitmap ); - /* this also converts the bitmap flow to `down' (i.e., pitch > 0) */ - err = FT_Bitmap_Convert( library, &slot->bitmap, &bitmap, 1 ); - if ( !err ) - { - MD5_CTX ctx; - unsigned char md5[16]; - int i; - unsigned int rows = bitmap.rows; - unsigned int pitch = (unsigned int)bitmap.pitch; - - - MD5_Init( &ctx ); - MD5_Update( &ctx, bitmap.buffer, rows * pitch ); - MD5_Final( md5, &ctx ); - - FT_TRACE3(( "MD5 checksum for %dx%d bitmap:\n" - " ", - rows, pitch )); - for ( i = 0; i < 16; i++ ) - FT_TRACE3(( "%02X", md5[i] )); - FT_TRACE3(( "\n" )); - } + /* this also converts the bitmap flow to `down' (i.e., pitch > 0) */ + err = FT_Bitmap_Convert( library, &slot->bitmap, &bitmap, 1 ); + if ( !err ) + { + MD5_CTX ctx; + unsigned char md5[16]; + int i; + unsigned int rows = bitmap.rows; + unsigned int pitch = (unsigned int)bitmap.pitch; + + + MD5_Init( &ctx ); + if ( bitmap.buffer ) + MD5_Update( &ctx, bitmap.buffer, rows * pitch ); + MD5_Final( md5, &ctx ); + + FT_TRACE3(( "MD5 checksum for %dx%d bitmap:\n" + " ", + rows, pitch )); + for ( i = 0; i < 16; i++ ) + FT_TRACE3(( "%02X", md5[i] )); + FT_TRACE3(( "\n" )); + } - FT_Bitmap_Done( library, &bitmap ); + FT_Bitmap_Done( library, &bitmap ); + } } #undef FT_COMPONENT @@ -4282,7 +4429,7 @@ { FT_Error error; FT_Memory memory; - FT_Module module; + FT_Module module = NULL; FT_UInt nn; @@ -4434,7 +4581,8 @@ FT_BASE_DEF( FT_Pointer ) ft_module_get_service( FT_Module module, - const char* service_id ) + const char* service_id, + FT_Bool global ) { FT_Pointer result = NULL; @@ -4447,7 +4595,7 @@ if ( module->clazz->get_interface ) result = module->clazz->get_interface( module, service_id ); - if ( result == NULL ) + if ( global && !result ) { /* we didn't find it, look in all other modules then */ FT_Library library = module->library; @@ -4464,7 +4612,7 @@ if ( cur[0]->clazz->get_interface ) { result = cur[0]->clazz->get_interface( cur[0], service_id ); - if ( result != NULL ) + if ( result ) break; } } @@ -4523,7 +4671,8 @@ const FT_String* module_name, const FT_String* property_name, void* value, - FT_Bool set ) + FT_Bool set, + FT_Bool value_is_string ) { FT_Module* cur; FT_Module* limit; @@ -4593,8 +4742,13 @@ return FT_THROW( Unimplemented_Feature ); } - return set ? service->set_property( cur[0], property_name, value ) - : service->get_property( cur[0], property_name, value ); + return set ? service->set_property( cur[0], + property_name, + value, + value_is_string ) + : service->get_property( cur[0], + property_name, + value ); } @@ -4610,7 +4764,8 @@ module_name, property_name, (void*)value, - TRUE ); + TRUE, + FALSE ); } @@ -4626,10 +4781,33 @@ module_name, property_name, value, + FALSE, FALSE ); } +#ifdef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES + + /* this variant is used for handling the FREETYPE_PROPERTIES */ + /* environment variable */ + + FT_BASE_DEF( FT_Error ) + ft_property_string_set( FT_Library library, + const FT_String* module_name, + const FT_String* property_name, + FT_String* value ) + { + return ft_property_do( library, + module_name, + property_name, + (void*)value, + TRUE, + TRUE ); + } + +#endif + + /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ @@ -4885,7 +5063,8 @@ service = (FT_Service_TrueTypeEngine) ft_module_get_service( module, - FT_SERVICE_ID_TRUETYPE_ENGINE ); + FT_SERVICE_ID_TRUETYPE_ENGINE, + 0 ); if ( service ) result = service->engine_type; } diff --git a/third_party/freetype/src/base/ftoutln.c b/third_party/freetype/src/base/ftoutln.c index 35cc9f5569..464a066dcc 100644 --- a/third_party/freetype/src/base/ftoutln.c +++ b/third_party/freetype/src/base/ftoutln.c @@ -4,7 +4,7 @@ /* */ /* FreeType outline management (body). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -42,7 +42,7 @@ static - const FT_Outline null_outline = { 0, 0, 0, 0, 0, 0 }; + const FT_Outline null_outline = { 0, 0, NULL, NULL, NULL, 0 }; /* documentation is in ftoutln.h */ @@ -287,7 +287,7 @@ return FT_Err_Ok; Exit: - FT_TRACE5(( "FT_Outline_Decompose: Error %d\n", error )); + FT_TRACE5(( "FT_Outline_Decompose: Error 0x%x\n", error )); return error; Invalid_Outline: @@ -415,11 +415,14 @@ if ( source == target ) return FT_Err_Ok; - FT_ARRAY_COPY( target->points, source->points, source->n_points ); - - FT_ARRAY_COPY( target->tags, source->tags, source->n_points ); + if ( source->n_points ) + { + FT_ARRAY_COPY( target->points, source->points, source->n_points ); + FT_ARRAY_COPY( target->tags, source->tags, source->n_points ); + } - FT_ARRAY_COPY( target->contours, source->contours, source->n_contours ); + if ( source->n_contours ) + FT_ARRAY_COPY( target->contours, source->contours, source->n_contours ); /* copy all flags, except the `FT_OUTLINE_OWNER' one */ is_owner = target->flags & FT_OUTLINE_OWNER; @@ -942,6 +945,9 @@ l_in = 0; last = outline->contours[c]; + /* pacify compiler */ + in.x = in.y = anchor.x = anchor.y = 0; + /* Counter j cycles though the points; counter i advances only */ /* when points are moved; anchor k marks the first moved point. */ for ( i = last, j = first, k = -1; @@ -1074,13 +1080,16 @@ FT_Int last = outline->contours[c]; - v_prev = points[last]; + v_prev.x = points[last].x >> xshift; + v_prev.y = points[last].y >> yshift; for ( n = first; n <= last; n++ ) { - v_cur = points[n]; - area += ( ( v_cur.y - v_prev.y ) >> yshift ) * - ( ( v_cur.x + v_prev.x ) >> xshift ); + v_cur.x = points[n].x >> xshift; + v_cur.y = points[n].y >> yshift; + + area += ( v_cur.y - v_prev.y ) * ( v_cur.x + v_prev.x ); + v_prev = v_cur; } diff --git a/third_party/freetype/src/base/ftpic.c b/third_party/freetype/src/base/ftpic.c index 6c4b1cd4e6..0f84fddc98 100644 --- a/third_party/freetype/src/base/ftpic.c +++ b/third_party/freetype/src/base/ftpic.c @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services (body). */ /* */ -/* Copyright 2009-2015 by */ +/* Copyright 2009-2017 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/third_party/freetype/src/base/ftrfork.c b/third_party/freetype/src/base/ftrfork.c index c30c76678e..f7b81375dd 100644 --- a/third_party/freetype/src/base/ftrfork.c +++ b/third_party/freetype/src/base/ftrfork.c @@ -4,7 +4,7 @@ /* */ /* Embedded resource forks accessor (body). */ /* */ -/* Copyright 2004-2015 by */ +/* Copyright 2004-2017 by */ /* Masatake YAMATO and Redhat K.K. */ /* */ /* FT_Raccess_Get_HeaderInfo() and raccess_guess_darwin_hfsplus() are */ @@ -56,7 +56,7 @@ { FT_Error error; unsigned char head[16], head2[16]; - FT_Long map_pos, rdata_len; + FT_Long map_pos, map_len, rdata_len; int allzeros, allmatch, i; FT_Long type_list; @@ -67,12 +67,15 @@ if ( error ) return error; - error = FT_Stream_Read( stream, (FT_Byte *)head, 16 ); + error = FT_Stream_Read( stream, (FT_Byte*)head, 16 ); if ( error ) return error; /* ensure positive values */ - if ( head[0] >= 0x80 || head[4] >= 0x80 || head[8] >= 0x80 ) + if ( head[0] >= 0x80 || + head[4] >= 0x80 || + head[8] >= 0x80 || + head[12] >= 0x80 ) return FT_THROW( Unknown_File_Format ); *rdata_pos = ( head[ 0] << 24 ) | @@ -87,14 +90,36 @@ ( head[ 9] << 16 ) | ( head[10] << 8 ) | head[11]; + map_len = ( head[12] << 24 ) | + ( head[13] << 16 ) | + ( head[14] << 8 ) | + head[15]; - /* map_len = head[12] .. head[15] */ - - if ( *rdata_pos != map_pos - rdata_len || map_pos == 0 ) + /* the map must not be empty */ + if ( !map_pos ) return FT_THROW( Unknown_File_Format ); - if ( FT_LONG_MAX - rfork_offset < *rdata_pos || - FT_LONG_MAX - rfork_offset < map_pos ) + /* check whether rdata and map overlap */ + if ( *rdata_pos < map_pos ) + { + if ( *rdata_pos > map_pos - rdata_len ) + return FT_THROW( Unknown_File_Format ); + } + else + { + if ( map_pos > *rdata_pos - map_len ) + return FT_THROW( Unknown_File_Format ); + } + + /* check whether end of rdata or map exceeds stream size */ + if ( FT_LONG_MAX - rdata_len < *rdata_pos || + FT_LONG_MAX - map_len < map_pos || + + FT_LONG_MAX - ( *rdata_pos + rdata_len ) < rfork_offset || + FT_LONG_MAX - ( map_pos + map_len ) < rfork_offset || + + (FT_ULong)( rfork_offset + *rdata_pos + rdata_len ) > stream->size || + (FT_ULong)( rfork_offset + map_pos + map_len ) > stream->size ) return FT_THROW( Unknown_File_Format ); *rdata_pos += rfork_offset; @@ -112,7 +137,7 @@ allzeros = 1; allmatch = 1; - for ( i = 0; i < 16; ++i ) + for ( i = 0; i < 16; i++ ) { if ( head2[i] != 0 ) allzeros = 0; @@ -124,15 +149,14 @@ /* If we have reached this point then it is probably a mac resource */ /* file. Now, does it contain any interesting resources? */ - /* Skip handle to next resource map, the file resource number, and */ - /* attributes. */ + (void)FT_STREAM_SKIP( 4 /* skip handle to next resource map */ + 2 /* skip file resource number */ + 2 ); /* skip attributes */ - if ( FT_READ_USHORT( type_list ) ) + if ( FT_READ_SHORT( type_list ) ) return error; - if ( type_list == -1 ) + if ( type_list < 0 ) return FT_THROW( Unknown_File_Format ); error = FT_Stream_Seek( stream, (FT_ULong)( map_pos + type_list ) ); @@ -181,15 +205,34 @@ if ( error ) return error; - if ( FT_READ_USHORT( cnt ) ) + if ( FT_READ_SHORT( cnt ) ) return error; cnt++; - for ( i = 0; i < cnt; ++i ) + /* `rpos' is a signed 16bit integer offset to resource records; the */ + /* size of a resource record is 12 bytes. The map header is 28 bytes, */ + /* and a type list needs 10 bytes or more. If we assume that the name */ + /* list is empty and we have only a single entry in the type list, */ + /* there can be at most */ + /* */ + /* (32768 - 28 - 10) / 12 = 2727 */ + /* */ + /* resources. */ + /* */ + /* A type list starts with a two-byte counter, followed by 10-byte */ + /* type records. Assuming that there are no resources, the number of */ + /* type records can be at most */ + /* */ + /* (32768 - 28 - 2) / 8 = 4079 */ + /* */ + if ( cnt > 4079 ) + return FT_THROW( Invalid_Table ); + + for ( i = 0; i < cnt; i++ ) { if ( FT_READ_LONG( tag_internal ) || - FT_READ_USHORT( subcnt ) || - FT_READ_USHORT( rpos ) ) + FT_READ_SHORT( subcnt ) || + FT_READ_SHORT( rpos ) ) return error; FT_TRACE2(( "Resource tags: %c%c%c%c\n", @@ -205,6 +248,11 @@ *count = subcnt + 1; rpos += map_offset; + /* a zero count might be valid in the resource specification, */ + /* however, it is completely useless to us */ + if ( *count < 1 || *count > 2727 ) + return FT_THROW( Invalid_Table ); + error = FT_Stream_Seek( stream, (FT_ULong)rpos ); if ( error ) return error; @@ -212,35 +260,44 @@ if ( FT_NEW_ARRAY( ref, *count ) ) return error; - for ( j = 0; j < *count; ++j ) + for ( j = 0; j < *count; j++ ) { - if ( FT_READ_USHORT( ref[j].res_id ) ) + if ( FT_READ_SHORT( ref[j].res_id ) ) goto Exit; - if ( FT_STREAM_SKIP( 2 ) ) /* resource name */ + if ( FT_STREAM_SKIP( 2 ) ) /* resource name offset */ goto Exit; - if ( FT_READ_LONG( temp ) ) + if ( FT_READ_LONG( temp ) ) /* attributes (8bit), offset (24bit) */ goto Exit; - if ( FT_STREAM_SKIP( 4 ) ) /* mbz */ + if ( FT_STREAM_SKIP( 4 ) ) /* mbz */ + goto Exit; + + if ( ref[j].res_id < 0 || temp < 0 ) + { + error = FT_THROW( Invalid_Table ); goto Exit; + } ref[j].offset = temp & 0xFFFFFFL; + FT_TRACE3(( " [%d]:" " resource_id=0x%04x, offset=0x%08x\n", j, ref[j].res_id, ref[j].offset )); } - if (sort_by_res_id) + if ( sort_by_res_id ) { - ft_qsort( ref, (size_t)*count, sizeof ( FT_RFork_Ref ), - ( int(*)(const void*, const void*) ) - ft_raccess_sort_ref_by_id ); + ft_qsort( ref, + (size_t)*count, + sizeof ( FT_RFork_Ref ), + ( int(*)(const void*, + const void*) )ft_raccess_sort_ref_by_id ); FT_TRACE3(( " -- sort resources by their ids --\n" )); - for ( j = 0; j < *count; ++ j ) { + + for ( j = 0; j < *count; j++ ) FT_TRACE3(( " [%d]:" " resource_id=0x%04x, offset=0x%08x\n", j, ref[j].res_id, ref[j].offset )); - } } if ( FT_NEW_ARRAY( offsets_internal, *count ) ) @@ -250,7 +307,7 @@ * gap between reference IDs are acceptable? * further investigation on Apple implementation is needed. */ - for ( j = 0; j < *count; ++j ) + for ( j = 0; j < *count; j++ ) offsets_internal[j] = rdata_pos + ref[j].offset; *offsets = offsets_internal; @@ -403,7 +460,7 @@ errors[i] = FT_Err_Ok; if ( errors[i] ) - continue ; + continue; errors[i] = (FT_RACCESS_GUESS_TABLE_GET[i].func)( library, stream, base_name, diff --git a/third_party/freetype/src/base/ftsnames.c b/third_party/freetype/src/base/ftsnames.c index 80304e5c85..a5b41eb884 100644 --- a/third_party/freetype/src/base/ftsnames.c +++ b/third_party/freetype/src/base/ftsnames.c @@ -7,7 +7,7 @@ /* */ /* This is _not_ used to retrieve glyph names! */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -58,7 +58,7 @@ /* load name on demand */ - if ( entry->stringLength > 0 && entry->string == NULL ) + if ( entry->stringLength > 0 && !entry->string ) { FT_Memory memory = face->memory; FT_Stream stream = face->stream; diff --git a/third_party/freetype/src/base/ftstream.c b/third_party/freetype/src/base/ftstream.c index b68f3f82d2..a3f8c8b3c9 100644 --- a/third_party/freetype/src/base/ftstream.c +++ b/third_party/freetype/src/base/ftstream.c @@ -4,7 +4,7 @@ /* */ /* I/O stream support (body). */ /* */ -/* Copyright 2000-2015 by */ +/* Copyright 2000-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -778,7 +778,7 @@ case ft_frame_short_be: case ft_frame_ushort_be: /* read a 2-byte big-endian short */ - value = FT_NEXT_USHORT( cursor) ; + value = FT_NEXT_USHORT( cursor ); sign_shift = 16; break; diff --git a/third_party/freetype/src/base/ftsystem.c b/third_party/freetype/src/base/ftsystem.c index 1938fd8917..324f949a49 100644 --- a/third_party/freetype/src/base/ftsystem.c +++ b/third_party/freetype/src/base/ftsystem.c @@ -4,7 +4,7 @@ /* */ /* ANSI-specific FreeType low-level system interface (body). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/third_party/freetype/src/base/fttrigon.c b/third_party/freetype/src/base/fttrigon.c index 5b24304c2f..7a4d17c829 100644 --- a/third_party/freetype/src/base/fttrigon.c +++ b/third_party/freetype/src/base/fttrigon.c @@ -4,7 +4,7 @@ /* */ /* FreeType trigonometric functions (body). */ /* */ -/* Copyright 2001-2015 by */ +/* Copyright 2001-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -71,7 +71,8 @@ /* 0x40000000 comes from regression analysis between true */ /* and CORDIC hypotenuse, so it minimizes the error */ - val = (FT_Fixed)( ( (FT_Int64)val * FT_TRIG_SCALE + 0x40000000UL ) >> 32 ); + val = (FT_Fixed)( + ( (FT_UInt64)val * FT_TRIG_SCALE + 0x40000000UL ) >> 32 ); return s < 0 ? -val : val; } diff --git a/third_party/freetype/src/base/fttype1.c b/third_party/freetype/src/base/fttype1.c index c549382afd..4d16a6371a 100644 --- a/third_party/freetype/src/base/fttype1.c +++ b/third_party/freetype/src/base/fttype1.c @@ -4,7 +4,7 @@ /* */ /* FreeType utility file for PS names support (body). */ /* */ -/* Copyright 2002-2015 by */ +/* Copyright 2002-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/third_party/freetype/src/base/ftutil.c b/third_party/freetype/src/base/ftutil.c index f5b72db708..dccc209f4d 100644 --- a/third_party/freetype/src/base/ftutil.c +++ b/third_party/freetype/src/base/ftutil.c @@ -4,7 +4,7 @@ /* */ /* FreeType utility file for memory and list management (body). */ /* */ -/* Copyright 2002-2015 by */ +/* Copyright 2002-2017 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -74,7 +74,7 @@ if ( size > 0 ) { block = memory->alloc( memory, size ); - if ( block == NULL ) + if ( !block ) error = FT_THROW( Out_Of_Memory ); } else if ( size < 0 ) @@ -141,7 +141,7 @@ } else if ( cur_count == 0 ) { - FT_ASSERT( block == NULL ); + FT_ASSERT( !block ); block = ft_mem_alloc( memory, new_count*item_size, &error ); } @@ -153,7 +153,7 @@ block2 = memory->realloc( memory, cur_size, new_size, block ); - if ( block2 == NULL ) + if ( !block2 ) error = FT_THROW( Out_Of_Memory ); else block = block2; |