Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions src/ShimSkiaSharp/SKShader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ public abstract record SKShader : IDeepCloneable<SKShader>
public static SKShader CreateColor(SKColor color, SKColorSpace colorSpace)
=> new ColorShader(color, colorSpace);

public static SKShader CreateLinearGradient(SKPoint start, SKPoint end, SKColorF[] colors, SKColorSpace colorSpace, float[] colorPos, SKShaderTileMode mode)
public static SKShader CreateLinearGradient(SKPoint start, SKPoint end, SKColorF[] colors, SKColorSpace colorSpace, float[]? colorPos, SKShaderTileMode mode)
=> new LinearGradientShader(start, end, colors, colorSpace, colorPos, mode, null);

public static SKShader CreateLinearGradient(SKPoint start, SKPoint end, SKColorF[] colors, SKColorSpace colorSpace, float[] colorPos, SKShaderTileMode mode, SKMatrix localMatrix)
public static SKShader CreateLinearGradient(SKPoint start, SKPoint end, SKColorF[] colors, SKColorSpace colorSpace, float[]? colorPos, SKShaderTileMode mode, SKMatrix localMatrix)
=> new LinearGradientShader(start, end, colors, colorSpace, colorPos, mode, localMatrix);

public static SKShader CreatePerlinNoiseFractalNoise(float baseFrequencyX, float baseFrequencyY, int numOctaves, float seed, SKPointI tileSize)
Expand All @@ -24,16 +24,16 @@ public static SKShader CreatePerlinNoiseTurbulence(float baseFrequencyX, float b
public static SKShader CreatePicture(SKPicture src, SKShaderTileMode tmx, SKShaderTileMode tmy, SKMatrix localMatrix, SKRect tile)
=> new PictureShader(src, tmx, tmy, localMatrix, tile);

public static SKShader CreateRadialGradient(SKPoint center, float radius, SKColorF[] colors, SKColorSpace colorSpace, float[] colorPos, SKShaderTileMode mode)
public static SKShader CreateRadialGradient(SKPoint center, float radius, SKColorF[] colors, SKColorSpace colorSpace, float[]? colorPos, SKShaderTileMode mode)
=> new RadialGradientShader(center, radius, colors, colorSpace, colorPos, mode, null);

public static SKShader CreateRadialGradient(SKPoint center, float radius, SKColorF[] colors, SKColorSpace colorSpace, float[] colorPos, SKShaderTileMode mode, SKMatrix localMatrix)
public static SKShader CreateRadialGradient(SKPoint center, float radius, SKColorF[] colors, SKColorSpace colorSpace, float[]? colorPos, SKShaderTileMode mode, SKMatrix localMatrix)
=> new RadialGradientShader(center, radius, colors, colorSpace, colorPos, mode, localMatrix);

public static SKShader CreateTwoPointConicalGradient(SKPoint start, float startRadius, SKPoint end, float endRadius, SKColorF[] colors, SKColorSpace colorSpace, float[] colorPos, SKShaderTileMode mode)
public static SKShader CreateTwoPointConicalGradient(SKPoint start, float startRadius, SKPoint end, float endRadius, SKColorF[] colors, SKColorSpace colorSpace, float[]? colorPos, SKShaderTileMode mode)
=> new TwoPointConicalGradientShader(start, startRadius, end, endRadius, colors, colorSpace, colorPos, mode, null);

public static SKShader CreateTwoPointConicalGradient(SKPoint start, float startRadius, SKPoint end, float endRadius, SKColorF[] colors, SKColorSpace colorSpace, float[] colorPos, SKShaderTileMode mode, SKMatrix localMatrix)
public static SKShader CreateTwoPointConicalGradient(SKPoint start, float startRadius, SKPoint end, float endRadius, SKColorF[] colors, SKColorSpace colorSpace, float[]? colorPos, SKShaderTileMode mode, SKMatrix localMatrix)
=> new TwoPointConicalGradientShader(start, startRadius, end, endRadius, colors, colorSpace, colorPos, mode, localMatrix);

public SKShader DeepClone() => DeepClone(new CloneContext());
Expand Down
47 changes: 34 additions & 13 deletions src/Svg.CodeGen.Skia/SkiaCSharpModelExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,17 @@ public static string ToIntString(this int value)

public static string ToFloatString(this float value)
{
if (float.IsNaN(value) || float.IsNegativeInfinity(value) || float.IsPositiveInfinity(value))
if (float.IsNaN(value))
{
return string.Concat("float.", value.ToString(s_ci));
return "float.NaN";
}
if (float.IsNegativeInfinity(value))
{
return "float.NegativeInfinity";
}
if (float.IsPositiveInfinity(value))
{
return "float.PositiveInfinity";
}
return string.Concat(value.ToString(s_ci), "f");
}
Expand Down Expand Up @@ -67,7 +75,7 @@ public static StringBuilder ToFloatArray(this float[] array)

for (int i = 0; i < array.Length; i++)
{
sb.AppendFormat(s_ci, "{0:g}f, ", array[i]); // C# allows trailing , on end element
sb.Append(array[i].ToFloatString()).Append(", "); // C# allows trailing , on end element
}

sb.Append(" }");
Expand All @@ -81,14 +89,24 @@ public static StringBuilder ToStringArray(this string[] array)

for (int i = 0; i < array.Length; i++)
{
sb.AppendFormat(s_ci, "@\"{0}\", ", array[i]); // C# allows trailing , on end element
sb.AppendFormat(s_ci, "@\"{0}\", ", array[i].Replace("\"", "\"\"")); // C# allows trailing , on end element
}

sb.Append(" }");

return sb;
}

private static string ToGradientColorPositions(float[]? array)
{
if (array is null || array.Any(static value => float.IsNaN(value) || float.IsNegativeInfinity(value) || float.IsPositiveInfinity(value)))
{
return "null";
}

return array.ToFloatArray().ToString();
}

public static string ToSKPoint(this SKPoint point)
{
return $"new SKPoint({point.X.ToFloatString()}, {point.Y.ToFloatString()})";
Expand Down Expand Up @@ -434,12 +452,13 @@ public static void ToSKShader(this SKShader? shader, SkiaCSharpCodeGenCounter co
}
case LinearGradientShader linearGradientShader:
{
if (linearGradientShader.Colors is null || linearGradientShader.ColorPos is null)
if (linearGradientShader.Colors is null)
{
sb.AppendLine($"{indent}var {counter.ShaderVarName}{counterShader} = default(SKShader);");
return;
}

var colorPos = ToGradientColorPositions(linearGradientShader.ColorPos);
if (linearGradientShader.LocalMatrix is { })
{
sb.Append($"{indent}var {counter.ShaderVarName}{counterShader} = ");
Expand All @@ -448,7 +467,7 @@ public static void ToSKShader(this SKShader? shader, SkiaCSharpCodeGenCounter co
sb.AppendLine($"{indent} {linearGradientShader.End.ToSKPoint()},");
sb.AppendLine($"{indent} {linearGradientShader.Colors.ToSKColors()},");
sb.AppendLine($"{indent} {(linearGradientShader.ColorSpace == SKColorSpace.Srgb ? s_srgb : s_srgbLinear)},");
sb.AppendLine($"{indent} {linearGradientShader.ColorPos.ToFloatArray()},");
sb.AppendLine($"{indent} {colorPos},");
sb.AppendLine($"{indent} {linearGradientShader.Mode.ToSKShaderTileMode()},");
sb.AppendLine($"{indent} {linearGradientShader.LocalMatrix.Value.ToSKMatrix()});");
return;
Expand All @@ -461,19 +480,20 @@ public static void ToSKShader(this SKShader? shader, SkiaCSharpCodeGenCounter co
sb.AppendLine($"{indent} {linearGradientShader.End.ToSKPoint()},");
sb.AppendLine($"{indent} {linearGradientShader.Colors.ToSKColors()},");
sb.AppendLine($"{indent} {(linearGradientShader.ColorSpace == SKColorSpace.Srgb ? s_srgb : s_srgbLinear)},");
sb.AppendLine($"{indent} {linearGradientShader.ColorPos.ToFloatArray()},");
sb.AppendLine($"{indent} {colorPos},");
sb.AppendLine($"{indent} {linearGradientShader.Mode.ToSKShaderTileMode()});");
return;
}
}
case RadialGradientShader radialGradientShader:
{
if (radialGradientShader.Colors is null || radialGradientShader.ColorPos is null)
if (radialGradientShader.Colors is null)
{
sb.AppendLine($"{indent}var {counter.ShaderVarName}{counterShader} = default(SKShader);");
return;
}

var colorPos = ToGradientColorPositions(radialGradientShader.ColorPos);
if (radialGradientShader.LocalMatrix is { })
{
sb.Append($"{indent}var {counter.ShaderVarName}{counterShader} = ");
Expand All @@ -482,7 +502,7 @@ public static void ToSKShader(this SKShader? shader, SkiaCSharpCodeGenCounter co
sb.AppendLine($"{indent} {radialGradientShader.Radius.ToFloatString()},");
sb.AppendLine($"{indent} {radialGradientShader.Colors.ToSKColors()},");
sb.AppendLine($"{indent} {(radialGradientShader.ColorSpace == SKColorSpace.Srgb ? s_srgb : s_srgbLinear)},");
sb.AppendLine($"{indent} {radialGradientShader.ColorPos.ToFloatArray()},");
sb.AppendLine($"{indent} {colorPos},");
sb.AppendLine($"{indent} {radialGradientShader.Mode.ToSKShaderTileMode()},");
sb.AppendLine($"{indent} {radialGradientShader.LocalMatrix.Value.ToSKMatrix()});");
return;
Expand All @@ -495,19 +515,20 @@ public static void ToSKShader(this SKShader? shader, SkiaCSharpCodeGenCounter co
sb.AppendLine($"{indent} {radialGradientShader.Radius.ToFloatString()},");
sb.AppendLine($"{indent} {radialGradientShader.Colors.ToSKColors()},");
sb.AppendLine($"{indent} {(radialGradientShader.ColorSpace == SKColorSpace.Srgb ? s_srgb : s_srgbLinear)},");
sb.AppendLine($"{indent} {radialGradientShader.ColorPos.ToFloatArray()},");
sb.AppendLine($"{indent} {colorPos},");
sb.AppendLine($"{indent} {radialGradientShader.Mode.ToSKShaderTileMode()});");
return;
}
}
case TwoPointConicalGradientShader twoPointConicalGradientShader:
{
if (twoPointConicalGradientShader.Colors is null || twoPointConicalGradientShader.ColorPos is null)
if (twoPointConicalGradientShader.Colors is null)
{
sb.AppendLine($"{indent}var {counter.ShaderVarName}{counterShader} = default(SKShader);");
return;
}

var colorPos = ToGradientColorPositions(twoPointConicalGradientShader.ColorPos);
if (twoPointConicalGradientShader.LocalMatrix is { })
{
sb.Append($"{indent}var {counter.ShaderVarName}{counterShader} = ");
Expand All @@ -518,7 +539,7 @@ public static void ToSKShader(this SKShader? shader, SkiaCSharpCodeGenCounter co
sb.AppendLine($"{indent} {twoPointConicalGradientShader.EndRadius.ToFloatString()},");
sb.AppendLine($"{indent} {twoPointConicalGradientShader.Colors.ToSKColors()},");
sb.AppendLine($"{indent} {(twoPointConicalGradientShader.ColorSpace == SKColorSpace.Srgb ? s_srgb : s_srgbLinear)},");
sb.AppendLine($"{indent} {twoPointConicalGradientShader.ColorPos.ToFloatArray()},");
sb.AppendLine($"{indent} {colorPos},");
sb.AppendLine($"{indent} {twoPointConicalGradientShader.Mode.ToSKShaderTileMode()},");
sb.AppendLine($"{indent} {twoPointConicalGradientShader.LocalMatrix.Value.ToSKMatrix()});");
return;
Expand All @@ -533,7 +554,7 @@ public static void ToSKShader(this SKShader? shader, SkiaCSharpCodeGenCounter co
sb.AppendLine($"{indent} {twoPointConicalGradientShader.EndRadius.ToFloatString()},");
sb.AppendLine($"{indent} {twoPointConicalGradientShader.Colors.ToSKColors()},");
sb.AppendLine($"{indent} {(twoPointConicalGradientShader.ColorSpace == SKColorSpace.Srgb ? s_srgb : s_srgbLinear)},");
sb.AppendLine($"{indent} {twoPointConicalGradientShader.ColorPos.ToFloatArray()},");
sb.AppendLine($"{indent} {colorPos},");
sb.AppendLine($"{indent} {twoPointConicalGradientShader.Mode.ToSKShaderTileMode()});");
return;
}
Expand Down
21 changes: 18 additions & 3 deletions src/Svg.Model/Services/PaintingService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -134,10 +134,8 @@ private static void GetStopsImpl(
{
stopColor = ToLinear(stopColor);
}
var offset = svgGradientStop.Offset.ToDeviceValue(UnitRenderingType.Horizontal, svgGradientServer, skBounds);
offset /= skBounds.Width;
colors.Add(stopColor);
colorPos.Add(offset);
colorPos.Add(GetGradientStopOffset(svgGradientStop));
}
}
}
Expand Down Expand Up @@ -183,6 +181,23 @@ private static void AdjustStopColorPos(List<float> colorPos)
}
}

private static float GetGradientStopOffset(SvgGradientStop svgGradientStop)
{
var offset = svgGradientStop.Offset;
var value = offset.Type == SvgUnitType.Percentage ? offset.Value / 100f : offset.Value;
if (float.IsNaN(value) || float.IsNegativeInfinity(value))
{
return 0f;
}

if (float.IsPositiveInfinity(value))
{
return 1f;
}

return Math.Min(Math.Max(value, 0f), 1f);
}

internal static SKColorF[] ToSkColorF(this SKColor[] skColors)
{
var skColorsF = new SKColorF[skColors.Length];
Expand Down
21 changes: 18 additions & 3 deletions src/Svg.SceneGraph/SvgScenePaintingService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -466,10 +466,8 @@ private static void GetStops(
stopColor = ToLinear(stopColor);
}

var offset = svgGradientStop.Offset.ToDeviceValue(UnitRenderingType.Horizontal, svgReferencedGradientServer, skBounds);
offset /= skBounds.Width;
colors.Add(stopColor);
colorPos.Add(offset);
colorPos.Add(GetGradientStopOffset(svgGradientStop));
}
}
}
Expand All @@ -491,6 +489,23 @@ private static void AdjustStopColorPos(List<float> colorPos)
}
}

private static float GetGradientStopOffset(SvgGradientStop svgGradientStop)
{
var offset = svgGradientStop.Offset;
var value = offset.Type == SvgUnitType.Percentage ? offset.Value / 100f : offset.Value;
if (float.IsNaN(value) || float.IsNegativeInfinity(value))
{
return 0f;
}

if (float.IsPositiveInfinity(value))
{
return 1f;
}

return Math.Min(Math.Max(value, 0f), 1f);
}

private static SKColorF[] ToSkColorF(IReadOnlyList<SKColor> skColors)
{
var skColorsF = new SKColorF[skColors.Count];
Expand Down
Loading
Loading