summaryrefslogtreecommitdiffstats
path: root/src/sfnt
diff options
context:
space:
mode:
Diffstat (limited to 'src/sfnt')
-rw-r--r--src/sfnt/pngshim.c336
-rw-r--r--src/sfnt/pngshim.h48
-rw-r--r--src/sfnt/sfdriver.c318
-rw-r--r--src/sfnt/sferrors.h4
-rw-r--r--src/sfnt/sfnt.c3
-rw-r--r--src/sfnt/sfntpic.c37
-rw-r--r--src/sfnt/sfntpic.h81
-rw-r--r--src/sfnt/sfobjs.c128
-rw-r--r--src/sfnt/ttbdf.c16
-rw-r--r--src/sfnt/ttcmap.c389
-rw-r--r--src/sfnt/ttcmap.h99
-rw-r--r--src/sfnt/ttcmapc.h19
-rw-r--r--src/sfnt/ttkern.c2
-rw-r--r--src/sfnt/ttload.c60
-rw-r--r--src/sfnt/ttmtx.c195
-rw-r--r--src/sfnt/ttpost.c22
-rw-r--r--src/sfnt/ttsbit.c2017
-rw-r--r--src/sfnt/ttsbit.h18
-rw-r--r--src/sfnt/ttsbit0.c1011
19 files changed, 1799 insertions, 3004 deletions
diff --git a/src/sfnt/pngshim.c b/src/sfnt/pngshim.c
new file mode 100644
index 0000000..408f879
--- /dev/null
+++ b/src/sfnt/pngshim.c
@@ -0,0 +1,336 @@
+/***************************************************************************/
+/* */
+/* pngshim.c */
+/* */
+/* PNG Bitmap glyph support. */
+/* */
+/* Copyright 2013 by Google, Inc. */
+/* Written by Stuart Gill and Behdad Esfahbod. */
+/* */
+/* This file is part of the FreeType project, and may only be used, */
+/* modified, and distributed under the terms of the FreeType project */
+/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
+/* this file you indicate that you have read the license and */
+/* understand and accept it fully. */
+/* */
+/***************************************************************************/
+
+
+#include <ft2build.h>
+#include FT_INTERNAL_DEBUG_H
+#include FT_INTERNAL_STREAM_H
+#include FT_TRUETYPE_TAGS_H
+#include FT_CONFIG_STANDARD_LIBRARY_H
+
+
+#ifdef FT_CONFIG_OPTION_USE_PNG
+
+ /* We always include <stjmp.h>, so make libpng shut up! */
+#define PNG_SKIP_SETJMP_CHECK 1
+#include <png.h>
+#include "pngshim.h"
+
+#include "sferrors.h"
+
+
+ /* This code is freely based on cairo-png.c. There's so many ways */
+ /* to call libpng, and the way cairo does it is defacto standard. */
+
+ static int
+ multiply_alpha( int alpha,
+ int color )
+ {
+ int temp = ( alpha * color ) + 0x80;
+
+
+ return ( temp + ( temp >> 8 ) ) >> 8;
+ }
+
+
+ /* Premultiplies data and converts RGBA bytes => native endian. */
+ static void
+ premultiply_data( png_structp png,
+ png_row_infop row_info,
+ png_bytep data )
+ {
+ unsigned int i;
+
+ FT_UNUSED( png );
+
+
+ for ( i = 0; i < row_info->rowbytes; i += 4 )
+ {
+ unsigned char* base = &data[i];
+ unsigned int alpha = base[3];
+
+
+ if ( alpha == 0 )
+ base[0] = base[1] = base[2] = base[3] = 0;
+
+ else
+ {
+ unsigned int red = base[0];
+ unsigned int green = base[1];
+ unsigned int blue = base[2];
+
+
+ if ( alpha != 0xFF )
+ {
+ red = multiply_alpha( alpha, red );
+ green = multiply_alpha( alpha, green );
+ blue = multiply_alpha( alpha, blue );
+ }
+
+ base[0] = blue;
+ base[1] = green;
+ base[2] = red;
+ base[3] = alpha;
+ }
+ }
+ }
+
+
+ /* Converts RGBx bytes to BGRA. */
+ static void
+ convert_bytes_to_data( png_structp png,
+ png_row_infop row_info,
+ png_bytep data )
+ {
+ unsigned int i;
+
+ FT_UNUSED( png );
+
+
+ for ( i = 0; i < row_info->rowbytes; i += 4 )
+ {
+ unsigned char* base = &data[i];
+ unsigned int red = base[0];
+ unsigned int green = base[1];
+ unsigned int blue = base[2];
+
+
+ base[0] = blue;
+ base[1] = green;
+ base[2] = red;
+ base[3] = 0xFF;
+ }
+ }
+
+
+ /* Use error callback to avoid png writing to stderr. */
+ static void
+ error_callback( png_structp png,
+ png_const_charp error_msg )
+ {
+ FT_Error* error = png_get_error_ptr( png );
+
+ FT_UNUSED( error_msg );
+
+
+ *error = FT_THROW( Out_Of_Memory );
+#ifdef PNG_SETJMP_SUPPORTED
+ longjmp( png_jmpbuf( png ), 1 );
+#endif
+ /* if we get here, then we have no choice but to abort ... */
+ }
+
+
+ /* Use warning callback to avoid png writing to stderr. */
+ static void
+ warning_callback( png_structp png,
+ png_const_charp error_msg )
+ {
+ FT_UNUSED( png );
+ FT_UNUSED( error_msg );
+
+ /* Just ignore warnings. */
+ }
+
+
+ static void
+ read_data_from_FT_Stream( png_structp png,
+ png_bytep data,
+ png_size_t length )
+ {
+ FT_Error error;
+ png_voidp p = png_get_io_ptr( png );
+ FT_Stream stream = (FT_Stream)p;
+
+
+ if ( FT_FRAME_ENTER( length ) )
+ {
+ FT_Error* e = png_get_error_ptr( png );
+
+
+ *e = FT_THROW( Invalid_Stream_Read );
+ png_error( png, NULL );
+
+ return;
+ }
+
+ memcpy( data, stream->cursor, length );
+
+ FT_FRAME_EXIT();
+ }
+
+
+ static FT_Error
+ Load_SBit_Png( FT_Bitmap* map,
+ FT_Int x_offset,
+ FT_Int y_offset,
+ FT_Int pix_bits,
+ TT_SBit_Metrics metrics,
+ FT_Memory memory,
+ FT_Byte* data,
+ FT_UInt png_len )
+ {
+ FT_Error error = FT_Err_Ok;
+ FT_StreamRec stream;
+
+ png_structp png;
+ png_infop info;
+ png_uint_32 imgWidth, imgHeight;
+
+ int bitdepth, color_type, interlace;
+ FT_Int i;
+ png_byte* *rows;
+
+
+ if ( x_offset < 0 || x_offset + metrics->width > map->width ||
+ y_offset < 0 || y_offset + metrics->height > map->rows ||
+ pix_bits != 32 || map->pixel_mode != FT_PIXEL_MODE_BGRA )
+ {
+ error = FT_THROW( Invalid_Argument );
+ goto Exit;
+ }
+
+ FT_Stream_OpenMemory( &stream, data, png_len );
+
+ png = png_create_read_struct( PNG_LIBPNG_VER_STRING,
+ &error,
+ error_callback,
+ warning_callback );
+ if ( !png )
+ {
+ error = FT_THROW( Out_Of_Memory );
+ goto Exit;
+ }
+
+ info = png_create_info_struct( png );
+ if ( !info )
+ {
+ error = FT_THROW( Out_Of_Memory );
+ png_destroy_read_struct( &png, NULL, NULL );
+ goto Exit;
+ }
+
+ if ( ft_setjmp( png_jmpbuf( png ) ) )
+ {
+ error = FT_THROW( Invalid_File_Format );
+ goto DestroyExit;
+ }
+
+ png_set_read_fn( png, &stream, read_data_from_FT_Stream );
+
+ png_read_info( png, info );
+ png_get_IHDR( png, info,
+ &imgWidth, &imgHeight,
+ &bitdepth, &color_type, &interlace,
+ NULL, NULL );
+
+ if ( error != FT_Err_Ok ||
+ (FT_Int)imgWidth != metrics->width ||
+ (FT_Int)imgHeight != metrics->height )
+ goto DestroyExit;
+
+ /* convert palette/gray image to rgb */
+ if ( color_type == PNG_COLOR_TYPE_PALETTE )
+ png_set_palette_to_rgb( png );
+
+ /* expand gray bit depth if needed */
+ if ( color_type == PNG_COLOR_TYPE_GRAY )
+ {
+#if PNG_LIBPNG_VER >= 10209
+ png_set_expand_gray_1_2_4_to_8( png );
+#else
+ png_set_gray_1_2_4_to_8( png );
+#endif
+ }
+
+ /* transform transparency to alpha */
+ if ( png_get_valid(png, info, PNG_INFO_tRNS ) )
+ png_set_tRNS_to_alpha( png );
+
+ if ( bitdepth == 16 )
+ png_set_strip_16( png );
+
+ if ( bitdepth < 8 )
+ png_set_packing( png );
+
+ /* convert grayscale to RGB */
+ if ( color_type == PNG_COLOR_TYPE_GRAY ||
+ color_type == PNG_COLOR_TYPE_GRAY_ALPHA )
+ png_set_gray_to_rgb( png );
+
+ if ( interlace != PNG_INTERLACE_NONE )
+ png_set_interlace_handling( png );
+
+ png_set_filler( png, 0xFF, PNG_FILLER_AFTER );
+
+ /* recheck header after setting EXPAND options */
+ png_read_update_info(png, info );
+ png_get_IHDR( png, info,
+ &imgWidth, &imgHeight,
+ &bitdepth, &color_type, &interlace,
+ NULL, NULL );
+
+ if ( bitdepth != 8 ||
+ !( color_type == PNG_COLOR_TYPE_RGB ||
+ color_type == PNG_COLOR_TYPE_RGB_ALPHA ) )
+ {
+ error = FT_THROW( Invalid_File_Format );
+ goto DestroyExit;
+ }
+
+ switch ( color_type )
+ {
+ default:
+ /* Shouldn't happen, but fall through. */
+
+ case PNG_COLOR_TYPE_RGB_ALPHA:
+ png_set_read_user_transform_fn( png, premultiply_data );
+ break;
+
+ case PNG_COLOR_TYPE_RGB:
+ /* Humm, this smells. Carry on though. */
+ png_set_read_user_transform_fn( png, convert_bytes_to_data );
+ break;
+ }
+
+ if ( FT_NEW_ARRAY( rows, imgHeight ) )
+ {
+ error = FT_THROW( Out_Of_Memory );
+ goto DestroyExit;
+ }
+
+ for ( i = 0; i < (FT_Int)imgHeight; i++ )
+ rows[i] = map->buffer + ( y_offset + i ) * map->pitch + x_offset * 4;
+
+ png_read_image( png, rows );
+
+ FT_FREE( rows );
+
+ png_read_end( png, info );
+
+ DestroyExit:
+ png_destroy_read_struct( &png, &info, NULL );
+ FT_Stream_Close( &stream );
+
+ Exit:
+ return error;
+ }
+
+#endif /* FT_CONFIG_OPTION_USE_PNG */
+
+
+/* END */
diff --git a/src/sfnt/pngshim.h b/src/sfnt/pngshim.h
new file mode 100644
index 0000000..8a2e69c
--- /dev/null
+++ b/src/sfnt/pngshim.h
@@ -0,0 +1,48 @@
+/***************************************************************************/
+/* */
+/* pngshim.h */
+/* */
+/* PNG Bitmap glyph support. */
+/* */
+/* Copyright 2013 by Google, Inc. */
+/* Written by Stuart Gill and Behdad Esfahbod. */
+/* */
+/* 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 __PNGSHIM_H__
+#define __PNGSHIM_H__
+
+
+#include <ft2build.h>
+#include "ttload.h"
+
+
+FT_BEGIN_HEADER
+
+#ifdef FT_CONFIG_OPTION_USE_PNG
+
+ FT_LOCAL( FT_Error )
+ Load_SBit_Png( FT_Bitmap* map,
+ FT_Int x_offset,
+ FT_Int y_offset,
+ FT_Int pix_bits,
+ TT_SBit_Metrics metrics,
+ FT_Memory memory,
+ FT_Byte* data,
+ FT_UInt png_len );
+
+#endif
+
+FT_END_HEADER
+
+#endif /* __PNGSHIM_H__ */
+
+
+/* END */
diff --git a/src/sfnt/sfdriver.c b/src/sfnt/sfdriver.c
index 847d83d..a368b8c 100644
--- a/src/sfnt/sfdriver.c
+++ b/src/sfnt/sfdriver.c
@@ -4,7 +4,7 @@
/* */
/* High-level SFNT driver interface (body). */
/* */
-/* Copyright 1996-2007, 2009-2011 by */
+/* Copyright 1996-2007, 2009-2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -50,6 +50,7 @@
#include FT_SERVICE_SFNT_H
#include FT_SERVICE_TT_CMAP_H
+
/*************************************************************************/
/* */
/* The macro FT_COMPONENT is used in trace mode. It is an implicit */
@@ -60,10 +61,10 @@
#define FT_COMPONENT trace_sfdriver
- /*
- * SFNT TABLE SERVICE
- *
- */
+ /*
+ * SFNT TABLE SERVICE
+ *
+ */
static void*
get_sfnt_table( TT_Face face,
@@ -118,37 +119,37 @@
FT_ULong *length )
{
if ( !offset || !length )
- return SFNT_Err_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
if ( !tag )
*length = face->num_tables;
else
{
if ( idx >= face->num_tables )
- return SFNT_Err_Table_Missing;
+ return FT_THROW( Table_Missing );
*tag = face->dir_tables[idx].Tag;
*offset = face->dir_tables[idx].Offset;
*length = face->dir_tables[idx].Length;
}
- return SFNT_Err_Ok;
+ return FT_Err_Ok;
}
- FT_DEFINE_SERVICE_SFNT_TABLEREC(sfnt_service_sfnt_table,
+ FT_DEFINE_SERVICE_SFNT_TABLEREC(
+ sfnt_service_sfnt_table,
(FT_SFNT_TableLoadFunc)tt_face_load_any,
(FT_SFNT_TableGetFunc) get_sfnt_table,
- (FT_SFNT_TableInfoFunc)sfnt_table_info
- )
+ (FT_SFNT_TableInfoFunc)sfnt_table_info )
#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
- /*
- * GLYPH DICT SERVICE
- *
- */
+ /*
+ * GLYPH DICT SERVICE
+ *
+ */
static FT_Error
sfnt_get_glyph_name( TT_Face face,
@@ -172,17 +173,18 @@
sfnt_get_name_index( TT_Face face,
FT_String* glyph_name )
{
- FT_Face root = &face->root;
- FT_UInt i, max_gid = FT_UINT_MAX;
+ FT_Face root = &face->root;
+
+ FT_UInt i, max_gid = FT_UINT_MAX;
if ( root->num_glyphs < 0 )
return 0;
- else if ( ( FT_ULong ) root->num_glyphs < FT_UINT_MAX )
- max_gid = ( FT_UInt ) root->num_glyphs;
+ else if ( (FT_ULong)root->num_glyphs < FT_UINT_MAX )
+ max_gid = (FT_UInt)root->num_glyphs;
else
FT_TRACE0(( "Ignore glyph names for invalid GID 0x%08x - 0x%08x\n",
- FT_UINT_MAX, root->num_glyphs ));
+ FT_UINT_MAX, root->num_glyphs ));
for ( i = 0; i < max_gid; i++ )
{
@@ -201,18 +203,19 @@
}
- FT_DEFINE_SERVICE_GLYPHDICTREC(sfnt_service_glyph_dict,
+ FT_DEFINE_SERVICE_GLYPHDICTREC(
+ sfnt_service_glyph_dict,
(FT_GlyphDict_GetNameFunc) sfnt_get_glyph_name,
- (FT_GlyphDict_NameIndexFunc)sfnt_get_name_index
- )
+ (FT_GlyphDict_NameIndexFunc)sfnt_get_name_index )
+
#endif /* TT_CONFIG_OPTION_POSTSCRIPT_NAMES */
- /*
- * POSTSCRIPT NAME SERVICE
- *
- */
+ /*
+ * POSTSCRIPT NAME SERVICE
+ *
+ */
static const char*
sfnt_get_ps_name( TT_Face face )
@@ -254,7 +257,7 @@
FT_Memory memory = face->root.memory;
TT_NameEntryRec* name = face->name_table.names + found_win;
FT_UInt len = name->stringLength / 2;
- FT_Error error = SFNT_Err_Ok;
+ FT_Error error = FT_Err_Ok;
FT_UNUSED( error );
@@ -296,7 +299,7 @@
FT_Memory memory = face->root.memory;
TT_NameEntryRec* name = face->name_table.names + found_apple;
FT_UInt len = name->stringLength;
- FT_Error error = SFNT_Err_Ok;
+ FT_Error error = FT_Err_Ok;
FT_UNUSED( error );
@@ -324,17 +327,18 @@
return result;
}
- FT_DEFINE_SERVICE_PSFONTNAMEREC(sfnt_service_ps_name,
- (FT_PsName_GetFunc)sfnt_get_ps_name
- )
+
+ FT_DEFINE_SERVICE_PSFONTNAMEREC(
+ sfnt_service_ps_name,
+ (FT_PsName_GetFunc)sfnt_get_ps_name )
/*
* TT CMAP INFO
*/
- FT_DEFINE_SERVICE_TTCMAPSREC(tt_service_get_cmap_info,
- (TT_CMap_Info_GetFunc)tt_get_cmap_info
- )
+ FT_DEFINE_SERVICE_TTCMAPSREC(
+ tt_service_get_cmap_info,
+ (TT_CMap_Info_GetFunc)tt_get_cmap_info )
#ifdef TT_CONFIG_OPTION_BDF
@@ -367,7 +371,7 @@
*acharset_registry = registry.u.atom;
}
else
- error = SFNT_Err_Invalid_Argument;
+ error = FT_THROW( Invalid_Argument );
}
}
@@ -375,10 +379,11 @@
}
- FT_DEFINE_SERVICE_BDFRec(sfnt_service_bdf,
- (FT_BDF_GetCharsetIdFunc) sfnt_get_charset_id,
- (FT_BDF_GetPropertyFunc) tt_face_find_bdf_prop
- )
+ FT_DEFINE_SERVICE_BDFRec(
+ sfnt_service_bdf,
+ (FT_BDF_GetCharsetIdFunc)sfnt_get_charset_id,
+ (FT_BDF_GetPropertyFunc) tt_face_find_bdf_prop )
+
#endif /* TT_CONFIG_OPTION_BDF */
@@ -388,33 +393,33 @@
*/
#if defined TT_CONFIG_OPTION_POSTSCRIPT_NAMES && defined TT_CONFIG_OPTION_BDF
- FT_DEFINE_SERVICEDESCREC5(sfnt_services,
- FT_SERVICE_ID_SFNT_TABLE, &FT_SFNT_SERVICE_SFNT_TABLE_GET,
- FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &FT_SFNT_SERVICE_PS_NAME_GET,
- FT_SERVICE_ID_GLYPH_DICT, &FT_SFNT_SERVICE_GLYPH_DICT_GET,
- FT_SERVICE_ID_BDF, &FT_SFNT_SERVICE_BDF_GET,
- FT_SERVICE_ID_TT_CMAP, &FT_TT_SERVICE_GET_CMAP_INFO_GET
- )
+ FT_DEFINE_SERVICEDESCREC5(
+ sfnt_services,
+ FT_SERVICE_ID_SFNT_TABLE, &SFNT_SERVICE_SFNT_TABLE_GET,
+ FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &SFNT_SERVICE_PS_NAME_GET,
+ FT_SERVICE_ID_GLYPH_DICT, &SFNT_SERVICE_GLYPH_DICT_GET,
+ FT_SERVICE_ID_BDF, &SFNT_SERVICE_BDF_GET,
+ FT_SERVICE_ID_TT_CMAP, &TT_SERVICE_CMAP_INFO_GET )
#elif defined TT_CONFIG_OPTION_POSTSCRIPT_NAMES
- FT_DEFINE_SERVICEDESCREC4(sfnt_services,
- FT_SERVICE_ID_SFNT_TABLE, &FT_SFNT_SERVICE_SFNT_TABLE_GET,
- FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &FT_SFNT_SERVICE_PS_NAME_GET,
- FT_SERVICE_ID_GLYPH_DICT, &FT_SFNT_SERVICE_GLYPH_DICT_GET,
- FT_SERVICE_ID_TT_CMAP, &FT_TT_SERVICE_GET_CMAP_INFO_GET
- )
+ FT_DEFINE_SERVICEDESCREC4(
+ sfnt_services,
+ FT_SERVICE_ID_SFNT_TABLE, &SFNT_SERVICE_SFNT_TABLE_GET,
+ FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &SFNT_SERVICE_PS_NAME_GET,
+ FT_SERVICE_ID_GLYPH_DICT, &SFNT_SERVICE_GLYPH_DICT_GET,
+ FT_SERVICE_ID_TT_CMAP, &TT_SERVICE_CMAP_INFO_GET )
#elif defined TT_CONFIG_OPTION_BDF
- FT_DEFINE_SERVICEDESCREC4(sfnt_services,
- FT_SERVICE_ID_SFNT_TABLE, &FT_SFNT_SERVICE_SFNT_TABLE_GET,
- FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &FT_SFNT_SERVICE_PS_NAME_GET,
- FT_SERVICE_ID_BDF, &FT_SFNT_SERVICE_BDF_GET,
- FT_SERVICE_ID_TT_CMAP, &FT_TT_SERVICE_GET_CMAP_INFO_GET
- )
+ FT_DEFINE_SERVICEDESCREC4(
+ sfnt_services,
+ FT_SERVICE_ID_SFNT_TABLE, &SFNT_SERVICE_SFNT_TABLE_GET,
+ FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &SFNT_SERVICE_PS_NAME_GET,
+ FT_SERVICE_ID_BDF, &SFNT_SERVICE_BDF_GET,
+ FT_SERVICE_ID_TT_CMAP, &TT_SERVICE_CMAP_INFO_GET )
#else
- FT_DEFINE_SERVICEDESCREC3(sfnt_services,
- FT_SERVICE_ID_SFNT_TABLE, &FT_SFNT_SERVICE_SFNT_TABLE_GET,
- FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &FT_SFNT_SERVICE_PS_NAME_GET,
- FT_SERVICE_ID_TT_CMAP, &FT_TT_SERVICE_GET_CMAP_INFO_GET
- )
+ FT_DEFINE_SERVICEDESCREC3(
+ sfnt_services,
+ FT_SERVICE_ID_SFNT_TABLE, &SFNT_SERVICE_SFNT_TABLE_GET,
+ FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &SFNT_SERVICE_PS_NAME_GET,
+ FT_SERVICE_ID_TT_CMAP, &TT_SERVICE_CMAP_INFO_GET )
#endif
@@ -422,7 +427,7 @@
sfnt_get_interface( FT_Module module,
const char* module_interface )
{
- /* FT_SFNT_SERVICES_GET derefers `library' in PIC mode */
+ /* SFNT_SERVICES_GET derefers `library' in PIC mode */
#ifdef FT_CONFIG_OPTION_PIC
FT_Library library;
@@ -435,149 +440,25 @@
#else
FT_UNUSED( module );
#endif
- return ft_service_list_lookup( FT_SFNT_SERVICES_GET, module_interface );
- }
-
-
-#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
-
- FT_CALLBACK_DEF( FT_Error )
- tt_face_load_sfnt_header_stub( TT_Face face,
- FT_Stream stream,
- FT_Long face_index,
- SFNT_Header header )
- {
- FT_UNUSED( face );
- FT_UNUSED( stream );
- FT_UNUSED( face_index );
- FT_UNUSED( header );
-
- return SFNT_Err_Unimplemented_Feature;
- }
-
-
- FT_CALLBACK_DEF( FT_Error )
- tt_face_load_directory_stub( TT_Face face,
- FT_Stream stream,
- SFNT_Header header )
- {
- FT_UNUSED( face );
- FT_UNUSED( stream );
- FT_UNUSED( header );
-
- return SFNT_Err_Unimplemented_Feature;
- }
-
-
- FT_CALLBACK_DEF( FT_Error )
- tt_face_load_hdmx_stub( TT_Face face,
- FT_Stream stream )
- {
- FT_UNUSED( face );
- FT_UNUSED( stream );
-
- return SFNT_Err_Unimplemented_Feature;
- }
-
-
- FT_CALLBACK_DEF( void )
- tt_face_free_hdmx_stub( TT_Face face )
- {
- FT_UNUSED( face );
- }
-
-
- FT_CALLBACK_DEF( FT_Error )
- tt_face_set_sbit_strike_stub( TT_Face face,
- FT_UInt x_ppem,
- FT_UInt y_ppem,
- FT_ULong* astrike_index )
- {
- /*
- * We simply forge a FT_Size_Request and call the real function
- * that does all the work.
- *
- * This stub might be called by libXfont in the X.Org Xserver,
- * compiled against version 2.1.8 or newer.
- */
-
- FT_Size_RequestRec req;
-
-
- req.type = FT_SIZE_REQUEST_TYPE_NOMINAL;
- req.width = (FT_F26Dot6)x_ppem;
- req.height = (FT_F26Dot6)y_ppem;
- req.horiResolution = 0;
- req.vertResolution = 0;
-
- *astrike_index = 0x7FFFFFFFUL;
- return tt_face_set_sbit_strike( face, &req, astrike_index );
+ return ft_service_list_lookup( SFNT_SERVICES_GET, module_interface );
}
- FT_CALLBACK_DEF( FT_Error )
- tt_face_load_sbit_stub( TT_Face face,
- FT_Stream stream )
- {
- FT_UNUSED( face );
- FT_UNUSED( stream );
-
- /*
- * This function was originally implemented to load the sbit table.
- * However, it has been replaced by `tt_face_load_eblc', and this stub
- * is only there for some rogue clients which would want to call it
- * directly (which doesn't make much sense).
- */
- return SFNT_Err_Unimplemented_Feature;
- }
-
-
- FT_CALLBACK_DEF( void )
- tt_face_free_sbit_stub( TT_Face face )
- {
- /* nothing to do in this stub */
- FT_UNUSED( face );
- }
-
-
- FT_CALLBACK_DEF( FT_Error )
- tt_face_load_charmap_stub( TT_Face face,
- void* cmap,
- FT_Stream input )
- {
- FT_UNUSED( face );
- FT_UNUSED( cmap );
- FT_UNUSED( input );
-
- return SFNT_Err_Unimplemented_Feature;
- }
-
-
- FT_CALLBACK_DEF( FT_Error )
- tt_face_free_charmap_stub( TT_Face face,
- void* cmap )
- {
- FT_UNUSED( face );
- FT_UNUSED( cmap );
-
- return SFNT_Err_Ok;
- }
-
-#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */
-
#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
-#define PUT_EMBEDDED_BITMAPS(a) a
+#define PUT_EMBEDDED_BITMAPS( a ) a
#else
-#define PUT_EMBEDDED_BITMAPS(a) 0
+#define PUT_EMBEDDED_BITMAPS( a ) NULL
#endif
+
#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
-#define PUT_PS_NAMES(a) a
+#define PUT_PS_NAMES( a ) a
#else
-#define PUT_PS_NAMES(a) 0
+#define PUT_PS_NAMES( a ) NULL
#endif
- FT_DEFINE_SFNT_INTERFACE(sfnt_interface,
+ FT_DEFINE_SFNT_INTERFACE(
+ sfnt_interface,
tt_face_goto_table,
sfnt_init_face,
@@ -587,9 +468,6 @@
tt_face_load_any,
- tt_face_load_sfnt_header_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */
- tt_face_load_directory_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */
-
tt_face_load_head,
tt_face_load_hhea,
tt_face_load_cmap,
@@ -600,54 +478,39 @@
tt_face_load_name,
tt_face_free_name,
- tt_face_load_hdmx_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */
- tt_face_free_hdmx_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */
-
tt_face_load_kern,
tt_face_load_gasp,
tt_face_load_pclt,
/* see `ttload.h' */
- PUT_EMBEDDED_BITMAPS(tt_face_load_bhed),
-
- tt_face_set_sbit_strike_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */
- tt_face_load_sbit_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */
-
- tt_find_sbit_image, /* FT_CONFIG_OPTION_OLD_INTERNALS */
- tt_load_sbit_metrics, /* FT_CONFIG_OPTION_OLD_INTERNALS */
-
- PUT_EMBEDDED_BITMAPS(tt_face_load_sbit_image),
+ PUT_EMBEDDED_BITMAPS( tt_face_load_bhed ),
- tt_face_free_sbit_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */
+ PUT_EMBEDDED_BITMAPS( tt_face_load_sbit_image ),
/* see `ttpost.h' */
- PUT_PS_NAMES(tt_face_get_ps_name),
- PUT_PS_NAMES(tt_face_free_ps_names),
-
- tt_face_load_charmap_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */
- tt_face_free_charmap_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */
+ PUT_PS_NAMES( tt_face_get_ps_name ),
+ PUT_PS_NAMES( tt_face_free_ps_names ),
/* since version 2.1.8 */
-
tt_face_get_kerning,
/* since version 2.2 */
-
tt_face_load_font_dir,
tt_face_load_hmtx,
/* see `ttsbit.h' and `sfnt.h' */
- PUT_EMBEDDED_BITMAPS(tt_face_load_eblc),
- PUT_EMBEDDED_BITMAPS(tt_face_free_eblc),
+ PUT_EMBEDDED_BITMAPS( tt_face_load_eblc ),
+ PUT_EMBEDDED_BITMAPS( tt_face_free_eblc ),
- PUT_EMBEDDED_BITMAPS(tt_face_set_sbit_strike),
- PUT_EMBEDDED_BITMAPS(tt_face_load_strike_metrics),
+ PUT_EMBEDDED_BITMAPS( tt_face_set_sbit_strike ),
+ PUT_EMBEDDED_BITMAPS( tt_face_load_strike_metrics ),
tt_face_get_metrics
)
- FT_DEFINE_MODULE(sfnt_module_class,
+ FT_DEFINE_MODULE(
+ sfnt_module_class,
0, /* not a font driver or renderer */
sizeof ( FT_ModuleRec ),
@@ -656,12 +519,11 @@
0x10000L, /* driver version 1.0 */
0x20000L, /* driver requires FreeType 2.0 or higher */
- (const void*)&FT_SFNT_INTERFACE_GET, /* module specific interface */
+ (const void*)&SFNT_INTERFACE_GET, /* module specific interface */
(FT_Module_Constructor)0,
(FT_Module_Destructor) 0,
- (FT_Module_Requester) sfnt_get_interface
- )
+ (FT_Module_Requester) sfnt_get_interface )
/* END */
diff --git a/src/sfnt/sferrors.h b/src/sfnt/sferrors.h
index 564a3fe..e981e1d 100644
--- a/src/sfnt/sferrors.h
+++ b/src/sfnt/sferrors.h
@@ -4,7 +4,7 @@
/* */
/* SFNT error codes (specification only). */
/* */
-/* Copyright 2001, 2004, 2012 by */
+/* Copyright 2001, 2004, 2012, 2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -33,8 +33,6 @@
#define FT_ERR_PREFIX SFNT_Err_
#define FT_ERR_BASE FT_Mod_Err_SFNT
-#define FT_KEEP_ERR_PREFIX
-
#include FT_ERRORS_H
#endif /* __SFERRORS_H__ */
diff --git a/src/sfnt/sfnt.c b/src/sfnt/sfnt.c
index fc507b4..d62ed4e 100644
--- a/src/sfnt/sfnt.c
+++ b/src/sfnt/sfnt.c
@@ -4,7 +4,7 @@
/* */
/* Single object library component. */
/* */
-/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by */
+/* Copyright 1996-2006, 2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -28,6 +28,7 @@
#include "sfdriver.c"
#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
+#include "pngshim.c"
#include "ttsbit.c"
#endif
diff --git a/src/sfnt/sfntpic.c b/src/sfnt/sfntpic.c
index 1372376..b3fb24b 100644
--- a/src/sfnt/sfntpic.c
+++ b/src/sfnt/sfntpic.c
@@ -4,7 +4,7 @@
/* */
/* The FreeType position independent code services for sfnt module. */
/* */
-/* Copyright 2009, 2010 by */
+/* Copyright 2009, 2010, 2012, 2013 by */
/* Oran Agra and Mickey Gabel. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -22,57 +22,52 @@
#include "sfntpic.h"
#include "sferrors.h"
+
#ifdef FT_CONFIG_OPTION_PIC
/* forward declaration of PIC init functions from sfdriver.c */
FT_Error
FT_Create_Class_sfnt_services( FT_Library library,
- FT_ServiceDescRec** ouput_class );
-
+ FT_ServiceDescRec** output_class );
void
FT_Destroy_Class_sfnt_services( FT_Library library,
FT_ServiceDescRec* clazz );
-
void
FT_Init_Class_sfnt_service_bdf( FT_Service_BDFRec* clazz );
-
void
FT_Init_Class_sfnt_interface( FT_Library library,
SFNT_Interface* clazz );
-
void
FT_Init_Class_sfnt_service_glyph_dict(
FT_Library library,
FT_Service_GlyphDictRec* clazz );
-
void
FT_Init_Class_sfnt_service_ps_name(
FT_Library library,
FT_Service_PsFontNameRec* clazz );
-
void
FT_Init_Class_tt_service_get_cmap_info(
FT_Library library,
FT_Service_TTCMapsRec* clazz );
-
void
FT_Init_Class_sfnt_service_sfnt_table(
FT_Service_SFNT_TableRec* clazz );
+
/* forward declaration of PIC init functions from ttcmap.c */
FT_Error
FT_Create_Class_tt_cmap_classes( FT_Library library,
TT_CMap_Class** output_class );
-
void
FT_Destroy_Class_tt_cmap_classes( FT_Library library,
TT_CMap_Class* clazz );
+
void
sfnt_module_class_pic_free( FT_Library library )
{
FT_PIC_Container* pic_container = &library->pic_container;
- FT_Memory memory = library->memory;
+ FT_Memory memory = library->memory;
if ( pic_container->sfnt )
@@ -84,10 +79,12 @@
FT_Destroy_Class_sfnt_services( library,
container->sfnt_services );
container->sfnt_services = NULL;
+
if ( container->tt_cmap_classes )
FT_Destroy_Class_tt_cmap_classes( library,
container->tt_cmap_classes );
container->tt_cmap_classes = NULL;
+
FT_FREE( container );
pic_container->sfnt = NULL;
}
@@ -95,25 +92,27 @@
FT_Error
- sfnt_module_class_pic_init( FT_Library library )
+ sfnt_module_class_pic_init( FT_Library library )
{
FT_PIC_Container* pic_container = &library->pic_container;
- FT_Error error = SFNT_Err_Ok;
- sfntModulePIC* container;
- FT_Memory memory = library->memory;
+ FT_Error error = FT_Err_Ok;
+ sfntModulePIC* container = NULL;
+ FT_Memory memory = library->memory;
/* allocate pointer, clear and set global container pointer */
- if ( FT_ALLOC ( container, sizeof ( *container ) ) )
+ if ( FT_ALLOC( container, sizeof ( *container ) ) )
return error;
FT_MEM_SET( container, 0, sizeof ( *container ) );
pic_container->sfnt = container;
- /* initialize pointer table - this is how the module usually expects this data */
+ /* initialize pointer table - */
+ /* this is how the module usually expects this data */
error = FT_Create_Class_sfnt_services( library,
&container->sfnt_services );
if ( error )
goto Exit;
+
error = FT_Create_Class_tt_cmap_classes( library,
&container->tt_cmap_classes );
if ( error )
@@ -132,14 +131,12 @@
#endif
FT_Init_Class_sfnt_interface( library, &container->sfnt_interface );
-Exit:
+ Exit:
if ( error )
sfnt_module_class_pic_free( library );
return error;
}
-
-
#endif /* FT_CONFIG_OPTION_PIC */
diff --git a/src/sfnt/sfntpic.h b/src/sfnt/sfntpic.h
index f7993d1..b09a914 100644
--- a/src/sfnt/sfntpic.h
+++ b/src/sfnt/sfntpic.h
@@ -4,7 +4,7 @@
/* */
/* The FreeType position independent code services for sfnt module. */
/* */
-/* Copyright 2009 by */
+/* Copyright 2009, 2012 by */
/* Oran Agra and Mickey Gabel. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -24,57 +24,76 @@ FT_BEGIN_HEADER
#include FT_INTERNAL_PIC_H
- #ifndef FT_CONFIG_OPTION_PIC
-#define FT_SFNT_SERVICES_GET sfnt_services
-#define FT_SFNT_SERVICE_GLYPH_DICT_GET sfnt_service_glyph_dict
-#define FT_SFNT_SERVICE_PS_NAME_GET sfnt_service_ps_name
-#define FT_TT_SERVICE_GET_CMAP_INFO_GET tt_service_get_cmap_info
-#define FT_SFNT_SERVICES_GET sfnt_services
-#define FT_TT_CMAP_CLASSES_GET tt_cmap_classes
-#define FT_SFNT_SERVICE_SFNT_TABLE_GET sfnt_service_sfnt_table
-#define FT_SFNT_SERVICE_BDF_GET sfnt_service_bdf
-#define FT_SFNT_INTERFACE_GET sfnt_interface
+
+#ifndef FT_CONFIG_OPTION_PIC
+
+#define SFNT_SERVICES_GET sfnt_services
+#define SFNT_SERVICE_GLYPH_DICT_GET sfnt_service_glyph_dict
+#define SFNT_SERVICE_PS_NAME_GET sfnt_service_ps_name
+#define TT_SERVICE_CMAP_INFO_GET tt_service_get_cmap_info
+#define SFNT_SERVICES_GET sfnt_services
+#define TT_CMAP_CLASSES_GET tt_cmap_classes
+#define SFNT_SERVICE_SFNT_TABLE_GET sfnt_service_sfnt_table
+#define SFNT_SERVICE_BDF_GET sfnt_service_bdf
+#define SFNT_INTERFACE_GET sfnt_interface
#else /* FT_CONFIG_OPTION_PIC */
-/* some include files required for members of sfntModulePIC */
+ /* some include files required for members of sfntModulePIC */
#include FT_SERVICE_GLYPH_DICT_H
#include FT_SERVICE_POSTSCRIPT_NAME_H
#include FT_SERVICE_SFNT_H
#include FT_SERVICE_TT_CMAP_H
+
#ifdef TT_CONFIG_OPTION_BDF
#include "ttbdf.h"
#include FT_SERVICE_BDF_H
#endif
+
#include FT_INTERNAL_DEBUG_H
#include FT_INTERNAL_STREAM_H
#include FT_INTERNAL_SFNT_H
#include "ttcmap.h"
-typedef struct sfntModulePIC_
+
+ typedef struct sfntModulePIC_
{
- FT_ServiceDescRec* sfnt_services;
- FT_Service_GlyphDictRec sfnt_service_glyph_dict;
+ FT_ServiceDescRec* sfnt_services;
+ FT_Service_GlyphDictRec sfnt_service_glyph_dict;
FT_Service_PsFontNameRec sfnt_service_ps_name;
- FT_Service_TTCMapsRec tt_service_get_cmap_info;
- TT_CMap_Class* tt_cmap_classes;
- FT_Service_SFNT_TableRec sfnt_service_sfnt_table;
+ FT_Service_TTCMapsRec tt_service_get_cmap_info;
+ TT_CMap_Class* tt_cmap_classes;
+ FT_Service_SFNT_TableRec sfnt_service_sfnt_table;
#ifdef TT_CONFIG_OPTION_BDF
- FT_Service_BDFRec sfnt_service_bdf;
+ FT_Service_BDFRec sfnt_service_bdf;
#endif
- SFNT_Interface sfnt_interface;
+ SFNT_Interface sfnt_interface;
+
} sfntModulePIC;
-#define GET_PIC(lib) ((sfntModulePIC*)((lib)->pic_container.sfnt))
-#define FT_SFNT_SERVICES_GET (GET_PIC(library)->sfnt_services)
-#define FT_SFNT_SERVICE_GLYPH_DICT_GET (GET_PIC(library)->sfnt_service_glyph_dict)
-#define FT_SFNT_SERVICE_PS_NAME_GET (GET_PIC(library)->sfnt_service_ps_name)
-#define FT_TT_SERVICE_GET_CMAP_INFO_GET (GET_PIC(library)->tt_service_get_cmap_info)
-#define FT_SFNT_SERVICES_GET (GET_PIC(library)->sfnt_services)
-#define FT_TT_CMAP_CLASSES_GET (GET_PIC(library)->tt_cmap_classes)
-#define FT_SFNT_SERVICE_SFNT_TABLE_GET (GET_PIC(library)->sfnt_service_sfnt_table)
-#define FT_SFNT_SERVICE_BDF_GET (GET_PIC(library)->sfnt_service_bdf)
-#define FT_SFNT_INTERFACE_GET (GET_PIC(library)->sfnt_interface)
+
+#define GET_PIC( lib ) \
+ ( (sfntModulePIC*)( (lib)->pic_container.sfnt ) )
+
+#define SFNT_SERVICES_GET \
+ ( GET_PIC( library )->sfnt_services )
+#define SFNT_SERVICE_GLYPH_DICT_GET \
+ ( GET_PIC( library )->sfnt_service_glyph_dict )
+#define SFNT_SERVICE_PS_NAME_GET \
+ ( GET_PIC( library )->sfnt_service_ps_name )
+#define TT_SERVICE_CMAP_INFO_GET \
+ ( GET_PIC( library )->tt_service_get_cmap_info )
+#define SFNT_SERVICES_GET \
+ ( GET_PIC( library )->sfnt_services )
+#define TT_CMAP_CLASSES_GET \
+ ( GET_PIC( library )->tt_cmap_classes )
+#define SFNT_SERVICE_SFNT_TABLE_GET \
+ ( GET_PIC( library )->sfnt_service_sfnt_table )
+#define SFNT_SERVICE_BDF_GET \
+ ( GET_PIC( library )->sfnt_service_bdf )
+#define SFNT_INTERFACE_GET \
+ ( GET_PIC( library )->sfnt_interface )
+
/* see sfntpic.c for the implementation */
void
@@ -85,7 +104,7 @@ typedef struct sfntModulePIC_
#endif /* FT_CONFIG_OPTION_PIC */
-/* */
+ /* */
FT_END_HEADER
diff --git a/src/sfnt/sfobjs.c b/src/sfnt/sfobjs.c
index d7be631..f975e71 100644
--- a/src/sfnt/sfobjs.c
+++ b/src/sfnt/sfobjs.c
@@ -4,7 +4,7 @@
/* */
/* SFNT object management (base). */
/* */
-/* Copyright 1996-2008, 2010-2011 by */
+/* Copyright 1996-2008, 2010-2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -64,13 +64,17 @@
for ( n = 0; n < len; n++ )
{
code = FT_NEXT_USHORT( read );
+
+ if ( code == 0 )
+ break;
+
if ( code < 32 || code > 127 )
code = '?';
string[n] = (char)code;
}
- string[len] = 0;
+ string[n] = 0;
return string;
}
@@ -95,13 +99,17 @@
for ( n = 0; n < len; n++ )
{
code = *read++;
+
+ if ( code == 0 )
+ break;
+
if ( code < 32 || code > 127 )
code = '?';
string[n] = (char)code;
}
- string[len] = 0;
+ string[n] = 0;
return string;
}
@@ -137,7 +145,7 @@
FT_String** name )
{
FT_Memory memory = face->root.memory;
- FT_Error error = SFNT_Err_Ok;
+ FT_Error error = FT_Err_Ok;
FT_String* result = NULL;
FT_UShort n;
TT_NameEntryRec* rec;
@@ -378,7 +386,7 @@
tag != 0x00020000UL )
{
FT_TRACE2(( " not a font using the SFNT container format\n" ));
- return SFNT_Err_Unknown_File_Format;
+ return FT_THROW( Unknown_File_Format );
}
face->ttc_header.tag = TTAG_ttcf;
@@ -394,7 +402,7 @@
return error;
if ( face->ttc_header.count == 0 )
- return SFNT_Err_Invalid_Table;
+ return FT_THROW( Invalid_Table );
/* a rough size estimate: let's conservatively assume that there */
/* is just a single table info in each subfont header (12 + 16*1 = */
@@ -402,7 +410,7 @@
/* size of the TTC header plus `28*count' bytes for all subfont */
/* headers */
if ( (FT_ULong)face->ttc_header.count > stream->size / ( 28 + 4 ) )
- return SFNT_Err_Array_Too_Large;
+ return FT_THROW( Array_Too_Large );
/* now read the offsets of each font in the file */
if ( FT_NEW_ARRAY( face->ttc_header.offsets, face->ttc_header.count ) )
@@ -457,7 +465,7 @@
if ( !sfnt )
{
FT_ERROR(( "sfnt_init_face: cannot access `sfnt' module\n" ));
- return SFNT_Err_Missing_Module;
+ return FT_THROW( Missing_Module );
}
face->sfnt = sfnt;
@@ -478,7 +486,7 @@
face_index = 0;
if ( face_index >= face->ttc_header.count )
- return SFNT_Err_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
if ( FT_STREAM_SEEK( face->ttc_header.offsets[face_index] ) )
return error;
@@ -495,42 +503,42 @@
}
-#define LOAD_( x ) \
- do { \
- FT_TRACE2(( "`" #x "' " )); \
- FT_TRACE3(( "-->\n" )); \
- \
- error = sfnt->load_##x( face, stream ); \
- \
- FT_TRACE2(( "%s\n", ( !error ) \
- ? "loaded" \
- : ( error == SFNT_Err_Table_Missing ) \
- ? "missing" \
- : "failed to load" )); \
- FT_TRACE3(( "\n" )); \
+#define LOAD_( x ) \
+ do { \
+ FT_TRACE2(( "`" #x "' " )); \
+ FT_TRACE3(( "-->\n" )); \
+ \
+ error = sfnt->load_ ## x( face, stream ); \
+ \
+ FT_TRACE2(( "%s\n", ( !error ) \
+ ? "loaded" \
+ : FT_ERR_EQ( error, Table_Missing ) \
+ ? "missing" \
+ : "failed to load" )); \
+ FT_TRACE3(( "\n" )); \
} while ( 0 )
-#define LOADM_( x, vertical ) \
- do { \
- FT_TRACE2(( "`%s" #x "' ", \
- vertical ? "vertical " : "" )); \
- FT_TRACE3(( "-->\n" )); \
- \
- error = sfnt->load_##x( face, stream, vertical ); \
- \
- FT_TRACE2(( "%s\n", ( !error ) \
- ? "loaded" \
- : ( error == SFNT_Err_Table_Missing ) \
- ? "missing" \
- : "failed to load" )); \
- FT_TRACE3(( "\n" )); \
+#define LOADM_( x, vertical ) \
+ do { \
+ FT_TRACE2(( "`%s" #x "' ", \
+ vertical ? "vertical " : "" )); \
+ FT_TRACE3(( "-->\n" )); \
+ \
+ error = sfnt->load_ ## x( face, stream, vertical ); \
+ \
+ FT_TRACE2(( "%s\n", ( !error ) \
+ ? "loaded" \
+ : FT_ERR_EQ( error, Table_Missing ) \
+ ? "missing" \
+ : "failed to load" )); \
+ FT_TRACE3(( "\n" )); \
} while ( 0 )
-#define GET_NAME( id, field ) \
- do { \
- error = tt_face_get_name( face, TT_NAME_ID_##id, field ); \
- if ( error ) \
- goto Exit; \
+#define GET_NAME( id, field ) \
+ do { \
+ error = tt_face_get_name( face, TT_NAME_ID_ ## id, field ); \
+ if ( error ) \
+ goto Exit; \
} while ( 0 )
@@ -547,13 +555,14 @@
#endif
FT_Bool has_outline;
FT_Bool is_apple_sbit;
- FT_Bool ignore_preferred_family = FALSE;
+ FT_Bool ignore_preferred_family = FALSE;
FT_Bool ignore_preferred_subfamily = FALSE;
SFNT_Service sfnt = (SFNT_Service)face->sfnt;
FT_UNUSED( face_index );
+
/* Check parameters */
{
@@ -619,7 +628,7 @@
if ( face->header.Units_Per_EM == 0 )
{
- error = SFNT_Err_Invalid_Table;
+ error = FT_THROW( Invalid_Table );
goto Exit;
}
@@ -647,9 +656,9 @@
if ( !error )
{
LOADM_( hmtx, 0 );
- if ( error == SFNT_Err_Table_Missing )
+ if ( FT_ERR_EQ( error, Table_Missing ) )
{
- error = SFNT_Err_Hmtx_Table_Missing;
+ error = FT_THROW( Hmtx_Table_Missing );
#ifdef FT_CONFIG_OPTION_INCREMENTAL
/* If this is an incrementally loaded font and there are */
@@ -659,12 +668,12 @@
get_glyph_metrics )
{
face->horizontal.number_Of_HMetrics = 0;
- error = SFNT_Err_Ok;
+ error = FT_Err_Ok;
}
#endif
}
}
- else if ( error == SFNT_Err_Table_Missing )
+ else if ( FT_ERR_EQ( error, Table_Missing ) )
{
/* No `hhea' table necessary for SFNT Mac fonts. */
if ( face->format_tag == TTAG_true )
@@ -672,11 +681,11 @@
FT_TRACE2(( "This is an SFNT Mac font.\n" ));
has_outline = 0;
- error = SFNT_Err_Ok;
+ error = FT_Err_Ok;
}
else
{
- error = SFNT_Err_Horiz_Header_Missing;
+ error = FT_THROW( Horiz_Header_Missing );
#ifdef FT_CONFIG_OPTION_INCREMENTAL
/* If this is an incrementally loaded font and there are */
@@ -686,7 +695,7 @@
get_glyph_metrics )
{
face->horizontal.number_Of_HMetrics = 0;
- error = SFNT_Err_Ok;
+ error = FT_Err_Ok;
}
#endif
@@ -705,7 +714,7 @@
face->vertical_info = 1;
}
- if ( error && error != SFNT_Err_Table_Missing )
+ if ( error && FT_ERR_NEQ( error, Table_Missing ) )
goto Exit;
LOAD_( os2 );
@@ -727,8 +736,8 @@
/* a font which contains neither bitmaps nor outlines is */
/* still valid (although rather useless in most cases); */
/* however, you can find such stripped fonts in PDFs */
- if ( error == SFNT_Err_Table_Missing )
- error = SFNT_Err_Ok;
+ if ( FT_ERR_EQ( error, Table_Missing ) )
+ error = FT_Err_Ok;
else
goto Exit;
}
@@ -737,7 +746,7 @@
LOAD_( pclt );
if ( error )
{
- if ( error != SFNT_Err_Table_Missing )
+ if ( FT_ERR_NEQ( error, Table_Missing ) )
goto Exit;
face->pclt.Version = 0;
@@ -803,7 +812,7 @@
FT_FACE_FLAG_HORIZONTAL; /* horizontal data */
#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
- if ( psnames_error == SFNT_Err_Ok &&
+ if ( !psnames_error &&
face->postscript.FormatType != 0x00030000L )
flags |= FT_FACE_FLAG_GLYPH_NAMES;
#endif
@@ -910,11 +919,7 @@
FT_UInt i, count;
-#ifndef FT_CONFIG_OPTION_OLD_INTERNALS
count = face->sbit_num_strikes;
-#else
- count = (FT_UInt)face->num_sbit_strikes;
-#endif
if ( count > 0 )
{
@@ -1115,7 +1120,6 @@
}
/* freeing the horizontal metrics */
-#ifndef FT_CONFIG_OPTION_OLD_INTERNALS
{
FT_Stream stream = FT_FACE_STREAM( face );
@@ -1125,10 +1129,6 @@
face->horz_metrics_size = 0;
face->vert_metrics_size = 0;
}
-#else
- FT_FREE( face->horizontal.long_metrics );
- FT_FREE( face->horizontal.short_metrics );
-#endif
/* freeing the vertical ones, if any */
if ( face->vertical_info )
diff --git a/src/sfnt/ttbdf.c b/src/sfnt/ttbdf.c
index 18845c3..9401dae 100644
--- a/src/sfnt/ttbdf.c
+++ b/src/sfnt/ttbdf.c
@@ -4,7 +4,7 @@
/* */
/* TrueType and OpenType embedded BDF properties (body). */
/* */
-/* Copyright 2005, 2006, 2010 by */
+/* Copyright 2005, 2006, 2010, 2013 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 @@
length < 8 ||
FT_FRAME_EXTRACT( length, bdf->table ) )
{
- error = SFNT_Err_Invalid_Table;
+ error = FT_THROW( Invalid_Table );
goto Exit;
}
@@ -131,7 +131,7 @@
BadTable:
FT_FRAME_RELEASE( bdf->table );
FT_ZERO( bdf );
- error = SFNT_Err_Invalid_Table;
+ error = FT_THROW( Invalid_Table );
goto Exit;
}
@@ -143,7 +143,7 @@
{
TT_BDF bdf = &face->bdf;
FT_Size size = FT_FACE(face)->size;
- FT_Error error = SFNT_Err_Ok;
+ FT_Error error = FT_Err_Ok;
FT_Byte* p;
FT_UInt count;
FT_Byte* strike;
@@ -163,7 +163,7 @@
p = bdf->table + 8;
strike = p + 4 * count;
- error = SFNT_Err_Invalid_Argument;
+ error = FT_ERR( Invalid_Argument );
if ( size == NULL || property_name == NULL )
goto Exit;
@@ -215,7 +215,7 @@
{
aprop->type = BDF_PROPERTY_TYPE_ATOM;
aprop->u.atom = (const char*)bdf->strings + value;
- error = SFNT_Err_Ok;
+ error = FT_Err_Ok;
goto Exit;
}
break;
@@ -223,13 +223,13 @@
case 0x02:
aprop->type = BDF_PROPERTY_TYPE_INTEGER;
aprop->u.integer = (FT_Int32)value;
- error = SFNT_Err_Ok;
+ error = FT_Err_Ok;
goto Exit;
case 0x03:
aprop->type = BDF_PROPERTY_TYPE_CARDINAL;
aprop->u.cardinal = value;
- error = SFNT_Err_Ok;
+ error = FT_Err_Ok;
goto Exit;
default:
diff --git a/src/sfnt/ttcmap.c b/src/sfnt/ttcmap.c
index 1dfd987..1507202 100644
--- a/src/sfnt/ttcmap.c
+++ b/src/sfnt/ttcmap.c
@@ -4,7 +4,7 @@
/* */
/* TrueType character mapping table (cmap) support (body). */
/* */
-/* Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 by */
+/* Copyright 2002-2010, 2012, 2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -56,7 +56,7 @@
FT_Byte* table )
{
cmap->data = table;
- return SFNT_Err_Ok;
+ return FT_Err_Ok;
}
@@ -110,7 +110,7 @@
}
}
- return SFNT_Err_Ok;
+ return FT_Err_Ok;
}
@@ -161,24 +161,28 @@
cmap_info->format = 0;
cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p );
- return SFNT_Err_Ok;
+ return FT_Err_Ok;
}
- FT_DEFINE_TT_CMAP(tt_cmap0_class_rec,
- sizeof ( TT_CMapRec ),
+ FT_DEFINE_TT_CMAP(
+ tt_cmap0_class_rec,
+ sizeof ( TT_CMapRec ),
- (FT_CMap_InitFunc) tt_cmap_init,
- (FT_CMap_DoneFunc) NULL,
- (FT_CMap_CharIndexFunc)tt_cmap0_char_index,
- (FT_CMap_CharNextFunc) tt_cmap0_char_next,
+ (FT_CMap_InitFunc) tt_cmap_init,
+ (FT_CMap_DoneFunc) NULL,
+ (FT_CMap_CharIndexFunc)tt_cmap0_char_index,
+ (FT_CMap_CharNextFunc) tt_cmap0_char_next,
+
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
- NULL, NULL, NULL, NULL, NULL
- ,
0,
- (TT_CMap_ValidateFunc) tt_cmap0_validate,
- (TT_CMap_Info_GetFunc) tt_cmap0_get_info
- )
+ (TT_CMap_ValidateFunc)tt_cmap0_validate,
+ (TT_CMap_Info_GetFunc)tt_cmap0_get_info )
#endif /* TT_CONFIG_CMAP_FORMAT_0 */
@@ -365,7 +369,7 @@
}
}
- return SFNT_Err_Ok;
+ return FT_Err_Ok;
}
@@ -537,24 +541,28 @@
cmap_info->format = 2;
cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p );
- return SFNT_Err_Ok;
+ return FT_Err_Ok;
}
- FT_DEFINE_TT_CMAP(tt_cmap2_class_rec,
- sizeof ( TT_CMapRec ),
+ FT_DEFINE_TT_CMAP(
+ tt_cmap2_class_rec,
+ sizeof ( TT_CMapRec ),
- (FT_CMap_InitFunc) tt_cmap_init,
- (FT_CMap_DoneFunc) NULL,
- (FT_CMap_CharIndexFunc)tt_cmap2_char_index,
- (FT_CMap_CharNextFunc) tt_cmap2_char_next,
+ (FT_CMap_InitFunc) tt_cmap_init,
+ (FT_CMap_DoneFunc) NULL,
+ (FT_CMap_CharIndexFunc)tt_cmap2_char_index,
+ (FT_CMap_CharNextFunc) tt_cmap2_char_next,
+
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
- NULL, NULL, NULL, NULL, NULL
- ,
2,
- (TT_CMap_ValidateFunc) tt_cmap2_validate,
- (TT_CMap_Info_GetFunc) tt_cmap2_get_info
- )
+ (TT_CMap_ValidateFunc)tt_cmap2_validate,
+ (TT_CMap_Info_GetFunc)tt_cmap2_get_info )
#endif /* TT_CONFIG_CMAP_FORMAT_2 */
@@ -662,7 +670,7 @@
cmap->cur_charcode = (FT_UInt32)0xFFFFFFFFUL;
cmap->cur_gindex = 0;
- return SFNT_Err_Ok;
+ return FT_Err_Ok;
}
@@ -812,7 +820,7 @@
FT_UInt length = TT_NEXT_USHORT( p );
FT_Byte *ends, *starts, *offsets, *deltas, *glyph_ids;
FT_UInt num_segs;
- FT_Error error = SFNT_Err_Ok;
+ FT_Error error = FT_Err_Ok;
if ( length < 16 )
@@ -1373,23 +1381,27 @@
cmap_info->format = 4;
cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p );
- return SFNT_Err_Ok;
+ return FT_Err_Ok;
}
- FT_DEFINE_TT_CMAP(tt_cmap4_class_rec,
- sizeof ( TT_CMap4Rec ),
- (FT_CMap_InitFunc) tt_cmap4_init,
- (FT_CMap_DoneFunc) NULL,
- (FT_CMap_CharIndexFunc)tt_cmap4_char_index,
- (FT_CMap_CharNextFunc) tt_cmap4_char_next,
+ FT_DEFINE_TT_CMAP(
+ tt_cmap4_class_rec,
+ sizeof ( TT_CMap4Rec ),
+ (FT_CMap_InitFunc) tt_cmap4_init,
+ (FT_CMap_DoneFunc) NULL,
+ (FT_CMap_CharIndexFunc)tt_cmap4_char_index,
+ (FT_CMap_CharNextFunc) tt_cmap4_char_next,
+
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
- NULL, NULL, NULL, NULL, NULL
- ,
4,
- (TT_CMap_ValidateFunc) tt_cmap4_validate,
- (TT_CMap_Info_GetFunc) tt_cmap4_get_info
- )
+ (TT_CMap_ValidateFunc)tt_cmap4_validate,
+ (TT_CMap_Info_GetFunc)tt_cmap4_get_info )
#endif /* TT_CONFIG_CMAP_FORMAT_4 */
@@ -1456,7 +1468,7 @@
}
}
- return SFNT_Err_Ok;
+ return FT_Err_Ok;
}
@@ -1532,24 +1544,28 @@
cmap_info->format = 6;
cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p );
- return SFNT_Err_Ok;
+ return FT_Err_Ok;
}
- FT_DEFINE_TT_CMAP(tt_cmap6_class_rec,
- sizeof ( TT_CMapRec ),
+ FT_DEFINE_TT_CMAP(
+ tt_cmap6_class_rec,
+ sizeof ( TT_CMapRec ),
- (FT_CMap_InitFunc) tt_cmap_init,
- (FT_CMap_DoneFunc) NULL,
- (FT_CMap_CharIndexFunc)tt_cmap6_char_index,
- (FT_CMap_CharNextFunc) tt_cmap6_char_next,
+ (FT_CMap_InitFunc) tt_cmap_init,
+ (FT_CMap_DoneFunc) NULL,
+ (FT_CMap_CharIndexFunc)tt_cmap6_char_index,
+ (FT_CMap_CharNextFunc) tt_cmap6_char_next,
+
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
- NULL, NULL, NULL, NULL, NULL
- ,
6,
- (TT_CMap_ValidateFunc) tt_cmap6_validate,
- (TT_CMap_Info_GetFunc) tt_cmap6_get_info
- )
+ (TT_CMap_ValidateFunc)tt_cmap6_validate,
+ (TT_CMap_Info_GetFunc)tt_cmap6_get_info )
#endif /* TT_CONFIG_CMAP_FORMAT_6 */
@@ -1700,7 +1716,7 @@
}
}
- return SFNT_Err_Ok;
+ return FT_Err_Ok;
}
@@ -1785,24 +1801,28 @@
cmap_info->format = 8;
cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p );
- return SFNT_Err_Ok;
+ return FT_Err_Ok;
}
- FT_DEFINE_TT_CMAP(tt_cmap8_class_rec,
- sizeof ( TT_CMapRec ),
+ FT_DEFINE_TT_CMAP(
+ tt_cmap8_class_rec,
+ sizeof ( TT_CMapRec ),
- (FT_CMap_InitFunc) tt_cmap_init,
- (FT_CMap_DoneFunc) NULL,
- (FT_CMap_CharIndexFunc)tt_cmap8_char_index,
- (FT_CMap_CharNextFunc) tt_cmap8_char_next,
+ (FT_CMap_InitFunc) tt_cmap_init,
+ (FT_CMap_DoneFunc) NULL,
+ (FT_CMap_CharIndexFunc)tt_cmap8_char_index,
+ (FT_CMap_CharNextFunc) tt_cmap8_char_next,
+
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
- NULL, NULL, NULL, NULL, NULL
- ,
8,
- (TT_CMap_ValidateFunc) tt_cmap8_validate,
- (TT_CMap_Info_GetFunc) tt_cmap8_get_info
- )
+ (TT_CMap_ValidateFunc)tt_cmap8_validate,
+ (TT_CMap_Info_GetFunc)tt_cmap8_get_info )
#endif /* TT_CONFIG_CMAP_FORMAT_8 */
@@ -1867,7 +1887,7 @@
}
}
- return SFNT_Err_Ok;
+ return FT_Err_Ok;
}
@@ -1934,24 +1954,28 @@
cmap_info->format = 10;
cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p );
- return SFNT_Err_Ok;
+ return FT_Err_Ok;
}
- FT_DEFINE_TT_CMAP(tt_cmap10_class_rec,
- sizeof ( TT_CMapRec ),
+ FT_DEFINE_TT_CMAP(
+ tt_cmap10_class_rec,
+ sizeof ( TT_CMapRec ),
+
+ (FT_CMap_InitFunc) tt_cmap_init,
+ (FT_CMap_DoneFunc) NULL,
+ (FT_CMap_CharIndexFunc)tt_cmap10_char_index,
+ (FT_CMap_CharNextFunc) tt_cmap10_char_next,
- (FT_CMap_InitFunc) tt_cmap_init,
- (FT_CMap_DoneFunc) NULL,
- (FT_CMap_CharIndexFunc)tt_cmap10_char_index,
- (FT_CMap_CharNextFunc) tt_cmap10_char_next,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
- NULL, NULL, NULL, NULL, NULL
- ,
10,
- (TT_CMap_ValidateFunc) tt_cmap10_validate,
- (TT_CMap_Info_GetFunc) tt_cmap10_get_info
- )
+ (TT_CMap_ValidateFunc)tt_cmap10_validate,
+ (TT_CMap_Info_GetFunc)tt_cmap10_get_info )
#endif /* TT_CONFIG_CMAP_FORMAT_10 */
@@ -2010,7 +2034,7 @@
cmap->valid = 0;
- return SFNT_Err_Ok;
+ return FT_Err_Ok;
}
@@ -2063,7 +2087,7 @@
}
}
- return SFNT_Err_Ok;
+ return FT_Err_Ok;
}
@@ -2254,24 +2278,28 @@
cmap_info->format = 12;
cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p );
- return SFNT_Err_Ok;
+ return FT_Err_Ok;
}
- FT_DEFINE_TT_CMAP(tt_cmap12_class_rec,
- sizeof ( TT_CMap12Rec ),
+ FT_DEFINE_TT_CMAP(
+ tt_cmap12_class_rec,
+ sizeof ( TT_CMap12Rec ),
+
+ (FT_CMap_InitFunc) tt_cmap12_init,
+ (FT_CMap_DoneFunc) NULL,
+ (FT_CMap_CharIndexFunc)tt_cmap12_char_index,
+ (FT_CMap_CharNextFunc) tt_cmap12_char_next,
- (FT_CMap_InitFunc) tt_cmap12_init,
- (FT_CMap_DoneFunc) NULL,
- (FT_CMap_CharIndexFunc)tt_cmap12_char_index,
- (FT_CMap_CharNextFunc) tt_cmap12_char_next,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
- NULL, NULL, NULL, NULL, NULL
- ,
12,
- (TT_CMap_ValidateFunc) tt_cmap12_validate,
- (TT_CMap_Info_GetFunc) tt_cmap12_get_info
- )
+ (TT_CMap_ValidateFunc)tt_cmap12_validate,
+ (TT_CMap_Info_GetFunc)tt_cmap12_get_info )
#endif /* TT_CONFIG_CMAP_FORMAT_12 */
@@ -2330,7 +2358,7 @@
cmap->valid = 0;
- return SFNT_Err_Ok;
+ return FT_Err_Ok;
}
@@ -2338,9 +2366,9 @@
tt_cmap13_validate( FT_Byte* table,
FT_Validator valid )
{
- FT_Byte* p;
- FT_ULong length;
- FT_ULong num_groups;
+ FT_Byte* p;
+ FT_ULong length;
+ FT_ULong num_groups;
if ( table + 16 > valid->limit )
@@ -2383,7 +2411,7 @@
}
}
- return SFNT_Err_Ok;
+ return FT_Err_Ok;
}
@@ -2490,7 +2518,6 @@
/* if `char_code' is not in any group, then `mid' is */
/* the group nearest to `char_code' */
- /* */
if ( char_code > end )
{
@@ -2570,24 +2597,28 @@
cmap_info->format = 13;
cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p );
- return SFNT_Err_Ok;
+ return FT_Err_Ok;
}
- FT_DEFINE_TT_CMAP(tt_cmap13_class_rec,
- sizeof ( TT_CMap13Rec ),
+ FT_DEFINE_TT_CMAP(
+ tt_cmap13_class_rec,
+ sizeof ( TT_CMap13Rec ),
- (FT_CMap_InitFunc) tt_cmap13_init,
- (FT_CMap_DoneFunc) NULL,
- (FT_CMap_CharIndexFunc)tt_cmap13_char_index,
- (FT_CMap_CharNextFunc) tt_cmap13_char_next,
+ (FT_CMap_InitFunc) tt_cmap13_init,
+ (FT_CMap_DoneFunc) NULL,
+ (FT_CMap_CharIndexFunc)tt_cmap13_char_index,
+ (FT_CMap_CharNextFunc) tt_cmap13_char_next,
+
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
- NULL, NULL, NULL, NULL, NULL
- ,
13,
- (TT_CMap_ValidateFunc) tt_cmap13_validate,
- (TT_CMap_Info_GetFunc) tt_cmap13_get_info
- )
+ (TT_CMap_ValidateFunc)tt_cmap13_validate,
+ (TT_CMap_Info_GetFunc)tt_cmap13_get_info )
#endif /* TT_CONFIG_CMAP_FORMAT_13 */
@@ -2688,8 +2719,8 @@
FT_UInt32 num_results,
FT_Memory memory )
{
- FT_UInt32 old_max = cmap->max_results;
- FT_Error error = SFNT_Err_Ok;
+ FT_UInt32 old_max = cmap->max_results;
+ FT_Error error = FT_Err_Ok;
if ( num_results > cmap->max_results )
@@ -2713,11 +2744,11 @@
cmap->cmap.data = table;
table += 6;
- cmap->num_selectors = FT_PEEK_ULONG( table );
- cmap->max_results = 0;
- cmap->results = NULL;
+ cmap->num_selectors = FT_PEEK_ULONG( table );
+ cmap->max_results = 0;
+ cmap->results = NULL;
- return SFNT_Err_Ok;
+ return FT_Err_Ok;
}
@@ -2791,7 +2822,7 @@
{
FT_Byte* ndp = table + nondefOff;
FT_ULong numMappings = TT_NEXT_ULONG( ndp );
- FT_ULong i, lastUni = 0;
+ FT_ULong i, lastUni = 0;
if ( numMappings * 4 > (FT_ULong)( valid->limit - ndp ) )
@@ -2819,7 +2850,7 @@
}
}
- return SFNT_Err_Ok;
+ return FT_Err_Ok;
}
@@ -2857,7 +2888,7 @@
/* subtable 14 does not define a language field */
cmap_info->language = 0xFFFFFFFFUL;
- return SFNT_Err_Ok;
+ return FT_Err_Ok;
}
@@ -2965,7 +2996,7 @@
tt_cmap14_char_var_index( TT_CMap cmap,
TT_CMap ucmap,
FT_UInt32 charcode,
- FT_UInt32 variantSelector)
+ FT_UInt32 variantSelector )
{
FT_Byte* p = tt_cmap14_find_variant( cmap->data + 6, variantSelector );
FT_ULong defOff;
@@ -3106,9 +3137,9 @@
static FT_UInt32*
- tt_cmap14_get_def_chars( TT_CMap cmap,
- FT_Byte* p,
- FT_Memory memory )
+ tt_cmap14_get_def_chars( TT_CMap cmap,
+ FT_Byte* p,
+ FT_Memory memory )
{
TT_CMap14 cmap14 = (TT_CMap14) cmap;
FT_UInt32 numRanges;
@@ -3124,7 +3155,7 @@
for ( q = cmap14->results; numRanges > 0; --numRanges )
{
- FT_UInt32 uni = (FT_UInt32)TT_NEXT_UINT24( p );
+ FT_UInt32 uni = (FT_UInt32)TT_NEXT_UINT24( p );
cnt = FT_NEXT_BYTE( p ) + 1;
@@ -3133,6 +3164,7 @@
q[0] = uni;
uni += 1;
q += 1;
+
} while ( --cnt != 0 );
}
q[0] = 0;
@@ -3306,25 +3338,25 @@
}
- FT_DEFINE_TT_CMAP(tt_cmap14_class_rec,
- sizeof ( TT_CMap14Rec ),
+ FT_DEFINE_TT_CMAP(
+ tt_cmap14_class_rec,
+ sizeof ( TT_CMap14Rec ),
- (FT_CMap_InitFunc) tt_cmap14_init,
- (FT_CMap_DoneFunc) tt_cmap14_done,
- (FT_CMap_CharIndexFunc)tt_cmap14_char_index,
- (FT_CMap_CharNextFunc) tt_cmap14_char_next,
+ (FT_CMap_InitFunc) tt_cmap14_init,
+ (FT_CMap_DoneFunc) tt_cmap14_done,
+ (FT_CMap_CharIndexFunc)tt_cmap14_char_index,
+ (FT_CMap_CharNextFunc) tt_cmap14_char_next,
+
+ /* Format 14 extension functions */
+ (FT_CMap_CharVarIndexFunc) tt_cmap14_char_var_index,
+ (FT_CMap_CharVarIsDefaultFunc)tt_cmap14_char_var_isdefault,
+ (FT_CMap_VariantListFunc) tt_cmap14_variants,
+ (FT_CMap_CharVariantListFunc) tt_cmap14_char_variants,
+ (FT_CMap_VariantCharListFunc) tt_cmap14_variant_chars,
- /* Format 14 extension functions */
- (FT_CMap_CharVarIndexFunc) tt_cmap14_char_var_index,
- (FT_CMap_CharVarIsDefaultFunc)tt_cmap14_char_var_isdefault,
- (FT_CMap_VariantListFunc) tt_cmap14_variants,
- (FT_CMap_CharVariantListFunc) tt_cmap14_char_variants,
- (FT_CMap_VariantCharListFunc) tt_cmap14_variant_chars
- ,
14,
(TT_CMap_ValidateFunc)tt_cmap14_validate,
- (TT_CMap_Info_GetFunc)tt_cmap14_get_info
- )
+ (TT_CMap_Info_GetFunc)tt_cmap14_get_info )
#endif /* TT_CONFIG_CMAP_FORMAT_14 */
@@ -3333,50 +3365,62 @@
static const TT_CMap_Class tt_cmap_classes[] =
{
-#define TTCMAPCITEM(a) &a,
+#define TTCMAPCITEM( a ) &a,
#include "ttcmapc.h"
NULL,
};
#else /*FT_CONFIG_OPTION_PIC*/
- void FT_Destroy_Class_tt_cmap_classes(FT_Library library, TT_CMap_Class* clazz)
+ void
+ FT_Destroy_Class_tt_cmap_classes( FT_Library library,
+ TT_CMap_Class* clazz )
{
- FT_Memory memory = library->memory;
+ FT_Memory memory = library->memory;
+
+
if ( clazz )
FT_FREE( clazz );
}
- FT_Error FT_Create_Class_tt_cmap_classes(FT_Library library, TT_CMap_Class** output_class)
+
+ FT_Error
+ FT_Create_Class_tt_cmap_classes( FT_Library library,
+ TT_CMap_Class** output_class )
{
- TT_CMap_Class* clazz;
- TT_CMap_ClassRec* recs;
- FT_Error error;
- FT_Memory memory = library->memory;
- int i = 0;
+ TT_CMap_Class* clazz = NULL;
+ TT_CMap_ClassRec* recs;
+ FT_Error error;
+ FT_Memory memory = library->memory;
-#define TTCMAPCITEM(a) i++;
+ int i = 0;
+
+
+#define TTCMAPCITEM( a ) i++;
#include "ttcmapc.h"
- /* allocate enough space for both the pointers +terminator and the class instances */
- if ( FT_ALLOC( clazz, sizeof(*clazz)*(i+1)+sizeof(TT_CMap_ClassRec)*i ) )
+ /* allocate enough space for both the pointers */
+ /* plus terminator and the class instances */
+ if ( FT_ALLOC( clazz, sizeof ( *clazz ) * ( i + 1 ) +
+ sizeof ( TT_CMap_ClassRec ) * i ) )
return error;
/* the location of the class instances follows the array of pointers */
- recs = (TT_CMap_ClassRec*) (((char*)clazz)+(sizeof(*clazz)*(i+1)));
- i=0;
+ recs = (TT_CMap_ClassRec*)( (char*)clazz +
+ sizeof ( *clazz ) * ( i + 1 ) );
+ i = 0;
#undef TTCMAPCITEM
-#define TTCMAPCITEM(a) \
- FT_Init_Class_##a(&recs[i]); \
- clazz[i] = &recs[i]; \
+#define TTCMAPCITEM( a ) \
+ FT_Init_Class_ ## a( &recs[i] ); \
+ clazz[i] = &recs[i]; \
i++;
#include "ttcmapc.h"
clazz[i] = NULL;
*output_class = clazz;
- return SFNT_Err_Ok;
+ return FT_Err_Ok;
}
#endif /*FT_CONFIG_OPTION_PIC*/
@@ -3398,7 +3442,7 @@
if ( !p || p + 4 > limit )
- return SFNT_Err_Invalid_Table;
+ return FT_THROW( Invalid_Table );
/* only recognize format 0 */
if ( TT_NEXT_USHORT( p ) != 0 )
@@ -3407,14 +3451,16 @@
FT_ERROR(( "tt_face_build_cmaps:"
" unsupported `cmap' table format = %d\n",
TT_PEEK_USHORT( p ) ));
- return SFNT_Err_Invalid_Table;
+ return FT_THROW( Invalid_Table );
}
num_cmaps = TT_NEXT_USHORT( p );
+
#ifdef FT_MAX_CHARMAP_CACHEABLE
if ( num_cmaps > FT_MAX_CHARMAP_CACHEABLE )
- FT_ERROR(( "tt_face_build_cmaps: too many cmap subtables(%d) "
- "subtable#%d and later are loaded but cannot be searched\n",
+ FT_ERROR(( "tt_face_build_cmaps: too many cmap subtables (%d)\n"
+ " subtable #%d and higher are loaded"
+ " but cannot be searched\n",
num_cmaps, FT_MAX_CHARMAP_CACHEABLE + 1 ));
#endif
@@ -3434,7 +3480,7 @@
{
FT_Byte* volatile cmap = table + offset;
volatile FT_UInt format = TT_PEEK_USHORT( cmap );
- const TT_CMap_Class* volatile pclazz = FT_TT_CMAP_CLASSES_GET;
+ const TT_CMap_Class* volatile pclazz = TT_CMAP_CLASSES_GET;
TT_CMap_Class volatile clazz;
@@ -3444,7 +3490,7 @@
if ( clazz->format == format )
{
volatile TT_ValidatorRec valid;
- volatile FT_Error error = SFNT_Err_Ok;
+ volatile FT_Error error = FT_Err_Ok;
ft_validator_init( FT_VALIDATOR( &valid ), cmap, limit,
@@ -3452,8 +3498,7 @@
valid.num_glyphs = (FT_UInt)face->max_profile.numGlyphs;
- if ( ft_setjmp(
- *((ft_jmp_buf*)&FT_VALIDATOR( &valid )->jump_buffer) ) == 0 )
+ if ( ft_setjmp( FT_VALIDATOR( &valid )->jump_buffer) == 0 )
{
/* validate this cmap sub-table */
error = clazz->validate( cmap, FT_VALIDATOR( &valid ) );
@@ -3464,9 +3509,9 @@
FT_CMap ttcmap;
- /* It might make sense to store the single variation selector */
- /* cmap somewhere special. But it would have to be in the */
- /* public FT_FaceRec, and we can't change that. */
+ /* It might make sense to store the single variation */
+ /* selector cmap somewhere special. But it would have to be */
+ /* in the public FT_FaceRec, and we can't change that. */
if ( !FT_CMap_New( (FT_CMap_Class)clazz,
cmap, &charmap, &ttcmap ) )
@@ -3493,7 +3538,7 @@
}
}
- return SFNT_Err_Ok;
+ return FT_Err_Ok;
}
diff --git a/src/sfnt/ttcmap.h b/src/sfnt/ttcmap.h
index 94f7978..0fde167 100644
--- a/src/sfnt/ttcmap.h
+++ b/src/sfnt/ttcmap.h
@@ -4,7 +4,7 @@
/* */
/* TrueType character mapping table (cmap) support (specification). */
/* */
-/* Copyright 2002, 2003, 2004, 2005 by */
+/* Copyright 2002-2005, 2009, 2012 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -55,47 +55,80 @@ FT_BEGIN_HEADER
} TT_CMap_ClassRec;
+
#ifndef FT_CONFIG_OPTION_PIC
-#define FT_DEFINE_TT_CMAP(class_, size_, init_, done_, char_index_, \
- char_next_, char_var_index_, char_var_default_, variant_list_, \
- charvariant_list_,variantchar_list_, \
- format_, validate_, get_cmap_info_) \
- FT_CALLBACK_TABLE_DEF \
- const TT_CMap_ClassRec class_ = \
- { \
- {size_, init_, done_, char_index_, \
- char_next_, char_var_index_, char_var_default_, variant_list_, \
- charvariant_list_, variantchar_list_}, \
- format_, validate_, get_cmap_info_ \
+#define FT_DEFINE_TT_CMAP( class_, \
+ size_, \
+ init_, \
+ done_, \
+ char_index_, \
+ char_next_, \
+ char_var_index_, \
+ char_var_default_, \
+ variant_list_, \
+ charvariant_list_, \
+ variantchar_list_, \
+ format_, \
+ validate_, \
+ get_cmap_info_ ) \
+ FT_CALLBACK_TABLE_DEF \
+ const TT_CMap_ClassRec class_ = \
+ { \
+ { size_, \
+ init_, \
+ done_, \
+ char_index_, \
+ char_next_, \
+ char_var_index_, \
+ char_var_default_, \
+ variant_list_, \
+ charvariant_list_, \
+ variantchar_list_ \
+ }, \
+ \
+ format_, \
+ validate_, \
+ get_cmap_info_ \
};
#else /* FT_CONFIG_OPTION_PIC */
-#define FT_DEFINE_TT_CMAP(class_, size_, init_, done_, char_index_, \
- char_next_, char_var_index_, char_var_default_, variant_list_, \
- charvariant_list_,variantchar_list_, \
- format_, validate_, get_cmap_info_) \
- void \
- FT_Init_Class_##class_( TT_CMap_ClassRec* clazz ) \
- { \
- clazz->clazz.size = size_; \
- clazz->clazz.init = init_; \
- clazz->clazz.done = done_; \
- clazz->clazz.char_index = char_index_; \
- clazz->clazz.char_next = char_next_; \
- clazz->clazz.char_var_index = char_var_index_; \
- clazz->clazz.char_var_default = char_var_default_; \
- clazz->clazz.variant_list = variant_list_; \
- clazz->clazz.charvariant_list = charvariant_list_; \
- clazz->clazz.variantchar_list = variantchar_list_; \
- clazz->format = format_; \
- clazz->validate = validate_; \
- clazz->get_cmap_info = get_cmap_info_; \
+#define FT_DEFINE_TT_CMAP( class_, \
+ size_, \
+ init_, \
+ done_, \
+ char_index_, \
+ char_next_, \
+ char_var_index_, \
+ char_var_default_, \
+ variant_list_, \
+ charvariant_list_, \
+ variantchar_list_, \
+ format_, \
+ validate_, \
+ get_cmap_info_ ) \
+ void \
+ FT_Init_Class_ ## class_( TT_CMap_ClassRec* clazz ) \
+ { \
+ clazz->clazz.size = size_; \
+ clazz->clazz.init = init_; \
+ clazz->clazz.done = done_; \
+ clazz->clazz.char_index = char_index_; \
+ clazz->clazz.char_next = char_next_; \
+ clazz->clazz.char_var_index = char_var_index_; \
+ clazz->clazz.char_var_default = char_var_default_; \
+ clazz->clazz.variant_list = variant_list_; \
+ clazz->clazz.charvariant_list = charvariant_list_; \
+ clazz->clazz.variantchar_list = variantchar_list_; \
+ clazz->format = format_; \
+ clazz->validate = validate_; \
+ clazz->get_cmap_info = get_cmap_info_; \
}
#endif /* FT_CONFIG_OPTION_PIC */
+
typedef struct TT_ValidatorRec_
{
FT_ValidatorRec validator;
@@ -104,7 +137,7 @@ FT_BEGIN_HEADER
} TT_ValidatorRec, *TT_Validator;
-#define TT_VALIDATOR( x ) ((TT_Validator)( x ))
+#define TT_VALIDATOR( x ) ( (TT_Validator)( x ) )
#define TT_VALID_GLYPH_COUNT( x ) TT_VALIDATOR( x )->num_glyphs
diff --git a/src/sfnt/ttcmapc.h b/src/sfnt/ttcmapc.h
index 4c9c6a5..2ea2043 100644
--- a/src/sfnt/ttcmapc.h
+++ b/src/sfnt/ttcmapc.h
@@ -17,39 +17,40 @@
#ifdef TT_CONFIG_CMAP_FORMAT_0
- TTCMAPCITEM(tt_cmap0_class_rec)
+ TTCMAPCITEM( tt_cmap0_class_rec )
#endif
#ifdef TT_CONFIG_CMAP_FORMAT_2
- TTCMAPCITEM(tt_cmap2_class_rec)
+ TTCMAPCITEM( tt_cmap2_class_rec )
#endif
#ifdef TT_CONFIG_CMAP_FORMAT_4
- TTCMAPCITEM(tt_cmap4_class_rec)
+ TTCMAPCITEM( tt_cmap4_class_rec )
#endif
#ifdef TT_CONFIG_CMAP_FORMAT_6
- TTCMAPCITEM(tt_cmap6_class_rec)
+ TTCMAPCITEM( tt_cmap6_class_rec )
#endif
#ifdef TT_CONFIG_CMAP_FORMAT_8
- TTCMAPCITEM(tt_cmap8_class_rec)
+ TTCMAPCITEM( tt_cmap8_class_rec )
#endif
#ifdef TT_CONFIG_CMAP_FORMAT_10
- TTCMAPCITEM(tt_cmap10_class_rec)
+ TTCMAPCITEM( tt_cmap10_class_rec )
#endif
#ifdef TT_CONFIG_CMAP_FORMAT_12
- TTCMAPCITEM(tt_cmap12_class_rec)
+ TTCMAPCITEM( tt_cmap12_class_rec )
#endif
#ifdef TT_CONFIG_CMAP_FORMAT_13
- TTCMAPCITEM(tt_cmap13_class_rec)
+ TTCMAPCITEM( tt_cmap13_class_rec )
#endif
#ifdef TT_CONFIG_CMAP_FORMAT_14
- TTCMAPCITEM(tt_cmap14_class_rec)
+ TTCMAPCITEM( tt_cmap14_class_rec )
#endif
+
/* END */
diff --git a/src/sfnt/ttkern.c b/src/sfnt/ttkern.c
index 4688898..60ee546 100644
--- a/src/sfnt/ttkern.c
+++ b/src/sfnt/ttkern.c
@@ -61,7 +61,7 @@
{
FT_ERROR(( "tt_face_load_kern:"
" kerning table is too small - ignored\n" ));
- error = SFNT_Err_Table_Missing;
+ error = FT_THROW( Table_Missing );
goto Exit;
}
diff --git a/src/sfnt/ttload.c b/src/sfnt/ttload.c
index 5fb9aea..fbe70f7 100644
--- a/src/sfnt/ttload.c
+++ b/src/sfnt/ttload.c
@@ -5,8 +5,7 @@
/* Load the basic TrueType tables, i.e., tables that can be either in */
/* TTF or OTF fonts (body). */
/* */
-/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, */
-/* 2010 by */
+/* Copyright 1996-2010, 2012, 2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -143,7 +142,7 @@
goto Exit;
}
else
- error = SFNT_Err_Table_Missing;
+ error = FT_THROW( Table_Missing );
Exit:
return error;
@@ -238,7 +237,7 @@
if ( table.Length < 0x36 )
{
FT_TRACE2(( "check_table_dir: `head' table too small\n" ));
- error = SFNT_Err_Table_Missing;
+ error = FT_THROW( Table_Missing );
goto Exit;
}
@@ -250,7 +249,7 @@
{
FT_TRACE2(( "check_table_dir:"
" no magic number found in `head' table\n"));
- error = SFNT_Err_Table_Missing;
+ error = FT_THROW( Table_Missing );
goto Exit;
}
@@ -268,14 +267,14 @@
if ( sfnt->num_tables == 0 )
{
FT_TRACE2(( "check_table_dir: no tables found\n" ));
- error = SFNT_Err_Unknown_File_Format;
+ error = FT_THROW( Unknown_File_Format );
goto Exit;
}
/* if `sing' and `meta' tables are present, there is no `head' table */
if ( has_head || ( has_sing && has_meta ) )
{
- error = SFNT_Err_Ok;
+ error = FT_Err_Ok;
goto Exit;
}
else
@@ -286,7 +285,7 @@
#else
FT_TRACE2(( " neither `head' nor `sing' table found\n" ));
#endif
- error = SFNT_Err_Table_Missing;
+ error = FT_THROW( Table_Missing );
}
Exit:
@@ -354,7 +353,7 @@
#if 0
if ( sfnt.search_range != 1 << ( sfnt.entry_selector + 4 ) ||
sfnt.search_range + sfnt.range_shift != sfnt.num_tables << 4 )
- return SFNT_Err_Unknown_File_Format;
+ return FT_THROW( Unknown_File_Format );
#endif
/* load the table directory */
@@ -362,14 +361,17 @@
FT_TRACE2(( "-- Number of tables: %10u\n", sfnt.num_tables ));
FT_TRACE2(( "-- Format version: 0x%08lx\n", sfnt.format_tag ));
- /* check first */
- error = check_table_dir( &sfnt, stream );
- if ( error )
+ if ( sfnt.format_tag != TTAG_OTTO )
{
- FT_TRACE2(( "tt_face_load_font_dir:"
- " invalid table directory for TrueType\n" ));
+ /* check first */
+ error = check_table_dir( &sfnt, stream );
+ if ( error )
+ {
+ FT_TRACE2(( "tt_face_load_font_dir:"
+ " invalid table directory for TrueType\n" ));
- goto Exit;
+ goto Exit;
+ }
}
face->num_tables = sfnt.num_tables;
@@ -480,7 +482,7 @@
table = tt_face_lookup_table( face, tag );
if ( !table )
{
- error = SFNT_Err_Table_Missing;
+ error = FT_THROW( Table_Missing );
goto Exit;
}
@@ -495,7 +497,7 @@
{
*length = size;
- return SFNT_Err_Ok;
+ return FT_Err_Ok;
}
if ( length )
@@ -624,7 +626,7 @@
FT_Error error;
TT_MaxProfile* maxProfile = &face->max_profile;
- const FT_Frame_Field maxp_fields[] =
+ static const FT_Frame_Field maxp_fields[] =
{
#undef FT_STRUCTURE
#define FT_STRUCTURE TT_MaxProfile
@@ -635,7 +637,7 @@
FT_FRAME_END
};
- const FT_Frame_Field maxp_fields_extra[] =
+ static const FT_Frame_Field maxp_fields_extra[] =
{
FT_FRAME_START( 26 ),
FT_FRAME_USHORT( maxPoints ),
@@ -721,7 +723,7 @@
/*************************************************************************/
/* */
/* <Function> */
- /* tt_face_load_names */
+ /* tt_face_load_name */
/* */
/* <Description> */
/* Loads the name records. */
@@ -799,7 +801,7 @@
if ( storage_start > storage_limit )
{
FT_ERROR(( "tt_face_load_name: invalid `name' table\n" ));
- error = SFNT_Err_Name_Table_Missing;
+ error = FT_THROW( Name_Table_Missing );
goto Exit;
}
@@ -952,7 +954,7 @@
FT_Error error;
TT_OS2* os2;
- const FT_Frame_Field os2_fields[] =
+ static const FT_Frame_Field os2_fields[] =
{
#undef FT_STRUCTURE
#define FT_STRUCTURE TT_OS2
@@ -1004,7 +1006,7 @@
FT_FRAME_END
};
- const FT_Frame_Field os2_fields_extra[] =
+ static const FT_Frame_Field os2_fields_extra[] =
{
FT_FRAME_START( 8 ),
FT_FRAME_ULONG( ulCodePageRange1 ),
@@ -1012,7 +1014,7 @@
FT_FRAME_END
};
- const FT_Frame_Field os2_fields_extra2[] =
+ static const FT_Frame_Field os2_fields_extra2[] =
{
FT_FRAME_START( 10 ),
FT_FRAME_SHORT ( sxHeight ),
@@ -1125,7 +1127,7 @@
FT_TRACE3(( "isFixedPitch: %s\n", post->isFixedPitch
? " yes" : " no" ));
- return SFNT_Err_Ok;
+ return FT_Err_Ok;
}
@@ -1233,18 +1235,18 @@
if ( face->gasp.version >= 2 )
{
face->gasp.numRanges = 0;
- error = SFNT_Err_Invalid_Table;
+ error = FT_THROW( Invalid_Table );
goto Exit;
}
num_ranges = face->gasp.numRanges;
FT_TRACE3(( "numRanges: %u\n", num_ranges ));
- if ( FT_QNEW_ARRAY( gaspranges, num_ranges ) ||
- FT_FRAME_ENTER( num_ranges * 4L ) )
+ if ( FT_QNEW_ARRAY( face->gasp.gaspRanges, num_ranges ) ||
+ FT_FRAME_ENTER( num_ranges * 4L ) )
goto Exit;
- face->gasp.gaspRanges = gaspranges;
+ gaspranges = face->gasp.gaspRanges;
for ( j = 0; j < num_ranges; j++ )
{
diff --git a/src/sfnt/ttmtx.c b/src/sfnt/ttmtx.c
index 73ac8b2..371a9ed 100644
--- a/src/sfnt/ttmtx.c
+++ b/src/sfnt/ttmtx.c
@@ -4,7 +4,7 @@
/* */
/* Load the metrics tables common to TTF and OTF fonts (body). */
/* */
-/* Copyright 2006-2009, 2011 by */
+/* Copyright 2006-2009, 2011-2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -35,13 +35,6 @@
#define FT_COMPONENT trace_ttmtx
- /*
- * Unfortunately, we can't enable our memory optimizations if
- * FT_CONFIG_OPTION_OLD_INTERNALS is defined. This is because at least
- * one rogue client (libXfont in the X.Org XServer) is directly accessing
- * the metrics.
- */
-
/*************************************************************************/
/* */
/* <Function> */
@@ -60,8 +53,6 @@
/* <Return> */
/* FreeType error code. 0 means success. */
/* */
-#ifndef FT_CONFIG_OPTION_OLD_INTERNALS
-
FT_LOCAL_DEF( FT_Error )
tt_face_load_hmtx( TT_Face face,
FT_Stream stream,
@@ -97,142 +88,6 @@
return error;
}
-#else /* !FT_CONFIG_OPTION_OLD_INTERNALS */
-
- FT_LOCAL_DEF( FT_Error )
- tt_face_load_hmtx( TT_Face face,
- FT_Stream stream,
- FT_Bool vertical )
- {
- FT_Error error;
- FT_Memory memory = stream->memory;
-
- FT_ULong table_len;
- FT_Long num_shorts, num_longs, num_shorts_checked;
-
- TT_LongMetrics* longs;
- TT_ShortMetrics** shorts;
- FT_Byte* p;
-
-
- if ( vertical )
- {
- void* lm = &face->vertical.long_metrics;
- void** sm = &face->vertical.short_metrics;
-
-
- error = face->goto_table( face, TTAG_vmtx, stream, &table_len );
- if ( error )
- goto Fail;
-
- num_longs = face->vertical.number_Of_VMetrics;
- if ( (FT_ULong)num_longs > table_len / 4 )
- num_longs = (FT_Long)( table_len / 4 );
-
- face->vertical.number_Of_VMetrics = 0;
-
- longs = (TT_LongMetrics*)lm;
- shorts = (TT_ShortMetrics**)sm;
- }
- else
- {
- void* lm = &face->horizontal.long_metrics;
- void** sm = &face->horizontal.short_metrics;
-
-
- error = face->goto_table( face, TTAG_hmtx, stream, &table_len );
- if ( error )
- goto Fail;
-
- num_longs = face->horizontal.number_Of_HMetrics;
- if ( (FT_ULong)num_longs > table_len / 4 )
- num_longs = (FT_Long)( table_len / 4 );
-
- face->horizontal.number_Of_HMetrics = 0;
-
- longs = (TT_LongMetrics*)lm;
- shorts = (TT_ShortMetrics**)sm;
- }
-
- /* never trust derived values */
-
- num_shorts = face->max_profile.numGlyphs - num_longs;
- num_shorts_checked = ( table_len - num_longs * 4L ) / 2;
-
- if ( num_shorts < 0 )
- {
- FT_TRACE0(( "tt_face_load_hmtx:"
- " %cmtx has more metrics than glyphs.\n",
- vertical ? 'v' : 'h' ));
-
- /* Adobe simply ignores this problem. So we shall do the same. */
-#if 0
- error = vertical ? SFNT_Err_Invalid_Vert_Metrics
- : SFNT_Err_Invalid_Horiz_Metrics;
- goto Exit;
-#else
- num_shorts = 0;
-#endif
- }
-
- if ( FT_QNEW_ARRAY( *longs, num_longs ) ||
- FT_QNEW_ARRAY( *shorts, num_shorts ) )
- goto Fail;
-
- if ( FT_FRAME_ENTER( table_len ) )
- goto Fail;
-
- p = stream->cursor;
-
- {
- TT_LongMetrics cur = *longs;
- TT_LongMetrics limit = cur + num_longs;
-
-
- for ( ; cur < limit; cur++ )
- {
- cur->advance = FT_NEXT_USHORT( p );
- cur->bearing = FT_NEXT_SHORT( p );
- }
- }
-
- /* do we have an inconsistent number of metric values? */
- {
- TT_ShortMetrics* cur = *shorts;
- TT_ShortMetrics* limit = cur +
- FT_MIN( num_shorts, num_shorts_checked );
-
-
- for ( ; cur < limit; cur++ )
- *cur = FT_NEXT_SHORT( p );
-
- /* We fill up the missing left side bearings with the */
- /* last valid value. Since this will occur for buggy CJK */
- /* fonts usually only, nothing serious will happen. */
- if ( num_shorts > num_shorts_checked && num_shorts_checked > 0 )
- {
- FT_Short val = (*shorts)[num_shorts_checked - 1];
-
-
- limit = *shorts + num_shorts;
- for ( ; cur < limit; cur++ )
- *cur = val;
- }
- }
-
- FT_FRAME_EXIT();
-
- if ( vertical )
- face->vertical.number_Of_VMetrics = (FT_UShort)num_longs;
- else
- face->horizontal.number_Of_HMetrics = (FT_UShort)num_longs;
-
- Fail:
- return error;
- }
-
-#endif /* !FT_CONFIG_OPTION_OLD_INTERNALS */
-
/*************************************************************************/
/* */
@@ -260,7 +115,7 @@
FT_Error error;
TT_HoriHeader* header;
- const FT_Frame_Field metrics_header_fields[] =
+ static const FT_Frame_Field metrics_header_fields[] =
{
#undef FT_STRUCTURE
#define FT_STRUCTURE TT_HoriHeader
@@ -343,8 +198,6 @@
/* */
/* advance :: The advance width resp. advance height. */
/* */
-#ifndef FT_CONFIG_OPTION_OLD_INTERNALS
-
FT_LOCAL_DEF( FT_Error )
tt_face_get_metrics( TT_Face face,
FT_Bool vertical,
@@ -419,50 +272,8 @@
*aadvance = 0;
}
- return SFNT_Err_Ok;
- }
-
-#else /* !FT_CONFIG_OPTION_OLD_INTERNALS */
-
- FT_LOCAL_DEF( FT_Error )
- tt_face_get_metrics( TT_Face face,
- FT_Bool vertical,
- FT_UInt gindex,
- FT_Short* abearing,
- FT_UShort* aadvance )
- {
- void* v = &face->vertical;
- void* h = &face->horizontal;
- TT_HoriHeader* header = vertical ? (TT_HoriHeader*)v
- : (TT_HoriHeader*)h;
- TT_LongMetrics longs_m;
- FT_UShort k = header->number_Of_HMetrics;
-
-
- if ( k == 0 ||
- !header->long_metrics ||
- gindex >= (FT_UInt)face->max_profile.numGlyphs )
- {
- *abearing = *aadvance = 0;
- return SFNT_Err_Ok;
- }
-
- if ( gindex < (FT_UInt)k )
- {
- longs_m = (TT_LongMetrics)header->long_metrics + gindex;
- *abearing = longs_m->bearing;
- *aadvance = longs_m->advance;
- }
- else
- {
- *abearing = ((TT_ShortMetrics*)header->short_metrics)[gindex - k];
- *aadvance = ((TT_LongMetrics)header->long_metrics)[k - 1].advance;
- }
-
- return SFNT_Err_Ok;
+ return FT_Err_Ok;
}
-#endif /* !FT_CONFIG_OPTION_OLD_INTERNALS */
-
/* END */
diff --git a/src/sfnt/ttpost.c b/src/sfnt/ttpost.c
index 6f4bb1d..47a85c0 100644
--- a/src/sfnt/ttpost.c
+++ b/src/sfnt/ttpost.c
@@ -5,7 +5,7 @@
/* Postcript name table processing for TrueType and OpenType fonts */
/* (body). */
/* */
-/* Copyright 1996-2001, 2002, 2003, 2006, 2007, 2008, 2009, 2010 by */
+/* Copyright 1996-2003, 2006-2010, 2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -178,7 +178,7 @@
if ( num_glyphs > face->max_profile.numGlyphs )
{
- error = SFNT_Err_Invalid_File_Format;
+ error = FT_THROW( Invalid_File_Format );
goto Exit;
}
@@ -284,7 +284,7 @@
table->glyph_indices = glyph_indices;
table->glyph_names = name_strings;
}
- return SFNT_Err_Ok;
+ return FT_Err_Ok;
Fail1:
{
@@ -325,7 +325,7 @@
/* check the number of glyphs */
if ( num_glyphs > face->max_profile.numGlyphs || num_glyphs > 258 )
{
- error = SFNT_Err_Invalid_File_Format;
+ error = FT_THROW( Invalid_File_Format );
goto Exit;
}
@@ -345,7 +345,7 @@
if ( idx < 0 || idx > num_glyphs )
{
- error = SFNT_Err_Invalid_File_Format;
+ error = FT_THROW( Invalid_File_Format );
goto Fail;
}
}
@@ -360,7 +360,7 @@
table->offsets = offset_table;
}
- return SFNT_Err_Ok;
+ return FT_Err_Ok;
Fail:
FT_FREE( offset_table );
@@ -402,7 +402,7 @@
else if ( format == 0x00028000L )
error = load_format_25( face, stream, post_limit );
else
- error = SFNT_Err_Invalid_File_Format;
+ error = FT_THROW( Invalid_File_Format );
face->postscript_names.loaded = 1;
@@ -488,15 +488,15 @@
if ( !face )
- return SFNT_Err_Invalid_Face_Handle;
+ return FT_THROW( Invalid_Face_Handle );
if ( idx >= (FT_UInt)face->max_profile.numGlyphs )
- return SFNT_Err_Invalid_Glyph_Index;
+ return FT_THROW( Invalid_Glyph_Index );
#ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES
psnames = (FT_Service_PsCMaps)face->psnames;
if ( !psnames )
- return SFNT_Err_Unimplemented_Feature;
+ return FT_THROW( Unimplemented_Feature );
#endif
names = &face->postscript_names;
@@ -556,7 +556,7 @@
/* nothing to do for format == 0x00030000L */
End:
- return SFNT_Err_Ok;
+ return FT_Err_Ok;
}
diff --git a/src/sfnt/ttsbit.c b/src/sfnt/ttsbit.c
index 283ba7e..cd3e5a4 100644
--- a/src/sfnt/ttsbit.c
+++ b/src/sfnt/ttsbit.c
@@ -4,10 +4,12 @@
/* */
/* TrueType and OpenType embedded bitmap support (body). */
/* */
-/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, */
-/* 2010 by */
+/* Copyright 2005-2009, 2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
+/* Copyright 2013 by Google, Inc. */
+/* Google Author(s): Behdad Esfahbod. */
+/* */
/* 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 */
@@ -16,29 +18,18 @@
/* */
/***************************************************************************/
-#include <ft2build.h>
-#include FT_INTERNAL_DEBUG_H
-#include FT_INTERNAL_STREAM_H
-#include FT_TRUETYPE_TAGS_H
-
- /*
- * Alas, the memory-optimized sbit loader can't be used when implementing
- * the `old internals' hack
- */
-#ifndef FT_CONFIG_OPTION_OLD_INTERNALS
-
-#include "ttsbit0.c"
-
-#else /* FT_CONFIG_OPTION_OLD_INTERNALS */
#include <ft2build.h>
#include FT_INTERNAL_DEBUG_H
#include FT_INTERNAL_STREAM_H
#include FT_TRUETYPE_TAGS_H
+#include FT_BITMAP_H
#include "ttsbit.h"
#include "sferrors.h"
+#include "pngshim.h"
+
/*************************************************************************/
/* */
@@ -50,1398 +41,1108 @@
#define FT_COMPONENT trace_ttsbit
- /*************************************************************************/
- /* */
- /* <Function> */
- /* blit_sbit */
- /* */
- /* <Description> */
- /* Blits a bitmap from an input stream into a given target. Supports */
- /* x and y offsets as well as byte padded lines. */
- /* */
- /* <Input> */
- /* target :: The target bitmap/pixmap. */
- /* */
- /* source :: The input packed bitmap data. */
- /* */
- /* line_bits :: The number of bits per line. */
- /* */
- /* byte_padded :: A flag which is true if lines are byte-padded. */
- /* */
- /* x_offset :: The horizontal offset. */
- /* */
- /* y_offset :: The vertical offset. */
- /* */
- /* <Note> */
- /* IMPORTANT: The x and y offsets are relative to the top corner of */
- /* the target bitmap (unlike the normal TrueType */
- /* convention). A positive y offset indicates a downwards */
- /* direction! */
- /* */
- static void
- blit_sbit( FT_Bitmap* target,
- FT_Byte* source,
- FT_Int line_bits,
- FT_Bool byte_padded,
- FT_Int x_offset,
- FT_Int y_offset,
- FT_Int source_height )
+ FT_LOCAL_DEF( FT_Error )
+ tt_face_load_eblc( TT_Face face,
+ FT_Stream stream )
{
- FT_Byte* line_buff;
- FT_Int line_incr;
- FT_Int height;
+ FT_Error error = FT_Err_Ok;
+ FT_Fixed version;
+ FT_ULong num_strikes, table_size;
+ FT_Byte* p;
+ FT_Byte* p_limit;
+ FT_UInt count;
- FT_UShort acc;
- FT_UInt loaded;
+ face->sbit_num_strikes = 0;
- /* first of all, compute starting write position */
- line_incr = target->pitch;
- line_buff = target->buffer;
+ /* this table is optional */
+ error = face->goto_table( face, TTAG_CBLC, stream, &table_size );
+ if ( error )
+ error = face->goto_table( face, TTAG_EBLC, stream, &table_size );
+ if ( error )
+ error = face->goto_table( face, TTAG_bloc, stream, &table_size );
+ if ( error )
+ goto Exit;
- if ( line_incr < 0 )
- line_buff -= line_incr * ( target->rows - 1 );
+ if ( table_size < 8 )
+ {
+ FT_ERROR(( "tt_face_load_sbit_strikes: table too short\n" ));
+ error = FT_THROW( Invalid_File_Format );
+ goto Exit;
+ }
- line_buff += ( x_offset >> 3 ) + y_offset * line_incr;
+ if ( FT_FRAME_EXTRACT( table_size, face->sbit_table ) )
+ goto Exit;
+
+ face->sbit_table_size = table_size;
- /***********************************************************************/
- /* */
- /* We use the extra-classic `accumulator' trick to extract the bits */
- /* from the source byte stream. */
- /* */
- /* Namely, the variable `acc' is a 16-bit accumulator containing the */
- /* last `loaded' bits from the input stream. The bits are shifted to */
- /* the upmost position in `acc'. */
- /* */
- /***********************************************************************/
+ p = face->sbit_table;
+ p_limit = p + table_size;
- acc = 0; /* clear accumulator */
- loaded = 0; /* no bits were loaded */
+ version = FT_NEXT_ULONG( p );
+ num_strikes = FT_NEXT_ULONG( p );
- for ( height = source_height; height > 0; height-- )
+ if ( version != 0x00020000UL || num_strikes >= 0x10000UL )
{
- FT_Byte* cur = line_buff; /* current write cursor */
- FT_Int count = line_bits; /* # of bits to extract per line */
- FT_Byte shift = (FT_Byte)( x_offset & 7 ); /* current write shift */
- FT_Byte space = (FT_Byte)( 8 - shift );
+ FT_ERROR(( "tt_face_load_sbit_strikes: invalid table version\n" ));
+ error = FT_THROW( Invalid_File_Format );
+ goto Fail;
+ }
+ /*
+ * Count the number of strikes available in the table. We are a bit
+ * paranoid there and don't trust the data.
+ */
+ count = (FT_UInt)num_strikes;
+ if ( 8 + 48UL * count > table_size )
+ count = (FT_UInt)( ( p_limit - p ) / 48 );
- /* first of all, read individual source bytes */
- if ( count >= 8 )
- {
- count -= 8;
- {
- do
- {
- FT_Byte val;
-
-
- /* ensure that there are at least 8 bits in the accumulator */
- if ( loaded < 8 )
- {
- acc |= (FT_UShort)((FT_UShort)*source++ << ( 8 - loaded ));
- loaded += 8;
- }
-
- /* now write one byte */
- val = (FT_Byte)( acc >> 8 );
- if ( shift )
- {
- cur[0] |= (FT_Byte)( val >> shift );
- cur[1] |= (FT_Byte)( val << space );
- }
- else
- cur[0] |= val;
-
- cur++;
- acc <<= 8; /* remove bits from accumulator */
- loaded -= 8;
- count -= 8;
-
- } while ( count >= 0 );
- }
+ face->sbit_num_strikes = count;
- /* restore `count' to correct value */
- count += 8;
- }
+ FT_TRACE3(( "sbit_num_strikes: %u\n", count ));
+ Exit:
+ return error;
- /* now write remaining bits (count < 8) */
- if ( count > 0 )
- {
- FT_Byte val;
+ Fail:
+ FT_FRAME_RELEASE( face->sbit_table );
+ face->sbit_table_size = 0;
+ goto Exit;
+ }
- /* ensure that there are at least `count' bits in the accumulator */
- if ( (FT_Int)loaded < count )
- {
- acc |= (FT_UShort)((FT_UShort)*source++ << ( 8 - loaded ));
- loaded += 8;
- }
-
- /* now write remaining bits */
- val = (FT_Byte)( ( (FT_Byte)( acc >> 8 ) ) & ~( 0xFF >> count ) );
- cur[0] |= (FT_Byte)( val >> shift );
+ FT_LOCAL_DEF( void )
+ tt_face_free_eblc( TT_Face face )
+ {
+ FT_Stream stream = face->root.stream;
- if ( count > space )
- cur[1] |= (FT_Byte)( val << space );
- acc <<= count;
- loaded -= count;
- }
+ FT_FRAME_RELEASE( face->sbit_table );
+ face->sbit_table_size = 0;
+ face->sbit_num_strikes = 0;
+ }
- /* now, skip to next line */
- if ( byte_padded )
- {
- acc = 0;
- loaded = 0; /* clear accumulator on byte-padded lines */
- }
- line_buff += line_incr;
- }
+ FT_LOCAL_DEF( FT_Error )
+ tt_face_set_sbit_strike( TT_Face face,
+ FT_Size_Request req,
+ FT_ULong* astrike_index )
+ {
+ return FT_Match_Size( (FT_Face)face, req, 0, astrike_index );
}
- static const FT_Frame_Field sbit_metrics_fields[] =
+ FT_LOCAL_DEF( FT_Error )
+ tt_face_load_strike_metrics( TT_Face face,
+ FT_ULong strike_index,
+ FT_Size_Metrics* metrics )
{
-#undef FT_STRUCTURE
-#define FT_STRUCTURE TT_SBit_MetricsRec
+ FT_Byte* strike;
- FT_FRAME_START( 8 ),
- FT_FRAME_BYTE( height ),
- FT_FRAME_BYTE( width ),
- FT_FRAME_CHAR( horiBearingX ),
- FT_FRAME_CHAR( horiBearingY ),
- FT_FRAME_BYTE( horiAdvance ),
+ if ( strike_index >= (FT_ULong)face->sbit_num_strikes )
+ return FT_THROW( Invalid_Argument );
- FT_FRAME_CHAR( vertBearingX ),
- FT_FRAME_CHAR( vertBearingY ),
- FT_FRAME_BYTE( vertAdvance ),
- FT_FRAME_END
- };
+ strike = face->sbit_table + 8 + strike_index * 48;
+ metrics->x_ppem = (FT_UShort)strike[44];
+ metrics->y_ppem = (FT_UShort)strike[45];
- /*************************************************************************/
- /* */
- /* <Function> */
- /* Load_SBit_Const_Metrics */
- /* */
- /* <Description> */
- /* Loads the metrics for `EBLC' index tables format 2 and 5. */
- /* */
- /* <Input> */
- /* range :: The target range. */
- /* */
- /* stream :: The input stream. */
- /* */
- /* <Return> */
- /* FreeType error code. 0 means success. */
- /* */
- static FT_Error
- Load_SBit_Const_Metrics( TT_SBit_Range range,
- FT_Stream stream )
+ metrics->ascender = (FT_Char)strike[16] << 6; /* hori.ascender */
+ metrics->descender = (FT_Char)strike[17] << 6; /* hori.descender */
+ metrics->height = metrics->ascender - metrics->descender;
+
+ /* XXX: Is this correct? */
+ metrics->max_advance = ( (FT_Char)strike[22] + /* min_origin_SB */
+ strike[18] + /* max_width */
+ (FT_Char)strike[23] /* min_advance_SB */
+ ) << 6;
+
+ return FT_Err_Ok;
+ }
+
+
+ typedef struct TT_SBitDecoderRec_
{
- FT_Error error;
+ TT_Face face;
+ FT_Stream stream;
+ FT_Bitmap* bitmap;
+ TT_SBit_Metrics metrics;
+ FT_Bool metrics_loaded;
+ FT_Bool bitmap_allocated;
+ FT_Byte bit_depth;
+ FT_ULong ebdt_start;
+ FT_ULong ebdt_size;
- if ( FT_READ_ULONG( range->image_size ) )
- return error;
+ FT_ULong strike_index_array;
+ FT_ULong strike_index_count;
+ FT_Byte* eblc_base;
+ FT_Byte* eblc_limit;
- return FT_STREAM_READ_FIELDS( sbit_metrics_fields, &range->metrics );
- }
+ } TT_SBitDecoderRec, *TT_SBitDecoder;
- /*************************************************************************/
- /* */
- /* <Function> */
- /* Load_SBit_Range_Codes */
- /* */
- /* <Description> */
- /* Loads the range codes for `EBLC' index tables format 4 and 5. */
- /* */
- /* <Input> */
- /* range :: The target range. */
- /* */
- /* stream :: The input stream. */
- /* */
- /* load_offsets :: A flag whether to load the glyph offset table. */
- /* */
- /* <Return> */
- /* FreeType error code. 0 means success. */
- /* */
static FT_Error
- Load_SBit_Range_Codes( TT_SBit_Range range,
- FT_Stream stream,
- FT_Bool load_offsets )
+ tt_sbit_decoder_init( TT_SBitDecoder decoder,
+ TT_Face face,
+ FT_ULong strike_index,
+ TT_SBit_MetricsRec* metrics )
{
FT_Error error;
- FT_ULong count, n, size;
- FT_Memory memory = stream->memory;
+ FT_Stream stream = face->root.stream;
+ FT_ULong ebdt_size;
- if ( FT_READ_ULONG( count ) )
+ error = face->goto_table( face, TTAG_CBDT, stream, &ebdt_size );
+ if ( error )
+ error = face->goto_table( face, TTAG_EBDT, stream, &ebdt_size );
+ if ( error )
+ error = face->goto_table( face, TTAG_bdat, stream, &ebdt_size );
+ if ( error )
goto Exit;
- range->num_glyphs = count;
+ decoder->face = face;
+ decoder->stream = stream;
+ decoder->bitmap = &face->root.glyph->bitmap;
+ decoder->metrics = metrics;
- /* Allocate glyph offsets table if needed */
- if ( load_offsets )
- {
- if ( FT_NEW_ARRAY( range->glyph_offsets, count ) )
- goto Exit;
+ decoder->metrics_loaded = 0;
+ decoder->bitmap_allocated = 0;
- size = count * 4L;
- }
- else
- size = count * 2L;
+ decoder->ebdt_start = FT_STREAM_POS();
+ decoder->ebdt_size = ebdt_size;
- /* Allocate glyph codes table and access frame */
- if ( FT_NEW_ARRAY ( range->glyph_codes, count ) ||
- FT_FRAME_ENTER( size ) )
- goto Exit;
+ decoder->eblc_base = face->sbit_table;
+ decoder->eblc_limit = face->sbit_table + face->sbit_table_size;
- for ( n = 0; n < count; n++ )
+ /* now find the strike corresponding to the index */
{
- range->glyph_codes[n] = FT_GET_USHORT();
+ FT_Byte* p;
- if ( load_offsets )
- range->glyph_offsets[n] = (FT_ULong)range->image_offset +
- FT_GET_USHORT();
- }
- FT_FRAME_EXIT();
+ if ( 8 + 48 * strike_index + 3 * 4 + 34 + 1 > face->sbit_table_size )
+ {
+ error = FT_THROW( Invalid_File_Format );
+ goto Exit;
+ }
+
+ p = decoder->eblc_base + 8 + 48 * strike_index;
+
+ decoder->strike_index_array = FT_NEXT_ULONG( p );
+ p += 4;
+ decoder->strike_index_count = FT_NEXT_ULONG( p );
+ p += 34;
+ decoder->bit_depth = *p;
+
+ if ( decoder->strike_index_array > face->sbit_table_size ||
+ decoder->strike_index_array + 8 * decoder->strike_index_count >
+ face->sbit_table_size )
+ error = FT_THROW( Invalid_File_Format );
+ }
Exit:
return error;
}
- /*************************************************************************/
- /* */
- /* <Function> */
- /* Load_SBit_Range */
- /* */
- /* <Description> */
- /* Loads a given `EBLC' index/range table. */
- /* */
- /* <Input> */
- /* range :: The target range. */
- /* */
- /* stream :: The input stream. */
- /* */
- /* <Return> */
- /* FreeType error code. 0 means success. */
- /* */
- static FT_Error
- Load_SBit_Range( TT_SBit_Range range,
- FT_Stream stream )
+ static void
+ tt_sbit_decoder_done( TT_SBitDecoder decoder )
{
- FT_Error error;
- FT_Memory memory = stream->memory;
-
-
- switch( range->index_format )
- {
- case 1: /* variable metrics with 4-byte offsets */
- case 3: /* variable metrics with 2-byte offsets */
- {
- FT_ULong num_glyphs, n;
- FT_Int size_elem;
- FT_Bool large = FT_BOOL( range->index_format == 1 );
+ FT_UNUSED( decoder );
+ }
+ static FT_Error
+ tt_sbit_decoder_alloc_bitmap( TT_SBitDecoder decoder,
+ FT_UInt load_flags )
+ {
+ FT_Error error = FT_Err_Ok;
+ FT_UInt width, height;
+ FT_Bitmap* map = decoder->bitmap;
+ FT_Long size;
- if ( range->last_glyph < range->first_glyph )
- {
- error = SFNT_Err_Invalid_File_Format;
- goto Exit;
- }
- num_glyphs = range->last_glyph - range->first_glyph + 1L;
- range->num_glyphs = num_glyphs;
- num_glyphs++; /* XXX: BEWARE - see spec */
+ if ( !decoder->metrics_loaded )
+ {
+ error = FT_THROW( Invalid_Argument );
+ goto Exit;
+ }
- size_elem = large ? 4 : 2;
+ width = decoder->metrics->width;
+ height = decoder->metrics->height;
- if ( FT_NEW_ARRAY( range->glyph_offsets, num_glyphs ) ||
- FT_FRAME_ENTER( num_glyphs * size_elem ) )
- goto Exit;
+ map->width = (int)width;
+ map->rows = (int)height;
- for ( n = 0; n < num_glyphs; n++ )
- range->glyph_offsets[n] = (FT_ULong)( range->image_offset +
- ( large ? FT_GET_ULONG()
- : FT_GET_USHORT() ) );
- FT_FRAME_EXIT();
- }
+ switch ( decoder->bit_depth )
+ {
+ case 1:
+ map->pixel_mode = FT_PIXEL_MODE_MONO;
+ map->pitch = ( map->width + 7 ) >> 3;
+ map->num_grays = 2;
break;
- case 2: /* all glyphs have identical metrics */
- error = Load_SBit_Const_Metrics( range, stream );
+ case 2:
+ map->pixel_mode = FT_PIXEL_MODE_GRAY2;
+ map->pitch = ( map->width + 3 ) >> 2;
+ map->num_grays = 4;
break;
case 4:
- error = Load_SBit_Range_Codes( range, stream, 1 );
+ map->pixel_mode = FT_PIXEL_MODE_GRAY4;
+ map->pitch = ( map->width + 1 ) >> 1;
+ map->num_grays = 16;
break;
- case 5:
- error = Load_SBit_Const_Metrics( range, stream );
- if ( !error )
- error = Load_SBit_Range_Codes( range, stream, 0 );
+ case 8:
+ map->pixel_mode = FT_PIXEL_MODE_GRAY;
+ map->pitch = map->width;
+ map->num_grays = 256;
+ break;
+
+ case 32:
+ if ( load_flags & FT_LOAD_COLOR )
+ {
+ map->pixel_mode = FT_PIXEL_MODE_BGRA;
+ map->pitch = map->width * 4;
+ map->num_grays = 256;
+ }
+ else
+ {
+ map->pixel_mode = FT_PIXEL_MODE_GRAY;
+ map->pitch = map->width;
+ map->num_grays = 256;
+ }
break;
default:
- error = SFNT_Err_Invalid_File_Format;
+ error = FT_THROW( Invalid_File_Format );
+ goto Exit;
}
+ size = map->rows * map->pitch;
+
+ /* check that there is no empty image */
+ if ( size == 0 )
+ goto Exit; /* exit successfully! */
+
+ error = ft_glyphslot_alloc_bitmap( decoder->face->root.glyph, size );
+ if ( error )
+ goto Exit;
+
+ decoder->bitmap_allocated = 1;
+
Exit:
return error;
}
- /*************************************************************************/
- /* */
- /* <Function> */
- /* tt_face_load_eblc */
- /* */
- /* <Description> */
- /* Loads the table of embedded bitmap sizes for this face. */
- /* */
- /* <Input> */
- /* face :: The target face object. */
- /* */
- /* stream :: The input stream. */
- /* */
- /* <Return> */
- /* FreeType error code. 0 means success. */
- /* */
- FT_LOCAL_DEF( FT_Error )
- tt_face_load_eblc( TT_Face face,
- FT_Stream stream )
+ static FT_Error
+ tt_sbit_decoder_load_metrics( TT_SBitDecoder decoder,
+ FT_Byte* *pp,
+ FT_Byte* limit,
+ FT_Bool big )
{
- FT_Error error = SFNT_Err_Ok;
- FT_Memory memory = stream->memory;
- FT_Fixed version;
- FT_ULong num_strikes;
- FT_ULong table_base;
+ FT_Byte* p = *pp;
+ TT_SBit_Metrics metrics = decoder->metrics;
- static const FT_Frame_Field sbit_line_metrics_fields[] =
- {
-#undef FT_STRUCTURE
-#define FT_STRUCTURE TT_SBit_LineMetricsRec
-
- /* no FT_FRAME_START */
- FT_FRAME_CHAR( ascender ),
- FT_FRAME_CHAR( descender ),
- FT_FRAME_BYTE( max_width ),
-
- FT_FRAME_CHAR( caret_slope_numerator ),
- FT_FRAME_CHAR( caret_slope_denominator ),
- FT_FRAME_CHAR( caret_offset ),
-
- FT_FRAME_CHAR( min_origin_SB ),
- FT_FRAME_CHAR( min_advance_SB ),
- FT_FRAME_CHAR( max_before_BL ),
- FT_FRAME_CHAR( min_after_BL ),
- FT_FRAME_CHAR( pads[0] ),
- FT_FRAME_CHAR( pads[1] ),
- FT_FRAME_END
- };
-
- static const FT_Frame_Field strike_start_fields[] =
- {
-#undef FT_STRUCTURE
-#define FT_STRUCTURE TT_SBit_StrikeRec
-
- /* no FT_FRAME_START */
- FT_FRAME_ULONG( ranges_offset ),
- FT_FRAME_SKIP_LONG,
- FT_FRAME_ULONG( num_ranges ),
- FT_FRAME_ULONG( color_ref ),
- FT_FRAME_END
- };
-
- static const FT_Frame_Field strike_end_fields[] =
+
+ if ( p + 5 > limit )
+ goto Fail;
+
+ metrics->height = p[0];
+ metrics->width = p[1];
+ metrics->horiBearingX = (FT_Char)p[2];
+ metrics->horiBearingY = (FT_Char)p[3];
+ metrics->horiAdvance = p[4];
+
+ p += 5;
+ if ( big )
{
- /* no FT_FRAME_START */
- FT_FRAME_USHORT( start_glyph ),
- FT_FRAME_USHORT( end_glyph ),
- FT_FRAME_BYTE ( x_ppem ),
- FT_FRAME_BYTE ( y_ppem ),
- FT_FRAME_BYTE ( bit_depth ),
- FT_FRAME_CHAR ( flags ),
- FT_FRAME_END
- };
+ if ( p + 3 > limit )
+ goto Fail;
+ metrics->vertBearingX = (FT_Char)p[0];
+ metrics->vertBearingY = (FT_Char)p[1];
+ metrics->vertAdvance = p[2];
- face->num_sbit_strikes = 0;
+ p += 3;
+ }
- /* this table is optional */
- error = face->goto_table( face, TTAG_EBLC, stream, 0 );
- if ( error )
- error = face->goto_table( face, TTAG_bloc, stream, 0 );
- if ( error )
- goto Exit;
+ decoder->metrics_loaded = 1;
+ *pp = p;
+ return FT_Err_Ok;
- table_base = FT_STREAM_POS();
- if ( FT_FRAME_ENTER( 8L ) )
- goto Exit;
+ Fail:
+ FT_TRACE1(( "tt_sbit_decoder_load_metrics: broken table" ));
+ return FT_THROW( Invalid_Argument );
+ }
- version = FT_GET_LONG();
- num_strikes = FT_GET_ULONG();
- FT_FRAME_EXIT();
+ /* forward declaration */
+ static FT_Error
+ tt_sbit_decoder_load_image( TT_SBitDecoder decoder,
+ FT_UInt load_flags,
+ FT_UInt glyph_index,
+ FT_Int x_pos,
+ FT_Int y_pos );
- /* check version number and strike count */
- if ( version != 0x00020000L ||
- num_strikes >= 0x10000L )
- {
- FT_ERROR(( "tt_face_load_sbit_strikes: invalid table version\n" ));
- error = SFNT_Err_Invalid_File_Format;
+ typedef FT_Error (*TT_SBitDecoder_LoadFunc)( TT_SBitDecoder decoder,
+ FT_UInt load_flags,
+ FT_Byte* p,
+ FT_Byte* plimit,
+ FT_Int x_pos,
+ FT_Int y_pos );
- goto Exit;
- }
- /* allocate the strikes table */
- if ( FT_NEW_ARRAY( face->sbit_strikes, num_strikes ) )
- goto Exit;
+ static FT_Error
+ tt_sbit_decoder_load_byte_aligned( TT_SBitDecoder decoder,
+ FT_UInt load_flags,
+ FT_Byte* p,
+ FT_Byte* limit,
+ FT_Int x_pos,
+ FT_Int y_pos )
+ {
+ FT_Error error = FT_Err_Ok;
+ FT_Byte* line;
+ FT_Int bit_height, bit_width, pitch, width, height, line_bits, h;
+ FT_Bitmap* bitmap;
- face->num_sbit_strikes = num_strikes;
+ FT_UNUSED( load_flags );
- /* now read each strike table separately */
- {
- TT_SBit_Strike strike = face->sbit_strikes;
- FT_ULong count = num_strikes;
+ /* check that we can write the glyph into the bitmap */
+ bitmap = decoder->bitmap;
+ bit_width = bitmap->width;
+ bit_height = bitmap->rows;
+ pitch = bitmap->pitch;
+ line = bitmap->buffer;
- if ( FT_FRAME_ENTER( 48L * num_strikes ) )
- goto Exit;
+ width = decoder->metrics->width;
+ height = decoder->metrics->height;
- while ( count > 0 )
- {
- if ( FT_STREAM_READ_FIELDS( strike_start_fields, strike ) ||
- FT_STREAM_READ_FIELDS( sbit_line_metrics_fields, &strike->hori ) ||
- FT_STREAM_READ_FIELDS( sbit_line_metrics_fields, &strike->vert ) ||
- FT_STREAM_READ_FIELDS( strike_end_fields, strike ) )
- break;
-
- count--;
- strike++;
- }
+ line_bits = width * decoder->bit_depth;
- FT_FRAME_EXIT();
+ if ( x_pos < 0 || x_pos + width > bit_width ||
+ y_pos < 0 || y_pos + height > bit_height )
+ {
+ FT_TRACE1(( "tt_sbit_decoder_load_byte_aligned:"
+ " invalid bitmap dimensions\n" ));
+ error = FT_THROW( Invalid_File_Format );
+ goto Exit;
}
- /* allocate the index ranges for each strike table */
+ if ( p + ( ( line_bits + 7 ) >> 3 ) * height > limit )
{
- TT_SBit_Strike strike = face->sbit_strikes;
- FT_ULong count = num_strikes;
+ FT_TRACE1(( "tt_sbit_decoder_load_byte_aligned: broken bitmap\n" ));
+ error = FT_THROW( Invalid_File_Format );
+ goto Exit;
+ }
+ /* now do the blit */
+ line += y_pos * pitch + ( x_pos >> 3 );
+ x_pos &= 7;
- while ( count > 0 )
+ if ( x_pos == 0 ) /* the easy one */
+ {
+ for ( h = height; h > 0; h--, line += pitch )
{
- TT_SBit_Range range;
- FT_ULong count2 = strike->num_ranges;
+ FT_Byte* pwrite = line;
+ FT_Int w;
- /* read each range */
- if ( FT_STREAM_SEEK( table_base + strike->ranges_offset ) ||
- FT_FRAME_ENTER( strike->num_ranges * 8L ) )
- goto Exit;
-
- if ( FT_NEW_ARRAY( strike->sbit_ranges, strike->num_ranges ) )
- goto Exit;
-
- range = strike->sbit_ranges;
- while ( count2 > 0 )
+ for ( w = line_bits; w >= 8; w -= 8 )
{
- range->first_glyph = FT_GET_USHORT();
- range->last_glyph = FT_GET_USHORT();
- range->table_offset = table_base + strike->ranges_offset +
- FT_GET_ULONG();
- count2--;
- range++;
+ pwrite[0] = (FT_Byte)( pwrite[0] | *p++ );
+ pwrite += 1;
}
- FT_FRAME_EXIT();
+ if ( w > 0 )
+ pwrite[0] = (FT_Byte)( pwrite[0] | ( *p++ & ( 0xFF00U >> w ) ) );
+ }
+ }
+ else /* x_pos > 0 */
+ {
+ for ( h = height; h > 0; h--, line += pitch )
+ {
+ FT_Byte* pwrite = line;
+ FT_Int w;
+ FT_UInt wval = 0;
+
- /* Now, read each index table */
- count2 = strike->num_ranges;
- range = strike->sbit_ranges;
- while ( count2 > 0 )
+ for ( w = line_bits; w >= 8; w -= 8 )
{
- /* Read the header */
- if ( FT_STREAM_SEEK( range->table_offset ) ||
- FT_FRAME_ENTER( 8L ) )
- goto Exit;
+ wval = (FT_UInt)( wval | *p++ );
+ pwrite[0] = (FT_Byte)( pwrite[0] | ( wval >> x_pos ) );
+ pwrite += 1;
+ wval <<= 8;
+ }
- range->index_format = FT_GET_USHORT();
- range->image_format = FT_GET_USHORT();
- range->image_offset = FT_GET_ULONG();
+ if ( w > 0 )
+ wval = (FT_UInt)( wval | ( *p++ & ( 0xFF00U >> w ) ) );
- FT_FRAME_EXIT();
+ /* all bits read and there are `x_pos + w' bits to be written */
- error = Load_SBit_Range( range, stream );
- if ( error )
- goto Exit;
+ pwrite[0] = (FT_Byte)( pwrite[0] | ( wval >> x_pos ) );
- count2--;
- range++;
+ if ( x_pos + w > 8 )
+ {
+ pwrite++;
+ wval <<= 8;
+ pwrite[0] = (FT_Byte)( pwrite[0] | ( wval >> x_pos ) );
}
-
- count--;
- strike++;
}
}
Exit:
+ if ( !error )
+ FT_TRACE3(( "tt_sbit_decoder_load_byte_aligned: loaded\n" ));
return error;
}
- /*************************************************************************/
- /* */
- /* <Function> */
- /* tt_face_free_eblc */
- /* */
- /* <Description> */
- /* Releases the embedded bitmap tables. */
- /* */
- /* <Input> */
- /* face :: The target face object. */
- /* */
- FT_LOCAL_DEF( void )
- tt_face_free_eblc( TT_Face face )
+ /*
+ * Load a bit-aligned bitmap (with pointer `p') into a line-aligned bitmap
+ * (with pointer `pwrite'). In the example below, the width is 3 pixel,
+ * and `x_pos' is 1 pixel.
+ *
+ * p p+1
+ * | | |
+ * | 7 6 5 4 3 2 1 0 | 7 6 5 4 3 2 1 0 |...
+ * | | |
+ * +-------+ +-------+ +-------+ ...
+ * . . .
+ * . . .
+ * v . .
+ * +-------+ . .
+ * | | .
+ * | 7 6 5 4 3 2 1 0 | .
+ * | | .
+ * pwrite . .
+ * . .
+ * v .
+ * +-------+ .
+ * | |
+ * | 7 6 5 4 3 2 1 0 |
+ * | |
+ * pwrite+1 .
+ * .
+ * v
+ * +-------+
+ * | |
+ * | 7 6 5 4 3 2 1 0 |
+ * | |
+ * pwrite+2
+ *
+ */
+
+ static FT_Error
+ tt_sbit_decoder_load_bit_aligned( TT_SBitDecoder decoder,
+ FT_UInt load_flags,
+ FT_Byte* p,
+ FT_Byte* limit,
+ FT_Int x_pos,
+ FT_Int y_pos )
{
- FT_Memory memory = face->root.memory;
- TT_SBit_Strike strike = face->sbit_strikes;
- TT_SBit_Strike strike_limit = strike + face->num_sbit_strikes;
+ FT_Error error = FT_Err_Ok;
+ FT_Byte* line;
+ FT_Int bit_height, bit_width, pitch, width, height, line_bits, h, nbits;
+ FT_Bitmap* bitmap;
+ FT_UShort rval;
+ FT_UNUSED( load_flags );
- if ( strike )
- {
- for ( ; strike < strike_limit; strike++ )
- {
- TT_SBit_Range range = strike->sbit_ranges;
- TT_SBit_Range range_limit = range + strike->num_ranges;
+ /* check that we can write the glyph into the bitmap */
+ bitmap = decoder->bitmap;
+ bit_width = bitmap->width;
+ bit_height = bitmap->rows;
+ pitch = bitmap->pitch;
+ line = bitmap->buffer;
- if ( range )
- {
- for ( ; range < range_limit; range++ )
- {
- /* release the glyph offsets and codes tables */
- /* where appropriate */
- FT_FREE( range->glyph_offsets );
- FT_FREE( range->glyph_codes );
- }
- }
- FT_FREE( strike->sbit_ranges );
- strike->num_ranges = 0;
- }
- FT_FREE( face->sbit_strikes );
+ width = decoder->metrics->width;
+ height = decoder->metrics->height;
+
+ line_bits = width * decoder->bit_depth;
+
+ if ( x_pos < 0 || x_pos + width > bit_width ||
+ y_pos < 0 || y_pos + height > bit_height )
+ {
+ FT_TRACE1(( "tt_sbit_decoder_load_bit_aligned:"
+ " invalid bitmap dimensions\n" ));
+ error = FT_THROW( Invalid_File_Format );
+ goto Exit;
}
- face->num_sbit_strikes = 0;
- }
+ if ( p + ( ( line_bits * height + 7 ) >> 3 ) > limit )
+ {
+ FT_TRACE1(( "tt_sbit_decoder_load_bit_aligned: broken bitmap\n" ));
+ error = FT_THROW( Invalid_File_Format );
+ goto Exit;
+ }
- FT_LOCAL_DEF( FT_Error )
- tt_face_set_sbit_strike( TT_Face face,
- FT_Size_Request req,
- FT_ULong* astrike_index )
- {
- return FT_Match_Size( (FT_Face)face, req, 0, astrike_index );
- }
+ /* now do the blit */
+ /* adjust `line' to point to the first byte of the bitmap */
+ line += y_pos * pitch + ( x_pos >> 3 );
+ x_pos &= 7;
- FT_LOCAL_DEF( FT_Error )
- tt_face_load_strike_metrics( TT_Face face,
- FT_ULong strike_index,
- FT_Size_Metrics* metrics )
- {
- TT_SBit_Strike strike;
+ /* the higher byte of `rval' is used as a buffer */
+ rval = 0;
+ nbits = 0;
+ for ( h = height; h > 0; h--, line += pitch )
+ {
+ FT_Byte* pwrite = line;
+ FT_Int w = line_bits;
- if ( strike_index >= face->num_sbit_strikes )
- return SFNT_Err_Invalid_Argument;
- strike = face->sbit_strikes + strike_index;
+ /* handle initial byte (in target bitmap) specially if necessary */
+ if ( x_pos )
+ {
+ w = ( line_bits < 8 - x_pos ) ? line_bits : 8 - x_pos;
- metrics->x_ppem = strike->x_ppem;
- metrics->y_ppem = strike->y_ppem;
+ if ( h == height )
+ {
+ rval = *p++;
+ nbits = x_pos;
+ }
+ else if ( nbits < w )
+ {
+ if ( p < limit )
+ rval |= *p++;
+ nbits += 8 - w;
+ }
+ else
+ {
+ rval >>= 8;
+ nbits -= w;
+ }
- metrics->ascender = strike->hori.ascender << 6;
- metrics->descender = strike->hori.descender << 6;
+ *pwrite++ |= ( ( rval >> nbits ) & 0xFF ) &
+ ( ~( 0xFF << w ) << ( 8 - w - x_pos ) );
+ rval <<= 8;
- /* XXX: Is this correct? */
- metrics->max_advance = ( strike->hori.min_origin_SB +
- strike->hori.max_width +
- strike->hori.min_advance_SB ) << 6;
+ w = line_bits - w;
+ }
- metrics->height = metrics->ascender - metrics->descender;
+ /* handle medial bytes */
+ for ( ; w >= 8; w -= 8 )
+ {
+ rval |= *p++;
+ *pwrite++ |= ( rval >> nbits ) & 0xFF;
- return SFNT_Err_Ok;
+ rval <<= 8;
+ }
+
+ /* handle final byte if necessary */
+ if ( w > 0 )
+ {
+ if ( nbits < w )
+ {
+ if ( p < limit )
+ rval |= *p++;
+ *pwrite |= ( ( rval >> nbits ) & 0xFF ) & ( 0xFF00U >> w );
+ nbits += 8 - w;
+
+ rval <<= 8;
+ }
+ else
+ {
+ *pwrite |= ( ( rval >> nbits ) & 0xFF ) & ( 0xFF00U >> w );
+ nbits -= w;
+ }
+ }
+ }
+
+ Exit:
+ if ( !error )
+ FT_TRACE3(( "tt_sbit_decoder_load_bit_aligned: loaded\n" ));
+ return error;
}
- /*************************************************************************/
- /* */
- /* <Function> */
- /* find_sbit_range */
- /* */
- /* <Description> */
- /* Scans a given strike's ranges and return, for a given glyph */
- /* index, the corresponding sbit range, and `EBDT' offset. */
- /* */
- /* <Input> */
- /* glyph_index :: The glyph index. */
- /* */
- /* strike :: The source/current sbit strike. */
- /* */
- /* <Output> */
- /* arange :: The sbit range containing the glyph index. */
- /* */
- /* aglyph_offset :: The offset of the glyph data in `EBDT' table. */
- /* */
- /* <Return> */
- /* FreeType error code. 0 means the glyph index was found. */
- /* */
static FT_Error
- find_sbit_range( FT_UInt glyph_index,
- TT_SBit_Strike strike,
- TT_SBit_Range *arange,
- FT_ULong *aglyph_offset )
+ tt_sbit_decoder_load_compound( TT_SBitDecoder decoder,
+ FT_UInt load_flags,
+ FT_Byte* p,
+ FT_Byte* limit,
+ FT_Int x_pos,
+ FT_Int y_pos )
{
- TT_SBit_RangeRec *range, *range_limit;
+ FT_Error error = FT_Err_Ok;
+ FT_UInt num_components, nn;
+ FT_Char horiBearingX = decoder->metrics->horiBearingX;
+ FT_Char horiBearingY = decoder->metrics->horiBearingY;
+ FT_Byte horiAdvance = decoder->metrics->horiAdvance;
+ FT_Char vertBearingX = decoder->metrics->vertBearingX;
+ FT_Char vertBearingY = decoder->metrics->vertBearingY;
+ FT_Byte vertAdvance = decoder->metrics->vertAdvance;
- /* check whether the glyph index is within this strike's */
- /* glyph range */
- if ( glyph_index < (FT_UInt)strike->start_glyph ||
- glyph_index > (FT_UInt)strike->end_glyph )
- goto Fail;
- /* scan all ranges in strike */
- range = strike->sbit_ranges;
- range_limit = range + strike->num_ranges;
- if ( !range )
+ if ( p + 2 > limit )
goto Fail;
- for ( ; range < range_limit; range++ )
+ num_components = FT_NEXT_USHORT( p );
+ if ( p + 4 * num_components > limit )
{
- if ( glyph_index >= (FT_UInt)range->first_glyph &&
- glyph_index <= (FT_UInt)range->last_glyph )
- {
- FT_UShort delta = (FT_UShort)( glyph_index - range->first_glyph );
+ FT_TRACE1(( "tt_sbit_decoder_load_compound: broken table\n" ));
+ goto Fail;
+ }
+ FT_TRACE3(( "tt_sbit_decoder_load_compound: loading %d components\n",
+ num_components ));
- switch ( range->index_format )
- {
- case 1:
- case 3:
- *aglyph_offset = range->glyph_offsets[delta];
- break;
-
- case 2:
- *aglyph_offset = range->image_offset +
- range->image_size * delta;
- break;
-
- case 4:
- case 5:
- {
- FT_ULong n;
-
-
- for ( n = 0; n < range->num_glyphs; n++ )
- {
- if ( (FT_UInt)range->glyph_codes[n] == glyph_index )
- {
- if ( range->index_format == 4 )
- *aglyph_offset = range->glyph_offsets[n];
- else
- *aglyph_offset = range->image_offset +
- n * range->image_size;
- goto Found;
- }
- }
- }
+ for ( nn = 0; nn < num_components; nn++ )
+ {
+ FT_UInt gindex = FT_NEXT_USHORT( p );
+ FT_Byte dx = FT_NEXT_BYTE( p );
+ FT_Byte dy = FT_NEXT_BYTE( p );
- /* fall-through */
- default:
- goto Fail;
- }
- Found:
- /* return successfully! */
- *arange = range;
- return SFNT_Err_Ok;
- }
+ /* NB: a recursive call */
+ error = tt_sbit_decoder_load_image( decoder, load_flags, gindex,
+ x_pos + dx, y_pos + dy );
+ if ( error )
+ break;
}
- Fail:
- *arange = 0;
- *aglyph_offset = 0;
+ FT_TRACE3(( "tt_sbit_decoder_load_compound: done\n" ));
- return SFNT_Err_Invalid_Argument;
- }
+ decoder->metrics->horiBearingX = horiBearingX;
+ decoder->metrics->horiBearingY = horiBearingY;
+ decoder->metrics->horiAdvance = horiAdvance;
+ decoder->metrics->vertBearingX = vertBearingX;
+ decoder->metrics->vertBearingY = vertBearingY;
+ decoder->metrics->vertAdvance = vertAdvance;
+ decoder->metrics->width = (FT_Byte)decoder->bitmap->width;
+ decoder->metrics->height = (FT_Byte)decoder->bitmap->rows;
+ Exit:
+ return error;
- /*************************************************************************/
- /* */
- /* <Function> */
- /* tt_find_sbit_image */
- /* */
- /* <Description> */
- /* Checks whether an embedded bitmap (an `sbit') exists for a given */
- /* glyph, at a given strike. */
- /* */
- /* <Input> */
- /* face :: The target face object. */
- /* */
- /* glyph_index :: The glyph index. */
- /* */
- /* strike_index :: The current strike index. */
- /* */
- /* <Output> */
- /* arange :: The SBit range containing the glyph index. */
- /* */
- /* astrike :: The SBit strike containing the glyph index. */
- /* */
- /* aglyph_offset :: The offset of the glyph data in `EBDT' table. */
- /* */
- /* <Return> */
- /* FreeType error code. 0 means success. Returns */
- /* SFNT_Err_Invalid_Argument if no sbit exists for the requested */
- /* glyph. */
- /* */
- FT_LOCAL( FT_Error )
- tt_find_sbit_image( TT_Face face,
- FT_UInt glyph_index,
- FT_ULong strike_index,
- TT_SBit_Range *arange,
- TT_SBit_Strike *astrike,
- FT_ULong *aglyph_offset )
- {
- FT_Error error;
- TT_SBit_Strike strike;
+ Fail:
+ error = FT_THROW( Invalid_File_Format );
+ goto Exit;
+ }
- if ( !face->sbit_strikes ||
- ( face->num_sbit_strikes <= strike_index ) )
- goto Fail;
+#ifdef FT_CONFIG_OPTION_USE_PNG
- strike = &face->sbit_strikes[strike_index];
+ static FT_Error
+ tt_sbit_decoder_load_png( TT_SBitDecoder decoder,
+ FT_UInt load_flags,
+ FT_Byte* p,
+ FT_Byte* limit,
+ FT_Int x_pos,
+ FT_Int y_pos )
+ {
+ FT_Error error = FT_Err_Ok;
+ FT_ULong png_len;
- error = find_sbit_range( glyph_index, strike,
- arange, aglyph_offset );
- if ( error )
- goto Fail;
+ FT_UNUSED( load_flags );
- *astrike = strike;
- return SFNT_Err_Ok;
+ if ( limit - p < 4 )
+ {
+ FT_TRACE1(( "tt_sbit_decoder_load_png: broken bitmap\n" ));
+ error = FT_THROW( Invalid_File_Format );
+ goto Exit;
+ }
- Fail:
- /* no embedded bitmap for this glyph in face */
- *arange = 0;
- *astrike = 0;
- *aglyph_offset = 0;
+ png_len = FT_NEXT_ULONG( p );
+ if ( (FT_ULong)( limit - p ) < png_len )
+ {
+ FT_TRACE1(( "tt_sbit_decoder_load_png: broken bitmap\n" ));
+ error = FT_THROW( Invalid_File_Format );
+ goto Exit;
+ }
+
+ error = Load_SBit_Png( decoder->bitmap,
+ x_pos,
+ y_pos,
+ decoder->bit_depth,
+ decoder->metrics,
+ decoder->stream->memory,
+ p,
+ png_len );
- return SFNT_Err_Invalid_Argument;
+ Exit:
+ if ( !error )
+ FT_TRACE3(( "tt_sbit_decoder_load_png: loaded\n" ));
+ return error;
}
+#endif /* FT_CONFIG_OPTION_USE_PNG */
- /*************************************************************************/
- /* */
- /* <Function> */
- /* tt_load_sbit_metrics */
- /* */
- /* <Description> */
- /* Gets the big metrics for a given SBit. */
- /* */
- /* <Input> */
- /* stream :: The input stream. */
- /* */
- /* range :: The SBit range containing the glyph. */
- /* */
- /* <Output> */
- /* big_metrics :: A big SBit metrics structure for the glyph. */
- /* */
- /* <Return> */
- /* FreeType error code. 0 means success. */
- /* */
- /* <Note> */
- /* The stream cursor must be positioned at the glyph's offset within */
- /* the `EBDT' table before the call. */
- /* */
- /* If the image format uses variable metrics, the stream cursor is */
- /* positioned just after the metrics header in the `EBDT' table on */
- /* function exit. */
- /* */
- FT_LOCAL( FT_Error )
- tt_load_sbit_metrics( FT_Stream stream,
- TT_SBit_Range range,
- TT_SBit_Metrics metrics )
+
+ static FT_Error
+ tt_sbit_decoder_load_bitmap( TT_SBitDecoder decoder,
+ FT_UInt load_flags,
+ FT_UInt glyph_format,
+ FT_ULong glyph_start,
+ FT_ULong glyph_size,
+ FT_Int x_pos,
+ FT_Int y_pos )
{
- FT_Error error = SFNT_Err_Ok;
+ FT_Error error;
+ FT_Stream stream = decoder->stream;
+ FT_Byte* p;
+ FT_Byte* p_limit;
+ FT_Byte* data;
- switch ( range->image_format )
+ /* seek into the EBDT table now */
+ if ( glyph_start + glyph_size > decoder->ebdt_size )
+ {
+ error = FT_THROW( Invalid_Argument );
+ goto Exit;
+ }
+
+ if ( FT_STREAM_SEEK( decoder->ebdt_start + glyph_start ) ||
+ FT_FRAME_EXTRACT( glyph_size, data ) )
+ goto Exit;
+
+ p = data;
+ p_limit = p + glyph_size;
+
+ /* read the data, depending on the glyph format */
+ switch ( glyph_format )
{
case 1:
case 2:
case 8:
- /* variable small metrics */
- {
- TT_SBit_SmallMetricsRec smetrics;
-
- static const FT_Frame_Field sbit_small_metrics_fields[] =
- {
-#undef FT_STRUCTURE
-#define FT_STRUCTURE TT_SBit_SmallMetricsRec
-
- FT_FRAME_START( 5 ),
- FT_FRAME_BYTE( height ),
- FT_FRAME_BYTE( width ),
- FT_FRAME_CHAR( bearingX ),
- FT_FRAME_CHAR( bearingY ),
- FT_FRAME_BYTE( advance ),
- FT_FRAME_END
- };
-
-
- /* read small metrics */
- if ( FT_STREAM_READ_FIELDS( sbit_small_metrics_fields, &smetrics ) )
- goto Exit;
-
- /* convert it to a big metrics */
- metrics->height = smetrics.height;
- metrics->width = smetrics.width;
- metrics->horiBearingX = smetrics.bearingX;
- metrics->horiBearingY = smetrics.bearingY;
- metrics->horiAdvance = smetrics.advance;
-
- /* these metrics are made up at a higher level when */
- /* needed. */
- metrics->vertBearingX = 0;
- metrics->vertBearingY = 0;
- metrics->vertAdvance = 0;
- }
+ case 17:
+ error = tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 0 );
break;
case 6:
case 7:
case 9:
- /* variable big metrics */
- if ( FT_STREAM_READ_FIELDS( sbit_metrics_fields, metrics ) )
- goto Exit;
+ case 18:
+ error = tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 1 );
break;
- case 5:
- default: /* constant metrics */
- if ( range->index_format == 2 || range->index_format == 5 )
- *metrics = range->metrics;
- else
- return SFNT_Err_Invalid_File_Format;
- }
-
- Exit:
- return error;
- }
+ default:
+ error = FT_Err_Ok;
+ }
+ if ( error )
+ goto Fail;
- /*************************************************************************/
- /* */
- /* <Function> */
- /* crop_bitmap */
- /* */
- /* <Description> */
- /* Crops a bitmap to its tightest bounding box, and adjusts its */
- /* metrics. */
- /* */
- /* <InOut> */
- /* map :: The bitmap. */
- /* */
- /* metrics :: The corresponding metrics structure. */
- /* */
- static void
- crop_bitmap( FT_Bitmap* map,
- TT_SBit_Metrics metrics )
- {
- /***********************************************************************/
- /* */
- /* In this situation, some bounding boxes of embedded bitmaps are too */
- /* large. We need to crop it to a reasonable size. */
- /* */
- /* --------- */
- /* | | ----- */
- /* | *** | |***| */
- /* | * | | * | */
- /* | * | ------> | * | */
- /* | * | | * | */
- /* | * | | * | */
- /* | *** | |***| */
- /* --------- ----- */
- /* */
- /***********************************************************************/
-
- FT_Int rows, count;
- FT_Long line_len;
- FT_Byte* line;
-
-
- /***********************************************************************/
- /* */
- /* first of all, check the top-most lines of the bitmap, and remove */
- /* them if they're empty. */
- /* */
{
- line = (FT_Byte*)map->buffer;
- rows = map->rows;
- line_len = map->pitch;
+ TT_SBitDecoder_LoadFunc loader;
- for ( count = 0; count < rows; count++ )
+ switch ( glyph_format )
{
- FT_Byte* cur = line;
- FT_Byte* limit = line + line_len;
-
-
- for ( ; cur < limit; cur++ )
- if ( cur[0] )
- goto Found_Top;
+ case 1:
+ case 6:
+ loader = tt_sbit_decoder_load_byte_aligned;
+ break;
- /* the current line was empty - skip to next one */
- line = limit;
- }
+ case 2:
+ case 5:
+ case 7:
+ loader = tt_sbit_decoder_load_bit_aligned;
+ break;
- Found_Top:
- /* check that we have at least one filled line */
- if ( count >= rows )
- goto Empty_Bitmap;
+ case 8:
+ if ( p + 1 > p_limit )
+ goto Fail;
- /* now, crop the empty upper lines */
- if ( count > 0 )
- {
- line = (FT_Byte*)map->buffer;
+ p += 1; /* skip padding */
+ /* fall-through */
- FT_MEM_MOVE( line, line + count * line_len,
- ( rows - count ) * line_len );
+ case 9:
+ loader = tt_sbit_decoder_load_compound;
+ break;
- metrics->height = (FT_Byte)( metrics->height - count );
- metrics->horiBearingY = (FT_Char)( metrics->horiBearingY - count );
- metrics->vertBearingY = (FT_Char)( metrics->vertBearingY - count );
+#ifdef FT_CONFIG_OPTION_USE_PNG
+ case 17: /* small metrics, PNG image data */
+ case 18: /* big metrics, PNG image data */
+ case 19: /* metrics in EBLC, PNG image data */
+ loader = tt_sbit_decoder_load_png;
+ break;
+#endif /* FT_CONFIG_OPTION_USE_PNG */
- map->rows -= count;
- rows -= count;
+ default:
+ error = FT_THROW( Invalid_Table );
+ goto Fail;
}
- }
- /***********************************************************************/
- /* */
- /* second, crop the lower lines */
- /* */
- {
- line = (FT_Byte*)map->buffer + ( rows - 1 ) * line_len;
-
- for ( count = 0; count < rows; count++ )
+ if ( !decoder->bitmap_allocated )
{
- FT_Byte* cur = line;
- FT_Byte* limit = line + line_len;
-
-
- for ( ; cur < limit; cur++ )
- if ( cur[0] )
- goto Found_Bottom;
-
- /* the current line was empty - skip to previous one */
- line -= line_len;
+ error = tt_sbit_decoder_alloc_bitmap( decoder, load_flags );
+ if ( error )
+ goto Fail;
}
- Found_Bottom:
- if ( count > 0 )
+ if ( decoder->bit_depth == 32 &&
+ decoder->bitmap->pixel_mode != FT_PIXEL_MODE_BGRA )
{
- metrics->height = (FT_Byte)( metrics->height - count );
- rows -= count;
- map->rows -= count;
- }
- }
-
- /***********************************************************************/
- /* */
- /* third, get rid of the space on the left side of the glyph */
- /* */
- do
- {
- FT_Byte* limit;
-
+ /* Flatten color bitmaps if color was not requested. */
- line = (FT_Byte*)map->buffer;
- limit = line + rows * line_len;
+ FT_Library library = decoder->face->root.glyph->library;
+ FT_Memory memory = decoder->stream->memory;
- for ( ; line < limit; line += line_len )
- if ( line[0] & 0x80 )
- goto Found_Left;
+ FT_Bitmap color, *orig;
- /* shift the whole glyph one pixel to the left */
- line = (FT_Byte*)map->buffer;
- limit = line + rows * line_len;
- for ( ; line < limit; line += line_len )
- {
- FT_Int n, width = map->width;
- FT_Byte old;
- FT_Byte* cur = line;
-
-
- old = (FT_Byte)(cur[0] << 1);
- for ( n = 8; n < width; n += 8 )
+ if ( decoder->bitmap->pixel_mode != FT_PIXEL_MODE_GRAY ||
+ x_pos != 0 || y_pos != 0 )
{
- FT_Byte val;
-
-
- val = cur[1];
- cur[0] = (FT_Byte)( old | ( val >> 7 ) );
- old = (FT_Byte)( val << 1 );
- cur++;
+ /* Shouldn't happen. */
+ error = FT_THROW( Invalid_Table );
+ goto Fail;
}
- cur[0] = old;
- }
- map->width--;
- metrics->horiBearingX++;
- metrics->vertBearingX++;
- metrics->width--;
+ FT_Bitmap_New( &color );
- } while ( map->width > 0 );
+ color.rows = decoder->bitmap->rows;
+ color.width = decoder->bitmap->width;
+ color.pitch = color.width * 4;
+ color.pixel_mode = FT_PIXEL_MODE_BGRA;
- Found_Left:
+ if ( FT_ALLOC( color.buffer, color.rows * color.pitch ) )
+ goto Fail;
- /***********************************************************************/
- /* */
- /* finally, crop the bitmap width to get rid of the space on the right */
- /* side of the glyph. */
- /* */
- do
- {
- FT_Int right = map->width - 1;
- FT_Byte* limit;
- FT_Byte mask;
+ orig = decoder->bitmap;
+ decoder->bitmap = &color;
+ error = loader( decoder, load_flags, p, p_limit, x_pos, y_pos );
- line = (FT_Byte*)map->buffer + ( right >> 3 );
- limit = line + rows * line_len;
- mask = (FT_Byte)( 0x80 >> ( right & 7 ) );
+ decoder->bitmap = orig;
- for ( ; line < limit; line += line_len )
- if ( line[0] & mask )
- goto Found_Right;
+ /* explicitly test against FT_Err_Ok to avoid compiler warnings */
+ /* (we do an assignment within a conditional) */
+ if ( error ||
+ ( error = FT_Bitmap_Convert( library,
+ &color,
+ decoder->bitmap,
+ 1 ) ) != FT_Err_Ok )
+ {
+ FT_Bitmap_Done( library, &color );
+ goto Fail;
+ }
- /* crop the whole glyph to the right */
- map->width--;
- metrics->width--;
+ FT_Bitmap_Done( library, &color );
+ }
- } while ( map->width > 0 );
+ else
+ error = loader( decoder, load_flags, p, p_limit, x_pos, y_pos );
+ }
- Found_Right:
- /* all right, the bitmap was cropped */
- return;
+ Fail:
+ FT_FRAME_RELEASE( data );
- Empty_Bitmap:
- map->width = 0;
- map->rows = 0;
- map->pitch = 0;
- map->pixel_mode = FT_PIXEL_MODE_MONO;
+ Exit:
+ return error;
}
static FT_Error
- Load_SBit_Single( FT_Bitmap* map,
- FT_Int x_offset,
- FT_Int y_offset,
- FT_Int pix_bits,
- FT_UShort image_format,
- TT_SBit_Metrics metrics,
- FT_Stream stream )
+ tt_sbit_decoder_load_image( TT_SBitDecoder decoder,
+ FT_UInt load_flags,
+ FT_UInt glyph_index,
+ FT_Int x_pos,
+ FT_Int y_pos )
{
- FT_Error error;
+ /*
+ * First, we find the correct strike range that applies to this
+ * glyph index.
+ */
+
+ FT_Byte* p = decoder->eblc_base + decoder->strike_index_array;
+ FT_Byte* p_limit = decoder->eblc_limit;
+ FT_ULong num_ranges = decoder->strike_index_count;
+ FT_UInt start, end, index_format, image_format;
+ FT_ULong image_start = 0, image_end = 0, image_offset;
- /* check that the source bitmap fits into the target pixmap */
- if ( x_offset < 0 || x_offset + metrics->width > map->width ||
- y_offset < 0 || y_offset + metrics->height > map->rows )
+ for ( ; num_ranges > 0; num_ranges-- )
{
- error = SFNT_Err_Invalid_Argument;
+ start = FT_NEXT_USHORT( p );
+ end = FT_NEXT_USHORT( p );
- goto Exit;
- }
+ if ( glyph_index >= start && glyph_index <= end )
+ goto FoundRange;
- {
- FT_Int glyph_width = metrics->width;
- FT_Int glyph_height = metrics->height;
- FT_Int glyph_size;
- FT_Int line_bits = pix_bits * glyph_width;
- FT_Bool pad_bytes = 0;
+ p += 4; /* ignore index offset */
+ }
+ goto NoBitmap;
+ FoundRange:
+ image_offset = FT_NEXT_ULONG( p );
- /* compute size of glyph image */
- switch ( image_format )
- {
- case 1: /* byte-padded formats */
- case 6:
- {
- FT_Int line_length;
+ /* overflow check */
+ p = decoder->eblc_base + decoder->strike_index_array;
+ if ( image_offset > (FT_ULong)( p_limit - p ) )
+ goto Failure;
+ p += image_offset;
+ if ( p + 8 > p_limit )
+ goto NoBitmap;
- switch ( pix_bits )
- {
- case 1:
- line_length = ( glyph_width + 7 ) >> 3;
- break;
- case 2:
- line_length = ( glyph_width + 3 ) >> 2;
- break;
- case 4:
- line_length = ( glyph_width + 1 ) >> 1;
- break;
- default:
- line_length = glyph_width;
- }
+ /* now find the glyph's location and extend within the ebdt table */
+ index_format = FT_NEXT_USHORT( p );
+ image_format = FT_NEXT_USHORT( p );
+ image_offset = FT_NEXT_ULONG ( p );
- glyph_size = glyph_height * line_length;
- pad_bytes = 1;
- }
- break;
+ switch ( index_format )
+ {
+ case 1: /* 4-byte offsets relative to `image_offset' */
+ {
+ p += 4 * ( glyph_index - start );
+ if ( p + 8 > p_limit )
+ goto NoBitmap;
- case 2:
- case 5:
- case 7:
- line_bits = glyph_width * pix_bits;
- glyph_size = ( glyph_height * line_bits + 7 ) >> 3;
- break;
+ image_start = FT_NEXT_ULONG( p );
+ image_end = FT_NEXT_ULONG( p );
- default: /* invalid format */
- return SFNT_Err_Invalid_File_Format;
+ if ( image_start == image_end ) /* missing glyph */
+ goto NoBitmap;
}
+ break;
- /* Now read data and draw glyph into target pixmap */
- if ( FT_FRAME_ENTER( glyph_size ) )
- goto Exit;
+ case 2: /* big metrics, constant image size */
+ {
+ FT_ULong image_size;
- /* don't forget to multiply `x_offset' by `map->pix_bits' as */
- /* the sbit blitter doesn't make a difference between pixmap */
- /* depths. */
- blit_sbit( map, (FT_Byte*)stream->cursor, line_bits, pad_bytes,
- x_offset * pix_bits, y_offset, metrics->height );
- FT_FRAME_EXIT();
- }
+ if ( p + 12 > p_limit )
+ goto NoBitmap;
- Exit:
- return error;
- }
+ image_size = FT_NEXT_ULONG( p );
+ if ( tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 1 ) )
+ goto NoBitmap;
- static FT_Error
- Load_SBit_Image( TT_SBit_Strike strike,
- TT_SBit_Range range,
- FT_ULong ebdt_pos,
- FT_ULong glyph_offset,
- FT_GlyphSlot slot,
- FT_Int x_offset,
- FT_Int y_offset,
- FT_Stream stream,
- TT_SBit_Metrics metrics,
- FT_Int depth )
- {
- FT_Memory memory = stream->memory;
- FT_Bitmap* map = &slot->bitmap;
- FT_Error error;
+ image_start = image_size * ( glyph_index - start );
+ image_end = image_start + image_size;
+ }
+ break;
+ case 3: /* 2-byte offsets relative to 'image_offset' */
+ {
+ p += 2 * ( glyph_index - start );
+ if ( p + 4 > p_limit )
+ goto NoBitmap;
- /* place stream at beginning of glyph data and read metrics */
- if ( FT_STREAM_SEEK( ebdt_pos + glyph_offset ) )
- goto Exit;
+ image_start = FT_NEXT_USHORT( p );
+ image_end = FT_NEXT_USHORT( p );
- error = tt_load_sbit_metrics( stream, range, metrics );
- if ( error )
- goto Exit;
+ if ( image_start == image_end ) /* missing glyph */
+ goto NoBitmap;
+ }
+ break;
- /* This function is recursive. At the top-level call, we */
- /* compute the dimensions of the higher-level glyph to */
- /* allocate the final pixmap buffer. */
- if ( depth == 0 )
- {
- FT_Long size;
+ case 4: /* sparse glyph array with (glyph,offset) pairs */
+ {
+ FT_ULong mm, num_glyphs;
- map->width = metrics->width;
- map->rows = metrics->height;
+ if ( p + 4 > p_limit )
+ goto NoBitmap;
- switch ( strike->bit_depth )
- {
- case 1:
- map->pixel_mode = FT_PIXEL_MODE_MONO;
- map->pitch = ( map->width + 7 ) >> 3;
- break;
+ num_glyphs = FT_NEXT_ULONG( p );
- case 2:
- map->pixel_mode = FT_PIXEL_MODE_GRAY2;
- map->pitch = ( map->width + 3 ) >> 2;
- break;
+ /* overflow check for p + ( num_glyphs + 1 ) * 4 */
+ if ( num_glyphs > (FT_ULong)( ( ( p_limit - p ) >> 2 ) - 1 ) )
+ goto NoBitmap;
- case 4:
- map->pixel_mode = FT_PIXEL_MODE_GRAY4;
- map->pitch = ( map->width + 1 ) >> 1;
- break;
+ for ( mm = 0; mm < num_glyphs; mm++ )
+ {
+ FT_UInt gindex = FT_NEXT_USHORT( p );
- case 8:
- map->pixel_mode = FT_PIXEL_MODE_GRAY;
- map->pitch = map->width;
- break;
- default:
- return SFNT_Err_Invalid_File_Format;
- }
+ if ( gindex == glyph_index )
+ {
+ image_start = FT_NEXT_USHORT( p );
+ p += 2;
+ image_end = FT_PEEK_USHORT( p );
+ break;
+ }
+ p += 2;
+ }
- size = map->rows * map->pitch;
+ if ( mm >= num_glyphs )
+ goto NoBitmap;
+ }
+ break;
- /* check that there is no empty image */
- if ( size == 0 )
- goto Exit; /* exit successfully! */
+ case 5: /* constant metrics with sparse glyph codes */
+ case 19:
+ {
+ FT_ULong image_size, mm, num_glyphs;
- error = ft_glyphslot_alloc_bitmap( slot, size );
- if (error)
- goto Exit;
- }
- switch ( range->image_format )
- {
- case 1: /* single sbit image - load it */
- case 2:
- case 5:
- case 6:
- case 7:
- return Load_SBit_Single( map, x_offset, y_offset, strike->bit_depth,
- range->image_format, metrics, stream );
+ if ( p + 16 > p_limit )
+ goto NoBitmap;
- case 8: /* compound format */
- if ( FT_STREAM_SKIP( 1L ) )
- {
- error = SFNT_Err_Invalid_Stream_Skip;
- goto Exit;
- }
- /* fallthrough */
+ image_size = FT_NEXT_ULONG( p );
- case 9:
- break;
+ if ( tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 1 ) )
+ goto NoBitmap;
- default: /* invalid image format */
- return SFNT_Err_Invalid_File_Format;
- }
+ num_glyphs = FT_NEXT_ULONG( p );
- /* All right, we have a compound format. First of all, read */
- /* the array of elements. */
- {
- TT_SBit_Component components = NULL;
- TT_SBit_Component comp;
- FT_UShort num_components, count;
+ /* overflow check for p + 2 * num_glyphs */
+ if ( num_glyphs > (FT_ULong)( ( p_limit - p ) >> 1 ) )
+ goto NoBitmap;
+ for ( mm = 0; mm < num_glyphs; mm++ )
+ {
+ FT_UInt gindex = FT_NEXT_USHORT( p );
- if ( FT_READ_USHORT( num_components ) ||
- FT_NEW_ARRAY( components, num_components ) )
- goto Exit;
- count = num_components;
+ if ( gindex == glyph_index )
+ break;
+ }
- if ( FT_FRAME_ENTER( 4L * num_components ) )
- goto Fail_Memory;
+ if ( mm >= num_glyphs )
+ goto NoBitmap;
- for ( comp = components; count > 0; count--, comp++ )
- {
- comp->glyph_code = FT_GET_USHORT();
- comp->x_offset = FT_GET_CHAR();
- comp->y_offset = FT_GET_CHAR();
+ image_start = image_size * mm;
+ image_end = image_start + image_size;
}
+ break;
- FT_FRAME_EXIT();
+ default:
+ goto NoBitmap;
+ }
- /* Now recursively load each element glyph */
- count = num_components;
- comp = components;
- for ( ; count > 0; count--, comp++ )
- {
- TT_SBit_Range elem_range;
- TT_SBit_MetricsRec elem_metrics;
- FT_ULong elem_offset;
+ if ( image_start > image_end )
+ goto NoBitmap;
+ image_end -= image_start;
+ image_start = image_offset + image_start;
- /* find the range for this element */
- error = find_sbit_range( comp->glyph_code,
- strike,
- &elem_range,
- &elem_offset );
- if ( error )
- goto Fail_Memory;
-
- /* now load the element, recursively */
- error = Load_SBit_Image( strike,
- elem_range,
- ebdt_pos,
- elem_offset,
- slot,
- x_offset + comp->x_offset,
- y_offset + comp->y_offset,
- stream,
- &elem_metrics,
- depth + 1 );
- if ( error )
- goto Fail_Memory;
- }
+ FT_TRACE3(( "tt_sbit_decoder_load_image:"
+ " found sbit (format %d) for glyph index %d\n",
+ image_format, glyph_index ));
- Fail_Memory:
- FT_FREE( components );
- }
+ return tt_sbit_decoder_load_bitmap( decoder,
+ load_flags,
+ image_format,
+ image_start,
+ image_end,
+ x_pos,
+ y_pos );
- Exit:
- return error;
+ Failure:
+ return FT_THROW( Invalid_Table );
+
+ NoBitmap:
+ FT_TRACE4(( "tt_sbit_decoder_load_image:"
+ " no sbit found for glyph index %d\n", glyph_index ));
+
+ return FT_THROW( Invalid_Argument );
}
- /*************************************************************************/
- /* */
- /* <Function> */
- /* tt_face_load_sbit_image */
- /* */
- /* <Description> */
- /* Loads a given glyph sbit image from the font resource. This also */
- /* returns its metrics. */
- /* */
- /* <Input> */
- /* face :: The target face object. */
- /* */
- /* strike_index :: The current strike index. */
- /* */
- /* glyph_index :: The current glyph index. */
- /* */
- /* load_flags :: The glyph load flags (the code checks for the flag */
- /* FT_LOAD_CROP_BITMAP). */
- /* */
- /* stream :: The input stream. */
- /* */
- /* <Output> */
- /* map :: The target pixmap. */
- /* */
- /* metrics :: A big sbit metrics structure for the glyph image. */
- /* */
- /* <Return> */
- /* FreeType error code. 0 means success. Returns an error if no */
- /* glyph sbit exists for the index. */
- /* */
- /* <Note> */
- /* The `map.buffer' field is always freed before the glyph is loaded. */
- /* */
- FT_LOCAL_DEF( FT_Error )
+ FT_LOCAL( FT_Error )
tt_face_load_sbit_image( TT_Face face,
FT_ULong strike_index,
FT_UInt glyph_index,
@@ -1450,59 +1151,27 @@
FT_Bitmap *map,
TT_SBit_MetricsRec *metrics )
{
- FT_Error error;
- FT_ULong ebdt_pos, glyph_offset;
+ TT_SBitDecoderRec decoder[1];
+ FT_Error error;
- TT_SBit_Strike strike;
- TT_SBit_Range range;
+ FT_UNUSED( load_flags );
+ FT_UNUSED( stream );
+ FT_UNUSED( map );
- /* Check whether there is a glyph sbit for the current index */
- error = tt_find_sbit_image( face, glyph_index, strike_index,
- &range, &strike, &glyph_offset );
- if ( error )
- goto Exit;
-
- /* now, find the location of the `EBDT' table in */
- /* the font file */
- error = face->goto_table( face, TTAG_EBDT, stream, 0 );
- if ( error )
- error = face->goto_table( face, TTAG_bdat, stream, 0 );
- if ( error )
- goto Exit;
-
- ebdt_pos = FT_STREAM_POS();
-
- error = Load_SBit_Image( strike, range, ebdt_pos, glyph_offset,
- face->root.glyph, 0, 0, stream, metrics, 0 );
- if ( error )
- goto Exit;
-
- /* setup vertical metrics if needed */
- if ( strike->flags & 1 )
+ error = tt_sbit_decoder_init( decoder, face, strike_index, metrics );
+ if ( !error )
{
- /* in case of a horizontal strike only */
- FT_Int advance;
-
-
- advance = strike->hori.ascender - strike->hori.descender;
-
- /* some heuristic values */
-
- metrics->vertBearingX = (FT_Char)(-metrics->width / 2 );
- metrics->vertBearingY = (FT_Char)( ( advance - metrics->height ) / 2 );
- metrics->vertAdvance = (FT_Char)( advance * 12 / 10 );
+ error = tt_sbit_decoder_load_image( decoder,
+ load_flags,
+ glyph_index,
+ 0,
+ 0 );
+ tt_sbit_decoder_done( decoder );
}
- /* Crop the bitmap now, unless specified otherwise */
- if ( load_flags & FT_LOAD_CROP_BITMAP )
- crop_bitmap( map, metrics );
-
- Exit:
return error;
}
-#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */
-
-/* END */
+/* EOF */
diff --git a/src/sfnt/ttsbit.h b/src/sfnt/ttsbit.h
index 7ea2af1..ea0b5f8 100644
--- a/src/sfnt/ttsbit.h
+++ b/src/sfnt/ttsbit.h
@@ -4,7 +4,7 @@
/* */
/* TrueType and OpenType embedded bitmap support (specification). */
/* */
-/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by */
+/* Copyright 1996-2008, 2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -45,22 +45,6 @@ FT_BEGIN_HEADER
FT_ULong strike_index,
FT_Size_Metrics* metrics );
-#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
- FT_LOCAL( FT_Error )
- tt_find_sbit_image( TT_Face face,
- FT_UInt glyph_index,
- FT_ULong strike_index,
- TT_SBit_Range *arange,
- TT_SBit_Strike *astrike,
- FT_ULong *aglyph_offset );
-
- FT_LOCAL( FT_Error )
- tt_load_sbit_metrics( FT_Stream stream,
- TT_SBit_Range range,
- TT_SBit_Metrics metrics );
-
-#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */
-
FT_LOCAL( FT_Error )
tt_face_load_sbit_image( TT_Face face,
FT_ULong strike_index,
diff --git a/src/sfnt/ttsbit0.c b/src/sfnt/ttsbit0.c
deleted file mode 100644
index 38bcf21..0000000
--- a/src/sfnt/ttsbit0.c
+++ /dev/null
@@ -1,1011 +0,0 @@
-/***************************************************************************/
-/* */
-/* ttsbit0.c */
-/* */
-/* TrueType and OpenType embedded bitmap support (body). */
-/* This is a heap-optimized version. */
-/* */
-/* Copyright 2005, 2006, 2007, 2008, 2009 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. */
-/* */
-/***************************************************************************/
-
-
-/* This file is included by ttsbit.c */
-
-
-#include <ft2build.h>
-#include FT_INTERNAL_DEBUG_H
-#include FT_INTERNAL_STREAM_H
-#include FT_TRUETYPE_TAGS_H
-#include "ttsbit.h"
-
-#include "sferrors.h"
-
-
- /*************************************************************************/
- /* */
- /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
- /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
- /* messages during execution. */
- /* */
-#undef FT_COMPONENT
-#define FT_COMPONENT trace_ttsbit
-
-
- FT_LOCAL_DEF( FT_Error )
- tt_face_load_eblc( TT_Face face,
- FT_Stream stream )
- {
- FT_Error error = SFNT_Err_Ok;
- FT_Fixed version;
- FT_ULong num_strikes, table_size;
- FT_Byte* p;
- FT_Byte* p_limit;
- FT_UInt count;
-
-
- face->sbit_num_strikes = 0;
-
- /* this table is optional */
- error = face->goto_table( face, TTAG_EBLC, stream, &table_size );
- if ( error )
- error = face->goto_table( face, TTAG_bloc, stream, &table_size );
- if ( error )
- goto Exit;
-
- if ( table_size < 8 )
- {
- FT_ERROR(( "tt_face_load_sbit_strikes: table too short\n" ));
- error = SFNT_Err_Invalid_File_Format;
- goto Exit;
- }
-
- if ( FT_FRAME_EXTRACT( table_size, face->sbit_table ) )
- goto Exit;
-
- face->sbit_table_size = table_size;
-
- p = face->sbit_table;
- p_limit = p + table_size;
-
- version = FT_NEXT_ULONG( p );
- num_strikes = FT_NEXT_ULONG( p );
-
- if ( version != 0x00020000UL || num_strikes >= 0x10000UL )
- {
- FT_ERROR(( "tt_face_load_sbit_strikes: invalid table version\n" ));
- error = SFNT_Err_Invalid_File_Format;
- goto Fail;
- }
-
- /*
- * Count the number of strikes available in the table. We are a bit
- * paranoid there and don't trust the data.
- */
- count = (FT_UInt)num_strikes;
- if ( 8 + 48UL * count > table_size )
- count = (FT_UInt)( ( p_limit - p ) / 48 );
-
- face->sbit_num_strikes = count;
-
- FT_TRACE3(( "sbit_num_strikes: %u\n", count ));
- Exit:
- return error;
-
- Fail:
- FT_FRAME_RELEASE( face->sbit_table );
- face->sbit_table_size = 0;
- goto Exit;
- }
-
-
- FT_LOCAL_DEF( void )
- tt_face_free_eblc( TT_Face face )
- {
- FT_Stream stream = face->root.stream;
-
-
- FT_FRAME_RELEASE( face->sbit_table );
- face->sbit_table_size = 0;
- face->sbit_num_strikes = 0;
- }
-
-
- FT_LOCAL_DEF( FT_Error )
- tt_face_set_sbit_strike( TT_Face face,
- FT_Size_Request req,
- FT_ULong* astrike_index )
- {
- return FT_Match_Size( (FT_Face)face, req, 0, astrike_index );
- }
-
-
- FT_LOCAL_DEF( FT_Error )
- tt_face_load_strike_metrics( TT_Face face,
- FT_ULong strike_index,
- FT_Size_Metrics* metrics )
- {
- FT_Byte* strike;
-
-
- if ( strike_index >= (FT_ULong)face->sbit_num_strikes )
- return SFNT_Err_Invalid_Argument;
-
- strike = face->sbit_table + 8 + strike_index * 48;
-
- metrics->x_ppem = (FT_UShort)strike[44];
- metrics->y_ppem = (FT_UShort)strike[45];
-
- metrics->ascender = (FT_Char)strike[16] << 6; /* hori.ascender */
- metrics->descender = (FT_Char)strike[17] << 6; /* hori.descender */
- metrics->height = metrics->ascender - metrics->descender;
-
- /* XXX: Is this correct? */
- metrics->max_advance = ( (FT_Char)strike[22] + /* min_origin_SB */
- strike[18] + /* max_width */
- (FT_Char)strike[23] /* min_advance_SB */
- ) << 6;
-
- return SFNT_Err_Ok;
- }
-
-
- typedef struct TT_SBitDecoderRec_
- {
- TT_Face face;
- FT_Stream stream;
- FT_Bitmap* bitmap;
- TT_SBit_Metrics metrics;
- FT_Bool metrics_loaded;
- FT_Bool bitmap_allocated;
- FT_Byte bit_depth;
-
- FT_ULong ebdt_start;
- FT_ULong ebdt_size;
-
- FT_ULong strike_index_array;
- FT_ULong strike_index_count;
- FT_Byte* eblc_base;
- FT_Byte* eblc_limit;
-
- } TT_SBitDecoderRec, *TT_SBitDecoder;
-
-
- static FT_Error
- tt_sbit_decoder_init( TT_SBitDecoder decoder,
- TT_Face face,
- FT_ULong strike_index,
- TT_SBit_MetricsRec* metrics )
- {
- FT_Error error;
- FT_Stream stream = face->root.stream;
- FT_ULong ebdt_size;
-
-
- error = face->goto_table( face, TTAG_EBDT, stream, &ebdt_size );
- if ( error )
- error = face->goto_table( face, TTAG_bdat, stream, &ebdt_size );
- if ( error )
- goto Exit;
-
- decoder->face = face;
- decoder->stream = stream;
- decoder->bitmap = &face->root.glyph->bitmap;
- decoder->metrics = metrics;
-
- decoder->metrics_loaded = 0;
- decoder->bitmap_allocated = 0;
-
- decoder->ebdt_start = FT_STREAM_POS();
- decoder->ebdt_size = ebdt_size;
-
- decoder->eblc_base = face->sbit_table;
- decoder->eblc_limit = face->sbit_table + face->sbit_table_size;
-
- /* now find the strike corresponding to the index */
- {
- FT_Byte* p;
-
-
- if ( 8 + 48 * strike_index + 3 * 4 + 34 + 1 > face->sbit_table_size )
- {
- error = SFNT_Err_Invalid_File_Format;
- goto Exit;
- }
-
- p = decoder->eblc_base + 8 + 48 * strike_index;
-
- decoder->strike_index_array = FT_NEXT_ULONG( p );
- p += 4;
- decoder->strike_index_count = FT_NEXT_ULONG( p );
- p += 34;
- decoder->bit_depth = *p;
-
- if ( decoder->strike_index_array > face->sbit_table_size ||
- decoder->strike_index_array + 8 * decoder->strike_index_count >
- face->sbit_table_size )
- error = SFNT_Err_Invalid_File_Format;
- }
-
- Exit:
- return error;
- }
-
-
- static void
- tt_sbit_decoder_done( TT_SBitDecoder decoder )
- {
- FT_UNUSED( decoder );
- }
-
-
- static FT_Error
- tt_sbit_decoder_alloc_bitmap( TT_SBitDecoder decoder )
- {
- FT_Error error = SFNT_Err_Ok;
- FT_UInt width, height;
- FT_Bitmap* map = decoder->bitmap;
- FT_Long size;
-
-
- if ( !decoder->metrics_loaded )
- {
- error = SFNT_Err_Invalid_Argument;
- goto Exit;
- }
-
- width = decoder->metrics->width;
- height = decoder->metrics->height;
-
- map->width = (int)width;
- map->rows = (int)height;
-
- switch ( decoder->bit_depth )
- {
- case 1:
- map->pixel_mode = FT_PIXEL_MODE_MONO;
- map->pitch = ( map->width + 7 ) >> 3;
- break;
-
- case 2:
- map->pixel_mode = FT_PIXEL_MODE_GRAY2;
- map->pitch = ( map->width + 3 ) >> 2;
- break;
-
- case 4:
- map->pixel_mode = FT_PIXEL_MODE_GRAY4;
- map->pitch = ( map->width + 1 ) >> 1;
- break;
-
- case 8:
- map->pixel_mode = FT_PIXEL_MODE_GRAY;
- map->pitch = map->width;
- break;
-
- default:
- error = SFNT_Err_Invalid_File_Format;
- goto Exit;
- }
-
- size = map->rows * map->pitch;
-
- /* check that there is no empty image */
- if ( size == 0 )
- goto Exit; /* exit successfully! */
-
- error = ft_glyphslot_alloc_bitmap( decoder->face->root.glyph, size );
- if ( error )
- goto Exit;
-
- decoder->bitmap_allocated = 1;
-
- Exit:
- return error;
- }
-
-
- static FT_Error
- tt_sbit_decoder_load_metrics( TT_SBitDecoder decoder,
- FT_Byte* *pp,
- FT_Byte* limit,
- FT_Bool big )
- {
- FT_Byte* p = *pp;
- TT_SBit_Metrics metrics = decoder->metrics;
-
-
- if ( p + 5 > limit )
- goto Fail;
-
- metrics->height = p[0];
- metrics->width = p[1];
- metrics->horiBearingX = (FT_Char)p[2];
- metrics->horiBearingY = (FT_Char)p[3];
- metrics->horiAdvance = p[4];
-
- p += 5;
- if ( big )
- {
- if ( p + 3 > limit )
- goto Fail;
-
- metrics->vertBearingX = (FT_Char)p[0];
- metrics->vertBearingY = (FT_Char)p[1];
- metrics->vertAdvance = p[2];
-
- p += 3;
- }
-
- decoder->metrics_loaded = 1;
- *pp = p;
- return SFNT_Err_Ok;
-
- Fail:
- return SFNT_Err_Invalid_Argument;
- }
-
-
- /* forward declaration */
- static FT_Error
- tt_sbit_decoder_load_image( TT_SBitDecoder decoder,
- FT_UInt glyph_index,
- FT_Int x_pos,
- FT_Int y_pos );
-
- typedef FT_Error (*TT_SBitDecoder_LoadFunc)( TT_SBitDecoder decoder,
- FT_Byte* p,
- FT_Byte* plimit,
- FT_Int x_pos,
- FT_Int y_pos );
-
-
- static FT_Error
- tt_sbit_decoder_load_byte_aligned( TT_SBitDecoder decoder,
- FT_Byte* p,
- FT_Byte* limit,
- FT_Int x_pos,
- FT_Int y_pos )
- {
- FT_Error error = SFNT_Err_Ok;
- FT_Byte* line;
- FT_Int bit_height, bit_width, pitch, width, height, h;
- FT_Bitmap* bitmap;
-
-
- if ( !decoder->bitmap_allocated )
- {
- error = tt_sbit_decoder_alloc_bitmap( decoder );
- if ( error )
- goto Exit;
- }
-
- /* check that we can write the glyph into the bitmap */
- bitmap = decoder->bitmap;
- bit_width = bitmap->width;
- bit_height = bitmap->rows;
- pitch = bitmap->pitch;
- line = bitmap->buffer;
-
- width = decoder->metrics->width;
- height = decoder->metrics->height;
-
- if ( x_pos < 0 || x_pos + width > bit_width ||
- y_pos < 0 || y_pos + height > bit_height )
- {
- error = SFNT_Err_Invalid_File_Format;
- goto Exit;
- }
-
- if ( p + ( ( width + 7 ) >> 3 ) * height > limit )
- {
- error = SFNT_Err_Invalid_File_Format;
- goto Exit;
- }
-
- /* now do the blit */
- line += y_pos * pitch + ( x_pos >> 3 );
- x_pos &= 7;
-
- if ( x_pos == 0 ) /* the easy one */
- {
- for ( h = height; h > 0; h--, line += pitch )
- {
- FT_Byte* write = line;
- FT_Int w;
-
-
- for ( w = width; w >= 8; w -= 8 )
- {
- write[0] = (FT_Byte)( write[0] | *p++ );
- write += 1;
- }
-
- if ( w > 0 )
- write[0] = (FT_Byte)( write[0] | ( *p++ & ( 0xFF00U >> w ) ) );
- }
- }
- else /* x_pos > 0 */
- {
- for ( h = height; h > 0; h--, line += pitch )
- {
- FT_Byte* write = line;
- FT_Int w;
- FT_UInt wval = 0;
-
-
- for ( w = width; w >= 8; w -= 8 )
- {
- wval = (FT_UInt)( wval | *p++ );
- write[0] = (FT_Byte)( write[0] | ( wval >> x_pos ) );
- write += 1;
- wval <<= 8;
- }
-
- if ( w > 0 )
- wval = (FT_UInt)( wval | ( *p++ & ( 0xFF00U >> w ) ) );
-
- /* all bits read and there are `x_pos + w' bits to be written */
-
- write[0] = (FT_Byte)( write[0] | ( wval >> x_pos ) );
-
- if ( x_pos + w > 8 )
- {
- write++;
- wval <<= 8;
- write[0] = (FT_Byte)( write[0] | ( wval >> x_pos ) );
- }
- }
- }
-
- Exit:
- return error;
- }
-
-
- /*
- * Load a bit-aligned bitmap (with pointer `p') into a line-aligned bitmap
- * (with pointer `write'). In the example below, the width is 3 pixel,
- * and `x_pos' is 1 pixel.
- *
- * p p+1
- * | | |
- * | 7 6 5 4 3 2 1 0 | 7 6 5 4 3 2 1 0 |...
- * | | |
- * +-------+ +-------+ +-------+ ...
- * . . .
- * . . .
- * v . .
- * +-------+ . .
- * | | .
- * | 7 6 5 4 3 2 1 0 | .
- * | | .
- * write . .
- * . .
- * v .
- * +-------+ .
- * | |
- * | 7 6 5 4 3 2 1 0 |
- * | |
- * write+1 .
- * .
- * v
- * +-------+
- * | |
- * | 7 6 5 4 3 2 1 0 |
- * | |
- * write+2
- *
- */
-
- static FT_Error
- tt_sbit_decoder_load_bit_aligned( TT_SBitDecoder decoder,
- FT_Byte* p,
- FT_Byte* limit,
- FT_Int x_pos,
- FT_Int y_pos )
- {
- FT_Error error = SFNT_Err_Ok;
- FT_Byte* line;
- FT_Int bit_height, bit_width, pitch, width, height, h, nbits;
- FT_Bitmap* bitmap;
- FT_UShort rval;
-
-
- if ( !decoder->bitmap_allocated )
- {
- error = tt_sbit_decoder_alloc_bitmap( decoder );
- if ( error )
- goto Exit;
- }
-
- /* check that we can write the glyph into the bitmap */
- bitmap = decoder->bitmap;
- bit_width = bitmap->width;
- bit_height = bitmap->rows;
- pitch = bitmap->pitch;
- line = bitmap->buffer;
-
- width = decoder->metrics->width;
- height = decoder->metrics->height;
-
- if ( x_pos < 0 || x_pos + width > bit_width ||
- y_pos < 0 || y_pos + height > bit_height )
- {
- error = SFNT_Err_Invalid_File_Format;
- goto Exit;
- }
-
- if ( p + ( ( width * height + 7 ) >> 3 ) > limit )
- {
- error = SFNT_Err_Invalid_File_Format;
- goto Exit;
- }
-
- /* now do the blit */
-
- /* adjust `line' to point to the first byte of the bitmap */
- line += y_pos * pitch + ( x_pos >> 3 );
- x_pos &= 7;
-
- /* the higher byte of `rval' is used as a buffer */
- rval = 0;
- nbits = 0;
-
- for ( h = height; h > 0; h--, line += pitch )
- {
- FT_Byte* write = line;
- FT_Int w = width;
-
-
- /* handle initial byte (in target bitmap) specially if necessary */
- if ( x_pos )
- {
- w = ( width < 8 - x_pos ) ? width : 8 - x_pos;
-
- if ( h == height )
- {
- rval = *p++;
- nbits = x_pos;
- }
- else if ( nbits < w )
- {
- if ( p < limit )
- rval |= *p++;
- nbits += 8 - w;
- }
- else
- {
- rval >>= 8;
- nbits -= w;
- }
-
- *write++ |= ( ( rval >> nbits ) & 0xFF ) &
- ( ~( 0xFF << w ) << ( 8 - w - x_pos ) );
- rval <<= 8;
-
- w = width - w;
- }
-
- /* handle medial bytes */
- for ( ; w >= 8; w -= 8 )
- {
- rval |= *p++;
- *write++ |= ( rval >> nbits ) & 0xFF;
-
- rval <<= 8;
- }
-
- /* handle final byte if necessary */
- if ( w > 0 )
- {
- if ( nbits < w )
- {
- if ( p < limit )
- rval |= *p++;
- *write |= ( ( rval >> nbits ) & 0xFF ) & ( 0xFF00U >> w );
- nbits += 8 - w;
-
- rval <<= 8;
- }
- else
- {
- *write |= ( ( rval >> nbits ) & 0xFF ) & ( 0xFF00U >> w );
- nbits -= w;
- }
- }
- }
-
- Exit:
- return error;
- }
-
-
- static FT_Error
- tt_sbit_decoder_load_compound( TT_SBitDecoder decoder,
- FT_Byte* p,
- FT_Byte* limit,
- FT_Int x_pos,
- FT_Int y_pos )
- {
- FT_Error error = SFNT_Err_Ok;
- FT_UInt num_components, nn;
-
- FT_Char horiBearingX = decoder->metrics->horiBearingX;
- FT_Char horiBearingY = decoder->metrics->horiBearingY;
- FT_Byte horiAdvance = decoder->metrics->horiAdvance;
- FT_Char vertBearingX = decoder->metrics->vertBearingX;
- FT_Char vertBearingY = decoder->metrics->vertBearingY;
- FT_Byte vertAdvance = decoder->metrics->vertAdvance;
-
-
- if ( p + 2 > limit )
- goto Fail;
-
- num_components = FT_NEXT_USHORT( p );
- if ( p + 4 * num_components > limit )
- goto Fail;
-
- if ( !decoder->bitmap_allocated )
- {
- error = tt_sbit_decoder_alloc_bitmap( decoder );
- if ( error )
- goto Exit;
- }
-
- for ( nn = 0; nn < num_components; nn++ )
- {
- FT_UInt gindex = FT_NEXT_USHORT( p );
- FT_Byte dx = FT_NEXT_BYTE( p );
- FT_Byte dy = FT_NEXT_BYTE( p );
-
-
- /* NB: a recursive call */
- error = tt_sbit_decoder_load_image( decoder, gindex,
- x_pos + dx, y_pos + dy );
- if ( error )
- break;
- }
-
- decoder->metrics->horiBearingX = horiBearingX;
- decoder->metrics->horiBearingY = horiBearingY;
- decoder->metrics->horiAdvance = horiAdvance;
- decoder->metrics->vertBearingX = vertBearingX;
- decoder->metrics->vertBearingY = vertBearingY;
- decoder->metrics->vertAdvance = vertAdvance;
- decoder->metrics->width = (FT_UInt)decoder->bitmap->width;
- decoder->metrics->height = (FT_UInt)decoder->bitmap->rows;
-
- Exit:
- return error;
-
- Fail:
- error = SFNT_Err_Invalid_File_Format;
- goto Exit;
- }
-
-
- static FT_Error
- tt_sbit_decoder_load_bitmap( TT_SBitDecoder decoder,
- FT_UInt glyph_format,
- FT_ULong glyph_start,
- FT_ULong glyph_size,
- FT_Int x_pos,
- FT_Int y_pos )
- {
- FT_Error error;
- FT_Stream stream = decoder->stream;
- FT_Byte* p;
- FT_Byte* p_limit;
- FT_Byte* data;
-
-
- /* seek into the EBDT table now */
- if ( glyph_start + glyph_size > decoder->ebdt_size )
- {
- error = SFNT_Err_Invalid_Argument;
- goto Exit;
- }
-
- if ( FT_STREAM_SEEK( decoder->ebdt_start + glyph_start ) ||
- FT_FRAME_EXTRACT( glyph_size, data ) )
- goto Exit;
-
- p = data;
- p_limit = p + glyph_size;
-
- /* read the data, depending on the glyph format */
- switch ( glyph_format )
- {
- case 1:
- case 2:
- case 8:
- error = tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 0 );
- break;
-
- case 6:
- case 7:
- case 9:
- error = tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 1 );
- break;
-
- default:
- error = SFNT_Err_Ok;
- }
-
- if ( error )
- goto Fail;
-
- {
- TT_SBitDecoder_LoadFunc loader;
-
-
- switch ( glyph_format )
- {
- case 1:
- case 6:
- loader = tt_sbit_decoder_load_byte_aligned;
- break;
-
- case 2:
- case 5:
- case 7:
- loader = tt_sbit_decoder_load_bit_aligned;
- break;
-
- case 8:
- if ( p + 1 > p_limit )
- goto Fail;
-
- p += 1; /* skip padding */
- /* fall-through */
-
- case 9:
- loader = tt_sbit_decoder_load_compound;
- break;
-
- default:
- goto Fail;
- }
-
- error = loader( decoder, p, p_limit, x_pos, y_pos );
- }
-
- Fail:
- FT_FRAME_RELEASE( data );
-
- Exit:
- return error;
- }
-
-
- static FT_Error
- tt_sbit_decoder_load_image( TT_SBitDecoder decoder,
- FT_UInt glyph_index,
- FT_Int x_pos,
- FT_Int y_pos )
- {
- /*
- * First, we find the correct strike range that applies to this
- * glyph index.
- */
-
- FT_Byte* p = decoder->eblc_base + decoder->strike_index_array;
- FT_Byte* p_limit = decoder->eblc_limit;
- FT_ULong num_ranges = decoder->strike_index_count;
- FT_UInt start, end, index_format, image_format;
- FT_ULong image_start = 0, image_end = 0, image_offset;
-
-
- for ( ; num_ranges > 0; num_ranges-- )
- {
- start = FT_NEXT_USHORT( p );
- end = FT_NEXT_USHORT( p );
-
- if ( glyph_index >= start && glyph_index <= end )
- goto FoundRange;
-
- p += 4; /* ignore index offset */
- }
- goto NoBitmap;
-
- FoundRange:
- image_offset = FT_NEXT_ULONG( p );
-
- /* overflow check */
- if ( decoder->eblc_base + decoder->strike_index_array + image_offset <
- decoder->eblc_base )
- goto Failure;
-
- p = decoder->eblc_base + decoder->strike_index_array + image_offset;
- if ( p + 8 > p_limit )
- goto NoBitmap;
-
- /* now find the glyph's location and extend within the ebdt table */
- index_format = FT_NEXT_USHORT( p );
- image_format = FT_NEXT_USHORT( p );
- image_offset = FT_NEXT_ULONG ( p );
-
- switch ( index_format )
- {
- case 1: /* 4-byte offsets relative to `image_offset' */
- {
- p += 4 * ( glyph_index - start );
- if ( p + 8 > p_limit )
- goto NoBitmap;
-
- image_start = FT_NEXT_ULONG( p );
- image_end = FT_NEXT_ULONG( p );
-
- if ( image_start == image_end ) /* missing glyph */
- goto NoBitmap;
- }
- break;
-
- case 2: /* big metrics, constant image size */
- {
- FT_ULong image_size;
-
-
- if ( p + 12 > p_limit )
- goto NoBitmap;
-
- image_size = FT_NEXT_ULONG( p );
-
- if ( tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 1 ) )
- goto NoBitmap;
-
- image_start = image_size * ( glyph_index - start );
- image_end = image_start + image_size;
- }
- break;
-
- case 3: /* 2-byte offsets relative to 'image_offset' */
- {
- p += 2 * ( glyph_index - start );
- if ( p + 4 > p_limit )
- goto NoBitmap;
-
- image_start = FT_NEXT_USHORT( p );
- image_end = FT_NEXT_USHORT( p );
-
- if ( image_start == image_end ) /* missing glyph */
- goto NoBitmap;
- }
- break;
-
- case 4: /* sparse glyph array with (glyph,offset) pairs */
- {
- FT_ULong mm, num_glyphs;
-
-
- if ( p + 4 > p_limit )
- goto NoBitmap;
-
- num_glyphs = FT_NEXT_ULONG( p );
-
- /* overflow check */
- if ( p + ( num_glyphs + 1 ) * 4 < p )
- goto Failure;
-
- if ( p + ( num_glyphs + 1 ) * 4 > p_limit )
- goto NoBitmap;
-
- for ( mm = 0; mm < num_glyphs; mm++ )
- {
- FT_UInt gindex = FT_NEXT_USHORT( p );
-
-
- if ( gindex == glyph_index )
- {
- image_start = FT_NEXT_USHORT( p );
- p += 2;
- image_end = FT_PEEK_USHORT( p );
- break;
- }
- p += 2;
- }
-
- if ( mm >= num_glyphs )
- goto NoBitmap;
- }
- break;
-
- case 5: /* constant metrics with sparse glyph codes */
- {
- FT_ULong image_size, mm, num_glyphs;
-
-
- if ( p + 16 > p_limit )
- goto NoBitmap;
-
- image_size = FT_NEXT_ULONG( p );
-
- if ( tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 1 ) )
- goto NoBitmap;
-
- num_glyphs = FT_NEXT_ULONG( p );
-
- /* overflow check */
- if ( p + 2 * num_glyphs < p )
- goto Failure;
-
- if ( p + 2 * num_glyphs > p_limit )
- goto NoBitmap;
-
- for ( mm = 0; mm < num_glyphs; mm++ )
- {
- FT_UInt gindex = FT_NEXT_USHORT( p );
-
-
- if ( gindex == glyph_index )
- break;
- }
-
- if ( mm >= num_glyphs )
- goto NoBitmap;
-
- image_start = image_size * mm;
- image_end = image_start + image_size;
- }
- break;
-
- default:
- goto NoBitmap;
- }
-
- if ( image_start > image_end )
- goto NoBitmap;
-
- image_end -= image_start;
- image_start = image_offset + image_start;
-
- return tt_sbit_decoder_load_bitmap( decoder,
- image_format,
- image_start,
- image_end,
- x_pos,
- y_pos );
-
- Failure:
- return SFNT_Err_Invalid_Table;
-
- NoBitmap:
- return SFNT_Err_Invalid_Argument;
- }
-
-
- FT_LOCAL( FT_Error )
- tt_face_load_sbit_image( TT_Face face,
- FT_ULong strike_index,
- FT_UInt glyph_index,
- FT_UInt load_flags,
- FT_Stream stream,
- FT_Bitmap *map,
- TT_SBit_MetricsRec *metrics )
- {
- TT_SBitDecoderRec decoder[1];
- FT_Error error;
-
- FT_UNUSED( load_flags );
- FT_UNUSED( stream );
- FT_UNUSED( map );
-
-
- error = tt_sbit_decoder_init( decoder, face, strike_index, metrics );
- if ( !error )
- {
- error = tt_sbit_decoder_load_image( decoder, glyph_index, 0, 0 );
- tt_sbit_decoder_done( decoder );
- }
-
- return error;
- }
-
-/* EOF */