LovyanGFX for PC を Ubuntu Linux で試す

遅くなって申し訳ない! 2日目分の記事を投稿します。

@pokibon(秋葉原ロボット部)さんの1日目の投稿
「LovyanGFX for Windowsを使ってみた」
https://qiita.com/pokibon/items/4f6f9b1f733ad60c708a

にて Windows で LovyanGFX を使えるようになりましたが、Ubuntu Linux でも使いたいので試してみました。

# 環境

- Ubuntu 22.04 LTS
- SDL2

# 下準備


SDLをこちらの記事の通り設定しています。

「SDL2 のサンプルプログラムを試す」
https://qiita.com/nanbuwks/items/379013b65fa10ce042a5


# Linux 対応版の LovyanGFX を用意

https://github.com/lovyan03/LovyanGFX/blob/develop/examples_for_PC/CMake_SDL/CMakeLists.txt
では、Linux に対応しそうな感じになっています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/4bd91dfd-1d7b-48ec-0f81-92e0b447e1d6.png)

しかしながら Ubuntu 上の g++ だと、コンパイルエラーが生じてしまいました。

```
.
.
.
../../../LovyanGFX/src/lgfx/utility/lgfx_pngle.c:562:16: note:   crosses initialization of ‘uint32_t chunk_remain_3’
  562 |       uint32_t chunk_remain_3 = chunk_remain / 3;
      |                ^~~~~~~~~~~~~~
../../../LovyanGFX/src/lgfx/utility/lgfx_qoi.c: In function ‘size_t lgfx_qoi_encode(const void*, const qoi_desc_t*, int, lgfx_qoi_encoder_get_row_func, lfgx_qoi_writer_func, void*)’:
../../../LovyanGFX/src/lgfx/utility/lgfx_qoi.c:319:33: error: invalid conversion from ‘void*’ to ‘qoi_rgba_t*’ [-fpermissive]
  319 |   qoi_rgba_t *qoi_index = calloc( 64, sizeof( qoi_rgba_t ) );
      |                           ~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~
      |                                 |
      |                                 void*
../../../LovyanGFX/src/lgfx/utility/lgfx_qoi.c:335:19: warning: format ‘%d’ expects argument of type ‘int’, but argument 3 has type ‘size_t’ {aka ‘long unsigned int’} [-Wformat=]
  335 |     debug_printf( "Can't malloc %d bytes", writeBufferSize);
      |                   ^~~~~~~~~~~~~~~~~~~~~~~  ~~~~~~~~~~~~~~~
      |                                            |
      |                                            size_t {aka long unsigned int}
../../../LovyanGFX/src/lgfx/utility/lgfx_qoi.c:73:43: note: in definition of macro ‘debug_printf’
   73 | #define debug_printf(...) fprintf(stderr, __VA_ARGS__)
      |                                           ^~~~~~~~~~~
../../../LovyanGFX/src/lgfx/utility/lgfx_qoi.c:335:34: note: format string is defined here
  335 |     debug_printf( "Can't malloc %d bytes", writeBufferSize);
      |                                 ~^
      |                                  |
      |                                  int
      |                                 %ld
../../../LovyanGFX/src/lgfx/utility/lgfx_tjpgd.c: In function ‘JRESULT lgfx_jd_prepare(lgfxJdec*, uint32_t (*)(void*, uint8_t*, uint32_t), void*, uint_fast16_t, void*)’:
../../../LovyanGFX/src/lgfx/utility/lgfx_tjpgd.c:912:22: error: jump to case label
  912 |                 case 0xC1:      /* SOF1 */
      |                      ^~~~
../../../LovyanGFX/src/lgfx/utility/lgfx_tjpgd.c:905:33: note:   crosses initialization of ‘int32_t dc’
  905 |                         int32_t dc = infunc(dev, seg + ofs, JD_SZBUF - ofs);
      |                                 ^~
.
.
.
```

らびやんさんにお聞きすると、 clang  でビルドしているそうです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/99a1195e-edcf-73ca-80da-a87fde9520fc.png)

どうやら g++ とは微妙に仕様が異なっている模様。
develop branch 上の LovyanGFX にて修正版を公開いただきましたので、今回はこれを使うことにします。

https://github.com/lovyan03/LovyanGFX/tree/develop

こちらから、 LovyanGFX-develop.zip をダウンロードします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/ba29d2fe-78e3-f82d-acc3-c4d648bb1db3.png)


適当な場所に LovyanGFX という場所に展開し、以下の場所に移ります。
```
$ cd LovyanGFX/
$ cd examples_for_PC/
$ cd CMake_SDL

```

なお、LovyanGFX-develop というフォルダになった場合は LovyanGFX という名前に変更してください。
# 手直し

~~../../../LovyanGFX/src/lgfx/utility/lgfx_qoi.c の 319行目~~

(2022/12/18 追記： この箇所の手直しは 2022/12/12 の develop branch 18a5440 で不要になりました)

```
  qoi_rgba_t *qoi_index = calloc( 64, sizeof( qoi_rgba_t ) );

```
↓

```

  qoi_rgba_t *qoi_index = static_cast<qoi_rgba_t *>(calloc( 64, sizeof( qoi_rgba_t ) ) );
```

また、あれこれ試したのですがフォントシンボルがリンクできないエラーが解消しませんでした。
```
/usr/bin/ld: /tmp/ccZHbtfd.o:(.data.rel.ro+0x8): undefined reference to `lgfx_font_japan_mincho_8&apos;
/usr/bin/ld: /tmp/ccZHbtfd.o:(.data.rel.ro+0x18): undefined reference to `lgfx_font_japan_mincho_12&apos;
/usr/bin/ld: /tmp/ccZHbtfd.o:(.data.rel.ro+0x28): undefined reference to `lgfx_font_japan_mincho_16&apos;
/usr/bin/ld: /tmp/ccZHbtfd.o:(.data.rel.ro+0x38): undefined reference to `lgfx_font_japan_mincho_20&apos;
/usr/bin/ld: /tmp/ccZHbtfd.o:(.data.rel.ro+0x48): undefined reference to `lgfx_font_japan_mincho_24&apos;
/usr/bin/ld: /tmp/ccZHbtfd.o:(.data.rel.ro+0x58): undefined reference to `lgfx_font_japan_mincho_28&apos;
/usr/bin/ld: /tmp/ccZHbtfd.o:(.data.rel.ro+0x68): undefined reference to `lgfx_font_japan_mincho_32&apos;
/usr/bin/ld: /tmp/ccZHbtfd.o:(.data.rel.ro+0x78): undefined reference to `lgfx_font_japan_mincho_36&apos;
.
.
.

```

~~なので負けを認めて、 "../../src/lgfx/v1/lgfx_fonts.cpp" の 1193 行目から 1310 行目までをコメントアウトします。~~

!!! 2022/12/18 追記 !!!
解決しました! アドベントカレンダー11日目、ないし13日目をご覧ください!
以下に記されているコメントアウト作業は必要ありません。また、ビルドオプションは アドベントカレンダー11日目、ないし13日目 のものを使ってください。


```
    const FixedBMPfont AsciiFont24x48 = { FontLib24x48, fontlib24x48_info, 24, 48, 40 };
/*

    const U8g2font lgfxJapanMincho_8   = { lgfx_font_japan_mincho_8    };
    const U8g2font lgfxJapanMincho_12  = { lgfx_font_japan_mincho_12   };
    const U8g2font lgfxJapanMincho_16  = { lgfx_font_japan_mincho_16   };
    const U8g2font lgfxJapanMincho_20  = { lgfx_font_japan_mincho_20   };

.
.
.

    const U8g2font efontTW_16_bi  = { lgfx_efont_tw_16_bi };
    const U8g2font efontTW_16_i   = { lgfx_efont_tw_16_i  };
    const U8g2font efontTW_24     = { lgfx_efont_tw_24    };
    const U8g2font efontTW_24_b   = { lgfx_efont_tw_24_b  };
    const U8g2font efontTW_24_bi  = { lgfx_efont_tw_24_bi };
*/

```
~~` const U8g2font 〜 ` を全部コメントアウトします。~~
 
# コンパイル

サンプルプログラムビルドします。

```
$ g++ -o LGFX_SDL LGFX_SDL.cpp user_code.cpp ../../../LovyanGFX/src/lgfx/Fonts/efont/*.c ../../../LovyanGFX/src/lgfx/Fonts/IPA/*.c ../../../LovyanGFX/src/lgfx/utility/*.c ../../../LovyanGFX/src/lgfx/v1/*.cpp ../../../LovyanGFX/src/lgfx/v1/misc/*.cpp ../../../LovyanGFX/src/lgfx/v1/panel/Panel_Device.cpp ../../../LovyanGFX/src/lgfx/v1/platforms/sdl/*.cpp  -lm -lSDL2  -lSDL2_image -I../../../LovyanGFX/src -I../../../LovyanGFX/src/lgfx/v1 -I../../../LovyanGFX/src/lgfx/Fonts/efont -L../../../LovyanGFX/src/lgfx -DLGFX_SDL 
```

これで  LGFX_SDL という実行ファイルができます。

```

$ ./LGFX_SDL
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/9d70e6ed-b4f9-1cab-5118-290dce0693bc.png)

実行できました

# Pokibon さんのサンプルプログラムを実行する


1日目のサンプルプログラムは、Sleepを実現するために
```
#include <windows.h>    // Sleep()を使うために追加
```

というように書いています。
これを Linux 用のライブラリに直してもいいのですが、今回 SDL2 を使っているので SDLのDelay関数を使ってみました。

まずは上記をコメントアウトして、`Sleep(10);` などとなっているところを `SDL_Delay(10);` というように書き換えます。

 うまくいきました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/3bd5988c-5ed3-3a60-fe8d-44784cb83659.png)