Create array of predefined arrays

114 Views Asked by At

With the help of PlatformIO and the U8G2 library, I want to write an application for an ESP8266 microcontroller. The U8G2 offers countless fonts, and I would like to display them on a graphical display so that I can select the appropriate ones. Each font is defined as follows:

extern const uint8_t u8g2_font_logisoso50_tn[] U8G2_FONT_SECTION("u8g2_font_logisoso50_tn");

about 2000 different way, where the macros are defined as

#define U8G2_FONT_SECTION(name) U8X8_FONT_SECTION(name)
...
#  define U8X8_FONT_SECTION(name) __attribute__((section(".text." name)))
...
typedef __uint8_t uint8_t ;
...
typedef unsigned char __uint8_t ;

The font is displayed by a function

void setFont(const uint8_t *font)

I want to create an array from the list of fonts, which I can iterate through and show them one by one on the display.

const char* fonts[] = {
  "u8g2_font_u8glib_4_tf",
  ...
};

and display using this:

u8g2.setFont( U8G2_FONT_SECTION(fonts[pos]) );

but the compiler gives error as follows:

In file included from .pio\libdeps\d1\U8g2\src/U8x8lib.h:47,
                 from .pio\libdeps\d1\U8g2\src/U8g2lib.h:53,
                 from src\main.cpp:2:
src\main.cpp: In function 'void put()':
.pio\libdeps\d1\U8g2\src/clib/u8x8.h:162:35: error: expected primary-expression before '__attribute__'
  162 | #  define U8X8_FONT_SECTION(name) __attribute__((section(".text." name)))
      |                                   ^~~~~~~~~~~~~
.pio\libdeps\d1\U8g2\src/clib/u8g2.h:188:33: note: in expansion of macro 'U8X8_FONT_SECTION'
  188 | #define U8G2_FONT_SECTION(name) U8X8_FONT_SECTION(name)
      |                                 ^~~~~~~~~~~~~~~~~
src\main.cpp:18:20: note: in expansion of macro 'U8G2_FONT_SECTION'
   18 |   uint8_t font[] = U8G2_FONT_SECTION(fonts[pos]);
      |                    ^~~~~~~~~~~~~~~~~
*** [.pio\build\d1\src\main.cpp.o] Error 1

What else should I write?

1

There are 1 best solutions below

0
On

Simply define an array of pointers:

Example:

const uint8_t* fonts[] = {
  u8g2_font_u8glib_4_tf,
  u8g2_font_u8glib (etc...) ,
  ...
};

You can be a bit more inventive and crate a map:

struct font_info
{
    const char* name;
    const uint8_t* font;
};

// use a stringifying macro to painlessly generate displayable names 
// for your fonts
#define FONT_INFO(x)  font_info{ #x, x }

const font_info fonts[] = 
{
    FONT_INFO(u8g2_font_u8glib_4_tf),
    FONT_INFO(u8g2_font_u8glib (whatever the next one is...),
    ...
};

// later...

for (const auto& f : fonts)
{
    display_font_name(f.name);   // your own display function
    u8g2.setfont(f.font);
    display_font_sample_text();  // your own text sample display function
    wait_for user_input();       // you'll need to wait a bit so the user 
                                 // can see the font being displayed.
};

Or something close to that, so you can display the font name as well, if needed.