xref: /netbsd/lib/libcurses/line.c (revision dd26fe31)
1 /*	$NetBSD: line.c,v 1.17 2021/09/06 07:03:50 rin Exp $	*/
2 
3 /*-
4  * Copyright (c) 1998-1999 Brett Lymn
5  *                         (blymn@baea.com.au, brett_lymn@yahoo.com.au)
6  * All rights reserved.
7  *
8  * This code has been donated to The NetBSD Foundation by the Author.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. The name of the author may not be used to endorse or promote products
16  *    derived from this software without specific prior written permission
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  *
29  *
30  */
31 
32 #include <sys/cdefs.h>
33 #ifndef lint
34 __RCSID("$NetBSD: line.c,v 1.17 2021/09/06 07:03:50 rin Exp $");
35 #endif				/* not lint */
36 
37 #include <string.h>
38 
39 #include "curses.h"
40 #include "curses_private.h"
41 
42 /*
43  * hline --
44  *	Draw a horizontal line of character c on stdscr.
45  */
46 int
hline(chtype ch,int count)47 hline(chtype ch, int count)
48 {
49 
50 	return whline(stdscr, ch, count);
51 }
52 
53 /*
54  * mvhline --
55  *	Move to location (y, x) and draw a horizontal line of character c
56  *	on stdscr.
57  */
58 int
mvhline(int y,int x,chtype ch,int count)59 mvhline(int y, int x, chtype ch, int count)
60 {
61 
62 	return mvwhline(stdscr, y, x, ch, count);
63 }
64 
65 /*
66  * mvwhline --
67  *	Move to location (y, x) and draw a horizontal line of character c
68  *	in the given window.
69  */
70 int
mvwhline(WINDOW * win,int y,int x,chtype ch,int count)71 mvwhline(WINDOW *win, int y, int x, chtype ch, int count)
72 {
73 
74 	if (wmove(win, y, x) == ERR)
75 		return ERR;
76 
77 	return whline(win, ch, count);
78 }
79 
80 /*
81  * whline --
82  *	Draw a horizontal line of character c in the given window moving
83  *	towards the rightmost column.  At most count characters are drawn
84  *	or until the edge of the screen, whichever comes first.
85  */
86 int
whline(WINDOW * win,chtype ch,int count)87 whline(WINDOW *win, chtype ch, int count)
88 {
89 #ifndef HAVE_WCHAR
90 	int ocury, ocurx, n, i;
91 
92 	n = min(count, win->maxx - win->curx);
93 	ocury = win->cury;
94 	ocurx = win->curx;
95 
96 	if (!(ch & __CHARTEXT))
97 		ch |= ACS_HLINE;
98 	for (i = 0; i < n; i++)
99 		mvwaddch(win, ocury, ocurx + i, ch);
100 
101 	wmove(win, ocury, ocurx);
102 	return OK;
103 #else
104 	cchar_t cch;
105 
106 	__cursesi_chtype_to_cchar(ch, &cch);
107 	return whline_set(win, &cch, count);
108 #endif
109 }
110 
111 /*
112  * vline --
113  *	Draw a vertical line of character ch on stdscr.
114  */
115 int
vline(chtype ch,int count)116 vline(chtype ch, int count)
117 {
118 
119 	return wvline(stdscr, ch, count);
120 }
121 
122 /*
123  * mvvline --
124  *	Move to the given location an draw a vertical line of character ch.
125  */
126 int
mvvline(int y,int x,chtype ch,int count)127 mvvline(int y, int x, chtype ch, int count)
128 {
129 
130 	return mvwvline(stdscr, y, x, ch, count);
131 }
132 
133 /*
134  * mvwvline --
135  *	Move to the given location and draw a vertical line of character ch
136  *	on the given window.
137  */
138 int
mvwvline(WINDOW * win,int y,int x,chtype ch,int count)139 mvwvline(WINDOW *win, int y, int x, chtype ch, int count)
140 {
141 
142 	if (wmove(win, y, x) == ERR)
143 		return ERR;
144 
145 	return wvline(win, ch, count);
146 }
147 
148 /*
149  * wvline --
150  *	Draw a vertical line of character ch in the given window moving
151  *	towards the bottom of the screen.  At most count characters are drawn
152  *	or until the edge of the screen, whichever comes first.
153  */
154 int
wvline(WINDOW * win,chtype ch,int count)155 wvline(WINDOW *win, chtype ch, int count)
156 {
157 #ifndef HAVE_WCHAR
158 	int ocury, ocurx, n, i;
159 
160 	n = min(count, win->maxy - win->cury);
161 	ocury = win->cury;
162 	ocurx = win->curx;
163 
164 	if (!(ch & __CHARTEXT))
165 		ch |= ACS_VLINE;
166 	for (i = 0; i < n; i++)
167 		mvwaddch(win, ocury + i, ocurx, ch);
168 
169 	wmove(win, ocury, ocurx);
170 	return OK;
171 #else
172 	cchar_t cch;
173 
174 	__cursesi_chtype_to_cchar(ch, &cch);
175 	return wvline_set(win, &cch, count);
176 #endif
177 }
178 
hline_set(const cchar_t * wch,int n)179 int hline_set(const cchar_t *wch, int n)
180 {
181 #ifndef HAVE_WCHAR
182 	return ERR;
183 #else
184 	return whline_set( stdscr, wch, n );
185 #endif /* HAVE_WCHAR */
186 }
187 
mvhline_set(int y,int x,const cchar_t * wch,int n)188 int mvhline_set(int y, int x, const cchar_t *wch, int n)
189 {
190 #ifndef HAVE_WCHAR
191 	return ERR;
192 #else
193 	return mvwhline_set( stdscr, y, x, wch, n );
194 #endif /* HAVE_WCHAR */
195 }
196 
mvwhline_set(WINDOW * win,int y,int x,const cchar_t * wch,int n)197 int mvwhline_set(WINDOW *win, int y, int x, const cchar_t *wch, int n)
198 {
199 #ifndef HAVE_WCHAR
200 	return ERR;
201 #else
202 	if ( wmove( win, y , x ) == ERR )
203 		return ERR;
204 
205 	return whline_set( win, wch, n );
206 #endif /* HAVE_WCHAR */
207 }
208 
whline_set(WINDOW * win,const cchar_t * wch,int n)209 int whline_set(WINDOW *win, const cchar_t *wch, int n)
210 {
211 #ifndef HAVE_WCHAR
212 	return ERR;
213 #else
214 	int ocury, ocurx, wcn, i, cw;
215 	cchar_t cc;
216 
217 	cc = *wch;
218 	if (!cc.vals[0]) {
219 		cc.vals[0] = WACS_HLINE->vals[0];
220 		cc.attributes |= WACS_HLINE->attributes;
221 	}
222 
223 	cw = wcwidth(cc.vals[0]);
224 	if (cw <= 0)
225 		cw = 1;
226 	if ( ( win->maxx - win->curx ) < cw )
227 		return ERR;
228 	wcn = min( n, ( win->maxx - win->curx ) / cw );
229 	__CTRACE(__CTRACE_LINE, "whline_set: line of %d\n", wcn);
230 	ocury = win->cury;
231 	ocurx = win->curx;
232 
233 	for (i = 0; i < wcn; i++ ) {
234 		__CTRACE(__CTRACE_LINE, "whline_set: (%d,%d)\n",
235 		   ocury, ocurx + i * cw);
236 		mvwadd_wch(win, ocury, ocurx + i * cw, &cc);
237 	}
238 
239 	wmove(win, ocury, ocurx);
240 	__sync(win);
241 	return OK;
242 #endif /* HAVE_WCHAR */
243 }
244 
vline_set(const cchar_t * wch,int n)245 int vline_set(const cchar_t *wch, int n)
246 {
247 #ifndef HAVE_WCHAR
248 	return ERR;
249 #else
250 	return wvline_set(stdscr, wch, n);
251 #endif /* HAVE_WCHAR */
252 }
253 
mvvline_set(int y,int x,const cchar_t * wch,int n)254 int mvvline_set(int y, int x, const cchar_t *wch, int n)
255 {
256 #ifndef HAVE_WCHAR
257 	return ERR;
258 #else
259 	return mvwvline_set(stdscr, y, x, wch, n);
260 #endif /* HAVE_WCHAR */
261 }
262 
mvwvline_set(WINDOW * win,int y,int x,const cchar_t * wch,int n)263 int mvwvline_set(WINDOW *win, int y, int x, const cchar_t *wch, int n)
264 {
265 #ifndef HAVE_WCHAR
266 	return ERR;
267 #else
268 	if (wmove(win, y, x) == ERR)
269 		return ERR;
270 
271 	return wvline_set(win, wch, n);
272 #endif /* HAVE_WCHAR */
273 }
274 
wvline_set(WINDOW * win,const cchar_t * wch,int n)275 int wvline_set(WINDOW *win, const cchar_t *wch, int n)
276 {
277 #ifndef HAVE_WCHAR
278 	return ERR;
279 #else
280 	int ocury, ocurx, wcn, i;
281 	cchar_t cc;
282 
283 	wcn = min(n, win->maxy - win->cury);
284 	__CTRACE(__CTRACE_LINE, "wvline_set: line of %d\n", wcn);
285 	ocury = win->cury;
286 	ocurx = win->curx;
287 
288 	cc = *wch;
289 	if (!cc.vals[0]) {
290 		cc.vals[0] = WACS_VLINE->vals[0];
291 		cc.attributes |= WACS_VLINE->attributes;
292 	}
293 	for (i = 0; i < wcn; i++) {
294 		mvwadd_wch(win, ocury + i, ocurx, &cc);
295 		__CTRACE(__CTRACE_LINE, "wvline_set: (%d,%d)\n",
296 		    ocury + i, ocurx);
297 	}
298 
299 	wmove(win, ocury, ocurx);
300 	__sync(win);
301 	return OK;
302 #endif /* HAVE_WCHAR */
303 }
304