GRASS GIS 8 Programmer's Manual  8.5.0dev(2024)-d6dec75dd4
font2.c
Go to the documentation of this file.
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 
11 struct glyph {
12  unsigned int offset : 20;
13  unsigned int count : 12;
14 };
15 
16 static struct glyph *glyphs;
17 static int glyphs_alloc;
18 
19 static unsigned char *xcoords, *ycoords;
20 static int coords_offset;
21 static int coords_alloc;
22 
23 static int fontmap[1024];
24 static int num_chars;
25 
26 static char current_font[16];
27 static int font_loaded;
28 
29 static struct glyph *glyph_slot(int idx)
30 {
31  if (glyphs_alloc <= idx) {
32  int new_alloc = idx + ((glyphs_alloc > 0) ? 1000 : 4000);
33 
34  glyphs = G_realloc(glyphs, new_alloc * sizeof(struct glyph));
35  memset(&glyphs[glyphs_alloc], 0,
36  (new_alloc - glyphs_alloc) * sizeof(struct glyph));
37  glyphs_alloc = new_alloc;
38  }
39 
40  return &glyphs[idx];
41 }
42 
43 static int coord_slots(int count)
44 {
45  int n;
46 
47  if (coords_alloc < coords_offset + count) {
48  coords_alloc =
49  coords_offset + count + ((coords_alloc > 0) ? 10000 : 60000);
50  xcoords = G_realloc(xcoords, coords_alloc);
51  ycoords = G_realloc(ycoords, coords_alloc);
52  }
53 
54  n = coords_offset;
55  coords_offset += count;
56 
57  return n;
58 }
59 
60 static void read_hersh(const char *filename)
61 {
62  FILE *fp = fopen(filename, "r");
63 
64  if (!fp)
65  return;
66 
67  while (!feof(fp)) {
68  char buf[8];
69  struct glyph *glyph;
70  int coords;
71  unsigned int i, idx, count;
72  int c;
73 
74  switch (c = fgetc(fp)) {
75  case '\r':
76  fgetc(fp);
77  continue;
78  case '\n':
79  continue;
80  default:
81  ungetc(c, fp);
82  break;
83  }
84 
85  if (fread(buf, 1, 5, fp) != 5)
86  break;
87 
88  buf[5] = 0;
89  idx = atoi(buf);
90 
91  if (fread(buf, 1, 3, fp) != 3)
92  break;
93 
94  buf[3] = 0;
95  count = atoi(buf);
96 
97  glyph = glyph_slot(idx);
98  coords = coord_slots(count);
99 
100  glyph->offset = coords;
101  glyph->count = count;
102 
103  for (i = 0; i < count; i++) {
104  if ((i + 4) % 36 == 0) {
105  /* skip newlines? */
106  if (fgetc(fp) == '\r')
107  fgetc(fp);
108  }
109 
110  xcoords[coords + i] = fgetc(fp);
111  ycoords[coords + i] = fgetc(fp);
112  }
113 
114  if (fgetc(fp) == '\r')
115  fgetc(fp);
116  }
117 
118  fclose(fp);
119 }
120 
121 static void load_glyphs(void)
122 {
123  int i;
124 
125  if (glyphs)
126  return;
127 
128  for (i = 1; i <= 4; i++) {
129  char buf[GPATH_MAX];
130 
131  sprintf(buf, "%s/fonts/hersh.oc%d", G_gisbase(), i);
132  read_hersh(buf);
133  }
134 }
135 
136 static void read_fontmap(const char *name)
137 {
138  char buf[GPATH_MAX];
139  FILE *fp;
140 
141  num_chars = 0;
142  memset(fontmap, 0, sizeof(fontmap));
143 
144  sprintf(buf, "%s/fonts/%s.hmp", G_gisbase(), name);
145 
146  fp = fopen(buf, "r");
147  if (!fp) {
148  G_warning("Unable to open font map '%s': %s. "
149  "Try running 'g.mkfontcap --overwrite'",
150  buf, strerror(errno));
151  return;
152  }
153 
154  while (fscanf(fp, "%s", buf) == 1) {
155  int a, b;
156 
157  if (sscanf(buf, "%d-%d", &a, &b) == 2)
158  while (a <= b)
159  fontmap[num_chars++] = a++;
160  else if (sscanf(buf, "%d", &a) == 1)
161  fontmap[num_chars++] = a;
162  }
163 
164  fclose(fp);
165 }
166 
167 static void load_font(void)
168 {
169  if (font_loaded)
170  return;
171 
172  if (!glyphs)
173  load_glyphs();
174 
175  read_fontmap(current_font);
176 
177  font_loaded = 1;
178 }
179 
180 int font_init(const char *name)
181 {
182  if (strcmp(name, current_font) == 0)
183  return 0;
184 
185  strcpy(current_font, name);
186  font_loaded = 0;
187 
188  return 0;
189 }
190 
191 int get_char_vects(unsigned char achar, int *n, unsigned char **X,
192  unsigned char **Y)
193 {
194  struct glyph *glyph;
195  int i;
196 
197  if (!font_loaded)
198  load_font();
199 
200  i = (int)achar - 040; /* translate achar to char# in font index */
201  if (i <= 0 || i >= num_chars) {
202  *n = 0;
203  return 1;
204  }
205 
206  glyph = &glyphs[fontmap[i]];
207 
208  *n = glyph->count;
209  *X = &xcoords[glyph->offset];
210  *Y = &ycoords[glyph->offset];
211 
212  return 0;
213 }
#define G_realloc(p, n)
Definition: defs/gis.h:96
void G_warning(const char *,...) __attribute__((format(printf
const char * G_gisbase(void)
Get full path name of the top level module directory.
Definition: gisbase.c:39
int get_char_vects(unsigned char achar, int *n, unsigned char **X, unsigned char **Y)
Definition: font2.c:191
int font_init(const char *name)
Definition: font2.c:180
#define GPATH_MAX
Definition: gis.h:194
int count
const char * name
Definition: named_colr.c:6
#define X
Definition: ogsf.h:140
#define Y
Definition: ogsf.h:141
#define strcpy
Definition: parson.c:62
double b
Definition: r_raster.c:39