123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103 |
- using System;
- using System.Windows;
- using System.Windows.Media;
- using HandyControl.Expression.Drawing;
- using HandyControl.Tools.Interop;
- namespace HandyControl.Tools;
- internal static class DpiHelper
- {
- private const double LogicalDpi = 96.0;
- [ThreadStatic]
- private static Matrix _transformToDip;
- static DpiHelper()
- {
- var dC = InteropMethods.GetDC(IntPtr.Zero);
- if (dC != IntPtr.Zero)
- {
- // 沿着屏幕宽度每逻辑英寸的像素数。在具有多个显示器的系统中,这个值对所有显示器都是相同的
- const int logicPixelsX = 88;
- // 沿着屏幕高度每逻辑英寸的像素数
- const int logicPixelsY = 90;
- DeviceDpiX = InteropMethods.GetDeviceCaps(dC, logicPixelsX);
- DeviceDpiY = InteropMethods.GetDeviceCaps(dC, logicPixelsY);
- InteropMethods.ReleaseDC(IntPtr.Zero, dC);
- }
- else
- {
- DeviceDpiX = LogicalDpi;
- DeviceDpiY = LogicalDpi;
- }
- var identity = Matrix.Identity;
- var identity2 = Matrix.Identity;
- identity.Scale(DeviceDpiX / LogicalDpi, DeviceDpiY / LogicalDpi);
- identity2.Scale(LogicalDpi / DeviceDpiX, LogicalDpi / DeviceDpiY);
- TransformFromDevice = new MatrixTransform(identity2);
- TransformFromDevice.Freeze();
- TransformToDevice = new MatrixTransform(identity);
- TransformToDevice.Freeze();
- }
- public static MatrixTransform TransformFromDevice { get; }
- public static MatrixTransform TransformToDevice { get; }
- public static double DeviceDpiX { get; }
- public static double DeviceDpiY { get; }
- public static double LogicalToDeviceUnitsScalingFactorX => TransformToDevice.Matrix.M11;
- public static double LogicalToDeviceUnitsScalingFactorY => TransformToDevice.Matrix.M22;
- public static Point DevicePixelsToLogical(Point devicePoint, double dpiScaleX, double dpiScaleY)
- {
- _transformToDip = Matrix.Identity;
- _transformToDip.Scale(1d / dpiScaleX, 1d / dpiScaleY);
- return _transformToDip.Transform(devicePoint);
- }
- public static Size DeviceSizeToLogical(Size deviceSize, double dpiScaleX, double dpiScaleY)
- {
- var pt = DevicePixelsToLogical(new Point(deviceSize.Width, deviceSize.Height), dpiScaleX, dpiScaleY);
- return new Size(pt.X, pt.Y);
- }
- public static Rect LogicalToDeviceUnits(this Rect logicalRect)
- {
- var result = logicalRect;
- result.Transform(TransformToDevice.Matrix);
- return result;
- }
- public static Rect DeviceToLogicalUnits(this Rect deviceRect)
- {
- var result = deviceRect;
- result.Transform(TransformFromDevice.Matrix);
- return result;
- }
- public static double RoundLayoutValue(double value, double dpiScale)
- {
- double newValue;
- if (!MathHelper.AreClose(dpiScale, 1.0))
- {
- newValue = Math.Round(value * dpiScale) / dpiScale;
- if (double.IsNaN(newValue) || double.IsInfinity(newValue) || MathHelper.AreClose(newValue, double.MaxValue))
- {
- newValue = value;
- }
- }
- else
- {
- newValue = Math.Round(value);
- }
- return newValue;
- }
- }
|