解决SVG透明度和渐变显示问题

This commit is contained in:
小红帽 2024-01-18 22:09:17 +08:00
parent e35f7f1e41
commit 7f9eb19a7d
8 changed files with 318 additions and 268 deletions

View File

@ -217,6 +217,10 @@ namespace CPF.Controls
{
Invoke(() =>
{
if (!s.Equals(Source))
{
return;
}
SetImage(a);
needDisposeImg = false;
if (a == null)

View File

@ -2512,6 +2512,11 @@ namespace CPF.Controls
{
views.TryRemove(this, out _);
base.Dispose(disposing);
if (viewImpl != null)
{
viewImpl.Dispose();
//viewImpl = null;
}
}
}
/// <summary>

View File

@ -529,11 +529,11 @@ namespace CPF.Controls
RaiseEvent(e, nameof(Closed));
}
protected override void Dispose(bool disposing)
{
windowImpl.Dispose();
base.Dispose(disposing);
}
//protected override void Dispose(bool disposing)
//{
// windowImpl.Dispose();
// base.Dispose(disposing);
//}
}
public class ClosingEventArgs : EventArgs

View File

@ -147,8 +147,8 @@ namespace CPF.Svg
public override ViewFill GetBrush(double opacity)
{
byte a = (byte)(255 * opacity / 100);
Color c = Color;
byte a = (byte)(c.A * opacity / 100);
Color newcol = Color.FromArgb(a, c.R, c.G, c.B);
if (sb == null || sb.IsDisposed)
{
@ -158,7 +158,7 @@ namespace CPF.Svg
return sb;
}
}
abstract class GradientColor : PaintServer
internal abstract class GradientColor : PaintServer
{
// http://www.w3.org/TR/SVG11/pservers.html#LinearGradients
List<GradientStop> m_stops = new List<GradientStop>();
@ -244,7 +244,11 @@ namespace CPF.Svg
{
LinearGradientFill b = new LinearGradientFill();
foreach (GradientStop stop in Stops)
b.GradientStops.Add(stop);
{
var c = stop.Color;
byte a = (byte)(c.A * opacity / 100);
b.GradientStops.Add(new GradientStop(Color.FromArgb(a, c.R, c.G, c.B), stop.Position));
}
//b.MappingMode = BrushMappingMode.RelativeToBoundingBox;
b.StartPoint = "0, 0";
@ -336,7 +340,11 @@ namespace CPF.Svg
{
RadialGradientFill b = new RadialGradientFill();
foreach (GradientStop stop in Stops)
b.GradientStops.Add(stop);
{
var c = stop.Color;
byte a = (byte)(c.A * opacity / 100);
b.GradientStops.Add(new GradientStop(Color.FromArgb(a, c.R, c.G, c.B), stop.Position));
}
//b.GradientOrigin = new System.Windows.Point(0.5, 0.5);
b.Center = "50%,50%";

View File

@ -168,7 +168,7 @@ namespace CPF.Svg
//public bool ClosePath { get; private set;}
// http://apike.ca/prog_svg_paths.html
public PathShape(XmlNode node) : base(node)
public PathShape(XmlNode node, SvgShape parent) : base(node, parent)
{
//ClosePath = false;
string path = XmlUtil.AttrValue(node, "d", string.Empty);

View File

@ -205,10 +205,13 @@ namespace CPF.Svg
var fill = Fill;
foreach (var item in m_elements)
{
if (item.GetFill().Color == null)
{
item.GetFill().FillBrush = fill;
}
}
}
/// <summary>
/// 图片缩放模式
@ -244,10 +247,13 @@ namespace CPF.Svg
{
var fill = newValue as ViewFill;
foreach (var item in m_elements)
{
if (item.GetFill().Color == null)
{
item.GetFill().FillBrush = fill;
}
}
}
Size naturalSize;
protected override Size MeasureOverride(in Size availableSize)
@ -504,6 +510,17 @@ namespace CPF.Svg
}
}
if (item.Fill != null && item.Fill.FillBrush != null)
{
if (item.Fill.Color is GradientColor svgFill)
{
using (var brush = item.Fill.FillBrush.CreateBrush(svgFill.GradientUnits == SVGTags.sGradientUserSpace ? new Rect(0, 0, naturalSize.Width, naturalSize.Height) : item.Geometry.GetBounds(), Root.RenderScaling))
{
dc.FillPath(brush, item.Geometry);
}
}
else
{
if (item.Fill.Color != null)
{
using (var brush = item.Fill.FillBrush.CreateBrush(item.Geometry.GetBounds(), Root.RenderScaling))
{
@ -511,6 +528,8 @@ namespace CPF.Svg
}
}
}
}
}
if (item.Transform != null)
{
dc.Transform = old;

View File

@ -63,8 +63,8 @@ namespace CPF.Svg
public float Opacity { get; set; } = 1;
public virtual Transform Transform { get; private set; }
public SvgShape Parent { get; set; }
public SvgShape(XmlNode node) : this(node, null) { }
public SvgShape Parent { get; private set; }
//public SvgShape(XmlNode node) : this(node, null) { }
public SvgShape(XmlNode node, SvgShape parent) : base(node)
{
Parent = parent;
@ -83,6 +83,18 @@ namespace CPF.Svg
m_stroke.Opacity *= Opacity;
}
}
if (parent != null && parent.Opacity != 1)
{
if (m_fill != null)
{
m_fill.Opacity *= parent.Opacity;
m_fill.FillBrush = null;
}
if (m_stroke != null)
{
m_stroke.Opacity *= parent.Opacity;
}
}
}
}
public SvgShape(List<ShapeUtil.Attribute> attrs, SvgShape parent) : base(null)
@ -308,7 +320,7 @@ namespace CPF.Svg
public float Height { get; set; }
public float RX { get; set; }
public float RY { get; set; }
public RectangleShape(XmlNode node) : base(node)
public RectangleShape(XmlNode node, SvgShape parent) : base(node, parent)
{
X = (float)XmlUtil.AttrValue(node, "x", 0);
Y = (float)XmlUtil.AttrValue(node, "y", 0);
@ -399,7 +411,7 @@ namespace CPF.Svg
public float CX { get; set; }
public float CY { get; set; }
public float R { get; set; }
public CircleShape(XmlNode node) : base(node)
public CircleShape(XmlNode node, SvgShape parent) : base(node, parent)
{
CX = (float)XmlUtil.AttrValue(node, "cx", 0);
CY = (float)XmlUtil.AttrValue(node, "cy", 0);
@ -456,7 +468,7 @@ namespace CPF.Svg
public float CY { get; set; }
public float RX { get; set; }
public float RY { get; set; }
public EllipseShape(XmlNode node) : base(node)
public EllipseShape(XmlNode node, SvgShape parent) : base(node, parent)
{
CX = (float)XmlUtil.AttrValue(node, "cx", 0);
CY = (float)XmlUtil.AttrValue(node, "cy", 0);
@ -510,7 +522,7 @@ namespace CPF.Svg
{
public Point P1 { get; private set; }
public Point P2 { get; private set; }
public LineShape(XmlNode node) : base(node)
public LineShape(XmlNode node, SvgShape parent) : base(node, parent)
{
double x1 = XmlUtil.AttrValue(node, "x1", 0);
double y1 = XmlUtil.AttrValue(node, "y1", 0);
@ -532,7 +544,7 @@ namespace CPF.Svg
class PolylineShape : SvgShape
{
public Point[] Points { get; private set; }
public PolylineShape(XmlNode node) : base(node)
public PolylineShape(XmlNode node, SvgShape parent) : base(node, parent)
{
string points = XmlUtil.AttrValue(node, SVGTags.sPoints, string.Empty);
ShapeUtil.StringSplitter split = new ShapeUtil.StringSplitter(points);
@ -562,7 +574,7 @@ namespace CPF.Svg
class PolygonShape : SvgShape
{
public Point[] Points { get; private set; }
public PolygonShape(XmlNode node) : base(node)
public PolygonShape(XmlNode node, SvgShape parent) : base(node, parent)
{
string points = XmlUtil.AttrValue(node, SVGTags.sPoints, string.Empty);
ShapeUtil.StringSplitter split = new ShapeUtil.StringSplitter(points);
@ -595,7 +607,7 @@ namespace CPF.Svg
public double X { get; set; }
public double Y { get; set; }
public string hRef { get; set; }
public UseShape(XmlNode node) : base(node)
public UseShape(XmlNode node, SvgShape parent) : base(node, parent)
{
X = XmlUtil.AttrValue(node, "x", 0);
Y = XmlUtil.AttrValue(node, "y", 0);
@ -646,21 +658,21 @@ namespace CPF.Svg
get { return m_elements; }
}
SvgShape AddChild(SvgShape shape)
//SvgShape AddChild(SvgShape shape)
//{
// m_elements.Add(shape);
// shape.Parent = this;
// return shape;
//}
public Group(XmlNode node, SvgShape parent) : base(node, parent)
{
m_elements.Add(shape);
shape.Parent = this;
return shape;
}
public Group(XmlNode node, SvgShape parent) : base(node)
{
// parent on group must be set before children are added
this.Parent = parent;
//// parent on group must be set before children are added
//this.Parent = parent;
foreach (XmlNode childnode in node.ChildNodes)
{
SvgShape shape = AddToList(m_elements, childnode, this);
if (shape != null)
shape.Parent = this;
//if (shape != null)
// shape.Parent = this;
}
//if (Id.Length > 0)
// svg.AddShape(Id, this);
@ -671,37 +683,37 @@ namespace CPF.Svg
return null;
if (childnode.Name == SVGTags.sShapeRect)
{
list.Add(new RectangleShape(childnode));
list.Add(new RectangleShape(childnode, parent));
return list[list.Count - 1];
}
if (childnode.Name == SVGTags.sShapeCircle)
{
list.Add(new CircleShape(childnode));
list.Add(new CircleShape(childnode, parent));
return list[list.Count - 1];
}
if (childnode.Name == SVGTags.sShapeEllipse)
{
list.Add(new EllipseShape(childnode));
list.Add(new EllipseShape(childnode, parent));
return list[list.Count - 1];
}
if (childnode.Name == SVGTags.sShapeLine)
{
list.Add(new LineShape(childnode));
list.Add(new LineShape(childnode, parent));
return list[list.Count - 1];
}
if (childnode.Name == SVGTags.sShapePolyline)
{
list.Add(new PolylineShape(childnode));
list.Add(new PolylineShape(childnode, parent));
return list[list.Count - 1];
}
if (childnode.Name == SVGTags.sShapePolygon)
{
list.Add(new PolygonShape(childnode));
list.Add(new PolygonShape(childnode, parent));
return list[list.Count - 1];
}
if (childnode.Name == SVGTags.sShapePath)
{
list.Add(new PathShape(childnode));
list.Add(new PathShape(childnode, parent));
return list[list.Count - 1];
}
if (childnode.Name == SVGTags.sShapeGroup)
@ -726,7 +738,7 @@ namespace CPF.Svg
}
if (childnode.Name == SVGTags.sShapeUse)
{
list.Add(new UseShape(childnode));
list.Add(new UseShape(childnode, parent));
return list[list.Count - 1];
}
//if (childnode.Name == SVGTags.sShapeImage)

View File

@ -25,11 +25,13 @@ namespace CPF.Svg
get
{
if (Color != null)
return Color.GetBrush(Opacity);
if (fillBrush != null)
return fillBrush;
return null;
if (Color != null)
{
return Color.GetBrush(Opacity);
}
return fillBrush;
}
set