- Timestamp:
- Oct 10, 2006, 9:20:15 AM (16 years ago)
- Location:
- toilet/trunk/src
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
toilet/trunk/src/figlet.c
r1193 r1196 32 32 #define EXT_GLYPHS (STD_GLYPHS + 7) 33 33 34 struct figfont 35 { 36 /* From the font format */ 37 unsigned long int hardblank; 38 unsigned int height, baseline, max_length; 39 int old_layout; 40 unsigned int print_direction, full_layout, codetag_count; 41 42 unsigned int glyphs; 43 cucul_canvas_t *image; 44 unsigned int *lookup; 45 }; 46 47 static struct figfont *open_font(context_t *cx); 48 static void free_font(struct figfont *); 49 50 cucul_canvas_t *render_figlet(context_t *cx, uint32_t const *string, 51 unsigned int length) 52 { 53 cucul_canvas_t *cv; 54 struct figfont *font; 55 unsigned int x, i, c; 56 57 font = open_font(cx); 58 59 if(!font) 60 return NULL; 61 62 cv = cucul_create_canvas(length * font->max_length, font->height); 63 64 for(x = 0, i = 0; i < length; i++) 65 { 66 for(c = 0; c < font->glyphs; c++) 67 if(font->lookup[c * 2] == string[i]) 68 break; 69 70 if(c == font->glyphs) 71 continue; 72 73 cucul_blit(cv, x, - (int)(c * font->height), font->image, NULL); 74 75 x += font->lookup[c * 2 + 1]; 76 } 77 78 cucul_set_canvas_boundaries(cv, 0, 0, x, font->height); 79 80 free_font(font); 81 82 return cv; 83 } 84 85 static struct figfont *open_font(context_t *cx) 34 static int feed_figlet(context_t *, uint32_t); 35 static int end_figlet(context_t *); 36 37 static int open_font(context_t *cx); 38 39 int init_figlet(context_t *cx) 40 { 41 if(open_font(cx)) 42 return -1; 43 44 cx->x = cx->y = 0; 45 cx->w = cx->h = 0; 46 cx->cv = cucul_create_canvas(1, 1); 47 48 cx->feed = feed_figlet; 49 cx->end = end_figlet; 50 51 return 0; 52 } 53 54 static int feed_figlet(context_t *cx, uint32_t ch) 55 { 56 unsigned int c, w, h, x, y; 57 58 switch(ch) 59 { 60 case (uint32_t)'\r': 61 return 0; 62 case (uint32_t)'\n': 63 cx->x = 0; 64 cx->y += cx->height; 65 return 0; 66 /* FIXME: handle '\t' */ 67 } 68 69 /* Look whether our glyph is available */ 70 for(c = 0; c < cx->glyphs; c++) 71 if(cx->lookup[c * 2] == ch) 72 break; 73 74 if(c == cx->glyphs) 75 return 0; 76 77 w = cx->lookup[c * 2 + 1]; 78 h = cx->height; 79 80 /* Check whether we reached the end of the screen */ 81 if(cx->x && cx->x + w > cx->term_width) 82 { 83 cx->x = 0; 84 cx->y += h; 85 } 86 87 /* Check whether the current canvas is large enough */ 88 if(cx->x + w > cx->w) 89 cx->w = cx->x + w < cx->term_width ? cx->x + w : cx->term_width; 90 91 if(cx->y + h > cx->h) 92 cx->h = cx->y + h; 93 94 cucul_set_canvas_size(cx->cv, cx->w, cx->h); 95 96 /* Render our char (FIXME: create a rect-aware cucul_blit_canvas?) */ 97 for(y = 0; y < h; y++) 98 for(x = 0; x < w; x++) 99 { 100 uint32_t tmp = cucul_getchar(cx->image, x, y + c * cx->height); 101 cucul_putchar(cx->cv, cx->x + x, cx->y + y, tmp); 102 } 103 104 /* Advance cursor */ 105 cx->x += w; 106 107 return 0; 108 } 109 110 static int end_figlet(context_t *cx) 111 { 112 cucul_free_canvas(cx->image); 113 free(cx->lookup); 114 115 return 0; 116 } 117 118 static int open_font(context_t *cx) 86 119 { 87 120 char *data = NULL; 88 121 char path[2048]; 89 122 char hardblank[10]; 90 struct figfont *font;91 123 cucul_buffer_t *b; 92 124 FILE *f; … … 105 137 { 106 138 fprintf(stderr, "font `%s' not found\n", path); 107 return NULL; 108 } 109 } 110 111 font = malloc(sizeof(struct figfont)); 139 return -1; 140 } 141 } 112 142 113 143 /* Read header */ 114 font->print_direction = 0;115 font->full_layout = 0;116 font->codetag_count = 0;144 cx->print_direction = 0; 145 cx->full_layout = 0; 146 cx->codetag_count = 0; 117 147 if(fscanf(f, "%*[ft]lf2a%6s %u %u %u %i %u %u %u %u\n", hardblank, 118 & font->height, &font->baseline, &font->max_length,119 & font->old_layout, &comment_lines, &font->print_direction,120 & font->full_layout, &font->codetag_count) < 6)148 &cx->height, &cx->baseline, &cx->max_length, 149 &cx->old_layout, &comment_lines, &cx->print_direction, 150 &cx->full_layout, &cx->codetag_count) < 6) 121 151 { 122 152 fprintf(stderr, "font `%s' has invalid header\n", path); 123 free(font);124 153 fclose(f); 125 return NULL;126 } 127 128 font->hardblank = cucul_utf8_to_utf32(hardblank, NULL);154 return -1; 155 } 156 157 cx->hardblank = cucul_utf8_to_utf32(hardblank, NULL); 129 158 130 159 /* Skip comment lines */ … … 137 166 /* Read mandatory characters (32-127, 196, 214, 220, 228, 246, 252, 223) 138 167 * then read additional characters. */ 139 font->glyphs = 0;140 font->lookup = NULL;141 142 for(i = 0, size = 0; !feof(f); font->glyphs++)143 { 144 if(( font->glyphs % 2048) == 0)145 font->lookup = realloc(font->lookup,146 ( font->glyphs + 2048) * 2 * sizeof(int));147 148 if( font->glyphs < STD_GLYPHS)149 { 150 font->lookup[font->glyphs * 2] = 32 + font->glyphs;151 } 152 else if( font->glyphs < EXT_GLYPHS)168 cx->glyphs = 0; 169 cx->lookup = NULL; 170 171 for(i = 0, size = 0; !feof(f); cx->glyphs++) 172 { 173 if((cx->glyphs % 2048) == 0) 174 cx->lookup = realloc(cx->lookup, 175 (cx->glyphs + 2048) * 2 * sizeof(int)); 176 177 if(cx->glyphs < STD_GLYPHS) 178 { 179 cx->lookup[cx->glyphs * 2] = 32 + cx->glyphs; 180 } 181 else if(cx->glyphs < EXT_GLYPHS) 153 182 { 154 183 static int const tab[7] = { 196, 214, 220, 228, 246, 252, 223 }; 155 font->lookup[font->glyphs * 2] = tab[font->glyphs - STD_GLYPHS];184 cx->lookup[cx->glyphs * 2] = tab[cx->glyphs - STD_GLYPHS]; 156 185 } 157 186 else … … 166 195 { 167 196 free(data); 168 free(font->lookup); 169 free(font); 197 free(cx->lookup); 170 198 fprintf(stderr, "read error at glyph %u in `%s'\n", 171 font->glyphs, path);172 return NULL;199 cx->glyphs, path); 200 return -1; 173 201 } 174 202 175 203 if(number[1] == 'x') 176 sscanf(number, "%x", & font->lookup[font->glyphs * 2]);204 sscanf(number, "%x", &cx->lookup[cx->glyphs * 2]); 177 205 else 178 sscanf(number, "%u", & font->lookup[font->glyphs * 2]);206 sscanf(number, "%u", &cx->lookup[cx->glyphs * 2]); 179 207 180 208 fscanf(f, "%*c"); 181 209 } 182 210 183 font->lookup[font->glyphs * 2 + 1] = 0;184 185 for(j = 0; j < font->height; j++)211 cx->lookup[cx->glyphs * 2 + 1] = 0; 212 213 for(j = 0; j < cx->height; j++) 186 214 { 187 215 if(i + 2048 >= size) … … 195 223 fclose(f); 196 224 197 if( font->glyphs < EXT_GLYPHS)225 if(cx->glyphs < EXT_GLYPHS) 198 226 { 199 227 free(data); 200 free(font->lookup); 201 free(font); 228 free(cx->lookup); 202 229 fprintf(stderr, "only %u glyphs in `%s', expected at least %u\n", 203 font->glyphs, path, EXT_GLYPHS);204 return NULL;230 cx->glyphs, path, EXT_GLYPHS); 231 return -1; 205 232 } 206 233 207 234 /* Import buffer into canvas */ 208 235 b = cucul_load_memory(data, i); 209 font->image = cucul_import_canvas(b, "utf8");236 cx->image = cucul_import_canvas(b, "utf8"); 210 237 cucul_free_buffer(b); 211 238 free(data); 212 239 213 if(!font->image) 214 { 215 free(font->lookup); 216 free(font); 240 if(!cx->image) 241 { 242 free(cx->lookup); 217 243 fprintf(stderr, "libcucul could not load data in `%s'\n", path); 218 return NULL;244 return -1; 219 245 } 220 246 221 247 /* Remove EOL characters. For now we ignore hardblanks, don’t do any 222 248 * smushing, nor any kind of error checking. */ 223 for(j = 0; j < font->height * font->glyphs; j++)249 for(j = 0; j < cx->height * cx->glyphs; j++) 224 250 { 225 251 unsigned long int ch, oldch = 0; 226 252 227 for(i = font->max_length; i--;)228 { 229 ch = cucul_getchar( font->image, i, j);230 231 /* Replace hardblanks with U+00A0 NO-BREAK SPACE */232 if(ch == font->hardblank)233 cucul_putchar( font->image, i, j, ch = ' ');234 //cucul_putchar( font->image, i, j, ch = 0xa0);253 for(i = cx->max_length; i--;) 254 { 255 ch = cucul_getchar(cx->image, i, j); 256 257 /* TODO: Replace hardblanks with U+00A0 NO-BREAK SPACE */ 258 if(ch == cx->hardblank) 259 cucul_putchar(cx->image, i, j, ch = ' '); 260 //cucul_putchar(cx->image, i, j, ch = 0xa0); 235 261 236 262 if(oldch && ch != oldch) 237 263 { 238 if(! font->lookup[j / font->height * 2 + 1])239 font->lookup[j / font->height * 2 + 1] = i + 1;264 if(!cx->lookup[j / cx->height * 2 + 1]) 265 cx->lookup[j / cx->height * 2 + 1] = i + 1; 240 266 } 241 267 else if(oldch && ch == oldch) 242 cucul_putchar( font->image, i, j, ' ');268 cucul_putchar(cx->image, i, j, ' '); 243 269 else if(ch != ' ') 244 270 { 245 271 oldch = ch; 246 cucul_putchar( font->image, i, j, ' ');272 cucul_putchar(cx->image, i, j, ' '); 247 273 } 248 274 } 249 275 } 250 276 251 return font; 252 } 253 254 static void free_font(struct figfont *font) 255 { 256 cucul_free_canvas(font->image); 257 free(font->lookup); 258 free(font); 259 } 260 277 return 0; 278 } 279 -
toilet/trunk/src/figlet.h
r1193 r1196 15 15 * This header defines functions for handling FIGlet fonts. 16 16 */ 17 extern cucul_canvas_t *render_figlet(context_t *, uint32_t const *, 18 unsigned int); 17 extern int init_figlet(context_t *); 19 18 -
toilet/trunk/src/main.c
r1194 r1196 172 172 if(!strcasecmp(cx->font, "mono9")) 173 173 init_big(cx); 174 else /* if(!strcasecmp(cx->font, "term")) */174 else if(!strcasecmp(cx->font, "term")) 175 175 init_tiny(cx); 176 else 177 init_figlet(cx); 176 178 177 179 if(optind >= argc) -
toilet/trunk/src/toilet.h
r1194 r1196 35 35 cucul_canvas_t *onechar; 36 36 unsigned char *buf; 37 38 /* Used by the FIGlet driver */ 39 unsigned long int hardblank; 40 unsigned int height, baseline, max_length; 41 int old_layout; 42 unsigned int print_direction, full_layout, codetag_count; 43 unsigned int glyphs; 44 cucul_canvas_t *image; 45 unsigned int *lookup; 37 46 }; 38 47
Note: See TracChangeset
for help on using the changeset viewer.