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

Last change on this file since 540 was 540, checked in by Sam Hocevar, 14 years ago
  • Polished the driver split a bit (still no events, except resize events), properly credited authors and documented a few things.
  • Property svn:keywords set to Id
File size: 5.7 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 540 2006-03-07 09:17:35Z 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#include <stdio.h> /* BUFSIZ */
23#include <string.h>
24#include <stdlib.h>
25#if defined(HAVE_UNISTD_H)
26#   include <unistd.h>
27#endif
28#include <stdarg.h>
29
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
37#include "cucul.h"
38#include "cucul_internals.h"
39
40/** \brief Set the default colour pair.
41 *
42 *  This function sets the default colour pair. String functions such as
43 *  caca_printf() and graphical primitive functions such as caca_draw_line()
44 *  will use these colour pairs.
45 *
46 *  \param fgcolor The requested foreground colour.
47 *  \param bgcolor The requested background colour.
48 */
49void cucul_set_color(cucul_t *qq, enum cucul_color fgcolor, enum cucul_color bgcolor)
50{
51    if(fgcolor < 0 || fgcolor > 15 || bgcolor < 0 || bgcolor > 15)
52        return;
53
54    qq->fgcolor = fgcolor;
55    qq->bgcolor = bgcolor;
56}
57
58/** \brief Get the current foreground colour.
59 *
60 *  This function returns the current foreground colour that was set with
61 *  cucul_set_color().
62 *
63 *  \return The current foreground colour.
64 */
65enum cucul_color cucul_get_fg_color(cucul_t *qq)
66{
67    return qq->fgcolor;
68}
69
70/** \brief Get the current background colour.
71 *
72 *  This function returns the current background colour that was set with
73 *  cucul_set_color().
74 *
75 *  \return The current background colour.
76 */
77enum cucul_color cucul_get_bg_color(cucul_t *qq)
78{
79    return qq->bgcolor;
80}
81
82/** \brief Print a character.
83 *
84 *  This function prints a character at the given coordinates, using the
85 *  default foreground and background values. If the coordinates are outside
86 *  the screen boundaries, nothing is printed.
87 *
88 *  \param x X coordinate.
89 *  \param y Y coordinate.
90 *  \param c The character to print.
91 */
92void cucul_putchar(cucul_t *qq, int x, int y, char c)
93{
94    if(x < 0 || x >= (int)qq->width ||
95       y < 0 || y >= (int)qq->height)
96        return;
97
98    qq->chars[x + y * qq->width] = c & 0x0000007f; /* FIXME: ASCII-only */
99    qq->attr[x + y * qq->width] = (qq->bgcolor << 4) | qq->fgcolor;
100}
101
102/** \brief Print a string.
103 *
104 *  This function prints a string at the given coordinates, using the
105 *  default foreground and background values. The coordinates may be outside
106 *  the screen boundaries (eg. a negative Y coordinate) and the string will
107 *  be cropped accordingly if it is too long.
108 *
109 *  \param x X coordinate.
110 *  \param y Y coordinate.
111 *  \param s The string to print.
112 */
113void cucul_putstr(cucul_t *qq, int x, int y, char const *s)
114{
115    uint32_t *chars;
116    uint8_t *attr;
117    char const *t;
118    unsigned int len;
119
120    if(y < 0 || y >= (int)qq->height || x >= (int)qq->width)
121        return;
122
123    len = strlen(s);
124
125    if(x < 0)
126    {
127        if(len < (unsigned int)-x)
128            return;
129        len -= -x;
130        s += -x;
131        x = 0;
132    }
133
134    if(x + len >= qq->width)
135    {
136        len = qq->width - x;
137        memcpy(qq->scratch_line, s, len);
138        qq->scratch_line[len] = '\0';
139        s = qq->scratch_line;
140    }
141
142    chars = qq->chars + x + y * qq->width;
143    attr = qq->attr + x + y * qq->width;
144    t = s;
145    while(*t)
146    {
147        *chars++ = *t++ & 0x0000007f; /* FIXME: ASCII-only */
148        *attr++ = (qq->bgcolor << 4) | qq->fgcolor;
149    }
150}
151
152/** \brief Format a string.
153 *
154 *  This function formats a string at the given coordinates, using the
155 *  default foreground and background values. The coordinates may be outside
156 *  the screen boundaries (eg. a negative Y coordinate) and the string will
157 *  be cropped accordingly if it is too long. The syntax of the format
158 *  string is the same as for the C printf() function.
159 *
160 *  \param x X coordinate.
161 *  \param y Y coordinate.
162 *  \param format The format string to print.
163 *  \param ... Arguments to the format string.
164 */
165void cucul_printf(cucul_t *qq, int x, int y, char const *format, ...)
166{
167    char tmp[BUFSIZ];
168    char *buf = tmp;
169    va_list args;
170
171    if(y < 0 || y >= (int)qq->height || x >= (int)qq->width)
172        return;
173
174    if(qq->width - x + 1 > BUFSIZ)
175        buf = malloc(qq->width - x + 1);
176
177    va_start(args, format);
178#if defined(HAVE_VSNPRINTF)
179    vsnprintf(buf, qq->width - x + 1, format, args);
180#else
181    vsprintf(buf, format, args);
182#endif
183    buf[qq->width - x] = '\0';
184    va_end(args);
185
186    cucul_putstr(qq, x, y, buf);
187
188    if(buf != tmp)
189        free(buf);
190}
191
192/** \brief Get the screen.
193 *
194 *  This function fills a byte array with the character values.
195 */
196void cucul_get_screen(cucul_t *qq, char *buffer)
197{
198    unsigned int x, y;
199
200    for(y = 0; y < qq->height; y++)
201    {
202        for(x = 0; x < qq->width; x++)
203        {
204            *buffer++ = qq->attr[x + y * qq->width];
205            *buffer++ = qq->chars[x + y * qq->width] & 0x7f; /* FIXME: ASCII */
206        }
207    }
208}
209
210/** \brief Clear the screen.
211 *
212 *  This function clears the screen using a black background.
213 */
214void cucul_clear(cucul_t *qq)
215{
216    enum cucul_color oldfg = cucul_get_fg_color(qq);
217    enum cucul_color oldbg = cucul_get_bg_color(qq);
218    int y = qq->height;
219
220    cucul_set_color(qq, CUCUL_COLOR_LIGHTGRAY, CUCUL_COLOR_BLACK);
221
222    /* We could use SLsmg_cls() etc., but drawing empty lines is much faster */
223    while(y--)
224        cucul_putstr(qq, 0, y, qq->empty_line);
225
226    cucul_set_color(qq, oldfg, oldbg);
227}
228
Note: See TracBrowser for help on using the repository browser.