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
1585c700
Commit
1585c700
authored
Sep 23, 2014
by
Ritch Melton
Browse files
merged
parents
cc4f2940
1818255b
Changes
107
Hide whitespace changes
Inline
Side-by-side
Samples/SVGViewer/DebugRenderer.cs
0 → 100644
View file @
1585c700
using
System
;
using
System.Collections.Generic
;
using
System.Linq
;
using
System.Text
;
using
Svg
;
using
System.Drawing.Drawing2D
;
using
System.Drawing
;
namespace
SVGViewer
{
class
DebugRenderer
:
ISvgRenderer
{
private
Region
_clip
=
new
Region
();
private
Matrix
_transform
=
new
Matrix
();
private
Stack
<
ISvgBoundable
>
_boundables
=
new
Stack
<
ISvgBoundable
>();
public
void
SetBoundable
(
ISvgBoundable
boundable
)
{
_boundables
.
Push
(
boundable
);
}
public
ISvgBoundable
GetBoundable
()
{
return
_boundables
.
Peek
();
}
public
ISvgBoundable
PopBoundable
()
{
return
_boundables
.
Pop
();
}
public
float
DpiY
{
get
{
return
96
;
}
}
public
void
DrawImage
(
Image
image
,
RectangleF
destRect
,
RectangleF
srcRect
,
GraphicsUnit
graphicsUnit
)
{
}
public
void
DrawImageUnscaled
(
Image
image
,
Point
location
)
{
}
public
void
DrawPath
(
Pen
pen
,
GraphicsPath
path
)
{
var
newPath
=
(
GraphicsPath
)
path
.
Clone
();
newPath
.
Transform
(
_transform
);
}
public
void
FillPath
(
Brush
brush
,
GraphicsPath
path
)
{
var
newPath
=
(
GraphicsPath
)
path
.
Clone
();
newPath
.
Transform
(
_transform
);
}
public
Region
GetClip
()
{
return
_clip
;
}
public
void
RotateTransform
(
float
fAngle
,
MatrixOrder
order
=
MatrixOrder
.
Append
)
{
_transform
.
Rotate
(
fAngle
,
order
);
}
public
void
ScaleTransform
(
float
sx
,
float
sy
,
MatrixOrder
order
=
MatrixOrder
.
Append
)
{
_transform
.
Scale
(
sx
,
sy
,
order
);
}
public
void
SetClip
(
Region
region
,
CombineMode
combineMode
=
CombineMode
.
Replace
)
{
switch
(
combineMode
)
{
case
CombineMode
.
Intersect
:
_clip
.
Intersect
(
region
);
break
;
case
CombineMode
.
Complement
:
_clip
.
Complement
(
region
);
break
;
case
CombineMode
.
Exclude
:
_clip
.
Exclude
(
region
);
break
;
case
CombineMode
.
Union
:
_clip
.
Union
(
region
);
break
;
case
CombineMode
.
Xor
:
_clip
.
Xor
(
region
);
break
;
default
:
_clip
=
region
;
break
;
}
}
public
void
TranslateTransform
(
float
dx
,
float
dy
,
MatrixOrder
order
=
MatrixOrder
.
Append
)
{
_transform
.
Translate
(
dx
,
dy
,
order
);
}
public
SmoothingMode
SmoothingMode
{
get
{
return
SmoothingMode
.
Default
;
}
set
{
/* Do Nothing */
}
}
public
Matrix
Transform
{
get
{
return
_transform
;
}
set
{
_transform
=
value
;
}
}
public
void
Dispose
()
{
}
}
}
Samples/SVGViewer/SVGViewer.csproj
View file @
1585c700
...
...
@@ -93,6 +93,7 @@
<Reference
Include=
"System.Xml"
/>
</ItemGroup>
<ItemGroup>
<Compile
Include=
"DebugRenderer.cs"
/>
<Compile
Include=
"SvgViewer.cs"
>
<SubType>
Form
</SubType>
</Compile>
...
...
Samples/SVGViewer/SvgViewer.cs
View file @
1585c700
...
...
@@ -43,7 +43,10 @@ namespace SVGViewer
private
void
RenderSvg
(
SvgDocument
svgDoc
)
{
//var render = new DebugRenderer();
//svgDoc.Draw(render);
svgImage
.
Image
=
svgDoc
.
Draw
();
svgImage
.
Image
.
Save
(
System
.
IO
.
Path
.
Combine
(
System
.
IO
.
Path
.
GetDirectoryName
(
svgDoc
.
BaseUri
.
LocalPath
),
"output.png"
));
}
}
}
Source/Basic Shapes/SvgCircle.cs
View file @
1585c700
...
...
@@ -98,7 +98,7 @@ namespace Svg
/// <summary>
/// Gets the <see cref="GraphicsPath"/> representing this element.
/// </summary>
public
override
GraphicsPath
Path
(
SvgRenderer
renderer
)
public
override
GraphicsPath
Path
(
I
SvgRenderer
renderer
)
{
if
(
this
.
_path
==
null
||
this
.
IsPathDirty
)
{
...
...
@@ -117,7 +117,7 @@ namespace Svg
/// Renders the circle to the specified <see cref="Graphics"/> object.
/// </summary>
/// <param name="graphics">The graphics object.</param>
protected
override
void
Render
(
SvgRenderer
renderer
)
protected
override
void
Render
(
I
SvgRenderer
renderer
)
{
// Don't draw if there is no radius set
if
(
this
.
Radius
.
Value
>
0.0f
)
...
...
Source/Basic Shapes/SvgEllipse.cs
View file @
1585c700
...
...
@@ -102,7 +102,7 @@ namespace Svg
/// Gets the <see cref="GraphicsPath"/> for this element.
/// </summary>
/// <value></value>
public
override
GraphicsPath
Path
(
SvgRenderer
renderer
)
public
override
GraphicsPath
Path
(
I
SvgRenderer
renderer
)
{
if
(
this
.
_path
==
null
||
this
.
IsPathDirty
)
{
...
...
@@ -122,7 +122,7 @@ namespace Svg
/// Renders the <see cref="SvgElement"/> and contents to the specified <see cref="Graphics"/> object.
/// </summary>
/// <param name="graphics">The <see cref="Graphics"/> object to render to.</param>
protected
override
void
Render
(
SvgRenderer
renderer
)
protected
override
void
Render
(
I
SvgRenderer
renderer
)
{
if
(
this
.
_radiusX
.
Value
>
0.0f
&&
this
.
_radiusY
.
Value
>
0.0f
)
{
...
...
Source/Basic Shapes/SvgImage.cs
View file @
1585c700
...
...
@@ -94,7 +94,7 @@ namespace Svg
/// <summary>
/// Gets the <see cref="GraphicsPath"/> for this element.
/// </summary>
public
override
GraphicsPath
Path
(
SvgRenderer
renderer
)
public
override
GraphicsPath
Path
(
I
SvgRenderer
renderer
)
{
return
null
;
}
...
...
@@ -102,95 +102,123 @@ namespace Svg
/// <summary>
/// Renders the <see cref="SvgElement"/> and contents to the specified <see cref="Graphics"/> object.
/// </summary>
protected
override
void
Render
(
SvgRenderer
renderer
)
protected
override
void
Render
(
I
SvgRenderer
renderer
)
{
if
(!
Visible
||
!
Displayable
)
return
;
if
(
Width
.
Value
>
0.0f
&&
Height
.
Value
>
0.0f
&&
this
.
Href
!=
null
)
{
using
(
Image
b
=
GetImage
(
this
.
Href
))
var
img
=
GetImage
(
this
.
Href
);
if
(
img
!=
null
)
{
if
(
b
!=
null
)
RectangleF
srcRect
;
var
bmp
=
img
as
Image
;
var
svg
=
img
as
SvgFragment
;
if
(
bmp
!=
null
)
{
var
srcRect
=
new
RectangleF
(
0
,
0
,
b
.
Width
,
b
.
Height
);
var
destClip
=
new
RectangleF
(
this
.
Location
.
ToDeviceValue
(
renderer
,
this
),
new
SizeF
(
Width
.
ToDeviceValue
(
renderer
,
UnitRenderingType
.
Horizontal
,
this
),
Height
.
ToDeviceValue
(
renderer
,
UnitRenderingType
.
Vertical
,
this
)));
RectangleF
destRect
=
destClip
;
this
.
PushTransforms
(
renderer
);
renderer
.
AddClip
(
new
Region
(
destClip
));
this
.
SetClip
(
renderer
);
srcRect
=
new
RectangleF
(
0
,
0
,
bmp
.
Width
,
bmp
.
Height
);
}
else
if
(
svg
!=
null
)
{
srcRect
=
new
RectangleF
(
new
PointF
(
0
,
0
),
svg
.
GetDimensions
());
}
else
{
return
;
}
if
(
AspectRatio
!=
null
&&
AspectRatio
.
Align
!=
SvgPreserveAspectRatio
.
none
)
{
var
fScaleX
=
destClip
.
Width
/
srcRect
.
Width
;
var
fScaleY
=
destClip
.
Height
/
srcRect
.
Height
;
var
xOffset
=
0.0f
;
var
yOffset
=
0.0f
;
var
destClip
=
new
RectangleF
(
this
.
Location
.
ToDeviceValue
(
renderer
,
this
),
new
SizeF
(
Width
.
ToDeviceValue
(
renderer
,
UnitRenderingType
.
Horizontal
,
this
),
Height
.
ToDeviceValue
(
renderer
,
UnitRenderingType
.
Vertical
,
this
)));
RectangleF
destRect
=
destClip
;
this
.
PushTransforms
(
renderer
);
renderer
.
SetClip
(
new
Region
(
destClip
),
CombineMode
.
Intersect
);
this
.
SetClip
(
renderer
);
if
(
AspectRatio
.
Slice
)
{
fScaleX
=
Math
.
Max
(
fScaleX
,
fScaleY
);
fScaleY
=
Math
.
Max
(
fScaleX
,
fScaleY
);
}
else
{
fScaleX
=
Math
.
Min
(
fScaleX
,
fScaleY
);
fScaleY
=
Math
.
Min
(
fScaleX
,
fScaleY
);
}
if
(
AspectRatio
!=
null
&&
AspectRatio
.
Align
!=
SvgPreserveAspectRatio
.
none
)
{
var
fScaleX
=
destClip
.
Width
/
srcRect
.
Width
;
var
fScaleY
=
destClip
.
Height
/
srcRect
.
Height
;
var
xOffset
=
0.0f
;
var
yOffset
=
0.0f
;
switch
(
AspectRatio
.
Align
)
{
case
SvgPreserveAspectRatio
.
xMinYMin
:
break
;
case
SvgPreserveAspectRatio
.
xMidYMin
:
xOffset
=
(
destClip
.
Width
-
srcRect
.
Width
*
fScaleX
)
/
2
;
break
;
case
SvgPreserveAspectRatio
.
xMaxYMin
:
xOffset
=
(
destClip
.
Width
-
srcRect
.
Width
*
fScaleX
);
break
;
case
SvgPreserveAspectRatio
.
xMinYMid
:
yOffset
=
(
destClip
.
Height
-
srcRect
.
Height
*
fScaleY
)
/
2
;
break
;
case
SvgPreserveAspectRatio
.
xMidYMid
:
xOffset
=
(
destClip
.
Width
-
srcRect
.
Width
*
fScaleX
)
/
2
;
yOffset
=
(
destClip
.
Height
-
srcRect
.
Height
*
fScaleY
)
/
2
;
break
;
case
SvgPreserveAspectRatio
.
xMaxYMid
:
xOffset
=
(
destClip
.
Width
-
srcRect
.
Width
*
fScaleX
);
yOffset
=
(
destClip
.
Height
-
srcRect
.
Height
*
fScaleY
)
/
2
;
break
;
case
SvgPreserveAspectRatio
.
xMinYMax
:
yOffset
=
(
destClip
.
Height
-
srcRect
.
Height
*
fScaleY
);
break
;
case
SvgPreserveAspectRatio
.
xMidYMax
:
xOffset
=
(
destClip
.
Width
-
srcRect
.
Width
*
fScaleX
)
/
2
;
yOffset
=
(
destClip
.
Height
-
srcRect
.
Height
*
fScaleY
);
break
;
case
SvgPreserveAspectRatio
.
xMaxYMax
:
xOffset
=
(
destClip
.
Width
-
srcRect
.
Width
*
fScaleX
);
yOffset
=
(
destClip
.
Height
-
srcRect
.
Height
*
fScaleY
);
break
;
}
if
(
AspectRatio
.
Slice
)
{
fScaleX
=
Math
.
Max
(
fScaleX
,
fScaleY
);
fScaleY
=
Math
.
Max
(
fScaleX
,
fScaleY
);
}
else
{
fScaleX
=
Math
.
Min
(
fScaleX
,
fScaleY
);
fScaleY
=
Math
.
Min
(
fScaleX
,
fScaleY
);
}
destRect
=
new
RectangleF
(
destClip
.
X
+
xOffset
,
destClip
.
Y
+
yOffset
,
srcRect
.
Width
*
fScaleX
,
srcRect
.
Height
*
fScaleY
);
switch
(
AspectRatio
.
Align
)
{
case
SvgPreserveAspectRatio
.
xMinYMin
:
break
;
case
SvgPreserveAspectRatio
.
xMidYMin
:
xOffset
=
(
destClip
.
Width
-
srcRect
.
Width
*
fScaleX
)
/
2
;
break
;
case
SvgPreserveAspectRatio
.
xMaxYMin
:
xOffset
=
(
destClip
.
Width
-
srcRect
.
Width
*
fScaleX
);
break
;
case
SvgPreserveAspectRatio
.
xMinYMid
:
yOffset
=
(
destClip
.
Height
-
srcRect
.
Height
*
fScaleY
)
/
2
;
break
;
case
SvgPreserveAspectRatio
.
xMidYMid
:
xOffset
=
(
destClip
.
Width
-
srcRect
.
Width
*
fScaleX
)
/
2
;
yOffset
=
(
destClip
.
Height
-
srcRect
.
Height
*
fScaleY
)
/
2
;
break
;
case
SvgPreserveAspectRatio
.
xMaxYMid
:
xOffset
=
(
destClip
.
Width
-
srcRect
.
Width
*
fScaleX
);
yOffset
=
(
destClip
.
Height
-
srcRect
.
Height
*
fScaleY
)
/
2
;
break
;
case
SvgPreserveAspectRatio
.
xMinYMax
:
yOffset
=
(
destClip
.
Height
-
srcRect
.
Height
*
fScaleY
);
break
;
case
SvgPreserveAspectRatio
.
xMidYMax
:
xOffset
=
(
destClip
.
Width
-
srcRect
.
Width
*
fScaleX
)
/
2
;
yOffset
=
(
destClip
.
Height
-
srcRect
.
Height
*
fScaleY
);
break
;
case
SvgPreserveAspectRatio
.
xMaxYMax
:
xOffset
=
(
destClip
.
Width
-
srcRect
.
Width
*
fScaleX
);
yOffset
=
(
destClip
.
Height
-
srcRect
.
Height
*
fScaleY
);
break
;
}
renderer
.
DrawImage
(
b
,
destRect
,
srcRect
,
GraphicsUnit
.
Pixel
);
this
.
ResetClip
(
renderer
);
this
.
PopTransforms
(
renderer
);
destRect
=
new
RectangleF
(
destClip
.
X
+
xOffset
,
destClip
.
Y
+
yOffset
,
srcRect
.
Width
*
fScaleX
,
srcRect
.
Height
*
fScaleY
);
}
if
(
bmp
!=
null
)
{
renderer
.
DrawImage
(
bmp
,
destRect
,
srcRect
,
GraphicsUnit
.
Pixel
);
bmp
.
Dispose
();
}
else
if
(
svg
!=
null
)
{
var
currOffset
=
new
PointF
(
renderer
.
Transform
.
OffsetX
,
renderer
.
Transform
.
OffsetY
);
renderer
.
TranslateTransform
(-
currOffset
.
X
,
-
currOffset
.
Y
);
renderer
.
ScaleTransform
(
destRect
.
Width
/
srcRect
.
Width
,
destRect
.
Height
/
srcRect
.
Height
);
renderer
.
TranslateTransform
(
currOffset
.
X
+
destRect
.
X
,
currOffset
.
Y
+
destRect
.
Y
);
renderer
.
SetBoundable
(
new
GenericBoundable
(
srcRect
));
svg
.
RenderElement
(
renderer
);
renderer
.
PopBoundable
();
}
this
.
ResetClip
(
renderer
);
this
.
PopTransforms
(
renderer
);
}
// TODO: cache images... will need a shared context for this
// TODO: support preserveAspectRatio, etc
}
}
protected
Image
GetImage
(
Uri
uri
)
protected
object
GetImage
(
Uri
uri
)
{
try
{
...
...
@@ -205,8 +233,10 @@ namespace Svg
// we're assuming base64, as ascii encoding would be *highly* unsusual for images
// also assuming it's png or jpeg mimetype
byte
[]
imageBytes
=
Convert
.
FromBase64String
(
uriString
.
Substring
(
dataIdx
));
Image
image
=
Image
.
FromStream
(
new
MemoryStream
(
imageBytes
));
return
image
;
using
(
var
stream
=
new
MemoryStream
(
imageBytes
))
{
return
Image
.
FromStream
(
stream
);
}
}
if
(!
uri
.
IsAbsoluteUri
)
...
...
@@ -219,15 +249,19 @@ namespace Svg
using
(
WebResponse
webResponse
=
httpRequest
.
GetResponse
())
{
MemoryStream
ms
=
BufferToMemoryStream
(
webResponse
.
GetResponseStream
());
if
(
uri
.
LocalPath
.
EndsWith
(
".svg"
,
StringComparison
.
InvariantCultureIgnoreCase
))
using
(
var
stream
=
webResponse
.
GetResponseStream
())
{
var
doc
=
SvgDocument
.
Open
<
SvgDocument
>(
ms
);
return
doc
.
Draw
();
}
else
{
return
Bitmap
.
FromStream
(
ms
);
stream
.
Position
=
0
;
if
(
uri
.
LocalPath
.
EndsWith
(
".svg"
,
StringComparison
.
InvariantCultureIgnoreCase
))
{
var
doc
=
SvgDocument
.
Open
<
SvgDocument
>(
stream
);
doc
.
BaseUri
=
uri
;
return
doc
;
}
else
{
return
Bitmap
.
FromStream
(
stream
);
}
}
}
}
...
...
Source/Basic Shapes/SvgLine.cs
View file @
1585c700
...
...
@@ -79,6 +79,38 @@ namespace Svg
}
}
/// <summary>
/// Gets or sets the marker (end cap) of the path.
/// </summary>
[
SvgAttribute
(
"marker-end"
)]
public
Uri
MarkerEnd
{
get
{
return
this
.
Attributes
.
GetAttribute
<
Uri
>(
"marker-end"
);
}
set
{
this
.
Attributes
[
"marker-end"
]
=
value
;
}
}
/// <summary>
/// Gets or sets the marker (start cap) of the path.
/// </summary>
[
SvgAttribute
(
"marker-mid"
)]
public
Uri
MarkerMid
{
get
{
return
this
.
Attributes
.
GetAttribute
<
Uri
>(
"marker-mid"
);
}
set
{
this
.
Attributes
[
"marker-mid"
]
=
value
;
}
}
/// <summary>
/// Gets or sets the marker (start cap) of the path.
/// </summary>
[
SvgAttribute
(
"marker-start"
)]
public
Uri
MarkerStart
{
get
{
return
this
.
Attributes
.
GetAttribute
<
Uri
>(
"marker-start"
);
}
set
{
this
.
Attributes
[
"marker-start"
]
=
value
;
}
}
public
override
SvgPaintServer
Fill
{
get
{
return
null
;
/* Line can't have a fill */
}
...
...
@@ -92,7 +124,7 @@ namespace Svg
{
}
public
override
System
.
Drawing
.
Drawing2D
.
GraphicsPath
Path
(
SvgRenderer
renderer
)
public
override
System
.
Drawing
.
Drawing2D
.
GraphicsPath
Path
(
I
SvgRenderer
renderer
)
{
if
(
this
.
_path
==
null
||
this
.
IsPathDirty
)
{
...
...
@@ -108,6 +140,37 @@ namespace Svg
return
this
.
_path
;
}
/// <summary>
/// Renders the stroke of the <see cref="SvgVisualElement"/> to the specified <see cref="ISvgRenderer"/>
/// </summary>
/// <param name="renderer">The <see cref="ISvgRenderer"/> object to render to.</param>
protected
internal
override
bool
RenderStroke
(
ISvgRenderer
renderer
)
{
var
result
=
base
.
RenderStroke
(
renderer
);
var
path
=
this
.
Path
(
renderer
);
if
(
this
.
MarkerStart
!=
null
)
{
SvgMarker
marker
=
this
.
OwnerDocument
.
GetElementById
<
SvgMarker
>(
this
.
MarkerStart
.
ToString
());
marker
.
RenderMarker
(
renderer
,
this
,
path
.
PathPoints
[
0
],
path
.
PathPoints
[
0
],
path
.
PathPoints
[
1
]);
}
if
(
this
.
MarkerMid
!=
null
)
{
SvgMarker
marker
=
this
.
OwnerDocument
.
GetElementById
<
SvgMarker
>(
this
.
MarkerMid
.
ToString
());
for
(
int
i
=
1
;
i
<=
path
.
PathPoints
.
Length
-
2
;
i
++)
marker
.
RenderMarker
(
renderer
,
this
,
path
.
PathPoints
[
i
],
path
.
PathPoints
[
i
-
1
],
path
.
PathPoints
[
i
],
path
.
PathPoints
[
i
+
1
]);
}
if
(
this
.
MarkerEnd
!=
null
)
{
SvgMarker
marker
=
this
.
OwnerDocument
.
GetElementById
<
SvgMarker
>(
this
.
MarkerEnd
.
ToString
());
marker
.
RenderMarker
(
renderer
,
this
,
path
.
PathPoints
[
path
.
PathPoints
.
Length
-
1
],
path
.
PathPoints
[
path
.
PathPoints
.
Length
-
2
],
path
.
PathPoints
[
path
.
PathPoints
.
Length
-
1
]);
}
return
result
;
}
public
override
System
.
Drawing
.
RectangleF
Bounds
{
get
{
return
this
.
Path
(
null
).
GetBounds
();
}
...
...
Source/Basic Shapes/SvgPolygon.cs
View file @
1585c700
...
...
@@ -15,16 +15,47 @@ namespace Svg
public
class
SvgPolygon
:
SvgVisualElement
{
private
GraphicsPath
_path
;
private
SvgUnitCollection
_points
;
/// <summary>
/// The points that make up the SvgPolygon
/// </summary>
[
SvgAttribute
(
"points"
)]
public
Svg
Uni
tCollection
Points
public
Svg
Poin
tCollection
Points
{
get
{
return
this
.
_points
;
}
set
{
this
.
_points
=
value
;
this
.
IsPathDirty
=
true
;
}
get
{
return
this
.
Attributes
[
"points"
]
as
SvgPointCollection
;
}
set
{
this
.
Attributes
[
"points"
]
=
value
;
this
.
IsPathDirty
=
true
;
}
}
/// <summary>
/// Gets or sets the marker (end cap) of the path.
/// </summary>
[
SvgAttribute
(
"marker-end"
)]
public
Uri
MarkerEnd
{
get
{
return
this
.
Attributes
.
GetAttribute
<
Uri
>(
"marker-end"
);
}
set
{
this
.
Attributes
[
"marker-end"
]
=
value
;
}
}
/// <summary>
/// Gets or sets the marker (start cap) of the path.
/// </summary>
[
SvgAttribute
(
"marker-mid"
)]
public
Uri
MarkerMid
{
get
{
return
this
.
Attributes
.
GetAttribute
<
Uri
>(
"marker-mid"
);
}
set
{
this
.
Attributes
[
"marker-mid"
]
=
value
;
}
}
/// <summary>
/// Gets or sets the marker (start cap) of the path.
/// </summary>
[
SvgAttribute
(
"marker-start"
)]
public
Uri
MarkerStart
{
get
{
return
this
.
Attributes
.
GetAttribute
<
Uri
>(
"marker-start"
);
}
set
{
this
.
Attributes
[
"marker-start"
]
=
value
;
}
}
protected
override
bool
RequiresSmoothRendering
...
...
@@ -32,7 +63,7 @@ namespace Svg
get
{
return
true
;
}
}
public
override
GraphicsPath
Path
(
SvgRenderer
renderer
)
public
override
GraphicsPath
Path
(
I
SvgRenderer
renderer
)
{
if
(
this
.
_path
==
null
||
this
.
IsPathDirty
)
{
...
...
@@ -41,14 +72,15 @@ namespace Svg
try
{
for
(
int
i
=
2
;
i
<
this
.
_points
.
Count
;
i
+=
2
)
var
points
=
this
.
Points
;
for
(
int
i
=
2
;
(
i
+
1
)
<
points
.
Count
;
i
+=
2
)
{
var
endPoint
=
SvgUnit
.
GetDevicePoint
(
this
.
_
points
[
i
],
this
.
_
points
[
i
+
1
],
renderer
,
this
);
var
endPoint
=
SvgUnit
.
GetDevicePoint
(
points
[
i
],
points
[
i
+
1
],
renderer
,
this
);
//first line
if
(
_path
.
PointCount
==
0
)
{
_path
.
AddLine
(
SvgUnit
.
GetDevicePoint
(
this
.
_
points
[
i
-
2
],
this
.
_
points
[
i
-
1
],
renderer
,
this
),
endPoint
);
_path
.
AddLine
(
SvgUnit
.
GetDevicePoint
(
points
[
i
-
2
],
points
[
i
-
1
],
renderer
,
this
),
endPoint
);
}
else
{
...
...
@@ -67,6 +99,37 @@ namespace Svg
return
this
.
_path
;
}
/// <summary>
/// Renders the stroke of the <see cref="SvgVisualElement"/> to the specified <see cref="ISvgRenderer"/>
/// </summary>
/// <param name="renderer">The <see cref="ISvgRenderer"/> object to render to.</param>
protected
internal
override
bool
RenderStroke
(
ISvgRenderer
renderer
)
{
var
result
=
base
.
RenderStroke
(
renderer
);
var
path
=
this
.
Path
(
renderer
);
if
(
this
.
MarkerStart
!=
null
)
{
SvgMarker
marker
=
this
.
OwnerDocument
.
GetElementById
<
SvgMarker
>(
this
.
MarkerStart
.
ToString
());
marker
.
RenderMarker
(
renderer
,
this
,
path
.
PathPoints
[
0
],
path
.
PathPoints
[
0
],
path
.
PathPoints
[
1
]);
}
if
(
this
.
MarkerMid
!=
null
)
{
SvgMarker
marker
=
this
.
OwnerDocument
.
GetElementById
<
SvgMarker
>(
this
.
MarkerMid
.
ToString
());
for
(
int
i
=
1
;
i
<=
path
.
PathPoints
.
Length
-
2
;
i
++)
marker
.
RenderMarker
(
renderer
,
this
,
path
.
PathPoints
[
i
],
path
.
PathPoints
[
i
-
1
],
path
.
PathPoints
[
i
],
path
.
PathPoints
[
i
+
1
]);
}
if
(
this
.
MarkerEnd
!=
null
)
{
SvgMarker
marker
=
this
.
OwnerDocument
.
GetElementById
<
SvgMarker
>(
this
.
MarkerEnd
.
ToString
());
marker
.
RenderMarker
(
renderer
,
this
,
path
.
PathPoints
[
path
.
PathPoints
.
Length
-
1
],
path
.
PathPoints
[
path
.
PathPoints
.
Length
-
2
],
path
.
PathPoints
[
path
.
PathPoints
.
Length
-
1
]);
}
return
result
;
}
public
override
RectangleF
Bounds
{
get
{
return
this
.
Path
(
null
).
GetBounds
();
}
...
...
@@ -81,7 +144,7 @@ namespace Svg
public
override
SvgElement
DeepCopy
<
T
>()
{
var
newObj
=
base
.
DeepCopy
<
T
>()
as
SvgPolygon
;
newObj
.
Points
=
new
Svg
Uni
tCollection
();
newObj
.
Points
=
new
Svg
Poin
tCollection
();
foreach
(
var
pt
in
this
.
Points
)
newObj
.
Points
.
Add
(
pt
);
return
newObj
;
...
...
Source/Basic Shapes/SvgPolyline.cs
View file @
1585c700
...
...
@@ -13,8 +13,40 @@ namespace Svg
[
SvgElement
(
"polyline"
)]
public
class
SvgPolyline
:
SvgPolygon
{
/// <summary>
/// Gets or sets the marker (end cap) of the path.
/// </summary>
[
SvgAttribute
(
"marker-end"
)]
public
Uri
MarkerEnd
{
get
{
return
this
.
Attributes
.
GetAttribute
<
Uri
>(
"marker-end"
);
}
set
{
this
.
Attributes
[
"marker-end"
]
=
value
;
}
}
/// <summary>
/// Gets or sets the marker (start cap) of the path.
/// </summary>
[
SvgAttribute
(
"marker-mid"
)]
public
Uri
MarkerMid
{
get
{
return
this
.
Attributes
.
GetAttribute
<
Uri
>(
"marker-mid"
);
}
set
{
this
.
Attributes
[
"marker-mid"
]
=
value
;
}
}
/// <summary>
/// Gets or sets the marker (start cap) of the path.
/// </summary>
[
SvgAttribute
(
"marker-start"
)]
public
Uri
MarkerStart
{
get
{
return
this
.
Attributes
.
GetAttribute
<
Uri
>(
"marker-start"
);
}
set
{
this
.
Attributes
[
"marker-start"
]
=
value
;
}
}
private
GraphicsPath
_Path
;
public
override
GraphicsPath
Path
(
SvgRenderer
renderer
)
public
override
GraphicsPath
Path
(
I
SvgRenderer
renderer
)
{
if
(
_Path
==
null
||
this
.
IsPathDirty
)
{
...
...
@@ -22,7 +54,7 @@ namespace Svg
try
{
for
(
int
i
=
0
;
i
<
Points
.
Count
;
i
+=
2
)
for
(
int
i
=
0
;
(
i
+
1
)
<
Points
.
Count
;
i
+=
2
)
{
PointF
endPoint
=
new
PointF
(
Points
[
i
].
ToDeviceValue
(
renderer
,
UnitRenderingType
.
Horizontal
,
this
),
Points
[
i
+
1
].
ToDeviceValue
(
renderer
,
UnitRenderingType
.
Vertical
,
this
));
...
...
@@ -46,5 +78,36 @@ namespace Svg
}
return
_Path
;
}
/// <summary>
/// Renders the stroke of the <see cref="SvgVisualElement"/> to the specified <see cref="ISvgRenderer"/>
/// </summary>
/// <param name="renderer">The <see cref="ISvgRenderer"/> object to render to.</param>
protected
internal
override
bool
RenderStroke
(
ISvgRenderer
renderer
)
{
var
result
=
base
.
RenderStroke
(
renderer
);
var
path
=
this
.
Path
(
renderer
);
if
(
this
.
MarkerStart
!=
null
)
{
SvgMarker
marker
=
this
.
OwnerDocument
.
GetElementById
<
SvgMarker
>(
this
.
MarkerStart
.
ToString
());
marker
.
RenderMarker
(
renderer
,
this
,
path
.
PathPoints
[
0
],
path
.
PathPoints
[
0
],
path
.
PathPoints
[
1
]);
}
if
(
this
.
MarkerMid
!=
null
)
{
SvgMarker
marker
=
this
.
OwnerDocument
.
GetElementById
<
SvgMarker
>(
this
.
MarkerMid
.
ToString
());
for
(
int
i
=
1
;
i
<=
path
.
PathPoints
.
Length
-
2
;
i
++)
marker
.
RenderMarker
(
renderer
,
this
,
path
.
PathPoints
[
i
],
path
.
PathPoints
[
i
-
1
],
path
.
PathPoints
[
i
],
path
.
PathPoints
[
i
+
1
]);
}
if
(
this
.
MarkerEnd
!=
null
)
{
SvgMarker
marker
=
this
.
OwnerDocument
.
GetElementById
<
SvgMarker
>(
this
.
MarkerEnd
.
ToString
());
marker
.
RenderMarker
(
renderer
,
this
,
path
.
PathPoints
[
path
.
PathPoints
.
Length
-
1
],
path
.
PathPoints
[
path
.
PathPoints
.
Length
-
2
],
path
.
PathPoints
[
path
.
PathPoints
.
Length
-
1
]);
}
return
result
;
}
}
}
\ No newline at end of file
Source/Basic Shapes/SvgRectangle.cs
View file @
1585c700
...
...
@@ -174,7 +174,7 @@ namespace Svg
/// <summary>
/// Gets the <see cref="GraphicsPath"/> for this element.
/// </summary>
public
override
GraphicsPath
Path
(
SvgRenderer
renderer
)
public
override
GraphicsPath
Path
(
I
SvgRenderer
renderer
)
{
if
(
_path
==
null
||
IsPathDirty
)
{
...
...
@@ -197,8 +197,8 @@ namespace Svg
var
lineEnd
=
new
PointF
();
var
width
=
Width
.
ToDeviceValue
(
renderer
,
UnitRenderingType
.
Horizontal
,
this
);
var
height
=
Height
.
ToDeviceValue
(
renderer
,
UnitRenderingType
.
Vertical
,
this
);
var
rx
=
CornerRadiusX
.
ToDeviceValue
(
renderer
,
UnitRenderingType
.
Horizontal
,
this
)
*
2
;
var
ry
=
CornerRadiusY
.
ToDeviceValue
(
renderer
,
UnitRenderingType
.
Vertical
,
this
)
*
2
;
var
rx
=
Math
.
Min
(
CornerRadiusX
.
ToDeviceValue
(
renderer
,
UnitRenderingType
.
Horizontal
,
this
)
*
2
,
width
)
;
var
ry
=
Math
.
Min
(
CornerRadiusY
.
ToDeviceValue
(
renderer
,
UnitRenderingType
.
Vertical
,
this
)
*
2
,
height
)
;
var
location
=
Location
.
ToDeviceValue
(
renderer
,
this
);
// Start
...
...
@@ -261,7 +261,7 @@ namespace Svg
/// <summary>
/// Renders the <see cref="SvgElement"/> and contents to the specified <see cref="Graphics"/> object.
/// </summary>
protected
override
void
Render
(
SvgRenderer
renderer
)
protected
override
void
Render
(
I
SvgRenderer
renderer
)
{
if
(
Width
.
Value
>
0.0f
&&
Height
.
Value
>
0.0f
)
{
...
...
Source/Basic Shapes/SvgVisualElement.cs
View file @
1585c700
using
System
;
using
System.Drawing
;
using
System.Drawing.Drawing2D
;
using
System.Diagnostics
;
using
System.Linq
;
namespace
Svg
{
...
...
@@ -9,14 +11,13 @@ namespace Svg
/// </summary>
public
abstract
partial
class
SvgVisualElement
:
SvgElement
,
ISvgBoundable
,
ISvgStylable
,
ISvgClipable
{
private
bool
_dirty
;
private
bool
_requiresSmoothRendering
;
private
Region
_previousClip
;
/// <summary>
/// Gets the <see cref="GraphicsPath"/> for this element.
/// </summary>
public
abstract
GraphicsPath
Path
(
SvgRenderer
renderer
);
public
abstract
GraphicsPath
Path
(
I
SvgRenderer
renderer
);
PointF
ISvgBoundable
.
Location
{
...
...
@@ -41,15 +42,13 @@ namespace Svg
public
abstract
RectangleF
Bounds
{
get
;
}
/// <summary>
/// Gets
or sets a value indicating whether this element's
<see cref="Path"/> i
s dirty
.
/// Gets
the associated
<see cref="
SvgClip
Path"/> i
f one has been specified
.
/// </summary>
/// <value>
/// <c>true</c> if the path is dirty; otherwise, <c>false</c>.
/// </value>
protected
virtual
bool
IsPathDirty
[
SvgAttribute
(
"clip"
)]
public
virtual
string
Clip
{
get
{
return
this
.
_dirty
;
}
set
{
this
.
_dirty
=
value
;
}
get
{
return
this
.
Attributes
.
GetInheritedAttribute
<
string
>(
"clip"
)
;
}
set
{
this
.
Attributes
[
"clip"
]
=
value
;
}
}
/// <summary>
...
...
@@ -58,7 +57,7 @@ namespace Svg
[
SvgAttribute
(
"clip-path"
)]
public
virtual
Uri
ClipPath
{
get
{
return
this
.
Attributes
.
GetAttribute
<
Uri
>(
"clip-path"
);
}
get
{
return
this
.
Attributes
.
Get
Inherited
Attribute
<
Uri
>(
"clip-path"
);
}
set
{
this
.
Attributes
[
"clip-path"
]
=
value
;
}
}
...
...
@@ -78,7 +77,7 @@ namespace Svg
[
SvgAttribute
(
"filter"
)]
public
virtual
Uri
Filter
{
get
{
return
this
.
Attributes
.
GetAttribute
<
Uri
>(
"filter"
);
}
get
{
return
this
.
Attributes
.
Get
Inherited
Attribute
<
Uri
>(
"filter"
);
}
set
{
this
.
Attributes
[
"filter"
]
=
value
;
}
}
...
...
@@ -95,50 +94,91 @@ namespace Svg
/// </summary>
public
SvgVisualElement
()
{
this
.
_d
irty
=
true
;
this
.
IsPathD
irty
=
true
;
this
.
_requiresSmoothRendering
=
false
;
}
protected
virtual
bool
Renderable
{
get
{
return
true
;
}
}
/// <summary>
/// Renders the <see cref="SvgElement"/> and contents to the specified <see cref="Graphics"/> object.
/// </summary>
/// <param name="renderer">The <see cref="SvgRenderer"/> object to render to.</param>
protected
override
void
Render
(
SvgRenderer
renderer
)
/// <param name="renderer">The <see cref="
I
SvgRenderer"/> object to render to.</param>
protected
override
void
Render
(
I
SvgRenderer
renderer
)
{
if
((
this
.
Path
(
renderer
)
!=
null
)
&&
this
.
Visible
&&
this
.
Displayable
)
this
.
Render
(
renderer
,
true
);
}
private
void
Render
(
ISvgRenderer
renderer
,
bool
renderFilter
)
{
if
(
this
.
Visible
&&
this
.
Displayable
&&
this
.
PushTransforms
(
renderer
)
&&
(!
Renderable
||
this
.
Path
(
renderer
)
!=
null
))
{
this
.
PushTransforms
(
renderer
);
this
.
SetClip
(
renderer
);
bool
renderNormal
=
true
;
// If this element needs smoothing enabled turn anti-aliasing on
if
(
this
.
RequiresSmoothRendering
)
if
(
renderFilter
&&
this
.
Filter
!=
null
)
{
renderer
.
SmoothingMode
=
SmoothingMode
.
AntiAlias
;
var
filterPath
=
this
.
Filter
;
if
(
filterPath
.
ToString
().
StartsWith
(
"url("
))
{
filterPath
=
new
Uri
(
filterPath
.
ToString
().
Substring
(
4
,
filterPath
.
ToString
().
Length
-
5
),
UriKind
.
RelativeOrAbsolute
);
}
var
filter
=
this
.
OwnerDocument
.
IdManager
.
GetElementById
(
filterPath
)
as
FilterEffects
.
SvgFilter
;
if
(
filter
!=
null
)
{
this
.
PopTransforms
(
renderer
);
try
{
filter
.
ApplyFilter
(
this
,
renderer
,
(
r
)
=>
this
.
Render
(
r
,
false
));
}
catch
(
Exception
ex
)
{
Debug
.
Print
(
ex
.
ToString
());
}
renderNormal
=
false
;
}
}
this
.
RenderFill
(
renderer
);
this
.
RenderStroke
(
renderer
);
// Reset the smoothing mode
if
(
this
.
RequiresSmoothRendering
&&
renderer
.
SmoothingMode
==
SmoothingMode
.
AntiAlias
)
if
(
renderNormal
)
{
renderer
.
SmoothingMode
=
SmoothingMode
.
Default
;
this
.
SetClip
(
renderer
);
if
(
Renderable
)
{
// If this element needs smoothing enabled turn anti-aliasing on
if
(
this
.
RequiresSmoothRendering
)
{
renderer
.
SmoothingMode
=
SmoothingMode
.
AntiAlias
;
}
this
.
RenderFill
(
renderer
);
this
.
RenderStroke
(
renderer
);
// Reset the smoothing mode
if
(
this
.
RequiresSmoothRendering
&&
renderer
.
SmoothingMode
==
SmoothingMode
.
AntiAlias
)
{
renderer
.
SmoothingMode
=
SmoothingMode
.
Default
;
}
}
else
{
base
.
RenderChildren
(
renderer
);
}
this
.
ResetClip
(
renderer
);
this
.
PopTransforms
(
renderer
);
}
this
.
ResetClip
(
renderer
);
this
.
PopTransforms
(
renderer
);
}
}
/// <summary>
/// Renders the fill of the <see cref="SvgVisualElement"/> to the specified <see cref="SvgRenderer"/>
/// Renders the fill of the <see cref="SvgVisualElement"/> to the specified <see cref="
I
SvgRenderer"/>
/// </summary>
/// <param name="renderer">The <see cref="SvgRenderer"/> object to render to.</param>
protected
internal
virtual
void
RenderFill
(
SvgRenderer
renderer
)
/// <param name="renderer">The <see cref="
I
SvgRenderer"/> object to render to.</param>
protected
internal
virtual
void
RenderFill
(
I
SvgRenderer
renderer
)
{
if
(
this
.
Fill
!=
null
)
{
using
(
Brush
brush
=
this
.
Fill
.
GetBrush
(
this
,
renderer
,
Math
.
Min
(
Math
.
Max
(
this
.
FillOpacity
*
this
.
Opacity
,
0
),
1
)))
using
(
var
brush
=
this
.
Fill
.
GetBrush
(
this
,
renderer
,
Math
.
Min
(
Math
.
Max
(
this
.
FillOpacity
*
this
.
Opacity
,
0
),
1
)))
{
if
(
brush
!=
null
)
{
...
...
@@ -150,72 +190,146 @@ namespace Svg
}
/// <summary>
/// Renders the stroke of the <see cref="SvgVisualElement"/> to the specified <see cref="SvgRenderer"/>
/// Renders the stroke of the <see cref="SvgVisualElement"/> to the specified <see cref="
I
SvgRenderer"/>
/// </summary>
/// <param name="renderer">The <see cref="SvgRenderer"/> object to render to.</param>
protected
internal
virtual
void
RenderStroke
(
SvgRenderer
renderer
)
/// <param name="renderer">The <see cref="
I
SvgRenderer"/> object to render to.</param>
protected
internal
virtual
bool
RenderStroke
(
I
SvgRenderer
renderer
)
{
if
(
this
.
Stroke
!=
null
)
if
(
this
.
Stroke
!=
null
&&
this
.
Stroke
!=
SvgColourServer
.
None
)
{
float
strokeWidth
=
this
.
StrokeWidth
.
ToDeviceValue
(
renderer
,
UnitRenderingType
.
Other
,
this
);
using
(
var
pen
=
new
Pen
(
this
.
Stroke
.
GetBrush
(
this
,
renderer
,
Math
.
Min
(
Math
.
Max
(
this
.
StrokeOpacity
*
this
.
Opacity
,
0
),
1
)
)
,
s
tr
okeWidth
))
using
(
var
brush
=
this
.
Stroke
.
GetBrush
(
this
,
renderer
,
Math
.
Min
(
Math
.
Max
(
this
.
StrokeOpacity
*
this
.
Opacity
,
0
),
1
),
tr
ue
))
{
if
(
this
.
StrokeDashArray
!=
null
&&
this
.
StrokeDashArray
.
Count
>
0
)
if
(
brush
!=
null
)
{
/* divide by stroke width - GDI behaviour that I don't quite understand yet.*/
pen
.
DashPattern
=
this
.
StrokeDashArray
.
ConvertAll
(
u
=>
((
u
.
Value
<=
0
)
?
1
:
u
.
Value
)
/
((
strokeWidth
<=
0
)
?
1
:
strokeWidth
)).
ToArray
();
}
var
path
=
this
.
Path
(
renderer
);
var
bounds
=
path
.
GetBounds
();
if
(
path
.
PointCount
<
1
)
return
false
;
if
(
bounds
.
Width
<=
0
&&
bounds
.
Height
<=
0
)
{
switch
(
this
.
StrokeLineCap
)
{
case
SvgStrokeLineCap
.
Round
:
using
(
var
capPath
=
new
GraphicsPath
())
{
capPath
.
AddEllipse
(
path
.
PathPoints
[
0
].
X
-
strokeWidth
/
2
,
path
.
PathPoints
[
0
].
Y
-
strokeWidth
/
2
,
strokeWidth
,
strokeWidth
);
renderer
.
FillPath
(
brush
,
capPath
);
}
break
;
case
SvgStrokeLineCap
.
Square
:
using
(
var
capPath
=
new
GraphicsPath
())
{
capPath
.
AddRectangle
(
new
RectangleF
(
path
.
PathPoints
[
0
].
X
-
strokeWidth
/
2
,
path
.
PathPoints
[
0
].
Y
-
strokeWidth
/
2
,
strokeWidth
,
strokeWidth
));
renderer
.
FillPath
(
brush
,
capPath
);
}
break
;
}
}
else
{
using
(
var
pen
=
new
Pen
(
brush
,
strokeWidth
))
{
if
(
this
.
StrokeDashArray
!=
null
&&
this
.
StrokeDashArray
.
Count
>
0
)
{
/* divide by stroke width - GDI behaviour that I don't quite understand yet.*/
pen
.
DashPattern
=
this
.
StrokeDashArray
.
ConvertAll
(
u
=>
((
u
.
ToDeviceValue
(
renderer
,
UnitRenderingType
.
Other
,
this
)
<=
0
)
?
1
:
u
.
ToDeviceValue
(
renderer
,
UnitRenderingType
.
Other
,
this
))
/
((
strokeWidth
<=
0
)
?
1
:
strokeWidth
)).
ToArray
();
}
switch
(
this
.
StrokeLineJoin
)
{
case
SvgStrokeLineJoin
.
Bevel
:
pen
.
LineJoin
=
LineJoin
.
Bevel
;
break
;
case
SvgStrokeLineJoin
.
Round
:
pen
.
LineJoin
=
LineJoin
.
Round
;
break
;
default
:
pen
.
LineJoin
=
LineJoin
.
Miter
;
break
;
}
pen
.
MiterLimit
=
this
.
StrokeMiterLimit
;
switch
(
this
.
StrokeLineCap
)
{
case
SvgStrokeLineCap
.
Round
:
pen
.
StartCap
=
LineCap
.
Round
;
pen
.
EndCap
=
LineCap
.
Round
;
break
;
case
SvgStrokeLineCap
.
Square
:
pen
.
StartCap
=
LineCap
.
Square
;
pen
.
EndCap
=
LineCap
.
Square
;
break
;
}
renderer
.
DrawPath
(
pen
,
this
.
Path
(
renderer
));
renderer
.
DrawPath
(
pen
,
path
);
return
true
;
}
}
}
}
}
return
false
;
}
/// <summary>
/// Sets the clipping region of the specified <see cref="SvgRenderer"/>.
/// Sets the clipping region of the specified <see cref="
I
SvgRenderer"/>.
/// </summary>
/// <param name="renderer">The <see cref="SvgRenderer"/> to have its clipping region set.</param>
protected
internal
virtual
void
SetClip
(
SvgRenderer
renderer
)
/// <param name="renderer">The <see cref="
I
SvgRenderer"/> to have its clipping region set.</param>
protected
internal
virtual
void
SetClip
(
I
SvgRenderer
renderer
)
{
if
(
this
.
ClipPath
!=
null
)
if
(
this
.
ClipPath
!=
null
||
!
string
.
IsNullOrEmpty
(
this
.
Clip
)
)
{
SvgClipPath
clipPath
=
this
.
OwnerDocument
.
GetElementById
<
SvgClipPath
>(
this
.
ClipPath
.
ToString
());
this
.
_previousClip
=
renderer
.
Clip
;
this
.
_previousClip
=
renderer
.
GetClip
();
if
(
this
.
ClipPath
!=
null
)
{
SvgClipPath
clipPath
=
this
.
OwnerDocument
.
GetElementById
<
SvgClipPath
>(
this
.
ClipPath
.
ToString
());
if
(
clipPath
!=
null
)
renderer
.
SetClip
(
clipPath
.
GetClipRegion
(
this
),
CombineMode
.
Intersect
);
}
if
(
clipPath
!=
null
)
var
clip
=
this
.
Clip
;
if
(!
string
.
IsNullOrEmpty
(
clip
)
&&
clip
.
StartsWith
(
"rect("
))
{
renderer
.
AddClip
(
clipPath
.
GetClipRegion
(
this
));
clip
=
clip
.
Trim
();
var
offsets
=
(
from
o
in
clip
.
Substring
(
5
,
clip
.
Length
-
6
).
Split
(
','
)
select
float
.
Parse
(
o
.
Trim
())).
ToList
();
var
bounds
=
this
.
Bounds
;
var
clipRect
=
new
RectangleF
(
bounds
.
Left
+
offsets
[
3
],
bounds
.
Top
+
offsets
[
0
],
bounds
.
Width
-
(
offsets
[
3
]
+
offsets
[
1
]),
bounds
.
Height
-
(
offsets
[
2
]
+
offsets
[
0
]));
renderer
.
SetClip
(
new
Region
(
clipRect
),
CombineMode
.
Intersect
);
}
}
}
/// <summary>
/// Resets the clipping region of the specified <see cref="SvgRenderer"/> back to where it was before the <see cref="SetClip"/> method was called.
/// Resets the clipping region of the specified <see cref="
I
SvgRenderer"/> back to where it was before the <see cref="SetClip"/> method was called.
/// </summary>
/// <param name="renderer">The <see cref="SvgRenderer"/> to have its clipping region reset.</param>
protected
internal
virtual
void
ResetClip
(
SvgRenderer
renderer
)
/// <param name="renderer">The <see cref="
I
SvgRenderer"/> to have its clipping region reset.</param>
protected
internal
virtual
void
ResetClip
(
I
SvgRenderer
renderer
)
{
if
(
this
.
_previousClip
!=
null
)
{
renderer
.
Clip
=
this
.
_previousClip
;
renderer
.
Set
Clip
(
this
.
_previousClip
)
;
this
.
_previousClip
=
null
;
}
}
/// <summary>
/// Sets the clipping region of the specified <see cref="SvgRenderer"/>.
/// Sets the clipping region of the specified <see cref="
I
SvgRenderer"/>.
/// </summary>
/// <param name="renderer">The <see cref="SvgRenderer"/> to have its clipping region set.</param>
void
ISvgClipable
.
SetClip
(
SvgRenderer
renderer
)
/// <param name="renderer">The <see cref="
I
SvgRenderer"/> to have its clipping region set.</param>
void
ISvgClipable
.
SetClip
(
I
SvgRenderer
renderer
)
{
this
.
SetClip
(
renderer
);
}
/// <summary>
/// Resets the clipping region of the specified <see cref="SvgRenderer"/> back to where it was before the <see cref="SetClip"/> method was called.
/// Resets the clipping region of the specified <see cref="
I
SvgRenderer"/> back to where it was before the <see cref="SetClip"/> method was called.
/// </summary>
/// <param name="renderer">The <see cref="SvgRenderer"/> to have its clipping region reset.</param>
void
ISvgClipable
.
ResetClip
(
SvgRenderer
renderer
)
/// <param name="renderer">The <see cref="
I
SvgRenderer"/> to have its clipping region reset.</param>
void
ISvgClipable
.
ResetClip
(
I
SvgRenderer
renderer
)
{
this
.
ResetClip
(
renderer
);
}
...
...
Source/Basic Shapes/SvgVisualElementStyle.cs
View file @
1585c700
using
System
;
using
System.Collections.Generic
;
using
System.Drawing
;
using
System.Text
;
using
System.Reflection
;
using
System.ComponentModel
;
...
...
@@ -11,13 +12,6 @@ namespace Svg
{
public
abstract
partial
class
SvgVisualElement
{
private
static
float
FixOpacityValue
(
float
value
)
{
const
float
max
=
1.0f
;
const
float
min
=
0.0f
;
return
Math
.
Min
(
Math
.
Max
(
value
,
min
),
max
);
}
/// <summary>
/// Gets or sets a value to determine whether the element will be rendered.
/// </summary>
...
...
@@ -56,331 +50,11 @@ namespace Svg
/// <summary>
/// Gets or sets the fill <see cref="SvgPaintServer"/> of this element.
/// </summary>
[
SvgAttribute
(
"fill"
)]
public
virtual
SvgPaintServer
Fill
{
get
{
return
(
this
.
Attributes
[
"fill"
]
==
null
)
?
SvgColourServer
.
NotSet
:
(
SvgPaintServer
)
this
.
Attributes
[
"fill"
];
}
set
{
this
.
Attributes
[
"fill"
]
=
value
;
}
}
/// <summary>
/// Gets or sets the <see cref="SvgPaintServer"/> to be used when rendering a stroke around this element.
/// </summary>
[
SvgAttribute
(
"stroke"
)]
public
virtual
SvgPaintServer
Stroke
{
get
{
return
(
this
.
Attributes
[
"stroke"
]
==
null
)
?
null
:
(
SvgPaintServer
)
this
.
Attributes
[
"stroke"
];
}
set
{
this
.
Attributes
[
"stroke"
]
=
value
;
}
}
[
SvgAttribute
(
"fill-rule"
)]
public
virtual
SvgFillRule
FillRule
{
get
{
return
(
this
.
Attributes
[
"fill-rule"
]
==
null
)
?
SvgFillRule
.
NonZero
:
(
SvgFillRule
)
this
.
Attributes
[
"fill-rule"
];
}
set
{
this
.
Attributes
[
"fill-rule"
]
=
value
;
}
}
/// <summary>
/// Gets or sets the opacity of this element's <see cref="Fill"/>.
/// </summary>
[
SvgAttribute
(
"fill-opacity"
)]
public
virtual
float
FillOpacity
{
get
{
return
(
this
.
Attributes
[
"fill-opacity"
]
==
null
)
?
this
.
Opacity
:
(
float
)
this
.
Attributes
[
"fill-opacity"
];
}
set
{
this
.
Attributes
[
"fill-opacity"
]
=
FixOpacityValue
(
value
);
}
}
/// <summary>
/// Gets or sets the width of the stroke (if the <see cref="Stroke"/> property has a valid value specified.
/// </summary>
[
SvgAttribute
(
"stroke-width"
)]
public
virtual
SvgUnit
StrokeWidth
{
get
{
return
(
this
.
Attributes
[
"stroke-width"
]
==
null
)
?
new
SvgUnit
(
1.0f
)
:
(
SvgUnit
)
this
.
Attributes
[
"stroke-width"
];
}
set
{
this
.
Attributes
[
"stroke-width"
]
=
value
;
}
}
[
SvgAttribute
(
"stroke-linecap"
)]
public
virtual
SvgStrokeLineCap
StrokeLineCap
{
get
{
return
(
this
.
Attributes
[
"stroke-linecap"
]
==
null
)
?
SvgStrokeLineCap
.
Butt
:
(
SvgStrokeLineCap
)
this
.
Attributes
[
"stroke-linecap"
];
}
set
{
this
.
Attributes
[
"stroke-linecap"
]
=
value
;
}
}
[
SvgAttribute
(
"stroke-linejoin"
)]
public
virtual
SvgStrokeLineJoin
StrokeLineJoin
{
get
{
return
(
this
.
Attributes
[
"stroke-linejoin"
]
==
null
)
?
SvgStrokeLineJoin
.
Miter
:
(
SvgStrokeLineJoin
)
this
.
Attributes
[
"stroke-linejoin"
];
}
set
{
this
.
Attributes
[
"stroke-linejoin"
]
=
value
;
}
}
[
SvgAttribute
(
"stroke-miterlimit"
)]
public
virtual
float
StrokeMiterLimit
{
get
{
return
(
this
.
Attributes
[
"stroke-miterlimit"
]
==
null
)
?
4.0f
:
(
float
)
this
.
Attributes
[
"stroke-miterlimit"
];
}
set
{
this
.
Attributes
[
"stroke-miterlimit"
]
=
value
;
}
}
[
SvgAttribute
(
"stroke-dasharray"
)]
public
virtual
SvgUnitCollection
StrokeDashArray
{
get
{
return
this
.
Attributes
[
"stroke-dasharray"
]
as
SvgUnitCollection
;
}
set
{
this
.
Attributes
[
"stroke-dasharray"
]
=
value
;
}
}
[
SvgAttribute
(
"stroke-dashoffset"
)]
public
virtual
SvgUnit
StrokeDashOffset
{
get
{
return
(
this
.
Attributes
[
"stroke-dashoffset"
]
==
null
)
?
SvgUnit
.
Empty
:
(
SvgUnit
)
this
.
Attributes
[
"stroke-dashoffset"
];
}
set
{
this
.
Attributes
[
"stroke-dashoffset"
]
=
value
;
}
}
/// <summary>
/// Gets or sets the opacity of the stroke, if the <see cref="Stroke"/> property has been specified. 1.0 is fully opaque; 0.0 is transparent.
/// </summary>
[
SvgAttribute
(
"stroke-opacity"
)]
public
virtual
float
StrokeOpacity
{
get
{
return
(
this
.
Attributes
[
"stroke-opacity"
]
==
null
)
?
this
.
Opacity
:
(
float
)
this
.
Attributes
[
"stroke-opacity"
];
}
set
{
this
.
Attributes
[
"stroke-opacity"
]
=
FixOpacityValue
(
value
);
}
}
/// <summary>
/// Gets or sets the opacity of the element. 1.0 is fully opaque; 0.0 is transparent.
/// </summary>
[
SvgAttribute
(
"opacity"
)]
public
virtual
float
Opacity
{
get
{
return
(
this
.
Attributes
[
"opacity"
]
==
null
)
?
1.0f
:
(
float
)
this
.
Attributes
[
"opacity"
];
}
set
{
this
.
Attributes
[
"opacity"
]
=
FixOpacityValue
(
value
);
}
}
/// <summary>
/// Indicates which font family is to be used to render the text.
/// </summary>
[
SvgAttribute
(
"font-family"
)]
public
virtual
string
FontFamily
[
SvgAttribute
(
"enable-background"
)]
public
virtual
string
EnableBackground
{
get
{
return
this
.
Attributes
[
"font-family"
]
as
string
;
}
set
{
this
.
Attributes
[
"font-family"
]
=
value
;
this
.
IsPathDirty
=
true
;
}
}
/// <summary>
/// Refers to the size of the font from baseline to baseline when multiple lines of text are set solid in a multiline layout environment.
/// </summary>
[
SvgAttribute
(
"font-size"
)]
public
virtual
SvgUnit
FontSize
{
get
{
return
(
this
.
Attributes
[
"font-size"
]
==
null
)
?
SvgUnit
.
Empty
:
(
SvgUnit
)
this
.
Attributes
[
"font-size"
];
}
set
{
this
.
Attributes
[
"font-size"
]
=
value
;
this
.
IsPathDirty
=
true
;
}
}
/// <summary>
/// Refers to the boldness of the font.
/// </summary>
[
SvgAttribute
(
"font-style"
)]
public
virtual
SvgFontStyle
FontStyle
{
get
{
return
(
this
.
Attributes
[
"font-style"
]
==
null
)
?
SvgFontStyle
.
inherit
:
(
SvgFontStyle
)
this
.
Attributes
[
"font-style"
];
}
set
{
this
.
Attributes
[
"font-style"
]
=
value
;
this
.
IsPathDirty
=
true
;
}
}
/// <summary>
/// Refers to the boldness of the font.
/// </summary>
[
SvgAttribute
(
"font-variant"
)]
public
virtual
SvgFontVariant
FontVariant
{
get
{
return
(
this
.
Attributes
[
"font-variant"
]
==
null
)
?
SvgFontVariant
.
inherit
:
(
SvgFontVariant
)
this
.
Attributes
[
"font-variant"
];
}
set
{
this
.
Attributes
[
"font-variant"
]
=
value
;
this
.
IsPathDirty
=
true
;
}
}
/// <summary>
/// Refers to the boldness of the font.
/// </summary>
[
SvgAttribute
(
"text-decoration"
)]
public
virtual
SvgTextDecoration
TextDecoration
{
get
{
return
(
this
.
Attributes
[
"text-decoration"
]
==
null
)
?
SvgTextDecoration
.
inherit
:
(
SvgTextDecoration
)
this
.
Attributes
[
"text-decoration"
];
}
set
{
this
.
Attributes
[
"text-decoration"
]
=
value
;
this
.
IsPathDirty
=
true
;
}
}
/// <summary>
/// Refers to the boldness of the font.
/// </summary>
[
SvgAttribute
(
"font-weight"
)]
public
virtual
SvgFontWeight
FontWeight
{
get
{
return
(
this
.
Attributes
[
"font-weight"
]
==
null
)
?
SvgFontWeight
.
inherit
:
(
SvgFontWeight
)
this
.
Attributes
[
"font-weight"
];
}
set
{
this
.
Attributes
[
"font-weight"
]
=
value
;
this
.
IsPathDirty
=
true
;
}
}
private
enum
FontParseState
{
fontStyle
,
fontVariant
,
fontWeight
,
fontSize
,
fontFamilyNext
,
fontFamilyCurr
}
/// <summary>
/// Set all font information.
/// </summary>
[
SvgAttribute
(
"font"
)]
public
virtual
string
Font
{
get
{
return
(
this
.
Attributes
[
"font"
]
==
null
?
""
:
this
.
Attributes
[
"font"
]
as
string
);
}
set
{
var
state
=
FontParseState
.
fontStyle
;
var
parts
=
value
.
Split
(
' '
);
SvgFontStyle
fontStyle
;
SvgFontVariant
fontVariant
;
SvgFontWeight
fontWeight
;
SvgUnit
fontSize
;
bool
success
;
string
[]
sizes
;
string
part
;
for
(
int
i
=
0
;
i
<
parts
.
Length
;
i
++)
{
part
=
parts
[
i
];
success
=
false
;
while
(!
success
)
{
switch
(
state
)
{
case
FontParseState
.
fontStyle
:
success
=
Enums
.
TryParse
<
SvgFontStyle
>(
part
,
out
fontStyle
);
if
(
success
)
this
.
FontStyle
=
fontStyle
;
state
++;
break
;
case
FontParseState
.
fontVariant
:
success
=
Enums
.
TryParse
<
SvgFontVariant
>(
part
,
out
fontVariant
);
if
(
success
)
this
.
FontVariant
=
fontVariant
;
state
++;
break
;
case
FontParseState
.
fontWeight
:
success
=
Enums
.
TryParse
<
SvgFontWeight
>(
part
,
out
fontWeight
);
if
(
success
)
this
.
FontWeight
=
fontWeight
;
state
++;
break
;
case
FontParseState
.
fontSize
:
sizes
=
part
.
Split
(
'/'
);
try
{
fontSize
=
(
SvgUnit
)(
new
SvgUnitConverter
().
ConvertFromInvariantString
(
sizes
[
0
]));
success
=
true
;
this
.
FontSize
=
fontSize
;
}
catch
{
}
state
++;
break
;
case
FontParseState
.
fontFamilyNext
:
state
++;
success
=
true
;
break
;
}
}
switch
(
state
)
{
case
FontParseState
.
fontFamilyNext
:
this
.
FontFamily
=
string
.
Join
(
" "
,
parts
,
i
+
1
,
parts
.
Length
-
(
i
+
1
));
i
=
int
.
MaxValue
-
2
;
break
;
case
FontParseState
.
fontFamilyCurr
:
this
.
FontFamily
=
string
.
Join
(
" "
,
parts
,
i
,
parts
.
Length
-
(
i
));
i
=
int
.
MaxValue
-
2
;
break
;
}
}
this
.
Attributes
[
"font"
]
=
value
;
this
.
IsPathDirty
=
true
;
}
}
private
const
string
DefaultFontFamily
=
"Times New Roman"
;
/// <summary>
/// Get the font information based on data stored with the text object or inherited from the parent.
/// </summary>
/// <returns></returns>
internal
System
.
Drawing
.
Font
GetFont
(
SvgRenderer
renderer
)
{
// Get the font-size
float
fontSize
;
var
fontSizeUnit
=
this
.
FontSize
;
if
(
fontSizeUnit
==
SvgUnit
.
None
)
{
fontSize
=
1.0f
;
}
else
{
fontSize
=
fontSizeUnit
.
ToDeviceValue
(
renderer
,
UnitRenderingType
.
Vertical
,
this
);
}
var
fontStyle
=
System
.
Drawing
.
FontStyle
.
Regular
;
// Get the font-weight
switch
(
this
.
FontWeight
)
{
case
SvgFontWeight
.
bold
:
case
SvgFontWeight
.
bolder
:
case
SvgFontWeight
.
w600
:
case
SvgFontWeight
.
w700
:
case
SvgFontWeight
.
w800
:
case
SvgFontWeight
.
w900
:
fontStyle
|=
System
.
Drawing
.
FontStyle
.
Bold
;
break
;
}
// Get the font-style
switch
(
this
.
FontStyle
)
{
case
SvgFontStyle
.
italic
:
case
SvgFontStyle
.
oblique
:
fontStyle
|=
System
.
Drawing
.
FontStyle
.
Italic
;
break
;
}
// Get the text-decoration
switch
(
this
.
TextDecoration
)
{
case
SvgTextDecoration
.
lineThrough
:
fontStyle
|=
System
.
Drawing
.
FontStyle
.
Strikeout
;
break
;
case
SvgTextDecoration
.
underline
:
fontStyle
|=
System
.
Drawing
.
FontStyle
.
Underline
;
break
;
}
// Get the font-family
string
family
=
ValidateFontFamily
(
this
.
FontFamily
)
??
DefaultFontFamily
;
return
new
System
.
Drawing
.
Font
(
family
,
fontSize
,
fontStyle
,
System
.
Drawing
.
GraphicsUnit
.
Pixel
);
}
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
families
=
System
.
Drawing
.
FontFamily
.
Families
;
// Find a the first font that exists in the list of installed font families.
//styles from IE get sent through as lowercase.
foreach
(
var
f
in
fontParts
.
Where
(
f
=>
families
.
Any
(
family
=>
family
.
Name
.
ToLower
()
==
f
.
ToLower
())))
{
return
f
;
}
// No valid font family found from the list requested.
return
null
;
get
{
return
this
.
Attributes
[
"enable-background"
]
as
string
;
}
set
{
this
.
Attributes
[
"enable-background"
]
=
value
;
}
}
}
...
...
Source/Clipping and Masking/ISvgClipable.cs
View file @
1585c700
...
...
@@ -20,14 +20,14 @@ namespace Svg
/// </summary>
SvgClipRule
ClipRule
{
get
;
set
;
}
/// <summary>
/// Sets the clipping region of the specified <see cref="SvgRenderer"/>.
/// Sets the clipping region of the specified <see cref="
I
SvgRenderer"/>.
/// </summary>
/// <param name="renderer">The <see cref="SvgRenderer"/> to have its clipping region set.</param>
void
SetClip
(
SvgRenderer
renderer
);
/// <param name="renderer">The <see cref="
I
SvgRenderer"/> to have its clipping region set.</param>
void
SetClip
(
I
SvgRenderer
renderer
);
/// <summary>
/// Resets the clipping region of the specified <see cref="SvgRenderer"/> back to where it was before the <see cref="SetClip"/> method was called.
/// Resets the clipping region of the specified <see cref="
I
SvgRenderer"/> back to where it was before the <see cref="SetClip"/> method was called.
/// </summary>
/// <param name="renderer">The <see cref="SvgRenderer"/> to have its clipping region reset.</param>
void
ResetClip
(
SvgRenderer
renderer
);
/// <param name="renderer">The <see cref="
I
SvgRenderer"/> to have its clipping region reset.</param>
void
ResetClip
(
I
SvgRenderer
renderer
);
}
}
\ No newline at end of file
Source/Clipping and Masking/SvgClipPath.cs
View file @
1585c700
...
...
@@ -26,7 +26,7 @@ namespace Svg
/// </summary>
public
SvgClipPath
()
{
this
.
ClipPathUnits
=
SvgCoordinateUnits
.
ObjectBoundingBox
;
this
.
ClipPathUnits
=
SvgCoordinateUnits
.
Inherit
;
}
private
GraphicsPath
cachedClipPath
=
null
;
...
...
@@ -49,7 +49,20 @@ namespace Svg
this
.
_pathDirty
=
false
;
}
return
new
Region
(
cachedClipPath
);
var
result
=
cachedClipPath
;
if
(
ClipPathUnits
==
SvgCoordinateUnits
.
ObjectBoundingBox
)
{
result
=
(
GraphicsPath
)
cachedClipPath
.
Clone
();
using
(
var
transform
=
new
Matrix
())
{
var
bounds
=
owner
.
Bounds
;
transform
.
Scale
(
bounds
.
Width
,
bounds
.
Height
,
MatrixOrder
.
Append
);
transform
.
Translate
(
bounds
.
Left
,
bounds
.
Top
,
MatrixOrder
.
Append
);
result
.
Transform
(
transform
);
}
}
return
new
Region
(
result
);
}
/// <summary>
...
...
@@ -75,7 +88,7 @@ namespace Svg
}
}
path
.
AddPath
(
childPath
,
false
);
if
(
childPath
.
PointCount
>
0
)
path
.
AddPath
(
childPath
,
false
);
}
foreach
(
SvgElement
child
in
element
.
Children
)
...
...
@@ -108,10 +121,10 @@ namespace Svg
}
/// <summary>
/// Renders the <see cref="SvgElement"/> and contents to the specified <see cref="SvgRenderer"/> object.
/// Renders the <see cref="SvgElement"/> and contents to the specified <see cref="
I
SvgRenderer"/> object.
/// </summary>
/// <param name="renderer">The <see cref="SvgRenderer"/> object to render to.</param>
protected
override
void
Render
(
SvgRenderer
renderer
)
/// <param name="renderer">The <see cref="
I
SvgRenderer"/> object to render to.</param>
protected
override
void
Render
(
I
SvgRenderer
renderer
)
{
// Do nothing
}
...
...
Source/Css/SvgElementOps.cs
View file @
1585c700
...
...
@@ -10,8 +10,12 @@ namespace Svg.Css
{
public
Selector
<
SvgElement
>
Type
(
NamespacePrefix
prefix
,
string
name
)
{
var
type
=
SvgElementFactory
.
AvailableElements
.
SingleOrDefault
(
e
=>
e
.
ElementName
==
name
);
return
nodes
=>
nodes
.
Where
(
n
=>
n
.
GetType
()
==
type
.
ElementType
);
SvgElementFactory
.
ElementInfo
type
=
null
;
if
(
SvgElementFactory
.
AvailableElements
.
TryGetValue
(
name
,
out
type
))
{
return
nodes
=>
nodes
.
Where
(
n
=>
n
.
GetType
()
==
type
.
ElementType
);
}
return
nodes
=>
Enumerable
.
Empty
<
SvgElement
>();
}
public
Selector
<
SvgElement
>
Universal
(
NamespacePrefix
prefix
)
...
...
@@ -31,7 +35,7 @@ namespace Svg.Css
public
Selector
<
SvgElement
>
AttributeExists
(
NamespacePrefix
prefix
,
string
name
)
{
return
nodes
=>
nodes
.
Where
(
n
=>
n
.
Attribute
s
.
ContainsKey
(
name
)
||
n
.
CustomAttributes
.
ContainsKey
(
name
));
return
nodes
=>
nodes
.
Where
(
n
=>
n
.
Contains
Attribute
(
name
));
}
public
Selector
<
SvgElement
>
AttributeExact
(
NamespacePrefix
prefix
,
string
name
,
string
value
)
...
...
@@ -39,9 +43,7 @@ namespace Svg.Css
return
nodes
=>
nodes
.
Where
(
n
=>
{
string
val
=
null
;
object
oval
=
null
;
return
(
n
.
CustomAttributes
.
TryGetValue
(
name
,
out
val
)
&&
val
==
value
)
||
(
n
.
Attributes
.
TryGetValue
(
name
,
out
oval
)
&&
oval
.
ToString
()
==
value
);
return
(
n
.
TryGetAttribute
(
name
,
out
val
)
&&
val
==
value
);
});
}
...
...
@@ -50,9 +52,7 @@ namespace Svg.Css
return
nodes
=>
nodes
.
Where
(
n
=>
{
string
val
=
null
;
object
oval
=
null
;
return
(
n
.
CustomAttributes
.
TryGetValue
(
name
,
out
val
)
&&
val
.
Split
(
' '
).
Contains
(
value
))
||
(
n
.
Attributes
.
TryGetValue
(
name
,
out
oval
)
&&
oval
.
ToString
().
Split
(
' '
).
Contains
(
value
));
return
(
n
.
TryGetAttribute
(
name
,
out
val
)
&&
val
.
Split
(
' '
).
Contains
(
value
));
});
}
...
...
@@ -63,9 +63,7 @@ namespace Svg.Css
:
(
nodes
=>
nodes
.
Where
(
n
=>
{
string
val
=
null
;
object
oval
=
null
;
return
(
n
.
CustomAttributes
.
TryGetValue
(
name
,
out
val
)
&&
val
.
Split
(
'-'
).
Contains
(
value
))
||
(
n
.
Attributes
.
TryGetValue
(
name
,
out
oval
)
&&
oval
.
ToString
().
Split
(
'-'
).
Contains
(
value
));
return
(
n
.
TryGetAttribute
(
name
,
out
val
)
&&
val
.
Split
(
'-'
).
Contains
(
value
));
}));
}
...
...
@@ -76,9 +74,7 @@ namespace Svg.Css
:
(
nodes
=>
nodes
.
Where
(
n
=>
{
string
val
=
null
;
object
oval
=
null
;
return
(
n
.
CustomAttributes
.
TryGetValue
(
name
,
out
val
)
&&
val
.
StartsWith
(
value
))
||
(
n
.
Attributes
.
TryGetValue
(
name
,
out
oval
)
&&
oval
.
ToString
().
StartsWith
(
value
));
return
(
n
.
TryGetAttribute
(
name
,
out
val
)
&&
val
.
StartsWith
(
value
));
}));
}
...
...
@@ -89,9 +85,7 @@ namespace Svg.Css
:
(
nodes
=>
nodes
.
Where
(
n
=>
{
string
val
=
null
;
object
oval
=
null
;
return
(
n
.
CustomAttributes
.
TryGetValue
(
name
,
out
val
)
&&
val
.
EndsWith
(
value
))
||
(
n
.
Attributes
.
TryGetValue
(
name
,
out
oval
)
&&
oval
.
ToString
().
EndsWith
(
value
));
return
(
n
.
TryGetAttribute
(
name
,
out
val
)
&&
val
.
EndsWith
(
value
));
}));
}
...
...
@@ -102,9 +96,7 @@ namespace Svg.Css
:
(
nodes
=>
nodes
.
Where
(
n
=>
{
string
val
=
null
;
object
oval
=
null
;
return
(
n
.
CustomAttributes
.
TryGetValue
(
name
,
out
val
)
&&
val
.
Contains
(
value
))
||
(
n
.
Attributes
.
TryGetValue
(
name
,
out
oval
)
&&
oval
.
ToString
().
Contains
(
value
));
return
(
n
.
TryGetAttribute
(
name
,
out
val
)
&&
val
.
Contains
(
value
));
}));
}
...
...
Source/DataTypes/SvgCoordinateUnits.cs
View file @
1585c700
...
...
@@ -2,14 +2,17 @@
using
System.Collections.Generic
;
using
System.Linq
;
using
System.Text
;
using
System.ComponentModel
;
namespace
Svg
{
/// <summary>
/// Defines the various coordinate units certain SVG elements may use.
/// </summary>
[
TypeConverter
(
typeof
(
SvgCoordinateUnitsConverter
))]
public
enum
SvgCoordinateUnits
{
Inherit
,
/// <summary>
/// Indicates that the coordinate system of the owner element is to be used.
/// </summary>
...
...
Source/DataTypes/SvgOverflow.cs
View file @
1585c700
...
...
@@ -7,10 +7,10 @@ namespace Svg
{
public
enum
SvgOverflow
{
inherit
,
auto
,
visible
,
hidden
,
scroll
,
inherit
scroll
}
}
Source/DataTypes/SvgPoint.cs
View file @
1585c700
...
...
@@ -23,7 +23,7 @@ namespace Svg
set
{
this
.
y
=
value
;
}
}
public
PointF
ToDeviceValue
(
SvgRenderer
renderer
,
SvgElement
owner
)
public
PointF
ToDeviceValue
(
I
SvgRenderer
renderer
,
SvgElement
owner
)
{
return
SvgUnit
.
GetDevicePoint
(
this
.
X
,
this
.
Y
,
renderer
,
owner
);
}
...
...
Source/DataTypes/SvgPointCollection.cs
0 → 100644
View file @
1585c700
using
System
;
using
System.Collections.Generic
;
using
System.Linq
;
using
System.Text
;
using
System.ComponentModel
;
using
System.Globalization
;
namespace
Svg
{
/// <summary>
/// Represents a list of <see cref="SvgUnits"/> used with the <see cref="SvgPolyline"/> and <see cref="SvgPolygon"/>.
/// </summary>
[
TypeConverter
(
typeof
(
SvgPointCollectionConverter
))]
public
class
SvgPointCollection
:
List
<
SvgUnit
>
{
public
override
string
ToString
()
{
string
ret
=
""
;
foreach
(
var
unit
in
this
)
{
ret
+=
unit
.
ToString
()
+
" "
;
}
return
ret
;
}
}
/// <summary>
/// A class to convert string into <see cref="SvgUnitCollection"/> instances.
/// </summary>
internal
class
SvgPointCollectionConverter
:
TypeConverter
{
//private static readonly SvgUnitConverter _unitConverter = new SvgUnitConverter();
/// <summary>
/// Converts the given object to the type of this converter, using the specified context and culture information.
/// </summary>
/// <param name="context">An <see cref="T:System.ComponentModel.ITypeDescriptorContext"/> that provides a format context.</param>
/// <param name="culture">The <see cref="T:System.Globalization.CultureInfo"/> to use as the current culture.</param>
/// <param name="value">The <see cref="T:System.Object"/> to convert.</param>
/// <returns>
/// An <see cref="T:System.Object"/> that represents the converted value.
/// </returns>
/// <exception cref="T:System.NotSupportedException">The conversion cannot be performed. </exception>
public
override
object
ConvertFrom
(
ITypeDescriptorContext
context
,
System
.
Globalization
.
CultureInfo
culture
,
object
value
)
{
if
(
value
is
string
)
{
var
strValue
=
((
string
)
value
).
Trim
();
if
(
string
.
Compare
(
strValue
,
"none"
,
StringComparison
.
InvariantCultureIgnoreCase
)
==
0
)
return
null
;
var
parser
=
new
CoordinateParser
(
strValue
);
var
pointValue
=
0.0f
;
var
result
=
new
SvgPointCollection
();
while
(
parser
.
TryGetFloat
(
out
pointValue
))
{
result
.
Add
(
new
SvgUnit
(
SvgUnitType
.
User
,
pointValue
));
}
return
result
;
}
return
base
.
ConvertFrom
(
context
,
culture
,
value
);
}
public
override
bool
CanConvertTo
(
ITypeDescriptorContext
context
,
Type
destinationType
)
{
if
(
destinationType
==
typeof
(
string
))
{
return
true
;
}
return
base
.
CanConvertTo
(
context
,
destinationType
);
}
public
override
object
ConvertTo
(
ITypeDescriptorContext
context
,
CultureInfo
culture
,
object
value
,
Type
destinationType
)
{
if
(
destinationType
==
typeof
(
string
))
{
return
((
SvgPointCollection
)
value
).
ToString
();
}
return
base
.
ConvertTo
(
context
,
culture
,
value
,
destinationType
);
}
}
}
Source/DataTypes/SvgTextLengthAdjust.cs
0 → 100644
View file @
1585c700
using
System
;
using
System.Collections.Generic
;
using
System.Linq
;
using
System.Text
;
namespace
Svg
{
public
enum
SvgTextLengthAdjust
{
spacing
,
spacingAndGlyphs
}
}
Prev
1
2
3
4
5
6
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