Beispiel #1
0
        public static bool TryParseNumberOrPercentage(string numberOrPercentageText, out float result)
        {
            var ptr = new StringPtr(numberOrPercentageText);

            ptr.AdvanceNumber();

            var percentage = false;

            if (!ptr.IsEnd && ptr.Char == '%')
            {
                percentage = true;
                ++ptr;
            }
            if (ptr.Index != numberOrPercentageText.Length)
            {
                result = 0.0F;
                return(false);
            }

            if (percentage)
            {
                numberOrPercentageText = numberOrPercentageText.Substring(0, numberOrPercentageText.Length - 1);
            }
            result = float.Parse(numberOrPercentageText, System.Globalization.CultureInfo.InvariantCulture);
            if (percentage)
            {
                result /= 100.0F;
            }
            return(true);
        }
Beispiel #2
0
        private void ParseSkewY(StringPtr ptr)
        {
            if (ptr.String.StartsWith("skewY"))
            {
                ptr += 5;

                ptr.AdvanceWhiteSpace();
                if (ptr.Char == '(')
                {
                    ++ptr;
                    ptr.AdvanceWhiteSpace();

                    var angle = ParseNumber(ptr).Value;
                    this.ParseCommaOrWhitespace(ptr);

                    ptr.AdvanceWhiteSpace();
                    if (ptr.Char == ')')
                    {
                        ++ptr;
                        this.Transforms.Add(SvgTransform.CreateSkewY(angle));
                        return;
                    }
                }
                throw new ArgumentException("transformData");
            }
        }
		private SvgPathSegmentParser(string pathData)
		{
			this.Segments = new Collection<SvgPathSegment>();

			var ptr = new StringPtr(pathData);
			ptr.AdvanceWhiteSpace();
			this.ParseMoveToDrawToCommandGroups(ptr);
		}
		private SvgTransformParser(string pathData)
		{
			this.Transforms = new Collection<SvgTransform>();

			var ptr = new StringPtr(pathData);
			ptr.AdvanceWhiteSpace();
			this.ParseTransforms(ptr);
		}
		private void ParseTransforms(StringPtr ptr)
		{
			this.ParseTransform(ptr);
			if (!ptr.IsEnd && this.ParseCommaOrWhitespace(ptr))
			{
				this.ParseTransforms(ptr);
			}
		}
Beispiel #6
0
 private void ParseTransforms(StringPtr ptr)
 {
     this.ParseTransform(ptr);
     if (!ptr.IsEnd && this.ParseCommaOrWhitespace(ptr))
     {
         this.ParseTransforms(ptr);
     }
 }
		private void ParseTransform(StringPtr ptr)
		{
			this.ParseMatrix(ptr);
			this.ParseTranslate(ptr);
			this.ParseScale(ptr);
			this.ParseRotate(ptr);
			this.ParseSkewX(ptr);
			this.ParseSkewY(ptr);
		}
Beispiel #8
0
        private SvgTransformParser(string pathData)
        {
            this.Transforms = new Collection <SvgTransform>();

            var ptr = new StringPtr(pathData);

            ptr.AdvanceWhiteSpace();
            this.ParseTransforms(ptr);
        }
Beispiel #9
0
 private void ParseTransform(StringPtr ptr)
 {
     this.ParseMatrix(ptr);
     this.ParseTranslate(ptr);
     this.ParseScale(ptr);
     this.ParseRotate(ptr);
     this.ParseSkewX(ptr);
     this.ParseSkewY(ptr);
 }
		private bool ParseDrawToCommand(StringPtr ptr)
		{
			switch (ptr.Char)
			{
				case 'Z':
				case 'z':
					this.ParseClosePath(ptr);
					break;

				case 'L':
				case 'l':
					this.ParseLineTo(ptr);
					break;

				case 'H':
				case 'h':
					this.ParseHorizontalLineTo(ptr);
					break;

				case 'V':
				case 'v':
					this.ParseVerticalLineTo(ptr);
					break;

				case 'C':
				case 'c':
					this.ParseCurveTo(ptr);
					break;

				case 'S':
				case 's':
					this.ParseSmoothCurveTo(ptr);
					break;

				case 'Q':
				case 'q':
					this.ParseQuadraticBezierCurveTo(ptr);
					break;

				case 'T':
				case 't':
					this.ParseSmoothQuadraticBezierCurveTo(ptr);
					break;

				case 'A':
				case 'a':
					this.ParseQllipticalArc(ptr);
					break;

				default:
					return false;
			}
			return true;
		}
Beispiel #11
0
		internal static bool TryParse(string numberText, out SvgNumber result)
		{
			var ptr = new StringPtr(numberText);
			ptr.AdvanceNumber();
			if (ptr.Index != numberText.Length)
			{
				result = 0.0F;
				return false;
			}

			result = float.Parse(numberText, System.Globalization.CultureInfo.InvariantCulture);
			return true;
		}
Beispiel #12
0
		internal static bool TryParse(string numberText, float min, float max, out SvgNumber result)
		{
			var ptr = new StringPtr(numberText);
			ptr.AdvanceNumber();
			if (ptr.Index != numberText.Length)
			{
				result = 0.0F;
				return false;
			}

			result = Math.Min(Math.Max(float.Parse(numberText), min), max);
			return true;
		}
Beispiel #13
0
        private float?ParseNumber(StringPtr ptr)
        {
            var begin = ptr.Index;

            ptr.AdvanceNumber();
            if (begin == ptr.Index)
            {
                return(null);
            }

            var numberText = ptr.Target.Substring(begin, ptr.Index - begin);

            return(float.Parse(numberText, System.Globalization.CultureInfo.InvariantCulture));
        }
Beispiel #14
0
        private void ParseRotate(StringPtr ptr)
        {
            if (ptr.String.StartsWith("rotate"))
            {
                ptr += 6;

                ptr.AdvanceWhiteSpace();
                if (ptr.Char == '(')
                {
                    ++ptr;
                    ptr.AdvanceWhiteSpace();

                    var r = ParseNumber(ptr).Value;

                    var current = ptr.Index;
                    this.ParseCommaOrWhitespace(ptr);

                    var cx = ParseNumber(ptr);
                    if (cx.HasValue)
                    {
                        this.ParseCommaOrWhitespace(ptr);

                        var cy = ParseNumber(ptr).Value;
                        this.ParseCommaOrWhitespace(ptr);

                        ptr.AdvanceWhiteSpace();
                        if (ptr.Char == ')')
                        {
                            ++ptr;
                            this.Transforms.Add(SvgTransform.CreateRotate(r, cx.Value, cy));
                            return;
                        }
                    }
                    else
                    {
                        ptr.Index = current;

                        ptr.AdvanceWhiteSpace();
                        if (ptr.Char == ')')
                        {
                            ++ptr;
                            this.Transforms.Add(SvgTransform.CreateRotate(r));
                            return;
                        }
                    }
                }
                throw new ArgumentException("transformData");
            }
        }
		private bool ParseDrawToCommands(StringPtr ptr)
		{
			if (this.ParseDrawToCommand(ptr))
			{
				var current = ptr.Index;
				ptr.AdvanceWhiteSpace();
				if (!ptr.IsEnd)
				{
					if (!this.ParseDrawToCommands(ptr))
					{
						ptr.Index = current;
					}
				}
				return true;
			}
			return false;
		}
Beispiel #16
0
        private void ParseTranslate(StringPtr ptr)
        {
            if (ptr.String.StartsWith("translate"))
            {
                ptr += 9;

                ptr.AdvanceWhiteSpace();
                if (ptr.Char == '(')
                {
                    ++ptr;
                    ptr.AdvanceWhiteSpace();

                    var tx = ParseNumber(ptr).Value;

                    var current = ptr.Index;
                    this.ParseCommaOrWhitespace(ptr);

                    var ty = ParseNumber(ptr);
                    if (ty.HasValue)
                    {
                        this.ParseCommaOrWhitespace(ptr);

                        ptr.AdvanceWhiteSpace();
                        if (ptr.Char == ')')
                        {
                            ++ptr;
                            this.Transforms.Add(SvgTransform.CreateTranslate(tx, ty.Value));
                            return;
                        }
                    }
                    else
                    {
                        ptr.Index = current;

                        ptr.AdvanceWhiteSpace();
                        if (ptr.Char == ')')
                        {
                            ++ptr;
                            this.Transforms.Add(SvgTransform.CreateTranslate(tx, 0.0F));
                            return;
                        }
                    }
                }
                throw new ArgumentException("transformData");
            }
        }
		private void ParseTranslate(StringPtr ptr)
		{
			if (ptr.String.StartsWith("translate"))
			{
				ptr += 9;

				ptr.AdvanceWhiteSpace();
				if (ptr.Char == '(')
				{
					++ptr;
					ptr.AdvanceWhiteSpace();

					var tx = ParseNumber(ptr).Value;

					var current = ptr.Index;
					this.ParseCommaOrWhitespace(ptr);

					var ty = ParseNumber(ptr);
					if (ty.HasValue)
					{
						this.ParseCommaOrWhitespace(ptr);

						ptr.AdvanceWhiteSpace();
						if (ptr.Char == ')')
						{
							++ptr;
							this.Transforms.Add(SvgTransform.CreateTranslate(tx, ty.Value));
							return;
						}
					}
					else
					{
						ptr.Index = current;

						ptr.AdvanceWhiteSpace();
						if (ptr.Char == ')')
						{
							++ptr;
							this.Transforms.Add(SvgTransform.CreateTranslate(tx, 0.0F));
							return;
						}
					}
				}
				throw new ArgumentException("transformData");
			}
		}
Beispiel #18
0
        private void ParseMatrix(StringPtr ptr)
        {
            if (ptr.String.StartsWith("matrix"))
            {
                ptr += 6;

                ptr.AdvanceWhiteSpace();
                if (ptr.Char == '(')
                {
                    ++ptr;
                    ptr.AdvanceWhiteSpace();

                    var a = ParseNumber(ptr).Value;
                    this.ParseCommaOrWhitespace(ptr);

                    var b = ParseNumber(ptr).Value;
                    this.ParseCommaOrWhitespace(ptr);

                    var c = ParseNumber(ptr).Value;
                    this.ParseCommaOrWhitespace(ptr);

                    var d = ParseNumber(ptr).Value;
                    this.ParseCommaOrWhitespace(ptr);

                    var e = ParseNumber(ptr).Value;
                    this.ParseCommaOrWhitespace(ptr);

                    var f = ParseNumber(ptr).Value;
                    this.ParseCommaOrWhitespace(ptr);

                    ptr.AdvanceWhiteSpace();
                    if (ptr.Char == ')')
                    {
                        ++ptr;
                        this.Transforms.Add(SvgTransform.CreateMatrix(new SvgMatrix(a, b, c, d, e, f)));
                        return;
                    }
                }
                throw new ArgumentException("transformData");
            }
        }
		private void ParseMatrix(StringPtr ptr)
		{
			if (ptr.String.StartsWith("matrix"))
			{
				ptr += 6;

				ptr.AdvanceWhiteSpace();
				if (ptr.Char == '(')
				{
					++ptr;
					ptr.AdvanceWhiteSpace();

					var a = ParseNumber(ptr).Value;
					this.ParseCommaOrWhitespace(ptr);

					var b = ParseNumber(ptr).Value;
					this.ParseCommaOrWhitespace(ptr);

					var c = ParseNumber(ptr).Value;
					this.ParseCommaOrWhitespace(ptr);

					var d = ParseNumber(ptr).Value;
					this.ParseCommaOrWhitespace(ptr);

					var e = ParseNumber(ptr).Value;
					this.ParseCommaOrWhitespace(ptr);

					var f = ParseNumber(ptr).Value;
					this.ParseCommaOrWhitespace(ptr);

					ptr.AdvanceWhiteSpace();
					if (ptr.Char == ')')
					{
						++ptr;
						this.Transforms.Add(SvgTransform.CreateMatrix(new SvgMatrix(a, b, c, d, e, f)));
						return;
					}
				}
				throw new ArgumentException("transformData");
			}
		}
Beispiel #20
0
 private bool ParseCommaOrWhitespace(StringPtr ptr)
 {
     if (ptr.IsWhitespace())
     {
         ++ptr;
         ptr.AdvanceWhiteSpace();
         if (ptr.Char == ',')
         {
             ++ptr;
         }
         ptr.AdvanceWhiteSpace();
         return(true);
     }
     else if (ptr.Char == ',')
     {
         ++ptr;
         ptr.AdvanceWhiteSpace();
         return(true);
     }
     return(false);
 }
Beispiel #21
0
		public static bool TryParseNumberOrPercentage(string numberOrPercentageText, out float result)
		{
			var ptr = new StringPtr(numberOrPercentageText);
			ptr.AdvanceNumber();

			var percentage = false;
			if (!ptr.IsEnd && ptr.Char == '%')
			{
				percentage = true;
				++ptr;
			}
			if (ptr.Index != numberOrPercentageText.Length)
			{
				result = 0.0F;
				return false;
			}

			if (percentage) numberOrPercentageText = numberOrPercentageText.Substring(0, numberOrPercentageText.Length - 1);
			result = float.Parse(numberOrPercentageText, System.Globalization.CultureInfo.InvariantCulture);
			if (percentage) result /= 100.0F;
			return true;
		}
		private void ParseSmoothQuadraticBezierCurveTo(StringPtr ptr)
		{
			var abs = ptr.Char == 'T';
			++ptr;
			ptr.AdvanceWhiteSpace();
			this.ParseSmoothQuadraticBezierCurveToArgumentSequence(ptr, abs);
		}
Beispiel #23
0
		private static RgbColor ParseColorFunc(string color)
		{
			var ptr = new StringPtr(color);
			ptr.AdvanceWhiteSpace();

			var s1 = ptr.Index;
			ptr.AdvanceInteger();
			if (ptr.Index == s1) throw new ArgumentException(nameof(color));
			var r = byte.Parse(color.Substring(s1, ptr.Index - s1));

			var percentage = false;
			if (ptr.Char == '%')
			{
				percentage = true;
				++ptr;
			}

			ptr.AdvanceWhiteSpace();
			if (ptr.Char != ',') throw new ArgumentException(nameof(color));
			++ptr;
			ptr.AdvanceWhiteSpace();

			var s2 = ptr.Index;
			ptr.AdvanceInteger();
			if (ptr.Index == s2) throw new ArgumentException(nameof(color));
			var g = byte.Parse(color.Substring(s2, ptr.Index - s2));

			if (percentage)
			{
				if (ptr.Char != '%') throw new ArgumentException(nameof(color));
				++ptr;
			}

			ptr.AdvanceWhiteSpace();
			if (ptr.Char != ',') throw new ArgumentException(nameof(color));
			++ptr;
			ptr.AdvanceWhiteSpace();

			var s3 = ptr.Index;
			ptr.AdvanceInteger();
			if (ptr.Index == s3) throw new ArgumentException(nameof(color));
			var b = byte.Parse(color.Substring(s3, ptr.Index - s3));

			if (percentage)
			{
				if (ptr.Char != '%') throw new ArgumentException(nameof(color));
				++ptr;
			}

			ptr.AdvanceWhiteSpace();

			if (ptr.Char != ')') throw new ArgumentException(nameof(color));

			return percentage
				? new RgbColor((byte)(255.0F * r / 100.0F), (byte)(255.0F * g / 100.0F), (byte)(255.0F * b / 100.0F))
				: new RgbColor(r, g, b);
		}
		private void ParseVerticalLineToArgumentSequence(StringPtr ptr, bool abs)
		{
			var coordinate = ParseCoordinate(ptr);
			if (!coordinate.HasValue) return;
			this.Segments.Add(SvgPathSegmentLineToVerticalBase.Create(coordinate.Value, abs));

			if (this.ParseCommaOrWhitespace(ptr))
			{
				this.ParseVerticalLineToArgumentSequence(ptr, abs);
			}
		}
		private void ParseSkewY(StringPtr ptr)
		{
			if (ptr.String.StartsWith("skewY"))
			{
				ptr += 5;

				ptr.AdvanceWhiteSpace();
				if (ptr.Char == '(')
				{
					++ptr;
					ptr.AdvanceWhiteSpace();

					var angle = ParseNumber(ptr).Value;
					this.ParseCommaOrWhitespace(ptr);

					ptr.AdvanceWhiteSpace();
					if (ptr.Char == ')')
					{
						++ptr;
						this.Transforms.Add(SvgTransform.CreateSkewY(angle));
						return;
					}
				}
				throw new ArgumentException("transformData");
			}
		}
		private void ParseMoveToDrawToCommandGroup(StringPtr ptr)
		{
			this.ParseMoveTo(ptr);
			ptr.AdvanceWhiteSpace();
			if (!ptr.IsEnd) this.ParseDrawToCommands(ptr);
		}
		private void ParseRotate(StringPtr ptr)
		{
			if (ptr.String.StartsWith("rotate"))
			{
				ptr += 6;

				ptr.AdvanceWhiteSpace();
				if (ptr.Char == '(')
				{
					++ptr;
					ptr.AdvanceWhiteSpace();

					var r = ParseNumber(ptr).Value;

					var current = ptr.Index;
					this.ParseCommaOrWhitespace(ptr);

					var cx = ParseNumber(ptr);
					if (cx.HasValue)
					{
						this.ParseCommaOrWhitespace(ptr);

						var cy = ParseNumber(ptr).Value;
						this.ParseCommaOrWhitespace(ptr);

						ptr.AdvanceWhiteSpace();
						if (ptr.Char == ')')
						{
							++ptr;
							this.Transforms.Add(SvgTransform.CreateRotate(r, cx.Value, cy));
							return;
						}
					}
					else
					{
						ptr.Index = current;

						ptr.AdvanceWhiteSpace();
						if (ptr.Char == ')')
						{
							++ptr;
							this.Transforms.Add(SvgTransform.CreateRotate(r));
							return;
						}
					}
				}
				throw new ArgumentException("transformData");
			}
		}
		private void ParseQllipticalArc(StringPtr ptr)
		{
			var abs = ptr.Char == 'A';
			++ptr;
			ptr.AdvanceWhiteSpace();
			this.ParseQllipticalArcArgumentSequence(ptr, abs);
		}
		private void ParseQllipticalArcArgumentSequence(StringPtr ptr, bool abs)
		{
			var nonNegativeNumber = this.ParseNonNegativeNumber(ptr);
			if (nonNegativeNumber == null) return;
			this.ParseCommaOrWhitespace(ptr);

			var nonNegativeNumber2 = this.ParseNonNegativeNumber(ptr).Value;
			this.ParseCommaOrWhitespace(ptr);

			var number = this.ParseNumber(ptr).Value;
			if (this.ParseCommaOrWhitespace(ptr))
			{
				var flag = this.ParseFlag(ptr);
				this.ParseCommaOrWhitespace(ptr);

				var flag2 = this.ParseFlag(ptr);
				this.ParseCommaOrWhitespace(ptr);

				var coordinate = this.ParseCoordinatePair(ptr);

				this.Segments.Add(SvgPathSegmentArcBase.Create(coordinate.Item1, coordinate.Item2, nonNegativeNumber.Value, nonNegativeNumber2, number, flag, flag2, abs));

				if (this.ParseCommaOrWhitespace(ptr))
				{
					this.ParseQllipticalArcArgumentSequence(ptr, abs);
				}
				return;
			}
			throw new ArgumentException("pathData");
		}
		private Tuple<float, float> ParseCoordinatePair(StringPtr ptr)
		{
			var x = this.ParseCoordinate(ptr);
			if (!x.HasValue) return null;

			this.ParseCommaOrWhitespace(ptr);
			var y = this.ParseCoordinate(ptr);
			if (!y.HasValue) return null;

			return Tuple.Create(x.Value, y.Value);
		}
		private float? ParseCoordinate(StringPtr ptr) => ParseNumber(ptr);
		private void ParseSmoothCurveToArgumentSequence(StringPtr ptr, bool abs)
		{
			var coordinate = ParseCoordinatePair(ptr);
			if (coordinate == null) return;
			this.ParseCommaOrWhitespace(ptr);

			var coordinate2 = ParseCoordinatePair(ptr);
			this.Segments.Add(SvgPathSegmentCurveToCubicSmoothBase.Create(coordinate.Item1, coordinate.Item2, coordinate2.Item1, coordinate2.Item2, abs));

			if (this.ParseCommaOrWhitespace(ptr))
			{
				this.ParseSmoothCurveToArgumentSequence(ptr, abs);
			}
		}
		private void ParseCurveTo(StringPtr ptr)
		{
			var abs = ptr.Char == 'C';
			++ptr;
			ptr.AdvanceWhiteSpace();
			this.ParseCurveToArgumentSequence(ptr, abs);
		}
		private float? ParseNumber(StringPtr ptr)
		{
			var begin = ptr.Index;
			ptr.AdvanceNumber();
			if (begin == ptr.Index) return null;

			var numberText = ptr.Target.Substring(begin, ptr.Index - begin);
			return float.Parse(numberText, System.Globalization.CultureInfo.InvariantCulture);
		}
		private void ParseHorizontalLineTo(StringPtr ptr)
		{
			var abs = ptr.Char == 'H';
			++ptr;
			ptr.AdvanceWhiteSpace();
			this.ParseHorizontalLineToArgumentSequence(ptr, abs);
		}
		private bool ParseCommaOrWhitespace(StringPtr ptr)
		{
			if (ptr.IsWhitespace())
			{
				++ptr;
				ptr.AdvanceWhiteSpace();
				if (ptr.Char == ',') ++ptr;
				ptr.AdvanceWhiteSpace();
				return true;
			}
			else if (ptr.Char == ',')
			{
				++ptr;
				ptr.AdvanceWhiteSpace();
				return true;
			}
			return false;
		}
		private void ParseClosePath(StringPtr ptr)
		{
			++ptr;
			this.Segments.Add(new SvgPathSegmentClosePath());
		}
		private void ParseSmoothQuadraticBezierCurveToArgumentSequence(StringPtr ptr, bool abs)
		{
			var coordinate = ParseCoordinatePair(ptr);
			this.Segments.Add(SvgPathSegmentCurveToQuadraticSmoothBase.Create(coordinate.Item1, coordinate.Item2, abs));

			if (this.ParseCommaOrWhitespace(ptr))
			{
				this.ParseSmoothQuadraticBezierCurveToArgumentSequence(ptr, abs);
			}
		}
		private void ParseMoveTo(StringPtr ptr)
		{
			if (char.ToLower(ptr.Char) == 'm')
			{
				var abs = ptr.Char == 'M';
				++ptr;
				ptr.AdvanceWhiteSpace();
				this.ParseMoveToArgumentSequence(ptr, abs);
				return;
			}
			throw new ArgumentException("pathData");
		}
		private bool ParseFlag(StringPtr ptr)
		{
			var flag = ptr.Char == '1';
			if (!flag && ptr.Char != '0') throw new ArgumentException("pathData");
			++ptr;
			return flag;
		}