summaryrefslogtreecommitdiffstats
path: root/src/base/ftobjs.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/base/ftobjs.c')
-rw-r--r--src/base/ftobjs.c321
1 files changed, 242 insertions, 79 deletions
diff --git a/src/base/ftobjs.c b/src/base/ftobjs.c
index f167b2f..72dea33 100644
--- a/src/base/ftobjs.c
+++ b/src/base/ftobjs.c
@@ -4,7 +4,7 @@
/* */
/* The FreeType private base classes (body). */
/* */
-/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by */
+/* Copyright 1996-2001, 2002, 2003, 2004, 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, */
@@ -26,6 +26,7 @@
#include FT_INTERNAL_STREAM_H
#include FT_INTERNAL_SFNT_H /* for SFNT_Load_Table_Func */
#include FT_TRUETYPE_TABLES_H
+#include FT_TRUETYPE_TAGS_H
#include FT_TRUETYPE_IDS_H
#include FT_OUTLINE_H
@@ -36,13 +37,11 @@
#include FT_SERVICE_KERNING_H
#include FT_SERVICE_TRUETYPE_ENGINE_H
-#ifdef ANDROID_FONT_HACK
-#include <unistd.h>
-#include <fcntl.h>
-#endif
+#include "ftbase.h"
#define GRID_FIT_METRICS
+
FT_BASE_DEF( FT_Pointer )
ft_service_list_lookup( FT_ServiceDesc service_descriptors,
const char* service_id )
@@ -133,13 +132,14 @@
FT_Stream stream;
+ *astream = 0;
+
if ( !library )
return FT_Err_Invalid_Library_Handle;
if ( !args )
return FT_Err_Invalid_Argument;
- *astream = 0;
memory = library->memory;
if ( FT_NEW( stream ) )
@@ -201,6 +201,12 @@
}
+ /*************************************************************************/
+ /* */
+ /* 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_objs
@@ -249,7 +255,7 @@
FT_BASE_DEF( void )
ft_glyphslot_free_bitmap( FT_GlyphSlot slot )
{
- if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP )
+ if ( slot->internal && ( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) )
{
FT_Memory memory = FT_FACE_MEMORY( slot->face );
@@ -547,7 +553,7 @@
FT_Driver driver;
FT_GlyphSlot slot;
FT_Library library;
- FT_Bool autohint = 0;
+ FT_Bool autohint = FALSE;
FT_Module hinter;
@@ -577,38 +583,6 @@
load_flags &= ~FT_LOAD_RENDER;
}
-#ifdef ANDROID_FONT_HACK
- else
- {
- static int hack_mode;
-
- if (hack_mode == 0) {
- do {
- int fd = open("/data/misc/font-hack", O_RDONLY);
- char buff[2];
- int ret;
-
- hack_mode = 1; /*means light node by default */
- if (fd < 0)
- break;
-
- ret = read(fd, buff, 1);
- if (ret == 1)
- hack_mode = 1 + (buff[0] - '0');
-
- close(fd);
- } while (0);
- }
-
- switch (hack_mode)
- {
- case 1:
- load_flags &= 0xfff0ffff;
- load_flags |= FT_LOAD_TARGET_LIGHT;
- break;
- }
- }
-#endif
/*
* Determine whether we need to auto-hint or not.
@@ -623,22 +597,22 @@
*
* - Otherwise, auto-hint for LIGHT hinting mode.
*
- * - Exception: The font requires the unpatented
- * bytecode interpreter to load properly.
+ * - Exception: The font is `tricky' and requires
+ * the native hinter to load properly.
*/
- autohint = 0;
- if ( hinter &&
- ( load_flags & FT_LOAD_NO_HINTING ) == 0 &&
- ( load_flags & FT_LOAD_NO_AUTOHINT ) == 0 &&
- FT_DRIVER_IS_SCALABLE( driver ) &&
- FT_DRIVER_USES_OUTLINES( driver ) &&
- face->internal->transform_matrix.yy > 0 &&
- face->internal->transform_matrix.yx == 0 )
+ if ( hinter &&
+ !( load_flags & FT_LOAD_NO_HINTING ) &&
+ !( load_flags & FT_LOAD_NO_AUTOHINT ) &&
+ FT_DRIVER_IS_SCALABLE( driver ) &&
+ FT_DRIVER_USES_OUTLINES( driver ) &&
+ !FT_IS_TRICKY( face ) &&
+ face->internal->transform_matrix.yy > 0 &&
+ face->internal->transform_matrix.yx == 0 )
{
- if ( ( load_flags & FT_LOAD_FORCE_AUTOHINT ) != 0 ||
- !FT_DRIVER_HAS_HINTER( driver ) )
- autohint = 1;
+ if ( ( load_flags & FT_LOAD_FORCE_AUTOHINT ) ||
+ !FT_DRIVER_HAS_HINTER( driver ) )
+ autohint = TRUE;
else
{
FT_Render_Mode mode = FT_LOAD_TARGET_MODE( load_flags );
@@ -646,7 +620,7 @@
if ( mode == FT_RENDER_MODE_LIGHT ||
face->internal->ignore_unpatented_hinter )
- autohint = 1;
+ autohint = TRUE;
}
}
@@ -729,7 +703,7 @@
/* compute the linear advance in 16.16 pixels */
if ( ( load_flags & FT_LOAD_LINEAR_DESIGN ) == 0 &&
- ( face->face_flags & FT_FACE_FLAG_SCALABLE ) )
+ ( FT_IS_SCALABLE( face ) ) )
{
FT_Size_Metrics* metrics = &face->size->metrics;
@@ -1147,7 +1121,7 @@
/* there's a Mac-specific extended implementation of FT_New_Face() */
/* in src/base/ftmac.c */
-#ifndef FT_MACINTOSH
+#if !defined( FT_MACINTOSH ) || defined( DARWIN_NO_CARBON )
/* documentation is in freetype.h */
@@ -1166,11 +1140,12 @@
args.flags = FT_OPEN_PATHNAME;
args.pathname = (char*)pathname;
+ args.stream = NULL;
return FT_Open_Face( library, &args, face_index, aface );
}
-#endif /* !FT_MACINTOSH */
+#endif /* defined( FT_MACINTOSH ) && !defined( DARWIN_NO_CARBON ) */
/* documentation is in freetype.h */
@@ -1192,12 +1167,13 @@
args.flags = FT_OPEN_MEMORY;
args.memory_base = file_base;
args.memory_size = file_size;
+ args.stream = NULL;
return FT_Open_Face( library, &args, face_index, aface );
}
-#if !defined( FT_MACINTOSH ) && defined( FT_CONFIG_OPTION_MAC_FONTS )
+#ifdef FT_CONFIG_OPTION_MAC_FONTS
/* The behavior here is very similar to that in base/ftmac.c, but it */
/* is designed to work on non-mac systems, so no mac specific calls. */
@@ -1226,9 +1202,9 @@
/* we don't really have access to it. */
- /* Finalizer for a memory stream; gets called by FT_Done_Face().
- It frees the memory it uses. */
- /* from ftmac.c */
+ /* Finalizer for a memory stream; gets called by FT_Done_Face(). */
+ /* It frees the memory it uses. */
+ /* From ftmac.c. */
static void
memory_stream_close( FT_Stream stream )
{
@@ -1244,7 +1220,7 @@
/* Create a new memory stream from a buffer and a size. */
- /* from ftmac.c */
+ /* From ftmac.c. */
static FT_Error
new_memory_stream( FT_Library library,
FT_Byte* base,
@@ -1281,7 +1257,7 @@
/* Create a new FT_Face given a buffer and a driver name. */
/* from ftmac.c */
- static FT_Error
+ FT_LOCAL_DEF( FT_Error )
open_face_from_buffer( FT_Library library,
FT_Byte* base,
FT_ULong size,
@@ -1314,20 +1290,172 @@
args.driver = FT_Get_Module( library, driver_name );
}
+#ifdef FT_MACINTOSH
+ /* At this point, face_index has served its purpose; */
+ /* whoever calls this function has already used it to */
+ /* locate the correct font data. We should not propagate */
+ /* this index to FT_Open_Face() (unless it is negative). */
+
+ if ( face_index > 0 )
+ face_index = 0;
+#endif
+
error = FT_Open_Face( library, &args, face_index, aface );
if ( error == FT_Err_Ok )
(*aface)->face_flags &= ~FT_FACE_FLAG_EXTERNAL_STREAM;
else
+#ifdef FT_MACINTOSH
+ FT_Stream_Free( stream, 0 );
+#else
{
FT_Stream_Close( stream );
FT_FREE( stream );
}
+#endif
return error;
}
+ /* Look up `TYP1' or `CID ' table from sfnt table directory. */
+ /* `offset' and `length' must exclude the binary header in tables. */
+
+ /* Type 1 and CID-keyed font drivers should recognize sfnt-wrapped */
+ /* format too. Here, since we can't expect that the TrueType font */
+ /* driver is loaded unconditially, we must parse the font by */
+ /* ourselves. We are only interested in the name of the table and */
+ /* the offset. */
+
+ static FT_Error
+ ft_lookup_PS_in_sfnt_stream( FT_Stream stream,
+ FT_Long face_index,
+ FT_ULong* offset,
+ FT_ULong* length,
+ FT_Bool* is_sfnt_cid )
+ {
+ FT_Error error;
+ FT_UShort numTables;
+ FT_Long pstable_index;
+ FT_ULong tag;
+ int i;
+
+
+ *offset = 0;
+ *length = 0;
+ *is_sfnt_cid = FALSE;
+
+ /* TODO: support for sfnt-wrapped PS/CID in TTC format */
+
+ /* version check for 'typ1' (should be ignored?) */
+ if ( FT_READ_ULONG( tag ) )
+ return error;
+ if ( tag != TTAG_typ1 )
+ return FT_Err_Unknown_File_Format;
+
+ if ( FT_READ_USHORT( numTables ) )
+ return error;
+ if ( FT_STREAM_SKIP( 2 * 3 ) ) /* skip binary search header */
+ return error;
+
+ pstable_index = -1;
+ *is_sfnt_cid = FALSE;
+
+ for ( i = 0; i < numTables; i++ )
+ {
+ if ( FT_READ_ULONG( tag ) || FT_STREAM_SKIP( 4 ) ||
+ FT_READ_ULONG( *offset ) || FT_READ_ULONG( *length ) )
+ return error;
+
+ if ( tag == TTAG_CID )
+ {
+ pstable_index++;
+ *offset += 22;
+ *length -= 22;
+ *is_sfnt_cid = TRUE;
+ if ( face_index < 0 )
+ return FT_Err_Ok;
+ }
+ else if ( tag == TTAG_TYP1 )
+ {
+ pstable_index++;
+ *offset += 24;
+ *length -= 24;
+ *is_sfnt_cid = FALSE;
+ if ( face_index < 0 )
+ return FT_Err_Ok;
+ }
+ if ( face_index >= 0 && pstable_index == face_index )
+ return FT_Err_Ok;
+ }
+ return FT_Err_Table_Missing;
+ }
+
+
+ FT_LOCAL_DEF( FT_Error )
+ open_face_PS_from_sfnt_stream( FT_Library library,
+ FT_Stream stream,
+ FT_Long face_index,
+ FT_Int num_params,
+ FT_Parameter *params,
+ FT_Face *aface )
+ {
+ FT_Error error;
+ FT_Memory memory = library->memory;
+ FT_ULong offset, length;
+ FT_Long pos;
+ FT_Bool is_sfnt_cid;
+ FT_Byte* sfnt_ps;
+
+ FT_UNUSED( num_params );
+ FT_UNUSED( params );
+
+
+ pos = FT_Stream_Pos( stream );
+
+ error = ft_lookup_PS_in_sfnt_stream( stream,
+ face_index,
+ &offset,
+ &length,
+ &is_sfnt_cid );
+ if ( error )
+ goto Exit;
+
+ if ( FT_Stream_Seek( stream, pos + offset ) )
+ goto Exit;
+
+ if ( FT_ALLOC( sfnt_ps, (FT_Long)length ) )
+ goto Exit;
+
+ error = FT_Stream_Read( stream, (FT_Byte *)sfnt_ps, length );
+ if ( error )
+ goto Exit;
+
+ error = open_face_from_buffer( library,
+ sfnt_ps,
+ length,
+ face_index < 0 ? face_index : 0,
+ is_sfnt_cid ? "cid" : "type1",
+ aface );
+ Exit:
+ {
+ FT_Error error1;
+
+
+ if ( error == FT_Err_Unknown_File_Format )
+ {
+ error1 = FT_Stream_Seek( stream, pos );
+ if ( error1 )
+ return error1;
+ }
+
+ return error;
+ }
+ }
+
+
+#if !defined( FT_MACINTOSH ) || defined( DARWIN_NO_CARBON )
+
/* The resource header says we've got resource_cnt `POST' (type1) */
/* resources in this file. They all need to be coalesced into */
/* one lump which gets passed on to the type1 driver. */
@@ -1482,17 +1610,25 @@
if ( rlen == -1 )
return FT_Err_Cannot_Open_Resource;
+ error = open_face_PS_from_sfnt_stream( library,
+ stream,
+ face_index,
+ 0, NULL,
+ aface );
+ if ( !error )
+ goto Exit;
+
+ /* rewind sfnt stream before open_face_PS_from_sfnt_stream() */
+ if ( FT_Stream_Seek( stream, flag_offset + 4 ) )
+ goto Exit;
+
if ( FT_ALLOC( sfnt_data, (FT_Long)rlen ) )
return error;
error = FT_Stream_Read( stream, (FT_Byte *)sfnt_data, rlen );
if ( error )
goto Exit;
- is_cff = rlen > 4 && sfnt_data[0] == 'O' &&
- sfnt_data[1] == 'T' &&
- sfnt_data[2] == 'T' &&
- sfnt_data[3] == 'O';
-
+ is_cff = rlen > 4 && !ft_memcmp( sfnt_data, "OTTO", 4 );
error = open_face_from_buffer( library,
sfnt_data,
rlen,
@@ -1531,7 +1667,7 @@
error = FT_Raccess_Get_DataOffsets( library, stream,
map_offset, rdara_pos,
- FT_MAKE_TAG( 'P', 'O', 'S', 'T' ),
+ TTAG_POST,
&data_offsets, &count );
if ( !error )
{
@@ -1546,7 +1682,7 @@
error = FT_Raccess_Get_DataOffsets( library, stream,
map_offset, rdara_pos,
- FT_MAKE_TAG( 's', 'f', 'n', 't' ),
+ TTAG_sfnt,
&data_offsets, &count );
if ( !error )
{
@@ -1637,7 +1773,7 @@
FT_Error errors[FT_RACCESS_N_RULES];
FT_Open_Args args2;
- FT_Stream stream2;
+ FT_Stream stream2 = 0;
FT_Raccess_Guess( library, stream,
@@ -1692,7 +1828,7 @@
}
- /* Check for some macintosh formats. */
+ /* Check for some macintosh formats without Carbon framework. */
/* Is this a macbinary file? If so look at the resource fork. */
/* Is this a mac dfont file? */
/* Is this an old style resource fork? (in data) */
@@ -1735,6 +1871,7 @@
face_index, aface, args );
return error;
}
+#endif
#endif /* !FT_MACINTOSH && FT_CONFIG_OPTION_MAC_FONTS */
@@ -1750,7 +1887,7 @@
FT_Error error;
FT_Driver driver;
FT_Memory memory;
- FT_Stream stream;
+ FT_Stream stream = 0;
FT_Face face = 0;
FT_ListNode node = 0;
FT_Bool external_stream;
@@ -1833,6 +1970,28 @@
if ( !error )
goto Success;
+#ifdef FT_CONFIG_OPTION_MAC_FONTS
+ if ( ft_strcmp( cur[0]->clazz->module_name, "truetype" ) == 0 &&
+ FT_ERROR_BASE( error ) == FT_Err_Table_Missing )
+ {
+ /* TrueType but essential tables are missing */
+ if ( FT_Stream_Seek( stream, 0 ) )
+ break;
+
+ error = open_face_PS_from_sfnt_stream( library,
+ stream,
+ face_index,
+ num_params,
+ params,
+ aface );
+ if ( !error )
+ {
+ FT_Stream_Free( stream, external_stream );
+ return error;
+ }
+ }
+#endif
+
if ( FT_ERROR_BASE( error ) != FT_Err_Unknown_File_Format )
goto Fail3;
}
@@ -2308,8 +2467,8 @@
}
else
{
- metrics->x_scale = 1L << 22;
- metrics->y_scale = 1L << 22;
+ metrics->x_scale = 1L << 16;
+ metrics->y_scale = 1L << 16;
metrics->ascender = bsize->y_ppem;
metrics->descender = 0;
metrics->height = bsize->height << 6;
@@ -2420,8 +2579,8 @@
else
{
FT_ZERO( metrics );
- metrics->x_scale = 1L << 22;
- metrics->y_scale = 1L << 22;
+ metrics->x_scale = 1L << 16;
+ metrics->y_scale = 1L << 16;
}
}
@@ -3302,11 +3461,11 @@
if ( size == NULL )
- return FT_Err_Bad_Argument;
+ return FT_Err_Invalid_Argument;
face = size->face;
if ( face == NULL || face->driver == NULL )
- return FT_Err_Bad_Argument;
+ return FT_Err_Invalid_Argument;
/* we don't need anything more complex than that; all size objects */
/* are already listed by the face */
@@ -4054,7 +4213,11 @@
faces = &FT_DRIVER(module)->faces_list;
while ( faces->head )
+ {
FT_Done_Face( FT_FACE( faces->head->data ) );
+ if ( faces->head )
+ FT_ERROR(( "FT_Done_Library: failed to free some faces\n" ));
+ }
}
}