TRUETYPE.C 88 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091
  1. /****************************************************************************
  2. * truetype.c
  3. *
  4. * This module implements rendering of TrueType fonts.
  5. * This file was written by Alexander Enzmann. He wrote the code for
  6. * rendering glyphs and generously provided us these enhancements.
  7. *
  8. * from Persistence of Vision(tm) Ray Tracer
  9. * Copyright 1996,1999 Persistence of Vision Team
  10. *---------------------------------------------------------------------------
  11. * NOTICE: This source code file is provided so that users may experiment
  12. * with enhancements to POV-Ray and to port the software to platforms other
  13. * than those supported by the POV-Ray Team. There are strict rules under
  14. * which you are permitted to use this file. The rules are in the file
  15. * named POVLEGAL.DOC which should be distributed with this file.
  16. * If POVLEGAL.DOC is not available or for more info please contact the POV-Ray
  17. * Team Coordinator by email to team-coord@povray.org or visit us on the web at
  18. * http://www.povray.org. The latest version of POV-Ray may be found at this site.
  19. *
  20. * This program is based on the popular DKB raytracer version 2.12.
  21. * DKBTrace was originally written by David K. Buck.
  22. * DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
  23. *
  24. * Alexander Ennzmann - original code...
  25. * Eduard Schwan - Mac compatibility...
  26. * Steve Demlow - Various bug fixes, data size independence...
  27. * Andreas Dilger - Kerning, multiple component glyphs...
  28. *
  29. * Changed I/O macros to functions for machine independence, Jan 1996 [AED]
  30. * Changed I/O functions for data size independence, Jan 1996 [AED], [SCD]
  31. * Major re-organization to make code more understandable, Jan 1996 [AED]
  32. * Added proper letter spacing, full kerning support, Jan 1996 [AED]
  33. * Changed to find own x/y min/max for each glyph (fonts bad?), Jan 1996 [AED]
  34. * Added special case for space character, Jan 1996 [AED]
  35. * Added support for multiple glyph characters, Feb 1996 [AED]
  36. * Changed functions to only use promoted types (no USHORTs), Mar 1996 [AED]
  37. * Cache Format 4 glyph table index to speed up parsing, Mar 1996 [AED]
  38. * Fixed TTF rendering bug that leaves horizontal streaks, Nov. 1996 Kochin Chang (KochinC@aol.com)
  39. * Allowed Macintosh-charmap TTF files to be processed, Nov. 1996 Bob Spence/Eduard Schwan
  40. *
  41. * Modifications by Hans-Detlev Fink, January 1999, used with permission
  42. * Modifications by Thomas Willhalm, March 1999, used with permission
  43. *
  44. *****************************************************************************/
  45. #include "frame.h"
  46. #include "povray.h"
  47. #include "vector.h"
  48. #include "povproto.h"
  49. #include "bbox.h"
  50. #include "matrices.h"
  51. #include "objects.h"
  52. #include "truetype.h"
  53. #include "csg.h" /* [ARE 11/94] */
  54. #include "povray.h"
  55. /*****************************************************************************
  56. * Local preprocessor defines
  57. ******************************************************************************/
  58. /* uncomment this to debug ttf. DEBUG1 gives less output than DEBUG2
  59. #define TTF_DEBUG2 1
  60. #define TTF_DEBUG 1
  61. */
  62. #undef EPSILON
  63. #define EPSILON 1.0e-10
  64. #ifndef TTF_Tolerance
  65. #define TTF_Tolerance 1.0e-6 /* -4 worked, -8 failed */
  66. #endif
  67. #ifndef SEEK_SET
  68. #define SEEK_SET 0 /* seek from start of file */
  69. #define SEEK_CUR 1 /* relative to current position */
  70. #define SEEK_END 2 /* relative to end of file */
  71. #endif
  72. #define MAX_ITERATIONS 50
  73. #define COEFF_LIMIT 1.0e-20
  74. /* For decoding glyph coordinate bit flags */
  75. #define ONCURVE 0x01
  76. #define XSHORT 0x02
  77. #define YSHORT 0x04
  78. #define REPEAT_FLAGS 0x08 /* repeat flag n times */
  79. #define SHORT_X_IS_POS 0x10 /* the short vector is positive */
  80. #define NEXT_X_IS_ZERO 0x10 /* the relative x coordinate is zero */
  81. #define SHORT_Y_IS_POS 0x20 /* the short vector is positive */
  82. #define NEXT_Y_IS_ZERO 0x20 /* the relative y coordinate is zero */
  83. /* For decoding multi-component glyph bit flags */
  84. #define ARG_1_AND_2_ARE_WORDS 0x0001
  85. #define ARGS_ARE_XY_VALUES 0x0002
  86. #define ROUND_XY_TO_GRID 0x0004
  87. #define WE_HAVE_A_SCALE 0x0008
  88. /* RESERVED 0x0010 */
  89. #define MORE_COMPONENTS 0x0020
  90. #define WE_HAVE_AN_X_AND_Y_SCALE 0x0040
  91. #define WE_HAVE_A_TWO_BY_TWO 0x0080
  92. #define WE_HAVE_INSTRUCTIONS 0x0100
  93. #define USE_MY_METRICS 0x0200
  94. /* For decoding kern coverage bit flags */
  95. #define KERN_HORIZONTAL 0x01
  96. #define KERN_MINIMUM 0x02
  97. #define KERN_CROSS_STREAM 0x04
  98. #define KERN_OVERRIDE 0x08
  99. /* Some marcos to make error detection easier, as well as clarify code */
  100. #define READSHORT(fp) readSHORT(fp, __LINE__, __FILE__)
  101. #define READLONG(fp) readLONG(fp, __LINE__, __FILE__)
  102. #define READUSHORT(fp) readUSHORT(fp, __LINE__, __FILE__)
  103. #define READULONG(fp) readULONG(fp, __LINE__, __FILE__)
  104. #define READFIXED(fp) readLONG(fp, __LINE__, __FILE__)
  105. #define READFWORD(fp) readSHORT(fp, __LINE__, __FILE__)
  106. #define READUFWORD(fp) readUSHORT(fp, __LINE__, __FILE__)
  107. /*****************************************************************************
  108. * Local typedefs
  109. ******************************************************************************/
  110. /* Type definitions to match the TTF spec, makes code clearer */
  111. typedef char CHAR;
  112. typedef unsigned char BYTE;
  113. typedef short SHORT;
  114. typedef unsigned short USHORT;
  115. typedef long LONG;
  116. typedef unsigned long ULONG;
  117. typedef short FWord;
  118. typedef unsigned short uFWord;
  119. #if !defined(MACOS)
  120. typedef long Fixed;
  121. #endif
  122. typedef struct
  123. {
  124. Fixed version; /* 0x10000 (1.0) */
  125. USHORT numTables; /* number of tables */
  126. USHORT searchRange; /* (max2 <= numTables)*16 */
  127. USHORT entrySelector; /* log2 (max2 <= numTables) */
  128. USHORT rangeShift; /* numTables*16-searchRange */
  129. } sfnt_OffsetTable;
  130. typedef struct
  131. {
  132. BYTE tag[4];
  133. ULONG checkSum;
  134. ULONG offset;
  135. ULONG length;
  136. } sfnt_TableDirectory;
  137. typedef sfnt_TableDirectory *sfnt_TableDirectoryPtr;
  138. typedef struct
  139. {
  140. ULONG bc;
  141. ULONG ad;
  142. } longDateTime;
  143. typedef struct
  144. {
  145. Fixed version; /* for this table, set to 1.0 */
  146. Fixed fontRevision; /* For Font Manufacturer */
  147. ULONG checkSumAdjustment;
  148. ULONG magicNumber; /* signature, must be 0x5F0F3CF5 == MAGIC */
  149. USHORT flags;
  150. USHORT unitsPerEm; /* How many in Font Units per EM */
  151. longDateTime created;
  152. longDateTime modified;
  153. FWord xMin; /* Font wide bounding box in ideal space */
  154. FWord yMin; /* Baselines and metrics are NOT worked */
  155. FWord xMax; /* into these numbers) */
  156. FWord yMax;
  157. USHORT macStyle; /* macintosh style word */
  158. USHORT lowestRecPPEM; /* lowest recommended pixels per Em */
  159. SHORT fontDirectionHint;
  160. SHORT indexToLocFormat; /* 0 - short offsets, 1 - long offsets */
  161. SHORT glyphDataFormat;
  162. } sfnt_FontHeader;
  163. typedef struct
  164. {
  165. USHORT platformID;
  166. USHORT specificID;
  167. ULONG offset;
  168. } sfnt_platformEntry;
  169. typedef sfnt_platformEntry *sfnt_platformEntryPtr;
  170. typedef struct
  171. {
  172. USHORT format;
  173. USHORT length;
  174. USHORT version;
  175. } sfnt_mappingTable;
  176. typedef struct
  177. {
  178. Fixed version;
  179. FWord Ascender;
  180. FWord Descender;
  181. FWord LineGap;
  182. uFWord advanceWidthMax;
  183. FWord minLeftSideBearing;
  184. FWord minRightSideBearing;
  185. FWord xMaxExtent;
  186. SHORT caretSlopeRise;
  187. SHORT caretSlopeRun;
  188. SHORT reserved1;
  189. SHORT reserved2;
  190. SHORT reserved3;
  191. SHORT reserved4;
  192. SHORT reserved5;
  193. SHORT metricDataFormat;
  194. USHORT numberOfHMetrics; /* number of hMetrics in the hmtx table */
  195. } sfnt_HorizHeader;
  196. typedef struct
  197. {
  198. SHORT numContours;
  199. SHORT xMin;
  200. SHORT yMin;
  201. SHORT xMax;
  202. SHORT yMax;
  203. } GlyphHeader;
  204. typedef struct
  205. {
  206. GlyphHeader header;
  207. USHORT numPoints;
  208. USHORT *endPoints;
  209. BYTE *flags;
  210. DBL *x, *y;
  211. USHORT myMetrics;
  212. } GlyphOutline;
  213. typedef struct
  214. {
  215. BYTE inside_flag; /* 1 if this an inside contour, 0 if outside */
  216. USHORT count; /* Number of points in the contour */
  217. BYTE *flags; /* On/off curve flags */
  218. DBL *x, *y; /* Coordinates of control vertices */
  219. } Contour;
  220. typedef struct GlyphStruct *GlyphPtr;
  221. /* Contour information for a single glyph */
  222. typedef struct GlyphStruct
  223. {
  224. GlyphHeader header; /* Count and sizing information about this
  225. * glyph */
  226. USHORT glyph_index; /* Internal glyph index for this character */
  227. Contour *contours; /* Array of outline contours */
  228. USHORT unitsPerEm; /* Max units character */
  229. GlyphPtr next; /* Next cached glyph */
  230. USHORT c; /* Character code */
  231. USHORT myMetrics; /* Which glyph index this is for metrics */
  232. } Glyph;
  233. typedef struct KernData_struct
  234. {
  235. USHORT left, right; /* Glyph index of left/right to kern */
  236. FWord value; /* Delta in FUnits to apply in between */
  237. } KernData;
  238. /*
  239. * [esp] There's already a "KernTable" on the Mac... renamed to TTKernTable for
  240. * now in memorium to its author.
  241. */
  242. typedef struct KernStruct
  243. {
  244. USHORT coverage; /* Coverage bit field of this subtable */
  245. USHORT nPairs; /* # of kerning pairs in this table */
  246. KernData *kern_pairs; /* Array of kerning values */
  247. } TTKernTable;
  248. typedef struct KernTableStruct
  249. {
  250. USHORT nTables; /* # of subtables in the kerning table */
  251. TTKernTable *tables;
  252. } KernTables;
  253. typedef struct longHorMertric
  254. {
  255. uFWord advanceWidth; /* Total width of a glyph in FUnits */
  256. FWord lsb; /* FUnits to the left of the glyph */
  257. } longHorMetric;
  258. /* Useful general data about this font */
  259. typedef struct FontFileInfoStruct
  260. {
  261. char *filename;
  262. FILE *fp;
  263. USHORT platformID; /* Which character encoding to use */
  264. USHORT specificID;
  265. ULONG cmap_table_offset; /* File locations for these tables */
  266. ULONG glyf_table_offset;
  267. USHORT numGlyphs; /* How many symbols in this file */
  268. USHORT unitsPerEm; /* The "resoultion" of this font */
  269. SHORT indexToLocFormat; /* 0 - short format, 1 - long format */
  270. ULONG *loca_table; /* Mapping from characters to glyphs */
  271. GlyphPtr glyphs; /* Cached info for this font */
  272. KernTables kerning_tables; /* Kerning info for this font */
  273. USHORT numberOfHMetrics; /* The number of explicit spacings */
  274. longHorMetric *hmtx_table; /* Horizontal spacing info */
  275. ULONG glyphIDoffset; /* Offset for Type 4 encoding tables */
  276. USHORT segCount, searchRange, /* Counts for Type 4 encoding tables */
  277. entrySelector, rangeShift;
  278. USHORT *startCount, *endCount, /* Type 4 (MS) encoding tables */
  279. *idDelta, *idRangeOffset;
  280. struct FontFileInfoStruct *next; /* Next font */
  281. } FontFileInfo;
  282. /*****************************************************************************
  283. * Local variables
  284. ******************************************************************************/
  285. static BYTE tag_CharToIndexMap[] = "cmap"; /* 0x636d6170; */
  286. static BYTE tag_FontHeader[] = "head"; /* 0x68656164; */
  287. static BYTE tag_GlyphData[] = "glyf"; /* 0x676c7966; */
  288. static BYTE tag_IndexToLoc[] = "loca"; /* 0x6c6f6361; */
  289. static BYTE tag_Kerning[] = "kern"; /* 0x6b65726e; */
  290. static BYTE tag_MaxProfile[] = "maxp"; /* 0x6d617870; */
  291. static BYTE tag_HorizHeader[] = "hhea"; /* 0x68686561; */
  292. static BYTE tag_HorizMetric[] = "hmtx"; /* 0x686d7478; */
  293. static FontFileInfo *TTFonts = NULL;
  294. /*****************************************************************************
  295. * Static functions
  296. ******************************************************************************/
  297. /* Byte order independent I/O routines (probably already in other routines) */
  298. static SHORT readSHORT (FILE *infile, int line, char *file);
  299. static USHORT readUSHORT (FILE *infile, int line, char *file);
  300. static LONG readLONG (FILE *infile, int line, char *file);
  301. static ULONG readULONG (FILE *infile, int line, char *file);
  302. static int compare_tag4 (BYTE *ttf_tag, BYTE *known_tag);
  303. /* Internal TTF input routines */
  304. static FontFileInfo *ProcessFontFile (char *fontfilename);
  305. static FontFileInfo *OpenFontFile (char *filename);
  306. static void ProcessHeadTable (FontFileInfo *ffile, long head_table_offset);
  307. static void ProcessLocaTable (FontFileInfo *ffile, long loca_table_offset);
  308. static void ProcessMaxpTable (FontFileInfo *ffile, long maxp_table_offset);
  309. static void ProcessKernTable (FontFileInfo *ffile, long kern_table_offset);
  310. static void ProcessHheaTable (FontFileInfo *ffile, long hhea_table_offset);
  311. static void ProcessHmtxTable (FontFileInfo *ffile, long hmtx_table_offset);
  312. static GlyphPtr ProcessCharacter (FontFileInfo *ffile, unsigned int search_char, unsigned int *glyph_index);
  313. static USHORT ProcessCharMap (FontFileInfo *ffile, unsigned int search_char);
  314. static USHORT ProcessFormat0Glyph (FontFileInfo *ffile, unsigned int search_char);
  315. static USHORT ProcessFormat4Glyph (FontFileInfo *ffile, unsigned int search_char);
  316. static USHORT ProcessFormat6Glyph (FontFileInfo *ffile, unsigned int search_char);
  317. static GlyphPtr ExtractGlyphInfo (FontFileInfo *ffile, unsigned int *glyph_index, unsigned int c);
  318. static GlyphOutline *ExtractGlyphOutline (FontFileInfo *ffile, unsigned int *glyph_index, unsigned int c);
  319. static GlyphPtr ConvertOutlineToGlyph (FontFileInfo *ffile, GlyphOutline *ttglyph);
  320. /* Glyph surface intersection routines */
  321. static int Inside_Glyph (double x, double y, GlyphPtr glyph);
  322. static int solve_quad (double *x, double *y, double mindist, DBL maxdist);
  323. static void GetZeroOneHits (GlyphPtr glyph, VECTOR P, VECTOR D, DBL glyph_depth, double *t0, double *t1);
  324. static int GlyphIntersect (OBJECT *Object, VECTOR P, VECTOR D, GlyphPtr glyph, DBL glyph_depth, RAY *Ray, ISTACK *Depth_Stack); /* tw */
  325. /* POV-Ray object intersection/creation routines */
  326. static TTF *Create_TTF (void);
  327. static int All_TTF_Intersections (OBJECT *Object, RAY *Ray, ISTACK *Depth_Stack);
  328. static int Inside_TTF (VECTOR IPoint, OBJECT *Object);
  329. static void TTF_Normal (VECTOR Result, OBJECT *Object, INTERSECTION *Inter);
  330. static TTF *Copy_TTF (OBJECT *Object);
  331. static void Translate_TTF (OBJECT *Object, VECTOR Vector, TRANSFORM *Trans);
  332. static void Rotate_TTF (OBJECT *Object, VECTOR Vector, TRANSFORM *Trans);
  333. static void Scale_TTF (OBJECT *Object, VECTOR Vector, TRANSFORM *Trans);
  334. static void Transform_TTF (OBJECT *Object, TRANSFORM *Trans);
  335. static void Invert_TTF (OBJECT *Object);
  336. static void Destroy_TTF (OBJECT *Object);
  337. METHODS TTF_Methods =
  338. {All_TTF_Intersections,
  339. Inside_TTF, TTF_Normal,
  340. (COPY_METHOD)Copy_TTF, Translate_TTF, Rotate_TTF, Scale_TTF, Transform_TTF,
  341. Invert_TTF, Destroy_TTF};
  342. /*
  343. * The following work as macros if sizeof(short) == 16 bits and
  344. * sizeof(long) == 32 bits, but tend to break otherwise. Making these
  345. * into error functions also allows file error checking. Do not attempt to
  346. * "optimize" these functions - some architectures require them the way
  347. * that they are written.
  348. */
  349. static SHORT readSHORT(FILE *infile, int line, char *file)
  350. {
  351. int i0, i1 = 0; /* To quiet warnings */
  352. if ((i0 = fgetc(infile)) == EOF || (i1 = fgetc(infile)) == EOF)
  353. {
  354. Error("Error reading TrueType font file at line %d, %s\n", line, file);
  355. }
  356. if (i0 & 0x80) /* Subtract 1 after value is negated to avoid overflow [AED] */
  357. return -(((255 - i0) << 8) | (255 - i1)) - 1;
  358. else
  359. return (i0 << 8) | i1;
  360. }
  361. static USHORT readUSHORT(FILE *infile, int line, char *file)
  362. {
  363. int i0, i1 = 0; /* To quiet warnings */
  364. if ((i0 = fgetc(infile)) == EOF || (i1 = fgetc(infile)) == EOF)
  365. {
  366. Error("Error reading TrueType font file at line %d, %s\n", line, file);
  367. }
  368. return (USHORT)((((USHORT)i0) << 8) | ((USHORT)i1));
  369. }
  370. static LONG readLONG(FILE *infile, int line, char *file)
  371. {
  372. LONG i0, i1 = 0, i2 = 0, i3 = 0; /* To quiet warnings */
  373. if ((i0 = fgetc(infile)) == EOF || (i1 = fgetc(infile)) == EOF ||
  374. (i2 = fgetc(infile)) == EOF || (i3 = fgetc(infile)) == EOF)
  375. {
  376. Error("Error reading TrueType font file at line %d, %s\n", line, file);
  377. }
  378. if (i0 & 0x80) /* Subtract 1 after value is negated to avoid overflow [AED] */
  379. return -(((255 - i0) << 24) | ((255 - i1) << 16) |
  380. ((255 - i2) << 8) | (255 - i3)) - 1;
  381. else
  382. return (i0 << 24) | (i1 << 16) | (i2 << 8) | i3;
  383. }
  384. static ULONG readULONG(FILE *infile, int line, char *file)
  385. {
  386. int i0, i1 = 0, i2 = 0, i3 = 0; /* To quiet warnings */
  387. if ((i0 = fgetc(infile)) == EOF || (i1 = fgetc(infile)) == EOF ||
  388. (i2 = fgetc(infile)) == EOF || (i3 = fgetc(infile)) == EOF)
  389. {
  390. Error("Error reading TrueType font file at line %d, %s\n", line, file);
  391. }
  392. return (ULONG) ((((ULONG) i0) << 24) | (((ULONG) i1) << 16) |
  393. (((ULONG) i2) << 8) | ((ULONG) i3));
  394. }
  395. static int compare_tag4(BYTE *ttf_tag, BYTE *known_tag)
  396. {
  397. return (ttf_tag[0] == known_tag[0] && ttf_tag[1] == known_tag[1] &&
  398. ttf_tag[2] == known_tag[2] && ttf_tag[3] == known_tag[3]);
  399. }
  400. /*****************************************************************************
  401. *
  402. * FUNCTION
  403. *
  404. * ProcessNewTTF
  405. *
  406. * INPUT
  407. *
  408. * OUTPUT
  409. *
  410. * RETURNS
  411. *
  412. * AUTHOR
  413. *
  414. * Alexander Ennzmann
  415. *
  416. * DESCRIPTION
  417. *
  418. * Takes an input string and a font filename, and creates a POV-Ray CSG
  419. * object for each letter in the string.
  420. *
  421. * CHANGES
  422. *
  423. * -
  424. *
  425. ******************************************************************************/
  426. void ProcessNewTTF(OBJECT *object, char *filename, char *text_string, DBL depth, VECTOR offset)
  427. {
  428. FontFileInfo *ffile;
  429. int slen;
  430. VECTOR local_offset, total_offset;
  431. CSG *Object = (CSG *) object;
  432. TTF *ttf;
  433. OBJECT *Local;
  434. GlyphPtr glyph;
  435. DBL funit_size;
  436. TTKernTable *table;
  437. USHORT coverage;
  438. unsigned int search_char;
  439. unsigned int glyph_index, last_index = 0;
  440. FWord kern_value_x, kern_value_min_x;
  441. FWord kern_value_y, kern_value_min_y;
  442. int i, j, k;
  443. TRANSFORM Trans;
  444. /* Get general font info */
  445. ffile = ProcessFontFile(filename);
  446. /* Get info about each character in the string */
  447. slen = strlen(text_string);
  448. Make_Vector(total_offset, 0.0, 0.0, 0.0);
  449. Object->Children = NULL;
  450. for (i = 0; i < slen; i++)
  451. {
  452. /*
  453. * We need to make sure (for now) that this is only the lower 8 bits,
  454. * so we don't have all the high bits set if converted from a signed
  455. * char to an unsigned short.
  456. */
  457. search_char = ((unsigned int)text_string[i]) & 0xFF;
  458. #ifdef TTF_DEBUG
  459. Debug_Info("\nChar: '%c' (0x%X), Offset[%d]: <%g,%g,%g>\n", text_string[i],
  460. search_char, i, total_offset[X], total_offset[Y], total_offset[Z]);
  461. #endif
  462. /* Make a new child for each character */
  463. ttf = Create_TTF();
  464. Local = (OBJECT *) ttf;
  465. /* Set the depth information for the character */
  466. ttf->depth = depth;
  467. /*
  468. * Get pointers to the contour information for each character
  469. * in the text string.
  470. */
  471. glyph = ProcessCharacter(ffile, search_char, &glyph_index);
  472. ttf->glyph = (void *)glyph;
  473. funit_size = 1.0 / (DBL)(ffile->unitsPerEm);
  474. /*
  475. * Spacing based on the horizontal metric table, the kerning table,
  476. * and (possibly) the previous glyph.
  477. */
  478. if (i == 0) /* Ignore spacing on the left for the first character only */
  479. {
  480. /* Shift the glyph to start at the origin */
  481. total_offset[X] = -glyph->header.xMin * funit_size;
  482. Compute_Translation_Transform(&Trans, total_offset);
  483. Translate_TTF(Local, total_offset, &Trans);
  484. /* Shift next glyph by the width of this one excluding the left offset*/
  485. total_offset[X] = (ffile->hmtx_table[glyph->myMetrics].advanceWidth -
  486. ffile->hmtx_table[glyph->myMetrics].lsb) * funit_size;
  487. #ifdef TTF_DEBUG
  488. Debug_Info("aw(%d): %g\n", i,
  489. (ffile->hmtx_table[glyph->myMetrics].advanceWidth -
  490. ffile->hmtx_table[glyph->myMetrics].lsb)*funit_size);
  491. #endif
  492. }
  493. else /* Kern all of the other characters */
  494. {
  495. kern_value_x = kern_value_y = 0;
  496. kern_value_min_x = kern_value_min_y = -ffile->unitsPerEm;
  497. Make_Vector(local_offset, 0.0, 0.0, 0.0);
  498. for (j = 0; j < ffile->kerning_tables.nTables; j++)
  499. {
  500. table = ffile->kerning_tables.tables;
  501. coverage = table->coverage;
  502. /*
  503. * Don't use vertical kerning until such a time when we support
  504. * characters moving in the vertical direction...
  505. */
  506. if (!(coverage & KERN_HORIZONTAL))
  507. continue;
  508. /*
  509. * If we were keen, we could do a binary search for this
  510. * character combination, since the pairs are sorted in
  511. * order as if the left and right index values were a 32 bit
  512. * unsigned int (mostly - at least they are sorted on the
  513. * left glyph). Something to do when everything else works...
  514. */
  515. for (k = 0; k < table[j].nPairs; k++)
  516. {
  517. if (table[j].kern_pairs[k].left == last_index &&
  518. table[j].kern_pairs[k].right == glyph->myMetrics)
  519. {
  520. #ifdef TTF_DEBUG2
  521. Debug_Info("Found a kerning for <%d, %d> = %d",
  522. last_index, glyph_index, table[j].kern_pairs[k].value);
  523. #endif
  524. /*
  525. * By default, Windows & OS/2 assume at most a single table with
  526. * !KERN_MINIMUM, !KERN_CROSS_STREAM, KERN_OVERRIDE.
  527. */
  528. if (coverage & KERN_MINIMUM)
  529. {
  530. #ifdef TTF_DEBUG2
  531. Debug_Info(" KERN_MINIMUM\n");
  532. #endif
  533. if (coverage & KERN_CROSS_STREAM)
  534. kern_value_min_y = table[j].kern_pairs[k].value;
  535. else
  536. kern_value_min_x = table[j].kern_pairs[k].value;
  537. }
  538. else
  539. {
  540. if (coverage & KERN_CROSS_STREAM)
  541. {
  542. #ifdef TTF_DEBUG2
  543. Debug_Info(" KERN_CROSS_STREAM\n");
  544. #endif
  545. if (table[j].kern_pairs[k].value == (FWord)0x8000)
  546. {
  547. kern_value_y = 0;
  548. }
  549. else
  550. {
  551. if (coverage & KERN_OVERRIDE)
  552. kern_value_y = table[j].kern_pairs[k].value;
  553. else
  554. kern_value_y += table[j].kern_pairs[k].value;
  555. }
  556. }
  557. else
  558. {
  559. #ifdef TTF_DEBUG2
  560. Debug_Info(" KERN_VALUE\n");
  561. #endif
  562. if (coverage & KERN_OVERRIDE)
  563. kern_value_x = table[j].kern_pairs[k].value;
  564. else
  565. kern_value_x += table[j].kern_pairs[k].value;
  566. }
  567. }
  568. break;
  569. }
  570. /* Abort now if we have passed all potential matches */
  571. else if (table[j].kern_pairs[k].left > last_index)
  572. {
  573. break;
  574. }
  575. }
  576. }
  577. kern_value_x = (kern_value_x > kern_value_min_x ?
  578. kern_value_x : kern_value_min_x);
  579. kern_value_y = (kern_value_y > kern_value_min_y ?
  580. kern_value_y : kern_value_min_y);
  581. /*
  582. * Offset this character so that the left edge of the glyph is at
  583. * the previous offset + the lsb + any kerning amount.
  584. */
  585. local_offset[X] = total_offset[X] +
  586. (DBL)(ffile->hmtx_table[glyph->myMetrics].lsb -
  587. glyph->header.xMin + kern_value_x) * funit_size;
  588. local_offset[Y] = total_offset[Y] + (DBL)kern_value_y * funit_size;
  589. /* Translate this glyph to its final position in the string */
  590. Compute_Translation_Transform(&Trans, local_offset);
  591. Translate_TTF(Local, local_offset, &Trans);
  592. /* Shift next glyph by the width of this one */
  593. total_offset[X] += ffile->hmtx_table[glyph->myMetrics].advanceWidth *
  594. funit_size;
  595. #ifdef TTF_DEBUG
  596. Debug_Info("kern(%d): <%d, %d> (%g,%g)\n", i, last_index, glyph_index,
  597. (DBL)kern_value_x*funit_size, (DBL)kern_value_y * funit_size);
  598. Debug_Info("lsb(%d): %g\n", i,
  599. (DBL)ffile->hmtx_table[glyph->myMetrics].lsb * funit_size);
  600. Debug_Info("aw(%d): %g\n", i,
  601. (DBL)ffile->hmtx_table[glyph->myMetrics].advanceWidth *
  602. funit_size);
  603. #endif
  604. }
  605. /*
  606. * Add to the offset of the next character the minimum spacing specified.
  607. */
  608. VAddEq(total_offset, offset);
  609. /* Link this glyph with the others in the union */
  610. Object->Type |= (Local->Type & CHILDREN_FLAGS);
  611. Local->Type |= IS_CHILD_OBJECT;
  612. Local->Sibling = Object->Children;
  613. Object->Children = Local;
  614. last_index = glyph_index;
  615. }
  616. #ifdef TTF_DEBUG
  617. Debug_Info("TTF parsing of \"%s\" from %s complete\n", text_string, filename);
  618. #endif
  619. /* Close the font file descriptor */
  620. if (ffile->fp != NULL) /* just to be sure it exists -hdf99- */
  621. {
  622. fclose(ffile->fp);
  623. ffile->fp = NULL;
  624. }
  625. }
  626. /*****************************************************************************
  627. *
  628. * FUNCTION
  629. *
  630. * ProcessFontFile
  631. *
  632. * INPUT
  633. *
  634. * OUTPUT
  635. *
  636. * RETURNS
  637. *
  638. * AUTHOR
  639. *
  640. * Alexander Ennzmann
  641. *
  642. * DESCRIPTION
  643. *
  644. * Read the header information about the specific font. Parse the tables
  645. * as we come across them.
  646. *
  647. * CHANGES
  648. *
  649. * Added tests for reading manditory tables/validity checks - Jan 1996 [AED]
  650. * Reordered table parsing to avoid lots of file seeking - Jan 1996 [AED]
  651. *
  652. ******************************************************************************/
  653. static FontFileInfo *ProcessFontFile(char *fontfilename)
  654. {
  655. unsigned i;
  656. long head_table_offset = 0;
  657. long loca_table_offset = 0;
  658. long maxp_table_offset = 0;
  659. long kern_table_offset = 0;
  660. long hhea_table_offset = 0;
  661. long hmtx_table_offset = 0;
  662. sfnt_OffsetTable OffsetTable;
  663. sfnt_TableDirectory Table;
  664. FontFileInfo *ffile;
  665. /* Open the font file */
  666. ffile = OpenFontFile(fontfilename);
  667. /* We have already read all the header info, no need to do it again */
  668. if (ffile->cmap_table_offset != 0)
  669. {
  670. return (ffile);
  671. }
  672. /*
  673. * Read the initial directory header on the TTF. The numTables variable
  674. * tells us how many tables are present in this file.
  675. */
  676. OffsetTable.version = READFIXED(ffile->fp);
  677. OffsetTable.numTables = READUSHORT(ffile->fp);
  678. OffsetTable.searchRange = READUSHORT(ffile->fp);
  679. OffsetTable.entrySelector = READUSHORT(ffile->fp);
  680. OffsetTable.rangeShift = READUSHORT(ffile->fp);
  681. #ifdef TTF_DEBUG
  682. Debug_Info("OffsetTable:\n");
  683. Debug_Info("version=%d\n", OffsetTable.version);
  684. Debug_Info("numTables=%u\n", OffsetTable.numTables);
  685. Debug_Info("searchRange=%u\n", OffsetTable.searchRange);
  686. Debug_Info("entrySelector=%u\n", OffsetTable.entrySelector);
  687. Debug_Info("rangeShift=%u\n", OffsetTable.rangeShift);
  688. #endif
  689. /*
  690. * I don't know why we limit this to 40 tables, since the spec says there
  691. * can be any number, but that's how it was when I got it. Added a warning
  692. * just in case it ever happens in real life. [AED]
  693. */
  694. if (OffsetTable.numTables > 40)
  695. {
  696. Warning(0.0, "More than 40 (%d) TTF Tables in %s - some info may be lost!",
  697. OffsetTable.numTables, ffile->filename);
  698. }
  699. /* Process general font information and save it. */
  700. for (i = 0; i < OffsetTable.numTables && i < 40; i++)
  701. {
  702. if (fread(&Table.tag, sizeof(BYTE), 4, ffile->fp) != 4)
  703. {
  704. Error("Error reading TrueType font file table tag\n");
  705. }
  706. Table.checkSum = READULONG(ffile->fp);
  707. Table.offset = READULONG(ffile->fp);
  708. Table.length = READULONG(ffile->fp);
  709. #ifdef TTF_DEBUG
  710. Debug_Info("\nTable %d:\n",i);
  711. Debug_Info("tag=%c%c%c%c\n", Table.tag[0], Table.tag[1],
  712. Table.tag[2], Table.tag[3]);
  713. Debug_Info("checkSum=%u\n", Table.checkSum);
  714. Debug_Info("offset=%u\n", Table.offset);
  715. Debug_Info("length=%u\n", Table.length);
  716. #endif
  717. if (compare_tag4(Table.tag, tag_CharToIndexMap))
  718. ffile->cmap_table_offset = Table.offset;
  719. else if (compare_tag4(Table.tag, tag_GlyphData))
  720. ffile->glyf_table_offset = Table.offset;
  721. else if (compare_tag4(Table.tag, tag_FontHeader))
  722. head_table_offset = Table.offset;
  723. else if (compare_tag4(Table.tag, tag_IndexToLoc))
  724. loca_table_offset = Table.offset;
  725. else if (compare_tag4(Table.tag, tag_MaxProfile))
  726. maxp_table_offset = Table.offset;
  727. else if (compare_tag4(Table.tag, tag_Kerning))
  728. kern_table_offset = Table.offset;
  729. else if (compare_tag4(Table.tag, tag_HorizHeader))
  730. hhea_table_offset = Table.offset;
  731. else if (compare_tag4(Table.tag, tag_HorizMetric))
  732. hmtx_table_offset = Table.offset;
  733. }
  734. if (ffile->cmap_table_offset == 0 || ffile->glyf_table_offset == 0 ||
  735. head_table_offset == 0 || loca_table_offset == 0 ||
  736. hhea_table_offset == 0 || hmtx_table_offset == 0 ||
  737. maxp_table_offset == 0)
  738. {
  739. Error("Invalid TrueType font headers in %s\n", ffile->filename);
  740. }
  741. ProcessHeadTable(ffile, head_table_offset); /* Need indexToLocFormat */
  742. if ((ffile->indexToLocFormat != 0 && ffile->indexToLocFormat != 1) ||
  743. (ffile->unitsPerEm < 16 || ffile->unitsPerEm > 16384))
  744. Error("Invalid TrueType font data in %s\n", ffile->filename);
  745. ProcessMaxpTable(ffile, maxp_table_offset); /* Need numGlyphs */
  746. if (ffile->numGlyphs <= 0)
  747. Error("Invalid TrueType font data in %s\n", ffile->filename);
  748. ProcessLocaTable(ffile, loca_table_offset); /* Now we can do loca_table */
  749. ProcessHheaTable(ffile, hhea_table_offset); /* Need numberOfHMetrics */
  750. if (ffile->numberOfHMetrics <= 0)
  751. Error("Invalid TrueType font data in %s\n", ffile->filename);
  752. ProcessHmtxTable(ffile, hmtx_table_offset); /* Now we can read HMetrics */
  753. if (kern_table_offset != 0)
  754. ProcessKernTable(ffile, kern_table_offset);
  755. /* Return the information about this font */
  756. return ffile;
  757. }
  758. /*****************************************************************************
  759. *
  760. * FUNCTION
  761. *
  762. * OpenFontFile
  763. *
  764. * INPUT
  765. *
  766. * OUTPUT
  767. *
  768. * RETURNS
  769. *
  770. * AUTHOR
  771. *
  772. * Alexander Ennzmann
  773. *
  774. * DESCRIPTION
  775. *
  776. * -
  777. *
  778. * CHANGES
  779. *
  780. * -
  781. *
  782. ******************************************************************************/
  783. static FontFileInfo *OpenFontFile(char *filename)
  784. {
  785. /* int i; */ /* tw, mtg */
  786. FontFileInfo *fontlist;
  787. char b[FILE_NAME_LENGTH];
  788. /* First look to see if we have already opened this font */
  789. for (fontlist = TTFonts; fontlist != NULL; fontlist = fontlist->next)
  790. if (!strcmp(filename, fontlist->filename))
  791. break;
  792. if (fontlist != NULL)
  793. {
  794. /* We have a match, use the previous information */
  795. if ((fontlist->fp == NULL) &&
  796. (fontlist->fp = Locate_File(fontlist->filename, READ_BINFILE_STRING,
  797. ".ttf", ".TTF",NULL,TRUE)) == NULL)
  798. Error("Can't open font file.\n");
  799. #ifdef TTF_DEBUG
  800. else
  801. Debug_Info("Using cached font info for %s\n", fontlist->filename);
  802. #endif
  803. }
  804. else
  805. {
  806. /*
  807. * We haven't looked at this font before, let's allocate a holder for the
  808. * information and set some defaults
  809. */
  810. fontlist = (FontFileInfo *)POV_CALLOC(1, sizeof(FontFileInfo), "FontFileInfo");
  811. if ((fontlist->fp = Locate_File(filename, READ_BINFILE_STRING,
  812. ".ttf", ".TTF",b,TRUE)) == NULL)
  813. {
  814. Error("Can't open font file.\n");
  815. }
  816. fontlist->filename = POV_STRDUP(b);
  817. /*
  818. * We try to choose ISO 8859-1 (Latin-1) as default for now.
  819. * For Microsoft encodings 3, 1 is for Unicode/Latin-1,
  820. * 3, 0 is for Non-unicode (ie symbols),
  821. * For Macintosh encodings 1, 0 is for Roman character set.
  822. */
  823. fontlist->platformID = 3;
  824. fontlist->specificID = 1;
  825. fontlist->next = TTFonts;
  826. TTFonts = fontlist;
  827. }
  828. return fontlist;
  829. }
  830. void FreeFontInfo()
  831. {
  832. int i;
  833. FontFileInfo *oldfont, *tempfont;
  834. GlyphPtr glyphs, tempglyph;
  835. for (oldfont = TTFonts; oldfont != NULL;)
  836. {
  837. if (oldfont->fp != NULL)
  838. fclose(oldfont->fp);
  839. if (oldfont->filename != NULL)
  840. POV_FREE(oldfont->filename);
  841. if (oldfont->loca_table != NULL)
  842. POV_FREE(oldfont->loca_table);
  843. if (oldfont->hmtx_table != NULL)
  844. POV_FREE(oldfont->hmtx_table);
  845. if (oldfont->kerning_tables.nTables != 0)
  846. {
  847. for (i = 0; i < oldfont->kerning_tables.nTables; i++)
  848. {
  849. if (oldfont->kerning_tables.tables[i].kern_pairs)
  850. POV_FREE(oldfont->kerning_tables.tables[i].kern_pairs);
  851. }
  852. POV_FREE(oldfont->kerning_tables.tables);
  853. }
  854. for (glyphs = oldfont->glyphs; glyphs != NULL;)
  855. {
  856. for (i = 0; i < glyphs->header.numContours; i++)
  857. {
  858. POV_FREE(glyphs->contours[i].flags);
  859. POV_FREE(glyphs->contours[i].x);
  860. POV_FREE(glyphs->contours[i].y);
  861. }
  862. if (glyphs->contours != NULL)
  863. POV_FREE(glyphs->contours);
  864. tempglyph = glyphs;
  865. glyphs = glyphs->next;
  866. POV_FREE(tempglyph);
  867. }
  868. if (oldfont->segCount != 0)
  869. {
  870. POV_FREE(oldfont->endCount);
  871. POV_FREE(oldfont->startCount);
  872. POV_FREE(oldfont->idDelta);
  873. POV_FREE(oldfont->idRangeOffset);
  874. }
  875. tempfont = oldfont;
  876. oldfont = oldfont->next;
  877. POV_FREE(tempfont);
  878. }
  879. TTFonts = NULL;
  880. }
  881. /* Process the font header table */
  882. static void ProcessHeadTable(FontFileInfo *ffile, long head_table_offset)
  883. {
  884. sfnt_FontHeader fontHeader;
  885. /* Read head table */
  886. fseek(ffile->fp, head_table_offset, SEEK_SET);
  887. fontHeader.version = READFIXED(ffile->fp);
  888. fontHeader.fontRevision = READFIXED(ffile->fp);
  889. fontHeader.checkSumAdjustment = READULONG(ffile->fp);
  890. fontHeader.magicNumber = READULONG(ffile->fp); /* should be 0x5F0F3CF5 */
  891. fontHeader.flags = READUSHORT(ffile->fp);
  892. fontHeader.unitsPerEm = READUSHORT(ffile->fp);
  893. fontHeader.created.bc = READULONG(ffile->fp);
  894. fontHeader.created.ad = READULONG(ffile->fp);
  895. fontHeader.modified.bc = READULONG(ffile->fp);
  896. fontHeader.modified.ad = READULONG(ffile->fp);
  897. fontHeader.xMin = READFWORD(ffile->fp);
  898. fontHeader.yMin = READFWORD(ffile->fp);
  899. fontHeader.xMax = READFWORD(ffile->fp);
  900. fontHeader.yMax = READFWORD(ffile->fp);
  901. fontHeader.macStyle = READUSHORT(ffile->fp);
  902. fontHeader.lowestRecPPEM = READUSHORT(ffile->fp);
  903. fontHeader.fontDirectionHint = READSHORT(ffile->fp);
  904. fontHeader.indexToLocFormat = READSHORT(ffile->fp);
  905. fontHeader.glyphDataFormat = READSHORT(ffile->fp);
  906. #ifdef TTF_DEBUG
  907. Debug_Info("\nfontHeader:\n");
  908. Debug_Info("version: %d\n",fontHeader.version);
  909. Debug_Info("fontRevision: %d\n",fontHeader.fontRevision);
  910. Debug_Info("checkSumAdjustment: %u\n",fontHeader.checkSumAdjustment);
  911. Debug_Info("magicNumber: 0x%8X\n",fontHeader.magicNumber);
  912. Debug_Info("flags: %u\n",fontHeader.flags);
  913. Debug_Info("unitsPerEm: %u\n",fontHeader.unitsPerEm);
  914. Debug_Info("created.bc: %u\n",fontHeader.created.bc);
  915. Debug_Info("created.ad: %u\n",fontHeader.created.ad);
  916. Debug_Info("modified.bc: %u\n",fontHeader.modified.bc);
  917. Debug_Info("modified.ad: %u\n",fontHeader.modified.ad);
  918. Debug_Info("xMin: %d\n",fontHeader.xMin);
  919. Debug_Info("yMin: %d\n",fontHeader.yMin);
  920. Debug_Info("xMax: %d\n",fontHeader.xMax);
  921. Debug_Info("yMax: %d\n",fontHeader.yMax);
  922. Debug_Info("macStyle: %u\n",fontHeader.macStyle);
  923. Debug_Info("lowestRecPPEM: %u\n",fontHeader.lowestRecPPEM);
  924. Debug_Info("fontDirectionHint: %d\n",fontHeader.fontDirectionHint);
  925. Debug_Info("indexToLocFormat: %d\n",fontHeader.indexToLocFormat);
  926. Debug_Info("glyphDataFormat: %d\n",fontHeader.glyphDataFormat);
  927. #endif
  928. if (fontHeader.magicNumber != 0x5F0F3CF5)
  929. {
  930. Error("Error reading TrueType font %s. Bad magic number (0x%8X)\n",
  931. ffile->filename, fontHeader.magicNumber);
  932. }
  933. ffile->indexToLocFormat = fontHeader.indexToLocFormat;
  934. ffile->unitsPerEm = fontHeader.unitsPerEm;
  935. }
  936. /* Determine the relative offsets of glyphs */
  937. static void ProcessLocaTable(FontFileInfo *ffile, long loca_table_offset)
  938. {
  939. int i;
  940. /* Move to location of table in file */
  941. fseek(ffile->fp, loca_table_offset, SEEK_SET);
  942. ffile->loca_table = (ULONG *)POV_MALLOC((ffile->numGlyphs+1) * sizeof(ULONG), "ttf");
  943. #ifdef TTF_DEBUG
  944. Debug_Info("\nlocation table:\n");
  945. Debug_Info("version: %s\n",(ffile->indexToLocFormat?"long":"short"));
  946. #endif
  947. /* Now read and save the location table */
  948. if (ffile->indexToLocFormat == 0) /* short version */
  949. {
  950. for (i = 0; i < ffile->numGlyphs; i++)
  951. {
  952. ffile->loca_table[i] = ((ULONG)READUSHORT(ffile->fp)) << 1;
  953. #ifdef TTF_DEBUG2
  954. Debug_Info("loca_table[%d] @ %u\n", i, ffile->loca_table[i]);
  955. #endif
  956. }
  957. }
  958. else /* long version */
  959. {
  960. for (i = 0; i < ffile->numGlyphs; i++)
  961. {
  962. ffile->loca_table[i] = READULONG(ffile->fp);
  963. #ifdef TTF_DEBUG2
  964. Debug_Info("loca_table[%d] @ %u\n", i, ffile->loca_table[i]);
  965. #endif
  966. }
  967. }
  968. }
  969. /*
  970. * This routine determines the total number of glyphs in a TrueType file.
  971. * Necessary so that we can allocate the proper amount of storage for the glyph
  972. * location table.
  973. */
  974. static void ProcessMaxpTable(FontFileInfo *ffile, long maxp_table_offset)
  975. {
  976. /* Seek to the maxp table, skipping the 4 byte version number */
  977. fseek(ffile->fp, maxp_table_offset + 4, SEEK_SET);
  978. ffile->numGlyphs = READUSHORT(ffile->fp);
  979. #ifdef TTF_DEBUG
  980. Debug_Info("\nmaximum profile table:\n");
  981. Debug_Info("numGlyphs: %u\n", ffile->numGlyphs);
  982. #endif
  983. }
  984. /* Read the kerning information for a glyph */
  985. static void ProcessKernTable(FontFileInfo *ffile, long kern_table_offset)
  986. {
  987. int i, j;
  988. USHORT temp16;
  989. USHORT length;
  990. KernTables *kern_table;
  991. kern_table = &ffile->kerning_tables;
  992. /* Move to the beginning of the kerning table, skipping the 2 byte version */
  993. fseek(ffile->fp, kern_table_offset + 2, SEEK_SET);
  994. /* Read in the number of kerning tables */
  995. kern_table->nTables = READUSHORT(ffile->fp);
  996. kern_table->tables = NULL; /*<==[esp] added (in case nTables is zero)*/
  997. #ifdef TTF_DEBUG
  998. Debug_Info("\nKerning table:\n", kern_table_offset);
  999. Debug_Info("Offset: %ld\n", kern_table_offset);
  1000. Debug_Info("Number of tables: %u\n",kern_table->nTables);
  1001. #endif
  1002. /* Don't do any more work if there isn't kerning info */
  1003. if (kern_table->nTables == 0)
  1004. return;
  1005. kern_table->tables = (TTKernTable *)POV_MALLOC(kern_table->nTables * sizeof(TTKernTable),
  1006. "ProcessKernTable");
  1007. for (i = 0; i < kern_table->nTables; i++)
  1008. {
  1009. /* Read in a subtable */
  1010. temp16 = READUSHORT(ffile->fp); /* Subtable version */
  1011. length = READUSHORT(ffile->fp); /* Subtable length */
  1012. kern_table->tables[i].coverage = READUSHORT(ffile->fp); /* Coverage bits */
  1013. #ifdef TTF_DEBUG
  1014. Debug_Info("Coverage table[%d] (0x%X):", i, kern_table->tables[i].coverage);
  1015. Debug_Info(" type %u", (kern_table->tables[i].coverage >> 8));
  1016. Debug_Info(" %s", (kern_table->tables[i].coverage & KERN_HORIZONTAL ?
  1017. "Horizontal" : "Vertical" ));
  1018. Debug_Info(" %s values", (kern_table->tables[i].coverage & KERN_MINIMUM ?
  1019. "Minimum" : "Kerning" ));
  1020. Debug_Info("%s", (kern_table->tables[i].coverage & KERN_CROSS_STREAM ?
  1021. " Cross-stream" : "" ));
  1022. Debug_Info("%s\n", (kern_table->tables[i].coverage & KERN_OVERRIDE ?
  1023. " Override" : "" ));
  1024. #endif
  1025. kern_table->tables[i].kern_pairs = NULL; /*<==[esp] added*/
  1026. kern_table->tables[i].nPairs = 0; /*<==[esp] added*/
  1027. if ((kern_table->tables[i].coverage >> 8) == 0)
  1028. {
  1029. /* Can only handle format 0 kerning subtables */
  1030. kern_table->tables[i].nPairs = READUSHORT(ffile->fp);
  1031. #ifdef TTF_DEBUG
  1032. Debug_Info("entries in table[%d]: %d\n", i, kern_table->tables[i].nPairs);
  1033. #endif
  1034. temp16 = READUSHORT(ffile->fp); /* searchRange */
  1035. temp16 = READUSHORT(ffile->fp); /* entrySelector */
  1036. temp16 = READUSHORT(ffile->fp); /* rangeShift */
  1037. kern_table->tables[i].kern_pairs =
  1038. (KernData *)POV_MALLOC(kern_table->tables[i].nPairs * sizeof(KernData), "Kern Pairs");
  1039. for (j = 0; j < kern_table->tables[i].nPairs; j++)
  1040. {
  1041. /* Read in a kerning pair */
  1042. kern_table->tables[i].kern_pairs[j].left = READUSHORT(ffile->fp);
  1043. kern_table->tables[i].kern_pairs[j].right = READUSHORT(ffile->fp);
  1044. kern_table->tables[i].kern_pairs[j].value = READFWORD(ffile->fp);
  1045. #ifdef TTF_DEBUG2
  1046. Debug_Info("Kern pair: <%d,%d> = %d\n",
  1047. (int)kern_table->tables[i].kern_pairs[j].left,
  1048. (int)kern_table->tables[i].kern_pairs[j].right,
  1049. (int)kern_table->tables[i].kern_pairs[j].value);
  1050. #endif
  1051. }
  1052. }
  1053. else
  1054. {
  1055. #ifdef TTF_DEBUG2
  1056. Warning(0.0, "Cannot handle format %u kerning data\n",
  1057. (kern_table->tables[i].coverage >> 8));
  1058. #endif
  1059. /*
  1060. * Seek to the end of this table, excluding the length of the version,
  1061. * length, and coverage USHORTs, which we have already read.
  1062. */
  1063. fseek(ffile->fp, (long)(length - 6), SEEK_CUR);
  1064. kern_table->tables[i].nPairs = 0;
  1065. }
  1066. }
  1067. }
  1068. /*
  1069. * This routine determines the total number of horizontal metrics.
  1070. */
  1071. static void ProcessHheaTable(FontFileInfo *ffile, long hhea_table_offset)
  1072. {
  1073. #ifdef TTF_DEBUG
  1074. sfnt_HorizHeader horizHeader;
  1075. /* Seek to the hhea table */
  1076. fseek(ffile->fp, hhea_table_offset, SEEK_SET);
  1077. horizHeader.version = READFIXED(ffile->fp);
  1078. horizHeader.Ascender = READFWORD(ffile->fp);
  1079. horizHeader.Descender = READFWORD(ffile->fp);
  1080. horizHeader.LineGap = READFWORD(ffile->fp);
  1081. horizHeader.advanceWidthMax = READUFWORD(ffile->fp);
  1082. horizHeader.minLeftSideBearing = READFWORD(ffile->fp);
  1083. horizHeader.minRightSideBearing = READFWORD(ffile->fp);
  1084. horizHeader.xMaxExtent = READFWORD(ffile->fp);
  1085. horizHeader.caretSlopeRise = READSHORT(ffile->fp);
  1086. horizHeader.caretSlopeRun = READSHORT(ffile->fp);
  1087. horizHeader.reserved1 = READSHORT(ffile->fp);
  1088. horizHeader.reserved2 = READSHORT(ffile->fp);
  1089. horizHeader.reserved3 = READSHORT(ffile->fp);
  1090. horizHeader.reserved4 = READSHORT(ffile->fp);
  1091. horizHeader.reserved5 = READSHORT(ffile->fp);
  1092. horizHeader.metricDataFormat = READSHORT(ffile->fp);
  1093. #else
  1094. /* Seek to the hhea table, skipping all that stuff we don't need */
  1095. fseek(ffile->fp, hhea_table_offset + 34, SEEK_SET);
  1096. #endif
  1097. ffile->numberOfHMetrics = READUSHORT(ffile->fp);
  1098. #ifdef TTF_DEBUG
  1099. Debug_Info("\nhorizontal header table:\n");
  1100. Debug_Info("Ascender: %d\n",horizHeader.Ascender);
  1101. Debug_Info("Descender: %d\n",horizHeader.Descender);
  1102. Debug_Info("LineGap: %d\n",horizHeader.LineGap);
  1103. Debug_Info("advanceWidthMax: %d\n",horizHeader.advanceWidthMax);
  1104. Debug_Info("minLeftSideBearing: %d\n",horizHeader.minLeftSideBearing);
  1105. Debug_Info("minRightSideBearing: %d\n",horizHeader.minRightSideBearing);
  1106. Debug_Info("xMaxExtent: %d\n",horizHeader.xMaxExtent);
  1107. Debug_Info("caretSlopeRise: %d\n",horizHeader.caretSlopeRise);
  1108. Debug_Info("caretSlopeRun: %d\n",horizHeader.caretSlopeRun);
  1109. Debug_Info("metricDataFormat: %d\n",horizHeader.metricDataFormat);
  1110. Debug_Info("numberOfHMetrics: %d\n",ffile->numberOfHMetrics);
  1111. #endif
  1112. }
  1113. static void ProcessHmtxTable (FontFileInfo *ffile, long hmtx_table_offset)
  1114. {
  1115. int i;
  1116. longHorMetric *metric;
  1117. uFWord lastAW = 0; /* Just to quiet warnings. */
  1118. fseek(ffile->fp, hmtx_table_offset, SEEK_SET);
  1119. ffile->hmtx_table = (longHorMetric *)POV_MALLOC(ffile->numGlyphs*sizeof(longHorMetric), "ttf");
  1120. /*
  1121. * Read in the total glyph width, and the left side offset. There is
  1122. * guaranteed to be at least one longHorMetric entry in this table to
  1123. * set the advanceWidth for the subsequent lsb entries.
  1124. */
  1125. for (i=0, metric=ffile->hmtx_table; i < ffile->numberOfHMetrics; i++,metric++)
  1126. {
  1127. lastAW = metric->advanceWidth = READUFWORD(ffile->fp);
  1128. metric->lsb = READFWORD(ffile->fp);
  1129. }
  1130. /* Read in the remaining left offsets */
  1131. for (; i < ffile->numGlyphs; i++, metric++)
  1132. {
  1133. metric->advanceWidth = lastAW;
  1134. metric->lsb = READFWORD(ffile->fp);
  1135. }
  1136. }
  1137. /*****************************************************************************
  1138. *
  1139. * FUNCTION
  1140. *
  1141. * ProcessCharacter
  1142. *
  1143. * INPUT
  1144. *
  1145. * OUTPUT
  1146. *
  1147. * RETURNS
  1148. *
  1149. * AUTHOR
  1150. *
  1151. * POV-Ray Team
  1152. *
  1153. * DESCRIPTION
  1154. *
  1155. * Finds the glyph description for the current character.
  1156. *
  1157. * CHANGES
  1158. *
  1159. * -
  1160. *
  1161. ******************************************************************************/
  1162. static GlyphPtr ProcessCharacter(FontFileInfo *ffile, unsigned int search_char, unsigned int *glyph_index)
  1163. {
  1164. GlyphPtr glyph;
  1165. /* See if we have already processed this glyph */
  1166. for (glyph = ffile->glyphs; glyph != NULL; glyph = glyph->next)
  1167. {
  1168. if (glyph->c == search_char)
  1169. {
  1170. /* Found it, no need to do any more work */
  1171. #ifdef TTF_DEBUG
  1172. Debug_Info("Cached glyph: %c/%u\n",(char)search_char,glyph->glyph_index);
  1173. #endif
  1174. *glyph_index = glyph->glyph_index;
  1175. return glyph;
  1176. }
  1177. }
  1178. *glyph_index = ProcessCharMap(ffile, search_char);
  1179. if (*glyph_index == 0)
  1180. Warning(0.0, "Character %d (0x%X) not found in %s\n", (BYTE)search_char,
  1181. search_char, ffile->filename);
  1182. /* See if we have already processed this glyph (using the glyph index) */
  1183. for (glyph = ffile->glyphs; glyph != NULL; glyph = glyph->next)
  1184. {
  1185. if (glyph->glyph_index == *glyph_index)
  1186. {
  1187. /* Found it, no need to do any more work */
  1188. #ifdef TTF_DEBUG
  1189. Debug_Info("Cached glyph: %c/%u\n",(char)search_char,glyph->glyph_index);
  1190. #endif
  1191. *glyph_index = glyph->glyph_index;
  1192. return glyph;
  1193. }
  1194. }
  1195. glyph = ExtractGlyphInfo(ffile, glyph_index, search_char);
  1196. /* Add this glyph to the ones we already know about */
  1197. glyph->next = ffile->glyphs;
  1198. ffile->glyphs = glyph;
  1199. /* Glyph is all built */
  1200. return glyph;
  1201. }
  1202. /*****************************************************************************
  1203. *
  1204. * FUNCTION
  1205. *
  1206. * ProcessCharMap
  1207. *
  1208. * INPUT
  1209. *
  1210. * OUTPUT
  1211. *
  1212. * RETURNS
  1213. *
  1214. * AUTHOR
  1215. *
  1216. * POV-Ray Team
  1217. *
  1218. * DESCRIPTION
  1219. *
  1220. * Find the character mapping for 'search_char'. We should really know
  1221. * which character set we are using (ie ISO 8859-1, Mac, Unicode, etc).
  1222. * Search char should really be a USHORT to handle double byte systems.
  1223. *
  1224. * CHANGES
  1225. *
  1226. * 961120 esp Added check to allow Macintosh encodings to pass
  1227. *
  1228. ******************************************************************************/
  1229. static USHORT ProcessCharMap(FontFileInfo *ffile, unsigned int search_char)
  1230. {
  1231. long old_table_offset;
  1232. long entry_offset;
  1233. sfnt_platformEntry cmapEntry;
  1234. sfnt_mappingTable encodingTable;
  1235. int i, table_count;
  1236. /* Move to the start of the character map, skipping the 2 byte version */
  1237. fseek(ffile->fp, ffile->cmap_table_offset + 2, SEEK_SET);
  1238. table_count = READUSHORT(ffile->fp);
  1239. #ifdef TTF_DEBUG
  1240. Debug_Info("table_count=%d\n", table_count);
  1241. #endif
  1242. /*
  1243. * Search the tables until we find the glyph index for the search character.
  1244. * Just return the first one we find...
  1245. */
  1246. for (i = 0; i < table_count; i++)
  1247. {
  1248. cmapEntry.platformID = READUSHORT(ffile->fp);
  1249. cmapEntry.specificID = READUSHORT(ffile->fp);
  1250. cmapEntry.offset = READULONG(ffile->fp);
  1251. #ifdef TTF_DEBUG
  1252. Debug_Info("cmapEntry: platformID=%d\n", cmapEntry.platformID);
  1253. Debug_Info("cmapEntry: specificID=%d\n", cmapEntry.specificID);
  1254. Debug_Info("cmapEntry: offset=%d\n", cmapEntry.offset);
  1255. #endif
  1256. /*
  1257. * Check if this is the encoding table we want to use. We can't
  1258. * be very picky, since we don't know what the user really wants.
  1259. * It would be nice to know what we are really looking for.
  1260. * Allow Type 1 platform as well (Macintosh) [esp]
  1261. */
  1262. if ((ffile->platformID != cmapEntry.platformID) && (1 != cmapEntry.platformID))
  1263. {
  1264. continue;
  1265. }
  1266. entry_offset = cmapEntry.offset;
  1267. old_table_offset = ftell(ffile->fp); /* Save the current position */
  1268. fseek(ffile->fp, ffile->cmap_table_offset + entry_offset, SEEK_SET);
  1269. encodingTable.format = READUSHORT(ffile->fp);
  1270. encodingTable.length = READUSHORT(ffile->fp);
  1271. encodingTable.version = READUSHORT(ffile->fp);
  1272. #ifdef TTF_DEBUG
  1273. Debug_Info("Encoding table, format: %u, length: %u, version: %u\n",
  1274. encodingTable.format, encodingTable.length, encodingTable.version);
  1275. #endif
  1276. if (encodingTable.format == 0)
  1277. {
  1278. /*
  1279. * Translation is simple - add 'entry_char' to the start of the
  1280. * table and grab what's there.
  1281. */
  1282. #ifdef TTF_DEBUG
  1283. Debug_Info("Apple standard index mapping\n");
  1284. #endif
  1285. return(ProcessFormat0Glyph(ffile, search_char));
  1286. }
  1287. #if 0 /* Want to get the rest of these working first */
  1288. else if (encodingTable.format == 2)
  1289. {
  1290. /* Used for multi-byte character encoding (Chinese, Japanese, etc) */
  1291. #ifdef TTF_DEBUG
  1292. Debug_Info("High-byte index mapping\n");
  1293. #endif
  1294. return(ProcessFormat2Glyph(ffile, search_char));
  1295. }
  1296. #endif
  1297. else if (encodingTable.format == 4)
  1298. {
  1299. /* Microsoft UGL encoding */
  1300. #ifdef TTF_DEBUG
  1301. Debug_Info("Microsoft standard index mapping\n");
  1302. #endif
  1303. return(ProcessFormat4Glyph(ffile, search_char));
  1304. }
  1305. else if (encodingTable.format == 6)
  1306. {
  1307. #ifdef TTF_DEBUG
  1308. Debug_Info("Trimmed table mapping\n");
  1309. #endif
  1310. return(ProcessFormat6Glyph(ffile, search_char));
  1311. }
  1312. #ifdef TTF_DEBUG
  1313. else
  1314. Debug_Info("Unsupported index mapping format: %u\n",
  1315. encodingTable.format);
  1316. #endif
  1317. /* Go to the next table entry if we didn't find a match */
  1318. fseek(ffile->fp, old_table_offset, SEEK_SET);
  1319. }
  1320. /*
  1321. * No character mapping was found - very odd, we should really have had the
  1322. * character in at least one table. Perhaps getting here means we didn't
  1323. * have any character mapping tables. '0' means no mapping.
  1324. */
  1325. return 0;
  1326. }
  1327. /*****************************************************************************
  1328. *
  1329. * FUNCTION
  1330. *
  1331. * ProcessFormat0Glyph
  1332. *
  1333. * INPUT
  1334. *
  1335. * OUTPUT
  1336. *
  1337. * RETURNS
  1338. *
  1339. * AUTHOR
  1340. *
  1341. * POV-Ray Team
  1342. *
  1343. * DESCRIPTION
  1344. *
  1345. * This handles the Apple standard index mapping for glyphs.
  1346. * The file pointer must be pointing immediately after the version entry in the
  1347. * encoding table for the next two functions to work.
  1348. *
  1349. * CHANGES
  1350. *
  1351. * -
  1352. *
  1353. ******************************************************************************/
  1354. static USHORT ProcessFormat0Glyph(FontFileInfo *ffile, unsigned int search_char)
  1355. {
  1356. BYTE temp_index;
  1357. fseek(ffile->fp, (long)search_char, SEEK_CUR);
  1358. if (fread(&temp_index, 1, 1, ffile->fp) != 1) /* Each index is 1 byte */
  1359. {
  1360. Error("Error reading TrueType font file at line %d, %s\n",
  1361. __LINE__, __FILE__);
  1362. }
  1363. return (USHORT)(temp_index);
  1364. }
  1365. /*****************************************************************************
  1366. *
  1367. * FUNCTION
  1368. *
  1369. * ProcessFormat4Glyph
  1370. *
  1371. * INPUT
  1372. *
  1373. * OUTPUT
  1374. *
  1375. * RETURNS
  1376. *
  1377. * AUTHOR
  1378. *
  1379. * POV-Ray Team
  1380. *
  1381. * DESCRIPTION
  1382. *
  1383. * This handles the Microsoft standard index mapping for glyph tables
  1384. *
  1385. * CHANGES
  1386. *
  1387. * Mar 26, 1996: Cache segment info rather than read each time. [AED]
  1388. *
  1389. ******************************************************************************/
  1390. static USHORT ProcessFormat4Glyph(FontFileInfo *ffile, unsigned int search_char)
  1391. {
  1392. int i;
  1393. unsigned int glyph_index = 0; /* Set the glyph index to "not present" */
  1394. /*
  1395. * If this is the first time we are here, read all of the segment headers,
  1396. * and save them for later calls to this function, rather than seeking and
  1397. * mallocing for each character
  1398. */
  1399. if (ffile->segCount == 0)
  1400. {
  1401. USHORT temp16;
  1402. ffile->segCount = READUSHORT(ffile->fp) >> 1;
  1403. ffile->searchRange = READUSHORT(ffile->fp);
  1404. ffile->entrySelector = READUSHORT(ffile->fp);
  1405. ffile->rangeShift = READUSHORT(ffile->fp);
  1406. /* Now allocate and read in the segment arrays */
  1407. ffile->endCount = (USHORT *)POV_MALLOC(ffile->segCount * sizeof(USHORT), "ttf");
  1408. ffile->startCount = (USHORT *)POV_MALLOC(ffile->segCount * sizeof(USHORT), "ttf");
  1409. ffile->idDelta = (USHORT *)POV_MALLOC(ffile->segCount * sizeof(USHORT), "ttf");
  1410. ffile->idRangeOffset = (USHORT *)POV_MALLOC(ffile->segCount * sizeof(USHORT), "ttf");
  1411. for (i = 0; i < ffile->segCount; i++)
  1412. {
  1413. ffile->endCount[i] = READUSHORT(ffile->fp);
  1414. }
  1415. temp16 = READUSHORT(ffile->fp); /* Skip over 'reservedPad' */
  1416. for (i = 0; i < ffile->segCount; i++)
  1417. {
  1418. ffile->startCount[i] = READUSHORT(ffile->fp);
  1419. }
  1420. for (i = 0; i < ffile->segCount; i++)
  1421. {
  1422. ffile->idDelta[i] = READUSHORT(ffile->fp);
  1423. }
  1424. /* location of start of idRangeOffset */
  1425. ffile->glyphIDoffset = ftell(ffile->fp);
  1426. for (i = 0; i < ffile->segCount; i++)
  1427. {
  1428. ffile->idRangeOffset[i] = READUSHORT(ffile->fp);
  1429. }
  1430. }
  1431. /* Search the segments for our character */
  1432. glyph_search:
  1433. for (i = 0; i < ffile->segCount; i++)
  1434. {
  1435. if (search_char <= ffile->endCount[i])
  1436. {
  1437. if (search_char >= ffile->startCount[i])
  1438. {
  1439. /* Found correct range for this character */
  1440. if (ffile->idRangeOffset[i] == 0)
  1441. {
  1442. glyph_index = search_char + ffile->idDelta[i];
  1443. }
  1444. else
  1445. {
  1446. /*
  1447. * Alternate encoding of glyph indices, relies on a quite unusual way
  1448. * of storing the offsets. We need the *2s because we are talking
  1449. * about addresses of shorts and not bytes.
  1450. *
  1451. * (glyphIDoffset + i*2 + idRangeOffset[i]) == &idRangeOffset[i]
  1452. */
  1453. fseek(ffile->fp, ffile->glyphIDoffset + 2*i + ffile->idRangeOffset[i]+
  1454. 2*(search_char - ffile->startCount[i]), SEEK_SET);
  1455. glyph_index = READUSHORT(ffile->fp);
  1456. if (glyph_index != 0)
  1457. glyph_index = glyph_index + ffile->idDelta[i];
  1458. }
  1459. }
  1460. break;
  1461. }
  1462. }
  1463. /*
  1464. * If we haven't found the character yet, and this is the first time to
  1465. * search the tables, try looking in the Unicode user space, since this
  1466. * is the location Microsoft recommends for symbol characters like those
  1467. * in wingdings and dingbats.
  1468. */
  1469. if (glyph_index == 0 && search_char < 0x100)
  1470. {
  1471. search_char += 0xF000;
  1472. #ifdef TTF_DEBUG
  1473. Debug_Info("Looking for glyph in Unicode user space (0x%X)\n", search_char);
  1474. #endif
  1475. goto glyph_search;
  1476. }
  1477. /* Deallocate the memory we used for the segment arrays */
  1478. return glyph_index;
  1479. }
  1480. /*****************************************************************************
  1481. *
  1482. * FUNCTION
  1483. *
  1484. * ProcessFormat6Glyph
  1485. *
  1486. * INPUT
  1487. *
  1488. * OUTPUT
  1489. *
  1490. * RETURNS
  1491. *
  1492. * AUTHOR
  1493. *
  1494. * POV-Ray Team
  1495. *
  1496. * DESCRIPTION
  1497. *
  1498. * This handles the trimmed table mapping for glyphs.
  1499. *
  1500. * CHANGES
  1501. *
  1502. * -
  1503. *
  1504. ******************************************************************************/
  1505. static USHORT ProcessFormat6Glyph(FontFileInfo *ffile, unsigned int search_char)
  1506. {
  1507. USHORT firstCode, entryCount;
  1508. BYTE glyph_index;
  1509. firstCode = READUSHORT(ffile->fp);
  1510. entryCount = READUSHORT(ffile->fp);
  1511. if (search_char >= firstCode && search_char < firstCode + entryCount)
  1512. {
  1513. fseek(ffile->fp, (long)(search_char - firstCode), SEEK_CUR);
  1514. glyph_index = READUSHORT(ffile->fp);
  1515. }
  1516. else
  1517. glyph_index = 0;
  1518. return glyph_index;
  1519. }
  1520. /*****************************************************************************
  1521. *
  1522. * FUNCTION
  1523. *
  1524. * ExtractGlyphInfo
  1525. *
  1526. * INPUT
  1527. *
  1528. * OUTPUT
  1529. *
  1530. * RETURNS
  1531. *
  1532. * AUTHOR
  1533. *
  1534. * POV-Ray Team
  1535. *
  1536. * DESCRIPTION
  1537. *
  1538. * Change TTF outline information for the glyph(s) into a useful format
  1539. *
  1540. * CHANGES
  1541. *
  1542. * -
  1543. *
  1544. ******************************************************************************/
  1545. static GlyphPtr ExtractGlyphInfo(FontFileInfo *ffile, unsigned int *glyph_index, unsigned int c)
  1546. {
  1547. GlyphOutline *ttglyph;
  1548. GlyphPtr glyph;
  1549. ttglyph = ExtractGlyphOutline(ffile, glyph_index, c);
  1550. /*
  1551. * Convert the glyph outline information from TrueType layout into a more
  1552. * easily processed format
  1553. */
  1554. glyph = ConvertOutlineToGlyph(ffile, ttglyph);
  1555. glyph->c = c;
  1556. glyph->glyph_index = *glyph_index;
  1557. glyph->myMetrics = ttglyph->myMetrics;
  1558. /* Free up outline information */
  1559. if (ttglyph)
  1560. {
  1561. if (ttglyph->y) POV_FREE(ttglyph->y);
  1562. if (ttglyph->x) POV_FREE(ttglyph->x);
  1563. if (ttglyph->endPoints) POV_FREE(ttglyph->endPoints);
  1564. if (ttglyph->flags) POV_FREE(ttglyph->flags);
  1565. POV_FREE(ttglyph);
  1566. }
  1567. return glyph;
  1568. }
  1569. /*****************************************************************************
  1570. *
  1571. * FUNCTION
  1572. *
  1573. * ExtractGlyphOutline
  1574. *
  1575. * INPUT
  1576. *
  1577. * OUTPUT
  1578. *
  1579. * RETURNS
  1580. *
  1581. * AUTHOR
  1582. *
  1583. * POV-Ray Team
  1584. *
  1585. * DESCRIPTION
  1586. *
  1587. * Read the contour information for a specific glyph. This has to be a
  1588. * separate routine from ExtractGlyphInfo because we call it recurisvely
  1589. * for multiple component glyphs.
  1590. *
  1591. * CHANGES
  1592. *
  1593. * -
  1594. *
  1595. ******************************************************************************/
  1596. static GlyphOutline *ExtractGlyphOutline(FontFileInfo *ffile, unsigned int *glyph_index, unsigned int c)
  1597. {
  1598. int i;
  1599. USHORT n;
  1600. SHORT nc;
  1601. GlyphOutline *ttglyph;
  1602. ttglyph = (GlyphOutline *)POV_CALLOC(1, sizeof(GlyphOutline), "ttf");
  1603. ttglyph->myMetrics = *glyph_index;
  1604. /* Have to treat space characters differently */
  1605. if (c != ' ')
  1606. {
  1607. fseek(ffile->fp, ffile->glyf_table_offset+ffile->loca_table[*glyph_index],
  1608. SEEK_SET);
  1609. ttglyph->header.numContours = READSHORT(ffile->fp);
  1610. ttglyph->header.xMin = READFWORD(ffile->fp); /* These may be */
  1611. ttglyph->header.yMin = READFWORD(ffile->fp); /* unreliable in */
  1612. ttglyph->header.xMax = READFWORD(ffile->fp); /* some fonts. */
  1613. ttglyph->header.yMax = READFWORD(ffile->fp);
  1614. }
  1615. #ifdef TTF_DEBUG
  1616. Debug_Info("ttglyph->header:\n");
  1617. Debug_Info("glyph_index=%d\n", *glyph_index);
  1618. Debug_Info("loca_table[%d]=%d\n",*glyph_index,ffile->loca_table[*glyph_index]);
  1619. Debug_Info("numContours=%d\n", ttglyph->header.numContours);
  1620. #endif
  1621. nc = ttglyph->header.numContours;
  1622. /*
  1623. * A positive number of contours means a regular glyph, with possibly
  1624. * several separate line segments making up the outline.
  1625. */
  1626. if (nc > 0)
  1627. {
  1628. FWord coord;
  1629. BYTE flag, repeat_count;
  1630. USHORT temp16;
  1631. /* Grab the contour endpoints */
  1632. ttglyph->endPoints = (USHORT *)POV_MALLOC(nc * sizeof(USHORT), "ttf");
  1633. for (i = 0; i < nc; i++)
  1634. {
  1635. ttglyph->endPoints[i] = READUSHORT(ffile->fp);
  1636. #ifdef TTF_DEBUG
  1637. Debug_Info("endPoints[%d]=%d\n", i, ttglyph->endPoints[i]);
  1638. #endif
  1639. }
  1640. /* Skip over the instructions */
  1641. temp16 = READUSHORT(ffile->fp);
  1642. fseek(ffile->fp, temp16, SEEK_CUR);
  1643. /* Determine the number of points making up this glyph */
  1644. n = ttglyph->numPoints = ttglyph->endPoints[nc - 1] + 1;
  1645. #ifdef TTF_DEBUG
  1646. Debug_Info("numPoints=%d\n", ttglyph->numPoints);
  1647. #endif
  1648. /* Read the flags */
  1649. ttglyph->flags = (BYTE *)POV_MALLOC(n * sizeof(BYTE), "ttf");
  1650. for (i = 0; i < ttglyph->numPoints; i++)
  1651. {
  1652. if (fread(&ttglyph->flags[i], sizeof(BYTE), 1, ffile->fp) != 1)
  1653. {
  1654. Error("Error reading TrueType font file at line %d, %s\n",
  1655. __LINE__, __FILE__);
  1656. }
  1657. if (ttglyph->flags[i] & REPEAT_FLAGS)
  1658. {
  1659. if (fread(&repeat_count, sizeof(BYTE), 1, ffile->fp) != 1)
  1660. {
  1661. Error("Error reading TrueType font file at line %d, %s\n",
  1662. __LINE__, __FILE__);
  1663. }
  1664. for (; repeat_count > 0; repeat_count--, i++)
  1665. {
  1666. ttglyph->flags[i + 1] = ttglyph->flags[i];
  1667. }
  1668. }
  1669. }
  1670. /* Read the coordinate vectors */
  1671. ttglyph->x = (DBL *)POV_MALLOC(n * sizeof(DBL), "ttf");
  1672. ttglyph->y = (DBL *)POV_MALLOC(n * sizeof(DBL), "ttf");
  1673. coord = 0;
  1674. for (i = 0; i < ttglyph->numPoints; i++)
  1675. {
  1676. /* Read each x coordinate */
  1677. flag = ttglyph->flags[i];
  1678. if (flag & XSHORT)
  1679. {
  1680. BYTE temp8;
  1681. if (fread(&temp8, 1, 1, ffile->fp) != 1)
  1682. {
  1683. Error("Error reading TrueType font file at line %d, %s\n",
  1684. __LINE__, __FILE__);
  1685. }
  1686. if (flag & SHORT_X_IS_POS)
  1687. coord += temp8;
  1688. else
  1689. coord -= temp8;
  1690. }
  1691. else if (!(flag & NEXT_X_IS_ZERO))
  1692. {
  1693. coord += READSHORT(ffile->fp);
  1694. }
  1695. /* Find our own maximum and minimum x coordinates */
  1696. if (coord > ttglyph->header.xMax)
  1697. ttglyph->header.xMax = coord;
  1698. if (coord < ttglyph->header.xMin)
  1699. ttglyph->header.xMin = coord;
  1700. ttglyph->x[i] = (DBL)coord / (DBL)ffile->unitsPerEm;
  1701. }
  1702. coord = 0;
  1703. for (i = 0; i < ttglyph->numPoints; i++)
  1704. {
  1705. /* Read each y coordinate */
  1706. flag = ttglyph->flags[i];
  1707. if (flag & YSHORT)
  1708. {
  1709. BYTE temp8;
  1710. if (fread(&temp8, 1, 1, ffile->fp) != 1)
  1711. {
  1712. Error("Error reading TrueType font file at line %d, %s\n",
  1713. __LINE__, __FILE__);
  1714. }
  1715. if (flag & SHORT_Y_IS_POS)
  1716. coord += temp8;
  1717. else
  1718. coord -= temp8;
  1719. }
  1720. else if (!(flag & NEXT_Y_IS_ZERO))
  1721. {
  1722. coord += READSHORT(ffile->fp);
  1723. }
  1724. /* Find out our own maximum and minimum y coordinates */
  1725. if (coord > ttglyph->header.yMax)
  1726. ttglyph->header.yMax = coord;
  1727. if (coord < ttglyph->header.yMin)
  1728. ttglyph->header.yMin = coord;
  1729. ttglyph->y[i] = (DBL)coord / (DBL)ffile->unitsPerEm;
  1730. }
  1731. }
  1732. /*
  1733. * A negative number for numContours means that this glyph is
  1734. * made up of several separate glyphs.
  1735. */
  1736. else if (nc < 0)
  1737. {
  1738. USHORT flags;
  1739. ttglyph->header.numContours = 0;
  1740. ttglyph->numPoints = 0;
  1741. do
  1742. {
  1743. GlyphOutline *sub_ttglyph;
  1744. unsigned int sub_glyph_index;
  1745. long current_pos;
  1746. SHORT arg1, arg2;
  1747. DBL xoff = 0, yoff = 0;
  1748. DBL xscale = 1, yscale = 1;
  1749. DBL scale01 = 0, scale10 = 0;
  1750. USHORT n2;
  1751. SHORT nc2;
  1752. flags = READUSHORT(ffile->fp);
  1753. sub_glyph_index = READUSHORT(ffile->fp);
  1754. #ifdef TTF_DEBUG
  1755. Debug_Info("sub_glyph %d: ", sub_glyph_index);
  1756. #endif
  1757. if (flags & ARG_1_AND_2_ARE_WORDS)
  1758. {
  1759. #ifdef TTF_DEBUG
  1760. Debug_Info("ARG_1_AND_2_ARE_WORDS ");
  1761. #endif
  1762. arg1 = READSHORT(ffile->fp);
  1763. arg2 = READSHORT(ffile->fp);
  1764. }
  1765. else
  1766. {
  1767. arg1 = READUSHORT(ffile->fp);
  1768. arg2 = arg1 & 0xFF;
  1769. arg1 = (arg1 >> 8) & 0xFF;
  1770. }
  1771. #ifdef TTF_DEBUG
  1772. if (flags & ROUND_XY_TO_GRID)
  1773. {
  1774. Debug_Info("ROUND_XY_TO_GRID ");
  1775. }
  1776. if (flags & MORE_COMPONENTS)
  1777. {
  1778. Debug_Info("MORE_COMPONENTS ");
  1779. }
  1780. #endif
  1781. if (flags & WE_HAVE_A_SCALE)
  1782. {
  1783. xscale = yscale = (DBL)READSHORT(ffile->fp)/0x4000;
  1784. #ifdef TTF_DEBUG
  1785. Debug_Info("WE_HAVE_A_SCALE ");
  1786. Debug_Info("xscale = %lf\t", xscale);
  1787. Debug_Info("scale01 = %lf\n", scale01);
  1788. Debug_Info("scale10 = %lf\t", scale10);
  1789. Debug_Info("yscale = %lf\n", yscale);
  1790. #endif
  1791. }
  1792. else if (flags & WE_HAVE_AN_X_AND_Y_SCALE)
  1793. {
  1794. xscale = (DBL)READSHORT(ffile->fp)/0x4000;
  1795. yscale = (DBL)READSHORT(ffile->fp)/0x4000;
  1796. #ifdef TTF_DEBUG
  1797. Debug_Info("WE_HAVE_AN_X_AND_Y_SCALE ");
  1798. Debug_Info("xscale = %lf\t", xscale);
  1799. Debug_Info("scale01 = %lf\n", scale01);
  1800. Debug_Info("scale10 = %lf\t", scale10);
  1801. Debug_Info("yscale = %lf\n", yscale);
  1802. #endif
  1803. }
  1804. else if (flags & WE_HAVE_A_TWO_BY_TWO)
  1805. {
  1806. xscale = (DBL)READSHORT(ffile->fp)/0x4000;
  1807. scale01 = (DBL)READSHORT(ffile->fp)/0x4000;
  1808. scale10 = (DBL)READSHORT(ffile->fp)/0x4000;
  1809. yscale = (DBL)READSHORT(ffile->fp)/0x4000;
  1810. #ifdef TTF_DEBUG
  1811. Debug_Info("WE_HAVE_A_TWO_BY_TWO ");
  1812. Debug_Info("xscale = %lf\t", xscale);
  1813. Debug_Info("scale01 = %lf\n", scale01);
  1814. Debug_Info("scale10 = %lf\t", scale10);
  1815. Debug_Info("yscale = %lf\n", yscale);
  1816. #endif
  1817. }
  1818. if (flags & ARGS_ARE_XY_VALUES)
  1819. {
  1820. xoff = (DBL)arg1 / ffile->unitsPerEm;
  1821. yoff = (DBL)arg2 / ffile->unitsPerEm;
  1822. #ifdef TTF_DEBUG
  1823. Debug_Info("ARGS_ARE_XY_VALUES ");
  1824. Debug_Info("\narg1 = %d xoff = %lf\t", arg1, xoff);
  1825. Debug_Info("arg2 = %d yoff = %lf\n", arg2, yoff);
  1826. #endif
  1827. }
  1828. else /* until I understand how this method works... */
  1829. {
  1830. Warning(0.0, "Can't handle part of glyph %d (0x%X).\n", c, c);
  1831. continue;
  1832. }
  1833. if (flags & USE_MY_METRICS)
  1834. {
  1835. #ifdef TTF_DEBUG
  1836. Debug_Info("USE_MY_METRICS ");
  1837. #endif
  1838. ttglyph->myMetrics = sub_glyph_index;
  1839. }
  1840. current_pos = ftell(ffile->fp);
  1841. sub_ttglyph = ExtractGlyphOutline(ffile, &sub_glyph_index, c);
  1842. fseek(ffile->fp, current_pos, SEEK_SET);
  1843. if ((nc2 = sub_ttglyph->header.numContours) == 0)
  1844. continue;
  1845. nc = ttglyph->header.numContours;
  1846. n = ttglyph->numPoints;
  1847. n2 = sub_ttglyph->numPoints;
  1848. ttglyph->endPoints = (USHORT *)POV_REALLOC(ttglyph->endPoints,
  1849. (nc + nc2) * sizeof(USHORT), "ttf");
  1850. ttglyph->flags = (BYTE *)POV_REALLOC(ttglyph->flags, (n+n2)*sizeof(BYTE), "ttf");
  1851. ttglyph->x = (DBL *)POV_REALLOC(ttglyph->x, (n + n2) * sizeof(DBL), "ttf");
  1852. ttglyph->y = (DBL *)POV_REALLOC(ttglyph->y, (n + n2) * sizeof(DBL), "ttf");
  1853. /* Add the sub glyph info to the end of the current glyph */
  1854. ttglyph->header.numContours += nc2;
  1855. ttglyph->numPoints += n2;
  1856. for (i = 0; i < nc2; i++)
  1857. {
  1858. ttglyph->endPoints[i + nc] = sub_ttglyph->endPoints[i] + n;
  1859. #ifdef TTF_DEBUG
  1860. Debug_Info("endPoints[%d]=%d\n", i + nc, ttglyph->endPoints[i + nc]);
  1861. #endif
  1862. }
  1863. for (i = 0; i < n2; i++)
  1864. {
  1865. #ifdef TTF_DEBUG
  1866. Debug_Info("x[%d]=%lf\t", i, sub_ttglyph->x[i]);
  1867. Debug_Info("y[%d]=%lf\n", i, sub_ttglyph->y[i]);
  1868. #endif
  1869. ttglyph->flags[i + n] = sub_ttglyph->flags[i];
  1870. ttglyph->x[i + n] = xscale * sub_ttglyph->x[i] +
  1871. scale01 * sub_ttglyph->y[i] + xoff;
  1872. ttglyph->y[i + n] = scale10 * sub_ttglyph->x[i] +
  1873. yscale * sub_ttglyph->y[i] + yoff;
  1874. #ifdef TTF_DEBUG
  1875. Debug_Info("x[%d]=%lf\t", i+n, ttglyph->x[i+n]);
  1876. Debug_Info("y[%d]=%lf\n", i+n, ttglyph->y[i+n]);
  1877. #endif
  1878. if (ttglyph->x[i + n] < ttglyph->header.xMin)
  1879. ttglyph->header.xMin = ttglyph->x[i + n];
  1880. if (ttglyph->x[i + n] > ttglyph->header.xMax)
  1881. ttglyph->header.xMax = ttglyph->x[i + n];
  1882. if (ttglyph->y[i + n] < ttglyph->header.yMin)
  1883. ttglyph->header.yMin = ttglyph->y[i + n];
  1884. if (ttglyph->y[i + n] > ttglyph->header.yMax)
  1885. ttglyph->header.yMax = ttglyph->y[i + n];
  1886. }
  1887. /* Free up the sub glyph outline information */
  1888. if (sub_ttglyph->y) POV_FREE(sub_ttglyph->y);
  1889. if (sub_ttglyph->x) POV_FREE(sub_ttglyph->x);
  1890. if (sub_ttglyph->endPoints) POV_FREE(sub_ttglyph->endPoints);
  1891. if (sub_ttglyph->flags) POV_FREE(sub_ttglyph->flags);
  1892. POV_FREE(sub_ttglyph);
  1893. } while (flags & MORE_COMPONENTS);
  1894. }
  1895. #ifdef TTF_DEBUG
  1896. Debug_Info("xMin=%d\n",ttglyph->header.xMin);
  1897. Debug_Info("yMin=%d\n",ttglyph->header.yMin);
  1898. Debug_Info("xMax=%d\n",ttglyph->header.xMax);
  1899. Debug_Info("yMax=%d\n",ttglyph->header.yMax);
  1900. #endif
  1901. return ttglyph;
  1902. }
  1903. /*****************************************************************************
  1904. *
  1905. * FUNCTION
  1906. *
  1907. * ConvertOutlineToGlyph
  1908. *
  1909. * INPUT
  1910. *
  1911. * OUTPUT
  1912. *
  1913. * RETURNS
  1914. *
  1915. * AUTHOR
  1916. *
  1917. * POV-Ray Team
  1918. *
  1919. * DESCRIPTION
  1920. *
  1921. * Transform a glyph from TrueType storage format to something a little easier
  1922. * to manage.
  1923. *
  1924. * CHANGES
  1925. *
  1926. * -
  1927. *
  1928. ******************************************************************************/
  1929. static GlyphPtr ConvertOutlineToGlyph(FontFileInfo *ffile, GlyphOutline *ttglyph)
  1930. {
  1931. GlyphPtr glyph;
  1932. DBL *temp_x, *temp_y;
  1933. BYTE *temp_f;
  1934. USHORT i, j, last_j;
  1935. /* Create storage for this glyph */
  1936. glyph = (Glyph *)POV_MALLOC(sizeof(Glyph), "ttf");
  1937. if (ttglyph->header.numContours > 0)
  1938. {
  1939. glyph->contours = (Contour *)POV_MALLOC(ttglyph->header.numContours * sizeof(Contour), "ttf");
  1940. }
  1941. else
  1942. {
  1943. glyph->contours = NULL;
  1944. }
  1945. /* Copy sizing information about this glyph */
  1946. memcpy(&glyph->header, &ttglyph->header, sizeof(GlyphHeader));
  1947. /* Keep track of the size for this glyph */
  1948. glyph->unitsPerEm = ffile->unitsPerEm;
  1949. /* Now copy the vertex information into the contours */
  1950. for (i = 0, last_j = 0; i < (USHORT) ttglyph->header.numContours; i++)
  1951. {
  1952. /* Figure out number of points in contour */
  1953. j = ttglyph->endPoints[i] - last_j + 1;
  1954. /* Copy the coordinate information into the glyph */
  1955. temp_x = (DBL *)POV_MALLOC((j + 1) * sizeof(DBL), "ttf");
  1956. temp_y = (DBL *)POV_MALLOC((j + 1) * sizeof(DBL), "ttf");
  1957. temp_f = (BYTE *)POV_MALLOC((j + 1) * sizeof(BYTE), "ttf");
  1958. memcpy(temp_x, &ttglyph->x[last_j], j * sizeof(DBL));
  1959. memcpy(temp_y, &ttglyph->y[last_j], j * sizeof(DBL));
  1960. memcpy(temp_f, &ttglyph->flags[last_j], j * sizeof(BYTE));
  1961. temp_x[j] = ttglyph->x[last_j];
  1962. temp_y[j] = ttglyph->y[last_j];
  1963. temp_f[j] = ttglyph->flags[last_j];
  1964. /* Figure out if this is an inside or outside contour */
  1965. glyph->contours[i].inside_flag = 0;
  1966. /* Plug in the reset of the contour components into the glyph */
  1967. glyph->contours[i].count = j;
  1968. glyph->contours[i].x = temp_x;
  1969. glyph->contours[i].y = temp_y;
  1970. glyph->contours[i].flags = temp_f;
  1971. /*
  1972. * Set last_j to point to the beginning of the next contour's coordinate
  1973. * information
  1974. */
  1975. last_j = ttglyph->endPoints[i] + 1;
  1976. }
  1977. /* Show statistics about this glyph */
  1978. #ifdef TTF_DEBUG
  1979. Debug_Info("Number of contours: %u\n", glyph->header.numContours);
  1980. Debug_Info("X extent: [%f, %f]\n",
  1981. (DBL)glyph->header.xMin / (DBL)ffile->unitsPerEm,
  1982. (DBL)glyph->header.xMax / (DBL)ffile->unitsPerEm);
  1983. Debug_Info("Y extent: [%f, %f]\n",
  1984. (DBL)glyph->header.yMin / (DBL)ffile->unitsPerEm,
  1985. (DBL)glyph->header.yMax / (DBL)ffile->unitsPerEm);
  1986. Debug_Info("Converted coord list(%d):\n", (int)glyph->header.numContours);
  1987. for (i=0;i<(USHORT)glyph->header.numContours;i++)
  1988. {
  1989. for (j=0;j<=glyph->contours[i].count;j++)
  1990. Debug_Info(" %c[%f, %f]\n",
  1991. (glyph->contours[i].flags[j] & ONCURVE ? '*' : ' '),
  1992. glyph->contours[i].x[j], glyph->contours[i].y[j]);
  1993. Debug_Info("\n");
  1994. }
  1995. #endif
  1996. return glyph;
  1997. }
  1998. /* Test to see if "point" is inside the splined polygon "points". */
  1999. static int Inside_Glyph(double x, double y, GlyphPtr glyph)
  2000. {
  2001. int i, j, k, n, n1, crossings;
  2002. int qi, ri, qj, rj;
  2003. Contour *contour;
  2004. double xt[3], yt[3], roots[2];
  2005. DBL *xv, *yv;
  2006. double x0, x1, x2, t;
  2007. double y0, y1, y2;
  2008. double m, b, xc;
  2009. BYTE *fv;
  2010. crossings = 0;
  2011. n = glyph->header.numContours;
  2012. contour = glyph->contours;
  2013. for (i = 0; i < n; i++)
  2014. {
  2015. xv = contour[i].x;
  2016. yv = contour[i].y;
  2017. fv = contour[i].flags;
  2018. x0 = xv[0];
  2019. y0 = yv[0];
  2020. n1 = contour[i].count;
  2021. for (j = 1; j <= n1; j++)
  2022. {
  2023. x1 = xv[j];
  2024. y1 = yv[j];
  2025. if (fv[j] & ONCURVE)
  2026. {
  2027. /* Straight line - first set up for the next */
  2028. /* Now do the crossing test */
  2029. qi = ri = qj = rj = 0;
  2030. if (y0 == y1)
  2031. goto end_line_test;
  2032. /* if (fabs((y - y0) / (y1 - y0)) < EPSILON) goto end_line_test; */
  2033. if (y0 < y)
  2034. qi = 1;
  2035. if (y1 < y)
  2036. qj = 1;
  2037. if (qi == qj)
  2038. goto end_line_test;
  2039. if (x0 > x)
  2040. ri = 1;
  2041. if (x1 > x)
  2042. rj = 1;
  2043. if (ri & rj)
  2044. {
  2045. crossings++;
  2046. goto end_line_test;
  2047. }
  2048. if ((ri | rj) == 0)
  2049. goto end_line_test;
  2050. m = (y1 - y0) / (x1 - x0);
  2051. b = (y1 - y) - m * (x1 - x);
  2052. if ((b / m) < EPSILON)
  2053. {
  2054. crossings++;
  2055. }
  2056. end_line_test:
  2057. x0 = x1;
  2058. y0 = y1;
  2059. }
  2060. else
  2061. {
  2062. if (j == n1)
  2063. {
  2064. x2 = xv[0];
  2065. y2 = yv[0];
  2066. }
  2067. else
  2068. {
  2069. x2 = xv[j + 1];
  2070. y2 = yv[j + 1];
  2071. if (!(fv[j + 1] & ONCURVE))
  2072. {
  2073. /*
  2074. * Parabola with far end floating - readjust the far end so that it
  2075. * is on the curve.
  2076. */
  2077. x2 = 0.5 * (x1 + x2);
  2078. y2 = 0.5 * (y1 + y2);
  2079. }
  2080. }
  2081. /* only test crossing when y is in the range */
  2082. /* this should also help saving some computations */
  2083. if (((y0 < y) && (y1 < y) && (y2 < y)) ||
  2084. ((y0 > y) && (y1 > y) && (y2 > y)))
  2085. goto end_curve_test;
  2086. yt[0] = y0 - 2.0 * y1 + y2;
  2087. yt[1] = 2.0 * (y1 - y0);
  2088. yt[2] = y0 - y;
  2089. k = solve_quad(yt, roots, 0.0, 1.0);
  2090. for (ri = 0; ri < k;) {
  2091. if (roots[ri] <= EPSILON) {
  2092. /* if y actually is not in range, discard the root */
  2093. if (((y <= y0) && (y < y1)) || ((y >= y0) && (y > y1))) {
  2094. k--;
  2095. if (k > ri)
  2096. roots[ri] = roots[ri+1];
  2097. continue;
  2098. }
  2099. }
  2100. else if (roots[ri] >= (1.0 - EPSILON)) {
  2101. /* if y actually is not in range, discard the root */
  2102. if (((y < y2) && (y < y1)) || ((y > y2) && (y > y1))) {
  2103. k--;
  2104. if (k > ri)
  2105. roots[ri] = roots[ri+1];
  2106. continue;
  2107. }
  2108. }
  2109. ri++;
  2110. }
  2111. if (k > 0)
  2112. {
  2113. xt[0] = x0 - 2.0 * x1 + x2;
  2114. xt[1] = 2.0 * (x1 - x0);
  2115. xt[2] = x0;
  2116. t = roots[0];
  2117. xc = (xt[0] * t + xt[1]) * t + xt[2];
  2118. if (xc > x)
  2119. crossings++;
  2120. if (k > 1)
  2121. {
  2122. t = roots[1];
  2123. xc = (xt[0] * t + xt[1]) * t + xt[2];
  2124. if (xc > x)
  2125. crossings++;
  2126. }
  2127. }
  2128. end_curve_test:
  2129. x0 = x2;
  2130. y0 = y2;
  2131. }
  2132. }
  2133. }
  2134. return (crossings & 1);
  2135. }
  2136. static int solve_quad(double *x, double *y, double mindist, DBL maxdist)
  2137. {
  2138. double d, t, a, b, c, q;
  2139. a = x[0];
  2140. b = -x[1];
  2141. c = x[2];
  2142. if (fabs(a) < COEFF_LIMIT)
  2143. {
  2144. if (fabs(b) < COEFF_LIMIT)
  2145. return 0;
  2146. q = c / b;
  2147. if (q >= mindist && q <= maxdist)
  2148. {
  2149. y[0] = q;
  2150. return 1;
  2151. }
  2152. else
  2153. return 0;
  2154. }
  2155. d = b * b - 4.0 * a * c;
  2156. if (d < EPSILON)
  2157. return 0;
  2158. d = sqrt(d);
  2159. t = 2.0 * a;
  2160. q = (b + d) / t;
  2161. if (q >= mindist && q <= maxdist)
  2162. {
  2163. y[0] = q;
  2164. q = (b - d) / t;
  2165. if (q >= mindist && q <= maxdist)
  2166. {
  2167. y[1] = q;
  2168. return 2;
  2169. }
  2170. return 1;
  2171. }
  2172. q = (b - d) / t;
  2173. if (q >= mindist && q <= maxdist)
  2174. {
  2175. y[0] = q;
  2176. return 1;
  2177. }
  2178. return 0;
  2179. }
  2180. /*
  2181. * Returns the distance to z = 0 in t0, and the distance to z = 1 in t1.
  2182. * These distances are to the the bottom and top surfaces of the glyph.
  2183. * The distances are set to -1 if there is no hit.
  2184. */
  2185. static void GetZeroOneHits(GlyphPtr glyph, VECTOR P, VECTOR D, DBL glyph_depth, double *t0, double *t1)
  2186. {
  2187. double x0, y0, t;
  2188. *t0 = -1.0;
  2189. *t1 = -1.0;
  2190. /* Are we parallel to the x-y plane? */
  2191. if (fabs(D[Z]) < EPSILON)
  2192. return;
  2193. /* Solve: P[Y] + t * D[Y] = 0 */
  2194. t = -P[Z] / D[Z];
  2195. x0 = P[X] + t * D[X];
  2196. y0 = P[Y] + t * D[Y];
  2197. if (Inside_Glyph(x0, y0, glyph))
  2198. *t0 = t;
  2199. /* Solve: P[Y] + t * D[Y] = glyph_depth */
  2200. t += (glyph_depth / D[Z]);
  2201. x0 = P[X] + t * D[X];
  2202. y0 = P[Y] + t * D[Y];
  2203. if (Inside_Glyph(x0, y0, glyph))
  2204. *t1 = t;
  2205. }
  2206. /*
  2207. * Solving for a linear sweep of a non-linear curve can be performed by
  2208. * projecting the ray onto the x-y plane, giving a parametric equation for the
  2209. * ray as:
  2210. *
  2211. * x = x0 + x1 t, y = y0 + y1 t
  2212. *
  2213. * Eliminating t from the above gives the implicit equation:
  2214. *
  2215. * y1 x - x1 y - (x0 y1 - y0 x1) = 0.
  2216. *
  2217. * Substituting a parametric equation for x and y gives:
  2218. *
  2219. * y1 x(s) - x1 y(s) - (x0 y1 - y0 x1) = 0.
  2220. *
  2221. * which can be written as
  2222. *
  2223. * a x(s) + b y(s) + c = 0,
  2224. *
  2225. * where a = y1, b = -x1, c = (y0 x1 - x0 y1).
  2226. *
  2227. * For piecewise quadratics, the parametric equations will have the forms:
  2228. *
  2229. * x(s) = (1-s)^2 P0(x) + 2 s (1 - s) P1(x) + s^2 P2(x) y(s) = (1-s)^2 P0(y) + 2 s
  2230. * (1 - s) P1(y) + s^2 P2(y)
  2231. *
  2232. * where P0 is the first defining vertex of the spline, P1 is the second, P2 is
  2233. * the third. Using the substitutions:
  2234. *
  2235. * xt2 = x0 - 2 x1 + x2, xt1 = 2 * (x1 - x0), xt0 = x0; yt2 = y0 - 2 y1 + y2, yt1
  2236. * = 2 * (y1 - y0), yt0 = y0;
  2237. *
  2238. * the equations can be written as:
  2239. *
  2240. * x(s) = xt2 s^2 + xt1 s + xt0, y(s) = yt2 s^2 + yt1 s + yt0.
  2241. *
  2242. * Substituting and multiplying out gives the following equation in s:
  2243. *
  2244. * s^2 * (a*xt2 + b*yt2) + s * (a*xt1 + b*yt1) + c + a*xt0 + b*yt0
  2245. *
  2246. * This is then solved using the quadratic formula. Any solutions of s that are
  2247. * between 0 and 1 (inclusive) are valid solutions.
  2248. */
  2249. static int GlyphIntersect(OBJECT *Object, VECTOR P, VECTOR D, GlyphPtr glyph, DBL glyph_depth,
  2250. RAY *Ray, ISTACK *Depth_Stack) /* tw */
  2251. {
  2252. Contour *contour;
  2253. int i, j, k, l, n, m, Flag = 0;
  2254. VECTOR N, IPoint;
  2255. DBL Depth;
  2256. double x0, x1, y0, y1, x2, y2, t, t0, t1, z;
  2257. double xt0, xt1, xt2, yt0, yt1, yt2;
  2258. double a, b, c, d0, d1, C[3], S[2];
  2259. DBL *xv, *yv;
  2260. BYTE *fv;
  2261. TTF *ttf = (TTF *) Object;
  2262. int dirflag = 0;
  2263. /*
  2264. * First thing to do is to get any hits at z = 0 and z = 1 (which are the
  2265. * bottom and top surfaces of the glyph.
  2266. */
  2267. GetZeroOneHits(glyph, P, D, glyph_depth, &t0, &t1);
  2268. if (t0 > 0.0)
  2269. {
  2270. Depth = t0 /* / len */;
  2271. VScale(IPoint, Ray->Direction, Depth);
  2272. VAddEq(IPoint, Ray->Initial);
  2273. if (Depth > TTF_Tolerance &&
  2274. Point_In_Clip(IPoint, Object->Clip))
  2275. {
  2276. Make_Vector(N, 0.0, 0.0, -1.0);
  2277. MTransNormal(N, N, ttf->Trans);
  2278. VNormalize(N, N);
  2279. push_normal_entry(Depth, IPoint, N, Object, Depth_Stack);
  2280. Flag = TRUE;
  2281. }
  2282. }
  2283. if (t1 > 0.0)
  2284. {
  2285. Depth = t1 /* / len */;
  2286. VScale(IPoint, Ray->Direction, Depth);
  2287. VAddEq(IPoint, Ray->Initial);
  2288. if (Depth > TTF_Tolerance &&
  2289. Point_In_Clip(IPoint, Object->Clip))
  2290. {
  2291. Make_Vector(N, 0.0, 0.0, 1.0);
  2292. MTransNormal(N, N, ttf->Trans);
  2293. VNormalize(N, N);
  2294. push_normal_entry(Depth, IPoint, N, Object, Depth_Stack);
  2295. Flag = TRUE;
  2296. }
  2297. }
  2298. /* Simple test to see if we can just toss this ray */
  2299. if (fabs(D[X]) < EPSILON)
  2300. {
  2301. if (fabs(D[Y]) < EPSILON)
  2302. {
  2303. /*
  2304. * This means the ray is moving parallel to the walls of the sweep
  2305. * surface
  2306. */
  2307. return Flag;
  2308. }
  2309. else
  2310. {
  2311. dirflag = 0;
  2312. }
  2313. }
  2314. else
  2315. {
  2316. dirflag = 1;
  2317. }
  2318. /*
  2319. * Now walk through the glyph, looking for places where the ray hits the
  2320. * walls
  2321. */
  2322. a = D[Y];
  2323. b = -D[X];
  2324. c = (P[Y] * D[X] - P[X] * D[Y]);
  2325. n = glyph->header.numContours;
  2326. for (i = 0, contour = glyph->contours; i < n; i++, contour++)
  2327. {
  2328. xv = contour->x;
  2329. yv = contour->y;
  2330. fv = contour->flags;
  2331. x0 = xv[0];
  2332. y0 = yv[0];
  2333. m = contour->count;
  2334. for (j = 1; j <= m; j++)
  2335. {
  2336. x1 = xv[j];
  2337. y1 = yv[j];
  2338. if (fv[j] & ONCURVE)
  2339. {
  2340. /* Straight line */
  2341. d0 = (x1 - x0);
  2342. d1 = (y1 - y0);
  2343. t0 = d1 * D[X] - d0 * D[Y];
  2344. if (fabs(t0) < EPSILON)
  2345. /* No possible intersection */
  2346. goto end_line_test;
  2347. t = (D[X] * (P[Y] - y0) - D[Y] * (P[X] - x0)) / t0;
  2348. if (t < 0.0 || t > 1.0)
  2349. goto end_line_test;
  2350. if (dirflag)
  2351. t = ((x0 + t * d0) - P[X]) / D[X];
  2352. else
  2353. t = ((y0 + t * d1) - P[Y]) / D[Y];
  2354. z = P[Z] + t * D[Z];
  2355. Depth = t /* / len */;
  2356. if (z >= 0 && z <= glyph_depth && Depth > TTF_Tolerance)
  2357. {
  2358. VScale(IPoint, Ray->Direction, Depth);
  2359. VAddEq(IPoint, Ray->Initial);
  2360. if (Point_In_Clip(IPoint, Object->Clip))
  2361. {
  2362. Make_Vector(N, d1, -d0, 0.0);
  2363. MTransNormal(N, N, ttf->Trans);
  2364. VNormalize(N, N);
  2365. push_normal_entry(Depth, IPoint, N, Object, Depth_Stack);
  2366. Flag = TRUE;
  2367. }
  2368. }
  2369. end_line_test:
  2370. x0 = x1;
  2371. y0 = y1;
  2372. }
  2373. else
  2374. {
  2375. if (j == m)
  2376. {
  2377. x2 = xv[0];
  2378. y2 = yv[0];
  2379. }
  2380. else
  2381. {
  2382. x2 = xv[j + 1];
  2383. y2 = yv[j + 1];
  2384. if (!(fv[j + 1] & ONCURVE))
  2385. {
  2386. /*
  2387. * Parabola with far end DBLing - readjust the far end so that it
  2388. * is on the curve. (In the correct place too.)
  2389. */
  2390. x2 = 0.5 * (x1 + x2);
  2391. y2 = 0.5 * (y1 + y2);
  2392. }
  2393. }
  2394. /* Make the interpolating quadrics */
  2395. xt2 = x0 - 2.0 * x1 + x2;
  2396. xt1 = 2.0 * (x1 - x0);
  2397. xt0 = x0;
  2398. yt2 = y0 - 2.0 * y1 + y2;
  2399. yt1 = 2.0 * (y1 - y0);
  2400. yt0 = y0;
  2401. C[0] = a * xt2 + b * yt2;
  2402. C[1] = a * xt1 + b * yt1;
  2403. C[2] = a * xt0 + b * yt0 + c;
  2404. k = solve_quad(C, S, 0.0, 1.0);
  2405. for (l = 0; l < k; l++)
  2406. {
  2407. if (dirflag)
  2408. t = ((S[l] * S[l] * xt2 + S[l] * xt1 + xt0) - P[X]) / D[X];
  2409. else
  2410. t = ((S[l] * S[l] * yt2 + S[l] * yt1 + yt0) - P[Y]) / D[Y];
  2411. /*
  2412. * If the intersection with this wall is between 0 and glyph_depth
  2413. * along the z-axis, then it is a valid hit.
  2414. */
  2415. z = P[Z] + t * D[Z];
  2416. Depth = t /* / len */;
  2417. if (z >= 0 && z <= glyph_depth && Depth > TTF_Tolerance)
  2418. {
  2419. VScale(IPoint, Ray->Direction, Depth);
  2420. VAddEq(IPoint, Ray->Initial);
  2421. if (Point_In_Clip(IPoint, Object->Clip))
  2422. {
  2423. Make_Vector(N, 2.0 * yt2 * S[l] + yt1, -2.0 * xt2 * S[l] - xt1, 0.0);
  2424. MTransNormal(N, N, ttf->Trans);
  2425. VNormalize(N, N);
  2426. push_normal_entry(Depth, IPoint, N, Object, Depth_Stack);
  2427. Flag = TRUE;
  2428. }
  2429. }
  2430. }
  2431. x0 = x2;
  2432. y0 = y2;
  2433. }
  2434. }
  2435. }
  2436. return Flag;
  2437. }
  2438. static int All_TTF_Intersections(OBJECT *Object, RAY *Ray, ISTACK *Depth_Stack)
  2439. {
  2440. TTF *ttf = (TTF *) Object;
  2441. /* DBL len; */ /* tw, mtg */
  2442. VECTOR P, D;
  2443. GlyphPtr glyph;
  2444. Increase_Counter(stats[Ray_TTF_Tests]);
  2445. /* Transform the point into the glyph's space */
  2446. MInvTransPoint(P, Ray->Initial, ttf->Trans);
  2447. MInvTransDirection(D, Ray->Direction, ttf->Trans);
  2448. /* Tweak the ray to try to avoid pathalogical intersections */
  2449. /*
  2450. D[0] *= 1.0000013147;
  2451. D[1] *= 1.0000022741;
  2452. D[2] *= 1.0000017011;
  2453. VLength(len, D);
  2454. VInverseScaleEq(D, len);
  2455. */
  2456. glyph = (GlyphPtr)ttf->glyph;
  2457. if (GlyphIntersect(Object, P, D, glyph,ttf->depth,Ray,Depth_Stack)) /* tw */
  2458. {
  2459. Increase_Counter(stats[Ray_TTF_Tests_Succeeded]);
  2460. return TRUE;
  2461. }
  2462. return FALSE;
  2463. }
  2464. static int Inside_TTF(VECTOR IPoint, OBJECT *Object)
  2465. {
  2466. VECTOR New_Point;
  2467. TTF *ttf = (TTF *) Object;
  2468. GlyphPtr glyph;
  2469. /* Transform the point into font space */
  2470. MInvTransPoint(New_Point, IPoint, ttf->Trans);
  2471. glyph = (GlyphPtr)ttf->glyph;
  2472. if (New_Point[Z] >= 0.0 && New_Point[Z] <= ttf->depth &&
  2473. Inside_Glyph(New_Point[X], New_Point[Y], glyph))
  2474. return (!Test_Flag(ttf, INVERTED_FLAG));
  2475. else
  2476. return (Test_Flag(ttf, INVERTED_FLAG));
  2477. }
  2478. static void TTF_Normal(VECTOR Result, OBJECT *Object, INTERSECTION *Inter)
  2479. {
  2480. /* Use precomputed normal. [ARE 11/94] */
  2481. Assign_Vector(Result, Inter->INormal);
  2482. }
  2483. static TTF *Copy_TTF(OBJECT *Object)
  2484. {
  2485. TTF *New, *Old = (TTF *) Object;
  2486. New = Create_TTF();
  2487. Destroy_Transform(New->Trans);
  2488. *New = *Old;
  2489. New->Trans = Copy_Transform(((TTF *) Object)->Trans);
  2490. New->glyph = Old->glyph;
  2491. return (New);
  2492. }
  2493. static void Translate_TTF(OBJECT *Object, VECTOR Vector, TRANSFORM *Trans)
  2494. {
  2495. Transform_TTF(Object, Trans);
  2496. }
  2497. static void Rotate_TTF(OBJECT *Object, VECTOR Vector, TRANSFORM *Trans)
  2498. {
  2499. Transform_TTF(Object, Trans);
  2500. }
  2501. static void Scale_TTF(OBJECT *Object, VECTOR Vector, TRANSFORM *Trans)
  2502. {
  2503. Transform_TTF(Object, Trans);
  2504. }
  2505. static void Invert_TTF(OBJECT *Object)
  2506. {
  2507. Invert_Flag(Object, INVERTED_FLAG);
  2508. }
  2509. static void Transform_TTF(OBJECT *Object, TRANSFORM *Trans)
  2510. {
  2511. TTF *ttf = (TTF *) Object;
  2512. Compose_Transforms(ttf->Trans, Trans);
  2513. /* Calculate the bounds */
  2514. Compute_TTF_BBox(ttf);
  2515. }
  2516. static TTF *Create_TTF()
  2517. {
  2518. TTF *New;
  2519. New = (TTF *) POV_MALLOC(sizeof(TTF), "ttf");
  2520. INIT_OBJECT_FIELDS(New, TTF_OBJECT, &TTF_Methods)
  2521. /* Initialize TTF specific information */
  2522. New->Trans = Create_Transform();
  2523. New->glyph = NULL;
  2524. New->depth = 1.0;
  2525. /* Default bounds */
  2526. Make_BBox(New->BBox, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0);
  2527. return New;
  2528. }
  2529. static void Destroy_TTF(OBJECT *Object)
  2530. {
  2531. TTF *ttf = (TTF *) Object;
  2532. Destroy_Transform(ttf->Trans);
  2533. POV_FREE(Object);
  2534. }
  2535. /*****************************************************************************
  2536. *
  2537. * FUNCTION
  2538. *
  2539. * Compute_TTF_BBox
  2540. *
  2541. * INPUT
  2542. *
  2543. * ttf - ttf
  2544. *
  2545. * OUTPUT
  2546. *
  2547. * ttf
  2548. *
  2549. * RETURNS
  2550. *
  2551. * AUTHOR
  2552. *
  2553. * Dieter Bayer, August 1994
  2554. *
  2555. * DESCRIPTION
  2556. *
  2557. * Calculate the bounding box of a true type font.
  2558. *
  2559. * CHANGES
  2560. *
  2561. * -
  2562. *
  2563. ******************************************************************************/
  2564. void Compute_TTF_BBox(TTF *ttf)
  2565. {
  2566. DBL funit_size, xMin, yMin, zMin, xMax, yMax, zMax;
  2567. GlyphPtr glyph;
  2568. glyph = (GlyphPtr)ttf->glyph;
  2569. funit_size = 1.0 / (DBL)(glyph->unitsPerEm);
  2570. xMin = (DBL)glyph->header.xMin * funit_size;
  2571. yMin = (DBL)glyph->header.yMin * funit_size;
  2572. zMin = -TTF_Tolerance;
  2573. xMax = (DBL)glyph->header.xMax * funit_size;
  2574. yMax = (DBL)glyph->header.yMax * funit_size;
  2575. zMax = ttf->depth + TTF_Tolerance;
  2576. Make_BBox(ttf->BBox, xMin, yMin, zMin, xMax - xMin, yMax - yMin, zMax - zMin);
  2577. #ifdef TTF_DEBUG
  2578. Debug_Info("Bounds: <%g,%g,%g> -> <%g,%g,%g>\n",
  2579. ttf->BBox.Lower_Left[0],
  2580. ttf->BBox.Lower_Left[1],
  2581. ttf->BBox.Lower_Left[2],
  2582. ttf->BBox.Lengths[0],
  2583. ttf->BBox.Lengths[1],
  2584. ttf->BBox.Lengths[2]);
  2585. #endif
  2586. /* Apply the transformation to the bounding box */
  2587. Recompute_BBox(&ttf->BBox, ttf->Trans);
  2588. }