source: libcaca/trunk/caca/dirty.c @ 3514

Last change on this file since 3514 was 3494, checked in by Sam Hocevar, 11 years ago

Change the dirty rectangle API once again so that calling applications get
a more natural (x,y,w,h) 4-tuple to handle.

  • Property svn:keywords set to Id
File size: 6.4 KB
Line 
1/*
2 *  libcaca       Colour ASCII-Art library
3 *  Copyright (c) 2002-2009 Sam Hocevar <sam@hocevar.net>
4 *                All Rights Reserved
5 *
6 *  $Id: dirty.c 3494 2009-05-21 20:55:13Z sam $
7 *
8 *  This library is free software. It comes 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
12 *  http://sam.zoy.org/wtfpl/COPYING for more details.
13 */
14
15/*
16 *  This file contains the dirty rectangle handling functions.
17 */
18
19#include "config.h"
20
21#if !defined(__KERNEL__)
22#   include <stdio.h>
23#endif
24
25#include "caca.h"
26#include "caca_internals.h"
27
28/** \brief Get the number of dirty rectangles in the canvas.
29 *
30 *  Get the number of dirty rectangles in a canvas. Dirty rectangles are
31 *  areas that contain cells that have changed since the last reset.
32 *
33 *  The dirty rectangles are used internally by display drivers to optimise
34 *  rendering by avoiding to redraw the whole screen. Once the display driver
35 *  has rendered the canvas, it resets the dirty rectangle list.
36 *
37 *  Dirty rectangles are guaranteed not to overlap.
38 *
39 *  This function never fails.
40 *
41 *  \param cv A libcaca canvas.
42 *  \return The number of dirty rectangles in the given canvas.
43 */
44int caca_get_dirty_rect_count(caca_canvas_t *cv)
45{
46    return cv->ndirty;
47}
48
49/** \brief Get a canvas's dirty rectangle.
50 *
51 *  Get the canvas's given dirty rectangle coordinates. The index must be
52 *  within the dirty rectangle count. See caca_get_dirty_rect_count()
53 *  for how to compute this count.
54 *
55 *  If an error occurs, no coordinates are written in the pointer arguments,
56 *  -1 is returned and \b errno is set accordingly:
57 *  - \c EINVAL Specified rectangle index is out of bounds.
58 *
59 *  \param cv A libcaca canvas.
60 *  \param r The requested rectangle index.
61 *  \param x A pointer to an integer where the leftmost edge of the
62 *           dirty rectangle will be stored.
63 *  \param y A pointer to an integer where the topmost edge of the
64 *           dirty rectangle will be stored.
65 *  \param width A pointer to an integer where the width of the
66 *               dirty rectangle will be stored.
67 *  \param height A pointer to an integer where the height of the
68 *                dirty rectangle will be stored.
69 *  \return 0 in case of success, -1 if an error occurred.
70 */
71int caca_get_dirty_rect(caca_canvas_t *cv, int r,
72                        int *x, int *y, int *width, int *height)
73{
74    if(r < 0 || r >= cv->ndirty)
75    {
76        seterrno(EINVAL);
77        return -1;
78    }
79
80    /* Normalise dirty rectangle so that the values can be directly used. */
81    if(cv->dirty_xmin < 0)
82        cv->dirty_xmin = 0;
83
84    if(cv->dirty_xmax > cv->width - 1)
85        cv->dirty_xmax = cv->width - 1;
86
87    if(cv->dirty_ymin < 0)
88        cv->dirty_ymin = 0;
89
90    if(cv->dirty_ymax > cv->height - 1)
91        cv->dirty_ymax = cv->height - 1;
92
93    *x = cv->dirty_xmin;
94    *y = cv->dirty_ymin;
95    *width = cv->dirty_xmax - cv->dirty_xmin + 1;
96    *height = cv->dirty_ymax - cv->dirty_ymin + 1;
97
98    return 0;
99}
100
101/** \brief Add an area to the canvas's dirty rectangle list.
102 *
103 *  Add an invalidating zone to the canvas's dirty rectangle list. For more
104 *  information about the dirty rectangles, see caca_get_dirty_rect().
105 *
106 *  This function may be useful to force refresh of a given zone of the
107 *  canvas even if the dirty rectangle tracking indicates that it is
108 *  unchanged. This may happen if the canvas contents were somewhat
109 *  directly modified.
110 *
111 *  If an error occurs, -1 is returned and \b errno is set accordingly:
112 *  - \c EINVAL Specified rectangle coordinates are out of bounds.
113 *
114 *  \param cv A libcaca canvas.
115 *  \param x The leftmost edge of the additional dirty rectangle.
116 *  \param y The topmost edge of the additional dirty rectangle.
117 *  \param width The width of the additional dirty rectangle.
118 *  \param height The height of the additional dirty rectangle.
119 *  \return 0 in case of success, -1 if an error occurred.
120 */
121int caca_add_dirty_rect(caca_canvas_t *cv, int x, int y,
122                             int width, int height)
123{
124    /* Ignore empty and out-of-bounds rectangles */
125    if(width <= 0 || height <= 0 || x + width <= 0 || x >= cv->width
126        || y + height <= 0 || y >= cv->height)
127    {
128        seterrno(EINVAL);
129        return -1;
130    }
131
132    if(cv->ndirty == 0)
133    {
134        cv->ndirty = 1;
135        cv->dirty_xmin = x;
136        cv->dirty_xmax = x + width - 1;
137        cv->dirty_ymin = y;
138        cv->dirty_ymax = y + height - 1;
139    }
140    else
141    {
142        if(x < cv->dirty_xmin)
143            cv->dirty_xmin = x;
144        if(x + width - 1 > cv->dirty_xmax)
145            cv->dirty_xmax = x + width - 1;
146        if(y < cv->dirty_ymin)
147            cv->dirty_ymin = y;
148        if(y + height - 1 > cv->dirty_ymax)
149            cv->dirty_ymax = y + height - 1;
150    }
151
152    return 0;
153}
154
155/** \brief Remove an area from the dirty rectangle list.
156 *
157 *  Mark a cell area in the canvas as not dirty. For more information about
158 *  the dirty rectangles, see caca_get_dirty_rect().
159 *
160 *  Values such that \b xmin > \b xmax or \b ymin > \b ymax indicate that
161 *  the dirty rectangle is empty. They will be silently ignored.
162 *
163 *  If an error occurs, -1 is returned and \b errno is set accordingly:
164 *  - \c EINVAL Specified rectangle coordinates are out of bounds.
165 *
166 *  \param cv A libcaca canvas.
167 *  \param x The leftmost edge of the clean rectangle.
168 *  \param y The topmost edge of the clean rectangle.
169 *  \param width The width of the clean rectangle.
170 *  \param height The height of the clean rectangle.
171 *  \return 0 in case of success, -1 if an error occurred.
172 */
173int caca_remove_dirty_rect(caca_canvas_t *cv, int x, int y,
174                           int width, int height)
175{
176    /* Ignore empty and out-of-bounds rectangles */
177    if(width <= 0 || height <= 0 || x + width <= 0 || x >= cv->width
178        || y + height <= 0 || y >= cv->height)
179    {
180        seterrno(EINVAL);
181        return -1;
182    }
183
184    /* FIXME: implement this function. It's OK to have it do nothing,
185     * since we take a conservative approach in dirty rectangle handling,
186     * but we ought to help the rendering eventually. */
187
188    return 0;
189}
190
191/** \brief Clear a canvas's dirty rectangle list.
192 *
193 *  Empty the canvas's dirty rectangle list.
194 *
195 *  This function never fails.
196 *
197 *  \param cv A libcaca canvas.
198 *  \return This function always returns 0.
199 */
200int caca_clear_dirty_rect_list(caca_canvas_t *cv)
201{
202    cv->ndirty = 0;
203
204    return 0;
205}
206
Note: See TracBrowser for help on using the repository browser.