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
+3
View File
@@ -33,6 +33,9 @@ type LayoutPreview struct {
CellHeightMM float64 `json:"cell_height_mm"`
FootprintWMM float64 `json:"footprint_width_mm"`
FootprintHMM float64 `json:"footprint_height_mm"`
TrimOffsetMM float64 `json:"trim_offset_mm"`
CanvasWidthMM float64 `json:"canvas_width_mm"`
CanvasHeightMM float64 `json:"canvas_height_mm"`
Columns int `json:"columns"`
Rows int `json:"rows"`
Count int `json:"count"`
+66 -5
View File
@@ -1,13 +1,74 @@
package model
import "time"
import (
"fmt"
"math"
"time"
)
// ItemSpec holds mask parameters (from template CLI).
type ItemSpec struct {
SizeMM float64 `json:"size_mm"`
BleedMM float64 `json:"bleed_mm"`
MarginMM float64 `json:"margin_mm"`
PaddingMM float64 `json:"padding_mm"`
// SizeMM is legacy: square product when width_mm/height_mm are unset.
SizeMM float64 `json:"size_mm,omitempty"`
WidthMM float64 `json:"width_mm,omitempty"`
HeightMM float64 `json:"height_mm,omitempty"`
CornerRadiusMM float64 `json:"corner_radius_mm,omitempty"`
BleedMM float64 `json:"bleed_mm"`
MarginMM float64 `json:"margin_mm"`
PaddingMM float64 `json:"padding_mm"`
}
// ViewportWidth returns the SVG viewport width used for layout packing.
func (s ItemSpec) ViewportWidth() float64 {
if s.WidthMM > 0 {
return s.WidthMM
}
return s.SizeMM
}
// ViewportHeight returns the SVG viewport height used for layout packing.
func (s ItemSpec) ViewportHeight() float64 {
if s.HeightMM > 0 {
return s.HeightMM
}
return s.SizeMM
}
// markLengthMM is crop-mark extension outside the product (must match svgtemplate).
const markLengthMM = 6
// TrimOffsetMM is bleed + margin + crop marks drawn outside the product rect.
func (s ItemSpec) TrimOffsetMM() float64 {
return s.BleedMM + s.MarginMM + markLengthMM
}
// CanvasWidthMM is the full item SVG width including trim and crop marks.
func (s ItemSpec) CanvasWidthMM() float64 {
return s.ViewportWidth() + 2*s.TrimOffsetMM()
}
// CanvasHeightMM is the full item SVG height including trim and crop marks.
func (s ItemSpec) CanvasHeightMM() float64 {
return s.ViewportHeight() + 2*s.TrimOffsetMM()
}
// Normalize fills width/height from legacy size_mm and validates dimensions.
func (s *ItemSpec) Normalize() error {
if s.WidthMM <= 0 && s.HeightMM <= 0 && s.SizeMM > 0 {
s.WidthMM = s.SizeMM
s.HeightMM = s.SizeMM
}
if s.WidthMM <= 0 || s.HeightMM <= 0 {
return fmt.Errorf("width_mm and height_mm must be positive")
}
if s.CornerRadiusMM < 0 {
return fmt.Errorf("corner_radius_mm must be non-negative")
}
maxR := math.Min(s.WidthMM, s.HeightMM) / 2
if s.CornerRadiusMM > maxR {
return fmt.Errorf("corner_radius_mm must be at most %.2f", maxR)
}
return nil
}
// Item is a printable product type (SVG mask) placed on a plate.