package platepdf import ( "bytes" "encoding/base64" "fmt" "printer.backend/internal/model" ) const renderDPI = 300 // BuildCompositeSVG assembles a plate-sized SVG by embedding each item as a PNG // rendered by rsvg-convert (identical to the standalone item file). func BuildCompositeSVG(plate model.Plate, spec model.ItemSpec, itemSVG []byte, preview model.LayoutPreview) ([]byte, error) { itemW, itemH, err := svgViewportMM(itemSVG) if err != nil { return nil, err } if itemW <= 0 || itemH <= 0 { itemW, itemH = spec.SizeMM, spec.SizeMM } itemPNG, err := svgToPNGViaRsvg(itemSVG, renderDPI) if err != nil { return nil, fmt.Errorf("render item: %w", err) } itemB64 := base64.StdEncoding.EncodeToString(itemPNG) var b bytes.Buffer fmt.Fprintf(&b, ` `, plate.WidthMM, plate.HeightMM, plate.WidthMM, plate.HeightMM, plate.WidthMM, plate.HeightMM, preview.PrintableXMM, preview.PrintableYMM, preview.PrintableWMM, preview.PrintableHMM, ) for _, pos := range preview.Positions { fmt.Fprintf(&b, ``, pos.XMM, pos.YMM, itemW, itemH, itemB64, ) } b.WriteString("\n") return b.Bytes(), nil }