1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-10 23:44:24 +00:00

FontOptions: Make it easier to specify font sizes in points

This commit is contained in:
reuk 2024-04-23 20:02:46 +01:00
parent c5a9e26960
commit 56d5445f8a
No known key found for this signature in database
GPG key ID: FCB43929F012EE5C
5 changed files with 94 additions and 13 deletions

View file

@ -193,7 +193,7 @@ class Font::SharedFontInternal : public ReferenceCountedObject
{
public:
explicit SharedFontInternal (FontOptions x)
: options (std::move (x))
: options (x.getName().isEmpty() ? x.withName (getDefaultSansSerifFontName()) : std::move (x))
{
}
@ -256,6 +256,7 @@ public:
String getTypefaceName() const { return options.getName(); }
String getTypefaceStyle() const { return options.getStyle(); }
float getHeight() const { return options.getHeight(); }
float getPointHeight() const { return options.getPointHeight(); }
float getHorizontalScale() const { return options.getHorizontalScale(); }
float getKerning() const { return options.getKerningFactor(); }
bool getUnderline() const { return options.getUnderline(); }
@ -300,6 +301,12 @@ public:
options = options.withHeight (x);
}
void setPointHeight (float x)
{
jassert (getReferenceCount() == 1);
options = options.withPointHeight (x);
}
void setHorizontalScale (float x)
{
jassert (getReferenceCount() == 1);
@ -360,7 +367,15 @@ Font::Font (FontOptions opt)
template <typename... Args>
auto legacyArgs (Args&&... args)
{
return FontOptions { std::forward<Args> (args)... }.withMetricsKind (TypefaceMetricsKind::legacy);
auto result = FontOptions { std::forward<Args> (args)... }.withMetricsKind (TypefaceMetricsKind::legacy);
if (result.getName().isEmpty())
result = result.withName (Font::getDefaultSansSerifFontName());
if (result.getPointHeight() > 0.0f)
result = result.withHeight (result.getPointHeight());
return result;
}
Font::Font() : font (new SharedFontInternal (legacyArgs())) {}
@ -541,7 +556,7 @@ float Font::getHeightToPointsFactor() const
Font Font::withPointHeight (float heightInPoints) const
{
Font f (*this);
f.setHeight (heightInPoints / getHeightToPointsFactor());
f.setPointHeight (heightInPoints);
return f;
}
@ -557,6 +572,18 @@ void Font::setHeight (float newHeight)
}
}
void Font::setPointHeight (float newHeight)
{
newHeight = FontValues::limitFontHeight (newHeight);
if (! approximatelyEqual (font->getPointHeight(), newHeight))
{
dupeInternalIfShared();
font->setPointHeight (newHeight);
font->resetTypeface();
}
}
void Font::setHeightWithoutChangingWidth (float newHeight)
{
newHeight = FontValues::limitFontHeight (newHeight);
@ -713,10 +740,22 @@ float Font::getAscent() const
return font->getMetrics (*this).ascent * getHeight();
}
float Font::getHeight() const noexcept { return font->getHeight(); }
float Font::getHeight() const noexcept
{
jassert ((font->getHeight() > 0.0f) != (font->getPointHeight() > 0.0f));
const auto height = font->getHeight();
return height > 0.0f ? height : font->getPointHeight() / getHeightToPointsFactor();
}
float Font::getDescent() const { return font->getHeight() - getAscent(); }
float Font::getHeightInPoints() const { return getHeight() * getHeightToPointsFactor(); }
float Font::getHeightInPoints() const
{
jassert ((font->getHeight() > 0.0f) != (font->getPointHeight() > 0.0f));
const auto pointHeight = font->getPointHeight();
return pointHeight > 0.0f ? pointHeight : font->getHeight() * getHeightToPointsFactor();
}
float Font::getAscentInPoints() const { return getAscent() * getHeightToPointsFactor(); }
float Font::getDescentInPoints() const { return getDescent() * getHeightToPointsFactor(); }
@ -875,7 +914,7 @@ Font::Native Font::getNativeDetails() const
Typeface::Ptr Font::getDefaultTypefaceForFont (const Font& font)
{
const auto systemTypeface = [&]() -> Typeface::Ptr
const auto resolvedTypeface = [&]() -> Typeface::Ptr
{
if (font.getTypefaceName() != getSystemUIFontName())
return {};
@ -893,8 +932,8 @@ Typeface::Ptr Font::getDefaultTypefaceForFont (const Font& font)
return getDefaultTypefaceForFont (copy);
}();
if (systemTypeface != nullptr)
return systemTypeface;
if (resolvedTypeface != nullptr)
return resolvedTypeface;
return Native::getDefaultPlatformTypefaceForFont (font);
}

View file

@ -265,10 +265,22 @@ public:
[[nodiscard]] Font withPointHeight (float heightInPoints) const;
/** Changes the font's height.
@see getHeight, withHeight, setHeightWithoutChangingWidth
The font will be scaled so that the sum of the ascender and descender is equal to the
provided height in logical pixels.
@see setPointHeight, getHeight, withHeight, setHeightWithoutChangingWidth
*/
void setHeight (float newHeight);
/** Changes the font's height.
The argument specifies the size of the font's em-square in logical pixels.
@see setHeight, getHeight, withHeight, setHeightWithoutChangingWidth
*/
void setPointHeight (float newHeight);
/** Changes the font's height without changing its width.
This alters the horizontal scale to compensate for the change in height.
*/

View file

@ -72,7 +72,7 @@ FontOptions::FontOptions (const String& typefaceName, float fontHeight, int styl
}
FontOptions::FontOptions (const String& typefaceName, const String& typefaceStyle, float fontHeight)
: name (typefaceName.isEmpty() ? Font::getDefaultSansSerifFontName() : typefaceName),
: name (typefaceName),
style (typefaceStyle),
height (FontValues::limitFontHeight (fontHeight))
{
@ -94,6 +94,7 @@ auto FontOptions::tie() const
fallbacks,
metricsKind,
height,
pointHeight,
tracking,
horizontalScale,
fallbackEnabled,

View file

@ -109,8 +109,22 @@ public:
/** Returns a copy of these options with font fallback enabled or disabled. */
[[nodiscard]] FontOptions withFallbackEnabled (bool x = true) const { return withMember (*this, &FontOptions::fallbackEnabled, x); }
/** Returns a copy of these options with the specified height in pixels (can be fractional). */
[[nodiscard]] FontOptions withHeight (float x) const { return withMember (*this, &FontOptions::height, x); }
/** Returns a copy of these options with the specified height in JUCE units (can be fractional).
FontOptions can hold either a JUCE height, set via withHeight(), or a point height, set via withPointHeight().
After calling withHeight(), the result of getPointHeight() will be -1.0f to indicate that the point height is unset.
For more information about how JUCE font heights work, see Font::setHeight().
*/
[[nodiscard]] FontOptions withHeight (float x) const { jassert (x > 0); auto copy = *this; copy.height = x; copy.pointHeight = -1.0f; return copy; }
/** Returns a copy of these options with the specified height in points (can be fractional).
After calling withPointHeight(), the result of getHeight() will be -1.0f to indicate that the JUCE height is unset.
For more information about how point heights work, see Font::setPointHeight().
*/
[[nodiscard]] FontOptions withPointHeight (float x) const { jassert (x > 0); auto copy = *this; copy.pointHeight = x; copy.height = -1.0f; return copy; }
/** Returns a copy of these options with the specified extra kerning factor (also called "tracking"). */
[[nodiscard]] FontOptions withKerningFactor (float x) const { return withMember (*this, &FontOptions::tracking, x); }
@ -134,6 +148,8 @@ public:
[[nodiscard]] auto getFallbacks() const { return fallbacks; }
/** @see withHeight() */
[[nodiscard]] auto getHeight() const { return height; }
/** @see withPointHeight() */
[[nodiscard]] auto getPointHeight() const { return pointHeight; }
/** @see withKerningFactor() */
[[nodiscard]] auto getKerningFactor() const { return tracking; }
/** @see withHorizontalScale() */
@ -165,7 +181,8 @@ private:
Typeface::Ptr typeface;
std::vector<String> fallbacks;
TypefaceMetricsKind metricsKind { TypefaceMetricsKind::portable };
float height{};
float height = -1.0f;
float pointHeight = -1.0f;
float tracking{};
float horizontalScale = 1.0f;
bool fallbackEnabled = true;

View file

@ -361,6 +361,18 @@ public:
On Android 29+, this will use AFontMatcher to return the "system-ui" font. On earlier
Android versions, this will attempt to return the Roboto font.
NOTE: The metrics of the system typeface may be significantly different from the metrics of
the sans-serif font that JUCE would normally select to be the default font. This is
especially evident on Windows: For Segoe UI (the Windows system typeface)
the sum of ascender and descender is somewhat larger than the em-size of the font,
but for Verdana (the JUCE default sans-serif font on Windows) the sum of ascender and
descender is closer to the em-size. When the size of a font is set via
FontOptions::withHeight() or Font::setHeight(), JUCE will scale fonts based on the sum of
ascender and descender, so switching to Segoe UI might cause text to render at a much
smaller size than with Verdana. You may get better results by setting font sizes in points
using FontOptions::withFontHeight() and Font::setPointHeight(). When using points, Segoe UI
still renders slightly smaller than Verdana, but the differences are less pronounced.
*/
static Typeface::Ptr findSystemTypeface();