1 /* -*- Mode: C; c-basic-offset: 4 -*- */
2 /* Dia -- an diagram creation/manipulation program
3 * Copyright (C) 1998 Alexander Larsson
5 * dxf-import.c: dxf import filter for dia
6 * Copyright (C) 2000 Steffen Macke
7 * Copyright (C) 2002 Angus Ainslie
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
38 #include "diarenderer.h"
41 #include "properties.h"
42 #include "propinternals.h"
43 #include "autocad_pal.h"
47 #include "attributes.h"
49 static real coord_scale
= 1.0, measure_scale
= 1.0;
50 static real text_scale
= 1.0;
52 #define WIDTH_SCALE measure_scale
53 #define DEFAULT_LINE_WIDTH 0.001
55 Point extent_min
, extent_max
;
56 Point limit_min
, limit_max
;
58 /* maximum line length */
59 #define DXF_LINE_LENGTH 256
61 typedef struct layer_data_tag
67 typedef struct _DxfData
69 char code
[DXF_LINE_LENGTH
];
70 char value
[DXF_LINE_LENGTH
];
73 gboolean
import_dxf(const gchar
*filename
, DiagramData
*dia
, void* user_data
);
74 gboolean
read_dxf_codes(FILE *filedxf
, DxfData
*data
);
75 DiaObject
*read_entity_line_dxf(FILE *filedxf
, DxfData
*data
, DiagramData
*dia
);
76 DiaObject
*read_entity_circle_dxf(FILE *filedxf
, DxfData
*data
, DiagramData
*dia
);
77 DiaObject
*read_entity_ellipse_dxf(FILE *filedxf
, DxfData
*data
, DiagramData
*dia
);
78 DiaObject
*read_entity_arc_dxf(FILE *filedxf
, DxfData
*data
, DiagramData
*dia
);
79 DiaObject
*read_entity_solid_dxf(FILE *filedxf
, DxfData
*data
, DiagramData
*dia
);
80 DiaObject
*read_entity_polyline_dxf(FILE *filedxf
, DxfData
*data
, DiagramData
*dia
);
81 DiaObject
*read_entity_text_dxf(FILE *filedxf
, DxfData
*data
, DiagramData
*dia
);
82 void read_entity_measurement_dxf(FILE *filedxf
, DxfData
*data
,
84 void read_entity_scale_dxf(FILE *filedxf
, DxfData
*data
, DiagramData
*dia
);
85 void read_entity_textsize_dxf(FILE *filedxf
, DxfData
*data
, DiagramData
*dia
);
86 void read_entity_mesurement_dxf(FILE *filedxf
, DxfData
*data
, DiagramData
*dia
);
87 void read_table_layer_dxf(FILE *filedxf
, DxfData
*data
, DiagramData
*dia
);
88 void read_section_header_dxf(FILE *filedxf
, DxfData
*data
, DiagramData
*dia
);
89 void read_section_classes_dxf(FILE *filedxf
, DxfData
*data
, DiagramData
*dia
);
90 void read_section_tables_dxf(FILE *filedxf
, DxfData
*data
, DiagramData
*dia
);
91 void read_section_entities_dxf(FILE *filedxf
, DxfData
*data
, DiagramData
*dia
);
92 void read_section_blocks_dxf(FILE *filedxf
, DxfData
*data
, DiagramData
*dia
);
93 Layer
*layer_find_by_name(char *layername
, DiagramData
*dia
);
94 LineStyle
get_dia_linestyle_dxf(char *dxflinestyle
);
96 /* returns the layer with the given name */
97 /* TODO: merge this with other layer code? */
98 Layer
*layer_find_by_name(char *layername
, DiagramData
*dia
)
100 Layer
*matching_layer
, *layer
;
103 matching_layer
= NULL
;
105 for (i
=0; i
<dia
->layers
->len
; i
++) {
106 layer
= (Layer
*)g_ptr_array_index(dia
->layers
, i
);
107 if(strcmp(layer
->name
, layername
) == 0) {
108 matching_layer
= layer
;
113 if( matching_layer
== NULL
)
115 matching_layer
= new_layer(g_strdup( layername
), dia
);
116 data_add_layer(dia
, matching_layer
);
119 return matching_layer
;
122 /* returns the matching dia linestyle for a given dxf linestyle */
123 /* if no matching style is found, LINESTYLE solid is returned as a default */
124 LineStyle
get_dia_linestyle_dxf(char *dxflinestyle
) {
125 if(strcmp(dxflinestyle
, "DASH") == 0) {
126 return LINESTYLE_DASHED
;
128 if(strcmp(dxflinestyle
, "DASHDOT") == 0){
129 return LINESTYLE_DASH_DOT
;
131 if(strcmp(dxflinestyle
, "DOT") == 0){
132 return LINESTYLE_DOTTED
;
134 return LINESTYLE_SOLID
;
137 static PropDescription dxf_prop_descs
[] = {
138 { "start_point", PROP_TYPE_POINT
},
139 { "end_point", PROP_TYPE_POINT
},
140 { "line_colour", PROP_TYPE_COLOUR
},
141 { "line_width", PROP_TYPE_REAL
},
142 { "line_style", PROP_TYPE_LINESTYLE
},
146 /* reads a line entity from the dxf file and creates a line object in dia*/
147 DiaObject
*read_entity_line_dxf(FILE *filedxf
, DxfData
*data
, DiagramData
*dia
){
154 DiaObjectType
*otype
= object_get_type("Standard - Line");
158 Color line_colour
= { 0.0, 0.0, 0.0 };
160 PointProperty
*ptprop
;
161 LinestyleProperty
*lsprop
;
162 ColorProperty
*cprop
;
165 real line_width
= DEFAULT_LINE_WIDTH
;
166 LineStyle style
= LINESTYLE_SOLID
;
169 old_locale
= setlocale(LC_NUMERIC
, "C");
171 if(read_dxf_codes(filedxf
, data
) == FALSE
){
172 setlocale(LC_NUMERIC
, old_locale
);
175 codedxf
= atoi(data
->code
);
177 case 6: style
= get_dia_linestyle_dxf(data
->value
);
179 case 8: layer
= layer_find_by_name(data
->value
, dia
);
182 start
.x
= atof(data
->value
) * coord_scale
* measure_scale
;
185 end
.x
= atof(data
->value
) * coord_scale
* measure_scale
;
188 start
.y
= (-1)*atof(data
->value
) * coord_scale
* measure_scale
;
191 end
.y
= (-1)*atof(data
->value
) * coord_scale
* measure_scale
;
194 line_width
= atof(data
->value
) * WIDTH_SCALE
;
195 /*printf( "line width %f\n", line_width ); */
198 } while(codedxf
!= 0);
199 setlocale(LC_NUMERIC
, old_locale
);
201 line_obj
= otype
->ops
->create(&start
, otype
->default_user_data
,
203 layer_add_object(layer
, line_obj
);
205 props
= prop_list_from_descs(dxf_prop_descs
,pdtpp_true
);
206 g_assert(props
->len
== 5);
208 ptprop
= g_ptr_array_index(props
,0);
209 ptprop
->point_data
= start
;
211 ptprop
= g_ptr_array_index(props
,1);
212 ptprop
->point_data
= end
;
214 cprop
= g_ptr_array_index(props
,2);
215 cprop
->color_data
= line_colour
;
217 rprop
= g_ptr_array_index(props
,3);
218 rprop
->real_data
= line_width
;
220 lsprop
= g_ptr_array_index(props
,4);
221 lsprop
->style
= style
;
224 line_obj
->ops
->set_props(line_obj
, props
);
226 prop_list_free(props
);
231 static PropDescription dxf_solid_prop_descs
[] = {
232 { "line_colour", PROP_TYPE_COLOUR
},
233 { "line_width", PROP_TYPE_REAL
},
234 { "line_style", PROP_TYPE_LINESTYLE
},
235 { "fill_colour", PROP_TYPE_COLOUR
},
236 { "show_background", PROP_TYPE_BOOL
},
239 /* reads a solid entity from the dxf file and creates a polygon object in dia*/
240 DiaObject
*read_entity_solid_dxf(FILE *filedxf
, DxfData
*data
, DiagramData
*dia
)
248 DiaObjectType
*otype
= object_get_type("Standard - Polygon");
251 DiaObject
*polygon_obj
;
252 MultipointCreateData
*pcd
;
254 Color fill_colour
= { 0.5, 0.5, 0.5 };
257 LinestyleProperty
*lsprop
;
258 ColorProperty
*cprop
, *fprop
;
262 real line_width
= 0.001;
263 LineStyle style
= LINESTYLE_SOLID
;
265 unsigned char colour
;
267 /* printf( "Solid " ); */
269 old_locale
= setlocale(LC_NUMERIC
, "C");
271 if(read_dxf_codes(filedxf
, data
) == FALSE
){
272 setlocale(LC_NUMERIC
, old_locale
);
275 codedxf
= atoi(data
->code
);
278 style
= get_dia_linestyle_dxf(data
->value
);
281 layer
= layer_find_by_name(data
->value
, dia
);
282 /*printf( "layer: %s ", data->value );*/
285 p
[0].x
= atof(data
->value
) * coord_scale
* measure_scale
;
286 /*printf( "P0.x: %f ", p[0].x );*/
289 p
[1].x
= atof(data
->value
) * coord_scale
* measure_scale
;
290 /*printf( "P1.x: %f ", p[1].x );*/
293 p
[2].x
= atof(data
->value
) * coord_scale
* measure_scale
;
294 /*printf( "P2.x: %f ", p[2].x );*/
297 p
[3].x
= atof(data
->value
) * coord_scale
* measure_scale
;
298 /*printf( "P3.x: %f ", p[3].x );*/
301 p
[0].y
= (-1)*atof(data
->value
) * coord_scale
* measure_scale
;
302 /*printf( "P0.y: %f ", p[0].y );*/
305 p
[1].y
= (-1)*atof(data
->value
) * coord_scale
* measure_scale
;
306 /*printf( "P1.y: %f ", p[1].y );*/
309 p
[2].y
= (-1)*atof(data
->value
) * coord_scale
* measure_scale
;
310 /*printf( "P2.y: %f ", p[2].y );*/
313 p
[3].y
= (-1)*atof(data
->value
) * coord_scale
* measure_scale
;
314 /*printf( "P3.y: %f\n", p[3].y );*/
317 line_width
= atof(data
->value
) * WIDTH_SCALE
;
318 /*printf( "width %f\n", line_width );*/
321 colour
= atoi(data
->value
);
322 fill_colour
.red
= acad_pal
[colour
].r
/ 255.0;
323 fill_colour
.green
= acad_pal
[colour
].g
/ 255.0;
324 fill_colour
.blue
= acad_pal
[colour
].b
/ 255.0;
325 /* printf( "acad colour %d %d %d\n", acad_pal[colour].r, acad_pal[colour].g, acad_pal[colour].b );
326 printf( "fill colour %f %f %f\n", fill_colour.red, fill_colour.green, fill_colour.blue );*/
329 } while(codedxf
!= 0);
330 setlocale(LC_NUMERIC
, old_locale
);
332 pcd
= g_new( MultipointCreateData
, 1);
334 if( p
[2].x
!= p
[3].x
&& p
[2].y
!= p
[3].y
)
339 pcd
->points
= g_new( Point
, pcd
->num_points
);
341 memcpy( pcd
->points
, p
, sizeof( Point
) * pcd
->num_points
);
343 polygon_obj
= otype
->ops
->create( NULL
, pcd
, &h1
, &h2
);
345 layer_add_object( layer
, polygon_obj
);
347 props
= prop_list_from_descs( dxf_solid_prop_descs
, pdtpp_true
);
348 g_assert(props
->len
== 5);
350 cprop
= g_ptr_array_index( props
,0 );
351 cprop
->color_data
= fill_colour
;
353 rprop
= g_ptr_array_index( props
,1 );
354 rprop
->real_data
= line_width
;
356 lsprop
= g_ptr_array_index( props
,2 );
357 lsprop
->style
= style
;
360 fprop
= g_ptr_array_index( props
, 3 );
361 fprop
->color_data
= fill_colour
;
363 bprop
= g_ptr_array_index( props
, 4 );
364 bprop
->bool_data
= TRUE
;
366 polygon_obj
->ops
->set_props( polygon_obj
, props
);
368 prop_list_free(props
);
370 return( polygon_obj
);
373 static PropDescription dxf_polyline_prop_descs
[] = {
374 { "line_colour", PROP_TYPE_COLOUR
},
375 { "line_width", PROP_TYPE_REAL
},
376 { "line_style", PROP_TYPE_LINESTYLE
},
379 static int is_equal( double a
, double b
)
381 double epsilon
= 0.001;
386 if(( a
+ epsilon
) > b
&& ( a
- epsilon
) < b
)
392 /* reads a polyline entity from the dxf file and creates a polyline object in dia*/
393 DiaObject
*read_entity_polyline_dxf(FILE *filedxf
, DxfData
*data
, DiagramData
*dia
)
399 Point
*p
= NULL
, start
, end
, center
;
401 DiaObjectType
*otype
= object_get_type("Standard - PolyLine");
404 DiaObject
*polyline_obj
;
405 MultipointCreateData
*pcd
;
407 Color line_colour
= { 0.0, 0.0, 0.0 };
410 LinestyleProperty
*lsprop
;
411 ColorProperty
*cprop
;
414 real line_width
= DEFAULT_LINE_WIDTH
;
415 real radius
, start_angle
= 0;
416 LineStyle style
= LINESTYLE_SOLID
;
418 unsigned char colour
, closed
= 0;
421 old_locale
= setlocale(LC_NUMERIC
, "C");
423 if(read_dxf_codes(filedxf
, data
) == FALSE
){
424 setlocale(LC_NUMERIC
, old_locale
);
427 codedxf
= atoi(data
->code
);
430 if( !strcmp( data
->value
, "VERTEX" ))
434 p
= realloc( p
, sizeof( Point
) * points
);
436 /*printf( "Vertex %d\n", points );*/
441 style
= get_dia_linestyle_dxf(data
->value
);
444 layer
= layer_find_by_name(data
->value
, dia
);
445 /*printf( "layer: %s ", data->value );*/
450 p
[points
-1].x
= atof(data
->value
) * coord_scale
* measure_scale
;
451 /*printf( "P[%d].x: %f ", points-1, p[points-1].x );*/
457 p
[points
-1].y
= (-1)*atof(data
->value
) * coord_scale
* measure_scale
;
458 /*printf( "P[%d].y: %f\n", points-1, p[points-1].y );*/
462 line_width
= atof(data
->value
) * WIDTH_SCALE
;
463 /*printf( "width %f\n", line_width );*/
466 /* FIXME - the bulge code doesn't work */
467 p
= realloc( p
, sizeof( Point
) * ( points
+ 10 ));
472 radius
= sqrt( pow( end
.x
- start
.x
, 2 ) + pow( end
.y
- start
.y
, 2 ))/2;
474 center
.x
= start
.x
+ ( end
.x
- start
.x
)/2;
475 center
.y
= start
.y
+ ( end
.y
- start
.y
)/2;
477 if( is_equal( start
.x
, end
.x
))
479 if( is_equal( start
.y
, end
.y
))
481 g_warning(_("Bad vertex bulge\n") );
483 else if( start
.y
> center
.y
)
485 /*start_angle = 90.0;*/
486 start_angle
= M_PI
/2;
490 /*start_angle = 270.0;*/
491 start_angle
= M_PI
* 1.5;
494 else if( is_equal( start
.y
, end
.y
))
496 if( is_equal( start
.x
, end
.x
))
498 g_warning( _("Bad vertex bulge\n") );
500 else if( start
.x
> center
.x
)
511 start_angle
= atan( center
.y
- start
.y
/center
.x
- start
.x
);
514 /*printf( "start x %f end x %f center x %f\n", start.x, end.x, center.x );
515 printf( "start y %f end y %f center y %f\n", start.y, end.y, center.y );
516 printf( "bulge %s %f startx_angle %f\n", data->value, radius, start_angle );*/
518 for( i
=(points
-1); i
<(points
+9); i
++ );
520 p
[i
].x
= center
.x
+ cos( start_angle
) * radius
;
521 p
[i
].y
= center
.y
+ sin( start_angle
) * radius
;
522 start_angle
+= M_PI
/10.0;
523 /*printf( "i %d x %f y %f\n", i, p[i].x, p[i].y );*/
530 colour
= atoi(data
->value
);
531 line_colour
.red
= acad_pal
[colour
].r
/ 255.0;
532 line_colour
.green
= acad_pal
[colour
].g
/ 255.0;
533 line_colour
.blue
= acad_pal
[colour
].b
/ 255.0;
536 closed
= 1 & atoi( data
->value
);
537 /*printf( "closed %d %s", closed, data->value );*/
540 } while( strcmp( data
->value
, "SEQEND" ));
542 setlocale(LC_NUMERIC
, old_locale
);
546 printf( "No vertexes defined\n" );
550 pcd
= g_new( MultipointCreateData
, 1);
555 p
= realloc( p
, sizeof( Point
) * points
);
556 p
[points
-1].x
= p
[0].x
;
557 p
[points
-1].y
= p
[0].y
;
560 pcd
->num_points
= points
;
561 pcd
->points
= g_new( Point
, pcd
->num_points
);
563 memcpy( pcd
->points
, p
, sizeof( Point
) * pcd
->num_points
);
567 polyline_obj
= otype
->ops
->create( NULL
, pcd
, &h1
, &h2
);
569 layer_add_object( layer
, polyline_obj
);
571 props
= prop_list_from_descs( dxf_polyline_prop_descs
, pdtpp_true
);
572 g_assert( props
->len
== 3 );
574 cprop
= g_ptr_array_index( props
,0 );
575 cprop
->color_data
= line_colour
;
577 rprop
= g_ptr_array_index( props
,1 );
578 rprop
->real_data
= line_width
;
580 lsprop
= g_ptr_array_index( props
,2 );
581 lsprop
->style
= style
;
584 polyline_obj
->ops
->set_props( polyline_obj
, props
);
586 prop_list_free(props
);
588 return( polyline_obj
);
591 static PropDescription dxf_ellipse_prop_descs
[] = {
592 { "elem_corner", PROP_TYPE_POINT
},
593 { "elem_width", PROP_TYPE_REAL
},
594 { "elem_height", PROP_TYPE_REAL
},
595 { "line_colour", PROP_TYPE_COLOUR
},
596 { "line_width", PROP_TYPE_REAL
},
597 { "show_background", PROP_TYPE_BOOL
},
600 /* reads a circle entity from the dxf file and creates a circle object in dia*/
601 DiaObject
*read_entity_circle_dxf(FILE *filedxf
, DxfData
*data
, DiagramData
*dia
)
610 DiaObjectType
*otype
= object_get_type("Standard - Ellipse");
613 DiaObject
*ellipse_obj
;
614 Color line_colour
= { 0.0, 0.0, 0.0 };
616 PointProperty
*ptprop
;
619 ColorProperty
*cprop
;
622 real line_width
= DEFAULT_LINE_WIDTH
;
625 old_locale
= setlocale(LC_NUMERIC
, "C");
627 if(read_dxf_codes(filedxf
, data
) == FALSE
){
628 setlocale(LC_NUMERIC
, old_locale
);
631 codedxf
= atoi(data
->code
);
634 layer
= layer_find_by_name(data
->value
, dia
);
637 center
.x
= atof(data
->value
) * coord_scale
* measure_scale
;
640 center
.y
= (-1)*atof(data
->value
) * coord_scale
* measure_scale
;
643 line_width
= atof(data
->value
) * WIDTH_SCALE
;
646 radius
= atof(data
->value
) * coord_scale
* measure_scale
;
650 } while(codedxf
!= 0);
651 setlocale(LC_NUMERIC
, old_locale
);
655 ellipse_obj
= otype
->ops
->create(¢er
, otype
->default_user_data
,
657 layer_add_object(layer
, ellipse_obj
);
659 props
= prop_list_from_descs(dxf_ellipse_prop_descs
,pdtpp_true
);
660 g_assert(props
->len
== 6);
662 ptprop
= g_ptr_array_index(props
,0);
663 ptprop
->point_data
= center
;
664 rprop
= g_ptr_array_index(props
,1);
665 rprop
->real_data
= radius
* 2.0;
666 rprop
= g_ptr_array_index(props
,2);
667 rprop
->real_data
= radius
* 2.0;
668 cprop
= g_ptr_array_index(props
,3);
669 cprop
->color_data
= line_colour
;
670 rprop
= g_ptr_array_index(props
,4);
671 rprop
->real_data
= line_width
;
672 bprop
= g_ptr_array_index(props
,5);
673 bprop
->bool_data
= FALSE
;
675 ellipse_obj
->ops
->set_props(ellipse_obj
, props
);
676 prop_list_free(props
);
678 return( ellipse_obj
);
681 static PropDescription dxf_arc_prop_descs
[] = {
682 { "start_point", PROP_TYPE_POINT
},
683 { "end_point", PROP_TYPE_POINT
},
684 { "curve_distance", PROP_TYPE_REAL
},
685 { "line_colour", PROP_TYPE_COLOUR
},
686 { "line_width", PROP_TYPE_REAL
},
689 /* reads a circle entity from the dxf file and creates a circle object in dia*/
690 DiaObject
*read_entity_arc_dxf(FILE *filedxf
, DxfData
*data
, DiagramData
*dia
)
696 Point start
,center
,end
;
697 real radius
= 1.0, start_angle
= 0.0, end_angle
=360.0;
700 DiaObjectType
*otype
= object_get_type("Standard - Arc");
704 Color line_colour
= { 0.0, 0.0, 0.0 };
706 ColorProperty
*cprop
;
707 PointProperty
*ptprop
;
711 real line_width
= DEFAULT_LINE_WIDTH
;
714 old_locale
= setlocale(LC_NUMERIC
, "C");
716 if(read_dxf_codes(filedxf
, data
) == FALSE
){
717 setlocale(LC_NUMERIC
,old_locale
);
720 codedxf
= atoi(data
->code
);
723 layer
= layer_find_by_name(data
->value
, dia
);
726 center
.x
= atof(data
->value
) * coord_scale
* measure_scale
;
729 center
.y
= (-1)*atof(data
->value
) * coord_scale
* measure_scale
;
732 line_width
= atof(data
->value
) * WIDTH_SCALE
;
735 radius
= atof(data
->value
) * coord_scale
* measure_scale
;
738 start_angle
= atof(data
->value
)*M_PI
/180.0;
741 end_angle
= atof(data
->value
)*M_PI
/180.0;
744 } while(codedxf
!= 0);
745 setlocale(LC_NUMERIC
, old_locale
);
747 /* printf("c.x=%f c.y=%f s",center.x,center.y); */
748 start
.x
= center
.x
+ cos(start_angle
) * radius
;
749 start
.y
= center
.y
- sin(start_angle
) * radius
;
750 end
.x
= center
.x
+ cos(end_angle
) * radius
;
751 end
.y
= center
.y
- sin(end_angle
) * radius
;
752 /*printf("s.x=%f s.y=%f e.x=%f e.y=%f\n",start.x,start.y,end.x,end.y);*/
755 if (end_angle
< start_angle
) end_angle
+= 2.0*M_PI
;
756 curve_distance
= radius
* (1 - cos ((end_angle
- start_angle
)/2));
758 /*printf("start_angle: %f end_angle: %f radius:%f curve_distance:%f\n",
759 start_angle,end_angle,radius,curve_distance);*/
761 arc_obj
= otype
->ops
->create(¢er
, otype
->default_user_data
,
763 layer_add_object(layer
, arc_obj
);
765 props
= prop_list_from_descs(dxf_arc_prop_descs
,pdtpp_true
);
766 g_assert(props
->len
== 5);
768 ptprop
= g_ptr_array_index(props
,0);
769 ptprop
->point_data
= start
;
770 ptprop
= g_ptr_array_index(props
,1);
771 ptprop
->point_data
= end
;
772 rprop
= g_ptr_array_index(props
,2);
773 rprop
->real_data
= curve_distance
;
774 cprop
= g_ptr_array_index(props
,3);
775 cprop
->color_data
= line_colour
;
776 rprop
= g_ptr_array_index(props
,4);
777 rprop
->real_data
= line_width
;
779 arc_obj
->ops
->set_props(arc_obj
, props
);
780 prop_list_free(props
);
785 /* reads an ellipse entity from the dxf file and creates an ellipse object in dia*/
786 DiaObject
*read_entity_ellipse_dxf(FILE *filedxf
, DxfData
*data
, DiagramData
*dia
){
793 real ratio_width_height
= 1.0;
795 DiaObjectType
*otype
= object_get_type("Standard - Ellipse");
798 DiaObject
*ellipse_obj
;
799 Color line_colour
= { 0.0, 0.0, 0.0 };
800 PointProperty
*ptprop
;
803 ColorProperty
*cprop
;
806 real line_width
= DEFAULT_LINE_WIDTH
;
809 old_locale
= setlocale(LC_NUMERIC
, "C");
811 if(read_dxf_codes(filedxf
, data
) == FALSE
){
812 setlocale(LC_NUMERIC
, old_locale
);
815 codedxf
= atoi(data
->code
);
818 layer
= layer_find_by_name(data
->value
, dia
);
821 center
.x
= atof(data
->value
) * coord_scale
* measure_scale
;
824 ratio_width_height
= atof(data
->value
) * coord_scale
* measure_scale
;
827 center
.y
= (-1)*atof(data
->value
) * coord_scale
* measure_scale
;
830 line_width
= atof(data
->value
) * WIDTH_SCALE
;
833 width
= atof(data
->value
) * 2; /* XXX what scale */
836 } while(codedxf
!= 0);
837 setlocale(LC_NUMERIC
, old_locale
);
840 center
.y
-= (width
*ratio_width_height
);
841 ellipse_obj
= otype
->ops
->create(¢er
, otype
->default_user_data
,
843 layer_add_object(layer
, ellipse_obj
);
845 props
= prop_list_from_descs(dxf_ellipse_prop_descs
,pdtpp_true
);
846 g_assert(props
->len
== 6);
848 ptprop
= g_ptr_array_index(props
,0);
849 ptprop
->point_data
= center
;
850 rprop
= g_ptr_array_index(props
,1);
851 rprop
->real_data
= width
;
852 rprop
= g_ptr_array_index(props
,2);
853 rprop
->real_data
= width
* ratio_width_height
;
854 cprop
= g_ptr_array_index(props
,3);
855 cprop
->color_data
= line_colour
;
856 rprop
= g_ptr_array_index(props
,4);
857 rprop
->real_data
= line_width
;
858 bprop
= g_ptr_array_index(props
,5);
859 bprop
->bool_data
= FALSE
;
861 ellipse_obj
->ops
->set_props(ellipse_obj
, props
);
862 prop_list_free(props
);
864 return( ellipse_obj
);
867 static PropDescription dxf_text_prop_descs
[] = {
868 { "text", PROP_TYPE_TEXT
},
871 DiaObject
*read_entity_text_dxf(FILE *filedxf
, DxfData
*data
, DiagramData
*dia
)
878 real height
= text_scale
* coord_scale
* measure_scale
;
880 Alignment textalignment
= ALIGN_LEFT
;
881 char *textvalue
= NULL
, *textp
;
883 DiaObjectType
*otype
= object_get_type("Standard - Text");
887 Color text_colour
= { 0.0, 0.0, 0.0 };
894 old_locale
= setlocale(LC_NUMERIC
, "C");
896 if (read_dxf_codes(filedxf
, data
) == FALSE
) {
897 setlocale(LC_NUMERIC
,old_locale
);
900 codedxf
= atoi(data
->code
);
903 textvalue
= g_strdup(data
->value
);
905 /* FIXME - poor tab to space converter */
908 if( textp
[0] == '^' && textp
[1] == 'I' )
916 while( *(++textp
) != '\0' );
918 /*printf( "Found text: %s\n", textvalue );*/
920 case 8: layer
= layer_find_by_name(data
->value
, dia
);
923 location
.x
= atof(data
->value
) * coord_scale
* measure_scale
;
924 /*printf( "Found text location x: %f\n", location.x );*/
927 location
.x
= atof(data
->value
) * coord_scale
* measure_scale
;
928 /*printf( "Found text location x: %f\n", location.x );*/
931 location
.y
= (-1)*atof(data
->value
) * coord_scale
* measure_scale
;
932 /*printf( "Found text location y: %f\n", location.y );*/
935 location
.y
= (-1)*atof(data
->value
) * coord_scale
* measure_scale
;
936 /*location.y = (-1)*atof(data->value) / text_scale;*/
937 printf( "Found text location y: %f\n", location
.y
);
940 height
= atof(data
->value
) * coord_scale
* measure_scale
;
941 /*printf( "text height %f\n", height );*/
944 colour
= atoi(data
->value
);
945 text_colour
.red
= acad_pal
[colour
].r
/ 255.0;
946 text_colour
.green
= acad_pal
[colour
].g
/ 255.0;
947 text_colour
.blue
= acad_pal
[colour
].b
/ 255.0;
950 switch(atoi(data
->value
))
953 textalignment
= ALIGN_LEFT
;
956 textalignment
= ALIGN_CENTER
;
959 textalignment
= ALIGN_RIGHT
;
962 /* FIXME - it's not clear what these are */
965 /* FIXME - it's not clear what these are */
968 /* FIXME - it's not clear what these are */
973 switch(atoi(data
->value
))
977 /* FIXME - not really the same vertical alignment */
993 } while(codedxf
!= 0);
994 setlocale(LC_NUMERIC
,old_locale
);
996 location
.y
+= y_offset
* height
;
998 text_obj
= otype
->ops
->create(&location
, otype
->default_user_data
,
1000 layer_add_object(layer
, text_obj
);
1001 props
= prop_list_from_descs(dxf_text_prop_descs
,pdtpp_true
);
1002 g_assert(props
->len
== 1);
1004 tprop
= g_ptr_array_index(props
,0);
1005 g_free(tprop
->text_data
);
1006 tprop
->text_data
= textvalue
;
1007 tprop
->attr
.alignment
= textalignment
;
1008 tprop
->attr
.position
.x
= location
.x
;
1009 tprop
->attr
.position
.y
= location
.y
;
1011 attributes_get_default_font(&tprop
->attr
.font
, &tprop
->attr
.height
);
1012 tprop
->attr
.color
= text_colour
;
1014 text_obj
->ops
->set_props(text_obj
, props
);
1015 prop_list_free(props
);
1020 /* reads the layer table from the dxf file and creates the layers */
1021 void read_table_layer_dxf(FILE *filedxf
, DxfData
*data
, DiagramData
*dia
){
1025 if(read_dxf_codes(filedxf
, data
) == FALSE
){
1029 codedxf
= atoi(data
->code
);
1031 layer_find_by_name( data
->value
, dia
);
1034 } while ((codedxf
!= 0) || (strcmp(data
->value
, "ENDTAB") != 0));
1037 /* reads a scale entity from the dxf file */
1038 void read_entity_scale_dxf(FILE *filedxf
, DxfData
*data
, DiagramData
*dia
)
1042 if(read_dxf_codes(filedxf
, data
) == FALSE
)
1045 codedxf
= atoi(data
->code
);
1050 coord_scale
= atof(data
->value
);
1051 g_message(_("Scale: %f\n"), coord_scale
);
1060 /* reads a scale entity from the dxf file */
1061 void read_entity_measurement_dxf(FILE *filedxf
, DxfData
*data
,
1066 if(read_dxf_codes(filedxf
, data
) == FALSE
)
1069 codedxf
= atoi(data
->code
);
1074 /* value 0 = English, 1 = Metric */
1075 if( atoi( data
->value
) == 0 )
1076 measure_scale
= 2.54;
1078 measure_scale
= 1.0;
1079 /*printf( "Measure Scale: %f\n", measure_scale );*/
1088 /* reads a textsize entity from the dxf file */
1089 void read_entity_textsize_dxf(FILE *filedxf
, DxfData
*data
, DiagramData
*dia
){
1092 if(read_dxf_codes(filedxf
, data
) == FALSE
)
1095 codedxf
= atoi(data
->code
);
1100 text_scale
= atof(data
->value
);
1101 /*printf( "Text Size: %f\n", text_scale );*/
1109 /* reads the headers section of the dxf file */
1110 void read_section_header_dxf(FILE *filedxf
, DxfData
*data
, DiagramData
*dia
) {
1113 if(read_dxf_codes(filedxf
, data
) == FALSE
){
1117 codedxf
= atoi(data
->code
);
1118 if((codedxf
== 9) && (strcmp(data
->value
, "$DIMSCALE") == 0)) {
1119 read_entity_scale_dxf(filedxf
, data
, dia
);
1120 } else if((codedxf
== 9) && (strcmp(data
->value
, "$TEXTSIZE") == 0)) {
1121 read_entity_textsize_dxf(filedxf
, data
, dia
);
1122 } else if((codedxf
== 9) && (strcmp(data
->value
, "$MEASUREMENT") == 0)) {
1123 read_entity_measurement_dxf(filedxf
, data
, dia
);
1125 if(read_dxf_codes(filedxf
, data
) == FALSE
){
1130 } while ((codedxf
!= 0) || (strcmp(data
->value
, "ENDSEC") != 0));
1133 /* reads the classes section of the dxf file */
1134 void read_section_classes_dxf(FILE *filedxf
, DxfData
*data
, DiagramData
*dia
) {
1137 if(read_dxf_codes(filedxf
, data
) == FALSE
){
1141 codedxf
= atoi(data
->code
);
1142 if((codedxf
== 9) && (strcmp(data
->value
, "$LTSCALE") == 0)) {
1143 read_entity_scale_dxf(filedxf
, data
, dia
);
1144 } else if((codedxf
== 9) && (strcmp(data
->value
, "$TEXTSIZE") == 0)) {
1145 read_entity_textsize_dxf(filedxf
, data
, dia
);
1147 if(read_dxf_codes(filedxf
, data
) == FALSE
){
1152 } while ((codedxf
!= 0) || (strcmp(data
->value
, "ENDSEC") != 0));
1155 /* reads the tables section of the dxf file */
1156 void read_section_tables_dxf(FILE *filedxf
, DxfData
*data
, DiagramData
*dia
) {
1159 if(read_dxf_codes(filedxf
, data
) == FALSE
){
1163 codedxf
= atoi(data
->code
);
1164 if((codedxf
== 0) && (strcmp(data
->value
, "LAYER") == 0)) {
1165 read_table_layer_dxf(filedxf
, data
, dia
);
1168 if(read_dxf_codes(filedxf
, data
) == FALSE
){
1172 } while ((codedxf
!= 0) || (strcmp(data
->value
, "ENDSEC") != 0));
1175 /* reads the entities section of the dxf file */
1176 void read_section_entities_dxf(FILE *filedxf
, DxfData
*data
, DiagramData
*dia
) {
1179 if (read_dxf_codes(filedxf
, data
) == FALSE
){
1182 codedxf
= atoi(data
->code
);
1184 if((codedxf
== 0) && (strcmp(data
->value
, "LINE") == 0)) {
1185 read_entity_line_dxf(filedxf
, data
, dia
);
1186 } else if((codedxf
== 0) && (strcmp(data
->value
, "VERTEX") == 0)) {
1187 read_entity_line_dxf(filedxf
, data
, dia
);
1188 } else if((codedxf
== 0) && (strcmp(data
->value
, "SOLID") == 0)) {
1189 read_entity_solid_dxf(filedxf
, data
, dia
);
1190 } else if((codedxf
== 0) && (strcmp(data
->value
, "POLYLINE") == 0)) {
1191 read_entity_polyline_dxf(filedxf
, data
, dia
);
1192 } else if((codedxf
== 0) && (strcmp(data
->value
, "CIRCLE") == 0)) {
1193 read_entity_circle_dxf(filedxf
, data
, dia
);
1194 } else if((codedxf
== 0) && (strcmp(data
->value
, "ELLIPSE") == 0)) {
1195 read_entity_ellipse_dxf(filedxf
, data
, dia
);
1196 } else if((codedxf
== 0) && (strcmp(data
->value
, "TEXT") == 0)) {
1197 read_entity_text_dxf(filedxf
, data
, dia
);
1198 } else if((codedxf
== 0) && (strcmp(data
->value
, "ARC") == 0)) {
1199 read_entity_arc_dxf(filedxf
,data
,dia
);
1201 if(read_dxf_codes(filedxf
, data
) == FALSE
) {
1205 codedxf
= atoi(data
->code
);
1206 } while((codedxf
!= 0) || (strcmp(data
->value
, "ENDSEC") != 0));
1209 /* reads the blocks section of the dxf file */
1210 void read_section_blocks_dxf(FILE *filedxf
, DxfData
*data
, DiagramData
*dia
)
1212 int codedxf
, group_items
= 0, group
= 0;
1213 GList
*group_list
= NULL
;
1214 DiaObject
*obj
= NULL
;
1215 Layer
*group_layer
= NULL
;
1217 if (read_dxf_codes(filedxf
, data
) == FALSE
){
1220 codedxf
= atoi(data
->code
);
1222 if((codedxf
== 0) && (strcmp(data
->value
, "LINE") == 0)) {
1223 read_entity_line_dxf(filedxf
, data
, dia
);
1224 } else if((codedxf
== 0) && (strcmp(data
->value
, "SOLID") == 0)) {
1225 obj
= read_entity_solid_dxf(filedxf
, data
, dia
);
1226 } else if((codedxf
== 0) && (strcmp(data
->value
, "VERTEX") == 0)) {
1227 read_entity_line_dxf(filedxf
, data
, dia
);
1228 } else if((codedxf
== 0) && (strcmp(data
->value
, "POLYLINE") == 0)) {
1229 obj
= read_entity_polyline_dxf(filedxf
, data
, dia
);
1230 } else if((codedxf
== 0) && (strcmp(data
->value
, "CIRCLE") == 0)) {
1231 read_entity_circle_dxf(filedxf
, data
, dia
);
1232 } else if((codedxf
== 0) && (strcmp(data
->value
, "ELLIPSE") == 0)) {
1233 read_entity_ellipse_dxf(filedxf
, data
, dia
);
1234 } else if((codedxf
== 0) && (strcmp(data
->value
, "TEXT") == 0)) {
1235 obj
= read_entity_text_dxf(filedxf
, data
, dia
);
1236 } else if((codedxf
== 0) && (strcmp(data
->value
, "ARC") == 0)) {
1237 read_entity_arc_dxf(filedxf
,data
,dia
);
1238 } else if((codedxf
== 0) && (strcmp(data
->value
, "BLOCK") == 0)) {
1239 /* printf("Begin group\n" ); */
1247 if(read_dxf_codes(filedxf
, data
) == FALSE
)
1250 codedxf
= atoi(data
->code
);
1253 group_layer
= layer_find_by_name( data
->value
, dia
);
1255 } while( codedxf
!= 0 );
1257 } else if((codedxf
== 0) && (strcmp(data
->value
, "ENDBLK") == 0)) {
1258 /* printf( "End group %d\n", group_items ); */
1260 if( group
&& group_items
> 0 && group_list
!= NULL
)
1262 obj
= group_create( group_list
);
1263 if( NULL
== group_layer
)
1264 layer_add_object( dia
->active_layer
, obj
);
1266 layer_add_object( group_layer
, obj
);
1274 if(read_dxf_codes(filedxf
, data
) == FALSE
)
1278 if(read_dxf_codes(filedxf
, data
) == FALSE
) {
1283 if( group
&& obj
!= NULL
)
1287 group_list
= g_list_prepend( group_list
, obj
);
1292 codedxf
= atoi(data
->code
);
1293 } while((codedxf
!= 0) || (strcmp(data
->value
, "ENDSEC") != 0));
1296 /* imports the given dxf-file, returns TRUE if successful */
1298 import_dxf(const gchar
*filename
, DiagramData
*dia
, void* user_data
)
1304 filedxf
= fopen(filename
,"r");
1305 if(filedxf
== NULL
){
1306 message_error(_("Couldn't open: '%s' for reading.\n"),
1307 dia_message_filename(filename
));
1311 data
= g_new(DxfData
, 1);
1314 if(read_dxf_codes(filedxf
, data
) == FALSE
) {
1316 message_error(_("read_dxf_codes failed on '%s'\n"),
1317 dia_message_filename(filename
) );
1321 codedxf
= atoi(data
->code
);
1323 if(strcmp(data
->value
, "ENTITIES") == 0) {
1324 /*printf( "reading section entities\n" );*/
1325 read_section_entities_dxf(filedxf
, data
, dia
);
1327 else if(strcmp(data
->value
, "BLOCKS") == 0) {
1328 /*printf( "reading section BLOCKS\n" );*/
1329 read_section_blocks_dxf(filedxf
, data
, dia
);
1331 else if(strcmp(data
->value
, "CLASSES") == 0) {
1332 /*printf( "reading section CLASSES\n" );*/
1333 read_section_classes_dxf(filedxf
, data
, dia
);
1335 else if(strcmp(data
->value
, "HEADER") == 0) {
1336 /*printf( "reading section HEADER\n" );*/
1337 read_section_header_dxf(filedxf
, data
, dia
);
1339 else if(strcmp(data
->value
, "TABLES") == 0) {
1340 /*printf( "reading section tables\n" );*/
1341 read_section_tables_dxf(filedxf
, data
, dia
);
1343 else if(strcmp(data
->value
, "OBJECTS") == 0) {
1344 /*printf( "reading section objects\n" );*/
1345 read_section_entities_dxf(filedxf
, data
, dia
);
1349 g_warning(_("Unknown dxf code %d\n"), codedxf
);
1351 }while((codedxf
!= 0) || (strcmp(data
->value
, "EOF") != 0));
1358 /* reads a code/value pair from the DXF file */
1359 gboolean
read_dxf_codes(FILE *filedxf
, DxfData
*data
){
1363 if(fgets(data
->code
, DXF_LINE_LENGTH
, filedxf
) == NULL
){
1366 if(fgets(data
->value
, DXF_LINE_LENGTH
, filedxf
) == NULL
){
1370 for(i
=0; i
< DXF_LINE_LENGTH
; i
++){
1371 if((c
[i
] == '\n')||(c
[i
] == '\r')){
1379 /* interface from filter.h */
1381 static const gchar
*extensions
[] = {"dxf", NULL
};
1382 DiaImportFilter dxf_import_filter
= {
1383 N_("Drawing Interchange File"),