Browse Source

Bring back auto-scaling through a different, better API

Signed-off-by: falkTX <falktx@falktx.com>
pull/517/head
falkTX 1 month ago
parent
commit
4d05c7af56
Signed by: falkTX <falktx@falktx.com> GPG Key ID: CDBAA37ABC74FBA0
14 changed files with 74 additions and 135 deletions
  1. +10
    -0
      dgl/Window.hpp
  2. +2
    -30
      dgl/src/Cairo.cpp
  3. +6
    -9
      dgl/src/ImageBaseWidgets.cpp
  4. +2
    -25
      dgl/src/OpenGL.cpp
  5. +7
    -2
      dgl/src/OpenGL2.cpp
  6. +0
    -6
      dgl/src/Stub.cpp
  7. +0
    -4
      dgl/src/SubWidgetPrivateData.hpp
  8. +0
    -7
      dgl/src/TopLevelWidgetPrivateData.cpp
  9. +2
    -14
      dgl/src/Vulkan.cpp
  10. +2
    -11
      dgl/src/WidgetPrivateData.cpp
  11. +1
    -6
      dgl/src/WidgetPrivateData.hpp
  12. +41
    -6
      dgl/src/Window.cpp
  13. +1
    -13
      dgl/src/WindowPrivateData.cpp
  14. +0
    -2
      dgl/src/WindowPrivateData.hpp

+ 10
- 0
dgl/Window.hpp View File

@@ -393,6 +393,16 @@ public:
*/
double getScaleFactor() const noexcept;

/**
Enable automatic internal scaling based on a custom width and height.
This will internally scale up drawing and scale down user events coordinates and sizes,
but the result is likely blurry.

This can be used as an early step for high-dpi support,
that scales up the window contents in a blurry but usable way.
*/
void enableInternalScalingWithSize(uint baseWidth, uint baseHeight, bool keepAspectRatio = false);

/**
Grab the keyboard input focus.
*/


+ 2
- 30
dgl/src/Cairo.cpp View File

@@ -736,11 +736,7 @@ template class ImageBaseSwitch<CairoImage>;

// -----------------------------------------------------------------------

void SubWidget::PrivateData::display(const uint width, const uint height
#if DGL_ALLOW_DEPRECATED_METHODS
, const double autoScaleFactor
#endif
)
void SubWidget::PrivateData::display(const uint width, const uint height, const double autoScaleFactor)
{
cairo_t* const handle = static_cast<const CairoGraphicsContext&>(self->getGraphicsContext()).handle;

@@ -758,13 +754,10 @@ void SubWidget::PrivateData::display(const uint width, const uint height
{
// full viewport size
cairo_translate(handle, 0, 0);
#if DGL_ALLOW_DEPRECATED_METHODS
cairo_scale(handle, autoScaleFactor, autoScaleFactor);
#endif
}
else
{
#if DGL_ALLOW_DEPRECATED_METHODS
// set viewport pos
cairo_translate(handle, absolutePos.getX() * autoScaleFactor, absolutePos.getY() * autoScaleFactor);

@@ -774,21 +767,12 @@ void SubWidget::PrivateData::display(const uint width, const uint height
0,
std::round(self->getWidth() * autoScaleFactor),
std::round(self->getHeight() * autoScaleFactor));
#else
// set viewport pos
cairo_translate(handle, absolutePos.getX(), absolutePos.getY());

// then cut the outer bounds
cairo_rectangle(handle, 0, 0, self->getWidth(), self->getHeight());
#endif

cairo_clip(handle);
needsResetClip = true;

#if DGL_ALLOW_DEPRECATED_METHODS
// set viewport scaling
cairo_scale(handle, autoScaleFactor, autoScaleFactor);
#endif
}

// display widget
@@ -799,11 +783,7 @@ void SubWidget::PrivateData::display(const uint width, const uint height

cairo_set_matrix(handle, &matrix);

#if DGL_ALLOW_DEPRECATED_METHODS
selfw->pData->displaySubWidgets(width, height, autoScaleFactor);
#else
selfw->pData->displaySubWidgets(width, height);
#endif
}

// -----------------------------------------------------------------------
@@ -819,9 +799,7 @@ void TopLevelWidget::PrivateData::display()
const uint width = size.getWidth();
const uint height = size.getHeight();

#if DGL_ALLOW_DEPRECATED_METHODS
const double autoScaleFactor = window.pData->autoScaleFactor;
#endif

cairo_matrix_t matrix;
cairo_get_matrix(handle, &matrix);
@@ -829,12 +807,10 @@ void TopLevelWidget::PrivateData::display()
// full viewport size
cairo_translate(handle, 0, 0);

#if DGL_ALLOW_DEPRECATED_METHODS
if (window.pData->autoScaling)
cairo_scale(handle, autoScaleFactor, autoScaleFactor);
else
cairo_scale(handle, 1.0, 1.0);
#endif

// main widget drawing
self->onDisplay();
@@ -842,11 +818,7 @@ void TopLevelWidget::PrivateData::display()
cairo_set_matrix(handle, &matrix);

// now draw subwidgets if there are any
selfw->pData->displaySubWidgets(width, height
#if DGL_ALLOW_DEPRECATED_METHODS
, autoScaleFactor
#endif
);
selfw->pData->displaySubWidgets(width, height, autoScaleFactor);
}

// -----------------------------------------------------------------------


+ 6
- 9
dgl/src/ImageBaseWidgets.cpp View File

@@ -31,9 +31,8 @@ ImageBaseAboutWindow<ImageType>::ImageBaseAboutWindow(Window& transientParentWin

if (image.isValid())
{
const double scaleFactor = getScaleFactor();
setSize(image.getSize() * scaleFactor);
setGeometryConstraints(image.getWidth() * scaleFactor, image.getHeight() * scaleFactor, true);
enableInternalScalingWithSize(image.getWidth(), image.getHeight(), true);
setSize(image.getSize());
}

done();
@@ -49,9 +48,8 @@ ImageBaseAboutWindow<ImageType>::ImageBaseAboutWindow(TopLevelWidget* const topL

if (image.isValid())
{
const double scaleFactor = getScaleFactor();
setSize(image.getSize() * scaleFactor);
setGeometryConstraints(image.getWidth(), image.getHeight(), true);
enableInternalScalingWithSize(image.getWidth(), image.getHeight(), true);
setSize(image.getSize());
}

done();
@@ -73,9 +71,8 @@ void ImageBaseAboutWindow<ImageType>::setImage(const ImageType& image)

img = image;

const double scaleFactor = getScaleFactor();
setSize(image.getSize() * scaleFactor);
setGeometryConstraints(image.getWidth() * scaleFactor, image.getHeight() * scaleFactor, true);
enableInternalScalingWithSize(image.getWidth(), image.getHeight(), true);
setSize(image.getSize());

done();
}


+ 2
- 25
dgl/src/OpenGL.cpp View File

@@ -157,11 +157,7 @@ OpenGLImage::OpenGLImage(const char* const rdata, const Size<uint>& s, const GLe

// --------------------------------------------------------------------------------------------------------------------

void SubWidget::PrivateData::display(const uint width, const uint height
#if DGL_ALLOW_DEPRECATED_METHODS
, const double autoScaleFactor
#endif
)
void SubWidget::PrivateData::display(const uint width, const uint height, const double autoScaleFactor)
{
if (skipDrawing)
return;
@@ -195,7 +191,6 @@ void SubWidget::PrivateData::display(const uint width, const uint height
}
else
{
#if DGL_ALLOW_DEPRECATED_METHODS
// set viewport pos
glViewport(d_roundToIntPositive(absolutePos.getX() * autoScaleFactor),
-d_roundToIntPositive(absolutePos.getY() * autoScaleFactor),
@@ -207,16 +202,6 @@ void SubWidget::PrivateData::display(const uint width, const uint height
d_roundToIntPositive(height - (static_cast<int>(self->getHeight()) + absolutePos.getY()) * autoScaleFactor),
d_roundToIntPositive(self->getWidth() * autoScaleFactor),
d_roundToIntPositive(self->getHeight() * autoScaleFactor));
#else
// set viewport pos
glViewport(absolutePos.getX(), -absolutePos.getY(), static_cast<int>(width), static_cast<int>(height));

// then cut the outer bounds
glScissor(absolutePos.getX(),
static_cast<int>(height) - self->getHeight() + absolutePos.getY(),
static_cast<int>(self->getWidth()),
static_cast<int>(self->getHeight()));
#endif

glEnable(GL_SCISSOR_TEST);
needsDisableScissor = true;
@@ -228,11 +213,7 @@ void SubWidget::PrivateData::display(const uint width, const uint height
if (needsDisableScissor)
glDisable(GL_SCISSOR_TEST);

#if DGL_ALLOW_DEPRECATED_METHODS
selfw->pData->displaySubWidgets(width, height, autoScaleFactor);
#else
selfw->pData->displaySubWidgets(width, height);
#endif
}

// --------------------------------------------------------------------------------------------------------------------
@@ -253,11 +234,7 @@ void TopLevelWidget::PrivateData::display()
self->onDisplay();

// now draw subwidgets if there are any
selfw->pData->displaySubWidgets(width, height
#if DGL_ALLOW_DEPRECATED_METHODS
, window.pData->autoScaleFactor
#endif
);
selfw->pData->displaySubWidgets(width, height, window.pData->autoScaleFactor);
}

// --------------------------------------------------------------------------------------------------------------------


+ 7
- 2
dgl/src/OpenGL2.cpp View File

@@ -1,6 +1,6 @@
/*
* DISTRHO Plugin Framework (DPF)
* Copyright (C) 2012-2025 Filipe Coelho <falktx@falktx.com>
* Copyright (C) 2012-2026 Filipe Coelho <falktx@falktx.com>
*
* Permission to use, copy, modify, and/or distribute this software for any purpose with
* or without fee is hereby granted, provided that the above copyright notice and this
@@ -538,7 +538,12 @@ void Window::PrivateData::startContext()
glViewport(0, 0, static_cast<GLsizei>(size.width), static_cast<GLsizei>(size.height));
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, static_cast<GLdouble>(size.width), static_cast<GLdouble>(size.height), 0.0, 0.0, 1.0);
glOrtho(0.0,
static_cast<GLdouble>(size.width) / autoScaleFactor,
static_cast<GLdouble>(size.height) / autoScaleFactor,
0.0,
0.0,
1.0);
glViewport(0, 0, static_cast<GLsizei>(size.width), static_cast<GLsizei>(size.height));
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();


+ 0
- 6
dgl/src/Stub.cpp View File

@@ -172,15 +172,9 @@ void Rectangle<T>::drawOutline()

// --------------------------------------------------------------------------------------------------------------------

#if DGL_ALLOW_DEPRECATED_METHODS
void SubWidget::PrivateData::display(uint, uint, double)
{
}
#else
void SubWidget::PrivateData::display(uint, uint)
{
}
#endif

// --------------------------------------------------------------------------------------------------------------------



+ 0
- 4
dgl/src/SubWidgetPrivateData.hpp View File

@@ -38,11 +38,7 @@ struct SubWidget::PrivateData {
~PrivateData();

// NOTE display function is different depending on build type, must call displaySubWidgets at the end
#if DGL_ALLOW_DEPRECATED_METHODS
void display(uint width, uint height, double autoScaleFactor);
#else
void display(uint width, uint height);
#endif

DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PrivateData)
};


+ 0
- 7
dgl/src/TopLevelWidgetPrivateData.cpp View File

@@ -17,7 +17,6 @@
#include "TopLevelWidgetPrivateData.hpp"
#include "WidgetPrivateData.hpp"
#include "WindowPrivateData.hpp"
#include "pugl.hpp"

START_NAMESPACE_DGL

@@ -75,7 +74,6 @@ bool TopLevelWidget::PrivateData::mouseEvent(const MouseEvent& ev)

MouseEvent rev = ev;

#if DGL_ALLOW_DEPRECATED_METHODS
if (window.pData->autoScaling)
{
const double autoScaleFactor = window.pData->autoScaleFactor;
@@ -85,7 +83,6 @@ bool TopLevelWidget::PrivateData::mouseEvent(const MouseEvent& ev)
rev.absolutePos.setX(ev.absolutePos.getX() / autoScaleFactor);
rev.absolutePos.setY(ev.absolutePos.getY() / autoScaleFactor);
}
#endif

// propagate event to all subwidgets recursively
return selfw->pData->giveMouseEventForSubWidgets(rev);
@@ -99,7 +96,6 @@ bool TopLevelWidget::PrivateData::motionEvent(const MotionEvent& ev)

MotionEvent rev = ev;

#if DGL_ALLOW_DEPRECATED_METHODS
if (window.pData->autoScaling)
{
const double autoScaleFactor = window.pData->autoScaleFactor;
@@ -109,7 +105,6 @@ bool TopLevelWidget::PrivateData::motionEvent(const MotionEvent& ev)
rev.absolutePos.setX(ev.absolutePos.getX() / autoScaleFactor);
rev.absolutePos.setY(ev.absolutePos.getY() / autoScaleFactor);
}
#endif

// propagate event to all subwidgets recursively
return selfw->pData->giveMotionEventForSubWidgets(rev);
@@ -123,7 +118,6 @@ bool TopLevelWidget::PrivateData::scrollEvent(const ScrollEvent& ev)

ScrollEvent rev = ev;

#if DGL_ALLOW_DEPRECATED_METHODS
if (window.pData->autoScaling)
{
const double autoScaleFactor = window.pData->autoScaleFactor;
@@ -135,7 +129,6 @@ bool TopLevelWidget::PrivateData::scrollEvent(const ScrollEvent& ev)
rev.delta.setX(ev.delta.getX() / autoScaleFactor);
rev.delta.setY(ev.delta.getY() / autoScaleFactor);
}
#endif

// propagate event to all subwidgets recursively
return selfw->pData->giveScrollEventForSubWidgets(rev);


+ 2
- 14
dgl/src/Vulkan.cpp View File

@@ -235,19 +235,11 @@ VulkanImage& VulkanImage::operator=(const VulkanImage& image) noexcept

// -----------------------------------------------------------------------

void SubWidget::PrivateData::display(const uint width, const uint height
#if DGL_ALLOW_DEPRECATED_METHODS
, const double autoScaleFactor
#endif
)
void SubWidget::PrivateData::display(const uint width, const uint height, const double autoScaleFactor)
{
// TODO

#if DGL_ALLOW_DEPRECATED_METHODS
selfw->pData->displaySubWidgets(width, height, autoScaleFactor);
#else
selfw->pData->displaySubWidgets(width, height);
#endif
}

// -----------------------------------------------------------------------
@@ -267,11 +259,7 @@ void TopLevelWidget::PrivateData::display()
self->onDisplay();

// now draw subwidgets if there are any
selfw->pData->displaySubWidgets(width, height
#if DGL_ALLOW_DEPRECATED_METHODS
, window.pData->autoScaleFactor
#endif
);
selfw->pData->displaySubWidgets(width, height, window.pData->autoScaleFactor);
}

// -----------------------------------------------------------------------


+ 2
- 11
dgl/src/WidgetPrivateData.cpp View File

@@ -56,12 +56,7 @@ Widget::PrivateData::~PrivateData()
std::free(name);
}

void Widget::PrivateData::displaySubWidgets(const uint width,
const uint height
#if DGL_ALLOW_DEPRECATED_METHODS
, const double autoScaleFactor
#endif
)
void Widget::PrivateData::displaySubWidgets(const uint width, const uint height, const double autoScaleFactor)
{
if (subWidgets.size() == 0)
return;
@@ -71,11 +66,7 @@ void Widget::PrivateData::displaySubWidgets(const uint width,
SubWidget* const subwidget(*it);

if (subwidget->isVisible())
subwidget->pData->display(width, height
#if DGL_ALLOW_DEPRECATED_METHODS
, autoScaleFactor
#endif
);
subwidget->pData->display(width, height, autoScaleFactor);
}
}



+ 1
- 6
dgl/src/WidgetPrivateData.hpp View File

@@ -42,12 +42,7 @@ struct Widget::PrivateData {
explicit PrivateData(Widget* const s, Widget* const pw);
~PrivateData();

void displaySubWidgets(uint width,
uint height
#if DGL_ALLOW_DEPRECATED_METHODS
, double autoScaleFactor
#endif
);
void displaySubWidgets(uint width, uint height, double autoScaleFactor);

bool giveKeyboardEventForSubWidgets(const KeyboardEvent& ev);
bool giveCharacterInputEventForSubWidgets(const CharacterInputEvent& ev);


+ 41
- 6
dgl/src/Window.cpp View File

@@ -270,20 +270,20 @@ void Window::setSize(uint width, uint height)
{
DISTRHO_SAFE_ASSERT_UINT2_RETURN(width > 1 && height > 1, width, height,);

const double scaleFactor = pData->scaleFactor;

if (pData->isEmbed)
{
uint minWidth = pData->minWidth;
uint minHeight = pData->minHeight;

#if DGL_ALLOW_DEPRECATED_METHODS
const double scaleFactor = pData->scaleFactor;

if (pData->autoScaling && d_isNotEqual(scaleFactor, 1.0))
{
minWidth = d_roundToUnsignedInt(minWidth * scaleFactor);
minHeight = d_roundToUnsignedInt(minHeight * scaleFactor);
width = d_roundToUnsignedInt(width * scaleFactor);
height = d_roundToUnsignedInt(height * scaleFactor);
}
#endif

// handle geometry constraints here
if (width < minWidth)
@@ -310,6 +310,14 @@ void Window::setSize(uint width, uint height)
}
}
}
else
{
if (pData->autoScaling && d_isNotEqual(scaleFactor, 1.0))
{
width = d_roundToUnsignedInt(width * scaleFactor);
height = d_roundToUnsignedInt(height * scaleFactor);
}
}

if (pData->usesSizeRequest)
{
@@ -415,6 +423,35 @@ double Window::getScaleFactor() const noexcept
return pData->scaleFactor;
}

void Window::enableInternalScalingWithSize(uint baseWidth, uint baseHeight, const bool keepAspectRatio)
{
DISTRHO_SAFE_ASSERT_RETURN(baseWidth > 0,);
DISTRHO_SAFE_ASSERT_RETURN(baseHeight > 0,);

const Size<uint> size(getSize());
const double scaleHorizontal = size.getWidth() / static_cast<double>(baseWidth);
const double scaleVertical = size.getHeight() / static_cast<double>(baseHeight);

pData->minWidth = baseWidth;
pData->minHeight = baseHeight;
pData->autoScaling = true;
pData->autoScaleFactor = scaleHorizontal < scaleVertical ? scaleHorizontal : scaleVertical;
pData->keepAspectRatio = keepAspectRatio;

if (pData->view == nullptr)
return;

const double scaleFactor = pData->scaleFactor;

if (d_isNotEqual(scaleFactor, 1.0))
{
baseWidth = d_roundToUnsignedInt(baseWidth * scaleFactor);
baseHeight = d_roundToUnsignedInt(baseHeight * scaleFactor);
}

puglSetGeometryConstraints(pData->view, baseWidth, baseHeight, keepAspectRatio);
}

void Window::focus()
{
pData->focus();
@@ -465,7 +502,6 @@ void Window::repaint(const Rectangle<uint>& rect) noexcept
uint width = rect.getWidth();
uint height = rect.getHeight();

#if DGL_ALLOW_DEPRECATED_METHODS
if (pData->autoScaling)
{
const double autoScaleFactor = pData->autoScaleFactor;
@@ -475,7 +511,6 @@ void Window::repaint(const Rectangle<uint>& rect) noexcept
width = d_roundToUnsignedInt(width * autoScaleFactor);
height = d_roundToUnsignedInt(height * autoScaleFactor);
}
#endif

puglObscureRegion(pData->view, x, y, width, height);
}


+ 1
- 13
dgl/src/WindowPrivateData.cpp View File

@@ -116,10 +116,8 @@ Window::PrivateData::PrivateData(Application& a, Window* const s)
usesScheduledRepaints(false),
usesSizeRequest(false),
scaleFactor(DGL_NAMESPACE::getScaleFactor(view)),
#if DGL_ALLOW_DEPRECATED_METHODS
autoScaling(false),
autoScaleFactor(1.0),
#endif
minWidth(0),
minHeight(0),
keepAspectRatio(false),
@@ -151,10 +149,8 @@ Window::PrivateData::PrivateData(Application& a, Window* const s, PrivateData* c
usesScheduledRepaints(false),
usesSizeRequest(false),
scaleFactor(ppData->scaleFactor),
#if DGL_ALLOW_DEPRECATED_METHODS
autoScaling(false),
autoScaleFactor(1.0),
#endif
minWidth(0),
minHeight(0),
keepAspectRatio(false),
@@ -188,10 +184,8 @@ Window::PrivateData::PrivateData(Application& a, Window* const s,
usesScheduledRepaints(false),
usesSizeRequest(false),
scaleFactor(scale != 0.0 ? scale : DGL_NAMESPACE::getScaleFactor(view)),
#if DGL_ALLOW_DEPRECATED_METHODS
autoScaling(false),
autoScaleFactor(1.0),
#endif
minWidth(0),
minHeight(0),
keepAspectRatio(false),
@@ -228,10 +222,8 @@ Window::PrivateData::PrivateData(Application& a, Window* const s,
usesScheduledRepaints(_usesScheduledRepaints),
usesSizeRequest(_usesSizeRequest),
scaleFactor(scale != 0.0 ? scale : DGL_NAMESPACE::getScaleFactor(view)),
#if DGL_ALLOW_DEPRECATED_METHODS
autoScaling(false),
autoScaleFactor(1.0),
#endif
minWidth(0),
minHeight(0),
keepAspectRatio(false),
@@ -660,7 +652,6 @@ void Window::PrivateData::onPuglConfigure(const uint width, const uint height)

createContextIfNeeded();

#if DGL_ALLOW_DEPRECATED_METHODS
if (autoScaling)
{
const double scaleHorizontal = width / static_cast<double>(minWidth);
@@ -671,12 +662,9 @@ void Window::PrivateData::onPuglConfigure(const uint width, const uint height)
{
autoScaleFactor = 1.0;
}

const uint uwidth = d_roundToUnsignedInt(width / autoScaleFactor);
const uint uheight = d_roundToUnsignedInt(height / autoScaleFactor);
#else
const uint uwidth = width;
const uint uheight = height;
#endif

#ifdef DGL_USE_WEB_VIEW
if (webViewHandle != nullptr)


+ 0
- 2
dgl/src/WindowPrivateData.hpp View File

@@ -73,11 +73,9 @@ struct Window::PrivateData : IdleCallback {
/** Scale factor to report to widgets on request, purely informational. */
double scaleFactor;

#if DGL_ALLOW_DEPRECATED_METHODS
/** Automatic scaling to apply on widgets, implemented internally. */
bool autoScaling;
double autoScaleFactor;
#endif

/** Pugl geometry constraints access. */
uint minWidth, minHeight;


Loading…
Cancel
Save