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
41581021
Commit
41581021
authored
Apr 16, 2012
by
Tebjan Halm
Browse files
Merge remote-tracking branch 'origin/master'
parents
79c12b63
220cac7f
Changes
54
Show whitespace changes
Inline
Side-by-side
Source/SvgDocument.cs
View file @
41581021
...
...
@@ -19,13 +19,9 @@ namespace Svg
public
class
SvgDocument
:
SvgFragment
,
ITypeDescriptorContext
{
public
static
readonly
int
PPI
=
96
;
private
SvgElementIdManager
_idManager
;
/// <summary>
/// Gets a <see cref="string"/> containing the XLink namespace (http://www.w3.org/1999/xlink).
/// </summary>
public
static
readonly
string
XLinkNamespace
=
"http://www.w3.org/1999/xlink"
;
private
SvgElementIdManager
_idManager
;
/// <summary>
/// Initializes a new instance of the <see cref="SvgDocument"/> class.
...
...
@@ -340,7 +336,7 @@ namespace Svg
var
size
=
GetDimensions
();
var
bitmap
=
new
Bitmap
((
int
)
Math
.
Ceiling
(
size
.
Width
),
(
int
)
Math
.
Ceiling
(
size
.
Height
));
// bitmap.SetResolution(300, 300);
try
{
Draw
(
bitmap
);
...
...
@@ -406,5 +402,6 @@ namespace Svg
this
.
Write
(
fs
);
}
}
}
}
\ No newline at end of file
Source/SvgElement.cs
View file @
41581021
...
...
@@ -196,7 +196,7 @@ namespace Svg
[
SvgAttribute
(
"transform"
)]
public
SvgTransformCollection
Transforms
{
get
{
return
this
.
Attributes
.
GetAttribute
<
SvgTransformCollection
>(
"Transforms"
);
}
get
{
return
(
this
.
Attributes
.
GetAttribute
<
SvgTransformCollection
>(
"Transforms"
)
??
new
SvgTransformCollection
())
;
}
set
{
this
.
Attributes
[
"Transforms"
]
=
value
;
}
}
...
...
@@ -271,13 +271,20 @@ namespace Svg
/// <summary>
/// Initializes a new instance of the <see cref="SvgElement"/> class.
/// </summary>
internal
SvgElement
()
public
SvgElement
()
{
this
.
_children
=
new
SvgElementCollection
(
this
);
this
.
_eventHandlers
=
new
EventHandlerList
();
this
.
_elementName
=
string
.
Empty
;
}
public
virtual
void
InitialiseFromXML
(
XmlTextReader
reader
,
SvgDocument
document
)
{
}
/// <summary>
/// Renders this element to the <see cref="SvgRenderer"/>.
/// </summary>
...
...
@@ -299,7 +306,13 @@ namespace Svg
writer
.
WriteStartElement
(
this
.
ElementName
);
if
(
this
.
ElementName
==
"svg"
)
{
writer
.
WriteAttributeString
(
"xmlns"
,
"http://www.w3.org/2000/svg"
);
foreach
(
var
ns
in
SvgAttributeAttribute
.
Namespaces
)
{
if
(
string
.
IsNullOrEmpty
(
ns
.
Key
))
writer
.
WriteAttributeString
(
"xmlns"
,
ns
.
Value
);
else
writer
.
WriteAttributeString
(
"xmlns:"
+
ns
.
Key
,
ns
.
Value
);
}
writer
.
WriteAttributeString
(
"version"
,
"1.1"
);
}
}
...
...
@@ -339,13 +352,13 @@ namespace Svg
{
string
value
=
(
string
)
attr
.
Property
.
Converter
.
ConvertTo
(
propertyValue
,
typeof
(
string
));
writer
.
WriteAttributeString
(
attr
.
Attribute
.
Name
,
value
);
writer
.
WriteAttributeString
(
attr
.
Attribute
.
Name
spaceAndName
,
value
);
}
}
else
if
(
attr
.
Attribute
.
Name
==
"fill"
)
//if fill equals null, write 'none'
{
string
value
=
(
string
)
attr
.
Property
.
Converter
.
ConvertTo
(
propertyValue
,
typeof
(
string
));
writer
.
WriteAttributeString
(
attr
.
Attribute
.
Name
,
value
);
writer
.
WriteAttributeString
(
attr
.
Attribute
.
Name
spaceAndName
,
value
);
}
}
}
...
...
@@ -485,10 +498,39 @@ namespace Svg
{
return
this
.
MemberwiseClone
();
}
public
abstract
SvgElement
DeepCopy
();
public
virtual
SvgElement
DeepCopy
<
T
>()
where
T
:
SvgElement
,
new
()
{
var
newObj
=
new
T
();
newObj
.
Content
=
this
.
Content
;
newObj
.
ElementName
=
this
.
ElementName
;
// if (this.Parent != null)
// this.Parent.Children.Add(newObj);
if
(
this
.
Transforms
!=
null
)
{
newObj
.
Transforms
=
new
SvgTransformCollection
();
foreach
(
var
transform
in
this
.
Transforms
)
newObj
.
Transforms
.
Add
(
transform
.
Clone
()
as
SvgTransform
);
}
foreach
(
var
child
in
this
.
Children
)
{
newObj
.
Children
.
Add
(
child
.
DeepCopy
());
}
return
newObj
;
}
}
internal
interface
ISvgElement
{
SvgElement
Parent
{
get
;}
SvgElementCollection
Children
{
get
;
}
void
Render
(
SvgRenderer
renderer
);
}
}
\ No newline at end of file
Source/SvgElementCollection.cs
View file @
41581021
using
System
;
using
System.Collections.Generic
;
using
System.Linq
;
using
System.Text
;
namespace
Svg
...
...
@@ -139,6 +140,32 @@ namespace Svg
return
removed
;
}
/// <summary>
/// expensive recursive search for nodes of type T
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public
IEnumerable
<
T
>
FindSvgElementsOf
<
T
>()
where
T
:
SvgElement
{
return
_elements
.
Where
(
x
=>
x
is
T
).
Select
(
x
=>
x
as
T
).
Concat
(
_elements
.
SelectMany
(
x
=>
x
.
Children
.
FindSvgElementsOf
<
T
>()));
}
/// <summary>
/// expensive recursive search for first node of type T
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public
T
FindSvgElementOf
<
T
>()
where
T
:
SvgElement
{
return
_elements
.
OfType
<
T
>().
FirstOrDefault
()
??
_elements
.
Select
(
x
=>
x
.
Children
.
FindSvgElementOf
<
T
>()).
FirstOrDefault
<
T
>(
x
=>
x
!=
null
);
}
public
T
GetSvgElementOf
<
T
>()
where
T
:
SvgElement
{
return
_elements
.
FirstOrDefault
(
x
=>
x
is
T
)
as
T
;
}
public
IEnumerator
<
SvgElement
>
GetEnumerator
()
{
return
this
.
_elements
.
GetEnumerator
();
...
...
Source/SvgElementFactory.cs
View file @
41581021
...
...
@@ -100,7 +100,6 @@ namespace Svg
if
(
createdElement
!=
null
)
{
createdElement
.
ElementName
=
elementName
;
SetAttributes
(
createdElement
,
reader
,
document
);
}
...
...
Source/Text/SvgText.cs
View file @
41581021
...
...
@@ -5,6 +5,8 @@ using System.ComponentModel;
using
System.Drawing
;
using
System.Drawing.Drawing2D
;
using
System.Drawing.Text
;
using
Svg.DataTypes
;
using
System.Linq
;
namespace
Svg
{
...
...
@@ -19,12 +21,12 @@ namespace Svg
private
SvgUnit
_letterSpacing
;
private
SvgUnit
_wordSpacing
;
private
SvgUnit
_fontSize
;
private
SvgFontWeight
_fontWeight
;
private
string
_font
;
private
string
_fontFamily
;
private
GraphicsPath
_path
;
private
SvgTextAnchor
_textAnchor
=
SvgTextAnchor
.
Start
;
private
static
readonly
SvgRenderer
_stringMeasure
;
/// <summary>
/// Initializes the <see cref="SvgText"/> class.
/// </summary>
...
...
@@ -135,6 +137,18 @@ namespace Svg
set
{
this
.
_fontSize
=
value
;
this
.
IsPathDirty
=
true
;
}
}
/// <summary>
/// Refers to the boldness of the font.
/// </summary>
[
SvgAttribute
(
"font-weight"
)]
public
virtual
SvgFontWeight
FontWeight
{
get
{
return
this
.
_fontWeight
;
}
set
{
this
.
_fontWeight
=
value
;
this
.
IsPathDirty
=
true
;
}
}
/// <summary>
/// Set all font information.
/// </summary>
...
...
@@ -205,7 +219,11 @@ namespace Svg
get
{
// Make sure the path is always null if there is no text
if
(
_path
==
null
||
this
.
IsPathDirty
&&
!
string
.
IsNullOrEmpty
(
this
.
Text
))
//if (string.IsNullOrEmpty(this.Text))
// _path = null;
//NOT SURE WHAT THIS IS ABOUT - Path gets created again anyway - WTF?
if
(
_path
==
null
||
this
.
IsPathDirty
)
{
float
fontSize
=
this
.
FontSize
.
ToDeviceValue
(
this
);
if
(
fontSize
==
0.0f
)
...
...
@@ -213,32 +231,64 @@ namespace Svg
fontSize
=
1.0f
;
}
FontStyle
fontWeight
=
(
this
.
FontWeight
==
SvgFontWeight
.
bold
?
FontStyle
.
Bold
:
FontStyle
.
Regular
);
Font
font
=
new
Font
(
this
.
_fontFamily
,
fontSize
,
fontWeight
,
GraphicsUnit
.
Pixel
);
_path
=
new
GraphicsPath
();
_path
.
StartFigure
();
if
(!
string
.
IsNullOrEmpty
(
this
.
Text
))
DrawString
(
_path
,
this
.
X
,
this
.
Y
,
SvgUnit
.
Empty
,
SvgUnit
.
Empty
,
font
,
fontSize
,
this
.
Text
);
foreach
(
var
tspan
in
this
.
Children
.
Where
(
x
=>
x
is
SvgTextSpan
).
Select
(
x
=>
x
as
SvgTextSpan
))
{
if
(!
string
.
IsNullOrEmpty
(
tspan
.
Text
))
DrawString
(
_path
,
tspan
.
X
==
SvgUnit
.
Empty
?
this
.
X
:
tspan
.
X
,
tspan
.
Y
==
SvgUnit
.
Empty
?
this
.
Y
:
tspan
.
Y
,
tspan
.
DX
,
tspan
.
DY
,
font
,
fontSize
,
tspan
.
Text
);
}
_path
.
CloseFigure
();
this
.
IsPathDirty
=
false
;
}
return
_path
;
}
}
private
void
DrawString
(
GraphicsPath
path
,
SvgUnit
x
,
SvgUnit
y
,
SvgUnit
dx
,
SvgUnit
dy
,
Font
font
,
float
fontSize
,
string
text
)
{
PointF
location
=
PointF
.
Empty
;
Font
font
=
new
Font
(
this
.
_fontFamily
,
fontSize
,
FontStyle
.
Regular
,
GraphicsUnit
.
Pixel
);
SizeF
stringBounds
=
_stringMeasure
.
MeasureString
(
this
.
Text
,
font
);
SizeF
stringBounds
=
_stringMeasure
.
MeasureString
(
text
,
font
);
float
xToDevice
=
x
.
ToDeviceValue
(
this
)
+
dx
.
ToDeviceValue
(
this
);
float
yToDevice
=
y
.
ToDeviceValue
(
this
,
true
)
+
dy
.
ToDeviceValue
(
this
,
true
);
// Minus FontSize because the x/y coords mark the bottom left, not bottom top.
switch
(
this
.
TextAnchor
)
{
case
SvgTextAnchor
.
Start
:
location
=
new
PointF
(
this
.
X
.
ToDevice
Value
(
this
),
this
.
Y
.
ToDeviceValue
(
this
,
true
)
-
stringBounds
.
Height
);
location
=
new
PointF
(
x
ToDevice
,
yToDevice
-
stringBounds
.
Height
);
break
;
case
SvgTextAnchor
.
Middle
:
location
=
new
PointF
(
this
.
X
.
ToDevice
Value
(
this
)
-
(
stringBounds
.
Width
/
2
),
this
.
Y
.
ToDevice
Value
(
this
,
true
)
-
stringBounds
.
Height
);
location
=
new
PointF
(
x
ToDevice
-
(
stringBounds
.
Width
/
2
),
y
ToDevice
-
stringBounds
.
Height
);
break
;
case
SvgTextAnchor
.
End
:
location
=
new
PointF
(
this
.
X
.
ToDevice
Value
(
this
)
-
stringBounds
.
Width
,
this
.
Y
.
ToDevice
Value
(
this
,
true
)
-
stringBounds
.
Height
);
location
=
new
PointF
(
x
ToDevice
-
stringBounds
.
Width
,
y
ToDevice
-
stringBounds
.
Height
);
break
;
}
_path
=
new
GraphicsPath
();
_path
.
StartFigure
();
// No way to do letter-spacing or word-spacing, so do manually
if
(
this
.
LetterSpacing
.
Value
>
0.0f
||
this
.
WordSpacing
.
Value
>
0.0f
)
{
// Cut up into words, or just leave as required
string
[]
words
=
(
this
.
WordSpacing
.
Value
>
0.0f
)
?
t
his
.
T
ext
.
Split
(
' '
)
:
new
string
[]
{
t
his
.
T
ext
};
string
[]
words
=
(
this
.
WordSpacing
.
Value
>
0.0f
)
?
text
.
Split
(
' '
)
:
new
string
[]
{
text
};
float
wordSpacing
=
this
.
WordSpacing
.
ToDeviceValue
(
this
);
float
letterSpacing
=
this
.
LetterSpacing
.
ToDeviceValue
(
this
);
float
start
=
this
.
X
.
ToDeviceValue
(
this
);
...
...
@@ -251,32 +301,48 @@ namespace Svg
char
[]
characters
=
word
.
ToCharArray
();
foreach
(
char
currentCharacter
in
characters
)
{
_
path
.
AddString
(
currentCharacter
.
ToString
(),
new
FontFamily
(
this
.
_fontFamily
),
0
,
fontSize
,
location
,
StringFormat
.
GenericTypographic
);
location
=
new
PointF
(
_
path
.
GetBounds
().
Width
+
start
+
letterSpacing
,
location
.
Y
);
path
.
AddString
(
currentCharacter
.
ToString
(),
new
FontFamily
(
this
.
_fontFamily
),
(
int
)
font
.
Style
,
fontSize
,
location
,
StringFormat
.
GenericTypographic
);
location
=
new
PointF
(
path
.
GetBounds
().
Width
+
start
+
letterSpacing
,
location
.
Y
);
}
}
else
{
_
path
.
AddString
(
word
,
new
FontFamily
(
this
.
_fontFamily
),
0
,
fontSize
,
location
,
StringFormat
.
GenericTypographic
);
path
.
AddString
(
word
,
new
FontFamily
(
this
.
_fontFamily
),
(
int
)
font
.
Style
,
fontSize
,
location
,
StringFormat
.
GenericTypographic
);
}
// Move the location of the word to be written along
location
=
new
PointF
(
_
path
.
GetBounds
().
Width
+
start
+
wordSpacing
,
location
.
Y
);
location
=
new
PointF
(
path
.
GetBounds
().
Width
+
start
+
wordSpacing
,
location
.
Y
);
}
}
else
{
if
(!
string
.
IsNullOrEmpty
(
t
his
.
T
ext
))
if
(!
string
.
IsNullOrEmpty
(
text
))
{
_
path
.
AddString
(
t
his
.
T
ext
,
new
FontFamily
(
this
.
_fontFamily
),
0
,
fontSize
,
location
,
StringFormat
.
GenericTypographic
);
path
.
AddString
(
text
,
new
FontFamily
(
this
.
_fontFamily
),
(
int
)
font
.
Style
,
fontSize
,
location
,
StringFormat
.
GenericTypographic
);
}
}
_path
.
CloseFigure
();
this
.
IsPathDirty
=
false
;
}
return
_path
;
public
override
SvgElement
DeepCopy
()
{
return
DeepCopy
<
SvgText
>();
}
public
override
SvgElement
DeepCopy
<
T
>()
{
var
newObj
=
base
.
DeepCopy
<
T
>()
as
SvgText
;
newObj
.
TextAnchor
=
this
.
TextAnchor
;
newObj
.
WordSpacing
=
this
.
WordSpacing
;
newObj
.
LetterSpacing
=
this
.
LetterSpacing
;
newObj
.
Font
=
this
.
Font
;
newObj
.
FontFamily
=
this
.
FontFamily
;
newObj
.
FontSize
=
this
.
FontSize
;
newObj
.
FontWeight
=
this
.
FontWeight
;
newObj
.
X
=
this
.
X
;
newObj
.
Y
=
this
.
Y
;
return
newObj
;
}
}
}
\ No newline at end of file
Source/Text/SvgTextSpan.cs
View file @
41581021
using
System
;
using
System.ComponentModel
;
using
System.Collections.Generic
;
using
System.Drawing.Drawing2D
;
using
System.Linq
;
using
System.Text
;
namespace
Svg
{
[
SvgElement
(
"tspan"
)]
public
class
SvgTextSpan
:
Svg
Tex
t
public
class
SvgTextSpan
:
Svg
Elemen
t
{
private
SvgUnit
_x
;
private
SvgUnit
_y
;
private
SvgUnit
_dx
;
private
SvgUnit
_dy
;
/// <summary>
/// Gets or sets the X.
/// </summary>
/// <value>The X.</value>
[
SvgAttribute
(
"x"
)]
public
SvgUnit
X
{
get
{
return
this
.
_x
;
}
set
{
this
.
_x
=
value
;
}
}
/// <summary>
/// Gets or sets the X.
/// </summary>
/// <value>The X.</value>
[
Browsable
(
false
),
DesignerSerializationVisibility
(
DesignerSerializationVisibility
.
Hidden
)]
public
override
SvgUnit
X
[
SvgAttribute
(
"y"
)]
public
SvgUnit
Y
{
get
{
return
base
.
X
;
}
set
{
base
.
X
=
value
;
}
get
{
return
this
.
_y
;
}
set
{
this
.
_y
=
value
;
}
}
/// <summary>
/// Gets or sets the deltaX from the containing text.
/// </summary>
/// <value>The dX.</value>
[
SvgAttribute
(
"dx"
)]
public
SvgUnit
DX
{
get
{
return
this
.
_dx
;
}
set
{
this
.
_dx
=
value
;
}
}
/// <summary>
/// Gets or sets the
Y
.
/// Gets or sets the
deltaY from the containing text
.
/// </summary>
/// <value>The Y.</value>
[
Browsable
(
false
),
DesignerSerializationVisibility
(
DesignerSerializationVisibility
.
Hidden
)]
public
override
SvgUnit
Y
/// <value>The
d
Y.</value>
[
SvgAttribute
(
"dy"
)]
public
SvgUnit
D
Y
{
get
{
return
base
.
Y
;
}
set
{
base
.
Y
=
value
;
}
get
{
return
this
.
_dy
;
}
set
{
this
.
_dy
=
value
;
}
}
/// <summary>
/// Gets or sets the text to be rendered.
/// </summary>
public
virtual
string
Text
{
get
{
return
base
.
Content
;
}
set
{
base
.
Content
=
value
;
this
.
Content
=
value
;
}
}
public
override
SvgElement
DeepCopy
()
{
return
DeepCopy
<
SvgTextSpan
>();
}
public
override
SvgElement
DeepCopy
<
T
>()
{
var
newObj
=
base
.
DeepCopy
<
T
>()
as
SvgTextSpan
;
newObj
.
X
=
this
.
X
;
newObj
.
Y
=
this
.
Y
;
newObj
.
DX
=
this
.
DX
;
newObj
.
DY
=
this
.
DY
;
newObj
.
Text
=
this
.
Text
;
return
newObj
;
}
}
}
\ No newline at end of file
Source/Transforms/SvgMatrix.cs
View file @
41581021
...
...
@@ -45,5 +45,12 @@ namespace Svg.Transforms
{
this
.
points
=
m
;
}
public
override
object
Clone
()
{
return
new
SvgMatrix
(
this
.
Points
);
}
}
}
\ No newline at end of file
Source/Transforms/SvgRotate.cs
View file @
41581021
...
...
@@ -54,5 +54,11 @@ namespace Svg.Transforms
this
.
CenterX
=
centerX
;
this
.
CenterY
=
centerY
;
}
public
override
object
Clone
()
{
return
new
SvgRotate
(
this
.
Angle
,
this
.
CenterX
,
this
.
CenterY
);
}
}
}
\ No newline at end of file
Source/Transforms/SvgScale.cs
View file @
41581021
...
...
@@ -45,5 +45,11 @@ namespace Svg.Transforms
this
.
scaleFactorX
=
x
;
this
.
scaleFactorY
=
y
;
}
public
override
object
Clone
()
{
return
new
SvgScale
(
this
.
X
,
this
.
Y
);
}
}
}
Source/Transforms/SvgShear.cs
View file @
41581021
...
...
@@ -48,5 +48,11 @@ namespace Svg.Transforms
this
.
shearFactorX
=
x
;
this
.
shearFactorY
=
y
;
}
public
override
object
Clone
()
{
return
new
SvgShear
(
this
.
X
,
this
.
Y
);
}
}
}
\ No newline at end of file
Source/Transforms/SvgSkew.cs
View file @
41581021
...
...
@@ -35,5 +35,11 @@ namespace Svg.Transforms
AngleX
=
x
;
AngleY
=
y
;
}
public
override
object
Clone
()
{
return
new
SvgSkew
(
this
.
AngleX
,
this
.
AngleY
);
}
}
}
\ No newline at end of file
Source/Transforms/SvgTransform.cs
View file @
41581021
...
...
@@ -6,9 +6,11 @@ using System.Drawing.Drawing2D;
namespace
Svg.Transforms
{
public
abstract
class
SvgTransform
public
abstract
class
SvgTransform
:
ICloneable
{
public
abstract
Matrix
Matrix
{
get
;
}
public
abstract
string
WriteToString
();
public
abstract
object
Clone
();
}
}
\ No newline at end of file
Source/Transforms/SvgTransformCollection.cs
View file @
41581021
...
...
@@ -32,5 +32,13 @@ namespace Svg.Transforms
return
transformMatrix
;
}
public
override
bool
Equals
(
object
obj
)
{
if
(
this
.
Count
==
0
&&
this
.
Count
==
this
.
Count
)
//default will be an empty list
return
true
;
return
base
.
Equals
(
obj
);
}
}
}
Source/Transforms/SvgTranslate.cs
View file @
41581021
...
...
@@ -47,5 +47,12 @@ namespace Svg.Transforms
:
this
(
x
,
0.0f
)
{
}
public
override
object
Clone
()
{
return
new
SvgTranslate
(
this
.
x
,
this
.
y
);
}
}
}
\ No newline at end of file
Prev
1
2
3
Next
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