|
- /*
- * libcucul Canvas for ultrafast compositing of Unicode letters
- * Copyright (c) 2002-2006 Sam Hocevar <sam@zoy.org>
- * All Rights Reserved
- *
- * $Id$
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the Do What The Fuck You Want To
- * Public License, Version 2, as published by Sam Hocevar. See
- * http://sam.zoy.org/wtfpl/COPYING for more details.
- */
-
- /*
- * This file contains a small framework for canvas frame management.
- */
-
- #include "config.h"
- #include "common.h"
-
- #if !defined(__KERNEL__)
- # include <stdio.h>
- # include <stdlib.h>
- # include <string.h>
- # if defined(HAVE_ERRNO_H)
- # include <errno.h>
- # endif
- #endif
-
- #include "cucul.h"
- #include "cucul_internals.h"
-
- /** \brief Get the number of frames in a canvas.
- *
- * Return the current canvas' frame count.
- *
- * This function never fails.
- *
- * \param cv A libcucul canvas
- * \return The frame count
- */
- unsigned int cucul_get_canvas_frame_count(cucul_canvas_t *cv)
- {
- return cv->framecount;
- }
-
- /** \brief Activate a given canvas frame.
- *
- * Set the active canvas frame. All subsequent drawing operations will
- * be performed on that frame. The current painting context set by
- * cucul_set_color() or cucul_set_truecolor() is inherited.
- *
- * If the frame index is outside the canvas' frame range, nothing happens.
- *
- * If an error occurs, -1 is returned and \b errno is set accordingly:
- * - \c EINVAL Requested frame is out of range.
- *
- * \param cv A libcucul canvas
- * \param frame The canvas frame to activate
- * \return 0 in case of success, -1 if an error occurred.
- */
- int cucul_set_canvas_frame(cucul_canvas_t *cv, unsigned int frame)
- {
- if(frame >= cv->framecount)
- {
- #if defined(HAVE_ERRNO_H)
- errno = EINVAL;
- #endif
- return -1;
- }
-
- cv->frame = frame;
-
- cv->chars = cv->allchars[cv->frame];
- cv->attr = cv->allattr[cv->frame];
-
- return 0;
- }
-
- /** \brief Add a frame to a canvas.
- *
- * Create a new frame within the given canvas. Its contents are copied
- * from the currently active frame.
- *
- * The frame index indicates where the frame should be inserted. Valid
- * values range from 0 to the current canvas frame count. If the frame
- * index is greater the or equals the current canvas frame count, the new
- * frame is appended at the end of the canvas.
- *
- * The active frame does not change, but its index may be renumbered due
- * to the insertion.
- *
- * If an error occurs, -1 is returned and \b errno is set accordingly:
- * - \c ENOMEM Not enough memory to allocate new frame.
- *
- * \param cv A libcucul canvas
- * \param frame The index where to insert the new frame
- * \return 0 in case of success, -1 if an error occurred.
- */
- int cucul_create_canvas_frame(cucul_canvas_t *cv, unsigned int frame)
- {
- unsigned int size = cv->width * cv->height * sizeof(uint32_t);
- unsigned int f;
-
- if(frame > cv->framecount)
- frame = cv->framecount;
-
- cv->framecount++;
- cv->allchars = realloc(cv->allchars, sizeof(uint32_t *) * cv->framecount);
- cv->allattr = realloc(cv->allattr, sizeof(uint32_t *) * cv->framecount);
-
- for(f = cv->framecount - 1; f > frame; f--)
- {
- cv->allchars[f] = cv->allchars[f - 1];
- cv->allattr[f] = cv->allattr[f - 1];
- }
-
- cv->allchars[frame] = malloc(size);
- memcpy(cv->allchars[frame], cv->chars, size);
- cv->allattr[frame] = malloc(size);
- memcpy(cv->allattr[frame], cv->attr, size);
-
- if(cv->frame >= frame)
- cv->frame++;
-
- cv->chars = cv->allchars[cv->frame];
- cv->attr = cv->allattr[cv->frame];
-
- return 0;
- }
-
- /** \brief Remove a frame from a canvas.
- *
- * Delete a frame from a given canvas.
- *
- * The frame index indicates the frame to delete. Valid values range from
- * 0 to the current canvas frame count minus 1. If the frame index is
- * greater the or equals the current canvas frame count, the last frame
- * is deleted.
- *
- * If the active frame is deleted, frame 0 becomes the new active frame.
- * Otherwise, the active frame does not change, but its index may be
- * renumbered due to the deletion.
- *
- * If an error occurs, -1 is returned and \b errno is set accordingly:
- * - \c EINVAL Requested frame is out of range, or attempt to delete the
- * last frame of the canvas.
- *
- * \param cv A libcucul canvas
- * \param frame The index of the frame to delete
- * \return 0 in case of success, -1 if an error occurred.
- */
- int cucul_free_canvas_frame(cucul_canvas_t *cv, unsigned int frame)
- {
- unsigned int f;
-
- if(frame >= cv->framecount)
- {
- #if defined(HAVE_ERRNO_H)
- errno = EINVAL;
- #endif
- return -1;
- }
-
- if(cv->framecount == 1)
- {
- #if defined(HAVE_ERRNO_H)
- errno = EINVAL;
- #endif
- return -1;
- }
-
- free(cv->allchars[frame]);
- free(cv->allattr[frame]);
-
- for(f = frame + 1; f < cv->framecount; f++)
- {
- cv->allchars[f - 1] = cv->allchars[f];
- cv->allattr[f - 1] = cv->allattr[f];
- }
-
- cv->framecount--;
- cv->allchars = realloc(cv->allchars, sizeof(uint32_t *) * cv->framecount);
- cv->allattr = realloc(cv->allattr, sizeof(uint32_t *) * cv->framecount);
-
- if(cv->frame > frame)
- cv->frame--;
- else if(cv->frame == frame)
- cv->frame = 0;
-
- cv->chars = cv->allchars[cv->frame];
- cv->attr = cv->allattr[cv->frame];
-
- return 0;
- }
|