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