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
780b5150
Commit
780b5150
authored
Sep 23, 2014
by
Tebjan Halm
Browse files
Merge pull request #93 from erdomke/master
Initial Filter, Svg Font, and Text on a Path Support
parents
1bc4c0f3
4200d302
Changes
107
Hide whitespace changes
Inline
Side-by-side
Samples/SVGViewer/DebugRenderer.cs
0 → 100644
View file @
780b5150
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 @
780b5150
...
...
@@ -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 @
780b5150
...
...
@@ -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 @
780b5150
...
...
@@ -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 @
780b5150
...
...
@@ -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 @
780b5150
...
...
@@ -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 @
780b5150
...
...
@@ -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 @
780b5150
...
...
@@ -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 @
780b5150
...
...
@@ -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 @
780b5150
...
...
@@ -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 @
780b5150
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 @
780b5150
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 @
780b5150
...
...
@@ -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 @
780b5150
...
...
@@ -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 @
780b5150
...
...
@@ -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 @
780b5150
...
...
@@ -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 @
780b5150
...
...
@@ -7,10 +7,10 @@ namespace Svg
{
public
enum
SvgOverflow
{
inherit
,
auto
,
visible
,
hidden
,
scroll
,
inherit
scroll
}
}
Source/DataTypes/SvgPoint.cs
View file @
780b5150
...
...
@@ -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 @
780b5150
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 @
780b5150
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