pdcurses/overlay.c

branch
protocol5
changeset 106
7b156b764d11
parent 97
2d43f05b284c
equal deleted inserted replaced
104:a76af67a3a4b 106:7b156b764d11
1 /* Public Domain Curses */
2
3 #include <curspriv.h>
4
5 RCSID("$Id: overlay.c,v 1.36 2008/07/14 12:35:23 wmcbrine Exp $")
6
7 /*man-start**************************************************************
8
9 Name: overlay
10
11 Synopsis:
12 int overlay(const WINDOW *src_w, WINDOW *dst_w)
13 int overwrite(const WINDOW *src_w, WINDOW *dst_w)
14 int copywin(const WINDOW *src_w, WINDOW *dst_w, int src_tr,
15 int src_tc, int dst_tr, int dst_tc, int dst_br,
16 int dst_bc, bool overlay)
17
18 Description:
19 overlay() and overwrite() copy all the text from src_w into
20 dst_w. The windows need not be the same size. Those characters
21 in the source window that intersect with the destination window
22 are copied, so that the characters appear in the same physical
23 position on the screen. The difference between the two functions
24 is that overlay() is non-destructive (blanks are not copied)
25 while overwrite() is destructive (blanks are copied).
26
27 copywin() is similar, but doesn't require that the two windows
28 overlap. The arguments src_tc and src_tr specify the top left
29 corner of the region to be copied. dst_tc, dst_tr, dst_br, and
30 dst_bc specify the region within the destination window to copy
31 to. The argument "overlay", if TRUE, indicates that the copy is
32 done non-destructively (as in overlay()); blanks in the source
33 window are not copied to the destination window. When overlay is
34 FALSE, blanks are copied.
35
36 Return Value:
37 All functions return OK on success and ERR on error.
38
39 Portability X/Open BSD SYS V
40 overlay Y Y Y
41 overwrite Y Y Y
42 copywin Y - 3.0
43
44 **man-end****************************************************************/
45
46 /* Thanks to Andreas Otte <venn@@uni-paderborn.de> for the
47 corrected overlay()/overwrite() behavior. */
48
49 static int _copy_win(const WINDOW *src_w, WINDOW *dst_w, int src_tr,
50 int src_tc, int src_br, int src_bc, int dst_tr,
51 int dst_tc, bool overlay)
52 {
53 int col, line, y1, fc, *minchng, *maxchng;
54 chtype *w1ptr, *w2ptr;
55
56 int lc = 0;
57 int xdiff = src_bc - src_tc;
58 int ydiff = src_br - src_tr;
59
60 if (!src_w || !dst_w)
61 return ERR;
62
63 minchng = dst_w->_firstch;
64 maxchng = dst_w->_lastch;
65
66 for (y1 = 0; y1 < dst_tr; y1++)
67 {
68 minchng++;
69 maxchng++;
70 }
71
72 for (line = 0; line < ydiff; line++)
73 {
74 w1ptr = src_w->_y[line + src_tr] + src_tc;
75 w2ptr = dst_w->_y[line + dst_tr] + dst_tc;
76
77 fc = _NO_CHANGE;
78
79 for (col = 0; col < xdiff; col++)
80 {
81 if ((*w1ptr) != (*w2ptr) &&
82 !((*w1ptr & A_CHARTEXT) == ' ' && overlay))
83 {
84 *w2ptr = *w1ptr;
85
86 if (fc == _NO_CHANGE)
87 fc = col + dst_tc;
88
89 lc = col + dst_tc;
90 }
91
92 w1ptr++;
93 w2ptr++;
94 }
95
96 if (*minchng == _NO_CHANGE)
97 {
98 *minchng = fc;
99 *maxchng = lc;
100 }
101 else if (fc != _NO_CHANGE)
102 {
103 if (fc < *minchng)
104 *minchng = fc;
105 if (lc > *maxchng)
106 *maxchng = lc;
107 }
108
109 minchng++;
110 maxchng++;
111 }
112
113 return OK;
114 }
115
116 int overlay(const WINDOW *src_w, WINDOW *dst_w)
117 {
118 int first_line, first_col, last_line, last_col;
119 int src_start_x, src_start_y, dst_start_x, dst_start_y;
120 int xdiff, ydiff;
121
122 PDC_LOG(("overlay() - called\n"));
123
124 if (!src_w || !dst_w)
125 return ERR;
126
127 first_col = max(dst_w->_begx, src_w->_begx);
128 first_line = max(dst_w->_begy, src_w->_begy);
129
130 last_col = min(src_w->_begx + src_w->_maxx, dst_w->_begx + dst_w->_maxx);
131 last_line = min(src_w->_begy + src_w->_maxy, dst_w->_begy + dst_w->_maxy);
132
133 /* determine the overlapping region of the two windows in real
134 coordinates */
135
136 /* if no overlapping region, do nothing */
137
138 if ((last_col < first_col) || (last_line < first_line))
139 return OK;
140
141 /* size of overlapping region */
142
143 xdiff = last_col - first_col;
144 ydiff = last_line - first_line;
145
146 if (src_w->_begx <= dst_w->_begx)
147 {
148 src_start_x = dst_w->_begx - src_w->_begx;
149 dst_start_x = 0;
150 }
151 else
152 {
153 dst_start_x = src_w->_begx - dst_w->_begx;
154 src_start_x = 0;
155 }
156
157 if (src_w->_begy <= dst_w->_begy)
158 {
159 src_start_y = dst_w->_begy - src_w->_begy;
160 dst_start_y = 0;
161 }
162 else
163 {
164 dst_start_y = src_w->_begy - dst_w->_begy;
165 src_start_y = 0;
166 }
167
168 return _copy_win(src_w, dst_w, src_start_y, src_start_x,
169 src_start_y + ydiff, src_start_x + xdiff,
170 dst_start_y, dst_start_x, TRUE);
171 }
172
173 int overwrite(const WINDOW *src_w, WINDOW *dst_w)
174 {
175 int first_line, first_col, last_line, last_col;
176 int src_start_x, src_start_y, dst_start_x, dst_start_y;
177 int xdiff, ydiff;
178
179 PDC_LOG(("overwrite() - called\n"));
180
181 if (!src_w || !dst_w)
182 return ERR;
183
184 first_col = max(dst_w->_begx, src_w->_begx);
185 first_line = max(dst_w->_begy, src_w->_begy);
186
187 last_col = min(src_w->_begx + src_w->_maxx, dst_w->_begx + dst_w->_maxx);
188 last_line = min(src_w->_begy + src_w->_maxy, dst_w->_begy + dst_w->_maxy);
189
190 /* determine the overlapping region of the two windows in real
191 coordinates */
192
193 /* if no overlapping region, do nothing */
194
195 if ((last_col < first_col) || (last_line < first_line))
196 return OK;
197
198 /* size of overlapping region */
199
200 xdiff = last_col - first_col;
201 ydiff = last_line - first_line;
202
203 if (src_w->_begx <= dst_w->_begx)
204 {
205 src_start_x = dst_w->_begx - src_w->_begx;
206 dst_start_x = 0;
207 }
208 else
209 {
210 dst_start_x = src_w->_begx - dst_w->_begx;
211 src_start_x = 0;
212 }
213
214 if (src_w->_begy <= dst_w->_begy)
215 {
216 src_start_y = dst_w->_begy - src_w->_begy;
217 dst_start_y = 0;
218 }
219 else
220 {
221 dst_start_y = src_w->_begy - dst_w->_begy;
222 src_start_y = 0;
223 }
224
225 return _copy_win(src_w, dst_w, src_start_y, src_start_x,
226 src_start_y + ydiff, src_start_x + xdiff,
227 dst_start_y, dst_start_x, FALSE);
228 }
229
230 int copywin(const WINDOW *src_w, WINDOW *dst_w, int src_tr, int src_tc,
231 int dst_tr, int dst_tc, int dst_br, int dst_bc, int overlay)
232 {
233 int src_end_x, src_end_y;
234 int src_rows, src_cols, dst_rows, dst_cols;
235 int min_rows, min_cols;
236
237 PDC_LOG(("copywin() - called\n"));
238
239 if (!src_w || !dst_w || dst_w == curscr || dst_br > dst_w->_maxy
240 || dst_bc > dst_w->_maxx || dst_tr < 0 || dst_tc < 0)
241 return ERR;
242
243 src_rows = src_w->_maxy - src_tr;
244 src_cols = src_w->_maxx - src_tc;
245 dst_rows = dst_br - dst_tr + 1;
246 dst_cols = dst_bc - dst_tc + 1;
247
248 min_rows = min(src_rows, dst_rows);
249 min_cols = min(src_cols, dst_cols);
250
251 src_end_y = src_tr + min_rows;
252 src_end_x = src_tc + min_cols;
253
254 return _copy_win(src_w, dst_w, src_tr, src_tc, src_end_y, src_end_x,
255 dst_tr, dst_tc, overlay);
256 }

mercurial