GRASS 8 Programmer's Manual 8.6.0dev(2026)-1d1e47ad9d
Loading...
Searching...
No Matches
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#include <grass/glocale.h>
11
12struct glyph {
13 unsigned int offset : 20;
14 unsigned int count : 12;
15};
16
17static struct glyph *glyphs;
18static int glyphs_alloc;
19
20static unsigned char *xcoords, *ycoords;
21static int coords_offset;
22static int coords_alloc;
23
24static int fontmap[1024];
25static int num_chars;
26
27static char current_font[16];
28static int font_loaded;
29
30static 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
44static 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
61static 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 i, idx, count;
73 int c;
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
122static 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 snprintf(buf, sizeof(buf), "%s/fonts/hersh.oc%d", G_gisbase(), i);
133 read_hersh(buf);
134 }
135}
136
137static 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 snprintf(buf, sizeof(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 --overwrite'",
151 buf, strerror(errno));
152 return;
153 }
154
155 while (fscanf(fp, "%s", buf) == 1) {
156 int a, b;
157
158 if (sscanf(buf, "%d-%d", &a, &b) == 2)
159 while (a <= b)
160 fontmap[num_chars++] = a++;
161 else if (sscanf(buf, "%d", &a) == 1)
162 fontmap[num_chars++] = a;
163 }
164
165 fclose(fp);
166}
167
168static void load_font(void)
169{
170 if (font_loaded)
171 return;
172
173 if (!glyphs)
174 load_glyphs();
175
176 read_fontmap(current_font);
177
178 font_loaded = 1;
179}
180
181int font_init(const char *name)
182{
183 if (strcmp(name, current_font) == 0)
184 return 0;
185
186 if (G_strlcpy(current_font, name, sizeof(current_font)) >=
187 sizeof(current_font)) {
188 G_fatal_error(_("Font name <%s> is too long"), name);
189 }
190 font_loaded = 0;
191
192 return 0;
193}
194
195int get_char_vects(unsigned char achar, int *n, unsigned char **X,
196 unsigned char **Y)
197{
198 struct glyph *glyph;
199 int i;
200
201 if (!font_loaded)
202 load_font();
203
204 i = (int)achar - 040; /* translate achar to char# in font index */
205 if (i <= 0 || i >= num_chars) {
206 *n = 0;
207 return 1;
208 }
209
210 glyph = &glyphs[fontmap[i]];
211
212 *n = glyph->count;
213 *X = &xcoords[glyph->offset];
214 *Y = &ycoords[glyph->offset];
215
216 return 0;
217}
#define G_realloc(p, n)
Definition defs/gis.h:141
void void void void G_fatal_error(const char *,...) __attribute__((format(printf
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
size_t G_strlcpy(char *, const char *, size_t)
Safe string copy function.
Definition strlcpy.c:52
Header file for msvc/fcntl.c.
int get_char_vects(unsigned char achar, int *n, unsigned char **X, unsigned char **Y)
Definition font2.c:195
int font_init(const char *name)
Definition font2.c:181
#define GPATH_MAX
Definition gis.h:199
#define _(str)
Definition glocale.h:10
int count
const char * name
Definition named_colr.c:6
#define X
Definition ogsf.h:140
#define Y
Definition ogsf.h:141
double b
Definition r_raster.c:39