├── .gitattributes
├── .github
└── workflows
│ └── tg-send.yml
├── LICENSE
├── README.md
├── README_EN.md
├── keywords.txt
├── library.properties
└── src
├── GyverGFX.h
├── RunningGFX.h
└── fonts
├── font5x8.h
├── fontEditor.html
└── icons8x8.h
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
--------------------------------------------------------------------------------
/.github/workflows/tg-send.yml:
--------------------------------------------------------------------------------
1 |
2 | name: Telegram Message
3 | on:
4 | release:
5 | types: [published]
6 | jobs:
7 | build:
8 | name: Send Message
9 | runs-on: ubuntu-latest
10 | steps:
11 | - name: send telegram message on push
12 | uses: appleboy/telegram-action@master
13 | with:
14 | to: ${{ secrets.TELEGRAM_TO }}
15 | token: ${{ secrets.TELEGRAM_TOKEN }}
16 | disable_web_page_preview: true
17 | message: |
18 | ${{ github.event.repository.name }} v${{ github.event.release.tag_name }}
19 | ${{ github.event.release.body }}
20 | https://github.com/${{ github.repository }}
21 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 AlexGyver
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://github.com/GyverLibs/GyverGFX/releases/latest/download/GyverGFX.zip)
2 | [](https://registry.platformio.org/libraries/gyverlibs/GyverGFX)
3 | [](https://alexgyver.ru/)
4 | [](https://alexgyver.ru/support_alex/)
5 | [](https://github-com.translate.goog/GyverLibs/GyverGFX?_x_tr_sl=ru&_x_tr_tl=en)
6 |
7 | [](https://t.me/GyverLibs)
8 |
9 | # GyverGFX
10 | Движок двухмерной графики для дисплеев и матриц
11 | - Точка
12 | - Линии
13 | - Прямоугольники
14 | - Окружность
15 | - Кривая Безье
16 | - Битмап
17 | - Вывод текста (русский, английский) нескольких размеров
18 | - Вшиты 155 иконок
19 | - Бегущая строка
20 |
21 | ### Совместимость
22 | Совместима со всеми Arduino платформами (используются Arduino-функции)
23 |
24 | ## Содержание
25 | - [Установка](#install)
26 | - [Использование](#usage)
27 | - [Пример](#example)
28 | - [Версии](#versions)
29 | - [Баги и обратная связь](#feedback)
30 |
31 |
32 | ## Установка
33 | - Библиотеку можно найти по названию **GyverGFX** и установить через менеджер библиотек в:
34 | - Arduino IDE
35 | - Arduino IDE v2
36 | - PlatformIO
37 | - [Скачать библиотеку](https://github.com/GyverLibs/GyverGFX/archive/refs/heads/main.zip) .zip архивом для ручной установки:
38 | - Распаковать и положить в *C:\Program Files (x86)\Arduino\libraries* (Windows x64)
39 | - Распаковать и положить в *C:\Program Files\Arduino\libraries* (Windows x32)
40 | - Распаковать и положить в *Документы/Arduino/libraries/*
41 | - (Arduino IDE) автоматическая установка из .zip: *Скетч/Подключить библиотеку/Добавить .ZIP библиотеку…* и указать скачанный архив
42 | - Читай более подробную инструкцию по установке библиотек [здесь](https://alexgyver.ru/arduino-first/#%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D0%B1%D0%B8%D0%B1%D0%BB%D0%B8%D0%BE%D1%82%D0%B5%D0%BA)
43 | ### Обновление
44 | - Рекомендую всегда обновлять библиотеку: в новых версиях исправляются ошибки и баги, а также проводится оптимизация и добавляются новые фичи
45 | - Через менеджер библиотек IDE: найти библиотеку как при установке и нажать "Обновить"
46 | - Вручную: **удалить папку со старой версией**, а затем положить на её место новую. "Замену" делать нельзя: иногда в новых версиях удаляются файлы, которые останутся при замене и могут привести к ошибкам!
47 |
48 |
49 | ## Использование
50 | ### GyverGFX
51 |
52 | ```cpp
53 | // конструктор
54 | GyverGFX();
55 | GyverGFX(int x, int y); // с указанием размеров "экрана"
56 |
57 | // методы
58 | void size(int x, int y); // установить размер
59 | int width(); // получить ширину
60 | int height(); // получить высоту
61 |
62 | // ============ PRIMITIVE ============
63 | // fill:
64 | // GFX_CLEAR - очистить фигуру
65 | // GFX_FILL - залить фигуру
66 | // GFX_STROKE - обвести фигуру
67 | virtual void dot(int x, int y, uint8_t fill = 1); // точка
68 | void fill(uint8_t fill = 1); // залить экран
69 | void clear(); // очистить экран
70 | void lineH(int y, int x0, int x1, uint8_t fill = 1); // горизонтальная линия
71 | void lineV(int x, int y0, int y1, uint8_t fill = 1); // вертикальная линия
72 | void line(int x0, int y0, int x1, int y1, uint8_t fill = 1); // линия
73 | void rect(int x0, int y0, int x1, int y1, uint8_t fill = 1); // прямоугольник (координаты углов)
74 | void rectWH(int x0, int y0, int w, int h, uint8_t fill = 1); // прямоугольник (координаты угла и размер)
75 | void roundRect(int x0, int y0, int x1, int y1, uint8_t fill = 1); // скруглённый прямоугольник (координаты углов)
76 | void roundRectWH(int x0, int y0, int w, int h, uint8_t fill = 1); // скруглённый прямоугольник (координаты угла и размер)
77 | void circle(int x, int y, int radius, uint8_t fill = 1); // окружность
78 | void bezier(uint8_t *arr, uint8_t size, uint8_t dense, uint8_t fill = 1); // кривая Безье
79 | void bezier16(int16_t *arr, uint8_t size, uint8_t dense, uint8_t fill = 1); // кривая Безье 16 бит
80 |
81 | // ============ TEXT ============
82 | // наследует Print.h
83 | print(любой тип);
84 | println(любой тип);
85 |
86 | // вывести столбик-байт в текущий курсор с учётом масштаба и режима текста, автоматически перенесёт курсор
87 | void drawByte(uint8_t bits);
88 | void drawBytes(uint8_t *bytes, int amount); // из массива
89 | void drawBytes_P(const uint8_t *bytes, int amount); // из PROGMEM массива
90 |
91 | // mode:
92 | // GFX_ADD - добавить к буферу
93 | // GFX_REPLACE - заменить информацию в буфере
94 | void drawBitmap(int x, int y, const uint8_t *frame, int width, int height, uint8_t invert = 0, byte mode = 0); // битмап (mode: GFX_ADD/GFX_REPLACE)
95 | void textDisplayMode(bool mode); // установить режим вывода текста
96 | bool getTextDisplayMode(); // получить режим вывода текста
97 |
98 | void setCursor(int x, int y); // установить курсор
99 | int getCursorX(); // получить курсор x
100 | int getCursorY(); // получить курсор y
101 |
102 | void setScale(uint8_t scale); // установить масштаб текста (1-4)
103 | uint8_t getScale(); // получить масштаб текста
104 |
105 | void invertText(bool inv); // установить инверсию текста
106 | bool getInvertText(); // получить инверсию текста
107 |
108 | void autoPrintln(bool mode); // установить автоматический перенос текста
109 | bool getAutoPrintln(); // получить автоматический перенос текста
110 |
111 | void setTextBound(int x0, int x1); // установить границы вывода текста по х
112 | void resetTextBound(); // сбросить границы вывода текста до (0, ширина)
113 | int getTextBoundX0(); // получить границу вывода 0
114 | int getTextBoundX1(); // получить границу вывода 1
115 |
116 | uint16_t strlen_fix(const char *str); // определить длину строки с любыми символами (в т.ч. русскими)
117 | uint16_t strlen_fix_P(PGM_P str); // определить длину PGM строки с любыми символами (в т.ч. русскими)
118 |
119 | // ============ DEFINE ============
120 | // дефайны настроек
121 | // (перед подключением библиотеки)
122 | #define GFX_NO_PRINT // отключить модуль вывода текста (экономия памяти)
123 | ```
124 |
125 | #### Встроенные иконки
126 | В библиотеке идёт набор из 155 иконок 8х8, файл *fonts/icons8x8.h*. Выводятся следующим образом:
127 | ```cpp
128 | obj.drawBytes_P(GFX_icons::alarm, 8);
129 | obj.drawBytes_P(GFX_icons::email, 8);
130 | ```
131 |
132 | ### RunningGFX
133 | Асинхронная бегущая строка. Не хранит строку внутри себя, поэтому по очевидным причинам поддерживает работу с:
134 | - Глобально созданными `String` - строками
135 | - Глобально созданными `PROGMEM` - строками
136 | - Глобально созданными `char[]` - строками
137 | - Строковыми константами (они изначально являются глобальными)
138 |
139 | Особенности:
140 | - Для автоматического обновления строки в классе должен быть реализован метод `update()`
141 | - Строку можно изменять во время движения: `setText()` не запускает движение заново, поэтому при обновлении String-строки можно вызвать setText для автоматического пересчёта длины
142 | - Настройки бегущей строки (масштаб, режим текста) не влияют на дисплей, точнее автоматически устанавливаются обратно
143 | - Один объект управляет одной строкой. если нужно несколько одновременно бегущих строк - создай несколько обьектов, пример ниже
144 |
145 | ```cpp
146 | // конструктор
147 | RunningGFX(GyverGFX* gfx);
148 |
149 | // методы
150 | void setText(const char* str); // установить текст const char*
151 | void setText(String& str); // установить текст String
152 | void setText_P(PGM_P str); // установить текст из PROGMEM (глобальный)
153 |
154 | void invertText(bool inv); // инвертировать текст
155 | void setScale(uint8_t scale); // масштаб текста
156 | void textDisplayMode(bool mode); // режим вывода текста GFX_ADD/GFX_REPLACE
157 | void setWindow(int16_t x0, int16_t x1, int16_t y); // установить окно (x0, x1, y)
158 | void setSpeed(uint16_t pixPerSec); // установить скорость (пикселей в секунду)
159 |
160 | void start(); // запустить бегущую строку с начала
161 | void stop(); // остановить бегущую строку
162 | void resume(); // продолжить движение с момента остановки
163 |
164 | // тикер. Вернёт 0 в холостом, 1 при новом шаге, 2 при завершении движения
165 | // Можно передать false чтобы дисплей не обновлялся сам
166 | uint8_t tick(bool update = true);
167 |
168 | // сдвинуть строку на 1 пиксель. Можно передать false чтобы дисплей не обновлялся сам
169 | uint8_t tickManual(bool update = true);
170 | ```
171 |
172 |
173 | ## Пример
174 |
175 | ```cpp
176 | // пример наследования в класс. Нужно реализовать методы dot и update
177 | class MAX7219 : public GyverGFX {
178 | public:
179 | MAX7219(int width, int height) : GyverGFX(width * 8, height * 8) {}
180 | void dot(int x, int y, uint8_t fill = GFX_FILL) {
181 | // ...
182 | }
183 | void update() {
184 | // ...
185 | }
186 | };
187 | ```
188 |
189 | ```cpp
190 | // пример RunningGFX
191 | // RunningGFX работает с классом, который наследует GyverGFX. Например библиотека GyverMAX7219
192 |
193 | MAX7219<4, 1, 5> mtrx; // одна матрица (1х1), пин CS на D5
194 | RunningGFX run1(&mtrx);
195 | RunningGFX run2(&mtrx);
196 | const char pstr_g[] PROGMEM = "Global pgm string";
197 | String str_g = "123";
198 |
199 | void setup() {
200 | mtrx.begin(); // запускаем
201 | mtrx.setBright(5); // яркость 0..15
202 |
203 | run1.setText("hello"); // строковая константа
204 | // run1.setText(str_g); // глобальная стринга
205 | run1.setSpeed(15);
206 | run1.setWindow(0, 16, 0);
207 | run1.start();
208 |
209 | run2.setText_P(pstr_g); // глобальная PGM строка
210 | run2.setSpeed(10);
211 | run2.setWindow(8, 16, 0);
212 | run2.start();
213 | }
214 |
215 | void loop() {
216 | run1.tick();
217 | run2.tick();
218 | }
219 | ```
220 |
221 |
222 | ## Версии
223 | - v1.0
224 | - v1.1 - оптимизация памяти
225 | - v1.2 - небольшая оптимизация
226 | - v1.3 - добавил фичи
227 | - v1.4 - мелкие фиксы
228 | - v1.5 - добавлено отключение модуля вывода текста GFX_NO_PRINT
229 | - v1.5.1 - мелкие фиксы
230 | - v1.6 - мелкие улучшения, добавлен движок бегущей строки
231 | - v1.7
232 | - Улучшена бегущая строка
233 | - Добавлены настройки
234 | - Добавлены новые инструменты вывода графики (drawByte, drawBytes, drawBytes_p)
235 | - Добавлены иконки
236 | - Улучшен шрифт
237 |
238 |
239 | ## Баги и обратная связь
240 | При нахождении багов создавайте **Issue**, а лучше сразу пишите на почту [alex@alexgyver.ru](mailto:alex@alexgyver.ru)
241 | Библиотека открыта для доработки и ваших **Pull Request**'ов!
242 |
243 | При сообщении о багах или некорректной работе библиотеки нужно обязательно указывать:
244 | - Версия библиотеки
245 | - Какой используется МК
246 | - Версия SDK (для ESP)
247 | - Версия Arduino IDE
248 | - Корректно ли работают ли встроенные примеры, в которых используются функции и конструкции, приводящие к багу в вашем коде
249 | - Какой код загружался, какая работа от него ожидалась и как он работает в реальности
250 | - В идеале приложить минимальный код, в котором наблюдается баг. Не полотно из тысячи строк, а минимальный код
251 |
--------------------------------------------------------------------------------
/README_EN.md:
--------------------------------------------------------------------------------
1 | This is an automatic translation, may be incorrect in some places. See sources and examples!
2 |
3 | # GyverGFX
4 | Lightweight 2D Graphics Library for Displays and Matrices
5 | - Points
6 | - Lines
7 | - Rectangles
8 | - Rounded rectangles
9 | - Circles
10 | - Bezier curve
11 | - Bitmap
12 | - Text output (Russian, English) of several sizes
13 |
14 | ### Compatibility
15 | Compatible with all Arduino platforms (using Arduino functions)
16 |
17 | ## Content
18 | - [Install](#install)
19 | - [Initialization](#init)
20 | - [Usage](#usage)
21 | - [Example](#example)
22 | - [Versions](#versions)
23 | - [Bugs and feedback](#feedback)
24 |
25 |
26 | ## Installation
27 | - The library can be found by the name **GyverGFX** and installed through the library manager in:
28 | - Arduino IDE
29 | - Arduino IDE v2
30 | - PlatformIO
31 | - [Download library](https://github.com/GyverLibs/GyverGFX/archive/refs/heads/main.zip) .zip archive for manual installation:
32 | - Unzip and put in *C:\Program Files (x86)\Arduino\libraries* (Windows x64)
33 | - Unzip and put in *C:\Program Files\Arduino\libraries* (Windows x32)
34 | - Unpack and put in *Documents/Arduino/libraries/*
35 | - (Arduino IDE) automatic installation from .zip: *Sketch/Include library/Add .ZIP library…* and specify the downloaded archive
36 | - Read more detailed instructions for installing libraries [here] (https://alexgyver.ru/arduino-first/#%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE% D0%B2%D0%BA%D0%B0_%D0%B1%D0%B8%D0%B1%D0%BB%D0%B8%D0%BE%D1%82%D0%B5%D0%BA)
37 |
38 |
39 | ## Initialization
40 | ```cppGyverGFX(int x, int y); // indicating the size of the "screen"
41 | ```
42 |
43 |
44 | ## Usage
45 | ```cpp
46 | //fill:
47 | // GFX_CLEAR - clear
48 | // GFX_FILL - fill the shape
49 | // GFX_STROKE - stroke the shape
50 |
51 | virtual void dot(int x, int y, uint8_t fill = 1); // dot
52 | virtual void fastLineH(int y, int x0, int x1, uint8_t fill = 1); // vertical line
53 | virtual void fastLineV(int x, int y0, int y1, uint8_t fill = 1); // horizontal line
54 | virtual void line(int x0, int y0, int x1, int y1, uint8_t fill = 1); // line
55 | virtual void rect(int x0, int y0, int x1, int y1, uint8_t fill = 1); // rectangle
56 | virtual void roundRect(int x0, int y0, int x1, int y1, uint8_t fill = 1); // rounded rectangle
57 | virtual void circle(int x, int y, int radius, uint8_t fill = 1); // circle
58 | virtual void bezier(uint8_t* arr, uint8_t size, uint8_t dense, uint8_t fill = 1); // bezier curve
59 | virtual void bezier16(int* arr, uint8_t size, uint8_t dense, uint8_t fill = 1); // bezier curve 16 bit. fill - GFX_CLEAR/GFX_FILL/GFX_STROKE
60 | virtual void drawBitmap(int x, int y, const uint8_t *frame, int width, int height, uint8_t invert = 0, byte mode = 0); // bitmap
61 |
62 | void setCursor(int x, int y); // set cursor
63 | void setScale(uint8_tscale); // text scale
64 | void invertText(bool inv); // invert text
65 | void autoPrintln(bool mode); // automatic line break
66 | void textDisplayMode(bool mode); // text output mode GFX_ADD/GFX_REPLACE
67 | ```
68 |
69 |
70 | ## Example
71 | ```cpp
72 | // example of inheritance into a class
73 | class MAX7219 : public GyverGFX {
74 | public:
75 | MAX7219() : GyverGFX(width * 8, height * 8) {
76 | begin();
77 | }
78 | ```
79 |
80 |
81 | ## Versions
82 | - v1.0
83 | - v1.1 - memory optimization
84 |
85 |
86 | ## Bugs and feedback
87 | When you find bugs, create an **Issue**, or better, immediately write to the mail [alex@alexgyver.ru](mailto:alex@alexgyver.ru)
88 | BeeThe Library is open for revision and your **Pull Request**'s!
--------------------------------------------------------------------------------
/keywords.txt:
--------------------------------------------------------------------------------
1 |
2 | #######################################
3 | # Syntax Coloring Map For GyverGFX
4 | #######################################
5 |
6 | #######################################
7 | # Datatypes (KEYWORD1)
8 | #######################################
9 | GyverGFX KEYWORD1
10 | RunningGFX KEYWORD1
11 |
12 | GFX_NO_PRINT KEYWORD1
13 |
14 | #######################################
15 | # Methods and Functions (KEYWORD2)
16 | #######################################
17 | size KEYWORD2
18 | width KEYWORD2
19 | height KEYWORD2
20 | fill KEYWORD2
21 | clear KEYWORD2
22 | dot KEYWORD2
23 | lineH KEYWORD2
24 | lineV KEYWORD2
25 | fastLineH KEYWORD2
26 | fastLineV KEYWORD2
27 | line KEYWORD2
28 | rect KEYWORD2
29 | rectWH KEYWORD2
30 | roundRect KEYWORD2
31 | roundRectWH KEYWORD2
32 | circle KEYWORD2
33 | bezier KEYWORD2
34 | bezier16 KEYWORD2
35 | drawBitmap KEYWORD2
36 |
37 | drawByte KEYWORD2
38 | drawBytes KEYWORD2
39 | drawBitmap KEYWORD2
40 | textDisplayMode KEYWORD2
41 | getTextDisplayMode KEYWORD2
42 | setCursor KEYWORD2
43 | getCursorX KEYWORD2
44 | getCursorY KEYWORD2
45 | setScale KEYWORD2
46 | getScale KEYWORD2
47 | invertText KEYWORD2
48 | getInvertText KEYWORD2
49 | autoPrintln KEYWORD2
50 | getAutoPrintln KEYWORD2
51 | setTextBound KEYWORD2
52 | resetTextBound KEYWORD2
53 | getTextBoundX0 KEYWORD2
54 | getTextBoundX1 KEYWORD2
55 | strlen_fix KEYWORD2
56 | strlen_fix_P KEYWORD2
57 |
58 | setText KEYWORD2
59 | setText_P KEYWORD2
60 | invertText KEYWORD2
61 | setScale KEYWORD2
62 | textDisplayMode KEYWORD2
63 | setWindow KEYWORD2
64 | setSpeed KEYWORD2
65 | start KEYWORD2
66 | stop KEYWORD2
67 | resume KEYWORD2
68 | tick KEYWORD2
69 | tickManual KEYWORD2
70 |
71 | #######################################
72 | # Constants (LITERAL1)
73 | #######################################
74 | GFX_CLEAR LITERAL1
75 | GFX_FILL LITERAL1
76 | GFX_STROKE LITERAL1
77 | GFX_ADD LITERAL1
78 | GFX_REPLACE LITERAL1
--------------------------------------------------------------------------------
/library.properties:
--------------------------------------------------------------------------------
1 | name=GyverGFX
2 | version=1.7.3
3 | author=AlexGyver
4 | maintainer=AlexGyver
5 | sentence=Fast GFX library for displays and matrixes
6 | paragraph=Fast GFX library for displays and matrixes
7 | category=Other
8 | url=https://github.com/GyverLibs/GyverGFX
9 | architectures=*
10 |
--------------------------------------------------------------------------------
/src/GyverGFX.h:
--------------------------------------------------------------------------------
1 | /*
2 | Лёгкая библиотека двухмерной графики для дисплеев и матриц
3 | Документация:
4 | GitHub: https://github.com/GyverLibs/GyverGFX
5 | Возможности:
6 | - Точки
7 | - Линии
8 | - Прямоугольники
9 | - Скруглённые прямоугольники
10 | - Круги
11 | - Кривая Безье
12 | - Битмап
13 | - Вывод текста (русский, английский) нескольких размеров
14 |
15 | AlexGyver, alex@alexgyver.ru
16 | https://alexgyver.ru/
17 | MIT License
18 | */
19 |
20 | #ifndef _GyverGFX_h
21 | #define _GyverGFX_h
22 |
23 | #include
24 |
25 | #define GFX_CLEAR 0
26 | #define GFX_FILL 1
27 | #define GFX_STROKE 2
28 |
29 | #define GFX_REPLACE 0
30 | #define GFX_ADD 1
31 |
32 | #ifndef GFX_NO_PRINT
33 | #include
34 |
35 | #include "fonts/font5x8.h"
36 | #include "fonts/icons8x8.h"
37 | struct gfx_config_t {
38 | int16_t x = 0, y = 0;
39 | uint8_t scale = 1;
40 | bool invert = 0, println = 0, tmode = 0;
41 | int16_t tx0, tx1;
42 | };
43 | #endif
44 |
45 | #ifdef GFX_NO_PRINT
46 | class GyverGFX {
47 | #else
48 | class GyverGFX : public Print {
49 | #endif
50 | public:
51 | GyverGFX() {
52 | size(0, 0);
53 | }
54 | GyverGFX(uint16_t x, uint16_t y) {
55 | size(x, y);
56 | }
57 |
58 | // установить размер
59 | void size(uint16_t x, uint16_t y) {
60 | _w = x;
61 | _h = y;
62 | #ifndef GFX_NO_PRINT
63 | resetTextBound();
64 | #endif
65 | }
66 |
67 | // получить ширину
68 | uint16_t width() const {
69 | return _w;
70 | }
71 | // получить высоту
72 | uint16_t height() const {
73 | return _h;
74 | }
75 |
76 | // =================== INTERFACE ===================
77 | // точка
78 | virtual void dot(int x, int y, uint8_t fill = GFX_FILL) {
79 | }
80 |
81 | // залить экран
82 | virtual void fill(uint8_t fill = GFX_FILL) {
83 | for (uint16_t i = 0; i < _w; i++) {
84 | for (uint16_t j = 0; j < _h; j++) {
85 | dotSecure(i, j, fill);
86 | }
87 | }
88 | }
89 |
90 | // очистить экран
91 | virtual void clear() {
92 | fill(0);
93 | }
94 |
95 | // обновить (интерфейсная)
96 | virtual void update() {
97 | }
98 |
99 | // =================== GFX ===================
100 |
101 | // вертикальная линия
102 | void lineH(int y, int x0, int x1, uint8_t fill = GFX_FILL) {
103 | swap(x0, x1);
104 | for (int x = x0; x <= x1; x++) dotSecure(x, y, fill);
105 | }
106 |
107 | // вертикальная линия
108 | void lineV(int x, int y0, int y1, uint8_t fill = GFX_FILL) {
109 | swap(y0, y1);
110 | for (int y = y0; y <= y1; y++) dotSecure(x, y, fill);
111 | }
112 |
113 | // линия
114 | void line(int x0, int y0, int x1, int y1, uint8_t fill = GFX_FILL) {
115 | if (x0 == x1) lineV(x0, y0, y1, fill);
116 | else if (y0 == y1) lineH(y0, x0, x1, fill);
117 | else {
118 | int8_t sx = (x0 < x1) ? 1 : -1;
119 | int8_t sy = (y0 < y1) ? 1 : -1;
120 | int dx = abs(x1 - x0);
121 | int dy = abs(y1 - y0);
122 | int err = dx - dy;
123 | int e2 = 0;
124 | for (;;) {
125 | dotSecure(x0, y0, fill);
126 | if (x0 == x1 && y0 == y1) return;
127 | e2 = err << 1;
128 | if (e2 > -dy) {
129 | err -= dy;
130 | x0 += sx;
131 | }
132 | if (e2 < dx) {
133 | err += dx;
134 | y0 += sy;
135 | }
136 | }
137 | }
138 | }
139 |
140 | // прямоугольник (x0, y0, x1, y1, fill)
141 | void rect(int x0, int y0, int x1, int y1, uint8_t fill = GFX_FILL) {
142 | swap(y0, y1);
143 | swap(x0, x1);
144 | if (fill == GFX_STROKE) {
145 | lineH(y0, x0 + 1, x1 - 1);
146 | lineH(y1, x0 + 1, x1 - 1);
147 | lineV(x0, y0, y1);
148 | lineV(x1, y0, y1);
149 | } else {
150 | for (int y = y0; y <= y1; y++) lineH(y, x0, x1, fill);
151 | }
152 | }
153 |
154 | // прямоугольник (x0, y0, w, h, fill)
155 | void rectWH(int x0, int y0, int w, int h, uint8_t fill = GFX_FILL) {
156 | rect(x0, y0, x0 + w - 1, y0 + h - 1, fill);
157 | }
158 |
159 | // скруглённый прямоугольник (x0, y0, x1, y1, fill)
160 | void roundRect(int x0, int y0, int x1, int y1, uint8_t fill = GFX_FILL) {
161 | swap(y0, y1);
162 | swap(x0, x1);
163 | if (fill == GFX_STROKE) {
164 | lineV(x0, y0 + 2, y1 - 2);
165 | lineV(x1, y0 + 2, y1 - 2);
166 | lineH(y0, x0 + 2, x1 - 2);
167 | lineH(y1, x0 + 2, x1 - 2);
168 | dotSecure(x0 + 1, y0 + 1);
169 | dotSecure(x1 - 1, y0 + 1);
170 | dotSecure(x1 - 1, y1 - 1);
171 | dotSecure(x0 + 1, y1 - 1);
172 | } else {
173 | lineV(x0, y0 + 2, y1 - 2, fill);
174 | lineV(x0 + 1, y0 + 1, y1 - 1, fill);
175 | lineV(x1 - 1, y0 + 1, y1 - 1, fill);
176 | lineV(x1, y0 + 2, y1 - 2, fill);
177 | rect(x0 + 2, y0, x1 - 2, y1, fill);
178 | }
179 | }
180 |
181 | // скруглённый прямоугольник (x0, y0, x1, y1, fill)
182 | void roundRectWH(int x0, int y0, int w, int h, uint8_t fill = GFX_FILL) {
183 | roundRect(x0, y0, x0 + w - 1, y0 + h - 1, fill);
184 | }
185 |
186 | // окружность
187 | void circle(int x, int y, int radius, uint8_t fill = GFX_FILL) {
188 | int f = 1 - radius;
189 | int ddF_x = 1;
190 | int ddF_y = -2 * radius;
191 | int x1 = 0;
192 | int y1 = radius;
193 | uint8_t fillLine = (fill == GFX_CLEAR) ? 0 : 1;
194 | dotSecure(x, y + radius, fillLine);
195 | dotSecure(x, y - radius, fillLine);
196 | dotSecure(x + radius, y, fillLine);
197 | dotSecure(x - radius, y, fillLine);
198 | if (fill != GFX_STROKE) lineV(x, y - radius, y + radius - 1, fillLine);
199 | while (x1 < y1) {
200 | if (f >= 0) {
201 | y1--;
202 | ddF_y += 2;
203 | f += ddF_y;
204 | }
205 | x1++;
206 | ddF_x += 2;
207 | f += ddF_x;
208 | if (fill == GFX_STROKE) {
209 | dotSecure(x + x1, y + y1);
210 | dotSecure(x - x1, y + y1);
211 | dotSecure(x + x1, y - y1);
212 | dotSecure(x - x1, y - y1);
213 | dotSecure(x + y1, y + x1);
214 | dotSecure(x - y1, y + x1);
215 | dotSecure(x + y1, y - x1);
216 | dotSecure(x - y1, y - x1);
217 | } else {
218 | lineV(x + x1, y - y1, y + y1, fillLine);
219 | lineV(x - x1, y - y1, y + y1, fillLine);
220 | lineV(x + y1, y - x1, y + x1, fillLine);
221 | lineV(x - y1, y - x1, y + x1, fillLine);
222 | }
223 | }
224 | }
225 |
226 | // кривая Безье
227 | void bezier(uint8_t *arr, uint8_t size, uint8_t dense, uint8_t fill = GFX_FILL) {
228 | uint16_t a[size * 2];
229 | for (uint16_t i = 0; i < (uint16_t)(1 << dense); i++) {
230 | for (uint16_t j = 0; j < size * 2; j++) a[j] = arr[j] << 3;
231 | for (uint16_t j = (size - 1) * 2 - 1; j > 0; j -= 2) {
232 | for (uint16_t k = 0; k <= j; k++) {
233 | a[k] = a[k] + (((a[k + 2] - a[k]) * i) >> dense);
234 | }
235 | }
236 | dotSecure(a[0] >> 3, a[1] >> 3, fill);
237 | }
238 | }
239 |
240 | // кривая Безье 16 бит
241 | void bezier16(int16_t *arr, uint8_t size, uint8_t dense, uint8_t fill = GFX_FILL) {
242 | uint16_t a[size * 2];
243 | for (uint16_t i = 0; i < (uint16_t)(1 << dense); i++) {
244 | for (uint16_t j = 0; j < size * 2; j++) a[j] = arr[j];
245 | for (uint16_t j = (size - 1) * 2 - 1; j > 0; j -= 2) {
246 | for (uint16_t k = 0; k <= j; k++) {
247 | a[k] = a[k] + (((a[k + 2] - a[k]) * i) >> dense);
248 | }
249 | }
250 | dotSecure(a[0], a[1], fill);
251 | }
252 | }
253 |
254 | // битмап
255 | void drawBitmap(int x, int y, const uint8_t *frame, int width, int height, uint8_t invert = 0, uint8_t mode = GFX_REPLACE, bool pgm = true) {
256 | uint8_t bytes = width >> 3;
257 | uint8_t left = width & 0b111;
258 | if (left) bytes++;
259 |
260 | for (int yy = 0; yy < height; yy++) {
261 | for (int xx = 0; xx < (width >> 3); xx++) {
262 | uint8_t thisByte = pgm ? (pgm_read_word(&(frame[xx + yy * bytes])) ^ invert) : (frame[xx + yy * bytes] ^ invert);
263 | for (uint8_t k = 0; k < 8; k++) {
264 | uint8_t val = thisByte & 0b10000000;
265 | if (val || !mode) dotSecure((xx << 3) + k + x, yy + y, val);
266 | thisByte <<= 1;
267 | }
268 | }
269 | if (left) {
270 | uint8_t thisByte = pgm ? (pgm_read_byte(&(frame[(width >> 3) + yy * bytes])) ^ invert) : (frame[(width >> 3) + yy * bytes] ^ invert);
271 | for (uint8_t k = 0; k < left; k++) {
272 | uint8_t val = thisByte & 0b10000000;
273 | if (val || !mode) dotSecure(((width >> 3) << 3) + k + x, yy + y, val);
274 | thisByte <<= 1;
275 | }
276 | }
277 | }
278 | }
279 |
280 | // ==================== TEXT =====================
281 | #ifndef GFX_NO_PRINT
282 | // определить длину строки с любыми символами (в т.ч. русскими)
283 | uint16_t strlen_fix(const char *str) {
284 | uint16_t i = 0, count = 0;
285 | while (str[i]) {
286 | if ((str[i] & 0xc0) != 0x80) count++;
287 | i++;
288 | }
289 | return count;
290 | }
291 |
292 | // определить длину PGM строки с любыми символами (в т.ч. русскими)
293 | uint16_t strlen_fix_P(PGM_P str) {
294 | uint16_t i = 0, count = 0;
295 | char c;
296 | while (1) {
297 | c = pgm_read_byte(str + i);
298 | if (!c) break;
299 | if ((c & 0xc0) != 0x80) count++;
300 | i++;
301 | }
302 | return count;
303 | }
304 |
305 | // установить курсор
306 | void setCursor(int x, int y) {
307 | cfg.x = x;
308 | cfg.y = y;
309 | }
310 |
311 | // получить курсор x
312 | int getCursorX() {
313 | return cfg.x;
314 | }
315 |
316 | // получить курсор y
317 | int getCursorY() {
318 | return cfg.y;
319 | }
320 |
321 | // установить масштаб текста (1-4)
322 | void setScale(uint8_t scale) {
323 | scale = constrain(scale, 1, 4);
324 | cfg.scale = scale;
325 | }
326 |
327 | // получить масштаб текста
328 | uint8_t getScale() {
329 | return cfg.scale;
330 | }
331 |
332 | // установить инверсию текста
333 | void invertText(bool inv) {
334 | cfg.invert = inv;
335 | }
336 |
337 | // получить инверсию текста
338 | bool getInvertText() {
339 | return cfg.invert;
340 | }
341 |
342 | // установить автоматический перенос текста
343 | void autoPrintln(bool mode) {
344 | cfg.println = mode;
345 | }
346 |
347 | // получить автоматический перенос текста
348 | bool getAutoPrintln() {
349 | return cfg.println;
350 | }
351 |
352 | // установить режим вывода текста GFX_ADD/GFX_REPLACE
353 | void textDisplayMode(bool mode) {
354 | cfg.tmode = mode;
355 | }
356 |
357 | // получить режим вывода текста
358 | bool getTextDisplayMode() {
359 | return cfg.tmode;
360 | }
361 |
362 | // установить границы вывода текста по х
363 | void setTextBound(int x0, int x1) {
364 | cfg.tx0 = x0;
365 | cfg.tx1 = x1;
366 | }
367 |
368 | // получить границу вывода 0
369 | int getTextBoundX0() {
370 | return cfg.tx0;
371 | }
372 |
373 | // получить границу вывода 1
374 | int getTextBoundX1() {
375 | return cfg.tx1;
376 | }
377 |
378 | // сбросить границы вывода текста до (0, ширина)
379 | void resetTextBound() {
380 | cfg.tx0 = 0;
381 | cfg.tx1 = _w - 1;
382 | }
383 |
384 | // ================== WRITE ===================
385 | size_t write(uint8_t data) {
386 | bool newPos = false;
387 | if (data == '\r') return 1;
388 |
389 | if (data == '\n') { // получен перевод строки
390 | cfg.y += (cfg.scale << 3);
391 | cfg.x = 0;
392 | newPos = true;
393 | data = 0;
394 | }
395 | if (cfg.println && (cfg.x + 6 * cfg.scale) >= (int16_t)_w) {
396 | cfg.x = 0; // строка переполненена, перевод и возврат
397 | cfg.y += (cfg.scale << 3);
398 | newPos = true;
399 | }
400 | if (newPos) setCursor(cfg.x, cfg.y); // переставляем курсор
401 | // if (cfg.y + (cfg.scale << 3) >= _h) data = 0; // дисплей переполнен
402 | if (cfg.println && data == ' ' && cfg.x == 0) data = 0; // первый пробел
403 |
404 | // фикс русских букв и некоторых символов
405 | if (data > 127) {
406 | uint8_t thisData = data;
407 | // data = 0 - флаг на пропуск
408 | if (data > 191) data = 0;
409 | else if (_lastChar == 209 && data == 145) data = 192; // ё кастомная
410 | else if (_lastChar == 208 && data == 129) data = 149; // Е вместо Ё
411 | else if (_lastChar == 226 && data == 128) data = 0; // тире вместо длинного тире (начало)
412 | else if (_lastChar == 128 && data == 148) data = 45; // тире вместо длинного тире
413 | _lastChar = thisData;
414 | }
415 | if (data == 0) return 1;
416 | // если тут не вылетели - печатаем символ
417 |
418 | int newX = cfg.x + cfg.scale * 6;
419 | if (newX < cfg.tx0 || cfg.x > cfg.tx1) { // пропускаем вывод "за экраном"
420 | cfg.x = newX;
421 | } else {
422 | for (uint8_t col = 0; col < 6; col++) { // 6 столбиков буквы
423 | uint8_t bits = getFont(data, col); // получаем байт
424 | drawByte(bits);
425 | }
426 | }
427 | return 1;
428 | }
429 |
430 | // вывести столбик-байт в текущий курсор с учётом масштаба и режима текста, автоматически перенесёт курсор
431 | void drawBytes_P(const uint8_t *bytes, int amount) {
432 | for (int i = 0; i < amount; i++) drawByte(pgm_read_byte(&bytes[i]));
433 | }
434 | void drawBytes(uint8_t *bytes, int amount) {
435 | for (int i = 0; i < amount; i++) drawByte(bytes[i]);
436 | }
437 | void drawByte(uint8_t bits) {
438 | if (cfg.invert) bits = ~bits;
439 | if (cfg.scale == 1) { // если масштаб 1
440 | if (cfg.x >= 0 && cfg.x < (int16_t)_w) { // внутри дисплея
441 | for (uint8_t y = 0; y < 8; y++) {
442 | bool bit = bitRead(bits, y);
443 | if ((bit || !cfg.tmode) && (cfg.x >= cfg.tx0 && cfg.x <= cfg.tx1)) dotSecure(cfg.x, cfg.y + y, bit);
444 | }
445 | }
446 | cfg.x++;
447 | } else { // масштаб 2, 3 или 4 - растягиваем шрифт
448 | uint32_t buf = 0;
449 | for (uint8_t i = 0, count = 0; i < 8; i++) {
450 | for (uint8_t j = 0; j < cfg.scale; j++, count++) {
451 | bitWrite(buf, count, bitRead(bits, i)); // пакуем растянутый шрифт
452 | }
453 | }
454 |
455 | for (uint8_t i = 0; i < cfg.scale; i++) {
456 | for (uint8_t j = 0; j < (cfg.scale << 3); j++) {
457 | bool bit = bitRead(buf, j);
458 | if ((bit || !cfg.tmode) && (cfg.x + i >= cfg.tx0 && cfg.x + i <= cfg.tx1)) dotSecure(cfg.x + i, cfg.y + j, bit);
459 | }
460 | }
461 | cfg.x += cfg.scale;
462 | }
463 | }
464 |
465 | gfx_config_t cfg;
466 | #endif
467 |
468 | // ============= DEPRECATED =============
469 | int W() {
470 | return _w;
471 | }
472 | int H() {
473 | return _h;
474 | }
475 | void fastLineH(int y, int x0, int x1, uint8_t fill = GFX_FILL) {
476 | lineH(y, x0, x1, fill);
477 | }
478 | void fastLineV(int x, int y0, int y1, uint8_t fill = GFX_FILL) {
479 | lineV(x, y0, y1, fill);
480 | }
481 |
482 | protected:
483 | void swap(int &a, int &b) {
484 | if (a > b) {
485 | int c = a;
486 | a = b;
487 | b = c;
488 | }
489 | }
490 | void dotSecure(int x, int y, uint8_t fill = 1) {
491 | if (x < 0 || x >= (int)_w || y < 0 || y >= (int)_h) return;
492 | dot(x, y, fill);
493 | }
494 | #ifndef GFX_NO_PRINT
495 | uint8_t getFont(uint8_t font, uint8_t row) {
496 | if (row > 4) return 0;
497 | font = font - '0' + 16; // перевод код символа из таблицы ASCII
498 | if (font <= 95) return pgm_read_byte(&(charMap[font][row])); // для английских букв и символов
499 | else if (font >= 96 && font <= 111) return pgm_read_byte(&(charMap[font + 47][row])); // для русских
500 | else if (font <= 159) return pgm_read_byte(&(charMap[font - 17][row]));
501 | else return pgm_read_byte(&(charMap[font - 1][row])); // для кастомных (ё)
502 | }
503 | uint8_t _lastChar;
504 | #endif
505 |
506 | uint16_t _w, _h;
507 | };
508 | #endif
509 |
--------------------------------------------------------------------------------
/src/RunningGFX.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 |
4 | // движок бегущей строки для GyverGFX
5 |
6 | #include "GyverGFX.h"
7 |
8 | #define RG_IDLE 0
9 | #define RG_MOVE 1
10 | #define RG_FINISH 2
11 |
12 | class RunningGFX {
13 | public:
14 | RunningGFX(GyverGFX* gfx) : _gfx(gfx) {
15 | _x0 = _y = 0;
16 | _x1 = _gfx->width();
17 | }
18 |
19 | // установить текст const char*
20 | void setText(const char* str) {
21 | _str = str;
22 | _p = 0;
23 | _len = _gfx->strlen_fix(_str) * 6;
24 | }
25 |
26 | // установить текст String
27 | void setText(String& str) {
28 | setText(str.c_str());
29 | }
30 |
31 | // установить текст из PROGMEM (глобальный)
32 | void setText_P(PGM_P str) {
33 | _str = str;
34 | _p = 1;
35 | _len = _gfx->strlen_fix_P(_str) * 6;
36 | }
37 |
38 | // инвертировать текст
39 | void invertText(bool inv) {
40 | _invert = inv;
41 | }
42 |
43 | // масштаб текста
44 | void setScale(uint8_t scale) {
45 | _scale = constrain(scale, 1, 4);
46 | }
47 |
48 | // режим вывода текста GFX_ADD/GFX_REPLACE
49 | void textDisplayMode(bool mode) {
50 | _tmode = mode;
51 | }
52 |
53 | // установить окно (x0, x1, y)
54 | void setWindow(int16_t x0, int16_t x1, int16_t y) {
55 | _x0 = x0;
56 | _x1 = x1;
57 | _y = y;
58 | }
59 |
60 | // установить скорость (пикселей в секунду)
61 | void setSpeed(uint16_t pixPerSec) {
62 | if (!pixPerSec) pixPerSec = 1;
63 | _prd = 1000 / pixPerSec;
64 | }
65 |
66 | // запустить бегущую строку с начала
67 | void start() {
68 | _pos = _x1 + 1;
69 | resume();
70 | }
71 |
72 | // остановить бегущую строку
73 | void stop() {
74 | _tmr = 0;
75 | }
76 |
77 | // продолжить движение с момента остановки
78 | void resume() {
79 | _tmr = (uint16_t)millis();
80 | if (!_tmr) _tmr = 1;
81 | }
82 |
83 | // тикер. Вернёт 0 в холостом, 1 при новом шаге, 2 при завершении движения
84 | // Можно передать false чтобы дисплей не обновлялся сам
85 | uint8_t tick(bool update = true) {
86 | if (!_str) return 0;
87 | if (_tmr && (uint16_t)((uint16_t)millis() - _tmr) >= _prd) {
88 | resume();
89 | return tickManual(update);
90 | }
91 | return RG_IDLE;
92 | }
93 |
94 | // сдвинуть строку на 1 пиксель. Можно передать false чтобы дисплей не обновлялся сам
95 | uint8_t tickManual(bool update = true) {
96 | if (!_str) return 0;
97 | gfx_config_t cfg = _gfx->cfg;
98 | _gfx->setScale(_scale);
99 | _gfx->invertText(_invert);
100 | _gfx->textDisplayMode(_tmode);
101 | _gfx->setTextBound(_x0, _x1);
102 | _gfx->setCursor(_pos, _y);
103 | if (_p) _gfx->print((const __FlashStringHelper*)_str);
104 | else _gfx->print(_str);
105 | _gfx->cfg = cfg;
106 | if (update) _gfx->update();
107 | if (--_pos <= _x0 - (int16_t)(_len * _scale)) {
108 | start();
109 | return RG_FINISH;
110 | }
111 | return RG_MOVE;
112 | }
113 |
114 | private:
115 | GyverGFX* _gfx;
116 | const char* _str = nullptr;
117 | uint16_t _tmr = 0, _prd = 50;
118 | uint16_t _len = 0;
119 | int16_t _x0, _x1, _y;
120 | int16_t _pos = 0;
121 | bool _p = 0;
122 | uint8_t _scale = 1;
123 | bool _invert = 0, _tmode = 0;
124 | };
--------------------------------------------------------------------------------
/src/fonts/font5x8.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | // шрифты для вывода текста
3 | const uint8_t charMap[][5] PROGMEM = {
4 | {0x00, 0x00, 0x00, 0x00, 0x00}, // 0x20 32
5 | {0x00, 0x00, 0x6f, 0x00, 0x00}, // ! 0x21 33
6 | {0x00, 0x07, 0x00, 0x07, 0x00}, // " 0x22 34
7 | {0x14, 0x7f, 0x14, 0x7f, 0x14}, // # 0x23 35
8 | {0x8C, 0x92, 0xFF, 0x92, 0x62}, // $ 0x24 36
9 | {0x23, 0x13, 0x08, 0x64, 0x62}, // % 0x25 37
10 | {0x36, 0x49, 0x56, 0x20, 0x50}, // & 0x26 38
11 | {0x00, 0x00, 0x07, 0x00, 0x00}, // ' 0x27 39
12 | {0x00, 0x1c, 0x22, 0x41, 0x00}, // ( 0x28 40
13 | {0x00, 0x41, 0x22, 0x1c, 0x00}, // ) 0x29 41
14 | {0x14, 0x08, 0x3e, 0x08, 0x14}, // * 0x2a 42
15 | {0x08, 0x08, 0x3e, 0x08, 0x08}, // + 0x2b 43
16 | {0x00, 0xa0, 0x60, 0x00, 0x00}, // , 0x2c 44
17 | {0x08, 0x08, 0x08, 0x08, 0x08}, // - 0x2d 45
18 | {0x00, 0x60, 0x60, 0x00, 0x00}, // . 0x2e 46
19 | {0x20, 0x10, 0x08, 0x04, 0x02}, // / 0x2f 47
20 | {0x3e, 0x51, 0x49, 0x45, 0x3e}, // 0 0x30 48
21 | {0x00, 0x42, 0x7f, 0x40, 0x00}, // 1 0x31 49
22 | {0x42, 0x61, 0x51, 0x49, 0x46}, // 2 0x32 50
23 | {0x21, 0x41, 0x45, 0x4b, 0x31}, // 3 0x33 51
24 | {0x18, 0x14, 0x12, 0x7f, 0x10}, // 4 0x34 52
25 | {0x27, 0x45, 0x45, 0x45, 0x39}, // 5 0x35 53
26 | {0x3c, 0x4a, 0x49, 0x49, 0x30}, // 6 0x36 54
27 | {0x01, 0x71, 0x09, 0x05, 0x03}, // 7 0x37 55
28 | {0x36, 0x49, 0x49, 0x49, 0x36}, // 8 0x38 56
29 | {0x06, 0x49, 0x49, 0x29, 0x1e}, // 9 0x39 57
30 | {0x00, 0x36, 0x36, 0x00, 0x00}, // : 0x3a 58
31 | {0x00, 0xa6, 0x66, 0x00, 0x00}, // ; 0x3b 59
32 | {0x08, 0x14, 0x22, 0x41, 0x00}, // < 0x3c 60
33 | {0x14, 0x14, 0x14, 0x14, 0x14}, // = 0x3d 61
34 | {0x00, 0x41, 0x22, 0x14, 0x08}, // > 0x3e 62
35 | {0x02, 0x01, 0x51, 0x09, 0x06}, // ? 0x3f 63
36 | {0x3e, 0x41, 0x5d, 0x49, 0x4e}, // @ 0x40 64
37 | {0x7E, 0x11, 0x11, 0x11, 0x7E}, // A 0x41 65
38 | {0x7f, 0x49, 0x49, 0x49, 0x36}, // B 0x42 66
39 | {0x3e, 0x41, 0x41, 0x41, 0x22}, // C 0x43 67
40 | {0x7f, 0x41, 0x41, 0x41, 0x3e}, // D 0x44 68
41 | {0x7f, 0x49, 0x49, 0x49, 0x41}, // E 0x45 69
42 | {0x7f, 0x09, 0x09, 0x09, 0x01}, // F 0x46 70
43 | {0x3e, 0x41, 0x49, 0x49, 0x7a}, // G 0x47 71
44 | {0x7f, 0x08, 0x08, 0x08, 0x7f}, // H 0x48 72
45 | {0x00, 0x41, 0x7f, 0x41, 0x00}, // I 0x49 73
46 | {0x20, 0x40, 0x41, 0x3f, 0x01}, // J 0x4a 74
47 | {0x7f, 0x08, 0x14, 0x22, 0x41}, // K 0x4b 75
48 | {0x7f, 0x40, 0x40, 0x40, 0x40}, // L 0x4c 76
49 | {0x7f, 0x02, 0x0c, 0x02, 0x7f}, // M 0x4d 77
50 | {0x7f, 0x04, 0x08, 0x10, 0x7f}, // N 0x4e 78
51 | {0x3e, 0x41, 0x41, 0x41, 0x3e}, // O 0x4f 79
52 | {0x7f, 0x09, 0x09, 0x09, 0x06}, // P 0x50 80
53 | {0x3e, 0x41, 0x51, 0x21, 0x5e}, // Q 0x51 81
54 | {0x7f, 0x09, 0x19, 0x29, 0x46}, // R 0x52 82
55 | {0x46, 0x49, 0x49, 0x49, 0x31}, // S 0x53 83
56 | {0x01, 0x01, 0x7f, 0x01, 0x01}, // T 0x54 84
57 | {0x3f, 0x40, 0x40, 0x40, 0x3f}, // U 0x55 85
58 | {0x0f, 0x30, 0x40, 0x30, 0x0f}, // V 0x56 86
59 | {0x3f, 0x40, 0x30, 0x40, 0x3f}, // W 0x57 87
60 | {0x63, 0x14, 0x08, 0x14, 0x63}, // X 0x58 88
61 | {0x07, 0x08, 0x70, 0x08, 0x07}, // Y 0x59 89
62 | {0x61, 0x51, 0x49, 0x45, 0x43}, // Z 0x5a 90
63 | {0x00, 0x00, 0x7f, 0x41, 0x00}, // [ 0x5b 91
64 | {0x02, 0x04, 0x08, 0x10, 0x20}, // \ 0x5c 92
65 | {0x00, 0x41, 0x7f, 0x00, 0x00}, // ] 0x5d 93
66 | {0x04, 0x02, 0x01, 0x02, 0x04}, // ^ 0x5e 94
67 | {0x40, 0x40, 0x40, 0x40, 0x40}, // _ 0x5f 95
68 | {0x00, 0x00, 0x03, 0x04, 0x00}, // ` 0x60 96
69 | {0x20, 0x54, 0x54, 0x54, 0x78}, // a 0x61 97
70 | {0x7f, 0x48, 0x44, 0x44, 0x38}, // b 0x62 98
71 | {0x38, 0x44, 0x44, 0x44, 0x20}, // c 0x63 99
72 | {0x38, 0x44, 0x44, 0x48, 0x7f}, // d 0x64 100
73 | {0x38, 0x54, 0x54, 0x54, 0x18}, // e 0x65 101
74 | {0x08, 0x7e, 0x09, 0x01, 0x02}, // f 0x66 102
75 | {0x18, 0xa4, 0xa4, 0xa4, 0x7c}, // g 0x67 103
76 | {0x7f, 0x08, 0x04, 0x04, 0x78}, // h 0x68 104
77 | {0x00, 0x44, 0x7d, 0x40, 0x00}, // i 0x69 105
78 | {0x40, 0x80, 0x88, 0x7a, 0x00}, // j 0x6a 106
79 | {0x00, 0x7f, 0x10, 0x28, 0x44}, // k 0x6b 107
80 | {0x00, 0x41, 0x7f, 0x40, 0x00}, // l 0x6c 108
81 | {0x7c, 0x04, 0x18, 0x04, 0x78}, // m 0x6d 109
82 | {0x7c, 0x08, 0x04, 0x04, 0x78}, // n 0x6e 110
83 | {0x38, 0x44, 0x44, 0x44, 0x38}, // o 0x6f 111
84 | {0xfc, 0x24, 0x24, 0x24, 0x18}, // p 0x70 112
85 | {0x18, 0x24, 0x24, 0x24, 0xfc}, // q 0x71 113
86 | {0x7c, 0x08, 0x04, 0x04, 0x08}, // r 0x72 114
87 | {0x48, 0x54, 0x54, 0x54, 0x20}, // s 0x73 115
88 | {0x04, 0x3f, 0x44, 0x40, 0x20}, // t 0x74 116
89 | {0x3c, 0x40, 0x40, 0x20, 0x7c}, // u 0x75 117
90 | {0x1c, 0x20, 0x40, 0x20, 0x1c}, // v 0x76 118
91 | {0x3c, 0x40, 0x30, 0x40, 0x3c}, // w 0x77 119
92 | {0x44, 0x28, 0x10, 0x28, 0x44}, // x 0x78 120
93 | {0x1c, 0xa0, 0xa0, 0xa0, 0x7c}, // y 0x79 121
94 | {0x44, 0x64, 0x54, 0x4c, 0x44}, // z 0x7a 122
95 | {0x00, 0x08, 0x36, 0x41, 0x41}, // { 0x7b 123
96 | {0x00, 0x00, 0x7f, 0x00, 0x00}, // | 0x7c 124
97 | {0x41, 0x41, 0x36, 0x08, 0x00}, // } 0x7d 125
98 | {0x08, 0x04, 0x08, 0x10, 0x08}, // ~ 0x7e 126
99 |
100 | {0x7E, 0x11, 0x11, 0x11, 0x7E}, // А (0xC0)
101 | {0x7f, 0x49, 0x49, 0x49, 0x31}, // Б (0xC1)
102 | {0x7F, 0x49, 0x49, 0x49, 0x36}, // В (0xC2)
103 | {0x7f, 0x01, 0x01, 0x01, 0x01}, // Г (0xC3)
104 | {0xE0, 0x51, 0x4F, 0x41, 0xFF}, // Д (0xC4)
105 | {0x7F, 0x49, 0x49, 0x49, 0x41}, // Е (0xC5)
106 | {0x77, 0x08, 0x7F, 0x08, 0x77}, // Ж (0xC6)
107 | {0x41, 0x49, 0x49, 0x49, 0x36}, // З (0xC7)
108 | {0x7F, 0x10, 0x08, 0x04, 0x7F}, // И (0xC8)
109 | {0x7C, 0x21, 0x12, 0x09, 0x7C}, // Й (0xC9)
110 | {0x7F, 0x08, 0x14, 0x22, 0x41}, // К (0xCA)
111 | {0x20, 0x40, 0x3f, 0x01, 0x7f}, // Л (0xCB)
112 | {0x7F, 0x02, 0x0C, 0x02, 0x7F}, // М (0xCC)
113 | {0x7F, 0x08, 0x08, 0x08, 0x7F}, // Н (0xCD)
114 | {0x3E, 0x41, 0x41, 0x41, 0x3E}, // О (0xCE)
115 | {0x7F, 0x01, 0x01, 0x01, 0x7F}, // П (0xCF)
116 | {0x7F, 0x09, 0x09, 0x09, 0x06}, // Р (0xD0)
117 | {0x3E, 0x41, 0x41, 0x41, 0x22}, // С (0xD1)
118 | {0x01, 0x01, 0x7F, 0x01, 0x01}, // Т (0xD2)
119 | {0x47, 0x48, 0x48, 0x48, 0x3f}, // У (0xD3)
120 | {0x1C, 0x22, 0x7F, 0x22, 0x1C}, // Ф (0xD4)
121 | {0x63, 0x14, 0x08, 0x14, 0x63}, // Х (0xD5)
122 | {0x7F, 0x40, 0x40, 0x40, 0xFF}, // Ц (0xD6)
123 | {0x07, 0x08, 0x08, 0x08, 0x7F}, // Ч (0xD7)
124 | {0x7F, 0x40, 0x7F, 0x40, 0x7F}, // Ш (0xD8)
125 | {0x7F, 0x40, 0x7F, 0x40, 0xFF}, // Щ (0xD9)
126 | {0x01, 0x7F, 0x48, 0x48, 0x30}, // Ъ (0xDA)
127 | {0x7F, 0x48, 0x30, 0x00, 0x7F}, // Ы (0xDB)
128 | {0x7f, 0x48, 0x48, 0x30, 0x0}, // Ь (0xDC)
129 | {0x22, 0x41, 0x49, 0x49, 0x3E}, // Э (0xDD)
130 | {0x7F, 0x08, 0x3E, 0x41, 0x3E}, // Ю (0xDE)
131 | {0x46, 0x29, 0x19, 0x09, 0x7F}, // Я (0xDF)
132 |
133 | {0x20, 0x54, 0x54, 0x54, 0x78}, // а (0xE0)
134 | {0x3C, 0x4A, 0x4A, 0x49, 0x31}, // б (0xE1)
135 | {0x7C, 0x54, 0x54, 0x28, 0x00}, // в (0xE2)
136 | {0x7c, 0x04, 0x04, 0x04, 0x00}, // г (0xE3)
137 | {0x31, 0x49, 0x4a, 0x4a, 0x3c}, // д (0xE4)
138 | {0x38, 0x54, 0x54, 0x54, 0x18}, // е (0xE5)
139 | {0x6C, 0x10, 0x7C, 0x10, 0x6C}, // ж (0xE6)
140 | {0x20, 0x44, 0x54, 0x54, 0x28}, // з (0xE7)
141 | {0x7C, 0x20, 0x10, 0x08, 0x7C}, // и (0xE8)
142 | {0x78, 0x42, 0x24, 0x12, 0x78}, // й (0xE9)
143 | {0x7C, 0x10, 0x28, 0x44, 0x00}, // к (0xEA)
144 | {0x70, 0x08, 0x04, 0x78, 0x00}, // л (0xEB)
145 | {0x7C, 0x08, 0x10, 0x08, 0x7C}, // м (0xEC)
146 | {0x7C, 0x10, 0x10, 0x10, 0x7C}, // н (0xED)
147 | {0x38, 0x44, 0x44, 0x44, 0x38}, // о (0xEE)
148 | {0x7C, 0x04, 0x04, 0x04, 0x7C}, // п (0xEF)
149 | {0xfc, 0x24, 0x24, 0x24, 0x18}, // р (0xF0)
150 | {0x38, 0x44, 0x44, 0x44, 0x20}, // с (0xF1)
151 | {0x04, 0x04, 0x7C, 0x04, 0x04}, // т (0xF2)
152 | {0x1c, 0xa0, 0xa0, 0xa0, 0x7c}, // у (0xF3)
153 | {0x18, 0x24, 0xfe, 0x24, 0x18}, // ф (0xF4)
154 | {0x44, 0x28, 0x10, 0x28, 0x44}, // х (0xF5)
155 | {0x7C, 0x40, 0x40, 0x7C, 0xC0}, // ц (0xF6)
156 | {0x0C, 0x10, 0x10, 0x10, 0x7C}, // ч (0xF7)
157 | {0x7C, 0x40, 0x7C, 0x40, 0x7C}, // ш (0xF8)
158 | {0x7C, 0x40, 0x7C, 0x40, 0xFC}, // щ (0xF9)
159 | {0x04, 0x7C, 0x50, 0x50, 0x20}, // ъ (0xFA)
160 | {0x7C, 0x50, 0x50, 0x20, 0x7C}, // ы (0xFB)
161 | {0x7C, 0x50, 0x50, 0x20, 0x00}, // ь (0xFC)
162 | {0x20, 0x44, 0x54, 0x54, 0x38}, // э (0xFD)
163 | {0x7C, 0x10, 0x38, 0x44, 0x38}, // ю (0xFE)
164 | {0x08, 0x54, 0x34, 0x14, 0x7C}, // я (0xFF)
165 | {0x38, 0x55, 0x54, 0x55, 0x18}, // ё (0xFF)
166 | };
--------------------------------------------------------------------------------
/src/fonts/fontEditor.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
70 |
71 |
72 |
--------------------------------------------------------------------------------
/src/fonts/icons8x8.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | namespace GFX_icons {
4 | #define GFX_PGM(name) const static uint8_t name[] PROGMEM
5 | GFX_PGM(email) = {0xff, 0x85, 0x89, 0x91, 0x91, 0x89, 0x85, 0xff}; // 0 email
6 | GFX_PGM(github) = {0x3c, 0x5e, 0xa3, 0x03, 0x03, 0xe3, 0x7e, 0x3c}; // 1 github
7 | GFX_PGM(user) = {0x80, 0xc0, 0xe6, 0xef, 0xef, 0xe6, 0xc0, 0x80}; // 2 user
8 | GFX_PGM(lock) = {0xf0, 0xfe, 0xf1, 0x91, 0x91, 0xf1, 0xfe, 0xf0}; // 3 lock, password
9 | GFX_PGM(cog) = {0x18, 0x7e, 0x7e, 0xe7, 0xe7, 0x7e, 0x7e, 0x18}; // 4 cog, settings
10 | GFX_PGM(clock) = {0x3c, 0x42, 0x81, 0x9d, 0x91, 0x91, 0x42, 0x3c}; // 5 clock
11 | GFX_PGM(search) = {0x1e, 0x33, 0x21, 0x21, 0x33, 0x7e, 0xe0, 0xc0}; // 6 search
12 | GFX_PGM(message) = {0x7e, 0x3f, 0x15, 0x15, 0x15, 0x1d, 0x1f, 0x0e}; // 7 message
13 | GFX_PGM(bluetooth) = {0x00, 0x42, 0x24, 0x18, 0xff, 0x99, 0x66, 0x00}; // 8 bluetooth
14 | GFX_PGM(battery100) = {0x00, 0x3c, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e}; // 9 battery 100%
15 | GFX_PGM(battery75) = {0x00, 0x3c, 0x7e, 0x42, 0x7e, 0x7e, 0x7e, 0x7e}; // 10 battery 75%
16 | GFX_PGM(battery50) = {0x00, 0x3c, 0x7e, 0x42, 0x42, 0x7e, 0x7e, 0x7e}; // 11 battery 50%
17 | GFX_PGM(battery25) = {0x00, 0x3c, 0x7e, 0x42, 0x42, 0x42, 0x7e, 0x7e}; // 12 battery 25%
18 | GFX_PGM(battery0) = {0x00, 0x3c, 0x7e, 0x42, 0x42, 0x42, 0x42, 0x7e}; // 13 battery 0%
19 | GFX_PGM(screen) = {0xe7, 0x81, 0x81, 0x00, 0x00, 0x81, 0x81, 0xe7}; // 14 full screen
20 | GFX_PGM(smallscreen) = {0x24, 0x24, 0xe7, 0x00, 0x00, 0xe7, 0x24, 0x24}; // 15 small screen
21 | GFX_PGM(trash) = {0x02, 0xfa, 0x8b, 0xfb, 0xfb, 0x8b, 0xfa, 0x02}; // 16 trash, remove, delete
22 | GFX_PGM(calendar) = {0x7c, 0x82, 0x83, 0x82, 0xb2, 0xb3, 0x82, 0x7c}; // 17 calendar
23 | GFX_PGM(minimize) = {0x7e, 0x81, 0x81, 0x9d, 0x98, 0x94, 0x82, 0x71}; // 18 minimize
24 | GFX_PGM(maximize) = {0x7e, 0x81, 0x81, 0x91, 0x88, 0x85, 0x83, 0x77}; // 19 maximize
25 | GFX_PGM(printer) = {0x7c, 0x44, 0xe7, 0xa5, 0xa5, 0xe7, 0x44, 0x7c}; // 20 printer
26 | GFX_PGM(share) = {0x00, 0x18, 0x18, 0x24, 0x24, 0xc3, 0xc3, 0x00}; // 21 share
27 | GFX_PGM(map) = {0x1c, 0x3e, 0x73, 0xe1, 0xe1, 0x73, 0x3e, 0x1c}; // 22 map
28 | GFX_PGM(handbag) = {0xd8, 0x88, 0xde, 0xda, 0xda, 0xde, 0x88, 0xd8}; // 23 case
29 | GFX_PGM(warning) = {0xe0, 0xfc, 0xfe, 0xa3, 0xfe, 0xfc, 0xe0, 0x00}; // 24 warning
30 | GFX_PGM(error) = {0x3c, 0x7e, 0xe7, 0xe7, 0xe7, 0xe7, 0x7e, 0x3c}; // 25 error
31 | GFX_PGM(record) = {0x3c, 0x42, 0x81, 0x99, 0x99, 0x81, 0x42, 0x3c}; // 26 record
32 | GFX_PGM(play) = {0xff, 0xff, 0xff, 0x7e, 0x7e, 0x3c, 0x3c, 0x18}; // 27 play
33 | GFX_PGM(stop) = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; // 28 stop
34 | GFX_PGM(pause) = {0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00}; // 29 pause
35 | GFX_PGM(forward) = {0xff, 0x7e, 0x3c, 0x18, 0xff, 0x7e, 0x3c, 0x18}; // 30 forward
36 | GFX_PGM(backward) = {0x18, 0x3c, 0x7e, 0xff, 0x18, 0x3c, 0x7e, 0xff}; // 31 backward
37 | GFX_PGM(filter) = {0x07, 0x0f, 0x1f, 0xff, 0xff, 0x1f, 0x0f, 0x07}; // 32 filter
38 | GFX_PGM(filter_out) = {0x07, 0x09, 0x11, 0xe1, 0xe1, 0x11, 0x09, 0x07}; // 33 filter outline
39 | GFX_PGM(sound100) = {0x3c, 0x7e, 0xff, 0x00, 0x18, 0x42, 0x3c, 0x00}; // 34 sound 100%
40 | GFX_PGM(sound50) = {0x3c, 0x7e, 0xff, 0x00, 0x18, 0x00, 0x00, 0x00}; // 35 sound 50%
41 | GFX_PGM(sound0) = {0x3c, 0x7e, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00}; // 36 sound 0%
42 | GFX_PGM(sound_off) = {0x01, 0x02, 0x3c, 0x7e, 0xff, 0x20, 0x40, 0x80}; // 37 sound off
43 | GFX_PGM(download) = {0xe0, 0x88, 0x90, 0xbf, 0xbf, 0x90, 0x88, 0xe0}; // 38 download
44 | GFX_PGM(upload) = {0xe0, 0x84, 0x82, 0xbf, 0xbf, 0x82, 0x84, 0xe0}; // 39 upload
45 | GFX_PGM(text_file) = {0x7e, 0x81, 0xa1, 0xa1, 0xaf, 0xa9, 0x8a, 0x7c}; // 40 text file
46 | GFX_PGM(link) = {0xf0, 0x88, 0xa0, 0x92, 0x49, 0x05, 0x11, 0x0f}; // 41 link
47 | GFX_PGM(pencil) = {0xe0, 0x90, 0x88, 0x44, 0x26, 0x19, 0x0a, 0x04}; // 42 pencil
48 | GFX_PGM(bookmark) = {0xfe, 0x7f, 0x3f, 0x1f, 0x1f, 0x3f, 0x7f, 0xfe}; // 43 bookmark
49 | GFX_PGM(flash) = {0x00, 0x98, 0xdc, 0xfe, 0x7f, 0x3b, 0x19, 0x18}; // 44 flash, lighting
50 | GFX_PGM(attach) = {0x7e, 0x81, 0x99, 0xa5, 0xa5, 0xa5, 0xa1, 0x9e}; // 45 attach
51 | GFX_PGM(heart) = {0x1e, 0x3f, 0x7f, 0xfe, 0xfe, 0x7f, 0x3f, 0x1e}; // 46 heart
52 | GFX_PGM(heart_out) = {0x1e, 0x21, 0x41, 0x82, 0x82, 0x41, 0x21, 0x1e}; // 47 heart outline
53 | GFX_PGM(direction) = {0x72, 0x77, 0x77, 0xff, 0xff, 0x77, 0x77, 0x27}; // 48 direction
54 | GFX_PGM(eye) = {0x18, 0x24, 0x42, 0x5a, 0x5a, 0x42, 0x24, 0x18}; // 49 eye, visible
55 | GFX_PGM(antenna) = {0x06, 0x09, 0x11, 0xff, 0xff, 0x11, 0x09, 0x06}; // 50 antenna
56 | GFX_PGM(signal_100) = {0x00, 0xe0, 0x00, 0xf0, 0x00, 0xfc, 0x00, 0xff}; // 51 mobile signal 100%
57 | GFX_PGM(signal_75) = {0x00, 0xe0, 0x00, 0xf0, 0x00, 0xfc, 0x00, 0x80}; // 52 mobile signal 75%
58 | GFX_PGM(signal_50) = {0x00, 0xe0, 0x00, 0xf0, 0x00, 0x80, 0x00, 0x80}; // 53 mobile signal 50%
59 | GFX_PGM(signal_25) = {0x00, 0xe0, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80}; // 54 mobile signal 25%
60 | GFX_PGM(signal_0) = {0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80}; // 55 mobile signal 0%
61 | GFX_PGM(sync) = {0x20, 0x40, 0xff, 0x00, 0x00, 0xff, 0x02, 0x04}; // 56 sync
62 | GFX_PGM(video) = {0x7e, 0x7e, 0x7e, 0x7e, 0x3c, 0x18, 0x3c, 0x7e}; // 57 video
63 | GFX_PGM(wifi) = {0x02, 0x09, 0x25, 0x95, 0x95, 0x25, 0x09, 0x02}; // 58 wifi
64 | GFX_PGM(cloud) = {0x70, 0x88, 0x84, 0x84, 0xa4, 0x98, 0x90, 0x60}; // 59 cloud
65 | GFX_PGM(flashlight_on) = {0x01, 0x0a, 0xf8, 0xfb, 0xf8, 0x0a, 0x01, 0x00}; // 60 flashlight on
66 | GFX_PGM(flashlight_off) = {0x00, 0x08, 0xf8, 0x88, 0xf8, 0x08, 0x00, 0x00}; // 61 flashlight off
67 | GFX_PGM(bell) = {0x70, 0x4e, 0x41, 0xc1, 0xc1, 0x41, 0x4e, 0x70}; // 62 bell
68 | GFX_PGM(unlock) = {0xf0, 0xfe, 0xf1, 0x91, 0x91, 0xf1, 0xf2, 0xf0}; // 63 unlock
69 | GFX_PGM(vibrate) = {0x3c, 0x00, 0xff, 0x81, 0x81, 0xff, 0x00, 0x3c}; // 64 vibrate
70 | GFX_PGM(checked) = {0x7e, 0x81, 0x91, 0xa1, 0x91, 0x89, 0x84, 0x72}; // 65 checked
71 | GFX_PGM(unchecked) = {0x7e, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x7e}; // 66 unchecked
72 | GFX_PGM(chip) = {0x54, 0x00, 0xff, 0x81, 0x81, 0xff, 0x00, 0x54}; // 67 chip
73 | GFX_PGM(bug) = {0x48, 0x48, 0xfd, 0x82, 0x82, 0xfd, 0x48, 0x48}; // 68 bug
74 | GFX_PGM(save) = {0xff, 0x89, 0xe9, 0xa9, 0xa9, 0xe9, 0x8a, 0xfc}; // 69 save
75 | GFX_PGM(open) = {0xfe, 0xa2, 0x92, 0x8a, 0x8a, 0xcc, 0x28, 0x18}; // 70 open
76 | GFX_PGM(tool) = {0xc0, 0xe0, 0x70, 0x3e, 0x19, 0x11, 0x10, 0x0c}; // 71 tool
77 | GFX_PGM(console) = {0xff, 0xdd, 0xeb, 0xb7, 0xbf, 0xbf, 0xbf, 0xff}; // 72 console
78 | GFX_PGM(list) = {0xdb, 0xdb, 0x00, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb}; // 73 todo, list
79 | GFX_PGM(apps) = {0xe7, 0xe7, 0xe7, 0x00, 0x00, 0xe2, 0xe7, 0xe2}; // 74 apps
80 | GFX_PGM(android) = {0xf1, 0x8a, 0xa4, 0x84, 0x84, 0xa4, 0x8a, 0xf1}; // 75 android
81 | GFX_PGM(bulb) = {0x00, 0x0e, 0x71, 0xa1, 0xa1, 0x71, 0x0e, 0x00}; // 76 bulb
82 | GFX_PGM(logout) = {0x7e, 0x81, 0x99, 0x99, 0x18, 0x5a, 0x3c, 0x18}; // 77 logout
83 | GFX_PGM(login) = {0x18, 0x18, 0x5a, 0x3c, 0x99, 0x81, 0x81, 0x7e}; // 78 login
84 | GFX_PGM(zoom_in) = {0x3e, 0x41, 0x49, 0x5d, 0x49, 0x41, 0xfe, 0xc0}; // 79 zoom in
85 | GFX_PGM(zoom_out) = {0x3e, 0x41, 0x49, 0x49, 0x49, 0x41, 0xfe, 0xc0}; // 80 zoom out
86 | GFX_PGM(dashboard) = {0xff, 0xff, 0xff, 0x00, 0xf7, 0xf7, 0xf7, 0xf7}; // 81 dashboard
87 | GFX_PGM(all_out) = {0xc3, 0x99, 0x3c, 0x7e, 0x7e, 0x3c, 0x99, 0xc3}; // 82 all out
88 | GFX_PGM(science) = {0xc0, 0xe0, 0xf1, 0xff, 0xff, 0xf1, 0xe0, 0xc0}; // 83 science
89 | GFX_PGM(block) = {0x3c, 0x42, 0xa1, 0x91, 0x89, 0x85, 0x42, 0x3c}; // 84 block
90 | GFX_PGM(cat) = {0x7f, 0x82, 0xb4, 0x84, 0x84, 0xb4, 0x82, 0x7f}; // 85 cat, fox
91 | GFX_PGM(celsius) = {0x06, 0x09, 0x09, 0x06, 0x78, 0x84, 0x84, 0x48}; // 86 celsius
92 | GFX_PGM(temperature) = {0x06, 0x09, 0x09, 0x06, 0x08, 0xfc, 0x88, 0xc0}; // 87 temperature
93 | GFX_PGM(kelvin) = {0x06, 0x09, 0x09, 0x06, 0xf8, 0x20, 0x50, 0x88}; // 88 kelvin
94 | GFX_PGM(tag) = {0x24, 0x24, 0xff, 0x24, 0x24, 0xff, 0x24, 0x24}; // 89 tag
95 | GFX_PGM(chevron_right) = {0x00, 0x00, 0x81, 0xc3, 0x66, 0x3c, 0x18, 0x00}; // 90 chevron right
96 | GFX_PGM(chevron_left) = {0x00, 0x18, 0x3c, 0x66, 0xc3, 0x81, 0x00, 0x00}; // 91 chevron left
97 | GFX_PGM(chevron_up) = {0x30, 0x18, 0x0c, 0x06, 0x06, 0x0c, 0x18, 0x30}; // 92 chevron up
98 | GFX_PGM(chevron_down) = {0x0c, 0x18, 0x30, 0x60, 0x60, 0x30, 0x18, 0x0c}; // 93 chevron down
99 | GFX_PGM(note1) = {0x00, 0x60, 0x90, 0x90, 0x7f, 0x00, 0x00, 0x00}; // 94 note 1
100 | GFX_PGM(note2) = {0x00, 0x60, 0xf0, 0xf0, 0x7f, 0x00, 0x00, 0x00}; // 95 note 2
101 | GFX_PGM(note3) = {0x00, 0x60, 0x90, 0x90, 0x7f, 0x01, 0x01, 0x00}; // 96 note 3
102 | GFX_PGM(note4) = {0x00, 0x60, 0xf0, 0xf0, 0x7f, 0x01, 0x01, 0x00}; // 97 note 4
103 | GFX_PGM(note5) = {0x00, 0x60, 0x90, 0x90, 0x7f, 0x05, 0x05, 0x00}; // 98 note 5
104 | GFX_PGM(note6) = {0x00, 0x60, 0xf0, 0xf0, 0x7f, 0x05, 0x05, 0x00}; // 99 note 6
105 | GFX_PGM(cup0) = {0x7f, 0x81, 0x81, 0x81, 0x81, 0x7f, 0x22, 0x1e}; // 100 cup empty
106 | GFX_PGM(cup20) = {0x7f, 0xe1, 0xe1, 0xe1, 0xe1, 0x7f, 0x22, 0x1e}; // 101 cup 20%
107 | GFX_PGM(cup40) = {0x7f, 0xf1, 0xf1, 0xf1, 0xf1, 0x7f, 0x22, 0x1e}; // 102 cup 40%
108 | GFX_PGM(cup60) = {0x7f, 0xf9, 0xf9, 0xf9, 0xf9, 0x7f, 0x22, 0x1e}; // 103 cup 60%
109 | GFX_PGM(cup80) = {0x7f, 0xfd, 0xfd, 0xfd, 0xfd, 0x7f, 0x22, 0x1e}; // 104 cup 80%
110 | GFX_PGM(cup100) = {0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x22, 0x1e}; // 105 cup 100%
111 | GFX_PGM(wineglass) = {0x07, 0x09, 0x91, 0xe1, 0xe1, 0x91, 0x09, 0x07}; // 106 wineglass
112 | GFX_PGM(glass) = {0x07, 0x19, 0xe1, 0x81, 0x81, 0xe1, 0x19, 0x07}; // 107 glass
113 | GFX_PGM(hammer) = {0x04, 0x06, 0xff, 0xff, 0xff, 0x06, 0x0f, 0x0f}; // 108 hammer
114 | GFX_PGM(folder_out) = {0xff, 0x81, 0x81, 0x81, 0x82, 0x82, 0x82, 0xfc}; // 109 folder outline
115 | GFX_PGM(folder) = {0xff, 0xff, 0xff, 0xff, 0xfe, 0xfe, 0xfe, 0xfc}; // 110 folder
116 | GFX_PGM(folder_add) = {0xff, 0x81, 0x81, 0x91, 0xba, 0x92, 0x82, 0xfc}; // 111 add folder
117 | GFX_PGM(microphone) = {0x1c, 0x30, 0x20, 0xef, 0xef, 0x20, 0x30, 0x1c}; // 112 microphone
118 | GFX_PGM(equalizer) = {0xe0, 0xe0, 0x00, 0xff, 0xff, 0x00, 0xfc, 0xfc}; // 113 equalizer
119 | GFX_PGM(next) = {0xff, 0xff, 0xff, 0x7e, 0x3c, 0x18, 0x00, 0xff}; // 114 next
120 | GFX_PGM(prev) = {0xff, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0xff}; // 115 prev
121 | GFX_PGM(monitor) = {0x3f, 0xa1, 0xa1, 0xe1, 0xe1, 0xa1, 0xa1, 0x3f}; // 116 monitor, display
122 | GFX_PGM(headset) = {0x7c, 0xe2, 0xe1, 0x01, 0x01, 0xe1, 0xe2, 0x7c}; // 117 headset, earphones
123 | GFX_PGM(workout) = {0x18, 0x3c, 0x7e, 0x18, 0x18, 0x7e, 0x3c, 0x18}; // 118 workout, fitness
124 | GFX_PGM(sport) = {0xff, 0x0a, 0x15, 0x0a, 0x15, 0x0a, 0x15, 0x0a}; // 119 sport flag
125 | GFX_PGM(location) = {0x18, 0x18, 0x24, 0xc3, 0xc3, 0x24, 0x18, 0x18}; // 120 location
126 | GFX_PGM(cellular1) = {0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0x01, 0xbd}; // 121 cellular 1
127 | GFX_PGM(cellular2) = {0xc0, 0xa0, 0x90, 0x88, 0x84, 0x82, 0x01, 0xbd}; // 122 cellular 2
128 | GFX_PGM(cellular3) = {0xc0, 0xa0, 0x90, 0x88, 0x84, 0x82, 0x81, 0xff}; // 123 cellular 3
129 | GFX_PGM(cellular4) = {0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff, 0xff}; // 124 cellular 4
130 | GFX_PGM(cellular5) = {0x43, 0x66, 0x7c, 0x78, 0x74, 0x6e, 0xdf, 0xbf}; // 125 cellular 5
131 | GFX_PGM(cellular6) = {0xc0, 0xe0, 0xf0, 0xf8, 0x0c, 0xae, 0x4f, 0xaf}; // 126 cellular 6
132 | GFX_PGM(waves) = {0x92, 0x49, 0x49, 0x92, 0x92, 0x49, 0x49, 0x92}; // 127 waves
133 | GFX_PGM(home) = {0x18, 0xf4, 0x92, 0x91, 0x91, 0x92, 0xf4, 0x18}; // 128 home
134 | GFX_PGM(dice1) = {0x7e, 0x81, 0xa5, 0x81, 0x81, 0xa5, 0x81, 0x7e}; // 129 dice 1
135 | GFX_PGM(dice2) = {0x7e, 0x81, 0x85, 0x81, 0x81, 0xa1, 0x81, 0x7e}; // 130 dice 2
136 | GFX_PGM(plug) = {0x3c, 0x44, 0x47, 0xc4, 0xc4, 0x47, 0x44, 0x3c}; // 131 plug
137 | GFX_PGM(home2) = {0xf8, 0x84, 0x82, 0x81, 0xb1, 0xb2, 0x84, 0xf8}; // 132 home 2
138 | GFX_PGM(radio) = {0xf0, 0x90, 0xf0, 0xf1, 0x92, 0x94, 0x98, 0xf0}; // 133 radio
139 | GFX_PGM(memory) = {0x24, 0x7e, 0xc3, 0x5a, 0x5a, 0xc3, 0x7e, 0x24}; // 134 memory
140 | GFX_PGM(gamepad) = {0x44, 0x92, 0xba, 0x92, 0x82, 0xaa, 0x82, 0x44}; // 135 gamepad
141 | GFX_PGM(router) = {0x70, 0x88, 0xa8, 0x8a, 0xa9, 0x8d, 0x89, 0x72}; // 136 router
142 | GFX_PGM(smile1) = {0x7e, 0x81, 0x95, 0xa1, 0xa1, 0x95, 0x81, 0x7e}; // 137 smile 1
143 | GFX_PGM(smile2) = {0x7e, 0x81, 0xa5, 0x91, 0x91, 0xa5, 0x81, 0x7e}; // 138 smile 2
144 | GFX_PGM(smile3) = {0x7e, 0x81, 0xa5, 0xa1, 0xa1, 0xa5, 0x81, 0x7e}; // 139 smile 3
145 | GFX_PGM(smile4) = {0x7e, 0x81, 0x85, 0xb1, 0xb1, 0x85, 0x81, 0x7e}; // 140 smile 4
146 | GFX_PGM(smile5) = {0x7e, 0x81, 0x8d, 0xe1, 0xe1, 0x8d, 0x81, 0x7e}; // 141 smile 5
147 | GFX_PGM(sms) = {0x01, 0x03, 0xff, 0xfb, 0xbb, 0xab, 0xab, 0xff}; // 142 sms
148 | GFX_PGM(toggle_on) = {0x3c, 0x7e, 0x7e, 0x7e, 0x7e, 0x66, 0x66, 0x3c}; // 143 toggle on
149 | GFX_PGM(toggle_off) = {0x3c, 0x5a, 0x5a, 0x42, 0x42, 0x42, 0x42, 0x3c}; // 144 toggle off
150 | GFX_PGM(arrow1_right) = {0x00, 0x00, 0xff, 0x7e, 0x3c, 0x18, 0x00, 0x00}; // 145 arrow type 1 right
151 | GFX_PGM(arrow1_left) = {0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0x00, 0x00}; // 146 arrow type 1 left
152 | GFX_PGM(arrow1_down) = {0x04, 0x0c, 0x1c, 0x3c, 0x3c, 0x1c, 0x0c, 0x04}; // 147 arrow type 1 down
153 | GFX_PGM(arrow1_up) = {0x20, 0x30, 0x38, 0x3c, 0x3c, 0x38, 0x30, 0x20}; // 148 arrow type 1 up
154 | GFX_PGM(arrow2_right) = {0x18, 0x18, 0x18, 0x18, 0xff, 0x7e, 0x3c, 0x18}; // 149 arrow type 2 right
155 | GFX_PGM(arrow2_left) = {0x18, 0x3c, 0x7e, 0xff, 0x18, 0x18, 0x18, 0x18}; // 150 arrow type 2 left
156 | GFX_PGM(arrow2_down) = {0x10, 0x30, 0x70, 0xff, 0xff, 0x70, 0x30, 0x10}; // 151 arrow type 2 down
157 | GFX_PGM(arrow2_up) = {0x08, 0x0c, 0x0e, 0xff, 0xff, 0x0e, 0x0c, 0x08}; // 152 arrow type 2 up
158 | GFX_PGM(alarm) = {0x02, 0x79, 0x85, 0xb4, 0xa4, 0x85, 0x79, 0x02}; // 153 alarm clock
159 | GFX_PGM(key) = {0x3c, 0x42, 0x42, 0x3c, 0x08, 0x18, 0x08, 0x38}; // 154 key
160 | }
--------------------------------------------------------------------------------