318 lines
8.0 KiB
C++
318 lines
8.0 KiB
C++
|
// This may look like C code, but it is really -*- C++ -*-
|
||
|
|
||
|
// ------------------------------------------------------------------
|
||
|
// The Goldware Library
|
||
|
// Copyright (C) 1990-1999 Odinn Sorensen
|
||
|
// Copyright (C) 1999-2000 Alexander S. Aganichev
|
||
|
// ------------------------------------------------------------------
|
||
|
// This library is free software; you can redistribute it and/or
|
||
|
// modify it under the terms of the GNU Library General Public
|
||
|
// License as published by the Free Software Foundation; either
|
||
|
// version 2 of the License, or (at your option) any later version.
|
||
|
//
|
||
|
// This library is distributed in the hope that it will be useful,
|
||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
|
// Library General Public License for more details.
|
||
|
//
|
||
|
// You should have received a copy of the GNU Library General Public
|
||
|
// License along with this program; if not, write to the Free
|
||
|
// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||
|
// MA 02111-1307, USA
|
||
|
// ------------------------------------------------------------------
|
||
|
// $Id$
|
||
|
// ------------------------------------------------------------------
|
||
|
// Based on CXL by Mike Smedley.
|
||
|
// ------------------------------------------------------------------
|
||
|
// whline() draws a horizontal text line in active window
|
||
|
// wvline() draws a vertical text line in active window
|
||
|
// ------------------------------------------------------------------
|
||
|
|
||
|
#include <gwinall.h>
|
||
|
|
||
|
|
||
|
// ------------------------------------------------------------------
|
||
|
|
||
|
#define HORZ 0
|
||
|
#define VERT 1
|
||
|
|
||
|
|
||
|
// ------------------------------------------------------------------
|
||
|
|
||
|
#define ULC _box_table(bt, 0) // upper left corner
|
||
|
#define UHL _box_table(bt, 1) // upper horizontal line
|
||
|
#define URC _box_table(bt, 2) // upper right corner
|
||
|
#define LVL _box_table(bt, 3) // left vertical line
|
||
|
#define RVL _box_table(bt, 4) // right vertical line
|
||
|
#define LLC _box_table(bt, 5) // lower left corner
|
||
|
#define LHL _box_table(bt, 6) // lower horizontal line
|
||
|
#define LRC _box_table(bt, 7) // lower right corner
|
||
|
#define MJ _box_table(bt, 8) // middle junction
|
||
|
#define LVJ _box_table(bt, 9) // left vertical junction
|
||
|
#define RVJ _box_table(bt, 10) // right vertical junction
|
||
|
#define UHJ _box_table(bt, 11) // upper horizontal junction
|
||
|
#define LHJ _box_table(bt, 12) // lower horizontal junction
|
||
|
|
||
|
|
||
|
// ------------------------------------------------------------------
|
||
|
|
||
|
static int disp_char(int wrow,int wcol,int attr,int btype,vchar ch,int direc) {
|
||
|
|
||
|
attr |= ACSET;
|
||
|
|
||
|
// see if next to a border, if so, connect to it
|
||
|
if(gwin.active->border) {
|
||
|
|
||
|
// abbreviate pointer
|
||
|
const int bt = btype;
|
||
|
|
||
|
// calculate effective row and column
|
||
|
int row = gwin.active->srow+gwin.active->border+wrow;
|
||
|
int col = gwin.active->scol+gwin.active->border+wcol;
|
||
|
|
||
|
// see if this is a horizontal or vertical line
|
||
|
if(direc==HORZ) {
|
||
|
|
||
|
// make sure that the box type characters match
|
||
|
if(LVL==_box_table(gwin.active->btype, 3)) {
|
||
|
|
||
|
// check left border
|
||
|
if(col==(gwin.active->scol+1)) {
|
||
|
vputc(row,gwin.active->scol,attr,LVJ);
|
||
|
ch=UHL;
|
||
|
}
|
||
|
|
||
|
// check right border
|
||
|
if(col==(gwin.active->ecol-1)) {
|
||
|
vputc(row,gwin.active->ecol,attr,RVJ);
|
||
|
ch=UHL;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
|
||
|
// make sure that the box type characters match
|
||
|
if(UHL==_box_table(gwin.active->btype, 1)) {
|
||
|
|
||
|
// check top border
|
||
|
if(row==(gwin.active->srow+1)) {
|
||
|
vputc(gwin.active->srow,col,attr,UHJ);
|
||
|
ch=LVL;
|
||
|
}
|
||
|
|
||
|
// check bottom border
|
||
|
if(row==(gwin.active->erow-1)) {
|
||
|
vputc(gwin.active->erow,col,attr,LHJ);
|
||
|
ch=LVL;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// display character
|
||
|
if(wprintc(wrow,wcol,attr,ch))
|
||
|
return gwin.werrno;
|
||
|
|
||
|
// return normally
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
// ------------------------------------------------------------------
|
||
|
|
||
|
static inline int isupvert(int btype, vchar ch) {
|
||
|
|
||
|
const int bt = btype;
|
||
|
return (ch==LVL or ch==UHJ or ch==ULC or ch==URC or ch==LVJ or ch==RVJ or ch==MJ) ? YES : NO;
|
||
|
}
|
||
|
|
||
|
|
||
|
// ------------------------------------------------------------------
|
||
|
|
||
|
static inline int isdownvert(int btype, vchar ch) {
|
||
|
|
||
|
const int bt = btype;
|
||
|
return (ch==LVL or ch==LHJ or ch==LLC or ch==LRC or ch==LVJ or ch==RVJ or ch==MJ) ? YES : NO;
|
||
|
}
|
||
|
|
||
|
|
||
|
// ------------------------------------------------------------------
|
||
|
|
||
|
static inline int islefthorz(int btype, vchar ch) {
|
||
|
|
||
|
const int bt = btype;
|
||
|
return (ch==UHL or ch==LVJ or ch==LLC or ch==ULC or ch==UHJ or ch==LHJ or ch==MJ) ? YES : NO;
|
||
|
}
|
||
|
|
||
|
|
||
|
// ------------------------------------------------------------------
|
||
|
|
||
|
static inline int isrighthorz(int btype, vchar ch) {
|
||
|
|
||
|
const int bt = btype;
|
||
|
return (ch==UHL or ch==RVJ or ch==LRC or ch==URC or ch==UHJ or ch==LHJ or ch==MJ) ? YES : NO;
|
||
|
}
|
||
|
|
||
|
|
||
|
// ------------------------------------------------------------------
|
||
|
|
||
|
int whline(int wsrow, int wscol, int count, int btype, int attr) {
|
||
|
|
||
|
register int bt;
|
||
|
int row,col,up,down;
|
||
|
vchar ch;
|
||
|
|
||
|
row=wsrow;
|
||
|
col=wscol;
|
||
|
|
||
|
// abbreviate pointer
|
||
|
bt = btype;
|
||
|
|
||
|
if(count) {
|
||
|
|
||
|
// see if a left junction or corner is needed
|
||
|
up = isupvert (btype,wgetc(row-1,col));
|
||
|
down = isdownvert(btype,wgetc(row+1,col));
|
||
|
if(up&&down)
|
||
|
ch=LVJ;
|
||
|
else if(up)
|
||
|
ch=LLC;
|
||
|
else if(down)
|
||
|
ch=ULC;
|
||
|
else
|
||
|
ch=UHL;
|
||
|
|
||
|
// display leftmost character
|
||
|
if(disp_char(row,col,attr,btype,ch,HORZ))
|
||
|
return gwin.werrno;
|
||
|
col++;
|
||
|
count--;
|
||
|
}
|
||
|
|
||
|
// do while not last character
|
||
|
while(count>1) {
|
||
|
|
||
|
// see if a middle junction is needed
|
||
|
up = isupvert (btype,wgetc(row-1,col));
|
||
|
down = isdownvert(btype,wgetc(row+1,col));
|
||
|
if(up&&down)
|
||
|
ch=MJ;
|
||
|
else if(up)
|
||
|
ch=LHJ;
|
||
|
else if(down)
|
||
|
ch=UHJ;
|
||
|
else
|
||
|
ch=UHL;
|
||
|
|
||
|
// display middle character
|
||
|
if(disp_char(row,col,attr,btype,ch,HORZ))
|
||
|
return gwin.werrno;
|
||
|
col++;
|
||
|
count--;
|
||
|
}
|
||
|
|
||
|
if(count) {
|
||
|
|
||
|
// see if a right junction or corner is needed
|
||
|
up = isupvert (btype,wgetc(row-1,col));
|
||
|
down = isdownvert(btype,wgetc(row+1,col));
|
||
|
if(up&&down)
|
||
|
ch=RVJ;
|
||
|
else if(up)
|
||
|
ch=LRC;
|
||
|
else if(down)
|
||
|
ch=URC;
|
||
|
else
|
||
|
ch=UHL;
|
||
|
|
||
|
// display rightmost character
|
||
|
if(disp_char(row,col,attr,btype,ch,HORZ))
|
||
|
return gwin.werrno;
|
||
|
}
|
||
|
|
||
|
// return normally
|
||
|
return gwin.werrno=W_NOERROR;
|
||
|
}
|
||
|
|
||
|
|
||
|
// ------------------------------------------------------------------
|
||
|
|
||
|
int wvline(int wsrow, int wscol, int count, int btype, int attr) {
|
||
|
|
||
|
register int bt;
|
||
|
int row,col,left,right;
|
||
|
vchar ch;
|
||
|
|
||
|
row=wsrow;
|
||
|
col=wscol;
|
||
|
|
||
|
// abbreviate pointer
|
||
|
bt = btype;
|
||
|
|
||
|
if(count) {
|
||
|
|
||
|
// see if a top junction or corner is needed
|
||
|
left = islefthorz (btype,wgetc(row,col-1));
|
||
|
right = isrighthorz(btype,wgetc(row,col+1));
|
||
|
if(left&&right)
|
||
|
ch=UHJ;
|
||
|
else if(left)
|
||
|
ch=URC;
|
||
|
else if(right)
|
||
|
ch=ULC;
|
||
|
else
|
||
|
ch=LVL;
|
||
|
|
||
|
// display uppermost character
|
||
|
if(disp_char(row,col,attr,btype,ch,VERT))
|
||
|
return gwin.werrno;
|
||
|
row++;
|
||
|
count--;
|
||
|
}
|
||
|
|
||
|
// do while not last character
|
||
|
while(count>1) {
|
||
|
left = islefthorz (btype,wgetc(row,col-1));
|
||
|
right = isrighthorz(btype,wgetc(row,col+1));
|
||
|
if(left&&right)
|
||
|
ch=MJ;
|
||
|
else if(left)
|
||
|
ch=RVJ;
|
||
|
else if(right)
|
||
|
ch=LVJ;
|
||
|
else
|
||
|
ch=LVL;
|
||
|
|
||
|
// display middle character
|
||
|
if(disp_char(row,col,attr,btype,ch,VERT))
|
||
|
return gwin.werrno;
|
||
|
row++;
|
||
|
count--;
|
||
|
}
|
||
|
|
||
|
if(count) {
|
||
|
|
||
|
// see if a bottom junction or corner is needed
|
||
|
left = islefthorz (btype,wgetc(row,col-1));
|
||
|
right = isrighthorz(btype,wgetc(row,col+1));
|
||
|
if(left&&right)
|
||
|
ch=LHJ;
|
||
|
else if(left)
|
||
|
ch=LRC;
|
||
|
else if(right)
|
||
|
ch=LLC;
|
||
|
else
|
||
|
ch=LVL;
|
||
|
|
||
|
// display bottommost character
|
||
|
if(disp_char(row,col,attr,btype,ch,VERT))
|
||
|
return gwin.werrno;
|
||
|
}
|
||
|
|
||
|
// return normally
|
||
|
return gwin.werrno=W_NOERROR;
|
||
|
}
|
||
|
|
||
|
|
||
|
// ------------------------------------------------------------------
|