Changeset 1401 for toilet


Ignore:
Timestamp:
Nov 15, 2006, 4:29:34 AM (13 years ago)
Author:
Sam Hocevar
Message:
  • Smushing support. Yeah baby.
Location:
toilet/trunk/src
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • toilet/trunk/src/figlet.c

    r1400 r1401  
    3838
    3939static int open_font(context_t *cx);
     40static uint32_t smush(uint32_t, uint32_t, unsigned int);
    4041
    4142int init_figlet(context_t *cx)
     
    4344    if(open_font(cx))
    4445        return -1;
     46
     47    /* FIXME: read the font's contents */
     48    if(cx->hlayout == H_DEFAULT)
     49        cx->hlayout = H_SMUSH;
     50
     51    cx->charcv = cucul_create_canvas(cx->max_length - 2, cx->height);
    4552
    4653    cx->left = malloc(cx->height * sizeof(int));
     
    5663static int feed_figlet(context_t *cx, uint32_t ch, uint32_t attr)
    5764{
    58     unsigned int c, w, h, x, y, overlap, mx;
     65    unsigned int c, w, h, x, y, overlap, extra, xleft, xright;
    5966
    6067    switch(ch)
     
    8087    h = cx->height;
    8188
     89    cucul_set_canvas_handle(cx->fontcv, 0, c * cx->height);
     90    cucul_blit(cx->charcv, 0, 0, cx->fontcv, NULL);
     91
    8292    /* Check whether we reached the end of the screen */
    8393    if(cx->x && cx->x + w > cx->term_width)
     
    8898
    8999    /* Compute how much the next character will overlap */
    90     overlap = w;
    91     for(y = 0; y < h; y++)
    92     {
    93         /* Compute how much spaces we can eat from the new glyph */
    94         for(x = 0; x < overlap; x++)
    95             if(cucul_get_char(cx->image, x, y + c * cx->height) != ' ')
    96                 break;
    97 
    98         /* Compute how much spaces we can eat from the previous glyph */
    99         for(mx = 0; x + mx < overlap && mx < cx->x; mx++)
    100             if(cucul_get_char(cx->cv, cx->x - 1 - mx, cx->y + y) != ' ')
    101                 break;
    102 
    103         if(x + mx < overlap)
    104             overlap = x + mx;
     100    switch(cx->hlayout)
     101    {
     102    case H_SMUSH:
     103    case H_KERN:
     104    case H_OVERLAP:
     105        extra = (cx->hlayout == H_OVERLAP);
     106        overlap = w;
     107        for(y = 0; y < h; y++)
     108        {
     109            /* Compute how much spaces we can eat from the new glyph */
     110            for(xright = 0; xright < overlap; xright++)
     111                if(cucul_get_char(cx->charcv, xright, y) != ' ')
     112                    break;
     113
     114            /* Compute how much spaces we can eat from the previous glyph */
     115            for(xleft = 0; xright + xleft < overlap && xleft < cx->x; xleft++)
     116                if(cucul_get_char(cx->cv, cx->x - 1 - xleft, cx->y + y) != ' ')
     117                    break;
     118
     119            /* Handle overlapping */
     120            if(cx->hlayout == H_OVERLAP && xleft < cx->x)
     121                xleft++;
     122
     123            /* Handle smushing */
     124            if(cx->hlayout == H_SMUSH)
     125            {
     126                if(xleft < cx->x &&
     127                   smush(cucul_get_char(cx->charcv, xright, y),
     128                         cucul_get_char(cx->cv, cx->x - 1 - xleft, cx->y + y),
     129                         0))
     130                    xleft++;
     131            }
     132 
     133            if(xleft + xright < overlap)
     134                overlap = xleft + xright;
     135        }
     136        break;
     137    case H_NONE:
     138        overlap = 0;
     139        break;
     140    default:
     141        return -1;
    105142    }
    106143
     
    121158        for(x = 0; x < w; x++)
    122159    {
    123         uint32_t tmpch = cucul_get_char(cx->image, x, y + c * cx->height);
    124         //uint32_t tmpat = cucul_get_attr(cx->image, x, y + c * cx->height);
    125         if(tmpch == ' ')
     160        uint32_t ch1, ch2;
     161        //uint32_t tmpat = cucul_get_attr(cx->fontcv, x, y + c * cx->height);
     162        ch2 = cucul_get_char(cx->charcv, x, y);
     163        if(ch2 == ' ')
    126164            continue;
     165        ch1 = cucul_get_char(cx->cv, cx->x + x - overlap, cx->y + y);
    127166        /* FIXME: this could be changed to cucul_put_attr() when the
    128167         * function is fixed in libcucul */
    129168        //cucul_set_attr(cx->cv, tmpat);
    130         cucul_put_char(cx->cv, cx->x + x - overlap, cx->y + y, tmpch);
     169        if(ch1 == ' ' || cx->hlayout != H_SMUSH)
     170            cucul_put_char(cx->cv, cx->x + x - overlap, cx->y + y, ch2);
     171        else
     172            cucul_put_char(cx->cv, cx->x + x - overlap, cx->y + y,
     173                           smush(ch1, ch2, 0));
    131174        //cucul_put_attr(cx->cv, cx->x + x, cx->y + y, tmpat);
    132175    }
     
    166209    free(cx->left);
    167210    free(cx->right);
    168     cucul_free_canvas(cx->image);
     211    cucul_free_canvas(cx->charcv);
     212    cucul_free_canvas(cx->fontcv);
    169213    free(cx->lookup);
    170214
     
    294338
    295339    /* Import buffer into canvas */
    296     cx->image = cucul_create_canvas(0, 0);
    297     cucul_import_memory(cx->image, data, i, "utf8");
     340    cx->fontcv = cucul_create_canvas(0, 0);
     341    cucul_import_memory(cx->fontcv, data, i, "utf8");
    298342    free(data);
    299343
     
    306350        for(i = cx->max_length; i--;)
    307351        {
    308             ch = cucul_get_char(cx->image, i, j);
     352            ch = cucul_get_char(cx->fontcv, i, j);
    309353
    310354            /* Replace hardblanks with U+00A0 NO-BREAK SPACE */
    311355            if(ch == cx->hardblank)
    312                 cucul_put_char(cx->image, i, j, ch = 0xa0);
     356                cucul_put_char(cx->fontcv, i, j, ch = 0xa0);
    313357
    314358            if(oldch && ch != oldch)
     
    318362            }
    319363            else if(oldch && ch == oldch)
    320                 cucul_put_char(cx->image, i, j, ' ');
     364                cucul_put_char(cx->fontcv, i, j, ' ');
    321365            else if(ch != ' ')
    322366            {
    323367                oldch = ch;
    324                 cucul_put_char(cx->image, i, j, ' ');
    325             }
    326         }
    327     }
    328 
    329     return 0;
    330 }
    331 
     368                cucul_put_char(cx->fontcv, i, j, ' ');
     369            }
     370        }
     371    }
     372
     373    return 0;
     374}
     375
     376static uint32_t smush(uint32_t ch1, uint32_t ch2, unsigned int mode)
     377{
     378
     379    /* Rule 1 */
     380    if(ch1 == ch2 && ch1 != 0xa0)
     381        return ch2;
     382
     383    if(ch1 < 0x80 && ch2 < 0x80)
     384    {
     385        char const rule2[] = "|/\\[]{}()<>";
     386        char const rule3[] = "||/\\[]{}()<>";
     387        char *tmp1, *tmp2;
     388        uint16_t s, p;
     389
     390        /* Rule 2 */
     391        if(ch1 == '_' && strchr(rule2, ch2))
     392            return ch2;
     393
     394        /* Rule 3 */
     395        if((tmp1 = strchr(rule3, ch1)) && (tmp2 = strchr(rule3, ch2)))
     396        {
     397            int cl1 = (tmp1 - rule3) / 2;
     398            int cl2 = (tmp2 - rule3) / 2;
     399
     400            if(cl1 < cl2)
     401                return ch2;
     402            if(cl1 > cl2)
     403                return ch1;
     404        }
     405
     406        /* Rule 4 */
     407        s = ch1 + ch2;
     408        p = ch1 * ch2;
     409
     410        if(p == 15375 /* '{' * '}' */
     411            || p == 8463 /* '[' * ']' */
     412            || (p == 1640 && s == 81)) /* '(' *|+ ')' */
     413            return '|';
     414
     415        /* Rule 5 */
     416        switch((ch1 << 8) | ch2)
     417        {
     418            case 0x2f5c: return '|'; /* /\ */
     419            case 0x5c2f: return 'Y'; /* \/ */
     420            case 0x3e3c: return 'X'; /* >< */
     421        }
     422
     423        /* Rule 6 */
     424        if(ch1 == ch2 && ch1 == 0xa0)
     425            return 0xa0;
     426    }
     427
     428    return 0;
     429}
     430
  • toilet/trunk/src/main.c

    r1326 r1401  
    5454
    5555    cx->term_width = 80;
     56
     57    cx->hlayout = H_DEFAULT;
    5658
    5759    cx->filters = NULL;
     
    8385        };
    8486
    85         int c = getopt_long(argc, argv, "f:d:w:tF:E:hI:v",
     87        int c = getopt_long(argc, argv, "f:d:w:tsSkWoF:E:hI:v",
    8688                            long_options, &option_index);
    8789#   else
    8890#       define MOREINFO "Try `%s -h' for more information.\n"
    89         int c = getopt(argc, argv, "f:d:w:tF:E:hI:v");
     91        int c = getopt(argc, argv, "f:d:w:tsSkWoF:E:hI:v");
    9092#   endif
    9193        if(c == -1)
     
    136138            break;
    137139        }
     140        case 's':
     141            cx->hlayout = H_DEFAULT;
     142            break;
     143        case 'S':
     144            cx->hlayout = H_SMUSH;
     145            break;
     146        case 'k':
     147            cx->hlayout = H_KERN;
     148            break;
     149        case 'W':
     150            cx->hlayout = H_NONE;
     151            break;
     152        case 'o':
     153            cx->hlayout = H_OVERLAP;
     154            break;
    138155        case 'E': /* --export */
    139156            if(!strcmp(optarg, "list"))
  • toilet/trunk/src/toilet.h

    r1400 r1401  
    3434
    3535    /* Used by the FIGlet driver */
     36    enum { H_DEFAULT, H_KERN, H_SMUSH, H_NONE, H_OVERLAP } hlayout;
    3637    unsigned long int hardblank;
    3738    unsigned int height, baseline, max_length;
     
    3940    unsigned int print_direction, full_layout, codetag_count;
    4041    unsigned int glyphs;
    41     cucul_canvas_t *image;
     42    cucul_canvas_t *fontcv, *charcv;
    4243    int *left, *right; /* Unused yet */
    4344    unsigned int *lookup;
Note: See TracChangeset for help on using the changeset viewer.