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.
 
 
 

110 lines
2.5 KiB

  1. /* psfd
  2. *
  3. * Decompiles a psf file into a text file.
  4. * part of a simple textfile based psf font editor suite.
  5. *
  6. * Gunnar Zötl <gz@tset.de> 2016
  7. * Released under the terms of the MIT license. See file LICENSE for details.
  8. */
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #include "psf.h"
  13. #include "psftools_version.h"
  14. static int psfd_print_header(struct psf_font *psf, FILE *out)
  15. {
  16. if (!psf) { return 0; }
  17. fprintf(out, "@psf%d\n", psf->version);
  18. if (psf->version == 1) {
  19. fprintf(out, "Width: %d\n", 8);
  20. fprintf(out, "Height: %d\n", psf->header.psf1.charsize);
  21. } else {
  22. fprintf(out, "Width: %d\n", psf->header.psf2.width);
  23. fprintf(out, "Height: %d\n", psf->header.psf2.height);
  24. }
  25. fputs("Pixel: #\n", out);
  26. return 1;
  27. }
  28. static int psfd_print_glyph(struct psf_font *psf, unsigned int n, FILE *out)
  29. {
  30. struct psf_glyph *glyph = psf_getglyph(psf, n);
  31. if (!glyph) { return 0; }
  32. unsigned int x, y, i;
  33. int hasseq = 0, inseq = 0;
  34. fprintf(out, "@%d", n);
  35. if (glyph->nucvals > 0) {
  36. fputc(':', out);
  37. for (i = 0; i < glyph->nucvals; ++i) {
  38. if (glyph->ucvals[i] == 0xFFFE) {
  39. hasseq = 0;
  40. inseq = 0;
  41. fputc(',', out);
  42. } else {
  43. int delim = ' ';
  44. if (hasseq && (inseq == 0)) {
  45. delim = ';';
  46. }
  47. fprintf(out, "%cU+%04x", delim, glyph->ucvals[i]);
  48. ++inseq;
  49. }
  50. }
  51. }
  52. fputc('\n', out);
  53. for (y = 0; y < psf_height(psf); ++y) {
  54. for (x = 0; x < psf_width(psf); ++x) {
  55. fputc(psf_glyph_getpx(psf, glyph, x, y) ? '.' : '#', out);
  56. }
  57. fputc('\n', out);
  58. }
  59. return 1;
  60. }
  61. static int psfd_print_glyphs(struct psf_font *psf, FILE *out)
  62. {
  63. unsigned int i;
  64. for (i = 0; i < psf_numglyphs(psf); ++i) {
  65. if (!psfd_print_glyph(psf, i, out)) {
  66. return 0;
  67. }
  68. }
  69. return 1;
  70. }
  71. int main(int argc, char **argv)
  72. {
  73. if (argc < 1 || argc > 3 || (argv[1] && (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")))) {
  74. fprintf(stderr, "%s [file.psf [file.txt]]\n", argv[0]);
  75. fprintf(stderr, "psftools version %s\n", PSFTOOLS_VERSION);
  76. exit(1);
  77. }
  78. const char* infile = argc >= 2 ? argv[1] : 0;
  79. const char* outfile = argc == 3 ? argv[2] : 0;
  80. struct psf_font *psf = (infile && strcmp(infile, "-") != 0) ? psf_load(infile) : psf_load_fromfile(stdin);
  81. if (!psf) {
  82. exit(1);
  83. }
  84. FILE *out = outfile ? fopen(outfile, "w") : stdout;
  85. if (!out) {
  86. perror("psfd: could not open output file");
  87. psf_delete(psf);
  88. exit(1);
  89. }
  90. if (!psfd_print_header(psf, out)) {
  91. exit(1);
  92. }
  93. if (!psfd_print_glyphs(psf, out)) {
  94. exit(1);
  95. }
  96. if (out != stdout) { fclose(out); }
  97. psf_delete(psf);
  98. exit(0);
  99. }