1 /* Public Domain Curses */
5 RCSID("$Id: overlay.c,v 1.36 2008/07/14 12:35:23 wmcbrine Exp $")
7 /*man-start**************************************************************
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)
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).
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.
37 All functions return OK on success and ERR on error.
39 Portability X/Open BSD SYS V
44 **man-end****************************************************************/
46 /* Thanks to Andreas Otte <venn@@uni-paderborn.de> for the
47 corrected overlay()/overwrite() behavior. */
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
)
53 int col
, line
, y1
, fc
, *minchng
, *maxchng
;
54 chtype
*w1ptr
, *w2ptr
;
57 int xdiff
= src_bc
- src_tc
;
58 int ydiff
= src_br
- src_tr
;
63 minchng
= dst_w
->_firstch
;
64 maxchng
= dst_w
->_lastch
;
66 for (y1
= 0; y1
< dst_tr
; y1
++)
72 for (line
= 0; line
< ydiff
; line
++)
74 w1ptr
= src_w
->_y
[line
+ src_tr
] + src_tc
;
75 w2ptr
= dst_w
->_y
[line
+ dst_tr
] + dst_tc
;
79 for (col
= 0; col
< xdiff
; col
++)
81 if ((*w1ptr
) != (*w2ptr
) &&
82 !((*w1ptr
& A_CHARTEXT
) == ' ' && _overlay
))
96 if (*minchng
== _NO_CHANGE
)
101 else if (fc
!= _NO_CHANGE
)
116 int overlay(const WINDOW
*src_w
, WINDOW
*dst_w
)
118 int first_line
, first_col
, last_line
, last_col
;
119 int src_start_x
, src_start_y
, dst_start_x
, dst_start_y
;
122 PDC_LOG(("overlay() - called\n"));
124 if (!src_w
|| !dst_w
)
127 first_col
= max(dst_w
->_begx
, src_w
->_begx
);
128 first_line
= max(dst_w
->_begy
, src_w
->_begy
);
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
);
133 /* determine the overlapping region of the two windows in real
136 /* if no overlapping region, do nothing */
138 if ((last_col
< first_col
) || (last_line
< first_line
))
141 /* size of overlapping region */
143 xdiff
= last_col
- first_col
;
144 ydiff
= last_line
- first_line
;
146 if (src_w
->_begx
<= dst_w
->_begx
)
148 src_start_x
= dst_w
->_begx
- src_w
->_begx
;
153 dst_start_x
= src_w
->_begx
- dst_w
->_begx
;
157 if (src_w
->_begy
<= dst_w
->_begy
)
159 src_start_y
= dst_w
->_begy
- src_w
->_begy
;
164 dst_start_y
= src_w
->_begy
- dst_w
->_begy
;
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
);
173 int overwrite(const WINDOW
*src_w
, WINDOW
*dst_w
)
175 int first_line
, first_col
, last_line
, last_col
;
176 int src_start_x
, src_start_y
, dst_start_x
, dst_start_y
;
179 PDC_LOG(("overwrite() - called\n"));
181 if (!src_w
|| !dst_w
)
184 first_col
= max(dst_w
->_begx
, src_w
->_begx
);
185 first_line
= max(dst_w
->_begy
, src_w
->_begy
);
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
);
190 /* determine the overlapping region of the two windows in real
193 /* if no overlapping region, do nothing */
195 if ((last_col
< first_col
) || (last_line
< first_line
))
198 /* size of overlapping region */
200 xdiff
= last_col
- first_col
;
201 ydiff
= last_line
- first_line
;
203 if (src_w
->_begx
<= dst_w
->_begx
)
205 src_start_x
= dst_w
->_begx
- src_w
->_begx
;
210 dst_start_x
= src_w
->_begx
- dst_w
->_begx
;
214 if (src_w
->_begy
<= dst_w
->_begy
)
216 src_start_y
= dst_w
->_begy
- src_w
->_begy
;
221 dst_start_y
= src_w
->_begy
- dst_w
->_begy
;
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
);
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
)
233 int src_end_x
, src_end_y
;
234 int src_rows
, src_cols
, dst_rows
, dst_cols
;
235 int min_rows
, min_cols
;
237 PDC_LOG(("copywin() - called\n"));
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)
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;
248 min_rows
= min(src_rows
, dst_rows
);
249 min_cols
= min(src_cols
, dst_cols
);
251 src_end_y
= src_tr
+ min_rows
;
252 src_end_x
= src_tc
+ min_cols
;
254 return _copy_win(src_w
, dst_w
, src_tr
, src_tc
, src_end_y
, src_end_x
,
255 dst_tr
, dst_tc
, _overlay
);