1 // This may look like C code, but it is really -*- C++ -*-
2
3 // ------------------------------------------------------------------
4 // The Goldware Library
5 // Copyright (C) 1990-1999 Odinn Sorensen
6 // Copyright (C) 1999-2000 Alexander S. Aganichev
7 // ------------------------------------------------------------------
8 // This library is free software; you can redistribute it and/or
9 // modify it under the terms of the GNU Library General Public
10 // License as published by the Free Software Foundation; either
11 // version 2 of the License, or (at your option) any later version.
12 //
13 // This library is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 // Library General Public License for more details.
17 //
18 // You should have received a copy of the GNU Library General Public
19 // License along with this program; if not, write to the Free
20 // Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21 // MA 02111-1307, USA
22 // ------------------------------------------------------------------
23 // $Id: gwinline.cpp,v 1.1 2011/02/18 19:46:02 stas_degteff Exp $
24 // ------------------------------------------------------------------
25 // GCUI: Golded+ Character-oriented User Interface.
26 // Functions for line drawing.
27 // Based on CXL by Mike Smedley.
28 // ------------------------------------------------------------------
29 // whline() draws a horizontal text line in active window
30 // wvline() draws a vertical text line in active window
31 // ------------------------------------------------------------------
32
33 #include <gwinall.h>
34
35
36 // ------------------------------------------------------------------
37
38 #define HORZ 0
39 #define VERT 1
40
41
42 // ------------------------------------------------------------------
43
44 #define ULC _box_table(bt, 0) // upper left corner
45 #define UHL _box_table(bt, 1) // upper horizontal line
46 #define URC _box_table(bt, 2) // upper right corner
47 #define LVL _box_table(bt, 3) // left vertical line
48 #define RVL _box_table(bt, 4) // right vertical line
49 #define LLC _box_table(bt, 5) // lower left corner
50 #define LHL _box_table(bt, 6) // lower horizontal line
51 #define LRC _box_table(bt, 7) // lower right corner
52 #define MJ _box_table(bt, 8) // middle junction
53 #define LVJ _box_table(bt, 9) // left vertical junction
54 #define RVJ _box_table(bt, 10) // right vertical junction
55 #define UHJ _box_table(bt, 11) // upper horizontal junction
56 #define LHJ _box_table(bt, 12) // lower horizontal junction
57
58
59 // ------------------------------------------------------------------
60
disp_char(int wrow,int wcol,vattr attr,int btype,vchar ch,int direc)61 static int disp_char(int wrow,int wcol, vattr attr,int btype,vchar ch,int direc) {
62
63 attr = attr|ACSET;
64
65 // see if next to a border, if so, connect to it
66 if(gwin.active->border) {
67
68 // abbreviate pointer
69 const int bt = btype;
70
71 // calculate effective row and column
72 int row = gwin.active->srow+gwin.active->border+wrow;
73 int col = gwin.active->scol+gwin.active->border+wcol;
74
75 // see if this is a horizontal or vertical line
76 if(direc==HORZ) {
77
78 // make sure that the box type characters match
79 if(LVL==_box_table(gwin.active->btype, 3)) {
80
81 // check left border
82 if(col==(gwin.active->scol+1)) {
83 vputc(row,gwin.active->scol,attr,LVJ);
84 ch=UHL;
85 }
86
87 // check right border
88 if(col==(gwin.active->ecol-1)) {
89 vputc(row,gwin.active->ecol,attr,RVJ);
90 ch=UHL;
91 }
92 }
93 }
94 else {
95
96 // make sure that the box type characters match
97 if(UHL==_box_table(gwin.active->btype, 1)) {
98
99 // check top border
100 if(row==(gwin.active->srow+1)) {
101 vputc(gwin.active->srow,col,attr,UHJ);
102 ch=LVL;
103 }
104
105 // check bottom border
106 if(row==(gwin.active->erow-1)) {
107 vputc(gwin.active->erow,col,attr,LHJ);
108 ch=LVL;
109 }
110 }
111 }
112 }
113
114 // display character
115 if(wprintc(wrow,wcol,attr,ch))
116 return gwin.werrno;
117
118 // return normally
119 return 0;
120 } /* disp_char() */
121
122
123 // ------------------------------------------------------------------
124
isupvert(int btype,vchar ch)125 static inline int isupvert(int btype, vchar ch) {
126
127 const int bt = btype;
128 return (ch==LVL or ch==UHJ or ch==ULC or ch==URC or ch==LVJ or ch==RVJ or ch==MJ) ? YES : NO;
129 }
130
131
132 // ------------------------------------------------------------------
133
isdownvert(int btype,vchar ch)134 static inline int isdownvert(int btype, vchar ch) {
135
136 const int bt = btype;
137 return (ch==LVL or ch==LHJ or ch==LLC or ch==LRC or ch==LVJ or ch==RVJ or ch==MJ) ? YES : NO;
138 }
139
140
141 // ------------------------------------------------------------------
142
islefthorz(int btype,vchar ch)143 static inline int islefthorz(int btype, vchar ch) {
144
145 const int bt = btype;
146 return (ch==UHL or ch==LVJ or ch==LLC or ch==ULC or ch==UHJ or ch==LHJ or ch==MJ) ? YES : NO;
147 }
148
149
150 // ------------------------------------------------------------------
151
isrighthorz(int btype,vchar ch)152 static inline int isrighthorz(int btype, vchar ch) {
153
154 const int bt = btype;
155 return (ch==UHL or ch==RVJ or ch==LRC or ch==URC or ch==UHJ or ch==LHJ or ch==MJ) ? YES : NO;
156 }
157
158
159 // ------------------------------------------------------------------
160
whline(int wsrow,int wscol,int count,int btype,vattr attr)161 int whline(int wsrow, int wscol, int count, int btype, vattr attr) {
162
163 register int bt;
164 int row,col,up,down;
165 vchar ch;
166
167 row=wsrow;
168 col=wscol;
169
170 // abbreviate pointer
171 bt = btype;
172
173 if(count) {
174
175 // see if a left junction or corner is needed
176 up = isupvert (btype,wgetc(row-1,col));
177 down = isdownvert(btype,wgetc(row+1,col));
178 if(up and down)
179 ch=LVJ;
180 else if(up)
181 ch=LLC;
182 else if(down)
183 ch=ULC;
184 else
185 ch=UHL;
186
187 // display leftmost character
188 if(disp_char(row,col,attr,btype,ch,HORZ))
189 return gwin.werrno;
190 col++;
191 count--;
192 }
193
194 // do while not last character
195 while(count>1) {
196
197 // see if a middle junction is needed
198 up = isupvert (btype,wgetc(row-1,col));
199 down = isdownvert(btype,wgetc(row+1,col));
200 if(up and down)
201 ch=MJ;
202 else if(up)
203 ch=LHJ;
204 else if(down)
205 ch=UHJ;
206 else
207 ch=UHL;
208
209 // display middle character
210 if(disp_char(row,col,attr,btype,ch,HORZ))
211 return gwin.werrno;
212 col++;
213 count--;
214 }
215
216 if(count) {
217
218 // see if a right junction or corner is needed
219 up = isupvert (btype,wgetc(row-1,col));
220 down = isdownvert(btype,wgetc(row+1,col));
221 if(up and down)
222 ch=RVJ;
223 else if(up)
224 ch=LRC;
225 else if(down)
226 ch=URC;
227 else
228 ch=UHL;
229
230 // display rightmost character
231 if(disp_char(row,col,attr,btype,ch,HORZ))
232 return gwin.werrno;
233 }
234
235 // return normally
236 return gwin.werrno=W_NOERROR;
237 } /* whline() */
238
239
240 // ------------------------------------------------------------------
241
wvline(int wsrow,int wscol,int count,int btype,vattr attr)242 int wvline(int wsrow, int wscol, int count, int btype, vattr attr) {
243
244 register int bt;
245 int row,col,left,right;
246 vchar ch;
247
248 row=wsrow;
249 col=wscol;
250
251 // abbreviate pointer
252 bt = btype;
253
254 if(count) {
255
256 // see if a top junction or corner is needed
257 left = islefthorz (btype,wgetc(row,col-1));
258 right = isrighthorz(btype,wgetc(row,col+1));
259 if(left and right)
260 ch=UHJ;
261 else if(left)
262 ch=URC;
263 else if(right)
264 ch=ULC;
265 else
266 ch=LVL;
267
268 // display uppermost character
269 if(disp_char(row,col,attr,btype,ch,VERT))
270 return gwin.werrno;
271 row++;
272 count--;
273 }
274
275 // do while not last character
276 while(count>1) {
277 left = islefthorz (btype,wgetc(row,col-1));
278 right = isrighthorz(btype,wgetc(row,col+1));
279 if(left and right)
280 ch=MJ;
281 else if(left)
282 ch=RVJ;
283 else if(right)
284 ch=LVJ;
285 else
286 ch=LVL;
287
288 // display middle character
289 if(disp_char(row,col,attr,btype,ch,VERT))
290 return gwin.werrno;
291 row++;
292 count--;
293 }
294
295 if(count) {
296
297 // see if a bottom junction or corner is needed
298 left = islefthorz (btype,wgetc(row,col-1));
299 right = isrighthorz(btype,wgetc(row,col+1));
300 if(left and right)
301 ch=LHJ;
302 else if(left)
303 ch=LRC;
304 else if(right)
305 ch=LLC;
306 else
307 ch=LVL;
308
309 // display bottommost character
310 if(disp_char(row,col,attr,btype,ch,VERT))
311 return gwin.werrno;
312 }
313
314 // return normally
315 return gwin.werrno=W_NOERROR;
316 } /* wvline() */
317
318 // ------------------------------------------------------------------
319