olikraus / U8g2_for_Adafruit_GFX

Add U8g2 fonts to any Adafruit GFX based graphics library.
Other
103 stars 32 forks source link

Problem with "u8g2_font_unifont_t_bengali" #33

Open muhit313 opened 2 years ago

muhit313 commented 2 years ago

Thanks for your big library support. But I had some problem with "u8g2_font_unifont_t_bengali" this font. I want to show Bengali word "আমার" on my ST7735 display. But it show me the output আম ার and want to show Bengali word "মুহিত" on my ST7735 display but it show me the output ম ুহ িত . I can't understand where is the wrong ? How can I solved it?

#include <Adafruit_GFX.h>
#include <Adafruit_ST7735.h>
#include <SPI.h>
#include <U8g2_for_Adafruit_GFX.h>

#define TFT_CS   8
#define TFT_RST  7
#define TFT_DC   6

Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);
U8G2_FOR_ADAFRUIT_GFX u8g2_for_adafruit_gfx;

void setup(void) {
  tft.initR(INITR_BLACKTAB);      // Init ST7735S chip, black tab
  tft.setRotation(0);
  tft.fillScreen(ST77XX_BLACK);
  u8g2_for_adafruit_gfx.begin(tft);
}

void loop() {
  u8g2_for_adafruit_gfx.setFontMode(0);                 
  u8g2_for_adafruit_gfx.setFontDirection(0);
  u8g2_for_adafruit_gfx.setForegroundColor(ST77XX_YELLOW);
  u8g2_for_adafruit_gfx.setFont(u8g2_font_unifont_t_bengali);
  u8g2_for_adafruit_gfx.setCursor(20, 20);
  u8g2_for_adafruit_gfx.print("আমার"); 
}
olikraus commented 2 years ago

This is not supported due to missing kerning support. There is an idea of a local kerning table implemented in u8g2 (https://github.com/olikraus/u8g2/issues/42), but not in this library.

muhit313 commented 2 years ago

I read your kernel table implementation algorithm. I am a begainer. So I don't have enough idea. This is a nice library for Bengali support with st7735 display. But other library may not. Please suggest me how can I do this.... with st7735 and your library.

olikraus commented 2 years ago

Not possible with this library

muhit313 commented 2 years ago

Not possible with this library

This is a sad news for me....... Please suggest me another library where I can do same things. Many thanks for your nice support.

olikraus commented 2 years ago

This is a sad news for me.......

You could still output each unicode individually, char by char with the correct distance to the previous char.

Please suggest me another library where I can do same things.

I have created a lib because there is nothing else out there ;-)

In other words: I do not know. Especially for a RGB display like the ST7735 i think there is not even unicode support in any other lib.

muhit313 commented 2 years ago

You could still output each unicode individually, char by char with the correct distance to the previous char.

This idea isn't bad.... But the problem is when I need to print big text with scrolling than may be I can't manage it.

olikraus commented 2 years ago

But the problem is when I need to print big text with scrolling than may be I can't manage it.

You could automate the process of outputting char by char, by creating a distance table for each char. Something like this: struct chardistance { unsigned firstchar; unsigned secondchar; int distance; }

struct chardistance distancetable[] = { { 'a', 'b', 4} // distance between a and b are 4 pixel };

So you create your own string output: Output the first char of the string while there are chars in the string get the distance to the second char by looking up the distance in your distance table advance by the distance found output second char. fist char = second char

muhit313 commented 2 years ago

Thanks again for your reply by wasting time for me.

I am really sorry for distrubing you again and again.

May be I understood your concept almost.
If I am not wrong, I have a String str = "আমার সোনার বাংলা আমি তোমায় ভালোবাসি। চিরদিন তোমার আকাশ, তোমার বাতাস...." or more big than that. First I need to split the string into char array. Then placed all of them char by char in a distance that I need.

I am right?

But as a newbie I am little bit confessed how to implement this using Structure. But I am trying to do this still now.

If you feel free and have enough time then can you help me by giving an example for this string "আমার সোনার বাংলা আমি তোমায় ভালোবাসি। চিরদিন তোমার আকাশ, তোমার বাতাস…." to implement.

olikraus commented 2 years ago

First I need to split the string into char array.

In C / C++ strings and char arrays are the same. But actually you need to specify the distance between each char. Let's take the first word: "আমার" It contains three chars, right? 1: আ 2: মা 3: র As a preparation you need to tell the distance between আ and মা --> 4 pixel distance মা and র --> 4 pixel distance

The 4 pixel distance is just an example. This is somehting you need to figure out.

Then you take the string "আমার" You print আ Then you look for the distance between আ and মা Then you move to the next position specified by the distance then you print মা Then you look for the distance between মা and র Then you move to the next position specified by the distance then you print র

The result shell look like "আমার"

muhit313 commented 2 years ago

@olikraus nice explanation ...Ok I will try to my best to implement this.

But if you give a code example for me it will more better for understanding ...

I am ashamed for this type of help.

Thank you.

olikraus commented 2 years ago
/*

  Bengali.ino

  List of all U8g2 fonts: https://github.com/olikraus/u8g2/wiki/fntlistall

*/
#include <Adafruit_SSD1306.h>
#include <U8g2_for_Adafruit_GFX.h>

const uint16_t distance_adjust_table[] = 
{
  /* first char, second char, gap reduction value */
  0x09AE, 0x9BE, 12, /* reduce distance between ম  and া  by 12 */
        /* add more pairs here... */

  /* this line terminates the table */
  0xffff, 0xffff, 0xffff
};

/* get distance from the distance table */
uint16_t get_distance_adjust(uint16_t e1, uint16_t e2)
{
  uint16_t i;
  i = 0;
  for(;;)
  {
    if ( distance_adjust_table[i] == 0x0ffff )
      break;
    if ( distance_adjust_table[i] == e1 && distance_adjust_table[i+1] == e2 )
      return distance_adjust_table[i+2];
    i+=3;
  }
  return 0;
}

int16_t draw_string(U8G2_FOR_ADAFRUIT_GFX &u8g2, int16_t x, int16_t y, const char *str)
{
  uint16_t e_prev = 0x0ffff;
  uint16_t e;
  uint16_t delta, adjust, sum;

  delta = 0;
  adjust = 0;
  u8g2.utf8_state = 0;

  sum = 0;
  for(;;)
  {
    e = u8g2.utf8_next((uint8_t)*str);
    if ( e == 0x0ffff )
      break;
    str++;
    if ( e != 0x0fffe )
    {
      delta = u8g2_GetGlyphWidth(&(u8g2.u8g2), e);      
      adjust = get_distance_adjust(e_prev, e);
      e_prev = e;
      u8g2_DrawGlyph(&(u8g2.u8g2), x-adjust, y, e);
      x += delta-adjust;
      sum += delta-adjust;    
    }
  }
  return sum;
}

Adafruit_SSD1306 display(/*MOSI*/ 11, /*CLK*/ 13, /*DC*/ 9, /*RESET*/ 8, /*CS*/ 10);
U8G2_FOR_ADAFRUIT_GFX u8g2_for_adafruit_gfx;

void setup() {
  display.begin(SSD1306_SWITCHCAPVCC);
  u8g2_for_adafruit_gfx.begin(display);                 // connect u8g2 procedures to Adafruit GFX
}

void loop() {  
  display.clearDisplay();                               // clear the graphcis buffer  
  u8g2_for_adafruit_gfx.setFont(u8g2_font_helvR14_tf);  // select u8g2 font from here: https://github.com/olikraus/u8g2/wiki/fntlistall
  u8g2_for_adafruit_gfx.setFontMode(1);                 // use u8g2 transparent mode (this is default)
  u8g2_for_adafruit_gfx.setFontDirection(0);            // left to right (this is default)
  u8g2_for_adafruit_gfx.setForegroundColor(WHITE);      // apply Adafruit GFX color
  u8g2_for_adafruit_gfx.setCursor(0,20);                // start writing at this position
  u8g2_for_adafruit_gfx.print("Hello World");
  u8g2_for_adafruit_gfx.setCursor(0,40);                // start writing at this position
  u8g2_for_adafruit_gfx.print("Umlaut ÄÖÜ");            // UTF-8 string with german umlaut chars
  u8g2_for_adafruit_gfx.setFont(u8g2_font_unifont_t_bengali);  // select Bengali font
  draw_string(u8g2_for_adafruit_gfx, 0,60, "আমার");          // draw Bengali string

  display.display();                                    // make everything visible
  delay(2000);
} 

NOT TESTED!

muhit313 commented 2 years ago

NOT TESTED!

No problem. You give me an example by wasting your time and its enough. I will test it myself and give you feedback if it works or not. Many thanks to you for your support. You are really a helpful man.

muhit313 commented 2 years ago

@olikraus Many many thanks for your example. Your example works fine.

May be this is the last request to you. After this I will close this issue. Because I disturb you many time. I am really sorry for that.

Now I want to show a full sentence like ""আমার সোনার বাংলা আমি". So I added some line in your example.

const uint16_t distance_adjust_table[] = 
{
  /* first char, second char, gap reduction value */
  0x09AE, 0x9BE, 12, /* reduce distance between ম  and া  by 12 */
 /* add more pairs here... */
  0x09B8, 0x09CB, 12, //for স and ো
  0x09A8, 0x09BE, 12, //for ন and া
  0x09AE, 0x09BF, 14, //for ম and ি
  0x09AC, 0x09BE, 12, //for ব and া
  0x09BE, 0x0982, 12, //for া and ং
  0x09B2, 0x09BE, 12, //for ল and া
  0x09AE, 0x09BF, 4, //for ম and ই
  /* this line terminates the table */
  0xffff, 0xffff, 0xffff
};

I want to print "সোনার" , "আমি" and আব্দ so I add 0x09B8, 0x09CB, 12 //for স and ো and 0x09AE, 0x09BF, 14, //for ম and ি in distance_adjust_table. But the out put is not expected. I changed the distance value 12 to 14/10/8..... and many more but can't saw any change. ো hide the স and ি hide the ম char.

Without ো , ি and ব্দ all works fine.

Where is the problem with this type of char? How can I overcome this?

Here is the full code:

#include <Adafruit_GFX.h>
#include <Adafruit_ST7735.h>
#include <SPI.h>
#include <U8g2_for_Adafruit_GFX.h>

#define TFT_CS   8
#define TFT_RST  7
#define TFT_DC   6

Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);
U8G2_FOR_ADAFRUIT_GFX u8g2_for_adafruit_gfx;

const uint16_t distance_adjust_table[] = 
{
  /* first char, second char, gap reduction value */
  0x09AE, 0x9BE, 12, /* reduce distance between ম  and া  by 12 */
 /* add more pairs here... */
  0x09B8, 0x09CB, 12, //for স and ো
  0x09A8, 0x09BE, 12, //for ন and া
  0x09AE, 0x09BF, 14, //for ম and ি
  0x09AC, 0x09BE, 12, //for ব and া
  0x09BE, 0x0982, 12, //for া and ং
  0x09B2, 0x09BE, 12, //for ল and া
  0x09AC, 0x09CD, 12, //for ব and ্
  0x09CD, 0x09A6, 12, //for ্ and দ
  /* this line terminates the table */
  0xffff, 0xffff, 0xffff
};

/* get distance from the distance table */
uint16_t get_distance_adjust(uint16_t e1, uint16_t e2)
{
  uint16_t i;
  i = 0;
  for(;;)
  {
    if ( distance_adjust_table[i] == 0x0ffff )
      break;
    if ( distance_adjust_table[i] == e1 && distance_adjust_table[i+1] == e2 )
      return distance_adjust_table[i+2];
    i+=3;
  }
  return 0;
}

int16_t draw_string(U8G2_FOR_ADAFRUIT_GFX &u8g2, int16_t x, int16_t y, const char *str)
{
  uint16_t e_prev = 0x0ffff;
  uint16_t e;
  uint16_t delta, adjust, sum;

  delta = 0;
  adjust = 0;
  u8g2.utf8_state = 0;

  sum = 0;
  for(;;)
  {
    e = u8g2.utf8_next((uint8_t)*str);
    if ( e == 0x0ffff )
      break;
    str++;
    if ( e != 0x0fffe )
    {
      delta = u8g2_GetGlyphWidth(&(u8g2.u8g2), e);      
      adjust = get_distance_adjust(e_prev, e);
      e_prev = e;
      u8g2_DrawGlyph(&(u8g2.u8g2), x-adjust, y, e);
      x += delta-adjust;
      sum += delta-adjust;    
    }
  }
  return sum;
}

void setup(void) {
  tft.initR(INITR_BLACKTAB);      // Init ST7735S chip, black tab
  tft.setRotation(0);
  tft.fillScreen(ST77XX_BLACK);
  u8g2_for_adafruit_gfx.begin(tft);
}

void loop() {
  u8g2_for_adafruit_gfx.setFont(u8g2_font_helvR14_tf);  // select u8g2 font from here: https://github.com/olikraus/u8g2/wiki/fntlistall
  u8g2_for_adafruit_gfx.setFontMode(1);                 // use u8g2 transparent mode (this is default)
  u8g2_for_adafruit_gfx.setFontDirection(0);            // left to right (this is default)
  u8g2_for_adafruit_gfx.setForegroundColor(ST77XX_WHITE);      // apply Adafruit GFX color
  u8g2_for_adafruit_gfx.setCursor(0,20);                // start writing at this position
  u8g2_for_adafruit_gfx.setFont(u8g2_font_unifont_t_bengali);  // select Bengali font
  draw_string(u8g2_for_adafruit_gfx, 0,20, "আমার সোনার");
  draw_string(u8g2_for_adafruit_gfx, 0,40, "বাংলা আমি");          // draw Bengali string
  draw_string(u8g2_for_adafruit_gfx, 0,60, "আব্দ");
  delay(2000); 
}

Here is the output:

20211121_115910

olikraus commented 2 years ago

Good question, but I don't know the answer. Maybe there is still a bug in the code?

muhit313 commented 2 years ago

Maybe there is still a bug in the code?

In which part of the code have bug? I can see all is ok. May be I had made some mistook when add char in in code ..... If you see the last code I post where I add some pair of char to reduce distance may be here is the bug? I am a not an professional programmer. As you are an expert you can find out the bug easily. If you can please tell me where are the bug.

olikraus commented 2 years ago

Maybe there is no bug. I also don't understand your problem clearly. Anyhow, I can give hints and maybe examples, but I can not solve your problems.

muhit313 commented 2 years ago

Maybe there is no bug. I also don't understand your problem clearly.

Yes you are right. I am not good at English too. That's why may be I fail to explain my problem. Sorry for that.

Anyhow, I can give hints and maybe examples, but I can not solve your problems.

Thanks for your continuous help by giving hints and examples. I am sorry for disturb you. You are right, I should solve my problem myself. Actually I am a learner that's why all things are not clear to me. Now I will try to solve it. But there is no good teacher besides me. I think you are really a good teacher for me.

There is no problem at all with your example.

  1. But when I want to show this word "সোনার" then স is hide. Only " োনার" is shown.
  2. And when I want to show this word "আব্দ" then ব is hide. Only "আদ" is shown.

Basically I don't know why it occurs.

Ok..... You should close this issue. Because I disturb you many times. Thanks you so much again.

olikraus commented 2 years ago

Did you use u8g2_for_adafruit_gfx.setFontMode(1); ? It is important to use the transparent mode.

muhit313 commented 2 years ago

Did you use u8g2_for_adafruit_gfx.setFontMode(1); ?

Yes, I used u8g2_for_adafruit_gfx.setFontMode(1);

You can see this in the code of the previous post.

I have a ssd1306 display too. Should I try it in ssd1306 display?

Or Is this two value is correct 0x09B8, 0x09CB, 12 //reduce distance between স and ো 0x09AE, 0x09BF, 10, //reduce distance between ম and ি May be here I had made a mistook.

olikraus commented 2 years ago

u8g2_for_adafruit_gfx.setFontMode(1); You can see this in the code of the previous post.

Yes, but it did work correctly when I tested this, so I think there is an issue with the font mode.

olikraus commented 2 years ago

my test happend here: https://github.com/olikraus/u8g2/blob/0c82f8cc5ec5cd4dd791e7df5a82f264ee44da3b/sys/sdl/text_kerning_manual/main.c#L92-L99

muhit313 commented 2 years ago

my test happend here: https://github.com/olikraus/u8g2/blob/0c82f8cc5ec5cd4dd791e7df5a82f264ee44da3b/sys/sdl/text_kerning_manual/main.c#L92-L99

You did it using c programming and may be compile with c compiler. I will test it in Arduino IDE. May I need to add some line from this code to previous code.

And that is:

do
    {
      k = u8g_sdl_get_key();
    } while( k < 0 );

    if ( k == 273 ) y -= 7;
    if ( k == 274 ) y += 7;
    if ( k == 276 ) x -= 7;
    if ( k == 275 ) x += 7;

    if ( k == 'e' ) y -= 1;
    if ( k == 'x' ) y += 1;
    if ( k == 's' ) x -= 1;
    if ( k == 'd' ) x += 1;
    if ( k == 'q' ) break;   
  }
  do
    {
      k = u8g_sdl_get_key();
    } while( k < 0 );

    if ( k == 273 ) y -= 7;
    if ( k == 274 ) y += 7;
    if ( k == 276 ) x -= 7;
    if ( k == 275 ) x += 7;

    if ( k == 'e' ) y -= 1;
    if ( k == 'x' ) y += 1;
    if ( k == 's' ) x -= 1;
    if ( k == 'd' ) x += 1;
    if ( k == 'q' ) break;  
}

This line are missing in previous code. Am I right?

But I am confused about u8g_sdl_get_key(); method. It made error when I compiled the code. Do I need to add the same method is arduino code?

olikraus commented 2 years ago

No, no, you can't takeover something. My test is u8g2 with SDL under Linux.

muhit313 commented 2 years ago

No, no, you can't takeover something. My test is u8g2 with SDL under Linux.

You mean that I don't need to add this line of code. Previous code are correct and work perfectly in you Linux SDL. And no need to add any extra line for "সোনার" this word?

muhit313 commented 2 years ago

I am really happy to meet a such helpful man like you. May be I can't solve it without your example and continuous help. You are really a great man for me. Thank you so much.

Finally I got the problem. When I remove u8g2_for_adafruit_gfx.setFont(u8g2_font_helvR14_tf); this line the code work perfectly for all word.

But In Bengali letter there are some compound letter like " ব্দ " which formed from "ব+্+দ" , and letter "ম্ম" is formed "ম+্+ম" . If this type of compound letter work then I can complete my main project perfectly.

Now I need to search for how to solve this " ব্দ " , "ম্ম" type of compound letter . I think this is difficult task than the previous one. But don't know how to do this.

olikraus commented 2 years ago

Now I need to search for how to solve this " ব্দ " , "ম্ম" type of compound letter . I think this is difficult task than the previous one. But don't know how to do this.

You might be used to enter "ম্ম" directly, but the problem is, that you do not know what character numbers are used by your editor (or Arduino IDE). It might be usefull to use the hex name of the intended letter, something like "\U00000444". This will not be readable, but you will have full control.

muhit313 commented 2 years ago

@olikraus After searching for longtime I saw that many people like david_prentice in Arduino forum suggest Oliver for help.

One person said that " ব্দ " , "ম্ম", "ল্ল", "স্ব" these are trigrams. So I need an additional table for trigrams. But don't know how to make a additional table for trigrams.

I think as an expert you know how to make additional table for trigrams for letter like " ব্দ " , "ম্ম", "ল্ল", "স্ব".

ZinggJM commented 2 years ago

One person suggested this:

I think you have 2 options.

Either you create a table with trigrams and distance adjustment, with '+্+' as the middle character, and also search through this table.

Or you create a table for trigrams, containing only the characters to combine with distance adjustment, and search through it whenever you encounter a '+্+'. In this case you draw the symbol for '+্+' if the adjacent characters are not found in the table.

This will terminate my effort to try to support you, as I have other pending work to do.

Jean-Marc

This forum section might be for you: Jobs and Paid Consultancy

in https://forum.arduino.cc/t/problem-with-utf8-or-unicode-support-in-any-display/928000/12?u=zinggjm

muhit313 commented 2 years ago

@ZinggJM Yes your are the person who suggest me this.

Can you give An example for trigram table for one compound letter?

ZinggJM commented 2 years ago

Yes, I could. Maybe next week.

muhit313 commented 2 years ago

Yes, I could. Maybe next week.

@ZinggJM Ok. Thank you. I am waiting for your replay.

olikraus commented 2 years ago

hmm never heard about trigrams. But all and all the problem becomes more and more complicated.

@muhit313 It is not like this, that we do not want to help, but this is beyond resources of open source developers. Help means: We can provide hints, but we are not able to provide code.

muhit313 commented 2 years ago

It is not like this, that we do not want to help, but this is beyond resources of open source developers. Help means: We can provide hints, but we are not able to provide code.

@olikraus Ok no problem. I want an example from you, Because i think as you develop this library so you may give me this.

Anyway I think you means this type of help is paid. Is my thinking right? If yes, there is no way. I am ready to pay you. Please let me know how much money should I pay? Email: muhitasraf@gmail.com

ZinggJM commented 2 years ago

Yes, I could. Maybe next week.

If you are so impatient as your wording sounds, you should give a reason. But yes, usually we give hints, as usual library users want to learn by coding themselves.

ZinggJM commented 2 years ago

But In Bengali letter there are some compound letter like " ব্দ " which formed from "ব+্+দ" , and letter "ম্ম" is formed "ম+্+ম" . If this type of compound letter work then I can complete my main project perfectly.

At first sight, the first case looked like it can be done by combining the two glyphs, using distance adjust. But in fact the wanted symbol needs a different glyph. For the second case this is more obvious. My coding attempt so far failed, and will never produce the desired result anyway.

@olikraus, do you know if these combined glyphs are available in the font?

ZinggJM commented 2 years ago

@olikraus, @muhit313,

I got code working for my approach somewhat, as far a that approach is usable.

But I have an issue with transparent mode in my setup, manifest on the first execution of loop(). Use setFontMode() after setFont() to fix.

updated:

#define USE_MY_ILI9486 0

#if !USE_MY_ILI9486

#include <Adafruit_GFX.h>
#include <Adafruit_ST7735.h>
#include <SPI.h>
#include <U8g2_for_Adafruit_GFX.h>

#define TFT_CS   8
#define TFT_RST  7
#define TFT_DC   6

Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);

#else

#include <U8g2_for_Adafruit_GFX.h>
#include <ILI9486_SPI.h> //Hardware-specific library
ILI9486_SPI tft(/*CS=D8*/ SS, /*DC=D3*/ 0, /*RST=D4*/ 2); // my D1 mini connection shield for e-paper displays

#endif

U8G2_FOR_ADAFRUIT_GFX u8g2_for_adafruit_gfx;

const uint16_t distance_adjust_table[] =
{
  /* first char, second char, gap reduction value */
  0x09AE, 0x9BE, 12, /* reduce distance between ম  and া  by 12 */
  /* add more pairs here... */
  0x09B8, 0x09CB, 14, //reduce distance between স and ো
  0x09A8, 0x09BE, 12, //reduce distance between ন and া
  0x09AE, 0x09BF, 16, //reduce distance between ম and ি
  0x09AC, 0x09BE, 12, //reduce distance between ব and া
  0x09BE, 0x0982, 12, //reduce distance between া and ং
  0x09B2, 0x09BE, 12, //reduce distance between ল and া
  0x09AC, 0x09CD, 12, //reduce distance between ব and ্
  0x09CD, 0x09A6, 12, //reduce distance between ্ and দ
  /* this line terminates the table */
  0xffff, 0xffff, 0xffff
};

const uint16_t trigram_distance_adjust_table[] =
{
  0x09AC, 0x09A6, 8,
  0x09B2, 0x09B2, 8,
  /* this line terminates the table */
  0xffff, 0xffff, 0xffff
};

/* get distance from the distance table */
uint16_t get_distance_adjust(uint16_t e1, uint16_t e2)
{
  uint16_t i;
  i = 0;
  for (;;)
  {
    if ( distance_adjust_table[i] == 0x0ffff )
      break;
    if ( distance_adjust_table[i] == e1 && distance_adjust_table[i + 1] == e2 )
      return distance_adjust_table[i + 2];
    i += 3;
  }
  return 0;
}

/* get distance from the distance table */
uint16_t get_trigram_distance_adjust(uint16_t e1, uint16_t e2)
{
  uint16_t i;
  i = 0;
  for (;;)
  {
    if ( trigram_distance_adjust_table[i] == 0x0ffff )
      break;
    if ( trigram_distance_adjust_table[i] == e1 && trigram_distance_adjust_table[i + 1] == e2 )
      return trigram_distance_adjust_table[i + 2];
    i += 3;
  }
  return 0;
}

int16_t draw_string(U8G2_FOR_ADAFRUIT_GFX &u8g2, int16_t x, int16_t y, const char *str)
{
  uint16_t e_prev = 0x0ffff;
  uint16_t e;
  uint16_t delta, adjust, sum;

  delta = 0;
  adjust = 0;
  u8g2.utf8_state = 0;

  sum = 0;
  for (;;)
  {
    e = u8g2.utf8_next((uint8_t) * str);
    if ( e == 0x0ffff )
      break;
    str++;
    //Serial.print("0x"); Serial.println(e, HEX);
    if ( e != 0x0fffe )
    {
      adjust = get_distance_adjust(e_prev, e);
      if ( e == 0x09CD)
      {
        // might be trigram, gets tricky
        const char* str_next = str;
        uint16_t e_next = 0x0fffe;;
        while (e_next == 0x0fffe) 
        {
          e_next = u8g2.utf8_next((uint8_t) * str_next);
          str_next++;
        }
        //Serial.print(">0x"); Serial.println(e_next, HEX);
        if (e_next == 0x0ffff) break;
        uint16_t adjust_next = get_trigram_distance_adjust(e_prev, e_next);
        if (adjust_next)
        {
          //Serial.print(">>"); Serial.println(adjust_next);
          adjust = adjust_next;
          e = e_next;
          str = str_next;
        }
      }
      delta = u8g2_GetGlyphWidth(&(u8g2.u8g2), e);
      e_prev = e;
      u8g2_DrawGlyph(&(u8g2.u8g2), x - adjust, y, e);
      x += delta - adjust;
      sum += delta - adjust;
    }
  }
  return sum;
}

void setup(void) {
#if !USE_MY_ILI9486
  tft.initR(INITR_BLACKTAB);      // Init ST7735S chip, black tab
  tft.setRotation(0);
  tft.fillScreen(ST77XX_BLACK);
#else
  tft.setSpiKludge(false); // false to disable rpi_spi16_mode
  tft.init();
  tft.fillScreen(0x0000);
  Serial.begin(115200);
#endif
  u8g2_for_adafruit_gfx.begin(tft);
}

void loop() {
  //u8g2_for_adafruit_gfx.setForegroundColor(ST77XX_WHITE);      // apply Adafruit GFX color
  u8g2_for_adafruit_gfx.setForegroundColor(0xFFFF);      // apply Adafruit GFX color
  //u8g2_for_adafruit_gfx.setBackgroundColor(0xF800);      // apply Adafruit GFX color
  u8g2_for_adafruit_gfx.setCursor(0, 20);               // start writing at this position
  u8g2_for_adafruit_gfx.setFont(u8g2_font_unifont_t_bengali);  // select Bengali font
  u8g2_for_adafruit_gfx.setFontMode(1);                 // use u8g2 transparent mode (this is default)
  u8g2_for_adafruit_gfx.setFontDirection(0);            // left to right (this is default)
  draw_string(u8g2_for_adafruit_gfx, 0, 20, "আমার সোনার");
  draw_string(u8g2_for_adafruit_gfx, 0, 40, "বাংলা আমি");         // draw Bengali string
  draw_string(u8g2_for_adafruit_gfx, 0, 60, "আব্দ ল্লাহ");
  //while (true) yield();
  delay(5000);
}
olikraus commented 2 years ago

@olikraus, do you know if these combined glyphs are available in the font?

According to this page there are two complicated chars are 0x09cb and 0x09cc. At least these two chars have something in the middle. Anyhow, all chars mentioned should be there in u8g2:

https://raw.githubusercontent.com/wiki/olikraus/u8g2/fntpic/u8g2_font_unifont_t_bengali.png

ZinggJM commented 2 years ago

Thank you, I think @muhit313 should take a look at the symbols, if there is a suitable replacement symbol that might be used with a trigram replacement table.

I need to fix the code I produced, there is an error and some unclear behavior. Done.

muhit313 commented 2 years ago

ccording to this page there are two complicated chars are 0x09cb and 0x09cc. At least these two chars have something in the middle. Anyhow, all chars mentioned should be there in u8g2:

https://raw.githubusercontent.com/wiki/olikraus/u8g2/fntpic/u8g2_font_unifont_t_bengali.png

@olikraus Thank you very much for example. In this table there is no combined glyphs liked ল্ল, ল্প, ন্ন, স্প, ন্ধ, ন্ড and many more. This type of letter made by using the normal letter showed in your given picture. I need letter like ল্ল, ল্প, ন্ন, স্প, ন্ধ, ন্ড and many more.

Thank you, I think @muhit313 should take a look at the symbols, if there is a suitable replacement symbol that might be used with a trigram replacement table. I need to fix the code I produced, there is an error and some unclear behavior. Done.

@ZinggJM Also thank your for adding an example. But your example is not working for ল্ল, ল্প, ন্ন, স্প, ন্ধ, ন্ড this type of letter.

ZinggJM commented 2 years ago

Yes, I said so:

At first sight, the first case looked like it can be done by combining the two glyphs, using distance adjust. But in fact the wanted symbol needs a different glyph. For the second case this is more obvious. My coding attempt so far failed, and will never produce the desired result anyway.

muhit313 commented 2 years ago

@olikraus If I want to complete this by paying money to an expert like you or @ZinggJM how much it will be cost ?

muhit313 commented 2 years ago

Another things, Can I set font size of u8g2_font_unifont_t_bengali this font?

olikraus commented 2 years ago

Difficult question. It depends also on your expectations: Would it be ok to have a solution which is based on the above table? This means: For each font the user (i mean you) has to provide a character shifting table. Second: We would need much more examples for Bengali words, which contain the glyphs with unicode 0x9bc and 0x9d7 in order to understand how this shifting should happen. Let's assume, you agree to the above table solution and you can additionally provde a list of Bengali words with the above unicodes. I would still asume that this will take a day for implementation.

olikraus commented 2 years ago

Can I set font size of u8g2_font_unifont_t_bengali this font?

No. On the fly scaling is not possible: Assume true type font: The corresponding library code is easily 500K in size. It will not it in most of the microcontrollers. In other words. font scaling is not an option for embedded microcontrolelrs.

Instead a different font with different size might be possible. u8g2_font_unifont_t_bengali font (like most other fonts in u8g2) is a fixed size bitmap font which was created by the brave people from https://unifoundry.com/, but it exists only at exactly one size.

Of course you can suggest other fonts and we can convert them to u8g2. But be warnded. .ttf is possible if we do a pre scaling as bitmap font, but results might be very poor due especially for small sizes.

Fonts from https://bengalifonts.net/fonts/sutonnymj-bold for example could be converted.

Another collection might be here: https://bengali.indiatyping.com/index.php/download-bengali-font/top-20-bengala-font

Again: The problem is to select a font which can be converted into a nice bitmap font for u8g2. The problem is: You need to open and investigate each and every font in detail to say this. Maybe you can just suggest one of the above fonts and I can check whether it can be converted or not.

ZinggJM commented 2 years ago

@muhit313,

I can see the text of your example from https://forum.arduino.cc/t/problem-with-utf8-or-unicode-support-in-any-display/928000 only in the browser, Windows Edge in my case. And I don't know if it is presented correctly, nor how Windows Edge does it, nor which true type font it uses.

@olikraus,

I only follow this issue with the intent to learn. I don't think I can contribute. But I will take a look at the fonts of your links. I would still be interested if any font has glyphs for the combined symbols, for the idea of a replacement table for the second case.

olikraus commented 2 years ago

@ZinggJM I use firefox (mostly) and it shows all the unicode glyphs nicely

olikraus commented 2 years ago

I spent some time to understand the construction of the words a little bit better. I fact i tried to find a word which includes 0x9cb or 0x9cc. Surprisingly there is one often used word in Bengali news which contains 0x9cb, which seems to be COVID: করোনা But the word is a good example. Separated with spaces it looks like this: করোনা ক র ো ন া HTML:

&#x0995;&#x09B0;&#x09CB;&#x09A8;&#x09BE;
&#x0995; &#x09B0; &#x09CB; &#x09A8; &#x09BE;

If we look more closer to &# x09B0;&# x09CB;: রো which is constructed out of র ো So the question is, how can u8g2 construct রো from র and ো? The above code implements া by shifting the second char to the left. I think the other required operation is shift of the previous char to the right.

Unfortunately there is one more case with chars like 0x09bf. What could be a suitable word for this? Maybe "digital" could be used: ডিজিটাল ড ি জ ি ট া ল Which is as HTML:

&#x09A1;&#x09BF;&#x099C;&#x09BF;&#x099F;&#x09BE;&#x09B2;
&#x09A1; &#x09BF; &#x099C; &#x09BF; &#x099F; &#x09BE; &#x09B2; 

So ডি is actually written as ড ি Which means, that the chars are swapped, but basically this could be similar to the র ো case. So we need two values for each pair:

  1. first char shift right
  2. second char shift left

After this the cursor position will be set to first char + deltax or second char+deltax, whatever sum has higher x coordinates.

how much it will be cost ?

I take a beer.

olikraus commented 2 years ago

The output of the glyphs becomes more complicated, because we need to delay the output of the previous glyph until we know whether we have to apply the right shift for the first char or not.

Let me design pseudo code:

prev_glyph = <no char>;
for(;;) {
  current_glyph = get_next_glyph()
  if ( current_glyph == 0xffff ) {  // handle end of string
    if ( prev_glyph != <no char> ) output(prev_glyp);
  }
  if ( prev_glyph == <no char> ) { 
    prev_glyph = current_glyph;
  } else {
    if ( /* kerning exists for prev_glyph and current_glyph */ ) {
     // apply shifts to both glyphs
     // calculate new cursor position
     prev_glyph = <no char>;
    } else {
     output(prev_char);
     prev_glyph = current_glyph;
    }
  }
}

how much it will be cost ?

I take one more beer.

muhit313 commented 2 years ago

It depends also on your expectations: Would it be ok to have a solution which is based on the above table?

Now my expectation is only show combined letter like ক্ক, ম্ম, স্ক, ব্দ, ক্ষ so on, which are made from ক+্+ক=ক্ক, ম +্+ম = ম্ম, স+্+ক=স্ক, ক+্+ষ=ক্ষ.

Because you already give me an example of normal glyph করোনা, ডিজিটাল which works perfectly with your previous example code.

muhit313 commented 2 years ago

Instead a different font with different size might be possible.

Yes, I also need different font with different size. Is this kalpurus font can be convert into u8g2 font. If yes, then what is the minimum size can be done?

করোনা ক র ো ন া ডিজিটাল ড ি জ ি ট া ল

This type of word works fine without any problem with your previous example code.

Now I need combine glyph like ক্ক, ম্ম, স্ক, ব্দ, ক্ষ so on, which are made from the more then one normal glyph like ক+্+ক=ক্ক, ম +্+ম = ম্ম, স+্+ক=স্ক, ক+্+ষ=ক্ষ.

I take a beer.

Ok then PM me in muhitasraf@gmail.com What will be it cost in us dollar ($)?