Changeset 2111 for libcaca/trunk


Ignore:
Timestamp:
Dec 1, 2007, 6:58:52 PM (12 years ago)
Author:
Sam Hocevar
Message:

=?utf-8?q?=20=20*=20Implement=20cucul=5Fput=5Ffigchar()=20to=20paste=20FIGlet/TOIlet=20characters=20in

=20=20=20=20=20=20=20=20=20=20=E2=96=8C=20=E2=96=8C=20=20=20=E2=96=9C=E2=96=9C=20=20=20=20=C2=A0=E2=96=8C=20=E2=96=8C=20=20=20=20=20=20=E2=96=9C=20=20=20=E2=96=8C=E2=96=90
=20=20=20=20=20=20=20=20=20=20=E2=96=99=E2=96=84=E2=96=8C=E2=96=9E=E2=96=80=E2=96=96=E2=96=90=E2=96=90=20=E2=96=9E=E2=96=80=E2=96=96=C2=A0=E2=96=8C=E2=96=96=E2=96=8C=E2=96=9E=E2=96=80=E2=96=96=E2=96=99=E2=96=80=E2=96=96=E2=96=90=20=E2=96=9E=E2=96=80=E2=96=8C=E2=96=90
=20=20=20=20=20=20=20=20=20=20=E2=96=8C=20=E2=96=8C=E2=96=9B=E2=96=80=20=E2=96=90=E2=96=90=20=E2=96=8C=20=E2=96=8C=C2=A0=E2=96=99=E2=96=9A=E2=96=8C=E2=96=8C=20=E2=96=8C=E2=96=8C=20=C2=A0=E2=96=90=20=E2=96=8C=20=E2=96=8C=E2=96=9D
=20=20=20=20=20=20=20=20=20=20=E2=96=98=20=E2=96=98=E2=96=9D=E2=96=80=E2=96=98=20=E2=96=98=E2=96=98=E2=96=9D=E2=96=80=20=C2=A0=E2=96=98=20=E2=96=98=E2=96=9D=E2=96=80=20=E2=96=98=20=20=20=E2=96=98=E2=96=9D=E2=96=80=E2=96=98=E2=96=9D?=
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit

Location:
libcaca/trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • libcaca/trunk/cucul/cucul.c

    r2110 r2111  
    309309    }
    310310
    311     if(cv->ff)
    312         _cucul_free_figfont(cv->ff);
     311    cucul_canvas_set_figfont(cv, NULL);
    313312
    314313    free(cv->frames);
  • libcaca/trunk/cucul/cucul.h

    r2110 r2111  
    287287 *  @{ */
    288288__extern int cucul_canvas_set_figfont(cucul_canvas_t *, char const *);
     289__extern int cucul_put_figchar(cucul_canvas_t *, unsigned long int);
    289290/*  @} */
    290291
  • libcaca/trunk/cucul/cucul_internals.h

    r2110 r2111  
    8686extern char *_cucul_file_gets(char *, int, cucul_file_t *);
    8787
    88 /* FIGfont functions */
    89 extern cucul_figfont_t * _cucul_open_figfont(char const *);
    90 extern int _cucul_free_figfont(cucul_figfont_t *);
    91 
    9288#endif /* __CUCUL_INTERNALS_H__ */
  • libcaca/trunk/cucul/figfont.c

    r2110 r2111  
    1717 */
    1818
     19/*
     20 *  FIXME: this file needs huge cleanup to be usable
     21 */
     22
    1923#include "config.h"
    2024#include "common.h"
     
    3135struct cucul_figfont
    3236{
    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;
    3442    unsigned long int hardblank;
    3543    unsigned int height, baseline, max_length;
     
    3745    unsigned int print_direction, full_layout, codetag_count;
    3846    unsigned int glyphs;
    39     cucul_canvas_t *fontcv;
     47    cucul_canvas_t *fontcv, *charcv;
     48    int *left, *right; /* Unused yet */
    4049    unsigned int *lookup;
    4150};
    4251
     52static uint32_t hsmush(uint32_t ch1, uint32_t ch2, unsigned int rule);
     53static cucul_figfont_t * open_figfont(char const *);
     54static int free_figfont(cucul_figfont_t *);
     55
    4356int cucul_canvas_set_figfont(cucul_canvas_t *cv, char const *path)
    4457{
     
    4760    if(path)
    4861    {
    49         ff = _cucul_open_figfont(path);
     62        ff = open_figfont(path);
    5063        if(!ff)
    5164            return -1;
     
    5366
    5467    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));
    56125
    57126    cv->ff = ff;
     
    60129}
    61130
     131int 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
     254static 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
    62284#define STD_GLYPHS (127 - 32)
    63285#define EXT_GLYPHS (STD_GLYPHS + 7)
    64286
    65 cucul_figfont_t * _cucul_open_figfont(char const *path)
     287cucul_figfont_t * open_figfont(char const *path)
    66288{
    67289    char altpath[2048];
     
    251473}
    252474
    253 int _cucul_free_figfont(cucul_figfont_t *ff)
     475int free_figfont(cucul_figfont_t *ff)
    254476{
    255477    cucul_free_canvas(ff->fontcv);
     
    260482}
    261483
     484static 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  
    1818#if !defined(__KERNEL__)
    1919#   include <stdio.h>
     20#   include <stdlib.h>
    2021#endif
    2122
     
    2526{
    2627    cucul_canvas_t *cv;
     28    void *buffer;
     29    unsigned long int len;
     30    uint8_t color = 0;
    2731
    28     if(argc < 2)
     32    if(argc < 3)
    2933    {
    3034        fprintf(stderr, "Too few arguments\n");
     
    3943    }
    4044
     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
    4155    cucul_free_canvas(cv);
    4256
Note: See TracChangeset for help on using the changeset viewer.