/// <summary> /// Normalize a brush /// </summary> private GraphicBrush NormalizeBrush(GraphicBrush graphicBrush) { GraphicBrush retBrush; switch (graphicBrush) { case GraphicLinearGradientBrush linearGradientBrush: { if (linearGradientBrush.MappingMode == GraphicBrushMappingMode.Absolute) { var newlinearGradientBrush = new GraphicLinearGradientBrush(); retBrush = newlinearGradientBrush; newlinearGradientBrush.StartPoint = NormalizePoint(linearGradientBrush.StartPoint); newlinearGradientBrush.EndPoint = NormalizePoint(linearGradientBrush.EndPoint); newlinearGradientBrush.MappingMode = linearGradientBrush.MappingMode; newlinearGradientBrush.GradientStops = linearGradientBrush.GradientStops; } else { retBrush = linearGradientBrush; } break; } case GraphicRadialGradientBrush radialGradientBrush: { if (radialGradientBrush.MappingMode == GraphicBrushMappingMode.Absolute) { var newlinearGradientBrush = new GraphicRadialGradientBrush(); retBrush = newlinearGradientBrush; newlinearGradientBrush.StartPoint = NormalizePoint(radialGradientBrush.StartPoint); newlinearGradientBrush.EndPoint = NormalizePoint(radialGradientBrush.EndPoint); newlinearGradientBrush.RadiusX = NormalizeWidth(radialGradientBrush.RadiusX); newlinearGradientBrush.RadiusY = NormalizeWidth(radialGradientBrush.RadiusY); newlinearGradientBrush.MappingMode = radialGradientBrush.MappingMode; newlinearGradientBrush.GradientStops = radialGradientBrush.GradientStops; } else { retBrush = radialGradientBrush; } break; } default: retBrush = graphicBrush; break; } return(retBrush); }
/// <summary> /// Normalize a brush /// </summary> private GraphicBrush TransformBrush(GraphicBrush graphicBrush) { GraphicBrush retBrush; switch (graphicBrush) { case GraphicLinearGradientBrush linearGradientBrush: { if (linearGradientBrush.MappingMode == GraphicBrushMappingMode.Absolute) { var newlinearGradientBrush = new GraphicLinearGradientBrush(); retBrush = newlinearGradientBrush; newlinearGradientBrush.StartPoint = MatrixUtilities.TransformPoint(linearGradientBrush.StartPoint, transformMatrix); newlinearGradientBrush.EndPoint = MatrixUtilities.TransformPoint(linearGradientBrush.EndPoint, transformMatrix); newlinearGradientBrush.MappingMode = linearGradientBrush.MappingMode; newlinearGradientBrush.GradientStops = linearGradientBrush.GradientStops; } else { retBrush = linearGradientBrush; } break; } case GraphicRadialGradientBrush radialGradientBrush: { if (radialGradientBrush.MappingMode == GraphicBrushMappingMode.Absolute) { var newlinearGradientBrush = new GraphicRadialGradientBrush(); retBrush = newlinearGradientBrush; newlinearGradientBrush.StartPoint = MatrixUtilities.TransformPoint(radialGradientBrush.StartPoint, transformMatrix); newlinearGradientBrush.EndPoint = MatrixUtilities.TransformPoint(radialGradientBrush.EndPoint, transformMatrix); (newlinearGradientBrush.RadiusX, newlinearGradientBrush.RadiusY) = MatrixUtilities.TransformSize(radialGradientBrush.RadiusX, radialGradientBrush.RadiusY, transformMatrix); newlinearGradientBrush.MappingMode = radialGradientBrush.MappingMode; newlinearGradientBrush.GradientStops = radialGradientBrush.GradientStops; } else { retBrush = radialGradientBrush; } break; } default: retBrush = graphicBrush; break; } return(retBrush); }
/// <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 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> /// Create a gradient brush of the specified id /// </summary> private GraphicBrush CreateGradientBrush(string gradientId, double opacity, Matrix currentTransformationMatrix, Rect bounds) { GraphicBrush brush = null; if (!globalDefinitions.ContainsKey(gradientId)) { return(brush); } var gradientElem = globalDefinitions[gradientId]; switch (gradientElem.Name.LocalName) { case "linearGradient": { var gradient = new GraphicLinearGradientBrush(); brush = gradient; ReadGradientProperties(gradientElem, opacity, gradient); Matrix matrix = GetGradientTransformMatrix(gradientElem) * currentTransformationMatrix; var x = doubleParser.GetLength(gradientElem, "x1", 0); var y = doubleParser.GetLength(gradientElem, "y1", 0); gradient.StartPoint = new Point(x, y); x = doubleParser.GetLength(gradientElem, "x2", 1); y = doubleParser.GetLength(gradientElem, "y2", 0); gradient.EndPoint = new Point(x, y); // see comment in LinearGradientShading.cs of the pdf parser in GetBrush for more details if (gradient.MappingMode == GraphicBrushMappingMode.Absolute) { gradient.MappingMode = GraphicBrushMappingMode.RelativeToBoundingBox; gradient.StartPoint = GetRelativePosition(bounds, gradient.StartPoint * matrix); gradient.EndPoint = GetRelativePosition(bounds, gradient.EndPoint * matrix); } break; } case "radialGradient": { var gradient = new GraphicRadialGradientBrush(); brush = gradient; ReadGradientProperties(gradientElem, opacity, gradient); Matrix matrix = GetGradientTransformMatrix(gradientElem); var x = doubleParser.GetLength(gradientElem, "cx", 0.5); var y = doubleParser.GetLength(gradientElem, "cy", 0.5); gradient.EndPoint = new Point(x, y); x = doubleParser.GetLength(gradientElem, "fx", x); y = doubleParser.GetLength(gradientElem, "fy", y); gradient.StartPoint = new Point(x, y); var r = doubleParser.GetLength(gradientElem, "r", 0.5); gradient.RadiusX = r; gradient.RadiusY = r; // see comment in LinearGradientShading.cs of the pdf parser in GetBrush for more details if (gradient.MappingMode == GraphicBrushMappingMode.Absolute) { gradient.MappingMode = GraphicBrushMappingMode.RelativeToBoundingBox; // calculate the start position relative to the object rectangle gradient.StartPoint = GetRelativePosition(bounds, gradient.StartPoint * matrix); // calculate the end position relative to the object rectangle gradient.EndPoint = GetRelativePosition(bounds, gradient.EndPoint * matrix); // 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(bounds.Right - bounds.Left); var objectHeight = Math.Abs(bounds.Bottom - bounds.Top); // calculate the relative radius X var relativeRadiusX = gradientRadiusXUserSpace / objectWidth; gradient.RadiusX = gradient.RadiusX * relativeRadiusX; // calculate the relative radius Y var relativeRadiusY = gradientRadiusYUserSpace / objectHeight; gradient.RadiusY = gradient.RadiusY * relativeRadiusY; } break; } } return(brush); }
/// <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); }