GRASS Programmer's Manual  6.4.2(2012)
font2.c
Go to the documentation of this file.
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 }
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines