mirror of
https://github.com/holub/mame
synced 2025-06-29 23:48:56 +03:00
Fix drawing characters outside Unicode BMP with SDL
Font selection on Linux seems to be working provided you don't choose C/J/K fonts Selecting a C/J/K font causes MAME to give a black screen when dropping back to main menu Since fallback fonts aren't used, this means you can't use the Chinese/Japanese localisations with SDL font provider
This commit is contained in:
parent
74e10d87fa
commit
6ecc87bc28
@ -8,7 +8,12 @@
|
||||
#include "font_module.h"
|
||||
#include "modules/osdmodule.h"
|
||||
|
||||
#if defined(SDLMAME_UNIX) && (!defined(SDLMAME_MACOSX)) && (!defined(SDLMAME_SOLARIS)) && (!defined(SDLMAME_HAIKU)) && (!defined(SDLMAME_EMSCRIPTEN))
|
||||
#if defined(SDLMAME_UNIX) && !defined(SDLMAME_MACOSX) && !defined(SDLMAME_SOLARIS) && !defined(SDLMAME_HAIKU) && !defined(SDLMAME_EMSCRIPTEN)
|
||||
|
||||
#include "corestr.h"
|
||||
#include "corealloc.h"
|
||||
#include "fileio.h"
|
||||
#include "unicode.h"
|
||||
|
||||
#include <SDL2/SDL_ttf.h>
|
||||
#ifndef SDLMAME_HAIKU
|
||||
@ -16,11 +21,6 @@
|
||||
#endif
|
||||
|
||||
|
||||
#include "corestr.h"
|
||||
#include "corealloc.h"
|
||||
#include "fileio.h"
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// font_open - attempt to "open" a handle to the
|
||||
// font with the given name
|
||||
@ -29,8 +29,8 @@
|
||||
class osd_font_sdl : public osd_font
|
||||
{
|
||||
public:
|
||||
osd_font_sdl() : m_font(nullptr) { }
|
||||
osd_font_sdl(osd_font_sdl &&obj) : m_font(obj.m_font) { obj.m_font = nullptr; }
|
||||
osd_font_sdl() : m_font(nullptr, &TTF_CloseFont) { }
|
||||
osd_font_sdl(osd_font_sdl &&obj) : m_font(std::move(obj.m_font)) { }
|
||||
virtual ~osd_font_sdl() { close(); }
|
||||
|
||||
virtual bool open(std::string const &font_path, std::string const &name, int &height);
|
||||
@ -45,25 +45,25 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
typedef std::unique_ptr<TTF_Font, void (*)(TTF_Font *)> TTF_Font_ptr;
|
||||
|
||||
osd_font_sdl(osd_font_sdl const &) = delete;
|
||||
osd_font_sdl & operator=(osd_font_sdl const &) = delete;
|
||||
|
||||
static constexpr double POINT_SIZE = 144.0;
|
||||
|
||||
#ifndef SDLMAME_HAIKU
|
||||
TTF_Font *search_font_config(std::string const &name, bool bold, bool italic, bool underline, bool &bakedstyles);
|
||||
TTF_Font_ptr search_font_config(std::string const &name, bool bold, bool italic, bool underline, bool &bakedstyles);
|
||||
#endif
|
||||
bool BDF_Check_Magic(std::string const &name);
|
||||
TTF_Font * TTF_OpenFont_Magic(std::string const &name, int fsize);
|
||||
TTF_Font_ptr TTF_OpenFont_Magic(std::string const &name, int fsize);
|
||||
|
||||
TTF_Font *m_font;
|
||||
TTF_Font_ptr m_font;
|
||||
};
|
||||
|
||||
bool osd_font_sdl::open(std::string const &font_path, std::string const &_name, int &height)
|
||||
{
|
||||
TTF_Font *font = nullptr;
|
||||
bool bakedstyles = false;
|
||||
int style = 0;
|
||||
|
||||
// accept qualifiers from the name
|
||||
std::string name(_name);
|
||||
@ -78,7 +78,7 @@ bool osd_font_sdl::open(std::string const &font_path, std::string const &_name,
|
||||
bool const strike = (strreplace(name, "[S]", "") + strreplace(name, "[s]", "") > 0);
|
||||
|
||||
// first up, try it as a filename
|
||||
font = TTF_OpenFont_Magic(name, POINT_SIZE);
|
||||
TTF_Font_ptr font = TTF_OpenFont_Magic(name, POINT_SIZE);
|
||||
|
||||
// if no success, try the font path
|
||||
|
||||
@ -114,6 +114,7 @@ bool osd_font_sdl::open(std::string const &font_path, std::string const &_name,
|
||||
}
|
||||
|
||||
// apply styles
|
||||
int style = 0;
|
||||
if (!bakedstyles)
|
||||
{
|
||||
style |= bold ? TTF_STYLE_BOLD : 0;
|
||||
@ -127,12 +128,11 @@ bool osd_font_sdl::open(std::string const &font_path, std::string const &_name,
|
||||
if (strike)
|
||||
osd_printf_warning("Ignoring strikethrough for SDL_TTF older than 2.0.10\n");
|
||||
#endif // PATCHLEVEL
|
||||
TTF_SetFontStyle(font, style);
|
||||
TTF_SetFontStyle(font.get(), style);
|
||||
|
||||
height = TTF_FontLineSkip(font);
|
||||
height = TTF_FontLineSkip(font.get());
|
||||
|
||||
close();
|
||||
m_font = font;
|
||||
m_font = std::move(font);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -143,9 +143,7 @@ bool osd_font_sdl::open(std::string const &font_path, std::string const &_name,
|
||||
|
||||
void osd_font_sdl::close()
|
||||
{
|
||||
if (m_font)
|
||||
TTF_CloseFont(m_font);
|
||||
m_font = nullptr;
|
||||
m_font.reset();
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
@ -158,16 +156,10 @@ void osd_font_sdl::close()
|
||||
|
||||
bool osd_font_sdl::get_bitmap(unicode_char chnum, bitmap_argb32 &bitmap, std::int32_t &width, std::int32_t &xoffs, std::int32_t &yoffs)
|
||||
{
|
||||
TTF_Font *ttffont;
|
||||
SDL_Surface *drawsurf;
|
||||
SDL_Color fcol = { 0xff, 0xff, 0xff };
|
||||
SDL_Color const fcol = { 0xff, 0xff, 0xff };
|
||||
std::uint16_t ustr[16];
|
||||
|
||||
ttffont = m_font;
|
||||
|
||||
memset(ustr,0,sizeof(ustr));
|
||||
ustr[0] = (std::uint16_t)chnum;
|
||||
drawsurf = TTF_RenderUNICODE_Solid(ttffont, ustr, fcol);
|
||||
ustr[utf16_from_uchar(ustr, ARRAY_LENGTH(ustr), chnum)] = 0;
|
||||
std::unique_ptr<SDL_Surface, void (*)(SDL_Surface *)> const drawsurf(TTF_RenderUNICODE_Solid(m_font.get(), ustr, fcol), &SDL_FreeSurface);
|
||||
|
||||
// was nothing returned?
|
||||
if (drawsurf)
|
||||
@ -178,39 +170,35 @@ bool osd_font_sdl::get_bitmap(unicode_char chnum, bitmap_argb32 &bitmap, std::in
|
||||
// copy the rendered character image into it
|
||||
for (int y = 0; y < bitmap.height(); y++)
|
||||
{
|
||||
std::uint32_t *dstrow = &bitmap.pix32(y);
|
||||
std::uint8_t *srcrow = (std::uint8_t *)drawsurf->pixels;
|
||||
|
||||
srcrow += (y * drawsurf->pitch);
|
||||
std::uint32_t *const dstrow = &bitmap.pix32(y);
|
||||
std::uint8_t const *const srcrow = reinterpret_cast<std::uint8_t const *>(drawsurf->pixels) + (y * drawsurf->pitch);
|
||||
|
||||
for (int x = 0; x < drawsurf->w; x++)
|
||||
{
|
||||
dstrow[x] = srcrow[x] ? rgb_t(0xff,0xff,0xff,0xff) : rgb_t(0x00,0xff,0xff,0xff);
|
||||
dstrow[x] = srcrow[x] ? rgb_t(0xff, 0xff, 0xff, 0xff) : rgb_t(0x00, 0xff, 0xff, 0xff);
|
||||
}
|
||||
}
|
||||
|
||||
// what are these?
|
||||
xoffs = yoffs = 0;
|
||||
width = drawsurf->w;
|
||||
|
||||
SDL_FreeSurface(drawsurf);
|
||||
}
|
||||
|
||||
return bitmap.valid();
|
||||
}
|
||||
|
||||
TTF_Font * 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)
|
||||
{
|
||||
emu_file file(OPEN_FLAG_READ);
|
||||
if (file.open(name.c_str()) == osd_file::error::NONE)
|
||||
{
|
||||
unsigned char buffer[5] = { 0xff, 0xff, 0xff, 0xff, 0xff };
|
||||
unsigned char magic[5] = { 0x00, 0x01, 0x00, 0x00, 0x00 };
|
||||
file.read(buffer,5);
|
||||
if (memcmp(buffer, magic, 5))
|
||||
return nullptr;
|
||||
unsigned char const magic[] = { 0x00, 0x01, 0x00, 0x00, 0x00 };
|
||||
unsigned char buffer[sizeof(magic)] = { 0xff, 0xff, 0xff, 0xff, 0xff };
|
||||
if ((sizeof(magic) != file.read(buffer, sizeof(magic))) || memcmp(buffer, magic, sizeof(magic)))
|
||||
return TTF_Font_ptr(nullptr, &TTF_CloseFont);
|
||||
file.close();
|
||||
}
|
||||
return TTF_OpenFont(name.c_str(), POINT_SIZE);
|
||||
return TTF_Font_ptr(TTF_OpenFont(name.c_str(), POINT_SIZE), &TTF_CloseFont);
|
||||
}
|
||||
|
||||
bool osd_font_sdl::BDF_Check_Magic(std::string const &name)
|
||||
@ -218,22 +206,18 @@ bool osd_font_sdl::BDF_Check_Magic(std::string const &name)
|
||||
emu_file file(OPEN_FLAG_READ);
|
||||
if (file.open(name.c_str()) == osd_file::error::NONE)
|
||||
{
|
||||
unsigned char buffer[9];
|
||||
unsigned char magic[9] = { 'S', 'T', 'A', 'R', 'T', 'F', 'O', 'N', 'T' };
|
||||
file.read(buffer, 9);
|
||||
file.close();
|
||||
if (!memcmp(buffer, magic, 9))
|
||||
unsigned char const magic[] = { 'S', 'T', 'A', 'R', 'T', 'F', 'O', 'N', 'T' };
|
||||
unsigned char buffer[sizeof(magic)];
|
||||
if ((sizeof(magic) != file.read(buffer, sizeof(magic))) || memcmp(buffer, magic, sizeof(magic)))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifndef SDLMAME_HAIKU
|
||||
TTF_Font *osd_font_sdl::search_font_config(std::string const &name, bool bold, bool italic, bool underline, bool &bakedstyles)
|
||||
osd_font_sdl::TTF_Font_ptr osd_font_sdl::search_font_config(std::string const &name, bool bold, bool italic, bool underline, bool &bakedstyles)
|
||||
{
|
||||
TTF_Font *font = nullptr;
|
||||
FcValue val;
|
||||
TTF_Font_ptr font(nullptr, &TTF_CloseFont);
|
||||
|
||||
FcConfig *const config = FcConfigGetCurrent();
|
||||
std::unique_ptr<FcPattern, void (*)(FcPattern *)> pat(FcPatternCreate(), &FcPatternDestroy);
|
||||
@ -262,24 +246,18 @@ TTF_Font *osd_font_sdl::search_font_config(std::string const &name, bool bold, b
|
||||
FcObjectSetAdd(os.get(), FC_FILE);
|
||||
std::unique_ptr<FcFontSet, void (*)(FcFontSet *)> fontset(FcFontList(config, pat.get(), os.get()), &FcFontSetDestroy);
|
||||
|
||||
for (int i = 0; i < fontset->nfont; i++)
|
||||
for (int i = 0; (i < fontset->nfont) && !font; i++)
|
||||
{
|
||||
if ((FcPatternGet(fontset->fonts[i], FC_FILE, 0, &val) != FcResultMatch) ||
|
||||
(val.type != FcTypeString))
|
||||
FcValue val;
|
||||
if ((FcPatternGet(fontset->fonts[i], FC_FILE, 0, &val) == FcResultMatch) && (val.type != FcTypeString))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
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);
|
||||
font = TTF_OpenFont_Magic(match_name, POINT_SIZE);
|
||||
}
|
||||
|
||||
if (font)
|
||||
{
|
||||
bakedstyles = true;
|
||||
break;
|
||||
if (font)
|
||||
bakedstyles = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -294,8 +272,8 @@ TTF_Font *osd_font_sdl::search_font_config(std::string const &name, bool bold, b
|
||||
|
||||
for (int i = 0; (i < fontset->nfont) && !font; i++)
|
||||
{
|
||||
if ((FcPatternGet(fontset->fonts[i], FC_FILE, 0, &val) == FcResultMatch) &&
|
||||
(val.type == FcTypeString))
|
||||
FcValue val;
|
||||
if ((FcPatternGet(fontset->fonts[i], FC_FILE, 0, &val) == FcResultMatch) && (val.type == FcTypeString))
|
||||
{
|
||||
osd_printf_verbose("Matching unstyled font: %s\n", val.u.s);
|
||||
|
||||
@ -340,6 +318,7 @@ public:
|
||||
virtual bool get_font_families(std::string const &font_path, std::vector<std::pair<std::string, std::string> > &result) override;
|
||||
};
|
||||
|
||||
|
||||
bool font_sdl::get_font_families(std::string const &font_path, std::vector<std::pair<std::string, std::string> > &result)
|
||||
{
|
||||
result.clear();
|
||||
|
Loading…
Reference in New Issue
Block a user