"""Export helpers for packaging assets.""" from __future__ import annotations from io import BytesIO from PIL import Image, ImageDraw from reportlab.lib.pagesizes import A4 from reportlab.lib.utils import ImageReader from reportlab.pdfgen import canvas try: import cairosvg # type: ignore except Exception: # pragma: no cover cairosvg = None def svg_to_png_bytes(svg_content: str, width: int = 1400, height: int = 1000) -> bytes: """Convert SVG content to PNG bytes with a Pillow fallback.""" if cairosvg is not None: return cairosvg.svg2png(bytestring=svg_content.encode("utf-8")) # Fallback when cairosvg is unavailable: branded placeholder raster. img = Image.new("RGB", (width, height), "#0b1220") draw = ImageDraw.Draw(img) draw.rectangle((24, 24, width - 24, height - 24), outline="#00e5ff", width=3) draw.text((48, 56), "Foodlinkk Packaging Preview", fill="#e2e8f0") draw.text((48, 92), "Install cairosvg for full SVG rendering.", fill="#94a3b8") stream = BytesIO() img.save(stream, format="PNG") return stream.getvalue() def svg_to_pdf_bytes(svg_content: str) -> bytes: """Render SVG in a PDF by first rasterizing to PNG.""" png_data = svg_to_png_bytes(svg_content, width=1800, height=1300) png_image = Image.open(BytesIO(png_data)).convert("RGB") output = BytesIO() pdf = canvas.Canvas(output, pagesize=A4) page_w, page_h = A4 img_w, img_h = png_image.size scale = min((page_w - 64) / img_w, (page_h - 64) / img_h) draw_w = img_w * scale draw_h = img_h * scale x = (page_w - draw_w) / 2 y = (page_h - draw_h) / 2 pdf.drawImage(ImageReader(png_image), x, y, width=draw_w, height=draw_h, preserveAspectRatio=True, mask="auto") pdf.showPage() pdf.save() return output.getvalue()