/// <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> /// Write a radial shading definition /// </summary> private void WriteRadialShading(GraphicRadialGradientBrush gradientBrush, Rect boundingBox) { string center0Str = FormatPoint(GetAbsolutePosition(boundingBox, gradientBrush.StartPoint)); string center1Str = FormatPoint(GetAbsolutePosition(boundingBox, gradientBrush.EndPoint)); string radius0Str = DoubleUtilities.FormatString(GetAbsoluteLength(boundingBox, 0)); string radius1Str = DoubleUtilities.FormatString(GetAbsoluteLength(boundingBox, gradientBrush.RadiusX)); string coordsStr = $"/Coords [{center0Str} {radius0Str} {center1Str} {radius1Str}]"; WriteShadingPattern("3", gradientBrush, boundingBox, coordsStr); }
/// <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> /// 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 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); }