コード例 #1
0
ファイル: simple.c プロジェクト: chazu/libcaca
int main(int argc, char *argv[])
{
    caca_canvas_t *cv;
    int tests = 0, passed = 0;

    cv = caca_create_canvas(0, 0);
    caca_put_char(cv, 0, 0, 'x');
    TEST(caca_get_char(cv, 0, 0) != 'x');

    caca_rotate_180(cv);

    caca_set_canvas_size(cv, 1, 1);
    TEST(caca_get_char(cv, 0, 0) != 'x');
    TEST(caca_get_char(cv, 0, 0) == ' ');

    caca_put_char(cv, 0, 0, 'y');
    TEST(caca_get_char(cv, 0, 0) == 'y');

    caca_set_canvas_size(cv, 1000, 1000);
    TEST(caca_get_canvas_width(cv) == 1000);

    caca_put_char(cv, 999, 999, 'z');
    TEST(caca_get_char(cv, 999, 999) == 'z');

    caca_free_canvas(cv);

    fprintf(stderr, "%i tests, %i errors\n", tests, tests - passed);

    return 0;
}
コード例 #2
0
ファイル: conio.c プロジェクト: gitpan/Term-Caca
static int conio_init_graphics(caca_display_t *dp)
{
    dp->drv.p = malloc(sizeof(struct driver_private));

    _wscroll = 0;
    _setcursortype(_NOCURSOR);
    clrscr();

    gettextinfo(&dp->drv.p->ti);
    dp->drv.p->screen = malloc(2 * dp->drv.p->ti.screenwidth
                                 * dp->drv.p->ti.screenheight * sizeof(char));
    if(dp->drv.p->screen == NULL)
        return -1;
#   if defined(SCREENUPDATE_IN_PC_H)
    ScreenRetrieve(dp->drv.p->screen);
#   else
    /* FIXME */
#   endif
    dp->resize.allow = 1;
    caca_set_canvas_size(dp->cv, dp->drv.p->ti.screenwidth,
                                  dp->drv.p->ti.screenheight);
    dp->resize.allow = 0;

    return 0;
}
コード例 #3
0
ファイル: vga.c プロジェクト: mwgoldsmith/caca
static int vga_init_graphics(caca_display_t *dp)
{
    int i;
    uint8_t tmp;

    /* Blank screen */
    memset(VGA_SCREEN, 0, 80 * 25 * 2);

    /* Fill VGA palette */
    for(i = 0; i < 16; i++)
    {
        outb(vga_colors[i][0], 0x3c8);
        outb(vga_colors[i][1], 0x3c9);
        outb(vga_colors[i][2], 0x3c9);
        outb(vga_colors[i][3], 0x3c9);
    }

    /* Hide cursor */
    outb(0x0a, 0x3d4);
    tmp = inb(0x3d5);
    tmp |= 0x20;
    outb(0x0a, 0x3d4);
    outb(tmp, 0x3d5);

    caca_add_dirty_rect(dp->cv, 0, 0, dp->cv->width, dp->cv->height);
    dp->resize.allow = 1;
    caca_set_canvas_size(dp->cv, 80, 25); /* We don't have much choice */
    dp->resize.allow = 0;

    return 0;
}
コード例 #4
0
ファイル: figfont.c プロジェクト: HuxyUK/libcaca
/** \brief flush the figlet context */
int caca_flush_figlet(caca_canvas_t *cv)
{
    caca_charfont_t *ff = cv->ff;
    int x, y;

    if (!ff)
        return -1;

    //ff->torender = cv;
    //caca_set_canvas_size(ff->torender, ff->w, ff->h);
    caca_set_canvas_size(cv, ff->w, ff->h);

    /* FIXME: do this somewhere else, or record hardblank positions */
    for(y = 0; y < ff->h; y++)
        for(x = 0; x < ff->w; x++)
            if(caca_get_char(cv, x, y) == 0xa0)
            {
                uint32_t attr = caca_get_attr(cv, x, y);
                caca_put_char(cv, x, y, ' ');
                caca_put_attr(cv, x, y, attr);
            }

    ff->x = ff->y = 0;
    ff->w = ff->h = 0;

    //cv = caca_create_canvas(1, 1); /* XXX */

    /* from render.c */
    ff->lines += caca_get_canvas_height(cv);

    return 0;
}
コード例 #5
0
ファイル: term.c プロジェクト: KubaKaszycki/toilet
static int flush_tiny(context_t *cx)
{
    cx->torender = cx->cv;
    caca_set_canvas_size(cx->torender, cx->w, cx->h);

    cx->ew = 16;
    cx->eh = 2;
    cx->x = cx->y = 0;
    cx->w = cx->h = 0;
    cx->cv = caca_create_canvas(cx->ew, cx->eh);

    return 0;
}
コード例 #6
0
void _caca_handle_resize(caca_display_t *dp)
{
    dp->drv.handle_resize(dp);

    /* Tell libcaca we changed size */
    if(dp->resize.w != caca_get_canvas_width(dp->cv)
            || dp->resize.h != caca_get_canvas_height(dp->cv))
    {
        dp->resize.allow = 1;
        caca_set_canvas_size(dp->cv, dp->resize.w, dp->resize.h);
        dp->resize.allow = 0;
    }
}
コード例 #7
0
ファイル: term.c プロジェクト: KubaKaszycki/toilet
static int feed_tiny(context_t *cx, uint32_t ch, uint32_t attr)
{
    switch(ch)
    {
        case (uint32_t)'\r':
            return 0;
        case (uint32_t)'\n':
            cx->x = 0;
            cx->y++;
            return 0;
        case (uint32_t)'\t':
            cx->x = (cx->x & ~7) + 8;
            return 0;
    }

    /* Check whether we reached the end of the screen */
    if(cx->x && cx->x + 1 > cx->term_width)
    {
        cx->x = 0;
        cx->y++;
    }

    /* Check whether the current canvas is large enough */
    if(cx->x + 1 > cx->w)
    {
        cx->w = cx->x + 1 < cx->term_width ? cx->x + 1 : cx->term_width;
        if(cx->w > cx->ew)
            cx->ew = cx->ew + cx->ew / 2;
    }

    if(cx->y + 1 > cx->h)
    {
        cx->h = cx->y + 1;
        if(cx->h > cx->eh)
            cx->eh = cx->eh + cx->eh / 2;
    }

    caca_set_attr(cx->cv, attr);
    caca_set_canvas_size(cx->cv, cx->ew, cx->eh);

    caca_put_char(cx->cv, cx->x, cx->y, ch);
    cx->x++;

    return 0;
}
コード例 #8
0
ファイル: figfont.c プロジェクト: HuxyUK/libcaca
/** \brief load a figfont and attach it to a canvas */
int caca_canvas_set_figfont(caca_canvas_t *cv, char const *path)
{
    caca_charfont_t *ff = NULL;

    if (path)
    {
        ff = open_charfont(path);
        if (!ff)
            return -1;
    }

    if (cv->ff)
    {
        caca_free_canvas(cv->ff->charcv);
        free(cv->ff->left);
        free(cv->ff->right);
        free_charfont(cv->ff);
    }

    cv->ff = ff;

    if (!path)
        return 0;

    /* from TOIlet’s main.c -- can be overriden by user */
    ff->term_width = 80;
    ff->hmode = H_DEFAULT;

    /* from TOIlet’s render.c */
    ff->x = ff->y = 0;
    ff->w = ff->h = 0;
    ff->lines = 0;
    caca_set_canvas_size(cv, 0, 0); /* XXX */

    cv->ff = ff;

    update_figfont_settings(cv);

    return 0;
}
コード例 #9
0
ファイル: font.c プロジェクト: Kirkman/libcaca
int main(int argc, char *argv[])
{
    caca_canvas_t *cv;
    caca_display_t *dp;
    caca_font_t *f;
    caca_dither_t *d;
    uint8_t *buf;
    unsigned int w, h;
    char const * const * fonts;

    /* Create a canvas */
    cv = caca_create_canvas(8, 2);
    if(cv == NULL)
    {
        printf("Can't create canvas\n");
        return -1;
    }


    /* Draw stuff on our canvas */
    caca_set_color_ansi(cv, CACA_WHITE, CACA_BLACK);
    caca_put_str(cv, 0, 0, "ABcde");
    caca_set_color_ansi(cv, CACA_LIGHTRED, CACA_BLACK);
    caca_put_str(cv, 5, 0, "\\o/");
    caca_set_color_ansi(cv, CACA_WHITE, CACA_BLUE);
    caca_put_str(cv, 0, 1, "&$âøÿØ?!");

    /* Load a libcaca internal font */
    fonts = caca_get_font_list();
    if(fonts[0] == NULL)
    {
        fprintf(stderr, "error: libcaca was compiled without any fonts\n");
        return -1;
    }
    f = caca_load_font(fonts[0], 0);
    if(f == NULL)
    {
        fprintf(stderr, "error: could not load font \"%s\"\n", fonts[0]);
        return -1;
    }

    /* Create our bitmap buffer (32-bit ARGB) */
    w = caca_get_canvas_width(cv) * caca_get_font_width(f);
    h = caca_get_canvas_height(cv) * caca_get_font_height(f);
    buf = malloc(4 * w * h);

    /* Render the canvas onto our image buffer */
    caca_render_canvas(cv, f, buf, w, h, 4 * w);

    /* Just for fun, render the image using libcaca */
    caca_set_canvas_size(cv, 80, 32);
    dp = caca_create_display(cv);

    {
#if defined(HAVE_ENDIAN_H)
        if(__BYTE_ORDER == __BIG_ENDIAN)
#else
        /* This is compile-time optimised with at least -O1 or -Os */
        uint32_t const tmp = 0x12345678;
        if(*(uint8_t const *)&tmp == 0x12)
#endif
            d = caca_create_dither(32, w, h, 4 * w,
                                    0xff0000, 0xff00, 0xff, 0xff000000);
        else
            d = caca_create_dither(32, w, h, 4 * w,
                                    0xff00, 0xff0000, 0xff000000, 0xff);
    }

    caca_dither_bitmap(cv, 0, 0, caca_get_canvas_width(cv),
                                  caca_get_canvas_height(cv), d, buf);
    caca_refresh_display(dp);

    caca_get_event(dp, CACA_EVENT_KEY_PRESS, NULL, -1);

    /* Free everything */
    caca_free_display(dp);
    free(buf);
    caca_free_dither(d);
    caca_free_font(f);
    caca_free_canvas(cv);

    return 0;
}
コード例 #10
0
ファイル: ncurses.c プロジェクト: mwgoldsmith/caca
static int ncurses_init_graphics(caca_display_t *dp)
{
    static int curses_colors[] =
    {
        /* Standard curses colours */
        COLOR_BLACK,
        COLOR_BLUE,
        COLOR_GREEN,
        COLOR_CYAN,
        COLOR_RED,
        COLOR_MAGENTA,
        COLOR_YELLOW,
        COLOR_WHITE,
        /* Extra values for xterm-16color */
        COLOR_BLACK + 8,
        COLOR_BLUE + 8,
        COLOR_GREEN + 8,
        COLOR_CYAN + 8,
        COLOR_RED + 8,
        COLOR_MAGENTA + 8,
        COLOR_YELLOW + 8,
        COLOR_WHITE + 8
    };

    mmask_t newmask;
    int fg, bg, max;

    dp->drv.p = malloc(sizeof(struct driver_private));

#if defined HAVE_GETENV && defined HAVE_PUTENV
    ncurses_install_terminal(dp);
#endif

#if defined HAVE_SIGNAL
    sigwinch_d = dp;
    signal(SIGWINCH, sigwinch_handler);
#endif

#if defined HAVE_LOCALE_H
    setlocale(LC_ALL, "");
#endif

    _caca_set_term_title("caca for ncurses");

    initscr();
    keypad(stdscr, TRUE);
    nonl();
    raw();
    noecho();
    nodelay(stdscr, TRUE);
    curs_set(0);

    /* Activate mouse */
    newmask = REPORT_MOUSE_POSITION | ALL_MOUSE_EVENTS;
    mousemask(newmask, &dp->drv.p->oldmask);
    mouseinterval(-1); /* No click emulation */

    /* Set the escape delay to a ridiculously low value */
    ESCDELAY = 10;

    /* Activate colour */
    start_color();

    /* If COLORS == 16, it means the terminal supports full bright colours
     * using setab and setaf (will use \e[90m \e[91m etc. for colours >= 8),
     * we can build 16*16 colour pairs.
     * If COLORS == 8, it means the terminal does not know about bright
     * colours and we need to get them through A_BOLD and A_BLINK (\e[1m
     * and \e[5m). We can only build 8*8 colour pairs. */
    max = COLORS >= 16 ? 16 : 8;

    for(bg = 0; bg < max; bg++)
        for(fg = 0; fg < max; fg++)
        {
            /* Use ((max + 7 - fg) % max) instead of fg so that colour 0
             * is light gray on black. Some terminals don't like this
             * colour pair to be redefined. */
            int col = ((max + 7 - fg) % max) + max * bg;
            init_pair(col, curses_colors[fg], curses_colors[bg]);
            dp->drv.p->attr[fg + 16 * bg] = COLOR_PAIR(col);

            if(max == 8)
            {
                /* Bright fg on simple bg */
                dp->drv.p->attr[fg + 8 + 16 * bg] = A_BOLD | COLOR_PAIR(col);
                /* Simple fg on bright bg */
                dp->drv.p->attr[fg + 16 * (bg + 8)] = A_BLINK
                                                    | COLOR_PAIR(col);
                /* Bright fg on bright bg */
                dp->drv.p->attr[fg + 8 + 16 * (bg + 8)] = A_BLINK | A_BOLD
                                                        | COLOR_PAIR(col);
            }
        }

    caca_add_dirty_rect(dp->cv, 0, 0, dp->cv->width, dp->cv->height);
    dp->resize.allow = 1;
    caca_set_canvas_size(dp->cv, COLS, LINES);
    dp->resize.allow = 0;

    return 0;
}
コード例 #11
0
ファイル: win32.c プロジェクト: mwgoldsmith/caca
static int win32_init_graphics(caca_display_t *dp)
{
    int width = caca_get_canvas_width(dp->cv);
    int height = caca_get_canvas_height(dp->cv);
    CONSOLE_SCREEN_BUFFER_INFO csbi;
    SMALL_RECT rect;
    COORD size;

    dp->drv.p = malloc(sizeof(struct driver_private));

    /* This call is allowed to fail in case we already have a console */
    AllocConsole();

    dp->drv.p->hin = GetStdHandle(STD_INPUT_HANDLE);
    dp->drv.p->hout = CreateFile("CONOUT$", GENERIC_READ | GENERIC_WRITE,
                                 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
                                 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    if(dp->drv.p->hout == INVALID_HANDLE_VALUE)
        return -1;

    GetConsoleCursorInfo(dp->drv.p->hout, &dp->drv.p->cci);
    dp->drv.p->cci.bVisible = FALSE;
    SetConsoleCursorInfo(dp->drv.p->hout, &dp->drv.p->cci);

    SetConsoleMode(dp->drv.p->hout, ENABLE_MOUSE_INPUT);

    dp->drv.p->screen =
        CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE,
                                  0, NULL, CONSOLE_TEXTMODE_BUFFER, NULL);
    if(!dp->drv.p->screen || dp->drv.p->screen == INVALID_HANDLE_VALUE)
        return -1;

    /* Set the new console size */
    size.X = width ? width : 80;
    size.Y = height ? height : 25;
    SetConsoleScreenBufferSize(dp->drv.p->screen, size);

    rect.Left = rect.Top = 0;
    rect.Right = size.X - 1;
    rect.Bottom = size.Y - 1;
    SetConsoleWindowInfo(dp->drv.p->screen, TRUE, &rect);

    /* Report our new size to libcaca */
    if(!GetConsoleScreenBufferInfo(dp->drv.p->screen, &csbi))
        return -1;

    dp->resize.allow = 1;
    caca_set_canvas_size(dp->cv,
                          csbi.srWindow.Right - csbi.srWindow.Left + 1,
                          csbi.srWindow.Bottom - csbi.srWindow.Top + 1);
    width = caca_get_canvas_width(dp->cv);
    height = caca_get_canvas_height(dp->cv);
    dp->resize.allow = 0;

    SetConsoleMode(dp->drv.p->screen, 0);

    GetConsoleCursorInfo(dp->drv.p->screen, &dp->drv.p->cci);
    dp->drv.p->cci.dwSize = 0;
    dp->drv.p->cci.bVisible = FALSE;
    SetConsoleCursorInfo(dp->drv.p->screen, &dp->drv.p->cci);

    SetConsoleActiveScreenBuffer(dp->drv.p->screen);

    dp->drv.p->buffer = malloc(width * height
                               * sizeof(CHAR_INFO));
    if(dp->drv.p->buffer == NULL)
        return -1;

    return 0;
}
コード例 #12
0
ファイル: slang.c プロジェクト: mwgoldsmith/caca
static int slang_init_graphics(caca_display_t *dp)
{
    dp->drv.p = malloc(sizeof(struct driver_private));
    dp->drv.p->sigint_event = 0;

#if defined(HAVE_GETENV) && defined(HAVE_PUTENV)
    slang_install_terminal(dp);
#endif

#if defined(HAVE_SIGNAL)
    sigwinch_d = dp;
    signal(SIGWINCH, sigwinch_handler);
#endif

    _caca_set_term_title("caca for S-Lang");

    /* Initialise slang library */
    SLsig_block_signals();
    /* Disable SLang's own SIGINT on ctrl-c */
    SLang_set_abort_signal(default_sigint);

    SLtt_get_terminfo();

    if(SLkp_init() == -1)
    {
        SLsig_unblock_signals();
        return -1;
    }

    SLang_init_tty(-1, 0, 1);

    if(SLsmg_init_smg() == -1)
    {
        SLsig_unblock_signals();
        return -1;
    }

    SLsmg_cls();
    SLtt_set_cursor_visibility(0);
    SLkp_define_keysym("\e[M", 1001);
    SLtt_set_mouse_mode(1, 0);
    SLsmg_refresh();

    /* Disable scrolling so that hashmap scrolling optimization code
     * does not cause ugly refreshes due to slow terminals */
    SLtt_Term_Cannot_Scroll = 1;

    slang_init_palette();

#if defined(VMS) || defined(REAL_UNIX_SYSTEM)
    /* Disable alt charset support so that we get a chance to have all
     * 256 colour pairs */
    SLtt_Has_Alt_Charset = 0;
#endif

#ifdef HAVE_SLSMG_UTF8_ENABLE
    SLsmg_utf8_enable(1); /* 1 == force, 0 == disable, -1 == autodetect */
    SLtt_utf8_enable(1);
#endif

    caca_add_dirty_rect(dp->cv, 0, 0, dp->cv->width, dp->cv->height);
    dp->resize.allow = 1;
    caca_set_canvas_size(dp->cv, SLtt_Screen_Cols, SLtt_Screen_Rows);
    dp->resize.allow = 0;

    SLsig_unblock_signals();

    return 0;
}
コード例 #13
0
ファイル: cacademo.c プロジェクト: zougloub/libcaca
int main(int argc, char **argv)
{
    static caca_display_t *dp;
    static caca_canvas_t *frontcv, *backcv, *mask;

    int demo, next = -1, paused = 0, next_transition = DEMO_FRAMES;
    unsigned int i;
    int tmode = caca_rand(0, TRANSITION_COUNT);

    /* Set up two canvases, a mask, and attach a display to the front one */
    frontcv = caca_create_canvas(0, 0);
    backcv = caca_create_canvas(0, 0);
    mask = caca_create_canvas(0, 0);

    dp = caca_create_display(frontcv);
    if(!dp)
        return 1;

    caca_set_canvas_size(backcv, caca_get_canvas_width(frontcv),
                         caca_get_canvas_height(frontcv));
    caca_set_canvas_size(mask, caca_get_canvas_width(frontcv),
                         caca_get_canvas_height(frontcv));

    caca_set_display_time(dp, 20000);

    /* Initialise all demos' lookup tables */
    for(i = 0; i < DEMOS; i++)
        fn[i](PREPARE, frontcv);

    /* Choose a demo at random */
    demo = caca_rand(0, DEMOS);
    fn[demo](INIT, frontcv);

    for(;;)
    {
        /* Handle events */
        caca_event_t ev;
        while(caca_get_event(dp, CACA_EVENT_KEY_PRESS
                             | CACA_EVENT_QUIT, &ev, 0))
        {
            if(caca_get_event_type(&ev) == CACA_EVENT_QUIT)
                goto end;

            switch(caca_get_event_key_ch(&ev))
            {
            case CACA_KEY_ESCAPE:
            case CACA_KEY_CTRL_C:
            case CACA_KEY_CTRL_Z:
                goto end;
            case ' ':
                paused = !paused;
                break;
            case '\r':
                if(next == -1)
                    next_transition = frame;
                break;
            }
        }

        /* Resize the spare canvas, just in case the main one changed */
        caca_set_canvas_size(backcv, caca_get_canvas_width(frontcv),
                             caca_get_canvas_height(frontcv));
        caca_set_canvas_size(mask, caca_get_canvas_width(frontcv),
                             caca_get_canvas_height(frontcv));

        if(paused)
            goto _paused;

        /* Update demo's data */
        fn[demo](UPDATE, frontcv);

        /* Handle transitions */
        if(frame == next_transition)
        {
            next = caca_rand(0, DEMOS);
            if(next == demo)
                next = (next + 1) % DEMOS;
            fn[next](INIT, backcv);
        }
        else if(frame == next_transition + TRANSITION_FRAMES)
        {
            fn[demo](FREE, frontcv);
            demo = next;
            next = -1;
            next_transition = frame + DEMO_FRAMES;
            tmode = caca_rand(0, TRANSITION_COUNT);
        }

        if(next != -1)
            fn[next](UPDATE, backcv);

        frame++;
_paused:
        /* Render main demo's canvas */
        fn[demo](RENDER, frontcv);

        /* If a transition is on its way, render it */
        if(next != -1)
        {
            fn[next](RENDER, backcv);
            caca_set_color_ansi(mask, CACA_LIGHTGRAY, CACA_BLACK);
            caca_clear_canvas(mask);
            caca_set_color_ansi(mask, CACA_WHITE, CACA_WHITE);
            transition(mask, tmode,
                       100 * (frame - next_transition) / TRANSITION_FRAMES);
            caca_blit(frontcv, 0, 0, backcv, mask);
        }

        caca_set_color_ansi(frontcv, CACA_WHITE, CACA_BLUE);
        if(frame < 100)
            caca_put_str(frontcv, caca_get_canvas_width(frontcv) - 30,
                         caca_get_canvas_height(frontcv) - 2,
                         " -=[ Powered by libcaca ]=- ");
        caca_refresh_display(dp);
    }
end:
    if(next != -1)
        fn[next](FREE, frontcv);
    fn[demo](FREE, frontcv);

    caca_free_display(dp);
    caca_free_canvas(mask);
    caca_free_canvas(backcv);
    caca_free_canvas(frontcv);

    return 0;
}
コード例 #14
0
ファイル: figfont.c プロジェクト: HuxyUK/libcaca
/** \brief paste a character using the current figfont */
int caca_put_figchar(caca_canvas_t *cv, uint32_t ch)
{
    caca_charfont_t *ff = cv->ff;
    int c, w, h, x, y, overlap, extra, xleft, xright;

    if (!ff)
        return -1;

    switch(ch)
    {
        case (uint32_t)'\r':
            return 0;
        case (uint32_t)'\n':
            ff->x = 0;
            ff->y += ff->height;
            return 0;
        /* FIXME: handle '\t' */
    }

    /* Look whether our glyph is available */
    for(c = 0; c < ff->glyphs; c++)
        if(ff->lookup[c * 2] == ch)
            break;

    if(c == ff->glyphs)
        return 0;

    w = ff->lookup[c * 2 + 1];
    h = ff->height;

    caca_set_canvas_handle(ff->fontcv, 0, c * ff->height);
    caca_blit(ff->charcv, 0, 0, ff->fontcv, NULL);

    /* Check whether we reached the end of the screen */
    if(ff->x && ff->x + w > ff->term_width)
    {
        ff->x = 0;
        ff->y += h;
    }

    /* Compute how much the next character will overlap */
    switch(ff->hmode)
    {
    case H_SMUSH:
    case H_KERN:
    case H_OVERLAP:
        extra = (ff->hmode == H_OVERLAP);
        overlap = w;
        for(y = 0; y < h; y++)
        {
            /* Compute how much spaces we can eat from the new glyph */
            for(xright = 0; xright < overlap; xright++)
                if(caca_get_char(ff->charcv, xright, y) != ' ')
                    break;

            /* Compute how much spaces we can eat from the previous glyph */
            for(xleft = 0; xright + xleft < overlap && xleft < ff->x; xleft++)
                if(caca_get_char(cv, ff->x - 1 - xleft, ff->y + y) != ' ')
                    break;

            /* Handle overlapping */
            if(ff->hmode == H_OVERLAP && xleft < ff->x)
                xleft++;

            /* Handle smushing */
            if(ff->hmode == H_SMUSH)
            {
                if(xleft < ff->x &&
                    hsmush(caca_get_char(cv, ff->x - 1 - xleft, ff->y + y),
                          caca_get_char(ff->charcv, xright, y),
                          ff->hsmushrule))
                    xleft++;
            }

            if(xleft + xright < overlap)
                overlap = xleft + xright;
        }
        break;
    case H_NONE:
        overlap = 0;
        break;
    default:
        return -1;
    }

    /* Check whether the current canvas is large enough */
    if(ff->x + w - overlap > ff->w)
        ff->w = ff->x + w - overlap < ff->term_width
              ? ff->x + w - overlap : ff->term_width;

    if(ff->y + h > ff->h)
        ff->h = ff->y + h;

#if 0 /* deactivated for libcaca insertion */
    if(attr)
        caca_set_attr(cv, attr);
#endif
    caca_set_canvas_size(cv, ff->w, ff->h);

    /* Render our char (FIXME: create a rect-aware caca_blit_canvas?) */
    for(y = 0; y < h; y++)
        for(x = 0; x < w; x++)
    {
        uint32_t ch1, ch2;
        uint32_t tmpat = caca_get_attr(ff->fontcv, x, y + c * ff->height);
        ch2 = caca_get_char(ff->charcv, x, y);
        if(ch2 == ' ')
            continue;
        ch1 = caca_get_char(cv, ff->x + x - overlap, ff->y + y);
        if(ch1 == ' ' || ff->hmode != H_SMUSH)
            caca_put_char(cv, ff->x + x - overlap, ff->y + y, ch2);
        else
            caca_put_char(cv, ff->x + x - overlap, ff->y + y,
                           hsmush(ch1, ch2, ff->hsmushrule));
        caca_put_attr(cv, ff->x + x, ff->y + y, tmpat);
    }

    /* Advance cursor */
    ff->x += w - overlap;

    return 0;
}
コード例 #15
0
JNIEXPORT void JNICALL
Java_org_zoy_caca_Canvas_setCanvasSize(JNIEnv *env, jclass cls, jlong ptr, jint w, jint h)
{
    caca_set_canvas_size((caca_canvas_t *)ptr, w, h);
}