/// <summary> /// Get our intermediate radial gradient color definition from the given psd color definition /// </summary> private (GraphicRadialGradientBrush, GraphicColorPrecision) GetRadialGradientBrush(RadialGradientColor radialGradientColor, double aspectRatio, bool returnDarkDefaultColor) { var gradient = new GraphicRadialGradientBrush(); gradient.StartPoint = new Point(0.5, 0.5); gradient.EndPoint = new Point(0.5, 0.5); var alpha = Math.Abs(radialGradientColor.Angle) % 90; double angleRad = alpha * Math.PI / 180.0; var beta = Math.Atan(aspectRatio); if (angleRad < beta) { var radius = 0.5 / Math.Cos(angleRad); gradient.RadiusX = radius; gradient.RadiusY = radius / aspectRatio; } else { var radius = 0.5 / Math.Cos(Math.PI / 2 - angleRad); gradient.RadiusY = radius; gradient.RadiusX = radius * aspectRatio; } gradient.GradientStops = new List <GraphicGradientStop>(); GraphicColorPrecision precision; var scale = radialGradientColor.Scale / 100; foreach (var stop in radialGradientColor.GradientStops) { var gs = new GraphicGradientStop(); gradient.GradientStops.Add(gs); (gs.Color, precision) = GetColor(stop.Color, returnDarkDefaultColor); gs.Position = stop.Position / radialGradientColor.MaxPosition; if (radialGradientColor.IsReverse) { gs.Position = 1 - gs.Position; } if (radialGradientColor.Scale != 100) { gs.Position *= scale; } } return(gradient, GraphicColorPrecision.Estimated); }
/// <summary> /// Get a brush /// </summary> public GraphicBrush GetBrush(Matrix matrix, PdfRect boundingBox, double alpha, List <FunctionStop> softMask) { var stops = function.GetBoundaryValues(); var linearGradientBrush = new GraphicLinearGradientBrush(); // The whole logic of the shape converter is able to handle both relative and // absolute coordinates of gradients. WPF also allows both mapping modes. But // there is one single case where absolute coordinates don't work: in a <Path/> // object when the stretch mode is other than None. Such a path isn't really // helpfull. That's why all parsers generate relative coordinates. #if GENERATE_RELATIVE_COORDINATES var p0 = coords0 * matrix; linearGradientBrush.StartPoint = GetRelativePosition(boundingBox, p0); var p1 = coords1 * matrix; linearGradientBrush.EndPoint = GetRelativePosition(boundingBox, p1); #else linearGradientBrush.MappingMode = BrushMappingMode.Absolute; var p0 = coords0 * matrix; linearGradientBrush.StartPoint = p0; var p1 = coords1 * matrix; linearGradientBrush.EndPoint = p1; #endif linearGradientBrush.GradientStops = new List <GraphicGradientStop>(); for (int i = 0; i < stops.Count; i++) { var stop = stops[i]; var graphicGradientStop = new GraphicGradientStop(); linearGradientBrush.GradientStops.Add(graphicGradientStop); var stopAlpha = alpha; if (softMask != null) { stopAlpha = stopAlpha * softMask[i].Value[0]; } var color = colorSpace.GetColor(stop.Value, stopAlpha); graphicGradientStop.Color = color; graphicGradientStop.Position = stop.Stop; } return(linearGradientBrush); }
/// <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); } }
/// <summary> /// Get a brush /// </summary> public GraphicBrush GetBrush(Matrix matrix, PdfRect rect, double alpha, List <FunctionStop> softMask) { var linear = new GraphicLinearGradientBrush(); linear.StartPoint = new System.Windows.Point(0, 0); linear.EndPoint = new System.Windows.Point(1, 1); linear.GradientStops = new List <GraphicGradientStop>(); var stop = new GraphicGradientStop(); linear.GradientStops.Add(stop); stop.Color = Colors.Yellow; stop.Position = 0; stop = new GraphicGradientStop(); linear.GradientStops.Add(stop); stop.Color = Colors.Salmon; stop.Position = 1; return(linear); }
/// <summary> /// Get a brush /// </summary> public GraphicBrush GetBrush(Matrix matrix, EpsRect rect) { var linear = new GraphicLinearGradientBrush(); linear.StartPoint = new System.Windows.Point(0, 1); linear.EndPoint = new System.Windows.Point(1, 0); linear.GradientStops = new List <GraphicGradientStop>(); var stop = new GraphicGradientStop(); linear.GradientStops.Add(stop); stop.Color = Colors.Yellow; stop.Position = 0; stop = new GraphicGradientStop(); linear.GradientStops.Add(stop); stop.Color = Colors.Cyan; stop.Position = 1; return(linear); }
/// <summary> /// Get our intermediate linear gradient color definition from the given psd color definition /// </summary> private (GraphicLinearGradientBrush, GraphicColorPrecision) GetLinearGradientBrush(LinearGradientColor linearGradientColor, double aspectRatio, bool returnDarkDefaultColor) { var gradient = new GraphicLinearGradientBrush(); double angle = linearGradientColor.Angle; if (linearGradientColor.IsReverse) { angle += 180; if (angle > 180) { angle -= 360; } } var scale = linearGradientColor.Scale / 100; double angleFullAbs = Math.Abs(angle); double x2; double x1; double y2; double y1; if (angle == 90) { x1 = 0.5; x2 = 0.5; y1 = 0.5 + scale * 0.5; y2 = 0.5 - scale * 0.5; } else if (angle == -90) { x1 = 0.5; x2 = 0.5; y1 = 0.5 - scale * 0.5; y2 = 0.5 + scale * 0.5; } else { var angleAbs = angleFullAbs; if (angleFullAbs > 90) { angleAbs = 180 - angleFullAbs; } double angleRad = angleAbs * Math.PI / 180.0; var beta = Math.Atan(aspectRatio); if (angleRad < beta) { var a = 0.5 * Math.Tan(angleRad) * scale; if (angleFullAbs <= 90) { x1 = 0.5 - scale * 0.5; x2 = 0.5 + scale * 0.5; } else { x1 = 0.5 + scale * 0.5; x2 = 0.5 - scale * 0.5; } if (angle >= 0) { y1 = 0.5 + a / aspectRatio; y2 = 0.5 - a / aspectRatio; } else { y1 = 0.5 - a / aspectRatio; y2 = 0.5 + a / aspectRatio; } } else { var a = 0.5 * Math.Tan(Math.PI / 2 - angleRad) * scale; if (angleFullAbs <= 90) { x1 = 0.5 - a * aspectRatio; x2 = 0.5 + a * aspectRatio; } else { x1 = 0.5 + a * aspectRatio; x2 = 0.5 - a * aspectRatio; } if (angle >= 0) { y1 = 0.5 + scale * 0.5; y2 = 0.5 - scale * 0.5; } else { y1 = 0.5 - scale * 0.5; y2 = 0.5 + scale * 0.5; } } } gradient.StartPoint = new Point(x1, y1); gradient.EndPoint = new Point(x2, y2); gradient.GradientStops = new List <GraphicGradientStop>(); GraphicColorPrecision precision; foreach (var stop in linearGradientColor.GradientStops) { var gs = new GraphicGradientStop(); gradient.GradientStops.Add(gs); (gs.Color, precision) = GetColor(stop.Color, returnDarkDefaultColor); gs.Position = stop.Position / linearGradientColor.MaxPosition; } return(gradient, GraphicColorPrecision.Estimated); }
/// <summary> /// Get the color /// </summary> public GraphicBrush GetBrush(Matrix matrix, PdfRect boundingBox, double alpha, List <FunctionStop> softMask) { var stops = function.GetBoundaryValues(); var linearGradientBrush = new GraphicRadialGradientBrush(); // see comment in LinearGradientShading.cs in GetBrush for more details #if GENERATE_RELATIVE_COORDINATES // calculate the start position relative to the object rectangle var center0UserSpace = center0 * matrix; linearGradientBrush.StartPoint = GetRelativePosition(boundingBox, center0UserSpace); // calculate the end position relative to the object rectangle var center1UserSpace = center1 * matrix; linearGradientBrush.EndPoint = GetRelativePosition(boundingBox, center1UserSpace); // get the center point and a point on the outer ring // in user space coordinates var centerPointUserSpace = new Point(0, 0) * matrix; var outerPointUserSpace = new Point(1, 1) * matrix; // get the radii in user space var gradientRadiusXUserSpace = Math.Abs(outerPointUserSpace.X - centerPointUserSpace.X); var gradientRadiusYUserSpace = Math.Abs(outerPointUserSpace.Y - centerPointUserSpace.Y); // get the object's size in the user space, we need the radii relative to this size var objectWidth = Math.Abs(boundingBox.Right - boundingBox.Left); var objectHeight = Math.Abs(boundingBox.Bottom - boundingBox.Top); // calculate the relative radius X var relativeRadiusX = gradientRadiusXUserSpace / objectWidth; linearGradientBrush.RadiusX = radius1 * relativeRadiusX; // calculate the relative radius Y var relativeRadiusY = gradientRadiusYUserSpace / objectHeight; linearGradientBrush.RadiusY = radius1 * relativeRadiusY; #else linearGradientBrush.MappingMode = BrushMappingMode.Absolute; // calculate the start position relative to the object rectangle var center0UserSpace = center0 * matrix; linearGradientBrush.StartPoint = center0UserSpace; // calculate the end position relative to the object rectangle var center1UserSpace = center1 * matrix; linearGradientBrush.EndPoint = center1UserSpace; // calculate the radius X linearGradientBrush.RadiusX = TransformX(radius1, matrix); // calculate the radius Y linearGradientBrush.RadiusY = TransformY(radius1, matrix); #endif linearGradientBrush.GradientStops = new List <GraphicGradientStop>(); if (stops.Count > 0 && !DoubleUtilities.IsZero(stops[0].Stop) && !DoubleUtilities.IsZero(radius0)) { var graphicGradientStop = new GraphicGradientStop(); linearGradientBrush.GradientStops.Add(graphicGradientStop); graphicGradientStop.Color = Colors.Transparent; graphicGradientStop.Position = 0; graphicGradientStop = new GraphicGradientStop(); linearGradientBrush.GradientStops.Add(graphicGradientStop); graphicGradientStop.Color = Colors.Transparent; graphicGradientStop.Position = stops[0].Stop; } for (int i = 0; i < stops.Count; i++) { var stop = stops[i]; var graphicGradientStop = new GraphicGradientStop(); linearGradientBrush.GradientStops.Add(graphicGradientStop); var stopAlpha = alpha; if (softMask != null) { stopAlpha = stopAlpha * softMask[i].Value[0]; } var color = colorSpace.GetColor(stop.Value, stopAlpha); graphicGradientStop.Color = color; graphicGradientStop.Position = stop.Stop; } return(linearGradientBrush); }