home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fish 'n' More 2
/
fishmore-publicdomainlibraryvol.ii1991xetec.iso
/
fish
/
applications
/
xlispstat
/
src
/
src1.lzh
/
Amiga
/
amiiviewwindow3.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-10-11
|
21KB
|
540 lines
/* AmiIviewWindow3.c - Low Level Window Objects for Amiga */
/* Copyright (c) 1990 by J.K. Lindsey */
/* Additions to XLISP-STAT 2.1 Copyright (c) 1990, by Luke Tierney */
/* Additions to Xlisp 2.1, Copyright (c) 1989 by David Michael Betz */
/* You may give out copies of this software; for conditions see the */
/* file COPYING included with this distribution. */
#include <proto/exec.h>
#include <proto/intuition.h>
#include <proto/graphics.h>
#include <graphics/gfxmacros.h>
#include <exec/memory.h>
#include <string.h>
#include <stdlib.h>
#include "autil2.h"
#include "plot2.h"
#include "xlisp.h"
#include "osdef.h"
#include "xlproto.h"
#include "xlsproto.h"
#include "Stproto.h"
#include "osproto.h"
#include "amivar.h"
#include "xlsvar.h"
/* forward declarations */
void draw_bitmap(StGWWinInfo *,int,int,int,int,char *,int);
/**************************************************************************/
/** **/
/** Utility Function **/
/** **/
/**************************************************************************/
static int dbmove(StGWWinInfo *gwinfo,int *x,int *y){
/*printf("left=%d top=%d width=%d height=%d\n",gwinfo->clip_rect.left,gwinfo->clip_rect.top,
gwinfo->clip_rect.width,gwinfo->clip_rect.height);*/
if(/*!gwinfo->clipped&&*/(*x<0||*y<0||*x>gwinfo->canvasWidth||*y>gwinfo->canvasHeight))return(1);
else if(!dbflag&&gwinfo->clipped&&(*x<gwinfo->clip_rect.left||*y<gwinfo->clip_rect.top||
*x>gwinfo->clip_rect.left+gwinfo->clip_rect.width||
*y>gwinfo->clip_rect.top+gwinfo->clip_rect.height))return(1);
else if(!dbflag){
rp=gwinfo->window->RPort; /* necessary for linked windows */
*x+=gwinfo->window->BorderLeft;
*y+=gwinfo->window->BorderTop;}
return(0);}
void scroll_clip(StGWWinInfo *gwinfo,int *x,int *y){
int width,height;
StGWGetViewRect(gwinfo,0,0,&width,&height);
if(gwinfo->hasVscroll&&height<gwinfo->canvasHeight){
(*y)+=(gwinfo->view_v*(gwinfo->canvasHeight-height))/MAXPOT;}
if(gwinfo->hasHscroll&&width<gwinfo->canvasWidth){
(*x)+=(gwinfo->view_h*(gwinfo->canvasWidth-width))/MAXPOT;}}
/**************************************************************************/
/** **/
/** Initialization Functions **/
/** **/
/**************************************************************************/
#define NUMSYMBOLS 18
#define SYMROWS 5
typedef struct {
short left,top,width,height;
short image[SYMROWS];
LVAL refcon;}
Symbol;
static Symbol chip Symbols[NUMSYMBOLS];
static void InitSymbol(int sym,int left,int top,int width,int height){
Symbols[sym].width=width;
Symbols[sym].height=height;
Symbols[sym].left=left;
Symbols[sym].top=top;}
void initialize_static_globals(void){
InitSymbol(0, 0, 0, 2, 2);
Symbols[0].image[0]=0x8000;
InitSymbol(1, 0, 0, 2, 2);
Symbols[1].image[0]=0xC000;
InitSymbol(2, 0, 0, 2, 2);
Symbols[2].image[0]=0xC000;
Symbols[2].image[1]=0x8000;
InitSymbol(3, 0, 0, 2, 2);
Symbols[3].image[0]=Symbols[3].image[1]=0xC000;
InitSymbol(4, 2, 2, 4, 4);
Symbols[4].image[0]=Symbols[4].image[3]=0x6000;
Symbols[4].image[1]=Symbols[4].image[2]=0x9000;
InitSymbol(5, 2, 2, 4, 4);
Symbols[5].image[0]=Symbols[5].image[3]=0x6000;
Symbols[5].image[1]=Symbols[5].image[2]=0xF000;
InitSymbol(6, 3, 3, 5, 5);
Symbols[6].image[0]=Symbols[6].image[4]=0x2000;
Symbols[6].image[1]=Symbols[6].image[3]=0x5000;
Symbols[6].image[2]=0x8800;
InitSymbol(7, 3, 3, 5, 5);
Symbols[7].image[0]=Symbols[7].image[4]=0x2000;
Symbols[7].image[1]=Symbols[7].image[3]=0x7000;
Symbols[7].image[2]=0xF800;
InitSymbol(8, 3, 3, 5, 5);
Symbols[8].image[0]=Symbols[8].image[4]=Symbols[8].image[1]=Symbols[8].image[3]=0x2000;
Symbols[8].image[2]=0xF800;
InitSymbol(9, 3, 3, 5, 5);
Symbols[9].image[0]=Symbols[9].image[4]=0x7000;
Symbols[9].image[1]=Symbols[9].image[3]=0xA800;
Symbols[9].image[2]=0xF800;
InitSymbol(10, 2, 2, 4, 4);
Symbols[10].image[0]=Symbols[10].image[3]=0xF000;
Symbols[10].image[1]=Symbols[10].image[2]=0x9000;
InitSymbol(11, 2, 2, 4, 4);
Symbols[11].image[0]=Symbols[11].image[3]=Symbols[11].image[1]=Symbols[11].image[2]=0xF000;
InitSymbol(12, 3, 3, 5, 5);
Symbols[12].image[0]=0x7000;
Symbols[12].image[1]=Symbols[12].image[2]=0x8800;
Symbols[12].image[3]=0x5000;
Symbols[12].image[4]=0x2000;
InitSymbol(13, 3, 3, 5, 5);
Symbols[13].image[0]=Symbols[13].image[3]=0x7000;
Symbols[13].image[1]=Symbols[13].image[2]=0xF800;
Symbols[13].image[4]=0x2000;
InitSymbol(14, 3, 3, 5, 5);
Symbols[14].image[0]=0x2000;
Symbols[14].image[1]=0x5000;
Symbols[14].image[2]=Symbols[14].image[3]=0x8800;
Symbols[14].image[4]=0x7000;
InitSymbol(15, 3, 3, 5, 5);
Symbols[15].image[0]=0x2000;
Symbols[15].image[1]=Symbols[15].image[4]=0x7000;
Symbols[15].image[2]=Symbols[15].image[3]=0xF800;
InitSymbol(16, 3, 3, 5, 5);
Symbols[16].image[2]=0x2000;
Symbols[16].image[0]=Symbols[16].image[4]=0x8800;
Symbols[16].image[1]=Symbols[16].image[3]=0x5000;
InitSymbol(17, 3, 3, 5, 5);
Symbols[17].image[2]=0x2000;
Symbols[17].image[0]=Symbols[17].image[4]=Symbols[17].image[1]=Symbols[17].image[3]=0xD800;}
/**************************************************************************/
/** **/
/** Line and Rectangle Drawing Functions **/
/** **/
/**************************************************************************/
static struct TmpRas tmpRas;
static struct AreaInfo areaInfo;
static void drawline(short a,short b,short c,short d){
Move(rp,a,b);
Draw(rp,c,d);}
static void draw_object(StGWWinInfo *gwinfo,int what,int how,int a,int b,int c,int d){
static short xy[10]={0,0,0,0,0,0,0,0,0,0};
static struct Border bd={0,0,0,0,0,5,xy,0};
struct Window *w;
PLANEPTR planePtr;
short areabuffer[5],i;
int cc,dd;
if(!gwinfo||!(w=gwinfo->window))return;
/*printf("what = %c how = %c a = %d b = %d c = %d d = %d\n",what,how,a,b,c,d);
printf("clipping=%d dbflag=%d\n",gwinfo->clipped,dbflag);*/
if(dbmove(gwinfo,&a,&b))return;
if(what=='R'||what=='O'){
cc=a+c;
dd=b+d;
if(!dbflag){
cc-=w->BorderLeft;
dd-=w->BorderTop;}
if(dbmove(gwinfo,&cc,&dd))return;}
if(how=='E')SetAPen(rp,gwinfo->backColor);
switch(what) {
case 'L': {
if(dbmove(gwinfo,&c,&d))return;
drawline((short)a,(short)b,(short)c,(short)d);
if(gwinfo->lineWidth>1){
if(a-c<b-d)drawline((short)a,(short)(b+1),(short)c,(short)(d+1));
else drawline((short)(a+1),(short)b,(short)(c+1),(short)d);
if(gwinfo->lineWidth>2){
if(a-c<b-d)drawline((short)a,(short)(b-1),(short)c,(short)(d-1));
else drawline((short)(a-1),(short)b,(short)(c-1),(short)d);}}
break;}
case 'P': {
WritePixel(rp,(short)a,(short)b);
break;}
case 'R': {
switch (how) {
case 'E':
case 'P': {
RectFill(rp,(short)a,(short)b,(short)(a+c-1),(short)(b+d-1));
break;}
case 'F': {
bd.LeftEdge=a;
bd.TopEdge=b;
bd.FrontPen=gwinfo->drawColor;
bd.BackPen=gwinfo->backColor;
bd.DrawMode=gwinfo->drawMode;
xy[2]=xy[4]=c-1;
xy[5]=xy[7]=d-1;
DrawBorder(rp,&bd,0,0);
if(gwinfo->lineWidth>1){
bd.LeftEdge++;
bd.TopEdge++;
xy[2]=xy[4]=c-3;
xy[5]=xy[7]=d-3;
DrawBorder(rp,&bd,0,0);
if(gwinfo->lineWidth>2){
bd.LeftEdge-=2;
bd.TopEdge-=2;
xy[2]=xy[4]=c+1;
xy[5]=xy[7]=d+1;
DrawBorder(rp,&bd,0,0);}}
break;}}
break;}
case 'O': {
switch(how) {
case 'E':
case 'P': {
if(!(planePtr=AllocRaster(screenw,screenh)))xlfail("unable to allocate raster");
for(i=0;i<5;i++)areabuffer[i]=0;
InitArea(&areaInfo,areabuffer,2);
rp->AreaInfo=&areaInfo;
InitTmpRas(&tmpRas,planePtr,RASSIZE(screenw,screenh));
rp->TmpRas=&tmpRas;
AreaEllipse(rp,(short)(a+c/2),(short)(b+d/2),(short)(c/2),(short)(d/2));
AreaEnd(rp);
FreeRaster(planePtr,screenw,screenh);
break;}
case 'F': {
SetOPen(rp,gwinfo->drawColor);
DrawEllipse(rp,(short)(a+c/2),(short)(b+d/2),(short)(c/2),(short)(d/2));
if(gwinfo->lineWidth>1){
DrawEllipse(rp,(short)(a+c/2),(short)(b+d/2),(short)(c/2-1),(short)(d/2-1));
if(gwinfo->lineWidth>2){
DrawEllipse(rp,(short)(a+c/2),(short)(b+d/2),(short)(c/2+1),(short)(d/2+1));}}
BNDRYOFF(rp);
break;}}
break;}}
if(how=='E')SetAPen(rp,gwinfo->drawColor);}
static void draw_poly(StGWWinInfo *gwinfo,char how,int n,short *p,int from_origin){
int i,x,y;
struct Window *w;
PLANEPTR planePtr;
short *areabuffer;
if(!gwinfo||!(w=gwinfo->window)||n<=0)return;
x=p[0];
y=p[1];
if(dbmove(gwinfo,&x,&y))return;
p[0]=x;
p[1]=y;
for(i=1;i<n;i++){
x=p[2*i];
y=p[2*i+1];
if(dbmove(gwinfo,&x,&y))return;
p[2*i]=x;
p[2*i+1]=y;}
if(how=='E')SetAPen(rp,gwinfo->backColor);
if(!from_origin)for(i=1;i<n;i++){
p[2*i]=p[2*i]+p[2*i-2];
p[2*i+1]=p[2*i+1]+p[2*i-1];}
switch(how){
case 'E':
case 'P': {
if(!(planePtr=AllocRaster(screenw,screenh)))xlfail("unable to allocate raster");
if(!(areabuffer=calloc(1,5*n*sizeof(short))))xlfail("unable to allocate raster buffer");
InitArea(&areaInfo,areabuffer,n);
rp->AreaInfo=&areaInfo;
InitTmpRas(&tmpRas,planePtr,RASSIZE(screenw,screenh));
rp->TmpRas=&tmpRas;
AreaMove(rp,p[0],p[1]);
for(i=1;i<n;i++)AreaDraw(rp,p[2*i],p[2*i+1]);
AreaEnd(rp);
free(areabuffer);
FreeRaster(planePtr,screenw,screenh);
break;}
case 'F': {
Move(rp,p[0],p[1]);
PolyDraw(rp,n,p);
break;}}
if(how=='E')SetAPen(rp,gwinfo->drawColor);}
void StGWDrawLine(StGWWinInfo *gwinfo,int x1,int y1,int x2,int y2){
draw_object(gwinfo,'L','0',x1,y1,x2,y2);}
void StGWDrawPoint(StGWWinInfo *gwinfo,int x,int y){
draw_object(gwinfo,'P','0',x,y,0,0);}
void StGWEraseRect(StGWWinInfo *gwinfo,int left,int top,int width,int height){
draw_object(gwinfo,'R','E',left,top,width,height);}
void StGWFrameRect(StGWWinInfo *gwinfo,int left,int top,int width,int height){
draw_object(gwinfo,'R','F',left,top,width,height);}
void StGWPaintRect(StGWWinInfo *gwinfo,int left,int top,int width,int height){
draw_object(gwinfo,'R','P',left,top,width,height);}
void StGWEraseOval(StGWWinInfo *gwinfo,int left,int top,int width,int height){
draw_object(gwinfo,'O','E',left,top,width,height);}
void StGWFrameOval(StGWWinInfo *gwinfo,int left,int top,int width,int height){
draw_object(gwinfo,'O','F',left,top,width,height);}
void StGWPaintOval(StGWWinInfo *gwinfo,int left,int top,int width,int height){
draw_object(gwinfo,'O','P',left,top,width,height);}
void StGWEraseArc(StGWWinInfo *gwinfo,int left,int top,int width,int height,double angle1,double angle2){
/*draw_arc(gwinfo,'E',left,top,width,height,angle1,angle2);}*/
xlfail("not supported 25"); }
void StGWFrameArc(StGWWinInfo *gwinfo,int left,int top,int width,int height,double angle1,double angle2){
/*draw_arc(gwinfo,'F',left,top,width,height,angle1,angle2);}*/
xlfail("not supported 26"); }
void StGWPaintArc(StGWWinInfo *gwinfo,int left,int top,int width,int height,double angle1,double angle2){
/*draw_arc(gwinfo,'P',left,top,width,height,angle1,angle2);}*/
xlfail("not supported 24"); }
void StGWErasePoly(StGWWinInfo *gwinfo,int n,short *p,int from_origin){
draw_poly(gwinfo,'E',n,p,from_origin);}
void StGWFramePoly(StGWWinInfo *gwinfo,int n,short *p,int from_origin){
draw_poly(gwinfo,'F',n,p,from_origin);}
void StGWPaintPoly(StGWWinInfo *gwinfo,int n,short *p,int from_origin){
draw_poly(gwinfo,'P',n,p,from_origin);}
/**************************************************************************/
/** **/
/** Text Functions **/
/** **/
/**************************************************************************/
int StGWTextAscent(StGWWinInfo *gwinfo){
return((int)window->RPort->TxBaseline);}
int StGWTextDescent(StGWWinInfo *gwinfo){
return((int)(window->RPort->TxHeight-window->RPort->TxBaseline));}
int StGWTextWidth(StGWWinInfo *gwinfo,char *text){
return((int)TextLength(window->RPort,text,strlen(text)));}
void StGWDrawString(StGWWinInfo *gwinfo,char *s,int x,int y){
struct Window *w;
if(!s||!gwinfo||!(w=gwinfo->window))return;
if(dbmove(gwinfo,&x,&y))return;
/*printf("x=%d y=%d s=%s\n",x,y,s);*/
Move(rp,(short)x,(short)(y+1));
Text(rp,s,strlen(s));}
void StGWDrawText(StGWWinInfo *gwinfo,char *text,int x,int y,int h,int v){
int FontAscent,string_width;
if(!text||!gwinfo)return;
FontAscent=StGWTextAscent(gwinfo);
string_width=StGWTextWidth(gwinfo,text);
if(v==1)y+=FontAscent;
if(h==1)x-=string_width/2;
if(h==2)x-=string_width;
StGWDrawString(gwinfo,text,x,y);}
static void DrawCharUp(struct Window *w,char myChar,int x,int y){
short i,j,hch,wch;
char dc,bc;
StGWWinInfo *gwinfo;
gwinfo=(StGWWinInfo *)w->UserData;
dc=gwinfo->drawColor;
bc=gwinfo->backColor;
if(dbmove(gwinfo,&x,&y))return;
hch=rp->TxHeight;
wch=rp->TxWidth;
SetAPen(&rp1,dc);
SetAPen(&rp2,dc);
SetBPen(&rp1,bc);
SetDrMd(&rp1,w->RPort->DrawMode);
SetDrMd(&rp2,w->RPort->DrawMode);
SetRast(&rp1,bc);
SetRast(&rp2,bc);
Move(&rp1,0,rp->TxBaseline);
Text(&rp1,&myChar,1);
for(i=0;i<wch;i++)for(j=0;j<hch;j++)if(ReadPixel(&rp1,i,j)==dc)WritePixel(&rp2,j,8-i);
ClipBlit(&rp2,0,0,rp,x,y-wch,hch,wch,0xC0);}
void StGWDrawStringUp(StGWWinInfo *gwinfo,char *s,int x,int y){
struct Window *w;
char str[2];
int n;
if(!s||!gwinfo||!(w=gwinfo->window))return;
str[1] = '\0';
for(n=strlen(s);n>0;n--,s++){
DrawCharUp(w,*s,x,y);
str[0]=*s;
y-=StGWTextWidth(gwinfo,str);}}
void StGWDrawTextUp(StGWWinInfo *gwinfo,char *text,int x,int y,int h,int v){
int FontAscent,string_width;
if(!text||!gwinfo)return;
FontAscent=StGWTextAscent(gwinfo);
string_width=StGWTextWidth(gwinfo,text);
if(v==1)x+=FontAscent;
if(h==1)y+=string_width/2;
if(h==2)y+=string_width;
StGWDrawStringUp(gwinfo,text,x,y);}
/**************************************************************************/
/** **/
/** Symbol Functions **/
/** **/
/**************************************************************************/
void StGWSetSymRefCon(int index,LVAL rc){
if(index<NUMSYMBOLS)Symbols[index].refcon=rc;}
LVAL StGWGetSymRefCon(int index){
if(index<NUMSYMBOLS)return(Symbols[index].refcon);
else return(0);}
void StGWGetSymbolSize(int sym,int *width,int *height){
*width=Symbols[sym].width;
*height=Symbols[sym].height;}
void StGWDrawSymbol(StGWWinInfo *gwinfo,int sym,int x,int y){
if(sym<0||sym>=NUMSYMBOLS)return;
draw_bitmap(gwinfo,x-(int)Symbols[sym].left,y-(int)Symbols[sym].top,
Symbols[sym].width,Symbols[sym].height,(char *)Symbols[sym].image,2);}
void StGWReplaceSymbol(StGWWinInfo *gwinfo,int oldsym,int newsym,int x,int y){
int oldwidth,oldheight,newwidth,newheight;
if(oldsym>=NUMSYMBOLS||newsym>=NUMSYMBOLS)return;
StGWGetSymbolSize(oldsym,&oldwidth,&oldheight);
StGWGetSymbolSize(newsym,&newwidth,&newheight);
if(oldwidth>newwidth||oldheight>newheight){
StGWEraseRect(gwinfo,x-Symbols[oldsym].left,y-Symbols[oldsym].top,
oldwidth,oldheight);}
StGWDrawSymbol(gwinfo,newsym,x,y);}
/**************************************************************************/
/** **/
/** Bitmap Functions **/
/** **/
/**************************************************************************/
static void draw_bitmap(StGWWinInfo *gwinfo,int left,int top,int width,int height,char *image,int modulus){
struct Window *w;
if(!gwinfo||!(w=gwinfo->window))return;
/*printf("bitmap left=%d top=%d width=%d height=%d\n",left,top,width,height);*/
if(dbmove(gwinfo,&left,&top))return;
SetDrMd(rp,gwinfo->symbolMode);
BltTemplate(image,0,modulus,rp,left,top,width,height); SetBPen(rp,gwinfo->backColor);
SetDrMd(rp,gwinfo->drawMode);}
void StGWDrawBitmap(StGWWinInfo *gwinfo,int left,int top,int width,int height,char *image){
unsigned short *im;
int rowwords,i,j,l,m;
rowwords=width/16+1;
if(rowwords*height<=0)return;
if(!(im=AllocMem(rowwords*height*2,MEMF_CHIP|MEMF_CLEAR)))return;
for(i=0;i<height;i++)for(j=0;j<rowwords;j++){
for(l=0;l<16;l++){
m=j*16+l;
if(m<width&&image[i*width+m])im[i*rowwords+j]|=(1<<(15-l));}}
draw_bitmap(gwinfo,left,top,width,height,(char *)im,2*rowwords);
FreeMem(im,rowwords*height*2);}
/**************************************************************************/
/** **/
/** Buffering Functions **/
/** **/
/**************************************************************************/
static int bufflevel=0;
void StGWStartBuffering(StGWWinInfo *gwinfo){
if(!gwinfo||!gwinfo->window)return;
bufflevel++;
if(dbflag)return;
dbflag=1;
rp=&dbrp;
SetRast(rp,gwinfo->backColor);}
/*
void StGWBufferToScreen(StGWWinInfo *gwinfo,int left,int top,int width,int height){
struct Window *w;
if(!gwinfo||!(w=gwinfo->window))return;
if(bufflevel>0)bufflevel--;
if(bufflevel>0)return;
if(dbflag){
left+=w->BorderLeft;
top+=w->BorderTop;
ClipBlit(&dbrp,left,top,w->RPort,left,top,width,height,0xC0);
dbflag=0;
rp=w->RPort;}}
*/
void StGWBufferToScreen(StGWWinInfo *gwinfo,int left,int top,int width,int height){
struct Window *w;
int vwidth,vheight,bleft,btop;
if(!gwinfo||!(w=gwinfo->window))return;
if(bufflevel>0)bufflevel--;
if(bufflevel>0)return;
if(dbflag){
dbflag=0;
rp=w->RPort;
if(left>=0&&top>=0){
bleft=left;
btop=top;
StGWGetViewRect(gwinfo,0,0,&vwidth,&vheight);
/*printf("buffer left=%d top=%d width=%d height=%d\n",left,top,width,height);*/
if(gwinfo->hasHscroll&&vwidth<gwinfo->canvasWidth){
bleft+=(gwinfo->view_h*(gwinfo->canvasWidth-vwidth))/MAXPOT;}
if(gwinfo->hasVscroll&&vheight<gwinfo->canvasHeight){
btop+=(gwinfo->view_v*(gwinfo->canvasHeight-vheight))/MAXPOT;}
ClipBlit(&dbrp,bleft,btop,rp,left+(int)w->BorderLeft,
top+(int)w->BorderTop,width,height,0xC0);}}}
/**************************************************************************/
/** **/
/** Miscellaneous Functions **/
/** **/
/**************************************************************************/
extern unsigned short icon[];
void StGWDumpImage(StGWWinInfo *gwinfo,char *fname,double scale){
struct Window *w;
unsigned long flags;
int test;
if(gwinfo&&(w=gwinfo->window)){
WindowToFront(w);
flags=w->IDCMPFlags;
Dodo(w,0);
wfile(fname);
test=SaveWindow(w,fname,w->BorderLeft,w->BorderTop,
w->Width-w->BorderRight-w->BorderLeft,w->Height-w->BorderTop-w->BorderBottom);
Dodo(w,flags);
if(test)xlfail("IFF save failed");}}
void StGWResetBuffer(){
bufflevel=dbflag=0;}