2
2
* libcaca Colour ASCII-Art library
3
* Copyright (c) 2002-2006 Sam Hocevar <sam@zoy.org>
3
* Copyright (c) 2002-2009 Sam Hocevar <sam@hocevar.net>
4
4
* All Rights Reserved
8
6
* This library is free software. It comes without any warranty, to
9
7
* the extent permitted by applicable law. You can redistribute it
10
8
* and/or modify it under the terms of the Do What The Fuck You Want
68
66
* \param cv A handle to the libcaca canvas.
69
67
* \return The cursor's X coordinate.
71
int caca_get_cursor_x(caca_canvas_t const *cv)
69
int caca_wherex(caca_canvas_t const *cv)
73
71
return cv->frames[cv->frame].x;
82
80
* \param cv A handle to the libcaca canvas.
83
81
* \return The cursor's Y coordinate.
85
int caca_get_cursor_y(caca_canvas_t const *cv)
83
int caca_wherey(caca_canvas_t const *cv)
87
85
return cv->frames[cv->frame].y;
101
99
* characters is undefined. To print a sequence of bytes forming an UTF-8
102
100
* character instead of an UTF-32 character, use the caca_put_str() function.
102
* This function returns the width of the printed character. If it is a
103
* fullwidth character, 2 is returned. Otherwise, 1 is returned.
104
105
* This function never fails.
106
107
* \param cv A handle to the libcaca canvas.
107
108
* \param x X coordinate.
108
109
* \param y Y coordinate.
109
110
* \param ch The character to print.
110
* \return This function always returns 0.
111
* \return The width of the printed character: 2 for a fullwidth character,
112
114
int caca_put_char(caca_canvas_t *cv, int x, int y, uint32_t ch)
114
116
uint32_t *curchar, *curattr, attr;
117
if(x >= (int)cv->width || y < 0 || y >= (int)cv->height)
117
int fullwidth, xmin, xmax, ret;
120
119
if(ch == CACA_MAGIC_FULLWIDTH)
123
122
fullwidth = caca_utf32_is_fullwidth(ch);
123
ret = fullwidth ? 2 : 1;
125
if(x >= (int)cv->width || y < 0 || y >= (int)cv->height)
125
128
if(x == -1 && fullwidth)
134
137
curchar = cv->chars + x + y * cv->width;
135
138
curattr = cv->attrs + x + y * cv->width;
136
139
attr = cv->curattr;
138
143
/* When overwriting the right part of a fullwidth character,
139
144
* replace its left part with a space. */
140
145
if(x && curchar[0] == CACA_MAGIC_FULLWIDTH)
141
147
curchar[-1] = ' ';
160
173
/* When overwriting the left part of a fullwidth character,
161
174
* replace its right part with a space. */
162
175
if(x + 1 != (int)cv->width && curchar[1] == CACA_MAGIC_FULLWIDTH)
163
177
curchar[1] = ' ';
182
/* Only add a dirty rectangle if we are pasting a different character
183
* or attribute at that place. This does not account for inconsistencies
184
* in the canvas, ie. if CACA_MAGIC_FULLWIDTH lies at illegal places,
185
* but it's the caller's responsibility not to corrupt the contents. */
186
if(!cv->dirty_disabled
187
&& (curchar[0] != ch || curattr[0] != attr))
188
caca_add_dirty_rect(cv, xmin, y, xmax - xmin + 1, 1);
167
191
curattr[0] = attr;
172
196
/** \brief Get the Unicode character at the given coordinates.
189
213
* \param cv A handle to the libcaca canvas.
190
214
* \param x X coordinate.
191
215
* \param y Y coordinate.
192
* \return This function always returns 0.
216
* \return The Unicode character at the given coordinates.
194
218
uint32_t caca_get_char(caca_canvas_t const *cv, int x, int y)
209
233
* See caca_put_char() for more information on how fullwidth characters
210
234
* are handled when overwriting each other or at the canvas' boundaries.
236
* This function returns the number of cells printed by the string. It is
237
* not the number of characters printed, because fullwidth characters
238
* account for two cells.
212
240
* This function never fails.
214
242
* \param cv A handle to the libcaca canvas.
215
243
* \param x X coordinate.
216
244
* \param y Y coordinate.
217
245
* \param s The string to print.
218
* \return This function always returns 0.
246
* \return The number of cells printed.
220
248
int caca_put_str(caca_canvas_t *cv, int x, int y, char const *s)
224
253
if(y < 0 || y >= (int)cv->height || x >= (int)cv->width)
229
x += caca_utf32_is_fullwidth(caca_utf8_to_utf32(s, &rd)) ? 2 : 1;
257
len += caca_utf32_is_fullwidth(caca_utf8_to_utf32(s, &rd)) ? 2 : 1;
233
while(*s && x < (int)cv->width)
235
265
uint32_t ch = caca_utf8_to_utf32(s, &rd);
236
caca_put_char(cv, x, y, ch);
237
x += caca_utf32_is_fullwidth(ch) ? 2 : 1;
267
if(x + len >= -1 && x + len < (int)cv->width)
268
caca_put_char(cv, x + len, y, ch);
270
len += caca_utf32_is_fullwidth(ch) ? 2 : 1;
244
277
/** \brief Print a formated string.
249
282
* accordingly if it is too long. The syntax of the format string is the
250
283
* same as for the C printf() function.
285
* This function returns the number of cells printed by the string. It is
286
* not the number of characters printed, because fullwidth characters
287
* account for two cells.
252
289
* This function never fails.
254
291
* \param cv A handle to the libcaca canvas.
256
293
* \param y Y coordinate.
257
294
* \param format The format string to print.
258
295
* \param ... Arguments to the format string.
259
* \return This function always returns 0.
296
* \return The number of cells printed.
261
298
int caca_printf(caca_canvas_t *cv, int x, int y, char const *format, ...)
302
va_start(args, format);
303
ret = caca_vprintf(cv, x, y, format, args);
308
/** \brief Print a formated string (va_list version).
310
* Format a string at the given coordinates, using the default foreground
311
* and background values. The coordinates may be outside the canvas
312
* boundaries (eg. a negative Y coordinate) and the string will be cropped
313
* accordingly if it is too long. The syntax of the format string is the
314
* same as for the C vprintf() function.
316
* This function returns the number of cells printed by the string. It is
317
* not the number of characters printed, because fullwidth characters
318
* account for two cells.
320
* This function never fails.
322
* \param cv A handle to the libcaca canvas.
323
* \param x X coordinate.
324
* \param y Y coordinate.
325
* \param format The format string to print.
326
* \param args A va_list containting the arguments to the format string.
327
* \return The number of cells printed.
329
int caca_vprintf(caca_canvas_t *cv, int x, int y, char const *format,
263
332
char tmp[BUFSIZ];
267
if(y < 0 || y >= (int)cv->height || x >= (int)cv->width)
270
336
if(cv->width - x + 1 > BUFSIZ)
271
337
buf = malloc(cv->width - x + 1);
273
va_start(args, format);
274
339
#if defined(HAVE_VSNPRINTF)
275
340
vsnprintf(buf, cv->width - x + 1, format, args);
277
342
vsprintf(buf, format, args);
279
344
buf[cv->width - x] = '\0';
282
caca_put_str(cv, x, y, buf);
346
ret = caca_put_str(cv, x, y, buf);
290
354
/** \brief Clear the canvas.
375
442
* \return 0 in case of success, -1 if an error occurred.
377
444
int caca_blit(caca_canvas_t *dst, int x, int y,
378
caca_canvas_t const *src, caca_canvas_t const *mask)
445
caca_canvas_t const *src, caca_canvas_t const *mask)
380
int i, j, starti, startj, endi, endj;
447
int i, j, starti, startj, endi, endj, stride, bleed_left, bleed_right;
382
449
if(mask && (src->width != mask->width || src->height != mask->height))
392
459
startj = y < 0 ? -y : 0;
393
460
endi = (x + src->width >= dst->width) ? dst->width - x : src->width;
394
461
endj = (y + src->height >= dst->height) ? dst->height - y : src->height;
462
stride = endi - starti;
396
464
if(starti > src->width || startj > src->height
397
465
|| starti >= endi || startj >= endj)
468
bleed_left = bleed_right = 0;
400
470
for(j = startj; j < endj; j++)
402
472
int dstix = (j + y) * dst->width + starti + x;
403
473
int srcix = j * src->width + starti;
404
int stride = endi - starti;
406
475
/* FIXME: we are ignoring the mask here */
407
476
if((starti + x) && dst->chars[dstix] == CACA_MAGIC_FULLWIDTH)
408
478
dst->chars[dstix - 1] = ' ';
410
482
if(endi + x < dst->width
411
483
&& dst->chars[dstix + stride] == CACA_MAGIC_FULLWIDTH)
412
485
dst->chars[dstix + stride] = ' ';
418
493
if(mask->chars[srcix + i] == (uint32_t)' ')
421
dst->chars[dstix + i] = src->chars[srcix + i];
422
dst->attrs[dstix + i] = src->attrs[srcix + i];
496
if(dst->chars[dstix + i] != src->chars[srcix + i] ||
497
dst->attrs[dstix + i] != src->attrs[srcix + i])
499
dst->chars[dstix + i] = src->chars[srcix + i];
500
dst->attrs[dstix + i] = src->attrs[srcix + i];
501
if(!dst->dirty_disabled)
502
caca_add_dirty_rect(dst, x + starti + i, y + j, 1, 1);
427
memcpy(dst->chars + dstix, src->chars + srcix, stride * 4);
428
memcpy(dst->attrs + dstix, src->attrs + srcix, stride * 4);
508
if(memcmp(dst->chars + dstix, src->chars + srcix, stride * 4) ||
509
memcmp(dst->attrs + dstix, src->attrs + srcix, stride * 4))
511
/* FIXME be more precise ? */
512
memcpy(dst->chars + dstix, src->chars + srcix, stride * 4);
513
memcpy(dst->attrs + dstix, src->attrs + srcix, stride * 4);
514
if(!dst->dirty_disabled)
515
caca_add_dirty_rect(dst, x + starti, y + j, stride, 1);
431
519
/* Fix split fullwidth chars */
499
588
caca_set_frame(cv, saved_f);
500
589
_caca_load_frame_info(cv);
591
/* FIXME: this may be optimised somewhat */
592
if(!cv->dirty_disabled)
593
caca_add_dirty_rect(cv, 0, 0, cv->width, cv->height);
509
602
int cucul_gotoxy(cucul_canvas_t *, int, int) CACA_ALIAS(caca_gotoxy);
510
int cucul_get_cursor_x(cucul_canvas_t const *) CACA_ALIAS(caca_get_cursor_x);
511
int cucul_get_cursor_y(cucul_canvas_t const *) CACA_ALIAS(caca_get_cursor_y);
603
int cucul_get_cursor_x(cucul_canvas_t const *) CACA_ALIAS(caca_wherex);
604
int cucul_get_cursor_y(cucul_canvas_t const *) CACA_ALIAS(caca_wherey);
605
int caca_get_cursor_x(caca_canvas_t const *) CACA_ALIAS(caca_wherex);
606
int caca_get_cursor_y(caca_canvas_t const *) CACA_ALIAS(caca_wherey);
512
607
int cucul_put_char(cucul_canvas_t *, int, int, uint32_t)
513
608
CACA_ALIAS(caca_put_char);
514
609
uint32_t cucul_get_char(cucul_canvas_t const *, int, int)