source: libcaca/trunk/cucul/char.c @ 568

Last change on this file since 568 was 568, checked in by Sam Hocevar, 14 years ago
  • Added glue code to compile libcaca without a libc and build applications as multiboot kernels.
  • Property svn:keywords set to Id
File size: 5.8 KB
Line 
1/*
2 *  libcucul      Unicode canvas library
3 *  Copyright (c) 2002-2006 Sam Hocevar <sam@zoy.org>
4 *                All Rights Reserved
5 *
6 *  This library is free software; you can redistribute it and/or
7 *  modify it under the terms of the Do What The Fuck You Want To
8 *  Public License, Version 2, as published by Sam Hocevar. See
9 *  http://sam.zoy.org/wtfpl/COPYING for more details.
10 */
11
12/** \file char.c
13 *  \version \$Id: char.c 568 2006-03-09 12:47:37Z sam $
14 *  \author Sam Hocevar <sam@zoy.org>
15 *  \brief Character drawing
16 *
17 *  This file contains character and string drawing functions.
18 */
19
20#include "config.h"
21
22#if !defined(__KERNEL__)
23#   include <stdio.h> /* BUFSIZ */
24#   include <string.h>
25#   include <stdlib.h>
26#   include <stdarg.h>
27#   if defined(HAVE_UNISTD_H)
28#       include <unistd.h>
29#   endif
30#   if defined(HAVE_SIGNAL_H)
31#       include <signal.h>
32#   endif
33#   if defined(HAVE_SYS_IOCTL_H)
34#       include <sys/ioctl.h>
35#   endif
36#endif
37
38#include "cucul.h"
39#include "cucul_internals.h"
40
41/** \brief Set the default colour pair.
42 *
43 *  This function sets the default colour pair. String functions such as
44 *  caca_printf() and graphical primitive functions such as caca_draw_line()
45 *  will use these colour pairs.
46 *
47 *  \param fgcolor The requested foreground colour.
48 *  \param bgcolor The requested background colour.
49 */
50void cucul_set_color(cucul_t *qq, enum cucul_color fgcolor, enum cucul_color bgcolor)
51{
52    if(fgcolor < 0 || fgcolor > 15 || bgcolor < 0 || bgcolor > 15)
53        return;
54
55    qq->fgcolor = fgcolor;
56    qq->bgcolor = bgcolor;
57}
58
59/** \brief Get the current foreground colour.
60 *
61 *  This function returns the current foreground colour that was set with
62 *  cucul_set_color().
63 *
64 *  \return The current foreground colour.
65 */
66enum cucul_color cucul_get_fg_color(cucul_t *qq)
67{
68    return qq->fgcolor;
69}
70
71/** \brief Get the current background colour.
72 *
73 *  This function returns the current background colour that was set with
74 *  cucul_set_color().
75 *
76 *  \return The current background colour.
77 */
78enum cucul_color cucul_get_bg_color(cucul_t *qq)
79{
80    return qq->bgcolor;
81}
82
83/** \brief Print a character.
84 *
85 *  This function prints a character at the given coordinates, using the
86 *  default foreground and background values. If the coordinates are outside
87 *  the screen boundaries, nothing is printed.
88 *
89 *  \param x X coordinate.
90 *  \param y Y coordinate.
91 *  \param c The character to print.
92 */
93void cucul_putchar(cucul_t *qq, int x, int y, char c)
94{
95    if(x < 0 || x >= (int)qq->width ||
96       y < 0 || y >= (int)qq->height)
97        return;
98
99    qq->chars[x + y * qq->width] = c & 0x0000007f; /* FIXME: ASCII-only */
100    qq->attr[x + y * qq->width] = (qq->bgcolor << 4) | qq->fgcolor;
101}
102
103/** \brief Print a string.
104 *
105 *  This function prints a string at the given coordinates, using the
106 *  default foreground and background values. The coordinates may be outside
107 *  the screen boundaries (eg. a negative Y coordinate) and the string will
108 *  be cropped accordingly if it is too long.
109 *
110 *  \param x X coordinate.
111 *  \param y Y coordinate.
112 *  \param s The string to print.
113 */
114void cucul_putstr(cucul_t *qq, int x, int y, char const *s)
115{
116    uint32_t *chars;
117    uint8_t *attr;
118    char const *t;
119    unsigned int len;
120
121    if(y < 0 || y >= (int)qq->height || x >= (int)qq->width)
122        return;
123
124    len = strlen(s);
125
126    if(x < 0)
127    {
128        if(len < (unsigned int)-x)
129            return;
130        len -= -x;
131        s += -x;
132        x = 0;
133    }
134
135    if(x + len >= qq->width)
136    {
137        len = qq->width - x;
138        memcpy(qq->scratch_line, s, len);
139        qq->scratch_line[len] = '\0';
140        s = qq->scratch_line;
141    }
142
143    chars = qq->chars + x + y * qq->width;
144    attr = qq->attr + x + y * qq->width;
145    t = s;
146    while(*t)
147    {
148        *chars++ = *t++ & 0x0000007f; /* FIXME: ASCII-only */
149        *attr++ = (qq->bgcolor << 4) | qq->fgcolor;
150    }
151}
152
153/** \brief Format a string.
154 *
155 *  This function formats a string at the given coordinates, using the
156 *  default foreground and background values. The coordinates may be outside
157 *  the screen boundaries (eg. a negative Y coordinate) and the string will
158 *  be cropped accordingly if it is too long. The syntax of the format
159 *  string is the same as for the C printf() function.
160 *
161 *  \param x X coordinate.
162 *  \param y Y coordinate.
163 *  \param format The format string to print.
164 *  \param ... Arguments to the format string.
165 */
166void cucul_printf(cucul_t *qq, int x, int y, char const *format, ...)
167{
168    char tmp[BUFSIZ];
169    char *buf = tmp;
170    va_list args;
171
172    if(y < 0 || y >= (int)qq->height || x >= (int)qq->width)
173        return;
174
175    if(qq->width - x + 1 > BUFSIZ)
176        buf = malloc(qq->width - x + 1);
177
178    va_start(args, format);
179#if defined(HAVE_VSNPRINTF)
180    vsnprintf(buf, qq->width - x + 1, format, args);
181#else
182    vsprintf(buf, format, args);
183#endif
184    buf[qq->width - x] = '\0';
185    va_end(args);
186
187    cucul_putstr(qq, x, y, buf);
188
189    if(buf != tmp)
190        free(buf);
191}
192
193/** \brief Get the screen.
194 *
195 *  This function fills a byte array with the character values.
196 */
197void cucul_get_screen(cucul_t *qq, char *buffer)
198{
199    unsigned int x, y;
200
201    for(y = 0; y < qq->height; y++)
202    {
203        for(x = 0; x < qq->width; x++)
204        {
205            *buffer++ = qq->attr[x + y * qq->width];
206            *buffer++ = qq->chars[x + y * qq->width] & 0x7f; /* FIXME: ASCII */
207        }
208    }
209}
210
211/** \brief Clear the screen.
212 *
213 *  This function clears the screen using a black background.
214 */
215void cucul_clear(cucul_t *qq)
216{
217    enum cucul_color oldfg = cucul_get_fg_color(qq);
218    enum cucul_color oldbg = cucul_get_bg_color(qq);
219    int y = qq->height;
220
221    cucul_set_color(qq, CUCUL_COLOR_LIGHTGRAY, CUCUL_COLOR_BLACK);
222
223    /* We could use SLsmg_cls() etc., but drawing empty lines is much faster */
224    while(y--)
225        cucul_putstr(qq, 0, y, qq->empty_line);
226
227    cucul_set_color(qq, oldfg, oldbg);
228}
229
Note: See TracBrowser for help on using the repository browser.