font2.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <unistd.h>
  5. #include <errno.h>
  6. #include <sys/types.h>
  7. #include <sys/stat.h>
  8. #include <fcntl.h>
  9. #include <grass/gis.h>
  10. struct glyph
  11. {
  12. unsigned int offset:20;
  13. unsigned int count:12;
  14. };
  15. static struct glyph *glyphs;
  16. static int glyphs_alloc;
  17. static unsigned char *xcoords, *ycoords;
  18. static int coords_offset;
  19. static int coords_alloc;
  20. static int fontmap[1024];
  21. static int num_chars;
  22. static char current_font[16];
  23. static int font_loaded;
  24. static struct glyph *glyph_slot(int idx)
  25. {
  26. if (glyphs_alloc <= idx) {
  27. int new_alloc = idx + ((glyphs_alloc > 0) ? 1000 : 4000);
  28. glyphs = G_realloc(glyphs, new_alloc * sizeof(struct glyph));
  29. memset(&glyphs[glyphs_alloc], 0,
  30. (new_alloc - glyphs_alloc) * sizeof(struct glyph));
  31. glyphs_alloc = new_alloc;
  32. }
  33. return &glyphs[idx];
  34. }
  35. static int coord_slots(int count)
  36. {
  37. int n;
  38. if (coords_alloc < coords_offset + count) {
  39. coords_alloc =
  40. coords_offset + count + ((coords_alloc > 0) ? 10000 : 60000);
  41. xcoords = G_realloc(xcoords, coords_alloc);
  42. ycoords = G_realloc(ycoords, coords_alloc);
  43. }
  44. n = coords_offset;
  45. coords_offset += count;
  46. return n;
  47. }
  48. static void read_hersh(const char *filename)
  49. {
  50. FILE *fp = fopen(filename, "r");
  51. if (!fp)
  52. return;
  53. while (!feof(fp)) {
  54. char buf[8];
  55. struct glyph *glyph;
  56. int coords;
  57. unsigned int idx, count;
  58. int c, i;
  59. switch (c = fgetc(fp)) {
  60. case '\r':
  61. fgetc(fp);
  62. continue;
  63. case '\n':
  64. continue;
  65. default:
  66. ungetc(c, fp);
  67. break;
  68. }
  69. if (fread(buf, 1, 5, fp) != 5)
  70. break;
  71. buf[5] = 0;
  72. idx = atoi(buf);
  73. if (fread(buf, 1, 3, fp) != 3)
  74. break;
  75. buf[3] = 0;
  76. count = atoi(buf);
  77. glyph = glyph_slot(idx);
  78. coords = coord_slots(count);
  79. glyph->offset = coords;
  80. glyph->count = count;
  81. for (i = 0; i < count; i++) {
  82. if ((i + 4) % 36 == 0) {
  83. /* skip newlines? */
  84. if (fgetc(fp) == '\r')
  85. fgetc(fp);
  86. }
  87. xcoords[coords + i] = fgetc(fp);
  88. ycoords[coords + i] = fgetc(fp);
  89. }
  90. if (fgetc(fp) == '\r')
  91. fgetc(fp);
  92. }
  93. fclose(fp);
  94. }
  95. static void load_glyphs(void)
  96. {
  97. int i;
  98. if (glyphs)
  99. return;
  100. for (i = 1; i <= 4; i++) {
  101. char buf[GPATH_MAX];
  102. sprintf(buf, "%s/fonts/hersh.oc%d", G_gisbase(), i);
  103. read_hersh(buf);
  104. }
  105. }
  106. static void read_fontmap(const char *name)
  107. {
  108. char buf[GPATH_MAX];
  109. FILE *fp;
  110. num_chars = 0;
  111. memset(fontmap, 0, sizeof(fontmap));
  112. sprintf(buf, "%s/fonts/%s.hmp", G_gisbase(), name);
  113. fp = fopen(buf, "r");
  114. if (!fp) {
  115. G_warning("Unable to open font map '%s': %s. "
  116. "Try running 'g.mkfontcap -o'", buf, strerror(errno));
  117. return;
  118. }
  119. while (fscanf(fp, "%s", buf) == 1) {
  120. int a, b;
  121. if (sscanf(buf, "%d-%d", &a, &b) == 2)
  122. while (a <= b)
  123. fontmap[num_chars++] = a++;
  124. else if (sscanf(buf, "%d", &a) == 1)
  125. fontmap[num_chars++] = a;
  126. }
  127. fclose(fp);
  128. }
  129. static void load_font(void)
  130. {
  131. if (font_loaded)
  132. return;
  133. if (!glyphs)
  134. load_glyphs();
  135. read_fontmap(current_font);
  136. font_loaded = 1;
  137. }
  138. int font_init(const char *name)
  139. {
  140. if (strcmp(name, current_font) == 0)
  141. return 0;
  142. strcpy(current_font, name);
  143. font_loaded = 0;
  144. return 0;
  145. }
  146. int get_char_vects(unsigned char achar,
  147. int *n, unsigned char **X, unsigned char **Y)
  148. {
  149. struct glyph *glyph;
  150. int i;
  151. if (!font_loaded)
  152. load_font();
  153. i = (int)achar - 040; /* translate achar to char# in font index */
  154. if (i <= 0 || i >= num_chars) {
  155. *n = 0;
  156. return 1;
  157. }
  158. glyph = &glyphs[fontmap[i]];
  159. *n = glyph->count;
  160. *X = &xcoords[glyph->offset];
  161. *Y = &ycoords[glyph->offset];
  162. return 0;
  163. }