[dia] dxf: respect specialties of SOLID and THICKNESS round-trip
- From: Hans Breuer <hans src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [dia] dxf: respect specialties of SOLID and THICKNESS round-trip
- Date: Sun, 19 Jun 2011 10:12:25 +0000 (UTC)
commit 71fe46cf8a0cf10b26e1e24500cba5466038405f
Author: Hans Breuer <hans breuer org>
Date: Sat Jun 18 12:30:00 2011 +0200
dxf: respect specialties of SOLID and THICKNESS round-trip
The order of SOLID points differs from Dia's. Also it is the
only way AFAICT to fill something.
The line THICKNESS was inconsistent with dxf-import.c. For me
it does not work at all to exchange line-width with other DXF
importers. Line-weight (370) almost does, but only with one
importer so it's still disabled.
Finally there was a bug when converting to g_ascci_formatd()
plug-ins/dxf/dxf-export.c | 79 ++++++++++++++++++++++++++++++++++-----------
plug-ins/dxf/dxf-import.c | 36 +++++++++++++++++---
2 files changed, 90 insertions(+), 25 deletions(-)
---
diff --git a/plug-ins/dxf/dxf-export.c b/plug-ins/dxf/dxf-export.c
index f0056b6..86cf518 100644
--- a/plug-ins/dxf/dxf-export.c
+++ b/plug-ins/dxf/dxf-export.c
@@ -39,6 +39,9 @@
#include "diarenderer.h"
#include "filter.h"
+/* used to be 10 and inconsistent with import and even here */
+#define MAGIC_THICKNESS_FACTOR (1.0)
+
#define DXF_TYPE_RENDERER (dxf_renderer_get_type ())
#define DXF_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), DXF_TYPE_RENDERER, DxfRenderer))
#define DXF_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), DXF_TYPE_RENDERER, DxfRendererClass))
@@ -258,7 +261,7 @@ end_render(DiaRenderer *self)
{
DxfRenderer *renderer = DXF_RENDERER(self);
- fprintf(renderer->file, "0\nENDSEC\n0\nEOF\n");
+ fprintf(renderer->file, " 0\nENDSEC\n 0\nEOF\n");
fclose(renderer->file);
}
@@ -361,8 +364,12 @@ draw_line(DiaRenderer *self,
fprintf(renderer->file, " 20\n%s\n", g_ascii_formatd (buf, sizeof(buf), "%g", (-1)*start->y));
fprintf(renderer->file, " 11\n%s\n", g_ascii_formatd (buf, sizeof(buf), "%g", end->x));
fprintf(renderer->file, " 21\n%s\n", g_ascii_formatd (buf, sizeof(buf), "%g", (-1)*end->y));
- fprintf(renderer->file, " 39\n%d\n", (int)(renderer->lcurrent.width)); /* Thickness */
+ fprintf(renderer->file, " 39\n%d\n", (int)(MAGIC_THICKNESS_FACTOR*renderer->lcurrent.width)); /* Thickness */
fprintf(renderer->file, " 62\n%d\n", dxf_color (line_colour));
+#if 0 /* approximately right effect, but only with one out of three DXF viewers */
+ /* Lineweight given in 100th of mm */
+ fprintf(renderer->file, "370\n%d\n", (int)(renderer->lcurrent.width * 1000.0));
+#endif
}
static void
@@ -410,6 +417,7 @@ fill_rect (DiaRenderer *self,
gchar buf2[G_ASCII_DTOSTR_BUF_SIZE];
fprintf(renderer->file, " 0\nSOLID\n");
+ fprintf(renderer->file, " 8\n%s\n", renderer->layername);
fprintf(renderer->file, " 62\n%d\n", dxf_color (color));
for (i = 0; i < 4; ++i)
fprintf(renderer->file, " %d\n%s\n %d\n%s\n",
@@ -418,11 +426,36 @@ fill_rect (DiaRenderer *self,
}
static void
-fill_polygon (DiaRenderer *renderer,
+fill_polygon (DiaRenderer *self,
Point *points, int num_points,
Color *color)
{
- /* not implemented, but no complaints by base class either */
+ DxfRenderer *renderer = DXF_RENDERER(self);
+ /* We could emulate all polygons with multiple SOLID but it might not be
+ * worth the effort. Following the easy part of polygons with 3 or 4 points.
+ */
+ int idx3[4] = {0, 1, 2, 2}; /* repeating last point is by specification
+ and should not be necessary but it helps
+ limited importers */
+ int idx4[4] = {0, 1, 3, 2}; /* SOLID point order differs from Dia's */
+ int *idx;
+ int i;
+ gchar buf[G_ASCII_DTOSTR_BUF_SIZE];
+ gchar buf2[G_ASCII_DTOSTR_BUF_SIZE];
+
+ if (num_points == 3)
+ idx = idx3;
+ else if (num_points == 4)
+ idx = idx4;
+ else
+ return; /* dont even try */
+ fprintf(renderer->file, " 0\nSOLID\n");
+ fprintf(renderer->file, " 8\n%s\n", renderer->layername);
+ fprintf(renderer->file, " 62\n%d\n", dxf_color (color));
+ for (i = 0; i < 4; ++i)
+ fprintf(renderer->file, " %d\n%s\n %d\n%s\n",
+ 10+i, g_ascii_formatd (buf, sizeof(buf), "%g", points[idx[i]].x),
+ 20+i, g_ascii_formatd (buf2, sizeof(buf2), "%g", -points[idx[i]].y));
}
static void
@@ -435,17 +468,21 @@ draw_arc(DiaRenderer *self,
DxfRenderer *renderer = DXF_RENDERER(self);
gchar buf[G_ASCII_DTOSTR_BUF_SIZE];
- if(height != 0.0){
+ if(width != 0.0){
fprintf(renderer->file, " 0\nARC\n");
fprintf(renderer->file, " 8\n%s\n", renderer->layername);
fprintf(renderer->file, " 6\n%s\n", renderer->lcurrent.style);
fprintf(renderer->file, " 10\n%s\n", g_ascii_formatd (buf, sizeof(buf), "%g", center->x));
fprintf(renderer->file, " 20\n%s\n", g_ascii_formatd (buf, sizeof(buf), "%g", (-1)*center->y));
fprintf(renderer->file, " 40\n%s\n", g_ascii_formatd (buf, sizeof(buf), "%g", width/2)); /* radius */
- fprintf(renderer->file, " 39\n%d\n", (int)(10*renderer->lcurrent.width)); /* Thickness */
- fprintf(renderer->file, " 50\n%s\n", g_ascii_formatd (buf, sizeof(buf), "%g", (angle1/360 ) * 2 * M_PI)); /*start angle */
- fprintf(renderer->file, " 51\n%f\n", g_ascii_formatd (buf, sizeof(buf), "%g", (angle2/360 ) * 2 * M_PI)); /* end angle */
+ fprintf(renderer->file, " 39\n%d\n", (int)(MAGIC_THICKNESS_FACTOR*renderer->lcurrent.width)); /* Thickness */
+ /* From specification: "output in degrees to DXF files". But radians work for all
+ * importers I tested. Also there seems to be a problem with arcs to be drawn counter-clockwise
+ */
+ fprintf(renderer->file, " 50\n%s\n", g_ascii_formatd (buf, sizeof(buf), "%g", (angle1/360 ) * 2 * M_PI)); /* start angle */
+ fprintf(renderer->file, " 51\n%s\n", g_ascii_formatd (buf, sizeof(buf), "%g", (angle2/360 ) * 2 * M_PI)); /* end angle */
}
+ fprintf(renderer->file, " 62\n%d\n", dxf_color (colour));
}
static void
@@ -455,7 +492,7 @@ fill_arc(DiaRenderer *self,
real angle1, real angle2,
Color *colour)
{
- draw_arc(self, center, width, height, angle1, angle2, colour);
+ /* emulate by SOLID? */
}
static void
@@ -475,7 +512,7 @@ draw_ellipse(DiaRenderer *self,
fprintf(renderer->file, " 10\n%s\n", g_ascii_formatd (buf, sizeof(buf), "%g", center->x));
fprintf(renderer->file, " 20\n%s\n", g_ascii_formatd (buf, sizeof(buf), "%g", (-1)*center->y));
fprintf(renderer->file, " 40\n%s\n", g_ascii_formatd (buf, sizeof(buf), "%g", height/2));
- fprintf(renderer->file, " 39\n%d\n", (int)(10*renderer->lcurrent.width)); /* Thickness */
+ fprintf(renderer->file, " 39\n%d\n", (int)(MAGIC_THICKNESS_FACTOR*renderer->lcurrent.width)); /* Thickness */
}
else if(height != 0.0){
fprintf(renderer->file, " 0\nELLIPSE\n");
@@ -485,10 +522,11 @@ draw_ellipse(DiaRenderer *self,
fprintf(renderer->file, " 20\n%s\n", g_ascii_formatd (buf, sizeof(buf), "%g", (-1)*center->y));
fprintf(renderer->file, " 11\n%s\n", g_ascii_formatd (buf, sizeof(buf), "%g", width/2)); /* Endpoint major axis relative to center X*/
fprintf(renderer->file, " 40\n%s\n", g_ascii_formatd (buf, sizeof(buf), "%g", height/width)); /*Ratio major/minor axis*/
- fprintf(renderer->file, " 39\n%d\n", (int)(10*renderer->lcurrent.width)); /* Thickness */
+ fprintf(renderer->file, " 39\n%d\n", (int)(MAGIC_THICKNESS_FACTOR*renderer->lcurrent.width)); /* Thickness */
fprintf(renderer->file, " 41\n%s\n", g_ascii_formatd (buf, sizeof(buf), "%g", 0.0)); /*Start Parameter full ellipse */
fprintf(renderer->file, " 42\n%s\n", g_ascii_formatd (buf, sizeof(buf), "%g", 2.0*3.14)); /* End Parameter full ellipse */
}
+ fprintf(renderer->file, " 62\n%d\n", dxf_color (colour));
}
static void
@@ -497,7 +535,7 @@ fill_ellipse(DiaRenderer *self,
real width, real height,
Color *colour)
{
- draw_ellipse(self, center, width, height, colour);
+ /* emulate by SOLID? */
}
@@ -531,7 +569,7 @@ draw_string(DiaRenderer *self,
}
fprintf(renderer->file, " 7\n%s\n", "0"); /* Text style */
fprintf(renderer->file, " 1\n%s\n", text);
- fprintf(renderer->file, " 39\n%d\n", (int)(10*renderer->lcurrent.width)); /* Thickness */
+ fprintf(renderer->file, " 39\n%d\n", (int)(MAGIC_THICKNESS_FACTOR*renderer->lcurrent.width)); /* Thickness */
fprintf(renderer->file, " 62\n%d\n", dxf_color(colour));
}
@@ -577,19 +615,22 @@ export_dxf(DiagramData *data, const gchar *filename,
fprintf(file, " 0\nENDSEC\n");
/* write layer description */
- fprintf(file,"0\nSECTION\n2\nTABLES\n0\nTABLE\n");
+ fprintf(file," 0\nSECTION\n 2\nTABLES\n 0\nTABLE\n");
+ /* some dummy entry to make it work for more DXF viewers */
+ fprintf(file," 2\nLAYER\n 70\n255\n");
+
for (i=0; i<data->layers->len; i++) {
layer = (Layer *) g_ptr_array_index(data->layers, i);
- fprintf(file,"0\nLAYER\n2\n%s\n",layer->name);
+ fprintf(file," 0\nLAYER\n 2\n%s\n",layer->name);
if(layer->visible)
- fprintf(file,"62\n%d\n",i+1);
+ fprintf(file," 62\n%d\n",i+1);
else
- fprintf(file,"62\n%d\n",(-1)*(i+1));
+ fprintf(file," 62\n%d\n",(-1)*(i+1));
}
- fprintf(file, "0\nENDTAB\n0\nENDSEC\n");
+ fprintf(file, " 0\nENDTAB\n 0\nENDSEC\n");
/* write graphics */
- fprintf(file,"0\nSECTION\n2\nENTITIES\n");
+ fprintf(file," 0\nSECTION\n 2\nENTITIES\n");
init_attributes(renderer);
diff --git a/plug-ins/dxf/dxf-import.c b/plug-ins/dxf/dxf-import.c
index bdab518..1d0b2a4 100644
--- a/plug-ins/dxf/dxf-import.c
+++ b/plug-ins/dxf/dxf-import.c
@@ -264,12 +264,12 @@ read_entity_solid_dxf(FILE *filedxf, DxfData *data, DiagramData *dia)
p[1].x = g_ascii_strtod(data->value, NULL) * coord_scale * measure_scale;
/*printf( "P1.x: %f ", p[1].x );*/
break;
- case 12:
- p[2].x = g_ascii_strtod(data->value, NULL) * coord_scale * measure_scale;
+ case 12: /* bot only swapped, but special for only 3 points given */
+ p[2].x = p[3].x = g_ascii_strtod(data->value, NULL) * coord_scale * measure_scale;
/*printf( "P2.x: %f ", p[2].x );*/
break;
- case 13:
- p[3].x = g_ascii_strtod(data->value, NULL) * coord_scale * measure_scale;
+ case 13: /* SOLID order swapped compared to Dia's */
+ p[2].x = g_ascii_strtod(data->value, NULL) * coord_scale * measure_scale;
/*printf( "P3.x: %f ", p[3].x );*/
break;
case 20:
@@ -281,11 +281,11 @@ read_entity_solid_dxf(FILE *filedxf, DxfData *data, DiagramData *dia)
/*printf( "P1.y: %f ", p[1].y );*/
break;
case 22:
- p[2].y = (-1)*g_ascii_strtod(data->value, NULL) * coord_scale * measure_scale;
+ p[2].y = p[3].y = (-1)*g_ascii_strtod(data->value, NULL) * coord_scale * measure_scale;
/*printf( "P2.y: %f ", p[2].y );*/
break;
case 23:
- p[3].y = (-1)*g_ascii_strtod(data->value, NULL) * coord_scale * measure_scale;
+ p[2].y = (-1)*g_ascii_strtod(data->value, NULL) * coord_scale * measure_scale;
/*printf( "P3.y: %f\n", p[3].y );*/
break;
case 39:
@@ -569,6 +569,7 @@ read_entity_circle_dxf(FILE *filedxf, DxfData *data, DiagramData *dia)
Handle *h1, *h2;
DiaObject *ellipse_obj;
+ RGB_t color;
Color line_colour = { 0.0, 0.0, 0.0, 1.0 };
GPtrArray *props;
@@ -596,6 +597,13 @@ read_entity_circle_dxf(FILE *filedxf, DxfData *data, DiagramData *dia)
case 40:
radius = g_ascii_strtod(data->value, NULL) * coord_scale * measure_scale;
break;
+ case 62 :
+ color = pal_get_rgb (atoi(data->value));
+ line_colour.red = color.r / 255.0;
+ line_colour.green = color.g / 255.0;
+ line_colour.blue = color.b / 255.0;
+ line_colour.alpha = 1.0;
+ break;
}
} while(data->code != 0);
@@ -639,6 +647,7 @@ read_entity_arc_dxf(FILE *filedxf, DxfData *data, DiagramData *dia)
Handle *h1, *h2;
DiaObject *arc_obj;
+ RGB_t color;
Color line_colour = { 0.0, 0.0, 0.0, 1.0 };
GPtrArray *props;
@@ -671,6 +680,13 @@ read_entity_arc_dxf(FILE *filedxf, DxfData *data, DiagramData *dia)
case 51:
end_angle = g_ascii_strtod(data->value, NULL)*M_PI/180.0;
break;
+ case 62 :
+ color = pal_get_rgb (atoi(data->value));
+ line_colour.red = color.r / 255.0;
+ line_colour.green = color.g / 255.0;
+ line_colour.blue = color.b / 255.0;
+ line_colour.alpha = 1.0;
+ break;
}
} while(data->code != 0);
@@ -722,6 +738,7 @@ read_entity_ellipse_dxf(FILE *filedxf, DxfData *data, DiagramData *dia)
Handle *h1, *h2;
DiaObject *ellipse_obj;
+ RGB_t color;
Color line_colour = { 0.0, 0.0, 0.0, 1.0 };
GPtrArray *props;
@@ -751,6 +768,13 @@ read_entity_ellipse_dxf(FILE *filedxf, DxfData *data, DiagramData *dia)
case 40:
width = g_ascii_strtod(data->value, NULL) * WIDTH_SCALE; /* XXX what scale */
break;
+ case 62 :
+ color = pal_get_rgb (atoi(data->value));
+ line_colour.red = color.r / 255.0;
+ line_colour.green = color.g / 255.0;
+ line_colour.blue = color.b / 255.0;
+ line_colour.alpha = 1.0;
+ break;
}
} while(data->code != 0);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]