Bug: Inconsistent rounding in VSTGUI's HiDPI support


We (the JUCE team) believe to have found a bug in the code for supporting fractional HiDPI scale factors:

The bug can easily be reproduced with any fixed editor sized VST3 plug-in using vstgui (like again.vst3) and a HiDPI screen with a fractional (non-integer) scaling factor (such as 1.75) on Windows.

The problem is that vstgui will receive cFrame::setZoom callback when the scale of the plug-in should change. cFrame::setZoom will then calculate the new expected window size:

CCoord newWidth  = std::ceil (origWidth  * zoomFactor);
CCoord newHeight = std::ceil (origHeight * zoomFactor);

cFrame::setZoom will then attempt to re-size the window to the new size via a call to setSize. Inside that setSize call and further down the call-stack, VST3Editor::requestSize will check if the new size matches the constraints of the plug-in

if (editingEnabled 
      || (width >= minSize.x * scaleFactor
           && width <= maxSize.x * scaleFactor 
           && height >= minSize.y * scaleFactor 
           && height <= maxSize.y * scaleFactor))

and bail out if the constraints are not met.

However, you can easily see that for any fractional scaling factor and fixed sized editors (minSize = maxSize), the extra std::ceil in setZoom will result in the constraints almost never being met.

Removing the std::ceil is also not an option as the window of plug-in must be an integer value. Putting std::ceil in both places also does not work in our testing - parts of vstgui do the reverse transform and then the ambiguity of two sizes with a difference of just less than a full pixel causes problems.

The fix that works in our case is to simply use std::round in both cases. Attached to this e-mail is a patch that does exactly that.

Thanks for your help!


VST3_rounding.patch.zip (2.15 KB)

Hi Fabian,
thanks for the report, we will look into it.