GRASS Programmer's Manual
6.4.2(2012)
|
00001 #include <stdio.h> 00002 #include <stdlib.h> 00003 #include <string.h> 00004 #include <unistd.h> 00005 #include <errno.h> 00006 #include <sys/types.h> 00007 #include <sys/stat.h> 00008 #include <fcntl.h> 00009 #include <grass/gis.h> 00010 00011 struct glyph 00012 { 00013 unsigned int offset:20; 00014 unsigned int count:12; 00015 }; 00016 00017 static struct glyph *glyphs; 00018 static int glyphs_alloc; 00019 00020 static unsigned char *xcoords, *ycoords; 00021 static int coords_offset; 00022 static int coords_alloc; 00023 00024 static int fontmap[1024]; 00025 static int num_chars; 00026 00027 static char current_font[16]; 00028 static int font_loaded; 00029 00030 static struct glyph *glyph_slot(int idx) 00031 { 00032 if (glyphs_alloc <= idx) { 00033 int new_alloc = idx + ((glyphs_alloc > 0) ? 1000 : 4000); 00034 00035 glyphs = G_realloc(glyphs, new_alloc * sizeof(struct glyph)); 00036 memset(&glyphs[glyphs_alloc], 0, 00037 (new_alloc - glyphs_alloc) * sizeof(struct glyph)); 00038 glyphs_alloc = new_alloc; 00039 } 00040 00041 return &glyphs[idx]; 00042 } 00043 00044 static int coord_slots(int count) 00045 { 00046 int n; 00047 00048 if (coords_alloc < coords_offset + count) { 00049 coords_alloc = 00050 coords_offset + count + ((coords_alloc > 0) ? 10000 : 60000); 00051 xcoords = G_realloc(xcoords, coords_alloc); 00052 ycoords = G_realloc(ycoords, coords_alloc); 00053 } 00054 00055 n = coords_offset; 00056 coords_offset += count; 00057 00058 return n; 00059 } 00060 00061 static void read_hersh(const char *filename) 00062 { 00063 FILE *fp = fopen(filename, "r"); 00064 00065 if (!fp) 00066 return; 00067 00068 while (!feof(fp)) { 00069 char buf[8]; 00070 struct glyph *glyph; 00071 int coords; 00072 unsigned int idx, count; 00073 int c, i; 00074 00075 switch (c = fgetc(fp)) { 00076 case '\r': 00077 fgetc(fp); 00078 continue; 00079 case '\n': 00080 continue; 00081 default: 00082 ungetc(c, fp); 00083 break; 00084 } 00085 00086 if (fread(buf, 1, 5, fp) != 5) 00087 break; 00088 00089 buf[5] = 0; 00090 idx = atoi(buf); 00091 00092 if (fread(buf, 1, 3, fp) != 3) 00093 break; 00094 00095 buf[3] = 0; 00096 count = atoi(buf); 00097 00098 glyph = glyph_slot(idx); 00099 coords = coord_slots(count); 00100 00101 glyph->offset = coords; 00102 glyph->count = count; 00103 00104 for (i = 0; i < count; i++) { 00105 if ((i + 4) % 36 == 0) { 00106 /* skip newlines? */ 00107 if (fgetc(fp) == '\r') 00108 fgetc(fp); 00109 } 00110 00111 xcoords[coords + i] = fgetc(fp); 00112 ycoords[coords + i] = fgetc(fp); 00113 } 00114 00115 if (fgetc(fp) == '\r') 00116 fgetc(fp); 00117 } 00118 00119 fclose(fp); 00120 } 00121 00122 static void load_glyphs(void) 00123 { 00124 int i; 00125 00126 if (glyphs) 00127 return; 00128 00129 for (i = 1; i <= 4; i++) { 00130 char buf[GPATH_MAX]; 00131 00132 sprintf(buf, "%s/fonts/hersh.oc%d", G_gisbase(), i); 00133 read_hersh(buf); 00134 } 00135 } 00136 00137 static void read_fontmap(const char *name) 00138 { 00139 char buf[GPATH_MAX]; 00140 FILE *fp; 00141 00142 num_chars = 0; 00143 memset(fontmap, 0, sizeof(fontmap)); 00144 00145 sprintf(buf, "%s/fonts/%s.hmp", G_gisbase(), name); 00146 00147 fp = fopen(buf, "r"); 00148 if (!fp) { 00149 G_warning("Unable to open font map '%s': %s. " 00150 "Try running 'g.mkfontcap -o'", buf, strerror(errno)); 00151 return; 00152 } 00153 00154 while (fscanf(fp, "%s", buf) == 1) { 00155 int a, b; 00156 00157 if (sscanf(buf, "%d-%d", &a, &b) == 2) 00158 while (a <= b) 00159 fontmap[num_chars++] = a++; 00160 else if (sscanf(buf, "%d", &a) == 1) 00161 fontmap[num_chars++] = a; 00162 } 00163 00164 fclose(fp); 00165 } 00166 00167 static void load_font(void) 00168 { 00169 if (font_loaded) 00170 return; 00171 00172 if (!glyphs) 00173 load_glyphs(); 00174 00175 read_fontmap(current_font); 00176 00177 font_loaded = 1; 00178 } 00179 00180 int font_init(const char *name) 00181 { 00182 if (strcmp(name, current_font) == 0) 00183 return 0; 00184 00185 strcpy(current_font, name); 00186 font_loaded = 0; 00187 00188 return 0; 00189 } 00190 00191 int get_char_vects(unsigned char achar, 00192 int *n, unsigned char **X, unsigned char **Y) 00193 { 00194 struct glyph *glyph; 00195 int i; 00196 00197 if (!font_loaded) 00198 load_font(); 00199 00200 i = (int)achar - 040; /* translate achar to char# in font index */ 00201 if (i <= 0 || i >= num_chars) { 00202 *n = 0; 00203 return 1; 00204 } 00205 00206 glyph = &glyphs[fontmap[i]]; 00207 00208 *n = glyph->count; 00209 *X = &xcoords[glyph->offset]; 00210 *Y = &ycoords[glyph->offset]; 00211 00212 return 0; 00213 }