bdf-converter.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752
  1. /****************************************************************************
  2. * tools/bdf-converter.c
  3. *
  4. * Licensed to the Apache Software Foundation (ASF) under one or more
  5. * contributor license agreements. See the NOTICE file distributed with
  6. * this work for additional information regarding copyright ownership. The
  7. * ASF licenses this file to you under the Apache License, Version 2.0 (the
  8. * "License"); you may not use this file except in compliance with the
  9. * License. You may obtain a copy of the License at
  10. *
  11. * http://www.apache.org/licenses/LICENSE-2.0
  12. *
  13. * Unless required by applicable law or agreed to in writing, software
  14. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  15. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  16. * License for the specific language governing permissions and limitations
  17. * under the License.
  18. *
  19. ****************************************************************************/
  20. /* Based one the "Glyph Bitmap Distribution Format (BDF) Specification",
  21. * Version 2.2, by Adobe Systems Incorporated.
  22. */
  23. /****************************************************************************
  24. * Included Files
  25. ****************************************************************************/
  26. #include <stdint.h>
  27. #include <stdio.h>
  28. #include <stdlib.h>
  29. #include <stdbool.h>
  30. #include <string.h>
  31. #include <ctype.h>
  32. /****************************************************************************
  33. * Pre-processor Definitions
  34. ****************************************************************************/
  35. #if 0
  36. # define VERBOSE
  37. # define DBG
  38. #endif
  39. /* BDF Specification Version 2.2:
  40. * This version lifts the restriction on line length. In this version,
  41. * the new maximum length of a value of the type string is 65535 characters,
  42. * and hence lines may now be at least this long.
  43. */
  44. #define BDF_MAX_LINE_LENGTH 65535
  45. /* Ranges of 7-bit and 8-bit fonts */
  46. #define NXFONT_MIN7BIT 33
  47. #define NXFONT_MAX7BIT 126
  48. #define NXFONT_MIN8BIT 161
  49. #define NXFONT_MAX8BIT 255
  50. /****************************************************************************
  51. * Private Types
  52. ****************************************************************************/
  53. /* This structure holds information about a glyph */
  54. typedef struct glyphinfo_s
  55. {
  56. char *name; /* Name for they glyph */
  57. int encoding; /* The Adobe Standard Encoding value */
  58. int dw_x0; /* Width in x of the vector indicating
  59. * the position of the next glyph's origin
  60. * relative to the origin of this glyph */
  61. int dw_y0; /* Width in y of the vector indicating
  62. * the position of the next glyph's origin
  63. * relative to the origin of this glyph */
  64. int bb_w; /* The width of the black pixels in x */
  65. int bb_h; /* The height of the black pixels in y */
  66. int bb_x_off; /* X displacement of the lower left corner
  67. * of the bitmap from origin 0 */
  68. int bb_y_off; /* Y displacement of the lower left corner
  69. * of the bitmap from origin 0 */
  70. uint64_t *bitmap; /* Hexadecimal data for the character bitmap */
  71. } glyphinfo_t;
  72. /* This structures provides the metrics for one glyph */
  73. typedef struct nx_fontmetric_s
  74. {
  75. uint32_t stride : 3; /* Width of one font row in bytes */
  76. uint32_t width : 6; /* Width of the font in bits */
  77. uint32_t height : 6; /* Height of the font in rows */
  78. uint32_t xoffset : 6; /* Top, left-hand corner X-offset in pixels */
  79. uint32_t yoffset : 6; /* Top, left-hand corner y-offset in pixels */
  80. uint32_t unused : 5;
  81. } nx_fontmetric_t;
  82. /****************************************************************************
  83. * Private Functions
  84. ****************************************************************************/
  85. /****************************************************************************
  86. * Name: my_strtok_r
  87. *
  88. * Description:
  89. * MinGW does not seem to provide strtok_r
  90. *
  91. ****************************************************************************/
  92. #ifndef HAVE_STRTOK_R
  93. static char *my_strtok_r(char *str, const char *delim, char **saveptr)
  94. {
  95. char *pbegin;
  96. char *pend = NULL;
  97. /* Decide if we are starting a new string or continuing from
  98. * the point we left off.
  99. */
  100. if (str)
  101. {
  102. pbegin = str;
  103. }
  104. else if (saveptr && *saveptr)
  105. {
  106. pbegin = *saveptr;
  107. }
  108. else
  109. {
  110. return NULL;
  111. }
  112. /* Find the beginning of the next token */
  113. for (;
  114. *pbegin && strchr(delim, *pbegin) != NULL;
  115. pbegin++);
  116. /* If we are at the end of the string with nothing
  117. * but delimiters found, then return NULL.
  118. */
  119. if (!*pbegin)
  120. {
  121. return NULL;
  122. }
  123. /* Find the end of the token */
  124. for (pend = pbegin + 1;
  125. *pend && strchr(delim, *pend) == NULL;
  126. pend++);
  127. /* pend either points to the end of the string or to
  128. * the first delimiter after the string.
  129. */
  130. if (*pend)
  131. {
  132. /* Turn the delimiter into a null terminator */
  133. *pend++ = '\0';
  134. }
  135. /* Save the pointer where we left off and return the
  136. * beginning of the token.
  137. */
  138. if (saveptr)
  139. {
  140. *saveptr = pend;
  141. }
  142. return pbegin;
  143. }
  144. #undef strtok_r
  145. #define strtok_r my_strtok_r
  146. #endif
  147. /****************************************************************************
  148. * Name: trimline
  149. *
  150. * Description:
  151. * Trims the line removing space characters at the front and at the end
  152. * of the line.
  153. *
  154. * Input Parameters:
  155. * line - The line to trim
  156. *
  157. ****************************************************************************/
  158. static void trimline(char *line)
  159. {
  160. char *str;
  161. str = line;
  162. char *strend;
  163. for (strend = str + strlen(str) - 1;
  164. strend >= str && isspace((int)(*strend));
  165. strend--);
  166. *(strend + 1) = 0;
  167. }
  168. /****************************************************************************
  169. * Name: bdf_parseIntLine
  170. *
  171. * Description:
  172. * Parses a line containing a BDF property followed by integers. It will
  173. * ignore the first token that corresponds to the property name.
  174. *
  175. * Input Parameters:
  176. * line - A line with a BDF property followed by integers, i.e.:
  177. * "FONTBOUNDINGBOX 8 13 0 -2"
  178. * count - How many integers are specified by the BDF property. In the
  179. * example above, count = 4.
  180. * info - A pointer to memory provided by the caller in which to
  181. * return the array of integers. For the example above:
  182. * info[0] = 8
  183. * info[1] = 13
  184. * info[2] = 0
  185. * info[3] = -2
  186. *
  187. ****************************************************************************/
  188. static void bdf_parseintline(char *line, unsigned int count, int *info)
  189. {
  190. char *str;
  191. char *token;
  192. char *saveptr1;
  193. str = line;
  194. /* Ignore the key */
  195. token = (char *)strtok_r(str, " ", &saveptr1);
  196. while ((token = (char *)strtok_r(NULL, " ", &saveptr1)) && count--)
  197. {
  198. *(info++) = atoi(token);
  199. }
  200. }
  201. /****************************************************************************
  202. * Name: bdf_printglyphinfo
  203. *
  204. * Description:
  205. * Prints the information available for a glyph.
  206. *
  207. * Input Parameters:
  208. * ginfo - A glyphinfo_t struct with the glyph's information.
  209. *
  210. ****************************************************************************/
  211. #ifdef DBG
  212. static void bdf_printglyphinfo(const glyphinfo_t *ginfo)
  213. {
  214. printf("NAME = %s\n", ginfo->name);
  215. printf("ENCODING = %d\n", ginfo->encoding);
  216. printf("DW_X0 = %d\n", ginfo->dw_x0);
  217. printf("DW_Y0 = %d\n", ginfo->dw_y0);
  218. printf("BB_W = %d\n", ginfo->bb_w);
  219. printf("BB_H = %d\n", ginfo->bb_h);
  220. printf("BB_X_OFF = %d\n", ginfo->bb_x_off);
  221. printf("BB_Y_OFF = %d\n", ginfo->bb_y_off);
  222. int i;
  223. for (i = 0; i < ginfo->bb_h; i++)
  224. {
  225. printf("BITMAP[%d] = %x\n", i, ginfo->bitmap[i]);
  226. }
  227. }
  228. #endif /* DBG */
  229. /****************************************************************************
  230. * Name: bdf_printnxmetricinfo
  231. *
  232. * Description:
  233. * Prints the information available for a glyph's metric in the NX
  234. * graphics system.
  235. *
  236. * Input Parameters:
  237. * info - A nx_fontmetric_t struct with the glyph's information.
  238. *
  239. ****************************************************************************/
  240. #ifdef DBG
  241. static void bdf_printnxmetricinfo(const nx_fontmetric_t *info)
  242. {
  243. printf("STRIDE = %d\n", info->stride);
  244. printf("WIDTH = %d\n", info->width);
  245. printf("HEIGHT = %d\n", info->height);
  246. printf("XOFFSET = %d\n", info->xoffset);
  247. printf("YOFFSET = %d\n", info->yoffset);
  248. }
  249. #endif /* DBG */
  250. /****************************************************************************
  251. * Name: bdf_getglyphinfo
  252. *
  253. * Description:
  254. * Obtains the information for an individual glyph. The BDF properties
  255. * taken into account are:
  256. * - ENCODING
  257. * - DWIDTH
  258. * - BBX
  259. * BDF properties ignored:
  260. * - SWIDTH
  261. * - SWIDTH1
  262. * - DWIDTH1
  263. * - VVECTOR
  264. *
  265. * Input Parameters:
  266. * file - The input file stream pointing to the first line of the
  267. * glyph's information (right after STARTCHAR).
  268. * ginfo - A glyphinfo_t struct to fill with the glyph's information.
  269. *
  270. ****************************************************************************/
  271. static void bdf_getglyphinfo(FILE *file, glyphinfo_t *ginfo)
  272. {
  273. char line[BDF_MAX_LINE_LENGTH];
  274. char linecopy[BDF_MAX_LINE_LENGTH];
  275. char *str;
  276. char *token;
  277. char *saveptr1;
  278. bool done;
  279. done = false;
  280. while (fgets(line, BDF_MAX_LINE_LENGTH, file) != NULL && !done)
  281. {
  282. trimline(line);
  283. strcpy(linecopy, line);
  284. str = line;
  285. while ((token = (char *)strtok_r(str, " ", &saveptr1)))
  286. {
  287. /* ENCODING information */
  288. if (strcmp(token, "ENCODING") == 0)
  289. {
  290. token = (char *)strtok_r(NULL, " ", &saveptr1);
  291. ginfo->encoding = atoi(token);
  292. }
  293. /* DWIDTH information */
  294. if (strcmp(token, "DWIDTH") == 0)
  295. {
  296. token = (char *)strtok_r(NULL, " ", &saveptr1);
  297. ginfo->dw_x0 = atoi(token);
  298. token = (char *)strtok_r(NULL, " ", &saveptr1);
  299. ginfo->dw_y0 = atoi(token);
  300. }
  301. /* BBX information */
  302. else if (strcmp(token, "BBX") == 0)
  303. {
  304. int bbxinfo[4];
  305. bdf_parseintline(linecopy, 4, bbxinfo);
  306. ginfo->bb_w = bbxinfo[0];
  307. ginfo->bb_h = bbxinfo[1];
  308. ginfo->bb_x_off = bbxinfo[2];
  309. ginfo->bb_y_off = bbxinfo[3];
  310. /* This is the last BDF property of interest */
  311. done = true;
  312. }
  313. str = NULL;
  314. }
  315. }
  316. }
  317. /****************************************************************************
  318. * Name: bdf_getglyphbitmap
  319. *
  320. * Description:
  321. * Obtains the character bitmap information for an individual glyph.
  322. *
  323. * Input Parameters:
  324. * file - The input file stream pointing to the first line of the
  325. * glyph's bitmap (right after BITMAP).
  326. * ginfo - A glyphinfo_t struct to fill with the glyph's bitmap.
  327. *
  328. ****************************************************************************/
  329. static void bdf_getglyphbitmap(FILE *file, glyphinfo_t *ginfo)
  330. {
  331. char line[BDF_MAX_LINE_LENGTH];
  332. uint64_t *bitmap;
  333. bool readingbitmap;
  334. bitmap = ginfo->bitmap;
  335. readingbitmap = true;
  336. while (readingbitmap)
  337. {
  338. if (fgets(line, BDF_MAX_LINE_LENGTH, file) != NULL)
  339. {
  340. trimline(line);
  341. if (strcmp(line, "ENDCHAR") == 0)
  342. {
  343. readingbitmap = false;
  344. }
  345. else
  346. {
  347. char *endptr;
  348. *bitmap = strtoul(line, &endptr, 16);
  349. bitmap++;
  350. }
  351. }
  352. else
  353. {
  354. /* error condition */
  355. readingbitmap = false;
  356. }
  357. }
  358. }
  359. /****************************************************************************
  360. * Name: bdf_getstride
  361. *
  362. * Description:
  363. * Obtains the stride for an individual glyph. The stride is the width
  364. * of one glyph's bitmap row in bytes.
  365. *
  366. * Input Parameters:
  367. * ginfo - A glyphinfo_t struct with the glyph's information.
  368. * stride - A pointer to memory provided by the caller in which to
  369. * return the stride.
  370. *
  371. ****************************************************************************/
  372. static void bdf_getstride(glyphinfo_t *ginfo, uint32_t *stride)
  373. {
  374. *stride = (ginfo->bb_w % 8 == 0) ? ginfo->bb_w / 8 : ginfo->bb_w / 8 + 1;
  375. }
  376. /****************************************************************************
  377. * Name: bdf_printoutput
  378. *
  379. * Description:
  380. * Prints to the output stream the information of an individual glyph in
  381. * the NuttX font format.
  382. *
  383. * Input Parameters:
  384. * out - The output stream.
  385. * ginfo - A glyphinfo_t struct with the glyph's information.
  386. * nxmetric - A nx_fontmetric_t struct with the glyph's information.
  387. *
  388. ****************************************************************************/
  389. static void bdf_printoutput(FILE *out,
  390. glyphinfo_t *ginfo,
  391. nx_fontmetric_t *nxmetric)
  392. {
  393. int i;
  394. int j;
  395. /* Only interested in the 7 and 8 bit ranges */
  396. if ((ginfo->encoding >= NXFONT_MIN7BIT &&
  397. ginfo->encoding <= NXFONT_MAX7BIT) ||
  398. (ginfo->encoding >= NXFONT_MIN8BIT &&
  399. ginfo->encoding <= NXFONT_MAX8BIT))
  400. {
  401. /* Glyph general info */
  402. if (ginfo->bb_x_off < 0)
  403. {
  404. fprintf(out,
  405. "/* %s (%d) -- NOTE: Xoffset should be %d, not 0. */\n",
  406. ginfo->name,
  407. ginfo->encoding,
  408. ginfo->bb_x_off);
  409. }
  410. else
  411. {
  412. fprintf(out, "/* %s (%d) */\n", ginfo->name, ginfo->encoding);
  413. }
  414. /* Glyph metrics */
  415. fprintf(out,
  416. "#define NXFONT_METRICS_%d {%d, %d, %d, %d, %d, 0}\n",
  417. ginfo->encoding,
  418. nxmetric->stride,
  419. nxmetric->width,
  420. nxmetric->height,
  421. nxmetric->xoffset,
  422. nxmetric->yoffset);
  423. /* Glyph bitmap */
  424. fprintf(out, "#define NXFONT_BITMAP_%d {", ginfo->encoding);
  425. for (i = 0; i < ginfo->bb_h - 1; i++)
  426. {
  427. for (j = 1; j <= nxmetric->stride; j++)
  428. {
  429. int nxbyteoffset;
  430. uint8_t nxbyte = 0;
  431. uint64_t tempbitmap = ginfo->bitmap[i];
  432. /* Get the next byte */
  433. nxbyteoffset = (nxmetric->stride - j) * 8;
  434. nxbyte = (uint8_t)(tempbitmap >> nxbyteoffset);
  435. fprintf(out, "0x%x, ", nxbyte);
  436. }
  437. }
  438. /* Different behavior for the last bitmap */
  439. for (j = 1; j <= nxmetric->stride; j++)
  440. {
  441. int nxbyteoffset;
  442. uint8_t nxbyte = 0;
  443. uint64_t tempbitmap = ginfo->bitmap[i];
  444. /* Get the next byte */
  445. nxbyteoffset = (nxmetric->stride - j) * 8;
  446. nxbyte = (uint8_t)(tempbitmap >> nxbyteoffset);
  447. if (j == nxmetric->stride)
  448. {
  449. fprintf(out, "0x%x}\n", nxbyte);
  450. }
  451. else
  452. {
  453. fprintf(out, "0x%x, ", nxbyte);
  454. }
  455. }
  456. fprintf(out, "\n");
  457. }
  458. }
  459. /****************************************************************************
  460. * Main
  461. ****************************************************************************/
  462. int main(int argc, char **argv)
  463. {
  464. FILE *file, *out;
  465. char line[BDF_MAX_LINE_LENGTH];
  466. char linecopy[BDF_MAX_LINE_LENGTH];
  467. char *str;
  468. char *token;
  469. char *saveptr1;
  470. char *input;
  471. char *output;
  472. /* FONTBOUNDINGBOX properties */
  473. int fbb_x = 0;
  474. int fbb_y = 0;
  475. int fbb_y_off = 0;
  476. /* int fbb_x_off = 0; */
  477. /* Input BDF file */
  478. input = argv[1];
  479. if (input == NULL)
  480. {
  481. printf("%s: no input file\n", argv[0]);
  482. exit(0);
  483. }
  484. file = fopen(input, "r");
  485. if (file == NULL)
  486. {
  487. printf("%s: error opening file %s\n", argv[0], input);
  488. exit(0);
  489. }
  490. else
  491. {
  492. #ifdef VERBOSE
  493. printf("Opening \"%s\"\n", input);
  494. #endif /* VERBOSE */
  495. }
  496. /* Output file */
  497. if (argv[2])
  498. {
  499. output = argv[2];
  500. }
  501. else
  502. {
  503. output = "nxfonts_myfont.h";
  504. }
  505. out = fopen(output, "w");
  506. if (out == NULL)
  507. {
  508. printf("%s: error opening file %s\n", argv[0], output);
  509. fclose(file);
  510. exit(0);
  511. }
  512. else
  513. {
  514. while (fgets(line, BDF_MAX_LINE_LENGTH, file) != NULL)
  515. {
  516. #ifdef DBG
  517. printf("--\n");
  518. #endif /* DBG */
  519. /* Save a copy of the line */
  520. strcpy(linecopy, line);
  521. /* Clean it */
  522. trimline(line);
  523. str = line;
  524. while ((token = (char *)strtok_r(str, " ", &saveptr1)))
  525. {
  526. /* FONTBOUNDINGBOX - Global font information */
  527. if (strcmp(token, "FONTBOUNDINGBOX") == 0)
  528. {
  529. int fbbinfo[4];
  530. bdf_parseintline(linecopy, 4, fbbinfo);
  531. fbb_x = fbbinfo[0];
  532. fbb_y = fbbinfo[1];
  533. /* fbb_x_off = fbbinfo[2]; */
  534. fbb_y_off = fbbinfo[3];
  535. /* Print FONTBOUNDINGBOX information */
  536. fprintf(out, "/* Maximum height and width of any");
  537. fprintf(out, " glyph in the set */\n\n");
  538. fprintf(out, "#define NXFONT_MAXHEIGHT %d\n", fbb_y);
  539. fprintf(out, "#define NXFONT_MAXWIDTH %d\n\n", fbb_x);
  540. }
  541. /* STARTCHAR - Individual glyph information */
  542. if (strcmp(token, "STARTCHAR") == 0)
  543. {
  544. glyphinfo_t ginfo;
  545. /* Glyph name */
  546. ginfo.name = (char *)strtok_r(NULL, " ", &saveptr1);
  547. #ifdef VERBOSE
  548. printf("Processing glyph: %s\n", ginfo.name);
  549. #endif /* VERBOSE */
  550. /* Glyph information:
  551. * ENCODING
  552. * DWIDTH
  553. * BBX
  554. */
  555. ginfo.encoding = 0;
  556. ginfo.dw_x0 = 0;
  557. ginfo.dw_y0 = 0;
  558. ginfo.bb_w = 0;
  559. ginfo.bb_h = 0;
  560. ginfo.bb_x_off = 0;
  561. ginfo.bb_y_off = 0;
  562. bdf_getglyphinfo(file, &ginfo);
  563. /* Glyph bitmap */
  564. ginfo.bitmap = malloc(sizeof(uint64_t) * ginfo.bb_h);
  565. bdf_getglyphbitmap(file, &ginfo);
  566. #ifdef DBG
  567. bdf_printglyphinfo(&ginfo);
  568. #endif /* DBG */
  569. /* Convert to nxfonts */
  570. nx_fontmetric_t nxmetric;
  571. uint32_t stride;
  572. bdf_getstride(&ginfo, &stride);
  573. nxmetric.stride = stride;
  574. nxmetric.width = ginfo.bb_w;
  575. nxmetric.height = ginfo.bb_h;
  576. /* The NuttX font format does not support
  577. * negative X offsets.
  578. */
  579. if (ginfo.bb_x_off < 0)
  580. {
  581. nxmetric.xoffset = 0;
  582. printf("%s: ignoring negative x offset for "
  583. "glyph '%s' (%d)\n",
  584. argv[0],
  585. ginfo.name,
  586. ginfo.encoding);
  587. }
  588. else
  589. {
  590. nxmetric.xoffset = ginfo.bb_x_off;
  591. }
  592. nxmetric.yoffset = fbb_y + fbb_y_off -
  593. ginfo.bb_y_off - ginfo.bb_h;
  594. #ifdef DBG
  595. bdf_printnxmetricinfo(&nxmetric);
  596. #endif /* DBG */
  597. /* The space (32) character is treated differently */
  598. if (ginfo.encoding == 32)
  599. {
  600. fprintf(out, "/* The width of a space */\n\n");
  601. fprintf(out, "#define NXFONT_SPACEWIDTH %d\n\n",
  602. ginfo.dw_x0);
  603. }
  604. else
  605. {
  606. bdf_printoutput(out, &ginfo, &nxmetric);
  607. }
  608. /* Free memory */
  609. free(ginfo.bitmap);
  610. }
  611. str = NULL;
  612. }
  613. }
  614. fclose(file);
  615. fclose(out);
  616. /* The End */
  617. printf("Generated \"%s\"\n", output);
  618. }
  619. return EXIT_SUCCESS;
  620. }