You are using staging server - a separate instance of the ESP Component Registry that allows you to try distribution tools and processes without affecting the real registry.

ddb0515/fastjsondl

1.1.0

Latest
uploaded 1 day ago
JSON Domain Language renderer for E-Ink displays. Parses a JSON layout description and issues drawing commands to a FASTEPD display instance. Designed as an ESP-IDF component for the ESP32 family. Supports optional raw-DEFLATE payload decompression via the lbernstone__miniz component (type 0x0002 in the transfer header protocol).

readme

![FastJsonDL](./examples/fastjsondl.svg)

A JSON Domain Language to draw on E-Ink displays by receiving a JSON payload
from any endpoint.  Built on top of
[FastEPD](https://github.com/bitbank2/FastEPD) and packaged as an
**ESP-IDF component** targeting the ESP32 family (primary targets: ESP32-C5, S3, P4).

If you would like a good start to make a web-interface for a basic Canvas draw tool, you can check out:
[FastJsonRenderer](https://github.com/martinberlin/FastJsonRenderer) Using Symfony as a PHP backend and Rest to make the dynamic canvas drawing tool. Is very basic but it can be a great starting point to understand the JSON format and draw some shapes. Soon it will have a Bluetooth send to device feature!
To try it online please go to [draw.fasani.de](https://draw.fasani.de) and be aware that to save or to use the import PNG/SVG feature into G5 image you need to login with your Github account.

---

## Features

- Parses a JSON layout description and issues the corresponding drawing
  commands to a `FASTEPD` display instance.
- Configurable bits-per-pixel mode (`display_bpp` in JSON, or via
  `setDefaultBpp()`).
- Named-font registry — map any string to a FastEPD font data blob.
- In-order item rendering: items in the `"items"` array are drawn
  sequentially, so layering (e.g. black bar behind white text) works
  exactly as written.
- Human-readable error reporting via `getLastError()`.
- **DEFLATE decompression** — `renderDeflatedJson()` accepts a raw
  DEFLATE-compressed payload (RFC 1951, no zlib/gzip wrapper) and
  decompresses it on-device before rendering.  Requires the
  `miniz` ESP-IDF component.

To run the demos easily please clone this repository using:

    git clone --recursive https://github.com/martinberlin/FastJsonDL.git

---

## DEMO

This json code:

```json
{
  "display_bpp": 4,
  "clear": true,
  "items": [
    { "type": "fillRect", "x": 0, "y": 0, "w": 540, "h": 120, "c": 14 },
    { "type": "fillRect", "x": 20, "y": 150, "w": 670, "h": 220, "c": 12 },
    { "type": "drawRect", "x": 20, "y": 150, "w": 670, "h": 220, "c": 4 },
    { "type": "drawLine", "x1": 20, "y1": 150, "x2": 520, "y2": 370, "c": 6 },
    { "type": "drawLine", "x1": 520, "y1": 150, "x2": 20, "y2": 370, "c": 6 },
    { "type": "fillCircle", "x": 90, "y": 520, "r": 60, "c": 10 },
    { "type": "drawCircle", "x": 90, "y": 520, "r": 60, "c": 2 },
    { "type": "fillCircle", "x": 270, "y": 520, "r": 60, "c": 7 },
    { "type": "drawCircle", "x": 270, "y": 520, "r": 60, "c": 2 },
    { "type": "fillCircle", "x": 450, "y": 520, "r": 60, "c": 3 },
    { "type": "drawCircle", "x": 450, "y": 520, "r": 60, "c": 2 },
    {
      "type": "drawString",
      "font": "Ubuntu40",
      "string": "FastJsonDL",
      "x": 30,
      "y": 70,
      "c": 0
    },
    {
      "type": "drawString",
      "font": "Ubuntu30",
      "string": "Grayscale: c0 c7 c14",
      "x": 30,
      "y": 240,
      "c": 7
    },
    {
      "type": "drawString",
      "font": "Ubuntu40",
      "string": "Now with working",
      "x": 30,
      "y": 330,
      "c": 14
    },
    {
      "type": "drawString",
      "font": "Ubuntu40",
      "string": "shades",
      "x": 690,
      "y": 330,
      "c": 9
    },
    {
      "type": "drawString",
      "font": "Ubuntu30",
      "string": "0",
      "x": 80,
      "y": 530,
      "c": 15
    }
  ]
}
```

Will generate the following drawing:
![FastJsonDL demo1](./examples/demo1.png)

## Top-level fields

| Field         | Type    | Default | Description |
|---------------|---------|---------|-------------|
| `display_bpp` | integer | current EPD mode (usually `1`) | Bits per pixel: `1`, `2`, or `4`. If omitted, FastJsonDL keeps the mode active on the `FASTEPD` instance when it was constructed. |
| `rotation`    | integer | — | Display rotation in degrees (`0`, `90`, `180`, `270`). When present, `setRotation()` is called and the logical display dimensions are refreshed so that portrait-mode items near the right/bottom edge render correctly. |
| `clear`       | bool    | `false` | When `true`, fills the framebuffer with white before rendering any items. Use this to avoid uninitialised pixel data appearing as vertical stripes on the display. |

## Supported item types

| `"type"`       | Required fields          | Optional |
|----------------|--------------------------|----------|
| `drawString`   | `string`, `x`, `y`       | `font`, `c` |
| `fillRect`     | `x`, `y`, `w`, `h`       | `c`      |
| `drawRect`     | `x`, `y`, `w`, `h`       | `c`      |
| `drawLine`     | `x1`, `y1`, `x2`, `y2`   | `c`      |
| `fillCircle`   | `x`, `y`, `r`            | `c`      |
| `drawCircle`   | `x`, `y`, `r`            | `c`      |
| `p`            | `x`, `y`                 | `c`      |
| `loadG5Image`  | `data`, `x`, `y`, `w`, `h` | `fg`, `bg` |

`c` is the colour value and depends on `display_bpp`:
- 1BPP: `0..1`   (`0` = black, `1` = white)
- 2BPP: `0..3`   (`0` = black, `3` = white)
- 4BPP: `0..15`  (`0` = black, `15` = white)

When omitted, `c` defaults to black (`0`).

For `loadG5Image`, `data` must be a byte array and supports:
- decimal byte values (`191, 187, 90, ...`)
- hex strings with or without the `0x` prefix (`"bf"`, `"0xbf"`, `"13"`, `"0x13"`)

> **`drawString` — y is the text baseline**
> FastEPD BB-format fonts (produced by `fontconvert`) treat `y` as the **text
> baseline**, not the top-left corner of the glyph.  For a 40 pt font the
> ascender height is approximately 50 px, so the top of the rendered characters
> sits at `y − 50`.  Setting `"y": 10` with such a font places the glyphs
> almost entirely above the top edge of the screen (invisible, no error).
> Always set `y` ≥ the font's ascender height — for Ubuntu40 use `"y": 50` or
> greater.

---

## Minimal Hello World JSON

```json
{
  "display_bpp": 4,
  "clear": true,
  "items": [
    {
      "type": "drawString",
      "font": "Ubuntu40",
      "string": "Hello from FastJsonDL!",
      "x": 10, "y": 70,
      "c": 0
    }
  ]
}
```

---

## C++ API

```cpp
// 1. Initialise the EPD panel (FastEPD)
FASTEPD epd;
epd.initPanel(BB_PANEL_M5PAPERS3);

// 2. Create the renderer
FastJsonDL dl(epd);

// 3. (Optional) Register named fonts
static const FastJsonDLFont fonts[] = {
    { "Ubuntu40", Ubuntu40 },
};
dl.setFontRegistry(fonts, 1);

// 4. (Optional) Override display dimensions or BPP default
dl.setDisplaySize(540, 960);
dl.setDefaultBpp(1);

// 5a. Render a plain JSON layout
if (!dl.renderJsonString(myJson)) {
    printf("Error: %s\n", dl.getLastError());
}

// 5b. Render a raw DEFLATE-compressed JSON layout (type 0x0002)
//     Requires lbernstone__miniz component.
if (!dl.renderDeflatedJson(compressedBuf, compressedLen)) {
    printf("Error: %s\n", dl.getLastError());
}

// 6. Push to the physical display
epd.fullUpdate();
```

---

## Adding to your ESP-IDF project

### As a managed component (recommended)

Add to your project's `idf_component.yml`:

```yaml
dependencies:
  martinberlin__FastJsonDL:
    git: "https://github.com/martinberlin/FastJsonDL.git"
```

`FastEPD` is intentionally not declared as a managed dependency by this
component. Add your own FastEPD source (for example a submodule or a custom
branch checkout) in your project and wire it as a normal ESP-IDF component
named `FastEPD`.

### As a local component

Clone into your project's `components/` directory:

```sh
cd components
git clone https://github.com/martinberlin/FastJsonDL.git FastJsonDL
```

Then add your own FastEPD component (for example as a submodule pointing to
your preferred branch) under `components/FastEPD`.

Then add `FastJsonDL` to the `REQUIRES` list in your app component's
`CMakeLists.txt`.

---

## Dependencies

| Dependency | Source |
|------------|--------|
| FastEPD | User-provided ESP-IDF component (e.g. local submodule/custom branch) |
| cJSON | Ships with ESP-IDF (`json` component) |
| lbernstone__miniz | ESP-IDF component manager (`lbernstone/miniz`); required for `renderDeflatedJson()` |

### DEFLATE support

`renderDeflatedJson()` requires the
[lbernstone/miniz](https://github.com/lbernstone/miniz-esp32) ESP-IDF component.
Add it to your project's `idf_component.yml`:

```yaml
dependencies:
  lbernstone__miniz:
    version: ">=0.0.1"
```

If the component is absent the library still compiles and all other methods
work normally; `renderDeflatedJson()` will return `false` and set an error
message explaining the missing dependency.

---

## Examples

| Example | Description |
|---------|-------------|
| [`examples/basic`](examples/basic) | Renders a static JSON layout at boot — good starting point. |
| [`examples/ble_receive`](examples/ble_receive) | BLE GATT server that receives a JSON payload over Bluetooth and renders it on the display. Supports both plain JSON (type `0x0001`) and raw DEFLATE-compressed JSON (type `0x0002`). Compatible with the [FastJsonRenderer](https://github.com/martinberlin/FastJsonRenderer) client. |

### BLE transfer protocol (header format)

The 8-byte binary header prepended by the client:

| Bytes | Field  | Value |
|-------|--------|-------|
| 0–1   | type   | `0x0001` — plain JSON  \|  `0x0002` — raw DEFLATE compressed JSON |
| 2–7   | length | payload byte count (little-endian uint48; bytes 6–7 are always `0x00`) |

Type `0x0002` payloads are raw DEFLATE streams as produced by
`pako.deflateRaw()` in JavaScript or `zlib.compress(data)[2:-4]` in Python.
The firmware decompresses the payload on-device using `tinfl_decompress_mem_to_heap`
from the miniz library before parsing the JSON.

---

## License

See [LICENSE](LICENSE).

Links

Supports all targets

License: MIT

To add this component to your project, run:

idf.py add-dependency "ddb0515/fastjsondl^1.1.0"

download archive

Stats

  • Archive size
    Archive size ~ 555.62 KB
  • Downloaded in total
    Downloaded in total 2 times
  • Weekly Downloads Weekly Downloads (All Versions)
  • Downloaded this version
    This version: 1 time

Badge

ddb0515/fastjsondl version: 1.1.0
|