openpencil/docs/reference/file-format.md

60 lines
2.2 KiB
Markdown

# File Format
## .fig File Structure
```
┌─────────────────────────────────┐
│ Magic header: "fig-kiwi" (8B) │
│ Version (4B uint32 LE) │
│ Schema length (4B uint32 LE) │
│ Compressed Kiwi schema │
│ Message length (4B uint32 LE) │
│ Compressed Kiwi message │ ← NodeChange[] (entire document)
│ Blob data │ ← Images, vector networks, fonts
└─────────────────────────────────┘
```
## Import Pipeline
```
.fig file → Parse header → Decompress Zstd → Decode Kiwi schema
→ Decode Message → NodeChange[] → Build SceneGraph
→ Resolve blob refs → Render on canvas
```
## Kiwi Binary Codec
The codec handles Figma's 194-definition Kiwi schema with NodeChange as the central type (~390 fields). Key components:
- **kiwi-schema** — vendored from evanw/kiwi, patched for ESM and sparse field IDs
- **codec.ts** — encode/decode Messages using the Kiwi schema
- **protocol.ts** — wire format parsing and message type detection
- **schema.ts** — 194 message/enum/struct definitions
### Sparse Field IDs
Figma's schema uses non-contiguous field IDs (e.g., 1, 2, 5, 10 with gaps). The vendored kiwi-schema parser is patched to handle this correctly.
### Compression
.fig files use Zstd compression for both the schema and message payloads. The `fzstd` library handles decompression. For clipboard encoding, `fflate` provides lightweight compression.
## Supported Formats
| Format | Import | Export |
|--------|--------|--------|
| .fig (Figma) | ✅ | — |
| .svg | Planned | Planned |
| .png | Planned | Planned |
| .pdf | — | Planned |
## Clipboard Format
Copy/paste uses the same fig-kiwi binary encoding:
1. **Copy** — encode selected NodeChange[] to Kiwi binary, compress, write to clipboard as `application/x-figma-design` MIME type
2. **Paste** — read clipboard, decompress, decode Kiwi binary, create nodes in scene graph
3. **Synchronous** — encoding happens in the copy event handler (not async Clipboard API) to ensure browser compatibility
This enables bidirectional clipboard between OpenPencil and Figma.