-
-
Notifications
You must be signed in to change notification settings - Fork 288
/
stroke_fonts.c
194 lines (154 loc) · 5.04 KB
/
stroke_fonts.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
/****************************************************************************
*
* MODULE: g.mkfontcap
* AUTHOR(S): Paul Kelly
* PURPOSE: Generates the font configuration file by scanning various
* directories for GRASS stroke and Freetype-compatible fonts.
*
* COPYRIGHT: (C) 2007 by the GRASS Development Team
*
* This program is free software under the GNU General Public
* License (>=v2). Read the file COPYING that comes with GRASS
* for details.
*
*****************************************************************************/
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <grass/gis.h>
#include <grass/fontcap.h>
#include "local_proto.h"
struct font_desc
{
char *filename; /**< Filename in fonts directory */
char *description;/**< Descriptive name of font contained in this file */
};
static struct font_desc *font_descriptions = NULL;
static int num_descriptions = 0;
static int load_font_descriptions(const char *);
static void free_font_descriptions(void);
static const char *get_desc(const char *);
/**
* \brief Find Stroke fonts and store them in a global GFONT_CAP struct
*
* The directory $GISBASE/fonts is listed to find all stroke fonts (i.e.
* files with a .hmp extension).
* Information on each font is stored in the global GFONT_CAP struct,
* fontcap, to be used by the main program.
**/
void find_stroke_fonts(void)
{
char *dirpath, *fonttable;
char **dirlisting;
int numfiles, i;
G_asprintf(&dirpath, "%s/fonts", G_gisbase());
dirlisting = G_ls2(dirpath, &numfiles);
G_asprintf(&fonttable, "%s/fonts.table", dirpath);
if (access(fonttable, R_OK) == 0)
load_font_descriptions(fonttable);
for (i = 0; i < numfiles; i++) {
if (!strstr(dirlisting[i], ".hmp"))
continue;
if (totalfonts >= maxfonts) {
maxfonts += 20;
fontcap = G_realloc(fontcap, maxfonts * sizeof(struct GFONT_CAP));
}
/* Path */
G_asprintf(&fontcap[totalfonts].path, "%s%c%s", dirpath,
HOST_DIRSEP, dirlisting[i]);
G_convert_dirseps_to_host(fontcap[totalfonts].path);
/* Description & Name */
fontcap[totalfonts].longname = G_store(get_desc(dirlisting[i]));
*(strstr(dirlisting[i], ".hmp")) = '\0';
fontcap[totalfonts].name = G_store(dirlisting[i]);
/* Font Type */
fontcap[totalfonts].type = GFONT_STROKE;
/* These two probably not relevant */
fontcap[totalfonts].index = 0;
fontcap[totalfonts].encoding = G_store("utf-8");
totalfonts++;
G_free(dirlisting[i]);
}
G_free(dirlisting);
if (font_descriptions)
free_font_descriptions();
return;
}
/**
* \brief Loads description file for stroke fonts into memory
*
* Parses the font description file and loads an array of filenames
* and corresponding descriptions pointed at by the static variable
* font_descriptions. After calling, num_descriptions will contain
* the number of font descriptions that were loaded.
*
* \param descfile Filename to be loaded
*
* \return 1 if at least one font description was loaded; 0 otherwise
**/
static int load_font_descriptions(const char *descfile)
{
size_t memsize = 0;
FILE *fp;
char buff[500];
fp = fopen(descfile, "r");
if (fp == NULL) {
G_warning("Unable to open font description file %s for reading: %s",
descfile, strerror(errno));
return 0;
}
while (G_getl2(buff, sizeof(buff), fp)) {
char name[100], description[256];
if (buff[0] == '#')
continue;
if (sscanf(buff, "%99[^|]|%255[^\n]", name, description) != 2)
continue;
if (num_descriptions >= memsize) {
memsize += 20;
font_descriptions = G_realloc(font_descriptions,
memsize * sizeof(struct font_desc));
}
font_descriptions[num_descriptions].filename = G_store(name);
font_descriptions[num_descriptions].description =
G_store(description);
num_descriptions++;
}
fclose(fp);
return (num_descriptions > 0);
}
/**
* \brief Returns the descriptive name corresponding to a stroke font
*
* Searches through the static font_descriptions name for a descriptive
* name matching the filename passed to the function. If a match is found,
* the descriptive name is returned; otherwise the filename that was
* originally passed is returned.
*
* \param filename Filename of stroke font
*
* \return Const string containing descriptive name for the font
**/
static const char *get_desc(const char *filename)
{
int i;
for (i = 0; i < num_descriptions; i++)
if (G_strcasecmp(filename, font_descriptions[i].filename) == 0)
return font_descriptions[i].description;
/* If there was no font descriptions file, or the filename wasn't found
* in it, we'll end up here and simply return the filename for the
* description */
return filename;
}
/**
* \brief Frees the memory used by the table of font descriptive names
**/
static void free_font_descriptions(void)
{
int i;
for (i = 0; i < num_descriptions; i++) {
G_free(font_descriptions[i].filename);
G_free(font_descriptions[i].description);
}
return;
}