Changeset 1106 for toilet/trunk/src/figlet.c
- Timestamp:
- Sep 26, 2006, 3:57:01 PM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
toilet/trunk/src/figlet.c
r1102 r1106 21 21 # include <inttypes.h> 22 22 #endif 23 #include <stdio.h> 24 #include <stdlib.h> 25 #include <string.h> 23 26 #include <cucul.h> 24 27 25 28 #include "figlet.h" 29 30 struct figfont 31 { 32 /* From the font format */ 33 unsigned char hardblank; 34 unsigned int height, baseline, max_length; 35 int old_layout; 36 unsigned int print_direction, full_layout, codetag_count; 37 38 unsigned int glyphs; 39 cucul_canvas_t *image; 40 unsigned int *lookup; 41 }; 42 43 static struct figfont *open_font(char const *); 44 static void free_font(struct figfont *); 26 45 27 46 cucul_canvas_t *render_figlet(uint32_t const *string, unsigned int length, … … 29 48 { 30 49 cucul_canvas_t *cv; 31 32 33 34 cv = cucul_create_canvas(3, 1); 35 cucul_putstr(cv, 0, 0, "LOL"); 50 struct figfont *font; 51 unsigned int x, i, c; 52 53 font = open_font(fontname); 54 55 cv = cucul_create_canvas(length * font->max_length, font->height); 56 57 for(x = 0, i = 0; i < length; i++) 58 { 59 for(c = 0; c < font->glyphs; c++) 60 if(font->lookup[c * 2] == string[i]) 61 break; 62 63 if(c == font->glyphs) 64 continue; 65 66 cucul_blit(cv, x, - (int)(c * font->height), font->image, NULL); 67 68 x += font->lookup[c * 2 + 1]; 69 } 70 71 free_font(font); 72 36 73 return cv; 37 74 } 38 75 76 static struct figfont *open_font(char const *fontname) 77 { 78 char *data = NULL; 79 char path[2048]; 80 struct figfont *font; 81 cucul_buffer_t *b; 82 FILE *f; 83 unsigned int i, j, size, comment_lines; 84 85 /* Open font */ 86 snprintf(path, 2047, "/usr/share/figlet/%s.flf", fontname); 87 path[2047] = '\0'; 88 f = fopen(path, "r"); 89 if(!f) 90 { 91 fprintf(stderr, "font `%s' not found\n", path); 92 return NULL; 93 } 94 95 font = malloc(sizeof(struct figfont)); 96 97 /* Read header */ 98 font->print_direction = 0; 99 font->full_layout = 0; 100 font->codetag_count = 0; 101 if(fscanf(f, "flf2a%c %u %u %u %i %u %u %u %u\n", &font->hardblank, 102 &font->height, &font->baseline, &font->max_length, 103 &font->old_layout, &comment_lines, &font->print_direction, 104 &font->full_layout, &font->codetag_count) < 6) 105 { 106 fprintf(stderr, "font `%s' has invalid header\n", path); 107 free(font); 108 fclose(f); 109 return NULL; 110 } 111 112 /* Skip comment lines */ 113 for(i = 0; i < comment_lines; i++) 114 { 115 fscanf(f, "%*[^\n]"); 116 fscanf(f, "%*c"); 117 } 118 119 /* Read mandatory characters (32-127, 196, 214, 220, 228, 246, 252, 223) 120 * then read additional characters. */ 121 font->glyphs = 0; 122 font->lookup = NULL; 123 124 for(i = 0, size = 0; !feof(f); font->glyphs++) 125 { 126 if((font->glyphs % 2048) == 0) 127 font->lookup = realloc(font->lookup, 128 (font->glyphs + 2048) * 2 * sizeof(int)); 129 130 if(font->glyphs < 127 - 32) 131 { 132 font->lookup[font->glyphs * 2] = 32 + font->glyphs; 133 } 134 else if(font->glyphs < (127 - 32) + 7) 135 { 136 static int const tab[7] = { 196, 214, 220, 228, 246, 252, 223 }; 137 font->lookup[font->glyphs * 2] = tab[font->glyphs = (127 - 32)]; 138 } 139 else 140 { 141 fscanf(f, "%u %*[^\n]", &font->lookup[font->glyphs * 2]); 142 fscanf(f, "%*c"); 143 } 144 145 font->lookup[font->glyphs * 2 + 1] = 0; 146 147 for(j = 0; j < font->height; j++) 148 { 149 if(i + 2048 >= size) 150 data = realloc(data, size += 2048); 151 152 fgets(data + i, 2048, f); 153 i = (uintptr_t)strchr(data + i, 0) - (uintptr_t)data; 154 } 155 } 156 157 fclose(f); 158 159 /* Import buffer into canvas */ 160 b = cucul_load_memory(data, i); 161 font->image = cucul_import_canvas(b, "ansi"); 162 cucul_free_buffer(b); 163 free(data); 164 165 /* Remove EOL characters. For now we ignore hardblanks, don’t do any 166 * smushing, nor any kind of error checking. */ 167 for(j = 0; j < font->height * font->glyphs; j++) 168 { 169 unsigned long int ch, oldch = 0; 170 171 for(i = font->max_length; i--;) 172 { 173 ch = cucul_getchar(font->image, i, j); 174 175 if(ch == font->hardblank) 176 cucul_putchar(font->image, i, j, ' '); 177 else if(oldch && ch != oldch) 178 { 179 if(!font->lookup[j / font->height * 2 + 1]) 180 font->lookup[j / font->height * 2 + 1] = i + 1; 181 } 182 else if(oldch && ch == oldch) 183 cucul_putchar(font->image, i, j, ' '); 184 else if(ch != ' ') 185 { 186 oldch = ch; 187 cucul_putchar(font->image, i, j, ' '); 188 } 189 } 190 } 191 192 return font; 193 } 194 195 static void free_font(struct figfont *font) 196 { 197 free(font->lookup); 198 free(font); 199 } 200
Note: See TracChangeset
for help on using the changeset viewer.