Fix TTC loading (thanks for the tip, Sarayan)

This commit is contained in:
Vas Crabb 2016-03-17 20:56:50 +11:00
parent c54c32a82e
commit a01a40c0a9
2 changed files with 30 additions and 15 deletions

View File

@ -1,5 +1,5 @@
// license:BSD-3-Clause // license:BSD-3-Clause
// copyright-holders:Olivier Galibert, R. Belmont // copyright-holders:Olivier Galibert, R. Belmont, Vas Crabb
/* /*
* font_osx.c * font_osx.c
* *

View File

@ -1,5 +1,5 @@
// license:BSD-3-Clause // license:BSD-3-Clause
// copyright-holders:Olivier Galibert, R. Belmont // copyright-holders:Olivier Galibert, R. Belmont, Vas Crabb
/* /*
* font_sdl.c * font_sdl.c
* *
@ -60,7 +60,7 @@ private:
TTF_Font_ptr search_font_config(std::string const &family, std::string const &style, bool &bakedstyles); TTF_Font_ptr search_font_config(std::string const &family, std::string const &style, bool &bakedstyles);
#endif #endif
bool BDF_Check_Magic(std::string const &name); bool BDF_Check_Magic(std::string const &name);
TTF_Font_ptr TTF_OpenFont_Magic(std::string const &name, int fsize); TTF_Font_ptr TTF_OpenFont_Magic(std::string const &name, int fsize, long index);
TTF_Font_ptr m_font; TTF_Font_ptr m_font;
}; };
@ -83,7 +83,7 @@ bool osd_font_sdl::open(std::string const &font_path, std::string const &_name,
std::string const style((std::string::npos != separator) ? name.substr(separator + 1) : std::string()); std::string const style((std::string::npos != separator) ? name.substr(separator + 1) : std::string());
// first up, try it as a filename // first up, try it as a filename
TTF_Font_ptr font = TTF_OpenFont_Magic(family, POINT_SIZE); TTF_Font_ptr font = TTF_OpenFont_Magic(family, POINT_SIZE, 0);
// if no success, try the font path // if no success, try the font path
if (!font) if (!font)
@ -94,7 +94,7 @@ bool osd_font_sdl::open(std::string const &font_path, std::string const &_name,
if (file.open(family.c_str()) == osd_file::error::NONE) if (file.open(family.c_str()) == osd_file::error::NONE)
{ {
std::string full_name = file.fullpath(); std::string full_name = file.fullpath();
font = TTF_OpenFont_Magic(full_name, POINT_SIZE); font = TTF_OpenFont_Magic(full_name, POINT_SIZE, 0);
if (font) if (font)
osd_printf_verbose("Found font %s\n", full_name.c_str()); osd_printf_verbose("Found font %s\n", full_name.c_str());
} }
@ -191,18 +191,26 @@ bool osd_font_sdl::get_bitmap(unicode_char chnum, bitmap_argb32 &bitmap, std::in
return bitmap.valid(); return bitmap.valid();
} }
osd_font_sdl::TTF_Font_ptr osd_font_sdl::TTF_OpenFont_Magic(std::string const &name, int fsize) osd_font_sdl::TTF_Font_ptr osd_font_sdl::TTF_OpenFont_Magic(std::string const &name, int fsize, long index)
{ {
emu_file file(OPEN_FLAG_READ); emu_file file(OPEN_FLAG_READ);
if (file.open(name.c_str()) == osd_file::error::NONE) if (file.open(name.c_str()) == osd_file::error::NONE)
{ {
unsigned char const magic[] = { 0x00, 0x01, 0x00, 0x00, 0x00 }; unsigned char const ttf_magic[] = { 0x00, 0x01, 0x00, 0x00, 0x00 };
unsigned char buffer[sizeof(magic)] = { 0xff, 0xff, 0xff, 0xff, 0xff }; unsigned char const ttc1_magic[] = { 0x74, 0x74, 0x63, 0x66, 0x00, 0x01, 0x00, 0x00 };
if ((sizeof(magic) != file.read(buffer, sizeof(magic))) || memcmp(buffer, magic, sizeof(magic))) unsigned char const ttc2_magic[] = { 0x74, 0x74, 0x63, 0x66, 0x00, 0x02, 0x00, 0x00 };
return TTF_Font_ptr(nullptr, &TTF_CloseFont); unsigned char buffer[std::max({ sizeof(ttf_magic), sizeof(ttc1_magic), sizeof(ttc2_magic) })];
auto const bytes_read = file.read(buffer, sizeof(buffer));
file.close(); file.close();
}
if ((bytes_read >= sizeof(ttf_magic)) && !std::memcmp(buffer, ttf_magic, sizeof(ttf_magic)))
return TTF_Font_ptr(TTF_OpenFont(name.c_str(), POINT_SIZE), &TTF_CloseFont); return TTF_Font_ptr(TTF_OpenFont(name.c_str(), POINT_SIZE), &TTF_CloseFont);
if (((bytes_read >= sizeof(ttc1_magic)) && !std::memcmp(buffer, ttc1_magic, sizeof(ttc1_magic))) ||
((bytes_read >= sizeof(ttc2_magic)) && !std::memcmp(buffer, ttc2_magic, sizeof(ttc2_magic))))
return TTF_Font_ptr(TTF_OpenFontIndex(name.c_str(), POINT_SIZE, index), &TTF_CloseFont);
}
return TTF_Font_ptr(nullptr, &TTF_CloseFont);
} }
bool osd_font_sdl::BDF_Check_Magic(std::string const &name) bool osd_font_sdl::BDF_Check_Magic(std::string const &name)
@ -235,6 +243,7 @@ osd_font_sdl::TTF_Font_ptr osd_font_sdl::search_font_config(std::string const &f
FcPatternAddString(pat.get(), FC_FONTFORMAT, (const FcChar8 *)"TrueType"); FcPatternAddString(pat.get(), FC_FONTFORMAT, (const FcChar8 *)"TrueType");
FcObjectSetAdd(os.get(), FC_FILE); FcObjectSetAdd(os.get(), FC_FILE);
FcObjectSetAdd(os.get(), FC_INDEX);
std::unique_ptr<FcFontSet, void (*)(FcFontSet *)> fontset(FcFontList(config, pat.get(), os.get()), &FcFontSetDestroy); std::unique_ptr<FcFontSet, void (*)(FcFontSet *)> fontset(FcFontList(config, pat.get(), os.get()), &FcFontSetDestroy);
for (int i = 0; (i < fontset->nfont) && !font; i++) for (int i = 0; (i < fontset->nfont) && !font; i++)
@ -244,8 +253,9 @@ osd_font_sdl::TTF_Font_ptr osd_font_sdl::search_font_config(std::string const &f
{ {
osd_printf_verbose("Matching font: %s\n", val.u.s); osd_printf_verbose("Matching font: %s\n", val.u.s);
std::string match_name((const char*)val.u.s); std::string const match_name((const char*)val.u.s);
font = TTF_OpenFont_Magic(match_name, POINT_SIZE); long const index = ((FcPatternGet(fontset->fonts[i], FC_INDEX, 0, &val) == FcResultMatch) && (val.type == FcTypeInteger)) ? val.u.i : 0;
font = TTF_OpenFont_Magic(match_name, POINT_SIZE, index);
if (font) if (font)
bakedstyles = true; bakedstyles = true;
@ -253,6 +263,7 @@ osd_font_sdl::TTF_Font_ptr osd_font_sdl::search_font_config(std::string const &f
} }
// didn't get a font above? try again with no baked-in styles // didn't get a font above? try again with no baked-in styles
// note that this simply returns the first match for the family name, which could be regular if you're lucky, but it could be bold oblique or something
if (!font && !style.empty()) if (!font && !style.empty())
{ {
pat.reset(FcPatternCreate()); pat.reset(FcPatternCreate());
@ -268,7 +279,11 @@ osd_font_sdl::TTF_Font_ptr osd_font_sdl::search_font_config(std::string const &f
osd_printf_verbose("Matching unstyled font: %s\n", val.u.s); osd_printf_verbose("Matching unstyled font: %s\n", val.u.s);
std::string const match_name((const char*)val.u.s); std::string const match_name((const char*)val.u.s);
font = TTF_OpenFont_Magic(match_name, POINT_SIZE); long const index = ((FcPatternGet(fontset->fonts[i], FC_INDEX, 0, &val) == FcResultMatch) && (val.type == FcTypeInteger)) ? val.u.i : 0;
font = TTF_OpenFont_Magic(match_name, POINT_SIZE, index);
if (font)
bakedstyles = false;
} }
} }
} }