PageRenderTime 57ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 1ms

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

http://ftk.googlecode.com/
C | 1507 lines | 860 code | 279 blank | 368 comment | 107 complexity | ddda31ee9074399c490171e6f0e77950 MD5 | raw file
Possible License(s): LGPL-3.0
  1. /***************************************************************************/
  2. /* */
  3. /* ttsbit.c */
  4. /* */
  5. /* TrueType and OpenType embedded bitmap support (body). */
  6. /* */
  7. /* Copyright 1996-2001, 2002, 2003, 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_INTERNAL_DEBUG_H
  19. #include FT_INTERNAL_STREAM_H
  20. #include FT_TRUETYPE_TAGS_H
  21. /*
  22. * Alas, the memory-optimized sbit loader can't be used when implementing
  23. * the `old internals' hack
  24. */
  25. #ifndef FT_CONFIG_OPTION_OLD_INTERNALS
  26. #include "ttsbit0.c"
  27. #else /* FT_CONFIG_OPTION_OLD_INTERNALS */
  28. #include <ft2build.h>
  29. #include FT_INTERNAL_DEBUG_H
  30. #include FT_INTERNAL_STREAM_H
  31. #include FT_TRUETYPE_TAGS_H
  32. #include "ttsbit.h"
  33. #include "sferrors.h"
  34. /*************************************************************************/
  35. /* */
  36. /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
  37. /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
  38. /* messages during execution. */
  39. /* */
  40. #undef FT_COMPONENT
  41. #define FT_COMPONENT trace_ttsbit
  42. /*************************************************************************/
  43. /* */
  44. /* <Function> */
  45. /* blit_sbit */
  46. /* */
  47. /* <Description> */
  48. /* Blits a bitmap from an input stream into a given target. Supports */
  49. /* x and y offsets as well as byte padded lines. */
  50. /* */
  51. /* <Input> */
  52. /* target :: The target bitmap/pixmap. */
  53. /* */
  54. /* source :: The input packed bitmap data. */
  55. /* */
  56. /* line_bits :: The number of bits per line. */
  57. /* */
  58. /* byte_padded :: A flag which is true if lines are byte-padded. */
  59. /* */
  60. /* x_offset :: The horizontal offset. */
  61. /* */
  62. /* y_offset :: The vertical offset. */
  63. /* */
  64. /* <Note> */
  65. /* IMPORTANT: The x and y offsets are relative to the top corner of */
  66. /* the target bitmap (unlike the normal TrueType */
  67. /* convention). A positive y offset indicates a downwards */
  68. /* direction! */
  69. /* */
  70. static void
  71. blit_sbit( FT_Bitmap* target,
  72. FT_Byte* source,
  73. FT_Int line_bits,
  74. FT_Bool byte_padded,
  75. FT_Int x_offset,
  76. FT_Int y_offset,
  77. FT_Int source_height )
  78. {
  79. FT_Byte* line_buff;
  80. FT_Int line_incr;
  81. FT_Int height;
  82. FT_UShort acc;
  83. FT_UInt loaded;
  84. /* first of all, compute starting write position */
  85. line_incr = target->pitch;
  86. line_buff = target->buffer;
  87. if ( line_incr < 0 )
  88. line_buff -= line_incr * ( target->rows - 1 );
  89. line_buff += ( x_offset >> 3 ) + y_offset * line_incr;
  90. /***********************************************************************/
  91. /* */
  92. /* We use the extra-classic `accumulator' trick to extract the bits */
  93. /* from the source byte stream. */
  94. /* */
  95. /* Namely, the variable `acc' is a 16-bit accumulator containing the */
  96. /* last `loaded' bits from the input stream. The bits are shifted to */
  97. /* the upmost position in `acc'. */
  98. /* */
  99. /***********************************************************************/
  100. acc = 0; /* clear accumulator */
  101. loaded = 0; /* no bits were loaded */
  102. for ( height = source_height; height > 0; height-- )
  103. {
  104. FT_Byte* cur = line_buff; /* current write cursor */
  105. FT_Int count = line_bits; /* # of bits to extract per line */
  106. FT_Byte shift = (FT_Byte)( x_offset & 7 ); /* current write shift */
  107. FT_Byte space = (FT_Byte)( 8 - shift );
  108. /* first of all, read individual source bytes */
  109. if ( count >= 8 )
  110. {
  111. count -= 8;
  112. {
  113. do
  114. {
  115. FT_Byte val;
  116. /* ensure that there are at least 8 bits in the accumulator */
  117. if ( loaded < 8 )
  118. {
  119. acc |= (FT_UShort)((FT_UShort)*source++ << ( 8 - loaded ));
  120. loaded += 8;
  121. }
  122. /* now write one byte */
  123. val = (FT_Byte)( acc >> 8 );
  124. if ( shift )
  125. {
  126. cur[0] |= (FT_Byte)( val >> shift );
  127. cur[1] |= (FT_Byte)( val << space );
  128. }
  129. else
  130. cur[0] |= val;
  131. cur++;
  132. acc <<= 8; /* remove bits from accumulator */
  133. loaded -= 8;
  134. count -= 8;
  135. } while ( count >= 0 );
  136. }
  137. /* restore `count' to correct value */
  138. count += 8;
  139. }
  140. /* now write remaining bits (count < 8) */
  141. if ( count > 0 )
  142. {
  143. FT_Byte val;
  144. /* ensure that there are at least `count' bits in the accumulator */
  145. if ( (FT_Int)loaded < count )
  146. {
  147. acc |= (FT_UShort)((FT_UShort)*source++ << ( 8 - loaded ));
  148. loaded += 8;
  149. }
  150. /* now write remaining bits */
  151. val = (FT_Byte)( ( (FT_Byte)( acc >> 8 ) ) & ~( 0xFF >> count ) );
  152. cur[0] |= (FT_Byte)( val >> shift );
  153. if ( count > space )
  154. cur[1] |= (FT_Byte)( val << space );
  155. acc <<= count;
  156. loaded -= count;
  157. }
  158. /* now, skip to next line */
  159. if ( byte_padded )
  160. {
  161. acc = 0;
  162. loaded = 0; /* clear accumulator on byte-padded lines */
  163. }
  164. line_buff += line_incr;
  165. }
  166. }
  167. static const FT_Frame_Field sbit_metrics_fields[] =
  168. {
  169. #undef FT_STRUCTURE
  170. #define FT_STRUCTURE TT_SBit_MetricsRec
  171. FT_FRAME_START( 8 ),
  172. FT_FRAME_BYTE( height ),
  173. FT_FRAME_BYTE( width ),
  174. FT_FRAME_CHAR( horiBearingX ),
  175. FT_FRAME_CHAR( horiBearingY ),
  176. FT_FRAME_BYTE( horiAdvance ),
  177. FT_FRAME_CHAR( vertBearingX ),
  178. FT_FRAME_CHAR( vertBearingY ),
  179. FT_FRAME_BYTE( vertAdvance ),
  180. FT_FRAME_END
  181. };
  182. /*************************************************************************/
  183. /* */
  184. /* <Function> */
  185. /* Load_SBit_Const_Metrics */
  186. /* */
  187. /* <Description> */
  188. /* Loads the metrics for `EBLC' index tables format 2 and 5. */
  189. /* */
  190. /* <Input> */
  191. /* range :: The target range. */
  192. /* */
  193. /* stream :: The input stream. */
  194. /* */
  195. /* <Return> */
  196. /* FreeType error code. 0 means success. */
  197. /* */
  198. static FT_Error
  199. Load_SBit_Const_Metrics( TT_SBit_Range range,
  200. FT_Stream stream )
  201. {
  202. FT_Error error;
  203. if ( FT_READ_ULONG( range->image_size ) )
  204. return error;
  205. return FT_STREAM_READ_FIELDS( sbit_metrics_fields, &range->metrics );
  206. }
  207. /*************************************************************************/
  208. /* */
  209. /* <Function> */
  210. /* Load_SBit_Range_Codes */
  211. /* */
  212. /* <Description> */
  213. /* Loads the range codes for `EBLC' index tables format 4 and 5. */
  214. /* */
  215. /* <Input> */
  216. /* range :: The target range. */
  217. /* */
  218. /* stream :: The input stream. */
  219. /* */
  220. /* load_offsets :: A flag whether to load the glyph offset table. */
  221. /* */
  222. /* <Return> */
  223. /* FreeType error code. 0 means success. */
  224. /* */
  225. static FT_Error
  226. Load_SBit_Range_Codes( TT_SBit_Range range,
  227. FT_Stream stream,
  228. FT_Bool load_offsets )
  229. {
  230. FT_Error error;
  231. FT_ULong count, n, size;
  232. FT_Memory memory = stream->memory;
  233. if ( FT_READ_ULONG( count ) )
  234. goto Exit;
  235. range->num_glyphs = count;
  236. /* Allocate glyph offsets table if needed */
  237. if ( load_offsets )
  238. {
  239. if ( FT_NEW_ARRAY( range->glyph_offsets, count ) )
  240. goto Exit;
  241. size = count * 4L;
  242. }
  243. else
  244. size = count * 2L;
  245. /* Allocate glyph codes table and access frame */
  246. if ( FT_NEW_ARRAY ( range->glyph_codes, count ) ||
  247. FT_FRAME_ENTER( size ) )
  248. goto Exit;
  249. for ( n = 0; n < count; n++ )
  250. {
  251. range->glyph_codes[n] = FT_GET_USHORT();
  252. if ( load_offsets )
  253. range->glyph_offsets[n] = (FT_ULong)range->image_offset +
  254. FT_GET_USHORT();
  255. }
  256. FT_FRAME_EXIT();
  257. Exit:
  258. return error;
  259. }
  260. /*************************************************************************/
  261. /* */
  262. /* <Function> */
  263. /* Load_SBit_Range */
  264. /* */
  265. /* <Description> */
  266. /* Loads a given `EBLC' index/range table. */
  267. /* */
  268. /* <Input> */
  269. /* range :: The target range. */
  270. /* */
  271. /* stream :: The input stream. */
  272. /* */
  273. /* <Return> */
  274. /* FreeType error code. 0 means success. */
  275. /* */
  276. static FT_Error
  277. Load_SBit_Range( TT_SBit_Range range,
  278. FT_Stream stream )
  279. {
  280. FT_Error error;
  281. FT_Memory memory = stream->memory;
  282. switch( range->index_format )
  283. {
  284. case 1: /* variable metrics with 4-byte offsets */
  285. case 3: /* variable metrics with 2-byte offsets */
  286. {
  287. FT_ULong num_glyphs, n;
  288. FT_Int size_elem;
  289. FT_Bool large = FT_BOOL( range->index_format == 1 );
  290. if ( range->last_glyph < range->first_glyph )
  291. {
  292. error = SFNT_Err_Invalid_File_Format;
  293. goto Exit;
  294. }
  295. num_glyphs = range->last_glyph - range->first_glyph + 1L;
  296. range->num_glyphs = num_glyphs;
  297. num_glyphs++; /* XXX: BEWARE - see spec */
  298. size_elem = large ? 4 : 2;
  299. if ( FT_NEW_ARRAY( range->glyph_offsets, num_glyphs ) ||
  300. FT_FRAME_ENTER( num_glyphs * size_elem ) )
  301. goto Exit;
  302. for ( n = 0; n < num_glyphs; n++ )
  303. range->glyph_offsets[n] = (FT_ULong)( range->image_offset +
  304. ( large ? FT_GET_ULONG()
  305. : FT_GET_USHORT() ) );
  306. FT_FRAME_EXIT();
  307. }
  308. break;
  309. case 2: /* all glyphs have identical metrics */
  310. error = Load_SBit_Const_Metrics( range, stream );
  311. break;
  312. case 4:
  313. error = Load_SBit_Range_Codes( range, stream, 1 );
  314. break;
  315. case 5:
  316. error = Load_SBit_Const_Metrics( range, stream );
  317. if ( !error )
  318. error = Load_SBit_Range_Codes( range, stream, 0 );
  319. break;
  320. default:
  321. error = SFNT_Err_Invalid_File_Format;
  322. }
  323. Exit:
  324. return error;
  325. }
  326. /*************************************************************************/
  327. /* */
  328. /* <Function> */
  329. /* tt_face_load_eblc */
  330. /* */
  331. /* <Description> */
  332. /* Loads the table of embedded bitmap sizes for this face. */
  333. /* */
  334. /* <Input> */
  335. /* face :: The target face object. */
  336. /* */
  337. /* stream :: The input stream. */
  338. /* */
  339. /* <Return> */
  340. /* FreeType error code. 0 means success. */
  341. /* */
  342. FT_LOCAL_DEF( FT_Error )
  343. tt_face_load_eblc( TT_Face face,
  344. FT_Stream stream )
  345. {
  346. FT_Error error = 0;
  347. FT_Memory memory = stream->memory;
  348. FT_Fixed version;
  349. FT_ULong num_strikes;
  350. FT_ULong table_base;
  351. static const FT_Frame_Field sbit_line_metrics_fields[] =
  352. {
  353. #undef FT_STRUCTURE
  354. #define FT_STRUCTURE TT_SBit_LineMetricsRec
  355. /* no FT_FRAME_START */
  356. FT_FRAME_CHAR( ascender ),
  357. FT_FRAME_CHAR( descender ),
  358. FT_FRAME_BYTE( max_width ),
  359. FT_FRAME_CHAR( caret_slope_numerator ),
  360. FT_FRAME_CHAR( caret_slope_denominator ),
  361. FT_FRAME_CHAR( caret_offset ),
  362. FT_FRAME_CHAR( min_origin_SB ),
  363. FT_FRAME_CHAR( min_advance_SB ),
  364. FT_FRAME_CHAR( max_before_BL ),
  365. FT_FRAME_CHAR( min_after_BL ),
  366. FT_FRAME_CHAR( pads[0] ),
  367. FT_FRAME_CHAR( pads[1] ),
  368. FT_FRAME_END
  369. };
  370. static const FT_Frame_Field strike_start_fields[] =
  371. {
  372. #undef FT_STRUCTURE
  373. #define FT_STRUCTURE TT_SBit_StrikeRec
  374. /* no FT_FRAME_START */
  375. FT_FRAME_ULONG( ranges_offset ),
  376. FT_FRAME_SKIP_LONG,
  377. FT_FRAME_ULONG( num_ranges ),
  378. FT_FRAME_ULONG( color_ref ),
  379. FT_FRAME_END
  380. };
  381. static const FT_Frame_Field strike_end_fields[] =
  382. {
  383. /* no FT_FRAME_START */
  384. FT_FRAME_USHORT( start_glyph ),
  385. FT_FRAME_USHORT( end_glyph ),
  386. FT_FRAME_BYTE ( x_ppem ),
  387. FT_FRAME_BYTE ( y_ppem ),
  388. FT_FRAME_BYTE ( bit_depth ),
  389. FT_FRAME_CHAR ( flags ),
  390. FT_FRAME_END
  391. };
  392. face->num_sbit_strikes = 0;
  393. /* this table is optional */
  394. error = face->goto_table( face, TTAG_EBLC, stream, 0 );
  395. if ( error )
  396. error = face->goto_table( face, TTAG_bloc, stream, 0 );
  397. if ( error )
  398. goto Exit;
  399. table_base = FT_STREAM_POS();
  400. if ( FT_FRAME_ENTER( 8L ) )
  401. goto Exit;
  402. version = FT_GET_LONG();
  403. num_strikes = FT_GET_ULONG();
  404. FT_FRAME_EXIT();
  405. /* check version number and strike count */
  406. if ( version != 0x00020000L ||
  407. num_strikes >= 0x10000L )
  408. {
  409. FT_ERROR(( "tt_face_load_sbit_strikes: invalid table version\n" ));
  410. error = SFNT_Err_Invalid_File_Format;
  411. goto Exit;
  412. }
  413. /* allocate the strikes table */
  414. if ( FT_NEW_ARRAY( face->sbit_strikes, num_strikes ) )
  415. goto Exit;
  416. face->num_sbit_strikes = num_strikes;
  417. /* now read each strike table separately */
  418. {
  419. TT_SBit_Strike strike = face->sbit_strikes;
  420. FT_ULong count = num_strikes;
  421. if ( FT_FRAME_ENTER( 48L * num_strikes ) )
  422. goto Exit;
  423. while ( count > 0 )
  424. {
  425. if ( FT_STREAM_READ_FIELDS( strike_start_fields, strike ) ||
  426. FT_STREAM_READ_FIELDS( sbit_line_metrics_fields, &strike->hori ) ||
  427. FT_STREAM_READ_FIELDS( sbit_line_metrics_fields, &strike->vert ) ||
  428. FT_STREAM_READ_FIELDS( strike_end_fields, strike ) )
  429. break;
  430. count--;
  431. strike++;
  432. }
  433. FT_FRAME_EXIT();
  434. }
  435. /* allocate the index ranges for each strike table */
  436. {
  437. TT_SBit_Strike strike = face->sbit_strikes;
  438. FT_ULong count = num_strikes;
  439. while ( count > 0 )
  440. {
  441. TT_SBit_Range range;
  442. FT_ULong count2 = strike->num_ranges;
  443. /* read each range */
  444. if ( FT_STREAM_SEEK( table_base + strike->ranges_offset ) ||
  445. FT_FRAME_ENTER( strike->num_ranges * 8L ) )
  446. goto Exit;
  447. if ( FT_NEW_ARRAY( strike->sbit_ranges, strike->num_ranges ) )
  448. goto Exit;
  449. range = strike->sbit_ranges;
  450. while ( count2 > 0 )
  451. {
  452. range->first_glyph = FT_GET_USHORT();
  453. range->last_glyph = FT_GET_USHORT();
  454. range->table_offset = table_base + strike->ranges_offset +
  455. FT_GET_ULONG();
  456. count2--;
  457. range++;
  458. }
  459. FT_FRAME_EXIT();
  460. /* Now, read each index table */
  461. count2 = strike->num_ranges;
  462. range = strike->sbit_ranges;
  463. while ( count2 > 0 )
  464. {
  465. /* Read the header */
  466. if ( FT_STREAM_SEEK( range->table_offset ) ||
  467. FT_FRAME_ENTER( 8L ) )
  468. goto Exit;
  469. range->index_format = FT_GET_USHORT();
  470. range->image_format = FT_GET_USHORT();
  471. range->image_offset = FT_GET_ULONG();
  472. FT_FRAME_EXIT();
  473. error = Load_SBit_Range( range, stream );
  474. if ( error )
  475. goto Exit;
  476. count2--;
  477. range++;
  478. }
  479. count--;
  480. strike++;
  481. }
  482. }
  483. Exit:
  484. return error;
  485. }
  486. /*************************************************************************/
  487. /* */
  488. /* <Function> */
  489. /* tt_face_free_eblc */
  490. /* */
  491. /* <Description> */
  492. /* Releases the embedded bitmap tables. */
  493. /* */
  494. /* <Input> */
  495. /* face :: The target face object. */
  496. /* */
  497. FT_LOCAL_DEF( void )
  498. tt_face_free_eblc( TT_Face face )
  499. {
  500. FT_Memory memory = face->root.memory;
  501. TT_SBit_Strike strike = face->sbit_strikes;
  502. TT_SBit_Strike strike_limit = strike + face->num_sbit_strikes;
  503. if ( strike )
  504. {
  505. for ( ; strike < strike_limit; strike++ )
  506. {
  507. TT_SBit_Range range = strike->sbit_ranges;
  508. TT_SBit_Range range_limit = range + strike->num_ranges;
  509. if ( range )
  510. {
  511. for ( ; range < range_limit; range++ )
  512. {
  513. /* release the glyph offsets and codes tables */
  514. /* where appropriate */
  515. FT_FREE( range->glyph_offsets );
  516. FT_FREE( range->glyph_codes );
  517. }
  518. }
  519. FT_FREE( strike->sbit_ranges );
  520. strike->num_ranges = 0;
  521. }
  522. FT_FREE( face->sbit_strikes );
  523. }
  524. face->num_sbit_strikes = 0;
  525. }
  526. FT_LOCAL_DEF( FT_Error )
  527. tt_face_set_sbit_strike( TT_Face face,
  528. FT_Size_Request req,
  529. FT_ULong* astrike_index )
  530. {
  531. return FT_Match_Size( (FT_Face)face, req, 0, astrike_index );
  532. }
  533. FT_LOCAL_DEF( FT_Error )
  534. tt_face_load_strike_metrics( TT_Face face,
  535. FT_ULong strike_index,
  536. FT_Size_Metrics* metrics )
  537. {
  538. TT_SBit_Strike strike;
  539. if ( strike_index >= face->num_sbit_strikes )
  540. return SFNT_Err_Invalid_Argument;
  541. strike = face->sbit_strikes + strike_index;
  542. metrics->x_ppem = strike->x_ppem;
  543. metrics->y_ppem = strike->y_ppem;
  544. metrics->ascender = strike->hori.ascender << 6;
  545. metrics->descender = strike->hori.descender << 6;
  546. /* XXX: Is this correct? */
  547. metrics->max_advance = ( strike->hori.min_origin_SB +
  548. strike->hori.max_width +
  549. strike->hori.min_advance_SB ) << 6;
  550. metrics->height = metrics->ascender - metrics->descender;
  551. return SFNT_Err_Ok;
  552. }
  553. /*************************************************************************/
  554. /* */
  555. /* <Function> */
  556. /* find_sbit_range */
  557. /* */
  558. /* <Description> */
  559. /* Scans a given strike's ranges and return, for a given glyph */
  560. /* index, the corresponding sbit range, and `EBDT' offset. */
  561. /* */
  562. /* <Input> */
  563. /* glyph_index :: The glyph index. */
  564. /* */
  565. /* strike :: The source/current sbit strike. */
  566. /* */
  567. /* <Output> */
  568. /* arange :: The sbit range containing the glyph index. */
  569. /* */
  570. /* aglyph_offset :: The offset of the glyph data in `EBDT' table. */
  571. /* */
  572. /* <Return> */
  573. /* FreeType error code. 0 means the glyph index was found. */
  574. /* */
  575. static FT_Error
  576. find_sbit_range( FT_UInt glyph_index,
  577. TT_SBit_Strike strike,
  578. TT_SBit_Range *arange,
  579. FT_ULong *aglyph_offset )
  580. {
  581. TT_SBit_RangeRec *range, *range_limit;
  582. /* check whether the glyph index is within this strike's */
  583. /* glyph range */
  584. if ( glyph_index < (FT_UInt)strike->start_glyph ||
  585. glyph_index > (FT_UInt)strike->end_glyph )
  586. goto Fail;
  587. /* scan all ranges in strike */
  588. range = strike->sbit_ranges;
  589. range_limit = range + strike->num_ranges;
  590. if ( !range )
  591. goto Fail;
  592. for ( ; range < range_limit; range++ )
  593. {
  594. if ( glyph_index >= (FT_UInt)range->first_glyph &&
  595. glyph_index <= (FT_UInt)range->last_glyph )
  596. {
  597. FT_UShort delta = (FT_UShort)( glyph_index - range->first_glyph );
  598. switch ( range->index_format )
  599. {
  600. case 1:
  601. case 3:
  602. *aglyph_offset = range->glyph_offsets[delta];
  603. break;
  604. case 2:
  605. *aglyph_offset = range->image_offset +
  606. range->image_size * delta;
  607. break;
  608. case 4:
  609. case 5:
  610. {
  611. FT_ULong n;
  612. for ( n = 0; n < range->num_glyphs; n++ )
  613. {
  614. if ( (FT_UInt)range->glyph_codes[n] == glyph_index )
  615. {
  616. if ( range->index_format == 4 )
  617. *aglyph_offset = range->glyph_offsets[n];
  618. else
  619. *aglyph_offset = range->image_offset +
  620. n * range->image_size;
  621. goto Found;
  622. }
  623. }
  624. }
  625. /* fall-through */
  626. default:
  627. goto Fail;
  628. }
  629. Found:
  630. /* return successfully! */
  631. *arange = range;
  632. return SFNT_Err_Ok;
  633. }
  634. }
  635. Fail:
  636. *arange = 0;
  637. *aglyph_offset = 0;
  638. return SFNT_Err_Invalid_Argument;
  639. }
  640. /*************************************************************************/
  641. /* */
  642. /* <Function> */
  643. /* tt_find_sbit_image */
  644. /* */
  645. /* <Description> */
  646. /* Checks whether an embedded bitmap (an `sbit') exists for a given */
  647. /* glyph, at a given strike. */
  648. /* */
  649. /* <Input> */
  650. /* face :: The target face object. */
  651. /* */
  652. /* glyph_index :: The glyph index. */
  653. /* */
  654. /* strike_index :: The current strike index. */
  655. /* */
  656. /* <Output> */
  657. /* arange :: The SBit range containing the glyph index. */
  658. /* */
  659. /* astrike :: The SBit strike containing the glyph index. */
  660. /* */
  661. /* aglyph_offset :: The offset of the glyph data in `EBDT' table. */
  662. /* */
  663. /* <Return> */
  664. /* FreeType error code. 0 means success. Returns */
  665. /* SFNT_Err_Invalid_Argument if no sbit exists for the requested */
  666. /* glyph. */
  667. /* */
  668. FT_LOCAL( FT_Error )
  669. tt_find_sbit_image( TT_Face face,
  670. FT_UInt glyph_index,
  671. FT_ULong strike_index,
  672. TT_SBit_Range *arange,
  673. TT_SBit_Strike *astrike,
  674. FT_ULong *aglyph_offset )
  675. {
  676. FT_Error error;
  677. TT_SBit_Strike strike;
  678. if ( !face->sbit_strikes ||
  679. ( face->num_sbit_strikes <= strike_index ) )
  680. goto Fail;
  681. strike = &face->sbit_strikes[strike_index];
  682. error = find_sbit_range( glyph_index, strike,
  683. arange, aglyph_offset );
  684. if ( error )
  685. goto Fail;
  686. *astrike = strike;
  687. return SFNT_Err_Ok;
  688. Fail:
  689. /* no embedded bitmap for this glyph in face */
  690. *arange = 0;
  691. *astrike = 0;
  692. *aglyph_offset = 0;
  693. return SFNT_Err_Invalid_Argument;
  694. }
  695. /*************************************************************************/
  696. /* */
  697. /* <Function> */
  698. /* tt_load_sbit_metrics */
  699. /* */
  700. /* <Description> */
  701. /* Gets the big metrics for a given SBit. */
  702. /* */
  703. /* <Input> */
  704. /* stream :: The input stream. */
  705. /* */
  706. /* range :: The SBit range containing the glyph. */
  707. /* */
  708. /* <Output> */
  709. /* big_metrics :: A big SBit metrics structure for the glyph. */
  710. /* */
  711. /* <Return> */
  712. /* FreeType error code. 0 means success. */
  713. /* */
  714. /* <Note> */
  715. /* The stream cursor must be positioned at the glyph's offset within */
  716. /* the `EBDT' table before the call. */
  717. /* */
  718. /* If the image format uses variable metrics, the stream cursor is */
  719. /* positioned just after the metrics header in the `EBDT' table on */
  720. /* function exit. */
  721. /* */
  722. FT_LOCAL( FT_Error )
  723. tt_load_sbit_metrics( FT_Stream stream,
  724. TT_SBit_Range range,
  725. TT_SBit_Metrics metrics )
  726. {
  727. FT_Error error = SFNT_Err_Ok;
  728. switch ( range->image_format )
  729. {
  730. case 1:
  731. case 2:
  732. case 8:
  733. /* variable small metrics */
  734. {
  735. TT_SBit_SmallMetricsRec smetrics;
  736. static const FT_Frame_Field sbit_small_metrics_fields[] =
  737. {
  738. #undef FT_STRUCTURE
  739. #define FT_STRUCTURE TT_SBit_SmallMetricsRec
  740. FT_FRAME_START( 5 ),
  741. FT_FRAME_BYTE( height ),
  742. FT_FRAME_BYTE( width ),
  743. FT_FRAME_CHAR( bearingX ),
  744. FT_FRAME_CHAR( bearingY ),
  745. FT_FRAME_BYTE( advance ),
  746. FT_FRAME_END
  747. };
  748. /* read small metrics */
  749. if ( FT_STREAM_READ_FIELDS( sbit_small_metrics_fields, &smetrics ) )
  750. goto Exit;
  751. /* convert it to a big metrics */
  752. metrics->height = smetrics.height;
  753. metrics->width = smetrics.width;
  754. metrics->horiBearingX = smetrics.bearingX;
  755. metrics->horiBearingY = smetrics.bearingY;
  756. metrics->horiAdvance = smetrics.advance;
  757. /* these metrics are made up at a higher level when */
  758. /* needed. */
  759. metrics->vertBearingX = 0;
  760. metrics->vertBearingY = 0;
  761. metrics->vertAdvance = 0;
  762. }
  763. break;
  764. case 6:
  765. case 7:
  766. case 9:
  767. /* variable big metrics */
  768. if ( FT_STREAM_READ_FIELDS( sbit_metrics_fields, metrics ) )
  769. goto Exit;
  770. break;
  771. case 5:
  772. default: /* constant metrics */
  773. if ( range->index_format == 2 || range->index_format == 5 )
  774. *metrics = range->metrics;
  775. else
  776. return SFNT_Err_Invalid_File_Format;
  777. }
  778. Exit:
  779. return error;
  780. }
  781. /*************************************************************************/
  782. /* */
  783. /* <Function> */
  784. /* crop_bitmap */
  785. /* */
  786. /* <Description> */
  787. /* Crops a bitmap to its tightest bounding box, and adjusts its */
  788. /* metrics. */
  789. /* */
  790. /* <InOut> */
  791. /* map :: The bitmap. */
  792. /* */
  793. /* metrics :: The corresponding metrics structure. */
  794. /* */
  795. static void
  796. crop_bitmap( FT_Bitmap* map,
  797. TT_SBit_Metrics metrics )
  798. {
  799. /***********************************************************************/
  800. /* */
  801. /* In this situation, some bounding boxes of embedded bitmaps are too */
  802. /* large. We need to crop it to a reasonable size. */
  803. /* */
  804. /* --------- */
  805. /* | | ----- */
  806. /* | *** | |***| */
  807. /* | * | | * | */
  808. /* | * | ------> | * | */
  809. /* | * | | * | */
  810. /* | * | | * | */
  811. /* | *** | |***| */
  812. /* --------- ----- */
  813. /* */
  814. /***********************************************************************/
  815. FT_Int rows, count;
  816. FT_Long line_len;
  817. FT_Byte* line;
  818. /***********************************************************************/
  819. /* */
  820. /* first of all, check the top-most lines of the bitmap, and remove */
  821. /* them if they're empty. */
  822. /* */
  823. {
  824. line = (FT_Byte*)map->buffer;
  825. rows = map->rows;
  826. line_len = map->pitch;
  827. for ( count = 0; count < rows; count++ )
  828. {
  829. FT_Byte* cur = line;
  830. FT_Byte* limit = line + line_len;
  831. for ( ; cur < limit; cur++ )
  832. if ( cur[0] )
  833. goto Found_Top;
  834. /* the current line was empty - skip to next one */
  835. line = limit;
  836. }
  837. Found_Top:
  838. /* check that we have at least one filled line */
  839. if ( count >= rows )
  840. goto Empty_Bitmap;
  841. /* now, crop the empty upper lines */
  842. if ( count > 0 )
  843. {
  844. line = (FT_Byte*)map->buffer;
  845. FT_MEM_MOVE( line, line + count * line_len,
  846. ( rows - count ) * line_len );
  847. metrics->height = (FT_Byte)( metrics->height - count );
  848. metrics->horiBearingY = (FT_Char)( metrics->horiBearingY - count );
  849. metrics->vertBearingY = (FT_Char)( metrics->vertBearingY - count );
  850. map->rows -= count;
  851. rows -= count;
  852. }
  853. }
  854. /***********************************************************************/
  855. /* */
  856. /* second, crop the lower lines */
  857. /* */
  858. {
  859. line = (FT_Byte*)map->buffer + ( rows - 1 ) * line_len;
  860. for ( count = 0; count < rows; count++ )
  861. {
  862. FT_Byte* cur = line;
  863. FT_Byte* limit = line + line_len;
  864. for ( ; cur < limit; cur++ )
  865. if ( cur[0] )
  866. goto Found_Bottom;
  867. /* the current line was empty - skip to previous one */
  868. line -= line_len;
  869. }
  870. Found_Bottom:
  871. if ( count > 0 )
  872. {
  873. metrics->height = (FT_Byte)( metrics->height - count );
  874. rows -= count;
  875. map->rows -= count;
  876. }
  877. }
  878. /***********************************************************************/
  879. /* */
  880. /* third, get rid of the space on the left side of the glyph */
  881. /* */
  882. do
  883. {
  884. FT_Byte* limit;
  885. line = (FT_Byte*)map->buffer;
  886. limit = line + rows * line_len;
  887. for ( ; line < limit; line += line_len )
  888. if ( line[0] & 0x80 )
  889. goto Found_Left;
  890. /* shift the whole glyph one pixel to the left */
  891. line = (FT_Byte*)map->buffer;
  892. limit = line + rows * line_len;
  893. for ( ; line < limit; line += line_len )
  894. {
  895. FT_Int n, width = map->width;
  896. FT_Byte old;
  897. FT_Byte* cur = line;
  898. old = (FT_Byte)(cur[0] << 1);
  899. for ( n = 8; n < width; n += 8 )
  900. {
  901. FT_Byte val;
  902. val = cur[1];
  903. cur[0] = (FT_Byte)( old | ( val >> 7 ) );
  904. old = (FT_Byte)( val << 1 );
  905. cur++;
  906. }
  907. cur[0] = old;
  908. }
  909. map->width--;
  910. metrics->horiBearingX++;
  911. metrics->vertBearingX++;
  912. metrics->width--;
  913. } while ( map->width > 0 );
  914. Found_Left:
  915. /***********************************************************************/
  916. /* */
  917. /* finally, crop the bitmap width to get rid of the space on the right */
  918. /* side of the glyph. */
  919. /* */
  920. do
  921. {
  922. FT_Int right = map->width - 1;
  923. FT_Byte* limit;
  924. FT_Byte mask;
  925. line = (FT_Byte*)map->buffer + ( right >> 3 );
  926. limit = line + rows * line_len;
  927. mask = (FT_Byte)( 0x80 >> ( right & 7 ) );
  928. for ( ; line < limit; line += line_len )
  929. if ( line[0] & mask )
  930. goto Found_Right;
  931. /* crop the whole glyph to the right */
  932. map->width--;
  933. metrics->width--;
  934. } while ( map->width > 0 );
  935. Found_Right:
  936. /* all right, the bitmap was cropped */
  937. return;
  938. Empty_Bitmap:
  939. map->width = 0;
  940. map->rows = 0;
  941. map->pitch = 0;
  942. map->pixel_mode = FT_PIXEL_MODE_MONO;
  943. }
  944. static FT_Error
  945. Load_SBit_Single( FT_Bitmap* map,
  946. FT_Int x_offset,
  947. FT_Int y_offset,
  948. FT_Int pix_bits,
  949. FT_UShort image_format,
  950. TT_SBit_Metrics metrics,
  951. FT_Stream stream )
  952. {
  953. FT_Error error;
  954. /* check that the source bitmap fits into the target pixmap */
  955. if ( x_offset < 0 || x_offset + metrics->width > map->width ||
  956. y_offset < 0 || y_offset + metrics->height > map->rows )
  957. {
  958. error = SFNT_Err_Invalid_Argument;
  959. goto Exit;
  960. }
  961. {
  962. FT_Int glyph_width = metrics->width;
  963. FT_Int glyph_height = metrics->height;
  964. FT_Int glyph_size;
  965. FT_Int line_bits = pix_bits * glyph_width;
  966. FT_Bool pad_bytes = 0;
  967. /* compute size of glyph image */
  968. switch ( image_format )
  969. {
  970. case 1: /* byte-padded formats */
  971. case 6:
  972. {
  973. FT_Int line_length;
  974. switch ( pix_bits )
  975. {
  976. case 1:
  977. line_length = ( glyph_width + 7 ) >> 3;
  978. break;
  979. case 2:
  980. line_length = ( glyph_width + 3 ) >> 2;
  981. break;
  982. case 4:
  983. line_length = ( glyph_width + 1 ) >> 1;
  984. break;
  985. default:
  986. line_length = glyph_width;
  987. }
  988. glyph_size = glyph_height * line_length;
  989. pad_bytes = 1;
  990. }
  991. break;
  992. case 2:
  993. case 5:
  994. case 7:
  995. line_bits = glyph_width * pix_bits;
  996. glyph_size = ( glyph_height * line_bits + 7 ) >> 3;
  997. break;
  998. default: /* invalid format */
  999. return SFNT_Err_Invalid_File_Format;
  1000. }
  1001. /* Now read data and draw glyph into target pixmap */
  1002. if ( FT_FRAME_ENTER( glyph_size ) )
  1003. goto Exit;
  1004. /* don't forget to multiply `x_offset' by `map->pix_bits' as */
  1005. /* the sbit blitter doesn't make a difference between pixmap */
  1006. /* depths. */
  1007. blit_sbit( map, (FT_Byte*)stream->cursor, line_bits, pad_bytes,
  1008. x_offset * pix_bits, y_offset, metrics->height );
  1009. FT_FRAME_EXIT();
  1010. }
  1011. Exit:
  1012. return error;
  1013. }
  1014. static FT_Error
  1015. Load_SBit_Image( TT_SBit_Strike strike,
  1016. TT_SBit_Range range,
  1017. FT_ULong ebdt_pos,
  1018. FT_ULong glyph_offset,
  1019. FT_GlyphSlot slot,
  1020. FT_Int x_offset,
  1021. FT_Int y_offset,
  1022. FT_Stream stream,
  1023. TT_SBit_Metrics metrics,
  1024. FT_Int depth )
  1025. {
  1026. FT_Memory memory = stream->memory;
  1027. FT_Bitmap* map = &slot->bitmap;
  1028. FT_Error error;
  1029. /* place stream at beginning of glyph data and read metrics */
  1030. if ( FT_STREAM_SEEK( ebdt_pos + glyph_offset ) )
  1031. goto Exit;
  1032. error = tt_load_sbit_metrics( stream, range, metrics );
  1033. if ( error )
  1034. goto Exit;
  1035. /* This function is recursive. At the top-level call, we */
  1036. /* compute the dimensions of the higher-level glyph to */
  1037. /* allocate the final pixmap buffer. */
  1038. if ( depth == 0 )
  1039. {
  1040. FT_Long size;
  1041. map->width = metrics->width;
  1042. map->rows = metrics->height;
  1043. switch ( strike->bit_depth )
  1044. {
  1045. case 1:
  1046. map->pixel_mode = FT_PIXEL_MODE_MONO;
  1047. map->pitch = ( map->width + 7 ) >> 3;
  1048. break;
  1049. case 2:
  1050. map->pixel_mode = FT_PIXEL_MODE_GRAY2;
  1051. map->pitch = ( map->width + 3 ) >> 2;
  1052. break;
  1053. case 4:
  1054. map->pixel_mode = FT_PIXEL_MODE_GRAY4;
  1055. map->pitch = ( map->width + 1 ) >> 1;
  1056. break;
  1057. case 8:
  1058. map->pixel_mode = FT_PIXEL_MODE_GRAY;
  1059. map->pitch = map->width;
  1060. break;
  1061. default:
  1062. return SFNT_Err_Invalid_File_Format;
  1063. }
  1064. size = map->rows * map->pitch;
  1065. /* check that there is no empty image */
  1066. if ( size == 0 )
  1067. goto Exit; /* exit successfully! */
  1068. error = ft_glyphslot_alloc_bitmap( slot, size );
  1069. if (error)
  1070. goto Exit;
  1071. }
  1072. switch ( range->image_format )
  1073. {
  1074. case 1: /* single sbit image - load it */
  1075. case 2:
  1076. case 5:
  1077. case 6:
  1078. case 7:
  1079. return Load_SBit_Single( map, x_offset, y_offset, strike->bit_depth,
  1080. range->image_format, metrics, stream );
  1081. case 8: /* compound format */
  1082. if ( FT_STREAM_SKIP( 1L ) )
  1083. {
  1084. error = SFNT_Err_Invalid_Stream_Skip;
  1085. goto Exit;
  1086. }
  1087. /* fallthrough */
  1088. case 9:
  1089. break;
  1090. default: /* invalid image format */
  1091. return SFNT_Err_Invalid_File_Format;
  1092. }
  1093. /* All right, we have a compound format. First of all, read */
  1094. /* the array of elements. */
  1095. {
  1096. TT_SBit_Component components;
  1097. TT_SBit_Component comp;
  1098. FT_UShort num_components, count;
  1099. if ( FT_READ_USHORT( num_components ) ||
  1100. FT_NEW_ARRAY( components, num_components ) )
  1101. goto Exit;
  1102. count = num_components;
  1103. if ( FT_FRAME_ENTER( 4L * num_components ) )
  1104. goto Fail_Memory;
  1105. for ( comp = components; count > 0; count--, comp++ )
  1106. {
  1107. comp->glyph_code = FT_GET_USHORT();
  1108. comp->x_offset = FT_GET_CHAR();
  1109. comp->y_offset = FT_GET_CHAR();
  1110. }
  1111. FT_FRAME_EXIT();
  1112. /* Now recursively load each element glyph */
  1113. count = num_components;
  1114. comp = components;
  1115. for ( ; count > 0; count--, comp++ )
  1116. {
  1117. TT_SBit_Range elem_range;
  1118. TT_SBit_MetricsRec elem_metrics;
  1119. FT_ULong elem_offset;
  1120. /* find the range for this element */
  1121. error = find_sbit_range( comp->glyph_code,
  1122. strike,
  1123. &elem_range,
  1124. &elem_offset );
  1125. if ( error )
  1126. goto Fail_Memory;
  1127. /* now load the element, recursively */
  1128. error = Load_SBit_Image( strike,
  1129. elem_range,
  1130. ebdt_pos,
  1131. elem_offset,
  1132. slot,
  1133. x_offset + comp->x_offset,
  1134. y_offset + comp->y_offset,
  1135. stream,
  1136. &elem_metrics,
  1137. depth + 1 );
  1138. if ( error )
  1139. goto Fail_Memory;
  1140. }
  1141. Fail_Memory:
  1142. FT_FREE( components );
  1143. }
  1144. Exit:
  1145. return error;
  1146. }
  1147. /*************************************************************************/
  1148. /* */
  1149. /* <Function> */
  1150. /* tt_face_load_sbit_image */
  1151. /* */
  1152. /* <Description> */
  1153. /* Loads a given glyph sbit image from the font resource. This also */
  1154. /* returns its metrics. */
  1155. /* */
  1156. /* <Input> */
  1157. /* face :: The target face object. */
  1158. /* */
  1159. /* strike_index :: The current strike index. */
  1160. /* */
  1161. /* glyph_index :: The current glyph index. */
  1162. /* */
  1163. /* load_flags :: The glyph load flags (the code checks for the flag */
  1164. /* FT_LOAD_CROP_BITMAP). */
  1165. /* */
  1166. /* stream :: The input stream. */
  1167. /* */
  1168. /* <Output> */
  1169. /* map :: The target pixmap. */
  1170. /* */
  1171. /* metrics :: A big sbit metrics structure for the glyph image. */
  1172. /* */
  1173. /* <Return> */
  1174. /* FreeType error code. 0 means success. Returns an error if no */
  1175. /* glyph sbit exists for the index. */
  1176. /* */
  1177. /* <Note> */
  1178. /* The `map.buffer' field is always freed before the glyph is loaded. */
  1179. /* */
  1180. FT_LOCAL_DEF( FT_Error )
  1181. tt_face_load_sbit_image( TT_Face face,
  1182. FT_ULong strike_index,
  1183. FT_UInt glyph_index,
  1184. FT_UInt load_flags,
  1185. FT_Stream stream,
  1186. FT_Bitmap *map,
  1187. TT_SBit_MetricsRec *metrics )
  1188. {
  1189. FT_Error error;
  1190. FT_ULong ebdt_pos, glyph_offset;
  1191. TT_SBit_Strike strike;
  1192. TT_SBit_Range range;
  1193. /* Check whether there is a glyph sbit for the current index */
  1194. error = tt_find_sbit_image( face, glyph_index, strike_index,
  1195. &range, &strike, &glyph_offset );
  1196. if ( error )
  1197. goto Exit;
  1198. /* now, find the location of the `EBDT' table in */
  1199. /* the font file */
  1200. error = face->goto_table( face, TTAG_EBDT, stream, 0 );
  1201. if ( error )
  1202. error = face->goto_table( face, TTAG_bdat, stream, 0 );
  1203. if ( error )
  1204. goto Exit;
  1205. ebdt_pos = FT_STREAM_POS();
  1206. error = Load_SBit_Image( strike, range, ebdt_pos, glyph_offset,
  1207. face->root.glyph, 0, 0, stream, metrics, 0 );
  1208. if ( error )
  1209. goto Exit;
  1210. /* setup vertical metrics if needed */
  1211. if ( strike->flags & 1 )
  1212. {
  1213. /* in case of a horizontal strike only */
  1214. FT_Int advance;
  1215. advance = strike->hori.ascender - strike->hori.descender;
  1216. /* some heuristic values */
  1217. metrics->vertBearingX = (FT_Char)(-metrics->width / 2 );
  1218. metrics->vertBearingY = (FT_Char)( ( advance - metrics->height ) / 2 );
  1219. metrics->vertAdvance = (FT_Char)( advance * 12 / 10 );
  1220. }
  1221. /* Crop the bitmap now, unless specified otherwise */
  1222. if ( load_flags & FT_LOAD_CROP_BITMAP )
  1223. crop_bitmap( map, metrics );
  1224. Exit:
  1225. return error;
  1226. }
  1227. #endif /* FT_CONFIG_OPTION_OLD_INTERNALS */
  1228. /* END */