You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

229 line
5.7 KiB

  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. /** \file char.c
  12. * \version \$Id$
  13. * \author Sam Hocevar <sam@zoy.org>
  14. * \brief Character drawing
  15. *
  16. * This file contains character and string drawing functions.
  17. */
  18. #include "config.h"
  19. #include <stdio.h> /* BUFSIZ */
  20. #include <string.h>
  21. #include <stdlib.h>
  22. #if defined(HAVE_UNISTD_H)
  23. # include <unistd.h>
  24. #endif
  25. #include <stdarg.h>
  26. #if defined(HAVE_SIGNAL_H)
  27. # include <signal.h>
  28. #endif
  29. #if defined(HAVE_SYS_IOCTL_H)
  30. # include <sys/ioctl.h>
  31. #endif
  32. #include "cucul.h"
  33. #include "cucul_internals.h"
  34. /** \brief Set the default colour pair.
  35. *
  36. * This function sets the default colour pair. String functions such as
  37. * caca_printf() and graphical primitive functions such as caca_draw_line()
  38. * will use these colour pairs.
  39. *
  40. * \param fgcolor The requested foreground colour.
  41. * \param bgcolor The requested background colour.
  42. */
  43. void cucul_set_color(cucul_t *qq, enum cucul_color fgcolor, enum cucul_color bgcolor)
  44. {
  45. if(fgcolor < 0 || fgcolor > 15 || bgcolor < 0 || bgcolor > 15)
  46. return;
  47. qq->fgcolor = fgcolor;
  48. qq->bgcolor = bgcolor;
  49. }
  50. /** \brief Get the current foreground colour.
  51. *
  52. * This function returns the current foreground colour that was set with
  53. * cucul_set_color().
  54. *
  55. * \return The current foreground colour.
  56. */
  57. enum cucul_color cucul_get_fg_color(cucul_t *qq)
  58. {
  59. return qq->fgcolor;
  60. }
  61. /** \brief Get the current background colour.
  62. *
  63. * This function returns the current background colour that was set with
  64. * cucul_set_color().
  65. *
  66. * \return The current background colour.
  67. */
  68. enum cucul_color cucul_get_bg_color(cucul_t *qq)
  69. {
  70. return qq->bgcolor;
  71. }
  72. /** \brief Print a character.
  73. *
  74. * This function prints a character at the given coordinates, using the
  75. * default foreground and background values. If the coordinates are outside
  76. * the screen boundaries, nothing is printed.
  77. *
  78. * \param x X coordinate.
  79. * \param y Y coordinate.
  80. * \param c The character to print.
  81. */
  82. void cucul_putchar(cucul_t *qq, int x, int y, char c)
  83. {
  84. if(x < 0 || x >= (int)qq->width ||
  85. y < 0 || y >= (int)qq->height)
  86. return;
  87. qq->chars[x + y * qq->width] = c & 0x0000007f; /* FIXME: ASCII-only */
  88. qq->attr[x + y * qq->width] = (qq->bgcolor << 4) | qq->fgcolor;
  89. }
  90. /** \brief Print a string.
  91. *
  92. * This function prints a string at the given coordinates, using the
  93. * default foreground and background values. The coordinates may be outside
  94. * the screen boundaries (eg. a negative Y coordinate) and the string will
  95. * be cropped accordingly if it is too long.
  96. *
  97. * \param x X coordinate.
  98. * \param y Y coordinate.
  99. * \param s The string to print.
  100. */
  101. void cucul_putstr(cucul_t *qq, int x, int y, char const *s)
  102. {
  103. uint32_t *chars;
  104. uint8_t *attr;
  105. char const *t;
  106. unsigned int len;
  107. if(y < 0 || y >= (int)qq->height || x >= (int)qq->width)
  108. return;
  109. len = strlen(s);
  110. if(x < 0)
  111. {
  112. if(len < (unsigned int)-x)
  113. return;
  114. len -= -x;
  115. s += -x;
  116. x = 0;
  117. }
  118. if(x + len >= qq->width)
  119. {
  120. len = qq->width - x;
  121. memcpy(qq->scratch_line, s, len);
  122. qq->scratch_line[len] = '\0';
  123. s = qq->scratch_line;
  124. }
  125. chars = qq->chars + x + y * qq->width;
  126. attr = qq->attr + x + y * qq->width;
  127. t = s;
  128. while(*t)
  129. {
  130. *chars++ = *t++ & 0x0000007f; /* FIXME: ASCII-only */
  131. *attr++ = (qq->bgcolor << 4) | qq->fgcolor;
  132. }
  133. }
  134. /** \brief Format a string.
  135. *
  136. * This function formats a string at the given coordinates, using the
  137. * default foreground and background values. The coordinates may be outside
  138. * the screen boundaries (eg. a negative Y coordinate) and the string will
  139. * be cropped accordingly if it is too long. The syntax of the format
  140. * string is the same as for the C printf() function.
  141. *
  142. * \param x X coordinate.
  143. * \param y Y coordinate.
  144. * \param format The format string to print.
  145. * \param ... Arguments to the format string.
  146. */
  147. void cucul_printf(cucul_t *qq, int x, int y, char const *format, ...)
  148. {
  149. char tmp[BUFSIZ];
  150. char *buf = tmp;
  151. va_list args;
  152. if(y < 0 || y >= (int)qq->height || x >= (int)qq->width)
  153. return;
  154. if(qq->width - x + 1 > BUFSIZ)
  155. buf = malloc(qq->width - x + 1);
  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. cucul_putstr(qq, x, y, buf);
  165. if(buf != tmp)
  166. free(buf);
  167. }
  168. /** \brief Get the screen.
  169. *
  170. * This function fills a byte array with the character values.
  171. */
  172. void cucul_get_screen(cucul_t *qq, char *buffer)
  173. {
  174. unsigned int x, y;
  175. for(y = 0; y < qq->height; y++)
  176. {
  177. for(x = 0; x < qq->width; x++)
  178. {
  179. *buffer++ = qq->attr[x + y * qq->width];
  180. *buffer++ = qq->chars[x + y * qq->width] & 0x7f; /* FIXME: ASCII */
  181. }
  182. }
  183. }
  184. /** \brief Clear the screen.
  185. *
  186. * This function clears the screen using a black background.
  187. */
  188. void cucul_clear(cucul_t *qq)
  189. {
  190. enum cucul_color oldfg = cucul_get_fg_color(qq);
  191. enum cucul_color oldbg = cucul_get_bg_color(qq);
  192. int y = qq->height;
  193. cucul_set_color(qq, CUCUL_COLOR_LIGHTGRAY, CUCUL_COLOR_BLACK);
  194. /* We could use SLsmg_cls() etc., but drawing empty lines is much faster */
  195. while(y--)
  196. cucul_putstr(qq, 0, y, qq->empty_line);
  197. cucul_set_color(qq, oldfg, oldbg);
  198. }