diff --git a/Ink Canvas/Helpers/WinRtInkShapeRecognizer.cs b/Ink Canvas/Helpers/WinRtInkShapeRecognizer.cs index 2798088e..53819a85 100644 --- a/Ink Canvas/Helpers/WinRtInkShapeRecognizer.cs +++ b/Ink Canvas/Helpers/WinRtInkShapeRecognizer.cs @@ -1,8 +1,10 @@ using System; using System.Collections.Generic; +using System.Numerics; using System.Runtime.InteropServices.WindowsRuntime; using System.Threading.Tasks; using System.Windows.Ink; +using System.Windows.Input; using System.Windows.Media; using OSVersionExtension; using WinRtInkAnalyzer = global::Windows.UI.Input.Inking.Analysis.InkAnalyzer; @@ -103,8 +105,7 @@ namespace Ink_Canvas.Helpers new global::Windows.Foundation.Point((float)pi.X, (float)pi.Y), (float)sp.PressureFactor)); } - var transform = global::Windows.Foundation.Numerics.Matrix3x2.Identity; - return builder.CreateStrokeFromInkPoints(inkPoints, transform); + return builder.CreateStrokeFromInkPoints(inkPoints, Matrix3x2.Identity); } private static global::Windows.UI.Input.Inking.Analysis.InkAnalysisInkDrawing FindPrimaryDrawing( diff --git a/Ink Canvas/MainWindow.xaml b/Ink Canvas/MainWindow.xaml index 61fcd07d..b4ee444a 100644 --- a/Ink Canvas/MainWindow.xaml +++ b/Ink Canvas/MainWindow.xaml @@ -1125,23 +1125,6 @@ - - - - - - - - - - @@ -4635,9 +4618,6 @@ PreviewTouchDown="InkCanvas_PreviewTouchDown" PreviewTouchMove="InkCanvas_PreviewTouchMove" PreviewTouchUp="InkCanvas_PreviewTouchUp" - PreviewStylusMove="inkCanvas_PreviewStylusMove" - PreviewMouseMove="inkCanvas_PreviewMouseMoveForPrediction" - LostStylusCapture="inkCanvas_LostStylusCapture" MouseDown="inkCanvas_MouseDown" MouseMove="inkCanvas_MouseMove" MouseUp="inkCanvas_MouseUp" @@ -4646,12 +4626,6 @@ StrokeCollected="inkCanvas_StrokeCollected" ClipToBounds="False" Background="Transparent" /> - - - - - /// 墨迹预测:书写过程中根据速度与选项外推一小段预览线,减轻感知延迟。 - /// - public partial class MainWindow - { - private bool _inkPredictionStrokeActive; - private bool _inkPredictionHasSample; - private bool _inkPredictionHasVelocity; - private Point _inkPredictionLastPos; - private int _inkPredictionLastTime; - private double _inkPredictionVx; - private double _inkPredictionVy; - - private void SyncInkStrokePredictionLeadComboVisibility() - { - try - { - bool on = Settings?.Canvas != null && Settings.Canvas.EnableInkStrokePrediction; - var v = on ? Visibility.Visible : Visibility.Collapsed; - if (ComboBoxInkStrokePredictionLeadSettings != null) - ComboBoxInkStrokePredictionLeadSettings.Visibility = v; - } - catch - { - // ignore - } - } - - private void ClearInkPredictionOverlay() - { - try - { - if (InkPredictionPolyline == null) return; - InkPredictionPolyline.Visibility = Visibility.Collapsed; - InkPredictionPolyline.Points.Clear(); - } - catch - { - // ignore - } - } - - private void BeginInkPredictionStrokeIfNeeded() - { - try - { - if (Settings?.Canvas == null || !Settings.Canvas.EnableInkStrokePrediction) - { - _inkPredictionStrokeActive = false; - return; - } - - _inkPredictionStrokeActive = inkCanvas != null - && inkCanvas.EditingMode == InkCanvasEditingMode.Ink - && penType != 1 - && !_isBoardBrushMode; - _inkPredictionHasSample = false; - _inkPredictionHasVelocity = false; - ClearInkPredictionOverlay(); - } - catch - { - _inkPredictionStrokeActive = false; - } - } - - private void EndInkPredictionStroke() - { - _inkPredictionStrokeActive = false; - _inkPredictionHasSample = false; - _inkPredictionHasVelocity = false; - ClearInkPredictionOverlay(); - } - - private double GetInkPredictionLeadMs() - { - int mode = Settings?.Canvas?.InkStrokePredictionLeadMode ?? 0; - if (mode == 1) return 25.0; - if (mode == 2) return 50.0; - - double speed = Math.Sqrt(_inkPredictionVx * _inkPredictionVx + _inkPredictionVy * _inkPredictionVy); - double norm = Math.Min(1.0, speed / 2600.0); - double lead = 16.0 + norm * 34.0; - return Math.Max(14.0, Math.Min(52.0, lead)); - } - - private double GetInkPredictionMaxDistance(double leadMs) - { - double baseD = Math.Max(4.0, Settings?.Canvas?.InkStrokePredictionMaxDistance ?? 18.0); - int mode = Settings?.Canvas?.InkStrokePredictionLeadMode ?? 0; - if (mode != 0) - return Math.Max(6.0, Math.Min(42.0, baseD * (leadMs / 24.0))); - - double speed = Math.Sqrt(_inkPredictionVx * _inkPredictionVx + _inkPredictionVy * _inkPredictionVy); - double norm = Math.Min(1.0, speed / 2200.0); - return Math.Max(6.0, Math.Min(48.0, baseD + norm * baseD * 0.9)); - } - - private void inkCanvas_PreviewStylusMove(object sender, StylusEventArgs e) - { - try - { - if (Settings?.Canvas == null || !Settings.Canvas.EnableInkStrokePrediction) return; - if (inkCanvas == null || InkPredictionPolyline == null) return; - if (!_inkPredictionStrokeActive || penType == 1) return; - if (inkCanvas.EditingMode != InkCanvasEditingMode.Ink) return; - - if (e.InAir) - { - ClearInkPredictionOverlay(); - return; - } - - var pos = e.GetPosition(inkCanvas); - UpdateInkPredictionCore(pos, e.Timestamp); - } - catch - { - // ignore - } - } - - private void inkCanvas_LostStylusCapture(object sender, StylusEventArgs e) - { - EndInkPredictionStroke(); - } - - private void inkCanvas_PreviewMouseMoveForPrediction(object sender, MouseEventArgs e) - { - try - { - if (Settings?.Canvas == null || !Settings.Canvas.EnableInkStrokePrediction) return; - if (inkCanvas == null || InkPredictionPolyline == null) return; - if (!_inkPredictionStrokeActive || penType == 1) return; - if (inkCanvas.EditingMode != InkCanvasEditingMode.Ink) return; - if (e.LeftButton != MouseButtonState.Pressed) return; - if (e.StylusDevice != null) return; - - var pos = e.GetPosition(inkCanvas); - UpdateInkPredictionCore(pos, Environment.TickCount & int.MaxValue); - } - catch - { - // ignore - } - } - - private void UpdateInkPredictionCore(Point pos, int timestamp) - { - if (InkPredictionPolyline == null || Settings?.Canvas == null) return; - - if (!_inkPredictionHasSample) - { - _inkPredictionLastPos = pos; - _inkPredictionLastTime = timestamp; - _inkPredictionHasSample = true; - return; - } - - double dtMs = timestamp - _inkPredictionLastTime; - if (dtMs <= 0 || dtMs > 120) dtMs = 16; - - double vx = (pos.X - _inkPredictionLastPos.X) / dtMs * 1000.0; - double vy = (pos.Y - _inkPredictionLastPos.Y) / dtMs * 1000.0; - - const double velocitySmooth = 0.62; - if (!_inkPredictionHasVelocity) - { - _inkPredictionVx = vx; - _inkPredictionVy = vy; - _inkPredictionHasVelocity = true; - } - else - { - _inkPredictionVx = velocitySmooth * _inkPredictionVx + (1.0 - velocitySmooth) * vx; - _inkPredictionVy = velocitySmooth * _inkPredictionVy + (1.0 - velocitySmooth) * vy; - } - - double leadMs = GetInkPredictionLeadMs(); - double predX = pos.X + _inkPredictionVx * (leadMs / 1000.0); - double predY = pos.Y + _inkPredictionVy * (leadMs / 1000.0); - - double maxDist = GetInkPredictionMaxDistance(leadMs); - double dx = predX - pos.X; - double dy = predY - pos.Y; - double len = Math.Sqrt(dx * dx + dy * dy); - if (len > maxDist && len > 1e-6) - { - double s = maxDist / len; - predX = pos.X + dx * s; - predY = pos.Y + dy * s; - } - - _inkPredictionLastPos = pos; - _inkPredictionLastTime = timestamp; - - var da = inkCanvas.DefaultDrawingAttributes; - var c = da.Color; - InkPredictionPolyline.Stroke = new SolidColorBrush(Color.FromArgb(110, c.R, c.G, c.B)); - InkPredictionPolyline.StrokeThickness = Math.Max(1.0, da.Width * 0.42); - - InkPredictionPolyline.Points.Clear(); - InkPredictionPolyline.Points.Add(pos); - InkPredictionPolyline.Points.Add(new Point(predX, predY)); - InkPredictionPolyline.Visibility = Visibility.Visible; - } - } -} diff --git a/Ink Canvas/MainWindow_cs/MW_Settings.cs b/Ink Canvas/MainWindow_cs/MW_Settings.cs index 16d36e1c..ce036a85 100644 --- a/Ink Canvas/MainWindow_cs/MW_Settings.cs +++ b/Ink Canvas/MainWindow_cs/MW_Settings.cs @@ -2700,28 +2700,6 @@ namespace Ink_Canvas SaveSettingsToFile(); } - private void ToggleSwitchInkStrokePredictionSettings_Toggled(object sender, RoutedEventArgs e) - { - if (!isLoaded) return; - - bool on = ToggleSwitchInkStrokePredictionSettings != null && ToggleSwitchInkStrokePredictionSettings.IsOn; - Settings.Canvas.EnableInkStrokePrediction = on; - SyncInkStrokePredictionLeadComboVisibility(); - if (!on) - EndInkPredictionStroke(); - SaveSettingsToFile(); - } - - private void ComboBoxInkStrokePredictionLeadSettings_SelectionChanged(object sender, SelectionChangedEventArgs e) - { - if (!isLoaded) return; - var cb = sender as ComboBox; - if (cb?.SelectedIndex < 0) return; - - Settings.Canvas.InkStrokePredictionLeadMode = cb.SelectedIndex; - SaveSettingsToFile(); - } - private void ToggleSwitchAutoStraightenLine_Toggled(object sender, RoutedEventArgs e) { if (!isLoaded) return; diff --git a/Ink Canvas/MainWindow_cs/MW_SettingsToLoad.cs b/Ink Canvas/MainWindow_cs/MW_SettingsToLoad.cs index e9b3a958..58f12fa9 100644 --- a/Ink Canvas/MainWindow_cs/MW_SettingsToLoad.cs +++ b/Ink Canvas/MainWindow_cs/MW_SettingsToLoad.cs @@ -951,16 +951,6 @@ namespace Ink_Canvas // 初始化直线端点吸附相关设置 ToggleSwitchLineEndpointSnapping.IsOn = Settings.Canvas.LineEndpointSnapping; ToggleSwitchCompressPicturesUploaded.IsOn = Settings.Canvas.IsCompressPicturesUploaded; - - int leadMode = Settings.Canvas.InkStrokePredictionLeadMode; - if (leadMode < 0 || leadMode > 2) leadMode = 0; - Settings.Canvas.InkStrokePredictionLeadMode = leadMode; - - if (ToggleSwitchInkStrokePredictionSettings != null) - ToggleSwitchInkStrokePredictionSettings.IsOn = Settings.Canvas.EnableInkStrokePrediction; - if (ComboBoxInkStrokePredictionLeadSettings != null) - ComboBoxInkStrokePredictionLeadSettings.SelectedIndex = leadMode; - SyncInkStrokePredictionLeadComboVisibility(); } else { diff --git a/Ink Canvas/MainWindow_cs/MW_ShapeDrawing.cs b/Ink Canvas/MainWindow_cs/MW_ShapeDrawing.cs index 219aec66..f2f8c7ea 100644 --- a/Ink Canvas/MainWindow_cs/MW_ShapeDrawing.cs +++ b/Ink Canvas/MainWindow_cs/MW_ShapeDrawing.cs @@ -2565,8 +2565,7 @@ namespace Ink_Canvas /// private void inkCanvas_MouseUp(object sender, MouseButtonEventArgs e) { - EndInkPredictionStroke(); - HandleEraserOperationEnded(); // 橡皮擦自动切换回批注模式:松手后启动/重置计时 + HandleEraserOperationEnded(); inkCanvas.ReleaseMouseCapture(); ViewboxFloatingBar.IsHitTestVisible = true; BlackboardUIGridForInkReplay.IsHitTestVisible = true; diff --git a/Ink Canvas/MainWindow_cs/MW_SimulatePressure&InkToShape.cs b/Ink Canvas/MainWindow_cs/MW_SimulatePressure&InkToShape.cs index 6433a45a..9ab42788 100644 --- a/Ink Canvas/MainWindow_cs/MW_SimulatePressure&InkToShape.cs +++ b/Ink Canvas/MainWindow_cs/MW_SimulatePressure&InkToShape.cs @@ -632,7 +632,6 @@ namespace Ink_Canvas else if (result.ShapeName.Contains("Triangle") && Settings.InkToShape.IsInkToShapeTriangle) { - var shape = result.InkDrawingNode.GetShape(); var p = result.HotPoints; if ((Math.Max(Math.Max(p[0].X, p[1].X), p[2].X) - Math.Min(Math.Min(p[0].X, p[1].X), p[2].X) >= 100 || @@ -671,10 +670,10 @@ namespace Ink_Canvas result.ShapeName.Contains("Diamond") || result.ShapeName.Contains("Parallelogram") || result.ShapeName.Contains("Square") || - result.ShapeName.Contains("Trapezoid")) && + result.ShapeName.Contains("Trapezoid") || + result.ShapeName.Contains("Quadrilateral")) && Settings.InkToShape.IsInkToShapeRectangle) { - var shape = result.InkDrawingNode.GetShape(); var p = result.HotPoints; if ((Math.Max(Math.Max(Math.Max(p[0].X, p[1].X), p[2].X), p[3].X) - Math.Min(Math.Min(Math.Min(p[0].X, p[1].X), p[2].X), p[3].X) >= 100 || diff --git a/Ink Canvas/Properties/Strings.enUS.xml b/Ink Canvas/Properties/Strings.enUS.xml index 82bf3d3f..7b469ec7 100644 --- a/Ink Canvas/Properties/Strings.enUS.xml +++ b/Ink Canvas/Properties/Strings.enUS.xml @@ -229,8 +229,6 @@ Auto IACore WinRT - Ink stroke prediction - # When on, shows a short ahead-of-stroke hint while inking. Choose Auto (speed-based), 25 ms, or 50 ms lead. Block fake pressure on corrected rectangles Block fake pressure on corrected triangles Correct freehand triangles diff --git a/Ink Canvas/Properties/Strings.resx b/Ink Canvas/Properties/Strings.resx index f61e5937..aaa9b928 100644 --- a/Ink Canvas/Properties/Strings.resx +++ b/Ink Canvas/Properties/Strings.resx @@ -244,8 +244,6 @@ 自动 IACore WinRT - 墨迹预测 - # 开启后可在书写时显示短暂外推预览线。打开开关后可选择:自动(随速度调整)、固定 25ms 或 50ms 提前量。 阻止矫正后的矩形带有模拟压感值 阻止矫正后的三角形带有模拟压感值 矫正手绘三角形 diff --git a/Ink Canvas/Resources/Settings.cs b/Ink Canvas/Resources/Settings.cs index 678e9208..e72468d9 100644 --- a/Ink Canvas/Resources/Settings.cs +++ b/Ink Canvas/Resources/Settings.cs @@ -146,34 +146,8 @@ namespace Ink_Canvas public bool EnableEraserAutoSwitchBack { get; set; } = false; [JsonProperty("eraserAutoSwitchBackDelaySeconds")] public int EraserAutoSwitchBackDelaySeconds { get; set; } = 10; // 默认10秒 - - /// - /// 是否在笔工具中启用墨迹预测预览线(由笔属性面板「墨迹预测」开关控制)。 - /// - [JsonProperty("enableInkStrokePrediction")] - public bool EnableInkStrokePrediction { get; set; } = false; - - /// - /// 墨迹预测提前量模式:0 自动(随书写速度调整),1 固定 25ms,2 固定 50ms。 - /// - [JsonProperty("inkStrokePredictionLeadMode")] - public int InkStrokePredictionLeadMode { get; set; } = 0; - - /// - /// 预测线段基准最大长度(逻辑像素/DIP);「自动」模式下会随速度在此值基础上略增。 - /// - [JsonProperty("inkStrokePredictionMaxDistance")] - public double InkStrokePredictionMaxDistance { get; set; } = 18.0; - - /// - /// 「实时」笔锋( = 3)下,速度项与硬件压感的混合比例 0–1。 - /// [JsonProperty("velocityBrushTipMix")] public double VelocityBrushTipMix { get; set; } = 0.22; - - /// - /// 已弃用:请使用 = 3(笔锋下拉选「实时」)。仅用于反序列化旧版配置。 - /// [JsonProperty("enableVelocityBrushTip")] public bool EnableVelocityBrushTip { get; set; }