Commit bcf5b85c authored by Tebjan Halm's avatar Tebjan Halm
Browse files

Merge pull request #171 from ubbn/master

Added new Draw method
parents 2c3265fc caae2cce
......@@ -100,15 +100,24 @@ namespace Svg
/// </summary>
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.StartFigure();
var center = this.Center.ToDeviceValue(renderer, this);
var radius = this.Radius.ToDeviceValue(renderer, UnitRenderingType.Other, this);
_path.AddEllipse(center.X - radius, center.Y - radius, 2 * radius, 2 * radius);
var center = this.Center.ToDeviceValue(renderer, this);
var radius = this.Radius.ToDeviceValue(renderer, UnitRenderingType.Other, this) + halfStrokeWidth;
_path.AddEllipse(center.X - radius, center.Y - radius, 2 * radius, 2 * radius);
_path.CloseFigure();
this.IsPathDirty = false;
}
return _path;
}
......
......@@ -104,16 +104,25 @@ namespace Svg
/// <value></value>
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 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();
_path.StartFigure();
_path.AddEllipse(center.X - radius.X, center.Y - radius.Y, 2 * radius.X, 2 * radius.Y);
_path.CloseFigure();
this.IsPathDirty = false;
}
return _path;
}
......
......@@ -23,6 +23,8 @@ namespace Svg
Height = new SvgUnit(0.0f);
}
private GraphicsPath _path;
/// <summary>
/// Gets an <see cref="SvgPoint"/> representing the top left point of the rectangle.
/// </summary>
......@@ -96,7 +98,19 @@ namespace Svg
/// </summary>
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>
......
......@@ -126,7 +126,7 @@ namespace Svg
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),
this.StartY.ToDeviceValue(renderer, UnitRenderingType.Vertical, this));
......@@ -134,8 +134,22 @@ namespace Svg
this.EndY.ToDeviceValue(renderer, UnitRenderingType.Vertical, this));
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;
}
......
......@@ -65,7 +65,7 @@ namespace Svg
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.StartFigure();
......@@ -77,6 +77,15 @@ namespace Svg
{
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
if (_path.PointCount == 0)
{
......@@ -94,7 +103,8 @@ namespace Svg
}
this._path.CloseFigure();
this.IsPathDirty = false;
if (renderer != null)
this.IsPathDirty = false;
}
return this._path;
}
......
......@@ -48,7 +48,7 @@ namespace Svg
private GraphicsPath _Path;
public override GraphicsPath Path(ISvgRenderer renderer)
{
if (_Path == null || this.IsPathDirty)
if ((_Path == null || this.IsPathDirty) && base.StrokeWidth > 0)
{
_Path = new GraphicsPath();
......@@ -59,6 +59,13 @@ namespace Svg
PointF endPoint = new PointF(Points[i].ToDeviceValue(renderer, UnitRenderingType.Horizontal, 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
if (_Path.PointCount == 0)
{
......@@ -74,7 +81,8 @@ namespace Svg
{
Trace.TraceError("Error rendering points: " + exc.Message);
}
this.IsPathDirty = false;
if (renderer != null)
this.IsPathDirty = false;
}
return _Path;
}
......
......@@ -176,13 +176,25 @@ namespace Svg
/// </summary>
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 (CornerRadiusX.Value == 0.0f && CornerRadiusY.Value == 0.0f)
{
var rectangle = new RectangleF(Location.ToDeviceValue(renderer, this),
SvgUnit.GetDeviceSize(this.Width, this.Height, renderer, this));
// Starting location which take consideration of stroke width
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.StartFigure();
......@@ -253,7 +265,6 @@ namespace Svg
// Close
_path.CloseFigure();
}
IsPathDirty = false;
}
return _path;
}
......
......@@ -244,12 +244,13 @@ namespace Svg
else
{
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)
{
w = (bounds.Width + bounds.X) * (Width.Value * 0.01f);
w = (bounds.Width) * (Width.Value * 0.01f);
}
else
{
......@@ -257,7 +258,7 @@ namespace Svg
}
if (isHeightperc)
{
h = (bounds.Height + bounds.Y) * (Height.Value * 0.01f);
h = (bounds.Height) * (Height.Value * 0.01f);
}
else
{
......
......@@ -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, 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.
this.Overflow = SvgOverflow.Auto;
......@@ -490,6 +492,61 @@ namespace Svg
//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)
{
//Save previous culture and switch to invariant for writing
......
......@@ -745,6 +745,12 @@ namespace Svg
{
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 SvgGroup))
......@@ -783,7 +789,7 @@ namespace Svg
{
var childPath = ((SvgVisualElement)child).Path(renderer);
if (childPath != null)
if (childPath != null && childPath.PointCount > 0)
{
childPath = (GraphicsPath)childPath.Clone();
if(child.Transforms != null)
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment