Sorry old habits die hard I meant Edge, I’ve corrected the original post.
Hi, sorry for the late reply. Thank you for your support, I’ve tried the font without hinting and now JUCE7 and JUCE8 are equivalent!
The hintless font resolved the problem for me too. Thank you!
I’ve been having some trouble upgrading some JUCE 7 plugins to JUCE 8, and this problem looks very similar to what I’ve been experiencing. The size and position of rendered text seems to have changed a lot, even when using legacy font metrics.
As a minimal example, here’s an editor with a simple paint method that draws some text at various sizes.
using namespace juce;
Font getFont()
{
constexpr Font::FontStyleFlags fontStyle {Font::bold};
constexpr int fontHeight = 15;
constexpr int fontKerning = 0;
String fontName {"Arial"};
// use non-deprecated Font constructor when using JUCE 8
#if JUCE_MAJOR_VERSION >= 8
const auto fontOptions = FontOptions( fontName, fontHeight, fontStyle).withMetricsKind(TypefaceMetricsKind::legacy);
Font font {fontOptions};
#else
Font font(fontName, fontHeight, fontStyle);
#endif
auto tfName {font.getTypefaceName()};
font.setExtraKerningFactor(fontKerning);
return font;
}
AudioPluginAudioProcessorEditor::AudioPluginAudioProcessorEditor (AudioPluginAudioProcessor& p)
: AudioProcessorEditor (&p), processorRef (p)
{
ignoreUnused (processorRef);
setSize (900, 900);
if (auto* peer = getPeer())
{
const auto engines = peer->getAvailableRenderingEngines();
const auto softwareIndex = engines.indexOf("Software Renderer");
if (softwareIndex >= 0)
{
peer->setCurrentRenderingEngine(softwareIndex);
}
}
}
void AudioPluginAudioProcessorEditor::paint (juce::Graphics& g)
{
g.fillAll (juce::Colours::white);
auto bounds = getLocalBounds();
constexpr int numSections = 10;
const auto sectionHeight = bounds.getHeight() / numSections;
int currentTextHeight = 30;
for (int i = 0; i < numSections; i++)
{
Font f = getFont().withHeight(currentTextHeight);
g.setFont(f);
String testStr {"ABCDEFG STOP stop"};
#if JUCE_MAJOR_VERSION >= 8
if (g.getCurrentFont().getMetricsKind() != TypefaceMetricsKind::legacy)
{
DBG("WARNING: Not using legacy font metrics");
jassertfalse;
}
#endif
auto section = bounds.removeFromTop(sectionHeight);
const auto textBounds = section.withSizeKeepingCentre( section.getWidth(), currentTextHeight);
g.drawFittedText(testStr, textBounds, juce::Justification::centred, 1);
currentTextHeight -= 3;
}
}
Even when using legacy font metrics and the software renderer, the text looks very different between JUCE 7 and JUCE 8.

The height of the text changes, and there are spacing differences (between the T and O).
Is this expected behavior? Am I correct in understanding that there’s no way to ensure consistent text rendering without using a bitmapped or non-hinted font?
Thank you!
Is this on Windows? If so it may well be due to font hinting which the Direct 2D renderer respects, where-as the software renderer was ignoring the information. How does the text compare to rendering it in other applications such as a browser?
EDIT:
Sorry you said you had tried the Software Renderer. I would still be interested to know if you see a big difference between other applications though.
Yes, this was rendered on Windows.
In other applications, the text is rendered pretty much identically to what JUCE 8 is rendering. I can appreciate that there was a lot of hard work put into improving text rendering in JUCE 8, and it certainly seems to be doing the right thing.
However, there are now some text alignment issues in plugins that I’m trying to upgrade to JUCE 8. It would be great if there was a way to opt back in to the older font rendering system for legacy plugins so they can be upgraded to JUCE 8 without UI changes.
It’s not clear to me if using legacy font metrics is intended to be sufficient to have text render as it did in previous versions of JUCE, since the sample I posted above leads to the overall height of the text changing between JUCE 7 and 8.
Based on the test you shared we dug into this and discovered a small regression going from J7 to J8. A fix has been released in develop
This however doesn’t explain all the differences you were seeing.
To have the closest possible behaviour to J7 rendering, you should
- use the software renderer
- disable kerning with
fontOptions.withFeatureDisabled ("kern")
For font sizes <= 3 or >= 25 this results in identical appearance in my testing.
For sizes between 3 and 25 the JUCE 7 software applies vertical hinting adjustments. This causes subtle differences, not nearly as apparent as the case demonstrated by your animgif.
Given the fundamental changes in the font rendering we can’t easily port this old hinting behaviour from JUCE 7, so there’s no way to avoid some minimal changes.
Thanks for looking into it and sharing those suggestions. Much appreciated!
