Commit 7c70bd11 authored by Eric Domke's avatar Eric Domke
Browse files

Text on a Path & SVG Fonts

- Extraction interface for SvgRenderer
- Initial support for Text on a Path
- Initial support for Svg Fonts
- Support for symbol element
- Minor bug fixes with image pattern rendering
- Additional support for Text whitespace modes
parent 1a00f391
...@@ -148,86 +148,13 @@ namespace Svg ...@@ -148,86 +148,13 @@ namespace Svg
} }
/// <summary> /// <summary>
/// Applies the required transforms to <see cref="SvgRenderer"/>. /// Applies the required transforms to <see cref="ISvgRenderer"/>.
/// </summary> /// </summary>
/// <param name="renderer">The <see cref="SvgRenderer"/> to be transformed.</param> /// <param name="renderer">The <see cref="ISvgRenderer"/> to be transformed.</param>
protected internal override bool PushTransforms(SvgRenderer renderer) protected internal override bool PushTransforms(ISvgRenderer renderer)
{ {
if (!base.PushTransforms(renderer)) return false; if (!base.PushTransforms(renderer)) return false;
this.ViewBox.AddViewBoxTransform(this.AspectRatio, renderer, this);
if (!this.ViewBox.Equals(SvgViewBox.Empty))
{
var width = this.Width.ToDeviceValue(renderer, UnitRenderingType.Horizontal, this);
var height = this.Height.ToDeviceValue(renderer, UnitRenderingType.Vertical, this);
var fScaleX = width / this.ViewBox.Width;
var fScaleY = height / this.ViewBox.Height;
var fMinX = -this.ViewBox.MinX;
var fMinY = -this.ViewBox.MinY;
if (AspectRatio.Align != SvgPreserveAspectRatio.none)
{
if (AspectRatio.Slice)
{
fScaleX = Math.Max(fScaleX, fScaleY);
fScaleY = Math.Max(fScaleX, fScaleY);
}
else
{
fScaleX = Math.Min(fScaleX, fScaleY);
fScaleY = Math.Min(fScaleX, fScaleY);
}
float fViewMidX = (this.ViewBox.Width / 2) * fScaleX;
float fViewMidY = (this.ViewBox.Height / 2) * fScaleY;
float fMidX = width / 2;
float fMidY = height / 2;
switch (AspectRatio.Align)
{
case SvgPreserveAspectRatio.xMinYMin:
break;
case SvgPreserveAspectRatio.xMidYMin:
fMinX += fMidX - fViewMidX;
break;
case SvgPreserveAspectRatio.xMaxYMin:
fMinX += width - this.ViewBox.Width * fScaleX;
break;
case SvgPreserveAspectRatio.xMinYMid:
fMinY += fMidY - fViewMidY;
break;
case SvgPreserveAspectRatio.xMidYMid:
fMinX += fMidX - fViewMidX;
fMinY += fMidY - fViewMidY;
break;
case SvgPreserveAspectRatio.xMaxYMid:
fMinX += width - this.ViewBox.Width * fScaleX;
fMinY += fMidY - fViewMidY;
break;
case SvgPreserveAspectRatio.xMinYMax:
fMinY += height - this.ViewBox.Height * fScaleY;
break;
case SvgPreserveAspectRatio.xMidYMax:
fMinX += fMidX - fViewMidX;
fMinY += height - this.ViewBox.Height * fScaleY;
break;
case SvgPreserveAspectRatio.xMaxYMax:
fMinX += width - this.ViewBox.Width * fScaleX;
fMinY += height - this.ViewBox.Height * fScaleY;
break;
default:
break;
}
}
var x = _x.ToDeviceValue(renderer, UnitRenderingType.Horizontal, this);
var y = _y.ToDeviceValue(renderer, UnitRenderingType.Vertical, this);
renderer.AddClip(new Region(new RectangleF(x, y, width, height)));
renderer.ScaleTransform(fScaleX, fScaleY, MatrixOrder.Prepend);
renderer.TranslateTransform(x,y);
renderer.TranslateTransform(fMinX, fMinY);
}
return true; return true;
} }
......
...@@ -9,15 +9,11 @@ namespace Svg ...@@ -9,15 +9,11 @@ namespace Svg
[SvgElement("g")] [SvgElement("g")]
public class SvgGroup : SvgVisualElement public class SvgGroup : SvgVisualElement
{ {
public SvgGroup()
{
}
/// <summary> /// <summary>
/// Gets the <see cref="GraphicsPath"/> for this element. /// Gets the <see cref="GraphicsPath"/> for this element.
/// </summary> /// </summary>
/// <value></value> /// <value></value>
public override System.Drawing.Drawing2D.GraphicsPath Path(SvgRenderer renderer) public override System.Drawing.Drawing2D.GraphicsPath Path(ISvgRenderer renderer)
{ {
return GetPaths(this, renderer); return GetPaths(this, renderer);
} }
...@@ -58,25 +54,6 @@ namespace Svg ...@@ -58,25 +54,6 @@ namespace Svg
protected override bool Renderable { get { return false; } } protected override bool Renderable { get { return false; } }
///// <summary>
///// 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)
//{
// if (!Visible || !Displayable)
// return;
// if (this.PushTransforms(renderer))
// {
// this.SetClip(renderer);
// base.RenderChildren(renderer);
// this.ResetClip(renderer);
// this.PopTransforms(renderer);
// }
//}
public override SvgElement DeepCopy() public override SvgElement DeepCopy()
{ {
return DeepCopy<SvgGroup>(); return DeepCopy<SvgGroup>();
......
...@@ -17,7 +17,7 @@ namespace Svg ...@@ -17,7 +17,7 @@ namespace Svg
/// Gets the <see cref="GraphicsPath"/> for this element. /// Gets the <see cref="GraphicsPath"/> for this element.
/// </summary> /// </summary>
/// <value></value> /// <value></value>
public override System.Drawing.Drawing2D.GraphicsPath Path(SvgRenderer renderer) public override System.Drawing.Drawing2D.GraphicsPath Path(ISvgRenderer renderer)
{ {
return GetPaths(this, renderer); return GetPaths(this, renderer);
} }
...@@ -60,7 +60,7 @@ namespace Svg ...@@ -60,7 +60,7 @@ namespace Svg
/// Renders the <see cref="SvgElement"/> and contents to the specified <see cref="Graphics"/> object. /// Renders the <see cref="SvgElement"/> and contents to the specified <see cref="Graphics"/> object.
/// </summary> /// </summary>
/// <param name="renderer">The <see cref="Graphics"/> object to render to.</param> /// <param name="renderer">The <see cref="Graphics"/> object to render to.</param>
protected override void Render(SvgRenderer renderer) protected override void Render(ISvgRenderer renderer)
{ {
if (!Visible || !Displayable) if (!Visible || !Displayable)
return; return;
......
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
namespace Svg.Document_Structure
{
/// <summary>
/// An element used to group SVG shapes.
/// </summary>
[SvgElement("symbol")]
public class SvgSymbol : SvgVisualElement
{
/// <summary>
/// Gets or sets the viewport of the element.
/// </summary>
/// <value></value>
[SvgAttribute("viewBox")]
public SvgViewBox ViewBox
{
get { return this.Attributes.GetAttribute<SvgViewBox>("viewBox"); }
set { this.Attributes["viewBox"] = value; }
}
/// <summary>
/// Gets or sets the aspect of the viewport.
/// </summary>
/// <value></value>
[SvgAttribute("preserveAspectRatio")]
public SvgAspectRatio AspectRatio
{
get { return this.Attributes.GetAttribute<SvgAspectRatio>("preserveAspectRatio"); }
set { this.Attributes["preserveAspectRatio"] = value; }
}
/// <summary>
/// Gets the <see cref="GraphicsPath"/> for this element.
/// </summary>
/// <value></value>
public override System.Drawing.Drawing2D.GraphicsPath Path(ISvgRenderer renderer)
{
return GetPaths(this, renderer);
}
/// <summary>
/// Gets the bounds of the element.
/// </summary>
/// <value>The bounds.</value>
public override System.Drawing.RectangleF Bounds
{
get
{
var r = new RectangleF();
foreach (var c in this.Children)
{
if (c is SvgVisualElement)
{
// First it should check if rectangle is empty or it will return the wrong Bounds.
// This is because when the Rectangle is Empty, the Union method adds as if the first values where X=0, Y=0
if (r.IsEmpty)
{
r = ((SvgVisualElement)c).Bounds;
}
else
{
var childBounds = ((SvgVisualElement)c).Bounds;
if (!childBounds.IsEmpty)
{
r = RectangleF.Union(r, childBounds);
}
}
}
}
return r;
}
}
protected override bool Renderable { get { return false; } }
/// <summary>
/// Applies the required transforms to <see cref="ISvgRenderer"/>.
/// </summary>
/// <param name="renderer">The <see cref="ISvgRenderer"/> to be transformed.</param>
protected internal override bool PushTransforms(ISvgRenderer renderer)
{
if (!base.PushTransforms(renderer)) return false;
this.ViewBox.AddViewBoxTransform(this.AspectRatio, renderer, null);
return true;
}
public override SvgElement DeepCopy()
{
return DeepCopy<SvgSymbol>();
}
public override SvgElement DeepCopy<T>()
{
var newObj = base.DeepCopy<T>() as SvgSymbol;
if (this.Fill != null)
newObj.Fill = this.Fill.DeepCopy() as SvgPaintServer;
return newObj;
}
}
}
...@@ -35,10 +35,10 @@ namespace Svg ...@@ -35,10 +35,10 @@ namespace Svg
} }
/// <summary> /// <summary>
/// Applies the required transforms to <see cref="SvgRenderer"/>. /// Applies the required transforms to <see cref="ISvgRenderer"/>.
/// </summary> /// </summary>
/// <param name="renderer">The <see cref="SvgRenderer"/> to be transformed.</param> /// <param name="renderer">The <see cref="ISvgRenderer"/> to be transformed.</param>
protected internal override bool PushTransforms(SvgRenderer renderer) protected internal override bool PushTransforms(ISvgRenderer renderer)
{ {
if (!base.PushTransforms(renderer)) return false; if (!base.PushTransforms(renderer)) return false;
renderer.TranslateTransform(this.X.ToDeviceValue(renderer, UnitRenderingType.Horizontal, this), renderer.TranslateTransform(this.X.ToDeviceValue(renderer, UnitRenderingType.Horizontal, this),
...@@ -55,7 +55,7 @@ namespace Svg ...@@ -55,7 +55,7 @@ namespace Svg
this.Y = 0; this.Y = 0;
} }
public override System.Drawing.Drawing2D.GraphicsPath Path(SvgRenderer renderer) public override System.Drawing.Drawing2D.GraphicsPath Path(ISvgRenderer renderer)
{ {
SvgVisualElement element = (SvgVisualElement)this.OwnerDocument.IdManager.GetElementById(this.ReferencedElement); SvgVisualElement element = (SvgVisualElement)this.OwnerDocument.IdManager.GetElementById(this.ReferencedElement);
return (element != null) ? element.Path(renderer) : null; return (element != null) ? element.Path(renderer) : null;
...@@ -66,20 +66,9 @@ namespace Svg ...@@ -66,20 +66,9 @@ namespace Svg
get { return new System.Drawing.RectangleF(); } get { return new System.Drawing.RectangleF(); }
} }
// public override SvgElementCollection Children
// {
// get
// {
// SvgElement element = this.OwnerDocument.IdManager.GetElementById(this.ReferencedElement);
// SvgElementCollection elements = new SvgElementCollection(this, true);
// elements.Add(element);
// return elements;
// }
// }
protected override bool Renderable { get { return false; } } protected override bool Renderable { get { return false; } }
protected override void Render(SvgRenderer renderer) protected override void Render(ISvgRenderer renderer)
{ {
if (!Visible || !Displayable) if (!Visible || !Displayable)
return; return;
......
...@@ -17,7 +17,7 @@ namespace Svg ...@@ -17,7 +17,7 @@ namespace Svg
/// Gets the <see cref="GraphicsPath"/> for this element. /// Gets the <see cref="GraphicsPath"/> for this element.
/// </summary> /// </summary>
/// <value></value> /// <value></value>
public override System.Drawing.Drawing2D.GraphicsPath Path(SvgRenderer renderer) public override System.Drawing.Drawing2D.GraphicsPath Path(ISvgRenderer renderer)
{ {
return GetPaths(this, renderer); return GetPaths(this, renderer);
} }
......
...@@ -14,8 +14,8 @@ namespace Svg.FilterEffects ...@@ -14,8 +14,8 @@ namespace Svg.FilterEffects
private Dictionary<string, Bitmap> _images; private Dictionary<string, Bitmap> _images;
private RectangleF _bounds; private RectangleF _bounds;
private SvgRenderer _renderer; private ISvgRenderer _renderer;
private Action<SvgRenderer> _renderMethod; private Action<ISvgRenderer> _renderMethod;
private float _inflate; private float _inflate;
public Matrix Transform { get; set; } public Matrix Transform { get; set; }
...@@ -41,7 +41,7 @@ namespace Svg.FilterEffects ...@@ -41,7 +41,7 @@ namespace Svg.FilterEffects
} }
} }
public ImageBuffer(RectangleF bounds, float inflate, SvgRenderer renderer, Action<SvgRenderer> renderMethod) public ImageBuffer(RectangleF bounds, float inflate, ISvgRenderer renderer, Action<ISvgRenderer> renderMethod)
{ {
_bounds = bounds; _bounds = bounds;
_inflate = inflate; _inflate = inflate;
...@@ -124,7 +124,7 @@ namespace Svg.FilterEffects ...@@ -124,7 +124,7 @@ namespace Svg.FilterEffects
} }
private string ProcessKey(string key) private string ProcessKey(string key)
{ {
if (string.IsNullOrEmpty(key)) return BufferKey; if (string.IsNullOrEmpty(key)) return _images.ContainsKey(BufferKey) ? BufferKey : SvgFilterPrimitive.SourceGraphic;
return key; return key;
} }
...@@ -136,7 +136,7 @@ namespace Svg.FilterEffects ...@@ -136,7 +136,7 @@ namespace Svg.FilterEffects
(int)(_bounds.Height + 2 * _inflate * _bounds.Height + _bounds.Y)); (int)(_bounds.Height + 2 * _inflate * _bounds.Height + _bounds.Y));
using (var renderer = SvgRenderer.FromImage(graphic)) using (var renderer = SvgRenderer.FromImage(graphic))
{ {
renderer.Boundable(_renderer.Boundable()); renderer.SetBoundable(_renderer.GetBoundable());
var transform = new Matrix(); var transform = new Matrix();
transform.Translate(_bounds.Width * _inflate, _bounds.Height * _inflate); transform.Translate(_bounds.Width * _inflate, _bounds.Height * _inflate);
renderer.Transform = transform; renderer.Transform = transform;
......
...@@ -80,10 +80,10 @@ namespace Svg.FilterEffects ...@@ -80,10 +80,10 @@ namespace Svg.FilterEffects
} }
/// <summary> /// <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="ISvgRenderer"/> object.
/// </summary> /// </summary>
/// <param name="renderer">The <see cref="SvgRenderer"/> object to render to.</param> /// <param name="renderer">The <see cref="ISvgRenderer"/> object to render to.</param>
protected override void Render(SvgRenderer renderer) protected override void Render(ISvgRenderer renderer)
{ {
base.RenderChildren(renderer); base.RenderChildren(renderer);
} }
...@@ -109,7 +109,7 @@ namespace Svg.FilterEffects ...@@ -109,7 +109,7 @@ namespace Svg.FilterEffects
return transformMatrix; return transformMatrix;
} }
private RectangleF GetPathBounds(SvgVisualElement element, SvgRenderer renderer, Matrix transform) private RectangleF GetPathBounds(SvgVisualElement element, ISvgRenderer renderer, Matrix transform)
{ {
var bounds = element.Path(renderer).GetBounds(); var bounds = element.Path(renderer).GetBounds();
var pts = new PointF[] { bounds.Location, new PointF(bounds.Right, bounds.Bottom) }; var pts = new PointF[] { bounds.Location, new PointF(bounds.Right, bounds.Bottom) };
...@@ -119,7 +119,7 @@ namespace Svg.FilterEffects ...@@ -119,7 +119,7 @@ namespace Svg.FilterEffects
Math.Abs(pts[0].X - pts[1].X), Math.Abs(pts[0].Y - pts[1].Y)); Math.Abs(pts[0].X - pts[1].X), Math.Abs(pts[0].Y - pts[1].Y));
} }
public void ApplyFilter(SvgVisualElement element, SvgRenderer renderer, Action<SvgRenderer> renderMethod) public void ApplyFilter(SvgVisualElement element, ISvgRenderer renderer, Action<ISvgRenderer> renderMethod)
{ {
var inflate = 0.5f; var inflate = 0.5f;
var transform = GetTransform(element); var transform = GetTransform(element);
...@@ -139,11 +139,10 @@ namespace Svg.FilterEffects ...@@ -139,11 +139,10 @@ namespace Svg.FilterEffects
var bufferImg = buffer.Buffer; var bufferImg = buffer.Buffer;
bufferImg.Save(@"C:\test.png"); bufferImg.Save(@"C:\test.png");
var imgDraw = RectangleF.Inflate(bounds, inflate * bounds.Width, inflate * bounds.Height); var imgDraw = RectangleF.Inflate(bounds, inflate * bounds.Width, inflate * bounds.Height);
var prevClip = renderer.Clip; var prevClip = renderer.GetClip();
renderer.Clip = new Region(imgDraw); renderer.SetClip(new Region(imgDraw));
renderer.DrawImage(bufferImg, imgDraw, new RectangleF(bounds.X, bounds.Y, imgDraw.Width, imgDraw.Height), GraphicsUnit.Pixel); renderer.DrawImage(bufferImg, imgDraw, new RectangleF(bounds.X, bounds.Y, imgDraw.Width, imgDraw.Height), GraphicsUnit.Pixel);
renderer.Clip = prevClip; renderer.SetClip(prevClip);
//renderer.DrawImage(bufferImg, bounds, bounds, GraphicsUnit.Pixel);
} }
} }
......
...@@ -19,6 +19,6 @@ namespace Svg ...@@ -19,6 +19,6 @@ namespace Svg
float StrokeMiterLimit { get; set; } float StrokeMiterLimit { get; set; }
SvgUnitCollection StrokeDashArray { get; set; } SvgUnitCollection StrokeDashArray { get; set; }
SvgUnit StrokeDashOffset { get; set; } SvgUnit StrokeDashOffset { get; set; }
GraphicsPath Path(SvgRenderer renderer); GraphicsPath Path(ISvgRenderer renderer);
} }
} }
\ No newline at end of file
...@@ -35,7 +35,7 @@ namespace Svg ...@@ -35,7 +35,7 @@ namespace Svg
set { this._colour = value; } set { this._colour = value; }
} }
public override Brush GetBrush(SvgVisualElement styleOwner, SvgRenderer renderer, float opacity) public override Brush GetBrush(SvgVisualElement styleOwner, ISvgRenderer renderer, float opacity)
{ {
//is none? //is none?
if (this == SvgPaintServer.None) return new SolidBrush(System.Drawing.Color.Transparent); if (this == SvgPaintServer.None) return new SolidBrush(System.Drawing.Color.Transparent);
......
...@@ -44,7 +44,7 @@ namespace Svg ...@@ -44,7 +44,7 @@ namespace Svg
} }
} }
public override System.Drawing.Brush GetBrush(SvgVisualElement styleOwner, SvgRenderer renderer, float opacity) public override System.Drawing.Brush GetBrush(SvgVisualElement styleOwner, ISvgRenderer renderer, float opacity)
{ {
EnsureServer(styleOwner); EnsureServer(styleOwner);
return _concreteServer.GetBrush(styleOwner, renderer, opacity); return _concreteServer.GetBrush(styleOwner, renderer, opacity);
......
...@@ -130,7 +130,7 @@ namespace Svg ...@@ -130,7 +130,7 @@ namespace Svg
/// </summary> /// </summary>
/// <param name="owner">The parent <see cref="SvgVisualElement"/>.</param> /// <param name="owner">The parent <see cref="SvgVisualElement"/>.</param>
/// <param name="opacity">The opacity of the colour blend.</param> /// <param name="opacity">The opacity of the colour blend.</param>
protected ColorBlend GetColorBlend(SvgRenderer renderer, float opacity, bool radial) protected ColorBlend GetColorBlend(ISvgRenderer renderer, float opacity, bool radial)
{ {
int colourBlends = this.Stops.Count; int colourBlends = this.Stops.Count;
bool insertStart = false; bool insertStart = false;
...@@ -184,7 +184,7 @@ namespace Svg ...@@ -184,7 +184,7 @@ namespace Svg
for (int i = 0; i < colourBlends; i++) for (int i = 0; i < colourBlends; i++)
{ {
var currentStop = this.Stops[radial ? this.Stops.Count - 1 - actualStops : actualStops]; var currentStop = this.Stops[radial ? this.Stops.Count - 1 - actualStops : actualStops];
var boundWidth = renderer.Boundable().Bounds.Width; var boundWidth = renderer.GetBoundable().Bounds.Width;
mergedOpacity = opacity * currentStop.Opacity; mergedOpacity = opacity * currentStop.Opacity;
position = position =
......
...@@ -79,7 +79,7 @@ namespace Svg ...@@ -79,7 +79,7 @@ namespace Svg
Y2 = new SvgUnit(SvgUnitType.Percentage, 0F); Y2 = new SvgUnit(SvgUnitType.Percentage, 0F);
} }
public override Brush GetBrush(SvgVisualElement renderingElement, SvgRenderer renderer, float opacity) public override Brush GetBrush(SvgVisualElement renderingElement, ISvgRenderer renderer, float opacity)
{ {
LoadStops(renderingElement); LoadStops(renderingElement);
if (IsInvalid) if (IsInvalid)
...@@ -89,7 +89,7 @@ namespace Svg ...@@ -89,7 +89,7 @@ namespace Svg
try try
{ {
if (this.GradientUnits == SvgCoordinateUnits.ObjectBoundingBox) renderer.Boundable(renderingElement); if (this.GradientUnits == SvgCoordinateUnits.ObjectBoundingBox) renderer.SetBoundable(renderingElement);
var specifiedStart = CalculateStart(renderer); var specifiedStart = CalculateStart(renderer);
var specifiedEnd = CalculateEnd(renderer); var specifiedEnd = CalculateEnd(renderer);
...@@ -116,12 +116,12 @@ namespace Svg ...@@ -116,12 +116,12 @@ namespace Svg
} }
} }
private PointF CalculateStart(SvgRenderer renderer) private PointF CalculateStart(ISvgRenderer renderer)
{ {
return TransformPoint(SvgUnit.GetDevicePointOffset(this.X1, this.Y1, renderer, this)); return TransformPoint(SvgUnit.GetDevicePointOffset(this.X1, this.Y1, renderer, this));
} }
private PointF CalculateEnd(SvgRenderer renderer) private PointF CalculateEnd(ISvgRenderer renderer)
{ {
return TransformPoint(SvgUnit.GetDevicePointOffset(this.X2, this.Y2, renderer, this)); return TransformPoint(SvgUnit.GetDevicePointOffset(this.X2, this.Y2, renderer, this));
} }
...@@ -181,7 +181,7 @@ namespace Svg ...@@ -181,7 +181,7 @@ namespace Svg
return new GradientPoints(effectiveStart, effectiveEnd); return new GradientPoints(effectiveStart, effectiveEnd);
} }
private ColorBlend CalculateColorBlend(SvgRenderer renderer, float opacity, PointF specifiedStart, PointF effectiveStart, PointF specifiedEnd, PointF effectiveEnd) private ColorBlend CalculateColorBlend(ISvgRenderer renderer, float opacity, PointF specifiedStart, PointF effectiveStart, PointF specifiedEnd, PointF effectiveEnd)
{ {
var colorBlend = GetColorBlend(renderer, opacity, false); var colorBlend = GetColorBlend(renderer, opacity, false);
......
...@@ -87,7 +87,7 @@ namespace Svg ...@@ -87,7 +87,7 @@ namespace Svg
Overflow = SvgOverflow.hidden; Overflow = SvgOverflow.hidden;
} }
public override System.Drawing.Drawing2D.GraphicsPath Path(SvgRenderer renderer) public override System.Drawing.Drawing2D.GraphicsPath Path(ISvgRenderer renderer)
{ {
var path = this.Children.FirstOrDefault(x => x is SvgPath); var path = this.Children.FirstOrDefault(x => x is SvgPath);
if (path != null) if (path != null)
...@@ -131,7 +131,7 @@ namespace Svg ...@@ -131,7 +131,7 @@ namespace Svg
/// <param name="pOwner"></param> /// <param name="pOwner"></param>
/// <param name="pMarkerPoint1"></param> /// <param name="pMarkerPoint1"></param>
/// <param name="pMarkerPoint2"></param> /// <param name="pMarkerPoint2"></param>
public void RenderMarker(SvgRenderer pRenderer, SvgPath pOwner, PointF pRefPoint, PointF pMarkerPoint1, PointF pMarkerPoint2) public void RenderMarker(ISvgRenderer pRenderer, SvgPath pOwner, PointF pRefPoint, PointF pMarkerPoint1, PointF pMarkerPoint2)
{ {
float xDiff = pMarkerPoint2.X - pMarkerPoint1.X; float xDiff = pMarkerPoint2.X - pMarkerPoint1.X;
float yDiff = pMarkerPoint2.Y - pMarkerPoint1.Y; float yDiff = pMarkerPoint2.Y - pMarkerPoint1.Y;
...@@ -148,7 +148,7 @@ namespace Svg ...@@ -148,7 +148,7 @@ namespace Svg
/// <param name="pMarkerPoint1"></param> /// <param name="pMarkerPoint1"></param>
/// <param name="pMarkerPoint2"></param> /// <param name="pMarkerPoint2"></param>
/// <param name="pMarkerPoint3"></param> /// <param name="pMarkerPoint3"></param>
public void RenderMarker(SvgRenderer pRenderer, SvgPath pOwner, PointF pRefPoint, PointF pMarkerPoint1, PointF pMarkerPoint2, PointF pMarkerPoint3) public void RenderMarker(ISvgRenderer pRenderer, SvgPath pOwner, PointF pRefPoint, PointF pMarkerPoint1, PointF pMarkerPoint2, PointF pMarkerPoint3)
{ {
float xDiff = pMarkerPoint2.X - pMarkerPoint1.X; float xDiff = pMarkerPoint2.X - pMarkerPoint1.X;
float yDiff = pMarkerPoint2.Y - pMarkerPoint1.Y; float yDiff = pMarkerPoint2.Y - pMarkerPoint1.Y;
...@@ -168,7 +168,7 @@ namespace Svg ...@@ -168,7 +168,7 @@ namespace Svg
/// <param name="pRenderer"></param> /// <param name="pRenderer"></param>
/// <param name="pOwner"></param> /// <param name="pOwner"></param>
/// <param name="pMarkerPoint"></param> /// <param name="pMarkerPoint"></param>
private void RenderPart2(float fAngle, SvgRenderer pRenderer, SvgPath pOwner, PointF pMarkerPoint) private void RenderPart2(float fAngle, ISvgRenderer pRenderer, SvgPath pOwner, PointF pMarkerPoint)
{ {
Pen pRenderPen = CreatePen(pOwner, pRenderer); Pen pRenderPen = CreatePen(pOwner, pRenderer);
...@@ -216,7 +216,7 @@ namespace Svg ...@@ -216,7 +216,7 @@ namespace Svg
/// </summary> /// </summary>
/// <param name="pStroke"></param> /// <param name="pStroke"></param>
/// <returns></returns> /// <returns></returns>
private Pen CreatePen(SvgPath pPath, SvgRenderer renderer) private Pen CreatePen(SvgPath pPath, ISvgRenderer renderer)
{ {
Brush pBrush = pPath.Stroke.GetBrush(this, renderer, Opacity); Brush pBrush = pPath.Stroke.GetBrush(this, renderer, Opacity);
switch (MarkerUnits) switch (MarkerUnits)
......
...@@ -26,10 +26,10 @@ namespace Svg ...@@ -26,10 +26,10 @@ namespace Svg
} }
/// <summary> /// <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="ISvgRenderer"/> object.
/// </summary> /// </summary>
/// <param name="renderer">The <see cref="SvgRenderer"/> object to render to.</param> /// <param name="renderer">The <see cref="ISvgRenderer"/> object to render to.</param>
protected override void Render(SvgRenderer renderer) protected override void Render(ISvgRenderer renderer)
{ {
// Never render paint servers or their children // Never render paint servers or their children
} }
...@@ -39,7 +39,7 @@ namespace Svg ...@@ -39,7 +39,7 @@ namespace Svg
/// </summary> /// </summary>
/// <param name="styleOwner">The owner <see cref="SvgVisualElement"/>.</param> /// <param name="styleOwner">The owner <see cref="SvgVisualElement"/>.</param>
/// <param name="opacity">The opacity of the brush.</param> /// <param name="opacity">The opacity of the brush.</param>
public abstract Brush GetBrush(SvgVisualElement styleOwner, SvgRenderer renderer, float opacity); public abstract Brush GetBrush(SvgVisualElement styleOwner, ISvgRenderer renderer, float opacity);
/// <summary> /// <summary>
/// Returns a <see cref="T:System.String"/> that represents the current <see cref="T:System.Object"/>. /// Returns a <see cref="T:System.String"/> that represents the current <see cref="T:System.Object"/>.
......
...@@ -20,8 +20,8 @@ namespace Svg ...@@ -20,8 +20,8 @@ namespace Svg
private SvgUnit _x; private SvgUnit _x;
private SvgUnit _y; private SvgUnit _y;
private SvgViewBox _viewBox; private SvgViewBox _viewBox;
private SvgCoordinateUnits _patternUnits; private SvgCoordinateUnits _patternUnits = SvgCoordinateUnits.ObjectBoundingBox;
private SvgCoordinateUnits _patternContentUnits; private SvgCoordinateUnits _patternContentUnits = SvgCoordinateUnits.UserSpaceOnUse;
[SvgAttribute("overflow")] [SvgAttribute("overflow")]
public SvgOverflow Overflow public SvgOverflow Overflow
...@@ -129,7 +129,7 @@ namespace Svg ...@@ -129,7 +129,7 @@ namespace Svg
/// </summary> /// </summary>
/// <param name="renderingElement">The owner <see cref="SvgVisualElement"/>.</param> /// <param name="renderingElement">The owner <see cref="SvgVisualElement"/>.</param>
/// <param name="opacity">The opacity of the brush.</param> /// <param name="opacity">The opacity of the brush.</param>
public override Brush GetBrush(SvgVisualElement renderingElement, SvgRenderer renderer, float opacity) public override Brush GetBrush(SvgVisualElement renderingElement, ISvgRenderer renderer, float opacity)
{ {
// If there aren't any children, return null // If there aren't any children, return null
if (this.Children.Count == 0) if (this.Children.Count == 0)
...@@ -141,7 +141,7 @@ namespace Svg ...@@ -141,7 +141,7 @@ namespace Svg
try try
{ {
if (this.PatternUnits == SvgCoordinateUnits.ObjectBoundingBox) renderer.Boundable(renderingElement); if (this.PatternUnits == SvgCoordinateUnits.ObjectBoundingBox) renderer.SetBoundable(renderingElement);
float width = this._width.ToDeviceValue(renderer, UnitRenderingType.Horizontal, this); float width = this._width.ToDeviceValue(renderer, UnitRenderingType.Horizontal, this);
float height = this._height.ToDeviceValue(renderer, UnitRenderingType.Vertical, this); float height = this._height.ToDeviceValue(renderer, UnitRenderingType.Vertical, this);
...@@ -153,11 +153,7 @@ namespace Svg ...@@ -153,11 +153,7 @@ namespace Svg
float x = this._x.ToDeviceValue(renderer, UnitRenderingType.HorizontalOffset, this); float x = this._x.ToDeviceValue(renderer, UnitRenderingType.HorizontalOffset, this);
float y = this._y.ToDeviceValue(renderer, UnitRenderingType.VerticalOffset, this); float y = this._y.ToDeviceValue(renderer, UnitRenderingType.VerticalOffset, this);
patternMatrix.Translate(x + -1.0f, y + -1.0f); patternMatrix.Translate(x, y);
}
else
{
patternMatrix.Translate(-1, -1);
} }
if (this.ViewBox.Height > 0 || this.ViewBox.Width > 0) if (this.ViewBox.Height > 0 || this.ViewBox.Width > 0)
...@@ -167,20 +163,16 @@ namespace Svg ...@@ -167,20 +163,16 @@ namespace Svg
} }
Bitmap image = new Bitmap((int)width, (int)height); Bitmap image = new Bitmap((int)width, (int)height);
using (SvgRenderer iRenderer = SvgRenderer.FromImage(image)) using (var iRenderer = SvgRenderer.FromImage(image))
{ {
iRenderer.Boundable((_patternContentUnits == SvgCoordinateUnits.ObjectBoundingBox) ? new GenericBoundable(0, 0, width, height) : renderer.Boundable()); iRenderer.SetBoundable((_patternContentUnits == SvgCoordinateUnits.ObjectBoundingBox) ? new GenericBoundable(0, 0, width, height) : renderer.GetBoundable());
iRenderer.Transform = patternMatrix; iRenderer.Transform = patternMatrix;
iRenderer.CompositingQuality = CompositingQuality.HighQuality;
iRenderer.SmoothingMode = SmoothingMode.AntiAlias; iRenderer.SmoothingMode = SmoothingMode.AntiAlias;
iRenderer.PixelOffsetMode = PixelOffsetMode.Half;
foreach (SvgElement child in this.Children) foreach (SvgElement child in this.Children)
{ {
child.RenderElement(iRenderer); child.RenderElement(iRenderer);
} }
iRenderer.Save();
} }
image.Save(string.Format(@"C:\test{0:D3}.png", imgNumber++)); image.Save(string.Format(@"C:\test{0:D3}.png", imgNumber++));
......
...@@ -98,16 +98,16 @@ namespace Svg ...@@ -98,16 +98,16 @@ namespace Svg
private object _lockObj = new Object(); private object _lockObj = new Object();
public override Brush GetBrush(SvgVisualElement renderingElement, SvgRenderer renderer, float opacity) public override Brush GetBrush(SvgVisualElement renderingElement, ISvgRenderer renderer, float opacity)
{ {
LoadStops(renderingElement); LoadStops(renderingElement);
try try
{ {
if (this.GradientUnits == SvgCoordinateUnits.ObjectBoundingBox) renderer.Boundable(renderingElement); if (this.GradientUnits == SvgCoordinateUnits.ObjectBoundingBox) renderer.SetBoundable(renderingElement);
// Calculate the path and transform it appropriately // Calculate the path and transform it appropriately
var origin = renderer.Boundable().Location; var origin = renderer.GetBoundable().Location;
var center = new PointF(origin.X + CenterX.ToDeviceValue(renderer, UnitRenderingType.HorizontalOffset, this), var center = new PointF(origin.X + CenterX.ToDeviceValue(renderer, UnitRenderingType.HorizontalOffset, this),
origin.Y + CenterY.ToDeviceValue(renderer, UnitRenderingType.VerticalOffset, this)); origin.Y + CenterY.ToDeviceValue(renderer, UnitRenderingType.VerticalOffset, this));
var specifiedRadius = Radius.ToDeviceValue(renderer, UnitRenderingType.Other, this); var specifiedRadius = Radius.ToDeviceValue(renderer, UnitRenderingType.Other, this);
...@@ -181,7 +181,7 @@ namespace Svg ...@@ -181,7 +181,7 @@ namespace Svg
return bounds.Height / (points[2].Y - points[1].Y); return bounds.Height / (points[2].Y - points[1].Y);
} }
private PointF CalculateFocalPoint(SvgRenderer renderer, PointF origin) private PointF CalculateFocalPoint(ISvgRenderer renderer, PointF origin)
{ {
var deviceFocalX = origin.X + FocalX.ToDeviceValue(renderer, UnitRenderingType.HorizontalOffset, this); var deviceFocalX = origin.X + FocalX.ToDeviceValue(renderer, UnitRenderingType.HorizontalOffset, this);
var deviceFocalY = origin.Y + FocalY.ToDeviceValue(renderer, UnitRenderingType.VerticalOffset, this); var deviceFocalY = origin.Y + FocalY.ToDeviceValue(renderer, UnitRenderingType.VerticalOffset, this);
...@@ -203,7 +203,7 @@ namespace Svg ...@@ -203,7 +203,7 @@ namespace Svg
return path; return path;
} }
private ColorBlend CalculateColorBlend(SvgRenderer renderer, float opacity, float scale, out float outScale) private ColorBlend CalculateColorBlend(ISvgRenderer renderer, float opacity, float scale, out float outScale)
{ {
var colorBlend = GetColorBlend(renderer, opacity, true); var colorBlend = GetColorBlend(renderer, opacity, true);
float newScale; float newScale;
......
...@@ -38,9 +38,9 @@ namespace Svg ...@@ -38,9 +38,9 @@ namespace Svg
/// Gets or sets the length of the path. /// Gets or sets the length of the path.
/// </summary> /// </summary>
[SvgAttribute("pathLength")] [SvgAttribute("pathLength")]
public int PathLength public float PathLength
{ {
get { return this.Attributes.GetAttribute<int>("pathLength"); } get { return this.Attributes.GetAttribute<float>("pathLength"); }
set { this.Attributes["pathLength"] = value; } set { this.Attributes["pathLength"] = value; }
} }
...@@ -81,7 +81,7 @@ namespace Svg ...@@ -81,7 +81,7 @@ namespace Svg
/// <summary> /// <summary>
/// Gets the <see cref="GraphicsPath"/> for this element. /// Gets the <see cref="GraphicsPath"/> for this element.
/// </summary> /// </summary>
public override GraphicsPath Path(SvgRenderer renderer) public override GraphicsPath Path(ISvgRenderer renderer)
{ {
if (this._path == null || this.IsPathDirty) if (this._path == null || this.IsPathDirty)
{ {
...@@ -131,15 +131,15 @@ namespace Svg ...@@ -131,15 +131,15 @@ namespace Svg
} }
/// <summary> /// <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="ISvgRenderer"/>
/// </summary> /// </summary>
/// <param name="renderer">The <see cref="SvgRenderer"/> object to render to.</param> /// <param name="renderer">The <see cref="ISvgRenderer"/> object to render to.</param>
protected internal override void RenderStroke(SvgRenderer renderer) protected internal override void RenderStroke(ISvgRenderer renderer)
{ {
if (this.Stroke != null) if (this.Stroke != null && this.Stroke != SvgColourServer.None)
{ {
float strokeWidth = this.StrokeWidth.ToDeviceValue(renderer, UnitRenderingType.Other, this); float strokeWidth = this.StrokeWidth.ToDeviceValue(renderer, UnitRenderingType.Other, this);
using (Pen pen = new Pen(this.Stroke.GetBrush(this, renderer, this.StrokeOpacity), strokeWidth)) using (Pen pen = new Pen(this.Stroke.GetBrush(this, renderer, this.StrokeOpacity * this.Opacity), strokeWidth))
{ {
if (this.StrokeDashArray != null && this.StrokeDashArray.Count > 0) if (this.StrokeDashArray != null && this.StrokeDashArray.Count > 0)
{ {
......
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
namespace Svg
{
public interface IGraphicsProvider
{
Graphics GetGraphics();
}
}
using System;
using System.Drawing.Drawing2D;
using System.Drawing;
using System.Collections.Generic;
namespace Svg
{
public interface ISvgRenderer : IDisposable
{
float DpiY { get; }
void DrawImage(Image image, RectangleF destRect, RectangleF srcRect, GraphicsUnit graphicsUnit);
void DrawImageUnscaled(Image image, Point location);
void DrawPath(Pen pen, GraphicsPath path);
void FillPath(Brush brush, GraphicsPath path);
float FontBaselineOffset(IFontDefn font);
ISvgBoundable GetBoundable();
Region GetClip();
IList<RectangleF> MeasureCharacters(string text, IFontDefn font);
SizeF MeasureString(string text, IFontDefn font);
ISvgBoundable PopBoundable();
void RotateTransform(float fAngle, MatrixOrder order = MatrixOrder.Append);
void ScaleTransform(float sx, float sy, MatrixOrder order = MatrixOrder.Append);
void SetBoundable(ISvgBoundable boundable);
void SetClip(Region region, CombineMode combineMode = CombineMode.Replace);
SmoothingMode SmoothingMode { get; set; }
Matrix Transform { get; set; }
void TranslateTransform(float dx, float dy, MatrixOrder order = MatrixOrder.Append);
}
}
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