PageRenderTime 56ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/src/freetype/src/sfnt/ttsbit.c

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