Beispiel #1
0
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;
}
Beispiel #2
0
static void filter_rainbow(context_t *cx)
{
    static unsigned char const rainbow[] =
    {
        CACA_LIGHTMAGENTA, CACA_LIGHTRED, CACA_YELLOW,
        CACA_LIGHTGREEN, CACA_LIGHTCYAN, CACA_LIGHTBLUE,
    };
    unsigned int x, y, w, h;

    w = caca_get_canvas_width(cx->torender);
    h = caca_get_canvas_height(cx->torender);

    for(y = 0; y < h; y++)
        for(x = 0; x < w; x++)
    {
        unsigned long int ch = caca_get_char(cx->torender, x, y);
        if(ch != (unsigned char)' ')
        {
            caca_set_color_ansi(cx->torender,
                                 rainbow[(x / 2 + y + cx->lines) % 6],
                                 CACA_TRANSPARENT);
            caca_put_char(cx->torender, x, y, ch);
        }
    }
}
Beispiel #3
0
static void filter_america(context_t *cx)
{
    unsigned int x, y, w, h, flag_w, flag_h;
    unsigned char color;

    w = caca_get_canvas_width(cx->torender);
    h = caca_get_canvas_height(cx->torender);
    flag_w = w * 3 / 7;
    flag_h = h * 1 / 3;
    /* flag_w = w; flag_h = h; */

    for(y = 0; y < h; y++)
        for(x = 0; x < w; x++)
    {
        unsigned long int ch = caca_get_char(cx->torender, x, y);

        if(ch == (unsigned char)' ')
            continue;

        if((x < flag_w) && (y < flag_h))
            // @todo this really needs to be better.
            color = ((x + y) % 2 && y % 2) ? CACA_WHITE : CACA_BLUE;
        else
            color = (y % 2) ? CACA_WHITE : CACA_RED;

        caca_set_color_ansi(cx->torender, color, CACA_TRANSPARENT);
        caca_put_char(cx->torender, x, y, ch);
    }
}
Beispiel #4
0
/** \brief Print a string.
 *
 *  Print an UTF-8 string at the given coordinates, using the default
 *  foreground and background values. The coordinates may be outside the
 *  canvas boundaries (eg. a negative Y coordinate) and the string will
 *  be cropped accordingly if it is too long.
 *
 *  See caca_put_char() for more information on how fullwidth characters
 *  are handled when overwriting each other or at the canvas' boundaries.
 *
 *  This function returns the number of cells printed by the string. It is
 *  not the number of characters printed, because fullwidth characters
 *  account for two cells.
 *
 *  This function never fails.
 *
 *  \param cv A handle to the libcaca canvas.
 *  \param x X coordinate.
 *  \param y Y coordinate.
 *  \param s The string to print.
 *  \return The number of cells printed.
 */
int caca_put_str(caca_canvas_t *cv, int x, int y, char const *s)
{
    size_t rd;
    int len = 0;

    if (y < 0 || y >= (int)cv->height || x >= (int)cv->width)
    {
        while (*s)
        {
            len += caca_utf32_is_fullwidth(caca_utf8_to_utf32(s, &rd)) ? 2 : 1;
            s += rd ? rd : 1;
        }
        return len;
    }

    while (*s)
    {
        uint32_t ch = caca_utf8_to_utf32(s, &rd);

        if (x + len >= -1 && x + len < (int)cv->width)
            caca_put_char(cv, x + len, y, ch);

        len += caca_utf32_is_fullwidth(ch) ? 2 : 1;
        s += rd ? rd : 1;
    }

    return len;
}
Beispiel #5
0
/** \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;
}
Beispiel #6
0
static void filter_metal(context_t *cx)
{
    static unsigned char const palette[] =
    {
        CACA_LIGHTBLUE, CACA_BLUE, CACA_LIGHTGRAY, CACA_DARKGRAY,
    };

    unsigned int x, y, w, h;

    w = caca_get_canvas_width(cx->torender);
    h = caca_get_canvas_height(cx->torender);

    for(y = 0; y < h; y++)
        for(x = 0; x < w; x++)
    {
        unsigned long int ch = caca_get_char(cx->torender, x, y);
        int i;

        if(ch == (unsigned char)' ')
            continue;

        i = ((cx->lines + y + x / 8) / 2) % 4;
        caca_set_color_ansi(cx->torender, palette[i], CACA_TRANSPARENT);
        caca_put_char(cx->torender, x, y, ch);
    }
}
Beispiel #7
0
void CacaWrapperGui::drawPixel(Point<int> const &point,
                               Color<unsigned char> const &color) {
    unsigned char moy = 0;
    moy += color.getRed();
    moy += color.getBlue();
    moy += color.getGreen();
    moy %= 26;
    caca_set_color_ansi(_cv, CACA_BLACK, CACA_WHITE);
    caca_put_char(_cv, point.getX() / MAP_TILE, point.getY() / MAP_TILE, moy + 'A');

}
Beispiel #8
0
static int draw_box(caca_canvas_t *cv, int x, int y, int w, int h,
                    uint32_t const *chars)
{
    int i, j, xmax, ymax;

    int x2 = x + w - 1;
    int y2 = y + h - 1;

    if(x > x2)
    {
        int tmp = x;
        x = x2; x2 = tmp;
    }

    if(y > y2)
    {
        int tmp = y;
        y = y2; y2 = tmp;
    }

    xmax = cv->width - 1;
    ymax = cv->height - 1;

    if(x2 < 0 || y2 < 0 || x > xmax || y > ymax)
        return 0;

    /* Draw edges */
    if(y >= 0)
        for(i = x < 0 ? 1 : x + 1; i < x2 && i < xmax; i++)
            caca_put_char(cv, i, y, chars[0]);

    if(y2 <= ymax)
        for(i = x < 0 ? 1 : x + 1; i < x2 && i < xmax; i++)
            caca_put_char(cv, i, y2, chars[0]);

    if(x >= 0)
        for(j = y < 0 ? 1 : y + 1; j < y2 && j < ymax; j++)
            caca_put_char(cv, x, j, chars[1]);

    if(x2 <= xmax)
        for(j = y < 0 ? 1 : y + 1; j < y2 && j < ymax; j++)
            caca_put_char(cv, x2, j, chars[1]);

    /* Draw corners */
    caca_put_char(cv, x, y, chars[2]);
    caca_put_char(cv, x, y2, chars[3]);
    caca_put_char(cv, x2, y, chars[4]);
    caca_put_char(cv, x2, y2, chars[5]);

    return 0;
}
Beispiel #9
0
/** \brief Fill a box on the canvas using the given character.
 *
 *  This function never fails.
 *
 *  \param cv The handle to the libcaca canvas.
 *  \param x X coordinate of the upper-left corner of the box.
 *  \param y Y coordinate of the upper-left corner of the box.
 *  \param w Width of the box.
 *  \param h Height of the box.
 *  \param ch UTF-32 character to be used to draw the box.
 *  \return This function always returns 0.
 */
int caca_fill_box(caca_canvas_t *cv, int x, int y, int w, int h,
                   uint32_t ch)
{
    int i, j, xmax, ymax;

    int x2 = x + w - 1;
    int y2 = y + h - 1;

    if(x > x2)
    {
        int tmp = x;
        x = x2; x2 = tmp;
    }

    if(y > y2)
    {
        int tmp = y;
        y = y2; y2 = tmp;
    }

    xmax = cv->width - 1;
    ymax = cv->height - 1;

    if(x2 < 0 || y2 < 0 || x > xmax || y > ymax)
        return 0;

    if(x < 0) x = 0;
    if(y < 0) y = 0;
    if(x2 > xmax) x2 = xmax;
    if(y2 > ymax) y2 = ymax;

#if 0
    /* FIXME: this fails with fullwidth character blits. Also, the dirty
     * rectangle handling may miss fullwidth cells. */
    /* Optimise dirty rectangle handling, part 1 */
    cv->dirty_disabled++;
#endif

    for(j = y; j <= y2; j++)
        for(i = x; i <= x2; i++)
            caca_put_char(cv, i, j, ch);

#if 0
    /* Optimise dirty rectangle handling, part 2 */
    cv->dirty_disabled--;
    if(!cv->dirty_disabled)
        caca_add_dirty_rect(cv, x, y, x2 - x + 1, y2 - y + 1);
#endif

    return 0;
}
Beispiel #10
0
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;
}
Beispiel #11
0
void CacaWrapperGui::drawBuffer(Point<int> const &point,
                                Buffer<unsigned char> const &buffer) {
    size_t width = buffer.getWidth();
    size_t height = buffer.getHeight();
    int nbPixBuff = 0;
    uint32_t moyR = 0;
    uint32_t moyG = 0;
    uint32_t moyB = 0;
    uint16_t color;

    for (size_t i = 0; i < height; ++i)
    {
        for (size_t j = 0; j < width; ++j)
        {
            Color<unsigned char> color = buffer.getPixel(j, i);
            moyR += color.getRed() / (255 / 16);
            moyB += color.getBlue() / (255 / 16);
            moyG += color.getGreen() / (255 / 16);
            nbPixBuff++;
        }
    }
    moyR /= nbPixBuff;
    moyB /= nbPixBuff;
    moyG /= nbPixBuff;
    color = 15;
    color <<= 4;
    color += moyR;
    color <<= 4;
    color += moyG;
    color <<= 4;
    color += moyB;
    moyG %= 26;

    caca_set_color_argb(_cv, color, CACA_BLACK);
    caca_put_char(_cv, point.getX() / MAP_TILE, point.getY() / MAP_TILE, moyG + 'A');
}
Beispiel #12
0
int main(int argc, char *argv[])
{
    caca_canvas_t *cv, *image, *tmp, *sprite;
    caca_display_t *dp;

    cv = caca_create_canvas(0, 0);
    if(cv == NULL)
    {
        printf("Can't created canvas\n");
        return -1;
    }
    dp = caca_create_display(cv);
    if(dp == NULL)
    {
        printf("Can't create display\n");
        return -1;
    }

    image = caca_create_canvas(70, 6);
    tmp = caca_create_canvas(70, 6);
    sprite = caca_create_canvas(0, 0);

    caca_set_color_ansi(sprite, CACA_LIGHTMAGENTA, CACA_BLACK);
    caca_import_canvas_from_memory(sprite, pig, strlen(pig), "text");
    caca_blit(image, 55, 0, sprite, NULL);

    caca_set_color_ansi(sprite, CACA_LIGHTGREEN, CACA_BLACK);
    caca_import_canvas_from_memory(sprite, duck, strlen(duck), "text");
    caca_blit(image, 30, 1, sprite, NULL);

    caca_set_color_ansi(image, CACA_LIGHTCYAN, CACA_BLACK);
    caca_put_str(image, 1, 1, "hahaha mais vieux porc immonde !! [⽼ ⾗]");
    caca_set_color_ansi(image, CACA_LIGHTRED, CACA_BLACK);
    caca_put_char(image, 38, 1, '|');

    caca_set_color_ansi(image, CACA_YELLOW, CACA_BLACK);
    caca_put_str(image, 4, 2, "\\o\\ \\o| _o/ \\o_ |o/ /o/");

    caca_set_color_ansi(image, CACA_WHITE, CACA_LIGHTRED);
    caca_put_str(image, 7, 3, "▙▘▌▙▘▞▖▞▖▌ ▞▖▌ ▌▌");
    caca_put_str(image, 7, 4, "▛▖▌▛▖▚▘▚▘▚▖▚▘▚▖▖▖");
    caca_set_color_ansi(image, CACA_BLACK, CACA_LIGHTRED);
    caca_put_str(image, 4, 3, "▓▒░");
    caca_put_str(image, 4, 4, "▓▒░");
    caca_put_str(image, 24, 3, "░▒▓");
    caca_put_str(image, 24, 4, "░▒▓");

    /* Blit the transformed canvas onto the main canvas */
    caca_set_color_ansi(cv, CACA_WHITE, CACA_BLUE);
    caca_put_str(cv, 0, 0, "normal");
    caca_blit(cv, 10, 0, image, NULL);

    caca_put_str(cv, 0, 6, "flip");
    caca_blit(tmp, 0, 0, image, NULL);
    caca_flip(tmp);
    caca_blit(cv, 10, 6, tmp, NULL);

    caca_put_str(cv, 0, 12, "flop");
    caca_blit(tmp, 0, 0, image, NULL);
    caca_flop(tmp);
    caca_blit(cv, 10, 12, tmp, NULL);

    caca_put_str(cv, 0, 18, "rotate");
    caca_blit(tmp, 0, 0, image, NULL);
    caca_rotate_180(tmp);
    caca_blit(cv, 10, 18, tmp, NULL);

    caca_refresh_display(dp);

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

    caca_free_display(dp);
    caca_free_canvas(tmp);
    caca_free_canvas(sprite);
    caca_free_canvas(image);
    caca_free_canvas(cv);

    return 0;
}
Beispiel #13
0
int cucul_putchar(cucul_canvas_t *cv, int x, int y, unsigned long int ch)
{
    return caca_put_char(cv, x, y, ch);
}
Beispiel #14
0
/** \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;
}
Beispiel #15
0
JNIEXPORT void JNICALL
Java_org_zoy_caca_Canvas_putCanvasChar(JNIEnv *env, jclass cls, jlong ptr, jint x, jint y, jint ch)
{
    caca_put_char((caca_canvas_t *)ptr, x, y, ch);
}
Beispiel #16
0
int main(void)
{
  caca_canvas_t *cv;
  caca_display_t *dp;
  caca_event_t ev;

  // Create canvas and display
  cv = caca_create_canvas(100,80);
  if(!cv) return 1;

  dp = caca_create_display_with_driver(cv, "ncurses");
  if(!dp) return 1;

  caca_set_display_title(dp, "WPC 66");
  caca_set_color_ansi(cv, CACA_WHITE, CACA_BLACK);

  // Tree stump
  caca_fill_box (cv, 47, 50, 6, 4, '|');

  // Tree body
  caca_draw_thin_triangle (cv,50,10,10,50,90,50);

  // Pot
  caca_fill_triangle(cv, 35, 53, 40, 60, 40, 53, '@');
  caca_fill_box(cv, 40, 53, 19, 8, '@');
  caca_fill_triangle(cv, 59, 60, 64, 53, 59, 53, '@');

  // Balls
  int balls[] = {50, 25, 35, 35, 25, 43, 58, 32, 68, 41, 50, 46};
  for (int i = 0; i <= 10; i += 2)
      caca_draw_thin_ellipse(cv, balls[i], balls[i+1], 2, 2);

  // Sparkly stuff
  int sparks[] = {54, 20, 42, 30, 40, 45, 46, 38, 60, 43, 75, 48};
  for (int i = 0; i <= 10; i += 2)
  {
    caca_put_char(cv, sparks[i], sparks[i+1], '*');
    caca_put_char(cv, sparks[i]-1, sparks[i+1], '<');
    caca_put_char(cv, sparks[i]+1, sparks[i+1], '>');
    caca_put_char(cv, sparks[i], sparks[i+1]-1, '^');
    caca_put_char(cv, sparks[i], sparks[i+1]+1, 'v');
  }

  // Guirlandes
  caca_draw_thin_line(cv, 32, 44, 70, 35);
  caca_draw_thin_line(cv, 17, 49, 30, 46);
  caca_draw_thin_line(cv, 60, 47, 80, 43);
  caca_draw_thin_line(cv, 43, 35, 52, 33);
  caca_draw_thin_line(cv, 55, 28, 60, 27);
  caca_draw_thin_line(cv, 40, 25, 45, 24);

  // Star outline
  caca_fill_triangle(cv, 50, 16, 40, 10, 60, 10, ' ');
  int star_x[] = {50, 45, 40, 45, 40, 45, 50, 55, 60, 55, 60, 55, 50};
  int star_y[] = { 4,  7,  7, 10, 13, 13, 16, 13, 13, 10,  7,  7,  4};
  caca_draw_thin_polyline(cv, star_x, star_y, 12);

  // Inside of star
  int star[] = {50,8,50,9,50,10,50,11,50,12,49,9,48,9,51,9,52,9,49,10,51,10,49,11,48,11,51,11,52,11};
  for (int i = 0; i <= 29; i += 2)
      caca_put_char(cv, star[i], star[i+1], '*');

  // Display and wait for key press
  caca_refresh_display(dp);
  caca_get_event(dp, CACA_EVENT_KEY_PRESS, &ev, -1);
  caca_free_display(dp);
  return 0;
}
Beispiel #17
0
int main(int argc, char *argv[])
{
    caca_canvas_t *cv, *caca, *line;
    caca_display_t *dp;

    unsigned int i;

    cv = caca_create_canvas(0, 0);
    if(cv == NULL)
    {
        printf("Can't created canvas\n");
        return -1;
    }
    dp = caca_create_display(cv);
    if(dp == NULL)
    {
        printf("Can't create display\n");
        return -1;
    }

    caca = caca_create_canvas(6, 10);
    line = caca_create_canvas(2, 1);

    /* Line of x's */
    for(i = 0; i < 10; i++)
    {
        caca_set_color_ansi(caca, CACA_WHITE, CACA_BLUE);
        caca_put_str(caca, 0, i, CACA);
        caca_set_color_ansi(caca, CACA_WHITE, CACA_RED);
        caca_put_char(caca, i - 2, i, 'x');
    }

    caca_blit(cv, 1, 1, caca, NULL);

    /* Line of ホ's */
    for(i = 0; i < 10; i++)
    {
        caca_set_color_ansi(caca, CACA_WHITE, CACA_BLUE);
        caca_put_str(caca, 0, i, CACA);
        caca_set_color_ansi(caca, CACA_WHITE, CACA_GREEN);
        caca_put_str(caca, i - 2, i, "ホ");
    }

    caca_blit(cv, 15, 1, caca, NULL);

    /* Line of canvas */
    caca_set_color_ansi(line, CACA_WHITE, CACA_MAGENTA);
    caca_put_str(line, 0, 0, "ほ");
    for(i = 0; i < 10; i++)
    {
        caca_set_color_ansi(caca, CACA_WHITE, CACA_BLUE);
        caca_put_str(caca, 0, i, CACA);
        caca_blit(caca, i - 2, i, line, NULL);
    }

    caca_blit(cv, 29, 1, caca, NULL);

    caca_refresh_display(dp);

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

    caca_free_display(dp);

    caca_free_canvas(line);
    caca_free_canvas(caca);
    caca_free_canvas(cv);

    return 0;
}
Beispiel #18
0
void langton(enum action action, caca_canvas_t *cv)
{
    static char gradient[] =
    {
        ' ', ' ', '.', '.', ':', ':', 'x', 'x',
        'X', 'X', '&', '&', 'W', 'W', '@', '@',
    };
    static int steps[][2] = { { 0, 1 }, { 1, 0 }, { 0, -1 }, { -1, 0 } };
    static uint8_t *screen;
    static int width, height;
    static int ax[ANTS], ay[ANTS], dir[ANTS];

    int i, a, x, y;

    switch(action)
    {
    case PREPARE:
        width = caca_get_canvas_width(cv);
        height = caca_get_canvas_height(cv);
        for(i = 0; i < ANTS; i++)
        {
            ax[i] = caca_rand(0, width);
            ay[i] = caca_rand(0, height);
            dir[i] = caca_rand(0, 4);
        }
        break;

    case INIT:
        screen = malloc(width * height);
        memset(screen, 0, width * height);
        break;

    case UPDATE:
        for(i = 0; i < ITER; i++)
        {
            for(x = 0; x < width * height; x++)
            {
                uint8_t p = screen[x];
                if((p & 0x0f) > 1)
                    screen[x] = p - 1;
            }

            for(a = 0; a < ANTS; a++)
            {
                uint8_t p = screen[ax[a] + width * ay[a]];

                if(p & 0x0f)
                {
                    dir[a] = (dir[a] + 1) % 4;
                    screen[ax[a] + width * ay[a]] = a << 4;
                }
                else
                {
                    dir[a] = (dir[a] + 3) % 4;
                    screen[ax[a] + width * ay[a]] = (a << 4) | 0x0f;
                }
                ax[a] = (width + ax[a] + steps[dir[a]][0]) % width;
                ay[a] = (height + ay[a] + steps[dir[a]][1]) % height;
            }
        }
        break;

    case RENDER:
        for(y = 0; y < height; y++)
        {
            for(x = 0; x < width; x++)
            {
                uint8_t p = screen[x + width * y];

                if(p & 0x0f)
                    caca_set_color_ansi(cv, CACA_WHITE, p >> 4);
                else
                    caca_set_color_ansi(cv, CACA_BLACK, CACA_BLACK);
                caca_put_char(cv, x, y, gradient[p & 0x0f]);
            }
        }
        break;

    case FREE:
        free(screen);
        break;
    }
Beispiel #19
0
static caca_charfont_t * open_charfont(char const *path)
{
    char buf[2048];
    char hardblank[10];
    caca_charfont_t *ff;
    char *data = NULL;
    caca_file_t *f;
#if !defined __KERNEL__ && (defined HAVE_SNPRINTF || defined HAVE_SPRINTF_S)
    int const pathlen = 2048;
    char *altpath = NULL;
#endif
    int i, j, size, comment_lines;

    ff = malloc(sizeof(caca_charfont_t));
    if(!ff)
    {
        seterrno(ENOMEM);
        return NULL;
    }

    /* Open font: if not found, try .tlf, then .flf */
    f = caca_file_open(path, "r");
#if !defined __KERNEL__ && (defined HAVE_SNPRINTF || defined HAVE_SPRINTF_S)
    if(!f)
        altpath = malloc(pathlen);
    if(!f)
    {
#if defined HAVE_SPRINTF_S
        sprintf_s(altpath, pathlen - 1, "%s.tlf", path);
#else
        snprintf(altpath, pathlen - 1, "%s.tlf", path);
#endif
        altpath[pathlen - 1] = '\0';
        f = caca_file_open(altpath, "r");
    }
    if(!f)
    {
#if defined HAVE_SPRINTF_S
        sprintf_s(altpath, pathlen - 1, "%s.flf", path);
#else
        snprintf(altpath, pathlen - 1, "%s.flf", path);
#endif
        altpath[pathlen - 1] = '\0';
        f = caca_file_open(altpath, "r");
    }
    if (altpath)
        free(altpath);
#endif
    if(!f)
    {
        free(ff);
        seterrno(ENOENT);
        return NULL;
    }

    /* Read header */
    ff->print_direction = 0;
    ff->full_layout = 0;
    ff->codetag_count = 0;
    caca_file_gets(f, buf, 2048);
    if(sscanf(buf, "%*[ft]lf2a%6s %u %u %u %i %u %u %u %u\n", hardblank,
              &ff->height, &ff->baseline, &ff->max_length,
              &ff->old_layout, &comment_lines, &ff->print_direction,
              &ff->full_layout, &ff->codetag_count) < 6)
    {
        debug("figfont error: `%s' has invalid header: %s", path, buf);
        caca_file_close(f);
        free(ff);
        seterrno(EINVAL);
        return NULL;
    }

    if(ff->old_layout < -1 || ff->old_layout > 63 || ff->full_layout > 32767
        || ((ff->full_layout & 0x80) && (ff->full_layout & 0x3f) == 0
            && ff->old_layout))
    {
        debug("figfont error: `%s' has invalid layout %i/%u",
                path, ff->old_layout, ff->full_layout);
        caca_file_close(f);
        free(ff);
        seterrno(EINVAL);
        return NULL;
    }

    ff->hardblank = caca_utf8_to_utf32(hardblank, NULL);

    /* Skip comment lines */
    for(i = 0; i < comment_lines; i++)
        caca_file_gets(f, buf, 2048);

    /* Read mandatory characters (32-127, 196, 214, 220, 228, 246, 252, 223)
     * then read additional characters. */
    ff->glyphs = 0;
    ff->lookup = NULL;

    for(i = 0, size = 0; !caca_file_eof(f); ff->glyphs++)
    {
        if((ff->glyphs % 2048) == 0)
            ff->lookup = realloc(ff->lookup,
                                   (ff->glyphs + 2048) * 2 * sizeof(int));

        if(ff->glyphs < STD_GLYPHS)
        {
            ff->lookup[ff->glyphs * 2] = 32 + ff->glyphs;
        }
        else if(ff->glyphs < EXT_GLYPHS)
        {
            static int const tab[7] = { 196, 214, 220, 228, 246, 252, 223 };
            ff->lookup[ff->glyphs * 2] = tab[ff->glyphs - STD_GLYPHS];
        }
        else
        {
            unsigned int tmp;

            if(caca_file_gets(f, buf, 2048) == NULL)
                break;

            /* Ignore blank lines, as in jacky.flf */
            if(buf[0] == '\n' || buf[0] == '\r')
                continue;

            /* Ignore negative indices for now, as in ivrit.flf */
            if(buf[0] == '-')
            {
                for(j = 0; j < ff->height; j++)
                    caca_file_gets(f, buf, 2048);
                continue;
            }

            if(!buf[0] || buf[0] < '0' || buf[0] > '9')
            {
                debug("figfont error: glyph #%u in `%s'", ff->glyphs, path);
                free(data);
                free(ff->lookup);
                free(ff);
                seterrno(EINVAL);
                return NULL;
            }

            sscanf(buf, buf[1] == 'x' ? "%x" : "%u", &tmp);
            ff->lookup[ff->glyphs * 2] = tmp;
        }

        ff->lookup[ff->glyphs * 2 + 1] = 0;

        for(j = 0; j < ff->height; j++)
        {
            if(i + 2048 >= size)
                data = realloc(data, size += 2048);

            caca_file_gets(f, data + i, 2048);
            i = (uintptr_t)strchr(data + i, 0) - (uintptr_t)data;
        }
    }

    caca_file_close(f);

    if(ff->glyphs < EXT_GLYPHS)
    {
        debug("figfont error: only %u glyphs in `%s', expected at least %u",
                        ff->glyphs, path, EXT_GLYPHS);
        free(data);
        free(ff->lookup);
        free(ff);
        seterrno(EINVAL);
        return NULL;
    }

    /* Remaining initialisation */
    ff->charcv = NULL;
    ff->left = NULL;
    ff->right = NULL;

    /* Import buffer into canvas */
    ff->fontcv = caca_create_canvas(0, 0);
    caca_import_canvas_from_memory(ff->fontcv, data, i, "utf8");
    free(data);

    /* Remove EOL characters. For now we ignore hardblanks, don’t do any
     * smushing, nor any kind of error checking. */
    for(j = 0; j < ff->height * ff->glyphs; j++)
    {
        uint32_t ch, oldch = 0;

        for(i = ff->max_length; i--;)
        {
            ch = caca_get_char(ff->fontcv, i, j);

            /* Replace hardblanks with U+00A0 NO-BREAK SPACE */
            if(ch == ff->hardblank)
                caca_put_char(ff->fontcv, i, j, ch = 0xa0);

            if(oldch && ch != oldch)
            {
                if(!ff->lookup[j / ff->height * 2 + 1])
                    ff->lookup[j / ff->height * 2 + 1] = i + 1;
            }
            else if(oldch && ch == oldch)
                caca_put_char(ff->fontcv, i, j, ' ');
            else if(ch != ' ')
            {
                oldch = ch;
                caca_put_char(ff->fontcv, i, j, ' ');
            }
        }
    }

    return ff;
}
Beispiel #20
0
int main(int argc, char *argv[])
{
    caca_canvas_t *cv;
    caca_dither_t *dither;
    void *buffer;
    char *file, *format;
    char const * const * exports, * const * p;
    size_t len;
    int x, y;

    exports = caca_get_export_list();

    if(argc < 2 || argc > 3)
    {
        fprintf(stderr, "%s: wrong argument count\n", argv[0]);
        fprintf(stderr, "usage: %s [file] <format>\n", argv[0]);
        fprintf(stderr, "where <format> is one of:\n");
        for(p = exports; *p; p += 2)
            fprintf(stderr, " \"%s\" (%s)\n", *p, *(p + 1));
        exit(-1);
    }

    if(argc == 2)
    {
        file = NULL;
        format = argv[1];
    }
    else
    {
        file = argv[1];
        format = argv[2];
    }

    for(p = exports; *p; p += 2)
        if(!strcasecmp(format, *p))
            break;

    if(!*p)
    {
        fprintf(stderr, "%s: unknown format `%s'\n", argv[0], format);
        fprintf(stderr, "please use one of:\n");
        for(p = exports; *p; p += 2)
            fprintf(stderr, " \"%s\" (%s)\n", *p, *(p + 1));
        exit(-1);
    }

    if(file)
    {
        cv = caca_create_canvas(0, 0);
        if(caca_import_canvas_from_file(cv, file, "") < 0)
        {
            fprintf(stderr, "%s: `%s' has unknown format\n", argv[0], file);
            exit(-1);
        }
    }
    else
    {
        cv = caca_create_canvas(WIDTH, HEIGHT);

        for(y = 0; y < 256; y++)
        {
            for(x = 0; x < 256; x++)
            {
                uint32_t r = x;
                uint32_t g = (255 - y + x) / 2;
                uint32_t b = y * (255 - x) / 256;
                pixels[y * 256 + x] = (r << 16) | (g << 8) | (b << 0);
            }
        }

        dither = caca_create_dither(32, 256, 256, 4 * 256,
                                     0x00ff0000, 0x0000ff00, 0x000000ff, 0x0);
        if(!strcmp(format, "ansi") || !strcmp(format, "utf8"))
            caca_set_dither_charset(dither, "shades");
        caca_dither_bitmap(cv, 0, 0, caca_get_canvas_width(cv),
                            caca_get_canvas_height(cv), dither, pixels);
        caca_free_dither(dither);

        caca_set_color_ansi(cv, CACA_WHITE, CACA_BLACK);
        caca_draw_thin_box(cv, 0, 0, WIDTH - 1, HEIGHT - 1);

        caca_set_color_ansi(cv, CACA_BLACK, CACA_WHITE);
        caca_fill_ellipse(cv, WIDTH / 2, HEIGHT / 2,
                               WIDTH / 4, HEIGHT / 4, ' ');

        caca_set_color_ansi(cv, CACA_LIGHTGRAY, CACA_BLACK);
        caca_put_str(cv, WIDTH / 2 - 12, HEIGHT / 2 - 6,
                      "   lightgray on black   ");
        caca_set_color_ansi(cv, CACA_DEFAULT, CACA_TRANSPARENT);
        caca_put_str(cv, WIDTH / 2 - 12, HEIGHT / 2 - 5,
                      " default on transparent ");
        caca_set_color_ansi(cv, CACA_BLACK, CACA_WHITE);
        caca_put_str(cv, WIDTH / 2 - 12, HEIGHT / 2 - 4,
                      "     black on white     ");

        caca_set_color_ansi(cv, CACA_BLACK, CACA_WHITE);
        caca_put_str(cv, WIDTH / 2 - 8, HEIGHT / 2 - 3, "[<><><><> <>--<>]");
        caca_put_str(cv, WIDTH / 2 - 8, HEIGHT / 2 - 2, "[ドラゴン ボーレ]");
        caca_put_str(cv, WIDTH / 2 - 7, HEIGHT / 2 + 2, "äβç ░▒▓█▓▒░ ΔЗҒ");
        caca_put_str(cv, WIDTH / 2 - 5, HEIGHT / 2 + 4, "(\") \\o/ <&>");

        caca_set_attr(cv, CACA_BOLD);
        caca_put_str(cv, WIDTH / 2 - 16, HEIGHT / 2 + 3, "Bold");
        caca_set_attr(cv, CACA_BLINK);
        caca_put_str(cv, WIDTH / 2 - 9, HEIGHT / 2 + 3, "Blink");
        caca_set_attr(cv, CACA_ITALICS);
        caca_put_str(cv, WIDTH / 2 - 1, HEIGHT / 2 + 3, "Italics");
        caca_set_attr(cv, CACA_UNDERLINE);
        caca_put_str(cv, WIDTH / 2 + 8, HEIGHT / 2 + 3, "Underline");
        caca_set_attr(cv, 0);

        caca_set_color_ansi(cv, CACA_WHITE, CACA_LIGHTBLUE);
        caca_put_str(cv, WIDTH / 2 - 7, HEIGHT / 2, "    LIBCACA    ");

        for(x = 0; x < 16; x++)
        {
            caca_set_color_argb(cv, 0xff00 | x, 0xf00f | (x << 4));
            caca_put_char(cv, WIDTH / 2 - 7 + x, HEIGHT / 2 + 6, '#');
        }
    }

    buffer = caca_export_canvas_to_memory(cv, format, &len);
    fwrite(buffer, len, 1, stdout);
    free(buffer);

    caca_free_canvas(cv);

    return 0;
}
Beispiel #21
0
int main(int argc, char *argv[])
{
    textentry entries[TEXT_ENTRIES];
    caca_canvas_t *cv;
    caca_display_t *dp;
    unsigned int i, e = 0, running = 1;

    cv = caca_create_canvas(0, 0);
    if(cv == NULL)
    {
        printf("Can't create canvas\n");
        return -1;
    }
    dp = caca_create_display(cv);
    if(dp == NULL)
    {
        printf("Can't create display\n");
        return -1;
    }
    caca_set_cursor(dp, 1);

    caca_set_color_ansi(cv, CACA_WHITE, CACA_BLUE);
    caca_put_str(cv, 1, 1, "Text entries - press tab to cycle");

    for(i = 0; i < TEXT_ENTRIES; i++)
    {
        entries[i].buffer[0] = 0;
        entries[i].size = 0;
        entries[i].cursor = 0;
        entries[i].changed = 1;
        caca_printf(cv, 3, 3 * i + 4, "[entry %i]", i + 1);
    }

    /* Put Unicode crap in the last text entry */
    entries[TEXT_ENTRIES - 1].buffer[0] = 'A';
    entries[TEXT_ENTRIES - 1].buffer[1] = 'b';
    entries[TEXT_ENTRIES - 1].buffer[2] = caca_utf8_to_utf32("Ç", NULL);
    entries[TEXT_ENTRIES - 1].buffer[3] = caca_utf8_to_utf32("đ", NULL);
    entries[TEXT_ENTRIES - 1].buffer[4] = caca_utf8_to_utf32("ボ", NULL);
    entries[TEXT_ENTRIES - 1].buffer[5] = CACA_MAGIC_FULLWIDTH;
    entries[TEXT_ENTRIES - 1].buffer[6] = caca_utf8_to_utf32("♥", NULL);
    entries[TEXT_ENTRIES - 1].size = 7;

    while(running)
    {
        caca_event_t ev;

        for(i = 0; i < TEXT_ENTRIES; i++)
        {
            unsigned int j, start, size;

            if(!entries[i].changed)
                continue;

            caca_set_color_ansi(cv, CACA_BLACK, CACA_LIGHTGRAY);
            caca_fill_box(cv, 2, 3 * i + 5, BUFFER_SIZE + 1, 1, ' ');

            start = 0;
            size = entries[i].size;

            for(j = 0; j < size; j++)
            {
                caca_put_char(cv, 2 + j, 3 * i + 5,
                              entries[i].buffer[start + j]);
            }

            entries[i].changed = 0;
        }

        /* Put the cursor on the active textentry */
        caca_gotoxy(cv, 2 + entries[e].cursor, 3 * e + 5);

        caca_refresh_display(dp);

        if(caca_get_event(dp, CACA_EVENT_KEY_PRESS, &ev, -1) == 0)
            continue;

        switch(caca_get_event_key_ch(&ev))
        {
            case CACA_KEY_ESCAPE:
                running = 0;
                break;
            case CACA_KEY_TAB:
            case CACA_KEY_RETURN:
                e = (e + 1) % TEXT_ENTRIES;
                break;
            case CACA_KEY_HOME:
                entries[e].cursor = 0;
                break;
            case CACA_KEY_END:
                entries[e].cursor = entries[e].size;
                break;
            case CACA_KEY_LEFT:
                if(entries[e].cursor)
                    entries[e].cursor--;
                break;
            case CACA_KEY_RIGHT:
                if(entries[e].cursor < entries[e].size)
                    entries[e].cursor++;
                break;
            case CACA_KEY_DELETE:
                if(entries[e].cursor < entries[e].size)
                {
                    memmove(entries[e].buffer + entries[e].cursor,
                            entries[e].buffer + entries[e].cursor + 1,
                            (entries[e].size - entries[e].cursor + 1) * 4);
                    entries[e].size--;
                    entries[e].changed = 1;
                }
                break;
            case CACA_KEY_BACKSPACE:
                if(entries[e].cursor)
                {
                    memmove(entries[e].buffer + entries[e].cursor - 1,
                            entries[e].buffer + entries[e].cursor,
                            (entries[e].size - entries[e].cursor) * 4);
                    entries[e].size--;
                    entries[e].cursor--;
                    entries[e].changed = 1;
                }
                break;
            default:
                if(entries[e].size < BUFFER_SIZE)
                {
                    memmove(entries[e].buffer + entries[e].cursor + 1,
                            entries[e].buffer + entries[e].cursor,
                            (entries[e].size - entries[e].cursor) * 4);
                    entries[e].buffer[entries[e].cursor] =
                                              caca_get_event_key_utf32(&ev);
                    entries[e].size++;
                    entries[e].cursor++;
                    entries[e].changed = 1;
                }
                break;
        }
    }

    caca_free_display(dp);
    caca_free_canvas(cv);

    return 0;
}