15 #define BUFFER_SIZE (32*1024*1024)
17 static char data
[BUFFER_SIZE
];
21 /*********************************++
23 * Read input data into a buffer
26 static void read_file(int fd
){
29 while ((res
=read(fd
,data
+data_size
,BUFFER_SIZE
-1-data_size
))) data_size
+=res
;
31 DBG("Read %i bytes.\n",data_left
);
34 static int comp(char ** pptr
, char * b
){
36 if (strncmp(ptr
,b
,strlen(b
))==0){
43 static struct point
* get_point(char ** pptr
){
45 struct point
*result
= (struct point
*)malloc(sizeof(struct point
));
47 result
->x
=strtold(*pptr
,&ptr2
);
48 if (ptr2
==*pptr
) result
->valid
=0;
51 *pptr
=index(*pptr
,',')+1;
52 result
->y
=strtold(*pptr
,&ptr2
);
53 if (ptr2
==*pptr
) result
->valid
=0;
57 result
->previous_in_path
=NULL
;
60 (*pptr
)++; /* Step over comma between point specs! */
64 static void output (struct path
* first_path
){
65 struct point
* last_point
=NULL
;
66 struct path
* current_path
;
68 for (current_path
=first_path
; current_path
!= NULL
;
69 current_path
=current_path
->next
){
71 struct point
* current_point
;
73 /* Initial move to start of plot */
74 current_point
=current_path
->plot_start_point
;
75 if (!equal(current_point
,last_point
)) {
76 printf("PU, %.2f,%.2f\n",current_point
->x
,current_point
->y
);
79 if (current_path
->plot_start_point
80 == current_path
->first_point
){ /* Forward */
82 for (current_point
=current_point
->next
; current_point
!= NULL
;
83 current_point
=current_point
->next
) {
84 if (!equal(current_point
,last_point
)) {
85 printf("PD, %.2f,%.2f\n",current_point
->x
,current_point
->y
);
87 last_point
=current_point
;
89 } else { /* Going backwards */
90 for (current_point
=current_point
->previous_in_path
; current_point
!= NULL
;
91 current_point
=current_point
->previous_in_path
) {
92 if (!equal(current_point
,last_point
)) {
93 printf("PD, %.2f,%.2f\n",current_point
->x
,current_point
->y
);
95 last_point
=current_point
;
101 /*******************************************************************************
105 *******************************************************************************
107 int main(int argc
, char ** args
){
109 int fd
=0; /* File descriptor for data input, defaults to standard input */
111 char * ptr
=data
; /* Input buffer */
112 enum plot_mode_t plot_mode
=absolute
; /* Coordinate modus */
113 enum pen_state_t pen_state
=up
;
115 struct point pen_pos
={0,0,1};
117 struct path
* first_path
=NULL
;
118 struct path
* current_path
=NULL
;
122 enum hpgl_cmd_t command
; /* Current command being processed */
126 /* Open input file to read if specified. */
128 fd
=open(args
[1],O_RDONLY
);
130 ERR("Could not open file: \"%s\"\n",args
[1]);
134 /* fd=open("haus.hpl",O_RDONLY); */
141 while(data_left
-3 && isspace(ptr
[0])) ptr
++;
143 /* Determine command */
145 if (comp(&ptr
, "SC")) command
=CMD_SC
;
146 if (comp(&ptr
, "PU")) command
=CMD_PU
;
147 if (comp(&ptr
, "PD")) command
=CMD_PD
;
148 if (comp(&ptr
, "LB")) command
=CMD_LB
;
149 if (comp(&ptr
, "DI")) command
=CMD_DI
;
150 if (comp(&ptr
, "SP")) command
=CMD_SP
;
151 if (comp(&ptr
, "PA")) command
=CMD_PA
;
152 if (comp(&ptr
, "PR")) command
=CMD_PR
;
153 if (comp(&ptr
, "IN")) command
=CMD_IN
;
154 if (command
==0) {data_left
-- ; ptr
++;}
155 else DBG("Command: %i %c%c\n",command
,ptr
[-2],ptr
[-1]);
157 int process_points
=0;
162 case CMD_PU
: /* Pen up - not much to do here. */
170 if (!in_path
){ /* Create and store a new path object with first point @pen_pos. */
172 struct point
* new_point
=(struct point
*)malloc(sizeof(struct point
));
173 new_point
->x
=pen_pos
.x
;
174 new_point
->y
=pen_pos
.y
;
175 new_point
->next
=NULL
;
176 new_point
->previous_in_path
=NULL
;
179 struct path
* new_path
=(struct path
*)malloc(sizeof(struct path
));
180 new_path
->next
=NULL
; /* This is the last in the chain. */
181 new_path
->first_point
=new_point
;
182 new_path
->last_point
=new_point
;
183 new_path
->plot_start_point
=new_path
->first_point
;
185 if (first_path
==NULL
){ /* This is the first path */
188 current_path
->next
=new_path
; /* Append to linked list */
190 current_path
=new_path
; /* Update pointer to current path. */
191 in_path
=1; /* We're in a path now, fine! */
209 case CMD_DI
: /* Character direction */
211 case CMD_SI
: /* Character size */
213 case CMD_SP
: /* Select pen */
225 if (process_points
) { /* Process point arguments */
226 struct point
* new_point
;
228 new_point
=get_point(&ptr
);
230 if (new_point
->valid
) { /* The following only works if we got a good point! */
232 /* Scale: Plot in cm!! */
233 new_point
->x
= new_point
->x
/ 500;
234 new_point
->y
= new_point
->y
/ 500;
236 DBG("Found point: %6.2f,%6.2f\n",new_point
->x
,new_point
->y
);
238 /* Convert relative coordinates to absolute coordinates if needed */
239 if (plot_mode
==relative
){
240 DBG("Relative -> absolute coordinate calculation!\n");
241 new_point
->x
+= pen_pos
.x
;
242 new_point
->y
+= pen_pos
.y
;
245 if (pen_state
==down
) { /* We're in a path, so add the point to current path */
246 current_path
->last_point
->next
=new_point
; /* Add to the end of list */
247 new_point
->previous_in_path
=current_path
->last_point
; /* Backwards reference */
248 current_path
->last_point
=new_point
; /* Fix the point */
250 pen_pos
.x
=new_point
->x
;
251 pen_pos
.y
=new_point
->y
;
254 } while (new_point
->valid
);
257 } /* while(data_left) */
259 struct path
* output_paths
;
261 round_path(first_path
);
263 /* output_paths = optimize(first_path); */
264 output_paths
=optimize(split_paths(first_path
));
265 output(output_paths
);
266 DBG("Programmende\n");