55using System . Text . RegularExpressions ;
66using FreeFrame . Components . Shapes . Path ;
77using DelaunatorSharp ;
8+ using OpenTK . Graphics . OpenGL4 ;
9+ using OpenTK . Mathematics ;
810
911namespace FreeFrame . Components . Shapes
1012{
1113 public class SVGPath : Shape
1214 {
1315 readonly Dictionary < char , Regex > _dAttributesRegex = new ( )
1416 {
15- { 'M' , new Regex ( @" *(\d+) *, *(\d+) *" ) } ,
16- { 'm' , new Regex ( @" *(\d+) *, *(\d+) *" ) } ,
17- { 'L' , new Regex ( @" *(\d+) *, *(\d+) *" ) } ,
18- { 'l' , new Regex ( @" *(\d+) *, *(\d+) *" ) } ,
19- { 'H' , new Regex ( @" *(\d+) *" ) } ,
20- { 'h' , new Regex ( @" *(\d+) *" ) } ,
21- { 'V' , new Regex ( @" *(\d+) *" ) } ,
22- { 'v' , new Regex ( @" *(\d+) *" ) } ,
23- { 'C' , new Regex ( @" *(\d+) *, *(\d+) +(\d+) *, *(\d+) +(\d+) *, *(\d+) *" ) } ,
24- { 'c' , new Regex ( @" *(\d+) *, *(\d+) +(\d+) *, *(\d+) +(\d+) *, *(\d+) *" ) } ,
25- { 'S' , new Regex ( @" *(\d+) *, *(\d+) +(\d+) *, *(\d+) *" ) } ,
26- { 's' , new Regex ( @" *(\d+) *, *(\d+) +(\d+) *, *(\d+) *" ) } ,
27- { 'Q' , new Regex ( @" *(\d+) *, *(\d+) +(\d+) *, *(\d+) *" ) } ,
28- { 'q' , new Regex ( @" *(\d+) *, *(\d+) +(\d+) *, *(\d+) *" ) } ,
29- { 'T' , new Regex ( @" *(\d+) *, *(\d+) *" ) } ,
30- { 't' , new Regex ( @" *(\d+) *, *(\d+) *" ) } ,
31- { 'A' , new Regex ( @" *(\d+) +(\d+) +(\d+) +(\d) +(\d) +(\d+) *, *(\d+) *" ) } ,
32- { 'a' , new Regex ( @" *(\d+) +(\d+) +(\d+) +(\d) +(\d) +(\d+) *, *(\d+) *" ) } ,
17+ { 'M' , new Regex ( @" *(-? \d+) *, *(-? \d+) *" ) } ,
18+ { 'm' , new Regex ( @" *(-? \d+) *, *(-? \d+) *" ) } ,
19+ { 'L' , new Regex ( @" *(-? \d+) *, *(-? \d+) *" ) } ,
20+ { 'l' , new Regex ( @" *(-? \d+) *, *(-? \d+) *" ) } ,
21+ { 'H' , new Regex ( @" *(-? \d+) *" ) } ,
22+ { 'h' , new Regex ( @" *(-? \d+) *" ) } ,
23+ { 'V' , new Regex ( @" *(-? \d+) *" ) } ,
24+ { 'v' , new Regex ( @" *(-? \d+) *" ) } ,
25+ { 'C' , new Regex ( @" *(-? \d+) *, *(-? \d+) +(-? \d+) *, *(-? \d+) +(-? \d+) *, *(-? \d+) *" ) } ,
26+ { 'c' , new Regex ( @" *(-? \d+) *, *(-? \d+) +(-? \d+) *, *(-? \d+) +(-? \d+) *, *(-? \d+) *" ) } ,
27+ { 'S' , new Regex ( @" *(-? \d+) *, *(-? \d+) +(-? \d+) *, *(-? \d+) *" ) } ,
28+ { 's' , new Regex ( @" *(-? \d+) *, *(-? \d+) +(-? \d+) *, *(-? \d+) *" ) } ,
29+ { 'Q' , new Regex ( @" *(-? \d+) *, *(-? \d+) +(-? \d+) *, *(-? \d+) *" ) } ,
30+ { 'q' , new Regex ( @" *(-? \d+) *, *(-? \d+) +(-? \d+) *, *(-? \d+) *" ) } ,
31+ { 'T' , new Regex ( @" *(-? \d+) *, *(-? \d+) *" ) } ,
32+ { 't' , new Regex ( @" *(-? \d+) *, *(-? \d+) *" ) } ,
33+ { 'A' , new Regex ( @" *(-? \d+) +(-? \d+) +(-? \d+) +(-? \d) +(-? \d) +(-? \d+) *, *(-? \d+) *" ) } ,
34+ { 'a' , new Regex ( @" *(-? \d+) +(-? \d+) +(-? \d+) +(-? \d) +(-? \d) +(-? \d+) *, *(-? \d+) *" ) } ,
3335 { 'Z' , new Regex ( "" ) } ,
3436 { 'z' , new Regex ( "" ) } ,
3537 } ;
3638
3739 List < DrawAttribute > _drawAttributes = new ( ) ;
3840
41+ List < uint > _indexes = new ( ) ;
42+
3943 public List < DrawAttribute > DrawAttributes { get => _drawAttributes ; set => _drawAttributes = value ; }
4044
4145 public SVGPath ( XmlReader reader ) //: this()
@@ -101,55 +105,17 @@ public SVGPath(XmlReader reader) //: this()
101105 }
102106 }
103107 }
108+ public override void Draw ( Vector2i clientSize )
109+ {
110+ base . Draw ( clientSize ) ;
104111
112+ foreach ( VertexArrayObject vao in _vaos )
113+ vao . Draw ( clientSize ) ;
114+ }
105115 public override float [ ] GetVertices ( )
106116 {
107117 // Delaunator polygon = new Delaunator(new IPoint[] { new Point(0.0, 0.0) });
108118
109-
110- /*
111- DrawAttribute? prev = null;
112- DrawAttribute? current = null;
113- foreach (DrawAttribute next in DrawAttributes)
114- {
115- if (current != null)
116- {
117- if (current.GetType() == typeof(LineTo))
118- {
119- vertices.AddRange(((LineTo)current).GetVertices());
120- }
121- else if (current.GetType() == typeof(HorizontalLineTo))
122- {
123- vertices.AddRange(((HorizontalLineTo)current).GetVertices());
124- }
125- else if (current.GetType() == typeof(VerticalLineTo))
126- {
127- vertices.AddRange(((VerticalLineTo)current).GetVertices());
128- }
129-
130- if (prev != null)
131- {
132- if (current.GetType() == typeof(CurveTo) || current.GetType() == typeof(SmoothCurveTo))
133- {
134- DrawAttribute.LastControlPointX = ((CurveTo)prev).X2; // Update last x and y (for relatives attributes points)
135- DrawAttribute.LastControlPointY = ((CurveTo)prev).Y2;
136- }
137- if (current.GetType() != typeof(MoveTo)) // Avoid trying to get last added vertices but MoveTo doesnt add vertices
138- {
139- DrawAttribute.LastX = vertices[-2]; // Update last x and y (for relatives attributes points)
140- DrawAttribute.LastY = vertices[-1];
141- }
142- }
143- }
144- (prev, current) = (current, next);
145- }
146-
147- if (current != null) // Last element
148- {
149-
150- }
151- */
152-
153119 // Edges
154120 List < float > vertices = new List < float > ( ) ;
155121 DrawAttribute ? previous = null ;
@@ -168,35 +134,75 @@ public override float[] GetVertices()
168134 current . GetType ( ) == typeof ( QuadraticBezierCurveTo ) ||
169135 current . GetType ( ) == typeof ( SmoothQuadraticBezierCurveTo ) ) // TODO: Add EllipticalArc support
170136 {
137+ int previousLength = vertices . Count ;
138+
139+ int i = 0 ;
140+ int count = 0 ;
171141 foreach ( float item in current . GetVertices ( ) )
172142 {
173143 vertices . Add ( item ) ;
144+ i ++ ;
174145 }
175- }
146+ if ( _indexes . Count > 0 )
147+ count = ( int ) _indexes . Last ( ) ;
148+ _indexes . AddRange ( Enumerable . Range ( count , i / 2 ) . Select ( i => ( uint ) i ) . ToArray ( ) ) ;
176149
177- if ( current . GetType ( ) != typeof ( MoveTo ) ) // MoveTo already update the lasts
178- {
179- DrawAttribute . LastX = vertices [ ^ 2 ] ; // Update last x and y (for relatives attributes points)
180- DrawAttribute . LastY = vertices [ ^ 1 ] ;
150+ //i++;
181151 }
182- if ( previous != null )
152+
153+ if ( current . GetType ( ) == typeof ( MoveTo ) )
183154 {
184- if ( previous . GetType ( ) == typeof ( CurveTo ) ) // Cubic Bézier Curves
155+ if ( previous != null )
185156 {
186- DrawAttribute . LastControlPointX = ( ( CurveTo ) previous ) . X2 ;
187- DrawAttribute . LastControlPointY = ( ( CurveTo ) previous ) . Y2 ;
157+ if ( previous . GetType ( ) != typeof ( MoveTo ) )
158+ {
159+ _indexes . Add ( _indexes . Last ( ) ) ;
160+ }
188161 }
189- else if ( previous . GetType ( ) == typeof ( QuadraticBezierCurveTo ) ) // Quadratic Bézier Curves
162+ if ( ( ( MoveTo ) current ) . IsRelative )
190163 {
191- DrawAttribute . LastControlPointX = ( ( QuadraticBezierCurveTo ) previous ) . X1 ;
192- DrawAttribute . LastControlPointY = ( ( QuadraticBezierCurveTo ) previous ) . Y1 ;
164+ DrawAttribute . LastX + = ( ( MoveTo ) current ) . X ; // Update last x and y (for relatives attributes points)
165+ DrawAttribute . LastY + = ( ( MoveTo ) current ) . Y ;
193166 }
194- else if ( current . GetType ( ) != typeof ( SmoothCurveTo ) && current . GetType ( ) != typeof ( SmoothQuadraticBezierCurveTo ) ) // Only reset if we're done with bézier curves
167+ else
195168 {
196- ( DrawAttribute . LastControlPointX , DrawAttribute . LastControlPointY ) = ( 0 , 0 ) ;
169+ DrawAttribute . LastX = ( ( MoveTo ) current ) . X ; // Update last x and y (for relatives attributes points)
170+ DrawAttribute . LastY = ( ( MoveTo ) current ) . Y ;
197171 }
198172 }
199- previous = current ; // previous element
173+ else
174+ {
175+ DrawAttribute . LastX = vertices [ ^ 2 ] ; // Update last x and y (for relatives attributes points)
176+ DrawAttribute . LastY = vertices [ ^ 1 ] ;
177+ }
178+
179+ if ( current . GetType ( ) == typeof ( CurveTo ) ) // Cubic Bézier Curves
180+ {
181+ if ( ( ( CurveTo ) current ) . X > ( ( CurveTo ) current ) . X2 ) // Control end point on the left
182+ DrawAttribute . LastControlPointX = ( ( CurveTo ) current ) . X + ( ( CurveTo ) current ) . X2 ;
183+ else if ( ( ( CurveTo ) current ) . X < ( ( CurveTo ) current ) . X2 ) // Control end point on the right
184+ DrawAttribute . LastControlPointX = ( ( CurveTo ) current ) . X - ( ( CurveTo ) current ) . X2 ;
185+ else // On the middle
186+ DrawAttribute . LastControlPointX = ( ( CurveTo ) current ) . X ;
187+
188+ if ( ( ( CurveTo ) current ) . Y > ( ( CurveTo ) current ) . Y2 ) // Control end point on the top
189+ DrawAttribute . LastControlPointY = ( ( CurveTo ) current ) . Y + ( ( CurveTo ) current ) . Y2 ;
190+ else if ( ( ( CurveTo ) current ) . Y < ( ( CurveTo ) current ) . Y2 ) // Control end point on the bottom
191+ DrawAttribute . LastControlPointY = ( ( CurveTo ) current ) . Y - ( ( CurveTo ) current ) . Y2 ;
192+ else // On the middle
193+ DrawAttribute . LastControlPointY = ( ( CurveTo ) current ) . Y ;
194+ }
195+ else if ( current . GetType ( ) == typeof ( QuadraticBezierCurveTo ) ) // Quadratic Bézier Curves
196+ {
197+ DrawAttribute . LastControlPointX = ( ( QuadraticBezierCurveTo ) current ) . X1 ;
198+ DrawAttribute . LastControlPointY = ( ( QuadraticBezierCurveTo ) current ) . Y1 ;
199+ }
200+ else if ( current . GetType ( ) != typeof ( SmoothCurveTo ) && current . GetType ( ) != typeof ( SmoothQuadraticBezierCurveTo ) ) // Only reset if we're done with bézier curves
201+ {
202+ ( DrawAttribute . LastControlPointX , DrawAttribute . LastControlPointY ) = ( 0 , 0 ) ;
203+ }
204+
205+ previous = current ;
200206 }
201207
202208 return vertices . ToArray ( ) ;
@@ -220,9 +226,13 @@ public override uint[] GetVerticesIndexes()
220226 return indexes.ToArray();
221227 */
222228
223- uint [ ] indexes = Enumerable . Range ( 0 , GetVertices ( ) . Length / 2 ) . Select ( i => ( uint ) i ) . ToArray ( ) ;
229+ //uint[] indexes = Enumerable.Range(0, GetVertices().Length / 2).Select(i => (uint)i).ToArray();
230+
231+ //return indexes;
224232
225- return indexes ;
233+ _indexes = new List < uint > ( ) ;
234+ GetVertices ( ) ;
235+ return _indexes . ToArray ( ) ;
226236 }
227237
228238 public override Hitbox Hitbox ( )
0 commit comments