Added the possibilty to not only make quadratic items

This commit is contained in:
2026-05-26 17:35:50 +02:00
parent be58c5941d
commit bca4fcc936
15 changed files with 371 additions and 134 deletions
+25 -19
View File
@@ -5,13 +5,17 @@ import (
)
// Pack computes the maximum grid of items that fit on the plate.
// Item spacing uses the SVG viewport size (spec.SizeMM); bleed/margin/padding live inside the template.
// Cells use the full item SVG canvas (product + bleed, margin, crop marks); spacing is between canvases.
func Pack(plate model.Plate, spec model.ItemSpec, spacingMM float64) model.LayoutPreview {
pw := plate.PrintableWidth()
ph := plate.PrintableHeight()
itemW := spec.SizeMM
cw := itemW + spacingMM
ch := itemW + spacingMM
footW := spec.ViewportWidth()
footH := spec.ViewportHeight()
canvasW := spec.CanvasWidthMM()
canvasH := spec.CanvasHeightMM()
trim := spec.TrimOffsetMM()
cw := canvasW + spacingMM
ch := canvasH + spacingMM
cols, rows := gridCount(pw, ph, cw, ch)
count := cols * rows
@@ -30,21 +34,23 @@ func Pack(plate model.Plate, spec model.ItemSpec, spacingMM float64) model.Layou
}
return model.LayoutPreview{
PlateWidthMM: plate.WidthMM,
PlateHeightMM: plate.HeightMM,
PrintableXMM: ox,
PrintableYMM: oy,
PrintableWMM: pw,
PrintableHMM: ph,
CellWidthMM: cw,
CellHeightMM: ch,
FootprintWMM: itemW,
FootprintHMM: itemW,
SpacingMM: spacingMM,
Columns: cols,
Rows: rows,
Count: count,
Positions: positions,
PlateWidthMM: plate.WidthMM,
PlateHeightMM: plate.HeightMM,
PrintableXMM: ox,
PrintableYMM: oy,
PrintableWMM: pw,
PrintableHMM: ph,
CellWidthMM: cw,
CellHeightMM: ch,
FootprintWMM: footW,
FootprintHMM: footH,
TrimOffsetMM: trim,
CanvasWidthMM: canvasW,
CanvasHeightMM: canvasH,
Columns: cols,
Rows: rows,
Count: count,
Positions: positions,
}
}
+33 -10
View File
@@ -15,29 +15,52 @@ func TestPack(t *testing.T) {
MarginBottom: 10,
MarginLeft: 10,
}
spec := model.ItemSpec{SizeMM: 80, BleedMM: 2, MarginMM: 5}
// viewport 80mm, cell = 80+2 = 82, printable 280x380 -> cols=3, rows=4 -> 12
spec := model.ItemSpec{WidthMM: 80, HeightMM: 80, BleedMM: 2, MarginMM: 5}
// canvas 106mm (80+2*13), cell 108, printable 280×380 cols=2, rows=3
preview := Pack(plate, spec, 2)
if preview.Columns != 3 {
t.Fatalf("columns: got %d want 3", preview.Columns)
if preview.Columns != 2 {
t.Fatalf("columns: got %d want 2", preview.Columns)
}
if preview.Rows != 4 {
t.Fatalf("rows: got %d want 4", preview.Rows)
if preview.Rows != 3 {
t.Fatalf("rows: got %d want 3", preview.Rows)
}
if preview.Count != 12 {
t.Fatalf("count: got %d want 12", preview.Count)
if preview.Count != 6 {
t.Fatalf("count: got %d want 6", preview.Count)
}
if preview.FootprintWMM != 80 {
t.Fatalf("footprint width: got %v want 80", preview.FootprintWMM)
}
if len(preview.Positions) != 12 {
t.Fatalf("positions: got %d want 12", len(preview.Positions))
if preview.CanvasWidthMM != 106 {
t.Fatalf("canvas width: got %v want 106", preview.CanvasWidthMM)
}
if len(preview.Positions) != 6 {
t.Fatalf("positions: got %d want 6", len(preview.Positions))
}
if preview.Positions[0].XMM != 10 || preview.Positions[0].YMM != 10 {
t.Fatalf("first position: got (%v,%v)", preview.Positions[0].XMM, preview.Positions[0].YMM)
}
}
func TestPackRectangle(t *testing.T) {
plate := model.Plate{
WidthMM: 300,
HeightMM: 400,
MarginTop: 10,
MarginRight: 10,
MarginBottom: 10,
MarginLeft: 10,
}
// 100×50 mm, trim 6 → canvas 112×62, cell 114×64, printable 280×380 → cols=2, rows=5
spec := model.ItemSpec{WidthMM: 100, HeightMM: 50, BleedMM: 0, MarginMM: 0}
preview := Pack(plate, spec, 2)
if preview.Columns != 2 || preview.Rows != 5 || preview.Count != 10 {
t.Fatalf("got %d cols, %d rows, %d count; want 2, 5, 10", preview.Columns, preview.Rows, preview.Count)
}
if preview.FootprintWMM != 100 || preview.FootprintHMM != 50 {
t.Fatalf("footprint: got %.0f×%.0f want 100×50", preview.FootprintWMM, preview.FootprintHMM)
}
}
func TestPackZeroCell(t *testing.T) {
plate := model.Plate{WidthMM: 10, HeightMM: 10}
spec := model.ItemSpec{SizeMM: 100}