/src/compiler/android-ndk/jni/freetype/src/sfnt/ttbdf.c

http://ftk.googlecode.com/ · C · 250 lines · 167 code · 54 blank · 29 comment · 27 complexity · a108e29367426406e89a30ad260d5c9e MD5 · raw file

  1. /***************************************************************************/
  2. /* */
  3. /* ttbdf.c */
  4. /* */
  5. /* TrueType and OpenType embedded BDF properties (body). */
  6. /* */
  7. /* Copyright 2005, 2006 by */
  8. /* David Turner, Robert Wilhelm, and Werner Lemberg. */
  9. /* */
  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. */
  15. /* */
  16. /***************************************************************************/
  17. #include <ft2build.h>
  18. #include FT_INTERNAL_DEBUG_H
  19. #include FT_INTERNAL_STREAM_H
  20. #include FT_TRUETYPE_TAGS_H
  21. #include "ttbdf.h"
  22. #include "sferrors.h"
  23. #ifdef TT_CONFIG_OPTION_BDF
  24. /*************************************************************************/
  25. /* */
  26. /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
  27. /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
  28. /* messages during execution. */
  29. /* */
  30. #undef FT_COMPONENT
  31. #define FT_COMPONENT trace_ttbdf
  32. FT_LOCAL_DEF( void )
  33. tt_face_free_bdf_props( TT_Face face )
  34. {
  35. TT_BDF bdf = &face->bdf;
  36. if ( bdf->loaded )
  37. {
  38. FT_Stream stream = FT_FACE(face)->stream;
  39. if ( bdf->table != NULL )
  40. FT_FRAME_RELEASE( bdf->table );
  41. bdf->table_end = NULL;
  42. bdf->strings = NULL;
  43. bdf->strings_size = 0;
  44. }
  45. }
  46. static FT_Error
  47. tt_face_load_bdf_props( TT_Face face,
  48. FT_Stream stream )
  49. {
  50. TT_BDF bdf = &face->bdf;
  51. FT_ULong length;
  52. FT_Error error;
  53. FT_ZERO( bdf );
  54. error = tt_face_goto_table( face, TTAG_BDF, stream, &length );
  55. if ( error ||
  56. length < 8 ||
  57. FT_FRAME_EXTRACT( length, bdf->table ) )
  58. {
  59. error = FT_Err_Invalid_Table;
  60. goto Exit;
  61. }
  62. bdf->table_end = bdf->table + length;
  63. {
  64. FT_Byte* p = bdf->table;
  65. FT_UInt version = FT_NEXT_USHORT( p );
  66. FT_UInt num_strikes = FT_NEXT_USHORT( p );
  67. FT_ULong strings = FT_NEXT_ULONG ( p );
  68. FT_UInt count;
  69. FT_Byte* strike;
  70. if ( version != 0x0001 ||
  71. strings < 8 ||
  72. ( strings - 8 ) / 4 < num_strikes ||
  73. strings + 1 > length )
  74. {
  75. goto BadTable;
  76. }
  77. bdf->num_strikes = num_strikes;
  78. bdf->strings = bdf->table + strings;
  79. bdf->strings_size = length - strings;
  80. count = bdf->num_strikes;
  81. p = bdf->table + 8;
  82. strike = p + count * 4;
  83. for ( ; count > 0; count-- )
  84. {
  85. FT_UInt num_items = FT_PEEK_USHORT( p + 2 );
  86. /*
  87. * We don't need to check the value sets themselves, since this
  88. * is done later.
  89. */
  90. strike += 10 * num_items;
  91. p += 4;
  92. }
  93. if ( strike > bdf->strings )
  94. goto BadTable;
  95. }
  96. bdf->loaded = 1;
  97. Exit:
  98. return error;
  99. BadTable:
  100. FT_FRAME_RELEASE( bdf->table );
  101. FT_ZERO( bdf );
  102. error = FT_Err_Invalid_Table;
  103. goto Exit;
  104. }
  105. FT_LOCAL_DEF( FT_Error )
  106. tt_face_find_bdf_prop( TT_Face face,
  107. const char* property_name,
  108. BDF_PropertyRec *aprop )
  109. {
  110. TT_BDF bdf = &face->bdf;
  111. FT_Size size = FT_FACE(face)->size;
  112. FT_Error error = 0;
  113. FT_Byte* p;
  114. FT_UInt count;
  115. FT_Byte* strike;
  116. FT_Offset property_len;
  117. aprop->type = BDF_PROPERTY_TYPE_NONE;
  118. if ( bdf->loaded == 0 )
  119. {
  120. error = tt_face_load_bdf_props( face, FT_FACE( face )->stream );
  121. if ( error )
  122. goto Exit;
  123. }
  124. count = bdf->num_strikes;
  125. p = bdf->table + 8;
  126. strike = p + 4 * count;
  127. error = FT_Err_Invalid_Argument;
  128. if ( size == NULL || property_name == NULL )
  129. goto Exit;
  130. property_len = ft_strlen( property_name );
  131. if ( property_len == 0 )
  132. goto Exit;
  133. for ( ; count > 0; count-- )
  134. {
  135. FT_UInt _ppem = FT_NEXT_USHORT( p );
  136. FT_UInt _count = FT_NEXT_USHORT( p );
  137. if ( _ppem == size->metrics.y_ppem )
  138. {
  139. count = _count;
  140. goto FoundStrike;
  141. }
  142. strike += 10 * _count;
  143. }
  144. goto Exit;
  145. FoundStrike:
  146. p = strike;
  147. for ( ; count > 0; count-- )
  148. {
  149. FT_UInt type = FT_PEEK_USHORT( p + 4 );
  150. if ( ( type & 0x10 ) != 0 )
  151. {
  152. FT_UInt32 name_offset = FT_PEEK_ULONG( p );
  153. FT_UInt32 value = FT_PEEK_ULONG( p + 6 );
  154. /* be a bit paranoid for invalid entries here */
  155. if ( name_offset < bdf->strings_size &&
  156. property_len < bdf->strings_size - name_offset &&
  157. ft_strncmp( property_name,
  158. (const char*)bdf->strings + name_offset,
  159. bdf->strings_size - name_offset ) == 0 )
  160. {
  161. switch ( type & 0x0F )
  162. {
  163. case 0x00: /* string */
  164. case 0x01: /* atoms */
  165. /* check that the content is really 0-terminated */
  166. if ( value < bdf->strings_size &&
  167. ft_memchr( bdf->strings + value, 0, bdf->strings_size ) )
  168. {
  169. aprop->type = BDF_PROPERTY_TYPE_ATOM;
  170. aprop->u.atom = (const char*)bdf->strings + value;
  171. error = 0;
  172. goto Exit;
  173. }
  174. break;
  175. case 0x02:
  176. aprop->type = BDF_PROPERTY_TYPE_INTEGER;
  177. aprop->u.integer = (FT_Int32)value;
  178. error = 0;
  179. goto Exit;
  180. case 0x03:
  181. aprop->type = BDF_PROPERTY_TYPE_CARDINAL;
  182. aprop->u.cardinal = value;
  183. error = 0;
  184. goto Exit;
  185. default:
  186. ;
  187. }
  188. }
  189. }
  190. p += 10;
  191. }
  192. Exit:
  193. return error;
  194. }
  195. #endif /* TT_CONFIG_OPTION_BDF */
  196. /* END */