Skip to content

Commit ef39d1d

Browse files
committed
Remove Clipper2
1 parent 7931558 commit ef39d1d

4 files changed

Lines changed: 87 additions & 22 deletions

File tree

‎Telegram/AI/RecognizedTextBoundingBoxSimplifier.cs‎

Lines changed: 87 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,15 @@
55
// file LICENSE or copy at https://www.gnu.org/licenses/gpl-3.0.txt)
66
//
77

8-
using Clipper2Lib;
8+
using Microsoft.Graphics.Canvas.Geometry;
99
using System;
1010
using System.Collections.Generic;
11-
using System.Linq;
1211
using System.Numerics;
1312
using Telegram.Native.AI;
1413

1514
namespace Telegram.AI
1615
{
17-
public static class RecognizedTextBoundingBoxSimplifier
16+
public static partial class RecognizedTextBoundingBoxSimplifier
1817
{
1918
public static List<List<Vector2>> Union<T>(IEnumerable<T> boxes, float tolerance, float padding) where T : IOcrObject
2019
{
@@ -43,27 +42,98 @@ public static List<List<Vector2>> Union<T>(IEnumerable<T> boxes, float tolerance
4342
return vectors;
4443
}
4544

46-
private static IEnumerable<List<Vector2>> GetUnionOfBoundingBoxes<T>(IEnumerable<T> boxes, float padding) where T : IOcrObject
45+
private static List<List<Vector2>> GetUnionOfBoundingBoxes<T>(IEnumerable<T> boxes, float padding) where T : IOcrObject
4746
{
48-
var clipper = new Clipper64();
49-
var paths = boxes.Select(box => ConvertToClipperPath(box.BoundingBox.Inflate(padding))).ToList();
47+
var empty = true;
5048

51-
clipper.AddSubject(new Paths64(paths));
52-
var solution = new Paths64();
53-
clipper.Execute(ClipType.Union, Clipper2Lib.FillRule.NonZero, solution);
49+
using (var builder = new CanvasPathBuilder(null))
50+
{
51+
// The quads overlap and all wind the same way, so under the winding rule the
52+
// filled region is their union, and Outline traces exactly that boundary.
53+
builder.SetFilledRegionDetermination(CanvasFilledRegionDetermination.Winding);
54+
55+
foreach (var box in boxes)
56+
{
57+
var quad = box.BoundingBox.Inflate(padding);
58+
59+
builder.BeginFigure(quad.TopLeft);
60+
builder.AddLine(quad.TopRight);
61+
builder.AddLine(quad.BottomRight);
62+
builder.AddLine(quad.BottomLeft);
63+
builder.EndFigure(CanvasFigureLoop.Closed);
64+
65+
empty = false;
66+
}
67+
68+
if (empty)
69+
{
70+
return new List<List<Vector2>>();
71+
}
72+
73+
var receiver = new PolygonReceiver();
5474

55-
return solution.Select(path => path.Select(p => new Vector2((float)(p.X / 1000), (float)(p.Y / 1000))).Distinct().ToList());
75+
using (var quads = CanvasGeometry.CreatePath(builder))
76+
using (var outline = quads.Outline())
77+
{
78+
outline.SendPathTo(receiver);
79+
}
80+
81+
return receiver.Polygons;
82+
}
5683
}
5784

58-
private static Path64 ConvertToClipperPath(RecognizedTextBoundingBox box)
85+
private partial class PolygonReceiver : ICanvasPathReceiver
5986
{
60-
return new Path64
87+
public List<List<Vector2>> Polygons { get; } = new();
88+
89+
private List<Vector2> _figure;
90+
91+
public void BeginFigure(Vector2 startPoint, CanvasFigureFill figureFill)
6192
{
62-
new Point64((long)(box.TopLeft.X * 1000), (long)(box.TopLeft.Y * 1000)),
63-
new Point64((long)(box.TopRight.X * 1000), (long)(box.TopRight.Y * 1000)),
64-
new Point64((long)(box.BottomRight.X * 1000), (long)(box.BottomRight.Y * 1000)),
65-
new Point64((long)(box.BottomLeft.X * 1000), (long)(box.BottomLeft.Y * 1000))
66-
};
93+
_figure = new List<Vector2> { startPoint };
94+
}
95+
96+
public void AddLine(Vector2 endPoint)
97+
{
98+
Add(endPoint);
99+
}
100+
101+
// The outline of a polygonal path has no curves, but the interface requires these.
102+
public void AddArc(Vector2 endPoint, float radiusX, float radiusY, float rotationAngle, CanvasSweepDirection sweepDirection, CanvasArcSize arcSize) => Add(endPoint);
103+
public void AddCubicBezier(Vector2 controlPoint1, Vector2 controlPoint2, Vector2 endPoint) => Add(endPoint);
104+
public void AddQuadraticBezier(Vector2 controlPoint, Vector2 endPoint) => Add(endPoint);
105+
106+
public void SetFilledRegionDetermination(CanvasFilledRegionDetermination filledRegionDetermination) { }
107+
public void SetSegmentOptions(CanvasFigureSegmentOptions figureSegmentOptions) { }
108+
109+
public void EndFigure(CanvasFigureLoop figureLoop)
110+
{
111+
if (_figure.Count > 1 && IsCoincident(_figure[0], _figure[^1]))
112+
{
113+
_figure.RemoveAt(_figure.Count - 1);
114+
}
115+
116+
if (_figure.Count > 2)
117+
{
118+
Polygons.Add(_figure);
119+
}
120+
121+
_figure = null;
122+
}
123+
124+
// The rounding pass normalizes (curr - prev), so a repeated vertex would give it NaN.
125+
private void Add(Vector2 point)
126+
{
127+
if (!IsCoincident(_figure[^1], point))
128+
{
129+
_figure.Add(point);
130+
}
131+
}
132+
133+
private static bool IsCoincident(Vector2 a, Vector2 b)
134+
{
135+
return Vector2.DistanceSquared(a, b) < 0.0001f;
136+
}
67137
}
68138

69139
private static void SimplifySection(List<Vector2> points, int start, int end, float tolerance, bool[] keep)

‎Telegram/Telegram.Modern.csproj‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,6 @@
212212
</ItemGroup>
213213

214214
<ItemGroup>
215-
<PackageReference Include="Clipper2" Version="1.5.4" />
216215
<PackageReference Include="Markdig" Version="1.3.2" />
217216
<PackageReference Include="Microsoft.UI.Xaml" Version="2.8.7" />
218217
<PackageReference Include="Microsoft.Web.WebView2" Version="1.0.4129.50" />

‎Telegram/Telegram.Win32.csproj‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,6 @@
180180
Versions are the ones Modern resolves to. -->
181181
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.26100.4654" />
182182
<PackageReference Include="Microsoft.Windows.SDK.BuildTools.MSIX" Version="1.7.20250806.1" />
183-
<PackageReference Include="Clipper2" Version="1.5.4" />
184183
<PackageReference Include="Markdig" Version="1.3.2" />
185184
<PackageReference Include="Microsoft.UI.Xaml" Version="2.8.7" />
186185
<PackageReference Include="Microsoft.Web.WebView2" Version="1.0.4129.50" />

‎Telegram/Telegram.csproj‎

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4680,9 +4680,6 @@
46804680
</Page>
46814681
</ItemGroup>
46824682
<ItemGroup>
4683-
<PackageReference Include="Clipper2">
4684-
<Version>1.5.4</Version>
4685-
</PackageReference>
46864683
<PackageReference Include="Markdig">
46874684
<Version>1.3.2</Version>
46884685
</PackageReference>

0 commit comments

Comments
 (0)