1
/***************************************************************************/
5
/* TrueType and OpenType embedded BDF properties (body). */
7
/* Copyright 2005, 2006, 2010 by */
8
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
10
/* This file is part of the FreeType project, and may only be used, */
11
/* modified, and distributed under the terms of the FreeType project */
12
/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
13
/* this file you indicate that you have read the license and */
14
/* understand and accept it fully. */
16
/***************************************************************************/
20
#include FT_INTERNAL_DEBUG_H
21
#include FT_INTERNAL_STREAM_H
22
#include FT_TRUETYPE_TAGS_H
28
#ifdef TT_CONFIG_OPTION_BDF
30
/*************************************************************************/
32
/* The macro FT_COMPONENT is used in trace mode. It is an implicit */
33
/* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
34
/* messages during execution. */
37
#define FT_COMPONENT trace_ttbdf
41
tt_face_free_bdf_props( TT_Face face )
43
TT_BDF bdf = &face->bdf;
48
FT_Stream stream = FT_FACE(face)->stream;
51
if ( bdf->table != NULL )
52
FT_FRAME_RELEASE( bdf->table );
54
bdf->table_end = NULL;
56
bdf->strings_size = 0;
62
tt_face_load_bdf_props( TT_Face face,
65
TT_BDF bdf = &face->bdf;
72
error = tt_face_goto_table( face, TTAG_BDF, stream, &length );
75
FT_FRAME_EXTRACT( length, bdf->table ) )
77
error = SFNT_Err_Invalid_Table;
81
bdf->table_end = bdf->table + length;
84
FT_Byte* p = bdf->table;
85
FT_UInt version = FT_NEXT_USHORT( p );
86
FT_UInt num_strikes = FT_NEXT_USHORT( p );
87
FT_ULong strings = FT_NEXT_ULONG ( p );
92
if ( version != 0x0001 ||
94
( strings - 8 ) / 4 < num_strikes ||
95
strings + 1 > length )
100
bdf->num_strikes = num_strikes;
101
bdf->strings = bdf->table + strings;
102
bdf->strings_size = length - strings;
104
count = bdf->num_strikes;
106
strike = p + count * 4;
109
for ( ; count > 0; count-- )
111
FT_UInt num_items = FT_PEEK_USHORT( p + 2 );
114
* We don't need to check the value sets themselves, since this
117
strike += 10 * num_items;
122
if ( strike > bdf->strings )
132
FT_FRAME_RELEASE( bdf->table );
134
error = SFNT_Err_Invalid_Table;
139
FT_LOCAL_DEF( FT_Error )
140
tt_face_find_bdf_prop( TT_Face face,
141
const char* property_name,
142
BDF_PropertyRec *aprop )
144
TT_BDF bdf = &face->bdf;
145
FT_Size size = FT_FACE(face)->size;
146
FT_Error error = SFNT_Err_Ok;
150
FT_Offset property_len;
153
aprop->type = BDF_PROPERTY_TYPE_NONE;
155
if ( bdf->loaded == 0 )
157
error = tt_face_load_bdf_props( face, FT_FACE( face )->stream );
162
count = bdf->num_strikes;
164
strike = p + 4 * count;
166
error = SFNT_Err_Invalid_Argument;
168
if ( size == NULL || property_name == NULL )
171
property_len = ft_strlen( property_name );
172
if ( property_len == 0 )
175
for ( ; count > 0; count-- )
177
FT_UInt _ppem = FT_NEXT_USHORT( p );
178
FT_UInt _count = FT_NEXT_USHORT( p );
180
if ( _ppem == size->metrics.y_ppem )
186
strike += 10 * _count;
192
for ( ; count > 0; count-- )
194
FT_UInt type = FT_PEEK_USHORT( p + 4 );
196
if ( ( type & 0x10 ) != 0 )
198
FT_UInt32 name_offset = FT_PEEK_ULONG( p );
199
FT_UInt32 value = FT_PEEK_ULONG( p + 6 );
201
/* be a bit paranoid for invalid entries here */
202
if ( name_offset < bdf->strings_size &&
203
property_len < bdf->strings_size - name_offset &&
204
ft_strncmp( property_name,
205
(const char*)bdf->strings + name_offset,
206
bdf->strings_size - name_offset ) == 0 )
208
switch ( type & 0x0F )
210
case 0x00: /* string */
211
case 0x01: /* atoms */
212
/* check that the content is really 0-terminated */
213
if ( value < bdf->strings_size &&
214
ft_memchr( bdf->strings + value, 0, bdf->strings_size ) )
216
aprop->type = BDF_PROPERTY_TYPE_ATOM;
217
aprop->u.atom = (const char*)bdf->strings + value;
224
aprop->type = BDF_PROPERTY_TYPE_INTEGER;
225
aprop->u.integer = (FT_Int32)value;
230
aprop->type = BDF_PROPERTY_TYPE_CARDINAL;
231
aprop->u.cardinal = value;
247
#endif /* TT_CONFIG_OPTION_BDF */