5 #include <Multimedia/SDX.h> 
    6 #include <Multimedia/Screen.h> 
    7 #include <Multimedia/IFont.h> 
    8 #include <Multimedia/SystemFont.h> 
    9 #include <Multimedia/Image.h> 
   10 #include <Framework/ImagePack.h> 
   11 #include <Multimedia/Window.h> 
   12 #include <Multimedia/File.h> 
   15 #include <unordered_map> 
   28         TTF_Font* handle = 
nullptr;
 
   32         mutable std::unordered_map<int, Image*> hash;
 
   34         int style = TTF_STYLE_NORMAL;
 
   36         static bool GetUTFSize(
unsigned char 一文字目,
int &文字長さ )
 
   45             if (一文字目 < 0x80){ 文字長さ = 1; }
 
   46             else if (一文字目 < 0xE0){ 文字長さ = 2; }
 
   47             else if (一文字目 < 0xF0){ 文字長さ = 3; }
 
   53         void DrawUTFString(
const Point &座標, 
const std::string &文字列 , 
const Color &描画色)
 const 
   58             for (
auto it = 文字列.begin(); it != 文字列.end(); it += charSize)
 
   60                 if (!GetUTFSize(*it, charSize)){ 
continue; }
 
   61                 if (handle == 
nullptr && *it == 
' ')
 
   67                 Image* str = GetHash(文字列.substr(std::distance(文字列.begin(), it), charSize).c_str() , charSize);
 
   68                 if (str == 
nullptr){ 
continue; }
 
   76         void DrawUTFString(
const Point &座標, 
double X拡大率, 
double Y拡大率, 
const std::string &文字列, 
const Color &描画色)
 const 
   81             for (
auto it = 文字列.begin(); it != 文字列.end(); it += charSize)
 
   83                 if (!GetUTFSize(*it, charSize)){ 
continue; }
 
   85                 Image* str = GetHash(文字列.substr(std::distance(文字列.begin(), it), charSize).c_str(),charSize);
 
   98         void DrawRotateUTFString(
const Point &座標, 
int X補正, 
int Y補正, 
double 拡大率, 
double 角度, 
const std::string &文字列, 
const Color &描画色)
 const 
  103             for (
auto it = 文字列.begin(); it != 文字列.end(); it += charSize)
 
  105                 if (!GetUTFSize(*it, charSize)){ 
continue; }
 
  107                 Image* str = GetHash(文字列.substr(std::distance(文字列.begin(), it), charSize).c_str(),charSize);
 
  114                 X補正 += int(str->
GetWidth() * 拡大率 * 0.5);
 
  115                 double x = 位置.
x + std::cos(角度) * X補正 + std::cos(角度 + 
PAI / 2) * Y補正;
 
  116                 double y = 位置.
y + std::sin(角度) * X補正 + std::sin(角度 + 
PAI / 2) * Y補正;
 
  120                 X補正 += int(str->
GetWidth() * 拡大率 * 0.5);
 
  125         Image* GetHash(
const char* 文字 , 
int 文字長さ)
 const 
  128             if (文字長さ >= 2){ ID += 文字[1]*256; }
 
  129             if (文字長さ >= 3){ ID += 文字[2]*256*256; }
 
  130             if (文字長さ >= 4){ ID += 文字[3] * 256 * 256 * 256; }
 
  132             auto it = hash.find(ID);
 
  134             if (it == hash.end())
 
  136                 if (handle == 
nullptr){ 
return nullptr; }
 
  138                 SDL_Surface* surface = 
nullptr;
 
  140 #ifndef OMIT_SDL2_TTF 
  143                     surface = TTF_RenderUTF8_Blended(handle, 文字, { 255, 255, 255 });
 
  147                     surface = TTF_RenderUTF8_Solid(handle, 文字, { 255, 255, 255 });
 
  152                 hash[ID] = 
new Image(moji, surface->w, surface->h);
 
  154                 SDL_FreeSurface(surface);
 
  161         void SetHash(
const char* 文字, 
int 文字長さ, 
Image *対応Image)
 
  164             if (文字長さ >= 2){ ID += 文字[1] * 256; }
 
  165             if (文字長さ >= 3){ ID += 文字[2] * 256 * 256; }
 
  166             if (文字長さ >= 4){ ID += 文字[3] * 256 * 256 * 256; }
 
  175         Font(
const char *フォント名, 
int 大きさ, 
int 行間 = 0 , 
bool 高品質レンダリングフラグ = 
true )
 
  177             Load(フォント名, 大きさ, 行間, 高品質レンダリングフラグ);
 
  183         bool Load(
const char *フォント名, 
int 大きさ, 
int 行間 = 0, 
bool 高品質レンダリングフラグ = 
true )
 
  185             if (Loading::isLoading)
 
  192             if (handle != 
nullptr){ 
return false; }
 
  195             this->enterHeight = 行間 + 大きさ;
 
  196             isBlendRender = 高品質レンダリングフラグ;
 
  198 #ifndef OMIT_SDL2_TTF 
  199             handle = TTF_OpenFont(フォント名, 大きさ);
 
  202             return (handle != 
nullptr);
 
  210             if (handle != 
nullptr){ 
return false; }
 
  211             TTF_CloseFont(handle);
 
  212             for (
auto && it : hash)
 
  214                 it.second->Release();
 
  228             if (handle == 
nullptr){ 
return Image(); }
 
  231             int 高さ = ((int)描画する文字列.
StringS.size() - 1) * enterHeight + size;
 
  234             std::vector<SDL_Surface*> surfaces;
 
  235             SDL_Surface* surface;
 
  237             for (
auto it : 描画する文字列.
StringS)
 
  241                     surface = TTF_RenderUTF8_Blended(handle, it.c_str(), 文字色);
 
  245                     surface = TTF_RenderUTF8_Solid(handle, it.c_str(), 文字色);
 
  248                 幅 = std::max(幅, surface->w);
 
  249                 surfaces.push_back(surface);
 
  252             SDL_Surface* toRend = SDL_CreateRGBSurface(0, 幅, 高さ, 32, 0, 0, 0, 0);
 
  253             SDL_Renderer* render = SDL_CreateSoftwareRenderer(toRend);
 
  255             for (
auto it : surfaces)
 
  257                 SDL_Texture* texture = SDL_CreateTextureFromSurface(render, it);
 
  259                 SDL_Rect temp = { 0, Y座標, it->w, it->h };
 
  260                 SDL_RenderCopy(render, texture, 0, &temp);
 
  262                 Y座標 += this->enterHeight;
 
  265                 SDL_DestroyTexture(texture);
 
  270             SDL_FreeSurface(toRend);
 
  271             SDL_DestroyRenderer(render);
 
  282             this->enterHeight = 行間 + 大きさ;
 
  291             if (handle == 
nullptr){ 
return false; }
 
  292             SDL_Surface* surface;
 
  304             Uint32 rmask, gmask, bmask, amask;
 
  305 #if SDL_BYTEORDER == SDL_BIG_ENDIAN 
  319             int count = strS.size();
 
  321             unsigned int index = 0;
 
  323             if( (
unsigned char)strS[0][0] == 0xEF && (
unsigned char)strS[0][1] == 0xBB && (
unsigned char)strS[0][2] == 0xBF ){index = 3;}
 
  327                 if( strS[0].size() <= index ){
break;}
 
  329                 if( (
unsigned char)strS[0][index] < 0x80 ){index += 1;}
 
  330                 else if ( (
unsigned char)strS[0][index] < 0xE0){ index += 2; }
 
  331                 else if ( (
unsigned char)strS[0][index] < 0xF0){ index += 3; }
 
  337             int high = TTF_FontHeight(handle);
 
  338             surface = SDL_CreateRGBSurface(0, size * 32 , high * (12+((count+31)/32) ) , 32, rmask, gmask, bmask, amask);
 
  343             for (
int a = 0; a < 12; ++a)
 
  348                     case  0: str = 
"!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`"; 
break;
 
  349                     case  1: str = 
"abcdefghijklmnopqrstuvwxyz{|}~。「」、・ヲァィゥェォャュョッーアイウエオカキクケコサシスセソ"; 
break;
 
  350                     case  2: str = 
"タチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン゙゚ "; 
break;
 
  351                     case  3: str = 
"ぁあぃいぅうぇえぉおかがきぎくぐけげこごさざしじすずせぜそぞただ"; 
break;
 
  352                     case  4: str = 
"ちぢっつづてでとどなにぬねのはばぱひびぴふぶぷへべぺほぼぽまみむ"; 
break;
 
  353                     case  5: str = 
"めもゃやゅゆょよらりるれろゎわゐゑをんゔゕゖ "; 
break;
 
  354                     case  6: str = 
"ァアィイゥウェエォオカガキギクグケゲコゴサザシジスズセゼソゾタダ"; 
break;
 
  355                     case  7: str = 
"チヂッツヅテデトドナニヌネノハバパヒビピフブプヘベペホボポマミム"; 
break;
 
  356                     case  8: str = 
"メモャヤュユョヨラリルレロヮワヰヱヲンヴヵヶヷヸヹヺ・ーヽヾヿ゠"; 
break;
 
  357                     case  9: str = 
"!"#$%&'()*+,-./0123456789:;<=>?@"; 
break;
 
  358                     case 10: str = 
"ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`"; 
break;
 
  359                     case 11: str = 
"abcdefghijklmnopqrstuvwxyz{|}~⦅⦆"; 
break;
 
  364                     buff = TTF_RenderUTF8_Blended(handle, str.c_str(), { 255, 255, 255 });
 
  368                     buff = TTF_RenderUTF8_Solid(handle, str.c_str(), { 255, 255, 255 });
 
  373                 SDL_BlitSurface(buff, NULL, surface, &pos);
 
  376                 SDL_FreeSurface(buff);
 
  385             if( (
unsigned char)strS[0][0] == 0xEF && (
unsigned char)strS[0][1] == 0xBB && (
unsigned char)strS[0][2] == 0xBF ){index = 3;}
 
  389                 if( strS[0].size() <= index ){
break;}
 
  391                 if( (
unsigned char)strS[0][index] < 0x80 )
 
  395                 else if ( (
unsigned char)strS[0][index] < 0xE0)
 
  399                 else if ( (
unsigned char)strS[0][index] < 0xF0)
 
  409                     buff = TTF_RenderUTF8_Blended(handle, strS[0].substr(index,length).c_str() , { 255, 255, 255 });
 
  413                     buff = TTF_RenderUTF8_Solid(handle, strS[0].substr(index,length).c_str() , { 255, 255, 255 });
 
  421                 SDL_BlitSurface(buff, NULL, surface, &pos);
 
  424                 if (pos.x >= size * 32)
 
  429                 SDL_FreeSurface(buff);
 
  432             std::string fileName = TTF_FontFaceFamilyName(handle);
 
  433             fileName += TTF_FontFaceStyleName(handle);
 
  434             fileName += std::to_string(size);
 
  437             SDL_SaveBMP(surface, fileName.c_str());
 
  438             SDL_FreeSurface(surface);
 
  447             if (Loading::isLoading)
 
  457             unsigned int index = 0;
 
  459             if( (
unsigned char)strS[0][0] == 0xEF && (
unsigned char)strS[0][1] == 0xBB && (
unsigned char)strS[0][2] == 0xBF ){index = 3;}
 
  463                 if( strS[0].size() <= index ){
break;}
 
  465                 if( (
unsigned char)strS[0][index] < 0x80 ){index += 1;}
 
  466                 else if ( (
unsigned char)strS[0][index] < 0xE0){ index += 2; }
 
  467                 else if ( (
unsigned char)strS[0][index] < 0xF0){ index += 3; }
 
  473             int h = BMPフォント.
GetHeight() / ((count+31)/32 + 12);
 
  481             for (
int a = 0; a < 12; ++a)
 
  485                     case  0: str = 
"!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`"; 
break;
 
  486                     case  1: str = 
"abcdefghijklmnopqrstuvwxyz{|}~。「」、・ヲァィゥェォャュョッーアイウエオカキクケコサシスセソ"; 
break;
 
  487                     case  2: str = 
"タチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン゙゚  "; 
break;
 
  488                     case  3: str = 
"ぁあぃいぅうぇえぉおかがきぎくぐけげこごさざしじすずせぜそぞただ"; 
break;
 
  489                     case  4: str = 
"ちぢっつづてでとどなにぬねのはばぱひびぴふぶぷへべぺほぼぽまみむ"; 
break;
 
  490                     case  5: str = 
"めもゃやゅゆょよらりるれろゎわゐゑをんゔゕゖ  "; 
break;
 
  491                     case  6: str = 
"ァアィイゥウェエォオカガキギクグケゲコゴサザシジスズセゼソゾタダ"; 
break;
 
  492                     case  7: str = 
"チヂッツヅテデトドナニヌネノハバパヒビピフブプヘベペホボポマミム"; 
break;
 
  493                     case  8: str = 
"メモャヤュユョヨラリルレロヮワヰヱヲンヴヵヶヷヸヹヺ・ーヽヾヿ゠"; 
break;
 
  494                     case  9: str = 
"!"#$%&'()*+,-./0123456789:;<=>?@"; 
break;
 
  495                     case 10: str = 
"ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`"; 
break;
 
  496                     case 11: str = 
"abcdefghijklmnopqrstuvwxyz{|}~⦅⦆"; 
break;
 
  500                 for (
int b = 0; b < 64; ++b)
 
  506                         if (a == 1 && b == 61){ 
break; }
 
  507                         if (a == 2 && b == 34){ 
break; }
 
  508                         GetUTFSize(str[count], 文字長);
 
  511                         if (文字長 > 1){ ID += str[count + 1] * 0x100; }
 
  512                         if (文字長 > 2){ ID += str[count + 2] * 0x10000; }
 
  513                         if (文字長 > 3){ ID += str[count + 3] * 0x1000000; }
 
  515                         hash[ID] = 
new Image(BMPフォント, { b * w/2, a * h, w / 2, h });
 
  520                         if (b >= 32){ 
break; }
 
  521                         if (a == 5 && b == 24){ 
break; }
 
  523                         ID = str[b * 3] + str[b * 3 + 1] * 256 + str[b * 3 + 2] * 256 * 256;
 
  524                         hash[ID] = 
new Image(BMPフォント, { b * w, a * h, w, h });
 
  529             hash[0x20] = 
new Image(BMPフォント, { 33 * w / 2, 2 * h, w / 2, h });
 
  537             if( (
unsigned char)strS[0][0] == 0xEF && (
unsigned char)strS[0][1] == 0xBB && (
unsigned char)strS[0][2] == 0xBF ){index = 3;}
 
  541                 if( strS[0].size() <= index ){
break;}
 
  543                 if( (
unsigned char)strS[0][index] < 0x80 )
 
  547                 else if ( (
unsigned char)strS[0][index] < 0xE0)
 
  551                 else if ( (
unsigned char)strS[0][index] < 0xF0)
 
  560                 SetImage(strS[0].substr(index,length).c_str(), 
new Image(BMPフォント, { c%32*w, (c/32+12)*h, w , h }));
 
  581             for (
auto 文字列 : 幅を計算する文字列.
StringS)
 
  587                 for (
auto it = 文字列.begin(); it != 文字列.end(); it += charSize)
 
  590                     if (lead < 0x20){ charSize = 1; 
continue; }
 
  591                     else if (lead < 0x80){ charSize = 1; }
 
  592                     else if (lead < 0xE0){ charSize = 2; }
 
  593                     else if (lead < 0xF0){ charSize = 3; }
 
  594                     else { charSize = 4; }
 
  596                     Image* buf = GetHash(文字列.substr(std::distance(文字列.begin(), it), charSize).c_str(), charSize);
 
  608                 最大幅 = std::max(幅, 最大幅);
 
  619             for (
auto it : 描画する文字列.
StringS)
 
  621                 DrawUTFString(位置, it, 描画色);
 
  622                 位置.
y += this->enterHeight;
 
  631             Draw({ 座標.
x + 1, 座標.
y + 1 }, 影色, 描画する文字列);
 
  632             return Draw(座標, 表色, 描画する文字列);
 
  639             int 行数 = 描画する文字列.
StringS.size();
 
  642             int Y補正 = int(-enterHeight * 拡大率 * (0.5*行数-0.5));
 
  644             for (
auto it : 描画する文字列.
StringS)
 
  646                 DrawRotateUTFString(座標, X補正, Y補正, 拡大率, 角度, it, 描画色);
 
  647                 Y補正 += int(enterHeight * 拡大率);
 
  659             for (
auto it : 描画する文字列.
StringS)
 
  661                 DrawUTFString(位置, X拡大率, Y拡大率, it, 描画色);
 
  662                 位置.
y += this->enterHeight * Y拡大率;
 
  672             if (Loading::isLoading)
 
  679             auto it = 文字.begin();
 
  681             if (!GetUTFSize(*it, charSize)){ 
return; }
 
  682             SetHash(文字.substr(std::distance(文字.begin(), it), charSize).c_str(), charSize, 対応画像);
 
  690             if (Loading::isLoading)
 
  698             auto it = 文字列.begin();
 
  699             if (!GetUTFSize(*it, charSize)){ 
return; }
 
  700             std::string str = 文字列.substr(0, charSize);
 
  702             for (
int a = 0; a < 登録数;++a)
 
  704                 if (!GetUTFSize(*it, charSize)){ 
continue; }
 
  705                 SetHash(str.c_str(),charSize,対応画像[0][a]);
 
  706                 if (str[charSize - 1] == 0xff)
 
  709                     str[charSize - 1] = 0;
 
bool Draw(const Point &座標, const Color &描画色, const VariadicStream &描画する文字列, bool 反転フラグ=false) const override
文字を描画. 
Definition: Font.h:615
const double PAI
円周率 
Definition: SDX.h:26
double y
座標 
Definition: Point.h:26
Fontのインターフェース. 
Definition: IFont.h:12
bool DrawExtend(const Rect &描画領域, bool 反転フラグ=false) const override
指定矩形内に描画. 
Definition: Image.h:201
bool MakeBMPFont(const std::string テキストファイル名)
BMPフォントデータを生成する. 
Definition: Font.h:289
void SetImageS(const std::string &文字列, ImagePack *対応画像, int 登録数)
指定した文字から連続してに対応するImageをまとめて設定. 
Definition: Font.h:688
点を表す図形クラス. 
Definition: Point.h:22
入出力可能なテキストかバイナリファイルを表すクラス. 
Definition: File.h:29
std::vector< std::string > GetLineS()
ファイルを改行区切りで一括して読み込む. 
Definition: File.h:390
TrueTypeFontとBMPFontをまとめて扱うクラス. 
Definition: Font.h:25
std::vector< std::string > StringS
一行ずつの文字列. 
Definition: VariadicStream.h:53
bool DrawRotate(const Point &座標, double 拡大率, double 角度, bool 反転フラグ=false) const override
角度、拡大率を指定して描画. 
Definition: Image.h:229
bool DrawRotate(const Point &座標, double 拡大率, double 角度, const Color &描画色, const VariadicStream &描画する文字列, bool 反転フラグ=false) const override
文字を回転して描画. 
Definition: Font.h:637
int GetSize() const 
大きさを取得. 
Definition: Font.h:571
画像データを表すクラス. 
Definition: Image.h:17
色を表すクラス. 
Definition: Color.h:11
bool Load(const char *フォント名, int 大きさ, int 行間=0, bool 高品質レンダリングフラグ=true)
フォントを作成する. 
Definition: Font.h:183
bool LoadBMPFont(const Image &BMPフォント, const std::string テキストファイル名)
MakeBMPFontで生成したBMPフォントデータを読み込む. 
Definition: Font.h:445
static void AddLoading(std::function< void(void)> &&読み込み関数)
非同期読み込み処理に追加. 
Definition: Loading.h:96
int GetHeight() const 
高さを取得. 
Definition: Image.h:310
int GetWidth() const 
幅を取得. 
Definition: Image.h:304
bool Release() const 
フォントハンドルをメモリから開放する. 
Definition: Font.h:207
TTF_Font * GetHandle() const 
フォントのハンドルを取得. 
Definition: Font.h:220
static SDL_Renderer * GetHandle()
スクリーンハンドルを取得. 
Definition: Screen.h:26
Image MakeImage(Color 文字色, bool 反転フラグ, const VariadicStream &描画する文字列) const 
FontからImageを生成. 
Definition: Font.h:226
bool DrawShadow(const Point &座標, Color 表色, Color 影色, const VariadicStream &描画する文字列) const 
文字を影付きで描画. 
Definition: Font.h:629
void SetSize(int 大きさ, int 行間=0)
フォントの行間を再指定する. 
Definition: Font.h:279
可変数引数な文字列を処理するクラス. 
Definition: VariadicStream.h:25
bool DrawExtend(const Point &座標, double X拡大率, double Y拡大率, const Color &描画色, const VariadicStream &描画する文字列, bool 反転フラグ=false) const override
拡大率を指定して文字を描画. 
Definition: Font.h:655
double x
座標 
Definition: Point.h:25
複数のImageをまとめるクラス. 
Definition: ImagePack.h:17
void SetColor(const Color &描画色)
描画色を指定. 
Definition: Image.h:316
bool Draw(const Point &座標, bool 反転フラグ=false) const override
指定座標に描画. 
Definition: Image.h:181
int GetDrawStringWidth(const VariadicStream &幅を計算する文字列) const 
描画時の幅を取得. 
Definition: Font.h:577
Font(const char *フォント名, int 大きさ, int 行間=0, bool 高品質レンダリングフラグ=true)
コンストラクタ 
Definition: Font.h:175
void SetImage(const std::string &文字, Image *対応画像)
指定した文字に対応するImageを設定. 
Definition: Font.h:670