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

http://ftk.googlecode.com/ · C · 351 lines · 240 code · 86 blank · 25 comment · 25 complexity · 57e2736c0dd1af97073bfda34ebc40a7 MD5 · raw file

  1. /***************************************************************************/
  2. /* */
  3. /* ftlcdfil.c */
  4. /* */
  5. /* FreeType API for color filtering of subpixel bitmap glyphs (body). */
  6. /* */
  7. /* Copyright 2006, 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_LCD_FILTER_H
  19. #include FT_IMAGE_H
  20. #include FT_INTERNAL_OBJECTS_H
  21. #ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
  22. /* define USE_LEGACY to implement the legacy filter */
  23. #define USE_LEGACY
  24. /* FIR filter used by the default and light filters */
  25. static void
  26. _ft_lcd_filter_fir( FT_Bitmap* bitmap,
  27. FT_Render_Mode mode,
  28. FT_Library library )
  29. {
  30. FT_Byte* weights = library->lcd_weights;
  31. FT_UInt width = (FT_UInt)bitmap->width;
  32. FT_UInt height = (FT_UInt)bitmap->rows;
  33. /* horizontal in-place FIR filter */
  34. if ( mode == FT_RENDER_MODE_LCD && width >= 4 )
  35. {
  36. FT_Byte* line = bitmap->buffer;
  37. for ( ; height > 0; height--, line += bitmap->pitch )
  38. {
  39. FT_UInt fir[5];
  40. FT_UInt val1, xx;
  41. val1 = line[0];
  42. fir[0] = weights[2] * val1;
  43. fir[1] = weights[3] * val1;
  44. fir[2] = weights[4] * val1;
  45. fir[3] = 0;
  46. fir[4] = 0;
  47. val1 = line[1];
  48. fir[0] += weights[1] * val1;
  49. fir[1] += weights[2] * val1;
  50. fir[2] += weights[3] * val1;
  51. fir[3] += weights[4] * val1;
  52. for ( xx = 2; xx < width; xx++ )
  53. {
  54. FT_UInt val, pix;
  55. val = line[xx];
  56. pix = fir[0] + weights[0] * val;
  57. fir[0] = fir[1] + weights[1] * val;
  58. fir[1] = fir[2] + weights[2] * val;
  59. fir[2] = fir[3] + weights[3] * val;
  60. fir[3] = weights[4] * val;
  61. pix >>= 8;
  62. pix |= -( pix >> 8 );
  63. line[xx - 2] = (FT_Byte)pix;
  64. }
  65. {
  66. FT_UInt pix;
  67. pix = fir[0] >> 8;
  68. pix |= -( pix >> 8 );
  69. line[xx - 2] = (FT_Byte)pix;
  70. pix = fir[1] >> 8;
  71. pix |= -( pix >> 8 );
  72. line[xx - 1] = (FT_Byte)pix;
  73. }
  74. }
  75. }
  76. /* vertical in-place FIR filter */
  77. else if ( mode == FT_RENDER_MODE_LCD_V && height >= 4 )
  78. {
  79. FT_Byte* column = bitmap->buffer;
  80. FT_Int pitch = bitmap->pitch;
  81. for ( ; width > 0; width--, column++ )
  82. {
  83. FT_Byte* col = column;
  84. FT_UInt fir[5];
  85. FT_UInt val1, yy;
  86. val1 = col[0];
  87. fir[0] = weights[2] * val1;
  88. fir[1] = weights[3] * val1;
  89. fir[2] = weights[4] * val1;
  90. fir[3] = 0;
  91. fir[4] = 0;
  92. col += pitch;
  93. val1 = col[0];
  94. fir[0] += weights[1] * val1;
  95. fir[1] += weights[2] * val1;
  96. fir[2] += weights[3] * val1;
  97. fir[3] += weights[4] * val1;
  98. col += pitch;
  99. for ( yy = 2; yy < height; yy++ )
  100. {
  101. FT_UInt val, pix;
  102. val = col[0];
  103. pix = fir[0] + weights[0] * val;
  104. fir[0] = fir[1] + weights[1] * val;
  105. fir[1] = fir[2] + weights[2] * val;
  106. fir[2] = fir[3] + weights[3] * val;
  107. fir[3] = weights[4] * val;
  108. pix >>= 8;
  109. pix |= -( pix >> 8 );
  110. col[-2 * pitch] = (FT_Byte)pix;
  111. col += pitch;
  112. }
  113. {
  114. FT_UInt pix;
  115. pix = fir[0] >> 8;
  116. pix |= -( pix >> 8 );
  117. col[-2 * pitch] = (FT_Byte)pix;
  118. pix = fir[1] >> 8;
  119. pix |= -( pix >> 8 );
  120. col[-pitch] = (FT_Byte)pix;
  121. }
  122. }
  123. }
  124. }
  125. #ifdef USE_LEGACY
  126. /* intra-pixel filter used by the legacy filter */
  127. static void
  128. _ft_lcd_filter_legacy( FT_Bitmap* bitmap,
  129. FT_Render_Mode mode,
  130. FT_Library library )
  131. {
  132. FT_UInt width = (FT_UInt)bitmap->width;
  133. FT_UInt height = (FT_UInt)bitmap->rows;
  134. FT_Int pitch = bitmap->pitch;
  135. static const int filters[3][3] =
  136. {
  137. { 65538 * 9/13, 65538 * 1/6, 65538 * 1/13 },
  138. { 65538 * 3/13, 65538 * 4/6, 65538 * 3/13 },
  139. { 65538 * 1/13, 65538 * 1/6, 65538 * 9/13 }
  140. };
  141. FT_UNUSED( library );
  142. /* horizontal in-place intra-pixel filter */
  143. if ( mode == FT_RENDER_MODE_LCD && width >= 3 )
  144. {
  145. FT_Byte* line = bitmap->buffer;
  146. for ( ; height > 0; height--, line += pitch )
  147. {
  148. FT_UInt xx;
  149. for ( xx = 0; xx < width; xx += 3 )
  150. {
  151. FT_UInt r = 0;
  152. FT_UInt g = 0;
  153. FT_UInt b = 0;
  154. FT_UInt p;
  155. p = line[xx];
  156. r += filters[0][0] * p;
  157. g += filters[0][1] * p;
  158. b += filters[0][2] * p;
  159. p = line[xx + 1];
  160. r += filters[1][0] * p;
  161. g += filters[1][1] * p;
  162. b += filters[1][2] * p;
  163. p = line[xx + 2];
  164. r += filters[2][0] * p;
  165. g += filters[2][1] * p;
  166. b += filters[2][2] * p;
  167. line[xx] = (FT_Byte)( r / 65536 );
  168. line[xx + 1] = (FT_Byte)( g / 65536 );
  169. line[xx + 2] = (FT_Byte)( b / 65536 );
  170. }
  171. }
  172. }
  173. else if ( mode == FT_RENDER_MODE_LCD_V && height >= 3 )
  174. {
  175. FT_Byte* column = bitmap->buffer;
  176. for ( ; width > 0; width--, column++ )
  177. {
  178. FT_Byte* col = column;
  179. FT_Byte* col_end = col + height * pitch;
  180. for ( ; col < col_end; col += 3 * pitch )
  181. {
  182. FT_UInt r = 0;
  183. FT_UInt g = 0;
  184. FT_UInt b = 0;
  185. FT_UInt p;
  186. p = col[0];
  187. r += filters[0][0] * p;
  188. g += filters[0][1] * p;
  189. b += filters[0][2] * p;
  190. p = col[pitch];
  191. r += filters[1][0] * p;
  192. g += filters[1][1] * p;
  193. b += filters[1][2] * p;
  194. p = col[pitch * 2];
  195. r += filters[2][0] * p;
  196. g += filters[2][1] * p;
  197. b += filters[2][2] * p;
  198. col[0] = (FT_Byte)( r / 65536 );
  199. col[pitch] = (FT_Byte)( g / 65536 );
  200. col[2 * pitch] = (FT_Byte)( b / 65536 );
  201. }
  202. }
  203. }
  204. }
  205. #endif /* USE_LEGACY */
  206. FT_EXPORT_DEF( FT_Error )
  207. FT_Library_SetLcdFilter( FT_Library library,
  208. FT_LcdFilter filter )
  209. {
  210. static const FT_Byte light_filter[5] =
  211. { 0, 85, 86, 85, 0 };
  212. /* the values here sum up to a value larger than 256, */
  213. /* providing a cheap gamma correction */
  214. static const FT_Byte default_filter[5] =
  215. { 0x10, 0x40, 0x70, 0x40, 0x10 };
  216. if ( library == NULL )
  217. return FT_Err_Invalid_Argument;
  218. switch ( filter )
  219. {
  220. case FT_LCD_FILTER_NONE:
  221. library->lcd_filter_func = NULL;
  222. library->lcd_extra = 0;
  223. break;
  224. case FT_LCD_FILTER_DEFAULT:
  225. #if defined( FT_FORCE_LEGACY_LCD_FILTER )
  226. library->lcd_filter_func = _ft_lcd_filter_legacy;
  227. library->lcd_extra = 0;
  228. #elif defined( FT_FORCE_LIGHT_LCD_FILTER )
  229. ft_memcpy( library->lcd_weights, light_filter, 5 );
  230. library->lcd_filter_func = _ft_lcd_filter_fir;
  231. library->lcd_extra = 2;
  232. #else
  233. ft_memcpy( library->lcd_weights, default_filter, 5 );
  234. library->lcd_filter_func = _ft_lcd_filter_fir;
  235. library->lcd_extra = 2;
  236. #endif
  237. break;
  238. case FT_LCD_FILTER_LIGHT:
  239. ft_memcpy( library->lcd_weights, light_filter, 5 );
  240. library->lcd_filter_func = _ft_lcd_filter_fir;
  241. library->lcd_extra = 2;
  242. break;
  243. #ifdef USE_LEGACY
  244. case FT_LCD_FILTER_LEGACY:
  245. library->lcd_filter_func = _ft_lcd_filter_legacy;
  246. library->lcd_extra = 0;
  247. break;
  248. #endif
  249. default:
  250. return FT_Err_Invalid_Argument;
  251. }
  252. library->lcd_filter = filter;
  253. return 0;
  254. }
  255. #else /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */
  256. FT_EXPORT_DEF( FT_Error )
  257. FT_Library_SetLcdFilter( FT_Library library,
  258. FT_LcdFilter filter )
  259. {
  260. FT_UNUSED( library );
  261. FT_UNUSED( filter );
  262. return FT_Err_Unimplemented_Feature;
  263. }
  264. #endif /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */
  265. /* END */