@@ -49,5 +49,5 @@ using System.Windows;
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.7.1.3")]
|
||||
[assembly: AssemblyFileVersion("1.7.1.3")]
|
||||
[assembly: AssemblyVersion("1.7.1.6")]
|
||||
[assembly: AssemblyFileVersion("1.7.1.6")]
|
||||
|
||||
@@ -0,0 +1,147 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Windows;
|
||||
using System.Windows.Ink;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using Point = System.Windows.Point;
|
||||
|
||||
namespace Ink_Canvas.Helpers
|
||||
{
|
||||
/// <summary>
|
||||
/// 适合手写/触摸的墨迹平滑方案:指数平滑+等距重采样+Catmull-Rom样条插值,防止自交和异常填充
|
||||
/// </summary>
|
||||
public class AdvancedBezierSmoothing
|
||||
{
|
||||
public double SmoothingStrength { get; set; } = 0.8;
|
||||
public double ResampleInterval { get; set; } = 0.8;
|
||||
public int InterpolationSteps { get; set; } = 64;
|
||||
|
||||
public Stroke SmoothStroke(Stroke stroke)
|
||||
{
|
||||
if (stroke == null || stroke.StylusPoints.Count < 2)
|
||||
return stroke;
|
||||
var originalPoints = stroke.StylusPoints.ToList();
|
||||
var smoothedPoints = ApplyExponentialSmoothing(originalPoints, SmoothingStrength);
|
||||
var resampledPoints = ResampleEquidistant(smoothedPoints, ResampleInterval);
|
||||
var interpolatedPoints = SlidingBezierFit(resampledPoints, 4, 24);
|
||||
var finalPoints = ApplyExponentialSmoothing(interpolatedPoints, 0.5); // 二次平滑
|
||||
var ultraSmoothPoints = SlidingWindowSmooth(finalPoints, 7); // 滑动窗口平滑
|
||||
var smoothedStroke = new Stroke(new StylusPointCollection(ultraSmoothPoints))
|
||||
{
|
||||
DrawingAttributes = stroke.DrawingAttributes.Clone()
|
||||
};
|
||||
return smoothedStroke;
|
||||
}
|
||||
|
||||
private List<StylusPoint> ApplyExponentialSmoothing(List<StylusPoint> points, double alpha)
|
||||
{
|
||||
var result = new List<StylusPoint>();
|
||||
if (points.Count == 0) return result;
|
||||
result.Add(points[0]);
|
||||
double lastX = points[0].X;
|
||||
double lastY = points[0].Y;
|
||||
float lastPressure = points[0].PressureFactor;
|
||||
for (int i = 1; i < points.Count; i++)
|
||||
{
|
||||
var p = points[i];
|
||||
lastX = alpha * p.X + (1 - alpha) * lastX;
|
||||
lastY = alpha * p.Y + (1 - alpha) * lastY;
|
||||
lastPressure = (float)(alpha * p.PressureFactor + (1 - alpha) * lastPressure);
|
||||
if (lastPressure < 0.1f) lastPressure = 0.1f;
|
||||
result.Add(new StylusPoint(lastX, lastY, lastPressure));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<StylusPoint> ResampleEquidistant(List<StylusPoint> points, double interval = 2.0)
|
||||
{
|
||||
var result = new List<StylusPoint>();
|
||||
if (points.Count == 0) return result;
|
||||
result.Add(points[0]);
|
||||
double accumulated = 0;
|
||||
for (int i = 1; i < points.Count; i++)
|
||||
{
|
||||
var prev = result.Last();
|
||||
var curr = points[i];
|
||||
double dx = curr.X - prev.X;
|
||||
double dy = curr.Y - prev.Y;
|
||||
double dist = Math.Sqrt(dx * dx + dy * dy);
|
||||
if (dist + accumulated >= interval)
|
||||
{
|
||||
double t = (interval - accumulated) / dist;
|
||||
double x = prev.X + t * dx;
|
||||
double y = prev.Y + t * dy;
|
||||
float pressure = (float)(prev.PressureFactor * (1 - t) + curr.PressureFactor * t);
|
||||
if (pressure < 0.1f) pressure = 0.1f;
|
||||
var newPoint = new StylusPoint(x, y, pressure);
|
||||
result.Add(newPoint);
|
||||
accumulated = 0;
|
||||
i--; // 重新处理当前点
|
||||
}
|
||||
else
|
||||
{
|
||||
accumulated += dist;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<StylusPoint> SlidingBezierFit(List<StylusPoint> points, int window = 4, int steps = 24)
|
||||
{
|
||||
var result = new List<StylusPoint>();
|
||||
if (points.Count < window) return points;
|
||||
for (int i = 0; i <= points.Count - window; i++)
|
||||
{
|
||||
var p0 = points[i];
|
||||
var p1 = points[i + 1];
|
||||
var p2 = points[i + 2];
|
||||
var p3 = points[i + 3];
|
||||
for (int j = 0; j < steps; j++)
|
||||
{
|
||||
double t = (double)j / steps;
|
||||
var pt = CubicBezier(p0, p1, p2, p3, t);
|
||||
result.Add(pt);
|
||||
}
|
||||
}
|
||||
// 保证最后一个点被包含
|
||||
result.Add(points.Last());
|
||||
return result;
|
||||
}
|
||||
|
||||
private StylusPoint CubicBezier(StylusPoint p0, StylusPoint p1, StylusPoint p2, StylusPoint p3, double t)
|
||||
{
|
||||
double u = 1 - t;
|
||||
double tt = t * t;
|
||||
double uu = u * u;
|
||||
double uuu = uu * u;
|
||||
double ttt = tt * t;
|
||||
double x = uuu * p0.X + 3 * uu * t * p1.X + 3 * u * tt * p2.X + ttt * p3.X;
|
||||
double y = uuu * p0.Y + 3 * uu * t * p1.Y + 3 * u * tt * p2.Y + ttt * p3.Y;
|
||||
float pressure = (float)(p1.PressureFactor * (1 - t) + p2.PressureFactor * t);
|
||||
if (pressure < 0.1f) pressure = 0.1f;
|
||||
return new StylusPoint(x, y, pressure);
|
||||
}
|
||||
|
||||
private List<StylusPoint> SlidingWindowSmooth(List<StylusPoint> points, int window = 5)
|
||||
{
|
||||
var result = new List<StylusPoint>();
|
||||
int half = window / 2;
|
||||
for (int i = 0; i < points.Count; i++)
|
||||
{
|
||||
double sumX = 0, sumY = 0, sumP = 0;
|
||||
int count = 0;
|
||||
for (int j = Math.Max(0, i - half); j <= Math.Min(points.Count - 1, i + half); j++)
|
||||
{
|
||||
sumX += points[j].X;
|
||||
sumY += points[j].Y;
|
||||
sumP += points[j].PressureFactor;
|
||||
count++;
|
||||
}
|
||||
result.Add(new StylusPoint(sumX / count, sumY / count, (float)(sumP / count)));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -210,8 +210,18 @@
|
||||
<!-- Plugins -->
|
||||
<Button Width="40" Height="40" Margin="0,5,0,0" Style="{StaticResource NavButton}"
|
||||
Click="NavPlugins_Click" Tag="plugins" ToolTip="插件">
|
||||
<TextBlock Text="" FontFamily="Segoe MDL2 Assets" FontSize="18"/>
|
||||
<Image Width="20" Height="20">
|
||||
<Image.Source>
|
||||
<DrawingImage>
|
||||
<DrawingImage.Drawing>
|
||||
<GeometryDrawing Brush="White"
|
||||
Geometry="M4 24V12H13V10C13 6.68629 15.6863 4 19 4C22.3137 4 25 6.68629 25 10V12H34V24H38C41.3137 24 44 26.6863 44 30C44 33.3137 41.3137 36 38 36H34V44H4V36H8C11.3137 36 14 33.3137 14 30C14 26.6863 11.3137 24 8 24H4Z"/>
|
||||
</DrawingImage.Drawing>
|
||||
</DrawingImage>
|
||||
</Image.Source>
|
||||
</Image>
|
||||
</Button>
|
||||
|
||||
<!-- Startup -->
|
||||
<Button Width="40" Height="40" Margin="0,10,0,0" Style="{StaticResource NavButton}"
|
||||
Click="NavStartup_Click" Tag="startup" ToolTip="启动设置">
|
||||
@@ -771,12 +781,19 @@
|
||||
<TextBlock Text="# 请注意,若不保留双曲线渐近线可能会有遇到撤回相关的 BUG 影响用。" TextWrapping="Wrap"
|
||||
Foreground="#a1a1aa" />
|
||||
<ui:SimpleStackPanel Orientation="Horizontal" HorizontalAlignment="Left">
|
||||
<TextBlock Foreground="#fafafa" Text="让墨迹使用贝塞尔曲线平滑处理"
|
||||
<TextBlock Foreground="#fafafa" Text="使用WPF默认贝塞尔曲线平滑"
|
||||
VerticalAlignment="Center" FontSize="14" Margin="0,0,16,0" />
|
||||
<ui:ToggleSwitch OnContent="" OffContent="" Name="ToggleSwitchFitToCurve"
|
||||
IsOn="True" FontFamily="Microsoft YaHei UI" FontWeight="Bold"
|
||||
IsOn="False" FontFamily="Microsoft YaHei UI" FontWeight="Bold"
|
||||
Toggled="ToggleSwitchFitToCurve_Toggled" />
|
||||
</ui:SimpleStackPanel>
|
||||
<ui:SimpleStackPanel Orientation="Horizontal" HorizontalAlignment="Left">
|
||||
<TextBlock Foreground="#fafafa" Text="使用高级曲线平滑(推荐)"
|
||||
VerticalAlignment="Center" FontSize="14" Margin="0,0,16,0" />
|
||||
<ui:ToggleSwitch OnContent="" OffContent="" Name="ToggleSwitchAdvancedBezierSmoothing"
|
||||
IsOn="True" FontFamily="Microsoft YaHei UI" FontWeight="Bold"
|
||||
Toggled="ToggleSwitchAdvancedBezierSmoothing_Toggled" />
|
||||
</ui:SimpleStackPanel>
|
||||
</ui:SimpleStackPanel>
|
||||
</GroupBox>
|
||||
<!-- 新增:崩溃后操作设置 -->
|
||||
@@ -1173,6 +1190,16 @@
|
||||
IsOn="True" FontFamily="Microsoft YaHei UI" FontWeight="Bold"
|
||||
Toggled="ToggleSwitchSupportWPS_Toggled" />
|
||||
</ui:SimpleStackPanel>
|
||||
<ui:SimpleStackPanel Orientation="Horizontal" HorizontalAlignment="Left">
|
||||
<Image Source="/Resources/Icons-png/WPS.png" Margin="0,0,6,0" Width="28"
|
||||
Height="28" VerticalAlignment="Center" />
|
||||
<TextBlock Foreground="#fafafa" Text="WPP进程查杀(防止WPP残留进程)" VerticalAlignment="Center"
|
||||
FontSize="14" Margin="0,0,16,0" />
|
||||
<ui:ToggleSwitch OnContent="" OffContent="" Name="ToggleSwitchEnableWppProcessKill"
|
||||
IsOn="True" FontFamily="Microsoft YaHei UI" FontWeight="Bold"
|
||||
Toggled="ToggleSwitchEnableWppProcessKill_Toggled" />
|
||||
</ui:SimpleStackPanel>
|
||||
<TextBlock Text="# 关闭后将不会自动查杀WPP残留进程,可能导致WPP关闭卡顿或无法彻底退出。" TextWrapping="Wrap" Foreground="#a1a1aa" />
|
||||
<Border BorderBrush="#ef4444"
|
||||
BorderThickness="2" Padding="8" CornerRadius="6" Background="#991b1b">
|
||||
<ui:SimpleStackPanel Orientation="Horizontal" Spacing="4">
|
||||
|
||||
@@ -34,6 +34,14 @@ namespace Ink_Canvas {
|
||||
private System.Windows.Controls.Canvas currentCanvas = null;
|
||||
private AutoUpdateHelper.UpdateLineGroup AvailableLatestLineGroup = null;
|
||||
|
||||
// Win32 API声明和常量(用于无焦点窗口)
|
||||
[DllImport("user32.dll")]
|
||||
private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
|
||||
[DllImport("user32.dll")]
|
||||
private static extern int GetWindowLong(IntPtr hWnd, int nIndex);
|
||||
private const int GWL_EXSTYLE = -20;
|
||||
private const int WS_EX_NOACTIVATE = 0x08000000;
|
||||
|
||||
#region Window Initialization
|
||||
|
||||
public MainWindow() {
|
||||
@@ -125,6 +133,15 @@ namespace Ink_Canvas {
|
||||
ShowPage(currentPageIndex);
|
||||
}
|
||||
|
||||
protected override void OnSourceInitialized(EventArgs e)
|
||||
{
|
||||
base.OnSourceInitialized(e);
|
||||
// 设置窗口为无焦点(不会抢占焦点)
|
||||
var hwnd = new WindowInteropHelper(this).Handle;
|
||||
int exStyle = GetWindowLong(hwnd, GWL_EXSTYLE);
|
||||
SetWindowLong(hwnd, GWL_EXSTYLE, exStyle | WS_EX_NOACTIVATE);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Ink Canvas Functions
|
||||
@@ -143,7 +160,15 @@ namespace Ink_Canvas {
|
||||
drawingAttributes.Height = 2.5;
|
||||
drawingAttributes.Width = 2.5;
|
||||
drawingAttributes.IsHighlighter = false;
|
||||
drawingAttributes.FitToCurve = Settings.Canvas.FitToCurve;
|
||||
// 默认使用高级贝塞尔曲线平滑,如果未启用则使用原来的FitToCurve
|
||||
if (Settings.Canvas.UseAdvancedBezierSmoothing)
|
||||
{
|
||||
drawingAttributes.FitToCurve = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
drawingAttributes.FitToCurve = Settings.Canvas.FitToCurve;
|
||||
}
|
||||
|
||||
inkCanvas.EditingMode = InkCanvasEditingMode.Ink;
|
||||
inkCanvas.Gesture += InkCanvas_Gesture;
|
||||
@@ -278,14 +303,8 @@ namespace Ink_Canvas {
|
||||
RadioCrashSilentRestart.IsChecked = true;
|
||||
else
|
||||
RadioCrashNoAction.IsChecked = true;
|
||||
|
||||
// 注册系统关机事件处理
|
||||
RegisterShutdownHandler();
|
||||
|
||||
// 设置默认为黑板模式
|
||||
Settings.Canvas.UsingWhiteboard = false;
|
||||
Settings.Canvas.CustomBackgroundColor = "#162924"; // 黑板默认颜色 RGB(22, 41, 36)
|
||||
SaveSettingsToFile();
|
||||
|
||||
|
||||
// 如果当前不是黑板模式,则切换到黑板模式
|
||||
if (currentMode == 0)
|
||||
|
||||
+674
-527
File diff suppressed because it is too large
Load Diff
@@ -168,6 +168,7 @@ namespace Ink_Canvas {
|
||||
{
|
||||
writer.WriteLine($"PPT名称: {pptApplication.SlideShowWindows[1].Presentation.Name}");
|
||||
writer.WriteLine($"PPT总页数: {pptApplication.SlideShowWindows[1].Presentation.Slides.Count}");
|
||||
writer.WriteLine($"PPT文件路径: {pptApplication.SlideShowWindows[1].Presentation.FullName}");
|
||||
}
|
||||
|
||||
for (int i = 0; i < allPageStrokes.Count; i++)
|
||||
@@ -432,6 +433,25 @@ namespace Ink_Canvas {
|
||||
throw new InvalidOperationException("当前不在PPT放映模式,无法恢复PPT墨迹");
|
||||
}
|
||||
|
||||
// 检查PPT文件路径是否匹配
|
||||
if (metadata.ContainsKey("PPT文件路径"))
|
||||
{
|
||||
string savedPptPath = metadata["PPT文件路径"];
|
||||
string currentPptPath = pptApplication.SlideShowWindows[1].Presentation.FullName;
|
||||
|
||||
if (!string.IsNullOrEmpty(savedPptPath) && !string.IsNullOrEmpty(currentPptPath))
|
||||
{
|
||||
// 使用文件路径哈希值进行比较,避免路径格式差异
|
||||
string savedHash = GetFileHash(savedPptPath);
|
||||
string currentHash = GetFileHash(currentPptPath);
|
||||
|
||||
if (savedHash != currentHash)
|
||||
{
|
||||
throw new InvalidOperationException($"墨迹文件与当前PPT文件不匹配。保存的PPT: {savedPptPath},当前PPT: {currentPptPath}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 清空当前墨迹
|
||||
ClearStrokes(true);
|
||||
timeMachine.ClearStrokeHistory();
|
||||
|
||||
@@ -1285,9 +1285,32 @@ namespace Ink_Canvas {
|
||||
if (!isLoaded) return;
|
||||
drawingAttributes.FitToCurve = ToggleSwitchFitToCurve.IsOn;
|
||||
Settings.Canvas.FitToCurve = ToggleSwitchFitToCurve.IsOn;
|
||||
|
||||
// 启用原来的FitToCurve时自动禁用高级贝塞尔平滑
|
||||
if (ToggleSwitchFitToCurve.IsOn)
|
||||
{
|
||||
ToggleSwitchAdvancedBezierSmoothing.IsOn = false;
|
||||
Settings.Canvas.UseAdvancedBezierSmoothing = false;
|
||||
}
|
||||
|
||||
SaveSettingsToFile();
|
||||
}
|
||||
|
||||
private void ToggleSwitchAdvancedBezierSmoothing_Toggled(object sender, RoutedEventArgs e) {
|
||||
if (!isLoaded) return;
|
||||
Settings.Canvas.UseAdvancedBezierSmoothing = ToggleSwitchAdvancedBezierSmoothing.IsOn;
|
||||
|
||||
// 启用高级贝塞尔平滑时自动禁用原来的FitToCurve
|
||||
if (ToggleSwitchAdvancedBezierSmoothing.IsOn)
|
||||
{
|
||||
ToggleSwitchFitToCurve.IsOn = false;
|
||||
Settings.Canvas.FitToCurve = false;
|
||||
drawingAttributes.FitToCurve = false;
|
||||
}
|
||||
|
||||
SaveSettingsToFile();
|
||||
}
|
||||
|
||||
private void ToggleSwitchAutoSaveStrokesInPowerPoint_Toggled(object sender, RoutedEventArgs e) {
|
||||
if (!isLoaded) return;
|
||||
Settings.PowerPointSettings.IsAutoSaveStrokesInPowerPoint = ToggleSwitchAutoSaveStrokesInPowerPoint.IsOn;
|
||||
@@ -1588,7 +1611,8 @@ namespace Ink_Canvas {
|
||||
Settings.Canvas.EraserShapeType = 1;
|
||||
Settings.Canvas.HideStrokeWhenSelecting = false;
|
||||
Settings.Canvas.ClearCanvasAndClearTimeMachine = false;
|
||||
Settings.Canvas.FitToCurve = true;
|
||||
Settings.Canvas.FitToCurve = false;
|
||||
Settings.Canvas.UseAdvancedBezierSmoothing = true;
|
||||
Settings.Canvas.EnablePressureTouchMode = false;
|
||||
Settings.Canvas.DisablePressure = false;
|
||||
Settings.Canvas.AutoStraightenLine = true;
|
||||
@@ -2135,5 +2159,11 @@ namespace Ink_Canvas {
|
||||
dialog.Owner = this;
|
||||
dialog.ShowDialog();
|
||||
}
|
||||
|
||||
private void ToggleSwitchEnableWppProcessKill_Toggled(object sender, RoutedEventArgs e) {
|
||||
if (!isLoaded) return;
|
||||
Settings.PowerPointSettings.EnableWppProcessKill = ToggleSwitchEnableWppProcessKill.IsOn;
|
||||
SaveSettingsToFile();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -375,6 +375,7 @@ namespace Ink_Canvas {
|
||||
|
||||
ToggleSwitchAutoSaveScreenShotInPowerPoint.IsOn =
|
||||
Settings.PowerPointSettings.IsAutoSaveScreenShotInPowerPoint;
|
||||
ToggleSwitchEnableWppProcessKill.IsOn = Settings.PowerPointSettings.EnableWppProcessKill;
|
||||
} else {
|
||||
Settings.PowerPointSettings = new PowerPointSettings();
|
||||
}
|
||||
@@ -515,13 +516,28 @@ namespace Ink_Canvas {
|
||||
|
||||
ToggleSwitchHideStrokeWhenSelecting.IsOn = Settings.Canvas.HideStrokeWhenSelecting;
|
||||
|
||||
if (Settings.Canvas.FitToCurve) {
|
||||
ToggleSwitchFitToCurve.IsOn = true;
|
||||
drawingAttributes.FitToCurve = true;
|
||||
} else {
|
||||
// 初始化贝塞尔曲线平滑设置
|
||||
if (Settings.Canvas.UseAdvancedBezierSmoothing)
|
||||
{
|
||||
// 如果启用高级贝塞尔平滑,则禁用原来的FitToCurve
|
||||
ToggleSwitchAdvancedBezierSmoothing.IsOn = true;
|
||||
ToggleSwitchFitToCurve.IsOn = false;
|
||||
drawingAttributes.FitToCurve = false;
|
||||
}
|
||||
else if (Settings.Canvas.FitToCurve)
|
||||
{
|
||||
// 如果启用原来的FitToCurve,则禁用高级贝塞尔平滑
|
||||
ToggleSwitchFitToCurve.IsOn = true;
|
||||
ToggleSwitchAdvancedBezierSmoothing.IsOn = false;
|
||||
drawingAttributes.FitToCurve = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 两者都禁用
|
||||
ToggleSwitchFitToCurve.IsOn = false;
|
||||
ToggleSwitchAdvancedBezierSmoothing.IsOn = false;
|
||||
drawingAttributes.FitToCurve = false;
|
||||
}
|
||||
|
||||
// 初始化直线自动拉直相关设置
|
||||
ToggleSwitchAutoStraightenLine.IsOn = Settings.Canvas.AutoStraightenLine;
|
||||
@@ -533,7 +549,6 @@ namespace Ink_Canvas {
|
||||
|
||||
// 初始化直线端点吸附相关设置
|
||||
ToggleSwitchLineEndpointSnapping.IsOn = Settings.Canvas.LineEndpointSnapping;
|
||||
LineEndpointSnappingThresholdSlider.Value = Settings.Canvas.LineEndpointSnappingThreshold;
|
||||
} else {
|
||||
Settings.Canvas = new Canvas();
|
||||
}
|
||||
|
||||
@@ -433,6 +433,7 @@ namespace Ink_Canvas {
|
||||
#region 形状绘制主函数
|
||||
|
||||
private void MouseTouchMove(Point endP) {
|
||||
// 禁用原有的FitToCurve,使用新的高级贝塞尔曲线平滑
|
||||
if (Settings.Canvas.FitToCurve == true) drawingAttributes.FitToCurve = false;
|
||||
ViewboxFloatingBar.IsHitTestVisible = false;
|
||||
BlackboardUIGridForInkReplay.IsHitTestVisible = false;
|
||||
@@ -1589,7 +1590,33 @@ namespace Ink_Canvas {
|
||||
}
|
||||
}
|
||||
|
||||
if (Settings.Canvas.FitToCurve == true) drawingAttributes.FitToCurve = true;
|
||||
// 应用高级贝塞尔曲线平滑
|
||||
if (Settings.Canvas.UseAdvancedBezierSmoothing)
|
||||
{
|
||||
try
|
||||
{
|
||||
var advancedSmoothing = new Helpers.AdvancedBezierSmoothing
|
||||
{
|
||||
};
|
||||
|
||||
// 对临时笔画应用平滑
|
||||
if (lastTempStroke != null)
|
||||
{
|
||||
var smoothedStroke = advancedSmoothing.SmoothStroke(lastTempStroke);
|
||||
inkCanvas.Strokes.Remove(lastTempStroke);
|
||||
lastTempStroke = smoothedStroke;
|
||||
inkCanvas.Strokes.Add(smoothedStroke);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine($"形状绘制高级贝塞尔曲线平滑失败: {ex.Message}");
|
||||
}
|
||||
}
|
||||
else if (Settings.Canvas.FitToCurve == true)
|
||||
{
|
||||
drawingAttributes.FitToCurve = true;
|
||||
}
|
||||
}
|
||||
|
||||
private bool NeedUpdateIniP() {
|
||||
|
||||
@@ -16,6 +16,10 @@ namespace Ink_Canvas {
|
||||
private const double LINE_STRAIGHTEN_THRESHOLD = 0.20; // 默认灵敏度阈值,与UI默认值对应
|
||||
|
||||
private void inkCanvas_StrokeCollected(object sender, InkCanvasStrokeCollectedEventArgs e) {
|
||||
// 标记是否进行了直线拉直
|
||||
bool wasStraightened = false;
|
||||
|
||||
// 禁用原有的FitToCurve,使用新的高级贝塞尔曲线平滑
|
||||
if (Settings.Canvas.FitToCurve == true) drawingAttributes.FitToCurve = false;
|
||||
|
||||
try {
|
||||
@@ -117,8 +121,9 @@ namespace Ink_Canvas {
|
||||
}
|
||||
}
|
||||
|
||||
// Apply line straightening and endpoint snapping if ink-to-shape is enabled
|
||||
if (Settings.InkToShape.IsInkToShapeEnabled) {
|
||||
// Apply line straightening and endpoint snapping if ink-to-shape is enabled
|
||||
|
||||
if (Settings.InkToShape.IsInkToShapeEnabled) {
|
||||
// 检查是否启用了直线自动拉直功能
|
||||
if (Settings.Canvas.AutoStraightenLine && IsPotentialStraightLine(e.Stroke)) {
|
||||
// Get start and end points of the stroke
|
||||
@@ -168,6 +173,8 @@ namespace Ink_Canvas {
|
||||
newStrokes.Remove(e.Stroke);
|
||||
newStrokes.Add(straightStroke);
|
||||
}
|
||||
|
||||
wasStraightened = true; // 标记已进行直线拉直
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -572,7 +579,38 @@ namespace Ink_Canvas {
|
||||
}
|
||||
catch { }
|
||||
|
||||
if (Settings.Canvas.FitToCurve == true) drawingAttributes.FitToCurve = true;
|
||||
// 应用高级贝塞尔曲线平滑(仅在未进行直线拉直时)
|
||||
if (Settings.Canvas.UseAdvancedBezierSmoothing && !wasStraightened)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 检查原始笔画是否仍然存在于画布中
|
||||
if (inkCanvas.Strokes.Contains(e.Stroke))
|
||||
{
|
||||
var advancedSmoothing = new Helpers.AdvancedBezierSmoothing
|
||||
{
|
||||
};
|
||||
|
||||
var smoothedStroke = advancedSmoothing.SmoothStroke(e.Stroke);
|
||||
|
||||
// 替换原始笔画
|
||||
SetNewBackupOfStroke();
|
||||
_currentCommitType = CommitReason.ShapeRecognition;
|
||||
inkCanvas.Strokes.Remove(e.Stroke);
|
||||
inkCanvas.Strokes.Add(smoothedStroke);
|
||||
_currentCommitType = CommitReason.UserInput;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// 如果高级平滑失败,回退到原始笔画
|
||||
System.Diagnostics.Debug.WriteLine($"高级贝塞尔曲线平滑失败: {ex.Message}");
|
||||
}
|
||||
}
|
||||
else if (Settings.Canvas.FitToCurve == true && !wasStraightened)
|
||||
{
|
||||
drawingAttributes.FitToCurve = true;
|
||||
}
|
||||
}
|
||||
|
||||
// New method: Checks if a stroke is potentially a straight line
|
||||
|
||||
@@ -49,5 +49,5 @@ using System.Windows;
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.7.1.3")]
|
||||
[assembly: AssemblyFileVersion("1.7.1.3")]
|
||||
[assembly: AssemblyVersion("1.7.1.6")]
|
||||
[assembly: AssemblyFileVersion("1.7.1.6")]
|
||||
|
||||
@@ -47,7 +47,9 @@ namespace Ink_Canvas
|
||||
[JsonProperty("hideStrokeWhenSelecting")]
|
||||
public bool HideStrokeWhenSelecting { get; set; } = true;
|
||||
[JsonProperty("fitToCurve")]
|
||||
public bool FitToCurve { get; set; } = true;
|
||||
public bool FitToCurve { get; set; } = false; // 默认关闭原来的贝塞尔平滑
|
||||
[JsonProperty("useAdvancedBezierSmoothing")]
|
||||
public bool UseAdvancedBezierSmoothing { get; set; } = true; // 默认启用高级贝塞尔曲线平滑
|
||||
[JsonProperty("clearCanvasAndClearTimeMachine")]
|
||||
public bool ClearCanvasAndClearTimeMachine { get; set; } = false;
|
||||
[JsonProperty("enablePressureTouchMode")]
|
||||
@@ -233,6 +235,8 @@ namespace Ink_Canvas
|
||||
public bool IsEnableFingerGestureSlideShowControl { get; set; } = true;
|
||||
[JsonProperty("isSupportWPS")]
|
||||
public bool IsSupportWPS { get; set; } = true;
|
||||
[JsonProperty("enableWppProcessKill")]
|
||||
public bool EnableWppProcessKill { get; set; } = true;
|
||||
}
|
||||
|
||||
public class Automation
|
||||
|
||||
@@ -12,7 +12,7 @@ TRACE;DEBUG;NETFRAMEWORK;NET472;;NET30_OR_GREATER;NET35_OR_GREATER;NET40_OR_GREA
|
||||
E:\ICC CE\ICC CE main\community\Ink Canvas\App.xaml
|
||||
21348134359
|
||||
|
||||
731095817143
|
||||
74373288771
|
||||
471037513499
|
||||
Helpers\Plugins\BuiltIn\SuperLauncher\LauncherSettingsControl.xaml;Helpers\Plugins\BuiltIn\SuperLauncher\LauncherWindow.xaml;MainWindow.xaml;MainWindow_cs\MW_Eraser.xaml;Resources\DrawShapeImageDictionary.xaml;Resources\IconImageDictionary.xaml;Resources\SeewoImageDictionary.xaml;Resources\Styles\Dark.xaml;Resources\Styles\Light.xaml;Windows\AddCustomIconWindow.xaml;Windows\AddPickNameBackgroundWindow.xaml;Windows\CountdownTimerWindow.xaml;Windows\CustomIconWindow.xaml;Windows\CycleProcessBar.xaml;Windows\HasNewUpdateWindow.xaml;Windows\ManagePickNameBackgroundsWindow.xaml;Windows\NamesInputWindow.xaml;Windows\OperatingGuideWindow.xaml;Windows\PluginSettingsWindow.xaml;Windows\RandWindow.xaml;Windows\YesOrNoNotificationWindow.xaml;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user