# What is this A utility which can be used to create custom images for TRMNL devices via code # How to build **NOTE: Tested on Ubuntu 24.04.** You will need the following packages: `build-essential` `libsdl2-dev` `libsdl2-image-dev` `libsdl2-ttf-dev` `imagemagick` Just run `make` and an executable called `trmnl_sdl` should be produced. # How to use 1. You will need to write a JSON config file. It can either be named `config.json` or you will need to pass it as the first command line parameter to the executable. An example structure of the config file can be found in `config_example.json`. You can find more info on the available Widgets and their parameters at the end of this file. 2. Run the executable 3. Convert the image to a suitable format via an ImageMagick command from below. # ImageMagick commands to prepare image for TRMNL device ### Convert image without dithering `convert trmnl.png -monochrome -colors 2 -depth 1 -strip png:output.png` ### Convert image with dithering `convert trmnl.png -dither FloydSteinberg -remap pattern:gray50 -depth 1 -strip png:output.png` ### Resize image to fit with dithering `convert image.png -resize 800x480 -background white -compose Copy -gravity center -extent 800x480 -dither FloydSteinberg -remap pattern:gray50 -depth 1 -strip png:output.png` # How to write new visual stuff 1. Inherit from `Widget` and then do your magic inside your own class. 2. Add your widget builder in `main.cpp` inside `init_builders`. 3. Rebuild the executable. # Notes json.hpp from [nlohmann/json](https://github.com/nlohmann/json) v3.11.2 # List of special types ### color * **Object** type * Components - Red, Green, Blue, Alpha * Each component ranges 0-255 * When Alpha is 255 - the color is fully opaque. When it is 0 - fully transparent. * Has the structure shown below: ``` "color": { "r": 0, "g": 0, "b": 0, "a": 255 } ``` **NOTE**: If only some components are present in the config then only the present ones are overwritten from the default. ### HAlign Controls horizontal alignment of elements. **String** type. Has several options: * left - Align objects to the left * center - Align objects to be centered * right - Align objects to the right ### VAlign Controls vertical alignment of elements. **String** type. Has several options: * top - Align objects to the top * center - Align objects to be centered * bottom - Align objects to the bottom ### ImageResize Controls image resizing. **String** type. Has several options: * none - Image is not resized and is only clipped by the bounding box * fit - Image is uniformly scaled to fit inside the box * stretch - Image is scaled (with possible stretching) to fully fill the box ### TextFit Controls automatic change the text size depending on contents. **String** type. Has several options: * none - Text is not changed in any way * shrink - Renders text with desired size and shrinks it to fit if contents are too large * auto - Renders text with desired size and enlarges/shrinks it to fit if contents are too small/large # List of Widgets and their parameters ### image Renders an image with optional scaling | Name | Type | Required | Default | Description | | ---: | :--: | :------: | ------: | :---------- | | x | int | | 0 | Horizontal position in pixels (from left to right) | | y | int | | 0 | Vertical position in pixels (from top to bottom) | | width | int | REQ | | Width in pixels | | height | int | REQ | | Height in pixels | | filename | string | | | Filename of the image to render | | resize_type | ImageResize | | fit | Whether to resize the image and how to do so | | bg_color | color | | 255, 255, 255, 0 (Transparent WHITE) | The background color to fill around the image if it is not fully in the box | | halign | HAlign | | center | Horizontal alignment of the image | | valign | VAlign | | center | Vertical alignment of the image | ### rect Renders a rectangle with optional rounded corners using either fill or internal stroke. | Name | Type | Required | Default | Description | | ---: | :--: | :------: | ------: | :---------- | | x | int | | 0 | Horizontal position in pixels (from left to right) | | y | int | | 0 | Vertical position in pixels (from top to bottom) | | width | int | REQ | | Width in pixels | | height | int | REQ | | Height in pixels | | radius | int | | 0 | Corner rounding radius in pixels | | stroke | int | | -1 | Internal stroke size in pixels. If <= 0 then the rectangle will be filled with the desired color | | color | color | | 0, 0, 0, 255 (BLACK) | Color to use for rectangle | ### text Renders text within a specified box | Name | Type | Required | Default | Description | | ---: | :--: | :------: | ------: | :---------- | | x | int | | 0 | Horizontal position in pixels (from left to right) | | y | int | | 0 | Vertical position in pixels (from top to bottom) | | width | int | REQ | | Max width in pixels | | height | int | REQ | | Max height in pixels | | text | string | | | The text to be shown | | size | int | REQ | | Desired size of the text to use | | font | string | | Global font key | Font file to use when rendering the text | | color | color | | 0, 0, 0, 255 (BLACK) | Color to use for text rendering | | should_wrap | boolean | | false | Whether the text should automatically wrap | | fit | TextFit | | none | Controls automatic change the text size depending on contents | | halign | HAlign | | center | Horizontal alignment of text | | valign | VAlign | | center | Vertical alignment of text | | halign_via_visible | boolean | | true | Whether to use visible pixels of the text for horizontal alignment. If false - uses text renderer hints | | valign_via_visible | boolean | | true | Whether to use visible pixels of the text for vertical alignment. If false - uses text renderer hints |