PageRenderTime 65ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 0ms

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

http://ftk.googlecode.com/
C | 2205 lines | 1429 code | 471 blank | 305 comment | 273 complexity | 7d02caf4d5d1a519f902fcc28bfc1bea MD5 | raw file
Possible License(s): LGPL-3.0
  1. /***************************************************************************/
  2. /* */
  3. /* ftobjs.c */
  4. /* */
  5. /* The FreeType private base classes (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_LIST_H
  20. #include FT_OUTLINE_H
  21. #include FT_INTERNAL_VALIDATE_H
  22. #include FT_INTERNAL_OBJECTS_H
  23. #include FT_INTERNAL_DEBUG_H
  24. #include FT_INTERNAL_RFORK_H
  25. #include FT_INTERNAL_STREAM_H
  26. #include FT_INTERNAL_SFNT_H /* for SFNT_Load_Table_Func */
  27. #include FT_TRUETYPE_TABLES_H
  28. #include FT_TRUETYPE_TAGS_H
  29. #include FT_TRUETYPE_IDS_H
  30. #include FT_OUTLINE_H
  31. #include FT_SERVICE_SFNT_H
  32. #include FT_SERVICE_POSTSCRIPT_NAME_H
  33. #include FT_SERVICE_GLYPH_DICT_H
  34. #include FT_SERVICE_TT_CMAP_H
  35. #include FT_SERVICE_KERNING_H
  36. #include FT_SERVICE_TRUETYPE_ENGINE_H
  37. #ifdef FT_CONFIG_OPTION_MAC_FONTS
  38. #include "ftbase.h"
  39. #endif
  40. #define GRID_FIT_METRICS
  41. FT_BASE_DEF( FT_Pointer )
  42. ft_service_list_lookup( FT_ServiceDesc service_descriptors,
  43. const char* service_id )
  44. {
  45. FT_Pointer result = NULL;
  46. FT_ServiceDesc desc = service_descriptors;
  47. if ( desc && service_id )
  48. {
  49. for ( ; desc->serv_id != NULL; desc++ )
  50. {
  51. if ( ft_strcmp( desc->serv_id, service_id ) == 0 )
  52. {
  53. result = (FT_Pointer)desc->serv_data;
  54. break;
  55. }
  56. }
  57. }
  58. return result;
  59. }
  60. FT_BASE_DEF( void )
  61. ft_validator_init( FT_Validator valid,
  62. const FT_Byte* base,
  63. const FT_Byte* limit,
  64. FT_ValidationLevel level )
  65. {
  66. valid->base = base;
  67. valid->limit = limit;
  68. valid->level = level;
  69. valid->error = FT_Err_Ok;
  70. }
  71. FT_BASE_DEF( FT_Int )
  72. ft_validator_run( FT_Validator valid )
  73. {
  74. /* This function doesn't work! None should call it. */
  75. FT_UNUSED( valid );
  76. return -1;
  77. }
  78. FT_BASE_DEF( void )
  79. ft_validator_error( FT_Validator valid,
  80. FT_Error error )
  81. {
  82. /* since the cast below also disables the compiler's */
  83. /* type check, we introduce a dummy variable, which */
  84. /* will be optimized away */
  85. volatile ft_jmp_buf* jump_buffer = &valid->jump_buffer;
  86. valid->error = error;
  87. /* throw away volatileness; use `jump_buffer' or the */
  88. /* compiler may warn about an unused local variable */
  89. ft_longjmp( *(ft_jmp_buf*) jump_buffer, 1 );
  90. }
  91. /*************************************************************************/
  92. /*************************************************************************/
  93. /*************************************************************************/
  94. /**** ****/
  95. /**** ****/
  96. /**** S T R E A M ****/
  97. /**** ****/
  98. /**** ****/
  99. /*************************************************************************/
  100. /*************************************************************************/
  101. /*************************************************************************/
  102. /* create a new input stream from an FT_Open_Args structure */
  103. /* */
  104. FT_BASE_DEF( FT_Error )
  105. FT_Stream_New( FT_Library library,
  106. const FT_Open_Args* args,
  107. FT_Stream *astream )
  108. {
  109. FT_Error error;
  110. FT_Memory memory;
  111. FT_Stream stream;
  112. *astream = 0;
  113. if ( !library )
  114. return FT_Err_Invalid_Library_Handle;
  115. if ( !args )
  116. return FT_Err_Invalid_Argument;
  117. memory = library->memory;
  118. if ( FT_NEW( stream ) )
  119. goto Exit;
  120. stream->memory = memory;
  121. if ( args->flags & FT_OPEN_MEMORY )
  122. {
  123. /* create a memory-based stream */
  124. FT_Stream_OpenMemory( stream,
  125. (const FT_Byte*)args->memory_base,
  126. args->memory_size );
  127. }
  128. else if ( args->flags & FT_OPEN_PATHNAME )
  129. {
  130. /* create a normal system stream */
  131. error = FT_Stream_Open( stream, args->pathname );
  132. stream->pathname.pointer = args->pathname;
  133. }
  134. else if ( ( args->flags & FT_OPEN_STREAM ) && args->stream )
  135. {
  136. /* use an existing, user-provided stream */
  137. /* in this case, we do not need to allocate a new stream object */
  138. /* since the caller is responsible for closing it himself */
  139. FT_FREE( stream );
  140. stream = args->stream;
  141. }
  142. else
  143. error = FT_Err_Invalid_Argument;
  144. if ( error )
  145. FT_FREE( stream );
  146. else
  147. stream->memory = memory; /* just to be certain */
  148. *astream = stream;
  149. Exit:
  150. return error;
  151. }
  152. FT_BASE_DEF( void )
  153. FT_Stream_Free( FT_Stream stream,
  154. FT_Int external )
  155. {
  156. if ( stream )
  157. {
  158. FT_Memory memory = stream->memory;
  159. FT_Stream_Close( stream );
  160. if ( !external )
  161. FT_FREE( stream );
  162. }
  163. }
  164. /*************************************************************************/
  165. /* */
  166. /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
  167. /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
  168. /* messages during execution. */
  169. /* */
  170. #undef FT_COMPONENT
  171. #define FT_COMPONENT trace_objs
  172. /*************************************************************************/
  173. /*************************************************************************/
  174. /*************************************************************************/
  175. /**** ****/
  176. /**** ****/
  177. /**** FACE, SIZE & GLYPH SLOT OBJECTS ****/
  178. /**** ****/
  179. /**** ****/
  180. /*************************************************************************/
  181. /*************************************************************************/
  182. /*************************************************************************/
  183. static FT_Error
  184. ft_glyphslot_init( FT_GlyphSlot slot )
  185. {
  186. FT_Driver driver = slot->face->driver;
  187. FT_Driver_Class clazz = driver->clazz;
  188. FT_Memory memory = driver->root.memory;
  189. FT_Error error = FT_Err_Ok;
  190. FT_Slot_Internal internal;
  191. slot->library = driver->root.library;
  192. if ( FT_NEW( internal ) )
  193. goto Exit;
  194. slot->internal = internal;
  195. if ( FT_DRIVER_USES_OUTLINES( driver ) )
  196. error = FT_GlyphLoader_New( memory, &internal->loader );
  197. if ( !error && clazz->init_slot )
  198. error = clazz->init_slot( slot );
  199. Exit:
  200. return error;
  201. }
  202. FT_BASE_DEF( void )
  203. ft_glyphslot_free_bitmap( FT_GlyphSlot slot )
  204. {
  205. if ( slot->internal && ( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) )
  206. {
  207. FT_Memory memory = FT_FACE_MEMORY( slot->face );
  208. FT_FREE( slot->bitmap.buffer );
  209. slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP;
  210. }
  211. else
  212. {
  213. /* assume that the bitmap buffer was stolen or not */
  214. /* allocated from the heap */
  215. slot->bitmap.buffer = NULL;
  216. }
  217. }
  218. FT_BASE_DEF( void )
  219. ft_glyphslot_set_bitmap( FT_GlyphSlot slot,
  220. FT_Byte* buffer )
  221. {
  222. ft_glyphslot_free_bitmap( slot );
  223. slot->bitmap.buffer = buffer;
  224. FT_ASSERT( (slot->internal->flags & FT_GLYPH_OWN_BITMAP) == 0 );
  225. }
  226. FT_BASE_DEF( FT_Error )
  227. ft_glyphslot_alloc_bitmap( FT_GlyphSlot slot,
  228. FT_ULong size )
  229. {
  230. FT_Memory memory = FT_FACE_MEMORY( slot->face );
  231. FT_Error error;
  232. if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP )
  233. FT_FREE( slot->bitmap.buffer );
  234. else
  235. slot->internal->flags |= FT_GLYPH_OWN_BITMAP;
  236. (void)FT_ALLOC( slot->bitmap.buffer, size );
  237. return error;
  238. }
  239. static void
  240. ft_glyphslot_clear( FT_GlyphSlot slot )
  241. {
  242. /* free bitmap if needed */
  243. ft_glyphslot_free_bitmap( slot );
  244. /* clear all public fields in the glyph slot */
  245. FT_ZERO( &slot->metrics );
  246. FT_ZERO( &slot->outline );
  247. slot->bitmap.width = 0;
  248. slot->bitmap.rows = 0;
  249. slot->bitmap.pitch = 0;
  250. slot->bitmap.pixel_mode = 0;
  251. /* `slot->bitmap.buffer' has been handled by ft_glyphslot_free_bitmap */
  252. slot->bitmap_left = 0;
  253. slot->bitmap_top = 0;
  254. slot->num_subglyphs = 0;
  255. slot->subglyphs = 0;
  256. slot->control_data = 0;
  257. slot->control_len = 0;
  258. slot->other = 0;
  259. slot->format = FT_GLYPH_FORMAT_NONE;
  260. slot->linearHoriAdvance = 0;
  261. slot->linearVertAdvance = 0;
  262. slot->lsb_delta = 0;
  263. slot->rsb_delta = 0;
  264. }
  265. static void
  266. ft_glyphslot_done( FT_GlyphSlot slot )
  267. {
  268. FT_Driver driver = slot->face->driver;
  269. FT_Driver_Class clazz = driver->clazz;
  270. FT_Memory memory = driver->root.memory;
  271. if ( clazz->done_slot )
  272. clazz->done_slot( slot );
  273. /* free bitmap buffer if needed */
  274. ft_glyphslot_free_bitmap( slot );
  275. /* slot->internal might be NULL in out-of-memory situations */
  276. if ( slot->internal )
  277. {
  278. /* free glyph loader */
  279. if ( FT_DRIVER_USES_OUTLINES( driver ) )
  280. {
  281. FT_GlyphLoader_Done( slot->internal->loader );
  282. slot->internal->loader = 0;
  283. }
  284. FT_FREE( slot->internal );
  285. }
  286. }
  287. /* documentation is in ftobjs.h */
  288. FT_BASE_DEF( FT_Error )
  289. FT_New_GlyphSlot( FT_Face face,
  290. FT_GlyphSlot *aslot )
  291. {
  292. FT_Error error;
  293. FT_Driver driver;
  294. FT_Driver_Class clazz;
  295. FT_Memory memory;
  296. FT_GlyphSlot slot;
  297. if ( !face || !face->driver )
  298. return FT_Err_Invalid_Argument;
  299. driver = face->driver;
  300. clazz = driver->clazz;
  301. memory = driver->root.memory;
  302. FT_TRACE4(( "FT_New_GlyphSlot: Creating new slot object\n" ));
  303. if ( !FT_ALLOC( slot, clazz->slot_object_size ) )
  304. {
  305. slot->face = face;
  306. error = ft_glyphslot_init( slot );
  307. if ( error )
  308. {
  309. ft_glyphslot_done( slot );
  310. FT_FREE( slot );
  311. goto Exit;
  312. }
  313. slot->next = face->glyph;
  314. face->glyph = slot;
  315. if ( aslot )
  316. *aslot = slot;
  317. }
  318. else if ( aslot )
  319. *aslot = 0;
  320. Exit:
  321. FT_TRACE4(( "FT_New_GlyphSlot: Return %d\n", error ));
  322. return error;
  323. }
  324. /* documentation is in ftobjs.h */
  325. FT_BASE_DEF( void )
  326. FT_Done_GlyphSlot( FT_GlyphSlot slot )
  327. {
  328. if ( slot )
  329. {
  330. FT_Driver driver = slot->face->driver;
  331. FT_Memory memory = driver->root.memory;
  332. FT_GlyphSlot prev;
  333. FT_GlyphSlot cur;
  334. /* Remove slot from its parent face's list */
  335. prev = NULL;
  336. cur = slot->face->glyph;
  337. while ( cur )
  338. {
  339. if ( cur == slot )
  340. {
  341. if ( !prev )
  342. slot->face->glyph = cur->next;
  343. else
  344. prev->next = cur->next;
  345. ft_glyphslot_done( slot );
  346. FT_FREE( slot );
  347. break;
  348. }
  349. prev = cur;
  350. cur = cur->next;
  351. }
  352. }
  353. }
  354. /* documentation is in freetype.h */
  355. FT_EXPORT_DEF( void )
  356. FT_Set_Transform( FT_Face face,
  357. FT_Matrix* matrix,
  358. FT_Vector* delta )
  359. {
  360. FT_Face_Internal internal;
  361. if ( !face )
  362. return;
  363. internal = face->internal;
  364. internal->transform_flags = 0;
  365. if ( !matrix )
  366. {
  367. internal->transform_matrix.xx = 0x10000L;
  368. internal->transform_matrix.xy = 0;
  369. internal->transform_matrix.yx = 0;
  370. internal->transform_matrix.yy = 0x10000L;
  371. matrix = &internal->transform_matrix;
  372. }
  373. else
  374. internal->transform_matrix = *matrix;
  375. /* set transform_flags bit flag 0 if `matrix' isn't the identity */
  376. if ( ( matrix->xy | matrix->yx ) ||
  377. matrix->xx != 0x10000L ||
  378. matrix->yy != 0x10000L )
  379. internal->transform_flags |= 1;
  380. if ( !delta )
  381. {
  382. internal->transform_delta.x = 0;
  383. internal->transform_delta.y = 0;
  384. delta = &internal->transform_delta;
  385. }
  386. else
  387. internal->transform_delta = *delta;
  388. /* set transform_flags bit flag 1 if `delta' isn't the null vector */
  389. if ( delta->x | delta->y )
  390. internal->transform_flags |= 2;
  391. }
  392. static FT_Renderer
  393. ft_lookup_glyph_renderer( FT_GlyphSlot slot );
  394. #ifdef GRID_FIT_METRICS
  395. static void
  396. ft_glyphslot_grid_fit_metrics( FT_GlyphSlot slot,
  397. FT_Bool vertical )
  398. {
  399. FT_Glyph_Metrics* metrics = &slot->metrics;
  400. FT_Pos right, bottom;
  401. if ( vertical )
  402. {
  403. metrics->horiBearingX = FT_PIX_FLOOR( metrics->horiBearingX );
  404. metrics->horiBearingY = FT_PIX_CEIL ( metrics->horiBearingY );
  405. right = FT_PIX_CEIL( metrics->vertBearingX + metrics->width );
  406. bottom = FT_PIX_CEIL( metrics->vertBearingY + metrics->height );
  407. metrics->vertBearingX = FT_PIX_FLOOR( metrics->vertBearingX );
  408. metrics->vertBearingY = FT_PIX_FLOOR( metrics->vertBearingY );
  409. metrics->width = right - metrics->vertBearingX;
  410. metrics->height = bottom - metrics->vertBearingY;
  411. }
  412. else
  413. {
  414. metrics->vertBearingX = FT_PIX_FLOOR( metrics->vertBearingX );
  415. metrics->vertBearingY = FT_PIX_FLOOR( metrics->vertBearingY );
  416. right = FT_PIX_CEIL ( metrics->horiBearingX + metrics->width );
  417. bottom = FT_PIX_FLOOR( metrics->horiBearingY - metrics->height );
  418. metrics->horiBearingX = FT_PIX_FLOOR( metrics->horiBearingX );
  419. metrics->horiBearingY = FT_PIX_CEIL ( metrics->horiBearingY );
  420. metrics->width = right - metrics->horiBearingX;
  421. metrics->height = metrics->horiBearingY - bottom;
  422. }
  423. metrics->horiAdvance = FT_PIX_ROUND( metrics->horiAdvance );
  424. metrics->vertAdvance = FT_PIX_ROUND( metrics->vertAdvance );
  425. }
  426. #endif /* GRID_FIT_METRICS */
  427. /* documentation is in freetype.h */
  428. FT_EXPORT_DEF( FT_Error )
  429. FT_Load_Glyph( FT_Face face,
  430. FT_UInt glyph_index,
  431. FT_Int32 load_flags )
  432. {
  433. FT_Error error;
  434. FT_Driver driver;
  435. FT_GlyphSlot slot;
  436. FT_Library library;
  437. FT_Bool autohint = FALSE;
  438. FT_Module hinter;
  439. if ( !face || !face->size || !face->glyph )
  440. return FT_Err_Invalid_Face_Handle;
  441. /* The validity test for `glyph_index' is performed by the */
  442. /* font drivers. */
  443. slot = face->glyph;
  444. ft_glyphslot_clear( slot );
  445. driver = face->driver;
  446. library = driver->root.library;
  447. hinter = library->auto_hinter;
  448. /* resolve load flags dependencies */
  449. if ( load_flags & FT_LOAD_NO_RECURSE )
  450. load_flags |= FT_LOAD_NO_SCALE |
  451. FT_LOAD_IGNORE_TRANSFORM;
  452. if ( load_flags & FT_LOAD_NO_SCALE )
  453. {
  454. load_flags |= FT_LOAD_NO_HINTING |
  455. FT_LOAD_NO_BITMAP;
  456. load_flags &= ~FT_LOAD_RENDER;
  457. }
  458. /*
  459. * Determine whether we need to auto-hint or not.
  460. * The general rules are:
  461. *
  462. * - Do only auto-hinting if we have a hinter module, a scalable font
  463. * format dealing with outlines, and no transforms except simple
  464. * slants and/or rotations by integer multiples of 90 degrees.
  465. *
  466. * - Then, auto-hint if FT_LOAD_FORCE_AUTOHINT is set or if we don't
  467. * have a native font hinter.
  468. *
  469. * - Otherwise, auto-hint for LIGHT hinting mode.
  470. *
  471. * - Exception: The font is `tricky' and requires the native hinter to
  472. * load properly.
  473. */
  474. if ( hinter &&
  475. !( load_flags & FT_LOAD_NO_HINTING ) &&
  476. !( load_flags & FT_LOAD_NO_AUTOHINT ) &&
  477. FT_DRIVER_IS_SCALABLE( driver ) &&
  478. FT_DRIVER_USES_OUTLINES( driver ) &&
  479. !FT_IS_TRICKY( face ) &&
  480. ( ( face->internal->transform_matrix.yx == 0 &&
  481. face->internal->transform_matrix.xx != 0 ) ||
  482. ( face->internal->transform_matrix.xx == 0 &&
  483. face->internal->transform_matrix.yx != 0 ) ) )
  484. {
  485. if ( ( load_flags & FT_LOAD_FORCE_AUTOHINT ) ||
  486. !FT_DRIVER_HAS_HINTER( driver ) )
  487. autohint = TRUE;
  488. else
  489. {
  490. FT_Render_Mode mode = FT_LOAD_TARGET_MODE( load_flags );
  491. if ( mode == FT_RENDER_MODE_LIGHT ||
  492. face->internal->ignore_unpatented_hinter )
  493. autohint = TRUE;
  494. }
  495. }
  496. if ( autohint )
  497. {
  498. FT_AutoHinter_Service hinting;
  499. /* try to load embedded bitmaps first if available */
  500. /* */
  501. /* XXX: This is really a temporary hack that should disappear */
  502. /* promptly with FreeType 2.1! */
  503. /* */
  504. if ( FT_HAS_FIXED_SIZES( face ) &&
  505. ( load_flags & FT_LOAD_NO_BITMAP ) == 0 )
  506. {
  507. error = driver->clazz->load_glyph( slot, face->size,
  508. glyph_index,
  509. load_flags | FT_LOAD_SBITS_ONLY );
  510. if ( !error && slot->format == FT_GLYPH_FORMAT_BITMAP )
  511. goto Load_Ok;
  512. }
  513. {
  514. FT_Face_Internal internal = face->internal;
  515. FT_Int transform_flags = internal->transform_flags;
  516. /* since the auto-hinter calls FT_Load_Glyph by itself, */
  517. /* make sure that glyphs aren't transformed */
  518. internal->transform_flags = 0;
  519. /* load auto-hinted outline */
  520. hinting = (FT_AutoHinter_Service)hinter->clazz->module_interface;
  521. error = hinting->load_glyph( (FT_AutoHinter)hinter,
  522. slot, face->size,
  523. glyph_index, load_flags );
  524. internal->transform_flags = transform_flags;
  525. }
  526. }
  527. else
  528. {
  529. error = driver->clazz->load_glyph( slot,
  530. face->size,
  531. glyph_index,
  532. load_flags );
  533. if ( error )
  534. goto Exit;
  535. if ( slot->format == FT_GLYPH_FORMAT_OUTLINE )
  536. {
  537. /* check that the loaded outline is correct */
  538. error = FT_Outline_Check( &slot->outline );
  539. if ( error )
  540. goto Exit;
  541. #ifdef GRID_FIT_METRICS
  542. if ( !( load_flags & FT_LOAD_NO_HINTING ) )
  543. ft_glyphslot_grid_fit_metrics( slot,
  544. FT_BOOL( load_flags & FT_LOAD_VERTICAL_LAYOUT ) );
  545. #endif
  546. }
  547. }
  548. Load_Ok:
  549. /* compute the advance */
  550. if ( load_flags & FT_LOAD_VERTICAL_LAYOUT )
  551. {
  552. slot->advance.x = 0;
  553. slot->advance.y = slot->metrics.vertAdvance;
  554. }
  555. else
  556. {
  557. slot->advance.x = slot->metrics.horiAdvance;
  558. slot->advance.y = 0;
  559. }
  560. /* compute the linear advance in 16.16 pixels */
  561. if ( ( load_flags & FT_LOAD_LINEAR_DESIGN ) == 0 &&
  562. ( FT_IS_SCALABLE( face ) ) )
  563. {
  564. FT_Size_Metrics* metrics = &face->size->metrics;
  565. /* it's tricky! */
  566. slot->linearHoriAdvance = FT_MulDiv( slot->linearHoriAdvance,
  567. metrics->x_scale, 64 );
  568. slot->linearVertAdvance = FT_MulDiv( slot->linearVertAdvance,
  569. metrics->y_scale, 64 );
  570. }
  571. if ( ( load_flags & FT_LOAD_IGNORE_TRANSFORM ) == 0 )
  572. {
  573. FT_Face_Internal internal = face->internal;
  574. /* now, transform the glyph image if needed */
  575. if ( internal->transform_flags )
  576. {
  577. /* get renderer */
  578. FT_Renderer renderer = ft_lookup_glyph_renderer( slot );
  579. if ( renderer )
  580. error = renderer->clazz->transform_glyph(
  581. renderer, slot,
  582. &internal->transform_matrix,
  583. &internal->transform_delta );
  584. else if ( slot->format == FT_GLYPH_FORMAT_OUTLINE )
  585. {
  586. /* apply `standard' transformation if no renderer is available */
  587. if ( &internal->transform_matrix )
  588. FT_Outline_Transform( &slot->outline,
  589. &internal->transform_matrix );
  590. if ( &internal->transform_delta )
  591. FT_Outline_Translate( &slot->outline,
  592. internal->transform_delta.x,
  593. internal->transform_delta.y );
  594. }
  595. /* transform advance */
  596. FT_Vector_Transform( &slot->advance, &internal->transform_matrix );
  597. }
  598. }
  599. FT_TRACE5(( " x advance: %d\n" , slot->advance.x ));
  600. FT_TRACE5(( " y advance: %d\n" , slot->advance.y ));
  601. FT_TRACE5(( " linear x advance: %d\n" , slot->linearHoriAdvance ));
  602. FT_TRACE5(( " linear y advance: %d\n" , slot->linearVertAdvance ));
  603. /* do we need to render the image now? */
  604. if ( !error &&
  605. slot->format != FT_GLYPH_FORMAT_BITMAP &&
  606. slot->format != FT_GLYPH_FORMAT_COMPOSITE &&
  607. load_flags & FT_LOAD_RENDER )
  608. {
  609. FT_Render_Mode mode = FT_LOAD_TARGET_MODE( load_flags );
  610. if ( mode == FT_RENDER_MODE_NORMAL &&
  611. (load_flags & FT_LOAD_MONOCHROME ) )
  612. mode = FT_RENDER_MODE_MONO;
  613. error = FT_Render_Glyph( slot, mode );
  614. }
  615. Exit:
  616. return error;
  617. }
  618. /* documentation is in freetype.h */
  619. FT_EXPORT_DEF( FT_Error )
  620. FT_Load_Char( FT_Face face,
  621. FT_ULong char_code,
  622. FT_Int32 load_flags )
  623. {
  624. FT_UInt glyph_index;
  625. if ( !face )
  626. return FT_Err_Invalid_Face_Handle;
  627. glyph_index = (FT_UInt)char_code;
  628. if ( face->charmap )
  629. glyph_index = FT_Get_Char_Index( face, char_code );
  630. return FT_Load_Glyph( face, glyph_index, load_flags );
  631. }
  632. /* destructor for sizes list */
  633. static void
  634. destroy_size( FT_Memory memory,
  635. FT_Size size,
  636. FT_Driver driver )
  637. {
  638. /* finalize client-specific data */
  639. if ( size->generic.finalizer )
  640. size->generic.finalizer( size );
  641. /* finalize format-specific stuff */
  642. if ( driver->clazz->done_size )
  643. driver->clazz->done_size( size );
  644. FT_FREE( size->internal );
  645. FT_FREE( size );
  646. }
  647. static void
  648. ft_cmap_done_internal( FT_CMap cmap );
  649. static void
  650. destroy_charmaps( FT_Face face,
  651. FT_Memory memory )
  652. {
  653. FT_Int n;
  654. if ( !face )
  655. return;
  656. for ( n = 0; n < face->num_charmaps; n++ )
  657. {
  658. FT_CMap cmap = FT_CMAP( face->charmaps[n] );
  659. ft_cmap_done_internal( cmap );
  660. face->charmaps[n] = NULL;
  661. }
  662. FT_FREE( face->charmaps );
  663. face->num_charmaps = 0;
  664. }
  665. /* destructor for faces list */
  666. static void
  667. destroy_face( FT_Memory memory,
  668. FT_Face face,
  669. FT_Driver driver )
  670. {
  671. FT_Driver_Class clazz = driver->clazz;
  672. /* discard auto-hinting data */
  673. if ( face->autohint.finalizer )
  674. face->autohint.finalizer( face->autohint.data );
  675. /* Discard glyph slots for this face. */
  676. /* Beware! FT_Done_GlyphSlot() changes the field `face->glyph' */
  677. while ( face->glyph )
  678. FT_Done_GlyphSlot( face->glyph );
  679. /* discard all sizes for this face */
  680. FT_List_Finalize( &face->sizes_list,
  681. (FT_List_Destructor)destroy_size,
  682. memory,
  683. driver );
  684. face->size = 0;
  685. /* now discard client data */
  686. if ( face->generic.finalizer )
  687. face->generic.finalizer( face );
  688. /* discard charmaps */
  689. destroy_charmaps( face, memory );
  690. /* finalize format-specific stuff */
  691. if ( clazz->done_face )
  692. clazz->done_face( face );
  693. /* close the stream for this face if needed */
  694. FT_Stream_Free(
  695. face->stream,
  696. ( face->face_flags & FT_FACE_FLAG_EXTERNAL_STREAM ) != 0 );
  697. face->stream = 0;
  698. /* get rid of it */
  699. if ( face->internal )
  700. {
  701. FT_FREE( face->internal );
  702. }
  703. FT_FREE( face );
  704. }
  705. static void
  706. Destroy_Driver( FT_Driver driver )
  707. {
  708. FT_List_Finalize( &driver->faces_list,
  709. (FT_List_Destructor)destroy_face,
  710. driver->root.memory,
  711. driver );
  712. /* check whether we need to drop the driver's glyph loader */
  713. if ( FT_DRIVER_USES_OUTLINES( driver ) )
  714. FT_GlyphLoader_Done( driver->glyph_loader );
  715. }
  716. /*************************************************************************/
  717. /* */
  718. /* <Function> */
  719. /* find_unicode_charmap */
  720. /* */
  721. /* <Description> */
  722. /* This function finds a Unicode charmap, if there is one. */
  723. /* And if there is more than one, it tries to favour the more */
  724. /* extensive one, i.e., one that supports UCS-4 against those which */
  725. /* are limited to the BMP (said UCS-2 encoding.) */
  726. /* */
  727. /* This function is called from open_face() (just below), and also */
  728. /* from FT_Select_Charmap( ..., FT_ENCODING_UNICODE ). */
  729. /* */
  730. static FT_Error
  731. find_unicode_charmap( FT_Face face )
  732. {
  733. FT_CharMap* first;
  734. FT_CharMap* cur;
  735. /* caller should have already checked that `face' is valid */
  736. FT_ASSERT( face );
  737. first = face->charmaps;
  738. if ( !first )
  739. return FT_Err_Invalid_CharMap_Handle;
  740. /*
  741. * The original TrueType specification(s) only specified charmap
  742. * formats that are capable of mapping 8 or 16 bit character codes to
  743. * glyph indices.
  744. *
  745. * However, recent updates to the Apple and OpenType specifications
  746. * introduced new formats that are capable of mapping 32-bit character
  747. * codes as well. And these are already used on some fonts, mainly to
  748. * map non-BMP Asian ideographs as defined in Unicode.
  749. *
  750. * For compatibility purposes, these fonts generally come with
  751. * *several* Unicode charmaps:
  752. *
  753. * - One of them in the "old" 16-bit format, that cannot access
  754. * all glyphs in the font.
  755. *
  756. * - Another one in the "new" 32-bit format, that can access all
  757. * the glyphs.
  758. *
  759. * This function has been written to always favor a 32-bit charmap
  760. * when found. Otherwise, a 16-bit one is returned when found.
  761. */
  762. /* Since the `interesting' table, with IDs (3,10), is normally the */
  763. /* last one, we loop backwards. This loses with type1 fonts with */
  764. /* non-BMP characters (<.0001%), this wins with .ttf with non-BMP */
  765. /* chars (.01% ?), and this is the same about 99.99% of the time! */
  766. cur = first + face->num_charmaps; /* points after the last one */
  767. for ( ; --cur >= first; )
  768. {
  769. if ( cur[0]->encoding == FT_ENCODING_UNICODE )
  770. {
  771. /* XXX If some new encodings to represent UCS-4 are added, */
  772. /* they should be added here. */
  773. if ( ( cur[0]->platform_id == TT_PLATFORM_MICROSOFT &&
  774. cur[0]->encoding_id == TT_MS_ID_UCS_4 ) ||
  775. ( cur[0]->platform_id == TT_PLATFORM_APPLE_UNICODE &&
  776. cur[0]->encoding_id == TT_APPLE_ID_UNICODE_32 ) )
  777. {
  778. face->charmap = cur[0];
  779. return FT_Err_Ok;
  780. }
  781. }
  782. }
  783. /* We do not have any UCS-4 charmap. */
  784. /* Do the loop again and search for UCS-2 charmaps. */
  785. cur = first + face->num_charmaps;
  786. for ( ; --cur >= first; )
  787. {
  788. if ( cur[0]->encoding == FT_ENCODING_UNICODE )
  789. {
  790. face->charmap = cur[0];
  791. return FT_Err_Ok;
  792. }
  793. }
  794. return FT_Err_Invalid_CharMap_Handle;
  795. }
  796. /*************************************************************************/
  797. /* */
  798. /* <Function> */
  799. /* find_variant_selector_charmap */
  800. /* */
  801. /* <Description> */
  802. /* This function finds the variant selector charmap, if there is one. */
  803. /* There can only be one (platform=0, specific=5, format=14). */
  804. /* */
  805. static FT_CharMap
  806. find_variant_selector_charmap( FT_Face face )
  807. {
  808. FT_CharMap* first;
  809. FT_CharMap* end;
  810. FT_CharMap* cur;
  811. /* caller should have already checked that `face' is valid */
  812. FT_ASSERT( face );
  813. first = face->charmaps;
  814. if ( !first )
  815. return NULL;
  816. end = first + face->num_charmaps; /* points after the last one */
  817. for ( cur = first; cur < end; ++cur )
  818. {
  819. if ( cur[0]->platform_id == TT_PLATFORM_APPLE_UNICODE &&
  820. cur[0]->encoding_id == TT_APPLE_ID_VARIANT_SELECTOR &&
  821. FT_Get_CMap_Format( cur[0] ) == 14 )
  822. return cur[0];
  823. }
  824. return NULL;
  825. }
  826. /*************************************************************************/
  827. /* */
  828. /* <Function> */
  829. /* open_face */
  830. /* */
  831. /* <Description> */
  832. /* This function does some work for FT_Open_Face(). */
  833. /* */
  834. static FT_Error
  835. open_face( FT_Driver driver,
  836. FT_Stream stream,
  837. FT_Long face_index,
  838. FT_Int num_params,
  839. FT_Parameter* params,
  840. FT_Face *aface )
  841. {
  842. FT_Memory memory;
  843. FT_Driver_Class clazz;
  844. FT_Face face = 0;
  845. FT_Error error, error2;
  846. FT_Face_Internal internal = NULL;
  847. clazz = driver->clazz;
  848. memory = driver->root.memory;
  849. /* allocate the face object and perform basic initialization */
  850. if ( FT_ALLOC( face, clazz->face_object_size ) )
  851. goto Fail;
  852. if ( FT_NEW( internal ) )
  853. goto Fail;
  854. face->internal = internal;
  855. face->driver = driver;
  856. face->memory = memory;
  857. face->stream = stream;
  858. #ifdef FT_CONFIG_OPTION_INCREMENTAL
  859. {
  860. int i;
  861. face->internal->incremental_interface = 0;
  862. for ( i = 0; i < num_params && !face->internal->incremental_interface;
  863. i++ )
  864. if ( params[i].tag == FT_PARAM_TAG_INCREMENTAL )
  865. face->internal->incremental_interface =
  866. (FT_Incremental_Interface)params[i].data;
  867. }
  868. #endif
  869. if ( clazz->init_face )
  870. error = clazz->init_face( stream,
  871. face,
  872. (FT_Int)face_index,
  873. num_params,
  874. params );
  875. if ( error )
  876. goto Fail;
  877. /* select Unicode charmap by default */
  878. error2 = find_unicode_charmap( face );
  879. /* if no Unicode charmap can be found, FT_Err_Invalid_CharMap_Handle */
  880. /* is returned. */
  881. /* no error should happen, but we want to play safe */
  882. if ( error2 && error2 != FT_Err_Invalid_CharMap_Handle )
  883. {
  884. error = error2;
  885. goto Fail;
  886. }
  887. *aface = face;
  888. Fail:
  889. if ( error )
  890. {
  891. destroy_charmaps( face, memory );
  892. if ( clazz->done_face )
  893. clazz->done_face( face );
  894. FT_FREE( internal );
  895. FT_FREE( face );
  896. *aface = 0;
  897. }
  898. return error;
  899. }
  900. /* there's a Mac-specific extended implementation of FT_New_Face() */
  901. /* in src/base/ftmac.c */
  902. #if !defined( FT_MACINTOSH ) || defined( DARWIN_NO_CARBON )
  903. /* documentation is in freetype.h */
  904. FT_EXPORT_DEF( FT_Error )
  905. FT_New_Face( FT_Library library,
  906. const char* pathname,
  907. FT_Long face_index,
  908. FT_Face *aface )
  909. {
  910. FT_Open_Args args;
  911. /* test for valid `library' and `aface' delayed to FT_Open_Face() */
  912. if ( !pathname )
  913. return FT_Err_Invalid_Argument;
  914. args.flags = FT_OPEN_PATHNAME;
  915. args.pathname = (char*)pathname;
  916. args.stream = NULL;
  917. return FT_Open_Face( library, &args, face_index, aface );
  918. }
  919. #endif /* defined( FT_MACINTOSH ) && !defined( DARWIN_NO_CARBON ) */
  920. /* documentation is in freetype.h */
  921. FT_EXPORT_DEF( FT_Error )
  922. FT_New_Memory_Face( FT_Library library,
  923. const FT_Byte* file_base,
  924. FT_Long file_size,
  925. FT_Long face_index,
  926. FT_Face *aface )
  927. {
  928. FT_Open_Args args;
  929. /* test for valid `library' and `face' delayed to FT_Open_Face() */
  930. if ( !file_base )
  931. return FT_Err_Invalid_Argument;
  932. args.flags = FT_OPEN_MEMORY;
  933. args.memory_base = file_base;
  934. args.memory_size = file_size;
  935. args.stream = NULL;
  936. return FT_Open_Face( library, &args, face_index, aface );
  937. }
  938. #ifdef FT_CONFIG_OPTION_MAC_FONTS
  939. /* The behavior here is very similar to that in base/ftmac.c, but it */
  940. /* is designed to work on non-mac systems, so no mac specific calls. */
  941. /* */
  942. /* We look at the file and determine if it is a mac dfont file or a mac */
  943. /* resource file, or a macbinary file containing a mac resource file. */
  944. /* */
  945. /* Unlike ftmac I'm not going to look at a `FOND'. I don't really see */
  946. /* the point, especially since there may be multiple `FOND' resources. */
  947. /* Instead I'll just look for `sfnt' and `POST' resources, ordered as */
  948. /* they occur in the file. */
  949. /* */
  950. /* Note that multiple `POST' resources do not mean multiple postscript */
  951. /* fonts; they all get jammed together to make what is essentially a */
  952. /* pfb file. */
  953. /* */
  954. /* We aren't interested in `NFNT' or `FONT' bitmap resources. */
  955. /* */
  956. /* As soon as we get an `sfnt' load it into memory and pass it off to */
  957. /* FT_Open_Face. */
  958. /* */
  959. /* If we have a (set of) `POST' resources, massage them into a (memory) */
  960. /* pfb file and pass that to FT_Open_Face. (As with ftmac.c I'm not */
  961. /* going to try to save the kerning info. After all that lives in the */
  962. /* `FOND' which isn't in the file containing the `POST' resources so */
  963. /* we don't really have access to it. */
  964. /* Finalizer for a memory stream; gets called by FT_Done_Face(). */
  965. /* It frees the memory it uses. */
  966. /* From ftmac.c. */
  967. static void
  968. memory_stream_close( FT_Stream stream )
  969. {
  970. FT_Memory memory = stream->memory;
  971. FT_FREE( stream->base );
  972. stream->size = 0;
  973. stream->base = 0;
  974. stream->close = 0;
  975. }
  976. /* Create a new memory stream from a buffer and a size. */
  977. /* From ftmac.c. */
  978. static FT_Error
  979. new_memory_stream( FT_Library library,
  980. FT_Byte* base,
  981. FT_ULong size,
  982. FT_Stream_CloseFunc close,
  983. FT_Stream *astream )
  984. {
  985. FT_Error error;
  986. FT_Memory memory;
  987. FT_Stream stream;
  988. if ( !library )
  989. return FT_Err_Invalid_Library_Handle;
  990. if ( !base )
  991. return FT_Err_Invalid_Argument;
  992. *astream = 0;
  993. memory = library->memory;
  994. if ( FT_NEW( stream ) )
  995. goto Exit;
  996. FT_Stream_OpenMemory( stream, base, size );
  997. stream->close = close;
  998. *astream = stream;
  999. Exit:
  1000. return error;
  1001. }
  1002. /* Create a new FT_Face given a buffer and a driver name. */
  1003. /* from ftmac.c */
  1004. FT_LOCAL_DEF( FT_Error )
  1005. open_face_from_buffer( FT_Library library,
  1006. FT_Byte* base,
  1007. FT_ULong size,
  1008. FT_Long face_index,
  1009. const char* driver_name,
  1010. FT_Face *aface )
  1011. {
  1012. FT_Open_Args args;
  1013. FT_Error error;
  1014. FT_Stream stream = NULL;
  1015. FT_Memory memory = library->memory;
  1016. error = new_memory_stream( library,
  1017. base,
  1018. size,
  1019. memory_stream_close,
  1020. &stream );
  1021. if ( error )
  1022. {
  1023. FT_FREE( base );
  1024. return error;
  1025. }
  1026. args.flags = FT_OPEN_STREAM;
  1027. args.stream = stream;
  1028. if ( driver_name )
  1029. {
  1030. args.flags = args.flags | FT_OPEN_DRIVER;
  1031. args.driver = FT_Get_Module( library, driver_name );
  1032. }
  1033. #ifdef FT_MACINTOSH
  1034. /* At this point, face_index has served its purpose; */
  1035. /* whoever calls this function has already used it to */
  1036. /* locate the correct font data. We should not propagate */
  1037. /* this index to FT_Open_Face() (unless it is negative). */
  1038. if ( face_index > 0 )
  1039. face_index = 0;
  1040. #endif
  1041. error = FT_Open_Face( library, &args, face_index, aface );
  1042. if ( error == FT_Err_Ok )
  1043. (*aface)->face_flags &= ~FT_FACE_FLAG_EXTERNAL_STREAM;
  1044. else
  1045. #ifdef FT_MACINTOSH
  1046. FT_Stream_Free( stream, 0 );
  1047. #else
  1048. {
  1049. FT_Stream_Close( stream );
  1050. FT_FREE( stream );
  1051. }
  1052. #endif
  1053. return error;
  1054. }
  1055. /* Look up `TYP1' or `CID ' table from sfnt table directory. */
  1056. /* `offset' and `length' must exclude the binary header in tables. */
  1057. /* Type 1 and CID-keyed font drivers should recognize sfnt-wrapped */
  1058. /* format too. Here, since we can't expect that the TrueType font */
  1059. /* driver is loaded unconditially, we must parse the font by */
  1060. /* ourselves. We are only interested in the name of the table and */
  1061. /* the offset. */
  1062. static FT_Error
  1063. ft_lookup_PS_in_sfnt_stream( FT_Stream stream,
  1064. FT_Long face_index,
  1065. FT_ULong* offset,
  1066. FT_ULong* length,
  1067. FT_Bool* is_sfnt_cid )
  1068. {
  1069. FT_Error error;
  1070. FT_UShort numTables;
  1071. FT_Long pstable_index;
  1072. FT_ULong tag;
  1073. int i;
  1074. *offset = 0;
  1075. *length = 0;
  1076. *is_sfnt_cid = FALSE;
  1077. /* TODO: support for sfnt-wrapped PS/CID in TTC format */
  1078. /* version check for 'typ1' (should be ignored?) */
  1079. if ( FT_READ_ULONG( tag ) )
  1080. return error;
  1081. if ( tag != TTAG_typ1 )
  1082. return FT_Err_Unknown_File_Format;
  1083. if ( FT_READ_USHORT( numTables ) )
  1084. return error;
  1085. if ( FT_STREAM_SKIP( 2 * 3 ) ) /* skip binary search header */
  1086. return error;
  1087. pstable_index = -1;
  1088. *is_sfnt_cid = FALSE;
  1089. for ( i = 0; i < numTables; i++ )
  1090. {
  1091. if ( FT_READ_ULONG( tag ) || FT_STREAM_SKIP( 4 ) ||
  1092. FT_READ_ULONG( *offset ) || FT_READ_ULONG( *length ) )
  1093. return error;
  1094. if ( tag == TTAG_CID )
  1095. {
  1096. pstable_index++;
  1097. *offset += 22;
  1098. *length -= 22;
  1099. *is_sfnt_cid = TRUE;
  1100. if ( face_index < 0 )
  1101. return FT_Err_Ok;
  1102. }
  1103. else if ( tag == TTAG_TYP1 )
  1104. {
  1105. pstable_index++;
  1106. *offset += 24;
  1107. *length -= 24;
  1108. *is_sfnt_cid = FALSE;
  1109. if ( face_index < 0 )
  1110. return FT_Err_Ok;
  1111. }
  1112. if ( face_index >= 0 && pstable_index == face_index )
  1113. return FT_Err_Ok;
  1114. }
  1115. return FT_Err_Table_Missing;
  1116. }
  1117. FT_LOCAL_DEF( FT_Error )
  1118. open_face_PS_from_sfnt_stream( FT_Library library,
  1119. FT_Stream stream,
  1120. FT_Long face_index,
  1121. FT_Int num_params,
  1122. FT_Parameter *params,
  1123. FT_Face *aface )
  1124. {
  1125. FT_Error error;
  1126. FT_Memory memory = library->memory;
  1127. FT_ULong offset, length;
  1128. FT_Long pos;
  1129. FT_Bool is_sfnt_cid;
  1130. FT_Byte* sfnt_ps;
  1131. FT_UNUSED( num_params );
  1132. FT_UNUSED( params );
  1133. pos = FT_Stream_Pos( stream );
  1134. error = ft_lookup_PS_in_sfnt_stream( stream,
  1135. face_index,
  1136. &offset,
  1137. &length,
  1138. &is_sfnt_cid );
  1139. if ( error )
  1140. goto Exit;
  1141. if ( FT_Stream_Seek( stream, pos + offset ) )
  1142. goto Exit;
  1143. if ( FT_ALLOC( sfnt_ps, (FT_Long)length ) )
  1144. goto Exit;
  1145. error = FT_Stream_Read( stream, (FT_Byte *)sfnt_ps, length );
  1146. if ( error )
  1147. goto Exit;
  1148. error = open_face_from_buffer( library,
  1149. sfnt_ps,
  1150. length,
  1151. face_index < 0 ? face_index : 0,
  1152. is_sfnt_cid ? "cid" : "type1",
  1153. aface );
  1154. Exit:
  1155. {
  1156. FT_Error error1;
  1157. if ( error == FT_Err_Unknown_File_Format )
  1158. {
  1159. error1 = FT_Stream_Seek( stream, pos );
  1160. if ( error1 )
  1161. return error1;
  1162. }
  1163. return error;
  1164. }
  1165. }
  1166. #if !defined( FT_MACINTOSH ) || defined( DARWIN_NO_CARBON )
  1167. /* The resource header says we've got resource_cnt `POST' (type1) */
  1168. /* resources in this file. They all need to be coalesced into */
  1169. /* one lump which gets passed on to the type1 driver. */
  1170. /* Here can be only one PostScript font in a file so face_index */
  1171. /* must be 0 (or -1). */
  1172. /* */
  1173. static FT_Error
  1174. Mac_Read_POST_Resource( FT_Library library,
  1175. FT_Stream stream,
  1176. FT_Long *offsets,
  1177. FT_Long resource_cnt,
  1178. FT_Long face_index,
  1179. FT_Face *aface )
  1180. {
  1181. FT_Error error = FT_Err_Cannot_Open_Resource;
  1182. FT_Memory memory = library->memory;
  1183. FT_Byte* pfb_data;
  1184. int i, type, flags;
  1185. FT_Long len;
  1186. FT_Long pfb_len, pfb_pos, pfb_lenpos;
  1187. FT_Long rlen, temp;
  1188. if ( face_index == -1 )
  1189. face_index = 0;
  1190. if ( face_index != 0 )
  1191. return error;
  1192. /* Find the length of all the POST resources, concatenated. Assume */
  1193. /* worst case (each resource in its own section). */
  1194. pfb_len = 0;
  1195. for ( i = 0; i < resource_cnt; ++i )
  1196. {
  1197. error = FT_Stream_Seek( stream, offsets[i] );
  1198. if ( error )
  1199. goto Exit;
  1200. if ( FT_READ_LONG( temp ) )
  1201. goto Exit;
  1202. pfb_len += temp + 6;
  1203. }
  1204. if ( FT_ALLOC( pfb_data, (FT_Long)pfb_len + 2 ) )
  1205. goto Exit;
  1206. pfb_data[0] = 0x80;
  1207. pfb_data[1] = 1; /* Ascii section */
  1208. pfb_data[2] = 0; /* 4-byte length, fill in later */
  1209. pfb_data[3] = 0;
  1210. pfb_data[4] = 0;
  1211. pfb_data[5] = 0;
  1212. pfb_pos = 6;
  1213. pfb_lenpos = 2;
  1214. len = 0;
  1215. type = 1;
  1216. for ( i = 0; i < resource_cnt; ++i )
  1217. {
  1218. error = FT_Stream_Seek( stream, offsets[i] );
  1219. if ( error )
  1220. goto Exit2;
  1221. if ( FT_READ_LONG( rlen ) )
  1222. goto Exit;
  1223. if ( FT_READ_USHORT( flags ) )
  1224. goto Exit;
  1225. rlen -= 2; /* the flags are part of the resource */
  1226. if ( ( flags >> 8 ) == type )
  1227. len += rlen;
  1228. else
  1229. {
  1230. pfb_data[pfb_lenpos ] = (FT_Byte)( len );
  1231. pfb_data[pfb_lenpos + 1] = (FT_Byte)( len >> 8 );
  1232. pfb_data[pfb_lenpos + 2] = (FT_Byte)( len >> 16 );
  1233. pfb_data[pfb_lenpos + 3] = (FT_Byte)( len >> 24 );
  1234. if ( ( flags >> 8 ) == 5 ) /* End of font mark */
  1235. break;
  1236. pfb_data[pfb_pos++] = 0x80;
  1237. type = flags >> 8;
  1238. len = rlen;
  1239. pfb_data[pfb_pos++] = (FT_Byte)type;
  1240. pfb_lenpos = pfb_pos;
  1241. pfb_data[pfb_pos++] = 0; /* 4-byte length, fill in later */
  1242. pfb_data[pfb_pos++] = 0;
  1243. pfb_data[pfb_pos++] = 0;
  1244. pfb_data[pfb_pos++] = 0;
  1245. }
  1246. error = FT_Stream_Read( stream, (FT_Byte *)pfb_data + pfb_pos, rlen );
  1247. pfb_pos += rlen;
  1248. }
  1249. pfb_data[pfb_pos++] = 0x80;
  1250. pfb_data[pfb_pos++] = 3;
  1251. pfb_data[pfb_lenpos ] = (FT_Byte)( len );
  1252. pfb_data[pfb_lenpos + 1] = (FT_Byte)( len >> 8 );
  1253. pfb_data[pfb_lenpos + 2] = (FT_Byte)( len >> 16 );
  1254. pfb_data[pfb_lenpos + 3] = (FT_Byte)( len >> 24 );
  1255. return open_face_from_buffer( library,
  1256. pfb_data,
  1257. pfb_pos,
  1258. face_index,
  1259. "type1",
  1260. aface );
  1261. Exit2:
  1262. FT_FREE( pfb_data );
  1263. Exit:
  1264. return error;
  1265. }
  1266. /* The resource header says we've got resource_cnt `sfnt' */
  1267. /* (TrueType/OpenType) resources in this file. Look through */
  1268. /* them for the one indicated by face_index, load it into mem, */
  1269. /* pass it on the the truetype driver and return it. */
  1270. /* */
  1271. static FT_Error
  1272. Mac_Read_sfnt_Resource( FT_Library library,
  1273. FT_Stream stream,
  1274. FT_Long *offsets,
  1275. FT_Long resource_cnt,
  1276. FT_Long face_index,
  1277. FT_Face *aface )
  1278. {
  1279. FT_Memory memory = library->memory;
  1280. FT_Byte* sfnt_data;
  1281. FT_Error error;
  1282. FT_Long flag_offset;
  1283. FT_Long rlen;
  1284. int is_cff;
  1285. FT_Long face_index_in_resource = 0;
  1286. if ( face_index == -1 )
  1287. face_index = 0;
  1288. if ( face_index >= resource_cnt )
  1289. return FT_Err_Cannot_Open_Resource;
  1290. flag_offset = offsets[face_index];
  1291. error = FT_Stream_Seek( stream, flag_offset );
  1292. if ( error )
  1293. goto Exit;
  1294. if ( FT_READ_LONG( rlen ) )
  1295. goto Exit;
  1296. if ( rlen == -1 )
  1297. return FT_Err_Cannot_Open_Resource;
  1298. error = open_face_PS_from_sfnt_stream( library,
  1299. stream,
  1300. face_index,
  1301. 0, NULL,
  1302. aface );
  1303. if ( !error )
  1304. goto Exit;
  1305. /* rewind sfnt stream before open_face_PS_from_sfnt_stream() */
  1306. if ( FT_Stream_Seek( stream, flag_offset + 4 ) )
  1307. goto Exit;
  1308. if ( FT_ALLOC( sfnt_data, (FT_Long)rlen ) )
  1309. return error;
  1310. error = FT_Stream_Read( stream, (FT_Byte *)sfnt_data, rlen );
  1311. if ( error )
  1312. goto Exit;
  1313. is_cff = rlen > 4 && !ft_memcmp( sfnt_data, "OTTO", 4 );
  1314. error = open_face_from_buffer( library,
  1315. sfnt_data,
  1316. rlen,
  1317. face_index_in_resource,
  1318. is_cff ? "cff" : "truetype",
  1319. aface );
  1320. Exit:
  1321. return error;
  1322. }
  1323. /* Check for a valid resource fork header, or a valid dfont */
  1324. /* header. In a resource fork the first 16 bytes are repeated */
  1325. /* at the location specified by bytes 4-7. In a dfont bytes */
  1326. /* 4-7 point to 16 bytes of zeroes instead. */
  1327. /* */
  1328. static FT_Error
  1329. IsMacResource( FT_Library library,
  1330. FT_Stream stream,
  1331. FT_Long resource_offset,
  1332. FT_Long face_index,
  1333. FT_Face *aface )
  1334. {
  1335. FT_Memory memory = library->memory;
  1336. FT_Error error;
  1337. FT_Long map_offset, rdara_pos;
  1338. FT_Long *data_offsets;
  1339. FT_Long count;
  1340. error = FT_Raccess_Get_HeaderInfo( library, stream, resource_offset,
  1341. &map_offset, &rdara_pos );
  1342. if ( error )
  1343. return error;
  1344. error = FT_Raccess_Get_DataOffsets( library, stream,
  1345. map_offset, rdara_pos,
  1346. TTAG_POST,
  1347. &data_offsets, &count );
  1348. if ( !error )
  1349. {
  1350. error = Mac_Read_POST_Resource( library, stream, data_offsets, count,
  1351. face_index, aface );
  1352. FT_FREE( data_offsets );
  1353. /* POST exists in an LWFN providing a single face */
  1354. if ( !error )
  1355. (*aface)->num_faces = 1;
  1356. return error;
  1357. }
  1358. error = FT_Raccess_Get_DataOffsets( library, stream,
  1359. map_offset, rdara_pos,
  1360. TTAG_sfnt,
  1361. &data_offsets, &count );
  1362. if ( !error )
  1363. {
  1364. FT_Long face_index_internal = face_index % count;
  1365. error = Mac_Read_sfnt_Resource( library, stream, data_offsets, count,
  1366. face_index_internal, aface );
  1367. FT_FREE( data_offsets );
  1368. if ( !error )
  1369. (*aface)->num_faces = count;
  1370. }
  1371. return error;
  1372. }
  1373. /* Check for a valid macbinary header, and if we find one */
  1374. /* check that the (flattened) resource fork in it is valid. */
  1375. /* */
  1376. static FT_Error
  1377. IsMacBinary( FT_Library library,
  1378. FT_Stream stream,
  1379. FT_Long face_index,
  1380. FT_Face *aface )
  1381. {
  1382. unsigned char header[128];
  1383. FT_Error error;
  1384. FT_Long dlen, offset;
  1385. if ( NULL == stream )
  1386. return FT_Err_Invalid_Stream_Operation;
  1387. error = FT_Stream_Seek( stream, 0 );
  1388. if ( error )
  1389. goto Exit;
  1390. error = FT_Stream_Read( stream, (FT_Byte*)header, 128 );
  1391. if ( error )
  1392. goto Exit;
  1393. if ( header[ 0] != 0 ||
  1394. header[74] != 0 ||
  1395. header[82] != 0 ||
  1396. header[ 1] == 0 ||
  1397. header[ 1] > 33 ||
  1398. header[63] != 0 ||
  1399. header[2 + header[1]] != 0 )
  1400. return FT_Err_Unknown_File_Format;
  1401. dlen = ( header[0x53] << 24 ) |
  1402. ( header[0x54] << 16 ) |
  1403. ( header[0x55] << 8 ) |
  1404. header[0x56];
  1405. #if 0
  1406. rlen = ( header[0x57] << 24 ) |
  1407. ( header[0x58] << 16 ) |
  1408. ( header[0x59] << 8 ) |
  1409. header[0x5a];
  1410. #endif /* 0 */
  1411. offset = 128 + ( ( dlen + 127 ) & ~127 );
  1412. return IsMacResource( library, stream, offset, face_index, aface );
  1413. Exit:
  1414. return error;
  1415. }
  1416. static FT_Error
  1417. load_face_in_embedded_rfork( FT_Library library,
  1418. FT_Stream stream,
  1419. FT_Long face_index,
  1420. FT_Face *aface,
  1421. const FT_Open_Args *args )
  1422. {
  1423. #undef FT_COMPONENT
  1424. #define FT_COMPONENT trace_raccess
  1425. FT_Memory memory = library->memory;
  1426. FT_Error error = FT_Err_Unknown_File_Format;
  1427. int i;
  1428. char * file_names[FT_RACCESS_N_RULES];
  1429. FT_Long offsets[FT_RACCESS_N_RULES];
  1430. FT_Error errors[FT_RACCESS_N_RULES];
  1431. FT_Open_Args args2;
  1432. FT_Stream stream2 = 0;
  1433. FT_Raccess_Guess( library, stream,
  1434. args->pathname, file_names, offsets, errors );
  1435. for ( i = 0; i < FT_RACCESS_N_RULES; i++ )
  1436. {
  1437. if ( errors[i] )
  1438. {
  1439. FT_TRACE3(( "Error[%d] has occurred in rule %d\n", errors[i], i ));
  1440. continue;
  1441. }
  1442. args2.flags = FT_OPEN_PATHNAME;
  1443. args2.pathname = file_names[i] ? file_names[i] : args->pathname;
  1444. FT_TRACE3(( "Try rule %d: %s (offset=%d) ...",
  1445. i, args2.pathname, offsets[i] ));
  1446. error = FT_Stream_New( library, &args2, &stream2 );
  1447. if ( error )
  1448. {
  1449. FT_TRACE3(( "failed\n" ));
  1450. continue;
  1451. }
  1452. error = IsMacResource( library, stream2, offsets[i],
  1453. face_index, aface );
  1454. FT_Stream_Free( stream2, 0 );
  1455. FT_TRACE3(( "%s\n", error ? "failed": "successful" ));
  1456. if ( !error )
  1457. break;
  1458. }
  1459. for (i = 0; i < FT_RACCESS_N_RULES; i++)
  1460. {
  1461. if ( file_names[i] )
  1462. FT_FREE( file_names[i] );
  1463. }
  1464. /* Caller (load_mac_face) requires FT_Err_Unknown_File_Format. */
  1465. if ( error )
  1466. error = FT_Err_Unknown_File_Format;
  1467. return error;
  1468. #undef FT_COMPONENT
  1469. #define FT_COMPONENT trace_objs
  1470. }
  1471. /* Check for some macintosh formats without Carbon framework. */
  1472. /* Is this a macbinary file? If so look at the resource fork. */
  1473. /* Is this a mac dfont file? */
  1474. /* Is this an old style resource fork? (in data) */
  1475. /* Else call load_face_in_embedded_rfork to try extra rules */
  1476. /* (defined in `ftrfork.c'). */
  1477. /* */
  1478. static FT_Error
  1479. load_mac_face( FT_Library library,
  1480. FT_Stream stream,
  1481. FT_Long face_index,
  1482. FT_Face *aface,
  1483. const FT_Open_Args *args )
  1484. {
  1485. FT_Error error;
  1486. FT_UNUSED( args );
  1487. error = IsMacBinary( library, stream, face_index, aface );
  1488. if ( FT_ERROR_BASE( error ) == FT_Err_Unknown_File_Format )
  1489. {
  1490. #undef FT_COMPONENT
  1491. #define FT_COMPONENT trace_raccess
  1492. FT_TRACE3(( "Try as dfont: %s ...", args->pathname ));
  1493. error = IsMacResource( library, stream, 0, face_index, aface );
  1494. FT_TRACE3(( "%s\n", error ? "failed" : "successful" ));
  1495. #undef FT_COMPONENT
  1496. #define FT_COMPONENT trace_objs
  1497. }
  1498. if ( ( FT_ERROR_BASE( error ) == FT_Err_Unknown_File_Format ||
  1499. FT_ERROR_BASE( error ) == FT_Err_Invalid_Stream_Operation ) &&
  1500. ( args->flags & FT_OPEN_PATHNAME ) )
  1501. error = load_face_in_embedded_rfork( library, stream,
  1502. face_index, aface, args );
  1503. return error;
  1504. }
  1505. #endif
  1506. #endif /* !FT_MACINTOSH && FT_CONFIG_OPTION_MAC_FONTS */
  1507. /* documentation is in freetype.h */
  1508. FT_EXPORT_DEF( FT_Error )
  1509. FT_Open_Face( FT_Library library,
  1510. const FT_Open_Args* args,
  1511. FT_Long face_index,
  1512. FT_Face *aface )
  1513. {
  1514. FT_Error error;
  1515. FT_Driver driver;
  1516. FT_Memory memory;
  1517. FT_Stream stream = 0;
  1518. FT_Face face = 0;
  1519. FT_ListNode node = 0;
  1520. FT_Bool external_stream;
  1521. FT_Module* cur;
  1522. FT_Module* limit;
  1523. /* test for valid `library' delayed to */
  1524. /* FT_Stream_New() */
  1525. if ( ( !aface && face_index >= 0 ) || !args )
  1526. return FT_Err_Invalid_Argument;
  1527. external_stream = FT_BOOL( ( args->flags & FT_OPEN_STREAM ) &&
  1528. args->stream );
  1529. /* create input stream */
  1530. error = FT_Stream_New( library, args, &stream );
  1531. if ( error )
  1532. goto Fail3;
  1533. memory = library->memory;
  1534. /* If the font driver is specified in the `args' structure, use */
  1535. /* it. Otherwise, we scan the list of registered drivers. */
  1536. if ( ( args->flags & FT_OPEN_DRIVER ) && args->driver )
  1537. {
  1538. driver = FT_DRIVER( args->driver );
  1539. /* not all modules are drivers, so check... */
  1540. if ( FT_MODULE_IS_DRIVER( driver ) )
  1541. {
  1542. FT_Int num_params = 0;
  1543. FT_Parameter* params = 0;
  1544. if ( args->flags & FT_OPEN_PARAMS )
  1545. {
  1546. num_params = args->num_params;
  1547. params = args->params;
  1548. }
  1549. error = open_face( driver, stream, face_index,
  1550. num_params, params, &face );
  1551. if ( !error )
  1552. goto Success;
  1553. }
  1554. else
  1555. error = FT_Err_Invalid_Handle;
  1556. FT_Stream_Free( stream, external_stream );
  1557. goto Fail;
  1558. }
  1559. else
  1560. {
  1561. /* check each font driver for an appropriate format */
  1562. cur = library->modules;
  1563. limit = cur + library->num_modules;
  1564. for ( ; cur < limit; cur++ )
  1565. {
  1566. /* not all modules are font drivers, so check... */
  1567. if ( FT_MODULE_IS_DRIVER( cur[0] ) )
  1568. {
  1569. FT_Int num_params = 0;
  1570. FT_Parameter* params = 0;
  1571. driver = FT_DRIVER( cur[0] );
  1572. if ( args->flags & FT_OPEN_PARAMS )
  1573. {
  1574. num_params = args->num_params;
  1575. params = args->params;
  1576. }
  1577. error = open_face( driver, stream, face_index,
  1578. num_params, params, &face );
  1579. if ( !error )
  1580. goto Success;
  1581. #ifdef FT_CONFIG_OPTION_MAC_FONTS
  1582. if ( ft_strcmp( cur[0]->clazz->module_name, "truetype" ) == 0 &&
  1583. FT_ERROR_BASE( error ) == FT_Err_Table_Missing )
  1584. {
  1585. /* TrueType but essential tables are missing */
  1586. if ( FT_Stream_Seek( stream, 0 ) )
  1587. break;
  1588. error = open_face_PS_from_sfnt_stream( library,
  1589. stream,
  1590. face_index,
  1591. num_params,
  1592. params,
  1593. aface );
  1594. if ( !error )
  1595. {
  1596. FT_Stream_Free( stream, external_stream );
  1597. return error;
  1598. }
  1599. }
  1600. #endif
  1601. if ( FT_ERROR_BASE( error ) != FT_Err_Unknown_File_Format )
  1602. goto Fail3;
  1603. }
  1604. }
  1605. Fail3:
  1606. /* If we are on the mac, and we get an FT_Err_Invalid_Stream_Operation */
  1607. /* it may be because we have an empty data fork, so we need to check */
  1608. /* the resource fork. */
  1609. if ( FT_ERROR_BASE( error ) != FT_Err_Cannot_Open_Stream &&
  1610. FT_ERROR_BASE( error ) != FT_Err_Unknown_File_Format &&
  1611. FT_ERROR_BASE( error ) != FT_Err_Invalid_Stream_Operation )
  1612. goto Fail2;
  1613. #if !defined( FT_MACINTOSH ) && defined( FT_CONFIG_OPTION_MAC_FONTS )
  1614. error = load_mac_face( library, stream, face_index, aface, args );
  1615. if ( !error )
  1616. {
  1617. /* We don't want to go to Success here. We've already done that. */
  1618. /* On the other hand, if we succeeded we still need to close this */
  1619. /* stream (we opened a different stream which extracted the */
  1620. /* interesting information out of this stream here. That stream */
  1621. /* will still be open and the face will point to it). */
  1622. FT_Stream_Free( stream, external_stream );
  1623. return error;
  1624. }
  1625. if ( FT_ERROR_BASE( error ) != FT_Err_Unknown_File_Format )
  1626. goto Fail2;
  1627. #endif /* !FT_MACINTOSH && FT_CONFIG_OPTION_MAC_FONTS */
  1628. /* no driver is able to handle this format */
  1629. error = FT_Err_Unknown_File_Format;
  1630. Fail2:
  1631. FT_Stream_Free( stream, external_stream );
  1632. goto Fail;
  1633. }
  1634. Success:
  1635. FT_TRACE4(( "FT_Open_Face: New face object, adding to list\n" ));
  1636. /* set the FT_FACE_FLAG_EXTERNAL_STREAM bit for FT_Done_Face */
  1637. if ( external_stream )
  1638. face->face_flags |= FT_FACE_FLAG_EXTERNAL_STREAM;
  1639. /* add the face object to its driver's list */
  1640. if ( FT_NEW( node ) )
  1641. goto Fail;
  1642. node->data = face;
  1643. /* don't assume driver is the same as face->driver, so use */
  1644. /* face->driver instead. */
  1645. FT_List_Add( &face->driver->faces_list, node );
  1646. /* now allocate a glyph slot object for the face */
  1647. FT_TRACE4(( "FT_Open_Face: Creating glyph slot\n" ));
  1648. if ( face_index >= 0 )
  1649. {
  1650. error = FT_New_GlyphSlot( face, NULL );
  1651. if ( error )
  1652. goto Fail;
  1653. /* finally, allocate a size object for the face */
  1654. {
  1655. FT_Size size;
  1656. FT_TRACE4(( "FT_Open_Face: Creating size object\n" ));
  1657. error = FT_New_Size( face, &size );
  1658. if ( error )
  1659. goto Fail;
  1660. face->size = size;
  1661. }
  1662. }
  1663. /* some checks */
  1664. if ( FT_IS_SCALABLE( face ) )
  1665. {
  1666. if ( face->height < 0 )
  1667. face->height = (FT_Short)-face->height;
  1668. if ( !FT_HAS_VERTICAL( face ) )
  1669. face->max_advance_height = (FT_Short)face->height;
  1670. }
  1671. if ( FT_HAS_FIXED_SIZES( face ) )
  1672. {
  1673. FT_Int i;
  1674. for ( i = 0; i < face->num_fixed_sizes; i++ )
  1675. {
  1676. FT_Bitmap_Size* bsize = face->available_sizes + i;
  1677. if ( bsize->height < 0 )
  1678. bsize->height = (FT_Short)-bsize->height;
  1679. if ( bsize->x_ppem < 0 )
  1680. bsize->x_ppem = (FT_Short)-bsize->x_ppem;
  1681. if ( bsize->y_ppem < 0 )
  1682. bsize->y_ppem = -bsize->y_ppem;
  1683. }
  1684. }
  1685. /* initialize internal face data */
  1686. {
  1687. FT_Face_Internal internal = face->internal;
  1688. internal->transform_matrix.xx = 0x10000L;
  1689. internal->transform_matrix.xy = 0;
  1690. internal->transform_matrix.yx = 0;
  1691. internal->transform_matrix.yy = 0x10000L;
  1692. internal->transform_delta.x = 0;
  1693. internal->transform_delta.y = 0;
  1694. }
  1695. if ( aface )
  1696. *aface = face;
  1697. else
  1698. FT_Done_Face( face );
  1699. goto Exit;
  1700. Fail:
  1701. FT_Done_Face( face );
  1702. Exit:
  1703. FT_TRACE4(( "FT_Open_Face: Return %d\n", error ));
  1704. return error;
  1705. }
  1706. /* documentation is in freetype.h */
  1707. FT_EXPORT_DEF( FT_Error )
  1708. FT_Attach_File( FT_Face face,
  1709. const char* filepathname )
  1710. {
  1711. FT_Open_Args open;
  1712. /* test for valid `face' delayed to FT_Attach_Stream() */
  1713. if ( !filepathname )
  1714. return FT_Err_Invalid_Argument;
  1715. open.stream = NULL;
  1716. open.flags = FT_OPEN_PATHNAME;
  1717. open.pathname = (char*)filepathname;
  1718. return FT_Attach_Stream( face, &open );
  1719. }
  1720. /* documentation is in freetype.h */
  1721. FT_EXPORT_DEF( FT_Error )
  1722. FT_Attach_Stream( FT_Face face,
  1723. FT_Open_Args* parameters )
  1724. {
  1725. FT_Stream stream;
  1726. FT_Error error;
  1727. FT_Driver driver;
  1728. FT_Driver_Class clazz;
  1729. /* test for valid `parameters' delayed to FT_Stream_New() */
  1730. if ( !face )
  1731. return FT_Err_Invalid_Face_Handle;
  1732. driver = face->driver;
  1733. if ( !driver )
  1734. return FT_Err_