Skip to content

Commit 059179a

Browse files
Copilotphilstopford
andcommitted
Fix viewport scaling for high DPI displays
Changed viewport to use logical dimensions (Width/Height) instead of physical pixels (RenderWidth/RenderHeight) throughout: - Draw() orthographic projection now uses logical size - zoomExtents() zoom calculation uses logical size - WorldToScreen and ScreenToWorld conversions use logical size - Grid and axes rendering use logical size - Mouse coordinate handling no longer scales by LogicalPixelSize This ensures geometry is properly fitted and centered regardless of DPI scaling. Co-authored-by: philstopford <1983851+philstopford@users.noreply.github.com>
1 parent e674002 commit 059179a

File tree

4 files changed

+43
-31
lines changed

4 files changed

+43
-31
lines changed

Eto/Eto.VeldridSurface/VeldridDriver_Conversions.cs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,30 +14,34 @@ private SizeF ScreenToWorld(SizeF pt)
1414

1515
private PointF ScreenToWorld(float x, float y)
1616
{
17-
double oX_2 = (double)Surface!.RenderWidth / 2;
17+
// Use logical size for coordinate conversions to ensure consistent
18+
// behavior across different DPI settings
19+
double oX_2 = (double)Surface!.Width / 2;
1820
double oX_3 = ovpSettings.getCameraX() / (ovpSettings.getZoomFactor() * ovpSettings.getBaseZoom());
1921
double oX_4 = x;
2022

2123
double oXC = oX_4 - oX_2 + oX_3;
2224

2325

24-
return new PointF((x - (float)Surface.RenderWidth / 2) * (ovpSettings.getZoomFactor() * ovpSettings.getBaseZoom()) + ovpSettings.getCameraX(),
25-
((float)Surface.RenderHeight / 2 - y) * (ovpSettings.getZoomFactor() * ovpSettings.getBaseZoom()) + ovpSettings.getCameraY());
26+
return new PointF((x - (float)Surface.Width / 2) * (ovpSettings.getZoomFactor() * ovpSettings.getBaseZoom()) + ovpSettings.getCameraX(),
27+
((float)Surface.Height / 2 - y) * (ovpSettings.getZoomFactor() * ovpSettings.getBaseZoom()) + ovpSettings.getCameraY());
2628
}
2729

2830
private Point WorldToScreen(float x, float y)
2931
{
30-
// int oX = (int)((x - ovpSettings.getCameraX() / (ovpSettings.getZoomFactor() * ovpSettings.getBaseZoom())) + Surface.RenderWidth / 2);
32+
// int oX = (int)((x - ovpSettings.getCameraX() / (ovpSettings.getZoomFactor() * ovpSettings.getBaseZoom())) + Surface.Width / 2);
3133

32-
double oX_2 = (double)Surface!.RenderWidth / 2;
34+
// Use logical size for coordinate conversions to ensure consistent
35+
// behavior across different DPI settings
36+
double oX_2 = (double)Surface!.Width / 2;
3337
double oX_3 = ovpSettings.getCameraX() / (ovpSettings.getZoomFactor() * ovpSettings.getBaseZoom());
3438
double oX_4 = x;
3539

3640
int oXC = (int)(oX_4 - oX_3 + oX_2);
3741

38-
// int oY = (int)((y - ovpSettings.getCameraY() / (ovpSettings.getZoomFactor() * ovpSettings.getBaseZoom())) + Surface.RenderHeight / 2);
42+
// int oY = (int)((y - ovpSettings.getCameraY() / (ovpSettings.getZoomFactor() * ovpSettings.getBaseZoom())) + Surface.Height / 2);
3943

40-
double oY_2 = (double)Surface.RenderHeight / 2;
44+
double oY_2 = (double)Surface.Height / 2;
4145
double oY_3 = ovpSettings.getCameraY() / (ovpSettings.getZoomFactor() * ovpSettings.getBaseZoom());
4246
double oY_4 = y;
4347

Eto/Eto.VeldridSurface/VeldridDriver_Draw.cs

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -477,7 +477,8 @@ private Task drawGrid()
477477
if (WorldToScreen(new SizeF(spacing, 0.0f)).Width >= 4.0f)
478478
{
479479
int k = 0;
480-
for (float i = 0; i > -(Surface!.RenderWidth * zoom) + x; i -= spacing)
480+
// Use logical size for grid extent calculations
481+
for (float i = 0; i > -(Surface!.Width * zoom) + x; i -= spacing)
481482
{
482483
float r = 0.0f;
483484
float g = 0.0f;
@@ -498,14 +499,14 @@ private Task drawGrid()
498499
}
499500

500501
k++;
501-
grid.Add(new VertexPositionColor(new Vector3(i, y + zoom * Surface!.RenderHeight, gridZ),
502+
grid.Add(new VertexPositionColor(new Vector3(i, y + zoom * Surface!.Height, gridZ),
502503
new RgbaFloat(r, g, b, 1.0f)));
503-
grid.Add(new VertexPositionColor(new Vector3(i, y + zoom * -Surface!.RenderHeight, gridZ),
504+
grid.Add(new VertexPositionColor(new Vector3(i, y + zoom * -Surface!.Height, gridZ),
504505
new RgbaFloat(r, g, b, 1.0f)));
505506
}
506507

507508
k = 0;
508-
for (float i = 0; i < Surface!.RenderWidth * zoom + x; i += spacing)
509+
for (float i = 0; i < Surface!.Width * zoom + x; i += spacing)
509510
{
510511
float r = 0.0f;
511512
float g = 0.0f;
@@ -526,14 +527,14 @@ private Task drawGrid()
526527
}
527528

528529
k++;
529-
grid.Add(new VertexPositionColor(new Vector3(i, y + zoom * Surface!.RenderHeight, gridZ),
530+
grid.Add(new VertexPositionColor(new Vector3(i, y + zoom * Surface!.Height, gridZ),
530531
new RgbaFloat(r, g, b, 1.0f)));
531-
grid.Add(new VertexPositionColor(new Vector3(i, y + zoom * -Surface!.RenderHeight, gridZ),
532+
grid.Add(new VertexPositionColor(new Vector3(i, y + zoom * -Surface!.Height, gridZ),
532533
new RgbaFloat(r, g, b, 1.0f)));
533534
}
534535

535536
k = 0;
536-
for (float i = 0; i > -(Surface!.RenderHeight * zoom) + y; i -= spacing)
537+
for (float i = 0; i > -(Surface!.Height * zoom) + y; i -= spacing)
537538
{
538539
float r = 0.0f;
539540
float g = 0.0f;
@@ -554,14 +555,14 @@ private Task drawGrid()
554555
}
555556

556557
k++;
557-
grid.Add(new VertexPositionColor(new Vector3(x + zoom * Surface!.RenderWidth, i, gridZ),
558+
grid.Add(new VertexPositionColor(new Vector3(x + zoom * Surface!.Width, i, gridZ),
558559
new RgbaFloat(r, g, b, 1.0f)));
559-
grid.Add(new VertexPositionColor(new Vector3(x + zoom * -Surface!.RenderWidth, i, gridZ),
560+
grid.Add(new VertexPositionColor(new Vector3(x + zoom * -Surface!.Width, i, gridZ),
560561
new RgbaFloat(r, g, b, 1.0f)));
561562
}
562563

563564
k = 0;
564-
for (float i = 0; i < Surface!.RenderHeight * zoom + y; i += spacing)
565+
for (float i = 0; i < Surface!.Height * zoom + y; i += spacing)
565566
{
566567
float r = 0.0f;
567568
float g = 0.0f;
@@ -582,9 +583,9 @@ private Task drawGrid()
582583
}
583584

584585
k++;
585-
grid.Add(new VertexPositionColor(new Vector3(x + zoom * Surface!.RenderWidth, i, gridZ),
586+
grid.Add(new VertexPositionColor(new Vector3(x + zoom * Surface!.Width, i, gridZ),
586587
new RgbaFloat(r, g, b, 1.0f)));
587-
grid.Add(new VertexPositionColor(new Vector3(x + zoom * -Surface!.RenderWidth, i, gridZ),
588+
grid.Add(new VertexPositionColor(new Vector3(x + zoom * -Surface!.Width, i, gridZ),
588589
new RgbaFloat(r, g, b, 1.0f)));
589590
}
590591
}
@@ -631,20 +632,21 @@ private Task drawAxes()
631632
}
632633

633634
float zoom = ovpSettings.getBaseZoom() * ovpSettings.getZoomFactor();
635+
// Use logical size for axis extent calculations
634636
axesArray = new VertexPositionColor[4];
635637
axesArray[0] =
636638
new VertexPositionColor(
637-
new Vector3(0.0f, ovpSettings.getCameraY() + Surface!.RenderHeight * zoom, axisZ),
639+
new Vector3(0.0f, ovpSettings.getCameraY() + Surface!.Height * zoom, axisZ),
638640
new RgbaFloat(ovpSettings.axisColor.R, ovpSettings.axisColor.G, ovpSettings.axisColor.B, 1.0f));
639641
axesArray[1] =
640642
new VertexPositionColor(
641-
new Vector3(0.0f, ovpSettings.getCameraY() - Surface!.RenderHeight * zoom, axisZ),
643+
new Vector3(0.0f, ovpSettings.getCameraY() - Surface!.Height * zoom, axisZ),
642644
new RgbaFloat(ovpSettings.axisColor.R, ovpSettings.axisColor.G, ovpSettings.axisColor.B, 1.0f));
643645
axesArray[2] =
644-
new VertexPositionColor(new Vector3(ovpSettings.getCameraX() + Surface!.RenderWidth * zoom, 0.0f, axisZ),
646+
new VertexPositionColor(new Vector3(ovpSettings.getCameraX() + Surface!.Width * zoom, 0.0f, axisZ),
645647
new RgbaFloat(ovpSettings.axisColor.R, ovpSettings.axisColor.G, ovpSettings.axisColor.B, 1.0f));
646648
axesArray[3] =
647-
new VertexPositionColor(new Vector3(ovpSettings.getCameraX() - Surface!.RenderWidth * zoom, 0.0f, axisZ),
649+
new VertexPositionColor(new Vector3(ovpSettings.getCameraX() - Surface!.Width * zoom, 0.0f, axisZ),
648650
new RgbaFloat(ovpSettings.axisColor.R, ovpSettings.axisColor.G, ovpSettings.axisColor.B, 1.0f));
649651

650652
axesIndices = [0, 1, 2, 3];
@@ -673,10 +675,12 @@ public void Draw()
673675

674676
float zoom = ovpSettings.getZoomFactor() * ovpSettings.getBaseZoom();
675677

676-
float left = ovpSettings.getCameraX() - (float)Surface!.RenderWidth / 2 * zoom;
677-
float right = ovpSettings.getCameraX() + (float)Surface!.RenderWidth / 2 * zoom;
678-
float bottom = ovpSettings.getCameraY() + (float)Surface!.RenderHeight / 2 * zoom;
679-
float top = ovpSettings.getCameraY() - (float)Surface!.RenderHeight / 2 * zoom;
678+
// Use logical size (Width/Height) instead of physical pixels (RenderWidth/RenderHeight)
679+
// to ensure consistent viewport behavior across different DPI settings
680+
float left = ovpSettings.getCameraX() - (float)Surface!.Width / 2 * zoom;
681+
float right = ovpSettings.getCameraX() + (float)Surface!.Width / 2 * zoom;
682+
float bottom = ovpSettings.getCameraY() + (float)Surface!.Height / 2 * zoom;
683+
float top = ovpSettings.getCameraY() - (float)Surface!.Height / 2 * zoom;
680684

681685
ViewMatrix = Matrix4x4.CreateOrthographicOffCenter(left, right, bottom, top, 0.0f, 1.0f);
682686
CommandList.UpdateBuffer(ViewBuffer, 0, ViewMatrix);

Eto/Eto.VeldridSurface/VeldridDriver_Handlers.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,8 @@ private void dragHandler(object sender, MouseEventArgs e)
125125
{
126126
case MouseButtons.Primary:
127127
{
128-
PointF scaledLocation = e.Location * Surface!.ParentWindow.LogicalPixelSize;
128+
// Since we now use logical dimensions throughout, no need to scale mouse coordinates
129+
PointF scaledLocation = e.Location;
129130

130131
switch (dragging)
131132
{
@@ -255,8 +256,9 @@ private void setDown(float x, float y)
255256
private void selectByClick(float x, float y)
256257
{
257258
// Where did we click?
259+
// Since we now use logical dimensions throughout, no need to scale mouse coordinates
258260
PointF scaledLocation = new(x, y);
259-
scaledLocation = ScreenToWorld(scaledLocation.X * Surface!.ParentWindow.LogicalPixelSize, scaledLocation.Y * Surface!.ParentWindow.LogicalPixelSize);
261+
scaledLocation = ScreenToWorld(scaledLocation.X, scaledLocation.Y);
260262

261263
PointF cPos = ovpSettings.getCameraPos();
262264

Eto/Eto.VeldridSurface/VeldridDriver_Public.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,8 +124,10 @@ public void zoomExtents(int index)
124124
float cY = dY / 2.0f + ovpSettings.minY;
125125

126126
// Now need to get the zoom level organized.
127-
float zoomLevel_x = dX / Surface!.RenderWidth;
128-
float zoomLevel_y = dY / Surface!.RenderHeight;
127+
// Use logical size (Width/Height) for zoom calculation to ensure consistent
128+
// behavior across different DPI settings
129+
float zoomLevel_x = dX / Surface!.Width;
130+
float zoomLevel_y = dY / Surface!.Height;
129131

130132
if (zoomLevel_x > zoomLevel_y)
131133
{

0 commit comments

Comments
 (0)