1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
//! Raw FFI bindings to the LibreDWG C sources (vendored, unmodified, from
//! the real upstream project at `lib/libredwg`, GPLv3+; see
//! docs/THIRD_PARTY_NOTICES.md).
//! Generated by `build.rs` via `bindgen` against the public
//! `dwg.h`/`dwg_api.h` headers plus this crate's own `uncad_write_dxf_file`
//! shim (see `shim/uncad_shim.h`).
//!
//! This crate is intentionally low-level and `unsafe`-heavy -- it exists to
//! be wrapped by the `uncad` crate, not used directly.
//!
//! # Not thread-safe -- callers must serialize every call themselves
//!
//! The underlying LibreDWG C library has non-reentrant global state (e.g.
//! the `loglevel` global read/written throughout `decode.c`/`bits.c`, and
//! likely more that hasn't been individually catalogued). Calling into any
//! function in this crate concurrently from multiple threads -- even two
//! calls that never touch the same `Dwg_Data`/`Dwg_Object` -- has
//! reproducibly caused `STATUS_HEAP_CORRUPTION` once both threads' work
//! overlapped enough for the shared C-side state to race. **This crate does
//! nothing to prevent that**; every FFI entry point here is exactly as
//! unsynchronized as the C library it binds.
//!
//! The `uncad` crate's own public API (`uncad::parse()` and friends) is
//! safe to call from multiple threads because it serializes every call
//! through a single process-wide `Mutex` before reaching this crate --
//! see `uncad`'s top-level doc comment / `docs/ARCHITECTURE.md`'s "Thread
//! safety" section. Any other consumer of `libredwg-sys` directly must
//! implement that same serialization itself (a single global lock around
//! every call into this crate, held for the call's entire duration) or
//! risk memory corruption under concurrent use.
// bindgen emits `mem::transmute(x)` for every bitfield accessor regardless
// of whether the source and target types happen to coincide (they do for
// every current `BITCODE_B`/`_BS`-backed bitfield in dwg.h) -- harmless,
// and not something editing generated code (re-generated fresh on every
// build) could fix. See docs/CAVEATS.md's "cargo clippy 현재 상태" note.
// Same rationale, for bindgen's generated `BindgenUninitializedField` helper
// (`as_slice`/`as_mut_slice`/`as_ref`/`as_mut`) -- its `unsafe fn`s have no
// `# Safety` doc section because bindgen doesn't emit one, not because this
// crate's own unsafe code is undocumented (see `dynapi.rs` in `uncad` for
// this project's own actual safety-doc convention).
// Same rationale again: bindgen's generated helper methods call other
// unsafe functions (`slice::from_raw_parts`, `mem::transmute`) without
// wrapping each one in its own `unsafe { }` block, relying on the whole
// `unsafe fn` body being implicitly unsafe (2021 edition default) --
// harmless and, again, not this crate's own code to restyle.
include!;
// --- Hand-defined HATCH sub-structs -----------------------------------
//
// bindgen can't generate real field access for these two (same struct-
// codegen limitation as Dwg_Object -- see build.rs's blocklist_type calls
// for the full explanation), but this project needs real field access
// into them (HATCH boundary-path geometry isn't reachable through dynapi
// at all -- dynapi only exposes top-level entity fields by name, not
// nested struct internals). Hand-defined here to match dwg.h's field
// order and types exactly; #[repr(C)] then reproduces C's own alignment/
// padding rules automatically; the layout_test() functions below assert
// the resulting sizes against clang's own authoritative sizeof() (56/200/
// 32 bytes -- the same numbers bindgen's own layout_tests() asserted
// against before these types were blocklisted) as a safety net against a
// transcription mistake in this hand-written mirror.
/// `_dwg_HATCH_ControlPoint` (dwg.h) -- a SPLINE-type boundary edge's
/// control point.
/// `_dwg_HATCH_PathSeg` (dwg.h) -- one edge of a non-polyline HATCH
/// boundary path. Not a real C union (despite the "could be a union"
/// comment in dwg.h) -- every field is present regardless of
/// `curve_type`; only the fields relevant to that specific curve type are
/// meaningfully populated.
/// `_dwg_HATCH_Path` (dwg.h) -- one HATCH boundary path, either a
/// polyline (`polyline_paths`, when `flag & 0x02`) or a list of curved/
/// straight edges (`segs`).
// _dwg_HATCH_PolylinePath (still bindgen-generated -- not blocklisted)
// references the raw tag name `_dwg_HATCH_Path` directly in its `parent`
// field, so this alias needs to exist even though nothing in this crate
// otherwise uses the tag name (only the `Dwg_HATCH_Path` typedef above).
pub type _dwg_HATCH_Path = Dwg_HATCH_Path;
/// `_dwg_HATCH_DefLine` (dwg.h) -- one pattern-fill "definition line": a
/// family of parallel lines (`angle`/`pt0`/`offset`, in the pattern's own
/// unscaled/unrotated definition space) plus an optional dash pattern
/// (`dashes`, positive = dash length, negative = gap length; empty means a
/// continuous line) -- one of `Dwg_Entity_HATCH.deflines`. Unlike
/// `Dwg_HATCH_Path`/`PathSeg`/`ControlPoint` above, this one *is* reachable
/// through dynapi (`num_deflines`/`deflines` are plain top-level
/// `Dwg_Entity_HATCH` fields, not nested inside a Path/PathSeg element) --
/// but it still has to be hand-defined and blocklisted the same way,
/// because allowlisting it directly forces bindgen to also generate a real
/// (non-opaque) `_dwg_entity_HATCH` for its `parent` field to point at
/// (nothing else in this crate ever allowlists `_dwg_entity_HATCH`; HATCH's
/// own fields are all read through dynapi's untyped `void*`), and
/// `_dwg_entity_HATCH` itself then hits the identical struct-codegen
/// failure. `parent` is left as an untyped `*mut c_void` here specifically
/// to avoid that cascade, matching the other three HATCH sub-structs' own
/// `parent` fields. `pt0`/`offset` are declared `BITCODE_2BD` in dwg.h, but
/// typed `BITCODE_2RD` here instead -- same interchangeable-once-decoded
/// reasoning as `Point2D`'s own doc comment (both are just 2 `double`s with
/// no padding); `BITCODE_2RD` is already a bound type elsewhere in this
/// crate (`Dwg_HATCH_PathSeg`), while nothing else pulls in the separate
/// `BITCODE_2BD` alias, so reusing it avoids introducing a type bindgen
/// would otherwise never generate.
pub type _dwg_HATCH_DefLine = Dwg_HATCH_DefLine;
/// `_dwg_HATCH_Color` (dwg.h) -- one gradient-fill color stop: `shift_value`
/// (0.0-1.0, this stop's position along the gradient) plus `color` (a plain
/// `Dwg_Color`, already a normally-bound type elsewhere in this crate --
/// e.g. entity/layer color -- so no further hand-writing needed for it).
/// One of `Dwg_Entity_HATCH.colors` (`num_colors`/`colors`). Same
/// `parent: struct _dwg_entity_HATCH *` cascade as `Dwg_HATCH_DefLine`
/// above (allowlisting it directly forces bindgen to also materialize a
/// real, cascade-failing `_dwg_entity_HATCH`), same fix: blocklisted and
/// hand-defined with `parent` left as an untyped `*mut c_void`. Verified
/// against clang's own authoritative `sizeof()` (64 bytes: parent@0,
/// shift_value@8, color@16) via the same allowlist-then-read-the-failing-
/// layout_tests()-assert technique used for the other hand-written HATCH
/// sub-structs.
pub type _dwg_HATCH_Color = Dwg_HATCH_Color;
/// `_dwg_MLINE_vertex` (dwg.h) -- same bindgen struct-codegen failure as
/// the HATCH types above, hand-defined the same way. Its `vertex`/
/// `vertex_direction`/`miter_direction` fields are declared `BITCODE_3BD`
/// in dwg.h, which bindgen never generates a binding for on its own (only
/// pulled in transitively by whatever references it, and nothing
/// currently allowlisted does) -- `dwg_point_3d` is used instead, since
/// `BITCODE_3BD`/`Dwg_Bitcode_3BD` is just 3 `double`s with no padding,
/// identically laid out. `lines` (the per-vertex parallel-line array,
/// `Dwg_MLINE_line*`) is declared as an opaque `*mut c_void` here rather
/// than a real pointer type -- nothing in this crate reads through it
/// (`uncad`'s MLINE rendering only uses `vertex`, the centerline point;
/// see docs/CAVEATS.md), and leaving it untyped avoids also needing to
/// bind/hand-write `Dwg_MLINE_line` just for a field no caller
/// dereferences.
/// `_dwg_MLINESTYLE_line` (dwg.h) -- one parallel-line definition in an
/// MLINESTYLE OBJECT: `offset` (distance from the MLINE centerline,
/// combined with each MLINE vertex's own `miter_direction` to get that
/// line's actual point -- see `uncad`'s `convert::convert_mline` doc
/// comment) plus `color`/`lt_index`/`lt_ltype` (this project only reads
/// `offset`; the rest aren't used for rendering). Same
/// `parent: struct _dwg_object_MLINESTYLE *` cascade as the HATCH
/// sub-structs above (confirmed: allowlisting it alone produces a
/// `1usize - 112usize` layout_tests() assert on `_dwg_object_MLINESTYLE`).
/// Blocklisted and hand-defined instead, same recipe -- verified against
/// clang's real `sizeof()` (80 bytes: parent@0, offset@8, color@16,
/// lt_index@64, lt_ltype@72) the same way. `lt_ltype` (`BITCODE_H`, since
/// 2018) is a real `*mut Dwg_Object_Ref` here rather than an opaque
/// `c_void` pointer -- `Dwg_Object_Ref` is already a plain bound type
/// elsewhere in this crate, so there's no extra hand-writing needed to type
/// it correctly, unlike `Dwg_MLINE_vertex.lines` above.
pub type _dwg_MLINESTYLE_line = Dwg_MLINESTYLE_line;
const _: = ;