private Point GetPosition(CssReader reader) { if (reader.CanRead) { var token = reader.Read().Trim(); if (token == "at") { var tokenX = reader.ReadNext(); var tokenY = reader.ReadNext(); var isPosX = tokenX.TryConvertOffset(out var posX); var isPosY = tokenY.TryConvertOffset(out var posY); var direction = Vector2.Zero; if (!isPosX && !string.IsNullOrEmpty(tokenX)) { direction.SetNamedDirection(tokenX); } if (!isPosY && !string.IsNullOrEmpty(tokenY)) { direction.SetNamedDirection(tokenY); } return(new Point( isPosX ? posX : (direction.X + 1) / 2, isPosY ? posY : (direction.Y + 1) / 2)); } } return(new Point(0.5, 0.5)); }
private (Point, RadialGradientFlags) GetPositionWithFlags(CssReader reader) { if (reader.CanRead) { var token = reader.Read().Trim(); if (token == "at") { var tokenX = reader.ReadNext(); var tokenY = reader.ReadNext(); var isPosX = OffsetConverter.TryExtractOffset(tokenX, out var posX); var isPosY = OffsetConverter.TryExtractOffset(tokenY, out var posY); var direction = Vector2.Zero; if (!isPosX && !string.IsNullOrEmpty(tokenX)) { direction.SetNamedDirection(tokenX); } if (!isPosY && !string.IsNullOrEmpty(tokenY)) { direction.SetNamedDirection(tokenY); } var flags = None; if (!isPosX || posX.Type == OffsetType.Proportional) { flags |= XProportional; } if (!isPosY || posY.Type == OffsetType.Proportional) { flags |= YProportional; } var center = new Point( isPosX ? posX.Value : (direction.X + 1) / 2, isPosY ? posY.Value : (direction.Y + 1) / 2); return(center, flags); } } return(new Point(0.5, 0.5), PositionProportional); }
public void Parse(CssReader reader, GradientBuilder builder) { var isRepeating = reader.Read().Trim() == CssToken.RepeatingRadialGradient; var token = reader.ReadNext().Trim(); var internalReader = new CssReader(token, ' '); var(hasShape, shape) = GetShape(internalReader); var(hasStretch, stretch) = GetStretch(internalReader); var(hasRadius, radius) = GeRadius(internalReader, shape); var(hasPos, position) = GetPosition(internalReader); builder.UseBuilder(new RadialGradientBuilder { Center = position, Shape = shape, Stretch = stretch, Radius = radius, IsRepeating = isRepeating }); if (!hasShape && !hasStretch && !hasRadius && !hasPos) { reader.Rollback(); } }
public void Parse(CssReader reader, GradientBuilder builder) { var isRepeating = reader.Read().Trim() == CssToken.RepeatingRadialGradient; var token = reader.ReadNext().Trim(); var internalReader = new CssReader(token, ' '); var flags = None; var(hasShape, shape) = GetShape(internalReader); var(hasSize, size) = GetSize(internalReader); var(hasRadius, radius) = GeRadius(internalReader, shape, ref flags); var(hasPos, position) = GetPosition(internalReader, ref flags); builder.UseBuilder(new RadialGradientBuilder { Center = position, Shape = shape, Size = size, RadiusX = radius.Width, RadiusY = radius.Height, Flags = flags, IsRepeating = isRepeating }); if (!hasShape && !hasSize && !hasRadius && !hasPos) { reader.Rollback(); } }
private (bool, Point) GetPosition(CssReader reader, ref RadialGradientFlags flags) { if (reader.CanRead) { var token = reader.Read().Trim(); if (token == "at") { var tokenX = reader.ReadNext(); var tokenY = reader.ReadNext(); var isPosX = OffsetConverter.TryExtractOffset(tokenX, out var posX); var isPosY = OffsetConverter.TryExtractOffset(tokenY, out var posY); var direction = Vector2.Zero; if (!isPosX && !string.IsNullOrEmpty(tokenX)) { direction.SetNamedDirection(tokenX); } if (!isPosY && !string.IsNullOrEmpty(tokenY)) { direction.SetNamedDirection(tokenY); } if (!isPosX || posX.Type == OffsetType.Proportional) { FlagsHelper.Set(ref flags, XProportional); } if (!isPosY || posY.Type == OffsetType.Proportional) { FlagsHelper.Set(ref flags, YProportional); } var center = new Point( isPosX ? posX.Value : (direction.X + 1) / 2, isPosY ? posY.Value : (direction.Y + 1) / 2); return(true, center); } } FlagsHelper.Set(ref flags, PositionProportional); return(false, new Point(0.5, 0.5)); }
private (bool, Size) GeRadius(CssReader reader, RadialGradientShape shape, ref RadialGradientFlags flags) { if (reader.CanRead) { var size = Dimensions.Zero; if (shape == RadialGradientShape.Circle) { var radiusToken = reader.Read(); var isRadius = OffsetConverter.TryExtractOffset(radiusToken, out var radius); if (isRadius) { size = new Dimensions(radius, radius); reader.MoveNext(); } } if (shape == RadialGradientShape.Ellipse) { var radiusHToken = reader.Read(); var radiusVToken = reader.ReadNext(); var isRadiusH = OffsetConverter.TryExtractOffset(radiusHToken, out var radiusH); var isRadiusV = OffsetConverter.TryExtractOffset(radiusVToken, out var radiusV); if (isRadiusH && isRadiusV) { size = new Dimensions(radiusH, radiusV); reader.MoveNext(); } else { // Revert radiusVToken reader.Rollback(); } } if (size != Dimensions.Zero) { if (size.Width.Type == OffsetType.Proportional) { FlagsHelper.Set(ref flags, WidthProportional); } if (size.Height.Type == OffsetType.Proportional) { FlagsHelper.Set(ref flags, HeightProportional); } return(true, new Size(size.Width.Value, size.Height.Value)); } } // Value -1 means undefined for RadialGradientShader return(false, new Size(-1, -1)); }
internal string GetColorString(CssReader reader) { var token = reader.Read().Trim(); var builder = new StringBuilder(token); builder.Append('('); builder.Append(reader.ReadNext()); builder.Append(','); builder.Append(reader.ReadNext()); builder.Append(','); builder.Append(reader.ReadNext()); if (token == CssToken.Rgba || token == CssToken.Hsla) { builder.Append(','); builder.Append(reader.ReadNext()); } builder.Append(')'); return(builder.ToString()); }
public void Parse(CssReader reader, LinearGradientBuilder builder) { var color = (Color)ColorConverter.ConvertFromInvariantString(GetColorString(reader)); if (TryConvertPercentToOffset(reader.ReadNext(), out var offset)) { builder.AddStop(color, offset); } else { builder.AddStop(color); reader.Rollback(); } }
public void Parse(CssReader reader, GradientBuilder builder) { var isRepeating = reader.Read().Trim() == CssToken.RepeatingRadialGradient; var token = reader.ReadNext().Trim(); var internalReader = new CssReader(token, ' '); var shape = GetShape(internalReader); var shapeSize = GetShapeSize(internalReader); var(position, flags) = GetPositionWithFlags(internalReader); builder.AddRadialGradient(position, shape, shapeSize, flags, isRepeating); }
public void Parse(CssReader reader, GradientBuilder builder) { var color = (Color)ColorConverter.ConvertFromInvariantString(GetColorString(reader)); var parts = reader.ReadNext().Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); if (parts.TryConvertOffsets(out var offsets)) { builder.AddStops(color, offsets); } else { builder.AddStop(color); reader.Rollback(); } }
private (bool, Position) GetPosition(CssReader reader) { if (reader.CanRead) { var token = reader.Read().Trim(); if (token == "at") { var tokenX = reader.ReadNext(); var tokenY = reader.ReadNext(); var isPosX = Offset.TryParseWithUnit(tokenX, out var posX); var isPosY = Offset.TryParseWithUnit(tokenY, out var posY); var direction = Vector2.Zero; if (!isPosX && !string.IsNullOrEmpty(tokenX)) { direction.SetNamedDirection(tokenX); } if (!isPosY && !string.IsNullOrEmpty(tokenY)) { direction.SetNamedDirection(tokenY); } var center = new Position( isPosX ? posX : Offset.Prop((direction.X + 1) / 2), isPosY ? posY : Offset.Prop((direction.Y + 1) / 2)); return(true, center); } } return(false, Position.Prop(0.5, 0.5)); }
public void Parse(CssReader reader, GradientBuilder builder) { var colorString = GetColorString(reader); var color = Color.Parse(colorString); var parts = reader.ReadNext().Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); var offsets = GetOffsets(parts); if (offsets.Any()) { builder.AddStops(color, offsets); } else { builder.AddStop(color); reader.Rollback(); } }
private (bool, Dimensions) GeRadius(CssReader reader, RadialGradientShape shape) { if (reader.CanRead) { var size = Dimensions.Zero; if (shape == RadialGradientShape.Circle) { var radiusToken = reader.Read(); var isRadius = Offset.TryParseWithUnit(radiusToken, out var radius); if (isRadius) { size = new Dimensions(radius, radius); reader.MoveNext(); } } if (shape == RadialGradientShape.Ellipse) { var radiusHToken = reader.Read(); var radiusVToken = reader.ReadNext(); var isRadiusH = Offset.TryParseWithUnit(radiusHToken, out var radiusH); var isRadiusV = Offset.TryParseWithUnit(radiusVToken, out var radiusV); if (isRadiusH && isRadiusV) { size = new Dimensions(radiusH, radiusV); reader.MoveNext(); } else { // Revert radiusVToken reader.Rollback(); } } if (size != Dimensions.Zero) { return(true, size); } } return(false, Dimensions.Zero); }
public void Parse(CssReader reader, LinearGradientBuilder builder) { var direction = reader.ReadNext().Trim(); if (TryConvertDegreeToAngle(direction, out var degreeToAngle)) { builder.AddGradient(degreeToAngle); } else if (TryConvertNamedDirectionToAngle(direction, out var directionToAngle)) { builder.AddGradient(directionToAngle); } else { builder.AddGradient(0); reader.Rollback(); } }
public void Parse(CssReader reader, GradientBuilder builder) { var repeating = reader.Read().Trim() == CssToken.RepeatingLinearGradient; var direction = reader.ReadNext().Trim(); var angle = 0d; var hasAngle = TryConvertDegreeToAngle(direction, out angle) || TryConvertTurnToAngle(direction, out angle) || TryConvertNamedDirectionToAngle(direction, out angle); if (hasAngle) { builder.AddLinearGradient(angle, repeating); } else { builder.AddLinearGradient(0, repeating); reader.Rollback(); } }
public void Parse(CssReader reader, GradientBuilder builder) { var repeating = reader.Read().Trim() == CssToken.RepeatingLinearGradient; var direction = reader.ReadNext().Trim(); var angle = 0d; var hasAngle = TryConvertDegreeToAngle(direction, out angle) || TryConvertTurnToAngle(direction, out angle) || TryConvertNamedDirectionToAngle(direction, out angle); builder.UseBuilder(new LinearGradientBuilder { Angle = angle, IsRepeating = repeating }); if (!hasAngle) { reader.Rollback(); } }