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

Last change on this file since 2299 was 2299, checked in by Sam Hocevar, 12 years ago
  • Remove #include <stdint.h> etc. from "common.h". Instead, make sure that <cucul.h> will provide the C99 types, even if libcaca has been installed.
  • Rename what's left of "common.h" to "stubs.h".
  • Remove all references to erroneous <inttypes.h> from source files.
  • 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 2299 2008-04-19 12:42:50Z sam $
7 *
[1462]8 *  This library is free software. It comes without any warranty, to
[1452]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"
20
[568]21#if !defined(__KERNEL__)
22#   include <stdio.h>
23#   include <stdlib.h>
24#   include <string.h>
25#endif
[115]26
[524]27#include "cucul.h"
28#include "cucul_internals.h"
[115]29
[842]30/** \brief Get the number of frames in a canvas.
[257]31 *
[1231]32 *  Return the current canvas' frame count.
[257]33 *
[920]34 *  This function never fails.
35 *
[842]36 *  \param cv A libcucul canvas
37 *  \return The frame count
[257]38 */
[2043]39unsigned int cucul_get_frame_count(cucul_canvas_t const *cv)
[121]40{
[842]41    return cv->framecount;
[153]42}
43
[842]44/** \brief Activate a given canvas frame.
[257]45 *
[1231]46 *  Set the active canvas frame. All subsequent drawing operations will
47 *  be performed on that frame. The current painting context set by
[1257]48 *  cucul_set_attr() is inherited.
[842]49 *
50 *  If the frame index is outside the canvas' frame range, nothing happens.
51 *
[920]52 *  If an error occurs, -1 is returned and \b errno is set accordingly:
53 *  - \c EINVAL Requested frame is out of range.
54 *
[842]55 *  \param cv A libcucul canvas
[1390]56 *  \param id The canvas frame to activate
[920]57 *  \return 0 in case of success, -1 if an error occurred.
[257]58 */
[1390]59int cucul_set_frame(cucul_canvas_t *cv, unsigned int id)
[153]60{
[1390]61    if(id >= cv->framecount)
[920]62    {
[1362]63        seterrno(EINVAL);
[920]64        return -1;
65    }
[153]66
[1381]67    _cucul_save_frame_info(cv);
[1390]68    cv->frame = id;
[1381]69    _cucul_load_frame_info(cv);
[121]70
[920]71    return 0;
[121]72}
73
[1390]74/** \brief Get the current frame's name.
75 *
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.
79 *
80 *  This function never fails.
81 *
82 *  \param cv A libcucul canvas.
83 *  \return The current frame's name.
84 */
[2043]85char const *cucul_get_frame_name(cucul_canvas_t const *cv)
[1390]86{
87    return cv->frames[cv->frame].name;
88}
89
90/** \brief Set the current frame's name.
91 *
92 *  Set the current frame's name. Upon creation, a frame has a default name
[1397]93 *  of \c "frame#xxxxxxxx" where \c xxxxxxxx is a self-incrementing
[1390]94 *  hexadecimal number.
95 *
96 *  If an error occurs, -1 is returned and \b errno is set accordingly:
97 *  - \c ENOMEM Not enough memory to allocate new frame.
98 *
99 *  \param cv A libcucul canvas.
[1397]100 *  \param name The name to give to the current frame.
[1390]101 *  \return 0 in case of success, -1 if an error occurred.
102 */
103int cucul_set_frame_name(cucul_canvas_t *cv, char const *name)
104{
105    char *newname = strdup(name);
106
107    if(!newname)
108    {
109        seterrno(ENOMEM);
110        return -1;
111    }
112
113    free(cv->frames[cv->frame].name);
114    cv->frames[cv->frame].name = newname;
115
116    return 0;
117}
118
[842]119/** \brief Add a frame to a canvas.
[257]120 *
[1341]121 *  Create a new frame within the given canvas. Its contents and attributes
122 *  are copied from the currently active frame.
[842]123 *
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
[1338]126 *  index is greater than or equals the current canvas frame count, the new
[842]127 *  frame is appended at the end of the canvas.
128 *
129 *  The active frame does not change, but its index may be renumbered due
130 *  to the insertion.
131 *
[920]132 *  If an error occurs, -1 is returned and \b errno is set accordingly:
133 *  - \c ENOMEM Not enough memory to allocate new frame.
134 *
[842]135 *  \param cv A libcucul canvas
[1357]136 *  \param id The index where to insert the new frame
[920]137 *  \return 0 in case of success, -1 if an error occurred.
[257]138 */
[1390]139int cucul_create_frame(cucul_canvas_t *cv, unsigned int id)
[121]140{
[1341]141    unsigned int size = cv->width * cv->height;
[842]142    unsigned int f;
[135]143
[1341]144    if(id > cv->framecount)
145        id = cv->framecount;
[153]146
[842]147    cv->framecount++;
[1338]148    cv->frames = realloc(cv->frames,
149                         sizeof(struct cucul_frame) * cv->framecount);
[121]150
[1341]151    for(f = cv->framecount - 1; f > id; f--)
[1338]152        cv->frames[f] = cv->frames[f - 1];
[153]153
[1342]154    if(cv->frame >= id)
155        cv->frame++;
156
[1341]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;
[153]164
[1342]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;
[153]169
[1390]170    cv->frames[id].name = strdup("frame#--------");
[1431]171    sprintf(cv->frames[id].name + 6, "%.08x", ++cv->autoinc);
[1390]172
[920]173    return 0;
[153]174}
175
[842]176/** \brief Remove a frame from a canvas.
[257]177 *
[1231]178 *  Delete a frame from a given canvas.
[842]179 *
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
[1431]182 *  greater than or equals the current canvas frame count, the last frame
[842]183 *  is deleted.
184 *
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.
188 *
[920]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.
192 *
[811]193 *  \param cv A libcucul canvas
[1357]194 *  \param id The index of the frame to delete
[920]195 *  \return 0 in case of success, -1 if an error occurred.
[257]196 */
[1390]197int cucul_free_frame(cucul_canvas_t *cv, unsigned int id)
[153]198{
[842]199    unsigned int f;
[115]200
[1341]201    if(id >= cv->framecount)
[920]202    {
[1362]203        seterrno(EINVAL);
[920]204        return -1;
205    }
[135]206
[842]207    if(cv->framecount == 1)
[920]208    {
[1362]209        seterrno(EINVAL);
[920]210        return -1;
211    }
[135]212
[1341]213    free(cv->frames[id].chars);
214    free(cv->frames[id].attrs);
[1390]215    free(cv->frames[id].name);
[153]216
[1341]217    for(f = id + 1; f < cv->framecount; f++)
[1338]218        cv->frames[f - 1] = cv->frames[f];
[153]219
[842]220    cv->framecount--;
[1338]221    cv->frames = realloc(cv->frames,
222                         sizeof(struct cucul_frame) * cv->framecount);
[115]223
[1341]224    if(cv->frame > id)
[842]225        cv->frame--;
[1341]226    else if(cv->frame == id)
[1338]227    {
[842]228        cv->frame = 0;
[1381]229        _cucul_load_frame_info(cv);
[1338]230    }
[121]231
[920]232    return 0;
[115]233}
234
[1338]235/*
236 * XXX: the following functions are local.
237 */
238
[1381]239void _cucul_save_frame_info(cucul_canvas_t *cv)
[1338]240{
241    cv->frames[cv->frame].width = cv->width;
242    cv->frames[cv->frame].height = cv->height;
243
244    cv->frames[cv->frame].curattr = cv->curattr;
245}
246
[1381]247void _cucul_load_frame_info(cucul_canvas_t *cv)
[1338]248{
249    cv->width = cv->frames[cv->frame].width;
250    cv->height = cv->frames[cv->frame].height;
251
252    cv->chars = cv->frames[cv->frame].chars;
253    cv->attrs = cv->frames[cv->frame].attrs;
254
255    cv->curattr = cv->frames[cv->frame].curattr;
256}
257
Note: See TracBrowser for help on using the repository browser.