Esempio n. 1
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;
}
Esempio n. 2
0
static void slang_write_utf32(uint32_t ch)
{
#ifdef HAVE_SLSMG_UTF8_ENABLE
    char buf[10];
    int bytes;
#else
    char ascii;
#endif

    if(ch == CACA_MAGIC_FULLWIDTH)
        return;

#ifdef HAVE_SLSMG_UTF8_ENABLE
    bytes = caca_utf32_to_utf8(buf, ch);
    buf[bytes] = '\0';
    SLsmg_write_string(buf);
#else
    ascii = caca_utf32_to_ascii(ch);
    SLsmg_write_char(ascii);
    if(caca_utf32_is_fullwidth(ch))
        SLsmg_write_char(ascii);
#endif
}
Esempio n. 3
0
/** \brief Print an ASCII or Unicode character.
 *
 *  Print an ASCII or Unicode character at the given coordinates, using
 *  the default foreground and background colour values.
 *
 *  If the coordinates are outside the canvas boundaries, nothing is printed.
 *  If a fullwidth Unicode character gets overwritten, its remaining visible
 *  parts are replaced with spaces. If the canvas' boundaries would split the
 *  fullwidth character in two, a space is printed instead.
 *
 *  The behaviour when printing non-printable characters or invalid UTF-32
 *  characters is undefined. To print a sequence of bytes forming an UTF-8
 *  character instead of an UTF-32 character, use the caca_put_str() function.
 *
 *  This function returns the width of the printed character. If it is a
 *  fullwidth character, 2 is returned. Otherwise, 1 is returned.
 *
 *  This function never fails.
 *
 *  \param cv A handle to the libcaca canvas.
 *  \param x X coordinate.
 *  \param y Y coordinate.
 *  \param ch The character to print.
 *  \return The width of the printed character: 2 for a fullwidth character,
 *          1 otherwise.
 */
int caca_put_char(caca_canvas_t *cv, int x, int y, uint32_t ch)
{
    uint32_t *curchar, *curattr, attr;
    int fullwidth, xmin, xmax, ret;

    if(ch == CACA_MAGIC_FULLWIDTH)
        return 1;

    fullwidth = caca_utf32_is_fullwidth(ch);
    ret = fullwidth ? 2 : 1;

    if(x >= (int)cv->width || y < 0 || y >= (int)cv->height)
        return ret;

    if(x == -1 && fullwidth)
    {
        x = 0;
        ch = ' ';
        fullwidth = 0;
    }
    else if(x < 0)
        return ret;

    curchar = cv->chars + x + y * cv->width;
    curattr = cv->attrs + x + y * cv->width;
    attr = cv->curattr;

    xmin = xmax = x;

    /* When overwriting the right part of a fullwidth character,
     * replace its left part with a space. */
    if(x && curchar[0] == CACA_MAGIC_FULLWIDTH)
    {
        curchar[-1] = ' ';
        xmin--;
    }

    if(fullwidth)
    {
        if(x + 1 == (int)cv->width)
            ch = ' ';
        else
        {
            xmax++;

            /* When overwriting the left part of a fullwidth character,
             * replace its right part with a space. */
            if(x + 2 < (int)cv->width && curchar[2] == CACA_MAGIC_FULLWIDTH)
            {
                curchar[2] = ' ';
                xmax++;
            }

            curchar[1] = CACA_MAGIC_FULLWIDTH;
            curattr[1] = attr;
        }
    }
    else
    {
        /* When overwriting the left part of a fullwidth character,
         * replace its right part with a space. */
        if(x + 1 != (int)cv->width && curchar[1] == CACA_MAGIC_FULLWIDTH)
        {
            curchar[1] = ' ';
            xmax++;
        }
    }

    /* Only add a dirty rectangle if we are pasting a different character
     * or attribute at that place. This does not account for inconsistencies
     * in the canvas, ie. if CACA_MAGIC_FULLWIDTH lies at illegal places,
     * but it's the caller's responsibility not to corrupt the contents. */
    if(!cv->dirty_disabled
        && (curchar[0] != ch || curattr[0] != attr))
        caca_add_dirty_rect(cv, xmin, y, xmax - xmin + 1, 1);

    curchar[0] = ch;
    curattr[0] = attr;

    return ret;
}
Esempio n. 4
0
static void ncurses_write_utf32(uint32_t ch)
{
#if defined HAVE_NCURSESW_NCURSES_H
    char buf[10];
    int bytes;
#endif

    if(ch == CACA_MAGIC_FULLWIDTH)
        return;

#if defined HAVE_NCURSESW_NCURSES_H
    bytes = caca_utf32_to_utf8(buf, ch);
    buf[bytes] = '\0';
    addstr(buf);
#else
    if(ch < 0x80)
    {
        addch(ch);
    }
    else
    {
        chtype cch;
        chtype cch2;

        cch = '?';
        cch2 = ' ';
        if ((ch > 0x0000ff00) && (ch < 0x0000ff5f))
        {
            cch = ch - 0x0000ff00 + ' ';
        }
        switch (ch)
        {
        case 0x000000a0: /* <nbsp> */
        case 0x00003000: /*   */
            cch = ' ';
            break;
        case 0x000000a3: /* £ */
            cch = ACS_STERLING;
            break;
        case 0x000000b0: /* ° */
            cch = ACS_DEGREE;
            break;
        case 0x000000b1: /* ± */
            cch = ACS_PLMINUS;
            break;
        case 0x000000b7: /* · */
        case 0x00002219: /* ∙ */
        case 0x000030fb: /* ・ */
            cch = ACS_BULLET;
            break;
        case 0x000003c0: /* π */
            cch = ACS_PI;
            break;
        case 0x00002018: /* ‘ */
        case 0x00002019: /* ’ */
            cch = '\'';
            break;
        case 0x0000201c: /* “ */
        case 0x0000201d: /* ” */
            cch = '"';
            break;
        case 0x00002190: /* ← */
            cch = ACS_LARROW;
            break;
        case 0x00002191: /* ↑ */
            cch = ACS_UARROW;
            break;
        case 0x00002192: /* → */
            cch = ACS_RARROW;
            break;
        case 0x00002193: /* ↓ */
            cch = ACS_DARROW;
            break;
        case 0x00002260: /* ≠ */
            cch = ACS_NEQUAL;
            break;
        case 0x00002261: /* ≡ */
            cch = '=';
            break;
        case 0x00002264: /* ≤ */
            cch = ACS_LEQUAL;
            break;
        case 0x00002265: /* ≥ */
            cch = ACS_GEQUAL;
            break;
        case 0x000023ba: /* ⎺ */
            cch = ACS_S1;
            cch2 = cch;
            break;
        case 0x000023bb: /* ⎻ */
            cch = ACS_S3;
            cch2 = cch;
            break;
        case 0x000023bc: /* ⎼ */
            cch = ACS_S7;
            cch2 = cch;
            break;
        case 0x000023bd: /* ⎽ */
            cch = ACS_S9;
            cch2 = cch;
            break;
        case 0x00002500: /* ─ */
        case 0x00002550: /* ═ */
            cch = ACS_HLINE;
            cch2 = cch;
            break;
        case 0x00002502: /* │ */
        case 0x00002551: /* ║ */
            cch = ACS_VLINE;
            break;
        case 0x0000250c: /* ┌ */
        case 0x00002552: /* ╒ */
        case 0x00002553: /* ╓ */
        case 0x00002554: /* ╔ */
            cch = ACS_ULCORNER;
            cch2 = ACS_HLINE;
            break;
        case 0x00002510: /* ┐ */
        case 0x00002555: /* ╕ */
        case 0x00002556: /* ╖ */
        case 0x00002557: /* ╗ */
            cch = ACS_URCORNER;
            break;
        case 0x00002514: /* └ */
        case 0x00002558: /* ╘ */
        case 0x00002559: /* ╙ */
        case 0x0000255a: /* ╚ */
            cch = ACS_LLCORNER;
            cch2 = ACS_HLINE;
            break;
        case 0x00002518: /* ┘ */
        case 0x0000255b: /* ╛ */
        case 0x0000255c: /* ╜ */
        case 0x0000255d: /* ╝ */
            cch = ACS_LRCORNER;
            break;
        case 0x0000251c: /* ├ */
        case 0x0000255e: /* ╞ */
        case 0x0000255f: /* ╟ */
        case 0x00002560: /* ╠ */
            cch = ACS_LTEE;
            cch2 = ACS_HLINE;
            break;
        case 0x00002524: /* ┤ */
        case 0x00002561: /* ╡ */
        case 0x00002562: /* ╢ */
        case 0x00002563: /* ╣ */
            cch = ACS_RTEE;
            break;
        case 0x0000252c: /* ┬ */
        case 0x00002564: /* ╤ */
        case 0x00002565: /* ╥ */
        case 0x00002566: /* ╦ */
            cch = ACS_TTEE;
            cch2 = ACS_HLINE;
            break;
        case 0x00002534: /* ┴ */
        case 0x00002567: /* ╧ */
        case 0x00002568: /* ╨ */
        case 0x00002569: /* ╩ */
            cch = ACS_BTEE;
            cch2 = ACS_HLINE;
            break;
        case 0x0000253c: /* ┼ */
        case 0x0000256a: /* ╪ */
        case 0x0000256b: /* ╫ */
        case 0x0000256c: /* ╬ */
            cch = ACS_PLUS;
            cch2 = ACS_HLINE;
            break;
        case 0x00002591: /* ░ */
            cch = ACS_BOARD;
            cch2 = cch;
            break;
        case 0x00002592: /* ▒ */
        case 0x00002593: /* ▓ */
            cch = ACS_CKBOARD;
            cch2 = cch;
            break;
        case 0x00002580: /* ▀ */
        case 0x00002584: /* ▄ */
        case 0x00002588: /* █ */
        case 0x0000258c: /* ▌ */
        case 0x00002590: /* ▐ */
        case 0x000025a0: /* ■ */
        case 0x000025ac: /* ▬ */
        case 0x000025ae: /* ▮ */
            cch = ACS_BLOCK;
            cch2 = cch;
            break;
        case 0x000025c6: /* ◆ */
        case 0x00002666: /* ♦ */
            cch = ACS_DIAMOND;
            break;
        case 0x00002022: /* • */
        case 0x000025cb: /* ○ */
        case 0x000025cf: /* ● */
        case 0x00002603: /* ☃ */
        case 0x0000263c: /* ☼ */
            cch = ACS_LANTERN;
            break;
        case 0x0000301c: /* 〜 */
            cch = '~';
            break;
        }
        addch(cch);
        if(caca_utf32_is_fullwidth(ch))
        {
            addch(cch2);
        }
    }
#endif
}