LOGO パソコン制御をもっと気軽に  
電子制御をもっと気楽に

漢字フォントの表示 KanjiDisplay

2026/01/05

Adafruit_GFX を継承する表示器に漢字を表示するためのライブラリーです。
cKanjiDisplayと元の表示器のクラスを多重継承することで漢字対応できます。
  SSD1306を漢字対応にした cKanjiDisplay_SSD1306
  ST7789を漢字対応にした cKanjiDisplay_ST7789
を参考にすれば簡単です。
ZIP file( 231Kbyte )

Viewer

KanjiDisplay/src/KanjiDisplay.cpp
#include <arduino.h>
#include <KanjiDisplay.h>

#ifdef USE_SHINONOME12_ALL
  #include "Kanji/Fonts/JF-Dot-Shinonome12_12x12_ALL.inc"		// 東雲14x14、JIS第1+2+記号その他
#endif
#ifdef USE_SHINONOME12_LEVEL1
  #include "Kanji/Fonts/JF-Dot-Shinonome12_12x12_LEVEL1.inc"	// 東雲14x14、JIS第1
#endif
#ifdef USE_SHINONOME12_SCHOOL
  #include "Kanji/Fonts/JF-Dot-Shinonome12_12x12_SCHOOL.inc"	// 東雲14x14、scool level
#endif

#ifdef USE_SHINONOME14_ALL
  #include "Kanji/Fonts/JF-Dot-Shinonome14_14x14_ALL.inc"		// 東雲14x14、JIS第1+2+記号その他
#endif
#ifdef USE_SHINONOME14_LEVEL1
  #include "Kanji/Fonts/JF-Dot-Shinonome14_14x14_LEVEL1.inc"	// 東雲14x14、JIS第1
#endif
#ifdef USE_SHINONOME14_SCHOOL
  #include "Kanji/Fonts/JF-Dot-Shinonome14_14x14_SCHOOL.inc"	// 東雲14x14、scool level
#endif


void cKanjiDisplay::SelectFont(FontKind aFontKind)
{
  SelectedFontKind = aFontKind ;
  switch ( aFontKind )
  {
  #ifdef USE_SHINONOME12_ALL
    case FontKind::Shinonome12_A:
      KanjiFont.SetKanjiFont(JFDotShinonome12_12x12_ALL,JFDotShinonome12_12x12_ALL_bitmap);
    break;
  #endif
  #ifdef USE_SHINONOME12_LEVEL1
    case FontKind::Shinonome12_1:
      KanjiFont.SetKanjiFont(JFDotShinonome12_12x12_LEVEL1,JFDotShinonome12_12x12_LEVEL1_bitmap);
    break;
  #endif
  #ifdef USE_SHINONOME12_SCHOOL
    case FontKind::Shinonome12_S:
      KanjiFont.SetKanjiFont(JFDotShinonome12_12x12_SCHOOL,JFDotShinonome12_12x12_SCHOOL_bitmap);
    break;
  #endif
  #ifdef USE_SHINONOME14_ALL
    case FontKind::Shinonome14_A:
      KanjiFont.SetKanjiFont(JFDotShinonome14_14x14_ALL,JFDotShinonome14_14x14_ALL_bitmap);
    break;
  #endif
  #ifdef USE_SHINONOME14_LEVEL1
    case FontKind::Shinonome14_1:
      KanjiFont.SetKanjiFont(JFDotShinonome14_14x14_LEVEL1,JFDotShinonome14_14x14_LEVEL1_bitmap);
    break;
  #endif
  #ifdef USE_SHINONOME14_SCHOOL
    case FontKind::Shinonome14_S:
      KanjiFont.SetKanjiFont(JFDotShinonome14_14x14_SCHOOL,JFDotShinonome14_14x14_SCHOOL_bitmap);
    break;
  #endif
  }
}



const KanjiData * cKanjiDisplay::KanjiWrite( int x, int y, uint8_t c,uint16_t color )
{
  //Serial.printf( "Utf8=%02X\n",c);
  if ( UTF8RemainByteCount == 0 ){
    if ( (c & 0x80) == 0x00) {
      UTF8Code=c;
      UTF8RemainByteCount=0;
      return DrawUTF8( x,y,UTF8Code,color) ;
    }
    if ( (c & 0xE0) == 0xC0) {
      UTF8Code=c;
      UTF8RemainByteCount=1;
      return NULL ;
    }
    if ( (c & 0xF0) == 0xE0) {
      UTF8Code=c;
      UTF8RemainByteCount=2;
      return NULL ;
    }
    if ( (c & 0xF8) == 0xF0) {
      UTF8Code=c;
      UTF8RemainByteCount=3;
      return NULL ;
    }
    // // decode error
    UTF8Code = 0;
    UTF8RemainByteCount=0;
    return NULL ;

  } else {
    if ( (c & 0xC0) != 0x80) {
      // decode error
      UTF8Code = 0;
      UTF8RemainByteCount=0;
      return NULL ;
    }
    UTF8Code = (UTF8Code<<8) | c ;
    UTF8RemainByteCount--;
    if ( UTF8RemainByteCount!=0 )
      return NULL ;
    //
    // Serial.printf( "Utf8=%08X\n",UTF8Code);
    return DrawUTF8( x,y,UTF8Code,color) ;
  }
}

int cKanjiDisplay::StrToUtf8Code(const char* pUTF8, uint32_t * Utf8Code )
{
  uint8_t b0 ;
  uint8_t bb ;
  b0 = *pUTF8++ ;
  *Utf8Code = b0 ;
  if ( (b0 & 0x80) == 0x00) {
      return 1;
  }
  //
  bb = *pUTF8++ ;
  if ( (bb & 0xC0) != 0x80)
    return 0 ;  
  *Utf8Code = (*Utf8Code<<8) | bb ;
  if ( (b0 & 0xE0) == 0xC0) {
      return 2;
  }
  //
  bb = *pUTF8++ ;
  if ( (bb & 0xC0) != 0x80)
    return 0 ;  
  *Utf8Code = (*Utf8Code<<8) | bb ;
  if ( (b0 & 0xF0) == 0xE0) {
      return 3;
  }
  //
  bb = *pUTF8++ ;
  if ( (bb & 0xC0) != 0x80)
    return 0 ;  
  *Utf8Code = (*Utf8Code<<8) | bb ;
  if ( (b0 & 0xF8) == 0xF0) {
      return 4;
  }
  return 0 ;
}

const KanjiData * cKanjiDisplay::DrawUTF8( int x, int y, uint32_t Utf8Code, uint16_t color )
{
    const KanjiData * Kanji = KanjiFont.FindKanji(Utf8Code);
    if( Kanji == NULL ){
      Serial.printf("KanjiData not found\n");
      return NULL ;
    }
  
    const uint8_t * bmp = KanjiFont.getBmpData(Kanji) ;
    vDrawBitmap(x, y, bmp, Kanji->width, Kanji->height, color);

    return Kanji ;


}

void cKanjiDisplay::DrawString( int x, int y, const char * str, uint16_t color)
{
  while ( *str )
  {
    uint32_t Utf8Code;
    int Cu=StrToUtf8Code( str , & Utf8Code) ;
    if (Cu==0){
      Serial.printf("StrToUtf8Code decode error\n");
      return;
    }
    const KanjiData * Kanji = DrawUTF8( x,y,Utf8Code,color) ;
    if( Kanji == NULL )
      return ;
    x += Kanji->width ;
    str += Cu ;
  }
}

シーブイデブ e-mail:mnakatani@cvdev-jp.com