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

http://ftk.googlecode.com/ · C · 663 lines · 462 code · 158 blank · 43 comment · 82 complexity · 468562d0a3d1e0b562f0ecd7bddad70d MD5 · raw file

  1. /***************************************************************************/
  2. /* */
  3. /* ftbitmap.c */
  4. /* */
  5. /* FreeType utility functions for bitmaps (body). */
  6. /* */
  7. /* Copyright 2004, 2005, 2006, 2007, 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_BITMAP_H
  19. #include FT_IMAGE_H
  20. #include FT_INTERNAL_OBJECTS_H
  21. static
  22. const FT_Bitmap null_bitmap = { 0, 0, 0, 0, 0, 0, 0, 0 };
  23. /* documentation is in ftbitmap.h */
  24. FT_EXPORT_DEF( void )
  25. FT_Bitmap_New( FT_Bitmap *abitmap )
  26. {
  27. *abitmap = null_bitmap;
  28. }
  29. /* documentation is in ftbitmap.h */
  30. FT_EXPORT_DEF( FT_Error )
  31. FT_Bitmap_Copy( FT_Library library,
  32. const FT_Bitmap *source,
  33. FT_Bitmap *target)
  34. {
  35. FT_Memory memory = library->memory;
  36. FT_Error error = FT_Err_Ok;
  37. FT_Int pitch = source->pitch;
  38. FT_ULong size;
  39. if ( source == target )
  40. return FT_Err_Ok;
  41. if ( source->buffer == NULL )
  42. {
  43. *target = *source;
  44. return FT_Err_Ok;
  45. }
  46. if ( pitch < 0 )
  47. pitch = -pitch;
  48. size = (FT_ULong)( pitch * source->rows );
  49. if ( target->buffer )
  50. {
  51. FT_Int target_pitch = target->pitch;
  52. FT_ULong target_size;
  53. if ( target_pitch < 0 )
  54. target_pitch = -target_pitch;
  55. target_size = (FT_ULong)( target_pitch * target->rows );
  56. if ( target_size != size )
  57. (void)FT_QREALLOC( target->buffer, target_size, size );
  58. }
  59. else
  60. (void)FT_QALLOC( target->buffer, size );
  61. if ( !error )
  62. {
  63. unsigned char *p;
  64. p = target->buffer;
  65. *target = *source;
  66. target->buffer = p;
  67. FT_MEM_COPY( target->buffer, source->buffer, size );
  68. }
  69. return error;
  70. }
  71. static FT_Error
  72. ft_bitmap_assure_buffer( FT_Memory memory,
  73. FT_Bitmap* bitmap,
  74. FT_UInt xpixels,
  75. FT_UInt ypixels )
  76. {
  77. FT_Error error;
  78. int pitch;
  79. int new_pitch;
  80. FT_UInt bpp;
  81. FT_Int i, width, height;
  82. unsigned char* buffer;
  83. width = bitmap->width;
  84. height = bitmap->rows;
  85. pitch = bitmap->pitch;
  86. if ( pitch < 0 )
  87. pitch = -pitch;
  88. switch ( bitmap->pixel_mode )
  89. {
  90. case FT_PIXEL_MODE_MONO:
  91. bpp = 1;
  92. new_pitch = ( width + xpixels + 7 ) >> 3;
  93. break;
  94. case FT_PIXEL_MODE_GRAY2:
  95. bpp = 2;
  96. new_pitch = ( width + xpixels + 3 ) >> 2;
  97. break;
  98. case FT_PIXEL_MODE_GRAY4:
  99. bpp = 4;
  100. new_pitch = ( width + xpixels + 1 ) >> 1;
  101. break;
  102. case FT_PIXEL_MODE_GRAY:
  103. case FT_PIXEL_MODE_LCD:
  104. case FT_PIXEL_MODE_LCD_V:
  105. bpp = 8;
  106. new_pitch = ( width + xpixels );
  107. break;
  108. default:
  109. return FT_Err_Invalid_Glyph_Format;
  110. }
  111. /* if no need to allocate memory */
  112. if ( ypixels == 0 && new_pitch <= pitch )
  113. {
  114. /* zero the padding */
  115. FT_Int bit_width = pitch * 8;
  116. FT_Int bit_last = ( width + xpixels ) * bpp;
  117. if ( bit_last < bit_width )
  118. {
  119. FT_Byte* line = bitmap->buffer + ( bit_last >> 3 );
  120. FT_Byte* end = bitmap->buffer + pitch;
  121. FT_Int shift = bit_last & 7;
  122. FT_UInt mask = 0xFF00U >> shift;
  123. FT_Int count = height;
  124. for ( ; count > 0; count--, line += pitch, end += pitch )
  125. {
  126. FT_Byte* write = line;
  127. if ( shift > 0 )
  128. {
  129. write[0] = (FT_Byte)( write[0] & mask );
  130. write++;
  131. }
  132. if ( write < end )
  133. FT_MEM_ZERO( write, end-write );
  134. }
  135. }
  136. return FT_Err_Ok;
  137. }
  138. if ( FT_QALLOC_MULT( buffer, new_pitch, bitmap->rows + ypixels ) )
  139. return error;
  140. if ( bitmap->pitch > 0 )
  141. {
  142. FT_Int len = ( width * bpp + 7 ) >> 3;
  143. for ( i = 0; i < bitmap->rows; i++ )
  144. FT_MEM_COPY( buffer + new_pitch * ( ypixels + i ),
  145. bitmap->buffer + pitch * i, len );
  146. }
  147. else
  148. {
  149. FT_Int len = ( width * bpp + 7 ) >> 3;
  150. for ( i = 0; i < bitmap->rows; i++ )
  151. FT_MEM_COPY( buffer + new_pitch * i,
  152. bitmap->buffer + pitch * i, len );
  153. }
  154. FT_FREE( bitmap->buffer );
  155. bitmap->buffer = buffer;
  156. if ( bitmap->pitch < 0 )
  157. new_pitch = -new_pitch;
  158. /* set pitch only, width and height are left untouched */
  159. bitmap->pitch = new_pitch;
  160. return FT_Err_Ok;
  161. }
  162. /* documentation is in ftbitmap.h */
  163. FT_EXPORT_DEF( FT_Error )
  164. FT_Bitmap_Embolden( FT_Library library,
  165. FT_Bitmap* bitmap,
  166. FT_Pos xStrength,
  167. FT_Pos yStrength )
  168. {
  169. FT_Error error;
  170. unsigned char* p;
  171. FT_Int i, x, y, pitch;
  172. FT_Int xstr, ystr;
  173. if ( !library )
  174. return FT_Err_Invalid_Library_Handle;
  175. if ( !bitmap || !bitmap->buffer )
  176. return FT_Err_Invalid_Argument;
  177. if ( ( ( FT_PIX_ROUND( xStrength ) >> 6 ) > FT_INT_MAX ) ||
  178. ( ( FT_PIX_ROUND( yStrength ) >> 6 ) > FT_INT_MAX ) )
  179. return FT_Err_Invalid_Argument;
  180. xstr = (FT_Int)FT_PIX_ROUND( xStrength ) >> 6;
  181. ystr = (FT_Int)FT_PIX_ROUND( yStrength ) >> 6;
  182. if ( xstr == 0 && ystr == 0 )
  183. return FT_Err_Ok;
  184. else if ( xstr < 0 || ystr < 0 )
  185. return FT_Err_Invalid_Argument;
  186. switch ( bitmap->pixel_mode )
  187. {
  188. case FT_PIXEL_MODE_GRAY2:
  189. case FT_PIXEL_MODE_GRAY4:
  190. {
  191. FT_Bitmap tmp;
  192. FT_Int align;
  193. if ( bitmap->pixel_mode == FT_PIXEL_MODE_GRAY2 )
  194. align = ( bitmap->width + xstr + 3 ) / 4;
  195. else
  196. align = ( bitmap->width + xstr + 1 ) / 2;
  197. FT_Bitmap_New( &tmp );
  198. error = FT_Bitmap_Convert( library, bitmap, &tmp, align );
  199. if ( error )
  200. return error;
  201. FT_Bitmap_Done( library, bitmap );
  202. *bitmap = tmp;
  203. }
  204. break;
  205. case FT_PIXEL_MODE_MONO:
  206. if ( xstr > 8 )
  207. xstr = 8;
  208. break;
  209. case FT_PIXEL_MODE_LCD:
  210. xstr *= 3;
  211. break;
  212. case FT_PIXEL_MODE_LCD_V:
  213. ystr *= 3;
  214. break;
  215. }
  216. error = ft_bitmap_assure_buffer( library->memory, bitmap, xstr, ystr );
  217. if ( error )
  218. return error;
  219. pitch = bitmap->pitch;
  220. if ( pitch > 0 )
  221. p = bitmap->buffer + pitch * ystr;
  222. else
  223. {
  224. pitch = -pitch;
  225. p = bitmap->buffer + pitch * ( bitmap->rows - 1 );
  226. }
  227. /* for each row */
  228. for ( y = 0; y < bitmap->rows ; y++ )
  229. {
  230. /*
  231. * Horizontally:
  232. *
  233. * From the last pixel on, make each pixel or'ed with the
  234. * `xstr' pixels before it.
  235. */
  236. for ( x = pitch - 1; x >= 0; x-- )
  237. {
  238. unsigned char tmp;
  239. tmp = p[x];
  240. for ( i = 1; i <= xstr; i++ )
  241. {
  242. if ( bitmap->pixel_mode == FT_PIXEL_MODE_MONO )
  243. {
  244. p[x] |= tmp >> i;
  245. /* the maximum value of 8 for `xstr' comes from here */
  246. if ( x > 0 )
  247. p[x] |= p[x - 1] << ( 8 - i );
  248. #if 0
  249. if ( p[x] == 0xff )
  250. break;
  251. #endif
  252. }
  253. else
  254. {
  255. if ( x - i >= 0 )
  256. {
  257. if ( p[x] + p[x - i] > bitmap->num_grays - 1 )
  258. {
  259. p[x] = (unsigned char)(bitmap->num_grays - 1);
  260. break;
  261. }
  262. else
  263. {
  264. p[x] = (unsigned char)(p[x] + p[x-i]);
  265. if ( p[x] == bitmap->num_grays - 1 )
  266. break;
  267. }
  268. }
  269. else
  270. break;
  271. }
  272. }
  273. }
  274. /*
  275. * Vertically:
  276. *
  277. * Make the above `ystr' rows or'ed with it.
  278. */
  279. for ( x = 1; x <= ystr; x++ )
  280. {
  281. unsigned char* q;
  282. q = p - bitmap->pitch * x;
  283. for ( i = 0; i < pitch; i++ )
  284. q[i] |= p[i];
  285. }
  286. p += bitmap->pitch;
  287. }
  288. bitmap->width += xstr;
  289. bitmap->rows += ystr;
  290. return FT_Err_Ok;
  291. }
  292. /* documentation is in ftbitmap.h */
  293. FT_EXPORT_DEF( FT_Error )
  294. FT_Bitmap_Convert( FT_Library library,
  295. const FT_Bitmap *source,
  296. FT_Bitmap *target,
  297. FT_Int alignment )
  298. {
  299. FT_Error error = FT_Err_Ok;
  300. FT_Memory memory;
  301. if ( !library )
  302. return FT_Err_Invalid_Library_Handle;
  303. memory = library->memory;
  304. switch ( source->pixel_mode )
  305. {
  306. case FT_PIXEL_MODE_MONO:
  307. case FT_PIXEL_MODE_GRAY:
  308. case FT_PIXEL_MODE_GRAY2:
  309. case FT_PIXEL_MODE_GRAY4:
  310. case FT_PIXEL_MODE_LCD:
  311. case FT_PIXEL_MODE_LCD_V:
  312. {
  313. FT_Int pad;
  314. FT_Long old_size;
  315. old_size = target->rows * target->pitch;
  316. if ( old_size < 0 )
  317. old_size = -old_size;
  318. target->pixel_mode = FT_PIXEL_MODE_GRAY;
  319. target->rows = source->rows;
  320. target->width = source->width;
  321. pad = 0;
  322. if ( alignment > 0 )
  323. {
  324. pad = source->width % alignment;
  325. if ( pad != 0 )
  326. pad = alignment - pad;
  327. }
  328. target->pitch = source->width + pad;
  329. if ( target->rows * target->pitch > old_size &&
  330. FT_QREALLOC( target->buffer,
  331. old_size, target->rows * target->pitch ) )
  332. return error;
  333. }
  334. break;
  335. default:
  336. error = FT_Err_Invalid_Argument;
  337. }
  338. switch ( source->pixel_mode )
  339. {
  340. case FT_PIXEL_MODE_MONO:
  341. {
  342. FT_Byte* s = source->buffer;
  343. FT_Byte* t = target->buffer;
  344. FT_Int i;
  345. target->num_grays = 2;
  346. for ( i = source->rows; i > 0; i-- )
  347. {
  348. FT_Byte* ss = s;
  349. FT_Byte* tt = t;
  350. FT_Int j;
  351. /* get the full bytes */
  352. for ( j = source->width >> 3; j > 0; j-- )
  353. {
  354. FT_Int val = ss[0]; /* avoid a byte->int cast on each line */
  355. tt[0] = (FT_Byte)( ( val & 0x80 ) >> 7 );
  356. tt[1] = (FT_Byte)( ( val & 0x40 ) >> 6 );
  357. tt[2] = (FT_Byte)( ( val & 0x20 ) >> 5 );
  358. tt[3] = (FT_Byte)( ( val & 0x10 ) >> 4 );
  359. tt[4] = (FT_Byte)( ( val & 0x08 ) >> 3 );
  360. tt[5] = (FT_Byte)( ( val & 0x04 ) >> 2 );
  361. tt[6] = (FT_Byte)( ( val & 0x02 ) >> 1 );
  362. tt[7] = (FT_Byte)( val & 0x01 );
  363. tt += 8;
  364. ss += 1;
  365. }
  366. /* get remaining pixels (if any) */
  367. j = source->width & 7;
  368. if ( j > 0 )
  369. {
  370. FT_Int val = *ss;
  371. for ( ; j > 0; j-- )
  372. {
  373. tt[0] = (FT_Byte)( ( val & 0x80 ) >> 7);
  374. val <<= 1;
  375. tt += 1;
  376. }
  377. }
  378. s += source->pitch;
  379. t += target->pitch;
  380. }
  381. }
  382. break;
  383. case FT_PIXEL_MODE_GRAY:
  384. case FT_PIXEL_MODE_LCD:
  385. case FT_PIXEL_MODE_LCD_V:
  386. {
  387. FT_Int width = source->width;
  388. FT_Byte* s = source->buffer;
  389. FT_Byte* t = target->buffer;
  390. FT_Int s_pitch = source->pitch;
  391. FT_Int t_pitch = target->pitch;
  392. FT_Int i;
  393. target->num_grays = 256;
  394. for ( i = source->rows; i > 0; i-- )
  395. {
  396. FT_ARRAY_COPY( t, s, width );
  397. s += s_pitch;
  398. t += t_pitch;
  399. }
  400. }
  401. break;
  402. case FT_PIXEL_MODE_GRAY2:
  403. {
  404. FT_Byte* s = source->buffer;
  405. FT_Byte* t = target->buffer;
  406. FT_Int i;
  407. target->num_grays = 4;
  408. for ( i = source->rows; i > 0; i-- )
  409. {
  410. FT_Byte* ss = s;
  411. FT_Byte* tt = t;
  412. FT_Int j;
  413. /* get the full bytes */
  414. for ( j = source->width >> 2; j > 0; j-- )
  415. {
  416. FT_Int val = ss[0];
  417. tt[0] = (FT_Byte)( ( val & 0xC0 ) >> 6 );
  418. tt[1] = (FT_Byte)( ( val & 0x30 ) >> 4 );
  419. tt[2] = (FT_Byte)( ( val & 0x0C ) >> 2 );
  420. tt[3] = (FT_Byte)( ( val & 0x03 ) );
  421. ss += 1;
  422. tt += 4;
  423. }
  424. j = source->width & 3;
  425. if ( j > 0 )
  426. {
  427. FT_Int val = ss[0];
  428. for ( ; j > 0; j-- )
  429. {
  430. tt[0] = (FT_Byte)( ( val & 0xC0 ) >> 6 );
  431. val <<= 2;
  432. tt += 1;
  433. }
  434. }
  435. s += source->pitch;
  436. t += target->pitch;
  437. }
  438. }
  439. break;
  440. case FT_PIXEL_MODE_GRAY4:
  441. {
  442. FT_Byte* s = source->buffer;
  443. FT_Byte* t = target->buffer;
  444. FT_Int i;
  445. target->num_grays = 16;
  446. for ( i = source->rows; i > 0; i-- )
  447. {
  448. FT_Byte* ss = s;
  449. FT_Byte* tt = t;
  450. FT_Int j;
  451. /* get the full bytes */
  452. for ( j = source->width >> 1; j > 0; j-- )
  453. {
  454. FT_Int val = ss[0];
  455. tt[0] = (FT_Byte)( ( val & 0xF0 ) >> 4 );
  456. tt[1] = (FT_Byte)( ( val & 0x0F ) );
  457. ss += 1;
  458. tt += 2;
  459. }
  460. if ( source->width & 1 )
  461. tt[0] = (FT_Byte)( ( ss[0] & 0xF0 ) >> 4 );
  462. s += source->pitch;
  463. t += target->pitch;
  464. }
  465. }
  466. break;
  467. default:
  468. ;
  469. }
  470. return error;
  471. }
  472. /* documentation is in ftbitmap.h */
  473. FT_EXPORT_DEF( FT_Error )
  474. FT_GlyphSlot_Own_Bitmap( FT_GlyphSlot slot )
  475. {
  476. if ( slot && slot->format == FT_GLYPH_FORMAT_BITMAP &&
  477. !( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) )
  478. {
  479. FT_Bitmap bitmap;
  480. FT_Error error;
  481. FT_Bitmap_New( &bitmap );
  482. error = FT_Bitmap_Copy( slot->library, &slot->bitmap, &bitmap );
  483. if ( error )
  484. return error;
  485. slot->bitmap = bitmap;
  486. slot->internal->flags |= FT_GLYPH_OWN_BITMAP;
  487. }
  488. return FT_Err_Ok;
  489. }
  490. /* documentation is in ftbitmap.h */
  491. FT_EXPORT_DEF( FT_Error )
  492. FT_Bitmap_Done( FT_Library library,
  493. FT_Bitmap *bitmap )
  494. {
  495. FT_Memory memory;
  496. if ( !library )
  497. return FT_Err_Invalid_Library_Handle;
  498. if ( !bitmap )
  499. return FT_Err_Invalid_Argument;
  500. memory = library->memory;
  501. FT_FREE( bitmap->buffer );
  502. *bitmap = null_bitmap;
  503. return FT_Err_Ok;
  504. }
  505. /* END */