Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.
 
 
 
 
 
 

216 Zeilen
5.7 KiB

  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$
  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. * This file contains a small framework for canvas frame management.
  15. */
  16. #include "config.h"
  17. #include "common.h"
  18. #if !defined(__KERNEL__)
  19. # include <stdio.h>
  20. # include <stdlib.h>
  21. # include <string.h>
  22. # if defined(HAVE_ERRNO_H)
  23. # include <errno.h>
  24. # endif
  25. #endif
  26. #include "cucul.h"
  27. #include "cucul_internals.h"
  28. static void save_frame_info(cucul_canvas_t *);
  29. static void load_frame_info(cucul_canvas_t *);
  30. /** \brief Get the number of frames in a canvas.
  31. *
  32. * Return the current canvas' frame count.
  33. *
  34. * This function never fails.
  35. *
  36. * \param cv A libcucul canvas
  37. * \return The frame count
  38. */
  39. unsigned int cucul_get_canvas_frame_count(cucul_canvas_t *cv)
  40. {
  41. return cv->framecount;
  42. }
  43. /** \brief Activate a given canvas frame.
  44. *
  45. * Set the active canvas frame. All subsequent drawing operations will
  46. * be performed on that frame. The current painting context set by
  47. * cucul_set_attr() is inherited.
  48. *
  49. * If the frame index is outside the canvas' frame range, nothing happens.
  50. *
  51. * If an error occurs, -1 is returned and \b errno is set accordingly:
  52. * - \c EINVAL Requested frame is out of range.
  53. *
  54. * \param cv A libcucul canvas
  55. * \param frame The canvas frame to activate
  56. * \return 0 in case of success, -1 if an error occurred.
  57. */
  58. int cucul_set_canvas_frame(cucul_canvas_t *cv, unsigned int frame)
  59. {
  60. if(frame >= cv->framecount)
  61. {
  62. #if defined(HAVE_ERRNO_H)
  63. errno = EINVAL;
  64. #endif
  65. return -1;
  66. }
  67. save_frame_info(cv);
  68. cv->frame = frame;
  69. load_frame_info(cv);
  70. return 0;
  71. }
  72. /** \brief Add a frame to a canvas.
  73. *
  74. * Create a new frame within the given canvas. Its contents and attributes
  75. * are copied from the currently active frame.
  76. *
  77. * The frame index indicates where the frame should be inserted. Valid
  78. * values range from 0 to the current canvas frame count. If the frame
  79. * index is greater than or equals the current canvas frame count, the new
  80. * frame is appended at the end of the canvas.
  81. *
  82. * The active frame does not change, but its index may be renumbered due
  83. * to the insertion.
  84. *
  85. * If an error occurs, -1 is returned and \b errno is set accordingly:
  86. * - \c ENOMEM Not enough memory to allocate new frame.
  87. *
  88. * \param cv A libcucul canvas
  89. * \param frame The index where to insert the new frame
  90. * \return 0 in case of success, -1 if an error occurred.
  91. */
  92. int cucul_create_canvas_frame(cucul_canvas_t *cv, unsigned int id)
  93. {
  94. unsigned int size = cv->width * cv->height;
  95. unsigned int f;
  96. if(id > cv->framecount)
  97. id = cv->framecount;
  98. cv->framecount++;
  99. cv->frames = realloc(cv->frames,
  100. sizeof(struct cucul_frame) * cv->framecount);
  101. for(f = cv->framecount - 1; f > id; f--)
  102. cv->frames[f] = cv->frames[f - 1];
  103. cv->frames[id].width = cv->width;
  104. cv->frames[id].height = cv->height;
  105. cv->frames[id].chars = malloc(size * sizeof(uint32_t));
  106. memcpy(cv->frames[id].chars, cv->chars, size * sizeof(uint32_t));
  107. cv->frames[id].attrs = malloc(size * sizeof(uint32_t));
  108. memcpy(cv->frames[id].attrs, cv->attrs, size * sizeof(uint32_t));
  109. cv->frames[id].curattr = cv->curattr;
  110. if(cv->frame >= id)
  111. cv->frame++;
  112. return 0;
  113. }
  114. /** \brief Remove a frame from a canvas.
  115. *
  116. * Delete a frame from a given canvas.
  117. *
  118. * The frame index indicates the frame to delete. Valid values range from
  119. * 0 to the current canvas frame count minus 1. If the frame index is
  120. * greater the or equals the current canvas frame count, the last frame
  121. * is deleted.
  122. *
  123. * If the active frame is deleted, frame 0 becomes the new active frame.
  124. * Otherwise, the active frame does not change, but its index may be
  125. * renumbered due to the deletion.
  126. *
  127. * If an error occurs, -1 is returned and \b errno is set accordingly:
  128. * - \c EINVAL Requested frame is out of range, or attempt to delete the
  129. * last frame of the canvas.
  130. *
  131. * \param cv A libcucul canvas
  132. * \param frame The index of the frame to delete
  133. * \return 0 in case of success, -1 if an error occurred.
  134. */
  135. int cucul_free_canvas_frame(cucul_canvas_t *cv, unsigned int id)
  136. {
  137. unsigned int f;
  138. if(id >= cv->framecount)
  139. {
  140. #if defined(HAVE_ERRNO_H)
  141. errno = EINVAL;
  142. #endif
  143. return -1;
  144. }
  145. if(cv->framecount == 1)
  146. {
  147. #if defined(HAVE_ERRNO_H)
  148. errno = EINVAL;
  149. #endif
  150. return -1;
  151. }
  152. free(cv->frames[id].chars);
  153. free(cv->frames[id].attrs);
  154. for(f = id + 1; f < cv->framecount; f++)
  155. cv->frames[f - 1] = cv->frames[f];
  156. cv->framecount--;
  157. cv->frames = realloc(cv->frames,
  158. sizeof(struct cucul_frame) * cv->framecount);
  159. if(cv->frame > id)
  160. cv->frame--;
  161. else if(cv->frame == id)
  162. {
  163. cv->frame = 0;
  164. load_frame_info(cv);
  165. }
  166. return 0;
  167. }
  168. /*
  169. * XXX: the following functions are local.
  170. */
  171. static void save_frame_info(cucul_canvas_t *cv)
  172. {
  173. cv->frames[cv->frame].width = cv->width;
  174. cv->frames[cv->frame].height = cv->height;
  175. cv->frames[cv->frame].curattr = cv->curattr;
  176. }
  177. static void load_frame_info(cucul_canvas_t *cv)
  178. {
  179. cv->width = cv->frames[cv->frame].width;
  180. cv->height = cv->frames[cv->frame].height;
  181. cv->chars = cv->frames[cv->frame].chars;
  182. cv->attrs = cv->frames[cv->frame].attrs;
  183. cv->curattr = cv->frames[cv->frame].curattr;
  184. }