/// <summary> /// Read the common properties and include the href chain recursively /// </summary> private void ReadGradientProperties(XElement gradientElem, double opacity, GraphicGradientBrush gradientBrush) { void ReadHrefGradientPropertiesRecurse(XElement gradientElemRecurse, double opacityRecurse, GraphicGradientBrush gradientBrushRecurse) { var hrefAttribute = gradientElemRecurse.Attribute(xlink + "href"); if (hrefAttribute == null) { hrefAttribute = gradientElemRecurse.Attribute("href"); } if (hrefAttribute != null) { var id = hrefAttribute.Value.Substring(1); if (globalDefinitions.ContainsKey(id)) { var hrefElem = globalDefinitions[id]; ReadHrefGradientPropertiesRecurse(hrefElem, opacityRecurse, gradientBrushRecurse); } } GetCommonGradientProperties(gradientElemRecurse, opacityRecurse, gradientBrushRecurse); } gradientBrush.GradientStops = new List <GraphicGradientStop>(); gradientBrush.MappingMode = GraphicBrushMappingMode.RelativeToBoundingBox; ReadHrefGradientPropertiesRecurse(gradientElem, opacity, gradientBrush); }
/// <summary> /// Write a shading pattern definition /// </summary> private void WriteShadingPattern(string shadingType, GraphicGradientBrush gradientBrush, Rect boundingBox, string coords) { outputStream.WriteLine("[/Pattern] setcolorspace"); outputStream.WriteLine("<<"); outputStream.WriteLine("/PatternType 2"); outputStream.WriteLine("/Shading"); outputStream.WriteLine("<<"); outputStream.WriteLine($"/ShadingType {shadingType}"); outputStream.WriteLine("/ColorSpace [/DeviceRGB]"); outputStream.WriteLine(coords); outputStream.WriteLine("/Domain [0 1]"); outputStream.WriteLine("/Extend [true true]"); outputStream.WriteLine("/Function"); if (gradientBrush.GradientStops.Count == 2) { WriteExponentialFunction(gradientBrush.GradientStops[0].Color, gradientBrush.GradientStops[1].Color); } else { WriteStitchingFunction(gradientBrush.GradientStops); } outputStream.WriteLine(">>"); outputStream.WriteLine(">>"); outputStream.WriteLine("matrix"); outputStream.WriteLine("makepattern"); outputStream.WriteLine("setcolor"); }
/// <summary> /// Write a linear shading definition /// </summary> private void WriteLinearShading(GraphicGradientBrush gradientBrush, Rect boundingBox) { string startPointStr = FormatPoint(GetAbsolutePosition(boundingBox, gradientBrush.StartPoint)); string endPointStr = FormatPoint(GetAbsolutePosition(boundingBox, gradientBrush.EndPoint)); string coordsStr = $"/Coords [{startPointStr} {endPointStr}]"; WriteShadingPattern("2", gradientBrush, boundingBox, coordsStr); }
/// <summary> /// Get common gradient properties for linear and radial gradient /// </summary> private void GetCommonGradientProperties(XElement gradientElem, double opacity, GraphicGradientBrush gradientBrush) { var gradientUnitsAttribute = gradientElem.Attribute("gradientUnits"); if (gradientUnitsAttribute != null) { switch (gradientUnitsAttribute.Value) { case "userSpaceOnUse": gradientBrush.MappingMode = GraphicBrushMappingMode.Absolute; break; case "objectBoundingBox": gradientBrush.MappingMode = GraphicBrushMappingMode.RelativeToBoundingBox; break; } } foreach (var stopElem in gradientElem.Elements(svgNamespace + "stop")) { cssStyleCascade.PushStyles(stopElem); var stop = new GraphicGradientStop(); gradientBrush.GradientStops.Add(stop); double retVal; (_, retVal) = doubleParser.GetNumberPercent(stopElem, "offset", 0); stop.Position = retVal; var stopOpacity = cssStyleCascade.GetNumberPercentFromTop("stop-opacity", 1); var colorAttr = cssStyleCascade.GetPropertyFromTop("stop-color"); if (colorAttr != null && ColorParser.TryParseColor(colorAttr, opacity * stopOpacity, out Color color)) { stop.Color = color; } else { stop.Color = Colors.Black; } cssStyleCascade.Pop(); } }
/// <summary> /// Get common gradient properties for linear and radial gradient /// </summary> private void GetCommonGradientProperties(XElement gradientElem, double opacity, GraphicGradientBrush gradientBrush) { var gradientUnitsAttribute = gradientElem.Attribute("gradientUnits"); if (gradientUnitsAttribute != null) { switch (gradientUnitsAttribute.Value) { case "userSpaceOnUse": gradientBrush.MappingMode = GraphicBrushMappingMode.Absolute; break; case "objectBoundingBox": gradientBrush.MappingMode = GraphicBrushMappingMode.RelativeToBoundingBox; break; } } foreach (var stopElem in gradientElem.Elements(svgNamespace + "stop")) { var stop = new GraphicGradientStop(); gradientBrush.GradientStops.Add(stop); stop.Position = GetDoubleAttribute(stopElem, "offset", 0); var stopOpacity = GetDoubleAttribute(stopElem, "stop-opacity", 1); XAttribute colorAttr = stopElem.Attribute("stop-color"); Color color; if (colorAttr != null) { color = (Color)ColorConverter.ConvertFromString(colorAttr.Value); } else { color = Colors.Black; } stop.Color = Color.FromArgb((byte)(opacity * stopOpacity * 255), color.R, color.G, color.B); } }