Arduino core for the ESP32では、ファイルシステム関連のライブラリは、FSクラスを継承するようなつくりとなっています。このため、今回作成したライブラリは、内部ではFSクラスだけを利用し、実際の実装については、パラメータで渡すような作りとしました。今回はSPIFFSで試しましたが、おそらく、SDカードを利用したときも利用できるのではないかと思います。ただし、実際に試してはいません。
#pragma once
#include<FS.h>typedefstruct{uint8_twidth;// Font width
uint8_theight;// Font height
uint8_tcodeFlag;// Code flag: 0 -> 1byte font, 1 -> 2byte font
uint8_tnumCodeBlocks;// Number of code block
uint8_tglyphSize;// Glyph size: per character size
fs::Filefs;// File structure for font file
}fontxFile_t;class fontxClass{public:fontxClass();boolbegin(FS*fs,constchar*hfile,constchar*zfile);voidend();boolgetGlyph(uint16_tcode,uint8_t*width,uint8_t*height,uint8_t*glyph);private:fontxFile_tfonts[2];boolopenFontx(FS*fs,constchar*filepath,intcodeFlag);intnumFonts;};
#include"fontxClass.h"fontxClass::fontxClass(){numFonts=0;}boolfontxClass::begin(FS*fs,constchar*hfile,constchar*zfile){if(!numFonts&&openFontx(fs,hfile,0)&&openFontx(fs,zfile,1)){returntrue;}else{returnfalse;}}voidfontxClass::end(){numFonts=0;for(inti=0;i<2;i++){fonts[i].fs.close();}}boolfontxClass::openFontx(FS*fs,constchar*filepath,intcodeFlag){charbuf[18];if(fonts[codeFlag].fs=fs->open(filepath,"r")){fonts[codeFlag].fs.readBytes(buf,sizeof(buf));fonts[codeFlag].width=buf[14];fonts[codeFlag].height=buf[15];fonts[codeFlag].codeFlag=buf[16];fonts[codeFlag].numCodeBlocks=buf[17];// for multibyte character set
fonts[codeFlag].glyphSize=(fonts[codeFlag].width+7)/8*fonts[codeFlag].height;if(fonts[codeFlag].codeFlag!=codeFlag){end();returnfalse;}numFonts++;returntrue;}returnfalse;}boolfontxClass::getGlyph(uint16_tscode,uint8_t*width,uint8_t*height,uint8_t*glyph){uint8_tncb;uint16_tstartCode,endCode;uint8_tfontIndex;uint16_tnumChars=0;uint32_toffset=0;uint8_tindex;if(scode<0x100){// single-byte character
index=0;offset=17+scode*fonts[index].glyphSize;}else{// multibyte character
index=1;ncb=fonts[index].numCodeBlocks;fonts[index].fs.seek(18);while(ncb--){fonts[index].fs.readBytes((char*)&startCode,2);fonts[index].fs.readBytes((char*)&endCode,2);if((scode>=startCode)&&(scode<=endCode)){// found the code
numChars+=scode-startCode;offset=18+4*fonts[index].numCodeBlocks+numChars*fonts[index].glyphSize;break;}numChars+=endCode-startCode+1;// add the number of characters in the code block
}}if(offset){fonts[index].fs.seek(offset);fonts[index].fs.readBytes((char*)glyph,fonts[index].glyphSize);*width=fonts[index].width;*height=fonts[index].height;returntrue;}returnfalse;}