pycadkit 0.3.3__tar.gz → 0.3.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (179) hide show
  1. {pycadkit-0.3.3 → pycadkit-0.3.4}/Cargo.lock +10 -10
  2. {pycadkit-0.3.3 → pycadkit-0.3.4}/Cargo.toml +7 -7
  3. {pycadkit-0.3.3 → pycadkit-0.3.4}/PKG-INFO +1 -1
  4. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dgn/src/native/decode_v8.rs +3 -2
  5. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dgn/src/writer/raster_template.rs +36 -12
  6. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dgn/src/writer/tests/raster_template.rs +117 -1
  7. {pycadkit-0.3.3 → pycadkit-0.3.4}/LICENSE-APACHE +0 -0
  8. {pycadkit-0.3.3 → pycadkit-0.3.4}/LICENSE-MIT +0 -0
  9. {pycadkit-0.3.3 → pycadkit-0.3.4}/NOTICE +0 -0
  10. {pycadkit-0.3.3 → pycadkit-0.3.4}/README.md +0 -0
  11. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit/Cargo.toml +0 -0
  12. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit/LICENSE-APACHE +0 -0
  13. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit/LICENSE-MIT +0 -0
  14. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit/NOTICE +0 -0
  15. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit/README.md +0 -0
  16. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit/examples/interchange.rs +0 -0
  17. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit/src/lib.rs +0 -0
  18. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-core/Cargo.toml +0 -0
  19. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-core/LICENSE-APACHE +0 -0
  20. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-core/LICENSE-MIT +0 -0
  21. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-core/NOTICE +0 -0
  22. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-core/README.md +0 -0
  23. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-core/src/aci.rs +0 -0
  24. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-core/src/bytes.rs +0 -0
  25. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-core/src/error.rs +0 -0
  26. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-core/src/export.rs +0 -0
  27. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-core/src/geom.rs +0 -0
  28. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-core/src/geom_ops.rs +0 -0
  29. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-core/src/lib.rs +0 -0
  30. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-core/src/model.rs +0 -0
  31. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-core/src/ops.rs +0 -0
  32. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-core/src/options.rs +0 -0
  33. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-core/src/polygon.rs +0 -0
  34. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-core/src/svg.rs +0 -0
  35. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-core/src/text.rs +0 -0
  36. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-core/src/units.rs +0 -0
  37. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dgn/Cargo.toml +0 -0
  38. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dgn/LICENSE-APACHE +0 -0
  39. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dgn/LICENSE-MIT +0 -0
  40. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dgn/NOTICE +0 -0
  41. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dgn/README.md +0 -0
  42. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dgn/examples/dgn_summary.rs +0 -0
  43. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dgn/examples/raster_structure.rs +0 -0
  44. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dgn/src/budget.rs +0 -0
  45. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dgn/src/cfb.rs +0 -0
  46. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dgn/src/fuzz_tests.rs +0 -0
  47. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dgn/src/le.rs +0 -0
  48. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dgn/src/level_names.rs +0 -0
  49. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dgn/src/lib.rs +0 -0
  50. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dgn/src/map/mod.rs +0 -0
  51. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dgn/src/map/v7.rs +0 -0
  52. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dgn/src/map/v8.rs +0 -0
  53. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dgn/src/native/element.rs +0 -0
  54. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dgn/src/native/linkage.rs +0 -0
  55. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dgn/src/native/mod.rs +0 -0
  56. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dgn/src/native/v7.rs +0 -0
  57. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dgn/src/native/v8.rs +0 -0
  58. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dgn/src/palette.rs +0 -0
  59. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dgn/src/text.rs +0 -0
  60. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dgn/src/writer/container.rs +0 -0
  61. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dgn/src/writer/encode.rs +0 -0
  62. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dgn/src/writer/mod.rs +0 -0
  63. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dgn/src/writer/polyline.rs +0 -0
  64. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dgn/src/writer/raster.rs +0 -0
  65. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dgn/src/writer/raster_builtin.rs +0 -0
  66. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dgn/src/writer/tables.rs +0 -0
  67. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dgn/src/writer/tests/application.rs +0 -0
  68. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dgn/src/writer/tests/microstation.rs +0 -0
  69. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dgn/src/writer/tests/raster.rs +0 -0
  70. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dgn/src/writer/tests/regressions.rs +0 -0
  71. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dgn/src/writer/tests/text.rs +0 -0
  72. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dgn/src/writer/tests.rs +0 -0
  73. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dgn/src/writer/text.rs +0 -0
  74. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dgn/src/zlib.rs +0 -0
  75. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dgn/tests/common/mod.rs +0 -0
  76. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dgn/tests/private_corpus.rs +0 -0
  77. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dgn/tests/robustness.rs +0 -0
  78. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dgn/tests/v7_corpus.rs +0 -0
  79. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dgn/tests/v8_oracle.rs +0 -0
  80. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dgn/tests/v8_public.rs +0 -0
  81. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dgn/tests/v8_range.rs +0 -0
  82. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dwg/Cargo.toml +0 -0
  83. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dwg/LICENSE-APACHE +0 -0
  84. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dwg/LICENSE-MIT +0 -0
  85. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dwg/NOTICE +0 -0
  86. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dwg/README.md +0 -0
  87. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dwg/examples/docsummary.rs +0 -0
  88. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dwg/examples/dwgdump.rs +0 -0
  89. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dwg/src/bits.rs +0 -0
  90. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dwg/src/classes.rs +0 -0
  91. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dwg/src/codepage.rs +0 -0
  92. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dwg/src/container/lz77_r2004.rs +0 -0
  93. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dwg/src/container/lz77_r2007.rs +0 -0
  94. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dwg/src/container/mod.rs +0 -0
  95. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dwg/src/container/r13.rs +0 -0
  96. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dwg/src/container/r2004.rs +0 -0
  97. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dwg/src/container/r2007.rs +0 -0
  98. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dwg/src/container/reed_solomon.rs +0 -0
  99. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dwg/src/crc.rs +0 -0
  100. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dwg/src/handles.rs +0 -0
  101. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dwg/src/header.rs +0 -0
  102. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dwg/src/lib.rs +0 -0
  103. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dwg/src/mapping/entity.rs +0 -0
  104. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dwg/src/mapping/mod.rs +0 -0
  105. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dwg/src/native/entities.rs +0 -0
  106. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dwg/src/native/mod.rs +0 -0
  107. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dwg/src/object/annotation.rs +0 -0
  108. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dwg/src/object/curves.rs +0 -0
  109. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dwg/src/object/entities.rs +0 -0
  110. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dwg/src/object/hatch.rs +0 -0
  111. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dwg/src/object/misc.rs +0 -0
  112. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dwg/src/object/mod.rs +0 -0
  113. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dwg/src/object/registry.rs +0 -0
  114. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dwg/src/object/tables.rs +0 -0
  115. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dwg/src/reader.rs +0 -0
  116. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dwg/src/version.rs +0 -0
  117. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dwg/tests/corpus.rs +0 -0
  118. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dwg/tests/oracle.rs +0 -0
  119. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dwg/tests/robustness.rs +0 -0
  120. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dxf/Cargo.toml +0 -0
  121. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dxf/LICENSE-APACHE +0 -0
  122. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dxf/LICENSE-MIT +0 -0
  123. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dxf/NOTICE +0 -0
  124. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dxf/README.md +0 -0
  125. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dxf/examples/dump.rs +0 -0
  126. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dxf/src/lib.rs +0 -0
  127. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dxf/src/native/mod.rs +0 -0
  128. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dxf/src/native/text.rs +0 -0
  129. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dxf/src/ocs.rs +0 -0
  130. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dxf/src/reader/common.rs +0 -0
  131. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dxf/src/reader/entities.rs +0 -0
  132. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dxf/src/reader/hatch.rs +0 -0
  133. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dxf/src/reader/mod.rs +0 -0
  134. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dxf/src/reader/records.rs +0 -0
  135. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dxf/src/reader/tables.rs +0 -0
  136. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dxf/src/writer/curves.rs +0 -0
  137. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dxf/src/writer/entities.rs +0 -0
  138. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dxf/src/writer/mod.rs +0 -0
  139. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dxf/src/writer/out.rs +0 -0
  140. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dxf/tests/ascii_vs_binary.rs +0 -0
  141. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dxf/tests/common/mod.rs +0 -0
  142. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dxf/tests/compare_reader_with_ezdxf.py +0 -0
  143. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dxf/tests/review_fixes.rs +0 -0
  144. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dxf/tests/robustness.rs +0 -0
  145. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dxf/tests/roundtrip.rs +0 -0
  146. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dxf/tests/synthetic_read.rs +0 -0
  147. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dxf/tests/synthetic_write.rs +0 -0
  148. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-dxf/tests/validate_with_ezdxf.py +0 -0
  149. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-gml/Cargo.toml +0 -0
  150. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-gml/LICENSE-APACHE +0 -0
  151. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-gml/LICENSE-MIT +0 -0
  152. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-gml/NOTICE +0 -0
  153. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-gml/README.md +0 -0
  154. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-gml/src/curves.rs +0 -0
  155. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-gml/src/export.rs +0 -0
  156. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-gml/src/geometry.rs +0 -0
  157. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-gml/src/lib.rs +0 -0
  158. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-gml/src/mapping.rs +0 -0
  159. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-gml/src/native.rs +0 -0
  160. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-gml/src/tkgm.rs +0 -0
  161. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-gml/src/validate.rs +0 -0
  162. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-gml/src/xml.rs +0 -0
  163. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-gml/tests/roundtrip.rs +0 -0
  164. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-gml/tests/support/export_cases.rs +0 -0
  165. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-gml/tests/support/tkgm_cases.rs +0 -0
  166. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-py/Cargo.toml +0 -0
  167. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-py/LICENSE-APACHE +0 -0
  168. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-py/LICENSE-MIT +0 -0
  169. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-py/NOTICE +0 -0
  170. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-py/README.md +0 -0
  171. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-py/src/lib.rs +0 -0
  172. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-py/tests/conftest.py +0 -0
  173. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-py/tests/test_cadkit.py +0 -0
  174. {pycadkit-0.3.3 → pycadkit-0.3.4}/crates/cadkit-py/tests/test_citygml.py +0 -0
  175. {pycadkit-0.3.3 → pycadkit-0.3.4}/pyproject.toml +0 -0
  176. {pycadkit-0.3.3 → pycadkit-0.3.4}/python/cadkit/__init__.py +0 -0
  177. {pycadkit-0.3.3 → pycadkit-0.3.4}/python/cadkit/__init__.pyi +0 -0
  178. {pycadkit-0.3.3 → pycadkit-0.3.4}/python/cadkit/_cadkit.pyi +0 -0
  179. {pycadkit-0.3.3 → pycadkit-0.3.4}/python/cadkit/py.typed +0 -0
@@ -66,7 +66,7 @@ checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649"
66
66
 
67
67
  [[package]]
68
68
  name = "cadkit"
69
- version = "0.3.3"
69
+ version = "0.3.4"
70
70
  dependencies = [
71
71
  "cadkit-core",
72
72
  "cadkit-dgn",
@@ -78,7 +78,7 @@ dependencies = [
78
78
 
79
79
  [[package]]
80
80
  name = "cadkit-capi"
81
- version = "0.3.3"
81
+ version = "0.3.4"
82
82
  dependencies = [
83
83
  "cadkit",
84
84
  "serde",
@@ -87,7 +87,7 @@ dependencies = [
87
87
 
88
88
  [[package]]
89
89
  name = "cadkit-cli"
90
- version = "0.3.3"
90
+ version = "0.3.4"
91
91
  dependencies = [
92
92
  "cadkit",
93
93
  "clap",
@@ -96,7 +96,7 @@ dependencies = [
96
96
 
97
97
  [[package]]
98
98
  name = "cadkit-core"
99
- version = "0.3.3"
99
+ version = "0.3.4"
100
100
  dependencies = [
101
101
  "serde",
102
102
  "serde_json",
@@ -105,7 +105,7 @@ dependencies = [
105
105
 
106
106
  [[package]]
107
107
  name = "cadkit-dgn"
108
- version = "0.3.3"
108
+ version = "0.3.4"
109
109
  dependencies = [
110
110
  "cadkit-core",
111
111
  "cfb",
@@ -116,7 +116,7 @@ dependencies = [
116
116
 
117
117
  [[package]]
118
118
  name = "cadkit-dwg"
119
- version = "0.3.3"
119
+ version = "0.3.4"
120
120
  dependencies = [
121
121
  "cadkit-core",
122
122
  "cadkit-dxf",
@@ -126,7 +126,7 @@ dependencies = [
126
126
 
127
127
  [[package]]
128
128
  name = "cadkit-dxf"
129
- version = "0.3.3"
129
+ version = "0.3.4"
130
130
  dependencies = [
131
131
  "cadkit-core",
132
132
  "encoding_rs",
@@ -135,7 +135,7 @@ dependencies = [
135
135
 
136
136
  [[package]]
137
137
  name = "cadkit-gml"
138
- version = "0.3.3"
138
+ version = "0.3.4"
139
139
  dependencies = [
140
140
  "cadkit-core",
141
141
  "quick-xml",
@@ -145,7 +145,7 @@ dependencies = [
145
145
 
146
146
  [[package]]
147
147
  name = "cadkit-py"
148
- version = "0.3.3"
148
+ version = "0.3.4"
149
149
  dependencies = [
150
150
  "cadkit",
151
151
  "pyo3",
@@ -155,7 +155,7 @@ dependencies = [
155
155
 
156
156
  [[package]]
157
157
  name = "cadkit-wasm"
158
- version = "0.3.3"
158
+ version = "0.3.4"
159
159
  dependencies = [
160
160
  "cadkit",
161
161
  "js-sys",
@@ -4,7 +4,7 @@ members = ["crates/*"]
4
4
  exclude = ["fuzz"]
5
5
 
6
6
  [workspace.package]
7
- version = "0.3.3"
7
+ version = "0.3.4"
8
8
  edition = "2024"
9
9
  rust-version = "1.85"
10
10
  license = "MIT OR Apache-2.0"
@@ -14,12 +14,12 @@ keywords = ["cad", "dwg", "dgn", "dxf", "citygml"]
14
14
  categories = ["parser-implementations", "graphics", "encoding", "science::geo"]
15
15
 
16
16
  [workspace.dependencies]
17
- cadkit-core = { path = "crates/cadkit-core", version = "0.3.3" }
18
- cadkit-dgn = { path = "crates/cadkit-dgn", version = "0.3.3" }
19
- cadkit-dwg = { path = "crates/cadkit-dwg", version = "0.3.3" }
20
- cadkit-dxf = { path = "crates/cadkit-dxf", version = "0.3.3" }
21
- cadkit-gml = { path = "crates/cadkit-gml", version = "0.3.3" }
22
- cadkit = { path = "crates/cadkit", version = "0.3.3" }
17
+ cadkit-core = { path = "crates/cadkit-core", version = "0.3.4" }
18
+ cadkit-dgn = { path = "crates/cadkit-dgn", version = "0.3.4" }
19
+ cadkit-dwg = { path = "crates/cadkit-dwg", version = "0.3.4" }
20
+ cadkit-dxf = { path = "crates/cadkit-dxf", version = "0.3.4" }
21
+ cadkit-gml = { path = "crates/cadkit-gml", version = "0.3.4" }
22
+ cadkit = { path = "crates/cadkit", version = "0.3.4" }
23
23
  serde = { version = "1", features = ["derive"] }
24
24
  serde_json = "1"
25
25
  thiserror = "2"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pycadkit
3
- Version: 0.3.3
3
+ Version: 0.3.4
4
4
  Classifier: Development Status :: 3 - Alpha
5
5
  Classifier: Intended Audience :: Developers
6
6
  Classifier: Intended Audience :: Science/Research
@@ -136,9 +136,10 @@ pub fn decode(raw: &RawElement, enc: &'static Encoding, limits: &Limits) -> Elem
136
136
  35 => d.cell().map(ElementData::SharedCellInstance),
137
137
  37 => d.tag(&linkages).map(ElementData::Tag),
138
138
  39 => d.tag_set(&linkages).map(ElementData::TagSet),
139
+ // An attachment written with a relative path stores an empty full path.
139
140
  90 => Ok(ElementData::RasterReference {
140
- file_name: linkage::string(&linkages, 3),
141
- full_path: linkage::string(&linkages, 0x1f),
141
+ file_name: linkage::string(&linkages, 3).filter(|s| !s.is_empty()),
142
+ full_path: linkage::string(&linkages, 0x1f).filter(|s| !s.is_empty()),
142
143
  }),
143
144
  94 => le::f64s::<16>(d.b, 0x78)
144
145
  .map(|matrix| ElementData::RasterFrame {
@@ -168,7 +168,7 @@ impl Template {
168
168
  let (Some(path), Some(size)) = (path, size_px) else {
169
169
  return Err(Error::Unsupported(NEEDS_PATH_AND_SIZE.into()));
170
170
  };
171
- let url = file_url(path)?;
171
+ let url = full_path(path)?;
172
172
  let name = file_name(e, path)?;
173
173
  let p = Placement::new(*position, *u_vector, *v_vector, *size, model)?;
174
174
  let dpi = self.dpi(e)?;
@@ -388,9 +388,11 @@ impl XAttribute {
388
388
  off = start.checked_add(len)?;
389
389
  }
390
390
  let trailer = payload.get(off..)?.to_vec();
391
- // Sub-records 3 and 4 must hold exactly one string, which is what gets replaced.
391
+ // Sub-records 3 and 4 must hold exactly one string, which is what gets replaced; the
392
+ // full path in 4 is empty in attachments written with a relative path.
392
393
  let single = |i: usize| subs.get(i).and_then(|(_, d)| utf16z_text(d));
393
- if trailer.len() > 16 || single(3).is_none() || single(4).is_none() {
394
+ let empty = subs.get(4).is_some_and(|(_, d)| d.as_slice() == [0, 0]);
395
+ if trailer.len() > 16 || single(3).is_none() || (single(4).is_none() && !empty) {
394
396
  return None;
395
397
  }
396
398
  Some(Self {
@@ -466,10 +468,14 @@ fn identity(b: &mut [u8], id: u64, time: f64) -> Result<()> {
466
468
  f64_at(b, 0x18, time)
467
469
  }
468
470
 
469
- /// The stored URL: the path as given when it is already a `file://` URL, else `file://`
470
- /// followed by the path. The path must be absolute (a drive, UNC or rooted path): the
471
- /// attachments carry no relative paths.
472
- fn file_url(path: &str) -> Result<String> {
471
+ /// The stored full path (string linkage `0x1F`, XAttribute sub-record 4).
472
+ ///
473
+ /// An absolute path (a drive, UNC or rooted path) is stored as a `file://` URL, as every
474
+ /// observed attachment stores it; a path that already is one is kept. A relative path
475
+ /// names a file beside the DGN, so the attachment carries no machine-specific location:
476
+ /// a bare file name stores an empty full path, `.\name` (or `./name`) is stored as given.
477
+ /// Relative paths into other folders are refused.
478
+ fn full_path(path: &str) -> Result<String> {
473
479
  let has_scheme = path
474
480
  .get(..7)
475
481
  .is_some_and(|s| s.eq_ignore_ascii_case("file://"));
@@ -478,17 +484,35 @@ fn file_url(path: &str) -> Result<String> {
478
484
  } else {
479
485
  path
480
486
  };
487
+ if local.contains('\0') {
488
+ return Err(Error::invalid(0, "DGN raster path contains NUL"));
489
+ }
481
490
  let bytes = local.as_bytes();
482
491
  let drive = matches!(bytes, [d, b':', b'\\' | b'/', ..] if d.is_ascii_alphabetic());
483
- if local.contains('\0') || !(drive || local.starts_with('\\') || local.starts_with('/')) {
492
+ if drive || local.starts_with('\\') || local.starts_with('/') {
493
+ return Ok(if has_scheme {
494
+ path.to_owned()
495
+ } else {
496
+ format!("file://{path}")
497
+ });
498
+ }
499
+ let name = local
500
+ .strip_prefix(".\\")
501
+ .or_else(|| local.strip_prefix("./"))
502
+ .unwrap_or(local);
503
+ if has_scheme
504
+ || name.is_empty()
505
+ || name.contains(['\\', '/', ':'])
506
+ || matches!(name, "." | "..")
507
+ {
484
508
  return Err(Error::Unsupported(
485
- "DGN raster path must be absolute".into(),
509
+ "DGN raster path must be absolute or name a file beside the DGN".into(),
486
510
  ));
487
511
  }
488
- Ok(if has_scheme {
489
- path.to_owned()
512
+ Ok(if name.len() == local.len() {
513
+ String::new()
490
514
  } else {
491
- format!("file://{path}")
515
+ local.to_owned()
492
516
  })
493
517
  }
494
518
 
@@ -622,7 +622,10 @@ fn invalid_attachments_are_reported() {
622
622
  no_size,
623
623
  Some("new DGN raster attachments need path and size_px"),
624
624
  ),
625
- (relative, Some("DGN raster path must be absolute")),
625
+ (
626
+ relative,
627
+ Some("DGN raster path must be absolute or name a file beside the DGN"),
628
+ ),
626
629
  (parallel, None),
627
630
  (lifted, Some("nonzero Z cannot be written into a 2D seed")),
628
631
  ] {
@@ -647,6 +650,119 @@ fn invalid_attachments_are_reported() {
647
650
  ));
648
651
  }
649
652
 
653
+ /// A relative path names a file beside the DGN: the name is stored and the full path is
654
+ /// empty for a bare name and kept as given for `.\name`, so the file carries no
655
+ /// machine-specific location. The output's groups serve as a template again.
656
+ #[test]
657
+ fn relative_paths_store_no_machine_location() {
658
+ let read = ReadOptions::default();
659
+ for (seed, three) in [(template_seed(false), false), (seed(true), true)] {
660
+ let mut written = attachments();
661
+ let paths = ["sheet.tif", "sheet.tif", ".\\other.tif", "kat planı.tif"];
662
+ for (e, p) in written.iter_mut().zip(paths) {
663
+ if let EntityKind::Image { path, .. } = &mut e.kind {
664
+ *path = Some(p.into());
665
+ }
666
+ }
667
+ let output = write_v8(&document(three, written), &seed, &clear()).unwrap();
668
+ let native = v8::read(&output, &read).unwrap();
669
+ let references: Vec<(String, String)> = native.models[0]
670
+ .control_pages
671
+ .iter()
672
+ .flat_map(|p| &p.elements)
673
+ .filter(|r| r.type_code() == 90)
674
+ .map(|r| {
675
+ let links = linkage::parse(
676
+ r.attributes(),
677
+ r.attribute_offset(),
678
+ true,
679
+ encoding_rs::UTF_8,
680
+ );
681
+ let text = |id: u32| {
682
+ links
683
+ .iter()
684
+ .find_map(|l| match &l.data {
685
+ LinkageData::String {
686
+ string_id, text, ..
687
+ } if *string_id == id => Some(text.clone()),
688
+ _ => None,
689
+ })
690
+ .unwrap()
691
+ };
692
+ (text(3), text(0x1f))
693
+ })
694
+ .collect();
695
+ let want = [
696
+ ("sheet.tif", ""),
697
+ ("sheet.tif", ""),
698
+ ("other.tif", ".\\other.tif"),
699
+ ("kat planı.tif", ""),
700
+ ];
701
+ assert_eq!(references, want.map(|(n, f)| (n.to_owned(), f.to_owned())));
702
+ let payloads: Vec<Vec<u8>> = native.models[0]
703
+ .graphic_aux
704
+ .iter()
705
+ .flat_map(|p| &p.records)
706
+ .filter(|a| a.kind == 170)
707
+ .map(|a| a.payload.clone())
708
+ .collect();
709
+ assert_eq!(payloads.len(), 4);
710
+ for (payload, (name, full)) in payloads.iter().zip(want) {
711
+ let has = |s: &str| payload.windows(utf16z(s).len()).any(|w| w == utf16z(s));
712
+ assert!(has(name));
713
+ assert!(full.is_empty() || has(full));
714
+ assert!(!has("file://"));
715
+ }
716
+ // Read back: the path is the stored full path, else the name; no raster warning.
717
+ let reread = crate::read(&output, &read).unwrap();
718
+ assert!(
719
+ reread
720
+ .warnings
721
+ .iter()
722
+ .all(|w| !w.code.starts_with("dgn.raster")),
723
+ "{:?}",
724
+ reread.warnings
725
+ );
726
+ let got: Vec<(Option<String>, Option<String>)> = reread.models[0]
727
+ .entities
728
+ .iter()
729
+ .map(|e| match &e.kind {
730
+ EntityKind::Image { path, .. } => (path.clone(), text(e, "dgn.raster_path")),
731
+ other => panic!("{other:?}"),
732
+ })
733
+ .collect();
734
+ assert_eq!(
735
+ got,
736
+ [
737
+ (Some("sheet.tif".into()), None),
738
+ (Some("sheet.tif".into()), None),
739
+ (Some(".\\other.tif".into()), Some(".\\other.tif".into())),
740
+ (Some("kat planı.tif".into()), None),
741
+ ]
742
+ );
743
+ assert!(crate::seed_has_raster_template(&output, &read).unwrap());
744
+ }
745
+ for bad in [
746
+ "plans\\sheet.tif",
747
+ "..\\sheet.tif",
748
+ "file://sheet.tif",
749
+ ".\\",
750
+ "..",
751
+ ] {
752
+ let mut e = attachments().remove(0);
753
+ if let EntityKind::Image { path, .. } = &mut e.kind {
754
+ *path = Some(bad.into());
755
+ }
756
+ assert!(
757
+ matches!(
758
+ write_v8(&document(false, vec![e]), &template_seed(false), &clear()),
759
+ Err(Error::Unsupported(_))
760
+ ),
761
+ "{bad}"
762
+ );
763
+ }
764
+ }
765
+
650
766
  #[test]
651
767
  fn incomplete_groups_are_not_templates() {
652
768
  // The seed of the preservation tests holds a 90, 92 and one 91 but no full group.
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes