📄 graphic.c
字号:
text=pop(stSTRING)->pointer; y=pop(stNUMBER)->value; x=pop(stNUMBER)->value; transform(&x,&y); if (!winopened) { error(ERROR,"Got no window to draw"); return; } len=strlen(text);#ifdef UNIX XTextExtents(myfont,text,len,&d1,&d2,&d3,&size); if (align[0]=='l') xoff=0; else if (align[0]=='r') xoff=-size.width; else xoff=-size.width/2; if (align[1]=='t') yoff=fontheight; else if (align[1]=='b') yoff=0; else yoff=fontheight/2; XDrawString(display,window,gc,x+xoff,y+yoff,text,len); XDrawString(display,backbit,gc,x+xoff,y+yoff,text,len); XFlush(display); if (printerfile) { for(i=0;i<INBUFFLEN;i++) { if (*text=='(' || *text==')') { string[i]='\\'; i++; } string[i]=*text; text++; } if (firsttext) { firsttext=FALSE; XTextExtents(myfont,sample,strlen(sample),&d1,&d2,&d3,&size); fprintf(printerfile,"/Helvetica findfont setfont 0 0 moveto\n"); fprintf(printerfile,"(%s) false charpath flattenpath pathbbox\n",sample); fprintf(printerfile,"3 -1 roll pop pop sub abs %g exch div\n", (double)psscale*size.width*1.095 /* mysterious scaling factor ! */); fprintf(printerfile,"/Helvetica findfont exch scalefont setfont\n"); } fprintf(printerfile,"%g %g (%c) (%s) AT\n", x*psscale,(winheight-y-yoff)*psscale,align[0],string); }#else /* WINDOWS */ startdraw(FALSE); SelectObject(devcon,myfont); SetBkMode(devcon,TRANSPARENT); SelectObject(bitcon,myfont); SetBkMode(bitcon,TRANSPARENT); algn=0; xoff=yoff=0; if (align[0]=='l') algn|=TA_LEFT; else if (align[0]=='r') algn|=TA_RIGHT; else algn|=TA_CENTER; if (align[1]=='t') algn|=TA_TOP; else if (align[1]=='b') algn|=TA_BOTTOM; else { algn|=TA_BOTTOM; yoff=fontheight/2; } SetTextAlign(devcon,algn); TextOut(devcon,(int)(x+xoff),(int)(y+yoff),text,len); SetTextAlign(bitcon,algn); TextOut(bitcon,(int)(x+xoff),(int)(y+yoff),text,len); ReleaseDC(window,devcon); if (printer) { SetBkMode(printer,TRANSPARENT); SetTextAlign(printer,algn); TextOut(printer,(int)((x+xoff)*prnscale+prnoffx), (int)((y+yoff)*prnscale+prnoffy),text,strlen(text)); }#endif}int check_alignement(char *al) /* checks, if text-alignement is valid */{ al[0]=tolower((int)al[0]); al[1]=tolower((int)al[1]); if (al[2]!='\0' || !strchr("clr",al[0]) || !strchr("ctb",al[1])) { error(ERROR,"invalid text-alignement"); return FALSE; } return TRUE;}void closewin() /* close the window */{#ifdef UNIX int status;#endif if (!winopened) { error(WARNING,"Got no window to close"); return; } winopened=FALSE;#ifdef UNIX if (backpid>0) { kill(backpid,SIGTERM); waitpid(backpid,&status,0); backpid=-1; } XFreePixmap(display,backbit); XDestroyWindow(display,window); XFlush(display); if (printerfile) closeprinter();#else /* WINDOWS */ PostThreadMessage(wtid,WM_QUIT,0,0);#endif}void clearwin() /* clear the window */{#ifdef WINDOWS RECT interior;#endif if (!winopened) { error(WARNING,"Got no window to clear"); return; }#ifdef UNIX XFillRectangle(display,window,rgc,0,0,winwidth,winheight); XFillRectangle(display,backbit,rgc,0,0,winwidth,winheight); XFlush(display); if (printerfile) { fprintf(printerfile,"showpage\n"); fflush(printerfile); }#else /* WINDOWS */ startdraw(FALSE); GetClientRect(window,&interior); FillRect(devcon,&interior,(HBRUSH)COLOR_WINDOW); FillRect(bitcon,&interior,(HBRUSH)COLOR_WINDOW); if (printer) { EndPage(printer); StartPage(printer); } ReleaseDC(window,devcon);#endif}void moveorigin(char *or) /* move origin of window */{ if (or==NULL) or=pop(stSTRING)->pointer; or[0]=tolower((int)or[0]); or[1]=tolower((int)or[1]); if (or[2]!='\0' || !strchr("lcr",or[0]) || !strchr("tbc",or[1])) { error(ERROR,"invalid window origin"); return; } strcpy(winorigin,or); return;}static void itransform(int *ix,int *iy) /* integer variant of transform() */{ double dx,dy; dx=*ix; dy=*iy; transform(&dx,&dy); *ix=(int)dx; *iy=(int)dy;}static void transform(double *x,double *y) /* do coordinate transformation */{ double xz,yz,xd,yd; double xalt,yalt; if (infolevel>=DEBUG) { xalt=*x; yalt=*y; } switch(winorigin[0]) { case 'l': xz=0;xd=1.0;break; case 'c': xz=winwidth/2;xd=1.0;break; case 'r': xz=winwidth;xd=-1.0;break; } switch(winorigin[1]) { case 't': yz=0;yd=1.0;break; case 'c': yz=winheight/2;yd=1.0;break; case 'b': yz=winheight;yd=-1.0;break; } if (infolevel>=DEBUG) { sprintf(string,"transforming (%g,%g) into (%g,%g)",xalt,yalt,*x,*y); error(DEBUG,string); } *x=xz+(*x)*xd; *y=yz+(*y)*yd;}void rect(struct command *cmd) /* draw a (filled) rect */{#ifdef WINDOWS RECT box,prbox;#endif int fill,clear; double x1,y1,x2,y2,s; if (!winopened) { error(ERROR,"Got no window to draw"); return; } fill=cmd->tag & dmFILL; clear=cmd->tag & dmCLEAR; y2=pop(stNUMBER)->value; x2=pop(stNUMBER)->value; y1=pop(stNUMBER)->value; x1=pop(stNUMBER)->value; transform(&x1,&y1); transform(&x2,&y2); if (x1>x2) {s=x2;x2=x1;x1=s;} if (y1>y2) {s=y2;y2=y1;y1=s;}#ifdef UNIX if (clear) { if (fill) { XFillRectangle(display,window,rgc,x1,y1,x2-x1+1,y2-y1+1); XFillRectangle(display,backbit,rgc,x1,y1,x2-x1+1,y2-y1+1); } else { XDrawRectangle(display,window,rgc,x1,y1,x2-x1,y2-y1); XDrawRectangle(display,backbit,rgc,x1,y1,x2-x1,y2-y1); } } else { if (fill) { XFillRectangle(display,window,gc,x1,y1,x2-x1+1,y2-y1+1); XFillRectangle(display,backbit,gc,x1,y1,x2-x1+1,y2-y1+1); } else { XDrawRectangle(display,window,gc,x1,y1,x2-x1,y2-y1); XDrawRectangle(display,backbit,gc,x1,y1,x2-x1,y2-y1); } } XFlush(display); if (printerfile) { fprintf(printerfile,"%g %g %g %g (%c) (%c) RE\n", x1*psscale,(winheight-y1)*psscale, x2*psscale,(winheight-y2)*psscale, clear?'y':'n',fill?'y':'n'); fflush(printerfile); }#else startdraw(clear); box.left=(long)x1; box.right=(long)x2+1; box.top=(long)y1; box.bottom=(long)y2+1; prbox.left=(long)(x1*prnscale+prnoffx); prbox.right=(long)(x2*prnscale+prnoffx); prbox.top=(long)(y1*prnscale+prnoffy); prbox.bottom=(long)(y2*prnscale+prnoffy); if (fill) { if (clear) FillRect(devcon,&box,(HBRUSH)COLOR_WINDOW); else FillRect(devcon,&box,GetStockObject(BLACK_BRUSH)); if (clear) FillRect(bitcon,&box,(HBRUSH)COLOR_WINDOW); else FillRect(bitcon,&box,GetStockObject(BLACK_BRUSH)); if (printer) { FillRect(printer,&prbox,GetStockObject(clear?WHITE_BRUSH:BLACK_BRUSH)); } } else { if (clear) FrameRect(devcon,&box,backbrush); else FrameRect(devcon,&box,GetStockObject(BLACK_BRUSH)); if (clear) FrameRect(bitcon,&box,backbrush); else FrameRect(bitcon,&box,GetStockObject(BLACK_BRUSH)); if (printer) { MoveToEx(printer,prbox.left,prbox.top,NULL); LineTo(printer,prbox.left,prbox.bottom); LineTo(printer,prbox.right,prbox.bottom); LineTo(printer,prbox.right,prbox.top); LineTo(printer,prbox.left,prbox.top); } } ReleaseDC(window,devcon); #endif}void putbit(void) /* put rect into win */{ char *mode,*pm,*bitstring,*pb; char m; int xe,ye,we,he; int x,y,xdest,ydest,w,h,n,badimage; int sbit,wbit,nbit;#ifdef UNIX XImage *bits=NULL; XGCValues vals;#endif mode=pop(stSTRING)->pointer; if (print_to_file) { error(ERROR,"Cannot bitblit to printer"); return; } if (!winopened) { error(ERROR,"Got no window to draw"); return; } for(pm=mode;*pm;pm++) *pm=tolower(*pm); if (!strcmp(mode,"replace") || !strcmp(mode,"rep")) m='r'; else if (!strcmp(mode,"and")) m='a'; else if (!strcmp(mode,"or")) m='o'; else if (!strcmp(mode,"xor")) m='x'; else if (!strcmp(mode,"nand")) m='n'; else if (!strcmp(mode,"1")) m='1'; else if (!strcmp(mode,"0")) m='0'; else if (!strcmp(mode,"clear")) m='c'; else { sprintf(string,"Invalid mode for bitblit: '%s'",mode); error(ERROR,string); } ydest=(int)pop(stNUMBER)->value; xdest=(int)pop(stNUMBER)->value; itransform(&xdest,&ydest); bitstring=pop(stSTRING)->pointer; badimage=FALSE; n=0; if (sscanf(bitstring,"%d,%d:%n",&w,&h,&n)!=2) badimage=TRUE; for(pb=bitstring+n;*pb;pb++) { *pb=tolower(*pb); if (!strchr("0123456789abcdef",*pb)) { badimage=TRUE; break; } } if (badimage || w<0 || h<0) { error(ERROR,"Invalid bitmap"); return; } if (xdest>=winwidth || ydest>=winheight || xdest+w<0 || ydest+h<0) return; xe=xdest;ye=ydest;we=w;he=h; if (xe<0) xe=0; if (ye<0) ye=0; if (xe+we>winwidth) we=winwidth-xe; if (ye+he>winheight) he=winheight-ye;#ifdef UNIX if (xe+we>=0 && ye+he>=0) { XGetGCValues(display,gc,GCPlaneMask,&vals); bits=XGetImage(display,window,xe,ye,we,he,vals.plane_mask,XYPixmap); if (!bits) { error(ERROR,"Couldn't get bits from window"); return; } }#endif readbits(bitstring+n); for(y=0;y<h;y++) { for(x=0;x<w;x++) { if (x+xdest>=xe && x+xdest<xe+we && y+ydest>=ye && y+ydest<ye+he)#ifdef UNIX wbit=(XGetPixel(bits,xdest+x-xe,ydest+y-ye)==f_color)?1:0;#else wbit=(GetPixel(bitcon,xdest+x,ydest+y)==RGB(0,0,0))?1:0;#endif else wbit=0; sbit=readbits(NULL); switch(m) { case 'a': nbit=wbit&sbit;break; case 'o': nbit=wbit|sbit;break; case 'x': nbit=wbit^sbit;break; case 'n': nbit=1-(wbit&sbit);break; case '1': nbit=1;break; case '0': nbit=0;break; case 'c': nbit=wbit-wbit*sbit;break; case 'r': default: nbit=sbit;break; } if (x+xdest>=xe && x+xdest<xe+we && y+ydest>=ye && y+ydest<ye+he)#ifdef UNIX XPutPixel(bits,x+xdest-xe,y+ydest-ye,nbit?f_color:b_color);#else SetPixelV(bitcon,xdest+x,ydest+y,nbit?RGB(0,0,0):backpixel);#endif } }#ifdef UNIX if (bits) { XPutImage(display,window,gc,bits,0,0,xe,ye,we,he); XPutImage(display,backbit,gc,bits,0,0,xe,ye,we,he); XFlush(display); XDestroyImage(bits); }#else startdraw(FALSE); BitBlt(devcon,xe,ye,we,he,bitcon,xe,ye,SRCCOPY); ReleaseDC(window,devcon);#endif return;}char *getbit(int x1,int y1,int x2,int y2) /* get rect from win */{ int s,x,y,pixel; int xe1,ye1,xe2,ye2; char *bitstring;#ifdef UNIX XImage *bits=NULL; XGCValues vals;#endif if (!winopened) { error(ERROR,"Got no window to draw"); return my_strdup(""); } itransform(&x1,&y1); itransform(&x2,&y2); if (x2<x1) {s=x1;x1=x2;x2=s;} if (y2<y1) {s=y1;y1=y2;y2=s;} xe1=x1;ye1=y1;xe2=x2;ye2=y2; if (xe1<0) xe1=0; if (ye1<0) ye1=0; if (xe2>=winwidth) xe2=winwidth-1; if (ye2>=winheight) ye2=winheight-1;#ifdef UNIX if (xe1<=xe2 && ye1<=ye2) { XGetGCValues(display,gc,GCPlaneMask,&vals); bits=XGetImage(display,window,xe1,ye1,xe2-xe1+1,ye2-ye1+1, vals.plane_mask,XYPixmap); if (!bits) { error(ERROR,"Couldn't get bits from window"); return my_strdup(""); } } bitstring=newbits(x2-x1+1,y2-y1+1); for(y=y1;y<=y2;y++) { for(x=x1;x<=x2;x++) { if (x>=xe1 && x<=xe2 && y>=ye1 && y<=ye2) pixel=(XGetPixel(bits,x-xe1,y-ye1)==f_color); else pixel=0; addbits(bitstring,pixel); } } if (bits) XDestroyImage(bits);#else bitstring=newbits(x2-x1+1,y2-y1+1); for(y=y1;y<=y2;y++) { for(x=x1;x<=x2;x++) { if (x>=xe1 && x<=xe2 && y>=ye1 && y<=ye2) pixel=(GetPixel(bitcon,x,y)==RGB(0,0,0)); else pixel=0; addbits(bitstring,pixel); } }#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -