//#if Net4 using System; using System.Collections.Generic; using System.Text; using System.Drawing; using System.Linq; using System.IO; using System.Drawing.Imaging; using CPF.Drawing; namespace CPF.GDIPlus { public class GDIPlusDrawingContext : DrawingContext { Graphics g; public Graphics Graphics { get { return g; } } IntPtr hdc = IntPtr.Zero; StringFormat GenericTypographic = (StringFormat)StringFormat.GenericTypographic.Clone(); StringFormat CenterFormat = new StringFormat() { Alignment = StringAlignment.Center, FormatFlags = StringFormatFlags.NoClip | StringFormatFlags.FitBlackBox | StringFormatFlags.LineLimit }; StringFormat RightFormat = new StringFormat { Alignment = StringAlignment.Far, FormatFlags = StringFormatFlags.NoClip | StringFormatFlags.FitBlackBox | StringFormatFlags.LineLimit }; Pen pen; public GDIPlusDrawingContext(Graphics g) { this.g = g; //g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; GenericTypographic.Trimming = StringTrimming.Character; CenterFormat.Trimming = StringTrimming.Character; RightFormat.Trimming = StringTrimming.Character; g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.Half; } public GDIPlusDrawingContext(IntPtr hdc, Rect rect) { this.hdc = hdc; g = Graphics.FromHdc(hdc); g.SetClip(new RectangleF((float)rect.X, (float)rect.Y, (float)rect.Width, (float)rect.Height)); //g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; GenericTypographic.Trimming = StringTrimming.Character; CenterFormat.Trimming = StringTrimming.Character; RightFormat.Trimming = StringTrimming.Character; g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.Half; } public GDIPlusDrawingContext(IntPtr hwnd) { this.g = Graphics.FromHwnd(hwnd); GenericTypographic.Trimming = StringTrimming.Character; CenterFormat.Trimming = StringTrimming.Character; RightFormat.Trimming = StringTrimming.Character; g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.Half; } public override AntialiasMode AntialiasMode { get { if (g.SmoothingMode == System.Drawing.Drawing2D.SmoothingMode.Default || g.SmoothingMode == System.Drawing.Drawing2D.SmoothingMode.None) { return AntialiasMode.Default; } return AntialiasMode.AntiAlias; } set { if (value == AntialiasMode.Default) { g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.Default; if (drawingFactory.ClearType) { g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit; } else { g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SystemDefault; } } else { if (drawingFactory.ClearType) { g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit; } else { g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit; } g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; } } } private void SetPen(Stroke stroke, System.Drawing.Brush strokeBrush) { if (pen == null) { pen = new Pen(strokeBrush); } pen.Width = stroke.Width; pen.DashStyle = stroke.DashStyle.ToGdiDashStyle(); if (stroke.DashStyle != DashStyles.Solid) { pen.DashOffset = stroke.DashOffset; pen.DashPattern = stroke.GetDashPattern(); pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Custom; } pen.StartCap = stroke.StrokeCap.ToLineCap(); pen.EndCap = pen.StartCap; pen.Brush = strokeBrush; } private Pen CreatePen(Stroke stroke, System.Drawing.Brush strokeBrush) { var pen = new Pen(strokeBrush); pen.Width = stroke.Width; pen.DashStyle = stroke.DashStyle.ToGdiDashStyle(); if (stroke.DashStyle != DashStyles.Solid) { pen.DashOffset = stroke.DashOffset; pen.DashPattern = stroke.GetDashPattern(); pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Custom; } pen.StartCap = stroke.StrokeCap.ToLineCap(); pen.EndCap = pen.StartCap; pen.Brush = strokeBrush; return pen; } public override void DrawLine(in Stroke stroke, CPF.Drawing.Brush strokeBrush, in CPF.Drawing.Point point1, in CPF.Drawing.Point point2) { InitializeBrush(strokeBrush); SetPen(stroke, (System.Drawing.Brush)strokeBrush.AdapterBrush); g.DrawLine(pen, point1.ToGdiPoint(), point2.ToGdiPoint()); } public override void DrawRectangle(CPF.Drawing.Brush strokeBrush, in CPF.Drawing.Stroke stroke, in CPF.Drawing.Rect rect) { InitializeBrush(strokeBrush); SetPen(stroke, (System.Drawing.Brush)strokeBrush.AdapterBrush); g.DrawRectangle(pen, (float)rect.X, (float)rect.Y, (float)rect.Width, (float)rect.Height); } public override void FillRectangle(CPF.Drawing.Brush fillBrush, Rect rect) { InitializeBrush(fillBrush); g.FillRectangle((System.Drawing.Brush)fillBrush.AdapterBrush, rect.X, (float)rect.Y, (float)rect.Width, (float)rect.Height); } //public override void DrawRoundedRectangle(Brush strokeBrush, Stroke stroke, Brush fillBrush, Rect rectangle, double radiusX, double radiusY) //{ // throw new NotImplementedException(); //} public override void DrawEllipse(CPF.Drawing.Brush strokeBrush, in Stroke stroke, in CPF.Drawing.Point center, in float radiusX, in float radiusY) { InitializeBrush(strokeBrush); SetPen(stroke, (System.Drawing.Brush)strokeBrush.AdapterBrush); var x = Math.Abs(radiusX); var y = Math.Abs(radiusY); g.DrawEllipse(pen, center.X - x, center.Y - y, x * 2, y * 2); } public override void FillEllipse(CPF.Drawing.Brush fillBrush, in CPF.Drawing.Point center, in float radiusX, in float radiusY) { InitializeBrush(fillBrush); var x = Math.Abs(radiusX); var y = Math.Abs(radiusY); g.FillEllipse((System.Drawing.Brush)fillBrush.AdapterBrush, center.X - x, center.Y - y, x * 2, y * 2); } public override void FillGeometry(CPF.Drawing.Brush fillBrush, Geometry geometry) { InitializeBrush(fillBrush); g.FillRegion((System.Drawing.Brush)fillBrush.AdapterBrush, (geometry.GeometryImpl as GDIPlusPathGeometry).Region); } public override void DrawImage(CPF.Drawing.Image image, in Rect destRect, in Rect srcRect, in float opacity = 1) { GDIPlusImage i = image.ImageImpl as GDIPlusImage; if (i != null) { if (opacity != 1) { ImageAttributes imageAttributes = new ImageAttributes(); ChangeOpacity(opacity, imageAttributes); g.DrawImage(i.Image, new Rectangle((int)destRect.X, (int)destRect.Y, (int)destRect.Width, (int)destRect.Height), srcRect.X, srcRect.Y, srcRect.Width, srcRect.Height, GraphicsUnit.Pixel, imageAttributes); } else { g.DrawImage(i.Image, new RectangleF(destRect.X, destRect.Y, destRect.Width, destRect.Height), new RectangleF(srcRect.X, srcRect.Y, srcRect.Width, srcRect.Height), GraphicsUnit.Pixel); } } } public static void ChangeOpacity(float opacity, ImageAttributes imageAttributes) { float[][] nArray ={ new float[] {1, 0, 0, 0, 0}, new float[] {0, 1, 0, 0, 0}, new float[] {0, 0, 1, 0, 0}, new float[] {0, 0, 0, opacity, 0}, new float[] {0, 0, 0, 0, 1} }; ColorMatrix matrix = new ColorMatrix(nArray); imageAttributes.SetColorMatrix(matrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap); } public override void DrawString(in CPF.Drawing.Point location, CPF.Drawing.Brush fillBrush, string text, in CPF.Drawing.Font font, in TextAlignment textAlignment = TextAlignment.Left, in float maxWidth = float.MaxValue, in TextDecoration decoration = default, in float maxHeight = float.MaxValue, in TextTrimming textTrimming = TextTrimming.None, in Stroke stroke = default, CPF.Drawing.Brush strokeBrush = null) { bool ellipsis = false; DrawString(out ellipsis, location, fillBrush, text, font, textAlignment, maxWidth, decoration, maxHeight, textTrimming, stroke, strokeBrush); } public override void DrawString(out bool ellipsis, in CPF.Drawing.Point location, CPF.Drawing.Brush fillBrush, string text, in CPF.Drawing.Font font, in TextAlignment textAlignment = TextAlignment.Left, in float maxWidth = float.MaxValue, in TextDecoration decoration = default, in float maxHeight = float.MaxValue, in TextTrimming textTrimming = TextTrimming.None, in Stroke stroke = default, CPF.Drawing.Brush strokeBrush = null) { InitializeBrush(fillBrush); ellipsis = false; Pen strokePen = null; if (strokeBrush != null && stroke.Width > 0) { InitializeBrush(strokeBrush); strokePen = CreatePen(stroke, strokeBrush.AdapterBrush as System.Drawing.Brush); } StringFormat stringFormat = GenericTypographic; var mw = maxWidth; switch (textAlignment) { case TextAlignment.Right: stringFormat = RightFormat; break; case TextAlignment.Center: stringFormat = CenterFormat; break; } var f = (FontStruct)font.AdapterFont; if (textAlignment != TextAlignment.Left && maxWidth == float.MaxValue) { mw = drawingFactory.g.MeasureString(text, f.Font).Width; } if (mw != float.MaxValue) { mw = (float)Math.Ceiling(mw); } var mH = maxHeight; if (mH != float.MaxValue) { mH = (float)Math.Ceiling(mH); } float y = location.Y; float x = location.X; var lines = text.Split('\n'); var drawLine = false; if (decoration.Brush != null && decoration.Stroke.Width > 0) { drawLine = true; InitializeBrush(decoration.Brush); SetPen(decoration.Stroke, (System.Drawing.Brush)decoration.Brush.AdapterBrush); } var fHeight = f.Height; var h = 0f; var br = false; //bool ellipsis = false; for (int i = 0; i < lines.Length; i++) { var line = lines[i].Trim('\r'); if (i == lines.Length - 1 && line == "") { break; } //Console.WriteLine(line + "," + cf + "," + ls); var index = 0; var count = 0; var len = line.Length; while (index < len) { h += fHeight; if (h > mH && y != location.Y) { br = true; break; } var s = drawingFactory.g.MeasureString(line, f.Font, new SizeF(mw, fHeight), stringFormat, out count, out var ls); string sub = line.Substring(0, count); if (!string.IsNullOrWhiteSpace(sub)) { var txt = sub; if (textTrimming == TextTrimming.CharacterEllipsis && (sub.Length < line.Length || i < lines.Length - 1)) { if (h + fHeight > mH) { if (s.Width < mw - fHeight) { txt = txt + "..."; } else { txt = txt.Substring(0, txt.Length - 1) + "..."; } ellipsis = true; } } if (textTrimming == TextTrimming.CharacterCenterEllipsis && (sub.Length < line.Length || i < lines.Length - 1)) { ellipsis = true; DrawCenterString(location, fillBrush, text, font, textAlignment, maxWidth, decoration, maxHeight, stroke, strokeBrush); return; } if (strokeBrush != null && stroke.Width > 0) { using (var path = new System.Drawing.Drawing2D.GraphicsPath()) { path.AddString(txt, f.Font.FontFamily, (int)f.Font.Style, f.Font.Size, new RectangleF(x - 0.5f, y - 0.5f, mw, fHeight), stringFormat); g.DrawPath(strokePen, path); g.FillPath((System.Drawing.Brush)fillBrush.AdapterBrush, path); } } else { g.DrawString(txt, f.Font, (System.Drawing.Brush)fillBrush.AdapterBrush, new RectangleF(x, y, mw, fHeight), stringFormat); } } if (drawLine) { var lw = drawingFactory.g.MeasureString(sub, f.Font).Width; if (decoration.Location.HasFlag(TextDecorationLocation.Underline)) { var ly = y; ly = y + fHeight; var lx = x; switch (textAlignment) { case TextAlignment.Right: lx = x + mw - lw; break; case TextAlignment.Center: lx = x + (mw - lw) / 2; break; } g.DrawLine(pen, lx, ly, lx + lw, ly); } if (decoration.Location.HasFlag(TextDecorationLocation.OverLine)) { var ly = y; var lx = x; switch (textAlignment) { case TextAlignment.Right: lx = x + mw - lw; break; case TextAlignment.Center: lx = x + (mw - lw) / 2; break; } g.DrawLine(pen, lx, ly, lx + lw, ly); } if (decoration.Location.HasFlag(TextDecorationLocation.Strikethrough)) { var ly = y; ly = y + fHeight / 2; var lx = x; switch (textAlignment) { case TextAlignment.Right: lx = x + mw - lw; break; case TextAlignment.Center: lx = x + (mw - lw) / 2; break; } g.DrawLine(pen, lx, ly, lx + lw, ly); } } y += fHeight; index += count; if (index >= len) { break; } line = line.Substring(count); } if (br) { break; } } strokePen?.Dispose(); } public void DrawCenterString(in CPF.Drawing.Point location, CPF.Drawing.Brush fillBrush, string text, in CPF.Drawing.Font font, in TextAlignment textAlignment = TextAlignment.Left, in float maxWidth = float.MaxValue, in TextDecoration decoration = default, in float maxHeight = float.MaxValue, in Stroke stroke = default, CPF.Drawing.Brush strokeBrush = null) { InitializeBrush(fillBrush); Pen strokePen = null; if (strokeBrush != null && stroke.Width > 0) { InitializeBrush(strokeBrush); strokePen = CreatePen(stroke, strokeBrush.AdapterBrush as System.Drawing.Brush); } StringFormat stringFormat = GenericTypographic; var mw = maxWidth; switch (textAlignment) { case TextAlignment.Right: stringFormat = RightFormat; break; case TextAlignment.Center: stringFormat = CenterFormat; break; } var f = (FontStruct)font.AdapterFont; if (textAlignment != TextAlignment.Left && maxWidth == float.MaxValue) { mw = drawingFactory.g.MeasureString(text, f.Font).Width; } if (mw != float.MaxValue) { mw = (float)Math.Ceiling(mw); } var mH = maxHeight; if (mH != float.MaxValue) { mH = (float)Math.Ceiling(mH); } float y = location.Y; float x = location.X; var drawLine = false; if (decoration.Brush != null && decoration.Stroke.Width > 0) { drawLine = true; InitializeBrush(decoration.Brush); SetPen(decoration.Stroke, (System.Drawing.Brush)decoration.Brush.AdapterBrush); } var fHeight = f.Height; var h = 0f; var br = false; //bool ellipsis = false; string newText = text; var lines = text.Split('\n'); if (lines.Length > 1) { newText = lines[0].Trim('\r') + "..." + lines[lines.Length - 1].Trim('\r'); } else { newText = text.Trim('\r'); } var index = 0; var count = 0; var len = newText.Length; while (index < len) { h += fHeight; if (h > mH && y != location.Y) { br = true; break; } var s = drawingFactory.g.MeasureString(newText, f.Font, new SizeF(mw, fHeight), stringFormat, out count, out var ls); string sub = newText.Substring(0, count); if (!string.IsNullOrWhiteSpace(sub) && sub == newText) { var txt = sub; if (strokeBrush != null && stroke.Width > 0) { using (var path = new System.Drawing.Drawing2D.GraphicsPath()) { path.AddString(txt, f.Font.FontFamily, (int)f.Font.Style, f.Font.Size, new RectangleF(x - 0.5f, y - 0.5f, mw, fHeight), stringFormat); g.DrawPath(strokePen, path); g.FillPath((System.Drawing.Brush)fillBrush.AdapterBrush, path); } } else { g.DrawString(txt, f.Font, (System.Drawing.Brush)fillBrush.AdapterBrush, new RectangleF(x, y, mw, fHeight), stringFormat); } } else if (!string.IsNullOrWhiteSpace(sub) && sub != newText) { var txt = sub; int countStart = 0; int countEnd = 0; var sStart = drawingFactory.g.MeasureString(newText, f.Font, new SizeF(mw / 2, fHeight), stringFormat, out countStart, out var lsStart); List wsEnds = new List(); for (int i = newText.Length - 1; i >= 0; i--) { wsEnds.Add(newText[i]); } StringBuilder wsEnd = new StringBuilder(); wsEnds.ForEach(p => { wsEnd.Append(p); }); var sEnd = drawingFactory.g.MeasureString(wsEnd.ToString(), f.Font, new SizeF(mw / 2, fHeight), stringFormat, out countEnd, out var lsEnd); string strStart = ""; if (countStart > 0) strStart = newText.Substring(0, countStart - 1); string strEnd = ""; if (countEnd > 0) strEnd = newText.Substring(newText.Length - countEnd + 1, countEnd - 1); newText = strStart + "..." + strEnd; txt = newText; if (strokeBrush != null && stroke.Width > 0) { using (var path = new System.Drawing.Drawing2D.GraphicsPath()) { path.AddString(txt, f.Font.FontFamily, (int)f.Font.Style, f.Font.Size, new RectangleF(x - 0.5f, y - 0.5f, mw, fHeight), stringFormat); g.DrawPath(strokePen, path); g.FillPath((System.Drawing.Brush)fillBrush.AdapterBrush, path); } } else { g.DrawString(txt, f.Font, (System.Drawing.Brush)fillBrush.AdapterBrush, new RectangleF(x, y, mw, fHeight), stringFormat); } } if (drawLine) { var lw = drawingFactory.g.MeasureString(sub, f.Font).Width; if (decoration.Location.HasFlag(TextDecorationLocation.Underline)) { var ly = y; ly = y + fHeight; var lx = x; switch (textAlignment) { case TextAlignment.Right: lx = x + mw - lw; break; case TextAlignment.Center: lx = x + (mw - lw) / 2; break; } g.DrawLine(pen, lx, ly, lx + lw, ly); } if (decoration.Location.HasFlag(TextDecorationLocation.OverLine)) { var ly = y; var lx = x; switch (textAlignment) { case TextAlignment.Right: lx = x + mw - lw; break; case TextAlignment.Center: lx = x + (mw - lw) / 2; break; } g.DrawLine(pen, lx, ly, lx + lw, ly); } if (decoration.Location.HasFlag(TextDecorationLocation.Strikethrough)) { var ly = y; ly = y + fHeight / 2; var lx = x; switch (textAlignment) { case TextAlignment.Right: lx = x + mw - lw; break; case TextAlignment.Center: lx = x + (mw - lw) / 2; break; } g.DrawLine(pen, lx, ly, lx + lw, ly); } } y += fHeight; index += count; if (index >= len) { break; } } strokePen?.Dispose(); } List oldRegions = new List(); public override void PushClip(Rect rect) { oldRegions.Add(g.Clip); g.SetClip(rect.ToRectangle(), System.Drawing.Drawing2D.CombineMode.Intersect); } public override void PopClip() { if (oldRegions.Count > 1) { g.SetClip(oldRegions[oldRegions.Count - 1], System.Drawing.Drawing2D.CombineMode.Replace); oldRegions.RemoveAt(oldRegions.Count - 1); } else { g.ResetClip(); } } public override Matrix Transform { get { return g.Transform.ToMatrix(); } set { //System.Drawing.Drawing2D.Matrix m = new System.Drawing.Drawing2D.Matrix((float)matrix.M11, (float)matrix.M12, (float)matrix.M21, (float)matrix.M22, (float)matrix.OffsetX, (float)matrix.OffsetY); g.Transform = value.ToMatrix(); } } GDIPlusDrawingFactory _drawingFactory; internal GDIPlusDrawingFactory drawingFactory { get { return _drawingFactory; } set { _drawingFactory = value; this.AntialiasMode = this.AntialiasMode; } } public override DrawingFactory DrawingFactory { get { return drawingFactory; } } protected override IDisposable CreateSolidBrush(CPF.Drawing.Color color) { return new SolidBrush(color.ToGdiColor()); } protected override IDisposable CreateLinearGradientBrush(GradientStop[] bcs, in CPF.Drawing.Point start, in CPF.Drawing.Point end, in Matrix matrix) { bcs[0].Position = 0; System.Drawing.Drawing2D.ColorBlend cb = new System.Drawing.Drawing2D.ColorBlend(); cb.Colors = bcs.Select(a => a.Color.ToGdiColor()).ToArray(); cb.Positions = bcs.Select(a => a.Position).ToArray(); System.Drawing.Drawing2D.LinearGradientBrush l = new System.Drawing.Drawing2D.LinearGradientBrush(start.ToGdiPoint(), end.ToGdiPoint(), bcs[0].Color.ToGdiColor(), bcs[1].Color.ToGdiColor()); l.InterpolationColors = cb; l.MultiplyTransform(matrix.ToMatrix()); //l.Transform = matrix.ToMatrix(); //l.RotateTransform(40); //var m = l.Transform; //m.Multiply(matrix.ToMatrix()); //l.Transform = m; return l; } public override void Dispose() { if (hdc != IntPtr.Zero) { g.Dispose(); hdc = IntPtr.Zero; } if (pen != null) { pen.Dispose(); pen = null; } if (GenericTypographic != null) { GenericTypographic.Dispose(); GenericTypographic = null; } foreach (var item in oldRegions) { item.Dispose(); } } public override void Clear(CPF.Drawing.Color color) { g.Clear(color.ToGdiColor()); } protected override IDisposable CreateTextureBrush(CPF.Drawing.Image image, in WrapMode wrapMode, in Matrix matrix) { GDIPlusImage i = image.ImageImpl as GDIPlusImage; //try //{ var wrap = wrapMode == WrapMode.Clamp ? System.Drawing.Drawing2D.WrapMode.Clamp : System.Drawing.Drawing2D.WrapMode.Tile; System.Drawing.TextureBrush hb; //if (i.Image.RawFormat.Guid == System.Drawing.Imaging.ImageFormat.Png.Guid) //{ //using (var bitmap = new System.Drawing.Bitmap(i.Width, i.Height)) //{//某些格式的图片会出现异常,只能重新创建过图片了 // using (Graphics g = Graphics.FromImage(bitmap)) // { // g.DrawImage(i.Image, new Rectangle(0, 0, i.Width, i.Height), new Rectangle(0, 0, i.Width, i.Height), GraphicsUnit.Pixel); // } // hb = new System.Drawing.TextureBrush(bitmap, wrap, new RectangleF(0, 0, i.Width, i.Height)); //} //} //else //{ // try // { hb = new System.Drawing.TextureBrush(i.Image, wrap, new RectangleF(0, 0, i.Width, i.Height)); // } // catch (Exception e) // { // throw new Exception("可能是GDI+图片兼容性问题,换个图片试试", e); // } //} //hb.ScaleTransform(96 / g.DpiX, 96 / g.DpiY); //hb.Transform = matrix.ToMatrix(); hb.MultiplyTransform(matrix.ToMatrix()); return hb; //} //catch (Exception e) //{ // //Console.WriteLine(i.Image + ":" + i.Image.Size + i.Image.PixelFormat + (i.Image.RawFormat == System.Drawing.Imaging.ImageFormat.Png)); // throw e; //} } public override void DrawPath(CPF.Drawing.Brush strokeBrush, in Stroke stroke, PathGeometry path) { InitializeBrush(strokeBrush); SetPen(stroke, (System.Drawing.Brush)strokeBrush.AdapterBrush); g.DrawPath(pen, (path.PathIml as GDIPlusPath).Path); } public override void FillPath(CPF.Drawing.Brush fillBrush, PathGeometry path) { InitializeBrush(fillBrush); g.FillPath((System.Drawing.Brush)fillBrush.AdapterBrush, (path.PathIml as GDIPlusPath).Path); } protected override IDisposable CreateRadialGradientBrush(in CPF.Drawing.Point center, in float radius, GradientStop[] blendColors, in Matrix matrix) { System.Drawing.Drawing2D.GraphicsPath path = new System.Drawing.Drawing2D.GraphicsPath(); path.AddEllipse(new RectangleF(center.X - radius, center.Y - radius, radius * 2, radius * 2)); System.Drawing.Drawing2D.PathGradientBrush p = new System.Drawing.Drawing2D.PathGradientBrush(path); p.CenterPoint = new PointF(center.X, center.Y); blendColors[0].Position = 0; System.Drawing.Drawing2D.ColorBlend cb = new System.Drawing.Drawing2D.ColorBlend(); cb.Colors = blendColors.Select(a => a.Color.ToGdiColor()).Reverse().ToArray(); cb.Positions = blendColors.Select(a => 1 - a.Position).Reverse().ToArray(); p.InterpolationColors = cb; //p.Transform = matrix.ToMatrix(); p.MultiplyTransform(matrix.ToMatrix()); return p; } //public override void DrawGeometry(CPF.Drawing.Brush strokeBrush, in Stroke stroke, Geometry geometry) //{ // //InitializeBrush(strokeBrush); // //g.FillRegion((System.Drawing.Brush)fillBrush.AdapterBrush, (geometry.GeometryImpl as GDIPlusPathGeometry).Region); // throw new Exception("未实现DrawGeometry"); //} //public override IDisposable CreateGeometry(Path path) //{ // return new Region((System.Drawing.Drawing2D.GraphicsPath)path.AdapterPath); //} } } //#endif