parent
de271ab8f0
commit
7f049f4221
11 changed files with 291 additions and 277 deletions
@ -1,250 +1,250 @@ |
||||
/***************************************************************************/ |
||||
/* */ |
||||
/* ttbdf.c */ |
||||
/* */ |
||||
/* TrueType and OpenType embedded BDF properties (body). */ |
||||
/* */ |
||||
/* Copyright 2005 by */ |
||||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ |
||||
/* */ |
||||
/* This file is part of the FreeType project, and may only be used, */ |
||||
/* modified, and distributed under the terms of the FreeType project */ |
||||
/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ |
||||
/* this file you indicate that you have read the license and */ |
||||
/* understand and accept it fully. */ |
||||
/* */ |
||||
/***************************************************************************/ |
||||
|
||||
|
||||
#include <ft2build.h> |
||||
#include FT_INTERNAL_DEBUG_H |
||||
#include FT_INTERNAL_STREAM_H |
||||
#include FT_TRUETYPE_TAGS_H |
||||
#include "ttbdf.h" |
||||
|
||||
#include "sferrors.h" |
||||
|
||||
|
||||
#ifdef TT_CONFIG_OPTION_BDF |
||||
|
||||
/*************************************************************************/ |
||||
/* */ |
||||
/* 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_ttbdf |
||||
|
||||
|
||||
FT_LOCAL_DEF( void ) |
||||
tt_face_free_bdf_props( TT_Face face ) |
||||
{ |
||||
TT_BDF bdf = &face->bdf; |
||||
|
||||
|
||||
if ( bdf->loaded ) |
||||
{ |
||||
FT_Stream stream = FT_FACE(face)->stream; |
||||
|
||||
|
||||
if ( bdf->table != NULL ) |
||||
FT_FRAME_RELEASE( bdf->table ); |
||||
|
||||
bdf->table_end = NULL; |
||||
bdf->strings = NULL; |
||||
bdf->strings_size = 0; |
||||
} |
||||
} |
||||
|
||||
|
||||
static FT_Error |
||||
tt_face_load_bdf_props( TT_Face face, |
||||
FT_Stream stream ) |
||||
{ |
||||
TT_BDF bdf = &face->bdf; |
||||
FT_ULong length; |
||||
FT_Error error; |
||||
|
||||
|
||||
FT_ZERO( bdf ); |
||||
|
||||
error = tt_face_goto_table( face, TTAG_BDF, stream, &length ); |
||||
if ( error || |
||||
length < 8 || |
||||
FT_FRAME_EXTRACT( length, bdf->table ) ) |
||||
{ |
||||
error = FT_Err_Invalid_Table; |
||||
goto Exit; |
||||
} |
||||
|
||||
bdf->table_end = bdf->table + length; |
||||
|
||||
{ |
||||
FT_Byte* p = bdf->table; |
||||
FT_UInt version = FT_NEXT_USHORT( p ); |
||||
FT_UInt num_strikes = FT_NEXT_USHORT( p ); |
||||
FT_UInt32 strings = FT_NEXT_ULONG ( p ); |
||||
FT_UInt count; |
||||
FT_Byte* strike; |
||||
|
||||
|
||||
if ( version != 0x0001 || |
||||
strings < 8 || |
||||
( strings - 8 ) / 4 < num_strikes || |
||||
strings + 1 > length ) |
||||
{ |
||||
goto BadTable; |
||||
} |
||||
|
||||
bdf->num_strikes = num_strikes; |
||||
bdf->strings = bdf->table + strings; |
||||
bdf->strings_size = length - strings; |
||||
|
||||
count = bdf->num_strikes; |
||||
p = bdf->table + 8; |
||||
strike = p + count * 4; |
||||
|
||||
|
||||
for ( ; count > 0; count-- ) |
||||
{ |
||||
FT_UInt num_items = FT_PEEK_USHORT( p + 2 ); |
||||
|
||||
/*
|
||||
* We don't need to check the value sets themselves, since this |
||||
* is done later. |
||||
*/ |
||||
strike += 10 * num_items; |
||||
|
||||
p += 4; |
||||
} |
||||
|
||||
if ( strike > bdf->strings ) |
||||
goto BadTable; |
||||
} |
||||
|
||||
bdf->loaded = 1; |
||||
|
||||
Exit: |
||||
return error; |
||||
|
||||
BadTable: |
||||
FT_FRAME_RELEASE( bdf->table ); |
||||
FT_ZERO( bdf ); |
||||
error = FT_Err_Invalid_Table; |
||||
goto Exit; |
||||
} |
||||
|
||||
|
||||
FT_LOCAL_DEF( FT_Error ) |
||||
tt_face_find_bdf_prop( TT_Face face, |
||||
const char* property_name, |
||||
BDF_PropertyRec *aprop ) |
||||
{ |
||||
TT_BDF bdf = &face->bdf; |
||||
FT_Size size = FT_FACE(face)->size; |
||||
FT_Error error = 0; |
||||
FT_Byte* p; |
||||
FT_UInt count; |
||||
FT_Byte* strike; |
||||
FT_UInt property_len; |
||||
|
||||
|
||||
aprop->type = BDF_PROPERTY_TYPE_NONE; |
||||
|
||||
if ( bdf->loaded == 0 ) |
||||
{ |
||||
error = tt_face_load_bdf_props( face, FT_FACE( face )->stream ); |
||||
if ( error ) |
||||
goto Exit; |
||||
} |
||||
|
||||
count = bdf->num_strikes; |
||||
p = bdf->table + 8; |
||||
strike = p + 4 * count; |
||||
|
||||
error = FT_Err_Invalid_Argument; |
||||
|
||||
if ( size == NULL || property_name == NULL ) |
||||
goto Exit; |
||||
|
||||
property_len = ft_strlen( property_name ); |
||||
if ( property_len == 0 ) |
||||
goto Exit; |
||||
|
||||
for ( ; count > 0; count-- ) |
||||
{ |
||||
FT_UInt _ppem = FT_NEXT_USHORT( p ); |
||||
FT_UInt _count = FT_NEXT_USHORT( p ); |
||||
|
||||
if ( _ppem == size->metrics.y_ppem ) |
||||
{ |
||||
count = _count; |
||||
goto FoundStrike; |
||||
} |
||||
|
||||
strike += 10 * _count; |
||||
} |
||||
goto Exit; |
||||
|
||||
FoundStrike: |
||||
p = strike; |
||||
for ( ; count > 0; count-- ) |
||||
{ |
||||
FT_UInt type = FT_PEEK_USHORT( p + 4 ); |
||||
|
||||
if ( ( type & 0x10 ) != 0 ) |
||||
{ |
||||
FT_UInt32 name_offset = FT_PEEK_ULONG( p ); |
||||
FT_UInt32 value = FT_PEEK_ULONG( p + 6 ); |
||||
|
||||
/* be a bit paranoid for invalid entries here */ |
||||
if ( name_offset < bdf->strings_size && |
||||
property_len < bdf->strings_size - name_offset && |
||||
ft_strncmp( property_name, |
||||
(const char*)bdf->strings + name_offset, |
||||
bdf->strings_size - name_offset ) == 0 ) |
||||
{ |
||||
switch ( type & 0x0F ) |
||||
{ |
||||
case 0x00: /* string */ |
||||
case 0x01: /* atoms */ |
||||
/* check that the content is really 0-terminated */ |
||||
if ( value < bdf->strings_size && |
||||
ft_memchr( bdf->strings + value, 0, bdf->strings_size ) ) |
||||
{ |
||||
aprop->type = BDF_PROPERTY_TYPE_ATOM; |
||||
aprop->u.atom = (const char*)bdf->strings + value; |
||||
error = 0; |
||||
goto Exit; |
||||
} |
||||
break; |
||||
|
||||
case 0x02: |
||||
aprop->type = BDF_PROPERTY_TYPE_INTEGER; |
||||
aprop->u.integer = (FT_Int32)value; |
||||
error = 0; |
||||
goto Exit; |
||||
|
||||
case 0x03: |
||||
aprop->type = BDF_PROPERTY_TYPE_CARDINAL; |
||||
aprop->u.cardinal = value; |
||||
error = 0; |
||||
goto Exit; |
||||
|
||||
default: |
||||
; |
||||
} |
||||
} |
||||
} |
||||
p += 10; |
||||
} |
||||
|
||||
Exit: |
||||
return error; |
||||
} |
||||
|
||||
#endif /* TT_CONFIG_OPTION_BDF */ |
||||
|
||||
|
||||
/* END */ |
||||
/***************************************************************************/ |
||||
/* */ |
||||
/* ttbdf.c */ |
||||
/* */ |
||||
/* TrueType and OpenType embedded BDF properties (body). */ |
||||
/* */ |
||||
/* Copyright 2005, 2006 by */ |
||||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ |
||||
/* */ |
||||
/* This file is part of the FreeType project, and may only be used, */ |
||||
/* modified, and distributed under the terms of the FreeType project */ |
||||
/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ |
||||
/* this file you indicate that you have read the license and */ |
||||
/* understand and accept it fully. */ |
||||
/* */ |
||||
/***************************************************************************/ |
||||
|
||||
|
||||
#include <ft2build.h> |
||||
#include FT_INTERNAL_DEBUG_H |
||||
#include FT_INTERNAL_STREAM_H |
||||
#include FT_TRUETYPE_TAGS_H |
||||
#include "ttbdf.h" |
||||
|
||||
#include "sferrors.h" |
||||
|
||||
|
||||
#ifdef TT_CONFIG_OPTION_BDF |
||||
|
||||
/*************************************************************************/ |
||||
/* */ |
||||
/* 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_ttbdf |
||||
|
||||
|
||||
FT_LOCAL_DEF( void ) |
||||
tt_face_free_bdf_props( TT_Face face ) |
||||
{ |
||||
TT_BDF bdf = &face->bdf; |
||||
|
||||
|
||||
if ( bdf->loaded ) |
||||
{ |
||||
FT_Stream stream = FT_FACE(face)->stream; |
||||
|
||||
|
||||
if ( bdf->table != NULL ) |
||||
FT_FRAME_RELEASE( bdf->table ); |
||||
|
||||
bdf->table_end = NULL; |
||||
bdf->strings = NULL; |
||||
bdf->strings_size = 0; |
||||
} |
||||
} |
||||
|
||||
|
||||
static FT_Error |
||||
tt_face_load_bdf_props( TT_Face face, |
||||
FT_Stream stream ) |
||||
{ |
||||
TT_BDF bdf = &face->bdf; |
||||
FT_ULong length; |
||||
FT_Error error; |
||||
|
||||
|
||||
FT_ZERO( bdf ); |
||||
|
||||
error = tt_face_goto_table( face, TTAG_BDF, stream, &length ); |
||||
if ( error || |
||||
length < 8 || |
||||
FT_FRAME_EXTRACT( length, bdf->table ) ) |
||||
{ |
||||
error = FT_Err_Invalid_Table; |
||||
goto Exit; |
||||
} |
||||
|
||||
bdf->table_end = bdf->table + length; |
||||
|
||||
{ |
||||
FT_Byte* p = bdf->table; |
||||
FT_UInt version = FT_NEXT_USHORT( p ); |
||||
FT_UInt num_strikes = FT_NEXT_USHORT( p ); |
||||
FT_UInt32 strings = FT_NEXT_ULONG ( p ); |
||||
FT_UInt count; |
||||
FT_Byte* strike; |
||||
|
||||
|
||||
if ( version != 0x0001 || |
||||
strings < 8 || |
||||
( strings - 8 ) / 4 < num_strikes || |
||||
strings + 1 > length ) |
||||
{ |
||||
goto BadTable; |
||||
} |
||||
|
||||
bdf->num_strikes = num_strikes; |
||||
bdf->strings = bdf->table + strings; |
||||
bdf->strings_size = length - strings; |
||||
|
||||
count = bdf->num_strikes; |
||||
p = bdf->table + 8; |
||||
strike = p + count * 4; |
||||
|
||||
|
||||
for ( ; count > 0; count-- ) |
||||
{ |
||||
FT_UInt num_items = FT_PEEK_USHORT( p + 2 ); |
||||
|
||||
/*
|
||||
* We don't need to check the value sets themselves, since this |
||||
* is done later. |
||||
*/ |
||||
strike += 10 * num_items; |
||||
|
||||
p += 4; |
||||
} |
||||
|
||||
if ( strike > bdf->strings ) |
||||
goto BadTable; |
||||
} |
||||
|
||||
bdf->loaded = 1; |
||||
|
||||
Exit: |
||||
return error; |
||||
|
||||
BadTable: |
||||
FT_FRAME_RELEASE( bdf->table ); |
||||
FT_ZERO( bdf ); |
||||
error = FT_Err_Invalid_Table; |
||||
goto Exit; |
||||
} |
||||
|
||||
|
||||
FT_LOCAL_DEF( FT_Error ) |
||||
tt_face_find_bdf_prop( TT_Face face, |
||||
const char* property_name, |
||||
BDF_PropertyRec *aprop ) |
||||
{ |
||||
TT_BDF bdf = &face->bdf; |
||||
FT_Size size = FT_FACE(face)->size; |
||||
FT_Error error = 0; |
||||
FT_Byte* p; |
||||
FT_UInt count; |
||||
FT_Byte* strike; |
||||
FT_UInt property_len; |
||||
|
||||
|
||||
aprop->type = BDF_PROPERTY_TYPE_NONE; |
||||
|
||||
if ( bdf->loaded == 0 ) |
||||
{ |
||||
error = tt_face_load_bdf_props( face, FT_FACE( face )->stream ); |
||||
if ( error ) |
||||
goto Exit; |
||||
} |
||||
|
||||
count = bdf->num_strikes; |
||||
p = bdf->table + 8; |
||||
strike = p + 4 * count; |
||||
|
||||
error = FT_Err_Invalid_Argument; |
||||
|
||||
if ( size == NULL || property_name == NULL ) |
||||
goto Exit; |
||||
|
||||
property_len = ft_strlen( property_name ); |
||||
if ( property_len == 0 ) |
||||
goto Exit; |
||||
|
||||
for ( ; count > 0; count-- ) |
||||
{ |
||||
FT_UInt _ppem = FT_NEXT_USHORT( p ); |
||||
FT_UInt _count = FT_NEXT_USHORT( p ); |
||||
|
||||
if ( _ppem == size->metrics.y_ppem ) |
||||
{ |
||||
count = _count; |
||||
goto FoundStrike; |
||||
} |
||||
|
||||
strike += 10 * _count; |
||||
} |
||||
goto Exit; |
||||
|
||||
FoundStrike: |
||||
p = strike; |
||||
for ( ; count > 0; count-- ) |
||||
{ |
||||
FT_UInt type = FT_PEEK_USHORT( p + 4 ); |
||||
|
||||
if ( ( type & 0x10 ) != 0 ) |
||||
{ |
||||
FT_UInt32 name_offset = FT_PEEK_ULONG( p ); |
||||
FT_UInt32 value = FT_PEEK_ULONG( p + 6 ); |
||||
|
||||
/* be a bit paranoid for invalid entries here */ |
||||
if ( name_offset < bdf->strings_size && |
||||
property_len < bdf->strings_size - name_offset && |
||||
ft_strncmp( property_name, |
||||
(const char*)bdf->strings + name_offset, |
||||
bdf->strings_size - name_offset ) == 0 ) |
||||
{ |
||||
switch ( type & 0x0F ) |
||||
{ |
||||
case 0x00: /* string */ |
||||
case 0x01: /* atoms */ |
||||
/* check that the content is really 0-terminated */ |
||||
if ( value < bdf->strings_size && |
||||
ft_memchr( bdf->strings + value, 0, bdf->strings_size ) ) |
||||
{ |
||||
aprop->type = BDF_PROPERTY_TYPE_ATOM; |
||||
aprop->u.atom = (const char*)bdf->strings + value; |
||||
error = 0; |
||||
goto Exit; |
||||
} |
||||
break; |
||||
|
||||
case 0x02: |
||||
aprop->type = BDF_PROPERTY_TYPE_INTEGER; |
||||
aprop->u.integer = (FT_Int32)value; |
||||
error = 0; |
||||
goto Exit; |
||||
|
||||
case 0x03: |
||||
aprop->type = BDF_PROPERTY_TYPE_CARDINAL; |
||||
aprop->u.cardinal = value; |
||||
error = 0; |
||||
goto Exit; |
||||
|
||||
default: |
||||
; |
||||
} |
||||
} |
||||
} |
||||
p += 10; |
||||
} |
||||
|
||||
Exit: |
||||
return error; |
||||
} |
||||
|
||||
#endif /* TT_CONFIG_OPTION_BDF */ |
||||
|
||||
|
||||
/* END */ |
||||
|
Loading…
Reference in new issue