From 0e20c1781974619a83bf1deeba356d8c832aec6f Mon Sep 17 00:00:00 2001 From: Christian Brunschen <6741909+cbrunschen@users.noreply.github.com> Date: Sat, 15 Nov 2025 11:08:18 +0000 Subject: [PATCH 1/8] (Strawman proposal for discussion) rendfont.cpp,rendlay.cpp: add font support to `` components This adds a "font" attribute to the `` layout component, defaulting to `"default"` if nothing is specified. It also changes the `render_font` constructor to accept not just a single "filename" but a comma-separated list of "filenames". These actually don't seem to be file names at all, but font specifications that may be symbolic (like the default `"Liberation Sans|Regular"` in `font_osd.cpp`), which includes a `|` separator between font family and style. This is in turn used in the Ensoniq VFX family of keyboards to use the ccorrect Bold and Italic styles of a suitable Helvetica-compatible sans-serif font, falling back to "default" of nothing is found. This includes a first choice of an explicitly nonexistent font to demonstrate that the list of fonts is in fact traversed. --- src/emu/rendfont.cpp | 34 ++- src/emu/rendlay.cpp | 4 +- src/mame/layout/sd1.lay | 541 +++++++++++++++++++------------------ src/mame/layout/sd132.lay | 543 +++++++++++++++++++------------------- src/mame/layout/vfx.lay | 457 ++++++++++++++++---------------- src/mame/layout/vfxsd.lay | 541 +++++++++++++++++++------------------ 6 files changed, 1093 insertions(+), 1027 deletions(-) diff --git a/src/emu/rendfont.cpp b/src/emu/rendfont.cpp index 259d7731fe50a..034c6db2e3b0b 100644 --- a/src/emu/rendfont.cpp +++ b/src/emu/rendfont.cpp @@ -491,7 +491,7 @@ inline render_font::glyph &render_font::get_char(char32_t chnum) // render_font - constructor //------------------------------------------------- -render_font::render_font(render_manager &manager, const char *filename) +render_font::render_font(render_manager &manager, const char *filenames) : m_manager(manager) , m_format(format::UNKNOWN) , m_height(0) @@ -507,27 +507,39 @@ render_font::render_font(render_manager &manager, const char *filename) memset(m_glyphs_cmd, 0, sizeof(m_glyphs_cmd)); // if this is an OSD font, we're done - if (filename) + if (filenames) { + std::string_view remaining(filenames); m_osdfont = manager.machine().osd().font_alloc(); - if (m_osdfont && m_osdfont->open(manager.machine().options().font_path(), filename, m_height)) + + while (!remaining.empty()) { - m_scale = 1.0f / float(m_height); - m_format = format::OSD; + std::string::size_type const separator = remaining.find(','); + std::string filename(remaining.substr(0, separator)); + LOG("Trying OSD font '%s'\n", filename); + remaining = separator != std::string::npos ? remaining.substr(separator + 1) : ""; - //mamep: allocate command glyph font - render_font_command_glyph(); - return; + if (m_osdfont && m_osdfont->open(manager.machine().options().font_path(), filename, m_height)) + { + LOG("- Using OSD font '%s'\n", filename); + m_scale = 1.0f / float(m_height); + m_format = format::OSD; + + //mamep: allocate command glyph font + render_font_command_glyph(); + return; + } } + m_osdfont.reset(); } // if the filename is 'default' default to 'ui.bdf' for backwards compatibility - if (filename && !core_stricmp(filename, "default")) - filename = "ui.bdf"; + if (filenames && !core_stricmp(filenames, "default")) + filenames = "ui.bdf"; // attempt to load an external BDF font first - if (filename && load_cached_bdf(filename)) + if (filenames && load_cached_bdf(filenames)) { //mamep: allocate command glyph font render_font_command_glyph(); diff --git a/src/emu/rendlay.cpp b/src/emu/rendlay.cpp index 97baf74037395..7958e673a43b7 100644 --- a/src/emu/rendlay.cpp +++ b/src/emu/rendlay.cpp @@ -2476,13 +2476,14 @@ class layout_element::text_component : public component { m_string = env.get_attribute_string(compnode, "string"); m_textalign = env.get_attribute_int(compnode, "align", 0); + m_font = env.get_attribute_string(compnode, "font", "default"); } protected: // overrides virtual void draw_aligned(running_machine &machine, bitmap_argb32 &dest, const rectangle &bounds, int state) override { - auto font = machine.render().font_alloc("default"); + auto font = machine.render().font_alloc(m_font.c_str()); draw_text(*font, dest, bounds, m_string, m_textalign, color(state)); } @@ -2490,6 +2491,7 @@ class layout_element::text_component : public component // internal state std::string m_string; // string for text components int m_textalign; // text alignment to box + std::string m_font; // the font to use }; diff --git a/src/mame/layout/sd1.lay b/src/mame/layout/sd1.lay index 521dce6d48df7..05be13c8e8e22 100644 --- a/src/mame/layout/sd1.lay +++ b/src/mame/layout/sd1.lay @@ -1,5 +1,9 @@ + + + + @@ -231,254 +235,263 @@ - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + + + + - + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - + - - + + - + + + + + + + - - + + @@ -941,10 +954,10 @@ - + - + @@ -972,46 +985,46 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -1143,175 +1156,175 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -1464,58 +1477,58 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -1539,16 +1552,16 @@ - + - + - + - + @@ -2083,16 +2096,16 @@ - + - + - + - + @@ -2420,7 +2433,7 @@ - + @@ -2434,7 +2447,7 @@ - + @@ -2455,7 +2468,7 @@ - + @@ -2520,13 +2533,13 @@ - + - + diff --git a/src/mame/layout/sd132.lay b/src/mame/layout/sd132.lay index 344b9dec29171..d2345da667724 100644 --- a/src/mame/layout/sd132.lay +++ b/src/mame/layout/sd132.lay @@ -1,5 +1,9 @@ + + + + @@ -231,257 +235,266 @@ - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + + + + - + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - + - - + + - + - + + + + + + + - - + + @@ -944,10 +957,10 @@ - + - + @@ -975,46 +988,46 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -1146,175 +1159,175 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -1467,58 +1480,58 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -1542,16 +1555,16 @@ - + - + - + - + @@ -2086,16 +2099,16 @@ - + - + - + - + @@ -2423,7 +2436,7 @@ - + @@ -2437,7 +2450,7 @@ - + @@ -2458,7 +2471,7 @@ - + @@ -2526,13 +2539,13 @@ - + - + diff --git a/src/mame/layout/vfx.lay b/src/mame/layout/vfx.lay index 97342c0dff30a..c634adfbbc4f4 100644 --- a/src/mame/layout/vfx.lay +++ b/src/mame/layout/vfx.lay @@ -1,5 +1,9 @@ + + + + @@ -214,215 +218,224 @@ - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + + + + - + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - + - - + + - + + + + + + + - - + + @@ -861,10 +874,10 @@ - + - + @@ -892,43 +905,43 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -1048,136 +1061,136 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -1300,46 +1313,46 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -1363,16 +1376,16 @@ - + - + - + - + @@ -1907,16 +1920,16 @@ - + - + - + - + @@ -2244,7 +2257,7 @@ - + @@ -2258,7 +2271,7 @@ - + @@ -2279,7 +2292,7 @@ - + @@ -2341,13 +2354,13 @@ - + - + diff --git a/src/mame/layout/vfxsd.lay b/src/mame/layout/vfxsd.lay index 1bd1c448909a2..3987861b69761 100644 --- a/src/mame/layout/vfxsd.lay +++ b/src/mame/layout/vfxsd.lay @@ -1,5 +1,9 @@ + + + + @@ -231,254 +235,263 @@ - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + + + + - + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - + - - + + - + + + + + + + - - + + @@ -941,10 +954,10 @@ - + - + @@ -972,46 +985,46 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -1143,175 +1156,175 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -1464,58 +1477,58 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -1539,16 +1552,16 @@ - + - + - + - + @@ -2083,16 +2096,16 @@ - + - + - + - + @@ -2420,7 +2433,7 @@ - + @@ -2434,7 +2447,7 @@ - + @@ -2455,7 +2468,7 @@ - + @@ -2520,13 +2533,13 @@ - + - + From d2c2b4a2dc68981d6194cc89f4164d2a9e6449d5 Mon Sep 17 00:00:00 2001 From: Christian Brunschen <6741909+cbrunschen@users.noreply.github.com> Date: Sat, 15 Nov 2025 13:40:17 +0000 Subject: [PATCH 2/8] Explicitly specify the Regular style. --- src/mame/layout/sd1.lay | 10 +++++----- src/mame/layout/sd132.lay | 12 ++++++------ src/mame/layout/vfx.lay | 8 ++++---- src/mame/layout/vfxsd.lay | 10 +++++----- 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/mame/layout/sd1.lay b/src/mame/layout/sd1.lay index 05be13c8e8e22..2195f044b7ff5 100644 --- a/src/mame/layout/sd1.lay +++ b/src/mame/layout/sd1.lay @@ -3,7 +3,7 @@ - + @@ -371,7 +371,7 @@ - + @@ -413,7 +413,7 @@ - + @@ -476,13 +476,13 @@ - + - + diff --git a/src/mame/layout/sd132.lay b/src/mame/layout/sd132.lay index d2345da667724..b254a7044fb0f 100644 --- a/src/mame/layout/sd132.lay +++ b/src/mame/layout/sd132.lay @@ -3,7 +3,7 @@ - + @@ -371,7 +371,7 @@ - + @@ -413,7 +413,7 @@ - + @@ -476,16 +476,16 @@ - + - + - + diff --git a/src/mame/layout/vfx.lay b/src/mame/layout/vfx.lay index c634adfbbc4f4..60b4ff537ecc0 100644 --- a/src/mame/layout/vfx.lay +++ b/src/mame/layout/vfx.lay @@ -3,7 +3,7 @@ - + @@ -351,7 +351,7 @@ - + @@ -420,13 +420,13 @@ - + - + diff --git a/src/mame/layout/vfxsd.lay b/src/mame/layout/vfxsd.lay index 3987861b69761..b2761e75716e2 100644 --- a/src/mame/layout/vfxsd.lay +++ b/src/mame/layout/vfxsd.lay @@ -3,7 +3,7 @@ - + @@ -371,7 +371,7 @@ - + @@ -413,7 +413,7 @@ - + @@ -476,13 +476,13 @@ - + - + From 00c53e8069aa415cc13a030a3d611523eb0ceba4 Mon Sep 17 00:00:00 2001 From: Christian Brunschen <6741909+cbrunschen@users.noreply.github.com> Date: Sat, 15 Nov 2025 15:51:15 +0000 Subject: [PATCH 3/8] Make all of font_{windows,dwrite,osx,sdl}.cpp handle "Font Famile|Style" type font names. --- src/osd/modules/font/font_dwrite.cpp | 11 +++++++++++ src/osd/modules/font/font_osx.cpp | 26 ++++++++++++++++++++++++-- src/osd/modules/font/font_sdl.cpp | 9 +++++++-- src/osd/modules/font/font_windows.cpp | 11 +++++++++++ 4 files changed, 53 insertions(+), 4 deletions(-) diff --git a/src/osd/modules/font/font_dwrite.cpp b/src/osd/modules/font/font_dwrite.cpp index 8ccec702117dd..c84cfa2ef4554 100644 --- a/src/osd/modules/font/font_dwrite.cpp +++ b/src/osd/modules/font/font_dwrite.cpp @@ -364,6 +364,17 @@ class osd_font_dwrite : public osd_font bool bold = (strreplace(name, "[B]", "") + strreplace(name, "[b]", "") > 0); bool italic = (strreplace(name, "[I]", "") + strreplace(name, "[i]", "") > 0); + if (name.find('|') != std::string::npos) + { + // Handle the "Font Family|Style" type of font name: + // Separate it into family and style, and extract bold and italic style information. + std::string::size_type const separator = name.rfind('|'); + std::string const style((std::string::npos != separator) ? name.substr(separator + 1) : std::string()); + bold |= (style.find("Bold") != std::string::npos) || (style.find("Black") != std::string::npos); + italic |= (style.find("Italic") != std::string::npos) || (style.find("Oblique") != std::string::npos); + name = name.substr(0, separator); + } + // convert the face name std::wstring familyName = text::to_wstring(name); diff --git a/src/osd/modules/font/font_osx.cpp b/src/osd/modules/font/font_osx.cpp index a020d51ddce37..0aa749b7402cd 100644 --- a/src/osd/modules/font/font_osx.cpp +++ b/src/osd/modules/font/font_osx.cpp @@ -9,6 +9,7 @@ #ifdef SDLMAME_MACOSX +#include "corestr.h" #include "emucore.h" #include "fileio.h" #include "osdcore.h" @@ -52,9 +53,30 @@ class osd_font_osx : public osd_font CGFloat m_height, m_baseline; }; -bool osd_font_osx::open(std::string const &font_path, std::string const &name, int &height) +bool osd_font_osx::open(std::string const &font_path, std::string const &_name, int &height) { - osd_printf_verbose("osd_font_osx::open: name=\"%s\"\n", name); + osd_printf_verbose("osd_font_osx::open: name=\"%s\"\n", _name); + + std::string name(_name); + + if (name.find('|') != std::string::npos) + { + // Handle the "Font Family|Style" type of font name, by + // modifying the name to be more likely a PostScript name: + // - Style is separated from family name by '-', not '|'. + strreplace(name, "|", "-"); + // - Spaces within the name are removed. + strreplace(name, " ", ""); + std::string regular("-Regular"); + + // - The "Regular" style is not spelled out. + if (name.rfind(regular) == name.length() - regular.length()) + { + name = name.substr(0, name.length() - regular.length()); + } + + osd_printf_verbose("osd_font_osx::open: candidate PostScript name=\"%s\"\n", name); + } CFStringRef font_name; if (name == "default") diff --git a/src/osd/modules/font/font_sdl.cpp b/src/osd/modules/font/font_sdl.cpp index 514e0cc0784a0..b024f5fb83721 100644 --- a/src/osd/modules/font/font_sdl.cpp +++ b/src/osd/modules/font/font_sdl.cpp @@ -75,9 +75,14 @@ bool osd_font_sdl::open(std::string const &font_path, std::string const &_name, // accept qualifiers from the name bool const underline = (strreplace(name, "[U]", "") + strreplace(name, "[u]", "") > 0); bool const strike = (strreplace(name, "[S]", "") + strreplace(name, "[s]", "") > 0); + + // Handle the "Font Family|Style" type of font name: + // Separate it into family and style, and extract bold and italic style information. std::string::size_type const separator = name.rfind('|'); std::string const family(name.substr(0, separator)); std::string const style((std::string::npos != separator) ? name.substr(separator + 1) : std::string()); + bool bold = (style.find("Bold") != std::string::npos) || (style.find("Black") != std::string::npos); + bool italic = (style.find("Italic") != std::string::npos) || (style.find("Oblique") != std::string::npos); // first up, try it as a filename TTF_Font_ptr font = TTF_OpenFont_Magic(family, POINT_SIZE, 0); @@ -118,8 +123,8 @@ bool osd_font_sdl::open(std::string const &font_path, std::string const &_name, int styleflags = 0; if (!bakedstyles) { - if ((style.find("Bold") != std::string::npos) || (style.find("Black") != std::string::npos)) styleflags |= TTF_STYLE_BOLD; - if ((style.find("Italic") != std::string::npos) || (style.find("Oblique") != std::string::npos)) styleflags |= TTF_STYLE_ITALIC; + if (bold) styleflags |= TTF_STYLE_BOLD; + if (italic) styleflags |= TTF_STYLE_ITALIC; } styleflags |= underline ? TTF_STYLE_UNDERLINE : 0; // SDL_ttf 2.0.9 and earlier does not define TTF_STYLE_STRIKETHROUGH diff --git a/src/osd/modules/font/font_windows.cpp b/src/osd/modules/font/font_windows.cpp index 0ec65b67aea6e..3a27c0729464c 100644 --- a/src/osd/modules/font/font_windows.cpp +++ b/src/osd/modules/font/font_windows.cpp @@ -67,6 +67,17 @@ bool osd_font_windows::open(std::string const &font_path, std::string const &_na bool bold = (strreplace(name, "[B]", "") + strreplace(name, "[b]", "") > 0); bool italic = (strreplace(name, "[I]", "") + strreplace(name, "[i]", "") > 0); + if (name.find('|') != std::string::npos) + { + // Handle the "Font Family|Style" type of font name: + // Separate it into family and style, and extract bold and italic style information. + std::string::size_type const separator = name.rfind('|'); + std::string const style((std::string::npos != separator) ? name.substr(separator + 1) : std::string()); + bold |= (style.find("Bold") != std::string::npos) || (style.find("Black") != std::string::npos); + italic |= (style.find("Italic") != std::string::npos) || (style.find("Oblique") != std::string::npos); + name = name.substr(0, separator); + } + // build a basic LOGFONT description of what we want LOGFONT logfont; logfont.lfHeight = DEFAULT_HEIGHT; From 6f580f4bd6d04174316590c7f04f5e735457feb9 Mon Sep 17 00:00:00 2001 From: Christian Brunschen <6741909+cbrunschen@users.noreply.github.com> Date: Sun, 16 Nov 2025 07:23:38 +0000 Subject: [PATCH 4/8] font_osx.cpp: don't try to convert the font name into a PostScript name. Instead, just like in the other OS versions, separate out the '|'-separated style information, extract bold/italic styling information from that into a CTFontSymbolicTraits, and then use CTFontDescriptorCreateCopyWithSymbolicTraits to apply those, if any are requested. --- src/osd/modules/font/font_osx.cpp | 42 ++++++++++++++++++++----------- 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/src/osd/modules/font/font_osx.cpp b/src/osd/modules/font/font_osx.cpp index 0aa749b7402cd..f30171eab51f9 100644 --- a/src/osd/modules/font/font_osx.cpp +++ b/src/osd/modules/font/font_osx.cpp @@ -59,23 +59,25 @@ bool osd_font_osx::open(std::string const &font_path, std::string const &_name, std::string name(_name); + CTFontSymbolicTraits traits = 0; + CTFontSymbolicTraits trait_mask = kCTFontTraitBold | kCTFontTraitItalic; + if (name.find('|') != std::string::npos) { - // Handle the "Font Family|Style" type of font name, by - // modifying the name to be more likely a PostScript name: - // - Style is separated from family name by '-', not '|'. - strreplace(name, "|", "-"); - // - Spaces within the name are removed. - strreplace(name, " ", ""); - std::string regular("-Regular"); - - // - The "Regular" style is not spelled out. - if (name.rfind(regular) == name.length() - regular.length()) + // Handle the "Font Family|Style" type of font name: + // Separate it into family and style, and extract bold and italic style information + // into CTFontSymbolicTraits. + std::string::size_type const separator = name.rfind('|'); + std::string const style((std::string::npos != separator) ? name.substr(separator + 1) : std::string()); + if ((style.find("Bold") != std::string::npos) || (style.find("Black") != std::string::npos)) { - name = name.substr(0, name.length() - regular.length()); + traits |= kCTFontTraitBold; } - - osd_printf_verbose("osd_font_osx::open: candidate PostScript name=\"%s\"\n", name); + if ((style.find("Italic") != std::string::npos) || (style.find("Oblique") != std::string::npos)) + { + traits |= kCTFontTraitItalic; + } + name = name.substr(0, separator); } CFStringRef font_name; @@ -103,7 +105,7 @@ bool osd_font_osx::open(std::string const &font_path, std::string const &_name, return false; } - CTFontDescriptorRef const font_descriptor(CTFontDescriptorCreateWithNameAndSize(font_name, 0.0)); + CTFontDescriptorRef font_descriptor(CTFontDescriptorCreateWithNameAndSize(font_name, 0.0)); CFRelease(font_name); if (!font_descriptor) { @@ -111,6 +113,18 @@ bool osd_font_osx::open(std::string const &font_path, std::string const &_name, return false; } + if (traits != 0) + { + CTFontDescriptorRef styled_descriptor(CTFontDescriptorCreateCopyWithSymbolicTraits(font_descriptor, traits, trait_mask)); + CFRelease(font_descriptor); + if (!styled_descriptor) + { + osd_printf_verbose("osd_font_osx::open: failed to create styled CoreText font descriptor for \"%s\" with traits=%08x\n", name, traits); + return false; + } + font_descriptor = styled_decscriptor; + } + CTFontRef const ct_font(CTFontCreateWithFontDescriptor(font_descriptor, POINT_SIZE, &CGAffineTransformIdentity)); CFRelease(font_descriptor); if (!ct_font) From ee43ee2748ed42c9efe211a61f336bd4b3dd0a44 Mon Sep 17 00:00:00 2001 From: Christian Brunschen <6741909+cbrunschen@users.noreply.github.com> Date: Sun, 16 Nov 2025 08:46:34 +0000 Subject: [PATCH 5/8] Fix variable name typo. --- src/osd/modules/font/font_osx.cpp | 2 +- src/osd/modules/font/font_sdl.cpp | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/osd/modules/font/font_osx.cpp b/src/osd/modules/font/font_osx.cpp index f30171eab51f9..755adf97b5356 100644 --- a/src/osd/modules/font/font_osx.cpp +++ b/src/osd/modules/font/font_osx.cpp @@ -122,7 +122,7 @@ bool osd_font_osx::open(std::string const &font_path, std::string const &_name, osd_printf_verbose("osd_font_osx::open: failed to create styled CoreText font descriptor for \"%s\" with traits=%08x\n", name, traits); return false; } - font_descriptor = styled_decscriptor; + font_descriptor = styled_descriptor; } CTFontRef const ct_font(CTFontCreateWithFontDescriptor(font_descriptor, POINT_SIZE, &CGAffineTransformIdentity)); diff --git a/src/osd/modules/font/font_sdl.cpp b/src/osd/modules/font/font_sdl.cpp index b024f5fb83721..c9e60aa716621 100644 --- a/src/osd/modules/font/font_sdl.cpp +++ b/src/osd/modules/font/font_sdl.cpp @@ -96,6 +96,7 @@ bool osd_font_sdl::open(std::string const &font_path, std::string const &_name, if (!file.open(family)) { std::string full_name = file.fullpath(); + osd_printf_verbose("Searching font %s in '%s'/s\n", family, full_name); font = TTF_OpenFont_Magic(full_name, POINT_SIZE, 0); if (font) osd_printf_verbose("Found font %s\n", full_name); @@ -119,6 +120,8 @@ bool osd_font_sdl::open(std::string const &font_path, std::string const &_name, return false; } + osd_printf_verbose("Found font '%s' style '%s'\n", TTF_FontFaceFamilyName(font.get()), TTF_FontFaceStyleName(font.get())); + // apply styles int styleflags = 0; if (!bakedstyles) From 38ab52e857475acf3a68ee334fd585ca24df30f7 Mon Sep 17 00:00:00 2001 From: Christian Brunschen <6741909+cbrunschen@users.noreply.github.com> Date: Mon, 17 Nov 2025 09:42:23 +0000 Subject: [PATCH 6/8] Add support for generic font families --- src/mame/layout/sd1.lay | 8 ++++---- src/mame/layout/sd132.lay | 8 ++++---- src/mame/layout/vfx.lay | 8 ++++---- src/mame/layout/vfxsd.lay | 8 ++++---- src/osd/modules/font/font_dwrite.cpp | 12 ++++++++++-- src/osd/modules/font/font_osx.cpp | 20 +++++++++++--------- src/osd/modules/font/font_sdl.cpp | 21 ++++++++++++++------- src/osd/modules/font/font_windows.cpp | 11 ++++++++++- 8 files changed, 61 insertions(+), 35 deletions(-) diff --git a/src/mame/layout/sd1.lay b/src/mame/layout/sd1.lay index 2195f044b7ff5..116c1ddccdbe4 100644 --- a/src/mame/layout/sd1.lay +++ b/src/mame/layout/sd1.lay @@ -1,9 +1,9 @@ - - - - + + + + diff --git a/src/mame/layout/sd132.lay b/src/mame/layout/sd132.lay index b254a7044fb0f..c49fd7792843f 100644 --- a/src/mame/layout/sd132.lay +++ b/src/mame/layout/sd132.lay @@ -1,9 +1,9 @@ - - - - + + + + diff --git a/src/mame/layout/vfx.lay b/src/mame/layout/vfx.lay index 60b4ff537ecc0..82e44590abc88 100644 --- a/src/mame/layout/vfx.lay +++ b/src/mame/layout/vfx.lay @@ -1,9 +1,9 @@ - - - - + + + + diff --git a/src/mame/layout/vfxsd.lay b/src/mame/layout/vfxsd.lay index b2761e75716e2..96ac0179040bd 100644 --- a/src/mame/layout/vfxsd.lay +++ b/src/mame/layout/vfxsd.lay @@ -1,9 +1,9 @@ - - - - + + + + diff --git a/src/osd/modules/font/font_dwrite.cpp b/src/osd/modules/font/font_dwrite.cpp index c84cfa2ef4554..8cacb38baa583 100644 --- a/src/osd/modules/font/font_dwrite.cpp +++ b/src/osd/modules/font/font_dwrite.cpp @@ -359,8 +359,6 @@ class osd_font_dwrite : public osd_font // accept qualifiers from the name std::string name(_name); - if (name.compare("default") == 0) - name = "Segoe UI"; bool bold = (strreplace(name, "[B]", "") + strreplace(name, "[b]", "") > 0); bool italic = (strreplace(name, "[I]", "") + strreplace(name, "[i]", "") > 0); @@ -375,6 +373,16 @@ class osd_font_dwrite : public osd_font name = name.substr(0, separator); } + // Translate generic names into platform-specific real ones + if (name == "serif") + name = "Times New Roman"; + else if (name == "sans-serif") + name = "Arial"; + else if (name == "monospace") + name = "Courier New"; + else if (name == "default") + name = "Segoe UI"; + // convert the face name std::wstring familyName = text::to_wstring(name); diff --git a/src/osd/modules/font/font_osx.cpp b/src/osd/modules/font/font_osx.cpp index 755adf97b5356..6b6ad710ac703 100644 --- a/src/osd/modules/font/font_osx.cpp +++ b/src/osd/modules/font/font_osx.cpp @@ -80,17 +80,19 @@ bool osd_font_osx::open(std::string const &font_path, std::string const &_name, name = name.substr(0, separator); } - CFStringRef font_name; - if (name == "default") - { + // Translate generic names into platform-specific real ones + if (name == "serif") + name = "Times"; + else if (name == "sans-serif") + name = "Helvetica"; + else if (name == "monospace") + name = "Courier"; + else if (name == "default") // Arial Unicode MS comes with Mac OS X 10.5 and later and is the only Mac default font with // the Unicode characters used by the vgmplay and aristmk5 layouts. - font_name = CFStringCreateWithCString(nullptr, "Arial Unicode MS", kCFStringEncodingUTF8); - } - else - { - font_name = CFStringCreateWithCString(nullptr, name.c_str(), kCFStringEncodingUTF8); - } + name = "Arial Unicode MS"; + + CFStringRef font_name = CFStringCreateWithCString(nullptr, name.c_str(), kCFStringEncodingUTF8); if (!font_name) { diff --git a/src/osd/modules/font/font_sdl.cpp b/src/osd/modules/font/font_sdl.cpp index c9e60aa716621..e624250646486 100644 --- a/src/osd/modules/font/font_sdl.cpp +++ b/src/osd/modules/font/font_sdl.cpp @@ -67,10 +67,6 @@ bool osd_font_sdl::open(std::string const &font_path, std::string const &_name, bool bakedstyles = false; std::string name(_name); - if (name.compare("default") == 0) - { - name = "Liberation Sans|Regular"; - } // accept qualifiers from the name bool const underline = (strreplace(name, "[U]", "") + strreplace(name, "[u]", "") > 0); @@ -79,12 +75,22 @@ bool osd_font_sdl::open(std::string const &font_path, std::string const &_name, // Handle the "Font Family|Style" type of font name: // Separate it into family and style, and extract bold and italic style information. std::string::size_type const separator = name.rfind('|'); - std::string const family(name.substr(0, separator)); - std::string const style((std::string::npos != separator) ? name.substr(separator + 1) : std::string()); + std::string family(name.substr(0, separator)); + std::string style((std::string::npos != separator) ? name.substr(separator + 1) : "Regular"); bool bold = (style.find("Bold") != std::string::npos) || (style.find("Black") != std::string::npos); bool italic = (style.find("Italic") != std::string::npos) || (style.find("Oblique") != std::string::npos); - // first up, try it as a filename + // Translate generic names into platform-specific real ones: + if (family == "serif") + family = "Liberation Serif"; + else if (family == "sans-serif") + family = "Liberation Sans"; + else if (family == "monospace") + family = "Liberation Mono"; + else if (family == "default") + family = "Liberation Sans"; + + // first up, try it as a filename TTF_Font_ptr font = TTF_OpenFont_Magic(family, POINT_SIZE, 0); // if no success, try the font path @@ -137,6 +143,7 @@ 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 + osd_printf_verbose("setting style flags %x\n", styleflags); TTF_SetFontStyle(font.get(), styleflags); height = TTF_FontLineSkip(font.get()); diff --git a/src/osd/modules/font/font_windows.cpp b/src/osd/modules/font/font_windows.cpp index 3a27c0729464c..633822572634c 100644 --- a/src/osd/modules/font/font_windows.cpp +++ b/src/osd/modules/font/font_windows.cpp @@ -63,7 +63,6 @@ bool osd_font_windows::open(std::string const &font_path, std::string const &_na // accept qualifiers from the name std::string name(_name); - if (name.compare("default")==0) name = "Tahoma"; bool bold = (strreplace(name, "[B]", "") + strreplace(name, "[b]", "") > 0); bool italic = (strreplace(name, "[I]", "") + strreplace(name, "[i]", "") > 0); @@ -78,6 +77,16 @@ bool osd_font_windows::open(std::string const &font_path, std::string const &_na name = name.substr(0, separator); } + // Translate generic names into platform-specific real ones: + if (name == "serif") + name = "Times New Roman"; + else if (name == "sans-serif") + name = "Arial"; + else if (name == "monospace") + name = "Courier New"; + else if (name == "default") + name = "Tahoma"; + // build a basic LOGFONT description of what we want LOGFONT logfont; logfont.lfHeight = DEFAULT_HEIGHT; From d98656994901ffcc9cd9b9ab35d771f691b27fdb Mon Sep 17 00:00:00 2001 From: Christian Brunschen <6741909+cbrunschen@users.noreply.github.com> Date: Tue, 18 Nov 2025 21:05:50 +0000 Subject: [PATCH 7/8] Add some documentation about the `font` attribute to the `text` element. --- docs/source/techspecs/layout_files.rst | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/docs/source/techspecs/layout_files.rst b/docs/source/techspecs/layout_files.rst index 7fb304b292c0d..a7d637d3f39f3 100644 --- a/docs/source/techspecs/layout_files.rst +++ b/docs/source/techspecs/layout_files.rst @@ -515,6 +515,18 @@ text be an integer, where 0 (zero) means centred, 1 (one) means left-aligned, and 2 (two) means right-aligned. If the ``align`` attribute is absent, the text will be centred. + + You can also specify the font to use using the ``font`` attribute. This + contains a comma (``,``)-separated list of fonts to use in order of preference. + Font styles (Regular, Bold, Italic,oldItalic) are specified after the font name + separated by a vertical bar (``|``). + + There are also three standard fonts available: ``serif``, ``sans-serif`` + and ``monospace``; these can be given styles as above. Finally there is + ``default`` as a fallback if no other fonts can be found. + + A complex font specification might look like + ``font="Helvetica|Regular,Arial|Bold,sans-serif|BoldItalic,default"`` led7seg Draws a standard seven-segment (plus decimal point) digital LED/fluorescent display in the specified colour. The low eight bits of the element’s state From 63838e1c662a57a76b9c50f5f81f07179c4d2439 Mon Sep 17 00:00:00 2001 From: Christian Brunschen <6741909+cbrunschen@users.noreply.github.com> Date: Wed, 19 Nov 2025 07:56:18 +0000 Subject: [PATCH 8/8] Indentation in documentation is with spaces, not tabs. --- docs/source/techspecs/layout_files.rst | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/source/techspecs/layout_files.rst b/docs/source/techspecs/layout_files.rst index a7d637d3f39f3..63c0651caca5a 100644 --- a/docs/source/techspecs/layout_files.rst +++ b/docs/source/techspecs/layout_files.rst @@ -516,17 +516,17 @@ text 2 (two) means right-aligned. If the ``align`` attribute is absent, the text will be centred. - You can also specify the font to use using the ``font`` attribute. This - contains a comma (``,``)-separated list of fonts to use in order of preference. - Font styles (Regular, Bold, Italic,oldItalic) are specified after the font name - separated by a vertical bar (``|``). + You can also specify the font to use using the ``font`` attribute. This + contains a comma (``,``)-separated list of fonts to use in order of preference. + Font styles (Regular, Bold, Italic,oldItalic) are specified after the font name + separated by a vertical bar (``|``). - There are also three standard fonts available: ``serif``, ``sans-serif`` - and ``monospace``; these can be given styles as above. Finally there is - ``default`` as a fallback if no other fonts can be found. + There are also three standard fonts available: ``serif``, ``sans-serif`` + and ``monospace``; these can be given styles as above. Finally there is + ``default`` as a fallback if no other fonts can be found. - A complex font specification might look like - ``font="Helvetica|Regular,Arial|Bold,sans-serif|BoldItalic,default"`` + A complex font specification might look like + ``font="Helvetica|Regular,Arial|Bold,sans-serif|BoldItalic,default"`` led7seg Draws a standard seven-segment (plus decimal point) digital LED/fluorescent display in the specified colour. The low eight bits of the element’s state