\input texinfo @c -*-texinfo-*-
@c %**start of header
@setfilename LibreDWG.info
@include version.texi
@settitle LibreDWG @value{VERSION}

@c Use 2 indices, cp (with fn and pg), and vr for the rest (mostly included).
@c @syncodeindex vr cp
@synindex fn cp
@synindex tp cp
@synindex pg cp
@c %**end of header

@copying
This manual is for GNU LibreDWG (version @value{VERSION}, @value{UPDATED}).

Copyright @copyright{} 2010-2024 Free Software Foundation, Inc.

@quotation
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3 or
any later version published by the Free Software Foundation; with no
Invariant Sections, with no Front-Cover Texts, and with no Back-Cover
Texts.  A copy of the license is included in the section entitled
``GNU Free Documentation License''.
@end quotation

All other trademarks, trade names or company names referenced herein are
used for identification purposes only and are the property of their respective owners.

DWG is the native and proprietary file format for AutoCAD® and a trademark of Autodesk, Inc.
LibreDWG is neither associated with Autodesk, nor with the Open Design Alliance.
@end copying

@dircategory Libraries
@direntry
* LibreDWG: (LibreDWG).         Free implementation of the DWG file format.
@end direntry

@titlepage
@title GNU LibreDWG
@subtitle for version @value{VERSION}, @value{UPDATED}
@c Hey, if you change this, you can comment in the next lines
@author GNU LibreDWG Developers
@author and Thien-Thi Nguyen
@page
@vskip 0pt plus 1filll
@insertcopying
@end titlepage

@contents


@ifnottex
@node Top
@top GNU LibreDWG

@insertcopying
@end ifnottex

@menu
* Overview::            General purpose and information.
* Usage::               How to use LibreDWG.
* Types::               Common types, enums, structs.
* Objects::             All supported objects and entities.
* Sections::            All supported sections.
* Structures::          Special structures.
* Functions::           Call them.
* Errors::              Error levels.
* Programs::            Included binaries.
* Bindings::            Bindings to other languages.
* Reference API::

* Reporting bugs::      Sending bug reports and feature suggestions.
* GNU Free Documentation License:: Copying and sharing this documentation.
* Index::
@end menu


@node Overview
@chapter Overview

@cindex overview
@cindex dwg file format
@cindex license

LibreDWG is a free C library to read and write @dfn{DWG files}.
The DWG file format is proprietary and was created in the 1970s for
one then-emerging CAD application.

This library is part of the GNU project, released under the aegis of
GNU.  It is made available under GPLv3+, i.e., under the terms of the
GNU General Public License version 3, or (at your option) any later
version.

It came out of code from the QCad Community Edition product from
Ribbonsoft.

@section API/ABI version

@cindex version, API/ABI

LibreDWG @value{VERSION} provides the API/ABI version 1.
We hope that this doesn't need to change much in the future.

See @file{include/dwg.h} for @code{LIBREDWG_VERSION_MAJOR}, 
@code{LIBREDWG_VERSION_MINOR} and @code{LIBREDWG_SO_VERSION}.

@ignore
In the past, these were released:

@table @code
@c [???] For first release, there is no history.  However, might me want
@c to describe the difference between LibreDWG and LibDWG here?  --ttn
@item 0
...
@end table
@end ignore

@section Coverage

@cindex coverage

Because the DWG file format is not open, its specification had to be
reverse-engineered.  The specification is almost complete.
The LibreDWG implementation of the specification is an ongoing process;
as of version @value{VERSION}, coverage is approximately 99%.

It can read all DWG formats from r1.2 to r2018 for 99%.
The internally supported DWG revisions are identified as
r1.1, r1.2, r1.3, r1.4, r2.0b, r2.0, r2.10, r2.21, r2.22, r2.4, r2.5, r2.6,
r9, r9c1, r10, r11b1, r11b2, r11, r13b1, r13b2, r13, r13c3, r14, r2000b, r2000,
r2000i, r2002, r2004a, r2004b, r2004c, r2004, r2007a, r2007b, r2007, r2010b,
r2010, r2013b, r2013, r2018b and r2018.

Here is a list of features that are still missing:

@cindex features, still missing

@table @asis

@item Writing r2004+ DWG
Writing DWG formats for r2004 and later: r2007, r2010, r2013, r2018 is an
ongoing effort. You need to patch the code to enable writing to the r2004+ format.
See the @code{work/2004} branch.
Writing to the specific r2007 format is not implemented.
We write as default in the r2000 or older formats only.

@item Reading binary DXF
DXF support is now mostly implemented.
ASCII DXF's are generated fully, with much more elements and fields and other free libraries,
but AutoCAD @registeredsymbol{} fails to import some of them. See the @file{TODO} file for a detailed coverage report.

Reading binary DXF should be complete but is undertested.

@item Reading and writing pre-R13 DXF
Reading and writing pre-R13 DXF's is work in progress.
There is no support planned for the very old pre-R2.0 DXF format.

@item Enabled entities and objects, but unstable, undertested. Field names may change:

For a detailed overview see the file @file{src/classes.inc} or @file{src/classes.c}.

  ACSH_BREP_CLASS ACSH_CHAMFER_CLASS ACSH_CONE_CLASS
  ACSH_PYRAMID_CLASS ARC_DIMENSION ASSOCACTION
  ASSOCBLENDSURFACEACTIONBODY ASSOCEXTENDSURFACEACTIONBODY
  ASSOCEXTRUDEDSURFACEACTIONBODY ASSOCFILLETSURFACEACTIONBODY
  ASSOCGEOMDEPENDENCY ASSOCLOFTEDSURFACEACTIONBODY ASSOCNETWORK
  ASSOCDEPENDENCY ASSOCVALUEDEPENDENCY ASSOCNETWORKSURFACEACTIONBODY
  ASSOCOFFSETSURFACEACTIONBODY ASSOCPATCHSURFACEACTIONBODY
  ASSOCPLANESURFACEACTIONBODY ASSOCREVOLVEDSURFACEACTIONBODY
  ASSOCTRIMSURFACEACTIONBODY BACKGROUND BLOCKLINEARPARAMETER
  BLOCKROTATIONPARAMETER BLOCKXYPARAMETER BLOCKVISIBILITYGRIP
  BLOCKVISIBILITYPARAMETER EVALUATION_GRAPH HELIX
  LARGE_RADIAL_DIMENSION LIGHTLIST MATERIAL MENTALRAYRENDERSETTINGS
  OBJECT_PTR RAPIDRTRENDERSETTINGS RENDERSETTINGS SECTION_SETTINGS
  SPATIAL_INDEX SUN TABLESTYLE (works only pre-2010)

@item Unhandled (fields spec'ed, but broken/undertested):

  ACMECOMMANDHISTORY ACMESCOPE ACMESTATEMGR ACSH_EXTRUSION_CLASS
  ACSH_LOFT_CLASS ACSH_REVOLVE_CLASS ACSH_SWEEP_CLASS
  ALDIMOBJECTCONTEXTDATA ANNOTSCALEOBJECTCONTEXTDATA
  ASSOC2DCONSTRAINTGROUP ASSOCACTION ASSOCALIGNEDDIMACTIONBODY
  ASSOCEXTRUDEDSURFACEACTIONBODY ASSOCGEOMDEPENDENCY
  ASSOCLOFTEDSURFACEACTIONBODY ASSOCNETWORK
  ASSOCOSNAPPOINTREFACTIONPARAM ASSOCOSNAPPOINTREFACTIONPARAM
  ASSOCPERSSUBENTMANAGER ASSOCREVOLVEDSURFACEACTIONBODY
  ASSOCVERTEXACTIONPARAM ATEXT BLKREFOBJECTCONTEXTDATA
  CONTEXTDATAMANAGER CSACDOCUMENTOPTIONS CURVEPATH DATALINK DATATABLE
  DIMASSOC DYNAMICBLOCKPROXYNODE EXTRUDEDSURFACE FCFOBJECTCONTEXTDATA
  GEOMAPIMAGE GEOPOSITIONMARKER LAYOUTPRINTCONFIG
  LEADEROBJECTCONTEXTDATA LOFTEDSURFACE MLEADEROBJECTCONTEXTDATA
  MOTIONPATH MTEXTATTRIBUTEOBJECTCONTEXTDATA MTEXTOBJECTCONTEXTDATA
  NAVISWORKSMODEL NAVISWORKSMODELDEF NURBSURFACE PERSUBENTMGR
  PLANESURFACE POINTPATH RENDERENTRY RENDERGLOBAL
  REVOLVEDSURFACE RTEXT SUNSTUDY SWEPTSURFACE TABLE (works only
  pre-2010) TABLECONTENT TEXTOBJECTCONTEXTDATA TVDEVICEPROPERTIES

  ASSOCDIMDEPENDENCYBODY BLOCKPARAMDEPENDENCYBODY
  ALIGNMENTPARAMETERENTITY BASEPOINTPARAMETERENTITY
  FLIPPARAMETERENTITY LINEARPARAMETERENTITY POINTPARAMETERENTITY
  ROTATIONPARAMETERENTITY VISIBILITYPARAMETERENTITY
  VISIBILITYGRIPENTITY XYPARAMETERENTITY
  BLOCKALIGNEDCONSTRAINTPARAMETER BLOCKANGULARCONSTRAINTPARAMETER
  BLOCKARRAYACTION BLOCKDIAMETRICCONSTRAINTPARAMETER
  BLOCKHORIZONTALCONSTRAINTPARAMETER BLOCKLINEARCONSTRAINTPARAMETER
  BLOCKLOOKUPACTION BLOCKLOOKUPPARAMETER BLOCKPOINTPARAMETER
  BLOCKPOLARGRIP BLOCKPOLARPARAMETER BLOCKPOLARSTRETCHACTION
  BLOCKPROPERTIESTABLE BLOCKPROPERTIESTABLEGRIP
  BLOCKRADIALCONSTRAINTPARAMETER BLOCKREPRESENTATION BLOCKSTRETCHACTION
  BLOCKUSERPARAMETER BLOCKVERTICALCONSTRAINTPARAMETER BLOCKXYGRIP
  POINTCLOUD POINTCLOUDEX POINTCLOUDDEF POINTCLOUDDEFEX
  POINTCLOUDDEF_REACTOR POINTCLOUDDEF_REACTOR_EX POINTCLOUDCOLORMAP

See @file{src/classes.inc}.

Missing:

* PROXY subentities, PROXY_ENTITY

Halfway:

  SUNSTUDY VBA_PROJECT ASSOCACTION ASSOCNETWORK
  ASSOCALIGNEDDIMACTIONBODY ASSOCOSNAPPOINTREFACTIONPARAM
  ASSOCPERSSUBENTMANAGER PERSUBENTMGR ASSOC2DCONSTRAINTGROUP EVALUATION_GRAPH
  ASSOCOSNAPPOINTREFACTIONPARAM ACSH_BOX_CLASS ACSH_EXTRUSION_CLASS
  ACSH_HISTORY_CLASS ACSH_SWEEP_CLASS NAVISWORKSMODEL (i.e. COORDINATION MODEL)
  NAVISWORKSMODELDEF DATATABLE TABLESTYLE ASSOCGEOMDEPENDENCY LAYOUTPRINTCONFIG
  RENDERENVIRONMENT RENDERGLOBAL LIGHTLIST SECTION_SETTINGS

@item Unhandled (i.e. passed through, no DXF and fields):

   ACDSRECORD ACDSSCHEMA NPOCOLLECTION
   RAPIDRTRENDERENVIRONMENT XREFPANELOBJECT

@item no test coverage for entities:

I.e. we need an extended @file{example_2018.dwg} with all types,
with the following missing entities:

  ARCALIGNEDTEXT BODY CAMERA DIMENSION_ANG3PT DIMENSION_DIAMETER
  DIMENSION_RADIUS DGNUNDERLAY DWFUNDERLAY
  GEOPOSITIONMARKER IMAGE LEADER LONG_TRANSACTION MESH MINSERT
  OLE2FRAME OLEFRAME POLYLINE_2D POLYLINE_MESH
  PROXY_ENTITY PROXY_LWPOLYLINE SHAPE
  TOLERANCE VERTEX_2D VERTEX_MESH

and objects:

  CSACDOCUMENTOPTIONS XREFPANELOBJECT IDBUFFER IMAGEDEF
  IMAGEDEF_REACTOR LAYER_INDEX LIGHTLIST
  NPOCOLLECTION OBJECT_PTR PLOTSETTINGS PROXY_OBJECT
  RASTERVARIABLES SPATIAL_INDEX UCS VBA_PROJECT

@end table

@section Related projects

@cindex projects, related

Some projects that use DWG (and specifically LibreDWG) are:

@table @asis
@item FreeCAD
@url{https://freecadweb.org/}

@item GRASS GIS
@url{http://grass.osgeo.org/}
@end table

Plans are to add support for SolveSpace, LibreCAD, FreeCAD, OpenSCAD
and PythonCAD.

Related libraries:

@table @asis
@item libdwg
The old version (documented in Esperanto) which was forked to LibreDWG in 2009.
But in the meantime it got a DXF reader.
@item libdxfrw
Read the DWG format for all versions r13+ but with much less elements,
only those needed for DXF.
Written in C++, under the GPLv2 license.
@item libopencad
Read the r2000 DWG format.
Written in C++, under the GPLv2 license.
@item ACadSharp
Read and write the basic objects in most DWG and DXF formats.
Written in C#, under the MIT license.
@item OpenDWG
The OpenDWG's license does not allow the usage in free software projects.
@end table

Compared to libdwg, libdxfrw and libopencad, LibreDWG can read and
write much more DWG versions and details. Which is especially important for
attached links and data from third party applications:
BIM, MAP, GIS, AEC, MECH, ..., for 3D solids and dynamic parametric constraints.

@node Usage
@chapter Usage

@cindex header
@cindex compilation
@cindex linking

This chapter describes how to compile and link a program against
LibreDWG.  To access LibreDWG interface elements (@pxref{Types},
@pxref{Functions}), include its header file in the C code.

@example
#include <dwg.h>
@end example

Optionally you can also use the 
@example
#include <dwg_api.h>
@end example
API.

@noindent
Make sure you specify @samp{-lredwg} when linking,
such as in this @file{Makefile.am} fragment:

@example
AM_LDFLAGS += -lredwg
@end example

@noindent
Note that the shared object library is named @file{libredwg} (with some
system-specific extension, e.g., @file{.so}), so you do @strong{not}
want to specify @code{-llibredwg}, as that would (try to) link against
@file{liblibredwg} and fail.


@node Types
@chapter Types

@cindex data types
@cindex enums
@cindex structs

LibreDWG types map closely to the type system of the DWG file format.
This chapter describes the enums and structs used to define the single
DWG structure, which is passed around the functions (@pxref{Functions}).

@deftypevr {define} BITCODE_RC char
1 raw unsigned char, uint8_t
@end deftypevr
@deftypevr {define} BITCODE_RS short
1 raw unsigned short int, uint16_t
@end deftypevr
@deftypevr {define} BITCODE_RL long
1 raw unsigned long int, uint32_t
@end deftypevr
@deftypevr {define} BITCODE_RD double
1 raw IEEE-754 double
@end deftypevr
@deftypevr {define} BITCODE_B byte
1 bit
@end deftypevr
@deftypevr {define} BITCODE_BB byte
2 bits
@end deftypevr
@deftypevr {define} BITCODE_3B byte
1-3 bits
@end deftypevr
@deftypevr {define} BITCODE_4BITS byte
4 bits (for VIEW view_mode)
@end deftypevr
@deftypevr {define} BITCODE_BS short
1 bit-encoded unsigned short
@end deftypevr
@deftypevr {define} BITCODE_BL long
1 bit-encoded unsigned long (max 32bit)
@end deftypevr
@deftypevr {define} BITCODE_BLL uint64_t
1 bit-encoded unsigned 64bit long
@end deftypevr
@deftypevr {define} BITCODE_BD double
1 bit-encoded double
@end deftypevr
@deftypevr {define} BITCODE_DD double
1 bit-encoded double with default
@end deftypevr
@deftypevr {define} BITCODE_MC long int
1-4 modular chars
@end deftypevr
@deftypevr {define} BITCODE_UMC long unsigned int
1-4 unsigned modular chars
@end deftypevr
@deftypevr {define} BITCODE_MS long unsigned int
1 modular short, max 2 words
@end deftypevr
@deftypevr {define} BITCODE_BE double[3]
1 bitencoded extrusion vector.

Note that this specifies an OCS (Object Coordinate System) for each
entity, with the default (0, 0, 1).  An extrusion of (0, 0, -1) is
typically caused by exploding a block inserted with a negative x
scale, i.e. the sign of each X point needs to be flipped.  For more
see the vendor DXF documentation on OCS and @file{programs/geom.c}.

@cindex OCS
@end deftypevr
@deftypevr {define} BITCODE_BT double
1 bitencoded thickness value
@end deftypevr
@deftypevr {define} BITCODE_TV char*
length + ASCIIZ string
The default text type until r2004.
@end deftypevr
@deftypevr {define} BITCODE_TU wchar*
length + windows 2-byte wchar string (UCS-2).
The default text type since r2007.
@end deftypevr
@deftypevr {define} BITCODE_TF char*
Fixed length buffer, which can include NUL characters.
@end deftypevr
@deftypevr {define} BITCODE_TFF char*
Embedded fixed length string, which can include NUL characters.
@end deftypevr
@deftypevr {define} BITCODE_H void*
handle-references
@end deftypevr
@deftypevr {define} BITCODE_CMC struct Dwg_Color
Dwg_Color struct with index or rgb, alpha and optional DBCOLOR handle, name, book_name.
@end deftypevr
[and some more]

@cindex return code
@cindex code, return
@cindex error code
@cindex code, error

Two types that do not derive from the type system of the DWG file format
are the enums for return codes and error codes.

On non-C99 systems ensure that stdint.h and inttypes.h are available
to use the proper C99 @code{int32_t},... types, and not just the
native fallback types int/long, which are different across platforms.

@node Objects
@chapter Objects

@c TODO CLASSES, TABLES? Or maybe add a ``is a table'' note to the object.
@menu
* HEADER::            All Header variables
* ENTITIES::          All Entities and its special and common fields
* OBJECTS::           All Objects and its special and common fields
@end menu

@include dynapi.texi

@node Sections
@chapter Sections
@cindex Sections

@menu
* HEADER_::           All Header variables
* OBJECTS_::          All Entities and Objects
* CLASSES::           The dynamically loaded class types
* HANDLES::           The sorted handle map (relative handle and size) of all objects
* R2004_Header::      r2004 Section meta-data to find the INFO and SYSTEM_MAP
* UNKNOWN::           Unknown Section
* SummaryInfo::       Some dwg meta-data
* Preview::           The Thumbnail BMP or WMF data
* VBAProject::        VBA Section
* AppInfo::           Which product and version exactly created that DWG
* AppInfoHistory::    AppInfoHistory Section
* FileDepList::       Features and File Dependencies. Image files, fonts, xrefs, plotconfigs.
* AcDS::              The AcDsPrototype_1b DataStorage, used mostly for binary ACIS blobs
* RevHistory::        Revision History
* Security::          Password Info
* ObjFreeSpace::      Some Objects meta-data
* Template::          Contains one Measurement Header variable.
* AuxHeader::         In case the original Header gets lost
* Signature::         Signature Section
* INFO::              The info of all used sections
* SYSTEM_MAP::        The map of all used sections and its chunked pages
* Tables::            How the old tables are mapped into the new objects
* EXTRAS::            The r10-r11 EXTRAS entity section
@end menu

The r2000 format (used for r13-r2000) knows the following 6 sections:

    HEADER
    CLASSES
    HANDLES
    OBJFREESPACE +
      2NDHEADER
    MEASUREMENT/TEMPLATE
    AUXHEADER (only r2000)

The r2004 and r2007 format (used for r2004-r2018) knows the following sections:

    R2004_Header
    UNKNOWN
    SUMMARYINFO
    PREVIEW
    VBAPROJECT
    APPINFO
    APPINFOHISTORY
    FILEDEPLIST
    ACDS
    REVHISTORY
    SECURITY
    OBJECTS
    OBJFREESPACE
    TEMPLATE
    HANDLES
    CLASSES
    AUXHEADER
    HEADER
    SIGNATURE
    INFO
    SYSTEM_MAP

The old pre-R13 formats (from r1.1 to r11) have those sections, with the
tables interleaved into the HEADER.

    HEADER
    ENTITIES
    BLOCKS entities
    EXTRAS entities

With (from r1.1 to r10) those 5 @ref{Tables}:

    BLOCKS
    LAYER
    STYLE
    LTYPE
    VIEW

With r11 came the additional tables:

    UCS
    VPORT
    APPID
    DIMSTYLE
    VX

But we convert them internally to r2004 table record and
table control objects. @xref{Tables}.

@node HEADER_
@section HEADER Section

@xref{Objects, HEADER}.

@node OBJECTS_
@section OBJECTS Section

The OBJECTS Section is usually split up into multiple pages (separate
sections of type AcDbObjects) and contains all entities and
objects. It is indexed by @ref{HANDLES}.

@xref{Objects, OBJECTS}.

@node CLASSES
@section CLASSES Section

The @strong{Classes} Section contains the basic info for all dynamically loaded types for entities and objects.
Its types start with 500, and are variable. An entity which has no class loaded is displayed as proxy.

LibreDWG contains support for many classes, but not all. See @file{src/classes.inc} and @file{src/classes.c}.
We define a stability for each class, one of stable, unstable, debugging and unhandled.

Objects in @strong{stable} classes are treated as the fixed-type objects with full support. Changes are treated as API breaking.

Objects in @strong{unstable} classes are sometimes written to DXF or JSON, but not to DWG. Changes are not treated as API breaking. Usually such objects are converted to UNKNOWN_OBJ or UNKNOWN_ENT objects, and when written to DWG converted to PLACEHOLDER, DUMMY or POINT objects with EED pointing to the original class and content.
Only when rewriting from-to the very same version with the full known unknown_bits blob (e.g. dwgrewrite or json) such classes can persist as such.

Objects in @strong{debugging} classes are only handled with the developer @code{configure --enable-debug} flag, otherwise ignored. See unstable above.

Objects in @strong{undhandled} classes are always ignored. There are no fields known, only its type.

@node HANDLES
@section HANDLES Section

The Handles section contains a sorted list of all object handles and its position in the Objects stream.
All values are stored relatively, as offsets. Handles only increase and can contain holews when an object is deleted, offsets can jump back also.

@node R2004_Header
@section R2004_Header

The R2004_Header section at fixed position @code{0x100} in the DWG contains some meta-data for r2004 sections to find the two important sections INFO and SYSTEM_MAP.

@node UNKNOWN
@section UNKNOWN Section

The content of the UNKNOWN section with type 0 is unknown and does not always exist.

@node SummaryInfo
@section SummaryInfo
@cindex SummaryInfo

All Section SummaryInfo fields:

@indentedblock
@vtable @code

@item TITLE
TU16,	DXF 1
@item SUBJECT
TU16,	DXF 1
@item AUTHOR
TU16,	DXF 1
@item KEYWORDS
TU16,	DXF 1
@item COMMENTS
TU16,	DXF 1
@item LASTSAVEDBY
TU16,	DXF 1
@item REVISIONNUMBER
TU16,	DXF 1
@item HYPERLINKBASE
TU16,	DXF 1
@item TDINDWG
TIMERLL
@item TDCREATE
TIMERLL
@item TDUPDATE
TIMERLL
@item num_props
RS
@item props
Dwg_SummaryInfo_Property*
@item unknown1
RL
@item unknown2
RL

@end vtable
@end indentedblock

@xref{Dwg_SummaryInfo_Property}

@node Preview
@section Preview

The optional Preview section contains the thumbnail stream of BMP, WMF or PNG data of the drawing. Note that blocks or proxy objects can also contain its own preview fields. The program @strong{dwgbmp} can extract the preview image from this section.

@node VBAProject
@section VBAProject

@node AppInfo
@section AppInfo

Which product and version exactly created that DWG.

@node AppInfoHistory
@section AppInfoHistory

@node FileDepList
@section FileDepList

Features and File Dependencies. Image files, fonts, xrefs, plotconfigs.

@node AcDS
@section AcDS

The AcDsPrototype_1b DataStorage, used mostly for binary ACIS blobs, embedded fonts, ...

@node RevHistory
@section RevHistory

Revision History

@node Security
@section Security

Password Info

@node ObjFreeSpace
@section ObjFreeSpace

Some Objects meta-data

@node Template
@section Template

Contains one Measurement Header variable.
 
@node AuxHeader
@section AuxHeader

In case the original Header gets lost.

@node Signature
@section Signature

@node INFO
@section INFO

The info of all used sections.

@node SYSTEM_MAP
@section SYSTEM_MAP

The map of all used sections and its chunked pages.

@node Tables
@section Tables
@cindex Tables

The old pre-R13 formats (from r1.1 to r11) have no objects and no sections,
just tables, which we store in the sections indexed by the enum
@b{Dwg_Section_Type_r11}.

    BLOCKS
    LAYER
    STYLE
    LTYPE
    VIEW

With r11 came the additional tables:

    UCS
    VPORT
    APPID
    DIMSTYLE
    VX

Since r13 all those tables are stored as table control objects and
tablerecord objects.

From pre-r13 DWG's these tables are imported as old r11 sections and
as new CONTROL objects, so that all entities are accessible via the
single BLOCK_CONTROL.model_space -> BLOCK_HEADER.entities iterator,
all layers via the LAYER_CONTROL.entries -> LAYER objects, and so on.
All blocks are accessed via all other model_space BLOCK_HEADER's,
@code{get_first_owned_block (BLOCK_HEADER)}.  Each CONTROL object
holds a list of all table records, i.e. entries.  Each table record
entry has a name and other common table fields.

@node EXTRAS
@section EXTRAS entities section

Before R13 we had no objects, just the 5-10 tables, and the entities divided into 3 sections.
The entities, the blocks and the extras.
Blocks just contains the entities from each BLOCK to the ENDBLK entity.

Extras contain entities which had no room in the original section,
e.g. when closing a polyline, which needs one additional byte. Thus
the original entity is replaced by an undocumented JUMP entity, which
gives the offset into the EXTRAS section, until a JUMP in the EXTRAS
jumps back to the next original entity.

See e.g. @file{r10/entities.dwg}

The JUMP [31] replaces the POLYLINE_2D entity which got later
closed. An open POLYLINE_2D needs size 8, but closed 9 bytes. Hence
they added the new closed replacement to the extras section at offset
0, index [66], and added another JUMP [67] back to the next original
entity. Here it jumps back to the VERTEX_2D [32] at offset 0x84f.

@example
  type: 18 [RCd]
  Add entity JUMP [31] Decode entity JUMP
  ===========================
  Entity number: 31, Type: 18, Addr: 847
  flag_r11: 0x0 [RC 0]
  size: 8 [RS]
  jump_address_raw: 0x80000000 [RLx 0]
  jump_entity_section: DWG_EXTRA_SECTION
  jump_address: 0x0

  type: 20 [RCd]
  Add entity VERTEX_2D [32] Decode entity VERTEX_2D
  ===========================
  Entity number: 32, Type: 20, Addr: 84f
  flag_r11: 0x0 [RC 0]
  size: 24 [RS]
  layer: 0 [H(RSd) 8]
  opts_r11: 0x0 [RSx 0]
  point: (5.500000, 7.500000) [2RD 10]

  ....

  extras entities: (0x10c0-0x10d1 (0), size 17)
  ==========================================
  type: 19 [RCd]
  Add entity POLYLINE_2D [66] Decode entity POLYLINE_2D
  ===========================
  Entity number: 66, Type: 19, Addr: 10c0
  flag_r11: 0x80 [RC 0]
            HAS_ATTRIBS(0x80)
  size: 9 [RS]
  layer: 0 [H(RSd) 8]
  opts_r11: 0x1 [RSx 0]
            HAS_FLAG(0x1)
  flag: 0x1 [RC 70]
        CLOSED(0x1)

  type: 18 [RCd]
  Add entity JUMP [67] Decode entity JUMP
  ===========================
  Entity number: 67, Type: 18, Addr: 10c9
  flag_r11: 0x0 [RC 0]
  size: 8 [RS]
  jump_address_raw: 0x84f [RLx 0]
  jump_entity_section: DWG_ENTITY_SECTION
  jump_address: 0x84f
  ==========================================
  extras entities: end
@end example

The entity iterator knows about these jumps.
The DXF structure resolves those jumps, and inserts the replaced entities.

@node Structures
@chapter Structures

@cindex structures

@menu
* EED::            eed[] array
* XDATA::          xdata list for XRECORD
@end menu

@node EED
@section EED

@cindex EED

``Extended Entity Data'' (EED) may be optionally attached to each object.
They consist of a handle to the registered APPID, and a list of
typed data. Each block is preceded with a size, the processing stops with
size 0.

Internally libredwg stores each eed line as an array of num_eed structs.
If the size > 0, then new block starts with a handle, an optional raw string
(when reading from a DWG), and a number of typed data entries. Only the first
eed struct of each block has a size, all subsequent eed structs have size 0.

Example:
@example
  EED[0] size: 109 [BS]
  EED[0] handle: 5.2.762
  EED[0] code: 70 [RC] short: 2 [RS]
  EED[1] code: 70 [RC] short: 0 [RS]
  EED[2] code: 70 [RC] short: 0 [RS]
  EED[3] code: 11 [RC] 3dpoint: (0.000000, 0.000000, 0.000000) [3RD]
  EED[4] code: 11 [RC] 3dpoint: (1.000000, 0.000000, 0.000000) [3RD]
  EED[5] code: 11 [RC] 3dpoint: (0.000000, 1.000000, 0.000000) [3RD]
  EED[6] code: 11 [RC] 3dpoint: (0.000000, 0.000000, 1.000000) [3RD]
  EED[7] size: 6 [BS]
  EED[7] handle: 5.2.763
  EED[7] code: 70 [RC] short: 0 [RS]
  EED[8] code: 70 [RC] short: 0 [RS]
  EED[9] size: 23 [BS]
  EED[9] handle: 5.1.12
  EED[9] code: 0 [RC] string: "RTMaterial" len=10 cp=30
  EED[10] code: 5 [RC] entity: 0x6507000000000000 [RLL]
  - size: 0 [BS]
@end example

These 10 num_eed structs consist of 3 blocks with 3 size and handle entries.
EED[0] starts with size 109, the handle pointing to object 762, 3 shorts
and 4 points. The next block at EED[7] has size 6, the handle pointing to object 763
and 2 shorts. The last block at EED[9] has size 9, the handle pointing to object 12
(the APPID.ACAD application) and a string and an entity reference.
The size is calculated by the needed room for all data code + values, without the handle.
E.g. EED[7] size: 6 is 1 + 2 for EED[7] RC + RS, and 1 + 2 for EED[8] RC + RS.

Each data block consists of a RC code, and a variable value.
A string may be a an old pre-r2007 ASCII string with a RC length (max 255
chars), a codepage and the string. Or a r2007+ wide string with a RS
length (max 32767 chars) and a UCS-2 wide string.

decode stores both, the raw data, and the structured data.
in_dxf just the data.
encode prefers raw over the data.

@node XDATA
@section XDATA

@cindex XDATA

XRECORD XDATA are very similar to the EED array, but internally it is
a single linked-list, consisting of something like the EED data code
+ value pairs. There's only one size, xdata_size, and only one handle
to the APPID, which handles this XRECORD XDATA.

@node Functions
@chapter Functions

@cindex functions

You can use LibreDWG immediately upon loading, without any particular
initialization. Only when using some @pxref{dynapi} functions you might need to
initialize the version via @code{dwg_api_init_version(&dwg)}, when you
need other formats than r2000 and you call an API function which does
not store the version internally. Most do. This limitation will soon be fixed.

You usually use one set of functions - either decoding or encoding -
at a time.  All functions use the common data types (@pxref{Types}).
All functions return an error code, and the high-level functions for
multiple objects add the error bitmask, which is sorted by severity.
When the error exceeds DWG_ERR_CRITICAL, processing is stopped.

The new @pxref{dynapi} has dynamic get and set functions for all objects and its fields.
You can get and set a property value from any object pointer by the object name
and the field name.

@menu
* Decoding::                    Functions on the DWG read path.
* Encoding::                    Functions on the DWG write path.
* add api::                     How to create a DWG and objects from scratch
* dynapi::                      Dynamic object field access.
* strings::                     The various string types, how Unicode strings are handled
* Other Formats::		Functions on the DWG to read or write other formats.
@end menu


@node Decoding
@section Decoding

@cindex functions, decoding
@cindex functions, read path

The highest level function for decoding a file is @strong{@code{dwg_read_file}}.

@deftypefn {Function} int dwg_read_file (char *@var{filename}, Dwg_Data *@var{dwg})
Open @var{filename} and decode it, saving information into @var{dwg}.
Return 0 if successful.
@end deftypefn

You can then iterate over the entities in model space or paper space
via two ways:

1. by using the @file{dwg.h} data structures. Via @code{dwg->object[0]}, which is of
   type @code{Dwg_Object_BLOCK_CONTROL},
   and a custom @code{void process_BLOCK_HEADER(Dwg_Object_Ref* ref)}:

@verbatim
  Dwg_Object_BLOCK_CONTROL* block_control = dwg->block_control;
  // first all entities in the model space
  process_BLOCK_HEADER(dwg->header_vars.BLOCK_RECORD_MSPACE);
  // then all entities in the blocks
  for (i=0; i < block_control->num_entries; i++)
    {
      process_BLOCK_HEADER(block_control->block_headers[i]);
    }
  // and last all entities in the paper space
  process_BLOCK_HEADER(dwg->header_vars.BLOCK_RECORD_PSPACE);
@end verbatim

or 2. by using the API functions from @file{dwg_api.h}:

@verbatim
  Dwg_Object_BLOCK_CONTROL* block_control = dwg_block_control(dwg);
  process_BLOCK_HEADER(dwg_model_space_ref(dwg));
  for (i=0; i < block_control->num_entries; i++)
    {
      process_BLOCK_HEADER(block_control->block_headers[i]);
    }
  process_BLOCK_HEADER(dwg_paper_space_ref(dwg));
@end verbatim

and inside the @code{process_BLOCK_HEADER} function, you iterate over the entities
from the block_header via:

@verbatim
  Dwg_Object* obj = get_first_owned_entity(ref->obj);
  while (obj)
    {
      process_object(obj);
      obj = get_next_owned_entity(ref->obj, obj);
    }
@end verbatim

where @code{process_object} checks the type of each entity under the
@var{Dwg_Object* obj}.

For each entity or object type (i.e. a non-graphical dwg object, also tables)
there also exist the simple and expensive @code{dwg_getall_ENTITY} and @code{dwg_getall_OBJECT}
functions:

@deftypefn {Function} int dwg_getall_ENTITY (Dwg_Object_Ref *@var{block_header_ref})
Return a malloc'ed NULL-terminated array of all such entities for Model Space,
Paper Space or an individual block.
@end deftypefn

@deftypefn {Function} int dwg_getall_OBJECT (Dwg_Data *@var{dwg})
Return a malloc'ed NULL-terminated array of all such DWG objects.
@end deftypefn

The decoder is driven by the fields definition in the @file{src/dwg.spec}, which adds each
field to the object. This is done in the @file{src/decode.c} or @file{src/decode_r2007.c}.
@deftypefn {Function} int dwg_decode_OBJECT (Bit_Chain *@var{dat}, Dwg_Object *@var{obj})
Sets the fields for the object from the DWG bitstream.
@end deftypefn

Note: Pre-R13 DWG's do contain all deleted entities, which e.g. where moved into a BLOCK.
Those entities do have a type > 127. You need to filter them out by yourself, when processing the DWG.

@node Encoding
@section Encoding

@cindex functions, encoding
@cindex functions, write path

Encoding DWG files, i.e. DWG write support, can be disabled via
@code{./configure --disable-write}. The default formats and only useful
ones are currently r1.1 - r2000. Experimentally work is ongoing for the r2004
format, which is also used for r2010, r2013, and r2018.
The r2007 format version is not covered yet.
The pre-r13 formats are much simpler and can be written, but need some
hand-holding and manual conversions when converting from newer formats still.

See @file{src/in_dxf.c} for a high-level usage example.
The default codepage is Latin-1, 30.

The highest level function for encoding a bitstream to a file is
@code{dwg_write_file}, which dumps the dwg to a file.

@deftypefn {Function} int dwg_write_file (char *@var{filename}, Dwg_Data *@var{dwg})
Open @var{filename} and write the @var{dwg} to it.
Return 0 if successful.
@end deftypefn

@xref{add api} for:
@deftypefn {Function} Dwg_Data* dwg_add_Document (const Dwg_Version_Type @var{version},
                                            const int @var{imperial}, const int @var{loglevel})
Creates an initial template dwg structure in memory, suitable to be written to a DWG or DXF file,
without any additional table records or entities. Creates ModelSpace, PaperSpace and most Tables
and basic Dictionaries.
@end deftypefn
and how to add entities and objects from scratch.

Low level-functions:

@deftypefn {Function} int dwg_add_object (Dwg_Data *@var{dwg})
Adds a new uninitialized object to the @var{dwg->object}[] array.
Return 0 or -1 if successful, otherwise DWG_ERR_OUTOFMEM. -1 is the array was re-allocated.
@end deftypefn

Then for each object or entity type there is a
@deftypefn {Function} int dwg_setup_<OBJECT> (Dwg_Object *@var{obj})
Initializes an object for the given OBJECT or ENTITY type, with all fields being zero'ed.
This does not initialize the @var{obj} size, type, address, handlestream_size, bitsize fields.
@end deftypefn

The encoder is driven by the fields definition in the @file{src/dwg.spec} and
the generated @file{src/dynapi.c}, which adds each field to the object.
This is done by @file{src/encode.c} or any @file{src/in_*.c} import module.

@deftypefn {Function} int dwg_encode_<OBJECT> (Bit_Chain *@var{dat}, Dwg_Object *@var{obj})
Encodes the DWG bitstream from the fields of the object.
@end deftypefn

The iterator is similar to above, but you want to encode all data structures, not just the entities. But note that you need many helper functions, such as the @ref{dynapi}, to create all needed sections to store a DWG if you didn't read a DWG into the right a @var{Dwg_Data* dwg} struct already. This is especially important when importing from DXF or from an earlier or later DWG version.

@node add api
@section add api

@cindex functions, create

The add api functions are useful for CAD programs which want to write DWG.
All the other API's are mostly to convert from and to DWG, so the main structures and links already do exist.
With the add api you can easily create an empty DWG from scratch, add table entries (into fixed Tables
or variables Dictionaries), and add entities. To set more entity fields use the @ref{dynapi}.

For each almost each entity and table exists a function at to add it, with arguments to initialize some fields
as in the VBA object model. The other objects are either created automatically, or handled separately.

All BITCODE_T strings are encoded as UTF-8, as with the dynapi. @xref{strings}.
Most names are copied, since most names are considered to be constant.
If not, you need to free them by yourself.
Exceptions are dxfname (there exists a separate dxfname_u variant),
the VX name, which does not exists anymore since r2000.

A very simple example using the add API is the example program @xref{dwgadd}.

@deftypefn {Function} Dwg_Data dwg_add_Document (const Dwg_Version_Type @var{version}, const int @var{imperial}, const int @var{loglevel}))

Creates an initial template dwg structure in memory, suitable to be written to a DWG or DXF file,
without any additional table records or entities. Creates ModelSpace, PaperSpace and most Tables
and basic Dictionaries.

When writing DWG, a @var{version} of R_2000 is recommended, only R_1_2 - R_2000
are supported yet. For DXF you can try all versions R_13 - R_2018.
@end deftypefn


For each OBJECT and ENTITY type there exists a specific @code{dwg_add_<OBJECT>} function, which takes the owner
and some default arguments. Entities are normally added to a block header, like modelspace,
paperspace or any block. Objects are normally added to the dwg, or to some other object or entity.
E.g.
@deftypefn {Function} Dwg_Entity_LINE *line = dwg_add_LINE (Dwg_Object_BLOCK_HEADER *modelspace,
                                                            dwg_point_3d *start_pt, dwg_point_3d *end_pt)
@end deftypefn
@deftypefn {Function} Dwg_Entity_TEXT* dwg_add_TEXT (Dwg_Object_BLOCK_HEADER *restrict @var{blkhdr}, const char* restrict @var{text_value}, const dwg_point_3d *restrict @var{ins_pt}, const double {height})

Adds a TEXT entity to the ModelSpace, PaperSpace or a Block. Entity specific arguments are here the text, the point (as pointer to the struct of 3 doubles), and the text height.
@end deftypefn
@deftypefn {Function} Dwg_Object_LAYER *layer = dwg_add_LAYER (Dwg_Data *dwg, const char *name)
Adds a new layer the Layer Table, i.e. creates the new LAYER object, and adds it to LAYER_CONTROL object,
the list of layers.
@end deftypefn

Names and strings are encoded as UTF-8 and will be translated to type BITCODE_T (i.e. versions specific
TU or TV types, either UCS-2 unicode or single-byte codepage) internally, as with the @b{dynapi}. Only
internally you will have to deal with 2 different DWG text representations: UCS-2 since r2007, single-byte before.
@pxref{strings}.

To understand the object model for the add API see some VBA Object model documentation, such as
e.g. @url{http://entercad.ru/acadauto.en/}.

The new add API mostly handles the direct @code{Dwg_Entity_ENTITY} structs, not all the generic @code{Dwg_Object} structs.
Thus you can access the object specific fields directly, the common fields, not so easily.

The DWG Document consists of 3 basic entity containers @code{ModelSpace}, @code{PaperSpace} and @code{Blocks}, plus
@code{Tables} (@code{Layers}, @code{Linetypes}, ...), @code{Dictionaries} as generic replacements of @code{Tables} with a root Dictionary, the @code{NOD} ("Named Object Dictionary"), and more support objects and complex entity groups.

Helper functions:

@deftypefn {Function} dwg_add_u8_input (Dwg_Data *restrict @var{dwg}, const char *restrict @var{u8str})
Convert UTF-8 strings to BITCODE_T fields. Returns a copy of the string. All external API's only deal with UTF-8 strings.
@end deftypefn

@node dynapi
@section dynapi

@cindex functions, dynamic field access

The new dynapi replaced the old dwg_api functions to access each object field. The old dwg_api functions
were deprecated, and need to be re-enabled by defining @code{CFLAGS="-DUSE_DEPRECATED_API"}.
See @pxref{Objects} for an description of each object and its fields..

For each of header, entity, common or subclass there is a function to get and set the value of any type,
or converted utf8 string.

@deftypefn {Function} bool dwg_dynapi_entity_value (void *@var{entity}, const char *@var{dxfname}, const char *@var{fieldname}, void *@var{out}, Dwg_DYNAPI_field *@var{fp})
@var{entity} is of type @code{dwg_ent_generic}, that is the pointer to the object specific struct.
@var{dxfname} is the dxfname of the object, @var{fieldname} is the field or property name of the field to be read from,
*@var{out} the result pointer and the optiona *@var{fp} is filled by the information for this field.
@end deftypefn

@deftypefn {Function} bool dwg_dynapi_common_value (void *@var{entity}, const char *@var{fieldname}, void *@var{out}, Dwg_DYNAPI_field *@var{fp})
This accesses the common @code{Dwg_Object_Object*} or @code{Dwg_Object_Entity*} fields.
@end deftypefn

@deftypefn {Function} bool dwg_dynapi_header_value (void *@var{dwg}, const char *@var{fieldname}, void *@var{out}, Dwg_DYNAPI_field *@var{fp})
This accesses the Header (or sometimes also called Database) fields.
@end deftypefn

@deftypefn {Function} bool dwg_dynapi_subclass_value (void *@var{ptr}, const char *@var{subclass}, const char *@var{fieldname}, void *@var{out}, Dwg_DYNAPI_field *@var{fp})
This accesses a subclass, a structure within the object.
@end deftypefn

The utf8text functions convert version-specific text strings to UTF-8 strings. Internally the dwg stores strings
as TU (unicode) or TV (single-byte codepage). The API treats all strings as UTF-8, as with JSON, DXF or the add API.

@deftypefn {Function} bool dwg_dynapi_entity_utf8text (void *@var{entity}, const char *@var{dxfname}, const char *@var{fieldname}, char *@var{textp}, int *@var{isnewp}, Dwg_DYNAPI_field *@var{fp})
isnewp is set to 1 f the string is a fresh copy, for unicode strings.
@end deftypefn

@deftypefn {Function} bool dwg_dynapi_common_utf8text (void *@var{entity}, const char *@var{fieldname}, char *@var{textp}, int *@var{isnewp}, Dwg_DYNAPI_field *@var{fp})
@end deftypefn

@deftypefn {Function} bool dwg_dynapi_header_utf8text (void *@var{dwg}, const char *@var{fieldname}, char *@var{textp}, int *@var{isnewp}, Dwg_DYNAPI_field *@var{fp})
This accesses the Header (or sometimes also called Database) fields.
@end deftypefn

@deftypefn {Function} bool dwg_dynapi_subclass_utf8text (void *@var{ptr}, const char *@var{subclass}, const char *@var{fieldname}, char *@var{textp}, int *@var{isnewp}, Dwg_DYNAPI_field *@var{fp})
This accesses a subclass, a structure within the object.
@end deftypefn

The setters don't differentiate between common values and strings.

@deftypefn {Function} bool dwg_dynapi_entity_set_value (dwg_ent_generic *@var{_obj}, const char *@var{fieldname}, const void *@var{value}, const bool @var{is_utf8})
Sets the ENTITY.fieldname to a value.
A malloc'ed struct is passed by ptr, not by the content.
A non-malloc'ed struct is set by content.
Arrays or strings must be malloced before. We just set the new pointer, the old value will be freed.
If is_utf8 is set, the given value is a UTF-8 string, and will be converted to TV or TU
@end deftypefn

@deftypefn {Function} bool dwg_dynapi_header_set_value (Dwg_Data *@var{dwg}, const char *@var{fieldname}, const void *@var{value}, const bool @var{is_utf8})
@end deftypefn

@deftypefn {Function} bool dwg_dynapi_common_set_value (dwg_ent_generic *@var{_obj}, const char *@var{fieldname}, const void *@var{value}, const bool @var{is_utf8})
@end deftypefn

See the sourcecode of the importers or programs for the usage of the API's.

@node strings
@section strings

@cindex strings

Internally the DWG consists of multiple different string formats, @pxref{Types}.
The most important are @code{BITCODE_TV} (i.e. @code{char*}) encoded according to @code{dwg->header.codepage},
and @code{BITCODE_TU} (i.e. @code{wchar_t} on Windows, UCS-2).

Externally most functions get and set strings as UTF-8, as in DXF or JSON.

Before r2007 DWG's the TV and T strings are encoded in its codepage, and converted from and
to their proper codepage to UTF-8 or \U+XXXX.

To encode unicode characters special \U+XXXX sequences are used, and pre-r2007 DXF MIF \M+nXXXX
sequences, where n is one of the asian wide-character codepages 932 (Japanese), 950 (trad. Chinese),
949 (Korean Wansung), 1361 (Johab), and 936 (simplified Chinese).

On DWG's r2007 and later most strings (T and TU) are encoded in the Microsoft specific two-byte
UCS-2 Unicode encoding, without proper support for surrogate pairs and the upper planes (i.e. emojis).

Fixed TF strings are not encoded and have a length stored also. Normal strings are all zero-delimited.
EED and XDATA strings do have a length though, but have length limitations.

Strings in DXF and JSON also have quoting rules for special characters, like \r, \n, \" and so on.

@b{Transformations}:

DWG to DWG: decode reads the T and TU strings in its natural format into the field. encode translate it to TV or TU. encode needs @code{header.from_version} and how it was read, from DWG or from an importer (in_dxf or in_json) or the @ref{add api} (DWG_OPTS_IN).

DXF/JSON to DWG: in_dxf/json keeps the T and TU strings as TV. encode to <r2007 keeps it as TV, r2007+ translates it to TU. Unicode is encoded as \U+XXXX.
It sets DWG_OPTS_IN.

DWG to DXF/JSON: decode keeps the T and TU strings as TV or TU. out_dxf/json translate them to TV or UTF-8 and quotes them via \U+XXXX.

add api to DWG/DXF: add reads strings as UTF-8, and encodes it from UTF-8 to TV or TU. (TU not yet, as we don't encode r2004+ yet). add sets DWG_OPTS_IN.


@node Other Formats
@section Other Formats

@cindex functions, other formats

@menu
* DXF::                    Write and read ASCII DXF
* DXFB::                   Write (and soon read) Binary DXF.
* JSON::		   Write and read our own JSON serialization of the DWG
* GeoJSON::		   See the GeoJSON spec
@end menu

@node DXF
@subsection DXF

@cindex DXF, ASCII DXF

We can write ASCII DXF files in various versions, with much more data
than other free DWG libraries, but not as stable as the unfree Teigha
library yet.  AutoCAD @registeredsymbol{} fails to import some of our
files still (~10% failure rate).

Options: @code{--minimal} (see @code{dwg2dxf} or @code{dwgread}) creates
only a short header with a ACADVER and HANDSEED element, and the
entities, without any subclass markers, reactors or handles.

Support for the different r1.x DXF format is not planned.

Reading DXF works for most objects.
Converting a minimal DXF to DWG may fail, and needs some fixes.

@node DXFB
@subsection DXFB

@cindex DXFB, Binary DXF

We can almost write Binary DXF files in various versions.

Reading DXFB is under construction and un-tested.

@node JSON
@subsection JSON

@cindex JSON

We write to and read back from our own JSON format, which is a
readable 1:1 mapping of the DWG structures, and carries much more
information than the DXF format. The idea is to dump a DWG to JSON and
filter/query or postprocess it with more powerful JSON query tools
such as @b{jq} (@url{https://stedolan.github.io/jq/}), and optionally
import it back in. @xref{Programs, dwgfilter, Programs:
dwgfilter}. JSON is much better structured than DXF.

The current first level objects are all the section names, like
``HEADER'', ``CLASSES'', ``OBJECTS''. For more see the specs.

Note that for the versions before R13 we convert all tables to table
control and record objects internally, so that we can use our iterators
needed for DXF support. This does not reflect the internal DWG structure.
@xref{Tables}.


@node GeoJSON
@subsection GeoJSON

@cindex GeoJSON

@code{dwgread} supports writing to the GeoJSON format as specified at
@uref{http://geojson.org/geojson-spec.html}.  See @code{dwgread} with
the @code{--fmt GeoJSON} option.

We write in the RFC7946 format, the new GeoJSON format since 2016,
which means smaller, less precision, and normalized polygons with
proper right-hande rule orientation.

We write all coordinates as [x, y], not [y, x]. z-coordinates are
optional, and only written if not 0.0.
Colors are either written as palette index as integer if not 256 (ByLayer),
or as TrueColor RGB hex string values for all r2004+ DWG's.

Missing entities:
No 3D entities, HATCH by definition.
ELLIPSE, polyline bulges would need segmention into line segments.
MLINE, SPLINE, MINSERT, SOLID, TRACE, RAY(?), XLINE(?)

Due to implementation quirks with ending commas in JSON, we mostly
add an empty dummy feature at the very end, with null properties and
null geometry.

@node Errors
@chapter Errors

@cindex error

LibreDWG is mostly a library, and as such collects error codes from
the highest level function down to the lowest level functions.
The error codes are sorted by severity, and only if the error exceeds
@var{DWG_ERR_CRITICAL}, i.e. @code{DWG_ERR_CLASSESNOTFOUND}, processing is stopped.

All error bitmasks are collected during read or write and returned at the end.

@vtable @code
@item DWG_ERR_WRONGCRC
1
@item DWG_ERR_NOTYETSUPPORTED
2
@item DWG_ERR_UNHANDLEDCLASS
4
@item DWG_ERR_INVALIDTYPE
8
@item DWG_ERR_INVALIDHANDLE
16
@item DWG_ERR_INVALIDEED
32
@item DWG_ERR_VALUEOUTOFBOUNDS
64
@item DWG_ERR_CLASSESNOTFOUND
128 = @code{DWG_ERR_CRITICAL}
@item DWG_ERR_SECTIONNOTFOUND
256
@item DWG_ERR_PAGENOTFOUND
512
@item DWG_ERR_INTERNALERROR
1024
@item DWG_ERR_INVALIDDWG
2048
@item DWG_ERR_IOERROR
4096
@item DWG_ERR_OUTOFMEM
8192
@end vtable

Additionally, verbose warning and error messages are printed to stderr.

Unhandled class and Invalid type errors of objects are not severe. A
DWG format can store a serialization of many third party classes and
objects, and thus we will never be able read all possible types.
Unknown types are just stored as binary blob without any DXF codes.

@node Programs
@chapter Programs

@cindex programs

LibreDWG installs some binary programs to read or write DWG files.

@table @asis

@item @file{dwgread}
@cindex dwgread
@anchor{dwgread}

This reads a DWG file, and optionally converts its content to some
output formats: JSON, Minimal JSON, GeoJSON, DXF, DXFB (i.e. Binary DXF), SVG.

@code{dwgread [OPTION]... DWGFILE}

Options:

       -v[0-9], --verbose [0-9]
              verbosity

       -O fmt,  --format fmt
              fmt: JSON, DXF, DXFB, minJSON, GeoJSON.

              More planned formats: YAML, XML/OGR, GPX, SVG, PS.

       -o outfile, --file outfile
              also defines the output fmt. Default: stdout

       --help display this help and exit

       --version
              output version information and exit

minJSON is minimized JSON, without whitespace.

@item @file{dwgwrite}
@cindex dwgwrite
@anchor{dwgwrite}

Create a DWG from a given input file (@pxref{DXF}, @pxref{DXFB, Binary DXF}, @pxref{JSON}),
optionally via @code{--as=rNNNN} as another version.
For now can only create r1.2-r2000 DWG files.

@item @file{dxfwrite}
@cindex dxfwrite
@anchor{dxfwrite}

Create a DXF from a given input file (@code{DWG}, @pxref{DXF}, @pxref{DXFB, Binary DXF}, @pxref{JSON}),
optionally via @code{--as=rNNNN} as another version. Experimental.
Supports the same options as @code{dwg2dxf}.

@item @file{dwg2dxf}
@cindex dwg2dxf
@anchor{dwg2dxf}

Converts DWG files to DXF, optionally via @code{--as=rNNNN} as another
version, an earlier or later version, or via @code{-m} or
@code{--minimal} as a minimal DXF version, skipping most headers vars,
classes, tables and objects.

@code{--binary} as a binary DXF file, with full precision, under construction.

The DXF files are created in the current directory and not overwritten, unless
the option @code{--overwrite} or @code{-y} is given.

@item @file{dxf2dwg}
@cindex dxf2dwg
@anchor{dxf2dwg}

Converts DXF (or Binary DXF) files to DWG, optionally via @code{--as=rVER} as another
version, an earlier or later version.

The DWG files are created in the current directory and not overwritten, unless
the option @code{--overwrite} or @code{-y} is given.

This program is experimental and AutoCAD @registeredsymbol{} may fail to import
it.
For now can only create r1.2-r2000 DWG. The default is writing as r2000.

@item @file{dwgrewrite}
@cindex dwgrewrite
@anchor{dwgrewrite}

Read and write the DWG, optionally via @code{--as=rNNNN} as another
version, an earlier or later version. The default is writing as r2000.
For now can only create r1.2-r2000 DWG.

@item @file{dwglayers}
@cindex dwglayers
@anchor{dwglayers}

Prints all layers in a DWG.
With @code{-x} or @code{--extnames} prints the extended displayed layer name with spaces,
not the internally stored old-style name with @code{_} instead.
Only relevant with old r13 and r14 DWGs, after that layers are always stored in the extended format.
With @code{-f} or @code{--flags} also the status of frown, on/off and locked.
With @code{--on} only the visible layers, which are on and not frozen.

You can get the same effect via this json filter:
@verbatim
  dwgfilter '.OBJECTS[]' example.dwg | \
    grep -A22 '"object": "LAYER"' | grep name
@end verbatim

@item @file{dwggrep}
@cindex dwggrep
@anchor{dwggrep}

Search regex pattern in all text values in a list of DWGs. dwggrep uses PCRE.

With @code{-i} searches case-insensitive.
With @code{-c} prints only the count of found texts.
With @code{-h} or @code{--no-filename} does not print the filename.
With @code{--type NAME} search only NAME entities or objects.
With @code{--dxf NUM} search only in DXF group NUM fields.
With @code{--text} searches only TEXT-like entities: TEXT, MTEXT, ATTRIB, ATTDEF.

@item @file{dwgfilter}
@cindex dwgfilter
@anchor{dwgfilter}

Search and modify a single DWG file via @code{jq}, using the powerful
JQ query expression language on a temporary json file. See @code{man jq}.

With @code{-i} replaces the DWG in-place. This only makes sense with an JQ expression which changes values.

@item @file{dwg2SVG}
@cindex dwg2SVG
@anchor{dwg2SVG}

Convert a DWG to a limited SVG. All paperspace or modelspace enties of type:
TEXT, LINE, CIRCLE, ARC, POLYLINE_2D, LWPOLYLINE, INSERT, ELLIPSE (unrotated),
SOLID, 3DFACE, RAY, XLINE.

With @code{-m} or @code{--mspace} all paper-space entities are
ignored, and only model-space is printed. The default is to print all
paper-space entities. But if there are none, print all model-space
entities instead.

Limitations: Many other graphical entities and some properties are still missing.

@item @file{dwg2ps}
@cindex dwg2ps
@anchor{dwg2ps}

Convert a DWG to a very limited Postscript file. All paperspace and modelspace entities of type LINE,
POLYLINE_2D, LWPOLYLINE, ARC and CIRCLE.

This requires installation of pslib @uref{http://pslib.sourceforge.net/doc/pslib.html}.

Note that the graphical representation for PS and SVG output is severely lacking, block references (insert entities) are not yet exploded, UCS and paper space transformations per entity are not yet done.

@end table

@cindex dwgplot
@anchor{dwgplot}

Planned is @strong{dwgplot}, via GNU Plotutils @uref{https://www.gnu.org/software/plotutils/}, to replace @code{dwg2SVG} and @code{dwg2ps}. This supports much more bitmap and vector formats.

There are also some more examples in the source distribution:

@table @asis

@item @file{load_dwg}
@cindex load_dwg
@anchor{load_dwg}
loads a DWG and adds some entities.

@item @file{dwg2svg2}
@cindex dwg2svg2
@anchor{dwg2svg2}
converts a DWG to SVG similar to @file{dwg2SVG},
but via the @file{dwg_api.h} only. The graphical representation for PS and SVG output is severely lacking, block references (insert entities) are not yet exploded , UCS and paper space transformations per entity are not yet done.

@item @file{unknown}
@cindex unknown
@anchor{unknown}
lists the not yet reverse-engineered blobs from our examples files, and
is the framework to guess the field layout for these. It is optionally using picat (@url{http://picat-lang.org/}) to solve some of the field-packing problems.

@item @file{dwgfuzz}
@cindex dwgfuzz
@anchor{dwgfuzz}
afl++ fuzzing frontend, to test and debug various fast shared-memory options for afl-clang-fast,
with the following runtime options: @code{-indxf}, @code{-injson}, @code{-rw}, @code{-dwg}, @code{-dxf}, @code{-dxfb}, @code{-json}, @code{-geojson}. All other output formats, like BMP, SVG, PS need to be fuzzed via their programs, which is the recommended way.
The now default and fastest method INMEM does not need the 2nd file argument @code{@@@@}, the 2nd method STDIN neither.

See also @url{https://github.com/LibreDWG/libredwg-fuzz} for our fuzzing setup to test new fuzzing campaigns automatically and find regressions.

@item @file{dwgadd}
@cindex dwgadd
@anchor{dwgadd}
is the easiest way to create DWG's (or DXF, JSON) from scratch or add entities to an existing DWG.
It accepts a very simple file with commands to create entities or objects and set its properties.
See @code{man 1 dwgadd} and @code{man 5 dwgadd}.

@end table

@node Bindings
@chapter Bindings

@cindex python
@cindex perl
@cindex gambas

LibreDWG generates library bindings to python and perl5 via
swig. These can be quite huge, and it is recommended to use @file{ccache}.
You can easily add bindings to other swig-supported languages, like Go, C#,
ruby, php, D, lua, tcl, common lisp, ocaml, or others by yourself. Patches accepted.

Bindings for gambas (which looks very close to VBA) are at
@uref{https://github.com/LibreDWG/gambas3-bindings, GitHub} and will
soon be added to gambas3 as gb.dwg component. This is in development
and about 80% finished.

@node Reference API
@chapter Reference API

@cindex Reference API

See the separate @uref{https://www.gnu.org/software/libredwg/refman/, refman} manual (in pdf or html format, the pdf has ~1800 pages) for a detailed API description, or see the relevant @file{dwg.h}, @file{dwg_api.h} or the @file{*.spec} files.

For reference you might also want to check the public DXF reference manuals, the VBA object model
and the ODA @file{OpenDesign_Specification_for_dwg_files.pdf}.

@comment It is unfortunately not possible to include the doxygen generated tex
@comment files into this texinfo format.

@node Reporting bugs
@chapter Reporting bugs

@cindex bug reporting
@cindex problems
@cindex reporting bugs

To report bugs or suggest enhancements for GNU LibreDWG, please
``submit a bug'' at
@uref{http://savannah.gnu.org/projects/libredwg, Savannah}
or send electronic mail to @email{libredwg@@gnu.org}.
(If you use the web interface, you don't need to also send email,
since that is done automatically.)
Issues and pull requests at the @uref{https://github.com/LibreDWG/libredwg, github mirror} are also accepted.

@cindex checklist for bug reports
For bug reports, please include enough information for the maintainers
to reproduce the problem.  Generally speaking, that means:

@itemize @bullet
@item The version numbers of LibreDWG and any other program(s) or manual(s) involved.
@item Hardware and operating system names and versions.
@item The contents of any input files necessary to reproduce the bug.
@item The expected behavior and/or output.
@item A description of the problem and samples of any erroneous output.
@item Options you gave to @command{configure} other than specifying
      installation directories.
@item Anything else that you think would be helpful. Usually that's the failing part
of the object processed with @file{dwgread -v5}, but only the failing part, not the whole output.
@end itemize

When in doubt whether something is needed or not, include it.  It's
better to include too much than to leave out something important.

@cindex patches, contributing
Patches are welcome; if possible, please make them with
@samp{git format-patch} and
include @file{ChangeLog} entries (@pxref{Change Log,,, emacs, The GNU
Emacs Manual}).  Please follow the existing GNU coding conventions.
For patches longer than 15 lines we need your copyright assignment to the FSF clerk.
See @file{CONTRIBUTING} in the source distribution.

@node GNU Free Documentation License
@appendix GNU Free Documentation License

@include fdl.texi
@include version.texi

@node Index
@chapter Index

@menu
* General Index::            Concepts, functions and types.
* Object and Field Index::   Objects, Entities and its fields.
@end menu

@node General Index
@section General Index

@printindex cp

@node Object and Field Index
@section Object and Field Index

@printindex vr

@bye
