# 🖨️ Capacitor USB Printer Plugin

A Capacitor plugin that allows Android apps to print receipts or images directly to a **USB thermal printer** using the **ESC/POS** command set.  
Supports both **PNG/JPEG** and **SVG (base64)** formats.

---

## 📦 Installation

```bash
npm i @atomsolution/usb-printer-capacitor
npx cap sync
```

---

## ⚙️ Android Setup

This plugin depends on the **DantSu ESC/POS Thermal Printer** library, distributed via **JitPack**.  
Add this line to your **root `android/build.gradle`** file:

```gradle
allprojects {
    repositories {
        ...
        maven { url 'https://jitpack.io' }
    }
}
```

> 💡 Usually located at `android/build.gradle` (not inside `app/`).

---

## 🚀 Usage

### 1. Import the Plugin

```typescript
import { UsbPrinter } from "@atomsolution/usb-printer-capacitor";
```

---

### 2. Connect to the USB Printer

```typescript
async function connectPrinter() {
  try {
    await UsbPrinter.connect();
    console.log('✅ Connected to USB printer');
  } catch (err) {
    console.error('❌ Failed to connect:', err);
  }
}
```

---

### 3. Print Text

```typescript
await UsbPrinter.printText({
  text: 'Hello from Capacitor USB Printer ✅\n\n',
});
```

---

### 4. Print Base64 Image (PNG / JPG / SVG)

You can print **base64-encoded** images (including SVG):

```typescript
await UsbPrinter.printBase64({
  data: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...',
});
```

or:

```typescript
await UsbPrinter.printBase64({
  data: 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDov...',
});
```

---

## 💡 Example React + Capacitor App

Here’s a simple example UI you can include in your React app (e.g. `src/App.tsx`) to test connection and printing:

```tsx
import React, { useState } from 'react';
import { UsbPrinter } from "@atomsolution/usb-printer-capacitor";

function App() {
  const [status, setStatus] = useState('Not connected');

  const connect = async () => {
    try {
      await UsbPrinter.connect();
      setStatus('✅ Connected');
    } catch (e) {
      setStatus('❌ Connection failed');
    }
  };

  const printText = async () => {
    try {
      await UsbPrinter.printText({ text: 'Hello World!\nFrom Capacitor 🖨️' });
      alert('Printed successfully!');
    } catch (e) {
      alert('Print failed: ' + e);
    }
  };

  const printImage = async () => {
    try {
      const base64 = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...'; // your image
      await UsbPrinter.printBase64({ data: base64 });
      alert('Image printed!');
    } catch (e) {
      alert('Print failed: ' + e);
    }
  };

  return (
    <div style={{ padding: 20, fontFamily: 'sans-serif' }}>
      <h2>🖨️ Capacitor USB Printer Demo</h2>
      <p>Status: {status}</p>
      <button onClick={connect}>Connect Printer</button>
      <button onClick={printText}>Print Text</button>
      <button onClick={printImage}>Print Image</button>
    </div>
  );
}

export default App;
```

> 💡 You can run this with `npm start` and test on your connected Android device via `npx cap open android`.

---

## 🧾 Supported Printers

Tested with:

- **XPrinter** XP-N160I / XP-58 / XP-80
- **Rongta** RP80
- **Zjiang** ZJ-5890 / ZJ-80
- Any printer supporting **ESC/POS USB**

---

## ⚙️ Printer Configuration

| Setting | Default | Description |
|----------|----------|-------------|
| DPI | `203` | Printer resolution |
| Paper Width | `72f` mm | Physical paper width |
| Printable Width | auto-calculated | Fitted to printer width |
| Output | Monochrome | Dithered bitmap for better contrast |

---

## 🧠 Notes

- Works on **Android 5.0 (Lollipop)** and above.  
- Requires **USB Host mode** on the device.  
- Automatically asks for **USB permission**.  
- Supports **PNG, JPEG, and SVG** base64 formats.  
- Automatically scales and pads width to prevent skew or cutoff.

---

## 🧰 Troubleshooting

| Issue | Possible Fix |
|--------|----------------|
| `Printer not connected` | Ensure printer is powered on and permission granted |
| `Failed to decode image data` | Verify correct base64 prefix |
| Image shifted or cropped | Adjust `paperWidthMM` in plugin |
| Faint output | Use higher contrast or adjust printer density |

---

## 🧑‍💻 Development

If you’re building the plugin locally:

```bash
# Inside plugin folder
npm run build

# Link with your Capacitor app
npx cap sync android
```

Then open the Android Studio project:

```bash
npx cap open android
```

---

## 📜 License

MIT License © 2025

---

## ❤️ Credits
- Built with [Capacitor Plugin API](https://capacitorjs.com/docs/plugins)
- Maintained with ❤️ by LUBAN team
