├── .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 | [![latest](https://img.shields.io/github/v/release/GyverLibs/GyverGFX.svg?color=brightgreen)](https://github.com/GyverLibs/GyverGFX/releases/latest/download/GyverGFX.zip) 2 | [![PIO](https://badges.registry.platformio.org/packages/gyverlibs/library/GyverGFX.svg)](https://registry.platformio.org/libraries/gyverlibs/GyverGFX) 3 | [![Foo](https://img.shields.io/badge/Website-AlexGyver.ru-blue.svg?style=flat-square)](https://alexgyver.ru/) 4 | [![Foo](https://img.shields.io/badge/%E2%82%BD%24%E2%82%AC%20%D0%9F%D0%BE%D0%B4%D0%B4%D0%B5%D1%80%D0%B6%D0%B0%D1%82%D1%8C-%D0%B0%D0%B2%D1%82%D0%BE%D1%80%D0%B0-orange.svg?style=flat-square)](https://alexgyver.ru/support_alex/) 5 | [![Foo](https://img.shields.io/badge/README-ENGLISH-blueviolet.svg?style=flat-square)](https://github-com.translate.goog/GyverLibs/GyverGFX?_x_tr_sl=ru&_x_tr_tl=en) 6 | 7 | [![Foo](https://img.shields.io/badge/ПОДПИСАТЬСЯ-НА%20ОБНОВЛЕНИЯ-brightgreen.svg?style=social&logo=telegram&color=blue)](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 | } --------------------------------------------------------------------------------