Compare commits
4 Commits
7c5cec7d8a
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 7b13f45bd3 | |||
| 5535bfe290 | |||
| 6b22d8465e | |||
| a80e23614d |
22
README.md
22
README.md
@@ -9,20 +9,36 @@ You will need the following packages: `build-essential` `libsdl2-dev` `libsdl2-i
|
|||||||
Just run `make` and an executable called `trmnl_sdl` should be produced.
|
Just run `make` and an executable called `trmnl_sdl` should be produced.
|
||||||
|
|
||||||
# How to use
|
# How to use
|
||||||
1. You will need to write a JSON config file.
|
### General use
|
||||||
It can either be named `config.json` or you will need to pass it as the first command line parameter to the executable.
|
1. You will need to write a JSON config file named `config.json`.
|
||||||
An example structure of the config file can be found in `config_example.json`.
|
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.
|
You can find more info on the available Widgets and their parameters at the end of this file.
|
||||||
2. Run the executable
|
2. Run the executable
|
||||||
3. Convert the image to a suitable format via an ImageMagick command from below.
|
3. Convert the image to a suitable format via an ImageMagick command from below.
|
||||||
|
|
||||||
|
### Different ways to supply JSON
|
||||||
|
1. Default
|
||||||
|
* Command: `./trmnl_sdl`
|
||||||
|
* JSON Used: `config.json`
|
||||||
|
|
||||||
|
2. Specified file
|
||||||
|
* Command: `./trmnl_sdl path/to/json/file.json`
|
||||||
|
* JSON Used: `path/to/json/file.json`
|
||||||
|
|
||||||
|
3. Standard input
|
||||||
|
* Command: `./trmnl_sdl -`
|
||||||
|
* JSON Used: Supplied on the standard input for the process.
|
||||||
|
|
||||||
# ImageMagick commands to prepare image for TRMNL device
|
# ImageMagick commands to prepare image for TRMNL device
|
||||||
### Convert image without dithering
|
### Convert image without dithering
|
||||||
`convert trmnl.png -monochrome -colors 2 -depth 1 -strip png:output.png`
|
`convert trmnl.png -monochrome -colors 2 -depth 1 -strip png:output.png`
|
||||||
|
|
||||||
### Convert image with dithering
|
### Convert image with Floyd Steinberg dithering (For normal images)
|
||||||
`convert trmnl.png -dither FloydSteinberg -remap pattern:gray50 -depth 1 -strip png:output.png`
|
`convert trmnl.png -dither FloydSteinberg -remap pattern:gray50 -depth 1 -strip png:output.png`
|
||||||
|
|
||||||
|
### Convert image with Ordered dithering (For flat colors)
|
||||||
|
`convert trmnl.png -ordered-dither o2x2 -remap pattern:gray50 -depth 1 -strip png:output.png`
|
||||||
|
|
||||||
### Resize image to fit with dithering
|
### 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`
|
`convert image.png -resize 800x480 -background white -compose Copy -gravity center -extent 800x480 -dither FloydSteinberg -remap pattern:gray50 -depth 1 -strip png:output.png`
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ void WidgetRect::set_color(SDL_Color color)
|
|||||||
|
|
||||||
void WidgetRect::set_stroke_size(int stroke_size)
|
void WidgetRect::set_stroke_size(int stroke_size)
|
||||||
{
|
{
|
||||||
m_stroke_size = stroke_size
|
m_stroke_size = stroke_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WidgetRect::set_radius(int radius)
|
void WidgetRect::set_radius(int radius)
|
||||||
|
|||||||
@@ -172,6 +172,7 @@ void WidgetText::set_halign_via_visible(bool value)
|
|||||||
{
|
{
|
||||||
m_halign_via_visible = value;
|
m_halign_via_visible = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WidgetText::set_valign_via_visible(bool value)
|
void WidgetText::set_valign_via_visible(bool value)
|
||||||
{
|
{
|
||||||
m_valign_via_visible = value;
|
m_valign_via_visible = value;
|
||||||
@@ -179,6 +180,7 @@ void WidgetText::set_valign_via_visible(bool value)
|
|||||||
|
|
||||||
void WidgetText::draw()
|
void WidgetText::draw()
|
||||||
{
|
{
|
||||||
|
int current_text_size = m_size;
|
||||||
if (nullptr == m_surface)
|
if (nullptr == m_surface)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@@ -193,7 +195,7 @@ void WidgetText::draw()
|
|||||||
font_name = default_font_name;
|
font_name = default_font_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
TTF_Font* font = get_font(m_size, font_name);
|
TTF_Font* font = get_font(current_text_size, font_name);
|
||||||
if (nullptr == font)
|
if (nullptr == font)
|
||||||
{
|
{
|
||||||
// TODO: Message printing
|
// TODO: Message printing
|
||||||
@@ -209,40 +211,42 @@ void WidgetText::draw()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if text fits
|
// Enlarge text until it becomes too big
|
||||||
|
if (FIT_AUTO == m_fit)
|
||||||
|
{
|
||||||
|
while ((txt_surface->w < m_surface->w) && (txt_surface->h < m_surface->h))
|
||||||
|
{
|
||||||
|
// Increase size and try again
|
||||||
|
++current_text_size;
|
||||||
|
|
||||||
|
// Re-render text
|
||||||
|
SDL_FreeSurface(txt_surface);
|
||||||
|
font = get_font(current_text_size, font_name);
|
||||||
|
if (nullptr == font)
|
||||||
|
{
|
||||||
|
// TODO: Message printing
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
txt_surface = render_text(m_should_wrap, font, m_text, m_text_color, m_rect.w);
|
||||||
|
if (nullptr == txt_surface)
|
||||||
|
{
|
||||||
|
// TODO: Message printing
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Shrink if it doesn't fit
|
||||||
if (m_fit != FIT_NONE)
|
if (m_fit != FIT_NONE)
|
||||||
{
|
{
|
||||||
double x_scale;
|
while ((txt_surface->w > m_surface->w) || (txt_surface->h > m_surface->h))
|
||||||
double y_scale;
|
|
||||||
|
|
||||||
x_scale = m_surface->w;
|
|
||||||
x_scale /= txt_surface->w;
|
|
||||||
|
|
||||||
y_scale = m_surface->h;
|
|
||||||
y_scale /= txt_surface->h;
|
|
||||||
|
|
||||||
// Find the scale needed to shrink or enlarge with
|
|
||||||
double min_scale = x_scale;
|
|
||||||
if (y_scale < min_scale)
|
|
||||||
{
|
{
|
||||||
min_scale = y_scale;
|
// Decrease size and try again
|
||||||
}
|
--current_text_size;
|
||||||
|
|
||||||
// Do not scale up if only shrinkage is allowed
|
// Re-render text
|
||||||
if ((min_scale > 1.0) && (FIT_SHRINK == m_fit))
|
|
||||||
{
|
|
||||||
min_scale = 1.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find new font size
|
|
||||||
int new_text_size = m_size;
|
|
||||||
new_text_size *= min_scale;
|
|
||||||
|
|
||||||
// Re-render text
|
|
||||||
if (new_text_size != m_size)
|
|
||||||
{
|
|
||||||
SDL_FreeSurface(txt_surface);
|
SDL_FreeSurface(txt_surface);
|
||||||
font = get_font(new_text_size, font_name);
|
font = get_font(current_text_size, font_name);
|
||||||
if (nullptr == font)
|
if (nullptr == font)
|
||||||
{
|
{
|
||||||
// TODO: Message printing
|
// TODO: Message printing
|
||||||
|
|||||||
14
main.cpp
14
main.cpp
@@ -60,8 +60,18 @@ int main(int argc, char **argv)
|
|||||||
cfg_filename = argv[1];
|
cfg_filename = argv[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read JSON CFG
|
// Read config
|
||||||
ok = read_config_json(cfg, cfg_filename);
|
if ("-" == cfg_filename)
|
||||||
|
{
|
||||||
|
// Read JSON from std input
|
||||||
|
ok = read_config_json(cfg, std::cin);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Read JSON from config file
|
||||||
|
ok = read_config_json(cfg, cfg_filename);
|
||||||
|
}
|
||||||
|
|
||||||
if (!ok)
|
if (!ok)
|
||||||
{
|
{
|
||||||
result = -1;
|
result = -1;
|
||||||
|
|||||||
@@ -141,15 +141,20 @@ bool read_config_json(json& cfg, const string& filename, ostream* log)
|
|||||||
{
|
{
|
||||||
if (nullptr != log)
|
if (nullptr != log)
|
||||||
{
|
{
|
||||||
*log << "Could not open config.json" << endl;
|
*log << "Could not open config file" << endl;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return read_config_json(cfg, cfg_file, log);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool read_config_json(json& cfg, istream& in, ostream* log)
|
||||||
|
{
|
||||||
// Parse with comments
|
// Parse with comments
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
cfg = json::parse(cfg_file, nullptr, true, true);
|
cfg = json::parse(in, nullptr, true, true);
|
||||||
}
|
}
|
||||||
catch (const std::exception &e)
|
catch (const std::exception &e)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -90,6 +90,12 @@ SDL_Rect surface_align(const SDL_Surface* base, const SDL_Surface* applied,
|
|||||||
// log - output errors to this ostream, silent if NULL
|
// log - output errors to this ostream, silent if NULL
|
||||||
bool read_config_json(nlohmann::json& cfg, const std::string& filename, std::ostream* log = &std::cout);
|
bool read_config_json(nlohmann::json& cfg, const std::string& filename, std::ostream* log = &std::cout);
|
||||||
|
|
||||||
|
// Reads the stream and tries to parse JSON from it with comments
|
||||||
|
// cfg - output json struct
|
||||||
|
// in - input stream to read
|
||||||
|
// log - output errors to this ostream, silent if NULL
|
||||||
|
bool read_config_json(nlohmann::json& cfg, std::istream& in, std::ostream* log = &std::cout);
|
||||||
|
|
||||||
// JSON Extractors - They do not override already set values if key is not present
|
// JSON Extractors - They do not override already set values if key is not present
|
||||||
|
|
||||||
void json_extract(const nlohmann::json& j, const std::string& key, std::string& out);
|
void json_extract(const nlohmann::json& j, const std::string& key, std::string& out);
|
||||||
|
|||||||
Reference in New Issue
Block a user