Small refactoring for Transforms (3).

This commit is contained in:
H1Gdev 2019-08-07 10:56:10 +09:00 коммит произвёл mrbean-bremen
Родитель 2646ca33c0
Коммит ec17c8a0e9
10 изменённых файлов: 124 добавлений и 271 удалений

Просмотреть файл

@ -1,9 +1,3 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Drawing.Drawing2D;
using Svg.Transforms;
namespace Svg
@ -28,4 +22,4 @@ namespace Svg
/// <param name="renderer">The <see cref="ISvgRenderer"/> that should have transforms removed.</param>
void PopTransforms(ISvgRenderer renderer);
}
}
}

Просмотреть файл

@ -1,6 +1,4 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Collections.Generic;
using System.Drawing.Drawing2D;
using System.Globalization;
@ -11,46 +9,37 @@ namespace Svg.Transforms
/// </summary>
public sealed class SvgMatrix : SvgTransform
{
private List<float> points;
public List<float> Points { get; set; }
public List<float> Points
{
get { return this.points; }
set { this.points = value; }
}
public override System.Drawing.Drawing2D.Matrix Matrix
public override Matrix Matrix
{
get
{
Matrix matrix = new Matrix(
this.points[0],
this.points[1],
this.points[2],
this.points[3],
this.points[4],
this.points[5]
return new Matrix(
Points[0],
Points[1],
Points[2],
Points[3],
Points[4],
Points[5]
);
return matrix;
}
}
public override string WriteToString()
{
return string.Format(CultureInfo.InvariantCulture, "matrix({0}, {1}, {2}, {3}, {4}, {5})",
this.points[0], this.points[1], this.points[2], this.points[3], this.points[4], this.points[5]);
Points[0], Points[1], Points[2], Points[3], Points[4], Points[5]);
}
public SvgMatrix(List<float> m)
{
this.points = m;
Points = m;
}
public override object Clone()
{
return new SvgMatrix(this.Points);
return new SvgMatrix(Points);
}
}
}
}

Просмотреть файл

@ -1,6 +1,3 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing.Drawing2D;
using System.Globalization;
@ -8,57 +5,44 @@ namespace Svg.Transforms
{
public sealed class SvgRotate : SvgTransform
{
public float Angle
{
get;
set;
}
public float Angle { get; set; }
public float CenterX
{
get;
set;
}
public float CenterX { get; set; }
public float CenterY
{
get;
set;
}
public float CenterY { get; set; }
public override Matrix Matrix
{
get
{
Matrix matrix = new Matrix();
matrix.Translate(this.CenterX, this.CenterY);
matrix.Rotate(this.Angle);
matrix.Translate(-this.CenterX, -this.CenterY);
var matrix = new Matrix();
matrix.Translate(CenterX, CenterY);
matrix.Rotate(Angle);
matrix.Translate(-CenterX, -CenterY);
return matrix;
}
}
public override string WriteToString()
{
return string.Format(CultureInfo.InvariantCulture, "rotate({0}, {1}, {2})", this.Angle, this.CenterX, this.CenterY);
return string.Format(CultureInfo.InvariantCulture, "rotate({0}, {1}, {2})", Angle, CenterX, CenterY);
}
public SvgRotate(float angle)
{
this.Angle = angle;
Angle = angle;
}
public SvgRotate(float angle, float centerX, float centerY)
: this(angle)
{
this.CenterX = centerX;
this.CenterY = centerY;
CenterX = centerX;
CenterY = centerY;
}
public override object Clone()
{
return new SvgRotate(this.Angle, this.CenterX, this.CenterY);
return new SvgRotate(Angle, CenterX, CenterY);
}
}
}
}

Просмотреть файл

@ -1,6 +1,3 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing.Drawing2D;
using System.Globalization;
@ -8,48 +5,41 @@ namespace Svg.Transforms
{
public sealed class SvgScale : SvgTransform
{
private float scaleFactorX;
private float scaleFactorY;
public float X { get; set; }
public float X
{
get { return this.scaleFactorX; }
set { this.scaleFactorX = value; }
}
public float Y { get; set; }
public float Y
{
get { return this.scaleFactorY; }
set { this.scaleFactorY = value; }
}
public override System.Drawing.Drawing2D.Matrix Matrix
public override Matrix Matrix
{
get
{
var matrix = new System.Drawing.Drawing2D.Matrix();
matrix.Scale(this.X, this.Y);
var matrix = new Matrix();
matrix.Scale(X, Y);
return matrix;
}
}
public override string WriteToString()
{
if (this.X == this.Y) return string.Format(CultureInfo.InvariantCulture, "scale({0})", this.X);
return string.Format(CultureInfo.InvariantCulture, "scale({0}, {1})", this.X, this.Y);
if (X == Y)
return string.Format(CultureInfo.InvariantCulture, "scale({0})", X);
return string.Format(CultureInfo.InvariantCulture, "scale({0}, {1})", X, Y);
}
public SvgScale(float x) : this(x, x) { }
public SvgScale(float x)
: this(x, x)
{
}
public SvgScale(float x, float y)
{
this.scaleFactorX = x;
this.scaleFactorY = y;
X = x;
Y = y;
}
public override object Clone()
{
return new SvgScale(this.X, this.Y);
return new SvgScale(X, Y);
}
}
}

Просмотреть файл

@ -1,7 +1,4 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing.Drawing2D;
using System.Drawing.Drawing2D;
using System.Globalization;
namespace Svg.Transforms
@ -11,48 +8,39 @@ namespace Svg.Transforms
/// </summary>
public sealed class SvgShear : SvgTransform
{
private float shearFactorX;
private float shearFactorY;
public float X { get; set; }
public float X
{
get { return this.shearFactorX; }
set { this.shearFactorX = value; }
}
public float Y
{
get { return this.shearFactorY; }
set { this.shearFactorY = value; }
}
public float Y { get; set; }
public override Matrix Matrix
{
get
{
Matrix matrix = new Matrix();
matrix.Shear(this.X, this.Y);
var matrix = new Matrix();
matrix.Shear(X, Y);
return matrix;
}
}
public override string WriteToString()
{
return string.Format(CultureInfo.InvariantCulture, "shear({0}, {1})", this.X, this.Y);
return string.Format(CultureInfo.InvariantCulture, "shear({0}, {1})", X, Y);
}
public SvgShear(float x) : this(x, x) { }
public SvgShear(float x)
: this(x, x)
{
}
public SvgShear(float x, float y)
{
this.shearFactorX = x;
this.shearFactorY = y;
X = x;
Y = y;
}
public override object Clone()
{
return new SvgShear(this.X, this.Y);
return new SvgShear(X, Y);
}
}
}
}

Просмотреть файл

@ -18,23 +18,16 @@ namespace Svg.Transforms
get
{
var matrix = new Matrix();
matrix.Shear(
(float)Math.Tan(AngleX / 180 * Math.PI),
(float)Math.Tan(AngleY / 180 * Math.PI));
matrix.Shear((float)Math.Tan(AngleX / 180f * Math.PI), (float)Math.Tan(AngleY / 180f * Math.PI));
return matrix;
}
}
public override string WriteToString()
{
if (this.AngleY == 0)
{
return string.Format(CultureInfo.InvariantCulture, "skewX({0})", this.AngleX);
}
else
{
return string.Format(CultureInfo.InvariantCulture, "skewY({0})", this.AngleY);
}
if (AngleY == 0f)
return string.Format(CultureInfo.InvariantCulture, "skewX({0})", AngleX);
return string.Format(CultureInfo.InvariantCulture, "skewY({0})", AngleY);
}
public SvgSkew(float x, float y)
@ -43,10 +36,9 @@ namespace Svg.Transforms
AngleY = y;
}
public override object Clone()
{
return new SvgSkew(this.AngleX, this.AngleY);
return new SvgSkew(AngleX, AngleY);
}
}
}
}

Просмотреть файл

@ -1,7 +1,4 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Drawing.Drawing2D;
namespace Svg.Transforms
@ -16,29 +13,18 @@ namespace Svg.Transforms
#region Equals implementation
public override bool Equals(object obj)
{
SvgTransform other = obj as SvgTransform;
var other = obj as SvgTransform;
if (other == null)
return false;
var thisMatrix = this.Matrix.Elements;
var otherMatrix = other.Matrix.Elements;
for (int i = 0; i < 6; i++)
{
if (thisMatrix[i] != otherMatrix[i])
return false;
}
return true;
return Matrix.Equals(other.Matrix);
}
public override int GetHashCode()
{
int hashCode = this.Matrix.GetHashCode();
return hashCode;
return Matrix.GetHashCode();
}
public static bool operator ==(SvgTransform lhs, SvgTransform rhs)
{
if (ReferenceEquals(lhs, rhs))
@ -59,4 +45,4 @@ namespace Svg.Transforms
return WriteToString();
}
}
}
}

Просмотреть файл

@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
namespace Svg.Transforms
{
@ -47,23 +46,15 @@ namespace Svg.Transforms
{
var transformMatrix = new Matrix();
// Return if there are no transforms
if (this.Count == 0)
{
return transformMatrix;
}
foreach (SvgTransform transformation in this)
{
transformMatrix.Multiply(transformation.Matrix);
}
foreach (var transform in this)
transformMatrix.Multiply(transform.Matrix);
return transformMatrix;
}
public override bool Equals(object obj)
{
if (this.Count == 0 && this.Count == base.Count) //default will be an empty list
if (Count == 0 && Count == base.Count) // default will be an empty list
return true;
return base.Equals(obj);
}
@ -94,25 +85,22 @@ namespace Svg.Transforms
{
var handler = TransformChanged;
if (handler != null)
{
//make a copy of the current value to avoid collection changed exceptions
handler(this, new AttributeEventArgs { Attribute = "transform", Value = this.Clone() });
}
// make a copy of the current value to avoid collection changed exceptions
handler(this, new AttributeEventArgs { Attribute = "transform", Value = Clone() });
}
public object Clone()
{
var result = new SvgTransformCollection();
foreach (var trans in this)
{
result.AddItem(trans.Clone() as SvgTransform);
}
return result;
foreach (var transform in this)
result.AddItem(transform.Clone() as SvgTransform);
return result;
}
public override string ToString()
{
if (this.Count < 1) return string.Empty;
if (Count < 1)
return string.Empty;
return (from t in this select t.ToString()).Aggregate((p, c) => p + " " + c);
}
}

Просмотреть файл

@ -1,10 +1,6 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.ComponentModel;
using System.Text.RegularExpressions;
using System.Globalization;
using System.Linq;
@ -14,17 +10,15 @@ namespace Svg.Transforms
{
private static IEnumerable<string> SplitTransforms(string transforms)
{
int transformEnd = 0;
transforms = transforms.Replace(',', ' ');
var transformStart = 0;
for (int i = 0; i < transforms.Length; i++)
{
for (var i = 0; i < transforms.Length; ++i)
if (transforms[i] == ')')
{
yield return transforms.Substring(transformEnd, i - transformEnd + 1).Trim();
while (i < transforms.Length && !char.IsLetter(transforms[i])) i++;
transformEnd = i;
yield return transforms.Substring(transformStart, i + 1 - transformStart).TrimStart();
transformStart = i + 1;
}
}
}
/// <summary>
@ -37,133 +31,108 @@ namespace Svg.Transforms
/// 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)
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
if (value is string)
{
SvgTransformCollection transformList = new SvgTransformCollection();
var transformList = new SvgTransformCollection();
string[] parts;
string contents;
string transformName;
foreach (string transform in SvgTransformConverter.SplitTransforms((string)value))
foreach (var transform in SplitTransforms((string)value))
{
if (string.IsNullOrEmpty(transform))
continue;
parts = transform.Split('(', ')');
transformName = parts[0].Trim();
transformName = parts[0].TrimEnd();
contents = parts[1].Trim();
switch (transformName)
{
case "translate":
string[] coords = contents.Split(new char[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries);
var coords = contents.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
if (coords.Length == 0 || coords.Length > 2)
{
throw new FormatException("Translate transforms must be in the format 'translate(x [,y])'");
}
throw new FormatException("Translate transforms must be in the format 'translate(x [y])'");
float x = float.Parse(coords[0].Trim(), NumberStyles.Float, CultureInfo.InvariantCulture);
var x = float.Parse(coords[0].Trim(), NumberStyles.Float, CultureInfo.InvariantCulture);
if (coords.Length > 1)
{
float y = float.Parse(coords[1].Trim(), NumberStyles.Float, CultureInfo.InvariantCulture);
var y = float.Parse(coords[1].Trim(), NumberStyles.Float, CultureInfo.InvariantCulture);
transformList.Add(new SvgTranslate(x, y));
}
else
{
transformList.Add(new SvgTranslate(x));
}
break;
case "rotate":
string[] args = contents.Split(new char[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries);
var args = contents.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
if (args.Length != 1 && args.Length != 3)
{
throw new FormatException("Rotate transforms must be in the format 'rotate(angle [cx cy ])'");
}
throw new FormatException("Rotate transforms must be in the format 'rotate(angle [cx cy])'");
float angle = float.Parse(args[0], NumberStyles.Float, CultureInfo.InvariantCulture);
var angle = float.Parse(args[0], NumberStyles.Float, CultureInfo.InvariantCulture);
if (args.Length == 1)
{
transformList.Add(new SvgRotate(angle));
}
else
{
float cx = float.Parse(args[1], NumberStyles.Float, CultureInfo.InvariantCulture);
float cy = float.Parse(args[2], NumberStyles.Float, CultureInfo.InvariantCulture);
var cx = float.Parse(args[1], NumberStyles.Float, CultureInfo.InvariantCulture);
var cy = float.Parse(args[2], NumberStyles.Float, CultureInfo.InvariantCulture);
transformList.Add(new SvgRotate(angle, cx, cy));
}
break;
case "scale":
string[] scales = contents.Split(new char[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries);
var scales = contents.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
if (scales.Length == 0 || scales.Length > 2)
{
throw new FormatException("Scale transforms must be in the format 'scale(x [,y])'");
}
float sx = float.Parse(scales[0].Trim(), NumberStyles.Float, CultureInfo.InvariantCulture);
throw new FormatException("Scale transforms must be in the format 'scale(x [y])'");
var sx = float.Parse(scales[0].Trim(), NumberStyles.Float, CultureInfo.InvariantCulture);
if (scales.Length > 1)
{
float sy = float.Parse(scales[1].Trim(), NumberStyles.Float, CultureInfo.InvariantCulture);
var sy = float.Parse(scales[1].Trim(), NumberStyles.Float, CultureInfo.InvariantCulture);
transformList.Add(new SvgScale(sx, sy));
}
else
{
transformList.Add(new SvgScale(sx));
}
break;
case "matrix":
string[] points = contents.Split(new char[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries);
var points = contents.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
if (points.Length != 6)
{
throw new FormatException("Matrix transforms must be in the format 'matrix(m11, m12, m21, m22, dx, dy)'");
}
throw new FormatException("Matrix transforms must be in the format 'matrix(m11 m12 m21 m22 dx dy)'");
List<float> mPoints = new List<float>();
foreach (string point in points)
{
var mPoints = new List<float>(6);
foreach (var point in points)
mPoints.Add(float.Parse(point.Trim(), NumberStyles.Float, CultureInfo.InvariantCulture));
}
transformList.Add(new SvgMatrix(mPoints));
break;
case "shear":
string[] shears = contents.Split(new char[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries);
var shears = contents.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
if (shears.Length == 0 || shears.Length > 2)
{
throw new FormatException("Shear transforms must be in the format 'shear(x [,y])'");
}
float hx = float.Parse(shears[0].Trim(), NumberStyles.Float, CultureInfo.InvariantCulture);
throw new FormatException("Shear transforms must be in the format 'shear(x [y])'");
var hx = float.Parse(shears[0].Trim(), NumberStyles.Float, CultureInfo.InvariantCulture);
if (shears.Length > 1)
{
float hy = float.Parse(shears[1].Trim(), NumberStyles.Float, CultureInfo.InvariantCulture);
var hy = float.Parse(shears[1].Trim(), NumberStyles.Float, CultureInfo.InvariantCulture);
transformList.Add(new SvgShear(hx, hy));
}
else
{
transformList.Add(new SvgShear(hx));
}
break;
case "skewX":
float ax = float.Parse(contents, NumberStyles.Float, CultureInfo.InvariantCulture);
transformList.Add(new SvgSkew(ax, 0));
var ax = float.Parse(contents, NumberStyles.Float, CultureInfo.InvariantCulture);
transformList.Add(new SvgSkew(ax, 0f));
break;
case "skewY":
float ay = float.Parse(contents, NumberStyles.Float, CultureInfo.InvariantCulture);
transformList.Add(new SvgSkew(0, ay));
var ay = float.Parse(contents, NumberStyles.Float, CultureInfo.InvariantCulture);
transformList.Add(new SvgSkew(0f, ay));
break;
}
}
@ -177,9 +146,7 @@ namespace Svg.Transforms
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
if (sourceType == typeof(string))
{
return true;
}
return base.CanConvertFrom(context, sourceType);
}
@ -187,24 +154,15 @@ namespace Svg.Transforms
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))
{
var transforms = value as SvgTransformCollection;
if (transforms != null)
{
return string.Join(" ", transforms.Select(t => t.WriteToString()).ToArray());
}
}
if (destinationType == typeof(string) && value is SvgTransformCollection)
return string.Join(" ", ((SvgTransformCollection)value).Select(t => t.WriteToString()).ToArray());
return base.ConvertTo(context, culture, value, destinationType);
}

Просмотреть файл

@ -1,59 +1,43 @@
using System;
using System.Collections.Generic;
using System.Drawing.Drawing2D;
using System.Globalization;
using System.Text;
namespace Svg.Transforms
{
public sealed class SvgTranslate : SvgTransform
{
private float x;
private float y;
public float X { get; set; }
public float X
{
get { return x; }
set { this.x = value; }
}
public float Y { get; set; }
public float Y
{
get { return y; }
set { this.y = value; }
}
public override System.Drawing.Drawing2D.Matrix Matrix
public override Matrix Matrix
{
get
{
Matrix matrix = new Matrix();
matrix.Translate(this.X, this.Y);
var matrix = new Matrix();
matrix.Translate(X, Y);
return matrix;
}
}
public override string WriteToString()
{
return string.Format(CultureInfo.InvariantCulture, "translate({0}, {1})", this.X, this.Y);
return string.Format(CultureInfo.InvariantCulture, "translate({0}, {1})", X, Y);
}
public SvgTranslate(float x, float y)
{
this.x = x;
this.y = y;
X = x;
Y = y;
}
public SvgTranslate(float x)
: this(x, 0.0f)
: this(x, 0f)
{
}
public override object Clone()
{
return new SvgTranslate(this.x, this.y);
return new SvgTranslate(X, Y);
}
}
}
}