source: libcaca/trunk/cucul/frame.c @ 1452

Last change on this file since 1452 was 1452, checked in by Sam Hocevar, 14 years ago
  • Add a no warranty clause to the code.
  • Property svn:keywords set to Id
File size: 7.0 KB
RevLine 
[115]1/*
[672]2 *  libcucul      Canvas for ultrafast compositing of Unicode letters
[527]3 *  Copyright (c) 2002-2006 Sam Hocevar <sam@zoy.org>
[268]4 *                All Rights Reserved
[115]5 *
[769]6 *  $Id: frame.c 1452 2006-12-11 15:48:46Z sam $
7 *
[1452]8 *  This library is free software. It commes without any warranty, to
9 *  the extent permitted by applicable law. You can redistribute it
10 *  and/or modify it under the terms of the Do What The Fuck You Want
11 *  To Public License, Version 2, as published by Sam Hocevar. See
[522]12 *  http://sam.zoy.org/wtfpl/COPYING for more details.
[115]13 */
14
[769]15/*
[842]16 *  This file contains a small framework for canvas frame management.
[205]17 */
18
[115]19#include "config.h"
[859]20#include "common.h"
[115]21
[568]22#if !defined(__KERNEL__)
23#   include <stdio.h>
24#   include <stdlib.h>
25#   include <string.h>
26#endif
[115]27
[524]28#include "cucul.h"
29#include "cucul_internals.h"
[115]30
[842]31/** \brief Get the number of frames in a canvas.
[257]32 *
[1231]33 *  Return the current canvas' frame count.
[257]34 *
[920]35 *  This function never fails.
36 *
[842]37 *  \param cv A libcucul canvas
38 *  \return The frame count
[257]39 */
[1390]40unsigned int cucul_get_frame_count(cucul_canvas_t *cv)
[121]41{
[842]42    return cv->framecount;
[153]43}
44
[842]45/** \brief Activate a given canvas frame.
[257]46 *
[1231]47 *  Set the active canvas frame. All subsequent drawing operations will
48 *  be performed on that frame. The current painting context set by
[1257]49 *  cucul_set_attr() is inherited.
[842]50 *
51 *  If the frame index is outside the canvas' frame range, nothing happens.
52 *
[920]53 *  If an error occurs, -1 is returned and \b errno is set accordingly:
54 *  - \c EINVAL Requested frame is out of range.
55 *
[842]56 *  \param cv A libcucul canvas
[1390]57 *  \param id The canvas frame to activate
[920]58 *  \return 0 in case of success, -1 if an error occurred.
[257]59 */
[1390]60int cucul_set_frame(cucul_canvas_t *cv, unsigned int id)
[153]61{
[1390]62    if(id >= cv->framecount)
[920]63    {
[1362]64        seterrno(EINVAL);
[920]65        return -1;
66    }
[153]67
[1381]68    _cucul_save_frame_info(cv);
[1390]69    cv->frame = id;
[1381]70    _cucul_load_frame_info(cv);
[121]71
[920]72    return 0;
[121]73}
74
[1390]75/** \brief Get the current frame's name.
76 *
77 *  Return the current frame's name. The returned string is valid until
78 *  the frame is deleted or cucul_set_frame_name() is called to change
79 *  the frame name again.
80 *
81 *  This function never fails.
82 *
83 *  \param cv A libcucul canvas.
84 *  \return The current frame's name.
85 */
86char const *cucul_get_frame_name(cucul_canvas_t *cv)
87{
88    return cv->frames[cv->frame].name;
89}
90
91/** \brief Set the current frame's name.
92 *
93 *  Set the current frame's name. Upon creation, a frame has a default name
[1397]94 *  of \c "frame#xxxxxxxx" where \c xxxxxxxx is a self-incrementing
[1390]95 *  hexadecimal number.
96 *
97 *  If an error occurs, -1 is returned and \b errno is set accordingly:
98 *  - \c ENOMEM Not enough memory to allocate new frame.
99 *
100 *  \param cv A libcucul canvas.
[1397]101 *  \param name The name to give to the current frame.
[1390]102 *  \return 0 in case of success, -1 if an error occurred.
103 */
104int cucul_set_frame_name(cucul_canvas_t *cv, char const *name)
105{
106    char *newname = strdup(name);
107
108    if(!newname)
109    {
110        seterrno(ENOMEM);
111        return -1;
112    }
113
114    free(cv->frames[cv->frame].name);
115    cv->frames[cv->frame].name = newname;
116
117    return 0;
118}
119
[842]120/** \brief Add a frame to a canvas.
[257]121 *
[1341]122 *  Create a new frame within the given canvas. Its contents and attributes
123 *  are copied from the currently active frame.
[842]124 *
125 *  The frame index indicates where the frame should be inserted. Valid
126 *  values range from 0 to the current canvas frame count. If the frame
[1338]127 *  index is greater than or equals the current canvas frame count, the new
[842]128 *  frame is appended at the end of the canvas.
129 *
130 *  The active frame does not change, but its index may be renumbered due
131 *  to the insertion.
132 *
[920]133 *  If an error occurs, -1 is returned and \b errno is set accordingly:
134 *  - \c ENOMEM Not enough memory to allocate new frame.
135 *
[842]136 *  \param cv A libcucul canvas
[1357]137 *  \param id The index where to insert the new frame
[920]138 *  \return 0 in case of success, -1 if an error occurred.
[257]139 */
[1390]140int cucul_create_frame(cucul_canvas_t *cv, unsigned int id)
[121]141{
[1341]142    unsigned int size = cv->width * cv->height;
[842]143    unsigned int f;
[135]144
[1341]145    if(id > cv->framecount)
146        id = cv->framecount;
[153]147
[842]148    cv->framecount++;
[1338]149    cv->frames = realloc(cv->frames,
150                         sizeof(struct cucul_frame) * cv->framecount);
[121]151
[1341]152    for(f = cv->framecount - 1; f > id; f--)
[1338]153        cv->frames[f] = cv->frames[f - 1];
[153]154
[1342]155    if(cv->frame >= id)
156        cv->frame++;
157
[1341]158    cv->frames[id].width = cv->width;
159    cv->frames[id].height = cv->height;
160    cv->frames[id].chars = malloc(size * sizeof(uint32_t));
161    memcpy(cv->frames[id].chars, cv->chars, size * sizeof(uint32_t));
162    cv->frames[id].attrs = malloc(size * sizeof(uint32_t));
163    memcpy(cv->frames[id].attrs, cv->attrs, size * sizeof(uint32_t));
164    cv->frames[id].curattr = cv->curattr;
[153]165
[1342]166    cv->frames[id].x = cv->frames[cv->frame].x;
167    cv->frames[id].y = cv->frames[cv->frame].y;
168    cv->frames[id].handlex = cv->frames[cv->frame].handlex;
169    cv->frames[id].handley = cv->frames[cv->frame].handley;
[153]170
[1390]171    cv->frames[id].name = strdup("frame#--------");
[1431]172    sprintf(cv->frames[id].name + 6, "%.08x", ++cv->autoinc);
[1390]173
[920]174    return 0;
[153]175}
176
[842]177/** \brief Remove a frame from a canvas.
[257]178 *
[1231]179 *  Delete a frame from a given canvas.
[842]180 *
181 *  The frame index indicates the frame to delete. Valid values range from
182 *  0 to the current canvas frame count minus 1. If the frame index is
[1431]183 *  greater than or equals the current canvas frame count, the last frame
[842]184 *  is deleted.
185 *
186 *  If the active frame is deleted, frame 0 becomes the new active frame.
187 *  Otherwise, the active frame does not change, but its index may be
188 *  renumbered due to the deletion.
189 *
[920]190 *  If an error occurs, -1 is returned and \b errno is set accordingly:
191 *  - \c EINVAL Requested frame is out of range, or attempt to delete the
192 *    last frame of the canvas.
193 *
[811]194 *  \param cv A libcucul canvas
[1357]195 *  \param id The index of the frame to delete
[920]196 *  \return 0 in case of success, -1 if an error occurred.
[257]197 */
[1390]198int cucul_free_frame(cucul_canvas_t *cv, unsigned int id)
[153]199{
[842]200    unsigned int f;
[115]201
[1341]202    if(id >= cv->framecount)
[920]203    {
[1362]204        seterrno(EINVAL);
[920]205        return -1;
206    }
[135]207
[842]208    if(cv->framecount == 1)
[920]209    {
[1362]210        seterrno(EINVAL);
[920]211        return -1;
212    }
[135]213
[1341]214    free(cv->frames[id].chars);
215    free(cv->frames[id].attrs);
[1390]216    free(cv->frames[id].name);
[153]217
[1341]218    for(f = id + 1; f < cv->framecount; f++)
[1338]219        cv->frames[f - 1] = cv->frames[f];
[153]220
[842]221    cv->framecount--;
[1338]222    cv->frames = realloc(cv->frames,
223                         sizeof(struct cucul_frame) * cv->framecount);
[115]224
[1341]225    if(cv->frame > id)
[842]226        cv->frame--;
[1341]227    else if(cv->frame == id)
[1338]228    {
[842]229        cv->frame = 0;
[1381]230        _cucul_load_frame_info(cv);
[1338]231    }
[121]232
[920]233    return 0;
[115]234}
235
[1338]236/*
237 * XXX: the following functions are local.
238 */
239
[1381]240void _cucul_save_frame_info(cucul_canvas_t *cv)
[1338]241{
242    cv->frames[cv->frame].width = cv->width;
243    cv->frames[cv->frame].height = cv->height;
244
245    cv->frames[cv->frame].curattr = cv->curattr;
246}
247
[1381]248void _cucul_load_frame_info(cucul_canvas_t *cv)
[1338]249{
250    cv->width = cv->frames[cv->frame].width;
251    cv->height = cv->frames[cv->frame].height;
252
253    cv->chars = cv->frames[cv->frame].chars;
254    cv->attrs = cv->frames[cv->frame].attrs;
255
256    cv->curattr = cv->frames[cv->frame].curattr;
257}
258
Note: See TracBrowser for help on using the repository browser.