package printer import ( "fmt" "image" "image/color" "image/png" "os" "time" ) // MockDriver implements PrinterDriver for testing and development. // Print() saves a PNG to SaveDir (default /tmp) and logs to stdout. // No hardware required — use this as the default driver until PRT Qutie arrives. type MockDriver struct { connected bool // SaveDir is the directory where label PNGs are written. // Defaults to /tmp. Override in tests to use t.TempDir(). SaveDir string } // NewMockDriver creates a MockDriver that saves PNGs to /tmp. func NewMockDriver() *MockDriver { return &MockDriver{SaveDir: "/tmp"} } // Connect marks the driver as connected. func (m *MockDriver) Connect() error { m.connected = true return nil } // Disconnect marks the driver as disconnected. func (m *MockDriver) Disconnect() error { m.connected = false return nil } // Print reconstructs the label image from the 1-bit bitmap and saves it as a PNG. // Returns ErrEmptyBitmap if bitmap is nil or empty. func (m *MockDriver) Print(bitmap []byte, width, height int) error { if len(bitmap) == 0 { return ErrEmptyBitmap } // Reconstruct image from 1-bit packed bitmap for visual inspection. img := image.NewGray(image.Rect(0, 0, width, height)) rowBytes := (width + 7) / 8 for y := 0; y < height; y++ { for x := 0; x < width; x++ { byteIdx := y*rowBytes + x/8 bit := (bitmap[byteIdx] >> (7 - uint(x%8))) & 1 if bit == 1 { img.SetGray(x, y, color.Gray{Y: 0}) } else { img.SetGray(x, y, color.Gray{Y: 255}) } } } path := fmt.Sprintf("%s/hwlab-label-%d.png", m.SaveDir, time.Now().UnixMilli()) f, err := os.Create(path) if err != nil { return fmt.Errorf("printer: mock create file: %w", err) } defer f.Close() if err := png.Encode(f, img); err != nil { return fmt.Errorf("printer: mock encode PNG: %w", err) } fmt.Printf("[MockDriver] label saved → %s (%dx%d)\n", path, width, height) return nil }