9
9
using System . Windows . Forms ;
10
10
using System . Linq ;
11
11
using System . Reflection ;
12
+ using System . Drawing . Drawing2D ;
12
13
13
14
namespace SvgFileTypePlugin
14
15
{
@@ -22,7 +23,11 @@ public SvgFileType()
22
23
{
23
24
}
24
25
25
- private static string groupAttribute = "import_grouped" ;
26
+ // Dont change this text! It's used by a PSD import plugin to keep photoshop folder strure.
27
+ public const string LayerGroupBegin = "Layer Group: {0}" ;
28
+ public const string LayerGroupEnd = "End Layer Group: {0}" ;
29
+
30
+ private static string groupAttribute = "import_group_name" ;
26
31
private static string visibilityAttribute = "import_visibility" ;
27
32
28
33
private static string [ ] allowedTitles = new string [ ] { "label" , "title" , "inskape:label" } ;
@@ -78,7 +83,7 @@ public static Document Get(Stream input)
78
83
// Store opacity as layer options.
79
84
var setOpacityForLayer = true ;
80
85
var importHiddenLayers = true ;
81
-
86
+ var importGroupBoundariesAsLayers = false ;
82
87
DialogResult dr = DialogResult . Cancel ;
83
88
using ( var dialog = new UiDialog ( ) )
84
89
{
@@ -105,6 +110,7 @@ public static Document Get(Stream input)
105
110
keepAspectRatio = dialog . KeepAspectRatio ;
106
111
setOpacityForLayer = dialog . ImportOpacity ;
107
112
importHiddenLayers = dialog . ImportHiddenLayers ;
113
+ importGroupBoundariesAsLayers = dialog . ImportGroupBoundariesAsLayers ;
108
114
}
109
115
110
116
doc . Ppi = resolution ;
@@ -128,8 +134,16 @@ public static Document Get(Stream input)
128
134
Document outputDocument = new Document ( canvasw , canvash ) ;
129
135
if ( layersMode == LayersMode . All )
130
136
{
137
+ // Dont render groups and boundaries if defined
131
138
allElements = allElements . Where ( p => ! ( p is SvgGroup ) ) . ToList ( ) ;
132
- RenderElements ( setOpacityForLayer , importHiddenLayers , allElements , outputDocument ) ;
139
+
140
+ // Filter out group boundaries if not set.
141
+ if ( ! importGroupBoundariesAsLayers )
142
+ {
143
+ allElements = allElements . Where ( p => ! ( p is PaintGroupBoundaries ) ) . ToList ( ) ;
144
+ }
145
+
146
+ RenderElements ( allElements , outputDocument , setOpacityForLayer , importHiddenLayers ) ;
133
147
}
134
148
else if ( layersMode == LayersMode . Groups )
135
149
{
@@ -138,6 +152,9 @@ public static Document Get(Stream input)
138
152
139
153
foreach ( var element in allElements )
140
154
{
155
+ if ( element is PaintGroupBoundaries )
156
+ continue ;
157
+
141
158
if ( element . ContainsAttribute ( groupAttribute ) )
142
159
{
143
160
// Get only root level
@@ -175,7 +192,7 @@ public static Document Get(Stream input)
175
192
}
176
193
}
177
194
178
- RenderElements ( setOpacityForLayer , importHiddenLayers , groupsAndElementsWithoutGroup , outputDocument ) ;
195
+ RenderElements ( groupsAndElementsWithoutGroup , outputDocument , setOpacityForLayer , importHiddenLayers ) ;
179
196
}
180
197
181
198
// Fallback. Nothing is added. Render one default layer.
@@ -221,14 +238,23 @@ private static int ConvertToPixels(SvgUnitType type, float value, float ppi)
221
238
}
222
239
}
223
240
224
- private static void RenderElements ( bool setOpacityForLayer , bool importHiddenLayers , List < SvgVisualElement > elements , Document outputDocument )
241
+ private static void RenderElements ( List < SvgVisualElement > elements , Document outputDocument , bool setOpacityForLayer , bool importHiddenLayers )
225
242
{
226
243
// I had problems to render each element directly while parent transformation can affect child.
227
244
// But we can do a trick and render full document each time with only required nodes set as visible.
228
245
229
246
// Render all visual elements that are passed here.
230
247
foreach ( var element in elements )
231
248
{
249
+ if ( element is PaintGroupBoundaries )
250
+ {
251
+ // Render empty boundary and continue
252
+ var pdnLayer = new BitmapLayer ( outputDocument . Width , outputDocument . Height ) ;
253
+ pdnLayer . Name = ( ( PaintGroupBoundaries ) element ) . ID ;
254
+ outputDocument . Layers . Add ( pdnLayer ) ;
255
+ continue ;
256
+ }
257
+
232
258
// Turn off visibility of all elements
233
259
foreach ( var elemntToChange in elements )
234
260
{
@@ -396,15 +422,17 @@ private static string GetLayerTitle(SvgElement element)
396
422
return layerName ;
397
423
}
398
424
399
- private static IEnumerable < SvgElement > PrepareFlatElements ( SvgElementCollection collection , bool grouped = false )
425
+ private static IEnumerable < SvgElement > PrepareFlatElements ( SvgElementCollection collection , string groupName = null )
400
426
{
427
+ // Prepare a collection of elements that about to be rendered.
401
428
if ( collection != null )
402
429
{
403
430
foreach ( var toRender in collection )
404
431
{
405
- if ( ! grouped && toRender is SvgGroup )
432
+ // Dont prepare for a separate parsing def lists.
433
+ if ( toRender is SvgDefinitionList )
406
434
{
407
- grouped = true ;
435
+ continue ;
408
436
}
409
437
410
438
// Dont prepare def lists for a separate rendering.
@@ -413,6 +441,15 @@ private static IEnumerable<SvgElement> PrepareFlatElements(SvgElementCollection
413
441
continue ;
414
442
}
415
443
444
+ var isGroup = toRender is SvgGroup ;
445
+ if ( isGroup )
446
+ {
447
+ groupName = GetLayerTitle ( ( SvgGroup ) toRender ) ;
448
+
449
+ // Return fake node to indicate group end.
450
+ yield return new PaintGroupBoundaries ( ) { ID = string . Format ( LayerGroupEnd , groupName ) } ;
451
+ }
452
+
416
453
var visual = toRender as SvgVisualElement ;
417
454
418
455
if ( visual != null )
@@ -427,14 +464,15 @@ private static IEnumerable<SvgElement> PrepareFlatElements(SvgElementCollection
427
464
// Store opacity
428
465
toRender . CustomAttributes . Add ( visibilityAttribute , visual . Visible . ToString ( ) ) ;
429
466
430
- if ( grouped && ! toRender . ContainsAttribute ( groupAttribute ) )
467
+ // Save current group to indicate that elements inside a group.
468
+ if ( ! string . IsNullOrEmpty ( groupName ) && ! toRender . ContainsAttribute ( groupAttribute ) )
431
469
{
432
470
// Store group info
433
- toRender . CustomAttributes . Add ( groupAttribute , grouped . ToString ( ) ) ;
471
+ toRender . CustomAttributes . Add ( groupAttribute , groupName ) ;
434
472
}
435
473
}
436
474
437
- var returned = PrepareFlatElements ( toRender . Children , grouped ) ;
475
+ var returned = PrepareFlatElements ( toRender . Children , groupName ) ;
438
476
if ( returned != null )
439
477
{
440
478
foreach ( var output in returned )
@@ -443,6 +481,14 @@ private static IEnumerable<SvgElement> PrepareFlatElements(SvgElementCollection
443
481
}
444
482
}
445
483
484
+ if ( isGroup )
485
+ {
486
+ groupName = GetLayerTitle ( ( SvgGroup ) toRender ) ;
487
+
488
+ // Return fake node to indicate group start.
489
+ yield return new PaintGroupBoundaries ( ) { ID = string . Format ( LayerGroupBegin , groupName ) , IsStart = true } ;
490
+ }
491
+
446
492
yield return toRender ;
447
493
}
448
494
}
@@ -481,4 +527,21 @@ public void Dispose()
481
527
#endregion
482
528
}
483
529
}
530
+
531
+ // Used to determine boundaries of a group.
532
+ public class PaintGroupBoundaries : SvgVisualElement
533
+ {
534
+ public bool IsStart { get ; set ; }
535
+ public override RectangleF Bounds => throw new NotImplementedException ( ) ;
536
+
537
+ public override SvgElement DeepCopy ( )
538
+ {
539
+ throw new NotImplementedException ( ) ;
540
+ }
541
+
542
+ public override GraphicsPath Path ( ISvgRenderer renderer )
543
+ {
544
+ throw new NotImplementedException ( ) ;
545
+ }
546
+ }
484
547
}
0 commit comments