feat(ui): add tooling to generate symbols, add GPS status icon and macro latch icon to the macro menu
Ref https://github.com/OpenRTX/OpenRTX/issues/161pull/180/head
|
@ -0,0 +1,33 @@
|
|||
name: "Check if symbols need to be regenerated"
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
paths:
|
||||
- 'openrtx/include/fonts/symbols/**/*'
|
||||
pull_request:
|
||||
paths:
|
||||
- 'openrtx/include/fonts/symbols/**/*'
|
||||
|
||||
|
||||
jobs:
|
||||
check-symbol-generation:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: recursive
|
||||
- name: install-deps
|
||||
run: |
|
||||
sudo apt update
|
||||
sudo apt install python3 python3-pip
|
||||
- name: Setup symbols script dependencies
|
||||
run: |
|
||||
cd ${{github.workspace}}
|
||||
pip3 install -r requirements.txt
|
||||
- name: Run symbols script
|
||||
run: ./scripts/generate_symbols.py
|
||||
- name: Fail the build if there are changes generated
|
||||
run: |
|
||||
git --no-pager diff
|
||||
git diff-index --quiet HEAD
|
|
@ -72,6 +72,7 @@ openrtx_inc = ['openrtx/include',
|
|||
'openrtx/include/calibration',
|
||||
'openrtx/include/protocols',
|
||||
'openrtx/include/fonts/adafruit',
|
||||
'openrtx/include/fonts/symbols',
|
||||
'platform/drivers/ADC',
|
||||
'platform/drivers/NVM',
|
||||
'platform/drivers/GPS',
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#ifndef GRAPHICS_H
|
||||
#define GRAPHICS_H
|
||||
|
||||
#include <symbols.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
@ -89,6 +90,13 @@ typedef enum
|
|||
FONT_SIZE_24PT
|
||||
} fontSize_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SYMBOLS_SIZE_5PT,
|
||||
SYMBOLS_SIZE_6PT,
|
||||
SYMBOLS_SIZE_8PT
|
||||
} symbolSize_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
TEXT_ALIGN_LEFT = 0,
|
||||
|
@ -263,6 +271,19 @@ point_t gfx_printLine(uint8_t cur, uint8_t tot, int16_t startY, int16_t endY,
|
|||
*/
|
||||
void gfx_printError(const char *text, fontSize_t size);
|
||||
|
||||
/**
|
||||
* Prints text on the screen at the specified coordinates.
|
||||
* @param start: text line start point, in pixel coordinates.
|
||||
* @param size: icon font size, defined as enum.
|
||||
* @param alignment: text alignment type, defined as enum. DEPRECATED: in the
|
||||
* future this will be always LEFT.
|
||||
* @param color: text color, in color_t format.
|
||||
* @param symbol: symbol to be printed.
|
||||
* @return text width and height as point_t coordinates
|
||||
*/
|
||||
point_t gfx_drawSymbol(point_t start, symbolSize_t size, textAlign_t alignment,
|
||||
color_t color, symbol_t symbol);
|
||||
|
||||
/**
|
||||
* Function to draw battery of arbitrary size.
|
||||
* Starting coordinates are relative to the top left point.
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
// This is a generated file, please do not edit it! Use generate_symbols.py
|
||||
static const uint8_t Symbols5pt7bBitmaps[] PROGMEM = {
|
||||
0x00, //space
|
||||
0x00, 0x7e, 0x5a, 0x66, 0x66, 0x42, 0x7e, 0x00, //alpha-m-box-outline.svg
|
||||
0x00, 0x18, 0x7e, 0x66, 0x66, 0x7e, 0x18, 0x00, //cog.svg
|
||||
0x00, 0x3c, 0x42, 0x5a, 0x5a, 0x42, 0x3c, 0x00, //crosshairs-gps.svg
|
||||
0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, //crosshairs.svg
|
||||
0x18, 0x24, 0x24, 0x7e, 0x7e, 0x7e, 0x7e, 0x00, //lock.svg
|
||||
0x00, 0x3c, 0x81, 0x42, 0x3c, 0x18, 0x18, 0x00, //wifi-strength-1.svg
|
||||
0x00, 0x3c, 0x81, 0x5a, 0x3c, 0x18, 0x18, 0x00, //wifi-strength-2.svg
|
||||
0x00, 0x3c, 0x81, 0x7e, 0x3c, 0x18, 0x18, 0x00, //wifi-strength-3.svg
|
||||
0x00, 0x3c, 0xff, 0x7e, 0x3c, 0x18, 0x18, 0x00, //wifi-strength-4.svg
|
||||
};
|
||||
|
||||
static const GFXglyph Symbols5pt7bGlyphs[] PROGMEM = {
|
||||
//Index, W, H,xAdv,dX, dY
|
||||
{ 0, 1, 1, 5, 0, -7}, // " " space
|
||||
{ 1, 8, 8, 5, 0, -7}, // "!" alpha-m-box-outline.svg
|
||||
{ 9, 8, 8, 5, 0, -7}, // """ cog.svg
|
||||
{ 17, 8, 8, 5, 0, -7}, // "#" crosshairs-gps.svg
|
||||
{ 25, 8, 8, 5, 0, -7}, // "$" crosshairs.svg
|
||||
{ 33, 8, 8, 5, 0, -7}, // "%" lock.svg
|
||||
{ 41, 8, 8, 5, 0, -7}, // "&" wifi-strength-1.svg
|
||||
{ 49, 8, 8, 5, 0, -7}, // "'" wifi-strength-2.svg
|
||||
{ 57, 8, 8, 5, 0, -7}, // "(" wifi-strength-3.svg
|
||||
{ 65, 8, 8, 5, 0, -7}, // ")" wifi-strength-4.svg
|
||||
};
|
||||
static const GFXfont Symbols5pt7b PROGMEM = {
|
||||
(uint8_t *)Symbols5pt7bBitmaps,
|
||||
(GFXglyph *)Symbols5pt7bGlyphs,
|
||||
//ASCII start, ASCII stop,y Advance
|
||||
32, 41, 19 };
|
|
@ -0,0 +1,32 @@
|
|||
// This is a generated file, please do not edit it! Use generate_symbols.py
|
||||
static const uint8_t Symbols6pt7bBitmaps[] PROGMEM = {
|
||||
0x00, //space
|
||||
0x00, 0x0f, 0xc4, 0x09, 0x7a, 0x52, 0x94, 0xa5, 0x29, 0x02, 0x3f, 0x00, 0x00, //alpha-m-box-outline.svg
|
||||
0x00, 0x03, 0x03, 0xf1, 0xfe, 0x33, 0x0c, 0xc7, 0xf8, 0xfc, 0x0c, 0x00, 0x00, //cog.svg
|
||||
0x00, 0x03, 0x03, 0x30, 0xb4, 0x5e, 0x97, 0xa2, 0xd0, 0xcc, 0x0c, 0x00, 0x00, //crosshairs-gps.svg
|
||||
0x00, 0x03, 0x03, 0x30, 0x84, 0x40, 0x90, 0x22, 0x10, 0xcc, 0x0c, 0x00, 0x00, //crosshairs.svg
|
||||
0x0c, 0x04, 0x81, 0x20, 0xfc, 0x3f, 0x0f, 0xc3, 0x30, 0xfc, 0x3f, 0x00, 0x00, //lock.svg
|
||||
0x00, 0x07, 0x86, 0x19, 0x02, 0x40, 0x8b, 0x41, 0xe0, 0x30, 0x00, 0x00, 0x00, //wifi-strength-1.svg
|
||||
0x00, 0x07, 0x86, 0x19, 0x02, 0x7f, 0x8f, 0xc1, 0xe0, 0x30, 0x00, 0x00, 0x00, //wifi-strength-2.svg
|
||||
0x00, 0x07, 0x86, 0x19, 0x32, 0x7f, 0x8f, 0xc1, 0xe0, 0x30, 0x00, 0x00, 0x00, //wifi-strength-3.svg
|
||||
0x00, 0x07, 0x87, 0xf9, 0xfe, 0x7f, 0x8f, 0xc1, 0xe0, 0x30, 0x00, 0x00, 0x00, //wifi-strength-4.svg
|
||||
};
|
||||
|
||||
static const GFXglyph Symbols6pt7bGlyphs[] PROGMEM = {
|
||||
//Index, W, H,xAdv,dX, dY
|
||||
{ 0, 1, 1, 6, 0, -8}, // " " space
|
||||
{ 1, 10, 10, 6, 0, -8}, // "!" alpha-m-box-outline.svg
|
||||
{ 14, 10, 10, 6, 0, -8}, // """ cog.svg
|
||||
{ 27, 10, 10, 6, 0, -8}, // "#" crosshairs-gps.svg
|
||||
{ 40, 10, 10, 6, 0, -8}, // "$" crosshairs.svg
|
||||
{ 53, 10, 10, 6, 0, -8}, // "%" lock.svg
|
||||
{ 66, 10, 10, 6, 0, -8}, // "&" wifi-strength-1.svg
|
||||
{ 79, 10, 10, 6, 0, -8}, // "'" wifi-strength-2.svg
|
||||
{ 92, 10, 10, 6, 0, -8}, // "(" wifi-strength-3.svg
|
||||
{ 105, 10, 10, 6, 0, -8}, // ")" wifi-strength-4.svg
|
||||
};
|
||||
static const GFXfont Symbols6pt7b PROGMEM = {
|
||||
(uint8_t *)Symbols6pt7bBitmaps,
|
||||
(GFXglyph *)Symbols6pt7bGlyphs,
|
||||
//ASCII start, ASCII stop,y Advance
|
||||
32, 41, 22 };
|
|
@ -0,0 +1,32 @@
|
|||
// This is a generated file, please do not edit it! Use generate_symbols.py
|
||||
static const uint8_t Symbols8pt7bBitmaps[] PROGMEM = {
|
||||
0x00, //space
|
||||
0x00, 0x00, 0x00, 0x0f, 0xf8, 0x40, 0x42, 0xfa, 0x15, 0x50, 0xaa, 0x85, 0x54, 0x2a, 0xa1, 0x01, 0x0f, 0xf8, 0x00, 0x00, 0x00, 0x00, //alpha-m-box-outline.svg
|
||||
0x00, 0x00, 0x38, 0x01, 0xc0, 0x7f, 0xc7, 0xff, 0x1c, 0x70, 0xe3, 0x87, 0x1c, 0x7f, 0xf1, 0xff, 0x01, 0xc0, 0x0e, 0x00, 0x00, 0x00, //cog.svg
|
||||
0x00, 0x00, 0x10, 0x03, 0xe0, 0x20, 0x82, 0x22, 0x13, 0x91, 0xbe, 0xc4, 0xe4, 0x22, 0x20, 0x82, 0x03, 0xe0, 0x04, 0x00, 0x00, 0x00, //crosshairs-gps.svg
|
||||
0x00, 0x00, 0x10, 0x03, 0xe0, 0x20, 0x82, 0x02, 0x10, 0x11, 0x80, 0xc4, 0x04, 0x20, 0x20, 0x82, 0x03, 0xe0, 0x04, 0x00, 0x00, 0x00, //crosshairs.svg
|
||||
0x00, 0x00, 0x7c, 0x02, 0x20, 0x11, 0x01, 0xfc, 0x1f, 0xf0, 0xff, 0x87, 0xbc, 0x3d, 0xe1, 0xff, 0x0f, 0xf8, 0x7f, 0xc0, 0x00, 0x00, //lock.svg
|
||||
0x00, 0x00, 0x00, 0x0f, 0xf8, 0xc0, 0x64, 0x01, 0x10, 0x10, 0xc1, 0x83, 0xf8, 0x0f, 0x80, 0x38, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, //wifi-strength-1.svg
|
||||
0x00, 0x00, 0x00, 0x0f, 0xf8, 0xc0, 0x64, 0x01, 0x11, 0x10, 0xff, 0x83, 0xf8, 0x0f, 0x80, 0x38, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, //wifi-strength-2.svg
|
||||
0x00, 0x00, 0x00, 0x0f, 0xf8, 0xc0, 0x64, 0x71, 0x1f, 0xf0, 0xff, 0x83, 0xf8, 0x0f, 0x80, 0x38, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, //wifi-strength-3.svg
|
||||
0x00, 0x00, 0x00, 0x0f, 0xf8, 0xff, 0xe7, 0xff, 0x1f, 0xf0, 0xff, 0x83, 0xf8, 0x0f, 0x80, 0x38, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, //wifi-strength-4.svg
|
||||
};
|
||||
|
||||
static const GFXglyph Symbols8pt7bGlyphs[] PROGMEM = {
|
||||
//Index, W, H,xAdv,dX, dY
|
||||
{ 0, 1, 1, 9, 0, -11}, // " " space
|
||||
{ 1, 13, 13, 9, 0, -11}, // "!" alpha-m-box-outline.svg
|
||||
{ 23, 13, 13, 9, 0, -11}, // """ cog.svg
|
||||
{ 45, 13, 13, 9, 0, -11}, // "#" crosshairs-gps.svg
|
||||
{ 67, 13, 13, 9, 0, -11}, // "$" crosshairs.svg
|
||||
{ 89, 13, 13, 9, 0, -11}, // "%" lock.svg
|
||||
{ 111, 13, 13, 9, 0, -11}, // "&" wifi-strength-1.svg
|
||||
{ 133, 13, 13, 9, 0, -11}, // "'" wifi-strength-2.svg
|
||||
{ 155, 13, 13, 9, 0, -11}, // "(" wifi-strength-3.svg
|
||||
{ 177, 13, 13, 9, 0, -11}, // ")" wifi-strength-4.svg
|
||||
};
|
||||
static const GFXfont Symbols8pt7b PROGMEM = {
|
||||
(uint8_t *)Symbols8pt7bBitmaps,
|
||||
(GFXglyph *)Symbols8pt7bGlyphs,
|
||||
//ASCII start, ASCII stop,y Advance
|
||||
32, 41, 30 };
|
|
@ -0,0 +1,24 @@
|
|||
## Pictogrammers Free License
|
||||
|
||||
Last Updated: February 1st, 2023
|
||||
|
||||
This package is released as free, open-source, and GPL friendly by
|
||||
the [Pictogrammers](https://pictogrammers.com/). You may use it
|
||||
for commercial projects, open-source projects, or anything really.
|
||||
|
||||
# Icons: Apache 2.0 (https://www.apache.org/licenses/LICENSE-2.0)
|
||||
|
||||
Some of the icons are redistributed under the Apache 2.0 license. All other
|
||||
icons are either redistributed under their respective licenses or are
|
||||
distributed under the Apache 2.0 license.
|
||||
|
||||
# Fonts: Apache 2.0 (https://www.apache.org/licenses/LICENSE-2.0)
|
||||
|
||||
All web and desktop fonts are distributed under the Apache 2.0 license. Web
|
||||
and desktop fonts contain some icons that are redistributed under the Apache
|
||||
2.0 license. All other icons are either redistributed under their respective
|
||||
licenses or are distributed under the Apache 2.0 license.
|
||||
|
||||
# Code: MIT (https://opensource.org/licenses/MIT)
|
||||
|
||||
The MIT license applies to all non-font and non-icon files.
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9,7H15A2,2 0 0,1 17,9V17H15V9H13V16H11V9H9V17H7V9A2,2 0 0,1 9,7M5,3H19A2,2 0 0,1 21,5V19A2,2 0 0,1 19,21H5A2,2 0 0,1 3,19V5A2,2 0 0,1 5,3M5,5V19H19V5H5Z" /></svg>
|
Po Szerokość: | Wysokość: | Rozmiar: 232 B |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12,15.5A3.5,3.5 0 0,1 8.5,12A3.5,3.5 0 0,1 12,8.5A3.5,3.5 0 0,1 15.5,12A3.5,3.5 0 0,1 12,15.5M19.43,12.97C19.47,12.65 19.5,12.33 19.5,12C19.5,11.67 19.47,11.34 19.43,11L21.54,9.37C21.73,9.22 21.78,8.95 21.66,8.73L19.66,5.27C19.54,5.05 19.27,4.96 19.05,5.05L16.56,6.05C16.04,5.66 15.5,5.32 14.87,5.07L14.5,2.42C14.46,2.18 14.25,2 14,2H10C9.75,2 9.54,2.18 9.5,2.42L9.13,5.07C8.5,5.32 7.96,5.66 7.44,6.05L4.95,5.05C4.73,4.96 4.46,5.05 4.34,5.27L2.34,8.73C2.21,8.95 2.27,9.22 2.46,9.37L4.57,11C4.53,11.34 4.5,11.67 4.5,12C4.5,12.33 4.53,12.65 4.57,12.97L2.46,14.63C2.27,14.78 2.21,15.05 2.34,15.27L4.34,18.73C4.46,18.95 4.73,19.03 4.95,18.95L7.44,17.94C7.96,18.34 8.5,18.68 9.13,18.93L9.5,21.58C9.54,21.82 9.75,22 10,22H14C14.25,22 14.46,21.82 14.5,21.58L14.87,18.93C15.5,18.67 16.04,18.34 16.56,17.94L19.05,18.95C19.27,19.03 19.54,18.95 19.66,18.73L21.66,15.27C21.78,15.05 21.73,14.78 21.54,14.63L19.43,12.97Z" /></svg>
|
Po Szerokość: | Wysokość: | Rozmiar: 986 B |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12,8A4,4 0 0,1 16,12A4,4 0 0,1 12,16A4,4 0 0,1 8,12A4,4 0 0,1 12,8M3.05,13H1V11H3.05C3.5,6.83 6.83,3.5 11,3.05V1H13V3.05C17.17,3.5 20.5,6.83 20.95,11H23V13H20.95C20.5,17.17 17.17,20.5 13,20.95V23H11V20.95C6.83,20.5 3.5,17.17 3.05,13M12,5A7,7 0 0,0 5,12A7,7 0 0,0 12,19A7,7 0 0,0 19,12A7,7 0 0,0 12,5Z" /></svg>
|
Po Szerokość: | Wysokość: | Rozmiar: 380 B |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3.05,13H1V11H3.05C3.5,6.83 6.83,3.5 11,3.05V1H13V3.05C17.17,3.5 20.5,6.83 20.95,11H23V13H20.95C20.5,17.17 17.17,20.5 13,20.95V23H11V20.95C6.83,20.5 3.5,17.17 3.05,13M12,5A7,7 0 0,0 5,12A7,7 0 0,0 12,19A7,7 0 0,0 19,12A7,7 0 0,0 12,5Z" /></svg>
|
Po Szerokość: | Wysokość: | Rozmiar: 313 B |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12,17A2,2 0 0,0 14,15C14,13.89 13.1,13 12,13A2,2 0 0,0 10,15A2,2 0 0,0 12,17M18,8A2,2 0 0,1 20,10V20A2,2 0 0,1 18,22H6A2,2 0 0,1 4,20V10C4,8.89 4.9,8 6,8H7V6A5,5 0 0,1 12,1A5,5 0 0,1 17,6V8H18M12,3A3,3 0 0,0 9,6V8H15V6A3,3 0 0,0 12,3Z" /></svg>
|
Po Szerokość: | Wysokość: | Rozmiar: 314 B |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12,3C7.79,3 3.7,4.41 0.38,7C4.41,12.06 7.89,16.37 12,21.5C16.08,16.42 20.24,11.24 23.65,7C20.32,4.41 16.22,3 12,3M12,5C15.07,5 18.09,5.86 20.71,7.45L15.61,13.81C14.5,13.28 13.25,13 12,13C10.75,13 9.5,13.28 8.39,13.8L3.27,7.44C5.91,5.85 8.93,5 12,5Z" /></svg>
|
Po Szerokość: | Wysokość: | Rozmiar: 328 B |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12,3C7.79,3 3.7,4.41 0.38,7C4.41,12.06 7.89,16.37 12,21.5C16.08,16.42 20.24,11.24 23.65,7C20.32,4.41 16.22,3 12,3M12,5C15.07,5 18.09,5.86 20.71,7.45L17.5,11.43C16.26,10.74 14.37,10 12,10C9.62,10 7.74,10.75 6.5,11.43L3.27,7.44C5.91,5.85 8.93,5 12,5Z" /></svg>
|
Po Szerokość: | Wysokość: | Rozmiar: 328 B |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12,3C7.79,3 3.7,4.41 0.38,7C4.41,12.06 7.89,16.37 12,21.5C16.08,16.42 20.24,11.24 23.65,7C20.32,4.41 16.22,3 12,3M12,5C15.07,5 18.09,5.86 20.71,7.45L18.77,9.88C17.26,9 14.88,8 12,8C9,8 6.68,9 5.21,9.84L3.27,7.44C5.91,5.85 8.93,5 12,5Z" /></svg>
|
Po Szerokość: | Wysokość: | Rozmiar: 314 B |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12,3C7.79,3 3.7,4.41 0.38,7C4.41,12.06 7.89,16.37 12,21.5C16.08,16.42 20.24,11.24 23.65,7C20.32,4.41 16.22,3 12,3Z" /></svg>
|
Po Szerokość: | Wysokość: | Rozmiar: 194 B |
|
@ -0,0 +1,13 @@
|
|||
// This is a generated file, please do not edit it! Use generate_symbols.py
|
||||
typedef enum {
|
||||
SYMBOL_SPACE = 32,
|
||||
SYMBOL_ALPHA_M_BOX_OUTLINE = 33,
|
||||
SYMBOL_COG = 34,
|
||||
SYMBOL_CROSSHAIRS_GPS = 35,
|
||||
SYMBOL_CROSSHAIRS = 36,
|
||||
SYMBOL_LOCK = 37,
|
||||
SYMBOL_WIFI_STRENGTH_1 = 38,
|
||||
SYMBOL_WIFI_STRENGTH_2 = 39,
|
||||
SYMBOL_WIFI_STRENGTH_3 = 40,
|
||||
SYMBOL_WIFI_STRENGTH_4 = 41,
|
||||
} symbol_t;
|
|
@ -164,6 +164,7 @@ typedef struct layout_t
|
|||
point_t line3_pos;
|
||||
point_t bottom_pos;
|
||||
fontSize_t top_font;
|
||||
symbolSize_t top_symbol_size;
|
||||
fontSize_t line1_font;
|
||||
fontSize_t line2_font;
|
||||
fontSize_t line3_font;
|
||||
|
|
|
@ -170,6 +170,7 @@ typedef struct layout_t
|
|||
point_t line5_pos;
|
||||
point_t bottom_pos;
|
||||
fontSize_t top_font;
|
||||
fontSize_t top_symbol_font;
|
||||
fontSize_t line1_font;
|
||||
fontSize_t line2_font;
|
||||
fontSize_t line3_font;
|
||||
|
|
|
@ -51,6 +51,10 @@
|
|||
#include <UbuntuRegular18pt7b.h>
|
||||
#include <UbuntuRegular24pt7b.h>
|
||||
|
||||
#include <Symbols5pt7b.h>
|
||||
#include <Symbols6pt7b.h>
|
||||
#include <Symbols8pt7b.h>
|
||||
|
||||
// Variable swap macro
|
||||
#define DEG_RAD 0.017453292519943295769236907684886
|
||||
#define SIN(x) sinf((x) * DEG_RAD)
|
||||
|
@ -68,7 +72,7 @@ static const GFXfont fonts[] = { TomThumb, // 5pt
|
|||
FreeSans12pt7b, // 12pt
|
||||
FreeSans16pt7b, // 16pt
|
||||
FreeSans18pt7b, // 16pt
|
||||
FreeSans24pt7b // 24pt
|
||||
FreeSans24pt7b, // 24pt
|
||||
#elif defined FONT_UBUNTU_REGULAR
|
||||
UbuntuRegular6pt7b, // 6pt
|
||||
UbuntuRegular8pt7b, // 8pt
|
||||
|
@ -77,10 +81,13 @@ static const GFXfont fonts[] = { TomThumb, // 5pt
|
|||
UbuntuRegular12pt7b, // 12pt
|
||||
UbuntuRegular16pt7b, // 16pt
|
||||
UbuntuRegular18pt7b, // 16pt
|
||||
UbuntuRegular24pt7b // 24pt
|
||||
UbuntuRegular24pt7b, // 24pt
|
||||
#else
|
||||
#error Unsupported font family!
|
||||
#endif
|
||||
Symbols5pt7b, // 5pt
|
||||
Symbols6pt7b, // 6pt
|
||||
Symbols8pt7b // 8pt
|
||||
};
|
||||
|
||||
#ifdef PIX_FMT_RGB565
|
||||
|
@ -616,6 +623,24 @@ void gfx_printError(const char *text, fontSize_t size)
|
|||
gfx_drawRect(box_start, text_size.x, text_size.y, red, false);
|
||||
}
|
||||
|
||||
point_t gfx_drawSymbol(point_t start, symbolSize_t size, textAlign_t alignment,
|
||||
color_t color, symbol_t symbol)
|
||||
{
|
||||
/*
|
||||
* Symbol tables come immediately after fonts in the general font table.
|
||||
* But, to prevent errors where symbol size is used instead of font size and
|
||||
* vice-versa, their enums are separate. The trickery below is used to put
|
||||
* together again the two enums in a single consecutive index.
|
||||
*
|
||||
* TODO: improve this.
|
||||
*/
|
||||
int symSize = size + FONT_SIZE_24PT + 1;
|
||||
char buffer[2] = {0};
|
||||
|
||||
buffer[0] = (char) symbol;
|
||||
return gfx_printBuffer(start, symSize, alignment, color, buffer);
|
||||
}
|
||||
|
||||
/*
|
||||
* Function to draw battery of arbitrary size
|
||||
* starting coordinates are relative to the top left point.
|
||||
|
|
|
@ -295,7 +295,8 @@ static layout_t _ui_calculateLayout()
|
|||
const uint16_t horizontal_pad = 4;
|
||||
|
||||
// Top bar font: 8 pt
|
||||
const fontSize_t top_font = FONT_SIZE_8PT;
|
||||
const fontSize_t top_font = FONT_SIZE_8PT;
|
||||
const symbolSize_t top_symbol_size = SYMBOLS_SIZE_8PT;
|
||||
// Text line font: 8 pt
|
||||
const fontSize_t line1_font = FONT_SIZE_8PT;
|
||||
const fontSize_t line2_font = FONT_SIZE_8PT;
|
||||
|
@ -330,7 +331,8 @@ static layout_t _ui_calculateLayout()
|
|||
const uint16_t horizontal_pad = 4;
|
||||
|
||||
// Top bar font: 6 pt
|
||||
const fontSize_t top_font = FONT_SIZE_6PT;
|
||||
const fontSize_t top_font = FONT_SIZE_6PT;
|
||||
const symbolSize_t top_symbol_size = SYMBOLS_SIZE_6PT;
|
||||
// Middle line fonts: 5, 8, 8 pt
|
||||
const fontSize_t line1_font = FONT_SIZE_6PT;
|
||||
const fontSize_t line2_font = FONT_SIZE_6PT;
|
||||
|
@ -363,8 +365,9 @@ static layout_t _ui_calculateLayout()
|
|||
const uint16_t big_line_v_pad = 0;
|
||||
const uint16_t horizontal_pad = 4;
|
||||
|
||||
// Top bar font: 8 pt
|
||||
const fontSize_t top_font = FONT_SIZE_6PT;
|
||||
// Top bar font: 6 pt
|
||||
const fontSize_t top_font = FONT_SIZE_6PT;
|
||||
const symbolSize_t top_symbol_size = SYMBOLS_SIZE_6PT;
|
||||
// Middle line fonts: 16, 16
|
||||
const fontSize_t line2_font = FONT_SIZE_6PT;
|
||||
const fontSize_t line3_font = FONT_SIZE_12PT;
|
||||
|
@ -410,6 +413,7 @@ static layout_t _ui_calculateLayout()
|
|||
line3_pos,
|
||||
bottom_pos,
|
||||
top_font,
|
||||
top_symbol_size,
|
||||
line1_font,
|
||||
line2_font,
|
||||
line3_font,
|
||||
|
|
|
@ -872,16 +872,34 @@ void _ui_drawSettingsReset2Defaults(ui_state_t* ui_state)
|
|||
drawcnt++;
|
||||
}
|
||||
|
||||
void _ui_drawMacroTop()
|
||||
{
|
||||
gfx_print(layout.top_pos, layout.top_font, TEXT_ALIGN_CENTER,
|
||||
color_white, currentLanguage->macroMenu);
|
||||
if (macro_latched)
|
||||
{
|
||||
gfx_drawSymbol(layout.top_pos, layout.top_symbol_size, TEXT_ALIGN_LEFT,
|
||||
color_white, SYMBOL_ALPHA_M_BOX_OUTLINE);
|
||||
}
|
||||
if(last_state.settings.gps_enabled)
|
||||
{
|
||||
if(last_state.gps_data.fix_quality > 0)
|
||||
{
|
||||
gfx_drawSymbol(layout.top_pos, layout.top_symbol_size, TEXT_ALIGN_RIGHT,
|
||||
color_white, SYMBOL_CROSSHAIRS_GPS);
|
||||
}
|
||||
else
|
||||
{
|
||||
gfx_drawSymbol(layout.top_pos, layout.top_symbol_size, TEXT_ALIGN_RIGHT,
|
||||
color_white, SYMBOL_CROSSHAIRS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool _ui_drawMacroMenu()
|
||||
{
|
||||
// Header
|
||||
gfx_print(layout.top_pos, layout.top_font, TEXT_ALIGN_CENTER,
|
||||
color_white, currentLanguage->macroMenu);
|
||||
if (macro_latched)
|
||||
{
|
||||
gfx_print(layout.top_pos, layout.top_font, TEXT_ALIGN_LEFT,
|
||||
color_white, "L");
|
||||
}
|
||||
_ui_drawMacroTop();
|
||||
// First row
|
||||
if (last_state.channel.mode == OPMODE_FM)
|
||||
{
|
||||
|
|
|
@ -224,7 +224,8 @@ layout_t _ui_calculateLayout()
|
|||
const uint16_t horizontal_pad = 4;
|
||||
|
||||
// Top bar font: 6 pt
|
||||
const fontSize_t top_font = FONT_SIZE_6PT;
|
||||
const fontSize_t top_font = FONT_SIZE_6PT;
|
||||
const symbolSize_t top_symbol_size = SYMBOLS_SIZE_6PT;
|
||||
// Middle line fonts: 5, 8, 8 pt
|
||||
const fontSize_t line1_font = FONT_SIZE_6PT;
|
||||
const fontSize_t line2_font = FONT_SIZE_6PT;
|
||||
|
@ -274,6 +275,7 @@ layout_t _ui_calculateLayout()
|
|||
line5_pos,
|
||||
bottom_pos,
|
||||
top_font,
|
||||
top_symbol_size,
|
||||
line1_font,
|
||||
line2_font,
|
||||
line3_font,
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
pyusb
|
||||
meson
|
||||
ffmpeg
|
||||
cairosvg==2.7.1
|
||||
numpy==1.25.2
|
|
@ -0,0 +1,164 @@
|
|||
#!/usr/bin/env python3
|
||||
# /***************************************************************************
|
||||
# * Copyright (C) 2023 by Ryan Turner K0RET *
|
||||
# * *
|
||||
# * This program is free software; you can redistribute it and/or modify *
|
||||
# * it under the terms of the GNU General Public License as published by *
|
||||
# * the Free Software Foundation; either version 3 of the License, or *
|
||||
# * (at your option) any later version. *
|
||||
# * *
|
||||
# * This program is distributed in the hope that it will be useful, *
|
||||
# * but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
# * GNU General Public License for more details. *
|
||||
# * *
|
||||
# * You should have received a copy of the GNU General Public License *
|
||||
# * along with this program; if not, see <http://www.gnu.org/licenses/> *
|
||||
# ***************************************************************************/
|
||||
#
|
||||
# Usage:
|
||||
#
|
||||
# 1. Find your source svg; https://pictogrammers.com/library/mdi/ is a good resource
|
||||
# 2. Add your source svg to openrtx/include/fonts/symbols/sources
|
||||
# 3. Execute this script; the corresponding `.h` files in the openrtx/include/fonts/symbols directory will regenerate
|
||||
# 4. Refer to the `symbols/symbols.h` file to find the enum that corresponds with your new symbol
|
||||
# 5. Utilize the `gfx_printSymbol()` method with your enum to access your symbol
|
||||
|
||||
import cairosvg
|
||||
import io
|
||||
from PIL import Image
|
||||
import numpy
|
||||
import os
|
||||
|
||||
absolute_path = os.path.dirname(__file__)
|
||||
|
||||
symbol_source_dir = "../openrtx/include/fonts/symbols/sources/"
|
||||
|
||||
debug = False
|
||||
sizes = [5, 6, 8]
|
||||
symbols = sorted([f for f in os.listdir(os.path.join(absolute_path, symbol_source_dir)) if "svg" in f])
|
||||
print(symbols)
|
||||
###################################################################
|
||||
|
||||
|
||||
def svgToBytes(filename, height):
|
||||
# Make memory buffer
|
||||
mem = io.BytesIO()
|
||||
# Convert SVG to PNG in memory
|
||||
cairosvg.svg2png(
|
||||
url=filename, write_to=mem, parent_height=height, parent_width=height
|
||||
)
|
||||
# Convert PNG to Numpy array
|
||||
img = Image.open(mem)
|
||||
# Split the channels, get just the alpha since that's what we need
|
||||
red, green, blue, alpha = img.split()
|
||||
# Convert the alpha to 1 and 0 (black and white)
|
||||
alpha = alpha.point(lambda x: 0 if x < 128 else 255, "1")
|
||||
if debug:
|
||||
alpha.show()
|
||||
return numpy.array(alpha)
|
||||
|
||||
|
||||
first_ascii = 32 # Start at ascii d32 which is " " per https://www.rapidtables.com/code/text/ascii-table.html
|
||||
dont_edit_banner = "// This is a generated file, please do not edit it! Use generate_symbols.py\n"
|
||||
|
||||
class FontDefinition:
|
||||
scalar = 1.6 # this number is used to roughly convert from pt to px
|
||||
yadvance_scalar = (
|
||||
7 / 3
|
||||
) # this number is applied to the width to scale up the yadvance; this is naively linear
|
||||
|
||||
def __init__(self, name, size):
|
||||
# Prepopulate with a space character
|
||||
self.bitmaps = [[0x00]]
|
||||
self.glyphNames = ["space"]
|
||||
self.initial_offset = 1
|
||||
|
||||
self.size = size
|
||||
self.name = name
|
||||
self.height = round(size * self.scalar)
|
||||
self.width = round(size * self.scalar)
|
||||
self.yadvance = round(size * self.scalar * self.yadvance_scalar)
|
||||
self.xadvance = round(size * self.scalar * 2 / 3)
|
||||
self.dY = round(-1 * self.height / 1.2)
|
||||
|
||||
def addGlyph(self, filename, glyphName):
|
||||
res = svgToBytes(filename, self.height)
|
||||
packed = numpy.packbits(res)
|
||||
charBytes = packed.tobytes()
|
||||
|
||||
self.bitmaps.append(charBytes)
|
||||
|
||||
self.glyphNames.append(glyphName)
|
||||
|
||||
def __str__(self):
|
||||
out = dont_edit_banner
|
||||
out += "static const uint8_t {}{}pt7bBitmaps[] PROGMEM = {{\n".format(
|
||||
self.name, self.size
|
||||
)
|
||||
for i, bitmap in enumerate(self.bitmaps):
|
||||
out += (
|
||||
(", ".join("0x{:02x}".format(x) for x in bitmap))
|
||||
+ ", //"
|
||||
+ self.glyphNames[i]
|
||||
+ "\n"
|
||||
)
|
||||
out += "};\n"
|
||||
out += "\n"
|
||||
out += (
|
||||
"static const GFXglyph {}{}pt7bGlyphs[] PROGMEM = {{".format(
|
||||
self.name, self.size
|
||||
)
|
||||
+ "\n"
|
||||
)
|
||||
out += " //Index, W, H,xAdv,dX, dY\n"
|
||||
offset = 0
|
||||
for glyphNumber, glyphName in enumerate(self.glyphNames):
|
||||
out += '{{ {}, {}, {}, {}, 0, {}}}, // "{}" {}\n'.format(
|
||||
offset,
|
||||
self.width if glyphNumber > 0 else 1,
|
||||
self.height if glyphNumber > 0 else 1,
|
||||
self.xadvance,
|
||||
self.dY,
|
||||
chr(first_ascii + glyphNumber),
|
||||
glyphName,
|
||||
)
|
||||
offset += len(self.bitmaps[glyphNumber])
|
||||
out += "};\n"
|
||||
out += (
|
||||
"static const GFXfont {}{}pt7b PROGMEM = {{".format(self.name, self.size)
|
||||
+ "\n"
|
||||
)
|
||||
out += "(uint8_t *){}{}pt7bBitmaps,".format(self.name, self.size) + "\n"
|
||||
out += "(GFXglyph *){}{}pt7bGlyphs,".format(self.name, self.size) + "\n"
|
||||
out += "//ASCII start, ASCII stop,y Advance \n"
|
||||
out += (
|
||||
" {}, {}, {} }};".format(
|
||||
first_ascii,
|
||||
first_ascii + len(self.glyphNames) - 1,
|
||||
round(self.yadvance),
|
||||
)
|
||||
+ "\n"
|
||||
)
|
||||
return out
|
||||
|
||||
|
||||
###################################################################
|
||||
|
||||
# Generate the font definitions
|
||||
for size in sizes:
|
||||
font = FontDefinition("Symbols", size)
|
||||
for symbol in symbols:
|
||||
font.addGlyph(os.path.join(absolute_path, symbol_source_dir + symbol), symbol)
|
||||
with open(os.path.join(absolute_path, "../openrtx/include/fonts/symbols/Symbols{}pt7b.h".format(size)), "w") as f:
|
||||
f.write(str(font))
|
||||
|
||||
# Generate the enum for convenience
|
||||
with open(os.path.join(absolute_path, "../openrtx/include/fonts/symbols/symbols.h".format(size)), "w") as f:
|
||||
out = dont_edit_banner
|
||||
out += "typedef enum {\n"
|
||||
symbols.insert(0, "SPACE")
|
||||
for symbolNumber, symbolName in enumerate(symbols):
|
||||
out += " SYMBOL_{} = {},\n".format(symbolName.split(".")[0].replace("-", "_").upper(), symbolNumber + first_ascii)
|
||||
out += "} symbol_t;\n"
|
||||
f.write(out)
|