Skip to content

Commit b0616cc

Browse files
committed
indxf: VIEWPORT needs to create a matching VX_TABLE_RECORD
TODO: and if the VIEWPORT is *Active, it needs to set HEADER.VX_TABLE_RECORD On LAYOUT.active_viewport
1 parent 34e81d0 commit b0616cc

File tree

7 files changed

+72
-7
lines changed

7 files changed

+72
-7
lines changed

doc/LibreDWG.texi

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -734,6 +734,15 @@ All blocks are accessed via all other model_space BLOCK_HEADER's,
734734
holds a list of all table records, i.e. entries. Each table record
735735
entry has a name and other common table fields.
736736

737+
The VX table (also vport_entity table) is a special table until r2004
738+
for VIEWPORT entities, which are VPORT extensions, esp. for Paper
739+
Space, but have no old-style table records. So VX_CONTROL contains a
740+
list of matching VX_TABLE_RECORD's, which are pointed to by
741+
VIEWPORT.vport_entity_header handles. Likewise the VX_TABLE_RECORD
742+
object links in its viewport field back to the VIEWPORT. The VX table
743+
is not represented in DXF, on DXF import we need to create them with
744+
the VIEWPORT entities.
745+
737746
@node EXTRAS
738747
@section EXTRAS entities section
739748

examples/dwgadd.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1718,6 +1718,7 @@ dwg_add_dat (Dwg_Data **dwgp, Bit_Chain *dat)
17181718
CHK_MISSING_BLOCK_HEADER
17191719
if (!dwg_is_valid_name (dwg, text))
17201720
fn_error ("Invalid table record name\n");
1721+
// add's a VX also if <r2004
17211722
ent = (lastent_t){ .u.viewport = dwg_add_VIEWPORT (hdr, text),
17221723
.type = DWG_TYPE_VIEWPORT };
17231724
}

src/dwg.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ EXPORT int dwg_read_dxfb (Bit_Chain *restrict dat, Dwg_Data *restrict dwg);
7575
BITCODE_H
7676
dwg_find_tablehandle_silent (Dwg_Data *restrict dwg, const char *restrict name,
7777
const char *restrict table);
78+
BITCODE_RLL dwg_new_handseed (Dwg_Data *restrict dwg);
7879
// used in encode.c
7980
void dwg_set_handle_size (Dwg_Handle *restrict hdl);
8081
void dwg_downgrade_MLINESTYLE (Dwg_Object_MLINESTYLE *o);
@@ -2213,6 +2214,14 @@ dwg_add_handleref_free (const BITCODE_RC code, const BITCODE_RLL absref)
22132214
return ref;
22142215
}
22152216

2217+
BITCODE_RLL
2218+
dwg_new_handseed (Dwg_Data *restrict dwg)
2219+
{
2220+
BITCODE_RLL old = dwg->header_vars.HANDSEED->absolute_ref;
2221+
dwg->header_vars.HANDSEED->handleref.value++;
2222+
dwg->header_vars.HANDSEED->absolute_ref++;
2223+
return old;
2224+
}
22162225
// Not checking the header_vars entry, only searching the objects
22172226
// Returning a hardowner ref (code 3) to it, as stored in header_vars.
22182227
EXPORT BITCODE_H

src/dwg.spec

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2535,7 +2535,7 @@ DWG_ENTITY (VIEWPORT)
25352535

25362536
COMMON_ENTITY_HANDLE_DATA;
25372537
VERSIONS (R_13b1, R_14) {
2538-
FIELD_HANDLE (vport_entity_header, 5, 0);
2538+
FIELD_HANDLE (vport_entity_header, 5, 0); // => VX
25392539
}
25402540
VERSIONS (R_2000b, R_2002) {
25412541
HANDLE_VECTOR (frozen_layers, num_frozen_layers, 5, 341);
@@ -2546,7 +2546,7 @@ DWG_ENTITY (VIEWPORT)
25462546
FIELD_HANDLE (clip_boundary, 5, 340);
25472547
}
25482548
VERSIONS (R_2000b, R_2002) {
2549-
FIELD_HANDLE (vport_entity_header, 5, 0);
2549+
FIELD_HANDLE (vport_entity_header, 5, 0); // => VX
25502550
}
25512551
SINCE (R_2000b) {
25522552
FIELD_HANDLE (named_ucs, 5, 345);

src/dwg_api.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27088,13 +27088,25 @@ EXPORT Dwg_Entity_VIEWPORT *
2708827088
dwg_add_VIEWPORT (Dwg_Object_BLOCK_HEADER *restrict blkhdr,
2708927089
const char *restrict name)
2709027090
{
27091-
API_ADD_ENTITY (VIEWPORT);
27091+
Dwg_Object_VX_TABLE_RECORD *vx = NULL;
27092+
API_ADD_PREP (VIEWPORT);
2709227093
if (dwg->header.version < R_11)
2709327094
{
2709427095
LOG_ERROR ("Invalid entity %s <r11", "VIEWPORT")
27095-
API_UNADD_ENTITY;
2709627096
return NULL;
2709727097
}
27098+
if (dwg->header.version < R_2004)
27099+
{
27100+
vx = dwg_add_VX (dwg, name);
27101+
}
27102+
API_ADD_ENTITY2 (VIEWPORT);
27103+
if (dwg->header.version < R_2004 && vx)
27104+
{
27105+
Dwg_Object *vxobj = dwg_obj_generic_to_object (vx, &error);
27106+
vx->is_on = 1;
27107+
vx->viewport = dwg_add_handleref (dwg, 4, obj->handle.value, NULL);
27108+
_obj->vport_entity_header = dwg_add_handleref (dwg, 5, vxobj ? vxobj->handle.value : 0, NULL);
27109+
}
2709827110
// TODO get defaults from name
2709927111
_obj->lens_length = 50.0;
2710027112
_obj->VIEWDIR.z = 1.0;

src/header_variables.spec

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,8 @@
100100
}
101101
VERSIONS (R_13b1, R_2000)
102102
{
103-
FIELD_HANDLE (VX_TABLE_RECORD, 5, 0); //current view
103+
// => VX. VX.viewport <=> active_viewport in LAYOUT
104+
FIELD_HANDLE (VX_TABLE_RECORD, 5, 0); // current view
104105
}
105106
SINCE (R_13b1)
106107
{

src/in_dxf.c

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,12 +60,16 @@ Dwg_Object *dwg_obj_generic_to_object (const void *restrict obj,
6060
int *restrict error);
6161
#endif
6262
// from dwg_api.c
63-
EXPORT Dwg_Object_DICTIONARY *
63+
Dwg_Object_DICTIONARY *
6464
dwg_add_DICTIONARY (Dwg_Data *restrict dwg,
6565
const char *restrict name, /* the NOD entry */
6666
const char *restrict text, /* maybe NULL */
6767
const BITCODE_RLL absolute_ref);
68+
Dwg_Object_VX_TABLE_RECORD *
69+
dwg_add_VX (Dwg_Data *restrict dwg, const char *restrict name /* maybe NULL */);
6870
// from dwg.c
71+
BITCODE_RLL
72+
dwg_new_handseed (Dwg_Data *restrict dwg);
6973
BITCODE_H
7074
dwg_find_tablehandle_silent (Dwg_Data *restrict dwg, const char *restrict name,
7175
const char *restrict table);
@@ -9345,6 +9349,27 @@ Dxf_Pair *new_object (
93459349
LOG_TRACE ("Reuse existing BLOCK_HEADER.*Model_Space %X [0]\n",
93469350
pair->value.u)
93479351
}
9352+
// special-case VIEWPORT -> VX.
9353+
if (strEQc (name, "VIEWPORT") && dwg->header.version < R_2004
9354+
&& dwg->header.version > R_11 && pair->code == 5)
9355+
{
9356+
Dwg_Object_VX_TABLE_RECORD *vx = dwg_add_VX (dwg, "");
9357+
Dwg_Object *vxobj = dwg_obj_generic_to_object (vx, &error);
9358+
Dwg_Entity_VIEWPORT *_vobj = obj->tio.entity->tio.VIEWPORT;
9359+
if (dwg->header_vars.HANDSEED)
9360+
{
9361+
vxobj->handle.value = dwg_new_handseed (dwg);
9362+
}
9363+
// vx->is_on = 1;
9364+
vx->viewport
9365+
= dwg_add_handleref (dwg, 4, pair->value.u, NULL);
9366+
LOG_TRACE ("VX_TABLE_RECORD.viewport = " FORMAT_REF " [H 4]\n",
9367+
ARGS_REF (vx->viewport));
9368+
_vobj->vport_entity_header
9369+
= dwg_add_handleref (dwg, 5, vxobj->handle.value, NULL);
9370+
LOG_TRACE ("VIEWPORT.vport_entity_header = " FORMAT_REF " [H 5]\n",
9371+
ARGS_REF (_vobj->vport_entity_header));
9372+
}
93489373
if (strNE (name, "DIMSTYLE") || pair->code == 105)
93499374
{
93509375
obj->handle.value = pair->value.u;
@@ -12925,8 +12950,16 @@ dxf_entities_read (Bit_Chain *restrict dat, Dwg_Data *restrict dwg)
1292512950
}
1292612951
if (pair->code == 0 && pair->value.s)
1292712952
{
12928-
Dwg_Object *obj = &dwg->object[dwg->num_objects - 1];
12953+
BITCODE_BL last_ent = dwg->num_objects - 1;
12954+
Dwg_Object *obj = &dwg->object[last_ent];
1292912955
Dwg_Object_Entity *ent = obj->tio.entity;
12956+
// FIXUP hack for added VX and VX_CONTROL
12957+
while (obj->supertype != DWG_SUPERTYPE_ENTITY)
12958+
{
12959+
last_ent--;
12960+
obj = &dwg->object[last_ent];
12961+
ent = obj->tio.entity;
12962+
}
1293012963
if (ent->ownerhandle)
1293112964
{
1293212965
if (ent->ownerhandle->absolute_ref == mspace)

0 commit comments

Comments
 (0)