работа дисплей MCUFRIEND

k134

✩✩✩✩✩✩✩
8 Июл 2020
35
0
Подскажите кто может. У меня MCUFRIEND 3,5 дюйма диплей . У него вот такая проблема, небыло у него русского языка я нашел статью как вставить русские шрифты и всё получилось, но вот беда вместе с тем он перестал обновлять экран или что типа того. В общем когда данные меняются на кране он их накладывает одни на другие. Можно конечно обновлять весь дисплей принудительно но это крайне не удобно и довольно накладно по коду. подскажите что делать может есть какая нибудь команда.
2021-09-08 07-11-46.JPG2021-09-08 07-30-47.JPG2021-09-08 16-37-11.JPG2021-09-08 16-38-09.JPG

библиотека:
#include <Adafruit_GFX.h>
#include <MCUFRIEND_kbv.h>
MCUFRIEND_kbv tft;


//#include <Fonts/CrystalNormal14.h>
#include <Fonts/FreeSans9pt7b.h>
#include <FontsRus/CourierCyr9.h>
#include <FontsRus/Bahamas8.h>
#include <FontsRus/Bahamas6.h>
#include <FontsRus/CourierCyr18.h>
#include <FontsRus/CourierCyr10.h>
#include <FontsRus/Crystal18.h>
#include <FreeDefaultFonts.h>


#define BLACK   0x0000
#define BLUE    0x001F
#define RED     0xF800
#define GREEN   0x07E0
#define CYAN    0x07FF
#define MAGENTA 0xF81F
#define YELLOW  0xFFE0
#define WHITE   0xFFFF

Перевод на руский:
String utf8rus(String source)
{
  int i, k;
  String target;
  unsigned char n;
  char m[2] = { '0', '\0' };

  k = source.length(); i = 0;

  while (i < k) {
    n = source[i]; i++;

    if (n >= 0xBF) {
      switch (n) {
        case 0xD0: {
            n = source[i]; i++;
            if (n == 0x81) {
              n = 0xA8;
              break;
            }
            if (n >= 0x90 && n <= 0xBF) n = n + 0x2F;
            break;
          }
        case 0xD1: {
            n = source[i]; i++;
            if (n == 0x91) {
              n = 0xB7;
              break;
            }
            if (n >= 0x80 && n <= 0x8F) n = n + 0x6F;
            break;
          }
      }
    }
    m[0] = n; target = target + String(m);
  }
  return target;
}




      tft.setFont(& CourierCyr18pt8b);
      //tft.fillScreen(MAGENTA);
      tft.setCursor(10, 25);
      tft.setTextColor(WHITE, BLACK);
      //////tft.setTextSize(2);
      //
      tft.println("Большая комната");
 

Эдуард Анисимов

★★★★★★✩
23 Сен 2019
2,265
944
58
Марий-Эл
Для того, что бы старые значения затирались, нужно воспользоваться предварительно функцией setTextColor("ЦветБукв", "ЦветФона"), которую Вы пытались использовать. Тогда она будет затирать старую надпись.
НО !!! Это работает только для стандартного шрифта. Для шрифта подгруженного из вне, это не работает. Об этом даже в самой библиотеке сказано. Только не помню какой MCUFRIEND или adafruit.
И предлагается простой выход из этого положения, затирать пробелами старое значение и выводить новое. Таким образом не нужно перерисовывать весь экран.
C++:
      tft.setCursor(10, 25);
      tft.setTextColor(WHITE, BLACK);
      tft.println("               ");
      //////tft.setTextSize(2);
      //
      tft.setCursor(10, 25);
      tft.println("Большая комната");
Если интересно, у меня есть стандартный русифицированный шрифт.
 

PiratFox

★★★★★✩✩
13 Фев 2020
1,695
472
Согласен с Эдиком. На нужное место вначале выводить пробелы, а затем, по этим же координатам нужные данные.
 

bort707

★★★★★★✩
21 Сен 2020
2,864
850
Проблема известная. Вариантов решения несколько. Или пробелы, или рисовать прямоугольник, или сначала выводить прежнюю надпись цветом фона...
 

Геннадий П

★★★★★★✩
14 Апр 2021
1,799
579
44
Либо фиксить код чтобы он выводил фон шрифта. Но самое простое - конечно же рисовать пробелы.
 

bort707

★★★★★★✩
21 Сен 2020
2,864
850
Либо фиксить код чтобы он выводил фон шрифта.
это легко сделать только для мноширинных фонтов. Для остальных это совсем не такая простая задача, как может показаться. Литеры в фонте разной ширины и разной высоты, поэтому фон одной буквы может не полностью закрасить другую. Например, если вывести строчную "а" поверх заглавной "Щ" - сверху и снизу останутся артефакты.
 

Геннадий П

★★★★★★✩
14 Апр 2021
1,799
579
44
@bort707, По ширине они да, будут разные и нужно "замазывать" лишнее пробелами.
Но по высоте они обычно все рисуются с одинаковой высотой. Т.е. например если шрифт рассчитан на высоту 14 пикселей, то все 14 пикселей по высоте будут перекрываться, на важно какой высоты буква, строчная или заглавная.

PS:
Например, если вывести строчную "а" поверх заглавной "Щ" - сверху и снизу останутся артефакты.
А "пробел" тогда какой высоты по пикселям? :)
 

Эдуард Анисимов

★★★★★★✩
23 Сен 2019
2,265
944
58
Марий-Эл
Но самое простое - конечно же рисовать пробелы.
Блин. Забыл. Это не поможет.
или рисовать прямоугольник
Вот это более правильно.

Сам пару лет назад разруливал эти грабли.
https://community.alexgyver.ru/threads/termometr-dlja-bani.2410/. Посмотрите там. Такую проблему я там то же вроде бы решал.
 
Изменено:

bort707

★★★★★★✩
21 Сен 2020
2,864
850
А "пробел" тогда какой высоты по пикселям? :)
нулевой.
Почитайте описание формата фонтов Адафруит, наследником которого является библиотека MCUFRIEND.
В этих фонтах кодируются только закрашенные точки, в пробеле таких нет.
 

Геннадий П

★★★★★★✩
14 Апр 2021
1,799
579
44
@bort707, Весьма странное решение. В некоторых моментах может быть полезно, но мне кажется от такого больше неудобства.
Свою библиотеку когда писал, то тупо всю высоту символа отрисовывал. Так гораздо проще, чем вычислять максимальную занимаемую высоту.
 

bort707

★★★★★★✩
21 Сен 2020
2,864
850
Весьма странное решение.
это сделано для уменьшения размера памяти, занимаемого шрифтом. Для больших размеров букв очень существенно
Добавка - вспомнил, это не только и не столько экономия места. Фонты с прозрачным фоном очень востребованы в графике. Попробуйте вывести надпись с прозрачным и непрозрачным фоном не поверх одноцветного поля, а поверх картинки - и вы сразу поймете в чем разница.
 
Изменено:

Геннадий П

★★★★★★✩
14 Апр 2021
1,799
579
44
@bort707, Для больших букв я бы вообще выводил текст только заглавными буквами, а строчные выкинул бы для уменьшения занимаемой памяти.
 

Эдуард Анисимов

★★★★★★✩
23 Сен 2019
2,265
944
58
Марий-Эл
@!_Евгений_!, Привет. Там не так всё просто. Нужно библиотеку print в ядре менять.
Сам шрифт выслал.
Менять нужно вот этот код.
C++:
size_t Print::print(const char *p)
{
  size_t n = 0;
  uint8_t c;
  while (1)
  {
    c = *p++;
    if(c >= 0xC0)
    {
      if(c == 0xD0)
      {
        c = *p++;
        if(c == 0x81)
        {
          c = 0xA8;
        }
        else if(c >= 0x90 && c <= 0xBF) c = c + 0x30;
      }
      else if(c == 0xD1)
      {
        c = *p++;
        if(c == 0x91)
        {
          c = 0xB8;
        }
        else if(c >= 0x80 && c <= 0x8F) c = c + 0x70;
      }
    }
    if(c == 0) break;
    if(write(c)) n++;
    else break;
  }
  return n;
}
 

Вложения