From 8646c6b2ddaf32ac7342cc8b61e559d46885af4f Mon Sep 17 00:00:00 2001 From: root <> Date: Sun, 8 Feb 2009 16:49:14 +0000 Subject: *** empty log message *** --- src/libjwg.c | 815 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 797 insertions(+), 18 deletions(-) (limited to 'src/libjwg.c') diff --git a/src/libjwg.c b/src/libjwg.c index f12f079..7678091 100644 --- a/src/libjwg.c +++ b/src/libjwg.c @@ -1,20 +1,799 @@ -/* - * libjwg.c: - * - * Copyright (c) 2009 James McKenzie <20@madingley.org>, - * All rights reserved. - * - */ - -static char rcsid[] = "$Id$"; - -/* - * $Log$ - * Revision 1.1 2009/02/08 16:25:32 root - * *** empty log message *** - * - * - */ - #include "project.h" +#include + +/* Kludgy stuff to handle fortran */ + +Handle_list handle_list; +int list_created=0; +int serial; + + +/* Destructors */ + +void Data_Destructor(Data data) +{ +if (data->data) free(data->data); + +printf("JWG: Freeing data at %08x\n",(unsigned int) data->data); + +} + +void Handle_Destructor(Handle handle) +{ +printf("JWG: Destroying handle %d\n",handle->serial); + +Obj_Delete(handle->private); + +fclose(handle->file); + +if (handle->data) Obj_Delete(handle->data); + +Obj_Remove(handle_list,handle); +free(handle); + +} + + + + + +Handle handle_from_serial(int serial) +{ +Handle ret; + +ret=handle_list->head; +while (ret) { + if (ret->serial==serial) return(ret); + ret=ret->next; +} + +printf("JWG: Could not find handle associated with serial %d\n",serial); +printf("JWG: Expect very bad things to happen.\n"); + +return(ret); +} + + + +/* C visible stuff */ + + +char * jwg_fiddle_text(char *str,int len) +{ +char *s,*ptr; + +s=(char *) malloc(len); + +bcopy(str,s,len); + +ptr=s+len; + +while ((ptr--)>s) { + +if (isgraph(*ptr)) { + ptr=s; +} else { + *ptr=0; +} + +} + +return(s); +} + + +void jwg_xform(Handle h,Jwgpos *pos) +{ +float x,y; + +x=pos->x; +y=pos->y; + +pos->x=h->transform.xc+(h->transform.a*x)+(h->transform.b*y); +pos->y=h->transform.yc+(h->transform.c*x)+(h->transform.d*y); + +} + + +void jwg_recalc_det(Handle h) +{ +Transform t=h->transform; + +h->transform.det=(t.a*t.d)-(t.b*t.c); + +if (h->transform.det==0.0) { + printf("JWG: Your transform matrix is now singular - I hope\n"); + printf("JWG: you know what you are doing.\n"); +} + +} + +/* Ok this is a horid kludge for devices that can't do things */ +/* like text at a reasonable angle....*/ +/* N describes the handedness of the devices */ +/* coord system 1=left handed (assumes y is inverted) */ + +float jwg_decompose_matrix(Transform t,int n) +{ +float m1,m2,r; +float th; + + +/* We're in trouble if there's a reflection in there so */ +/* Patch it up! */ + +if (n) { + t.c=-t.c; + t.d=-t.d; +} + + +if (t.det<0) { + printf("JWG: jwg_decompose_matrix found a reflection. You are probably trying\n"); + printf("JWG: to write text backwards on a device which can't\n"); + t.c=-t.c; + t.d=-t.d; +} + +m1=hypot(t.a,t.c); +m2=hypot(t.b,t.d); + +if (m1>m2) { + r=m1/m2; +} else { + r=m2/m1; +} + +if (r>1.001) { + printf("JWG: jwg_decompse_matrix found a non conformal transformation expect\n"); + printf("JWG: angles to be wrong\n"); +} + + +th=atan2(t.c,t.a); + +return(th); +} + +Transform jwg_unitize(Transform t) +{ +Transform ret; + +ret.a=t.a/t.det; +ret.b=t.b/t.det; +ret.c=t.c/t.det; +ret.d=t.d/t.det; + +ret.det=1.0; + +return(ret); +} + + + + + +void init_pen(Pen *pen) +{ +pen->width=0.0; +pen->color.r=0.0; +pen->color.g=0.0; +pen->color.b=0.0; +} + +void init_brush(Brush *brush) +{ +brush->density=1.0; +brush->color.r=0.0; +brush->color.g=0.0; +brush->color.b=0.0; + +} + +void init_ink(Ink *ink) +{ +ink->font=0; +ink->color.r=0.0; +ink->color.g=0.0; +ink->color.b=0.0; +ink->height=10.0; +} + +void init_transform(Handle h) +{ + + +h->transform.xc=0.0; +h->transform.yc=0.0; +h->transform.a=1.0; +h->transform.b=0.0; +h->transform.c=0.0; +h->transform.d=1.0; + +switch(h->format) { +case 0: + xfig_init_xform(h); + break; +case 1: + cgm_init_xform(h); + break; +default: + printf("JWG: Cannot find initial xform matrix - you have probably\n"); + printf("JWG: Specified an unknown format - using identity matrix\n"); +} + + +jwg_recalc_det(h); + +/* Kludge*/ +h->ink.height*=h->transform.det; + +} + + +void jwg_write_line(Handle h,Jwgline *line) +{ + + +switch (h->format) { +case 0: + xfig_do_line(h,line); + break; +case 1: + cgm_do_line(h,line); + break; +} + + + +} + +void jwg_write_polygon(Handle h,Jwgline *line) +{ + +switch (h->format) { +case 0: + xfig_do_poly(h,line); + break; +case 1: + cgm_do_poly(h,line); + break; +} + + + + +} + + +jwg_print_transform(Transform t) +{ +printf("/%03.3f %03.3f %03.3f\\\n",t.a,t.b,t.xc); +printf("|%03.3f %03.3f %03.3f|\n",t.c,t.d,t.yc); +printf("\\ 0.000 0.000 1.000/\n"); + +} + +/* Fortran Visible Stuff */ + +int jwg_create_handle(int *format,char *fname,int len) +{ +Handle ret; +char *name; + +name=jwg_fiddle_text(fname,len); + + +if (!list_created) { + printf("JWG: Initializing\n"); + handle_list=CREATE_LIST(Handle); + serial=1; +} + +if (!name) { + printf("JWG: passed null pointer for filename\n"); + return(0); +} + +ret=CREATE_OBJ(Handle); + +printf("JWG: Creating handle %d\n",serial); + +ret->serial=serial++; +ret->format=*format; +ret->stack=(Handle) NULL; + +init_pen(&ret->pen); +init_brush(&ret->brush); +init_ink(&ret->ink); +init_transform(ret); + +ret->data=(Data) NULL; + +ret->current_line_size=JWG_DEFAULT_LINE_SIZE; + +ret->current_line.data=(Jwgpos *) + malloc(sizeof(Jwgpos)*ret->current_line_size); +ret->current_line.npts=0; + + +ret->file=fopen(name,"w"); + +if (!ret->file) { + printf("JWG: couldn't open file %s: %s",name,strerror(errno)); + free(name); + return(-1); +} +free(name); + + +switch(ret->format) { +case 0: + xfig_init_private(ret); + break; +case 1: + cgm_init_private(ret); + break; +default: + printf("JWG: Unknown format %d\n",ret->format); + return(-1); +} + + + + +Obj_Insert(handle_list,ret,ObjInsertTail); + +return(ret->serial); +} + + +void jwg_pass_data(int *serial,float *ptr,int *w,int *h,int *l) +{ +Handle ha=handle_from_serial(*serial); +int size; +Data data; +float *dptr; + +if (ha->data) { + printf("JWG: Attempt to pass data when data allready present\n"); + printf("JWG: you must first deallocate data resources\n"); + return; +} + +data=CREATE_OBJ(Data); +ha->data=data; + +data->w=(*w)+2; +data->h=(*h)+2; + +size=sizeof(float)*(data->w)*(data->h); + +dptr=data->data=(float *) malloc(size); +bzero(dptr,size); + +printf("JWG: Allocated %d bytes for data at %08x\n",size,(unsigned int) data->data); + + + + +size=(*w)*sizeof(float); + +{ +int mh=(*h); + +dptr+=data->w; + +while (mh--) { +bcopy(ptr,dptr+1,size); + +ptr+=(*l); +dptr+=data->w; +} + +} + +} + + +void jwg_destroy_data(int *serial) +{ +Handle h=handle_from_serial(*serial); +if (h->data) Obj_Delete(h->data); +h->data=(Data) NULL; +} + + + + +void jwg_set_xform(int *serial,float *xc,float *yc,float *a, + float *b, + float *c, + float *d) +{ +Handle h=handle_from_serial(*serial); +h->transform.xc=*xc; +h->transform.yc=*yc; +h->transform.a=*a; +h->transform.b=*b; +h->transform.c=*c; +h->transform.d=*d; +jwg_recalc_det(h); +} + +void jwg_add_xform(int *serial,float *xc,float *yc,float *a, + float *b, + float *c, + float *d) +{ +Handle h=handle_from_serial(*serial); +Transform t; +t=h->transform; + +h->transform.xc=(t.a*(*xc))+(t.b*(*yc))+t.xc; +h->transform.yc=(t.c*(*xc))+(t.d*(*yc))+t.yc; + +h->transform.a=(t.a*(*a))+(t.b*(*c)); +h->transform.b=(t.a*(*b))+(t.b*(*d)); +h->transform.c=(t.c*(*a))+(t.d*(*c)); +h->transform.d=(t.c*(*b))+(t.d*(*d)); + + +jwg_recalc_det(h); +} + +void jwg_add_rotation(int *serial,float *th) +{ +Handle h=handle_from_serial(*serial); +Transform t; +extern double sin(double); + +float a=cos(*th); +float b=-sin(*th); +float c=sin(*th); +float d=sin(*th); + +t=h->transform; + +h->transform.xc=t.xc; +h->transform.yc=t.yc; + + +h->transform.a=(t.a*(a))+(t.b*(c)); +h->transform.b=(t.a*(b))+(t.b*(d)); +h->transform.c=(t.c*(a))+(t.d*(c)); +h->transform.d=(t.c*(b))+(t.d*(d)); + + +jwg_recalc_det(h); + +} + + +void jwg_def_xform(int *serial) +{ +Handle h=handle_from_serial(*serial); +init_transform(h); +jwg_recalc_det(h); +} + +void jwg_set_brush(int *serial, float *r,float *g,float *b,float *density) +{ +Handle h=handle_from_serial(*serial); +h->brush.density=*density; +h->brush.color.r=*r; +h->brush.color.g=*g; +h->brush.color.b=*b; +} + +void jwg_set_pen(int *serial, float *r,float *g,float *b,float *width) +{ +Handle h=handle_from_serial(*serial); +extern double sqrt(double); +extern double fabs(double); + +h->pen.width=(*width)*sqrt(fabs(h->transform.det)); +h->pen.color.r=*r; +h->pen.color.g=*g; +h->pen.color.b=*b; +} + +void jwg_set_textcolor(int *serial, float *r,float *g,float *b) +{ +Handle h=handle_from_serial(*serial); +h->ink.color.r=*r; +h->ink.color.g=*g; +h->ink.color.b=*b; +} + +void jwg_set_textheight(int *serial, float *height) +{ +Handle h=handle_from_serial(*serial); +extern double hypot(double,double); +float moo; + +moo=hypot(h->transform.b,h->transform.d); + +h->ink.height=*height*moo; +printf("JWG: height is now %f specified %f\n",(float) h->ink.height,*height); +} + +void jwg_contour(int *serial, float *level,int *side,int *lp) +{ +extern void do_contour(Handle,float,int,int); +Handle h=handle_from_serial(*serial); + +printf("JWG: called jwg_contour(%d,%f,%d,%d)\n",*serial,*level,*side,*lp); + +do_contour( h, *level, *side, *lp); + +} + + +void jwg_draw_line(int *serial,float *x,float *y,int *n) +{ +Handle h=handle_from_serial(*serial); +int m=*n; +Jwgline line; +Jwgpos *ptr; + +ptr=line.data=(Jwgpos *) malloc(sizeof(Jwgpos)*(*n)); +line.npts=*n; + +while (m--) { + ptr->x=*(x++); + ptr->y=*(y++); + jwg_xform(h,ptr++); +} + +jwg_write_line(h,&line); + +} + +void jwg_draw_polygon(int *serial,float *x, float *y,int *n) +{ +Handle h=handle_from_serial(*serial); +int m=*n; +Jwgline line; +Jwgpos *ptr; + +ptr=line.data=(Jwgpos *) malloc(sizeof(Jwgpos)*(*n)); +line.npts=*n; + +while (m--) { + ptr->x=*(x++); + ptr->y=*(y++); + jwg_xform(h,ptr++); +} + +jwg_write_polygon(h,&line); + +} + +void jwg_reset_point(int *serial) +{ +Handle h=handle_from_serial(*serial); + +h->current_line.npts=0; +} + +void jwg_add_point(int *serial,float *x,float *y) +{ +Handle h=handle_from_serial(*serial); +Jwgpos *ptr; +int n; + +if (h->current_line.npts==h->current_line_size) { +/* uh-oh we're about to over flow */ + +ptr=h->current_line.data; + + +n=h->current_line_size; +printf("JWG: Increasing maximum line size from %d to %d\n", + n,n*2); + +h->current_line_size=n*2; + +h->current_line.data=malloc(sizeof(Jwgpos)*n*2); +bcopy(ptr,h->current_line.data,sizeof(Jwgpos)*n); + +free(ptr); + +} + + + +h->current_line.data[h->current_line.npts].x=*x; +h->current_line.data[h->current_line.npts].y=*y; +h->current_line.npts++; + +} + +void jwg_close_polygon(int *serial) +{ +Handle h=handle_from_serial(*serial); +Jwgline line; +Jwgpos *ptr; +int m; + +line=h->current_line; + +if (!line.npts) return; + +ptr=line.data; + +m=line.npts; + +while (m--) { + jwg_xform(h,ptr++); +} + +jwg_write_polygon(h,&line); + +h->current_line.npts=0; + +} + +void jwg_close_line(int *serial) +{ +Handle h=handle_from_serial(*serial); +Jwgline line; +Jwgpos *ptr; +int m; + +line=h->current_line; + +if (!line.npts) return; + +ptr=line.data; + +m=line.npts; + +while (m--) { + jwg_xform(h,ptr++); +} + +jwg_write_line(h,&line); + +h->current_line.npts=0; + +} + + + + +void jwg_destroy_handle(int *serial) +{ +Handle h=handle_from_serial(*serial); +Obj_Delete(h); +} + + +void jwg_push_state(int *serial) +{ +Handle h=handle_from_serial(*serial); +Handle s; + + + +s=(Handle) malloc(sizeof(struct Handle_struct)); + +bcopy(h,s,sizeof(struct Handle_struct)); + +h->stack=s; + +/* We also need to have a new current line */ + +h->current_line.npts=0; +h->current_line_size=JWG_DEFAULT_LINE_SIZE; + +h->current_line.data=(Jwgpos *) + malloc(sizeof(Jwgpos)*h->current_line_size); + +} + +void jwg_pop_state(int *serial) +{ +Handle h=handle_from_serial(*serial); +Handle n,p,s; + +if (!h->stack) { + printf("JWG: attempt to pop from empty stack\n"); + printf("JWG: carrying on (probably shouldn't) \n"); + return; +} + + +if (h->current_line.npts) + printf("JWG: warning poping state with non emtpy current line\n"); + + +free(h->current_line.data); + +n=h->next; +p=h->prev; + +s=h->stack; + +bcopy(s,h,sizeof(struct Handle_struct)); + +h->next=n; +h->prev=p; + +free(s); + + +} + + + +void jwg_draw_text(int *serial,float *x,float *y,char *str,int len) +{ +Handle h=handle_from_serial(*serial); +char *s,*ptr; +Jwgpos pos; + +pos.x=*x; +pos.y=*y; + +jwg_xform(h,&pos); + + +s=jwg_fiddle_text(str,len); + +switch(h->format) { +case 0: + xfig_do_text(h,pos,s); + break; +case 1: + cgm_do_text(h,pos,s); + break; +default: + printf("JWG: Text not yet implemented on this device\n"); + break; +} + + +} + + +void jwg_draw_text_matrix(int *serial,float *x,float *y,float *a,float *b,float *c,float *d,char *str,int len) +{ +Handle h=handle_from_serial(*serial); +char *s,*ptr; +Jwgpos pos; +Transform t; + +pos.x=*x; +pos.y=*y; + +jwg_xform(h,&pos); + + +t=h->transform; + +h->transform.a=(t.a*(*a))+(t.b*(*c)); +h->transform.b=(t.a*(*b))+(t.b*(*d)); +h->transform.c=(t.c*(*a))+(t.d*(*c)); +h->transform.d=(t.c*(*b))+(t.d*(*d)); + + +s=jwg_fiddle_text(str,len); + +switch(h->format) { +case 0: + xfig_do_text(h,pos,s); + break; +case 1: + cgm_do_text(h,pos,s); + break; +default: + printf("JWG: Text not yet implemented on this device\n"); + break; +} + +h->transform=t; + +} -- cgit v1.2.3