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
bcf5b85c
Commit
bcf5b85c
authored
Aug 07, 2015
by
Tebjan Halm
Browse files
Merge pull request #171 from ubbn/master
Added new Draw method
parents
2c3265fc
caae2cce
Changes
10
Hide whitespace changes
Inline
Side-by-side
Source/Basic Shapes/SvgCircle.cs
View file @
bcf5b85c
...
@@ -100,15 +100,24 @@ namespace Svg
...
@@ -100,15 +100,24 @@ namespace Svg
/// </summary>
/// </summary>
public
override
GraphicsPath
Path
(
ISvgRenderer
renderer
)
public
override
GraphicsPath
Path
(
ISvgRenderer
renderer
)
{
{
if
(
this
.
_path
==
null
||
this
.
IsPathDirty
)
if
(
(
this
.
_path
==
null
||
this
.
IsPathDirty
)
&&
base
.
StrokeWidth
>
0
)
{
{
float
halfStrokeWidth
=
base
.
StrokeWidth
/
2
;
// If it is to render, don't need to consider stroke width.
// i.e stroke width only to be considered when calculating boundary
if
(
renderer
!=
null
)
{
halfStrokeWidth
=
0
;
this
.
IsPathDirty
=
false
;
}
_path
=
new
GraphicsPath
();
_path
=
new
GraphicsPath
();
_path
.
StartFigure
();
_path
.
StartFigure
();
var
center
=
this
.
Center
.
ToDeviceValue
(
renderer
,
this
);
var
center
=
this
.
Center
.
ToDeviceValue
(
renderer
,
this
);
var
radius
=
this
.
Radius
.
ToDeviceValue
(
renderer
,
UnitRenderingType
.
Other
,
this
);
var
radius
=
this
.
Radius
.
ToDeviceValue
(
renderer
,
UnitRenderingType
.
Other
,
this
)
+
halfStrokeWidth
;
_path
.
AddEllipse
(
center
.
X
-
radius
,
center
.
Y
-
radius
,
2
*
radius
,
2
*
radius
);
_path
.
AddEllipse
(
center
.
X
-
radius
,
center
.
Y
-
radius
,
2
*
radius
,
2
*
radius
);
_path
.
CloseFigure
();
_path
.
CloseFigure
();
this
.
IsPathDirty
=
false
;
}
}
return
_path
;
return
_path
;
}
}
...
...
Source/Basic Shapes/SvgEllipse.cs
View file @
bcf5b85c
...
@@ -104,16 +104,25 @@ namespace Svg
...
@@ -104,16 +104,25 @@ namespace Svg
/// <value></value>
/// <value></value>
public
override
GraphicsPath
Path
(
ISvgRenderer
renderer
)
public
override
GraphicsPath
Path
(
ISvgRenderer
renderer
)
{
{
if
(
this
.
_path
==
null
||
this
.
IsPathDirty
)
if
(
(
this
.
_path
==
null
||
this
.
IsPathDirty
)
&&
base
.
StrokeWidth
>
0
)
{
{
float
halfStrokeWidth
=
base
.
StrokeWidth
/
2
;
// If it is to render, don't need to consider stroke width.
// i.e stroke width only to be considered when calculating boundary
if
(
renderer
!=
null
)
{
halfStrokeWidth
=
0
;
this
.
IsPathDirty
=
false
;
}
var
center
=
SvgUnit
.
GetDevicePoint
(
this
.
_centerX
,
this
.
_centerY
,
renderer
,
this
);
var
center
=
SvgUnit
.
GetDevicePoint
(
this
.
_centerX
,
this
.
_centerY
,
renderer
,
this
);
var
radius
=
SvgUnit
.
GetDevicePoint
(
this
.
_radiusX
,
this
.
_radiusY
,
renderer
,
this
);
var
radius
=
SvgUnit
.
GetDevicePoint
(
this
.
_radiusX
+
halfStrokeWidth
,
this
.
_radiusY
+
halfStrokeWidth
,
renderer
,
this
);
this
.
_path
=
new
GraphicsPath
();
this
.
_path
=
new
GraphicsPath
();
_path
.
StartFigure
();
_path
.
StartFigure
();
_path
.
AddEllipse
(
center
.
X
-
radius
.
X
,
center
.
Y
-
radius
.
Y
,
2
*
radius
.
X
,
2
*
radius
.
Y
);
_path
.
AddEllipse
(
center
.
X
-
radius
.
X
,
center
.
Y
-
radius
.
Y
,
2
*
radius
.
X
,
2
*
radius
.
Y
);
_path
.
CloseFigure
();
_path
.
CloseFigure
();
this
.
IsPathDirty
=
false
;
}
}
return
_path
;
return
_path
;
}
}
...
...
Source/Basic Shapes/SvgImage.cs
View file @
bcf5b85c
...
@@ -23,6 +23,8 @@ namespace Svg
...
@@ -23,6 +23,8 @@ namespace Svg
Height
=
new
SvgUnit
(
0.0f
);
Height
=
new
SvgUnit
(
0.0f
);
}
}
private
GraphicsPath
_path
;
/// <summary>
/// <summary>
/// Gets an <see cref="SvgPoint"/> representing the top left point of the rectangle.
/// Gets an <see cref="SvgPoint"/> representing the top left point of the rectangle.
/// </summary>
/// </summary>
...
@@ -96,7 +98,19 @@ namespace Svg
...
@@ -96,7 +98,19 @@ namespace Svg
/// </summary>
/// </summary>
public
override
GraphicsPath
Path
(
ISvgRenderer
renderer
)
public
override
GraphicsPath
Path
(
ISvgRenderer
renderer
)
{
{
return
null
;
if
(
_path
==
null
)
{
// Same size of rectangle can suffice to provide bounds of the image
var
rectangle
=
new
RectangleF
(
Location
.
ToDeviceValue
(
renderer
,
this
),
SvgUnit
.
GetDeviceSize
(
Width
,
Height
,
renderer
,
this
));
_path
=
new
GraphicsPath
();
_path
.
StartFigure
();
_path
.
AddRectangle
(
rectangle
);
_path
.
CloseFigure
();
}
return
_path
;
}
}
/// <summary>
/// <summary>
...
...
Source/Basic Shapes/SvgLine.cs
View file @
bcf5b85c
...
@@ -126,7 +126,7 @@ namespace Svg
...
@@ -126,7 +126,7 @@ namespace Svg
public
override
System
.
Drawing
.
Drawing2D
.
GraphicsPath
Path
(
ISvgRenderer
renderer
)
public
override
System
.
Drawing
.
Drawing2D
.
GraphicsPath
Path
(
ISvgRenderer
renderer
)
{
{
if
(
this
.
_path
==
null
||
this
.
IsPathDirty
)
if
(
(
this
.
_path
==
null
||
this
.
IsPathDirty
)
&&
base
.
StrokeWidth
>
0
)
{
{
PointF
start
=
new
PointF
(
this
.
StartX
.
ToDeviceValue
(
renderer
,
UnitRenderingType
.
Horizontal
,
this
),
PointF
start
=
new
PointF
(
this
.
StartX
.
ToDeviceValue
(
renderer
,
UnitRenderingType
.
Horizontal
,
this
),
this
.
StartY
.
ToDeviceValue
(
renderer
,
UnitRenderingType
.
Vertical
,
this
));
this
.
StartY
.
ToDeviceValue
(
renderer
,
UnitRenderingType
.
Vertical
,
this
));
...
@@ -134,8 +134,22 @@ namespace Svg
...
@@ -134,8 +134,22 @@ namespace Svg
this
.
EndY
.
ToDeviceValue
(
renderer
,
UnitRenderingType
.
Vertical
,
this
));
this
.
EndY
.
ToDeviceValue
(
renderer
,
UnitRenderingType
.
Vertical
,
this
));
this
.
_path
=
new
GraphicsPath
();
this
.
_path
=
new
GraphicsPath
();
this
.
_path
.
AddLine
(
start
,
end
);
this
.
IsPathDirty
=
false
;
// If it is to render, don't need to consider stroke width.
// i.e stroke width only to be considered when calculating boundary
if
(
renderer
!=
null
)
{
this
.
_path
.
AddLine
(
start
,
end
);
this
.
IsPathDirty
=
false
;
}
else
{
// only when calculating boundary
_path
.
StartFigure
();
var
radius
=
base
.
StrokeWidth
/
2
;
_path
.
AddEllipse
(
start
.
X
-
radius
,
start
.
Y
-
radius
,
2
*
radius
,
2
*
radius
);
_path
.
AddEllipse
(
end
.
X
-
radius
,
end
.
Y
-
radius
,
2
*
radius
,
2
*
radius
);
_path
.
CloseFigure
();
}
}
}
return
this
.
_path
;
return
this
.
_path
;
}
}
...
...
Source/Basic Shapes/SvgPolygon.cs
View file @
bcf5b85c
...
@@ -65,7 +65,7 @@ namespace Svg
...
@@ -65,7 +65,7 @@ namespace Svg
public
override
GraphicsPath
Path
(
ISvgRenderer
renderer
)
public
override
GraphicsPath
Path
(
ISvgRenderer
renderer
)
{
{
if
(
this
.
_path
==
null
||
this
.
IsPathDirty
)
if
(
(
this
.
_path
==
null
||
this
.
IsPathDirty
)
&&
base
.
StrokeWidth
>
0
)
{
{
this
.
_path
=
new
GraphicsPath
();
this
.
_path
=
new
GraphicsPath
();
this
.
_path
.
StartFigure
();
this
.
_path
.
StartFigure
();
...
@@ -77,6 +77,15 @@ namespace Svg
...
@@ -77,6 +77,15 @@ namespace Svg
{
{
var
endPoint
=
SvgUnit
.
GetDevicePoint
(
points
[
i
],
points
[
i
+
1
],
renderer
,
this
);
var
endPoint
=
SvgUnit
.
GetDevicePoint
(
points
[
i
],
points
[
i
+
1
],
renderer
,
this
);
// If it is to render, don't need to consider stroke width.
// i.e stroke width only to be considered when calculating boundary
if
(
renderer
==
null
)
{
var
radius
=
base
.
StrokeWidth
/
2
;
_path
.
AddEllipse
(
endPoint
.
X
-
radius
,
endPoint
.
Y
-
radius
,
2
*
radius
,
2
*
radius
);
continue
;
}
//first line
//first line
if
(
_path
.
PointCount
==
0
)
if
(
_path
.
PointCount
==
0
)
{
{
...
@@ -94,7 +103,8 @@ namespace Svg
...
@@ -94,7 +103,8 @@ namespace Svg
}
}
this
.
_path
.
CloseFigure
();
this
.
_path
.
CloseFigure
();
this
.
IsPathDirty
=
false
;
if
(
renderer
!=
null
)
this
.
IsPathDirty
=
false
;
}
}
return
this
.
_path
;
return
this
.
_path
;
}
}
...
...
Source/Basic Shapes/SvgPolyline.cs
View file @
bcf5b85c
...
@@ -48,7 +48,7 @@ namespace Svg
...
@@ -48,7 +48,7 @@ namespace Svg
private
GraphicsPath
_Path
;
private
GraphicsPath
_Path
;
public
override
GraphicsPath
Path
(
ISvgRenderer
renderer
)
public
override
GraphicsPath
Path
(
ISvgRenderer
renderer
)
{
{
if
(
_Path
==
null
||
this
.
IsPathDirty
)
if
(
(
_Path
==
null
||
this
.
IsPathDirty
)
&&
base
.
StrokeWidth
>
0
)
{
{
_Path
=
new
GraphicsPath
();
_Path
=
new
GraphicsPath
();
...
@@ -59,6 +59,13 @@ namespace Svg
...
@@ -59,6 +59,13 @@ namespace Svg
PointF
endPoint
=
new
PointF
(
Points
[
i
].
ToDeviceValue
(
renderer
,
UnitRenderingType
.
Horizontal
,
this
),
PointF
endPoint
=
new
PointF
(
Points
[
i
].
ToDeviceValue
(
renderer
,
UnitRenderingType
.
Horizontal
,
this
),
Points
[
i
+
1
].
ToDeviceValue
(
renderer
,
UnitRenderingType
.
Vertical
,
this
));
Points
[
i
+
1
].
ToDeviceValue
(
renderer
,
UnitRenderingType
.
Vertical
,
this
));
if
(
renderer
==
null
)
{
var
radius
=
base
.
StrokeWidth
/
2
;
_Path
.
AddEllipse
(
endPoint
.
X
-
radius
,
endPoint
.
Y
-
radius
,
2
*
radius
,
2
*
radius
);
continue
;
}
// TODO: Remove unrequired first line
// TODO: Remove unrequired first line
if
(
_Path
.
PointCount
==
0
)
if
(
_Path
.
PointCount
==
0
)
{
{
...
@@ -74,7 +81,8 @@ namespace Svg
...
@@ -74,7 +81,8 @@ namespace Svg
{
{
Trace
.
TraceError
(
"Error rendering points: "
+
exc
.
Message
);
Trace
.
TraceError
(
"Error rendering points: "
+
exc
.
Message
);
}
}
this
.
IsPathDirty
=
false
;
if
(
renderer
!=
null
)
this
.
IsPathDirty
=
false
;
}
}
return
_Path
;
return
_Path
;
}
}
...
...
Source/Basic Shapes/SvgRectangle.cs
View file @
bcf5b85c
...
@@ -176,13 +176,25 @@ namespace Svg
...
@@ -176,13 +176,25 @@ namespace Svg
/// </summary>
/// </summary>
public
override
GraphicsPath
Path
(
ISvgRenderer
renderer
)
public
override
GraphicsPath
Path
(
ISvgRenderer
renderer
)
{
{
if
(
_path
==
null
||
IsPathDirty
)
if
(
(
_path
==
null
||
IsPathDirty
)
&&
base
.
StrokeWidth
>
0
)
{
{
float
halfStrokeWidth
=
base
.
StrokeWidth
/
2
;
// If it is to render, don't need to consider stroke
if
(
renderer
!=
null
)
{
halfStrokeWidth
=
0
;
this
.
IsPathDirty
=
false
;
}
// If the corners aren't to be rounded just create a rectangle
// If the corners aren't to be rounded just create a rectangle
if
(
CornerRadiusX
.
Value
==
0.0f
&&
CornerRadiusY
.
Value
==
0.0f
)
if
(
CornerRadiusX
.
Value
==
0.0f
&&
CornerRadiusY
.
Value
==
0.0f
)
{
{
var
rectangle
=
new
RectangleF
(
Location
.
ToDeviceValue
(
renderer
,
this
),
// Starting location which take consideration of stroke width
SvgUnit
.
GetDeviceSize
(
this
.
Width
,
this
.
Height
,
renderer
,
this
));
SvgPoint
strokedLocation
=
new
SvgPoint
(
Location
.
X
-
halfStrokeWidth
,
Location
.
Y
-
halfStrokeWidth
);
var
rectangle
=
new
RectangleF
(
strokedLocation
.
ToDeviceValue
(
renderer
,
this
),
SvgUnit
.
GetDeviceSize
(
this
.
Width
+
halfStrokeWidth
*
2
,
this
.
Height
+
halfStrokeWidth
*
2
,
renderer
,
this
));
_path
=
new
GraphicsPath
();
_path
=
new
GraphicsPath
();
_path
.
StartFigure
();
_path
.
StartFigure
();
...
@@ -253,7 +265,6 @@ namespace Svg
...
@@ -253,7 +265,6 @@ namespace Svg
// Close
// Close
_path
.
CloseFigure
();
_path
.
CloseFigure
();
}
}
IsPathDirty
=
false
;
}
}
return
_path
;
return
_path
;
}
}
...
...
Source/Document Structure/SvgFragment.cs
View file @
bcf5b85c
...
@@ -244,12 +244,13 @@ namespace Svg
...
@@ -244,12 +244,13 @@ namespace Svg
else
else
{
{
bounds
=
this
.
Bounds
;
//do just one call to the recursive bounds property
bounds
=
this
.
Bounds
;
//do just one call to the recursive bounds property
this
.
ViewBox
=
new
SvgViewBox
(
bounds
.
X
,
bounds
.
Y
,
bounds
.
Width
,
bounds
.
Height
);
}
}
}
}
if
(
isWidthperc
)
if
(
isWidthperc
)
{
{
w
=
(
bounds
.
Width
+
bounds
.
X
)
*
(
Width
.
Value
*
0.01f
);
w
=
(
bounds
.
Width
)
*
(
Width
.
Value
*
0.01f
);
}
}
else
else
{
{
...
@@ -257,7 +258,7 @@ namespace Svg
...
@@ -257,7 +258,7 @@ namespace Svg
}
}
if
(
isHeightperc
)
if
(
isHeightperc
)
{
{
h
=
(
bounds
.
Height
+
bounds
.
Y
)
*
(
Height
.
Value
*
0.01f
);
h
=
(
bounds
.
Height
)
*
(
Height
.
Value
*
0.01f
);
}
}
else
else
{
{
...
...
Source/SvgDocument.cs
View file @
bcf5b85c
...
@@ -473,8 +473,10 @@ namespace Svg
...
@@ -473,8 +473,10 @@ namespace Svg
//EO, 2014-12-05: Requested to ensure proper zooming (draw the svg in the bitmap size, ==> proper scaling)
//EO, 2014-12-05: Requested to ensure proper zooming (draw the svg in the bitmap size, ==> proper scaling)
//EO, 2015-01-09, Added GetDimensions to use its returned size instead of this.Width and this.Height (request of Icarrere).
//EO, 2015-01-09, Added GetDimensions to use its returned size instead of this.Width and this.Height (request of Icarrere).
SizeF
size
=
this
.
GetDimensions
();
renderer
.
ScaleTransform
(
bitmap
.
Width
/
size
.
Width
,
bitmap
.
Height
/
size
.
Height
);
//BBN, 2015-07-29, it is unnecassary to call again GetDimensions and transform to 1x1
//SizeF size = this.GetDimensions();
//renderer.ScaleTransform(bitmap.Width / size.Width, bitmap.Height / size.Height);
//EO, 2014-12-05: Requested to ensure proper zooming out (reduce size). Otherwise it clip the image.
//EO, 2014-12-05: Requested to ensure proper zooming out (reduce size). Otherwise it clip the image.
this
.
Overflow
=
SvgOverflow
.
Auto
;
this
.
Overflow
=
SvgOverflow
.
Auto
;
...
@@ -490,6 +492,61 @@ namespace Svg
...
@@ -490,6 +492,61 @@ namespace Svg
//Trace.TraceInformation("End Render");
//Trace.TraceInformation("End Render");
}
}
/// <summary>
/// Renders the <see cref="SvgDocument"/> in given size and returns the image as a <see cref="Bitmap"/>.
/// </summary>
/// <returns>A <see cref="Bitmap"/> containing the rendered document.</returns>
public
virtual
Bitmap
Draw
(
int
rasterWidth
,
int
rasterHeight
)
{
var
size
=
GetDimensions
();
RasterizeDimensions
(
ref
size
,
rasterWidth
,
rasterHeight
);
if
(
size
.
Width
==
0
||
size
.
Height
==
0
)
return
null
;
var
bitmap
=
new
Bitmap
((
int
)
Math
.
Round
(
size
.
Width
),
(
int
)
Math
.
Round
(
size
.
Height
));
try
{
Draw
(
bitmap
);
}
catch
{
bitmap
.
Dispose
();
throw
;
}
//Trace.TraceInformation("End Render");
return
bitmap
;
}
/// <summary>
/// If both or one of raster height and width is not given (0), calculate that missing value from original SVG size
/// while keeping original SVG size ratio
/// </summary>
/// <param name="size"></param>
/// <param name="rasterWidth"></param>
/// <param name="rasterHeight"></param>
public
virtual
void
RasterizeDimensions
(
ref
SizeF
size
,
int
rasterWidth
,
int
rasterHeight
)
{
if
(
size
==
null
||
size
.
Width
==
0
)
return
;
// Ratio of height/width of the original SVG size, to be used for scaling transformation
float
ratio
=
size
.
Height
/
size
.
Width
;
size
.
Width
=
rasterWidth
>
0
?
(
float
)
rasterWidth
:
size
.
Width
;
size
.
Height
=
rasterHeight
>
0
?
(
float
)
rasterHeight
:
size
.
Height
;
if
(
rasterHeight
==
0
&&
rasterWidth
>
0
)
{
size
.
Height
=
(
int
)(
rasterWidth
*
ratio
);
}
else
if
(
rasterHeight
>
0
&&
rasterWidth
==
0
)
{
size
.
Width
=
(
int
)(
rasterHeight
/
ratio
);
}
}
public
override
void
Write
(
XmlTextWriter
writer
)
public
override
void
Write
(
XmlTextWriter
writer
)
{
{
//Save previous culture and switch to invariant for writing
//Save previous culture and switch to invariant for writing
...
...
Source/SvgElement.cs
View file @
bcf5b85c
...
@@ -745,6 +745,12 @@ namespace Svg
...
@@ -745,6 +745,12 @@ namespace Svg
{
{
foreach
(
var
child
in
elem
.
Children
)
foreach
(
var
child
in
elem
.
Children
)
{
{
// Skip to avoid double calculate Symbol element
// symbol element is only referenced by use element
// So here we need to skip when it is directly considered
if
(
child
is
Svg
.
Document_Structure
.
SvgSymbol
)
continue
;
if
(
child
is
SvgVisualElement
)
if
(
child
is
SvgVisualElement
)
{
{
if
(!(
child
is
SvgGroup
))
if
(!(
child
is
SvgGroup
))
...
@@ -783,7 +789,7 @@ namespace Svg
...
@@ -783,7 +789,7 @@ namespace Svg
{
{
var
childPath
=
((
SvgVisualElement
)
child
).
Path
(
renderer
);
var
childPath
=
((
SvgVisualElement
)
child
).
Path
(
renderer
);
if
(
childPath
!=
null
)
if
(
childPath
!=
null
&&
childPath
.
PointCount
>
0
)
{
{
childPath
=
(
GraphicsPath
)
childPath
.
Clone
();
childPath
=
(
GraphicsPath
)
childPath
.
Clone
();
if
(
child
.
Transforms
!=
null
)
if
(
child
.
Transforms
!=
null
)
...
...
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