/src/compiler/android-ndk/jni/freetype/src/base/ftadvanc.c

http://ftk.googlecode.com/ · C · 163 lines · 94 code · 42 blank · 27 comment · 29 complexity · 82a7e778ad150d26505ee3093aed0bcd MD5 · raw file

  1. /***************************************************************************/
  2. /* */
  3. /* ftadvanc.c */
  4. /* */
  5. /* Quick computation of advance widths (body). */
  6. /* */
  7. /* Copyright 2008, 2009 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_ADVANCES_H
  19. #include FT_INTERNAL_OBJECTS_H
  20. static FT_Error
  21. _ft_face_scale_advances( FT_Face face,
  22. FT_Fixed* advances,
  23. FT_UInt count,
  24. FT_Int32 flags )
  25. {
  26. FT_Fixed scale;
  27. FT_UInt nn;
  28. if ( flags & FT_LOAD_NO_SCALE )
  29. return FT_Err_Ok;
  30. if ( face->size == NULL )
  31. return FT_Err_Invalid_Size_Handle;
  32. if ( flags & FT_LOAD_VERTICAL_LAYOUT )
  33. scale = face->size->metrics.y_scale;
  34. else
  35. scale = face->size->metrics.x_scale;
  36. /* this must be the same scaling as to get linear{Hori,Vert}Advance */
  37. /* (see `FT_Load_Glyph' implementation in src/base/ftobjs.c) */
  38. for ( nn = 0; nn < count; nn++ )
  39. advances[nn] = FT_MulDiv( advances[nn], scale, 64 );
  40. return FT_Err_Ok;
  41. }
  42. /* at the moment, we can perform fast advance retrieval only in */
  43. /* the following cases: */
  44. /* */
  45. /* - unscaled load */
  46. /* - unhinted load */
  47. /* - light-hinted load */
  48. #define LOAD_ADVANCE_FAST_CHECK( flags ) \
  49. ( flags & ( FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING ) || \
  50. FT_LOAD_TARGET_MODE( flags ) == FT_RENDER_MODE_LIGHT )
  51. /* documentation is in ftadvanc.h */
  52. FT_EXPORT_DEF( FT_Error )
  53. FT_Get_Advance( FT_Face face,
  54. FT_UInt gindex,
  55. FT_Int32 flags,
  56. FT_Fixed *padvance )
  57. {
  58. FT_Face_GetAdvancesFunc func;
  59. if ( !face )
  60. return FT_Err_Invalid_Face_Handle;
  61. if ( gindex >= (FT_UInt)face->num_glyphs )
  62. return FT_Err_Invalid_Glyph_Index;
  63. func = face->driver->clazz->get_advances;
  64. if ( func && LOAD_ADVANCE_FAST_CHECK( flags ) )
  65. {
  66. FT_Error error;
  67. error = func( face, gindex, 1, flags, padvance );
  68. if ( !error )
  69. return _ft_face_scale_advances( face, padvance, 1, flags );
  70. if ( error != FT_ERROR_BASE( FT_Err_Unimplemented_Feature ) )
  71. return error;
  72. }
  73. return FT_Get_Advances( face, gindex, 1, flags, padvance );
  74. }
  75. /* documentation is in ftadvanc.h */
  76. FT_EXPORT_DEF( FT_Error )
  77. FT_Get_Advances( FT_Face face,
  78. FT_UInt start,
  79. FT_UInt count,
  80. FT_Int32 flags,
  81. FT_Fixed *padvances )
  82. {
  83. FT_Face_GetAdvancesFunc func;
  84. FT_UInt num, end, nn;
  85. FT_Error error = FT_Err_Ok;
  86. if ( !face )
  87. return FT_Err_Invalid_Face_Handle;
  88. num = (FT_UInt)face->num_glyphs;
  89. end = start + count;
  90. if ( start >= num || end < start || end > num )
  91. return FT_Err_Invalid_Glyph_Index;
  92. if ( count == 0 )
  93. return FT_Err_Ok;
  94. func = face->driver->clazz->get_advances;
  95. if ( func && LOAD_ADVANCE_FAST_CHECK( flags ) )
  96. {
  97. error = func( face, start, count, flags, padvances );
  98. if ( !error )
  99. goto Exit;
  100. if ( error != FT_ERROR_BASE( FT_Err_Unimplemented_Feature ) )
  101. return error;
  102. }
  103. error = FT_Err_Ok;
  104. if ( flags & FT_ADVANCE_FLAG_FAST_ONLY )
  105. return FT_Err_Unimplemented_Feature;
  106. flags |= (FT_UInt32)FT_LOAD_ADVANCE_ONLY;
  107. for ( nn = 0; nn < count; nn++ )
  108. {
  109. error = FT_Load_Glyph( face, start + nn, flags );
  110. if ( error )
  111. break;
  112. padvances[nn] = ( flags & FT_LOAD_VERTICAL_LAYOUT )
  113. ? face->glyph->advance.y
  114. : face->glyph->advance.x;
  115. }
  116. if ( error )
  117. return error;
  118. Exit:
  119. return _ft_face_scale_advances( face, padvances, count, flags );
  120. }
  121. /* END */