Code

Translations. French translation minor update.
[inkscape.git] / src / extension / dxf2svg / entities2elements.cpp
1 /*
2  * Code for converting dxf entities to SVG elements
3  * There are multiple ways for converting different items
4  * If possible most DXF enetities will be converted to paths because that is the most flexable object
5  *
6  * Author:
7  *   Matt Squires <squiresm@colorado.edu>
8  *
9  * Copyright (C) 2005 Matt Squires
10  *
11  * Released under GNU GPL and LGPL, read the file 'GPL.txt' and 'LGPL.txt' for details
12  */
16 /* 
18 Matt Squires
19 SoC 2005
21 */
23 #include "entities2elements.h"
24 #include "tables2svg_info.h"
25 #include <iostream>
26 #include <math.h>
27 #include <string.h>
28 #include <stdlib.h>
29 // The names indicate the DXF entitiy first and the SVG element last
31 // Common elements
32 char* to_arc(double bulge, double r, double start_ang, double end_ang, int precision,char* delim, char * units, double scaling, char *out){
33         // This is used for arcs, polylines, and lwpolylines
34         char temp[50];
35         
36         // Assume that we are adding to the input and not starting over
37         strcat(out," A ");
38         // For arcs there is only one radius
39         strcat(out,gcvt(scaling*r,precision,temp) );
40         strcat(out,",");
41         strcat(out,gcvt(scaling*r,precision,temp) );
42         
43         strcat(out," 0"); // For arc assume no x-axis rotation.  That seems to apply to elipse elements only
44         // Determine if it is a large arc
45         if ( (end_ang > start_ang) && ( (end_ang - start_ang) > 180) ){
46                 //strcat(out," 1,0 "); // Large arc flag...Always use a zero sweep flag
47                 strcat(out," 1, "); // Large arc flag...Always use a zero sweep flag
48         }
49         else{
50                 //strcat(out," 0,0 "); // Small arc flag...Always use a zero sweep flag
51                 strcat(out," 0,");
52         }
53         // This may be easier if I allow r to be plus and minus, but for now this works
54         if (bulge > 0){
55                 strcat(out,"0 ");
56         }
57         else{
58                 strcat(out,"1 ");
59         }
60 }
62 // Build Coordinate
63 void coord(entity *ent, int precision,char* delim, char * units, double scaling, char *out); // Pairs of coords with units will be used so often build a function
64 void coord(entity *ent, int precision,char* delim, char * units, double scaling, char *out){
65         // Pairs of coords with units will be used so often build a function build a dedicated function for returning such
66         
67         char temp[20];
68         if (units != NULL) scaling = 1;  // If units have been defined then ignore the scaling parameter
69         strcat(out, gcvt(scaling*ent->ret_x(),precision,temp) );  // There must be a better function for double to ascii conversion that is defined in most libraries
70         if (units != NULL) strcat(out, units);
71         strcat(out, delim);
72         strcat(out, gcvt(-scaling*ent->ret_y(),precision,temp) ); // Because SVG has a the Y-axis pointed down multiply by -1
73         if (units != NULL) strcat(out, units);
74         strcat(out, " ");
75 }
77 // DXF Polyline -> SVG
78 void pline2svg(polyline pline, int type, int precision, char * units, double scaling, tables plot_info, char *out); // General function for the conversion of a pline to a SVG element.  Very similar functions just make accomidations for parts that may not be supported
79 void pline2svg(polyline pline, int type, int precision, char * units, double scaling, tables plot_info, char *out){
80         // 0 is pline2path
81         // 1 is pline2pline
82         // 2 is pline2polygon
83         
84         
85         char delim[2];
86         double mag_bulge = 0;
87         double prev_mag_bulge = 0;
88         
89         std::vector< vertex >::iterator vver_iter;
90         std::vector< vertex > points = pline.ret_points();
91         
92         if (type < 1){
93                 // Put the first Move To at the first, everything else will be a lineto
94                 strcpy(delim," ");
95                 strcat(out, "M ");
96                 coord( &points[0], precision, delim, units, scaling, out ); 
97                 prev_mag_bulge = sqrt(pow(points[0].ret_bulge(),2));  // Because the bulge value can be positive or negative calculate the magnitude
98                 if ( prev_mag_bulge > pow(0.1,precision) ){
99                                 to_arc(pline.bulge(0), pline.bulge_r(0), pline.bulge_start_angle(0), pline.bulge_end_angle(0), precision, delim, units, scaling, out);
100                 }
101                 for (int i = 1; i < points.size(); i++){
102                         if ( prev_mag_bulge < pow(0.1,precision) ){
103                                 // If the previous point was a bulge then don't use a line to
104                                 strcat(out, "L ");
105                         }
106                         coord( &points[i], precision, delim, units, scaling, out ); 
107                         // If bulge > some precsion then add bulge
108                         mag_bulge = sqrt(pow(points[i].ret_bulge(),2));
109                         if ( (mag_bulge > pow(0.1,precision))  && (i < (points.size() - 1) )){
110                                 to_arc(pline.bulge(i), pline.bulge_r(i), pline.bulge_start_angle(i), pline.bulge_end_angle(i), precision, delim, units, scaling, out);
111                         }
112                         prev_mag_bulge = mag_bulge;
113                 }
114                 if ( pline.is_closed() ){
115                         strcat(out,"z");
116                 }
117                 strcat(out,"\" ");
118         }
119         else{
120                 strcpy(delim,",");              
121                 for (int i = 0; i < points.size(); i++){
122                         coord( &points[i], precision, delim, NULL, scaling, out ); 
123                         // If bulge > some precsion then add bulge      
124                 }
125                 // if the element is a SVG::pline and the DXF::pline is closed then simulate by adding an extra point
126                 if ( (type == 1) && pline.is_closed() ){
127                         coord( &points[0], precision, delim, NULL, scaling, out ); 
128                 }
129         }       
130                 
133 char* pline2path(polyline pline, char * units, double scaling, tables plot_info){
134         // Convert a dxf polyline to a SVG path.  This is the closest conversion of the DXF polyline to an SVG element
135         char *out_ptr;
136         char out[10000] = "<path d=\"";
137         entity *ent_ptr = &pline;
138         char temp[20];
139         int precision = 6;
140         
141         pline2svg(pline, 0, precision, units, scaling, plot_info, out);
142         // Add some line information
143         strcat(out,"fill=\"none\" stroke=\"black\" stroke-width=\"1\" ");
144         pattern2dasharray(plot_info.ret_ltype( ent_ptr->ret_ltype_name(temp),ent_ptr->ret_layer_name(temp) ), precision, scaling, out);  // Add the linetype information
145         
146         strcat(out," />");
147         out_ptr = out;
148         return out_ptr; 
151 char* pline2pline(polyline pline, char * units, double scaling, tables plot_info){
152         // Convert a dxf polyline to a SVG polyline.  The conversion is not 1:1 because the SVG pline doesn't support closed objects or curves
153         entity *ent_ptr = &pline;
154         char temp[2000];
155         int precision = 6;
156         
157         char out[10000] = "<polyline fill=\"none\" stroke=\"black\" stroke-width=\"1\" ";
158         ltype linfo = plot_info.ret_ltype(ent_ptr->ret_ltype_name(temp), ent_ptr->ret_layer_name(temp));
159         pattern2dasharray(linfo, precision, scaling, out);  // Add the linetype information
160         //strcpy(temp," ");
161         
162         strcat(out,"points=\"");
163         
164         //strcat(out,"<polyline fill=\"none\" stroke=\"black\" stroke-width=\"1\" points=\"");
165         pline2svg(pline, 1, precision, units, scaling, plot_info, out);
166         // Add some line information
167         // if the DXF pline is closed then add an extra point
168         
169         strcat(out,"\"/>");
170         char *out_ptr = out;
171         return out_ptr;
173 char* pline2polygon(polyline pline, char * units, double scaling, tables plot_info){
174         // Convert a dxf polyline to a SVG polygon.  The conversion is not 1:1 because the SVG polygone assumes a closed path.  If the pline is not closed it will be forced closed
175         //return pline2svg(pline, 2, 6, units, double scaling,out);     
179 // DXF LWPolyline -> SVG
182 // This could be a template with polyline and lwpolyline but right now it is not that important
183 void lwpline2svg(lwpolyline pline, int type, int precision, char * units, double scaling, tables plot_info, char *out); // General function for the conversion of a pline to a SVG element.  Very similar functions just make accomidations for parts that may not be supported
184 void lwpline2svg(lwpolyline pline, int type, int precision, char * units, double scaling, tables plot_info, char *out){
185         // 0 is pline2path
186         // 1 is pline2pline
187         // 2 is pline2polygon
188         
189         
190         char delim[2];
191         double mag_bulge = 0;
192         double prev_mag_bulge = 0;
193         
194         std::vector< vertex >::iterator vver_iter;
195         std::vector< vertex > points = pline.ret_points();
196         
197         if (type < 1){
198                 // Put the first Move To at the first, everything else will be a lineto
199                 strcpy(delim," ");
200                 strcat(out, "M ");
201                 coord( &points[0], precision, delim, NULL, scaling, out );
202                 prev_mag_bulge = sqrt(pow(points[0].ret_bulge(),2));  // Because the bulge value can be positive or negative calculate the magnitude
203                 if ( prev_mag_bulge > pow(0.1,precision) ){
204                                 to_arc(pline.bulge(0),pline.bulge_r(0), pline.bulge_start_angle(0), pline.bulge_end_angle(0), precision, delim, NULL, scaling, out);
205                 }
206                 
207                 for (int i = 1; i < points.size(); i++){
208                         if ( prev_mag_bulge < pow(0.1,precision) ){
209                                 // If the previous point was a bulge then don't use a line to
210                                 strcat(out, "L ");
211                         }
212                         coord( &points[i], precision, delim, NULL , scaling, out ); 
213                         // If bulge > some precsion then add bulge
214                         mag_bulge = sqrt(pow(points[i].ret_bulge(),2));
215                         if ( ( mag_bulge > pow(0.1,precision) ) && (i < (points.size() - 1) )){ // Make sure the final point doesn't add a bulge on accident
216                                 to_arc(pline.bulge(i), pline.bulge_r(i), pline.bulge_start_angle(i), pline.bulge_end_angle(i), precision, delim, units, scaling, out);
217                         }
218                         prev_mag_bulge = mag_bulge;     
219                 }
220                 if ( pline.is_closed() ){
221                         strcat(out,"z");
222                 }
223                 strcat(out,"\" ");
224         }
225         else{
226                 strcpy(delim,",");              
227                 for (int i = 0; i < points.size(); i++){
228                         coord( &points[i], precision, delim, units, scaling, out ); 
229                         // If bulge > some precsion then add bulge      
230                 }
231                 // if the element is a SVG::pline and the DXF::pline is closed then simulate by adding an extra point
232                 if ( (type == 1) && pline.is_closed() ){
233                         coord( &points[0], precision, delim, units, scaling, out ); 
234                 }
235         }       
236                 
239 char* lwpline2path(lwpolyline pline, char * units, double scaling, tables plot_info){
240         // Convert a dxf polyline to a SVG path.  This is the closest conversion of the DXF polyline to an SVG element
241         char *out_ptr;
242         char out[10000] = "<path d=\"";
243         entity *ent_ptr = &pline;
244         char temp[20];
245         int precision = 6;
246         
247         lwpline2svg(pline, 0, precision, units, scaling, plot_info, out);
248         // Add some line information
249         strcat(out,"fill=\"none\" stroke=\"black\" stroke-width=\"1\" ");
250         pattern2dasharray(plot_info.ret_ltype( ent_ptr->ret_ltype_name(temp),ent_ptr->ret_layer_name(temp) ), precision, scaling, out);  // Add the linetype information
251         
252         strcat(out," />");
253         out_ptr = out;
254         return out_ptr; 
257 // DXF ARC -> SVG
258 char* arc2path(arc a, int precision, char * units, double scaling, tables plot_info, char *out){
259         // So far this appears to be the only way to convert arcs into something recognized by SVG
260         char *out_ptr;
261         char temp[20];
262         entity *ent_ptr = &a;
263         
264         strcpy(out,"<path d=\"M");
265         // Calculate the starting point from the center and the start angle.  As far as I can tell the rotation is CCW in the dxf notation and it in degrees
266         strcat(out,gcvt(scaling*(ent_ptr->ret_x()+a.ret_radius()*cos( a.ret_srt_ang()*3.14159/180 )),precision,temp) );
267         strcat(out," ");
268         strcat(out,gcvt(-1*scaling*(ent_ptr->ret_y()+a.ret_radius()*sin( a.ret_srt_ang()*3.14159/180 )),precision,temp) );
269         strcat(out," A ");
270         // For arcs there is only one radius
271         strcat(out,gcvt(scaling*a.ret_radius(),precision,temp) );
272         strcat(out,",");
273         strcat(out,gcvt(scaling*a.ret_radius(),precision,temp) );
274         
275         strcat(out," 0"); // For arc assume no x-axis rotation.  That seems to apply to elipse elements only
276         // Determine if it is a large arc
277         if ( (a.ret_end_ang() > a.ret_srt_ang()) && ( (a.ret_end_ang() - a.ret_srt_ang()) > 180) ){
278                 strcat(out," 1,0 "); // Large arc flag...Always use a zero sweep flag
279         }
280         else{
281                 strcat(out," 0,0 "); // Small arc flag...Always use a zero sweep flag
282         }
283         
284         //The final point
285         strcat(out,gcvt(scaling*(ent_ptr->ret_x()+a.ret_radius()*cos( a.ret_end_ang()*3.14159/180 )),precision,temp) );
286         strcat(out,",");
287         strcat(out,gcvt(-1*scaling*(ent_ptr->ret_y()+a.ret_radius()*sin( a.ret_end_ang()*3.14159/180 )),precision,temp) );
288         strcat(out,"\" fill=\"none\" stroke=\"black\" stroke-width=\"1\" ");
289         ltype linfo = plot_info.ret_ltype(ent_ptr->ret_ltype_name(temp), ent_ptr->ret_layer_name(temp));
290         pattern2dasharray(linfo, precision, scaling, out);  // Add the linetype information
291         strcat(out, " />");
292         
293         
294         out_ptr = out;
295         return out_ptr;
296         
300 // DXF Circle -> SVG
301 char* circle2circle(circle circ, int precision, char * units, double scaling, tables plot_info, char *out){
302         // Direct conversion of DXF circle to SVG circle
303         char *out_ptr;
304         char temp[1000]="\" cy=\"";
305         entity *ent_ptr = &circ;
306         strcpy(out,"<circle cx=\"");
307         coord(ent_ptr, precision,temp, units, scaling, out);
308         strcat(out,"\" r=\"");
309         strcat(out,gcvt(circ.ret_radius(),precision,temp) );
310         strcat(out,units);
311         strcat(out,"\" fill=\"none\" stroke=\"black\" stroke-width=\"1\" ");
312         ltype linfo = plot_info.ret_ltype(ent_ptr->ret_ltype_name(temp), ent_ptr->ret_layer_name(temp));
313         //plot_info.ret_ltype(ent_ptr->ret_ltype_name(temp), ent_ptr->ret_layer_name(temp));
314         pattern2dasharray(linfo, precision, scaling, out);  // Add the linetype information
315         //pattern2dasharray(plot_info.ret_ltype(ent_ptr->ret_ltype_name(temp), ent_ptr->ret_layer_name(temp)), precision, scaling, out);  // Add the linetype information
316         strcat(out, " />");
317         out_ptr = out;
318         return out_ptr;
321 char* circle2path(circle circ, int precision, char * units, double scaling, tables plot_info, char *out){
322         // Conversion of DXF circle to SVG circle assuming the path will represent the circle
323         
324         char *out_ptr;
325         char temp[20]=",";
326         entity *ent_ptr = &circ;        
327         
328         strcpy(out,"<path d=\"M");
329         // The starting point is x-r,y so subtract off the radius from the x coord
330         strcat(out,gcvt(ent_ptr->ret_x()-circ.ret_radius(),precision,temp) );
331         strcat(out," ");
332         strcat(out,gcvt(ent_ptr->ret_y(),precision,temp) );
333         
334         strcat(out," a");
335         strcat(out,gcvt(circ.ret_radius(),precision,temp) );
336         strcat(out,",");
337         strcat(out,gcvt(circ.ret_radius(),precision,temp) );
338         strcat(out,"0 0,0 0,0\"  fill=\"none\" stroke=\"black\" stroke-width=\"1\"");
339                 
340         out_ptr = out;
341         return out_ptr;
345 // DXF Line -> SVG
346 char* line2line(line ln, int precision, char * units, double scaling, tables plot_info, char *out){
347         // Directly convert DXF to SVG because it works
348         char *out_ptr;
349         char temp[20];
350         entity *ent_ptr = &ln;  
351         
352         strcpy(out,"<line x1=\"");
353         strcat(out,gcvt(ent_ptr->ret_x(),precision,temp) );
354         strcat(out,units);
355         strcat(out,"\" y1=\"");
356         strcat(out,gcvt(-1*ent_ptr->ret_y(),precision,temp) ); // Put in an extra minus because of the way SVG has defined the axis
357         strcat(out,units);
358         
359         strcat(out,"\" x2=\"");
360         strcat(out,gcvt(ln.ret_xf(),precision,temp) );
361         strcat(out,units);
362         strcat(out,"\" y2=\"");  
363         strcat(out,gcvt(-1*ln.ret_yf(),precision,temp) ); // Put in an extra minus because of the way SVG has defined the axis
364         strcat(out,units);
365         strcat(out,"\" stroke-width=\"1\" stroke=\"black\" ");
366         ltype linfo = plot_info.ret_ltype(ent_ptr->ret_ltype_name(temp), ent_ptr->ret_layer_name(temp));
367         pattern2dasharray(linfo, precision, scaling, out);  // Add the linetype information
368         strcat(out, " />");
369                 
370         out_ptr = out;
371         return out_ptr;
375 char* line2path(line ln, int precision, char * units, double scaling, tables plot_info, char *out){
376         // Convert DXF line to SVG path
377         
378         char *out_ptr;
379         char temp[20];
380         entity *ent_ptr = &ln;  
381         
382         strcpy(out,"<path d=\"M");
383         strcat(out,gcvt(scaling*ent_ptr->ret_x(),precision,temp) );
384         strcat(out," ");
385         strcat(out,gcvt(scaling*ent_ptr->ret_y(),precision,temp) );
386         
387         strcat(out," L");
388         strcat(out,gcvt(scaling*ln.ret_xf(),precision,temp) );
389         strcat(out," ");
390         strcat(out,gcvt(scaling*ln.ret_yf(),precision,temp) );
391         strcat(out,"\" fill=\"none\" stroke=\"black\" stroke-width=\"1\" /");
392                 
393         out_ptr = out;
394         return out_ptr;
397 // DXF Text -> SVG
398 char* text2text(text txt, int precision, char * units, double scaling, tables plot_info, char *out){
399         // Directly convert DXF to SVG because it works
400         char *out_ptr;
401         char temp[10000];       
402         entity *ent_ptr = &txt;
403         
404         // If the text is rotated use the transform matrix
406         if ( txt.ret_txt_rot() > precision ){
407                 double ca = cos(0.017453*txt.ret_txt_rot()); // ca = cosine(a)
408                 double sa = sin(-0.017453*txt.ret_txt_rot()); // sa = sine(a)
409                 double tx = ent_ptr->ret_x()*scaling;
410                 double ty = -ent_ptr->ret_y()*scaling;
411                 // Apply a translation to the orgin, then a rotation, then a translation back to the original position
412                 double a = ca;
413                 double b = sa;
414                 double c = -sa;
415                 double d = ca;
416                 double e = -1*(tx*ca-ty*sa-tx);
417                 double f = -1*(tx*sa+ty*ca-ty);
418                 
419                 strcpy(out, "<g transform=\"matrix(");
420                 strcat(out,gcvt(a,precision,temp) );
421                 strcat(out," ");
422                 strcat(out,gcvt(b,precision,temp) );
423                 strcat(out," ");
424                 strcat(out,gcvt(c,precision,temp) );
425                 strcat(out," ");
426                 strcat(out,gcvt(d,precision,temp) );
427                 strcat(out," ");
428                 strcat(out,gcvt(e,precision,temp) );
429                 strcat(out," ");
430                 strcat(out,gcvt(f,precision,temp) );
431                 strcat(out,")\" >\n<text x=\"");
432         }
433         else{
434                 strcpy(out,"<text x=\"");
435         }
436         /*
437         strcat(out,gcvt(ent_ptr->ret_x(),precision,temp) );
438         strcat(out,units);
439         strcat(out,"\" y=\"-"); // Put in an extra minus because of the way SVG has defined the axis
440         strcat(out,gcvt(ent_ptr->ret_y(),precision,temp) );
441         strcat(out,units);
442         */
443         strcat(out,gcvt(ent_ptr->ret_x()*scaling,precision,temp) );
444         //strcat(out,units);
445         strcat(out,"\" y=\"-"); // Put in an extra minus because of the way SVG has defined the axis
446         strcat(out,gcvt(ent_ptr->ret_y()*scaling,precision,temp) );
447         //strcat(out,units);
448         strcat(out,"\" font-family=\"Verdana\" font-size=\"");
449         strcat(out,gcvt(scaling*txt.ret_txt_ht(),precision,temp) );
450         strcat(out,"\" Fill=\"black\"");
451         
452         strcat(out," >");
453         //  Now put in the text
454         strcat(out,txt.ret_text(temp));
455         
456         // Now close the text element
457         strcat(out,"</text>");  
458         // If the text was rotated finish off the tranform group
459         if ( txt.ret_txt_rot() > precision ){
460                 strcat(out,"</g>");
461         }
462         
463         out_ptr = out;
464         return out_ptr;
469 // DXF Insert -> SVG
470 char* insert2group(insert in, int precision, char * units, double scaling, tables plot_info, blocks blks, char *out){
471         char *out_ptr;
472         char tmp_char[100000];
473         
474         //  get the block using the name from the insert information
475         block blk = blks.ret_block(in.name(tmp_char));
476         
477         entity *ent_ptr = &in;
478         entities *ents_ptr = &blk;
479         // For now just translations  MBS 22 Aug 05
480         strcpy(out, "<g transform=\"matrix(1,0,0,1,");
481         strcat(out,gcvt(scaling*ent_ptr->ret_x(),precision,tmp_char) );
482         strcat(out,",");
483         strcat(out,gcvt(-scaling*ent_ptr->ret_y(),precision,tmp_char) );
484         strcat(out,")\" >\n");
485         
486         
487         // Now convert the entities in the block
488         std::vector< polyline > plines = ents_ptr->ret_plines();
489         std::vector< lwpolyline > lwplines = ents_ptr->ret_lwplines();
490         std::vector< arc > arcs = ents_ptr->ret_arcs();
491         std::vector< circle > circs = ents_ptr->ret_circles();
492         std::vector< line > lns = ents_ptr->ret_lines();
493         std::vector< text > txts = ents_ptr->ret_texts();
494         
495                 
496         
497         for(int i = 0; i < plines.size();i++){
498                 strcat( out,pline2pline(plines[i], units, scaling, plot_info ) );
499                 strcat( out, "\n" );
500         }
501         for(int i = 0; i < lwplines.size();i++){
502                 strcat( out,lwpline2path(lwplines[i], units, scaling, plot_info ) );
503                 strcat( out, "\n" );
504         }
505         for(int i = 0; i < arcs.size();i++){
506                 strcat( out, arc2path(arcs[i], 6,units, scaling, plot_info, tmp_char ) );
507                 strcat( out, "\n" );
508         }
509         for(int i = 0; i < circs.size();i++){
510                 strcat( out, circle2circle(circs[i], 6, units, scaling, plot_info, tmp_char) );
511                 strcat( out, "\n" );
512         }
513         for(int i = 0; i < lns.size();i++){
514                 strcat( out, line2line(lns[i], 6, units, scaling, plot_info, tmp_char) );
515                 strcat( out, "\n" );
516         }
517         for(int i = 0; i < txts.size();i++){
518                 strcat( out, text2text(txts[i], 6, units, scaling, plot_info, tmp_char) );
519                 strcat( out, "\n" );
520         }
521         // End the group
522         strcat(out,"</g>");
523         
524         out_ptr = out;
525         return out_ptr; 
530 char* write_by_layer(int output_type, entities &ents, tables &tbls, blocks &blks, double scaling, char * units, char * layer, char * out){
531         // output_type = 0 is to std:out
532         // output_type = 1 is to the input filename but with .dxf on the end
533         
534         // For now everything will go to stdout later may directed to other places
535         
536         // Get the various file informations as dependent on the layer type
537         std::vector< polyline > plines = ents.ret_plines(layer);
538         std::vector< lwpolyline > lwplines = ents.ret_lwplines(layer);
539         std::vector< arc > arcs = ents.ret_arcs(layer);
540         std::vector< circle > circs = ents.ret_circles(layer);
541         std::vector< line > lns = ents.ret_lines(layer);
542         std::vector< text > txts = ents.ret_texts(layer);
543         std::vector< insert > ins = ents.ret_inserts(layer);
544         
545         // It would be better to redirect stdout to different places.  That would make the code cleaner but I don't think it will work better
546         char tmp_char[100000];
547         for(int i = 0; i < plines.size();i++){
548                 if (output_type == 0){
549                         std::cout << "\t" << pline2path(plines[i], NULL, scaling, tbls ) << std::endl;
550                 }
551                 else if (output_type == 1){
552                         std::cout << "\t" << pline2path(plines[i], NULL, scaling, tbls ) << std::endl;
553                 }
554         }
555         for(int i = 0; i < lwplines.size();i++){
556                 if (output_type == 0){
557                         std::cout << "\t" << lwpline2path(lwplines[i], units, scaling, tbls ) << std::endl;
558                 }
559                 else if (output_type == 1){
560                         std::cout << "\t" << lwpline2path(lwplines[i], units, scaling, tbls ) << std::endl;
561                 }
562         }
563         for(int i = 0; i < arcs.size();i++){
564                 if (output_type == 0){
565                         std::cout << "\t" << arc2path(arcs[i], 6,units, scaling, tbls, tmp_char ) << std::endl;
566                 }
567                 else if (output_type == 1){
568                         std::cout << "\t" << arc2path(arcs[i], 6,units, scaling, tbls, tmp_char ) << std::endl;
569                 }
570         }
571         for(int i = 0; i < circs.size();i++){
572                 if (output_type == 0){
573                         std::cout << "\t" << circle2circle(circs[i], 6, units, scaling, tbls, tmp_char) << std::endl;
574                 }
575                 else if (output_type == 1){
576                         std::cout << "\t" << circle2circle(circs[i], 6, units, scaling, tbls, tmp_char) << std::endl;
577                 }
578         }
579         for(int i = 0; i < lns.size();i++){
580                 if (output_type == 0){
581                         std::cout << "\t" << line2line(lns[i], 6, units, scaling, tbls, tmp_char) << std::endl;
582                 }
583                 else if (output_type == 1){
584                         std::cout << "\t" << line2line(lns[i], 6, units, scaling, tbls, tmp_char) << std::endl;
585                 }
586         }
587         for(int i = 0; i < txts.size();i++){
588                 if (output_type == 0){
589                         std::cout << "\t" << text2text(txts[i], 6, units, scaling, tbls, tmp_char) << std::endl;
590                 }
591                 else if (output_type == 1){
592                         std::cout << "\t" << text2text(txts[i], 6, units, scaling, tbls, tmp_char) << std::endl;
593                 }
594         }
595         for(int i = 0; i < ins.size();i++){
596                 if (output_type == 0){
597                         std::cout << "\t" << insert2group(ins[i], 6, units, scaling, tbls, blks, tmp_char) << std::endl;
598                 }
599                 else if (output_type == 1){
600                         std::cout << "\t" << insert2group(ins[i], 6, units, scaling, tbls, blks, tmp_char) << std::endl;
601                 }
602         }
607 char* write_all(int output_type, entities &ents, tables &tbls, blocks &blks, double scaling, char * units, char * out){
608         // output_type = 0 is to std:out
609         // output_type = 1 is to the input filename but with .dxf on the end
610         
611         // For now everything will go to stdout later may directed to other places
612         
613         // Get the various file informations as dependent on the layer type
614         std::vector< polyline > plines = ents.ret_plines();
615         std::vector< lwpolyline > lwplines = ents.ret_lwplines();
616         std::vector< arc > arcs = ents.ret_arcs();
617         std::vector< circle > circs = ents.ret_circles();
618         std::vector< line > lns = ents.ret_lines();
619         std::vector< text > txts = ents.ret_texts();
620         std::vector< insert > ins = ents.ret_inserts();
621         
622         // It would be better to redirect stdout to different places.  That would make the code cleaner but I don't think it will work better
623         char tmp_char[100000];
624         for(int i = 0; i < plines.size();i++){
625                 if (output_type == 0){
626                         std::cout << "\t" << pline2path(plines[i], NULL, scaling, tbls ) << std::endl;
627                 }
628                 else if (output_type == 1){
629                         std::cout << "\t" << pline2path(plines[i], NULL, scaling, tbls ) << std::endl;
630                 }
631         }
632         for(int i = 0; i < lwplines.size();i++){
633                 if (output_type == 0){
634                         std::cout << "\t" << lwpline2path(lwplines[i], units, scaling, tbls ) << std::endl;
635                 }
636                 else if (output_type == 1){
637                         std::cout << "\t" << lwpline2path(lwplines[i], units, scaling, tbls ) << std::endl;
638                 }
639         }
640         for(int i = 0; i < arcs.size();i++){
641                 if (output_type == 0){
642                         std::cout << "\t" << arc2path(arcs[i], 6,units, scaling, tbls, tmp_char ) << std::endl;
643                 }
644                 else if (output_type == 1){
645                         std::cout << "\t" << arc2path(arcs[i], 6,units, scaling, tbls, tmp_char ) << std::endl;
646                 }
647         }
648         for(int i = 0; i < circs.size();i++){
649                 if (output_type == 0){
650                         std::cout << "\t" << circle2circle(circs[i], 6, units, scaling, tbls, tmp_char) << std::endl;
651                 }
652                 else if (output_type == 1){
653                         std::cout << "\t" << circle2circle(circs[i], 6, units, scaling, tbls, tmp_char) << std::endl;
654                 }
655         }
656         for(int i = 0; i < lns.size();i++){
657                 if (output_type == 0){
658                         std::cout << "\t" << line2line(lns[i], 6, units, scaling, tbls, tmp_char) << std::endl;
659                 }
660                 else if (output_type == 1){
661                         std::cout << "\t" << line2line(lns[i], 6, units, scaling, tbls, tmp_char) << std::endl;
662                 }
663         }
664         for(int i = 0; i < txts.size();i++){
665                 if (output_type == 0){
666                         std::cout << "\t" << text2text(txts[i], 6, units, scaling, tbls, tmp_char) << std::endl;
667                 }
668                 else if (output_type == 1){
669                         std::cout << "\t" << text2text(txts[i], 6, units, scaling, tbls, tmp_char) << std::endl;
670                 }
671         }
672         for(int i = 0; i < ins.size();i++){
673                 if (output_type == 0){
674                         std::cout << "\t" << insert2group(ins[i], 6, units, scaling, tbls, blks, tmp_char) << std::endl;
675                 }
676                 else if (output_type == 1){
677                         std::cout << "\t" << insert2group(ins[i], 6, units, scaling, tbls, blks, tmp_char) << std::endl;
678                 }
679         }