Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
ImportedProjects
SVG
Commits
6c1198d2
Commit
6c1198d2
authored
Jun 01, 2014
by
joreg
Browse files
Merge branch 'master' of
https://github.com/vvvv/SVG
parents
220d8370
87e7be2d
Changes
13
Hide whitespace changes
Inline
Side-by-side
Source/Basic Shapes/SvgVisualElement.cs
View file @
6c1198d2
...
...
@@ -91,7 +91,7 @@ namespace Svg
/// <summary>
/// Renders the <see cref="SvgElement"/> and contents to the specified <see cref="Graphics"/> object.
/// </summary>
/// <param name="
graphics
">The <see cref="SvgRenderer"/> object to render to.</param>
/// <param name="
renderer
">The <see cref="SvgRenderer"/> object to render to.</param>
protected
override
void
Render
(
SvgRenderer
renderer
)
{
if
(
this
.
Path
!=
null
&&
this
.
Visible
)
...
...
Source/Clipping and Masking/SvgClipPath.cs
View file @
6c1198d2
...
...
@@ -98,7 +98,7 @@ namespace Svg
/// <summary>
/// Called by the underlying <see cref="SvgElement"/> when an element has been removed from the
/// <see cref="Children"/> collection.
/// <see cref="
SvgElement.
Children"/> collection.
/// </summary>
/// <param name="child">The <see cref="SvgElement"/> that has been removed.</param>
protected
override
void
RemoveElement
(
SvgElement
child
)
...
...
Source/DataTypes/SvgUnitConverter.cs
View file @
6c1198d2
...
...
@@ -23,6 +23,13 @@ namespace Svg
throw
new
ArgumentOutOfRangeException
(
"value must be a string."
);
}
//support exponents (the SVG that comes back from IE may be an exponent ugh!!!)
if
((
value
as
string
).
Contains
(
"e"
))
{
var
d
=
Decimal
.
Parse
((
string
)
value
,
System
.
Globalization
.
NumberStyles
.
Float
);
value
=
d
.
ToString
();
}
// http://www.w3.org/TR/CSS21/syndata.html#values
// http://www.w3.org/TR/SVG11/coords.html#Units
...
...
Source/Document Structure/SvgGroup.cs
View file @
6c1198d2
...
...
@@ -47,10 +47,18 @@ namespace Svg
var
r
=
new
RectangleF
();
foreach
(
var
c
in
this
.
Children
)
{
if
(
c
is
SvgVisualElement
)
r
=
RectangleF
.
Union
(
r
,
((
SvgVisualElement
)
c
).
Bounds
);
if
(
c
is
SvgVisualElement
)
{
// First it should check if rectangle is empty or it will return the wrong Bounds.
// This is because when the Rectangle is Empty, the Union method adds as if the first values where X=0, Y=0
if
(
r
.
IsEmpty
)
r
=
((
SvgVisualElement
)
c
).
Bounds
;
else
r
=
RectangleF
.
Union
(
r
,
((
SvgVisualElement
)
c
).
Bounds
);
}
}
return
r
;
return
r
;
}
}
...
...
@@ -81,4 +89,4 @@ namespace Svg
return
newObj
;
}
}
}
\ No newline at end of file
}
Source/Painting/SvgColourConverter.cs
View file @
6c1198d2
...
...
@@ -38,9 +38,21 @@ namespace Svg
try
{
int
start
=
colour
.
IndexOf
(
"("
)
+
1
;
string
[]
values
=
colour
.
Substring
(
start
,
colour
.
IndexOf
(
")"
)
-
start
).
Split
(
new
char
[]{
','
,
' '
},
StringSplitOptions
.
RemoveEmptyEntries
);
//get the values from the RGB string
string
[]
values
=
colour
.
Substring
(
start
,
colour
.
IndexOf
(
")"
)
-
start
).
Split
(
new
char
[]{
','
,
' '
},
StringSplitOptions
.
RemoveEmptyEntries
);
return
System
.
Drawing
.
Color
.
FromArgb
(
int
.
Parse
(
values
[
0
]),
int
.
Parse
(
values
[
1
]),
int
.
Parse
(
values
[
2
]));
//determine the alpha value if this is an RGBA (it will be the 4th value if there is one)
int
alphaValue
=
255
;
if
(
values
.
Length
>
3
)
{
//the alpha portion of the rgba is not an int 0-255 it is a decimal between 0 and 1
//so we have to determine the corosponding byte value
alphaValue
=
(
int
)(
decimal
.
Parse
(
values
[
3
])
*
255
);
}
Color
colorpart
=
System
.
Drawing
.
Color
.
FromArgb
(
alphaValue
,
int
.
Parse
(
values
[
0
]),
int
.
Parse
(
values
[
1
]),
int
.
Parse
(
values
[
2
]));
return
colorpart
;
}
catch
{
...
...
Source/Painting/SvgGradientServer.cs
View file @
6c1198d2
using
System
;
using
System.Collections.Generic
;
using
System.Collections
;
using
System.Text
;
using
System.Drawing
;
using
System.Drawing.Drawing2D
;
...
...
@@ -100,19 +97,20 @@ namespace Svg
}
/// <summary>
/// Gets a <see cref="Colo
u
rBlend"/> representing the <see cref="SvgGradientServer"/>'s gradient stops.
/// Gets a <see cref="ColorBlend"/> representing the <see cref="SvgGradientServer"/>'s gradient stops.
/// </summary>
/// <param name="owner">The parent <see cref="SvgVisualElement"/>.</param>
/// <param name="opacity">The opacity of the colour blend.</param>
protected
ColorBlend
GetColourBlend
(
SvgVisualElement
owner
,
float
opacity
)
protected
ColorBlend
GetColourBlend
(
SvgVisualElement
owner
,
float
opacity
,
bool
radial
)
{
ColorBlend
blend
=
new
ColorBlend
();
int
colourBlends
=
this
.
Stops
.
Count
;
bool
insertStart
=
false
;
bool
insertEnd
=
false
;
//gradient.Transform = renderingElement.Transforms.Matrix;
//stops should be processed in reverse order if it's a radial gradient
// May need to increase the number of colour blends because the range *must* be from 0.0 to 1.0.
// E.g. 0.5 - 0.8 isn't valid therefore the rest need to be calculated.
...
...
@@ -120,8 +118,15 @@ namespace Svg
if
(
this
.
Stops
[
0
].
Offset
.
Value
>
0
)
{
colourBlends
++;
// Indicate that a colour has to be dynamically added at the start
insertStart
=
true
;
if
(
radial
)
{
insertEnd
=
true
;
}
else
{
insertStart
=
true
;
}
}
// If the last stop doesn't end at 1 a stop
...
...
@@ -129,12 +134,17 @@ namespace Svg
if
(
lastValue
<
100
||
lastValue
<
1
)
{
colourBlends
++;
// Indicate that a colour has to be dynamically added at the end
insertEnd
=
true
;
if
(
radial
)
{
insertStart
=
true
;
}
else
{
insertEnd
=
true
;
}
}
blend
.
Positions
=
new
float
[
colourBlends
];
blend
.
Colors
=
new
Color
[
colourBlends
];
ColorBlend
blend
=
new
ColorBlend
(
colourBlends
);
// Set positions and colour values
int
actualStops
=
0
;
...
...
@@ -144,15 +154,24 @@ namespace Svg
for
(
int
i
=
0
;
i
<
colourBlends
;
i
++)
{
mergedOpacity
=
opacity
*
this
.
Stops
[
actualStops
].
Opacity
;
position
=
(
this
.
Stops
[
actualStops
].
Offset
.
ToDeviceValue
(
owner
)
/
owner
.
Bounds
.
Width
);
colour
=
Color
.
FromArgb
((
int
)(
mergedOpacity
*
255
),
this
.
Stops
[
actualStops
++].
Colour
);
var
currentStop
=
this
.
Stops
[
radial
?
this
.
Stops
.
Count
-
1
-
actualStops
:
actualStops
];
mergedOpacity
=
opacity
*
currentStop
.
Opacity
;
position
=
radial
?
1
-
(
currentStop
.
Offset
.
ToDeviceValue
(
owner
)
/
owner
.
Bounds
.
Width
)
:
(
currentStop
.
Offset
.
ToDeviceValue
(
owner
)
/
owner
.
Bounds
.
Width
);
colour
=
Color
.
FromArgb
((
int
)(
mergedOpacity
*
255
),
currentStop
.
Colour
);
actualStops
++;
// Insert this colour before itself at position 0
if
(
insertStart
&&
i
==
0
)
{
blend
.
Positions
[
i
]
=
0.0f
;
blend
.
Colors
[
i
++]
=
colour
;
blend
.
Colors
[
i
]
=
colour
;
i
++;
}
blend
.
Positions
[
i
]
=
position
;
...
...
@@ -161,8 +180,10 @@ namespace Svg
// Insert this colour after itself at position 0
if
(
insertEnd
&&
i
==
colourBlends
-
2
)
{
blend
.
Positions
[
i
+
1
]
=
1.0f
;
blend
.
Colors
[++
i
]
=
colour
;
i
++;
blend
.
Positions
[
i
]
=
1.0f
;
blend
.
Colors
[
i
]
=
colour
;
}
}
...
...
@@ -184,12 +205,12 @@ namespace Svg
public
override
SvgElement
DeepCopy
<
T
>()
{
var
newObj
=
base
.
DeepCopy
<
T
>()
as
SvgGradientServer
;
newObj
.
SpreadMethod
=
this
.
SpreadMethod
;
newObj
.
SpreadMethod
=
this
.
SpreadMethod
;
newObj
.
GradientUnits
=
this
.
GradientUnits
;
newObj
.
InheritGradient
=
this
.
InheritGradient
;
return
newObj
;
return
newObj
;
}
}
}
\ No newline at end of file
Source/Painting/SvgLinearGradientServer.cs
View file @
6c1198d2
...
...
@@ -109,7 +109,7 @@ namespace Svg
}
LinearGradientBrush
gradient
=
new
LinearGradientBrush
(
start
,
end
,
Color
.
Transparent
,
Color
.
Transparent
);
gradient
.
InterpolationColors
=
base
.
GetColourBlend
(
owner
,
opacity
);
gradient
.
InterpolationColors
=
base
.
GetColourBlend
(
owner
,
opacity
,
false
);
// Needed to fix an issue where the gradient was being wrapped when though it had the correct bounds
gradient
.
WrapMode
=
WrapMode
.
TileFlipX
;
...
...
Source/Painting/SvgPatternServer.cs
View file @
6c1198d2
...
...
@@ -105,7 +105,7 @@ namespace Svg
/// <summary>
/// Gets a <see cref="Brush"/> representing the current paint server.
/// </summary>
/// <param name="
styleOwner
">The owner <see cref="SvgVisualElement"/>.</param>
/// <param name="
renderingElement
">The owner <see cref="SvgVisualElement"/>.</param>
/// <param name="opacity">The opacity of the brush.</param>
public
override
Brush
GetBrush
(
SvgVisualElement
renderingElement
,
float
opacity
)
{
...
...
Source/Painting/SvgRadialGradientServer.cs
View file @
6c1198d2
using
System
;
using
System.Collections.Generic
;
using
System.Text
;
using
System.Drawing
;
using
System.Drawing.Drawing2D
;
...
...
@@ -33,14 +30,36 @@ namespace Svg
[
SvgAttribute
(
"fx"
)]
public
SvgUnit
FocalX
{
get
{
return
this
.
Attributes
.
GetAttribute
<
SvgUnit
>(
"fx"
);
}
get
{
var
value
=
this
.
Attributes
.
GetAttribute
<
SvgUnit
>(
"fx"
);
if
(
value
.
IsEmpty
||
value
.
IsNone
)
{
value
=
this
.
CenterX
;
}
return
value
;
}
set
{
this
.
Attributes
[
"fx"
]
=
value
;
}
}
[
SvgAttribute
(
"fy"
)]
public
SvgUnit
FocalY
{
get
{
return
this
.
Attributes
.
GetAttribute
<
SvgUnit
>(
"fy"
);
}
get
{
var
value
=
this
.
Attributes
.
GetAttribute
<
SvgUnit
>(
"fy"
);
if
(
value
.
IsEmpty
||
value
.
IsNone
)
{
value
=
this
.
CenterY
;
}
return
value
;
}
set
{
this
.
Attributes
[
"fy"
]
=
value
;
}
}
...
...
@@ -57,26 +76,35 @@ namespace Svg
public
override
Brush
GetBrush
(
SvgVisualElement
renderingElement
,
float
opacity
)
{
float
radius
=
this
.
Radius
.
ToDeviceValue
(
renderingElement
);
if
(
radius
<=
0
)
{
return
null
;
}
GraphicsPath
path
=
new
GraphicsPath
();
float
left
=
this
.
CenterX
.
ToDeviceValue
(
renderingElement
);
float
top
=
this
.
CenterY
.
ToDeviceValue
(
renderingElement
,
true
);
float
radius
=
this
.
Radius
.
ToDeviceValue
(
renderingElement
);
RectangleF
boundingBox
=
(
this
.
GradientUnits
==
SvgCoordinateUnits
.
ObjectBoundingBox
)
?
renderingElement
.
Bounds
:
renderingElement
.
OwnerDocument
.
GetDimensions
();
if
(
radius
>
0
)
{
path
.
AddEllipse
(
left
-
radius
,
top
-
radius
,
radius
*
2
,
radius
*
2
);
path
.
AddEllipse
(
boundingBox
.
Left
+
left
-
radius
,
boundingBox
.
Top
+
top
-
radius
,
radius
*
2
,
radius
*
2
);
PathGradientBrush
brush
=
new
PathGradientBrush
(
path
);
ColorBlend
blend
=
base
.
GetColourBlend
(
renderingElement
,
opacity
);
PathGradientBrush
brush
=
new
PathGradientBrush
(
path
);
ColorBlend
blend
=
base
.
GetColourBlend
(
renderingElement
,
opacity
,
true
);
brush
.
InterpolationColors
=
blend
;
brush
.
CenterPoint
=
new
PointF
(
this
.
FocalX
.
ToDeviceValue
(
renderingElement
),
this
.
FocalY
.
ToDeviceValue
(
renderingElement
,
true
));
brush
.
InterpolationColors
=
blend
;
brush
.
CenterPoint
=
new
PointF
(
boundingBox
.
Left
+
this
.
FocalX
.
ToDeviceValue
(
renderingElement
),
boundingBox
.
Top
+
this
.
FocalY
.
ToDeviceValue
(
renderingElement
,
true
));
return
brush
;
}
return
null
;
return
brush
;
}
...
...
@@ -89,13 +117,14 @@ namespace Svg
public
override
SvgElement
DeepCopy
<
T
>()
{
var
newObj
=
base
.
DeepCopy
<
T
>()
as
SvgRadialGradientServer
;
newObj
.
CenterX
=
this
.
CenterX
;
newObj
.
CenterY
=
this
.
CenterY
;
newObj
.
Radius
=
this
.
Radius
;
newObj
.
FocalX
=
this
.
FocalX
;
newObj
.
FocalY
=
this
.
FocalY
;
return
newObj
;
return
newObj
;
}
}
}
\ No newline at end of file
Source/SvgElementCollection.cs
View file @
6c1198d2
...
...
@@ -53,7 +53,12 @@ namespace Svg
/// <param name="item">The <see cref="SvgElement"/> to be added.</param>
public
void
Insert
(
int
index
,
SvgElement
item
)
{
InsertAndForceUniqueID
(
index
,
item
,
false
,
false
);
InsertAndForceUniqueID
(
index
,
item
,
true
,
true
,
LogIDChange
);
}
private
void
LogIDChange
(
SvgElement
elem
,
string
oldId
,
string
newID
)
{
Console
.
WriteLine
(
"ID of SVG element "
+
elem
.
ToString
()
+
" changed from "
+
oldId
+
" to "
+
newID
);
}
public
void
InsertAndForceUniqueID
(
int
index
,
SvgElement
item
,
bool
autoForceUniqueID
=
true
,
bool
autoFixChildrenID
=
true
,
Action
<
SvgElement
,
string
,
string
>
logElementOldIDNewID
=
null
)
...
...
@@ -81,7 +86,7 @@ namespace Svg
public
void
Add
(
SvgElement
item
)
{
this
.
AddAndForceUniqueID
(
item
,
false
,
fals
e
);
this
.
AddAndForceUniqueID
(
item
,
true
,
true
,
LogIDChang
e
);
}
public
void
AddAndForceUniqueID
(
SvgElement
item
,
bool
autoForceUniqueID
=
true
,
bool
autoFixChildrenID
=
true
,
Action
<
SvgElement
,
string
,
string
>
logElementOldIDNewID
=
null
)
...
...
Source/SvgElementFactory.cs
View file @
6c1198d2
...
...
@@ -134,6 +134,19 @@ namespace Svg
SetPropertyValue
(
element
,
style
[
0
].
Trim
(),
style
[
1
].
Trim
(),
document
);
}
//defaults for text can come from the document
if
(
element
.
ElementName
==
"text"
)
{
if
(!
styles
.
Contains
(
"font-size"
)
&&
document
.
CustomAttributes
.
ContainsKey
(
"font-size"
)
&&
document
.
CustomAttributes
[
"font-size"
]
!=
null
)
{
SetPropertyValue
(
element
,
"font-size"
,
document
.
CustomAttributes
[
"font-size"
],
document
);
}
if
(!
styles
.
Contains
(
"font-family"
)
&&
document
.
CustomAttributes
.
ContainsKey
(
"font-family"
)
&&
document
.
CustomAttributes
[
"font-family"
]
!=
null
)
{
SetPropertyValue
(
element
,
"font-family"
,
document
.
CustomAttributes
[
"font-family"
],
document
);
}
}
continue
;
}
...
...
@@ -176,7 +189,14 @@ namespace Svg
try
{
descriptor
.
SetValue
(
element
,
descriptor
.
Converter
.
ConvertFrom
(
document
,
CultureInfo
.
InvariantCulture
,
attributeValue
));
if
(
attributeName
==
"opacity"
&&
attributeValue
==
"undefined"
)
{
attributeValue
=
"1"
;
}
descriptor
.
SetValue
(
element
,
descriptor
.
Converter
.
ConvertFrom
(
document
,
CultureInfo
.
InvariantCulture
,
attributeValue
));
}
catch
{
...
...
Source/SvgElementIdManager.cs
View file @
6c1198d2
...
...
@@ -97,6 +97,7 @@ namespace Svg
/// Ensures that the specified ID is valid within the containing <see cref="SvgDocument"/>.
/// </summary>
/// <param name="id">A <see cref="string"/> containing the ID to validate.</param>
/// <param name="autoForceUniqueID">Creates a new unique id <see cref="string"/>.</param>
/// <exception cref="SvgException">
/// <para>The ID cannot start with a digit.</para>
/// <para>An element with the same ID already exists within the containing <see cref="SvgDocument"/>.</para>
...
...
Source/Text/SvgText.cs
View file @
6c1198d2
...
...
@@ -19,6 +19,8 @@ namespace Svg
{
private
SvgUnit
_x
;
private
SvgUnit
_y
;
private
SvgUnit
_dy
;
private
SvgUnit
_dx
;
private
SvgUnit
_letterSpacing
;
private
SvgUnit
_wordSpacing
;
private
SvgUnit
_fontSize
;
...
...
@@ -47,6 +49,8 @@ namespace Svg
{
this
.
_fontFamily
=
DefaultFontFamily
;
this
.
_fontSize
=
new
SvgUnit
(
0.0f
);
this
.
_dy
=
new
SvgUnit
(
0.0f
);
this
.
_dx
=
new
SvgUnit
(
0.0f
);
}
/// <summary>
...
...
@@ -97,6 +101,25 @@ namespace Svg
}
}
/// <summary>
/// Gets or sets the dX.
/// </summary>
/// <value>The dX.</value>
[
SvgAttribute
(
"dx"
)]
public
virtual
SvgUnit
Dx
{
get
{
return
this
.
_dx
;
}
set
{
if
(
_dx
!=
value
)
{
this
.
_dx
=
value
;
this
.
IsPathDirty
=
true
;
OnAttributeChanged
(
new
AttributeEventArgs
{
Attribute
=
"dx"
,
Value
=
value
});
}
}
}
/// <summary>
/// Gets or sets the Y.
/// </summary>
...
...
@@ -116,6 +139,25 @@ namespace Svg
}
}
/// <summary>
/// Gets or sets the dY.
/// </summary>
/// <value>The dY.</value>
[
SvgAttribute
(
"dy"
)]
public
virtual
SvgUnit
Dy
{
get
{
return
this
.
_dy
;
}
set
{
if
(
_dy
!=
value
)
{
this
.
_dy
=
value
;
this
.
IsPathDirty
=
true
;
OnAttributeChanged
(
new
AttributeEventArgs
{
Attribute
=
"dy"
,
Value
=
value
});
}
}
}
/// <summary>
/// Specifies spacing behavior between text characters.
/// </summary>
...
...
@@ -270,9 +312,11 @@ namespace Svg
get
{
// Make sure the path is always null if there is no text
//if (string.IsNullOrEmpty(this.Text))
// _path = null;
//if there is a TSpan inside of this text element then path should not be null (even if this text is empty!)
if
(
string
.
IsNullOrWhiteSpace
(
this
.
Text
)
&&
this
.
Children
.
Where
(
x
=>
x
is
SvgTextSpan
).
Select
(
x
=>
x
as
SvgTextSpan
).
Count
()
==
0
)
return
_path
=
null
;
//NOT SURE WHAT THIS IS ABOUT - Path gets created again anyway - WTF?
// When an empty string is passed to GraphicsPath, it rises an InvalidArgumentException...
if
(
_path
==
null
||
this
.
IsPathDirty
)
{
...
...
@@ -289,7 +333,7 @@ namespace Svg
_path
.
StartFigure
();
if
(!
string
.
IsNullOrEmpty
(
this
.
Text
))
DrawString
(
_path
,
this
.
X
,
this
.
Y
,
SvgUnit
.
Empty
,
SvgUnit
.
Empt
y
,
font
,
fontSize
,
this
.
Text
);
DrawString
(
_path
,
this
.
X
,
this
.
Y
,
this
.
Dx
,
this
.
D
y
,
font
,
fontSize
,
this
.
Text
);
foreach
(
var
tspan
in
this
.
Children
.
Where
(
x
=>
x
is
SvgTextSpan
).
Select
(
x
=>
x
as
SvgTextSpan
))
{
...
...
@@ -319,7 +363,7 @@ namespace Svg
private
static
string
ValidateFontFamily
(
string
fontFamilyList
)
{
// Split font family list on "," and then trim start and end spaces and quotes.
var
fontParts
=
fontFamilyList
.
Split
(
new
[]
{
','
}).
Select
(
fontName
=>
fontName
.
Trim
(
new
[]
{
'"'
,
' '
}));
var
fontParts
=
fontFamilyList
.
Split
(
new
[]
{
','
}).
Select
(
fontName
=>
fontName
.
Trim
(
new
[]
{
'"'
,
' '
,
'\''
}));
var
families
=
System
.
Drawing
.
FontFamily
.
Families
;
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment