Home | History | Annotate | Line # | Download | only in libcurses
line.c revision 1.14
      1 /*	$NetBSD: line.c,v 1.14 2020/06/30 21:27:18 uwe Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 1998-1999 Brett Lymn
      5  *                         (blymn (at) baea.com.au, brett_lymn (at) 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.14 2020/06/30 21:27:18 uwe 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
     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
     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
     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
     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->curx;
     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, *cchp;
    105 
    106 	if (ch & __CHARTEXT) {
    107 		__cursesi_chtype_to_cchar(ch, &cch);
    108 		cchp = & cch;
    109 	} else
    110 		cchp = WACS_HLINE;
    111 
    112 	return whline_set(win, cchp, count);
    113 #endif
    114 }
    115 
    116 /*
    117  * vline --
    118  *	Draw a vertical line of character ch on stdscr.
    119  */
    120 int
    121 vline(chtype ch, int count)
    122 {
    123 
    124 	return wvline(stdscr, ch, count);
    125 }
    126 
    127 /*
    128  * mvvline --
    129  *	Move to the given location an draw a vertical line of character ch.
    130  */
    131 int
    132 mvvline(int y, int x, chtype ch, int count)
    133 {
    134 
    135 	return mvwvline(stdscr, y, x, ch, count);
    136 }
    137 
    138 /*
    139  * mvwvline --
    140  *	Move to the given location and draw a vertical line of character ch
    141  *	on the given window.
    142  */
    143 int
    144 mvwvline(WINDOW *win, int y, int x, chtype ch, int count)
    145 {
    146 
    147 	if (wmove(win, y, x) == ERR)
    148 		return ERR;
    149 
    150 	return wvline(win, ch, count);
    151 }
    152 
    153 /*
    154  * wvline --
    155  *	Draw a vertical line of character ch in the given window moving
    156  *	towards the bottom of the screen.  At most count characters are drawn
    157  *	or until the edge of the screen, whichever comes first.
    158  */
    159 int
    160 wvline(WINDOW *win, chtype ch, int count)
    161 {
    162 #ifndef HAVE_WCHAR
    163 	int ocury, ocurx, n, i;
    164 
    165 	n = min(count, win->maxy - win->cury);
    166 	ocury = win->cury;
    167 	ocurx = win->curx;
    168 
    169 	if (!(ch & __CHARTEXT))
    170 		ch |= ACS_VLINE;
    171 	for (i = 0; i < n; i++)
    172 		mvwaddch(win, ocury + i, ocurx, ch);
    173 
    174 	wmove(win, ocury, ocurx);
    175 	return OK;
    176 #else
    177 	cchar_t cch, *cchp;
    178 
    179 	if (ch & __CHARTEXT) {
    180 		__cursesi_chtype_to_cchar(ch, &cch);
    181 		cchp = & cch;
    182 	} else
    183 		cchp = WACS_VLINE;
    184 
    185 	return wvline_set(win, cchp, count);
    186 #endif
    187 }
    188 
    189 int hline_set(const cchar_t *wch, int n)
    190 {
    191 #ifndef HAVE_WCHAR
    192 	return ERR;
    193 #else
    194 	return whline_set( stdscr, wch, n );
    195 #endif /* HAVE_WCHAR */
    196 }
    197 
    198 int mvhline_set(int y, int x, const cchar_t *wch, int n)
    199 {
    200 #ifndef HAVE_WCHAR
    201 	return ERR;
    202 #else
    203 	return mvwhline_set( stdscr, y, x, wch, n );
    204 #endif /* HAVE_WCHAR */
    205 }
    206 
    207 int mvwhline_set(WINDOW *win, int y, int x, const cchar_t *wch, int n)
    208 {
    209 #ifndef HAVE_WCHAR
    210 	return ERR;
    211 #else
    212 	if ( wmove( win, y , x ) == ERR )
    213 		return ERR;
    214 
    215 	return whline_set( win, wch, n );
    216 #endif /* HAVE_WCHAR */
    217 }
    218 
    219 int whline_set(WINDOW *win, const cchar_t *wch, int n)
    220 {
    221 #ifndef HAVE_WCHAR
    222 	return ERR;
    223 #else
    224 	int ocury, ocurx, wcn, i, cw;
    225 	cchar_t cc;
    226 
    227 	cw = wcwidth( wch->vals[ 0 ]);
    228 	if (cw < 0)
    229 		cw = 1;
    230 	if ( ( win->maxx - win->curx ) < cw )
    231 		return ERR;
    232 	wcn = min( n, ( win->maxx - win->curx ) / cw );
    233 #ifdef DEBUG
    234 	__CTRACE(__CTRACE_LINE, "whline_set: line of %d\n", wcn);
    235 #endif /* DEBUG */
    236 	ocury = win->cury;
    237 	ocurx = win->curx;
    238 
    239 	memcpy( &cc, wch, sizeof( cchar_t ));
    240 	if (!(wch->vals[ 0 ]))
    241 		cc.vals[ 0 ] |= WACS_HLINE->vals[0];
    242 	for (i = 0; i < wcn; i++ ) {
    243 #ifdef DEBUG
    244 		__CTRACE(__CTRACE_LINE, "whline_set: (%d,%d)\n",
    245 		   ocury, ocurx + i * cw);
    246 #endif /* DEBUG */
    247 		mvwadd_wch(win, ocury, ocurx + i * cw, &cc);
    248 	}
    249 
    250 	wmove(win, ocury, ocurx);
    251 	__sync(win);
    252 	return OK;
    253 #endif /* HAVE_WCHAR */
    254 }
    255 
    256 int vline_set(const cchar_t *wch, int n)
    257 {
    258 #ifndef HAVE_WCHAR
    259 	return ERR;
    260 #else
    261 	return wvline_set(stdscr, wch, n);
    262 #endif /* HAVE_WCHAR */
    263 }
    264 
    265 int mvvline_set(int y, int x, const cchar_t *wch, int n)
    266 {
    267 #ifndef HAVE_WCHAR
    268 	return ERR;
    269 #else
    270 	return mvwvline_set(stdscr, y, x, wch, n);
    271 #endif /* HAVE_WCHAR */
    272 }
    273 
    274 int mvwvline_set(WINDOW *win, int y, int x, const cchar_t *wch, int n)
    275 {
    276 #ifndef HAVE_WCHAR
    277 	return ERR;
    278 #else
    279 	if (wmove(win, y, x) == ERR)
    280 		return ERR;
    281 
    282 	return wvline_set(win, wch, n);
    283 #endif /* HAVE_WCHAR */
    284 }
    285 
    286 int wvline_set(WINDOW *win, const cchar_t *wch, int n)
    287 {
    288 #ifndef HAVE_WCHAR
    289 	return ERR;
    290 #else
    291 	int ocury, ocurx, wcn, i;
    292 	cchar_t cc;
    293 
    294 	wcn = min(n, win->maxy - win->cury);
    295 #ifdef DEBUG
    296 	__CTRACE(__CTRACE_LINE, "wvline_set: line of %d\n", wcn);
    297 #endif /* DEBUG */
    298 	ocury = win->cury;
    299 	ocurx = win->curx;
    300 
    301 	memcpy(&cc, wch, sizeof(cchar_t));
    302 	if (!(wch->vals[0]))
    303 		cc.vals[0] |= WACS_VLINE->vals[0];
    304 	for (i = 0; i < wcn; i++) {
    305 		mvwadd_wch(win, ocury + i, ocurx, &cc);
    306 #ifdef DEBUG
    307 		__CTRACE(__CTRACE_LINE, "wvline_set: (%d,%d)\n",
    308 		    ocury + i, ocurx);
    309 #endif /* DEBUG */
    310 	}
    311 
    312 	wmove(win, ocury, ocurx);
    313 	__sync(win);
    314 	return OK;
    315 #endif /* HAVE_WCHAR */
    316 }
    317