mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-09 23:34:20 +00:00
Font: Allow overriding typeface ascent and descent metrics
This commit is contained in:
parent
f12d29899c
commit
a381fdf81d
7 changed files with 190 additions and 48 deletions
|
|
@ -54,8 +54,7 @@
|
|||
|
||||
//==============================================================================
|
||||
class FontsDemo final : public Component,
|
||||
private ListBoxModel,
|
||||
private Slider::Listener
|
||||
private ListBoxModel
|
||||
{
|
||||
public:
|
||||
FontsDemo()
|
||||
|
|
@ -68,6 +67,10 @@ public:
|
|||
addAndMakeVisible (heightLabel);
|
||||
addAndMakeVisible (kerningLabel);
|
||||
addAndMakeVisible (kerningSlider);
|
||||
addAndMakeVisible (ascentLabel);
|
||||
addAndMakeVisible (ascentSlider);
|
||||
addAndMakeVisible (descentLabel);
|
||||
addAndMakeVisible (descentSlider);
|
||||
addAndMakeVisible (scaleLabel);
|
||||
addAndMakeVisible (horizontalJustificationLabel);
|
||||
addAndMakeVisible (verticalJustificationLabel);
|
||||
|
|
@ -84,12 +87,13 @@ public:
|
|||
heightLabel .attachToComponent (&heightSlider, true);
|
||||
scaleLabel .attachToComponent (&scaleSlider, true);
|
||||
styleLabel .attachToComponent (&styleBox, true);
|
||||
ascentLabel .attachToComponent (&ascentSlider, true);
|
||||
descentLabel .attachToComponent (&descentSlider, true);
|
||||
horizontalJustificationLabel.attachToComponent (&horizontalJustificationBox, true);
|
||||
verticalJustificationLabel .attachToComponent (&verticalJustificationBox, true);
|
||||
|
||||
heightSlider .addListener (this);
|
||||
kerningSlider.addListener (this);
|
||||
scaleSlider .addListener (this);
|
||||
for (auto* slider : { &heightSlider, &kerningSlider, &scaleSlider, &ascentSlider, &descentSlider })
|
||||
slider->onValueChange = [this] { refreshPreviewBoxFont(); };
|
||||
|
||||
boldToggle .onClick = [this] { refreshPreviewBoxFont(); };
|
||||
italicToggle .onClick = [this] { refreshPreviewBoxFont(); };
|
||||
|
|
@ -107,6 +111,11 @@ public:
|
|||
heightSlider .setRange (3.0, 150.0, 0.01);
|
||||
scaleSlider .setRange (0.2, 3.0, 0.01);
|
||||
kerningSlider.setRange (-2.0, 2.0, 0.01);
|
||||
ascentSlider .setRange (0.0, 2.0, 0.01);
|
||||
descentSlider.setRange (0.0, 2.0, 0.01);
|
||||
|
||||
ascentSlider .setValue (1, dontSendNotification);
|
||||
descentSlider.setValue (1, dontSendNotification);
|
||||
|
||||
// set up the layout and resizer bars..
|
||||
verticalLayout.setItemLayout (0, -0.2, -0.8, -0.35); // width of the font list must be
|
||||
|
|
@ -190,6 +199,10 @@ public:
|
|||
r.removeFromBottom (8);
|
||||
verticalJustificationBox.setBounds (r.removeFromBottom (30).withTrimmedLeft (labelWidth * 3));
|
||||
r.removeFromBottom (8);
|
||||
descentSlider.setBounds (r.removeFromBottom (30).withTrimmedLeft (labelWidth));
|
||||
r.removeFromBottom (8);
|
||||
ascentSlider.setBounds (r.removeFromBottom (30).withTrimmedLeft (labelWidth));
|
||||
r.removeFromBottom (8);
|
||||
scaleSlider.setBounds (r.removeFromBottom (30).withTrimmedLeft (labelWidth));
|
||||
r.removeFromBottom (8);
|
||||
kerningSlider.setBounds (r.removeFromBottom (30).withTrimmedLeft (labelWidth));
|
||||
|
|
@ -199,13 +212,6 @@ public:
|
|||
demoTextBox.setBounds (r);
|
||||
}
|
||||
|
||||
void sliderValueChanged (Slider* sliderThatWasMoved) override
|
||||
{
|
||||
if (sliderThatWasMoved == &heightSlider) refreshPreviewBoxFont();
|
||||
else if (sliderThatWasMoved == &kerningSlider) refreshPreviewBoxFont();
|
||||
else if (sliderThatWasMoved == &scaleSlider) refreshPreviewBoxFont();
|
||||
}
|
||||
|
||||
// The following methods implement the ListBoxModel virtual methods:
|
||||
int getNumRows() override
|
||||
{
|
||||
|
|
@ -223,7 +229,7 @@ public:
|
|||
AttributedString s;
|
||||
s.setWordWrap (AttributedString::none);
|
||||
s.setJustification (Justification::centredLeft);
|
||||
s.append (getNameForRow (rowNumber), font.withHeight ((float) height * 0.7f), Colours::black);
|
||||
s.append (getNameForRow (rowNumber), font.withPointHeight ((float) height * 0.7f), Colours::black);
|
||||
s.append (" " + font.getTypefaceName(), FontOptions ((float) height * 0.5f, Font::italic), Colours::grey);
|
||||
|
||||
s.draw (g, Rectangle<int> (width, height).expanded (-4, 50).toFloat());
|
||||
|
|
@ -236,6 +242,7 @@ public:
|
|||
|
||||
void selectedRowsChanged (int /*lastRowselected*/) override
|
||||
{
|
||||
resetMetricsSliders();
|
||||
refreshPreviewBoxFont();
|
||||
}
|
||||
|
||||
|
|
@ -251,14 +258,12 @@ private:
|
|||
ListBox listBox;
|
||||
TextEditor demoTextBox;
|
||||
|
||||
const double defaultScale = 1.0, defaultHeight = 20.0, defaultKerning = 0.0;
|
||||
const bool defaultBold = false, defaultItalic = false, defaultUnderlined = false;
|
||||
const int defaultStyle = 0, defaultHorizontalJustification = 0, defaultVerticalJustification = 0;
|
||||
|
||||
Label heightLabel { {}, "Height:" },
|
||||
kerningLabel { {}, "Kerning:" },
|
||||
scaleLabel { {}, "Scale:" },
|
||||
styleLabel { {}, "Style:" },
|
||||
ascentLabel { {}, "Ascent:" },
|
||||
descentLabel { {}, "Descent:" },
|
||||
horizontalJustificationLabel { {}, "Justification (horizontal):" },
|
||||
verticalJustificationLabel { {}, "Justification (vertical):" };
|
||||
|
||||
|
|
@ -268,7 +273,7 @@ private:
|
|||
|
||||
TextButton resetButton { "Reset" };
|
||||
|
||||
Slider heightSlider, kerningSlider, scaleSlider;
|
||||
Slider heightSlider, kerningSlider, scaleSlider, ascentSlider, descentSlider;
|
||||
ComboBox styleBox, horizontalJustificationBox, verticalJustificationBox;
|
||||
|
||||
StretchableLayoutManager verticalLayout;
|
||||
|
|
@ -283,17 +288,28 @@ private:
|
|||
//==============================================================================
|
||||
void resetToDefaultParameters()
|
||||
{
|
||||
scaleSlider .setValue (defaultScale);
|
||||
heightSlider .setValue (defaultHeight);
|
||||
kerningSlider.setValue (defaultKerning);
|
||||
scaleSlider .setValue (1.0);
|
||||
heightSlider .setValue (20.0);
|
||||
kerningSlider.setValue (0.0);
|
||||
|
||||
boldToggle .setToggleState (defaultBold, sendNotificationSync);
|
||||
italicToggle .setToggleState (defaultItalic, sendNotificationSync);
|
||||
underlineToggle.setToggleState (defaultUnderlined, sendNotificationSync);
|
||||
boldToggle .setToggleState (false, sendNotificationSync);
|
||||
italicToggle .setToggleState (false, sendNotificationSync);
|
||||
underlineToggle.setToggleState (false, sendNotificationSync);
|
||||
|
||||
styleBox.setSelectedItemIndex (defaultStyle);
|
||||
horizontalJustificationBox.setSelectedItemIndex (defaultHorizontalJustification);
|
||||
verticalJustificationBox .setSelectedItemIndex (defaultVerticalJustification);
|
||||
styleBox.setSelectedItemIndex (0);
|
||||
horizontalJustificationBox.setSelectedItemIndex (0);
|
||||
verticalJustificationBox .setSelectedItemIndex (0);
|
||||
|
||||
resetMetricsSliders();
|
||||
}
|
||||
|
||||
void resetMetricsSliders()
|
||||
{
|
||||
auto font = getFont (listBox.getSelectedRow());
|
||||
font.setPointHeight (1.0f);
|
||||
|
||||
ascentSlider .setValue (font.getAscentInPoints());
|
||||
descentSlider.setValue (font.getDescentInPoints());
|
||||
}
|
||||
|
||||
void setupJustificationOptions()
|
||||
|
|
@ -339,6 +355,8 @@ private:
|
|||
font = font.withTypefaceStyle (styleBox.getText());
|
||||
|
||||
font.setUnderline (underlineToggle.getToggleState());
|
||||
font.setAscentOverride ((float) ascentSlider .getValue());
|
||||
font.setDescentOverride ((float) descentSlider.getValue());
|
||||
|
||||
demoTextBox.applyFontToAllText (font);
|
||||
}
|
||||
|
|
@ -353,7 +371,7 @@ private:
|
|||
|
||||
styleBox.clear();
|
||||
styleBox.addItemList (newStyles, 1);
|
||||
styleBox.setSelectedItemIndex (defaultStyle);
|
||||
styleBox.setSelectedItemIndex (0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -220,17 +220,24 @@ public:
|
|||
const ScopedLock lock (mutex);
|
||||
|
||||
if (auto ptr = getTypefacePtr (f))
|
||||
return ptr->getNativeDetails().getFontAtSizeAndScale (f.getMetricsKind(), f.getHeight(), f.getHorizontalScale());
|
||||
return ptr->getNativeDetails().getFontAtPointSizeAndScale (f.getHeightInPoints(), f.getHorizontalScale());
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
TypefaceMetrics getMetrics (const Font& f)
|
||||
TypefaceAscentDescent getAscentDescent (const Font& f)
|
||||
{
|
||||
const ScopedLock lock (mutex);
|
||||
|
||||
if (auto ptr = getTypefacePtr (f))
|
||||
return ptr->getMetrics (f.getMetricsKind());
|
||||
{
|
||||
const auto ascentDescent = ptr->getNativeDetails().getAscentDescent (f.getMetricsKind());
|
||||
|
||||
auto adjusted = ascentDescent;
|
||||
adjusted.ascent = getAscentOverride().value_or (adjusted.ascent);
|
||||
adjusted.descent = getDescentOverride().value_or (adjusted.descent);
|
||||
return adjusted;
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
|
@ -262,6 +269,9 @@ public:
|
|||
bool getFallbackEnabled() const { return options.getFallbackEnabled(); }
|
||||
TypefaceMetricsKind getMetricsKind() const { return options.getMetricsKind(); }
|
||||
|
||||
std::optional<float> getAscentOverride() const { return options.getAscentOverride(); }
|
||||
std::optional<float> getDescentOverride() const { return options.getDescentOverride(); }
|
||||
|
||||
/* This shared state may be shared between two or more Font instances that are being
|
||||
read/modified from multiple threads.
|
||||
Before modifying a shared instance you *must* call dupeInternalIfShared to
|
||||
|
|
@ -316,6 +326,18 @@ public:
|
|||
options = options.withKerningFactor (x);
|
||||
}
|
||||
|
||||
void setAscentOverride (std::optional<float> x)
|
||||
{
|
||||
jassert (getReferenceCount() == 1);
|
||||
options = options.withAscentOverride (x);
|
||||
}
|
||||
|
||||
void setDescentOverride (std::optional<float> x)
|
||||
{
|
||||
jassert (getReferenceCount() == 1);
|
||||
options = options.withDescentOverride (x);
|
||||
}
|
||||
|
||||
void setUnderline (bool x)
|
||||
{
|
||||
jassert (getReferenceCount() == 1);
|
||||
|
|
@ -544,7 +566,7 @@ Font Font::withHeight (const float newHeight) const
|
|||
|
||||
float Font::getHeightToPointsFactor() const
|
||||
{
|
||||
return getTypefacePtr()->getMetrics (getMetricsKind()).heightToPoints;
|
||||
return font->getAscentDescent (*this).getHeightToPointsFactor();
|
||||
}
|
||||
|
||||
Font Font::withPointHeight (float heightInPoints) const
|
||||
|
|
@ -699,6 +721,26 @@ void Font::setExtraKerningFactor (const float extraKerning)
|
|||
font->resetTypeface();
|
||||
}
|
||||
|
||||
std::optional<float> Font::getAscentOverride() const noexcept
|
||||
{
|
||||
return font->getAscentOverride();
|
||||
}
|
||||
|
||||
void Font::setAscentOverride (std::optional<float> x)
|
||||
{
|
||||
font->setAscentOverride (x);
|
||||
}
|
||||
|
||||
std::optional<float> Font::getDescentOverride() const noexcept
|
||||
{
|
||||
return font->getDescentOverride();
|
||||
}
|
||||
|
||||
void Font::setDescentOverride (std::optional<float> x)
|
||||
{
|
||||
font->setDescentOverride (x);
|
||||
}
|
||||
|
||||
Font Font::boldened() const { return withStyle (getStyleFlags() | bold); }
|
||||
Font Font::italicised() const { return withStyle (getStyleFlags() | italic); }
|
||||
|
||||
|
|
@ -731,14 +773,14 @@ void Font::setUnderline (const bool shouldBeUnderlined)
|
|||
|
||||
float Font::getAscent() const
|
||||
{
|
||||
return font->getMetrics (*this).ascent * getHeight();
|
||||
return font->getAscentDescent (*this).getScaledAscent() * 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();
|
||||
return height > 0.0f ? height : font->getPointHeight() * font->getAscentDescent (*this).getPointsToHeightFactor();
|
||||
}
|
||||
|
||||
float Font::getDescent() const { return getHeight() - getAscent(); }
|
||||
|
|
@ -747,7 +789,17 @@ 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();
|
||||
|
||||
if (pointHeight > 0.0f)
|
||||
return pointHeight;
|
||||
|
||||
const auto factor = font->getAscentDescent (*this).getPointsToHeightFactor();
|
||||
|
||||
if (factor > 0.0f)
|
||||
return font->getHeight() / factor;
|
||||
|
||||
jassertfalse;
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
float Font::getAscentInPoints() const { return getAscent() * getHeightToPointsFactor(); }
|
||||
|
|
|
|||
|
|
@ -434,6 +434,50 @@ public:
|
|||
*/
|
||||
void setExtraKerningFactor (float extraKerning);
|
||||
|
||||
/** @see setAscentOverride() */
|
||||
std::optional<float> getAscentOverride() const noexcept;
|
||||
|
||||
/** This is designed to mirror CSS's ascent-override property.
|
||||
|
||||
When the font size is specified in points (using setPointHeight(),
|
||||
FontOptions::withPointHeight(), etc.), then the font's ascent value in points will be equal
|
||||
to the font's size in points multiplied by the override value. That is, if the font size
|
||||
is 14pt and the ascent override is 0.5f, then the ascent will be 7pt.
|
||||
|
||||
When the font size is *not* specified in points (using setHeight(),
|
||||
FontOptions::withHeight(), etc.), then the behaviour is more subtle.
|
||||
The ascent override still specifies the size of the font's ascender as a proportion of the
|
||||
font's em size.
|
||||
However, the point size of the font is now found by multiplying the JUCE height by the
|
||||
height-to-point factor, where this factor is equal to
|
||||
(1.0f / (ascent-in-em-units + descent-in-em-units)).
|
||||
As an example, if the JUCE font height is 14, the ascent override is 0.5f, and the
|
||||
descent override is 0.5f, then the font size will be 14pt and the ascent will be 7pt.
|
||||
Changing the ascent override to 1.0f and the descent override to 0.0f will preserve the
|
||||
font size of 14pt but give an ascender of 14pt and a descender of 0pt.
|
||||
Changing the ascent and descent overrides both to 1.0f will result in the
|
||||
font's size changing to 7pt with an ascent of 3.5pt.
|
||||
|
||||
@see setDescentOverride()
|
||||
*/
|
||||
void setAscentOverride (std::optional<float>);
|
||||
|
||||
/** @see setDescentOverride() */
|
||||
std::optional<float> getDescentOverride() const noexcept;
|
||||
|
||||
/** This is designed to mirror CSS's descent-override property.
|
||||
|
||||
Specifies a value to replace the built-in typeface descent metric.
|
||||
The final descent value will be found by multiplying the provided value by the font
|
||||
size. You may also pass std::nullopt to use the descent value specified in the typeface.
|
||||
|
||||
The documentation for setAscentOverride() includes a more thorough discussion
|
||||
of the mechanism used for overriding.
|
||||
|
||||
@see setAscentOverride()
|
||||
*/
|
||||
void setDescentOverride (std::optional<float>);
|
||||
|
||||
//==============================================================================
|
||||
/** Changes all the font's characteristics with one call. */
|
||||
void setSizeAndStyle (float newHeight,
|
||||
|
|
|
|||
|
|
@ -93,6 +93,8 @@ auto FontOptions::tie() const
|
|||
typeface.get(),
|
||||
fallbacks,
|
||||
metricsKind,
|
||||
ascentOverride,
|
||||
descentOverride,
|
||||
height,
|
||||
pointHeight,
|
||||
tracking,
|
||||
|
|
|
|||
|
|
@ -161,9 +161,21 @@ public:
|
|||
/** Returns a copy of these options with underline enabled or disabled, defaults to disabled. */
|
||||
[[nodiscard]] FontOptions withUnderline (bool x = true) const { return withMember (*this, &FontOptions::underlined, x); }
|
||||
|
||||
/** Returns a copy of these options the specified metrics kind. */
|
||||
/** Returns a copy of these options with the specified metrics kind. */
|
||||
[[nodiscard]] FontOptions withMetricsKind (TypefaceMetricsKind x) const { return withMember (*this, &FontOptions::metricsKind, x); }
|
||||
|
||||
/** Returns a copy of these options with the specified font metrics value override.
|
||||
std::nullopt indicates that the font should use the built-in typeface metric; otherwise,
|
||||
the ascent value will be found by multiplying the provided value by the font size in points.
|
||||
*/
|
||||
[[nodiscard]] FontOptions withAscentOverride (std::optional<float> x) const { return withMember (*this, &FontOptions::ascentOverride, x.value_or (-1.0f)); }
|
||||
|
||||
/** Returns a copy of these options with the specified font metrics value override.
|
||||
std::nullopt indicates that the font should use the built-in typeface metric; otherwise,
|
||||
the descent value will be found by multiplying the provided value by the font size in points.
|
||||
*/
|
||||
[[nodiscard]] FontOptions withDescentOverride (std::optional<float> x) const { return withMember (*this, &FontOptions::descentOverride, x.value_or (-1.0f)); }
|
||||
|
||||
/** @see withName() */
|
||||
[[nodiscard]] auto getName() const { return name; }
|
||||
/** @see withStyle() */
|
||||
|
|
@ -186,6 +198,10 @@ public:
|
|||
[[nodiscard]] auto getUnderline() const { return underlined; }
|
||||
/** @see withMetricsKind() */
|
||||
[[nodiscard]] auto getMetricsKind() const { return metricsKind; }
|
||||
/** @see withAscentOverride() */
|
||||
[[nodiscard]] auto getAscentOverride() const { return ascentOverride >= 0.0f ? std::make_optional (ascentOverride) : std::nullopt; }
|
||||
/** @see withDescentOverride() */
|
||||
[[nodiscard]] auto getDescentOverride() const { return descentOverride >= 0.0f ? std::make_optional (descentOverride) : std::nullopt; }
|
||||
|
||||
/** Equality operator. */
|
||||
[[nodiscard]] bool operator== (const FontOptions& other) const;
|
||||
|
|
@ -211,6 +227,8 @@ private:
|
|||
float pointHeight = -1.0f;
|
||||
float tracking{};
|
||||
float horizontalScale = 1.0f;
|
||||
float ascentOverride = -1.0f;
|
||||
float descentOverride = -1.0f;
|
||||
bool fallbackEnabled = true;
|
||||
bool underlined{};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -185,7 +185,7 @@ public:
|
|||
|
||||
auto* getFont() const { return font; }
|
||||
|
||||
TypefaceAscentDescent getMetrics (TypefaceMetricsKind kind) const
|
||||
TypefaceAscentDescent getAscentDescent (TypefaceMetricsKind kind) const
|
||||
{
|
||||
switch (kind)
|
||||
{
|
||||
|
|
@ -199,10 +199,9 @@ public:
|
|||
return {};
|
||||
}
|
||||
|
||||
HbFont getFontAtSizeAndScale (TypefaceMetricsKind kind, float height, float horizontalScale) const
|
||||
HbFont getFontAtPointSizeAndScale (float points, float horizontalScale) const
|
||||
{
|
||||
HbFont subFont { hb_font_create_sub_font (font) };
|
||||
const auto points = height * getMetrics (kind).getHeightToPointsFactor();
|
||||
|
||||
hb_font_set_ptem (subFont.get(), points);
|
||||
hb_font_set_scale (subFont.get(), HbScale::juceToHb (points * horizontalScale), HbScale::juceToHb (points));
|
||||
|
|
@ -405,8 +404,10 @@ void Typeface::getOutlineForGlyph (TypefaceMetricsKind kind, int glyphNumber, Pa
|
|||
{
|
||||
const auto native = getNativeDetails();
|
||||
auto* font = native.getFont();
|
||||
const auto metrics = native.getMetrics (kind);
|
||||
const auto scale = metrics.getHeightToPointsFactor() / (float) hb_face_get_upem (hb_font_get_face (font));
|
||||
const auto metrics = native.getAscentDescent (kind);
|
||||
const auto factor = metrics.getHeightToPointsFactor();
|
||||
jassert (! std::isinf (factor));
|
||||
const auto scale = factor / (float) hb_face_get_upem (hb_font_get_face (font));
|
||||
|
||||
// getTypefaceGlyph returns glyphs in em space, getOutlineForGlyph returns glyphs in "special JUCE units" space
|
||||
path = getGlyphPathInGlyphUnits ((hb_codepoint_t) glyphNumber, getNativeDetails().getFont());
|
||||
|
|
@ -422,8 +423,10 @@ Rectangle<float> Typeface::getGlyphBounds (TypefaceMetricsKind kind, int glyphNu
|
|||
return {};
|
||||
|
||||
const auto native = getNativeDetails();
|
||||
const auto metrics = native.getMetrics (kind);
|
||||
const auto scale = metrics.getHeightToPointsFactor() / (float) hb_face_get_upem (hb_font_get_face (font));
|
||||
const auto metrics = native.getAscentDescent (kind);
|
||||
const auto factor = metrics.getHeightToPointsFactor();
|
||||
jassert (! std::isinf (factor));
|
||||
const auto scale = factor / (float) hb_face_get_upem (hb_font_get_face (font));
|
||||
|
||||
return Rectangle { (float) extents.width, (float) extents.height }
|
||||
.withPosition ((float) extents.x_bearing, (float) extents.y_bearing)
|
||||
|
|
@ -524,8 +527,10 @@ static std::vector<GlyphLayer> getBitmapLayer (const Typeface& typeface, int gly
|
|||
std::vector<GlyphLayer> Typeface::getLayersForGlyph (TypefaceMetricsKind kind, int glyphNumber, const AffineTransform& transform, float) const
|
||||
{
|
||||
auto* font = getNativeDetails().getFont();
|
||||
const auto metrics = getNativeDetails().getMetrics (kind);
|
||||
const auto scale = metrics.getHeightToPointsFactor() / (float) hb_face_get_upem (hb_font_get_face (font));
|
||||
const auto metrics = getNativeDetails().getAscentDescent (kind);
|
||||
const auto factor = metrics.getHeightToPointsFactor();
|
||||
jassert (! std::isinf (factor));
|
||||
const auto scale = factor / (float) hb_face_get_upem (hb_font_get_face (font));
|
||||
const auto combinedTransform = AffineTransform::scale (scale, -scale).followedBy (transform);
|
||||
|
||||
if (auto bitmapLayer = getBitmapLayer (*this, glyphNumber, combinedTransform); ! bitmapLayer.empty())
|
||||
|
|
@ -558,7 +563,7 @@ int Typeface::getColourGlyphFormats() const
|
|||
|
||||
TypefaceMetrics Typeface::getMetrics (TypefaceMetricsKind kind) const
|
||||
{
|
||||
return getNativeDetails().getMetrics (kind).getTypefaceMetrics();
|
||||
return getNativeDetails().getAscentDescent (kind).getTypefaceMetrics();
|
||||
}
|
||||
|
||||
Typeface::Ptr Typeface::createSystemTypefaceFor (const void* fontFileData, size_t fontFileDataSize)
|
||||
|
|
@ -601,7 +606,8 @@ static float doSimpleShapeWithNoBreaks (const Typeface& typeface,
|
|||
hb_buffer_guess_segment_properties (buffer.get());
|
||||
|
||||
const auto& native = typeface.getNativeDetails();
|
||||
const auto sized = native.getFontAtSizeAndScale (kind, height, horizontalScale);
|
||||
const auto points = typeface.getMetrics (kind).heightToPoints * height;
|
||||
const auto sized = native.getFontAtPointSizeAndScale (points, horizontalScale);
|
||||
auto* font = sized.get();
|
||||
|
||||
// Disable ligatures, because TextEditor requires a 1:1 codepoint/glyph mapping for caret
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ enum class TypefaceMetricsKind
|
|||
*/
|
||||
struct TypefaceMetrics
|
||||
{
|
||||
/** The proportion of the typeface's height that it above the baseline, as a value between 0 and 1.
|
||||
/** The proportion of the typeface's height that is above the baseline, as a value between 0 and 1.
|
||||
Note that 'height' here refers to the result of adding the absolute ascent and descent values.
|
||||
That is, the sum of the ascent and descent will equal 1.
|
||||
The sum of the ascent and descent will normally differ from the em size of the font.
|
||||
|
|
@ -107,6 +107,8 @@ struct TypefaceMetrics
|
|||
|
||||
/** The factor by which a JUCE font height should be multiplied in order to convert to a font
|
||||
size in points.
|
||||
|
||||
May be inf if the font ascent and descent overrides have both been set to 0!
|
||||
*/
|
||||
float heightToPoints{};
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue