a simple textfile based psf font editor suite
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

612 lines
15 KiB

  1. /* psf.c
  2. *
  3. * a simple psf handling library.
  4. *
  5. * Gunnar Zötl <gz@tset.de> 2016
  6. * Released under the terms of the MIT license. See file LICENSE for details.
  7. *
  8. * info about the psf font file format(s) from
  9. * http://www.win.tue.nl/~aeb/linux/kbd/font-formats-1.html
  10. */
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <string.h>
  14. #include "psf.h"
  15. #include "mini_utf8.h"
  16. static int psf_reallocglyphs(struct psf_font *psf, unsigned int num);
  17. struct psf_font *psf_new(unsigned int version, unsigned int width, unsigned int height)
  18. {
  19. if (version != 1 && version != 2) {
  20. fprintf(stderr, "%s: invalid version\n", __func__);
  21. return 0;
  22. }
  23. if ((version == 1 && width != 8) || width == 0 || height == 0) {
  24. fprintf(stderr, "%s: invalid char size\n", __func__);
  25. return 0;
  26. }
  27. struct psf_font *psf = calloc(1, sizeof(struct psf_font));
  28. if (!psf) {
  29. perror(__func__);
  30. return 0;
  31. }
  32. psf->version = version;
  33. if (version == 1) {
  34. psf->header.psf1.charsize = height;
  35. psf->header.psf1.magic[0] = PSF1_MAGIC0;
  36. psf->header.psf1.magic[1] = PSF1_MAGIC1;
  37. psf_reallocglyphs(psf, 256);
  38. } else {
  39. psf->header.psf2.width = width;
  40. psf->header.psf2.height = height;
  41. psf->header.psf2.charsize = ((width + 7) / 8) * height;
  42. psf->header.psf2.magic[0] = PSF2_MAGIC0;
  43. psf->header.psf2.magic[1] = PSF2_MAGIC1;
  44. psf->header.psf2.magic[2] = PSF2_MAGIC2;
  45. psf->header.psf2.magic[3] = PSF2_MAGIC3;
  46. psf->header.psf2.version = 0;
  47. psf->header.psf2.headersize = sizeof(struct psf2_header);
  48. }
  49. return psf;
  50. }
  51. static int psf_read_byte(FILE *file, unsigned int *bval)
  52. {
  53. int rd = fgetc(file);
  54. if (rd == EOF) {
  55. perror(__func__);
  56. return 0;
  57. }
  58. *bval = (unsigned int) rd & 0xff;
  59. return 1;
  60. }
  61. static int psf_write_byte(FILE *file, unsigned int bval)
  62. {
  63. int wr = fputc(bval & 0xff, file);
  64. if (wr == EOF) {
  65. perror(__func__);
  66. return 0;
  67. }
  68. return 1;
  69. }
  70. static int psf_read_word(FILE *file, unsigned int *wval)
  71. {
  72. unsigned int byte0, byte1;
  73. if (!psf_read_byte(file, &byte0) || !psf_read_byte(file, &byte1)) {
  74. return 0;
  75. }
  76. *wval = byte0 + (byte1 << 8);
  77. return 1;
  78. }
  79. static int psf_write_word(FILE *file, unsigned int wval)
  80. {
  81. unsigned int byte0, byte1;
  82. byte0 = wval & 0xff;
  83. byte1 = (wval >> 8) & 0xff;
  84. return psf_write_byte(file, byte0) && psf_write_byte(file, byte1);
  85. }
  86. static int psf_read_int(FILE *file, unsigned int *ival)
  87. {
  88. unsigned int byte0, byte1, byte2, byte3;
  89. if (!psf_read_byte(file, &byte0) || !psf_read_byte(file, &byte1) || !psf_read_byte(file, &byte2) || !psf_read_byte(file, &byte3)) {
  90. return 0;
  91. }
  92. *ival = byte0 + (byte1 << 8) + (byte2 << 16) + (byte3 << 24);
  93. return 1;
  94. }
  95. static int psf_write_int(FILE *file, unsigned int ival)
  96. {
  97. unsigned int byte0, byte1, byte2, byte3;
  98. byte0 = ival & 0xff;
  99. byte1 = (ival >> 8) & 0xff;
  100. byte2 = (ival >> 16) & 0xff;
  101. byte3 = (ival >> 24) & 0xff;
  102. return psf_write_byte(file, byte0) && psf_write_byte(file, byte1) && psf_write_byte(file, byte2) && psf_write_byte(file, byte3);
  103. }
  104. static int psf_read_glyphs(FILE *file, struct psf_font *psf, unsigned int numglyphs, unsigned int glyphsize)
  105. {
  106. unsigned int glyph;
  107. psf->glyph = calloc(numglyphs, sizeof(struct psf_glyph));
  108. if (!psf->glyph) { return 0; }
  109. for (glyph = 0; glyph < numglyphs; ++glyph) {
  110. psf->glyph[glyph].data = malloc(glyphsize);
  111. if (!psf->glyph[glyph].data) { return 0; } /* psf_delete will take care of cleanup */
  112. if (fread(psf->glyph[glyph].data, 1, glyphsize, file) != glyphsize) { return 0; }
  113. }
  114. return 1;
  115. }
  116. static int psf1_read_ucvals(FILE *file, struct psf_font *psf, unsigned int numglyphs)
  117. {
  118. unsigned int i;
  119. for (i = 0; i < numglyphs; ++i) {
  120. struct psf_glyph *glyph = &psf->glyph[i];
  121. unsigned int ucval;
  122. while (1) {
  123. if (!psf_read_word(file, &ucval)) { return 0; }
  124. if (ucval == PSF1_SEPARATOR) { break; }
  125. psf_glyph_adducval(psf, glyph, ucval);
  126. }
  127. }
  128. return 1;
  129. }
  130. static struct psf_font *psf1_load_fromfile(FILE* file)
  131. {
  132. unsigned char magic[2];
  133. magic[0] = PSF1_MAGIC0;
  134. if (fread(&magic[1], 1, 1, file) != 1) {
  135. perror(__func__);
  136. return 0;
  137. }
  138. if (magic[1] != PSF1_MAGIC1) {
  139. fprintf(stderr, "%s: invalid magic number", __func__);
  140. return 0;
  141. }
  142. unsigned int mode, height;
  143. if (!psf_read_byte(file, &mode)) { return 0; }
  144. if (!psf_read_byte(file, &height)) { return 0; }
  145. struct psf_font *psf = psf_new(1, 8, height);
  146. psf->header.psf1.mode = mode;
  147. int numglyphs = (mode & PSF1_MODE512) ? 512 : 256;
  148. if (!psf_read_glyphs(file, psf, numglyphs, height)) {
  149. psf_delete(psf);
  150. return 0;
  151. }
  152. if (!psf1_read_ucvals(file, psf, numglyphs)) {
  153. psf_delete(psf);
  154. return 0;
  155. }
  156. return psf;
  157. }
  158. static unsigned char *psf2_read_remaining_file(FILE *file, unsigned int *size)
  159. {
  160. unsigned char buf[BUFSIZ], *ubuf = 0;
  161. size_t nrd = 0, total = 0;
  162. while ((nrd = fread(buf, 1, BUFSIZ, file)) > 0) {
  163. unsigned char *newubuf = realloc(ubuf, total + nrd);
  164. if (newubuf) {
  165. ubuf = newubuf;
  166. } else {
  167. perror(__func__);
  168. free(ubuf);
  169. return 0;
  170. }
  171. memcpy(&ubuf[total], buf, nrd);
  172. total += nrd;
  173. }
  174. if (ferror(file)) {
  175. perror(__func__);
  176. free(ubuf);
  177. return 0;
  178. }
  179. *size = total;
  180. return ubuf;
  181. }
  182. static int psf2_read_ucvals(FILE *file, struct psf_font *psf, unsigned int numglyphs)
  183. {
  184. unsigned int size = 0, i;
  185. unsigned char *ubuf = psf2_read_remaining_file(file, &size);
  186. if (!ubuf) { return 0; }
  187. unsigned char *ptr = ubuf, *end = ubuf + size;
  188. for (i = 0; i < numglyphs; ++i) {
  189. struct psf_glyph *glyph = &psf->glyph[i];
  190. int ucval;
  191. while (1) {
  192. if (ptr >= end) {
  193. fprintf(stderr, "%s: unexpected end of file\n", __func__);
  194. return 0;
  195. }
  196. if (*ptr == PSF2_SEPARATOR) { ++ptr; break; }
  197. if (*ptr == PSF2_STARTSEQ) {
  198. ++ptr;
  199. ucval = PSF1_STARTSEQ;
  200. } else {
  201. ucval = mini_utf8_decode((const char**)&ptr);
  202. if (ucval < 0) {
  203. fprintf(stderr, "%s: invalid utf8 char\n", __func__);
  204. return 0;
  205. }
  206. }
  207. psf_glyph_adducval(psf, glyph, (unsigned)ucval & 0x1FFFFF);
  208. }
  209. }
  210. return 1;
  211. }
  212. static struct psf_font *psf2_load_fromfile(FILE* file)
  213. {
  214. unsigned char magic[4];
  215. magic[0] = PSF2_MAGIC0;
  216. if (fread(&magic[1], 1, 3, file) != 3) {
  217. perror(__func__);
  218. return 0;
  219. }
  220. if (magic[0] != PSF2_MAGIC0 || magic[1] != PSF2_MAGIC1 || magic[2] != PSF2_MAGIC2 || magic[3] != PSF2_MAGIC3) {
  221. fprintf(stderr, "%s: invalid magic number", __func__);
  222. return 0;
  223. }
  224. unsigned int version, headersize, flags, length, charsize, width, height;
  225. if (!psf_read_int(file, &version)) { return 0; }
  226. if (!psf_read_int(file, &headersize)) { return 0; }
  227. if (!psf_read_int(file, &flags)) { return 0; }
  228. if (!psf_read_int(file, &length)) { return 0; }
  229. if (!psf_read_int(file, &charsize)) { return 0; }
  230. if (!psf_read_int(file, &height)) { return 0; }
  231. if (!psf_read_int(file, &width)) { return 0; }
  232. struct psf_font *psf = psf_new(2, width, height);
  233. psf->header.psf2.version = version;
  234. psf->header.psf2.headersize = headersize;
  235. psf->header.psf2.flags = flags;
  236. psf->header.psf2.length = length;
  237. psf->header.psf2.charsize = charsize;
  238. psf->header.psf2.width = width;
  239. psf->header.psf2.height = height;
  240. if (!psf_read_glyphs(file, psf, length, charsize)) {
  241. psf_delete(psf);
  242. return 0;
  243. }
  244. if (!psf2_read_ucvals(file, psf, length)) {
  245. psf_delete(psf);
  246. return 0;
  247. }
  248. return psf;
  249. }
  250. struct psf_font *psf_load_fromfile(FILE* file)
  251. {
  252. struct psf_font *res = 0;
  253. int byte = fgetc(file);
  254. if (byte == PSF1_MAGIC0) {
  255. res = psf1_load_fromfile(file);
  256. } else if (byte == PSF2_MAGIC0) {
  257. res = psf2_load_fromfile(file);
  258. } else {
  259. fprintf(stderr, "%s: invalid magic number", __func__);
  260. }
  261. return res;
  262. }
  263. struct psf_font *psf_load(const char* filename)
  264. {
  265. FILE *file = fopen(filename, "rb");
  266. if (!file) {
  267. perror(__func__);
  268. return 0;
  269. }
  270. struct psf_font *res = psf_load_fromfile(file);
  271. fclose(file);
  272. return res;
  273. }
  274. static int psf_write_dummy(FILE *file, unsigned int size)
  275. {
  276. unsigned int i;
  277. for (i = 0; i < size; ++i) {
  278. if (fputc('\0', file) == EOF) { return 0; }
  279. }
  280. return 1;
  281. }
  282. static int psf_write_glyphs(FILE *file, struct psf_font *psf, unsigned int numglyphs, unsigned int glyphsize)
  283. {
  284. unsigned int i;
  285. for (i = 0; i < numglyphs; ++i) {
  286. if (psf->glyph[i].data) {
  287. int nwr = fwrite(psf->glyph[i].data, 1, glyphsize, file);
  288. if (nwr != (int) glyphsize) {
  289. perror(__func__);
  290. return 0;
  291. }
  292. } else {
  293. if (!psf_write_dummy(file, glyphsize)) {
  294. perror(__func__);
  295. return 0;
  296. }
  297. }
  298. }
  299. return 1;
  300. }
  301. static int psf1_write_ucvals(FILE *file, struct psf_font *psf, unsigned int numglyphs)
  302. {
  303. unsigned int i, ucv;
  304. for (i = 0; i < numglyphs; ++i) {
  305. for (ucv = 0; ucv < psf->glyph[i].nucvals; ++ucv) {
  306. if (!psf_write_word(file, psf->glyph[i].ucvals[ucv])) { return 0; }
  307. }
  308. if (!psf_write_word(file, PSF1_SEPARATOR)) { return 0; }
  309. }
  310. return 1;
  311. }
  312. static int psf1_save_tofile(FILE *file, struct psf_font *psf)
  313. {
  314. if (!psf_write_byte(file, psf->header.psf1.magic[0])) { return 0; }
  315. if (!psf_write_byte(file, psf->header.psf1.magic[1])) { return 0; }
  316. if (!psf_write_byte(file, psf->header.psf1.mode)) { return 0; }
  317. if (!psf_write_byte(file, psf->header.psf1.charsize)) { return 0; }
  318. int numglyphs = (psf->header.psf1.mode & PSF1_MODE512) ? 512 : 256;
  319. if (!psf_write_glyphs(file, psf, numglyphs, psf->header.psf1.charsize)) {
  320. return 0;
  321. }
  322. if (psf->header.psf1.mode & (PSF1_MODEHASTAB | PSF1_MODEHASSEQ)) {
  323. if (!psf1_write_ucvals(file, psf, numglyphs)) {
  324. return 0;
  325. }
  326. }
  327. return 1;
  328. }
  329. static int psf2_write_ucvals(FILE *file, struct psf_font *psf, unsigned int numglyphs)
  330. {
  331. char u8buf[8];
  332. unsigned int i, ucv;
  333. for (i = 0; i < numglyphs; ++i) {
  334. for (ucv = 0; ucv < psf->glyph[i].nucvals; ++ucv) {
  335. if (psf->glyph[i].ucvals[ucv] == PSF1_STARTSEQ) {
  336. if (!psf_write_byte(file, PSF2_STARTSEQ)) { return 0; }
  337. } else {
  338. unsigned int len = mini_utf8_encode(psf->glyph[i].ucvals[ucv], u8buf, 8);
  339. if (len <= 0) {
  340. fprintf(stderr, "%s: invalid unicode value\n", __func__);
  341. return 0;
  342. }
  343. if (fwrite(u8buf, 1, len, file) < len) {
  344. perror(__func__);
  345. return 0;
  346. }
  347. }
  348. }
  349. if (!psf_write_byte(file, PSF2_SEPARATOR)) { return 0; }
  350. }
  351. return 1;
  352. }
  353. static int psf2_save_tofile(FILE *file, struct psf_font *psf)
  354. {
  355. int i;
  356. for (i = 0; i < 4; ++i) {
  357. if (!psf_write_byte(file, psf->header.psf2.magic[i])) { return 0; }
  358. }
  359. if (!psf_write_int(file, psf->header.psf2.version)) { return 0; }
  360. if (!psf_write_int(file, psf->header.psf2.headersize)) { return 0; }
  361. if (!psf_write_int(file, psf->header.psf2.flags)) { return 0; }
  362. if (!psf_write_int(file, psf->header.psf2.length)) { return 0; }
  363. if (!psf_write_int(file, psf->header.psf2.charsize)) { return 0; }
  364. if (!psf_write_int(file, psf->header.psf2.height)) { return 0; }
  365. if (!psf_write_int(file, psf->header.psf2.width)) { return 0; }
  366. if (!psf_write_glyphs(file, psf, psf->header.psf2.length, psf->header.psf2.charsize)) {
  367. return 0;
  368. }
  369. if (psf->header.psf2.flags & PSF2_HAS_UNICODE_TABLE) {
  370. if (!psf2_write_ucvals(file, psf, psf->header.psf2.length)) {
  371. return 0;
  372. }
  373. }
  374. return 1;
  375. }
  376. int psf_save_tofile(FILE *file, struct psf_font *psf)
  377. {
  378. int res = 0;
  379. if (psf->version == 1) {
  380. res = psf1_save_tofile(file, psf);
  381. } else {
  382. res = psf2_save_tofile(file, psf);
  383. }
  384. return res;
  385. }
  386. int psf_save(const char *filename, struct psf_font *psf)
  387. {
  388. FILE *file = fopen(filename, "wb");
  389. if (!file) {
  390. perror(__func__);
  391. return 0;
  392. }
  393. int res = psf_save_tofile(file, psf);
  394. fclose(file);
  395. return res;
  396. }
  397. void psf_delete(struct psf_font *psf)
  398. {
  399. if (psf->glyph) {
  400. int i, nglyphs;
  401. if (psf->version == 1) {
  402. nglyphs = (psf->header.psf1.mode & PSF1_MODE512) ? 512 : 256;
  403. } else {
  404. nglyphs = psf->header.psf2.length;
  405. }
  406. for (i = 0; i < nglyphs; ++i) {
  407. if (psf->glyph[i].data) { free(psf->glyph[i].data); }
  408. if (psf->glyph[i].ucvals) { free(psf->glyph[i].ucvals); }
  409. }
  410. free(psf->glyph);
  411. }
  412. free(psf);
  413. }
  414. static int psf_reallocglyphs(struct psf_font *psf, unsigned int num)
  415. {
  416. int alloced = (psf->glyph != 0);
  417. unsigned int ng = alloced ? psf_numglyphs(psf) : 0;
  418. if (psf->version == 1) {
  419. if (num > 512) {
  420. fprintf(stderr, "%s: no more than 512 chars for a version 1 psf font\n", __func__);
  421. return 0;
  422. }
  423. unsigned int nng = num <= 256 ? 256 : 512;
  424. if (nng > ng) {
  425. struct psf_glyph *newglyph = calloc(nng, sizeof(struct psf_glyph));
  426. if (!newglyph) {
  427. perror(__func__);
  428. return 0;
  429. }
  430. if (alloced) {
  431. /* this can only be true if 256 glyphs were allocated and the new size is 512 */
  432. memcpy(newglyph, psf->glyph, 256 * sizeof(struct psf_glyph));
  433. free(psf->glyph);
  434. }
  435. psf->glyph = newglyph;
  436. if (nng == 512) {
  437. psf->header.psf1.mode |= PSF1_MODE512;
  438. }
  439. return 1;
  440. }
  441. } else {
  442. if (num > ng) {
  443. struct psf_glyph *newglyph = calloc(num, sizeof(struct psf_glyph));
  444. if (!newglyph) {
  445. perror(__func__);
  446. return 0;
  447. }
  448. if (alloced) {
  449. memcpy(newglyph, psf->glyph, ng * sizeof(struct psf_glyph));
  450. free(psf->glyph);
  451. }
  452. psf->glyph = newglyph;
  453. psf->header.psf2.length = num;
  454. return 1;
  455. }
  456. }
  457. return 0;
  458. }
  459. struct psf_glyph *psf_getglyph(struct psf_font *psf, unsigned int no)
  460. {
  461. if (no >= psf_numglyphs(psf)) {
  462. return 0;
  463. }
  464. return &psf->glyph[no];
  465. }
  466. struct psf_glyph *psf_addglyph(struct psf_font *psf, unsigned int no)
  467. {
  468. if (no >= psf_numglyphs(psf)) {
  469. if (!psf_reallocglyphs(psf, no + 1)) {
  470. return 0;
  471. }
  472. }
  473. psf_glyph_init(psf, &psf->glyph[no]);
  474. return &psf->glyph[no];
  475. }
  476. int psf_glyph_init(struct psf_font *psf, struct psf_glyph *glyph)
  477. {
  478. if (glyph->data != 0) { free(glyph->data); }
  479. if (glyph->ucvals != 0) { free(glyph->ucvals); }
  480. unsigned int charsize = (psf->version == 1) ? psf->header.psf1.charsize : psf->header.psf2.charsize;
  481. glyph->data = calloc(1, charsize);
  482. glyph->nucvals = 0;
  483. glyph->ucvals = 0;
  484. return 1;
  485. }
  486. int psf_glyph_setpx(struct psf_font *psf, struct psf_glyph *glyph, unsigned int x, unsigned int y, unsigned int val)
  487. {
  488. if (!glyph->data) { return 0; }
  489. unsigned int w = psf_width(psf);
  490. unsigned int h = psf_height(psf);
  491. if (x >= w || y >= h) { return 0; }
  492. unsigned int byte = y * ((w + 7) >> 3) + (x >> 3);
  493. unsigned int mask = 0x80 >> (x & 7);
  494. if (val) {
  495. glyph->data[byte] |= mask;
  496. } else {
  497. glyph->data[byte] &= ~mask;
  498. }
  499. return 1;
  500. }
  501. int psf_glyph_getpx(struct psf_font *psf, struct psf_glyph *glyph, unsigned int x, unsigned int y)
  502. {
  503. if (!glyph->data) { return 0; }
  504. unsigned int w = psf_width(psf);
  505. unsigned int h = psf_height(psf);
  506. if (x >= w || y >= h) { return 0; }
  507. unsigned int byte = y * ((w + 7) >> 3) + (x >> 3);
  508. unsigned int mask = 0x80 >> (x & 7);
  509. return (glyph->data[byte] & mask) == 0;
  510. }
  511. int psf_glyph_adducval(struct psf_font *psf, struct psf_glyph *glyph, unsigned int uni)
  512. {
  513. if (psf->version == 1 && uni > 0xFFFF) {
  514. fprintf(stderr, "%s: unicode value too big for psf1\n", __func__);
  515. return 0;
  516. }
  517. unsigned int newnucvals = glyph->nucvals + 1;
  518. unsigned int *newucvals = calloc(newnucvals, sizeof(unsigned int));
  519. if (!newucvals) {
  520. perror(__func__);
  521. return 0;
  522. }
  523. if (glyph->ucvals) {
  524. memcpy(newucvals, glyph->ucvals, glyph->nucvals * sizeof(unsigned int));
  525. free(glyph->ucvals);
  526. }
  527. glyph->ucvals = newucvals;
  528. glyph->nucvals = newnucvals;
  529. glyph->ucvals[newnucvals - 1] = uni;
  530. if (psf->version == 1) {
  531. psf->header.psf1.mode |= PSF1_MODEHASTAB;
  532. if (uni == PSF1_STARTSEQ) {
  533. psf->header.psf1.mode |= PSF1_MODEHASSEQ;
  534. }
  535. } else {
  536. psf->header.psf2.flags |= PSF2_HAS_UNICODE_TABLE;
  537. }
  538. return 1;
  539. }
  540. unsigned int psf_numglyphs(struct psf_font *psf)
  541. {
  542. if (psf->version == 1) {
  543. return psf->header.psf1.mode & PSF1_MODE512 ? 512 : 256;
  544. } else {
  545. return psf->header.psf2.length;
  546. }
  547. }
  548. unsigned int psf_hasunicodetable(struct psf_font *psf)
  549. {
  550. if (psf->version == 1) {
  551. return (psf->header.psf1.mode & PSF1_MODEHASTAB) != 0;
  552. } else {
  553. return (psf->header.psf2.flags & PSF2_HAS_UNICODE_TABLE) != 0;
  554. }
  555. }