otf2bdf.c 45 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625
  1. /*
  2. * Copyright 2008 Department of Mathematical Sciences, New Mexico State University
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a
  5. * copy of this software and associated documentation files (the "Software"),
  6. * to deal in the Software without restriction, including without limitation
  7. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8. * and/or sell copies of the Software, and to permit persons to whom the
  9. * Software is furnished to do so, subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice shall be included in
  12. * all copies or substantial portions of the Software.
  13. *
  14. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  17. * DEPARTMENT OF MATHEMATICAL SCIENCES OR NEW MEXICO STATE UNIVERSITY BE
  18. * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
  19. * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  20. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  21. */
  22. #include <stdio.h>
  23. #ifdef WIN32
  24. #include <windows.h>
  25. #else
  26. #include <stdlib.h>
  27. #include <unistd.h>
  28. #endif
  29. #include <string.h>
  30. #include <ft2build.h>
  31. #include FT_GLYPH_H
  32. #include FT_SFNT_NAMES_H
  33. #include FT_TRUETYPE_TABLES_H
  34. /*
  35. * Include the remapping support.
  36. */
  37. #include "remap.h"
  38. /**************************************************************************
  39. *
  40. * Macros.
  41. *
  42. **************************************************************************/
  43. /*
  44. * The version of otf2bdf.
  45. */
  46. #define OTF2BDF_VERSION "3.0"
  47. /*
  48. * Set the default values used to generate a BDF font.
  49. */
  50. #ifndef DEFAULT_PLATFORM_ID
  51. #define DEFAULT_PLATFORM_ID 3
  52. #endif
  53. #ifndef DEFAULT_ENCODING_ID
  54. #define DEFAULT_ENCODING_ID 1
  55. #endif
  56. #ifndef DEFAULT_POINT_SIZE
  57. #define DEFAULT_POINT_SIZE 12
  58. #endif
  59. #ifndef DEFAULT_RESOLUTION
  60. #define DEFAULT_RESOLUTION 100
  61. #endif
  62. /*
  63. * Used as a fallback for XLFD names where the character set/encoding can not
  64. * be determined.
  65. */
  66. #ifndef DEFAULT_XLFD_CSET
  67. #define DEFAULT_XLFD_CSET "-FontSpecific-0"
  68. #endif
  69. /*
  70. * nameID macros for getting strings from the OT font.
  71. */
  72. #define BDFOTF_COPYRIGHT_STRING 0
  73. #define BDFOTF_FAMILY_STRING 1
  74. #define BDFOTF_SUBFAMILY_STRING 2
  75. #define BDFOTF_UNIQUEID_STRING 3
  76. #define BDFOTF_FULLNAME_STRING 4
  77. #define BDFOTF_VENDOR_STRING 5
  78. #define BDFOTF_POSTSCRIPT_STRING 6
  79. #define BDFOTF_TRADEMARK_STRING 7
  80. /*
  81. * String names for the string indexes. Used for error messages.
  82. */
  83. static char *string_names[] = {
  84. "\"Copyright\"",
  85. "\"Family\"",
  86. "\"SubFamily\"",
  87. "\"Unique ID\"",
  88. "\"Full Name\"",
  89. "\"Vendor\"",
  90. "\"Postscript Name\"",
  91. "\"Trademark\""
  92. };
  93. #if 0
  94. #define TTF_COPYRIGHT 0
  95. #define TTF_TYPEFACE 1
  96. #define TTF_PSNAME 6
  97. #endif
  98. #ifndef MAX
  99. #define MAX(h,i) ((h) > (i) ? (h) : (i))
  100. #endif
  101. #ifndef MIN
  102. #define MIN(l,o) ((l) < (o) ? (l) : (o))
  103. #endif
  104. /**************************************************************************
  105. *
  106. * General globals set from command line.
  107. *
  108. **************************************************************************/
  109. /*
  110. * The program name.
  111. */
  112. static char *prog;
  113. /*
  114. * The flag indicating whether messages should be printed or not.
  115. */
  116. static int verbose = 0;
  117. static int alternate_y_offset_calculation = 0; // u8g2 issue 2406 https://github.com/olikraus/u8g2/issues/2406
  118. /*
  119. * Flags used when loading glyphs.
  120. */
  121. static int load_flags = FT_LOAD_DEFAULT;
  122. /*
  123. * The default platform and encoding ID's.
  124. */
  125. static int pid = DEFAULT_PLATFORM_ID;
  126. static int eid = DEFAULT_ENCODING_ID;
  127. /*
  128. * Default point size and resolutions.
  129. */
  130. static int point_size = DEFAULT_POINT_SIZE;
  131. static int hres = DEFAULT_RESOLUTION;
  132. static int vres = DEFAULT_RESOLUTION;
  133. /*
  134. * The user supplied foundry name to use in the XLFD name.
  135. */
  136. static char *foundry_name = 0;
  137. /*
  138. * The user supplied typeface name to use in the XLFD name.
  139. */
  140. static char *face_name = 0;
  141. /*
  142. * The user supplied weight name to use in the XLFD name.
  143. */
  144. static char *weight_name = 0;
  145. /*
  146. * The user supplied slant name to use in the XLFD name.
  147. */
  148. static char *slant_name = 0;
  149. /*
  150. * The user supplied width name to use in the XLFD name.
  151. */
  152. static char *width_name = 0;
  153. /*
  154. * The user supplied additional style name to use in the XLFD name.
  155. */
  156. static char *style_name = 0;
  157. /*
  158. * The user supplied spacing (p = proportional, c = character cell,
  159. * m = monospace).
  160. */
  161. static int spacing = 0;
  162. /*
  163. * The dash character to use in the names retrieved from the font. Default is
  164. * the space.
  165. */
  166. static int dashchar = ' ';
  167. /*
  168. * Flag, bitmask, and max code for generating a subset of the glyphs in a font.
  169. */
  170. static int do_subset = 0;
  171. static unsigned short maxcode;
  172. static unsigned long subset[2048];
  173. /*
  174. * The flag that indicates the remapping table should be used to
  175. * reencode the font.
  176. */
  177. static int do_remap = 0;
  178. /**************************************************************************
  179. *
  180. * Internal globals.
  181. *
  182. **************************************************************************/
  183. /*
  184. * Structure used for calculating the font bounding box as the glyphs are
  185. * generated.
  186. */
  187. typedef struct {
  188. short minlb;
  189. short maxlb;
  190. short maxrb;
  191. short maxas;
  192. short maxds;
  193. short rbearing;
  194. } bbx_t;
  195. static bbx_t bbx;
  196. /*
  197. * The buffer used to transfer the temporary file to the actual output file.
  198. */
  199. #define OTF2BDF_IOBUFSIZ 8192
  200. static char iobuf[OTF2BDF_IOBUFSIZ];
  201. /*
  202. * The Units Per Em value used in numerous places.
  203. */
  204. static FT_UShort upm;
  205. /*
  206. * A flag indicating if a CMap was found or not.
  207. */
  208. static FT_UShort nocmap;
  209. static FT_UShort forcenocmap;
  210. /*
  211. * The scaling factor needed to compute the SWIDTH (scalable width) value
  212. * for BDF glyphs.
  213. */
  214. static double swscale;
  215. /**************************************************************************
  216. *
  217. * Platform and encoding table names.
  218. *
  219. **************************************************************************/
  220. static char *platform_names[] = {
  221. "Apple Unicode", "Macintosh", "ISO", "Microsoft", "Unknown"
  222. };
  223. static int nplatform_names = sizeof(platform_names)/sizeof(platform_names[0]);
  224. /*
  225. * Mac encoding names used when creating the BDF XLFD font name.
  226. */
  227. static char *mac_encodings[] = {
  228. "-MacRoman-0", "-MacJapanese-0", "-MacChinese-0", "-MacKorean-0",
  229. "-MacArabic-0", "-MacHebrew-0", "-MacGreek-0", "-MacRussian-0",
  230. "-MacRSymbol-0", "-MacDevanagari-0", "-MacGurmukhi-0", "-MacGujarati-0",
  231. "-MacOriya-0", "-MacBengali-0", "-MacTamil-0", "-MacTelugu-0",
  232. "-MacKannada-0", "-MacMalayalam-0", "-MacSinhalese-0", "-MacBurmese-0",
  233. "-MacKhmer-0", "-MacThai-0", "-MacLaotian-0", "-MacGeorgian-0",
  234. "-MacArmenian-0", "-MacMaldivian-0", "-MacTibetan-0", "-MacMongolian-0",
  235. "-MacGeez-0", "-MacSlavic-0", "-MacVietnamese-0","-MacSindhi-0",
  236. "-MacUninterp-0"
  237. };
  238. static int nmac_encodings = sizeof(mac_encodings)/sizeof(mac_encodings[0]);
  239. /*
  240. * ISO encoding names used when creating the BDF XLFD font name.
  241. */
  242. static char *iso_encodings[] = {
  243. "-ASCII-0", "-ISO10646-1", "-ISO8859-1"
  244. };
  245. static int niso_encodings = sizeof(iso_encodings)/sizeof(iso_encodings[0]);
  246. /*
  247. * Microsoft encoding names used when creating the BDF XLFD font name.
  248. */
  249. static char *ms_encodings[] = {
  250. "-Symbol-0", "-ISO10646-1", "-ShiftJIS-0", "-GB2312.1980-0", "-Big5-0",
  251. "-KSC5601.1987-0", "-KSC5601.1992-0"
  252. };
  253. static int nms_encodings = sizeof(ms_encodings)/sizeof(ms_encodings[0]);
  254. /*
  255. * The propery names for all the XLFD properties.
  256. */
  257. static char *xlfd_props[] = {
  258. "FOUNDRY",
  259. "FAMILY_NAME",
  260. "WEIGHT_NAME",
  261. "SLANT",
  262. "SETWIDTH_NAME",
  263. "ADD_STYLE_NAME",
  264. "PIXEL_SIZE",
  265. "POINT_SIZE",
  266. "RESOLUTION_X",
  267. "RESOLUTION_Y",
  268. "SPACING",
  269. "AVERAGE_WIDTH",
  270. "CHARSET_REGISTRY",
  271. "CHARSET_ENCODING",
  272. };
  273. /**************************************************************************
  274. *
  275. * Freetype globals.
  276. *
  277. **************************************************************************/
  278. static FT_Library library;
  279. static FT_Face face;
  280. static FT_Size_Metrics imetrics;
  281. static TT_HoriHeader *horizontal;
  282. /**************************************************************************
  283. *
  284. * Freetype related code.
  285. *
  286. **************************************************************************/
  287. /*
  288. * A generic routine to get a name from the OT name table. This routine
  289. * always looks for English language names and checks three possibilities:
  290. * 1. English names with the MS Unicode encoding ID.
  291. * 2. English names with the MS unknown encoding ID.
  292. * 3. English names with the Apple Unicode encoding ID.
  293. *
  294. * The particular name ID mut be provided (e.g. nameID = 0 for copyright
  295. * string, nameID = 6 for Postscript name, nameID = 1 for typeface name.
  296. *
  297. * If the `dash_to_space' flag is non-zero, all dashes (-) in the name will be
  298. * replaced with the character passed.
  299. *
  300. * Returns the number of bytes added.
  301. */
  302. static int
  303. otf_get_english_string(FT_Face face, int nameID, int dash_to_space,
  304. char *name, int name_size)
  305. {
  306. int j, encid;
  307. FT_UInt i, nrec;
  308. FT_SfntName sfntName;
  309. unsigned char *s;
  310. unsigned short slen;
  311. nrec = FT_Get_Sfnt_Name_Count(face);
  312. for (encid = 1, j = 0; j < 2; j++, encid--) {
  313. /*
  314. * Locate one of the MS English font names.
  315. */
  316. for (i = 0; i < nrec; i++) {
  317. FT_Get_Sfnt_Name(face, i, &sfntName);
  318. if (sfntName.platform_id == 3 &&
  319. sfntName.encoding_id == encid &&
  320. sfntName.name_id == nameID &&
  321. (sfntName.language_id == 0x0409 ||
  322. sfntName.language_id == 0x0809 ||
  323. sfntName.language_id == 0x0c09 ||
  324. sfntName.language_id == 0x1009 ||
  325. sfntName.language_id == 0x1409 ||
  326. sfntName.language_id == 0x1809)) {
  327. s = sfntName.string;
  328. slen = sfntName.string_len;
  329. break;
  330. }
  331. }
  332. if (i < nrec) {
  333. if (slen >> 1 >= name_size) {
  334. fprintf(stderr, "%s: warning: %s string longer than buffer. Truncating to %d bytes.\n", prog, string_names[nameID], name_size);
  335. slen = name_size << 1;
  336. }
  337. /*
  338. * Found one of the MS English font names. The name is by
  339. * definition encoded in Unicode, so copy every second byte into
  340. * the `name' parameter, assuming there is enough space.
  341. */
  342. for (i = 1; i < slen; i += 2) {
  343. if (dash_to_space)
  344. *name++ = (s[i] != '-') ? s[i] : ' ';
  345. else if (s[i] == '\r' || s[i] == '\n') {
  346. if (s[i] == '\r' && i + 2 < slen && s[i + 2] == '\n')
  347. i += 2;
  348. *name++ = ' ';
  349. *name++ = ' ';
  350. } else
  351. *name++ = s[i];
  352. }
  353. *name = 0;
  354. return (slen >> 1);
  355. }
  356. }
  357. /*
  358. * No MS English name found, attempt to find an Apple Unicode English
  359. * name.
  360. */
  361. for (i = 0; i < nrec; i++) {
  362. FT_Get_Sfnt_Name(face, i, &sfntName);
  363. if (sfntName.platform_id == 0 && sfntName.language_id == 0 &&
  364. sfntName.name_id == nameID) {
  365. s = sfntName.string;
  366. slen = sfntName.string_len;
  367. break;
  368. }
  369. }
  370. if (i < nrec) {
  371. if (slen >> 1 >= name_size) {
  372. fprintf(stderr, "%s: warning: %s string longer than buffer. Truncating to %d bytes.\n", prog, string_names[nameID], name_size);
  373. slen = name_size << 1;
  374. }
  375. /*
  376. * Found the Apple Unicode English name. The name is by definition
  377. * encoded in Unicode, so copy every second byte into the `name'
  378. * parameter, assuming there is enough space.
  379. */
  380. for (i = 1; i < slen; i += 2) {
  381. if (dash_to_space)
  382. *name++ = (s[i] != '-') ? s[i] : ' ';
  383. else if (s[i] == '\r' || s[i] == '\n') {
  384. if (s[i] == '\r' && i + 2 < slen && s[i + 2] == '\n')
  385. i += 2;
  386. *name++ = ' ';
  387. *name++ = ' ';
  388. } else
  389. *name++ = s[i];
  390. }
  391. *name = 0;
  392. return (slen >> 1);
  393. }
  394. return 0;
  395. }
  396. /**************************************************************************
  397. *
  398. * Encoding table related functions.
  399. *
  400. **************************************************************************/
  401. static char *
  402. platform_name(short pid)
  403. {
  404. return (pid < nplatform_names) ?
  405. platform_names[pid] : platform_names[nplatform_names - 1];
  406. }
  407. static char *
  408. encoding_name(short pid, short eid)
  409. {
  410. int nnames;
  411. char **names;
  412. switch (pid) {
  413. case 0: return "-ISO10646-1";
  414. case 1:
  415. nnames = nmac_encodings;
  416. names = mac_encodings;
  417. break;
  418. case 2:
  419. nnames = niso_encodings;
  420. names = iso_encodings;
  421. break;
  422. case 3:
  423. nnames = nms_encodings;
  424. names = ms_encodings;
  425. break;
  426. default: return "-Unknown-0";
  427. }
  428. return (eid < nnames) ? names[eid] : "-Unknown-0";
  429. }
  430. static char *spaces = " ";
  431. static void
  432. print_encoding_table(void)
  433. {
  434. int ncmaps, i, j;
  435. short pid, eid, lasteid;
  436. char *np, *platform, encoding[64];
  437. printf("Encoding tables available in the font:\n\n");
  438. printf("Platform%.*sEncoding\n", 6, spaces);
  439. printf("-------------------------------------------\n");
  440. printf("Default%.*sDefault%.*s(-pid %d -eid %d)\n",
  441. 7, spaces, 7, spaces, DEFAULT_PLATFORM_ID, DEFAULT_ENCODING_ID);
  442. ncmaps = face->num_charmaps;
  443. for (lasteid = -1, i = 0; i < ncmaps; i++) {
  444. pid = face->charmaps[i]->platform_id;
  445. eid = face->charmaps[i]->encoding_id;
  446. platform = platform_name(pid);
  447. np = encoding_name(pid, eid);
  448. np++;
  449. for (j = 0; j < 63 && *np != '-'; np++, j++)
  450. encoding[j] = *np;
  451. encoding[j] = 0;
  452. /*
  453. * Typecast the result of 14-strlen(). This returns a size_t on
  454. * some platforms and causes a compilation warning.
  455. */
  456. printf("%s%.*s%s%.*s(-pid %hd -eid %hd)\n",
  457. platform, (int) (14 - strlen(platform)), spaces,
  458. encoding, (int) (14 - strlen(encoding)), spaces, pid, eid);
  459. }
  460. }
  461. /**************************************************************************
  462. *
  463. * General code.
  464. *
  465. **************************************************************************/
  466. /*
  467. * Create an XLFD name. Assumes there is enough space in the string passed
  468. * to fit a reasonably long XLFD name into, up to the 256 byte maximum.
  469. */
  470. static void
  471. make_xlfd_name(char *name, int name_size, FT_Long awidth, int ismono)
  472. {
  473. FT_Long i;
  474. FT_ULong val;
  475. char *r, *e;
  476. double dr, dp;
  477. TT_OS2 *os2 = FT_Get_Sfnt_Table(face, ft_sfnt_os2);
  478. /*
  479. * Default the foundry name to "FreeType" in honor of the project and
  480. * because the foundry name is too difficult to automatically determine
  481. * from the names in TT fonts. But the user can provide his own.
  482. */
  483. if (foundry_name == 0) {
  484. (void) strcpy(name, "-FreeType");
  485. name += 9;
  486. } else {
  487. *(name++)='-';
  488. strcpy(name,foundry_name);
  489. name+=strlen(foundry_name);
  490. }
  491. /*
  492. * Add the typeface name from the font. The fallback default will be
  493. * "Unknown".
  494. */
  495. *name++ = '-';
  496. if (face_name == 0) {
  497. if((i = otf_get_english_string(face, BDFOTF_FAMILY_STRING, dashchar,
  498. name, name_size)))
  499. name += i;
  500. else {
  501. (void) strcpy(name, "Unknown");
  502. name += 7;
  503. }
  504. } else {
  505. (void) strcpy(name, face_name);
  506. name += strlen(face_name);
  507. }
  508. /*
  509. * Add the weight name. The default will be "Medium".
  510. */
  511. if (weight_name != 0) {
  512. sprintf(name, "-%s", weight_name);
  513. name += strlen(weight_name) + 1;
  514. } else {
  515. if (os2->fsSelection & 0x20) {
  516. (void) strcpy(name, "-Bold");
  517. name += 5;
  518. } else {
  519. (void) strcpy(name, "-Medium");
  520. name += 7;
  521. }
  522. }
  523. /*
  524. * Add the slant name. The default will be 'R'.
  525. */
  526. if (slant_name) {
  527. sprintf(name, "-%s", slant_name);
  528. name += strlen(slant_name) + 1;
  529. } else {
  530. *name++ = '-';
  531. if (os2->fsSelection & 0x01)
  532. *name++ = 'I';
  533. else
  534. *name++ = 'R';
  535. }
  536. /*
  537. * Default the setwidth name to "Normal" but user can specify one.
  538. */
  539. if (width_name == 0) {
  540. (void) strcpy(name, "-Normal");
  541. name += 7;
  542. } else {
  543. *(name++)='-';
  544. (void) strcpy(name, width_name);
  545. name += strlen(width_name);
  546. }
  547. /*
  548. * Default the additional style name to NULL but user can specify one.
  549. */
  550. *name++ = '-';
  551. if (style_name != 0) {
  552. (void) strcpy(name, style_name);
  553. name += strlen(style_name);
  554. }
  555. /*
  556. * Determine the pixel size from the point size and resolution.
  557. */
  558. dr = (double) vres;
  559. dp = (double) (point_size * 10);
  560. val = (unsigned long) (((dp * dr) / 722.7) + 0.5);
  561. /*
  562. * Set the pixel size, point size, and resolution.
  563. */
  564. sprintf(name, "-%ld-%d-%d-%d", val, point_size * 10, hres, vres);
  565. name += strlen(name);
  566. switch (spacing) {
  567. case 'p': case 'P': spacing = 'P'; break;
  568. case 'm': case 'M': spacing = 'M'; break;
  569. case 'c': case 'C': spacing = 'C'; break;
  570. default: spacing = 0; break;
  571. }
  572. /*
  573. * Set the spacing.
  574. */
  575. if (!spacing)
  576. spacing = (ismono) ? 'M' : 'P';
  577. *name++ = '-';
  578. *name++ = spacing;
  579. /*
  580. * Add the average width.
  581. */
  582. sprintf(name, "-%ld", awidth);
  583. name += strlen(name);
  584. /*
  585. * Check to see if the remapping table specified a registry and encoding
  586. * and use those if they both exist.
  587. */
  588. otf2bdf_remap_charset(&r, &e);
  589. if (r != 0 && e != 0) {
  590. sprintf(name, "-%s-%s", r, e);
  591. return;
  592. }
  593. /*
  594. * If the cmap for the platform and encoding id was not found, or the
  595. * platform id is unknown, assume the character set registry and encoding
  596. * are the XLFD default.
  597. */
  598. if (nocmap || pid > 3)
  599. (void) strcpy(name, DEFAULT_XLFD_CSET);
  600. else {
  601. /*
  602. * Finally, determine the character set registry and encoding from the
  603. * platform and encoding ID.
  604. */
  605. switch (pid) {
  606. case 0:
  607. /*
  608. * Apple Unicode platform, so "-Apple-Unicode" is the default.
  609. */
  610. (void) strcpy(name, "-Apple-Unicode");
  611. break;
  612. case 1:
  613. /*
  614. * Macintosh platform, so choose from the Macintosh encoding
  615. * strings.
  616. */
  617. if (eid < 0 || eid >= nmac_encodings)
  618. (void) strcpy(name, DEFAULT_XLFD_CSET);
  619. else
  620. (void) strcpy(name, mac_encodings[eid]);
  621. break;
  622. case 2:
  623. /*
  624. * ISO platform, so choose from the ISO encoding strings.
  625. */
  626. if (eid < 0 || eid >= niso_encodings)
  627. (void) strcpy(name, DEFAULT_XLFD_CSET);
  628. else
  629. (void) strcpy(name, iso_encodings[eid]);
  630. break;
  631. case 3:
  632. /*
  633. * Microsoft platform, so choose from the MS encoding strings.
  634. */
  635. if (eid < 0 || eid >= nms_encodings)
  636. (void) strcpy(name, DEFAULT_XLFD_CSET);
  637. else
  638. (void) strcpy(name, ms_encodings[eid]);
  639. break;
  640. }
  641. }
  642. }
  643. static int
  644. generate_font(FILE *out, char *iname, char *oname)
  645. {
  646. int eof, ismono, i;
  647. FILE *tmp;
  648. FT_Short x, y, dwidth, swidth;
  649. FT_Short y_off, x_off;
  650. FT_Long sx, sy, ex, ey, wd, ht;
  651. FT_Long code, idx, ng, aw;
  652. FT_UShort remapped_code;
  653. unsigned char *bp;
  654. double dw;
  655. char *xp, xlfd[BUFSIZ];
  656. char *tmpdir, tmpfile[BUFSIZ];
  657. imetrics = face->size->metrics;
  658. horizontal = FT_Get_Sfnt_Table(face, ft_sfnt_hhea);
  659. /*
  660. * Clear the BBX.
  661. */
  662. memset((char *) &bbx, 0, sizeof(bbx_t));
  663. /*
  664. * Open a temporary file to store the bitmaps in until the exact number
  665. * of bitmaps are known.
  666. */
  667. if ((tmpdir = getenv("TMPDIR")) == 0)
  668. tmpdir = "/tmp";
  669. sprintf(tmpfile, "%s/otf2bdf%ld", tmpdir, (long) getpid());
  670. if ((tmp = fopen(tmpfile, "w")) == 0) {
  671. fprintf(stderr, "%s: unable to open temporary file '%s'.\n",
  672. prog, tmpfile);
  673. return -1;
  674. }
  675. /*
  676. * Calculate the scale factor for the SWIDTH field.
  677. */
  678. swscale = ((double) vres) * ((double) point_size);
  679. /*
  680. * Initialize the flag that tracks if the font is monowidth or not and
  681. * initialize the glyph width variable that is used for testing for a
  682. * monowidth font.
  683. */
  684. wd = 0xffff;
  685. ismono = 1;
  686. for (ng = code = 0, eof = 0, aw = 0; eof != EOF && code < 0xffff; code++) {
  687. /*
  688. * If a remap is indicated, attempt to remap the code. If a remapped
  689. * code is not found, then skip generating the glyph.
  690. */
  691. remapped_code = (FT_UShort) code;
  692. if (do_remap && !otf2bdf_remap(&remapped_code))
  693. continue;
  694. /*
  695. * If a subset is being generated and the code is greater than the max
  696. * code of the subset, break out of the loop to avoid doing any more
  697. * work.
  698. */
  699. if (do_subset && remapped_code > maxcode)
  700. break;
  701. /*
  702. * If a subset is being generated and the index is not in the subset
  703. * bitmap, just continue.
  704. */
  705. if (do_subset &&
  706. !(subset[remapped_code >> 5] & (1 << (remapped_code & 31))))
  707. continue;
  708. if (nocmap) {
  709. if (code >= face->num_glyphs)
  710. /*
  711. * At this point, all the glyphs are done.
  712. */
  713. break;
  714. idx = code;
  715. } else
  716. idx = FT_Get_Char_Index(face, code);
  717. /*
  718. * If the glyph could not be loaded for some reason, or a subset is
  719. * being generated and the index is not in the subset bitmap, just
  720. * continue.
  721. */
  722. if (idx <= 0 || FT_Load_Glyph(face, idx, load_flags))
  723. continue;
  724. if (FT_Render_Glyph(face->glyph, FT_RENDER_MODE_MONO))
  725. continue;
  726. /*
  727. * Determine the DWIDTH (device width, or advance width in TT terms)
  728. * and the SWIDTH (scalable width) values.
  729. */
  730. dwidth = face->glyph->metrics.horiAdvance >> 6;
  731. dw = (double) dwidth;
  732. swidth = (FT_Short) ((dw * 72000.0) / swscale);
  733. /*
  734. * Determine the actual bounding box of the glyph bitmap. Do not
  735. * forget that the glyph is rendered upside down!
  736. */
  737. sx = sy = 0xffff;
  738. ex = ey = 0;
  739. bp = face->glyph->bitmap.buffer;
  740. for (y = 0; y < face->glyph->bitmap.rows; y++) {
  741. for (x = 0; x < face->glyph->bitmap.width; x++) {
  742. if (bp[x >> 3] & (0x80 >> (x & 7))) {
  743. if (x < sx) sx = x;
  744. if (x > ex) ex = x;
  745. if (y < sy) sy = y;
  746. if (y > ey) ey = y;
  747. }
  748. }
  749. bp += face->glyph->bitmap.pitch;
  750. }
  751. /*
  752. * If the glyph is actually an empty bitmap, set the size to 0 all
  753. * around.
  754. */
  755. if (sx == 0xffff && sy == 0xffff && ex == 0 && ey == 0)
  756. sx = ex = sy = ey = 0;
  757. else {
  758. /*
  759. * Adjust the end points.
  760. */
  761. ex++;
  762. ey++;
  763. }
  764. /*
  765. * Increment the number of glyphs generated.
  766. */
  767. ng++;
  768. /*
  769. * Test to see if the font is going to be monowidth or not by
  770. * comparing the current glyph width against the last one.
  771. */
  772. if (wd != 0xffff && ismono && (ex - sx) + 1 != wd)
  773. ismono = 0;
  774. /*
  775. * Adjust the font bounding box.
  776. */
  777. wd = ex - sx;
  778. ht = ey - sy;
  779. x_off = sx + face->glyph->bitmap_left;
  780. y_off = sy + face->glyph->bitmap_top - face->glyph->bitmap.rows;
  781. // u8g2 issue 2406
  782. // the above calculation seems to be wrong, this should be:
  783. if ( alternate_y_offset_calculation )
  784. y_off = face->glyph->bitmap_top - ey;
  785. bbx.maxas = MAX(bbx.maxas, ht + y_off);
  786. bbx.maxds = MAX(bbx.maxds, -y_off);
  787. bbx.rbearing = wd + x_off;
  788. bbx.maxrb = MAX(bbx.maxrb, bbx.rbearing);
  789. bbx.minlb = MIN(bbx.minlb, x_off);
  790. bbx.maxlb = MAX(bbx.maxlb, x_off);
  791. /*
  792. * Add to the average width accumulator.
  793. */
  794. aw += wd;
  795. /*
  796. * Print the bitmap header.
  797. */
  798. fprintf(tmp, "STARTCHAR %04lX\nENCODING %ld\n", code,
  799. (long) remapped_code);
  800. fprintf(tmp, "SWIDTH %hd 0\n", swidth);
  801. fprintf(tmp, "DWIDTH %hd 0\n", dwidth);
  802. fprintf(tmp, "BBX %ld %ld %hd %hd\n", wd, ht, x_off, y_off);
  803. // debug output (u8g2 issue 2406)
  804. //if ( remapped_code >= 96 && remapped_code <= 103 )
  805. // fprintf(stderr, "%05ld BBX %ld %ld %hd %hd sy=%d, ey=%d bitmap_top=%d bitmap.rows=%d\n", (long) remapped_code, wd, ht, x_off, y_off, (int)sy, (int)ey, face->glyph->bitmap_top, face->glyph->bitmap.rows);
  806. /*
  807. * Check for an error return here in case the temporary file system
  808. * fills up or the file is deleted while it is being used.
  809. */
  810. eof = fprintf(tmp, "BITMAP\n");
  811. bp = face->glyph->bitmap.buffer + (sy * face->glyph->bitmap.pitch);
  812. for (y = 0; eof != EOF && y < ey - sy; y++) {
  813. for (idx = 0, x = 0; eof != EOF && x < ex - sx; x++) {
  814. if (x > 0 && (x & 7) == 0) {
  815. /*
  816. * Print the next byte.
  817. */
  818. eof = fprintf(tmp, "%02lX", idx & 0xff);
  819. idx = 0;
  820. }
  821. if (bp[(x+sx) >> 3] & (0x80 >> ((x+sx) & 7)))
  822. idx |= (0x80 >> (x & 7));
  823. }
  824. bp += face->glyph->bitmap.pitch;
  825. if (eof != EOF)
  826. /*
  827. * Because of the structure of the loop, the last byte should
  828. * always be printed.
  829. */
  830. fprintf(tmp, "%02lX\n", idx & 0xff);
  831. }
  832. if (eof != EOF)
  833. fprintf(tmp, "ENDCHAR\n");
  834. }
  835. fclose(tmp);
  836. /*
  837. * If a write error occured, delete the temporary file and issue an error
  838. * message.
  839. */
  840. if (eof == EOF) {
  841. (void) unlink(tmpfile);
  842. fprintf(stderr, "%s: problem writing to temporary file '%s'.\n",
  843. prog, tmpfile);
  844. return -1;
  845. }
  846. /*
  847. * If no characters were generated, just unlink the temp file and issue a
  848. * warning.
  849. */
  850. if (ng == 0) {
  851. (void) unlink(tmpfile);
  852. fprintf(stderr, "%s: no glyphs generated from '%s'.\n", prog, iname);
  853. return -1;
  854. }
  855. /*
  856. * Reopen the temporary file so it can be copied to the actual output
  857. * file.
  858. */
  859. if ((tmp = fopen(tmpfile, "r")) == 0) {
  860. /*
  861. * Unable to open the file for read, so attempt to delete it and issue
  862. * an error message.
  863. */
  864. (void) unlink(tmpfile);
  865. fprintf(stderr, "%s: unable to open temporary file '%s' for read.\n",
  866. prog, tmpfile);
  867. return -1;
  868. }
  869. /*
  870. * Calculate the average width.
  871. */
  872. aw = (FT_Long) ((((double) aw / (double) ng) + 0.5) * 10.0);
  873. /*
  874. * Generate the XLFD font name.
  875. */
  876. make_xlfd_name(xlfd, sizeof(xlfd), aw, ismono);
  877. /*
  878. * Start writing the font out.
  879. */
  880. fprintf(out, "STARTFONT 2.1\n");
  881. /*
  882. * Add the vanity comments.
  883. */
  884. fprintf(out, "COMMENT\n");
  885. fprintf(out, "COMMENT Converted from OpenType font \"%s\" by \"%s %s\".\n",
  886. iname, prog, OTF2BDF_VERSION);
  887. fprintf(out, "COMMENT\n");
  888. fprintf(out, "FONT %s\n", xlfd);
  889. fprintf(out, "SIZE %d %d %d\n", point_size, hres, vres);
  890. /*
  891. * Generate the font bounding box.
  892. */
  893. fprintf(out, "FONTBOUNDINGBOX %hd %hd %hd %hd\n",
  894. bbx.maxrb - bbx.minlb, bbx.maxas + bbx.maxds,
  895. bbx.minlb, -bbx.maxds);
  896. /*
  897. * Print the properties.
  898. */
  899. fprintf(out, "STARTPROPERTIES %hd\n", 19);
  900. /*
  901. * Print the font properties from the XLFD name.
  902. */
  903. for (i = 0, xp = xlfd; i < 14; i++) {
  904. /*
  905. * Print the XLFD property name.
  906. */
  907. fprintf(out, "%s ", xlfd_props[i]);
  908. /*
  909. * Make sure the ATOM properties are wrapped in double quotes.
  910. */
  911. if (i < 6 || i == 10 || i > 11)
  912. putc('"', out);
  913. /*
  914. * Skip the leading '-' in the XLFD name.
  915. */
  916. xp++;
  917. /*
  918. * Skip until the next '-' or NULL.
  919. */
  920. for (; *xp && *xp != '-'; xp++)
  921. putc(*xp, out);
  922. /*
  923. * Make sure the ATOM properties are wrapped in double quotes.
  924. */
  925. if (i < 6 || i == 10 || i > 11)
  926. putc('"', out);
  927. putc('\n', out);
  928. }
  929. /*
  930. * Make sure to add the FONT_ASCENT and FONT_DESCENT properties
  931. * because X11 can not live without them.
  932. */
  933. fprintf(out, "FONT_ASCENT %hd\nFONT_DESCENT %hd\n",
  934. (horizontal->Ascender * imetrics.y_ppem) / upm,
  935. -((horizontal->Descender * imetrics.y_ppem) / upm));
  936. /*
  937. * Get the copyright string from the font.
  938. */
  939. (void) otf_get_english_string(face, BDFOTF_COPYRIGHT_STRING, 0, xlfd,
  940. sizeof(xlfd));
  941. fprintf(out, "COPYRIGHT \"%s\"\n", xlfd);
  942. /*
  943. * Last, print the two user-defined properties _OTF_FONTFILE and
  944. * _OTF_PSNAME. _OTF_FONTFILE provides a reference to the original OT
  945. * font file which some systems can take advantage of, and _OTF_PSNAME
  946. * provides the Postscript name of the font if it exists.
  947. */
  948. (void) otf_get_english_string(face, BDFOTF_POSTSCRIPT_STRING, 0, xlfd,
  949. sizeof(xlfd));
  950. fprintf(out, "_OTF_FONTFILE \"%s\"\n_OTF_PSNAME \"%s\"\n", iname, xlfd);
  951. fprintf(out, "ENDPROPERTIES\n");
  952. /*
  953. * Print the actual number of glyphs to the output file.
  954. */
  955. eof = fprintf(out, "CHARS %ld\n", ng);
  956. /*
  957. * Copy the temporary file to the output file.
  958. */
  959. while (eof != EOF && (ng = fread(iobuf, 1, OTF2BDF_IOBUFSIZ, tmp))) {
  960. if (fwrite(iobuf, 1, ng, out) == 0)
  961. eof = EOF;
  962. }
  963. /*
  964. * Close the temporary file and delete it.
  965. */
  966. fclose(tmp);
  967. (void) unlink(tmpfile);
  968. /*
  969. * If an error occured when writing to the output file, issue a warning
  970. * and return.
  971. */
  972. if (eof == EOF) {
  973. fprintf(stderr, "%s: problem writing to output file '%s'.\n",
  974. prog, oname);
  975. return -1;
  976. }
  977. /*
  978. * End the font and do memory cleanup on the glyph and raster structures.
  979. */
  980. eof = fprintf(out, "ENDFONT\n");
  981. return eof;
  982. }
  983. static int
  984. generate_bdf(FILE *out, char *iname, char *oname)
  985. {
  986. FT_Long i;
  987. /*
  988. * Get the requested cmap.
  989. */
  990. for (i = 0; i < face->num_charmaps; i++) {
  991. if (face->charmaps[i]->platform_id == pid &&
  992. face->charmaps[i]->encoding_id == eid)
  993. break;
  994. }
  995. if (i == face->num_charmaps && pid == 3 && eid == 1) {
  996. /*
  997. * Make a special case when this fails with pid == 3 and eid == 1.
  998. * Change to eid == 0 and try again. This captures the two possible
  999. * cases for MS fonts. Some other method should be used to cycle
  1000. * through all the alternatives later.
  1001. */
  1002. for (i = 0; i < face->num_charmaps; i++) {
  1003. if (face->charmaps[i]->platform_id == pid &&
  1004. face->charmaps[i]->encoding_id == 0)
  1005. break;
  1006. }
  1007. if (i < face->num_charmaps) {
  1008. pid = 3;
  1009. eid = 1;
  1010. FT_Set_Charmap(face, face->charmaps[i]);
  1011. } else {
  1012. /*
  1013. * No CMAP was found.
  1014. */
  1015. nocmap = 1;
  1016. pid = eid = -1;
  1017. }
  1018. } else {
  1019. if ( forcenocmap )
  1020. {
  1021. nocmap = 1;
  1022. pid = eid = -1;
  1023. }
  1024. else
  1025. {
  1026. FT_Set_Charmap(face, face->charmaps[i]);
  1027. nocmap = 0;
  1028. }
  1029. }
  1030. if (nocmap && verbose) {
  1031. fprintf(stderr,
  1032. "%s: no character map for platform %d encoding %d. ",
  1033. prog, pid, eid);
  1034. fprintf(stderr, "Generating all glyphs.\n");
  1035. }
  1036. /*
  1037. * Now go through and generate the glyph bitmaps themselves.
  1038. */
  1039. return generate_font(out, iname, oname);
  1040. }
  1041. #define isdig(cc) ((cc) >= '0' && (cc) <= '9')
  1042. /*
  1043. * Routine to parse a subset specification supplied on the command line.
  1044. * The syntax for this specification is the same as the syntax used for
  1045. * the XLFD font names (XLFD documentation, page 9).
  1046. *
  1047. * Example:
  1048. *
  1049. * "60 70 80_90" means the glyphs at codes 60, 70, and between 80 and
  1050. * 90 inclusive.
  1051. */
  1052. static void
  1053. parse_subset(char *s)
  1054. {
  1055. long l, r;
  1056. /*
  1057. * Make sure to clear the flag and bitmap in case more than one subset is
  1058. * specified on the command line.
  1059. */
  1060. maxcode = 0;
  1061. do_subset = 0;
  1062. (void) memset((char *) subset, 0, sizeof(unsigned long) * 2048);
  1063. while (*s) {
  1064. /*
  1065. * Collect the next code value.
  1066. */
  1067. for (l = r = 0; *s && isdig(*s); s++)
  1068. l = (l * 10) + (*s - '0');
  1069. /*
  1070. * If the next character is an '_', advance and collect the end of the
  1071. * specified range.
  1072. */
  1073. if (*s == '_') {
  1074. s++;
  1075. for (; *s && isdig(*s); s++)
  1076. r = (r * 10) + (*s - '0');
  1077. } else
  1078. r = l;
  1079. /*
  1080. * Add the range just collected to the subset bitmap and set the flag
  1081. * that indicates a subset is wanted.
  1082. */
  1083. for (; l <= r; l++) {
  1084. do_subset = 1;
  1085. subset[l >> 5] |= (1 << (l & 31));
  1086. if (l > maxcode)
  1087. maxcode = l;
  1088. }
  1089. /*
  1090. * Skip all non-digit characters.
  1091. */
  1092. while (*s && !isdig(*s))
  1093. s++;
  1094. }
  1095. }
  1096. static void
  1097. usage(int eval)
  1098. {
  1099. printf("Usage: %s [options below] font.ttf\n", prog);
  1100. printf("-h\t\tThis message.\n");
  1101. printf("-v\t\tPrint warning messages during conversion.\n");
  1102. printf("-l \"subset\"\tSpecify a subset of glyphs to generate.\n");
  1103. printf("-m mapfile\tGlyph reencoding file.\n");
  1104. printf("-n\t\tTurn off glyph hinting.\n");
  1105. printf("-a\t\tForce auto hinting.\n");
  1106. printf("-y\t\tApply bugfix for the bbx y offset calculation (u8g2 issue 2406).\n");
  1107. printf("-g\t\tOutput raw glyphs instead of unicode chars.\n");
  1108. printf("-et\t\tDisplay the encoding tables available in the font.\n");
  1109. printf("-c c\t\tSet the character spacing (default: from font).\n");
  1110. printf("-f name\t\tSet the foundry name (default: freetype).\n");
  1111. printf("-t name\t\tSet the typeface name (default: from font).\n");
  1112. printf("-w name\t\tSet the weight name (default: Medium).\n");
  1113. printf("-s name\t\tSet the slant name (default: R).\n");
  1114. printf("-k name\t\tSet the width name (default: Normal).\n");
  1115. printf("-d name\t\tSet the additional style name (default: empty).\n");
  1116. printf("-u char\t\tSet the character to replace '-' in names ");
  1117. printf("(default: space).\n");
  1118. printf("-pid id\t\tSet the platform ID for encoding (default: %d).\n",
  1119. DEFAULT_PLATFORM_ID);
  1120. printf("-eid id\t\tSet the encoding ID for encoding (default: %d).\n",
  1121. DEFAULT_ENCODING_ID);
  1122. printf("-p n\t\tSet the point size (default: %dpt).\n",
  1123. DEFAULT_POINT_SIZE);
  1124. printf("-r n\t\tSet the horizontal and vertical resolution ");
  1125. printf("(default: %ddpi).\n", DEFAULT_RESOLUTION);
  1126. printf("-rh n\t\tSet the horizontal resolution ");
  1127. printf("(default: %ddpi)\n", DEFAULT_RESOLUTION);
  1128. printf("-rv n\t\tSet the vertical resolution ");
  1129. printf("(default: %ddpi)\n", DEFAULT_RESOLUTION);
  1130. printf("-o outfile\tSet the output filename (default: stdout).\n");
  1131. exit(eval);
  1132. }
  1133. int
  1134. main(int argc, char *argv[])
  1135. {
  1136. int res, pet;
  1137. char *infile, *outfile, *iname, *oname;
  1138. FILE *out, *mapin;
  1139. if ((prog = strrchr(argv[0], '/')))
  1140. prog++;
  1141. else
  1142. prog = argv[0];
  1143. /*
  1144. * Flag indicating whether the encoding tables are supposed to be printed
  1145. * or not.
  1146. */
  1147. pet = 0;
  1148. out = stdout;
  1149. infile = outfile = 0;
  1150. argc--;
  1151. argv++;
  1152. while (argc > 0) {
  1153. if (argv[0][0] == '-') {
  1154. switch (argv[0][1]) {
  1155. case 'v': case 'V':
  1156. verbose = 1;
  1157. break;
  1158. case 'l': case 'L':
  1159. argc--;
  1160. argv++;
  1161. parse_subset(argv[0]);
  1162. break;
  1163. case 'n': case 'N':
  1164. load_flags |= FT_LOAD_NO_HINTING;
  1165. break;
  1166. case 'a': case 'A':
  1167. load_flags |= FT_LOAD_FORCE_AUTOHINT;
  1168. break;
  1169. case 'y': case 'Y':
  1170. alternate_y_offset_calculation = 1;
  1171. break;
  1172. case 'g': case 'G':
  1173. forcenocmap = 1;
  1174. break;
  1175. case 'c': case 'C':
  1176. argc--;
  1177. argv++;
  1178. spacing = argv[0][0];
  1179. break;
  1180. case 't': case 'T':
  1181. argc--;
  1182. argv++;
  1183. face_name = argv[0];
  1184. break;
  1185. case 'w': case 'W':
  1186. argc--;
  1187. argv++;
  1188. weight_name = argv[0];
  1189. break;
  1190. case 's': case 'S':
  1191. argc--;
  1192. argv++;
  1193. slant_name = argv[0];
  1194. break;
  1195. case 'k': case 'K':
  1196. argc--;
  1197. argv++;
  1198. width_name = argv[0];
  1199. break;
  1200. case 'd': case 'D':
  1201. argc--;
  1202. argv++;
  1203. style_name = argv[0];
  1204. break;
  1205. case 'f': case 'F':
  1206. argc--;
  1207. argv++;
  1208. foundry_name = argv[0];
  1209. break;
  1210. case 'u': case 'U':
  1211. argc--;
  1212. argv++;
  1213. dashchar = argv[0][0];
  1214. break;
  1215. case 'p': case 'P':
  1216. res = argv[0][2];
  1217. argc--;
  1218. argv++;
  1219. if (res == 'i' || res == 'I') {
  1220. /*
  1221. * No need to print the encoding tables if the user
  1222. * is supplying a platform ID.
  1223. */
  1224. pet = 0;
  1225. /*
  1226. * Set the platform ID.
  1227. */
  1228. pid = atoi(argv[0]);
  1229. } else
  1230. /*
  1231. * Set the point size.
  1232. */
  1233. point_size = atoi(argv[0]);
  1234. break;
  1235. case 'e': case 'E':
  1236. if (argv[0][2] == 't' || argv[0][2] == 'T')
  1237. pet = 1;
  1238. else {
  1239. /*
  1240. * No need to print the encoding tables if the user
  1241. * is supplying a platform ID.
  1242. */
  1243. pet = 0;
  1244. /*
  1245. * Set the encoding ID.
  1246. */
  1247. argc--;
  1248. argv++;
  1249. eid = atoi(argv[0]);
  1250. }
  1251. break;
  1252. case 'r':
  1253. /*
  1254. * Set the horizontal and vertical resolutions.
  1255. */
  1256. if (argv[0][2] == 'h')
  1257. hres = atoi(argv[1]);
  1258. else if (argv[0][2] == 'v')
  1259. vres = atoi(argv[1]);
  1260. else
  1261. hres = vres = atoi(argv[1]);
  1262. argc--;
  1263. argv++;
  1264. break;
  1265. case 'm': case 'M':
  1266. /*
  1267. * Try to load a remap table.
  1268. */
  1269. argc--;
  1270. argv++;
  1271. /*
  1272. * Always reset the `do_remap' variable here in case more than
  1273. * one map file appears on the command line.
  1274. */
  1275. do_remap = 0;
  1276. if ((mapin = fopen(argv[0], "r")) == 0)
  1277. fprintf(stderr, "%s: unable to open the remap table '%s'.\n",
  1278. prog, argv[0]);
  1279. else {
  1280. if (otf2bdf_load_map(mapin) < 0) {
  1281. fprintf(stderr,
  1282. "%s: problem loading remap table '%s'.\n",
  1283. prog, argv[0]);
  1284. do_remap = 0;
  1285. } else
  1286. do_remap = 1;
  1287. fclose(mapin);
  1288. }
  1289. break;
  1290. case 'o': case 'O':
  1291. /*
  1292. * Set the output file name.
  1293. */
  1294. argc--;
  1295. argv++;
  1296. outfile = argv[0];
  1297. break;
  1298. default:
  1299. usage(1);
  1300. }
  1301. } else
  1302. /*
  1303. * Set the input file name.
  1304. */
  1305. infile = argv[0];
  1306. argc--;
  1307. argv++;
  1308. }
  1309. /*
  1310. * Validate the values passed on the command line.
  1311. */
  1312. if (infile == 0) {
  1313. fprintf(stderr, "%s: no input file provided.\n", prog);
  1314. usage(1);
  1315. }
  1316. /*
  1317. * Set the input filename that will be passed to the generator
  1318. * routine.
  1319. */
  1320. if ((iname = strrchr(infile, '/')))
  1321. iname++;
  1322. else
  1323. iname = infile;
  1324. /*
  1325. * Check the platform and encoding IDs.
  1326. */
  1327. if (pid < 0 || pid > 255) {
  1328. fprintf(stderr, "%s: invalid platform ID '%d'.\n", prog, pid);
  1329. exit(1);
  1330. }
  1331. if (eid < 0 || eid > 65535) {
  1332. fprintf(stderr, "%s: invalid encoding ID '%d'.\n", prog, eid);
  1333. exit(1);
  1334. }
  1335. /*
  1336. * Arbitrarily limit the point size to a minimum of 2pt and maximum of
  1337. * 256pt.
  1338. */
  1339. if (point_size < 2 || point_size > 256) {
  1340. fprintf(stderr, "%s: invalid point size '%dpt'.\n", prog, point_size);
  1341. exit(1);
  1342. }
  1343. /*
  1344. * Arbitrarily limit the resolutions to a minimum of 10dpi and a maximum
  1345. * of 1200dpi.
  1346. */
  1347. if (hres < 10 || hres > 1200) {
  1348. fprintf(stderr, "%s: invalid horizontal resolution '%ddpi'.\n",
  1349. prog, hres);
  1350. exit(1);
  1351. }
  1352. if (vres < 10 || vres > 1200) {
  1353. fprintf(stderr, "%s: invalid vertical resolution '%ddpi'.\n",
  1354. prog, vres);
  1355. exit(1);
  1356. }
  1357. /*
  1358. * Open the output file if specified.
  1359. */
  1360. if (outfile != 0) {
  1361. /*
  1362. * Attempt to open the output file.
  1363. */
  1364. if ((out = fopen(outfile, "w")) == 0) {
  1365. fprintf(stderr, "%s: unable to open the output file '%s'.\n",
  1366. prog, outfile);
  1367. exit(1);
  1368. }
  1369. /*
  1370. * Set the output filename to be passed to the generator routine.
  1371. */
  1372. if ((oname = strrchr(outfile, '/')))
  1373. oname++;
  1374. else
  1375. oname = outfile;
  1376. } else
  1377. /*
  1378. * Set the default output file name to <stdout>.
  1379. */
  1380. oname = "<stdout>";
  1381. /*
  1382. * Intialize Freetype.
  1383. */
  1384. if ((res = FT_Init_FreeType(&library))) {
  1385. /*
  1386. * Close the output file.
  1387. */
  1388. if (out != stdout) {
  1389. fclose(out);
  1390. (void) unlink(outfile);
  1391. }
  1392. fprintf(stderr, "%s[%d]: unable to initialize renderer.\n",
  1393. prog, res);
  1394. exit(1);
  1395. }
  1396. /*
  1397. * Open the input file.
  1398. */
  1399. if ((res = FT_New_Face(library, infile, 0, &face))) {
  1400. if (out != stdout) {
  1401. fclose(out);
  1402. (void) unlink(outfile);
  1403. }
  1404. fprintf(stderr, "%s[%d]: unable to open input file '%s'.\n",
  1405. prog, res, infile);
  1406. exit(1);
  1407. }
  1408. if (pet)
  1409. /*
  1410. * Simply print the encoding tables and do nothing else.
  1411. */
  1412. print_encoding_table();
  1413. else {
  1414. /*
  1415. * Set the instance resolution and point size and the relevant
  1416. * metrics.
  1417. */
  1418. FT_Set_Char_Size(face, 0, point_size * 64, hres, vres);
  1419. /*
  1420. * Set the global units per em value for convenience.
  1421. */
  1422. upm = face->units_per_EM;
  1423. /*
  1424. * Generate the BDF font from the TrueType font.
  1425. */
  1426. res = generate_bdf(out, iname, oname);
  1427. }
  1428. /*
  1429. * Free up the mapping table if one was loaded.
  1430. */
  1431. otf2bdf_free_map();
  1432. /*
  1433. * Close the input and output files.
  1434. */
  1435. (void) FT_Done_Face(face);
  1436. if (out != stdout) {
  1437. fclose(out);
  1438. if (res < 0)
  1439. /*
  1440. * An error occured when generating the font, so delete the
  1441. * output file.
  1442. */
  1443. (void) unlink(outfile);
  1444. }
  1445. /*
  1446. * Shut down the renderer.
  1447. */
  1448. FT_Done_FreeType(library);
  1449. exit(res);
  1450. return 0;
  1451. }