source: libcaca/trunk/cucul/canvas.c @ 769

Last change on this file since 769 was 769, checked in by Sam Hocevar, 14 years ago
  • Removed \file directives from all files except caca.h and cucul.h, to remove redundencies in the Doxygen documentation.
  • Property svn:keywords set to Id
File size: 7.0 KB
Line 
1/*
2 *  libcucul      Canvas for ultrafast compositing of Unicode letters
3 *  Copyright (c) 2002-2006 Sam Hocevar <sam@zoy.org>
4 *                All Rights Reserved
5 *
6 *  $Id: canvas.c 769 2006-04-14 07:30:53Z sam $
7 *
8 *  This library is free software; you can redistribute it and/or
9 *  modify it under the terms of the Do What The Fuck You Want To
10 *  Public License, Version 2, as published by Sam Hocevar. See
11 *  http://sam.zoy.org/wtfpl/COPYING for more details.
12 */
13
14/*
15 *  This file contains various canvas handling functions such as character
16 *  and string drawing.
17 */
18
19#include "config.h"
20
21#if !defined(__KERNEL__)
22#   include <stdio.h> /* BUFSIZ */
23#   include <string.h>
24#   include <stdlib.h>
25#   include <stdarg.h>
26#   if defined(HAVE_UNISTD_H)
27#       include <unistd.h>
28#   endif
29#   if defined(HAVE_SIGNAL_H)
30#       include <signal.h>
31#   endif
32#   if defined(HAVE_SYS_IOCTL_H)
33#       include <sys/ioctl.h>
34#   endif
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, unsigned int fgcolor, unsigned int bgcolor)
50{
51    /* FIXME */
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 Print an ASCII character.
60 *
61 *  This function prints an ASCII character at the given coordinates, using
62 *  the default foreground and background values. If the coordinates are
63 *  outside the screen boundaries, nothing is printed. If the character
64 *  value is a non-printable character or is outside the ASCII range, it is
65 *  replaced with a space. To print a sequence of bytes forming an UTF-8
66 *  character, use cucul_putstr() instead.
67 *
68 *  \param x X coordinate.
69 *  \param y Y coordinate.
70 *  \param c The character to print.
71 */
72void cucul_putchar(cucul_t *qq, int x, int y, char c)
73{
74    if(x < 0 || x >= (int)qq->width ||
75       y < 0 || y >= (int)qq->height)
76        return;
77
78    if((unsigned char)c < 0x20 || (unsigned char)c > 0x7f)
79        c = 0x20;
80
81    qq->chars[x + y * qq->width] = c;
82    qq->attr[x + y * qq->width] = (qq->bgcolor << 16) | qq->fgcolor;
83}
84
85/** \brief Print a string.
86 *
87 *  This function prints an UTF-8 string at the given coordinates, using the
88 *  default foreground and background values. The coordinates may be outside
89 *  the screen boundaries (eg. a negative Y coordinate) and the string will
90 *  be cropped accordingly if it is too long.
91 *
92 *  \param x X coordinate.
93 *  \param y Y coordinate.
94 *  \param s The string to print.
95 */
96void cucul_putstr(cucul_t *qq, int x, int y, char const *s)
97{
98    uint32_t *chars, *attr;
99    unsigned int len;
100
101    if(y < 0 || y >= (int)qq->height || x >= (int)qq->width)
102        return;
103
104    len = _cucul_strlen_utf8(s);
105
106    if(x < 0)
107    {
108        if(len < (unsigned int)-x)
109            return;
110        len -= -x;
111        s = _cucul_skip_utf8(s, -x);
112        x = 0;
113    }
114
115    chars = qq->chars + x + y * qq->width;
116    attr = qq->attr + x + y * qq->width;
117
118    if(x + len >= qq->width)
119        len = qq->width - x;
120
121    while(len)
122    {
123        *chars++ = _cucul_utf8_to_utf32(s);
124        *attr++ = (qq->bgcolor << 16) | qq->fgcolor;
125
126        s = _cucul_skip_utf8(s, 1);
127        len--;
128    }
129}
130
131/** \brief Format a string.
132 *
133 *  This function formats a string at the given coordinates, using the
134 *  default foreground and background values. The coordinates may be outside
135 *  the screen boundaries (eg. a negative Y coordinate) and the string will
136 *  be cropped accordingly if it is too long. The syntax of the format
137 *  string is the same as for the C printf() function.
138 *
139 *  \param x X coordinate.
140 *  \param y Y coordinate.
141 *  \param format The format string to print.
142 *  \param ... Arguments to the format string.
143 */
144void cucul_printf(cucul_t *qq, int x, int y, char const *format, ...)
145{
146    char tmp[BUFSIZ];
147    char *buf = tmp;
148    va_list args;
149
150    if(y < 0 || y >= (int)qq->height || x >= (int)qq->width)
151        return;
152
153    if(qq->width - x + 1 > BUFSIZ)
154        buf = malloc(qq->width - x + 1);
155
156    va_start(args, format);
157#if defined(HAVE_VSNPRINTF)
158    vsnprintf(buf, qq->width - x + 1, format, args);
159#else
160    vsprintf(buf, format, args);
161#endif
162    buf[qq->width - x] = '\0';
163    va_end(args);
164
165    cucul_putstr(qq, x, y, buf);
166
167    if(buf != tmp)
168        free(buf);
169}
170
171/** \brief Clear the screen.
172 *
173 *  This function clears the screen using a black background.
174 */
175void cucul_clear(cucul_t *qq)
176{
177    uint16_t oldfg = qq->fgcolor;
178    uint16_t oldbg = qq->bgcolor;
179    int y = qq->height;
180
181    cucul_set_color(qq, CUCUL_COLOR_LIGHTGRAY, CUCUL_COLOR_BLACK);
182
183    /* We could use SLsmg_cls() etc., but drawing empty lines is much faster */
184    while(y--)
185        cucul_putstr(qq, 0, y, qq->empty_line);
186
187    qq->fgcolor = oldfg;
188    qq->bgcolor = oldbg;
189}
190
191/** \brief Blit a canvas onto another one.
192 *
193 *  This function blits a canvas onto another one at the given coordinates.
194 *  An optional mask canvas can be used.
195 *
196 *  \param dst The destination canvas.
197 *  \param x X coordinate.
198 *  \param y Y coordinate.
199 *  \param src The source canvas.
200 *  \param mask The mask canvas.
201 */
202void cucul_blit(cucul_t *dst, int x, int y,
203                cucul_t const *src, cucul_t const *mask)
204{
205    int i, j, starti, startj, endi, endj;
206
207    if(mask && (src->width != mask->width || src->height != mask->height))
208        return;
209
210    starti = x < 0 ? -x : 0;
211    startj = y < 0 ? -y : 0;
212    endi = (x + src->width >= dst->width) ? dst->width - x : src->width;
213    endj = (y + src->height >= dst->height) ? dst->height - y : src->height;
214
215    if(starti >= endi || startj >= endj)
216        return;
217
218    for(j = startj; j < endj; j++)
219    {
220        if(mask)
221        {
222            for(i = starti; i < endi; i++)
223            {
224                if(mask->chars[j * src->width + i] == (uint32_t)' ')
225                    continue;
226
227                dst->chars[(j + y) * dst->width + (i + x)]
228                                             = src->chars[j * src->width + i];
229                dst->attr[(j + y) * dst->width + (i + x)]
230                                             = src->attr[j * src->width + i];
231            }
232        }
233        else
234        {
235            memcpy(dst->chars + (j + y) * dst->width + starti + x,
236                   src->chars + j * src->width + starti,
237                   (endi - starti) * 4);
238            memcpy(dst->attr + (j + y) * dst->width + starti + x,
239                   src->attr + j * src->width + starti,
240                   (endi - starti) * 4);
241        }
242    }
243}
244
245/*
246 * XXX: The following functions are not exported
247 */
248
249void _cucul_putchar32(cucul_t *qq, int x, int y, uint32_t c)
250{
251    if(x < 0 || x >= (int)qq->width ||
252       y < 0 || y >= (int)qq->height)
253        return;
254
255    qq->chars[x + y * qq->width] = c;
256    qq->attr[x + y * qq->width] = (qq->bgcolor << 16) | qq->fgcolor;
257}
258
Note: See TracBrowser for help on using the repository browser.