use dxfbin::{BinarySink, convert_all};
fn text_to_binary(text: &[u8]) -> Vec<u8> {
let mut out = Vec::new();
let mut sink = BinarySink::new(&mut out);
convert_all(text, &mut sink).expect("dxfbin conversion failed");
out
}
#[test]
fn header_variables() {
let text = b"\
0\nSECTION\n\
2\nHEADER\n\
9\n$ACADVER\n\
1\nAC1027\n\
9\n$INSUNITS\n\
70\n4\n\
9\n$LTSCALE\n\
40\n2.5\n\
9\n$INSBASE\n\
10\n100.0\n\
20\n200.0\n\
30\n0.0\n\
0\nENDSEC\n\
0\nEOF\n";
let binary = text_to_binary(text);
let drawing = dxfscan::scan(&binary).expect("scan failed");
match drawing.header("$ACADVER") {
Some(dxfscan::GroupValue::String(s)) => assert_eq!(*s, b"AC1027"),
other => panic!("expected String, got {other:?}"),
}
match drawing.header("$INSUNITS") {
Some(dxfscan::GroupValue::Int16(v)) => assert_eq!(*v, 4),
other => panic!("expected Int16, got {other:?}"),
}
match drawing.header("$LTSCALE") {
Some(dxfscan::GroupValue::Double(v)) => assert_eq!(*v, 2.5),
other => panic!("expected Double, got {other:?}"),
}
match drawing.header("$INSBASE") {
Some(dxfscan::GroupValue::Double(v)) => assert_eq!(*v, 100.0),
other => panic!("expected Double (first component), got {other:?}"),
}
assert!(drawing.header("$NOSUCH").is_none());
}
#[test]
fn minimal_dxf_sections() {
let text = b"\
0\nSECTION\n\
2\nTABLES\n\
0\nTABLE\n\
2\nLAYER\n\
70\n1\n\
0\nLAYER\n\
5\nA\n\
2\nWalls\n\
70\n0\n\
62\n7\n\
370\n50\n\
0\nENDTAB\n\
0\nENDSEC\n\
0\nSECTION\n\
2\nBLOCKS\n\
0\nBLOCK\n\
2\nDoor\n\
10\n0.0\n\
20\n0.0\n\
0\nLINE\n\
5\n10\n\
8\nWalls\n\
10\n0.0\n\
20\n0.0\n\
11\n1.0\n\
21\n0.0\n\
0\nENDBLK\n\
0\nENDSEC\n\
0\nSECTION\n\
2\nENTITIES\n\
0\nLINE\n\
5\n20\n\
8\nWalls\n\
62\n1\n\
10\n0.0\n\
20\n0.0\n\
11\n10.0\n\
21\n5.0\n\
0\nCIRCLE\n\
5\n21\n\
8\nWalls\n\
10\n5.0\n\
20\n5.0\n\
40\n2.5\n\
0\nINSERT\n\
5\n22\n\
8\nWalls\n\
2\nDoor\n\
10\n3.0\n\
20\n4.0\n\
41\n1.0\n\
42\n1.0\n\
50\n90.0\n\
0\nENDSEC\n\
0\nEOF\n";
let binary = text_to_binary(text);
let drawing = dxfscan::scan(&binary).expect("scan failed");
assert_eq!(drawing.layers.len(), 1);
assert_eq!(drawing.layers[0].name, b"Walls");
assert_eq!(drawing.layers[0].color, 7);
assert_eq!(drawing.layers[0].lineweight, 50);
assert!(drawing.layer_by_name(b"Walls").is_some());
assert_eq!(drawing.blocks.len(), 1);
assert_eq!(drawing.blocks[0].name, b"Door");
assert_eq!(drawing.blocks[0].entities.len(), 1);
assert!(drawing.block_by_name(b"Door").is_some());
assert_eq!(drawing.entities.len(), 3);
match &drawing.entities[0] {
dxfscan::Entity::Line(common, line) => {
assert_eq!(common.handle, b"20");
assert_eq!(common.layer, b"Walls");
assert_eq!(common.color, 1);
assert_eq!(line.p1.x, 0.0);
assert_eq!(line.p2.x, 10.0);
assert_eq!(line.p2.y, 5.0);
}
other => panic!("expected Line, got {other:?}"),
}
match &drawing.entities[1] {
dxfscan::Entity::Circle(common, circle) => {
assert_eq!(common.handle, b"21");
assert_eq!(circle.center.x, 5.0);
assert_eq!(circle.center.y, 5.0);
assert_eq!(circle.radius, 2.5);
}
other => panic!("expected Circle, got {other:?}"),
}
match &drawing.entities[2] {
dxfscan::Entity::Insert(common, insert) => {
assert_eq!(common.handle, b"22");
assert_eq!(insert.name, b"Door");
assert_eq!(insert.location.x, 3.0);
assert_eq!(insert.location.y, 4.0);
assert_eq!(insert.rotation, 90.0);
}
other => panic!("expected Insert, got {other:?}"),
}
assert!(drawing.entity_by_handle(b"20").is_some());
assert!(drawing.entity_by_handle(b"21").is_some());
assert!(drawing.entity_by_handle(b"99").is_none());
}
#[test]
fn numeric_entity_types() {
let text = b"\
0\nSECTION\n\
2\nENTITIES\n\
0\nARC\n\
5\n1\n\
8\n0\n\
10\n1.0\n\
20\n2.0\n\
40\n5.0\n\
50\n0.0\n\
51\n180.0\n\
0\nELLIPSE\n\
5\n2\n\
8\n0\n\
10\n0.0\n\
20\n0.0\n\
11\n3.0\n\
21\n0.0\n\
40\n0.5\n\
41\n0.0\n\
42\n6.283185307\n\
0\nENDSEC\n\
0\nEOF\n";
let binary = text_to_binary(text);
let drawing = dxfscan::scan(&binary).expect("scan failed");
assert_eq!(drawing.entities.len(), 2);
match &drawing.entities[0] {
dxfscan::Entity::Arc(_, arc) => {
assert_eq!(arc.center.x, 1.0);
assert_eq!(arc.center.y, 2.0);
assert_eq!(arc.radius, 5.0);
assert_eq!(arc.start_angle, 0.0);
assert_eq!(arc.end_angle, 180.0);
}
other => panic!("expected Arc, got {other:?}"),
}
match &drawing.entities[1] {
dxfscan::Entity::Ellipse(_, ellipse) => {
assert_eq!(ellipse.major_axis.x, 3.0);
assert_eq!(ellipse.minor_axis_ratio, 0.5);
}
other => panic!("expected Ellipse, got {other:?}"),
}
}
#[test]
fn lwpolyline_vertices() {
let text = b"\
0\nSECTION\n\
2\nENTITIES\n\
0\nLWPOLYLINE\n\
5\n1\n\
8\n0\n\
70\n1\n\
10\n0.0\n\
20\n0.0\n\
42\n0.5\n\
10\n10.0\n\
20\n0.0\n\
10\n10.0\n\
20\n10.0\n\
0\nENDSEC\n\
0\nEOF\n";
let binary = text_to_binary(text);
let drawing = dxfscan::scan(&binary).expect("scan failed");
match &drawing.entities[0] {
dxfscan::Entity::LwPolyline(_, lw) => {
assert!(lw.is_closed());
assert_eq!(lw.vertices.len(), 3);
assert_eq!(lw.vertices[0].x, 0.0);
assert_eq!(lw.vertices[0].bulge, 0.5);
assert_eq!(lw.vertices[1].x, 10.0);
assert_eq!(lw.vertices[1].bulge, 0.0); assert_eq!(lw.vertices[2].y, 10.0);
}
other => panic!("expected LwPolyline, got {other:?}"),
}
}
#[test]
fn attrib_with_embedded_mtext() {
let text = b"\
0\nSECTION\n\
2\nENTITIES\n\
0\nINSERT\n\
5\n100\n\
8\n0\n\
100\nAcDbEntity\n\
100\nAcDbBlockReference\n\
2\nMyBlock\n\
10\n0.0\n\
20\n0.0\n\
66\n1\n\
0\nATTRIB\n\
5\n101\n\
8\n0\n\
100\nAcDbEntity\n\
100\nAcDbText\n\
10\n1.0\n\
20\n2.0\n\
40\n5.0\n\
1\n\n\
100\nAcDbAttribute\n\
2\nTAG1\n\
70\n0\n\
74\n0\n\
100\nAcDbMText\n\
1\nHello from MTEXT\n\
0\nSEQEND\n\
5\n102\n\
0\nENDSEC\n\
0\nEOF\n";
let binary = text_to_binary(text);
let drawing = dxfscan::scan(&binary).expect("scan failed");
assert_eq!(drawing.entities.len(), 1);
match &drawing.entities[0] {
dxfscan::Entity::Insert(_, ins) => {
assert_eq!(ins.attributes.len(), 1);
let a = &ins.attributes[0];
assert_eq!(a.value, b"");
let mt = a.mtext.as_ref().unwrap();
assert_eq!(mt.text, b"Hello from MTEXT");
assert_eq!(a.tag, b"TAG1");
}
other => panic!("expected Insert, got {other:?}"),
}
}
#[test]
fn attrib_justification_and_second_alignment_point() {
let text = b"\
0\nSECTION\n\
2\nENTITIES\n\
0\nINSERT\n\
5\n200\n\
8\n0\n\
100\nAcDbEntity\n\
100\nAcDbBlockReference\n\
2\nTestBlock\n\
10\n0.0\n\
20\n0.0\n\
66\n1\n\
0\nATTRIB\n\
5\n201\n\
8\nLayer1\n\
100\nAcDbEntity\n\
100\nAcDbText\n\
10\n100.0\n\
20\n200.0\n\
40\n8.0\n\
1\n6046\n\
72\n1\n\
11\n110.0\n\
21\n205.0\n\
100\nAcDbAttribute\n\
2\nNUMBER\n\
70\n0\n\
74\n2\n\
0\nSEQEND\n\
5\n202\n\
0\nENDSEC\n\
0\nEOF\n";
let binary = text_to_binary(text);
let drawing = dxfscan::scan(&binary).expect("scan failed");
match &drawing.entities[0] {
dxfscan::Entity::Insert(_, ins) => {
let a = &ins.attributes[0];
assert_eq!(a.value, b"6046");
assert_eq!(a.h_justify, 1); assert_eq!(a.v_justify, 2); assert_eq!(a.second_alignment_point.x, 110.0);
assert_eq!(a.second_alignment_point.y, 205.0);
assert_eq!(a.location.x, 100.0);
assert_eq!(a.location.y, 200.0);
}
other => panic!("expected Insert, got {other:?}"),
}
}