using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing.Drawing2D;
using System.Drawing;
using System.ComponentModel;
using Svg.Transforms;
namespace Svg
{
///
/// A pattern is used to fill or stroke an object using a pre-defined graphic object which can be replicated ("tiled") at fixed intervals in x and y to cover the areas to be painted.
///
[SvgElement("pattern")]
public sealed class SvgPatternServer : SvgPaintServer, ISvgViewPort, ISvgSupportsCoordinateUnits
{
private SvgUnit _width;
private SvgUnit _height;
private SvgUnit _x;
private SvgUnit _y;
private SvgViewBox _viewBox;
private SvgCoordinateUnits _patternUnits;
private SvgCoordinateUnits _patternContentUnits;
[SvgAttribute("overflow")]
public SvgOverflow Overflow
{
get { return this.Attributes.GetAttribute("overflow"); }
set { this.Attributes["overflow"] = value; }
}
///
/// Specifies a supplemental transformation which is applied on top of any
/// transformations necessary to create a new pattern coordinate system.
///
[SvgAttribute("viewBox")]
public SvgViewBox ViewBox
{
get { return this._viewBox; }
set { this._viewBox = value; }
}
///
/// Gets or sets the aspect of the viewport.
///
///
[SvgAttribute("preserveAspectRatio")]
public SvgAspectRatio AspectRatio
{
get;
set;
}
///
/// Gets or sets the width of the pattern.
///
[SvgAttribute("width")]
public SvgUnit Width
{
get { return this._width; }
set { this._width = value; }
}
///
/// Gets or sets the width of the pattern.
///
[SvgAttribute("patternUnits")]
public SvgCoordinateUnits PatternUnits
{
get { return this._patternUnits; }
set { this._patternUnits = value; }
}
///
/// Gets or sets the width of the pattern.
///
[SvgAttribute("patternUnits")]
public SvgCoordinateUnits PatternContentUnits
{
get { return this._patternContentUnits; }
set { this._patternContentUnits = value; }
}
///
/// Gets or sets the height of the pattern.
///
[SvgAttribute("height")]
public SvgUnit Height
{
get { return this._height; }
set { this._height = value; }
}
///
/// Gets or sets the X-axis location of the pattern.
///
[SvgAttribute("x")]
public SvgUnit X
{
get { return this._x; }
set { this._x = value; }
}
///
/// Gets or sets the Y-axis location of the pattern.
///
[SvgAttribute("y")]
public SvgUnit Y
{
get { return this._y; }
set { this._y = value; }
}
///
/// Initializes a new instance of the class.
///
public SvgPatternServer()
{
this._x = new SvgUnit(0.0f);
this._y = new SvgUnit(0.0f);
this._width = new SvgUnit(0.0f);
this._height = new SvgUnit(0.0f);
}
///
/// Gets a representing the current paint server.
///
/// The owner .
/// The opacity of the brush.
public override Brush GetBrush(SvgVisualElement renderingElement, SvgRenderer renderer, float opacity)
{
// If there aren't any children, return null
if (this.Children.Count == 0)
return null;
// Can't render if there are no dimensions
if (this._width.Value == 0.0f || this._height.Value == 0.0f)
return null;
try
{
if (this.PatternUnits == SvgCoordinateUnits.ObjectBoundingBox) renderer.Boundable(renderingElement);
float width = this._width.ToDeviceValue(renderer, UnitRenderingType.Horizontal, this);
float height = this._height.ToDeviceValue(renderer, UnitRenderingType.Vertical, this);
Matrix patternMatrix = new Matrix();
// Apply a translate if needed
if (this._x.Value > 0.0f || this._y.Value > 0.0f)
{
float x = this._x.ToDeviceValue(renderer, UnitRenderingType.HorizontalOffset, this);
float y = this._y.ToDeviceValue(renderer, UnitRenderingType.VerticalOffset, this);
patternMatrix.Translate(x + -1.0f, y + -1.0f);
}
else
{
patternMatrix.Translate(-1, -1);
}
if (this.ViewBox.Height > 0 || this.ViewBox.Width > 0)
{
patternMatrix.Scale(this.Width.ToDeviceValue(renderer, UnitRenderingType.Horizontal, this) / this.ViewBox.Width,
this.Height.ToDeviceValue(renderer, UnitRenderingType.Vertical, this) / this.ViewBox.Height);
}
Bitmap image = new Bitmap((int)width, (int)height);
using (SvgRenderer iRenderer = SvgRenderer.FromImage(image))
{
iRenderer.Boundable((_patternContentUnits == SvgCoordinateUnits.ObjectBoundingBox) ? new GenericBoundable(0, 0, width, height) : renderer.Boundable());
iRenderer.Transform = patternMatrix;
iRenderer.CompositingQuality = CompositingQuality.HighQuality;
iRenderer.SmoothingMode = SmoothingMode.AntiAlias;
iRenderer.PixelOffsetMode = PixelOffsetMode.Half;
foreach (SvgElement child in this.Children)
{
child.RenderElement(iRenderer);
}
iRenderer.Save();
}
image.Save(string.Format(@"C:\test{0:D3}.png", imgNumber++));
TextureBrush textureBrush = new TextureBrush(image);
return textureBrush;
}
finally
{
if (this.PatternUnits == SvgCoordinateUnits.ObjectBoundingBox) renderer.PopBoundable();
}
}
private static int imgNumber = 0;
public override SvgElement DeepCopy()
{
return DeepCopy();
}
public override SvgElement DeepCopy()
{
var newObj = base.DeepCopy() as SvgPatternServer;
newObj.Overflow = this.Overflow;
newObj.ViewBox = this.ViewBox;
newObj.AspectRatio = this.AspectRatio;
newObj.X = this.X;
newObj.Y = this.Y;
newObj.Width = this.Width;
newObj.Height = this.Height;
return newObj;
}
public SvgCoordinateUnits GetUnits()
{
return _patternUnits;
}
}
}