diff --git a/docs/source/techspecs/layout_files.rst b/docs/source/techspecs/layout_files.rst index 760d584cd757a..a6d63baaf2c18 100644 --- a/docs/source/techspecs/layout_files.rst +++ b/docs/source/techspecs/layout_files.rst @@ -516,6 +516,18 @@ text 2 (two) means right-aligned, and 3 (three) means that the text will be stretched horizontally to fill its bounds. 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 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 5c0a93a85f848..f5ae752a63935 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 cf30e689dcad7..cfb53df400137 100644 --- a/src/mame/layout/sd1.lay +++ b/src/mame/layout/sd1.lay @@ -1,5 +1,9 @@ + + + + @@ -231,254 +235,263 @@ - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + + + + - + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - + - - + + - + + + + + + + - - + + @@ -939,10 +952,10 @@ - + - + @@ -970,46 +983,46 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -1141,175 +1154,175 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -1462,58 +1475,58 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -1537,16 +1550,16 @@ - + - + - + - + @@ -2081,16 +2094,16 @@ - + - + - + - + @@ -2418,7 +2431,7 @@ - + @@ -2432,7 +2445,7 @@ - + @@ -2453,7 +2466,7 @@ - + @@ -2518,13 +2531,13 @@ - + - + diff --git a/src/mame/layout/sd132.lay b/src/mame/layout/sd132.lay index 0db7c371690b9..637ed60f82f66 100644 --- a/src/mame/layout/sd132.lay +++ b/src/mame/layout/sd132.lay @@ -1,5 +1,9 @@ + + + + @@ -231,257 +235,266 @@ - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + + + + - + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - + - - + + - + - + + + + + + + - - + + @@ -942,10 +955,10 @@ - + - + @@ -973,46 +986,46 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -1144,175 +1157,175 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -1465,58 +1478,58 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -1540,16 +1553,16 @@ - + - + - + - + @@ -2084,16 +2097,16 @@ - + - + - + - + @@ -2421,7 +2434,7 @@ - + @@ -2435,7 +2448,7 @@ - + @@ -2456,7 +2469,7 @@ - + @@ -2524,13 +2537,13 @@ - + - + diff --git a/src/mame/layout/vfx.lay b/src/mame/layout/vfx.lay index 0a754b21a59a4..7d0aebc834f5c 100644 --- a/src/mame/layout/vfx.lay +++ b/src/mame/layout/vfx.lay @@ -1,5 +1,9 @@ + + + + @@ -214,215 +218,224 @@ - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + + + + - + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - + - - + + - + + + + + + + - - + + @@ -859,10 +872,10 @@ - + - + @@ -890,43 +903,43 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -1046,136 +1059,136 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -1298,46 +1311,46 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -1361,16 +1374,16 @@ - + - + - + - + @@ -1905,16 +1918,16 @@ - + - + - + - + @@ -2242,7 +2255,7 @@ - + @@ -2256,7 +2269,7 @@ - + @@ -2277,7 +2290,7 @@ - + @@ -2339,13 +2352,13 @@ - + - + diff --git a/src/mame/layout/vfxsd.lay b/src/mame/layout/vfxsd.lay index 3cced4a0e2a2f..25907b7eaa065 100644 --- a/src/mame/layout/vfxsd.lay +++ b/src/mame/layout/vfxsd.lay @@ -1,5 +1,9 @@ + + + + @@ -231,254 +235,263 @@ - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + + + + - + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - + - - + + - + + + + + + + - - + + @@ -939,10 +952,10 @@ - + - + @@ -970,46 +983,46 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -1141,175 +1154,175 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -1462,58 +1475,58 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -1537,16 +1550,16 @@ - + - + - + - + @@ -2081,16 +2094,16 @@ - + - + - + - + @@ -2418,7 +2431,7 @@ - + @@ -2432,7 +2445,7 @@ - + @@ -2453,7 +2466,7 @@ - + @@ -2518,13 +2531,13 @@ - + - + diff --git a/src/osd/modules/font/font_dwrite.cpp b/src/osd/modules/font/font_dwrite.cpp index 8ccec702117dd..8cacb38baa583 100644 --- a/src/osd/modules/font/font_dwrite.cpp +++ b/src/osd/modules/font/font_dwrite.cpp @@ -359,11 +359,30 @@ 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); + 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); + } + + // 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 a020d51ddce37..6b6ad710ac703 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,21 +53,46 @@ 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); - CFStringRef font_name; - if (name == "default") + 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: + // 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)) + { + traits |= kCTFontTraitBold; + } + if ((style.find("Italic") != std::string::npos) || (style.find("Oblique") != std::string::npos)) + { + traits |= kCTFontTraitItalic; + } + name = name.substr(0, separator); + } + + // 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) { @@ -81,7 +107,7 @@ bool osd_font_osx::open(std::string const &font_path, std::string const &name, i 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) { @@ -89,6 +115,18 @@ bool osd_font_osx::open(std::string const &font_path, std::string const &name, i 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_descriptor; + } + CTFontRef const ct_font(CTFontCreateWithFontDescriptor(font_descriptor, POINT_SIZE, &CGAffineTransformIdentity)); CFRelease(font_descriptor); if (!ct_font) diff --git a/src/osd/modules/font/font_sdl.cpp b/src/osd/modules/font/font_sdl.cpp index 514e0cc0784a0..e624250646486 100644 --- a/src/osd/modules/font/font_sdl.cpp +++ b/src/osd/modules/font/font_sdl.cpp @@ -67,19 +67,30 @@ 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); bool const strike = (strreplace(name, "[S]", "") + strreplace(name, "[s]", "") > 0); - 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()); - // first up, try it as a filename + // 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 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); + + // 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 @@ -91,6 +102,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); @@ -114,12 +126,14 @@ 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) { - 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 @@ -129,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 0ec65b67aea6e..633822572634c 100644 --- a/src/osd/modules/font/font_windows.cpp +++ b/src/osd/modules/font/font_windows.cpp @@ -63,10 +63,30 @@ 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); + 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); + } + + // 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;