1 /****************************************************************************
5 * TrueType and OpenType embedded BDF properties (body).
7 * Copyright (C) 2005-2020 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.
19 #include <freetype/internal/ftdebug.h>
20 #include <freetype/internal/ftstream.h>
21 #include <freetype/tttags.h>
27 #ifdef TT_CONFIG_OPTION_BDF
29 /**************************************************************************
31 * The macro FT_COMPONENT is used in trace mode. It is an implicit
32 * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
33 * messages during execution.
36 #define FT_COMPONENT ttbdf
40 tt_face_free_bdf_props( TT_Face face )
42 TT_BDF bdf = &face->bdf;
47 FT_Stream stream = FT_FACE( face )->stream;
51 FT_FRAME_RELEASE( bdf->table );
53 bdf->table_end = NULL;
55 bdf->strings_size = 0;
61 tt_face_load_bdf_props( TT_Face face,
64 TT_BDF bdf = &face->bdf;
71 error = tt_face_goto_table( face, TTAG_BDF, stream, &length );
74 FT_FRAME_EXTRACT( length, bdf->table ) )
76 error = FT_THROW( Invalid_Table );
80 bdf->table_end = bdf->table + length;
83 FT_Byte* p = bdf->table;
84 FT_UInt version = FT_NEXT_USHORT( p );
85 FT_UInt num_strikes = FT_NEXT_USHORT( p );
86 FT_ULong strings = FT_NEXT_ULONG ( p );
91 if ( version != 0x0001 ||
93 ( strings - 8 ) / 4 < num_strikes ||
94 strings + 1 > length )
99 bdf->num_strikes = num_strikes;
100 bdf->strings = bdf->table + strings;
101 bdf->strings_size = length - strings;
103 count = bdf->num_strikes;
105 strike = p + count * 4;
108 for ( ; count > 0; count-- )
110 FT_UInt num_items = FT_PEEK_USHORT( p + 2 );
113 * We don't need to check the value sets themselves, since this
116 strike += 10 * num_items;
121 if ( strike > bdf->strings )
131 FT_FRAME_RELEASE( bdf->table );
133 error = FT_THROW( Invalid_Table );
138 FT_LOCAL_DEF( FT_Error )
139 tt_face_find_bdf_prop( TT_Face face,
140 const char* property_name,
141 BDF_PropertyRec *aprop )
143 TT_BDF bdf = &face->bdf;
144 FT_Size size = FT_FACE( face )->size;
145 FT_Error error = FT_Err_Ok;
149 FT_Offset property_len;
152 aprop->type = BDF_PROPERTY_TYPE_NONE;
154 if ( bdf->loaded == 0 )
156 error = tt_face_load_bdf_props( face, FT_FACE( face )->stream );
161 count = bdf->num_strikes;
163 strike = p + 4 * count;
165 error = FT_ERR( Invalid_Argument );
167 if ( !size || !property_name )
170 property_len = ft_strlen( property_name );
171 if ( property_len == 0 )
174 for ( ; count > 0; count-- )
176 FT_UInt _ppem = FT_NEXT_USHORT( p );
177 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 );
197 if ( ( type & 0x10 ) != 0 )
199 FT_UInt32 name_offset = FT_PEEK_ULONG( p );
200 FT_UInt32 value = FT_PEEK_ULONG( p + 6 );
202 /* be a bit paranoid for invalid entries here */
203 if ( name_offset < bdf->strings_size &&
204 property_len < bdf->strings_size - name_offset &&
205 ft_strncmp( property_name,
206 (const char*)bdf->strings + name_offset,
207 bdf->strings_size - name_offset ) == 0 )
209 switch ( type & 0x0F )
211 case 0x00: /* string */
212 case 0x01: /* atoms */
213 /* check that the content is really 0-terminated */
214 if ( value < bdf->strings_size &&
215 ft_memchr( bdf->strings + value, 0, bdf->strings_size ) )
217 aprop->type = BDF_PROPERTY_TYPE_ATOM;
218 aprop->u.atom = (const char*)bdf->strings + value;
225 aprop->type = BDF_PROPERTY_TYPE_INTEGER;
226 aprop->u.integer = (FT_Int32)value;
231 aprop->type = BDF_PROPERTY_TYPE_CARDINAL;
232 aprop->u.cardinal = value;
248 #else /* !TT_CONFIG_OPTION_BDF */
250 /* ANSI C doesn't like empty source files */
251 typedef int _tt_bdf_dummy;
253 #endif /* !TT_CONFIG_OPTION_BDF */