Path: blob/master/Utilities/cmpdcurses/pdcurses/overlay.c
3153 views
/* PDCurses */12#include <curspriv.h>34/*man-start**************************************************************56overlay7-------89### Synopsis1011int overlay(const WINDOW *src_w, WINDOW *dst_w)12int overwrite(const WINDOW *src_w, WINDOW *dst_w)13int copywin(const WINDOW *src_w, WINDOW *dst_w, int src_tr,14int src_tc, int dst_tr, int dst_tc, int dst_br,15int dst_bc, int _overlay)1617### Description1819overlay() and overwrite() copy all the text from src_w into dst_w.20The windows need not be the same size. Those characters in the source21window that intersect with the destination window are copied, so that22the characters appear in the same physical position on the screen.23The difference between the two functions is that overlay() is non-24destructive (blanks are not copied) while overwrite() is destructive25(blanks are copied).2627copywin() is similar, but doesn't require that the two windows28overlap. The arguments src_tc and src_tr specify the top left corner29of the region to be copied. dst_tc, dst_tr, dst_br, and dst_bc30specify the region within the destination window to copy to. The31argument "overlay", if TRUE, indicates that the copy is done non-32destructively (as in overlay()); blanks in the source window are not33copied to the destination window. When overlay is FALSE, blanks are34copied.3536### Return Value3738All functions return OK on success and ERR on error.3940### Portability41X/Open ncurses NetBSD42overlay Y Y Y43overwrite Y Y Y44copywin Y Y Y4546**man-end****************************************************************/4748/* Thanks to Andreas Otte <venn@@uni-paderborn.de> for the49corrected overlay()/overwrite() behavior. */5051static int _copy_win(const WINDOW *src_w, WINDOW *dst_w, int src_tr,52int src_tc, int src_br, int src_bc, int dst_tr,53int dst_tc, bool _overlay)54{55int col, line, y1, fc, *minchng, *maxchng;56chtype *w1ptr, *w2ptr;5758int lc = 0;59int xdiff = src_bc - src_tc;60int ydiff = src_br - src_tr;6162if (!src_w || !dst_w)63return ERR;6465minchng = dst_w->_firstch;66maxchng = dst_w->_lastch;6768for (y1 = 0; y1 < dst_tr; y1++)69{70minchng++;71maxchng++;72}7374for (line = 0; line < ydiff; line++)75{76w1ptr = src_w->_y[line + src_tr] + src_tc;77w2ptr = dst_w->_y[line + dst_tr] + dst_tc;7879fc = _NO_CHANGE;8081for (col = 0; col < xdiff; col++)82{83if ((*w1ptr) != (*w2ptr) &&84!((*w1ptr & A_CHARTEXT) == ' ' && _overlay))85{86*w2ptr = *w1ptr;8788if (fc == _NO_CHANGE)89fc = col + dst_tc;9091lc = col + dst_tc;92}9394w1ptr++;95w2ptr++;96}9798if (*minchng == _NO_CHANGE)99{100*minchng = fc;101*maxchng = lc;102}103else if (fc != _NO_CHANGE)104{105if (fc < *minchng)106*minchng = fc;107if (lc > *maxchng)108*maxchng = lc;109}110111minchng++;112maxchng++;113}114115return OK;116}117118int _copy_overlap(const WINDOW *src_w, WINDOW *dst_w, bool overlay)119{120int first_line, first_col, last_line, last_col;121int src_start_x, src_start_y, dst_start_x, dst_start_y;122int xdiff, ydiff;123124if (!src_w || !dst_w)125return ERR;126127first_col = max(dst_w->_begx, src_w->_begx);128first_line = max(dst_w->_begy, src_w->_begy);129130last_col = min(src_w->_begx + src_w->_maxx, dst_w->_begx + dst_w->_maxx);131last_line = min(src_w->_begy + src_w->_maxy, dst_w->_begy + dst_w->_maxy);132133/* determine the overlapping region of the two windows in real134coordinates */135136/* if no overlapping region, do nothing */137138if ((last_col < first_col) || (last_line < first_line))139return OK;140141/* size of overlapping region */142143xdiff = last_col - first_col;144ydiff = last_line - first_line;145146if (src_w->_begx <= dst_w->_begx)147{148src_start_x = dst_w->_begx - src_w->_begx;149dst_start_x = 0;150}151else152{153dst_start_x = src_w->_begx - dst_w->_begx;154src_start_x = 0;155}156157if (src_w->_begy <= dst_w->_begy)158{159src_start_y = dst_w->_begy - src_w->_begy;160dst_start_y = 0;161}162else163{164dst_start_y = src_w->_begy - dst_w->_begy;165src_start_y = 0;166}167168return _copy_win(src_w, dst_w, src_start_y, src_start_x,169src_start_y + ydiff, src_start_x + xdiff,170dst_start_y, dst_start_x, overlay);171}172173int overlay(const WINDOW *src_w, WINDOW *dst_w)174{175PDC_LOG(("overlay() - called\n"));176177return _copy_overlap(src_w, dst_w, TRUE);178}179180int overwrite(const WINDOW *src_w, WINDOW *dst_w)181{182PDC_LOG(("overwrite() - called\n"));183184return _copy_overlap(src_w, dst_w, FALSE);185}186187int copywin(const WINDOW *src_w, WINDOW *dst_w, int src_tr, int src_tc,188int dst_tr, int dst_tc, int dst_br, int dst_bc, int _overlay)189{190int src_end_x, src_end_y;191int src_rows, src_cols, dst_rows, dst_cols;192int min_rows, min_cols;193194PDC_LOG(("copywin() - called\n"));195196if (!src_w || !dst_w || dst_w == curscr || dst_br >= dst_w->_maxy197|| dst_bc >= dst_w->_maxx || dst_tr < 0 || dst_tc < 0)198return ERR;199200src_rows = src_w->_maxy - src_tr;201src_cols = src_w->_maxx - src_tc;202dst_rows = dst_br - dst_tr + 1;203dst_cols = dst_bc - dst_tc + 1;204205min_rows = min(src_rows, dst_rows);206min_cols = min(src_cols, dst_cols);207208src_end_y = src_tr + min_rows;209src_end_x = src_tc + min_cols;210211return _copy_win(src_w, dst_w, src_tr, src_tc, src_end_y, src_end_x,212dst_tr, dst_tc, _overlay);213}214215216