color table and various fixes

- use the actual color table in tagtype json for rendering images (until now, that color table was ignored)
- added proper ordered dithering (works with all colors now, not just gray and pink)
- on the static image content card, you can now choose floyd-steinberg or ordered dithering (or turn dithering off)
- added ÅÄÖ to twcondensed20 font
- small bugfixes
- fix serial passthrough via UART in OEPL-flasher.py
This commit is contained in:
Nic Limper
2024-03-26 01:13:02 +01:00
parent cb2f3aed5a
commit 6197b8962e
54 changed files with 207 additions and 301 deletions

Binary file not shown.

View File

@@ -3,6 +3,8 @@
#pragma once
#include "tag_db.h"
extern TFT_eSPI tft;
#define SHORTLUT_DISABLED 0
@@ -10,10 +12,12 @@ extern TFT_eSPI tft;
#define SHORTLUT_ALLOWED 2
struct imgParam {
HwType hwdata;
bool hasRed;
uint8_t dataType;
uint8_t dither;
bool grayLut = false;
// bool grayLut = false;
uint8_t bufferbpp = 8;
uint8_t rotate = 0;
uint16_t highlightColor = 2;

View File

@@ -76,7 +76,15 @@ struct Config {
String env;
};
struct Color {
uint8_t r, g, b;
Color() : r(0), g(0), b(0) {}
Color(uint16_t value_) : r((value_ >> 8) & 0xF8 | (value_ >> 13) & 0x07), g((value_ >> 3) & 0xFC | (value_ >> 9) & 0x03), b((value_ << 3) & 0xF8 | (value_ >> 2) & 0x07) {}
Color(uint8_t r_, uint8_t g_, uint8_t b_) : r(r_), g(g_), b(b_) {}
};
struct HwType {
uint8_t id;
uint16_t width;
uint16_t height;
uint8_t rotatebuffer;
@@ -84,6 +92,7 @@ struct HwType {
uint8_t shortlut;
uint8_t zlib;
uint16_t highlightColor;
std::vector<Color> colortable;
};
struct varStruct {
@@ -109,6 +118,7 @@ extern void clearPending(tagRecord* taginfo);
extern void initAPconfig();
extern void saveAPconfig();
extern HwType getHwType(const uint8_t id);
/// @brief Update a variable with the given key and value
///
/// @param key Variable key
@@ -117,6 +127,7 @@ extern HwType getHwType(const uint8_t id);
/// @return true If variable was created/updated
/// @return false If not
extern bool setVarDB(const std::string& key, const String& value, const bool notify = true);
extern void cleanupCurrent();
extern void pushTagInfo(tagRecord* taginfo);
extern void popTagInfo(const uint8_t mac[8] = nullptr);

View File

@@ -201,16 +201,18 @@ void drawNew(const uint8_t mac[8], tagRecord *&taginfo) {
taginfo->nextupdate = now + 60;
imgParam imageParams;
imageParams.hwdata = hwdata;
imageParams.width = hwdata.width;
imageParams.height = hwdata.height;
imageParams.bpp = hwdata.bpp;
imageParams.rotatebuffer = hwdata.rotatebuffer;
imageParams.shortlut = hwdata.shortlut;
imageParams.highlightColor = getColor(String(hwdata.highlightColor));
imageParams.hasRed = false;
imageParams.dataType = DATATYPE_IMG_RAW_1BPP;
imageParams.dither = 2;
if (taginfo->hasCustomLUT && taginfo->lut != 1) imageParams.grayLut = true;
// if (taginfo->hasCustomLUT && taginfo->lut != 1) imageParams.grayLut = true;
imageParams.invert = taginfo->invert;
imageParams.symbols = 0;
@@ -220,7 +222,6 @@ void drawNew(const uint8_t mac[8], tagRecord *&taginfo) {
} else {
imageParams.zlib = 0;
}
imageParams.shortlut = hwdata.shortlut;
imageParams.lut = EPD_LUT_NO_REPEATS;
if (taginfo->lut == 2) imageParams.lut = EPD_LUT_FAST_NO_REDS;
@@ -655,7 +656,11 @@ void drawString(TFT_eSprite &spr, String content, int16_t posx, int16_t posy, St
posx -= truetype.getStringWidth(content);
}
truetype.setTextBoundary(posx, spr.width(), spr.height());
truetype.setTextColor(spr.color16to8(color), spr.color16to8(color));
if (spr.getColorDepth() == 8) {
truetype.setTextColor(spr.color16to8(color), spr.color16to8(color));
} else {
truetype.setTextColor(color, color);
}
truetype.textDraw(posx, posy, content);
truetype.end();
} break;
@@ -716,9 +721,14 @@ void drawTextBox(TFT_eSprite &spr, String &content, int16_t &posx, int16_t &posy
}
void initSprite(TFT_eSprite &spr, int w, int h, imgParam &imageParams) {
spr.setColorDepth(8);
spr.setColorDepth(16);
spr.createSprite(w, h);
spr.setRotation(3);
if (spr.getPointer() == nullptr) {
wsErr("low on memory. Fallback to 8bpp");
util::printLargestFreeBlock();
spr.setColorDepth(8);
spr.createSprite(w, h);
}
if (spr.getPointer() == nullptr) {
wsErr("low on memory. Fallback to 1bpp");
util::printLargestFreeBlock();
@@ -730,6 +740,7 @@ void initSprite(TFT_eSprite &spr, int w, int h, imgParam &imageParams) {
if (spr.getPointer() == nullptr) {
wsErr("Failed to create sprite");
}
spr.setRotation(3);
spr.fillSprite(TFT_WHITE);
}
@@ -1266,9 +1277,9 @@ bool getCalFeed(String &filename, JsonObject &cfgobj, tagRecord *&taginfo, imgPa
drawString(spr, String(languageDaysShort[dayInfo->tm_wday]) + " " + String(dayInfo->tm_mday), colStart + colWidth / 2, calTop, loc["gridparam"][3], TC_DATUM, TFT_BLACK);
if (dayInfo->tm_wday == 0 || dayInfo->tm_wday == 6) {
spr.fillRect(colStart + 1, calTop + calYOffset, colWidth - 1, calHeight - 1, TFT_DARKGREY);
spr.fillRect(colStart + 1, calTop + calYOffset, colWidth - 1, calHeight - 1, getColor("darkgray"));
} else {
spr.fillRect(colStart + 1, calTop + calYOffset, colWidth - 1, calHeight - 1, TFT_LIGHTGREY);
spr.fillRect(colStart + 1, calTop + calYOffset, colWidth - 1, calHeight - 1, getColor("lightgray"));
}
}
@@ -2153,9 +2164,9 @@ uint16_t getColor(const String &color) {
if (color == "1" || color == "" || color == "black") return TFT_BLACK;
if (color == "2" || color == "red") return TFT_RED;
if (color == "3" || color == "yellow") return TFT_YELLOW;
if (color == "4" || color == "lightgray") return TFT_LIGHTGREY;
if (color == "4" || color == "lightgray") return 0xBDF7;
if (color == "5" || color == "darkgray") return TFT_DARKGREY;
if (color == "6" || color == "pink") return TFT_PINK;
if (color == "6" || color == "pink") return 0xFBCF;
uint16_t r, g, b;
if (color.length() == 7 && color[0] == '#' &&
sscanf(color.c_str(), "#%2hx%2hx%2hx", &r, &g, &b) == 3) {

View File

@@ -8,6 +8,7 @@
#include "leds.h"
#include "miniz-oepl.h"
#include "storage.h"
#include "tag_db.h"
#include "util.h"
#ifdef HAS_TFT
@@ -62,13 +63,6 @@ void jpg2buffer(String filein, String fileout, imgParam &imageParams) {
}
}
struct Color {
uint8_t r, g, b;
Color() : r(0), g(0), b(0) {}
Color(uint16_t value_) : r((value_ >> 8) & 0xF8 | (value_ >> 13) & 0x07), g((value_ >> 3) & 0xFC | (value_ >> 9) & 0x03), b((value_ << 3) & 0xF8 | (value_ >> 2) & 0x07) {}
Color(uint8_t r_, uint8_t g_, uint8_t b_) : r(r_), g(g_), b(b_) {}
};
struct Error {
int32_t r;
int32_t g;
@@ -102,32 +96,22 @@ void spr2color(TFT_eSprite &spr, imgParam &imageParams, uint8_t *buffer, size_t
memset(buffer, 0, buffer_size);
std::vector<Color> palette = {
{255, 255, 255}, // White
{0, 0, 0}, // Black
{255, 0, 0} // Red
};
std::vector<Color> palette = imageParams.hwdata.colortable;
if (imageParams.invert == 1) {
std::swap(palette[0], palette[1]);
}
Color color;
if (imageParams.dither == 2) {
color = {128, 128, 128};
palette.push_back(color);
color = {211, 211, 211};
palette.push_back(color);
color = {255, 192, 203};
palette.push_back(color);
} else if (imageParams.grayLut) {
color = {160, 160, 160};
palette.push_back(color);
Serial.println("rendering with gray");
}
int num_colors = palette.size();
if (imageParams.bufferbpp == 1) num_colors = 2;
Error *error_bufferold = new Error[bufw + 4];
Error *error_buffernew = new Error[bufw + 4];
const uint8_t ditherMatrix[4][4] = {
{0, 9, 2, 10},
{12, 5, 14, 6},
{3, 11, 1, 8},
{15, 7, 13, 4}};
memset(error_bufferold, 0, bufw * sizeof(Error));
for (uint16_t y = 0; y < bufh; y++) {
memset(error_buffernew, 0, bufw * sizeof(Error));
@@ -147,8 +131,17 @@ void spr2color(TFT_eSprite &spr, imgParam &imageParams, uint8_t *buffer, size_t
break;
}
if (imageParams.dither == 2) {
// Ordered dithering
uint8_t ditherValue = ditherMatrix[y % 4][x % 4];
error_bufferold[x].r = (ditherValue << 4) - 120; // * 256 / 16 - 128 + 8
error_bufferold[x].g = (ditherValue << 4) - 120;
error_bufferold[x].b = (ditherValue << 4) - 120;
}
int best_color_index = 0;
uint32_t best_color_distance = colorDistance(color, palette[0], error_bufferold[x]);
for (int i = 1; i < num_colors; i++) {
if (best_color_distance == 0) break;
uint32_t distance = colorDistance(color, palette[i], error_bufferold[x]);
@@ -157,7 +150,6 @@ void spr2color(TFT_eSprite &spr, imgParam &imageParams, uint8_t *buffer, size_t
best_color_index = i;
}
}
uint8_t bitIndex = 7 - (x % 8);
uint32_t byteIndex = (y * bufw + x) / 8;
@@ -173,29 +165,19 @@ void spr2color(TFT_eSprite &spr, imgParam &imageParams, uint8_t *buffer, size_t
buffer[byteIndex] |= (1 << bitIndex);
break;
case 3:
if (imageParams.grayLut) {
buffer[byteIndex] |= (1 << bitIndex);
imageParams.hasRed = true;
} else {
if (!is_red && (x + y) % 2) buffer[byteIndex] |= (1 << bitIndex);
}
break;
case 4:
if (!is_red && ((x + y / 2) % 2 == 0) && (y % 2 == 0)) buffer[byteIndex] |= (1 << bitIndex);
break;
case 5:
if (is_red && (x + y) % 2) buffer[byteIndex] |= (1 << bitIndex);
imageParams.hasRed = true;
buffer[byteIndex] |= (1 << bitIndex);
break;
}
if (imageParams.dither == 1) {
// Burkes Dithering
Error error = {
color.r + error_bufferold[x].r - palette[best_color_index].r,
color.g + error_bufferold[x].g - palette[best_color_index].g,
color.b + error_bufferold[x].b - palette[best_color_index].b};
// Burkes Dithering
error_buffernew[x].r += error.r >> 2;
error_buffernew[x].g += error.g >> 2;
error_buffernew[x].b += error.b >> 2;

View File

@@ -526,12 +526,12 @@ void processDataReq(struct espAvailDataReq* eadr, bool local, IPAddress remoteIP
if (taginfo == nullptr) {
if (config.lock == 1 || (config.lock == 2 && eadr->adr.wakeupReason != WAKEUP_REASON_FIRSTBOOT)) return;
#ifdef HAS_SUBGHZ
if(apInfo.hasSubGhz && eadr->adr.currentChannel > 0 && eadr->adr.currentChannel == apInfo.SubGhzChannel) {
// Empty intentionally
if (apInfo.hasSubGhz && eadr->adr.currentChannel > 0 && eadr->adr.currentChannel == apInfo.SubGhzChannel) {
// Empty intentionally
} else
#endif
if (eadr->adr.currentChannel > 0 && eadr->adr.currentChannel != apInfo.channel) {
Serial.printf("Tag %s reports illegal channel %d\n", hexmac, eadr->adr.currentChannel);
if (local == true && eadr->adr.currentChannel > 0 && eadr->adr.currentChannel != apInfo.channel) {
Serial.printf("Tag %s reports illegal channel %d\n", hexmac, eadr->adr.currentChannel);
return;
}
taginfo = new tagRecord;
@@ -662,23 +662,23 @@ void setAPchannel() {
udpsync.getAPList();
} else {
if (curChannel.channel != config.channel) {
curChannel.channel = config.channel;
bSendRadioLayer = true;
curChannel.channel = config.channel;
bSendRadioLayer = true;
}
}
#ifdef HAS_SUBGHZ
if(curChannel.subghzchannel != config.subghzchannel) {
curChannel.subghzchannel = config.subghzchannel;
apInfo.SubGhzChannel = config.subghzchannel;
bSendRadioLayer = true;
if (curChannel.subghzchannel != config.subghzchannel) {
curChannel.subghzchannel = config.subghzchannel;
apInfo.SubGhzChannel = config.subghzchannel;
bSendRadioLayer = true;
}
#endif
if(bSendRadioLayer) {
tmp = curChannel;
if(config.channel == 0) {
tmp.channel = 0; // don't set the 802.15.4 channel
if (bSendRadioLayer) {
tmp = curChannel;
if (config.channel == 0) {
tmp.channel = 0; // don't set the 802.15.4 channel
}
sendChannelPower(&tmp);
sendChannelPower(&tmp);
}
}

View File

@@ -388,6 +388,7 @@ HwType getHwType(const uint8_t id) {
filter["shortlut"] = true;
filter["zlib_compression"] = true;
filter["highlight_color"] = true;
filter["colortable"] = true;
StaticJsonDocument<1000> doc;
DeserializationError error = deserializeJson(doc, jsonFile, DeserializationOption::Filter(filter));
jsonFile.close();
@@ -395,17 +396,28 @@ HwType getHwType(const uint8_t id) {
Serial.println("json error in " + String(filename));
Serial.println(error.c_str());
} else {
hwdata[id].width = doc["width"];
hwdata[id].height = doc["height"];
hwdata[id].rotatebuffer = doc["rotatebuffer"];
hwdata[id].bpp = doc["bpp"];
hwdata[id].shortlut = doc["shortlut"];
HwType& hwType = hwdata[id];
hwType.id = id;
hwType.width = doc["width"];
hwType.height = doc["height"];
hwType.rotatebuffer = doc["rotatebuffer"];
hwType.bpp = doc["bpp"];
hwType.shortlut = doc["shortlut"];
if (doc.containsKey("zlib_compression")) {
hwdata[id].zlib = strtol(doc["zlib_compression"], nullptr, 16);
hwType.zlib = strtol(doc["zlib_compression"], nullptr, 16);
} else {
hwdata[id].zlib = 0;
hwType.zlib = 0;
}
hwType.highlightColor = doc.containsKey("highlight_color") ? doc["highlight_color"].as<uint16_t>() : 2;
JsonObject colorTable = doc["colortable"];
for (auto kv : colorTable) {
JsonArray color = kv.value();
Color c;
c.r = color[0];
c.g = color[1];
c.b = color[2];
hwType.colortable.push_back(c);
}
hwdata[id].highlightColor = doc.containsKey("highlight_color") ? doc["highlight_color"].as<uint16_t>() : 2;
return hwdata.at(id);
}
}

View File

@@ -1023,7 +1023,8 @@ void truetypeClass::addPixel(int16_t _x, int16_t _y, uint16_t _colorCode) {
switch (framebufferBit) {
case 16: // 16bit horizontal
{
uint16_t *p = (uint16_t *)&userFrameBuffer[(uint16_t)_x + (uint16_t)_y * displayWidthFrame];
uint16_t *p = (uint16_t *)&userFrameBuffer[(uint16_t)_x * 2 + (uint16_t)_y * displayWidthFrame];
_colorCode = (_colorCode >> 8) | (_colorCode << 8);
*p = _colorCode;
} break;
case 8: // 8bit Horizontal

View File

@@ -290,6 +290,11 @@ void init_web() {
uint8_t md5[8];
if (hex2mac(request->getParam("md5")->value(), md5)) {
PendingItem *queueItem = getQueueItem(mac, *reinterpret_cast<uint64_t *>(md5));
if (queueItem == nullptr) {
Serial.println("getQueueItem: no queue item");
request->send(404, "text/plain", "File not found");
return;
}
if (queueItem->data == nullptr) {
fs::File file = contentFS->open(queueItem->filename);
if (file) {

View File

@@ -23,7 +23,8 @@
"type": "select",
"options": {
"0": "off",
"1": "on"
"1": "floyd-steinberg dithering",
"2": "ordered dithering"
}
}
]
@@ -479,7 +480,8 @@
"type": "select",
"options": {
"0": "off",
"1": "on"
"1": "floyd-steinberg dithering",
"2": "ordered dithering"
}
},
{

View File

@@ -238,7 +238,7 @@
It sets the mac automatically, tries to recognize the type, and starts flashing. Currently, Solum M2 tags only.
<br><br>
<button class="button" id="doUSBflash">Command line</button><br><br>
Using <a href="https://github.com/jjwbruijn/OpenEPaperLink/raw/master/Tag_Flasher/OEPL-Flasher.py" target="_blank">OEPL-Flasher.py</a>, you have full control over the flashing of the tag.<br>
Using <a href="https://github.com/jjwbruijn/OpenEPaperLink/tree/master/Tag_Flasher#oepl-flasherpy" target="_blank">OEPL-Flasher.py</a>, you have full control over the flashing of the tag.<br>
Use the --ip argument to connect to the flasher.<br>
<br>
Usage:<br>

View File

@@ -1012,7 +1012,7 @@ function populateSelectTag(hwtype, capabilities) {
let option;
cardconfig.forEach(item => {
const capcheck = item.capabilities ?? 0;
if (tagTypes[hwtype].contentids.includes(item.id) && (capabilities & capcheck || capcheck == 0) && (apConfig.savespace == 0 || !item.properties?.includes("savespace"))) {
if (tagTypes[hwtype].contentids?.includes(item.id) && (capabilities & capcheck || capcheck == 0) && (apConfig.savespace == 0 || !item.properties?.includes("savespace"))) {
option = document.createElement("option");
option.value = item.id;
option.text = item.name;
@@ -1327,6 +1327,10 @@ const downloadTagtype = async (hwtype) => {
console.log(url);
const response = await fetch(url);
if (!response.ok) {
console.log("github download error " + response.status);
return response;
}
const clonedResponse = response.clone();
const fileContent = await clonedResponse.blob();
@@ -1398,7 +1402,7 @@ async function getTagtype(hwtype) {
}
if (!response.ok) {
let data = { name: 'unknown id ' + hwtype.toString(16), width: 0, height: 0, bpp: 0, rotatebuffer: 0, colortable: [], busy: false };
let data = { name: 'unknown id ' + hwtype.toString(16).toUpperCase(), width: 0, height: 0, bpp: 0, rotatebuffer: 0, colortable: [], busy: false };
tagTypes[hwtype] = data;
getTagtypeBusy = false;
return data;

View File

@@ -418,17 +418,19 @@ def main():
if transport == TRANSPORT_TCP:
try:
data = tcp_socket.recv(1)
data_str = data.decode('utf-8')
except socket.timeout:
data = ""
data_str = ""
pass
else:
try:
data = ser.read(1)
data_str = data.decode('utf-8')
except UnicodeDecodeError:
data = ""
data_str = ""
pass
print(data, end='')
if chr(0x04) in data:
print(data_str, end='')
if chr(0x04) in data_str:
break
except KeyboardInterrupt:

View File

@@ -56,7 +56,7 @@ void setup() {
String str = "!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_abcdefghijklmnopqrstuvwxyz{|}~°ÄÅÆÖØÚÜßáäåæéíöøúüýąČěľłńŘřŚŠź";
char[] charsetbasic = str.toCharArray();
str = "ACDEFHIJLMNOPRSTUVWZiortzÁØÚČŚŠ0123456789-";
str = "ACDEFHIJLMNOPRSTUVWZiortzÁÅÄÖØÚČŚŠ0123456789-";
char[] charsetdaynames = str.toCharArray();
str = "0123456789.°-";
char[] charsetnumbers = str.toCharArray();

View File

@@ -1,16 +1,14 @@
{
"version": 0,
"version": 1,
"name": "M2 1.54\"",
"width": 152,
"height": 152,
"rotatebuffer": 0,
"bpp": 2,
"colors": 3,
"colortable": {
"white": [ 255, 255, 255 ],
"black": [ 0, 0, 0 ],
"red": [ 255, 0, 0 ],
"gray": [ 150, 150, 150 ]
"red": [ 255, 0, 0 ]
},
"shortlut": 2,
"options": [ "button", "customlut" ],

View File

@@ -1,16 +1,14 @@
{
"version": 0,
"version": 1,
"name": "M2 2.9\"",
"width": 296,
"height": 128,
"rotatebuffer": 1,
"bpp": 2,
"colors": 3,
"colortable": {
"white": [ 255, 255, 255 ],
"black": [ 0, 0, 0 ],
"red": [ 255, 0, 0 ],
"gray": [ 150, 150, 150 ]
"red": [ 255, 0, 0 ]
},
"shortlut": 2,
"options": [ "button", "customlut" ],

View File

@@ -1,16 +1,14 @@
{
"version": 0,
"version": 1,
"name": "M2 4.2\"",
"width": 400,
"height": 300,
"rotatebuffer": 0,
"bpp": 2,
"colors": 3,
"colortable": {
"white": [ 255, 255, 255 ],
"black": [ 0, 0, 0 ],
"red": [ 255, 0, 0 ],
"gray": [ 150, 150, 150 ]
"red": [ 255, 0, 0 ]
},
"shortlut": 1,
"options": [ "button" ],

View File

@@ -1,16 +1,14 @@
{
"version": 0,
"version": 1,
"name": "M2 7.4\"",
"width": 640,
"height": 384,
"rotatebuffer": 0,
"bpp": 2,
"colors": 3,
"colortable": {
"white": [ 255, 255, 255 ],
"black": [ 0, 0, 0 ],
"red": [ 255, 0, 0 ],
"gray": [ 150, 150, 150 ]
"red": [ 255, 0, 0 ]
},
"shortlut": 1,
"zlib_compression": "27",

View File

@@ -1,16 +1,14 @@
{
"version": 0,
"version": 1,
"name": "M2 2.9\" (UC8151)",
"width": 296,
"height": 128,
"rotatebuffer": 1,
"bpp": 2,
"colors": 3,
"colortable": {
"white": [ 255, 255, 255 ],
"black": [ 0, 0, 0 ],
"red": [ 255, 0, 0 ],
"gray": [ 150, 150, 150 ]
"red": [ 255, 0, 0 ]
},
"shortlut": 0,
"options": [ "button" ],

View File

@@ -1,15 +1,13 @@
{
"version": 0,
"version": 1,
"name": "STGM29XXF 2.9\"",
"width": 296,
"height": 128,
"rotatebuffer": 1,
"bpp": 1,
"colors": 2,
"colortable": {
"white": [ 255, 255, 255 ],
"black": [ 0, 0, 0 ],
"gray": [ 150, 150, 150 ]
"black": [ 0, 0, 0 ]
},
"highlight_color": 5,
"shortlut": 0,

View File

@@ -1,16 +1,14 @@
{
"version": 0,
"version": 1,
"name": "M2 2.7\"",
"width": 264,
"height": 176,
"rotatebuffer": 1,
"bpp": 2,
"colors": 3,
"colortable": {
"white": [ 255, 255, 255 ],
"black": [ 0, 0, 0 ],
"red": [ 255, 0, 0 ],
"gray": [ 150, 150, 150 ]
"red": [ 255, 0, 0 ]
},
"shortlut": 0,
"options": [ "button" ],

View File

@@ -1,11 +1,10 @@
{
"version": 0,
"version": 1,
"name": "M2 7.5\" BW",
"width": 640,
"height": 384,
"rotatebuffer": 0,
"bpp": 1,
"colors": 2,
"colortable": {
"white": [ 255, 255, 255 ],
"black": [ 0, 0, 0 ]

View File

@@ -1,15 +1,15 @@
{
"version": 0,
"version": 1,
"name": "STGM29MT1 2.9\"",
"width": 296,
"height": 128,
"rotatebuffer": 1,
"bpp": 1,
"colors": 2,
"colortable": {
"white": [ 255, 255, 255 ],
"black": [ 0, 0, 0 ]
},
"highlight_color": 5,
"shortlut": 0,
"options": [ "button", "customlut" ],
"contentids": [ 22, 23, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 15, 16, 17, 18, 19, 20, 21 ],

View File

@@ -1,16 +1,14 @@
{
"version": 0,
"version": 1,
"name": "M3 9.7\"",
"width": 960,
"height": 672,
"rotatebuffer": 2,
"bpp": 2,
"colors": 3,
"colortable": {
"white": [ 255, 255, 255 ],
"black": [ 0, 0, 0 ],
"red": [ 255, 0, 0 ],
"gray": [ 150, 150, 150 ]
"red": [ 255, 0, 0 ]
},
"shortlut": 0,
"zlib_compression": "27",

View File

@@ -1,16 +1,14 @@
{
"version": 0,
"version": 1,
"name": "M3 4.3\"",
"width": 522,
"height": 152,
"rotatebuffer": 3,
"bpp": 2,
"colors": 3,
"colortable": {
"white": [ 255, 255, 255 ],
"black": [ 0, 0, 0 ],
"red": [ 255, 0, 0 ],
"gray": [ 150, 150, 150 ]
"red": [ 255, 0, 0 ]
},
"shortlut": 0,
"zlib_compression": "27",

View File

@@ -1,16 +1,14 @@
{
"version": 0,
"version": 1,
"name": "M3 1.6\"",
"width": 200,
"height": 200,
"rotatebuffer": 0,
"bpp": 2,
"colors": 3,
"colortable": {
"white": [ 255, 255, 255 ],
"black": [ 0, 0, 0 ],
"red": [ 255, 0, 0 ],
"gray": [ 150, 150, 150 ]
"red": [ 255, 0, 0 ]
},
"shortlut": 0,
"zlib_compression": "27",

View File

@@ -5,12 +5,10 @@
"height": 160,
"rotatebuffer": 3,
"bpp": 2,
"colors": 3,
"colortable": {
"white": [ 255, 255, 255 ],
"black": [ 0, 0, 0 ],
"red": [ 255, 0, 0 ],
"gray": [ 150, 150, 150 ]
"red": [ 255, 0, 0 ]
},
"shortlut": 0,
"zlib_compression": "27",

View File

@@ -1,16 +1,14 @@
{
"version": 0,
"version": 1,
"name": "M3 2.6\"",
"width": 360,
"height": 184,
"rotatebuffer": 3,
"bpp": 2,
"colors": 3,
"colortable": {
"white": [ 255, 255, 255 ],
"black": [ 0, 0, 0 ],
"red": [ 255, 0, 0 ],
"gray": [ 150, 150, 150 ]
"red": [ 255, 0, 0 ]
},
"shortlut": 0,
"zlib_compression": "27",

View File

@@ -1,16 +1,14 @@
{
"version": 0,
"version": 1,
"name": "M3 2.9\"",
"width": 384,
"height": 168,
"rotatebuffer": 3,
"bpp": 2,
"colors": 3,
"colortable": {
"white": [ 255, 255, 255 ],
"black": [ 0, 0, 0 ],
"red": [ 255, 0, 0 ],
"gray": [ 150, 150, 150 ]
"red": [ 255, 0, 0 ]
},
"shortlut": 0,
"zlib_compression": "27",

View File

@@ -1,16 +1,14 @@
{
"version": 0,
"version": 1,
"name": "M3 4.2\"",
"width": 400,
"height": 300,
"rotatebuffer": 0,
"bpp": 2,
"colors": 3,
"colortable": {
"white": [ 255, 255, 255 ],
"black": [ 0, 0, 0 ],
"red": [ 255, 0, 0 ],
"gray": [ 150, 150, 150 ]
"red": [ 255, 0, 0 ]
},
"shortlut": 0,
"zlib_compression": "27",

View File

@@ -1,16 +1,14 @@
{
"version": 0,
"version": 1,
"name": "M3 6.0\"",
"width": 600,
"height": 448,
"rotatebuffer": 0,
"bpp": 2,
"colors": 3,
"colortable": {
"white": [ 255, 255, 255 ],
"black": [ 0, 0, 0 ],
"red": [ 255, 0, 0 ],
"gray": [ 150, 150, 150 ]
"red": [ 255, 0, 0 ]
},
"shortlut": 0,
"zlib_compression": "27",

View File

@@ -1,16 +1,14 @@
{
"version": 0,
"version": 1,
"name": "M3 7.5\"",
"width": 800,
"height": 480,
"rotatebuffer": 0,
"bpp": 2,
"colors": 3,
"colortable": {
"white": [ 255, 255, 255 ],
"black": [ 0, 0, 0 ],
"red": [ 255, 0, 0 ],
"gray": [ 150, 150, 150 ]
"red": [ 255, 0, 0 ]
},
"shortlut": 0,
"zlib_compression": "27",

View File

@@ -1,16 +1,14 @@
{
"version": 0,
"version": 1,
"name": "M3 5.85\"",
"width": 792,
"height": 272,
"rotatebuffer": 0,
"bpp": 2,
"colors": 3,
"colortable": {
"white": [ 255, 255, 255 ],
"black": [ 0, 0, 0 ],
"red": [ 255, 0, 0 ],
"gray": [ 150, 150, 150 ]
"red": [ 255, 0, 0 ]
},
"shortlut": 0,
"zlib_compression": "27",

View File

@@ -1,15 +1,13 @@
{
"version": 0,
"name": "M3 5.85\" FREEZER",
"version": 1,
"name": "M3 5.85\" BW",
"width": 792,
"height": 272,
"rotatebuffer": 0,
"bpp": 1,
"colors": 2,
"colortable": {
"white": [ 255, 255, 255 ],
"black": [ 0, 0, 0 ],
"gray": [ 150, 150, 150 ]
"black": [ 0, 0, 0 ]
},
"shortlut": 0,
"zlib_compression": "27",

View File

@@ -0,0 +1,19 @@
{
"version": 1,
"name": "M3 1.3\" Peghook",
"width": 200,
"height": 144,
"rotatebuffer": 3,
"bpp": 2,
"colors": 3,
"colortable": {
"white": [ 255, 255, 255 ],
"black": [ 0, 0, 0 ],
"red": [ 255, 0, 0 ]
},
"shortlut": 0,
"zlib_compression": "27",
"options": [ "button" ],
"contentids": [ 22, 23, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 14, 15, 16, 17, 18, 19, 20, 21, 27 ],
"usetemplate": 0
}

View File

@@ -1,16 +1,14 @@
{
"version": 0,
"version": 1,
"name": "HS BWR 2.13\"",
"width": 256,
"height": 128,
"rotatebuffer": 1,
"bpp": 2,
"colors": 3,
"colortable": {
"white": [ 255, 255, 255 ],
"black": [ 0, 0, 0 ],
"red": [ 255, 0, 0 ],
"gray": [ 150, 150, 150 ]
"red": [ 255, 0, 0 ]
},
"shortlut": 0,
"options": [ "led" ],

View File

@@ -1,16 +1,14 @@
{
"version": 0,
"version": 1,
"name": "HS BWY 3.5\"",
"width": 384,
"height": 184,
"rotatebuffer": 1,
"bpp": 2,
"colors": 3,
"colortable": {
"white": [ 255, 255, 255 ],
"black": [ 0, 0, 0 ],
"yellow": [ 200, 200, 0 ],
"gray": [ 150, 150, 150 ]
"yellow": [ 255, 255, 0 ]
},
"highlight_color": 2,
"shortlut": 0,

View File

@@ -1,16 +1,14 @@
{
"version": 0,
"version": 1,
"name": "HS BWR 3.5\"",
"width": 384,
"height": 184,
"rotatebuffer": 1,
"bpp": 2,
"colors": 3,
"colortable": {
"white": [ 255, 255, 255 ],
"black": [ 0, 0, 0 ],
"red": [ 255, 0, 0 ],
"gray": [ 150, 150, 150 ]
"red": [ 255, 0, 0 ]
},
"shortlut": 0,
"options": [ "led" ],

View File

@@ -1,15 +1,13 @@
{
"version": 0,
"version": 1,
"name": "HS BW 3.5\"",
"width": 384,
"height": 184,
"rotatebuffer": 1,
"bpp": 1,
"colors": 2,
"colortable": {
"white": [ 255, 255, 255 ],
"black": [ 0, 0, 0 ],
"gray": [ 150, 150, 150 ]
"black": [ 0, 0, 0 ]
},
"highlight_color": 5,
"shortlut": 0,

View File

@@ -1,58 +1,17 @@
{
"version": 0,
"version": 1,
"name": "Chroma 7.4\"",
"width": 640,
"height": 384,
"rotatebuffer": 0,
"bpp": 2,
"colors": 3,
"colortable": {
"white": [ 255, 255, 255 ],
"black": [ 0, 0, 0 ],
"red": [ 255, 0, 0 ],
"gray": [ 150, 150, 150 ]
"red": [ 255, 0, 0 ]
},
"shortlut": 1,
"options": [ ],
"contentids": [ 22, 23, 1, 4, 5, 7, 8, 9, 10, 11, 17, 18, 19, 20 ],
"template": {
"1": {
"weekday": [ 320, -5, "Signika-SB.ttf", 100 ],
"month": [ 320, 265, "Signika-SB.ttf", 100 ],
"day": [ 320, 60, "Signika-SB.ttf", 220 ]
},
"4": {
"location": [ 20, 20, "fonts/calibrib30" ],
"wind": [ 90, 83, "fonts/calibrib30" ],
"temp": [ 20, 170, "fonts/calibrib30" ],
"icon": [ 385, 0, 100, 2 ],
"dir": [ 40, 50, 80 ],
"umbrella": [ 325, 155, 78 ]
},
"8": {
"location": [ 10, 10, "fonts/calibrib30" ],
"column": [ 6, 66 ],
"day": [ 33, 60, "fonts/bahnschrift20", 104, 230 ],
"rain": [ 34, 260 ],
"icon": [ 32, 145, 30 ],
"wind": [ 17, 90 ],
"line": [ 50, 300 ]
},
"9": {
"title": [ 6, 0, "Signika-SB.ttf", 32 ],
"items": 5,
"line": [ 9, 40, "calibrib16.vlw" ],
"desc": [ 2, 8, "REFSAN12.vlw", 1.2 ]
},
"10": {
"title": [ 320, 10, "fonts/bahnschrift20" ],
"pos": [ 320, 40 ]
},
"11": {
"rotate": 0,
"mode": 1,
"days": 7,
"gridparam": [ 3, 17, 30, "calibrib16.vlw", "BellCent10.vlw", 14 ]
}
}
"usetemplate": 5
}

View File

@@ -1,16 +1,14 @@
{
"version": 0,
"version": 1,
"name": "Chroma29 2.9\" (UC8154)",
"width": 296,
"height": 128,
"rotatebuffer": 1,
"bpp": 2,
"colors": 3,
"colortable": {
"white": [255, 255, 255],
"black": [0, 0, 0],
"red": [255, 0, 0],
"gray": [150, 150, 150]
"red": [255, 0, 0]
},
"shortlut": 0,
"contentids": [ 22, 23, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 14, 15, 16, 17, 18, 19, 20, 21, 27],

View File

@@ -1,16 +1,14 @@
{
"version": 0,
"version": 1,
"name": "Chroma29 2.9\"",
"width": 296,
"height": 128,
"rotatebuffer": 1,
"bpp": 2,
"colors": 3,
"colortable": {
"white": [255, 255, 255],
"black": [0, 0, 0],
"red": [255, 0, 0],
"gray": [150, 150, 150]
"red": [255, 0, 0]
},
"shortlut": 0,
"contentids": [ 22, 23, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 14, 15, 16, 17, 18, 19, 20, 21, 27],

View File

@@ -1,57 +1,16 @@
{
"version": 0,
"version": 1,
"name": "Chroma42 4.2\"",
"width": 400,
"height": 300,
"rotatebuffer": 0,
"bpp": 2,
"colors": 3,
"colortable": {
"white": [255, 255, 255],
"black": [0, 0, 0],
"red": [255, 0, 0],
"gray": [150, 150, 150]
"red": [255, 0, 0]
},
"shortlut": 0,
"contentids": [ 22, 23, 1, 4, 5, 7, 8, 9, 10, 11, 17, 18, 19, 20],
"template": {
"1": {
"weekday": [ 200, 0, "Signika-SB.ttf", 70 ],
"month": [ 200, 210, "Signika-SB.ttf", 70 ],
"day": [ 200, 45, "Signika-SB.ttf", 170 ]
},
"4": {
"location": [ 20, 20, "fonts/calibrib30" ],
"wind": [ 90, 83, "fonts/calibrib50" ],
"temp": [ 20, 170, "fonts/calibrib100" ],
"icon": [ 385, 0, 100, 2 ],
"dir": [ 40, 50, 80 ],
"umbrella": [ 325, 155, 78 ]
},
"8": {
"location": [ 10, 10, "fonts/calibrib30" ],
"column": [ 6, 66 ],
"day": [ 33, 60, "fonts/bahnschrift20", 104, 230 ],
"rain": [ 34, 260 ],
"icon": [ 32, 145, 30 ],
"wind": [ 17, 90 ],
"line": [ 50, 300 ]
},
"9": {
"title": [ 6, 0, "Signika-SB.ttf", 25 ],
"items": 4,
"line": [ 9, 40, "calibrib16.vlw" ],
"desc": [ 2, 8, "REFSAN12.vlw", 1.2 ]
},
"10": {
"title": [ 200, 10, "fonts/bahnschrift20" ],
"pos": [ 200, 35 ]
},
"11": {
"rotate": 0,
"mode": 1,
"days": 4,
"gridparam": [ 5, 17, 20, "calibrib16.vlw", "BellCent10.vlw", 14 ]
}
}
"contentids": [ 22, 23, 1, 4, 5, 7, 8, 9, 10, 11, 17, 18, 19, 20 ],
"usetemplate": 2
}

View File

@@ -1,11 +1,10 @@
{
"version": 0,
"version": 1,
"name": "Gicisky BLE EPD BW 2.9\"",
"width": 296,
"height": 128,
"rotatebuffer": 1,
"bpp": 1,
"colors": 2,
"colortable": {
"white": [ 255, 255, 255 ],
"black": [ 0, 0, 0 ]

View File

@@ -1,16 +1,14 @@
{
"version": 0,
"version": 1,
"name": "Gicisky BLE EPD BWR 2.9\"",
"width": 296,
"height": 128,
"rotatebuffer": 1,
"bpp": 2,
"colors": 3,
"colortable": {
"white": [ 255, 255, 255 ],
"black": [ 0, 0, 0 ],
"red": [ 255, 0, 0 ],
"gray": [ 150, 150, 150 ]
"red": [ 255, 0, 0 ]
},
"contentids": [ 22, 23, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 15, 16, 17, 18, 19, 20, 21, 27 ],
"usetemplate": 1

View File

@@ -1,16 +1,14 @@
{
"version": 0,
"version": 1,
"name": "Gicisky BLE EPD BWR 4.2\"",
"width": 400,
"height": 300,
"rotatebuffer": 0,
"bpp": 2,
"colors": 3,
"colortable": {
"white": [ 255, 255, 255 ],
"black": [ 0, 0, 0 ],
"red": [ 255, 0, 0 ],
"gray": [ 150, 150, 150 ]
"red": [ 255, 0, 0 ]
},
"contentids": [ 22, 23, 1, 4, 5, 7, 8, 9, 10, 11, 17, 18, 19, 20 ],
"usetemplate": 2

View File

@@ -1,16 +1,14 @@
{
"version": 0,
"version": 1,
"name": "BLE EPD BWR 2.9\" Silabs",
"width": 384,
"height": 168,
"rotatebuffer": 1,
"bpp": 2,
"colors": 3,
"colortable": {
"white": [255, 255, 255],
"black": [0, 0, 0],
"red": [255, 0, 0],
"gray": [150, 150, 150]
"red": [255, 0, 0]
},
"contentids": [ 22, 23, 1, 4, 5, 7, 8, 9, 10, 11, 17, 18, 19, 20],
"usetemplate": 1,

View File

@@ -1,15 +1,11 @@
{
"version": 0,
"version": 1,
"name": "ATC MiThermometer BLE",
"width": 6,
"height": 8,
"rotatebuffer": 1,
"bpp": 1,
"colors": 1,
"colortable": {
"white": [ 255, 255, 255 ],
"black": [ 0, 0, 0 ]
},
"colortable": {},
"shortlut": 0,
"options": [ ],
"contentids": [ 22 ],

View File

@@ -1,16 +1,14 @@
{
"version": 0,
"version": 1,
"name": "TFT 320x172",
"width": 320,
"height": 172,
"rotatebuffer": 0,
"bpp": 16,
"colors": 4,
"colortable": {
"white": [ 255, 255, 255 ],
"black": [ 0, 0, 0 ],
"red": [ 255, 0, 0 ],
"gray": [ 150, 150, 150 ]
"red": [ 255, 0, 0 ]
},
"shortlut": 0,
"options": [ ],

View File

@@ -1,16 +1,14 @@
{
"version": 0,
"version": 1,
"name": "TFT 160x80",
"width": 160,
"height": 80,
"rotatebuffer": 1,
"bpp": 16,
"colors": 4,
"colortable": {
"white": [ 255, 255, 255 ],
"black": [ 0, 0, 0 ],
"red": [ 255, 0, 0 ],
"gray": [ 150, 150, 150 ]
"red": [ 255, 0, 0 ]
},
"shortlut": 0,
"options": [ ],

View File

@@ -1,11 +1,10 @@
{
"version": 0,
"version": 1,
"name": "SLTEM007 Segmented",
"width": 0,
"height": 0,
"rotatebuffer": 0,
"bpp": 1,
"colors": 0,
"colortable": { },
"shortlut": 0,
"options": [ ],