Code

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