- Timestamp:
- Dec 1, 2007, 6:58:52 PM (13 years ago)
- Location:
- libcaca/trunk
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
libcaca/trunk/cucul/cucul.c
r2110 r2111 309 309 } 310 310 311 if(cv->ff) 312 _cucul_free_figfont(cv->ff); 311 cucul_canvas_set_figfont(cv, NULL); 313 312 314 313 free(cv->frames); -
libcaca/trunk/cucul/cucul.h
r2110 r2111 287 287 * @{ */ 288 288 __extern int cucul_canvas_set_figfont(cucul_canvas_t *, char const *); 289 __extern int cucul_put_figchar(cucul_canvas_t *, unsigned long int); 289 290 /* @} */ 290 291 -
libcaca/trunk/cucul/cucul_internals.h
r2110 r2111 86 86 extern char *_cucul_file_gets(char *, int, cucul_file_t *); 87 87 88 /* FIGfont functions */89 extern cucul_figfont_t * _cucul_open_figfont(char const *);90 extern int _cucul_free_figfont(cucul_figfont_t *);91 92 88 #endif /* __CUCUL_INTERNALS_H__ */ -
libcaca/trunk/cucul/figfont.c
r2110 r2111 17 17 */ 18 18 19 /* 20 * FIXME: this file needs huge cleanup to be usable 21 */ 22 19 23 #include "config.h" 20 24 #include "common.h" … … 31 35 struct cucul_figfont 32 36 { 33 /* Used by the FIGlet driver */ 37 unsigned int term_width; 38 int x, y, w, h, lines; 39 40 enum { H_DEFAULT, H_KERN, H_SMUSH, H_NONE, H_OVERLAP } hmode; 41 unsigned int hsmushrule; 34 42 unsigned long int hardblank; 35 43 unsigned int height, baseline, max_length; … … 37 45 unsigned int print_direction, full_layout, codetag_count; 38 46 unsigned int glyphs; 39 cucul_canvas_t *fontcv; 47 cucul_canvas_t *fontcv, *charcv; 48 int *left, *right; /* Unused yet */ 40 49 unsigned int *lookup; 41 50 }; 42 51 52 static uint32_t hsmush(uint32_t ch1, uint32_t ch2, unsigned int rule); 53 static cucul_figfont_t * open_figfont(char const *); 54 static int free_figfont(cucul_figfont_t *); 55 43 56 int cucul_canvas_set_figfont(cucul_canvas_t *cv, char const *path) 44 57 { … … 47 60 if(path) 48 61 { 49 ff = _cucul_open_figfont(path);62 ff = open_figfont(path); 50 63 if(!ff) 51 64 return -1; … … 53 66 54 67 if(cv->ff) 55 _cucul_free_figfont(cv->ff); 68 { 69 cucul_free_canvas(cv->ff->charcv); 70 free(cv->ff->left); 71 free(cv->ff->right); 72 free_figfont(cv->ff); 73 } 74 75 cv->ff = ff; 76 77 if(!path) 78 return 0; 79 80 /* from TOIlet’s main.c */ 81 ff->term_width = 80; 82 ff->hmode = H_DEFAULT; 83 84 /* from TOIlet’s render.c */ 85 ff->x = ff->y = 0; 86 ff->w = ff->h = 0; 87 ff->lines = 0; 88 cucul_set_canvas_size(cv, 0, 0); /* XXX */ 89 90 /* from TOIlet’s figlet.c */ 91 if(ff->full_layout & 0x3f) 92 ff->hsmushrule = ff->full_layout & 0x3f; 93 else if(ff->old_layout > 0) 94 ff->hsmushrule = ff->old_layout; 95 96 switch(ff->hmode) 97 { 98 case H_DEFAULT: 99 if(ff->old_layout == -1) 100 ff->hmode = H_NONE; 101 else if(ff->old_layout == 0 && (ff->full_layout & 0xc0) == 0x40) 102 ff->hmode = H_KERN; 103 else if((ff->old_layout & 0x3f) && (ff->full_layout & 0x3f) 104 && (ff->full_layout & 0x80)) 105 { 106 ff->hmode = H_SMUSH; 107 ff->hsmushrule = ff->full_layout & 0x3f; 108 } 109 else if(ff->old_layout == 0 && (ff->full_layout & 0xbf) == 0x80) 110 { 111 ff->hmode = H_SMUSH; 112 ff->hsmushrule = 0x3f; 113 } 114 else 115 ff->hmode = H_OVERLAP; 116 break; 117 default: 118 break; 119 } 120 121 ff->charcv = cucul_create_canvas(ff->max_length - 2, ff->height); 122 123 ff->left = malloc(ff->height * sizeof(int)); 124 ff->right = malloc(ff->height * sizeof(int)); 56 125 57 126 cv->ff = ff; … … 60 129 } 61 130 131 int cucul_put_figchar(cucul_canvas_t *cv, unsigned long int ch) 132 { 133 cucul_figfont_t *ff = cv->ff; 134 unsigned int c, w, h, x, y, overlap, extra, xleft, xright; 135 136 switch(ch) 137 { 138 case (uint32_t)'\r': 139 return 0; 140 case (uint32_t)'\n': 141 ff->x = 0; 142 ff->y += ff->height; 143 return 0; 144 /* FIXME: handle '\t' */ 145 } 146 147 /* Look whether our glyph is available */ 148 for(c = 0; c < ff->glyphs; c++) 149 if(ff->lookup[c * 2] == ch) 150 break; 151 152 if(c == ff->glyphs) 153 return 0; 154 155 w = ff->lookup[c * 2 + 1]; 156 h = ff->height; 157 158 cucul_set_canvas_handle(ff->fontcv, 0, c * ff->height); 159 cucul_blit(ff->charcv, 0, 0, ff->fontcv, NULL); 160 161 /* Check whether we reached the end of the screen */ 162 if(ff->x && ff->x + w > ff->term_width) 163 { 164 ff->x = 0; 165 ff->y += h; 166 } 167 168 /* Compute how much the next character will overlap */ 169 switch(ff->hmode) 170 { 171 case H_SMUSH: 172 case H_KERN: 173 case H_OVERLAP: 174 extra = (ff->hmode == H_OVERLAP); 175 overlap = w; 176 for(y = 0; y < h; y++) 177 { 178 /* Compute how much spaces we can eat from the new glyph */ 179 for(xright = 0; xright < overlap; xright++) 180 if(cucul_get_char(ff->charcv, xright, y) != ' ') 181 break; 182 183 /* Compute how much spaces we can eat from the previous glyph */ 184 for(xleft = 0; xright + xleft < overlap && xleft < ff->x; xleft++) 185 if(cucul_get_char(cv, ff->x - 1 - xleft, ff->y + y) != ' ') 186 break; 187 188 /* Handle overlapping */ 189 if(ff->hmode == H_OVERLAP && xleft < ff->x) 190 xleft++; 191 192 /* Handle smushing */ 193 if(ff->hmode == H_SMUSH) 194 { 195 if(xleft < ff->x && 196 hsmush(cucul_get_char(cv, ff->x - 1 - xleft, ff->y + y), 197 cucul_get_char(ff->charcv, xright, y), 198 ff->hsmushrule)) 199 xleft++; 200 } 201 202 if(xleft + xright < overlap) 203 overlap = xleft + xright; 204 } 205 break; 206 case H_NONE: 207 overlap = 0; 208 break; 209 default: 210 return -1; 211 } 212 213 /* Check whether the current canvas is large enough */ 214 if(ff->x + w - overlap > ff->w) 215 ff->w = ff->x + w - overlap < ff->term_width 216 ? ff->x + w - overlap : ff->term_width; 217 218 if(ff->y + h > ff->h) 219 ff->h = ff->y + h; 220 221 #if 0 /* deactivated for libcaca insertion */ 222 if(attr) 223 cucul_set_attr(cv, attr); 224 #endif 225 cucul_set_canvas_size(cv, ff->w, ff->h); 226 227 /* Render our char (FIXME: create a rect-aware cucul_blit_canvas?) */ 228 for(y = 0; y < h; y++) 229 for(x = 0; x < w; x++) 230 { 231 uint32_t ch1, ch2; 232 //uint32_t tmpat = cucul_get_attr(ff->fontcv, x, y + c * ff->height); 233 ch2 = cucul_get_char(ff->charcv, x, y); 234 if(ch2 == ' ') 235 continue; 236 ch1 = cucul_get_char(cv, ff->x + x - overlap, ff->y + y); 237 /* FIXME: this could be changed to cucul_put_attr() when the 238 * function is fixed in libcucul */ 239 //cucul_set_attr(cv, tmpat); 240 if(ch1 == ' ' || ff->hmode != H_SMUSH) 241 cucul_put_char(cv, ff->x + x - overlap, ff->y + y, ch2); 242 else 243 cucul_put_char(cv, ff->x + x - overlap, ff->y + y, 244 hsmush(ch1, ch2, ff->hsmushrule)); 245 //cucul_put_attr(cv, ff->x + x, ff->y + y, tmpat); 246 } 247 248 /* Advance cursor */ 249 ff->x += w - overlap; 250 251 return 0; 252 } 253 254 static int flush_figlet(cucul_canvas_t *cv) 255 { 256 cucul_figfont_t *ff = cv->ff; 257 unsigned int x, y; 258 259 //ff->torender = cv; 260 //cucul_set_canvas_size(ff->torender, ff->w, ff->h); 261 cucul_set_canvas_size(cv, ff->w, ff->h); 262 263 /* FIXME: do this somewhere else, or record hardblank positions */ 264 for(y = 0; y < ff->h; y++) 265 for(x = 0; x < ff->w; x++) 266 if(cucul_get_char(cv, x, y) == 0xa0) 267 { 268 uint32_t attr = cucul_get_attr(cv, x, y); 269 cucul_put_char(cv, x, y, ' '); 270 cucul_put_attr(cv, x, y, attr); 271 } 272 273 ff->x = ff->y = 0; 274 ff->w = ff->h = 0; 275 276 //cv = cucul_create_canvas(1, 1); /* XXX */ 277 278 /* from render.c */ 279 ff->lines += cucul_get_canvas_height(cv); 280 281 return 0; 282 } 283 62 284 #define STD_GLYPHS (127 - 32) 63 285 #define EXT_GLYPHS (STD_GLYPHS + 7) 64 286 65 cucul_figfont_t * _cucul_open_figfont(char const *path)287 cucul_figfont_t * open_figfont(char const *path) 66 288 { 67 289 char altpath[2048]; … … 251 473 } 252 474 253 int _cucul_free_figfont(cucul_figfont_t *ff)475 int free_figfont(cucul_figfont_t *ff) 254 476 { 255 477 cucul_free_canvas(ff->fontcv); … … 260 482 } 261 483 484 static uint32_t hsmush(uint32_t ch1, uint32_t ch2, unsigned int rule) 485 { 486 /* Rule 1 */ 487 if((rule & 0x01) && ch1 == ch2 && ch1 != 0xa0) 488 return ch2; 489 490 if(ch1 < 0x80 && ch2 < 0x80) 491 { 492 char const charlist[] = "|/\\[]{}()<>"; 493 char *tmp1, *tmp2; 494 495 /* Rule 2 */ 496 if(rule & 0x02) 497 { 498 if(ch1 == '_' && strchr(charlist, ch2)) 499 return ch2; 500 501 if(ch2 == '_' && strchr(charlist, ch1)) 502 return ch1; 503 } 504 505 /* Rule 3 */ 506 if((rule & 0x04) && 507 (tmp1 = strchr(charlist, ch1)) && (tmp2 = strchr(charlist, ch2))) 508 { 509 int cl1 = (tmp1 + 1 - charlist) / 2; 510 int cl2 = (tmp2 + 1 - charlist) / 2; 511 512 if(cl1 < cl2) 513 return ch2; 514 if(cl1 > cl2) 515 return ch1; 516 } 517 518 /* Rule 4 */ 519 if(rule & 0x08) 520 { 521 uint16_t s = ch1 + ch2; 522 uint16_t p = ch1 * ch2; 523 524 if(p == 15375 /* '{' * '}' */ 525 || p == 8463 /* '[' * ']' */ 526 || (p == 1640 && s == 81)) /* '(' *|+ ')' */ 527 return '|'; 528 } 529 530 /* Rule 5 */ 531 if(rule & 0x10) 532 { 533 switch((ch1 << 8) | ch2) 534 { 535 case 0x2f5c: return '|'; /* /\ */ 536 case 0x5c2f: return 'Y'; /* \/ */ 537 case 0x3e3c: return 'X'; /* >< */ 538 } 539 } 540 541 /* Rule 6 */ 542 if((rule & 0x20) && ch1 == ch2 && ch1 == 0xa0) 543 return 0xa0; 544 } 545 546 return 0; 547 } 548 -
libcaca/trunk/examples/figfont.c
r2110 r2111 18 18 #if !defined(__KERNEL__) 19 19 # include <stdio.h> 20 # include <stdlib.h> 20 21 #endif 21 22 … … 25 26 { 26 27 cucul_canvas_t *cv; 28 void *buffer; 29 unsigned long int len; 30 uint8_t color = 0; 27 31 28 if(argc < 2)32 if(argc < 3) 29 33 { 30 34 fprintf(stderr, "Too few arguments\n"); … … 39 43 } 40 44 45 while(argv[2][0]) 46 { 47 cucul_set_color_ansi(cv, 1 + ((color += 4) % 15), CUCUL_TRANSPARENT); 48 cucul_put_figchar(cv, argv[2]++[0]); 49 } 50 51 buffer = cucul_export_memory(cv, "utf8", &len); 52 fwrite(buffer, len, 1, stdout); 53 free(buffer); 54 41 55 cucul_free_canvas(cv); 42 56
Note: See TracChangeset
for help on using the changeset viewer.