Skip to content

Commit

Permalink
Merge branch 'gh97-dynapi'
Browse files Browse the repository at this point in the history
Closes GH #97, but there are no test-cases for the new API yet.
  • Loading branch information
rurban committed Jul 18, 2019
2 parents 553aabe + b1c07a1 commit f5fa76d
Show file tree
Hide file tree
Showing 10 changed files with 3,271 additions and 2,476 deletions.
61 changes: 61 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,67 @@ GNU LibreDWG NEWS -- history of user-visible changes. -*-indented-text-*-
Copyright (C) 2019 Free Software Foundation, Inc.
See the end for copying conditions.

LibreDWG version 0.9 - released 2019/?? - beta:

new API:
* Added utf8text conversion functions to the dynapi:
dwg_dynapi_header_utf8text, dwg_dynapi_entity_utf8text,
dwg_dynapi_common_utf8text converting unicode strings to UTF-8.

API breaking changes:
* Added an is_utf8 arg to the dynapi setters:
dwg_dynapi_header_set_value, dwg_dynapi_entity_set_value,
dwg_dynapi_common_set_value, converting UTF-8 strings to TV or TU.
* Generalize object handles:
* Rename common field ownerhandle, exp. not NAME_control 330.
* Remove various null_handle fields.
* Rename LTYPE.null_handle to LTYPE.extref_handle
* Add SORTENTSTABLE.dict_handle (previous called ownerhandle,
it IS the ownerhandle. ok, there we do have both, the parenthandle
and the ownerhandle)
* Remove xrecord,proxy get_ownerhandle API
* Move ownerhandle to parent Object_Object along reactors and xdicobjhandle.
This field is common to all objects. (#118)
* Remove unneeded ownerhandle fields.
* Renamed STYLE.null_handle to STYLE.extref_handle

Important bugfixes:
* Fixed all remaining null pointer dereferences and memory leaks. We added
a smoke with asan, ubsan and lsan. The very first clang-analyzer scan
revealed not a single complaint!
* Fixed wrong object address (#112). handlestream_size is not part of obj->size.
This fixes the hdlpos += 8 FIXME's and many handles.
* Fixed FIELDLIST standard handles (#118)
* Fixed FIELD.childs and objects (#117)
* Fixed MLINESTYLE.ltype handles (#116)
* Fixed MULTILEADER content_block (#113)
* Added many missing handles 2007+ (#115)
Due to the fixed handle_stream offset, we can now reliably read many
more handles:
DIMENSION_ORDINATE
DIMENSION_LINEAR
DIMENSION_ALIGNED
DIMENSION_ANG3PT
DIMENSION_ANG2LN
DIMENSION_RADIUS
DIMENSION_DIAMETER
MTEXT
BLOCK_CONTROL
STYLE
SORTENTSTABLE
APPID
DICTIONARYVAR
VPORT_ENTITY_HEADER
Closes GH #114
* Fixed EED code 5 as int64 (#110)

Other newsworthy changes:
* Restricted the three dat, hdl_dat and str_dat streams in its size and
offset to the current object to detect every overflow. And report this
overflow.
* Better LOG_TRACE [rcount1], [rcount2] logging, expanded to the actual
index.

LibreDWG version 0.8 - released 2019/6/25 - still alpha:

new API:
Expand Down
101 changes: 49 additions & 52 deletions examples/dwg2svg2.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,23 @@ help (void)
fprintf (stderr, "ERROR: %s", msg); \
exit (1); \
}
#define log_error(msg) \
{ \
fprintf (stderr, "ERROR: %s", msg); \
exit (1); \
}
#define dynget(obj, name, field, var) \
if (!dwg_dynapi_entity_value (obj, "" name, "" field, var, NULL)) \
{ \
fprintf (stderr, "ERROR: %s.%s", name, field); \
exit (1); \
}
#define dynget_utf8(obj, name, field, var) \
if (!dwg_dynapi_entity_utf8text (obj, "" name, "" field, var, NULL)) \
{ \
fprintf (stderr, "ERROR: %s.%s", name, field); \
exit (1); \
}

static double
transform_X (double x)
Expand Down Expand Up @@ -117,28 +134,23 @@ output_TEXT (dwg_object *obj)
Dwg_Entity_TEXT *text;
char *text_value;
double fontsize;
const Dwg_Version_Type dwg_version = obj->parent->header.version;

index = dwg_object_get_index (obj, &error);
log_if_error ("object_get_index");
text = dwg_object_to_TEXT (obj);
if (!text)
{
error = 1;
log_if_error ("dwg_object_to_TEXT");
}
text_value = dwg_ent_text_get_text (text, &error);
log_if_error ("text_get_text");
dwg_ent_text_get_insertion_point (text, &ins_pt, &error);
log_if_error ("text_get_insertion_point");
fontsize = dwg_ent_text_get_height (text, &error);
log_if_error ("text_get_height");
log_error ("dwg_object_to_TEXT");
dynget_utf8 (text, "TEXT", "text_value", &text_value);
dynget (text, "TEXT", "insertion_pt", &ins_pt);
dynget (text, "TEXT", "height", &fontsize);

printf ("\t<text id=\"dwg-object-%d\" x=\"%f\" y=\"%f\" "
"font-family=\"Verdana\" font-size=\"%f\" fill=\"blue\">%s</text>\n",
index, transform_X (ins_pt.x), transform_Y (ins_pt.y), fontsize,
text_value);

if (text_value && obj->parent->header.version >= 15)
if (text_value && dwg_version >= R_2007)
free (text_value);
}

Expand All @@ -153,14 +165,12 @@ output_LINE (dwg_object *obj)
log_if_error ("object_get_index");
line = dwg_object_to_LINE (obj);
if (!line)
{
error = 1;
log_if_error ("dwg_object_to_LINE");
}
dwg_ent_line_get_start_point (line, &start, &error);
log_if_error ("line_get_start_point");
dwg_ent_line_get_end_point (line, &end, &error);
log_if_error ("line_get_end_point");
log_error ("dwg_object_to_LINE");
if (!dwg_get_LINE (line, "start", &start))
log_error ("LINE.start");
if (!dwg_get_LINE (line, "end", &end))
log_error ("LINE.end");

printf ("\t<path id=\"dwg-object-%d\" d=\"M %f,%f %f,%f\" "
"style=\"fill:none;stroke:blue;stroke-width:0.1px\" />\n",
index, transform_X (start.x), transform_Y (start.y),
Expand All @@ -179,14 +189,12 @@ output_CIRCLE (dwg_object *obj)
log_if_error ("object_get_index");
circle = dwg_object_to_CIRCLE (obj);
if (!circle)
{
error = 1;
log_if_error ("dwg_object_to_LINE");
}
dwg_ent_circle_get_center (circle, &center, &error);
log_if_error ("circle_get_center");
radius = dwg_ent_circle_get_radius (circle, &error);
log_if_error ("circle_get_radius");
log_error ("dwg_object_to_CIRCLE");
if (!dwg_get_CIRCLE (circle, "center", &center))
log_error ("CIRCLE.center");
if (!dwg_get_CIRCLE (circle, "radius", &radius))
log_error ("CIRCLE.radius");

printf ("\t<circle id=\"dwg-object-%d\" cx=\"%f\" cy=\"%f\" r=\"%f\" "
"fill=\"none\" stroke=\"blue\" stroke-width=\"0.1px\" />\n",
index, transform_X (center.x), transform_Y (center.y), radius);
Expand All @@ -206,25 +214,19 @@ output_ARC (dwg_object *obj)
log_if_error ("object_get_index");
arc = dwg_object_to_ARC (obj);
if (!arc)
{
error = 1;
log_if_error ("dwg_object_to_ARC");
}
radius = dwg_ent_arc_get_radius (arc, &error);
log_if_error ("arc_get_radius");
start_angle = dwg_ent_arc_get_start_angle (arc, &error);
log_if_error ("arc_get_start_angle");
end_angle = dwg_ent_arc_get_end_angle (arc, &error);
log_if_error ("arc_get_end_angle");
dwg_ent_arc_get_center (arc, &center, &error);
log_if_error ("arc_get_center");
log_error ("dwg_object_to_ARC");
dynget (arc, "ARC", "radius", &radius);
dynget (arc, "ARC", "center", &center);
dynget (arc, "ARC", "start_angle", &start_angle);
dynget (arc, "ARC", "end_angle", &end_angle);

x_start = center.x + radius * cos (start_angle);
y_start = center.y + radius * sin (start_angle);
x_end = center.x + radius * cos (end_angle);
y_end = center.y + radius * sin (end_angle);
// Assuming clockwise arcs.
large_arc = (end_angle - start_angle < 3.1415) ? 0 : 1;

printf ("\t<path id=\"dwg-object-%d\" d=\"M %f,%f A %f,%f 0 %d 0 %f,%f\" "
"fill=\"none\" stroke=\"blue\" stroke-width=\"%f\" />\n",
index, transform_X (x_start), transform_Y (y_start), radius, radius,
Expand All @@ -243,18 +245,12 @@ output_INSERT (dwg_object *obj)

insert = dwg_object_to_INSERT (obj);
if (!insert)
{
error = 1;
log_if_error ("dwg_object_to_INSERT");
}
log_error ("dwg_object_to_INSERT");
index = dwg_object_get_index (obj, &error);
log_if_error ("object_get_index");
rotation = dwg_ent_insert_get_rotation (insert, &error);
log_if_error ("insert_get_rotation");
dwg_ent_insert_get_ins_pt (insert, &ins_pt, &error);
log_if_error ("insert_get_ins_pt");
dwg_ent_insert_get_scale (insert, &_scale, &error);
log_if_error ("insert_get_scale");
dynget (insert, "INSERT", "rotation", &rotation);
dynget (insert, "INSERT", "ins_pt", &ins_pt);
dynget (insert, "INSERT", "scale", &_scale);
obj_handle = dwg_object_get_handle (obj, &error);
log_if_error ("get_handle");
ins_handle = &obj->handle;
Expand Down Expand Up @@ -341,10 +337,11 @@ output_BLOCK_HEADER (dwg_object_ref *ref)
}

_hdr = dwg_object_to_BLOCK_HEADER (hdr);
name = dwg_obj_block_header_get_name (_hdr, &error);
log_if_error ("block_header_get_name");
dynget (_hdr, "BLOCK_HEADER", "name", &name);
//name = dwg_obj_block_header_get_name (_hdr, &error);
//log_if_error ("block_header_get_name");
printf ("\t<g id=\"symbol-%lu\" >\n\t\t<!-- %s -->\n", abs_ref, name);
if (name != NULL && name != _hdr->name && hdr->parent->header.version >= 15)
if (name != NULL && name != _hdr->name && hdr->parent->header.version >= R_2007)
free (name);

obj = get_first_owned_entity (hdr);
Expand Down
29 changes: 27 additions & 2 deletions include/dwg.h
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,31 @@ typedef Dwg_Bitcode_3BD BITCODE_3BD_1;
typedef Dwg_Bitcode_3BD BITCODE_BE;
#define BITCODE_3DVECTOR BITCODE_3BD_1

typedef enum DWG_VERSION_TYPE
{
R_INVALID,
R_1_1, /* MC0.0 MicroCAD Release 1.1 */
R_1_2, /* AC1.2 AutoCAD Release 1.2 */
R_1_4, /* AC1.4 AutoCAD Release 1.4 */
R_2_0, /* AC1.50 AutoCAD Release 2.0 */
R_2_1, /* AC2.10 AutoCAD Release 2.10 */
R_2_5, /* AC1002 AutoCAD Release 2.5 */
R_2_6, /* AC1003 AutoCAD Release 2.6 */
R_9, /* AC1004 AutoCAD Release 9 */
R_10, /* AC1006 AutoCAD Release 10 */
R_11, /* AC1009 AutoCAD Release 11/12 (LT R1/R2) */
R_13, /* AC1012 AutoCAD Release 13 */
R_14, /* AC1014 AutoCAD Release 14 */
R_2000, /* AC1015 AutoCAD Release 2000 */
R_2004, /* AC1018 AutoCAD Release 2004 */
R_2007, /* AC1021 AutoCAD Release 2007 */
R_2010, /* AC1024 AutoCAD Release 2010 */
R_2013, /* AC1027 AutoCAD Release 2013 */
R_2018, /* AC1032 AutoCAD Release 2018 */
R_AFTER
} Dwg_Version_Type;
#define DWG_VERSIONS (int)(R_AFTER+1)

/**
Object supertypes that exist in dwg-files.
*/
Expand Down Expand Up @@ -5476,8 +5501,8 @@ typedef struct _dwg_struct
{
struct Dwg_Header
{
unsigned int version; /* see Dwg_Version_Type */
unsigned int from_version;
Dwg_Version_Type version; /* calculated from the header magic */
Dwg_Version_Type from_version; /* option. set by --as (convert from) */
BITCODE_RC zero_5[5];
BITCODE_RC is_maint;
BITCODE_RC zero_one_or_three;
Expand Down

0 comments on commit f5fa76d

Please sign in to comment.