GRASS GIS 7 Programmer's Manual  7.9.dev(2021)-e5379bbd7
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 {
13  unsigned int offset:20;
14  unsigned int count:12;
15 };
16 
17 static struct glyph *glyphs;
18 static int glyphs_alloc;
19 
20 static unsigned char *xcoords, *ycoords;
21 static int coords_offset;
22 static int coords_alloc;
23 
24 static int fontmap[1024];
25 static int num_chars;
26 
27 static char current_font[16];
28 static int font_loaded;
29 
30 static struct glyph *glyph_slot(int idx)
31 {
32  if (glyphs_alloc <= idx) {
33  int new_alloc = idx + ((glyphs_alloc > 0) ? 1000 : 4000);
34 
35  glyphs = G_realloc(glyphs, new_alloc * sizeof(struct glyph));
36  memset(&glyphs[glyphs_alloc], 0,
37  (new_alloc - glyphs_alloc) * sizeof(struct glyph));
38  glyphs_alloc = new_alloc;
39  }
40 
41  return &glyphs[idx];
42 }
43 
44 static int coord_slots(int count)
45 {
46  int n;
47 
48  if (coords_alloc < coords_offset + count) {
49  coords_alloc =
50  coords_offset + count + ((coords_alloc > 0) ? 10000 : 60000);
51  xcoords = G_realloc(xcoords, coords_alloc);
52  ycoords = G_realloc(ycoords, coords_alloc);
53  }
54 
55  n = coords_offset;
56  coords_offset += count;
57 
58  return n;
59 }
60 
61 static void read_hersh(const char *filename)
62 {
63  FILE *fp = fopen(filename, "r");
64 
65  if (!fp)
66  return;
67 
68  while (!feof(fp)) {
69  char buf[8];
70  struct glyph *glyph;
71  int coords;
72  unsigned int idx, count;
73  int c, i;
74 
75  switch (c = fgetc(fp)) {
76  case '\r':
77  fgetc(fp);
78  continue;
79  case '\n':
80  continue;
81  default:
82  ungetc(c, fp);
83  break;
84  }
85 
86  if (fread(buf, 1, 5, fp) != 5)
87  break;
88 
89  buf[5] = 0;
90  idx = atoi(buf);
91 
92  if (fread(buf, 1, 3, fp) != 3)
93  break;
94 
95  buf[3] = 0;
96  count = atoi(buf);
97 
98  glyph = glyph_slot(idx);
99  coords = coord_slots(count);
100 
101  glyph->offset = coords;
102  glyph->count = count;
103 
104  for (i = 0; i < count; i++) {
105  if ((i + 4) % 36 == 0) {
106  /* skip newlines? */
107  if (fgetc(fp) == '\r')
108  fgetc(fp);
109  }
110 
111  xcoords[coords + i] = fgetc(fp);
112  ycoords[coords + i] = fgetc(fp);
113  }
114 
115  if (fgetc(fp) == '\r')
116  fgetc(fp);
117  }
118 
119  fclose(fp);
120 }
121 
122 static void load_glyphs(void)
123 {
124  int i;
125 
126  if (glyphs)
127  return;
128 
129  for (i = 1; i <= 4; i++) {
130  char buf[GPATH_MAX];
131 
132  sprintf(buf, "%s/fonts/hersh.oc%d", G_gisbase(), i);
133  read_hersh(buf);
134  }
135 }
136 
137 static void read_fontmap(const char *name)
138 {
139  char buf[GPATH_MAX];
140  FILE *fp;
141 
142  num_chars = 0;
143  memset(fontmap, 0, sizeof(fontmap));
144 
145  sprintf(buf, "%s/fonts/%s.hmp", G_gisbase(), name);
146 
147  fp = fopen(buf, "r");
148  if (!fp) {
149  G_warning("Unable to open font map '%s': %s. "
150  "Try running 'g.mkfontcap -o'", 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,
192  int *n, unsigned char **X, 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 }
int font_init(const char *name)
Definition: font2.c:180
int count
double b
Definition: r_raster.c:39
int get_char_vects(unsigned char achar, int *n, unsigned char **X, unsigned char **Y)
Definition: font2.c:191
#define GPATH_MAX
Definition: gis.h:170
#define Y
Definition: ogsf.h:138
const char * G_gisbase(void)
Get full path name of the top level module directory.
Definition: gisbase.c:41
void G_warning(const char *,...) __attribute__((format(printf
#define G_realloc(p, n)
Definition: defs/gis.h:114
#define X
Definition: ogsf.h:137
const char * name
Definition: named_colr.c:7