mirror of
https://github.com/Genaker/LoraSA.git
synced 2026-03-28 17:42:59 +01:00
Visualize scan_max_result better - add frequency labels
This commit is contained in:
@@ -200,5 +200,21 @@ void DecoratedBarChart::draw()
|
||||
int tick_pos = bar.x2pos(bar.min_x + step * MINOR_TICKS);
|
||||
display.drawVerticalLine(pos_x + tick_pos, y, MINOR_TICK_LENGTH);
|
||||
}
|
||||
|
||||
if (draw_labels)
|
||||
{ // TODO: adjust chart size; for now we'll just assume that we are not ruining
|
||||
// display
|
||||
display.setColor(BLACK);
|
||||
display.fillRect(pos_x, y + MAJOR_TICK_LENGTH, width,
|
||||
display.getStringWidth("00000"));
|
||||
display.setColor(WHITE);
|
||||
for (float step = 1; bar.min_x + step * MAJOR_TICKS < bar.max_x; step += 1)
|
||||
{
|
||||
int tick_pos = bar.x2pos(bar.min_x + step * MAJOR_TICKS);
|
||||
drawVerticalString(display, ArialMT_Plain_10_Vert, pos_x + tick_pos - 5,
|
||||
y + MAJOR_TICK_LENGTH,
|
||||
String((int)(bar.min_x + step * MAJOR_TICKS)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
147
lib/charts/Font.cpp
Normal file
147
lib/charts/Font.cpp
Normal file
@@ -0,0 +1,147 @@
|
||||
#include "charts.h"
|
||||
|
||||
extern const uint8_t ArialMT_Plain_10[]; // borrowed from OLEDDisplayFonts.h
|
||||
|
||||
uint8_t *ArialMT_Plain_10_Vert = NULL;
|
||||
|
||||
uint64_t _horz_line(const uint8_t *font, size_t chr_off, size_t height, size_t bytes,
|
||||
size_t ln)
|
||||
{
|
||||
size_t raster_height = (height + 7) / 8;
|
||||
uint8_t b = 1 << (ln & 7);
|
||||
|
||||
uint64_t ret = 0;
|
||||
uint64_t mask = 1;
|
||||
for (size_t y = ln / 8; y < bytes; y += raster_height, mask <<= 1)
|
||||
{
|
||||
if (font[chr_off + y] & b)
|
||||
{
|
||||
ret |= mask;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint64_t _flip(uint64_t v, size_t width)
|
||||
{
|
||||
for (uint64_t b = 1, e = 1 << (width - 1); b < e; b <<= 1, e >>= 1)
|
||||
{
|
||||
if (!!(v & b) != !!(v & e))
|
||||
{
|
||||
v = v ^ (b | e);
|
||||
}
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
uint8_t *_rot(const uint8_t *font)
|
||||
{
|
||||
size_t sz = 10000;
|
||||
size_t p = 0;
|
||||
uint8_t *vert = (uint8_t *)malloc(sz);
|
||||
|
||||
size_t height = font[1];
|
||||
vert[0] = (uint8_t)height; // height -> width
|
||||
vert[1] = font[0]; // width -> height
|
||||
vert[2] = font[2]; // first char
|
||||
size_t chars = font[3]; // char count
|
||||
vert[3] = (uint8_t)chars;
|
||||
|
||||
size_t map_off = chars * 4 + 4;
|
||||
|
||||
for (int i = 0; i < chars; i++)
|
||||
{
|
||||
uint32_t v = ((uint32_t *)font)[i + 1];
|
||||
size_t chr_off = ((v & 0xff) << 8) | ((v >> 8) & 0xff);
|
||||
if (chr_off != 0xffff)
|
||||
{
|
||||
size_t bs = (v >> 16) & 0xff;
|
||||
size_t width = (v >> 24) & 0xff;
|
||||
size_t raster_height =
|
||||
(width + 7) / 8; // how many bytes needed to store one vertical line
|
||||
|
||||
size_t bytes = height * raster_height;
|
||||
v = (v & 0xff000000L) | (bytes << 16) | ((p >> 8) & 0xff) | ((p & 0xff) << 8);
|
||||
|
||||
chr_off += map_off;
|
||||
|
||||
if (map_off + p + bytes > sz)
|
||||
{
|
||||
uint8_t *vv = vert;
|
||||
sz += 1000;
|
||||
vert = (uint8_t *)malloc(sz);
|
||||
memcpy(vert, vv, sz - 1000);
|
||||
free(vv);
|
||||
}
|
||||
|
||||
for (size_t j = 0; j < height; j++)
|
||||
{
|
||||
uint64_t ln = _flip(_horz_line(font, chr_off, height, bs, j), width);
|
||||
for (size_t k = 0; k < raster_height; k++, p++, ln >>= 8)
|
||||
{
|
||||
vert[map_off + p] = (uint8_t)ln;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
((uint32_t *)vert)[i + 1] = v;
|
||||
}
|
||||
|
||||
if (map_off + p < sz)
|
||||
{
|
||||
uint8_t *vv = vert;
|
||||
sz = map_off + p;
|
||||
vert = (uint8_t *)malloc(sz);
|
||||
memcpy(vert, vv, sz);
|
||||
free(vv);
|
||||
}
|
||||
return vert;
|
||||
}
|
||||
|
||||
void init_fonts()
|
||||
{
|
||||
if (ArialMT_Plain_10_Vert != NULL)
|
||||
{
|
||||
free(ArialMT_Plain_10_Vert);
|
||||
ArialMT_Plain_10_Vert = NULL;
|
||||
}
|
||||
|
||||
ArialMT_Plain_10_Vert = _rot(ArialMT_Plain_10);
|
||||
}
|
||||
|
||||
void drawVerticalString(Display_t &display, const uint8_t *v_font, int x, int y, String s)
|
||||
{
|
||||
if (v_font == NULL)
|
||||
return;
|
||||
|
||||
size_t w = v_font[0];
|
||||
char init_ch = v_font[2];
|
||||
size_t chars = v_font[3];
|
||||
|
||||
const uint8_t *v_chars = v_font + (chars + 1) * 4;
|
||||
|
||||
for (int i = s.length(); i-- > 0;)
|
||||
{
|
||||
char c = s.charAt(i);
|
||||
if (c < init_ch)
|
||||
continue;
|
||||
c -= init_ch;
|
||||
if (c >= chars)
|
||||
continue;
|
||||
|
||||
size_t map_off = (c + 1) * 4;
|
||||
size_t chr_off = (((uint16_t)v_font[map_off]) << 8) | (v_font[map_off + 1]);
|
||||
size_t bs = v_font[map_off + 2];
|
||||
size_t h = v_font[map_off + 3];
|
||||
if (chr_off == 0xffff)
|
||||
{
|
||||
y += h;
|
||||
continue;
|
||||
}
|
||||
|
||||
display.drawFastImage(x, y, w, h, v_chars + chr_off);
|
||||
y += h;
|
||||
}
|
||||
}
|
||||
@@ -101,12 +101,14 @@ struct BarChart : ProgressChart, Listener
|
||||
struct DecoratedBarChart : Chart
|
||||
{
|
||||
BarChart bar;
|
||||
bool draw_labels;
|
||||
|
||||
DecoratedBarChart(Display_t &d, uint16_t x, uint16_t y, uint16_t w, uint16_t h,
|
||||
float min_x, float max_x, float min_y, float max_y, float level_y)
|
||||
: Chart(d, x, y, w, h),
|
||||
bar(d, x, y + LABEL_HEIGHT, w, h - LABEL_HEIGHT - AXIS_HEIGHT, min_x, max_x,
|
||||
min_y, max_y, level_y) {};
|
||||
min_y, max_y, level_y),
|
||||
draw_labels(false) {};
|
||||
|
||||
void reset(uint16_t x, uint16_t y, uint16_t w, uint16_t h) override;
|
||||
void draw() override;
|
||||
@@ -176,4 +178,10 @@ struct UptimeClock : Chart
|
||||
virtual void draw() override;
|
||||
};
|
||||
|
||||
extern uint8_t *ArialMT_Plain_10_Vert;
|
||||
|
||||
void init_fonts();
|
||||
void drawVerticalString(Display_t &display, const uint8_t *v_font, int x, int y,
|
||||
String s);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1177,6 +1177,7 @@ void setup(void)
|
||||
|
||||
configurePages();
|
||||
display.clear();
|
||||
init_fonts();
|
||||
Serial.println();
|
||||
|
||||
#ifdef METHOD_RSSI
|
||||
@@ -2229,6 +2230,7 @@ void display_scan_result(ScanTaskResult &dump)
|
||||
float step = (bar->bar.max_x - bar->bar.min_x) / bar->bar.width;
|
||||
|
||||
bar->bar.clear();
|
||||
bar->draw_labels = true;
|
||||
|
||||
for (int i = 0; i < config.scan_ranges_sz; i++)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user