ncurses 5.3
[ncurses.git] / ncurses / base / lib_overlay.c
1 /****************************************************************************
2  * Copyright (c) 1998-2001,2002 Free Software Foundation, Inc.              *
3  *                                                                          *
4  * Permission is hereby granted, free of charge, to any person obtaining a  *
5  * copy of this software and associated documentation files (the            *
6  * "Software"), to deal in the Software without restriction, including      *
7  * without limitation the rights to use, copy, modify, merge, publish,      *
8  * distribute, distribute with modifications, sublicense, and/or sell       *
9  * copies of the Software, and to permit persons to whom the Software is    *
10  * furnished to do so, subject to the following conditions:                 *
11  *                                                                          *
12  * The above copyright notice and this permission notice shall be included  *
13  * in all copies or substantial portions of the Software.                   *
14  *                                                                          *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
16  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
18  * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
19  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
20  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
21  * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
22  *                                                                          *
23  * Except as contained in this notice, the name(s) of the above copyright   *
24  * holders shall not be used in advertising or otherwise to promote the     *
25  * sale, use or other dealings in this Software without prior written       *
26  * authorization.                                                           *
27  ****************************************************************************/
28
29 /****************************************************************************
30  *  Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995               *
31  *     and: Eric S. Raymond <esr@snark.thyrsus.com>                         *
32  ****************************************************************************/
33
34 /*
35 **      lib_overlay.c
36 **
37 **      The routines overlay(), copywin(), and overwrite().
38 **
39 */
40
41 #include <curses.priv.h>
42
43 MODULE_ID("$Id: lib_overlay.c,v 1.21 2002/09/21 23:03:32 tom Exp $")
44
45 static int
46 overlap(const WINDOW *const s, WINDOW *const d, int const flag)
47 {
48     int sx1, sy1, sx2, sy2;
49     int dx1, dy1, dx2, dy2;
50     int sminrow, smincol;
51     int dminrow, dmincol;
52     int dmaxrow, dmaxcol;
53
54     T((T_CALLED("overlap(%p,%p,%d)"), s, d, flag));
55
56     if (s == 0 || d == 0) {
57         returnCode(ERR);
58     } else {
59         T(("src : begy %d, begx %d, maxy %d, maxx %d",
60            s->_begy, s->_begx, s->_maxy, s->_maxx));
61         T(("dst : begy %d, begx %d, maxy %d, maxx %d",
62            d->_begy, d->_begx, d->_maxy, d->_maxx));
63
64         sx1 = s->_begx;
65         sy1 = s->_begy;
66         sx2 = sx1 + s->_maxx;
67         sy2 = sy1 + s->_maxy;
68
69         dx1 = d->_begx;
70         dy1 = d->_begy;
71         dx2 = dx1 + d->_maxx;
72         dy2 = dy1 + d->_maxy;
73
74         if (dx2 < sx1 || dx1 > sx2 || dy2 < sy1 || dy1 > sy2) {
75             returnCode(ERR);    /* No intersection */
76         } else {
77             sminrow = max(sy1, dy1) - sy1;
78             smincol = max(sx1, dx1) - sx1;
79             dminrow = max(sy1, dy1) - dy1;
80             dmincol = max(sx1, dx1) - dx1;
81             dmaxrow = min(sy2, dy2) - dy1;
82             dmaxcol = min(sx2, dx2) - dx1;
83
84             returnCode(copywin(s, d,
85                                sminrow, smincol,
86                                dminrow, dmincol,
87                                dmaxrow, dmaxcol,
88                                flag));
89         }
90     }
91 }
92
93 /*
94 **
95 **      overlay(win1, win2)
96 **
97 **
98 **      overlay() writes the overlapping area of win1 behind win2
99 **      on win2 non-destructively.
100 **
101 **/
102
103 NCURSES_EXPORT(int)
104 overlay(const WINDOW *win1, WINDOW *win2)
105 {
106     T((T_CALLED("overlay(%p,%p)"), win1, win2));
107     returnCode(overlap(win1, win2, TRUE));
108 }
109
110 /*
111 **
112 **      overwrite(win1, win2)
113 **
114 **
115 **      overwrite() writes the overlapping area of win1 behind win2
116 **      on win2 destructively.
117 **
118 **/
119
120 NCURSES_EXPORT(int)
121 overwrite(const WINDOW *win1, WINDOW *win2)
122 {
123     T((T_CALLED("overwrite(%p,%p)"), win1, win2));
124     returnCode(overlap(win1, win2, FALSE));
125 }
126
127 NCURSES_EXPORT(int)
128 copywin(const WINDOW *src, WINDOW *dst,
129         int sminrow, int smincol,
130         int dminrow, int dmincol,
131         int dmaxrow, int dmaxcol,
132         int over)
133 {
134     int sx, sy, dx, dy;
135     bool touched;
136     attr_t bk = AttrOf(dst->_nc_bkgd);
137     attr_t mask = ~(attr_t) ((bk & A_COLOR) ? A_COLOR : 0);
138
139     T((T_CALLED("copywin(%p, %p, %d, %d, %d, %d, %d, %d, %d)"),
140        src, dst, sminrow, smincol, dminrow, dmincol, dmaxrow, dmaxcol, over));
141
142     if (!src || !dst)
143         returnCode(ERR);
144
145     /* make sure rectangle exists in source */
146     if ((sminrow + dmaxrow - dminrow) > (src->_maxy + 1) ||
147         (smincol + dmaxcol - dmincol) > (src->_maxx + 1)) {
148         returnCode(ERR);
149     }
150
151     T(("rectangle exists in source"));
152
153     /* make sure rectangle fits in destination */
154     if (dmaxrow > dst->_maxy || dmaxcol > dst->_maxx) {
155         returnCode(ERR);
156     }
157
158     T(("rectangle fits in destination"));
159
160     for (dy = dminrow, sy = sminrow; dy <= dmaxrow; sy++, dy++) {
161         touched = FALSE;
162         for (dx = dmincol, sx = smincol; dx <= dmaxcol; sx++, dx++) {
163             if (over) {
164                 if ((CharOf(src->_line[sy].text[sx]) != L(' ')) &&
165                     (!CharEq(dst->_line[dy].text[dx], src->_line[sy].text[sx]))) {
166                     dst->_line[dy].text[dx] = src->_line[sy].text[sx];
167                     SetAttr(dst->_line[dy].text[dx],
168                             (AttrOf(src->_line[sy].text[sx]) & mask) | bk);
169                     touched = TRUE;
170                 }
171             } else {
172                 if (!CharEq(dst->_line[dy].text[dx], src->_line[sy].text[sx])) {
173                     dst->_line[dy].text[dx] = src->_line[sy].text[sx];
174                     touched = TRUE;
175                 }
176             }
177         }
178         if (touched) {
179             touchline(dst, dminrow, (dmaxrow - dminrow + 1));
180         }
181     }
182     T(("finished copywin"));
183     returnCode(OK);
184 }