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.
 
 
 

126 lines
3.0 KiB

  1. /* psfid
  2. *
  3. * Prints information about a psf 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. void usage()
  15. {
  16. fputs( "Usage: psfid [-v] [-w] [-h] [-n] [-u] font.psf\n"
  17. " print information about a psf font:\n"
  18. " -v psf version\n"
  19. " -w font width\n"
  20. " -h font height\n"
  21. " -n number of chars in font\n"
  22. " -u presence of unicode translation table in font (1 for yes, 0 for no)\n"
  23. " -l list table of encoded chars\n"
  24. " default if no options are specified is -v -w -h -n -u\n"
  25. ,stderr);
  26. fprintf(stderr, "psftools version %s\n", PSFTOOLS_VERSION);
  27. exit(1);
  28. }
  29. int unic_cmp(const void *a, const void *b)
  30. {
  31. unsigned int uca = *(unsigned int*)a;
  32. unsigned int ucb = *(unsigned int*)b;
  33. return uca < ucb ? -1 : uca > ucb ? 1 : 0;
  34. }
  35. void listunicodechartable(struct psf_font *psf)
  36. {
  37. unsigned int nglyphs = psf_numglyphs(psf);
  38. unsigned int gno, uno, ucnt = 0, nuc = 0;
  39. for (gno = 0; gno < nglyphs; ++gno) {
  40. struct psf_glyph *glyph = psf_getglyph(psf, gno);
  41. nuc += glyph->nucvals ? glyph->nucvals : 1;
  42. }
  43. unsigned int ucvals[nuc];
  44. for (gno = 0; gno < nglyphs; ++gno) {
  45. struct psf_glyph *glyph = psf_getglyph(psf, gno);
  46. if (glyph->nucvals == 0) {
  47. ucvals[ucnt++] = gno;
  48. } else {
  49. for (uno = 0; uno < glyph->nucvals; ++uno) {
  50. ucvals[ucnt++] = glyph->ucvals[uno];
  51. }
  52. }
  53. }
  54. qsort(ucvals, nuc, sizeof(int), unic_cmp);
  55. printf("%d chars encoded:\n", nuc);
  56. for (uno = 0; uno < nuc; ++uno) {
  57. printf("U+%05x\n", ucvals[uno]);
  58. }
  59. }
  60. int main(int argc, char **argv)
  61. {
  62. char options[8] = {0};
  63. int optc = 0, arg = 0;
  64. const char *psfn = 0;
  65. if (argc < 2 || argc > 7) {
  66. usage();
  67. }
  68. for (arg = 1; arg < argc; ++arg) {
  69. const char* opt = argv[arg];
  70. if (*opt == '-') {
  71. switch (opt[1]) {
  72. case 'v': case 'w': case 'h': case 'n': case 'u': case 'l':
  73. if (opt[2] == '\0' && strchr(options, opt[1]) == 0) {
  74. options[optc++] = opt[1];
  75. break;
  76. }
  77. /* fallthru on error */
  78. default:
  79. fprintf(stderr, "psfid: unknown option: %s\n", opt);
  80. usage();
  81. }
  82. } else if (arg + 1 == argc) {
  83. psfn = argv[arg];
  84. } else {
  85. fprintf(stderr, "psfid: psf file name must be the last argument.\n");
  86. usage();
  87. }
  88. }
  89. if (!psfn) {
  90. fprintf(stderr, "psfid: psf file missing.\n");
  91. usage();
  92. }
  93. if (!options[0]) {
  94. strcpy(options, "vwhnu");
  95. }
  96. struct psf_font *psf = psf_load(psfn);
  97. if (!psf) {
  98. exit(1);
  99. }
  100. const char *ptr = options;
  101. while (*ptr) {
  102. switch (*ptr) {
  103. case 'v': printf(" v:%d", psf->version); break;
  104. case 'w': printf(" w:%d", psf_width(psf)); break;
  105. case 'h': printf(" h:%d", psf_height(psf)); break;
  106. case 'n': printf(" n:%d", psf_numglyphs(psf)); break;
  107. case 'u': printf(" u:%d", psf_hasunicodetable(psf)); break;
  108. case 'l': listunicodechartable(psf); break;
  109. }
  110. ++ptr;
  111. }
  112. exit(0);
  113. }