Skip to content

Commit

Permalink
Fixed screenScalingFactor
Browse files Browse the repository at this point in the history
Signed-off-by: ahcorde <[email protected]>
  • Loading branch information
ahcorde committed Feb 2, 2021
1 parent 61cc21b commit 95a6347
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 6 deletions.
7 changes: 7 additions & 0 deletions include/ignition/rendering/Utils.hh
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,13 @@ namespace ignition
IGNITION_RENDERING_VISIBLE
float screenScalingFactor();

/// \brief Get the screen scaling factor.
/// \param[out] _xScale The X screen scaling factor.
/// \param[out] _yScale The Y screen scaling factor.
/// \return The screen scaling factor.
IGNITION_RENDERING_VISIBLE
void screenScalingFactor(float &_xScale, float &_yScale);

/// \brief Transform a bounding box.
/// \param[in] _box The bounding box.
/// \param[in] _pose Pose used to transform the bounding box.
Expand Down
7 changes: 4 additions & 3 deletions ogre/src/OgreCamera.cc
Original file line number Diff line number Diff line change
Expand Up @@ -216,10 +216,11 @@ VisualPtr OgreCamera::VisualAt(const ignition::math::Vector2i
}
}

float ratio = screenScalingFactor();
float xScale, YScale;
screenScalingFactor(xScale, YScale);
ignition::math::Vector2i mousePos(
static_cast<int>(std::rint(ratio * _mousePos.X())),
static_cast<int>(std::rint(ratio * _mousePos.Y())));
static_cast<int>(std::rint(xScale * _mousePos.X())),
static_cast<int>(std::rint(YScale * _mousePos.Y())));

Ogre::Entity *entity = this->selectionBuffer->OnSelectionClick(
mousePos.X(), mousePos.Y());
Expand Down
7 changes: 4 additions & 3 deletions ogre2/src/Ogre2Camera.cc
Original file line number Diff line number Diff line change
Expand Up @@ -208,10 +208,11 @@ VisualPtr Ogre2Camera::VisualAt(const ignition::math::Vector2i &_mousePos)
}
}

float ratio = screenScalingFactor();
float xScale, YScale;
screenScalingFactor(xScale, YScale);
ignition::math::Vector2i mousePos(
static_cast<int>(std::rint(ratio * _mousePos.X())),
static_cast<int>(std::rint(ratio * _mousePos.Y())));
static_cast<int>(std::rint(xScale * _mousePos.X())),
static_cast<int>(std::rint(YScale * _mousePos.Y())));

Ogre::Item *ogreItem = this->selectionBuffer->OnSelectionClick(
mousePos.X(), mousePos.Y());
Expand Down
66 changes: 66 additions & 0 deletions src/Utils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,72 @@ float screenScalingFactor()
return ratio;
}

/////////////////////////////////////////////////
void screenScalingFactor(float &_xScale, float &_yScale)
{
// todo(anyone) set device pixel ratio for high dpi displays on Windows
#ifdef __linux__
auto closeDisplay = [](Display * display)
{
if (display)
XCloseDisplay(display);
};
auto display =
std::unique_ptr<Display, decltype(closeDisplay)>(
XOpenDisplay(nullptr), closeDisplay);
char *resourceString = XResourceManagerString(display.get());

if (resourceString)
{
char *type = nullptr;
float dpiDesktop = 0.0;

// Need to initialize the DB before calling Xrm* functions
XrmInitialize();

XrmValue value;
XrmDatabase db = XrmGetStringDatabase(resourceString);

// Debug:
// printf("Entire DB:\n%s\n", resourceString);

if (XrmGetResource(db, "Xft.dpi", "String", &type, &value) == True)
{
if (value.addr)
dpiDesktop = atof(value.addr);
}

// To get the ratio we need the DPI as reported by the Xrmdatabase,
// which takes into account desktop scaling, and the DPI computed by the
// actual display resolution.
//
// dpiRes = N pixels / (M millimeters / (25.4 millimeters / 1 inch))
// = N pixels / (M inch / 25.4)
// = (N * 25.4 pixels) / M inch
//
// We can use either the width or height in the following line. The zero
// values in DisplayHeight and DisplayHeightMM is the screen number. A
// value of zero uses the default screen.
float xDpiRes = (DisplayWidth(display.get(), 0) * 25.4) /
DisplayWidthMM(display.get(), 0);
float yDpiRes = (DisplayHeight(display.get(), 0) * 25.4) /
DisplayHeightMM(display.get(), 0);

if (!math::equal(dpiDesktop, 0.0f) && !math::equal(yDpiRes, 0.0f))
_yScale = yDpiRes / dpiDesktop;
if (_yScale < 1) _yScale = 1;

if (!math::equal(dpiDesktop, 0.0f) && !math::equal(xDpiRes, 0.0f))
_xScale = xDpiRes / dpiDesktop;
if (_xScale < 1) _xScale = 1;

// Debug:
// printf("DPI Desktop: %f, DPI XY: [%f, %f], Scale XY: [%f, %f]\n",
// dpiDesktop, xDpiRes, yDpiRes, _xScale, _yScale);
}
#endif
}

/////////////////////////////////////////////////
ignition::math::AxisAlignedBox transformAxisAlignedBox(
const ignition::math::AxisAlignedBox &_bbox,
Expand Down

0 comments on commit 95a6347

Please sign in to comment.