2
* libcucul Canvas for ultrafast compositing of Unicode letters
3
* Copyright (c) 2002-2006 Sam Hocevar <sam@zoy.org>
6
* $Id: frame.c 1070 2006-11-14 18:05:02Z sam $
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.
15
* This file contains a small framework for canvas frame management.
21
#if !defined(__KERNEL__)
28
#include "cucul_internals.h"
30
/** \brief Get the number of frames in a canvas.
32
* Return the current canvas' frame count.
34
* This function never fails.
36
* \param cv A libcucul canvas
37
* \return The frame count
39
unsigned int cucul_get_frame_count(cucul_canvas_t *cv)
41
return cv->framecount;
44
/** \brief Activate a given canvas frame.
46
* Set the active canvas frame. All subsequent drawing operations will
47
* be performed on that frame. The current painting context set by
48
* cucul_set_attr() is inherited.
50
* If the frame index is outside the canvas' frame range, nothing happens.
52
* If an error occurs, -1 is returned and \b errno is set accordingly:
53
* - \c EINVAL Requested frame is out of range.
55
* \param cv A libcucul canvas
56
* \param id The canvas frame to activate
57
* \return 0 in case of success, -1 if an error occurred.
59
int cucul_set_frame(cucul_canvas_t *cv, unsigned int id)
61
if(id >= cv->framecount)
67
_cucul_save_frame_info(cv);
69
_cucul_load_frame_info(cv);
74
/** \brief Get the current frame's name.
76
* Return the current frame's name. The returned string is valid until
77
* the frame is deleted or cucul_set_frame_name() is called to change
78
* the frame name again.
80
* This function never fails.
82
* \param cv A libcucul canvas.
83
* \return The current frame's name.
85
char const *cucul_get_frame_name(cucul_canvas_t *cv)
87
return cv->frames[cv->frame].name;
90
/** \brief Set the current frame's name.
92
* Set the current frame's name. Upon creation, a frame has a default name
93
* of \c "frame#xxxxxxxx" where \c xxxxxxxx is a self-incrementing
96
* If an error occurs, -1 is returned and \b errno is set accordingly:
97
* - \c ENOMEM Not enough memory to allocate new frame.
99
* \param cv A libcucul canvas.
100
* \param name The name to give to the current frame.
101
* \return 0 in case of success, -1 if an error occurred.
103
int cucul_set_frame_name(cucul_canvas_t *cv, char const *name)
105
char *newname = strdup(name);
113
free(cv->frames[cv->frame].name);
114
cv->frames[cv->frame].name = newname;
119
/** \brief Add a frame to a canvas.
121
* Create a new frame within the given canvas. Its contents and attributes
122
* are copied from the currently active frame.
124
* The frame index indicates where the frame should be inserted. Valid
125
* values range from 0 to the current canvas frame count. If the frame
126
* index is greater than or equals the current canvas frame count, the new
127
* frame is appended at the end of the canvas.
129
* The active frame does not change, but its index may be renumbered due
132
* If an error occurs, -1 is returned and \b errno is set accordingly:
133
* - \c ENOMEM Not enough memory to allocate new frame.
135
* \param cv A libcucul canvas
136
* \param id The index where to insert the new frame
137
* \return 0 in case of success, -1 if an error occurred.
139
int cucul_create_frame(cucul_canvas_t *cv, unsigned int id)
141
unsigned int size = cv->width * cv->height;
144
if(id > cv->framecount)
148
cv->frames = realloc(cv->frames,
149
sizeof(struct cucul_frame) * cv->framecount);
151
for(f = cv->framecount - 1; f > id; f--)
152
cv->frames[f] = cv->frames[f - 1];
157
cv->frames[id].width = cv->width;
158
cv->frames[id].height = cv->height;
159
cv->frames[id].chars = malloc(size * sizeof(uint32_t));
160
memcpy(cv->frames[id].chars, cv->chars, size * sizeof(uint32_t));
161
cv->frames[id].attrs = malloc(size * sizeof(uint32_t));
162
memcpy(cv->frames[id].attrs, cv->attrs, size * sizeof(uint32_t));
163
cv->frames[id].curattr = cv->curattr;
165
cv->frames[id].x = cv->frames[cv->frame].x;
166
cv->frames[id].y = cv->frames[cv->frame].y;
167
cv->frames[id].handlex = cv->frames[cv->frame].handlex;
168
cv->frames[id].handley = cv->frames[cv->frame].handley;
170
cv->frames[id].name = strdup("frame#--------");
171
sprintf(cv->frames[id].name + 6, "%.08x", cv->autoinc++);
176
/** \brief Remove a frame from a canvas.
178
* Delete a frame from a given canvas.
180
* The frame index indicates the frame to delete. Valid values range from
181
* 0 to the current canvas frame count minus 1. If the frame index is
182
* greater the or equals the current canvas frame count, the last frame
185
* If the active frame is deleted, frame 0 becomes the new active frame.
186
* Otherwise, the active frame does not change, but its index may be
187
* renumbered due to the deletion.
189
* If an error occurs, -1 is returned and \b errno is set accordingly:
190
* - \c EINVAL Requested frame is out of range, or attempt to delete the
191
* last frame of the canvas.
193
* \param cv A libcucul canvas
194
* \param id The index of the frame to delete
195
* \return 0 in case of success, -1 if an error occurred.
197
int cucul_free_frame(cucul_canvas_t *cv, unsigned int id)
201
if(id >= cv->framecount)
207
if(cv->framecount == 1)
213
free(cv->frames[id].chars);
214
free(cv->frames[id].attrs);
215
free(cv->frames[id].name);
217
for(f = id + 1; f < cv->framecount; f++)
218
cv->frames[f - 1] = cv->frames[f];
221
cv->frames = realloc(cv->frames,
222
sizeof(struct cucul_frame) * cv->framecount);
226
else if(cv->frame == id)
229
_cucul_load_frame_info(cv);
236
* XXX: the following functions are local.
239
void _cucul_save_frame_info(cucul_canvas_t *cv)
241
cv->frames[cv->frame].width = cv->width;
242
cv->frames[cv->frame].height = cv->height;
244
cv->frames[cv->frame].curattr = cv->curattr;
247
void _cucul_load_frame_info(cucul_canvas_t *cv)
249
cv->width = cv->frames[cv->frame].width;
250
cv->height = cv->frames[cv->frame].height;
252
cv->chars = cv->frames[cv->frame].chars;
253
cv->attrs = cv->frames[cv->frame].attrs;
255
cv->curattr = cv->frames[cv->frame].curattr;