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/Makefile.am | 8 +- src/cgm.c | 231 ++++++++++++++++ src/contour.c | 383 ++++++++++++++++++++++++++ src/ctext.c | 18 ++ src/fish.h | 102 +++++++ src/fortran.h | 24 ++ src/ftext.c | 0 src/ftext.f | 29 ++ src/libjwg.c | 815 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- src/project.h | 77 +----- src/xfig.c | 253 ++++++++++++++++++ 11 files changed, 1851 insertions(+), 89 deletions(-) create mode 100644 src/cgm.c create mode 100644 src/contour.c create mode 100644 src/ctext.c create mode 100644 src/fish.h create mode 100644 src/fortran.h create mode 100644 src/ftext.c create mode 100644 src/ftext.f create mode 100644 src/xfig.c (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index fb8a416..17c94d8 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -8,6 +8,9 @@ # $Id$ # # $Log$ +# Revision 1.2 2009/02/08 16:48:21 root +# *** empty log message *** +# # Revision 1.1 2009/02/08 16:25:32 root # *** empty log message *** # @@ -17,10 +20,11 @@ INCLUDES = -SRCS= libjwg.c version.c +SRCS= libjwg.c version.c cgm.c contour.c ctext.c ftext.c version.c xfig.c +FSRCS=ftext.f CPROTO=cproto -JWGSRCS=${SRCS} +JWGSRCS=${SRCS} ${FSRCS} noinst_HEADERS= project.h prototypes.h jwg-tail.h ext_prototypes.h diff --git a/src/cgm.c b/src/cgm.c new file mode 100644 index 0000000..18bd762 --- /dev/null +++ b/src/cgm.c @@ -0,0 +1,231 @@ +#include "project.h" +#include "cd/cd.h" +BEGIN_OBJECT(CGMc) + int r,g,b,n; +END_OBJECT(CGMc) + +CREATOR(CGMc)=Obj_DefaultCreator; +DESTRUCTOR(CGMc)=Obj_DefaultDestructor; + +BEGIN_OBJECT(Private) + CGMc_list cgmcs; + int maxcol; + cdImagePtr im; + FILE *file; +END_OBJECT(Private) + + +int cgm_sortout_color(Private p,int r,int g,int b) +{ +CGMc c; + +c=p->cgmcs->head; + +while (c) +{ +if ((c->r==r) && (c->g==g) && (c->b==b)) return(c->n); +c=c->next; +} + + +c=CREATE_OBJ(CGMc); +c->r=r; +c->g=g; +c->b=b; +c->n=cdImageColorAllocate(p->im,r,g,b); + +Obj_Insert(p->cgmcs,c,ObjInsertHead); + + +return(c->n); +} + +static void private_constructor(Private p) +{ +char name[1024]; + +p->cgmcs=CREATE_LIST(CGMc); +/* We need a square image otherwise nasty things happen to +lines!*/ +p->im=cdImageCreate(7100,7100); +} + +static void private_destructor(Private p) +{ +CGMc c; +int i; + +printf("JWG: Writing cgm file \n"); + +Obj_Delete(p->cgmcs); + +cdImageCgm(p->im,p->file); +cdImageDestroy(p->im); + +free(p); +} + + +CREATOR(Private)=private_constructor; +DESTRUCTOR(Private)=private_destructor; + + +void cgm_init_private(Handle h) +{ +Private p; + +p=CREATE_OBJ(Private); +p->file=h->file; + +h->private=(void *) p; + +} + + + +void cgm_do_line(Handle h,Jwgline *line) +{ +Private p=(Private) h->private; +int i,c; +int r,g,b; +int n=line->npts; +int w; +cdPointPtr ptr,base; + +r=(int) (h->pen.color.r*255.0); +g=(int) (h->pen.color.g*255.0); +b=(int) (h->pen.color.b*255.0); +c=cgm_sortout_color(p,r,g,b); + + +if (h->pen.width==0.0) { + w=1; +} else { + w=(int) (h->pen.width/7.10); + if (w<1) w=1; +} + +cdSetLineWidth(p->im,w); +cdSetLineType(p->im,1); +cdSetLineColor(p->im,c); + +ptr=base=(cdPointPtr) malloc(sizeof(struct cdPointStruct) * n); + +for (i=0;ix=(int) line->data[i].x; +ptr->y=(int) line->data[i].y; +ptr++; +} + +cdPolyLine(p->im,base,n); + +free(base); + + +} + +void cgm_init_xform(Handle h) +{ +/* this should map 1000,1414.21 to an A4 page */ + +h->transform.xc=0.0; +h->transform.yc=0.0; +h->transform.a=5.0; +h->transform.d=5.0; + +h->transform.b=0.0; +h->transform.c=0.0; + + +} + +void cgm_do_poly(Handle h,Jwgline *line) +{ +int i,c; +int r,g,b; +int n=line->npts; +Private p=(Private) h->private; +cdPointPtr ptr,base; + +r=(int) (h->brush.color.r*255.0); +g=(int) (h->brush.color.g*255.0); +b=(int) (h->brush.color.b*255.0); +c=cgm_sortout_color(p,r,g,b); + +cdSetFillStyle(p->im,1); +cdSetFillColor(p->im,c); +cdSetEdgeVis(p->im,0); + +ptr=base=(cdPointPtr) malloc(sizeof(struct cdPointStruct) * n); + +for (i=0;ix=(int) line->data[i].x; +ptr->y=(int) line->data[i].y; +ptr++; +} + +cdPolygon(p->im,base,n); + +free(base); + +} + + +void cgm_do_text(Handle h,Jwgpos pos,char *str) +{ +int color,r,g,b; +Transform t=h->transform; +Private p=(Private) h->private; +float s; +int height; + +height=(int) h->ink.height; + +r=(int) (h->ink.color.r*255.0); +g=(int) (h->ink.color.g*255.0); +b=(int) (h->ink.color.b*255.0); +color=cgm_sortout_color(p,r,g,b); + +if (t.det<0) { + printf("JWG: Text cannot be written backwards in a CGM file\n"); + return; +} + +{ +float a,b,c,d; + +a=fabs(t.a); +b=fabs(t.b); +c=fabs(t.c); +d=fabs(t.d); + +s=(a>b) ? a: ((b>c) ? b: ((c>d) ? c: d)); + +s=16384.0/s; + + +} + +{ +int a,b,c,d; + +a=(int) (s*t.a); +b=(int) (s*t.b); +c=(int) (s*t.c); +d=(int) (s*t.d); + +printf("JWG: Text vectors are up=(%d,%d) right=(%d,%d)\n",c,d,a,b); +cdSetTextOrient(p->im, c, d, a, b); +} + +cdSetTextHeight(p->im,height); + +cdSetTextFont(p->im,5); +cdSetTextColor(p->im,color); + +cdText(p->im,(int) pos.x,(int) pos.y,str); + +return; +} diff --git a/src/contour.c b/src/contour.c new file mode 100644 index 0000000..8022adb --- /dev/null +++ b/src/contour.c @@ -0,0 +1,383 @@ +#include "project.h" + +#ifndef PI +#define PI 3.141592654 +#endif + + +typedef struct { + int x, y; +} Point; + +typedef struct contour_struct { + float *data; + float **dcol; + unsigned char *flags; + unsigned char **fcol; + int x, y; + int x1, y1; + Jwgline current_line; + int current_line_size; + int lp; + Handle h; +} *Contour; + + +#define INRANGE(l1,l2,c) ( ((c)<(l2)) && ((c)>=(l1)) ) +#define RANGEX(c,x) ( ((x)>0) ? ( ((x)<((c)->x1)) ? (x):((c)->x1)) : 1) +#define RANGEY(c,y) (((y)>0) ? ( ((y)<((c)->y1)) ? (y):((c)->y1)) : 1) + +#define FLAGS(c,p) ((c->fcol[p.y])[p.x]) +#define DATA(c,p) ((c->dcol[p.y])[p.x]) + +#define DEF_LINE_SIZE 8192 + + + + + +void +cont_reset_point(Contour c) +{ + c->current_line.npts = 0; +} + +void +cont_add_point(Contour c, Jwgpos pos) +{ + Jwgpos *ptr; + int n; + + if (c->current_line.npts == c->current_line_size) { + /* uh-oh we're about to over flow */ + + ptr = c->current_line.data; + + + n = c->current_line_size; + printf("JWG: CONTOUR: Increasing maximum line size from %d to %d\n", + n, n * 2); + + c->current_line_size = n * 2; + + c->current_line.data = malloc(sizeof(Jwgpos) * n * 2); + bcopy(ptr, c->current_line.data, sizeof(Jwgpos) * n); + + free(ptr); + + } + jwg_xform(c->h, &pos); + + c->current_line.data[c->current_line.npts] = pos; + c->current_line.npts++; + +} + +unsigned char +find_direction(Point p1, Point p2) +{ + p2.x -= p1.x; + p2.y -= p1.y; + + switch (p2.y) { + case -1: + switch (p2.x) { + case -1: + return (1); + case 0: + return (2); + case 1: + return (4); + } + case 0: + switch (p2.x) { + case -1: + return (128); + case 1: + return (8); + } + case 1: + switch (p2.x) { + case -1: + return (64); + case 0: + return (32); + case 1: + return (16); + } + } + + + fprintf(stderr, "Contouring cockup type 3 ... (bye bye)\n"); + abort(); + +} + +Point +add_direction(Point p, int d) +{ + Point dirs[8] = {{-1, -1}, {0, -1}, {1, -1}, {1, 0}, {1, 1}, {0, 1}, {-1, 1}, {-1, 0}}; + + p.x = dirs[d].x; + p.y = dirs[d].y; + + return (p); +} + + +int +points_marked(Contour c, Point p1, Point p2) +{ + return (c->fcol[p1.y])[p1.x] & find_direction(p1, p2); +} + +void +mark_points(Contour c, Point p1, Point p2) +{ + (c->fcol[p1.y])[p1.x] |= find_direction(p1, p2); + (c->fcol[p2.y])[p2.x] |= find_direction(p2, p1); +} + + + +trace(Contour c, Point p1, Point p2, Point pl, float level) +{ + Point pn; + float v1, v2, vn; + Jwgpos pos; + float r; + +printf("."); +fflush(stdout); + + if (!c->lp) + { + pos.x = 1; + pos.y = 1; + + cont_add_point(c, pos); + } + + v1 = DATA(c, p1); + v2 = DATA(c, p2); + + while (1) { + + /* + * printf("(%d,%d,%f) (%d,%d,%f) (%d,%d,%f)\n", p1.x, p1.y, DATA(c, p1), + * p2.x, p2.y, DATA(c, p2), pl.x, pl.y, DATA(c, pl)); + */ + + r = (v2 - v1); + if (r == 0.0) { + r = 0.5; + } else { + r = (level - v1) / r; + } + + pos.x = r * (float) RANGEX(c, p2.x); + pos.y = r * (float) RANGEY(c, p2.y); + + r = 1.0 - r; + + pos.x += r * (float) RANGEX(c, p1.x); + pos.y += r * (float) RANGEY(c, p1.y); + + cont_add_point(c, pos); + + + + + + + + if (DATA(c, p1) > level) { + printf("Contouring cockup type 1 -- bye bye\n"); + abort(); + } + if (DATA(c, p2) <= level) { + printf("Contouring cockup type 2 -- bye bye\n"); + abort(); + } + if (points_marked(c, p1, p2)) { + if (c->lp) { + jwg_write_line(c->h, &c->current_line); + c->current_line.npts = 0; + } else { + pos.x = 1; + pos.y = 1; + + cont_add_point(c, pos); + } + + + return; + } + mark_points(c, p1, p2); + + pn.x = p1.x + p2.x - pl.x; + pn.y = p1.y + p2.y - pl.y; + + vn = DATA(c, pn); + + if (vn <= level) { + pl = p1; + p1 = pn; + v1 = vn; + } else { + pl = p2; + p2 = pn; + v2 = vn; + } + + + + + } + +} + + + + + +possible(Contour c, int x1, int y1, int x2, int y2, int xl, int yl, float level) +{ + Point p1, p2, pl; + + p1.x = x1; + p1.y = y1; + p2.x = x2; + p2.y = y2; + pl.x = xl; + pl.y = yl; + + if (points_marked(c, p1, p2)) + return; + + trace(c, p1, p2, pl, level); + + +} + + +contour(Contour c, float level) +{ + int x, y; + float **c0, **c1; + float *r00, *r10, *r11, *r01; + + c1 = c0 = c->dcol; + c1--; + + for (y = 0; y < c->y; ++y) { + r00 = r01 = *(c0); + r01--; + if (y) { + r10 = r11 = *(c1); + r11--; + } + for (x = 0; x < c->x; ++x) { + + if (x) { + if (INRANGE(*r00, *r01, level)) + possible(c, x, y, x - 1, y, x, y - 1, level); + if (INRANGE(*r01, *r00, level)) + possible(c, x - 1, y, x, y, x - 1, y + 1, level); + } + if (y) { + if (INRANGE(*r00, *r10, level)) + possible(c, x, y - 1, x, y, x - 1, y, level); + if (INRANGE(*r10, *r00, level)) + possible(c, x, y, x, y - 1, x + 1, y - 1, level); + } + r00++; + r10++; + r11++; + r01++; + } + c0++; + c1++; + } + +} + + + +void +do_contour(Handle h, float level, int side, int lp) +{ + Contour c = (Contour) malloc(sizeof(struct contour_struct)); + int i; + float hug = 1.0e10 * (float) side; + + + c->data = h->data->data; + c->x1 = c->x = h->data->w; + c->y1 = c->y = h->data->h; + + + c->dcol = (float **) malloc(sizeof(float *) * c->y); + + + + c->dcol[0] = c->data; + for (i = 1; i < c->y; ++i) + c->dcol[i] = c->dcol[i - 1] + c->x; + + c->flags = (unsigned char *) malloc(c->x * c->y); + bzero(c->flags, c->x * c->y); + + c->fcol = (unsigned char **) malloc(c->y * sizeof(unsigned char *)); + + c->fcol[0] = c->flags; + for (i = 1; i < c->y; ++i) + c->fcol[i] = c->fcol[i - 1] + c->x; + + c->x1--; + c->y1--; + + for (i = 0; i < c->y; ++i) { + (c->dcol[i])[0] = hug; + (c->dcol[i])[c->x1] = hug; + } + for (i = 0; i < c->x; ++i) { + (c->dcol[0])[i] = hug; + (c->dcol[c->y1])[i] = hug; + } + + c->x1--; + c->y1--; + + /* + * { Point p; + * + * for (p.y=0;p.yy;++p.y) { for (p.x=0;p.xx;++p.x) { + * + * printf("%.1f ",DATA(c,p)); + * + * } printf("\n"); + * + * } + * } */ + + c->current_line.npts = 0; + c->current_line_size = DEF_LINE_SIZE; + c->current_line.data = (Jwgpos *) malloc(sizeof(Jwgpos) * DEF_LINE_SIZE); + + c->h = h; + c->lp = lp; + + contour(c, level); + printf("\n"); + + + if (!c->lp) + jwg_write_polygon(c->h, &c->current_line); + + free(c->flags); + free(c->fcol); + free(c->dcol); + free(c->current_line.data); + +} diff --git a/src/ctext.c b/src/ctext.c new file mode 100644 index 0000000..4f82832 --- /dev/null +++ b/src/ctext.c @@ -0,0 +1,18 @@ +#include "project.h" + +Textrequest_list textrequests; + +void jwg_priv_init_textlist() +{ + + + + + + + + + +} + + diff --git a/src/fish.h b/src/fish.h new file mode 100644 index 0000000..1a7a874 --- /dev/null +++ b/src/fish.h @@ -0,0 +1,102 @@ +#include + +typedef struct { + float x,y; +} Jwgpos; + +typedef struct { + Jwgpos *data; + int npts; +} Jwgline; + + + +typedef struct { + float xc,yc; + float a,b,c,d; + float det; +} Transform; + +BEGIN_OBJECT(Data) + int w,h; + int l; + float *data; +END_OBJECT(Data); + +extern void Data_Destructor(Data); + +CREATOR(Data)=Obj_DefaultCreator; +DESTRUCTOR(Data)=Data_Destructor; + +typedef struct { + float r,g,b; +} Color; + +typedef struct { + float width; + Color color; +} Pen; + +typedef struct { + float density; + Color color; +} Brush; + +typedef struct { + int font; + Color color; + float height; +} Ink; + + +#define JWG_FM_XFIG 0 +#define JWG_FM_CGM 1 + +#define JWG_DEFAULT_LINE_SIZE 4096 + +BEGIN_OBJECT(Handle) + int serial; + + struct Handle_struct *stack; + + Data data; + Transform transform; + + Brush brush; + Pen pen; + Ink ink; + + int format; + FILE *file; + + Jwgline current_line; + int current_line_size; + + void *private; +END_OBJECT(Handle) + +extern void Handle_Destructor(Handle); + +CREATOR(Handle)=Obj_DefaultCreator; +DESTRUCTOR(Handle)=Handle_Destructor; + +extern void jwg_xform(Handle,Jwgpos *); +extern void jwg_write_line(Handle,Jwgline *); +extern void jwg_write_polygon(Handle,Jwgline *); + +extern float jwg_decompose_matrix(Transform,int); + + +extern int jwg_create_handle(int *,char *,int); +extern void jwg_pass_data(int *,float *,int *,int *,int *); +extern void jwg_destory_data(int *); +extern void jwg_set_xform(int *,float *,float *,float *,float *, float *, float *); +extern void jwg_set_brush(int *, float *,float *,float *,float *); +extern void jwg_set_pen(int *, float *,float *,float *,float *); +extern void jwg_set_textcolor(int *,float *,float *,float *); +extern void jwg_set_textheight(int *,float *); +extern void jwg_draw_text(int *,float *,float *,char *,int); +extern void jwg_contour(int *, float *,int *,int *); +extern void jwg_draw_line(int *,float *,float *,int *); +extern void jwg_draw_polygon(int *,float *,float *,int *); +extern void jwg_destroy_handle(int *); diff --git a/src/fortran.h b/src/fortran.h new file mode 100644 index 0000000..22c2cd1 --- /dev/null +++ b/src/fortran.h @@ -0,0 +1,24 @@ +#define FORT(x) x ## __ + +#define jwg_create_handle FORT(jwg_create_handle) +#define jwg_pass_data FORT(jwg_pass_data) +#define jwg_destroy_data FORT(jwg_destroy_data) +#define jwg_set_xform FORT(jwg_set_xform) +#define jwg_set_brush FORT(jwg_set_brush) +#define jwg_set_pen FORT(jwg_set_pen) +#define jwg_contour FORT(jwg_contour) +#define jwg_draw_line FORT(jwg_draw_line) +#define jwg_draw_polygon FORT(jwg_draw_polygon) +#define jwg_destroy_handle FORT(jwg_destroy_handle) +#define jwg_pop_state FORT(jwg_pop_state) +#define jwg_push_state FORT(jwg_push_state) +#define jwg_add_xform FORT(jwg_add_xform) +#define jwg_def_xform FORT(jwg_def_xform) +#define jwg_add_point FORT(jwg_add_point) +#define jwg_reset_point FORT(jwg_reset_point) +#define jwg_close_line FORT(jwg_close_line) +#define jwg_close_polygon FORT(jwg_close_polygon) +#define jwg_draw_text FORT(jwg_draw_text) +#define jwg_set_textcolor FORT(jwg_set_textcolor) +#define jwg_set_textheight FORT(jwg_set_textheight) +#define jwg_draw_text_matrix FORT(jwg_draw_text_matrix) diff --git a/src/ftext.c b/src/ftext.c new file mode 100644 index 0000000..e69de29 diff --git a/src/ftext.f b/src/ftext.f new file mode 100644 index 0000000..f1de29d --- /dev/null +++ b/src/ftext.f @@ -0,0 +1,29 @@ + function jwg_open_textunit + + integer jwg_priv_init_textlist*4 + + parameter (default_textunit=32767) + + character textpipe*1024 + integer textunit*4,setup*4 + + + setup=jwg_priv_init_textlist + +C Is all this gubbins working or do we need to fiddle? + + if (setup.ne.0) then +C +C this will check that the string is correctly passed +C + textpipe='sanity check' + + call jwg_priv_setup_textpipe(textpipe) + + textunit=default_textunit + open (file=textpipe,unit=textunit,action='write',status=old) + + endif + + jwg_open_textunit=textunit + 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; + +} diff --git a/src/project.h b/src/project.h index 7e5289d..4179632 100644 --- a/src/project.h +++ b/src/project.h @@ -1,78 +1,17 @@ -/* - * project.h: - * - * Copyright (c) 2009 James McKenzie <20@madingley.org>, - * All rights reserved. - * - */ - -/* - * $Id$ - */ - -/* - * $Log$ - * Revision 1.1 2009/02/08 16:25:32 root - * *** empty log message *** - * - * - */ - -#ifndef __PROJECT_H__ -#define __PROJECT_H__ - -#include "config.h" - -#ifdef TM_IN_SYS_TIME -#include -#ifdef TIME_WITH_SYS_TIME -#include -#endif -#else -#ifdef TIME_WITH_SYS_TIME -#include -#endif -#include -#endif - #include -#include - -#ifdef HAVE_MALLOC_H +#include +#include #include -#endif - -#ifdef HAVE_STRING_H #include -#endif - -#ifdef HAVE_STRINGS_H #include -#endif -#ifdef HAVE_UNISTD_H -#include -#endif +#include -#if defined(HAVE_STDINT_H) -#include -#elif defined(HAVE_SYS_INT_TYPES_H) -#include -#endif -#ifdef INT_PROTOS -#define INTERNAL -#define EXTERNAL -#else -#ifdef EXT_PROTOS -#define INTERNAL static -#define EXTERNAL -#else -#define INTERNAL -#define EXTERNAL -#endif -#endif +#include "fortran.h" -#include "prototypes.h" +#include "jwg.h" -#endif /* __PROJECT_H__ */ +#define PI 3.141592653589793238462643383276 +#define R2D 57.295779513082320876798154814169 +#define D2R 0.017453292519943295769236907684 diff --git a/src/xfig.c b/src/xfig.c new file mode 100644 index 0000000..10da5e4 --- /dev/null +++ b/src/xfig.c @@ -0,0 +1,253 @@ +#include "project.h" + +BEGIN_OBJECT(Xfc) + int r,g,b,n; +END_OBJECT(Xfc) + +CREATOR(Xfc)=Obj_DefaultCreator; +DESTRUCTOR(Xfc)=Obj_DefaultDestructor; + +BEGIN_OBJECT(Private) + Xfc_list xfcs; + int maxcol; + FILE *tmpfile; + FILE *file; +END_OBJECT(Private) + +static void private_constructor(Private p) +{ +char name[1024]; + +p->xfcs=CREATE_LIST(Xfc); + +p->tmpfile=fopen(tmpnam(name),"w+"); + +unlink(name); + + + +} + +#define BUFSIZ 1024 + +static void private_destructor(Private p) +{ +Xfc c; +char buf[BUFSIZ]; +int i; + +fflush(p->tmpfile); +rewind(p->tmpfile); + + +printf("JWG: Writing xfig colors\n"); + +c=p->xfcs->head; + +while (c) { +fprintf(p->file,"0 %d #%02x%02x%02x\n",c->n,c->r,c->g,c->b); +c=c->next; +} + + +Obj_Delete(p->xfcs); + +printf("JWG: Writing xfig file\n"); + +while ((i=fread(buf,1,BUFSIZ,p->tmpfile))>0) { + + fwrite(buf,1,i,p->file); +} + +fclose(p->tmpfile); + +printf("JWG: xfig done\n"); + + + +free(p); +} + + +CREATOR(Private)=private_constructor; +DESTRUCTOR(Private)=private_destructor; + + + + +void xfig_init_private(Handle h) +{ +Private p; + +p=CREATE_OBJ(Private); +p->maxcol=32; +p->file=h->file; + +h->private=(void *) p; + + fprintf(h->file,"#FIG 3.1\n"); + fprintf(h->file,"Portrait\nFlush Left\nInches\n1200 2\n"); + +} + + +int xfig_sortout_color(Handle h,int r,int g,int b) +{ +Private p=(Private) h->private; +Xfc c; + +c=p->xfcs->head; + +while (c) +{ +if ((c->r==r) && (c->g==g) && (c->b==b)) return(c->n); +c=c->next; +} + +if (p->maxcol==512) { + printf("JWG: Xfig colors exhusted: this kludge needs fixing...\n"); + return(32); +} + +c=CREATE_OBJ(Xfc); +c->r=r; +c->g=g; +c->b=b; +c->n=(p->maxcol++); + +Obj_Insert(p->xfcs,c,ObjInsertHead); + + +return(c->n); +} + +void xfig_do_line(Handle h,Jwgline *line) +{ +Private p=(Private) h->private; +int i,c; +int r,g,b; +int w; +int x,y; +int n=line->npts; +extern double sqrt(double); +extern double fabs(double); + +r=(int) (h->pen.color.r*255.0); +g=(int) (h->pen.color.g*255.0); +b=(int) (h->pen.color.b*255.0); +c=xfig_sortout_color(h,r,g,b); + +if (h->pen.width==0.0) { + w=1; +} else { + w=(int) ((h->pen.width)/15.0); + if (w<1) w=1; +} + + + +fprintf(p->tmpfile,"2 1 0 %d %d 0 0 0 -1 0.0 1 1 -1 0 0 %d\n",w,c,n); + +for (i=0;idata[i].x; +y=(int) line->data[i].y; + +fprintf(p->tmpfile,"%d %d ",x,y); +} +fprintf(p->tmpfile,"\n"); + + +} + +void xfig_init_xform(Handle h) +{ + +h->transform.xc=0.0; +h->transform.yc=14422.8; +h->transform.a=10.2; +h->transform.d=-10.2; + +h->transform.b=0.0; +h->transform.c=0.0; + + +} + +xfig_do_poly(Handle h,Jwgline *line) +{ +int i,c; +int r,g,b; +int w; +int x,y; +int n=line->npts; +Private p=(Private) h->private; + +r=(int) (h->brush.color.r*255.0); +g=(int) (h->brush.color.g*255.0); +b=(int) (h->brush.color.b*255.0); +c=xfig_sortout_color(h,r,g,b); + + +printf("COL FOR POLY %d\n",c); + + +fprintf(p->tmpfile,"2 3 0 0 0 %d 0 0 20 0.0 1 1 -1 0 0 %d\n",c,n+1); + +for (i=0;idata[i].x; +y=(int) line->data[i].y; + +fprintf(p->tmpfile,"%d %d ",x,y); +} + +x=(int) line->data->x; +y=(int) line->data->y; + +fprintf(p->tmpfile,"%d %d",x,y); + +fprintf(p->tmpfile,"\n"); + +} + +void xfig_do_text(Handle h,Jwgpos pos,char *str) +{ +int c,r,g,b; +int x,y; +double atan2(double,double); + +Transform t=h->transform; +Private p=(Private) h->private; +int height; +float angle; + +x=(int) pos.x; +y=(int) pos.y; + +height=(int) (h->ink.height/16.66); + +r=(int) (h->ink.color.r*255.0); +g=(int) (h->ink.color.g*255.0); +b=(int) (h->ink.color.b*255.0); +c=xfig_sortout_color(h,r,g,b); + + +if (t.det>0) { + printf("JWG: Text cannot be written backwards in an xfig file\n"); + return; +} + + +angle=-atan2(t.b,t.a); + + +fprintf(p->tmpfile,"4 0 %d 0 0 %d %d %f 4 1 1 %d %d %s\\001\n",c,0, + height, angle,x,y,str); + + + + + +return; +} -- cgit v1.2.3