From 444d9058abca4cbeb6662f12d8d1cca51624bd7b Mon Sep 17 00:00:00 2001
From: Christian Brunschen <6741909+cbrunschen@users.noreply.github.com>
Date: Wed, 19 Nov 2025 16:20:47 +0000
Subject: [PATCH] rendlay.cpp: Improve accuracy and performance calculating
text aspect ratio,
Also adds another text alignment option to stretch the text to fill its bounds horizontally.
The current code calculating the aspect ratio for text involves looping, calculating the width of text for a variety of decreasing aspect ratios until the text's width is less than the available bounds. However, this string width calculation performs the same loop over the text each time, finally multiplying by the candidate aspect ratio. That text width calculation thus really only needs to be done once. Further, instead of trying different aspect ratios, the ratio can simply be calculated directly by dividing the width of the bounds by the string's width. This also calculates a more accurate aspect ratio, rather than always resulting in an aspect ratio of (0.95)^n.
For example, when trying to fit a 101-pixel wide text into a 100-pixel wide space, the current code would result in an aspect ratio of 0.95, making the text 96 pixels wide, leaving 4 pixels unused; the new code will instead calculate the aspect ratio as 100/101 == 0.9900990099... , making the text use the full 100 available pixels.
This in turn allows us to easily calculate the ratio also if we want to not just schrink but also stretch the text to fill the available space, so we add that as another text alignment option, number 3 (three).
This PR also demonstrates this in the VFX family of layouts, where on the default Full view, the text "MUSIC PRODUCTION SYNTHESIZER" ("DYNAMIC COMPONENT SYNTHESIZER" on the VFX), the logo-like text "ensoniq", and the keyboard-specific markers "VFX", "VFX-SD", "SD-1" and "3 2 V O I C E" can now be made to fill their available space horizontally as they should, making it all look that much more like the real thing.
---
docs/source/techspecs/layout_files.rst | 7 +++--
scripts/build/complay.py | 2 +-
src/emu/rendlay.cpp | 40 +++++++-------------------
src/mame/layout/sd1.lay | 26 ++++++++---------
src/mame/layout/sd132.lay | 32 ++++++++++-----------
src/mame/layout/vfx.lay | 26 ++++++++---------
src/mame/layout/vfxsd.lay | 26 ++++++++---------
7 files changed, 67 insertions(+), 92 deletions(-)
diff --git a/docs/source/techspecs/layout_files.rst b/docs/source/techspecs/layout_files.rst
index 7fb304b292c0d..760d584cd757a 100644
--- a/docs/source/techspecs/layout_files.rst
+++ b/docs/source/techspecs/layout_files.rst
@@ -512,9 +512,10 @@ text
Draws text in using the UI font in the specified colour. The text to draw
must be supplied using a ``string`` attribute. An ``align`` attribute may
be supplied to set text alignment. If present, the ``align`` attribute must
- 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.
+ be an integer, where 0 (zero) means centred, 1 (one) means left-aligned,
+ 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.
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/scripts/build/complay.py b/scripts/build/complay.py
index 0460992f87e7b..9fab191242813 100755
--- a/scripts/build/complay.py
+++ b/scripts/build/complay.py
@@ -452,7 +452,7 @@ def elementStartHandler(self, name, attrs):
if 'string' not in attrs:
self.handle_error('Element text missing attribute string')
align = self.check_int_attribute(name, attrs, 'align', None)
- if (align is not None) and ((0 > align) or (2 < align)):
+ if (align is not None) and ((0 > align) or (3 < align)):
self.handle_error('Element text attribute align "%s" not in valid range 0-2' % (attrs['align'], ))
self.check_component(name, attrs)
elif 'simplecounter' == name:
diff --git a/src/emu/rendlay.cpp b/src/emu/rendlay.cpp
index 97baf74037395..5c0a93a85f848 100644
--- a/src/emu/rendlay.cpp
+++ b/src/emu/rendlay.cpp
@@ -3219,16 +3219,8 @@ class layout_element::reel_component : public component
bitmap_argb32 tempbitmap(dest.width(), dest.height());
// get the width of the string
- float aspect = 1.0f;
- s32 width;
-
- while (1)
- {
- width = font->string_width(ourheight / num_shown, aspect, m_stopnames[fruit]);
- if (width < bounds.width())
- break;
- aspect *= 0.95f;
- }
+ s32 width = font->string_width(ourheight / num_shown, 1.0f, m_stopnames[fruit]);
+ float aspect = width > bounds.width() ? (float) bounds.width() / (float) width : 1.0f;
float curx = bounds.left() + (bounds.width() - width) / 2.0f;
@@ -3368,15 +3360,8 @@ class layout_element::reel_component : public component
else // render text (fallback)
{
// get the width of the string
- float aspect = 1.0f;
- s32 width;
- while (1)
- {
- width = font->string_width(dest.height(), aspect, m_stopnames[fruit]);
- if (width < bounds.width())
- break;
- aspect *= 0.95f;
- }
+ s32 width = font->string_width(dest.height(), 1.0f, m_stopnames[fruit]);
+ float aspect = width > bounds.width() ? (float) bounds.width() / (float) width : 1.0f;
float curx = bounds.left();
@@ -3716,16 +3701,8 @@ void layout_element::component::draw_text(
const render_color &color)
{
// get the width of the string
- float aspect = 1.0f;
- s32 width;
-
- while (1)
- {
- width = font.string_width(bounds.height(), aspect, str);
- if (width < bounds.width())
- break;
- aspect *= 0.95f;
- }
+ s32 width = font.string_width(bounds.height(), 1.0f, str);
+ float aspect = (align == 3 || width > bounds.width()) ? (float) bounds.width() / (float) width : 1.0f;
// get alignment
float curx;
@@ -3740,6 +3717,11 @@ void layout_element::component::draw_text(
case 2:
curx = bounds.right() - width;
break;
+
+ // stretch
+ case 3:
+ curx = bounds.left();
+ break;
// default to center
default:
diff --git a/src/mame/layout/sd1.lay b/src/mame/layout/sd1.lay
index 521dce6d48df7..cf30e689dcad7 100644
--- a/src/mame/layout/sd1.lay
+++ b/src/mame/layout/sd1.lay
@@ -468,23 +468,21 @@
-
-
+
+
-
-
+
+
-
-
+
+
-
-
-
+
@@ -2523,13 +2521,13 @@
-
-
+
+
-
-
+
+
-
+
diff --git a/src/mame/layout/sd132.lay b/src/mame/layout/sd132.lay
index 344b9dec29171..0db7c371690b9 100644
--- a/src/mame/layout/sd132.lay
+++ b/src/mame/layout/sd132.lay
@@ -468,26 +468,24 @@
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
-
+
@@ -2529,17 +2527,17 @@
-
-
+
+
-
-
+
+
-
+
-
+
diff --git a/src/mame/layout/vfx.lay b/src/mame/layout/vfx.lay
index 97342c0dff30a..0a754b21a59a4 100644
--- a/src/mame/layout/vfx.lay
+++ b/src/mame/layout/vfx.lay
@@ -412,23 +412,21 @@
-
-
+
+
-
-
+
+
-
-
+
+
-
-
-
+
@@ -2344,13 +2342,13 @@
-
-
+
+
-
-
+
+
-
+
diff --git a/src/mame/layout/vfxsd.lay b/src/mame/layout/vfxsd.lay
index 1bd1c448909a2..3cced4a0e2a2f 100644
--- a/src/mame/layout/vfxsd.lay
+++ b/src/mame/layout/vfxsd.lay
@@ -468,23 +468,21 @@
-
-
+
+
-
-
+
+
-
-
+
+
-
-
-
+
@@ -2523,13 +2521,13 @@
-
-
+
+
-
-
+
+
-
+