diff --git a/SpineViewer/Extensions/SFMLExtension.cs b/SpineViewer/Extensions/SFMLExtension.cs
index dcfb9ce..a4b9fc7 100644
--- a/SpineViewer/Extensions/SFMLExtension.cs
+++ b/SpineViewer/Extensions/SFMLExtension.cs
@@ -8,6 +8,39 @@ namespace SpineViewer.Extensions
{
public static class SFMLExtension
{
+ ///
+ /// 获取适合指定画布参数下能够覆盖包围盒的画布视区包围盒
+ ///
+ public static RectangleF GetCanvasBounds(this RectangleF bounds, Size resolution) => GetCanvasBounds(bounds, resolution, new(0), new(0));
+
+ ///
+ /// 获取适合指定画布参数下能够覆盖包围盒的画布视区包围盒
+ ///
+ public static RectangleF GetCanvasBounds(this RectangleF bounds, Size resolution, Padding margin) => GetCanvasBounds(bounds, resolution, margin, new(0));
+
+ ///
+ /// 获取适合指定画布参数下能够覆盖包围盒的画布视区包围盒
+ ///
+ public static RectangleF GetCanvasBounds(this RectangleF bounds, Size resolution, Padding margin, Padding padding)
+ {
+ float sizeW = bounds.Width;
+ float sizeH = bounds.Height;
+ float innerW = resolution.Width - padding.Horizontal;
+ float innerH = resolution.Height - padding.Vertical;
+ float scale = Math.Max(Math.Abs(sizeW / innerW), Math.Abs(sizeH / innerH)); // 取两方向上较大的缩放比, 以此让画布可以覆盖内容
+ float scaleW = scale * Math.Sign(sizeW);
+ float scaleH = scale * Math.Sign(sizeH);
+
+ innerW *= scaleW;
+ innerH *= scaleH;
+
+ var x = bounds.X - (innerW - sizeW) / 2 - (margin.Left + padding.Left) * scaleW;
+ var y = bounds.Y - (innerH - sizeH) / 2 - (margin.Top + padding.Top) * scaleH;
+ var w = (resolution.Width + margin.Horizontal) * scaleW;
+ var h = (resolution.Height + margin.Vertical) * scaleH;
+ return new(x, y, w, h);
+ }
+
///
/// 获取 Winforms Bitmap 对象, 需要使用 Dispose 释放对象
///
@@ -29,26 +62,33 @@ namespace SpineViewer.Extensions
}
///
- /// 获取适合指定画布参数下能够覆盖包围盒的视区包围盒
+ /// 获取视图的包围盒
///
- public static RectangleF GetResolutionBounds(this RectangleF bounds, Size resolution, Padding margin, Padding padding)
+ public static RectangleF GetBounds(this SFML.Graphics.View view)
+ => new(view.Center.X - view.Size.X / 2, view.Center.Y - view.Size.Y / 2, view.Size.X, view.Size.Y);
+
+ ///
+ /// 按画布设置视区, 边缘和填充区域将不会出现内容
+ ///
+ public static void SetViewport(this SFML.Graphics.View view, Size resolution, Padding margin, Padding padding)
{
- float sizeW = bounds.Width;
- float sizeH = bounds.Height;
- float innerW = resolution.Width - padding.Horizontal;
- float innerH = resolution.Height - padding.Vertical;
- float scale = Math.Max(Math.Abs(sizeW / innerW), Math.Abs(sizeH / innerH)); // 取两方向上较大的缩放比, 以此让画布可以覆盖内容
- float scaleW = scale * Math.Sign(sizeW);
- float scaleH = scale * Math.Sign(sizeH);
+ var innerW = resolution.Width - padding.Horizontal;
+ var innerH = resolution.Height - padding.Vertical;
- innerW *= scaleW;
- innerH *= scaleH;
+ float width = resolution.Width + margin.Horizontal;
+ float height = resolution.Height + margin.Vertical;
- var x = bounds.X - (innerW - sizeW) / 2 - (margin.Left + padding.Left) * scaleW;
- var y = bounds.Y - (innerH - sizeH) / 2 - (margin.Top + padding.Top) * scaleH;
- var w = (resolution.Width + margin.Horizontal) * scaleW;
- var h = (resolution.Height + margin.Vertical) * scaleH;
- return new(x, y, w, h);
+ view.Viewport = new(
+ (margin.Left + padding.Left) / width,
+ (margin.Top + padding.Top) / height,
+ innerW / width,
+ innerH / height
+ );
+
+ var bounds = view.GetBounds().GetCanvasBounds(new(innerW, innerH));
+
+ view.Center = new(bounds.X + bounds.Width / 2, bounds.Y + bounds.Height / 2);
+ view.Size = new(bounds.Width, bounds.Height);
}
}
}