# pdfme-svg

A pdfME plugin that renders SVG content inside PDF templates.

## Fork note

This codebase is mainly a fork of `github.com/yWorks/svg2pdf.js`. The only repository-specific modifications are the jsPDF shim (`src/jspdf-shim.ts`) and the pdfME plugin wrapper (`src/index.ts`). Other changes include improving svg2pdf's handling of SVGs, which may be contributed to upstream.

## Install

```bash
npm install @hadi77ir/pdfme-svg @pdfme/common @pdfme/pdf-lib
```

## Build

This package ships its compiled output in `dist/`.

```bash
npm run build
```

## Usage with pdfME

Register the plugin under the `svg` type and pass SVG strings as field values.

```ts
import { generate } from '@pdfme/generator';
import createSvgPlugin from '@hadi77ir/pdfme-svg';

const template = {
  basePdf: { width: 210, height: 297, padding: 0 },
  schemas: [
    {
      name: 'logo',
      type: 'svg',
      position: { x: 20, y: 20 },
      width: 60,
      height: 60,
      loadExternalStyleSheets: false,
    },
  ],
};

const inputs = [
  {
    logo: `<svg viewBox="0 0 120 120" xmlns="http://www.w3.org/2000/svg">
  <rect x="10" y="10" width="100" height="100" rx="12" fill="#111827"/>
  <circle cx="60" cy="60" r="30" fill="#60A5FA"/>
  <path d="M40 62 L55 77 L82 46" stroke="#F9FAFB" stroke-width="8" fill="none"/>
</svg>`,
  },
];

const pdf = await generate({
  template,
  inputs,
  plugins: { svg: createSvgPlugin() },
});
```

### Scaling

Optional schema fields let you control how SVG content fits inside the schema box:

- `scale`: Uniform scale factor (alias: `zoom`).
- `fit`: How to fit the SVG content inside the box. One of `none` (default), `contain`, `cover`, `stretch`.

When both are provided, `scale` is applied after the fit calculation.

Example:

```ts
{
  name: 'logo',
  type: 'svg',
  position: { x: 20, y: 20 },
  width: 60,
  height: 60,
  fit: 'contain',
  scale: 1.1,
}
```

For advanced measurement, `getSvgBoundingBox` is exported and can be used with a DOM and a jsPDF instance.

### Notes

- Positions and sizes are in millimeters, matching pdfME's layout system.
- When a DOM is available (browser or a DOM shim in Node), the plugin uses the internal svg2pdf pipeline for higher fidelity.
- When no DOM is available, it can fall back to `pdf-lib`'s `drawSvg` for compatibility (if `fallbackToPdfLib` is set to `true` in input schema) or throw an error.
- Fit modes rely on SVG bounding boxes and require a DOM-enabled environment.
- Set `loadExternalStyleSheets: true` to allow external CSS in SVGs (requires network access and a DOM-enabled environment).

## License
- Plugin Code and changes to Main Code: MIT License, Copyright (c) 2025 Mohammad Hadi Hosseinpour
- Main Code: From [svg2pdf.js](https://github.com/yWorks/svg2pdf.js), MIT License, Copyright (c) 2015-2025 yWorks GmbH
- `tsconfig.*.json`, import info parts of `package.json` and npm scripts: From [pdfME](https://github.com/pdfme/pdfme), MIT License, Copyright (c) 2020 HandDot

## LLM Usage

Most of the new modifications in this repository (the plugin code) has been written by LLMs (Gemini-3-Pro-Preview and GPT-5.2-Codex-ExtraHigh).
