上一篇中介绍了动态添加Silverlight绘图元素,由于这些绘图元素的使用并不简洁,接着就要构造基本图形库了。
工程应用中的图形库,基本有两种构建方式:一种是类似Win Form中的Graphics类,绘制图形简洁,但这种图形不是以“元素”的形式出现,绘制之后图形元素不能被索引,它自身没有属性或事件的概念,因此这种方式适用于“一次绘制好后,只供用户观看”的场合,例如背景图的绘制、示意曲线的绘制等;另一种是类似Silverlight中的图形绘制方式,各图形元素是一个真正的类,自身有属性或事件,可以被索引,相比第一种情况,这是一种“重量级”的绘图方式,适用于“随时捕捉图形,并对其施加操作”的场合,例如绘制工作流图等。本文称第一种库为图形绘制库,称第二种库为图形元素库。本文只关注图形绘制库的建立。
本文还有一个目的,尽量消除在WinForm和Silverlight中绘制图形的不同,同一套代码,几乎不用修改就能在WinForm和Silverlight中绘制出相同的图形。由于Silverlight应用中不能随便引用其他C#类库,所以Silverlight应用与其他应用中的通用功能,只能通过代码共用。
WinFormGraphics的源代码。
工程应用中的图形库,基本有两种构建方式:一种是类似Win Form中的Graphics类,绘制图形简洁,但这种图形不是以“元素”的形式出现,绘制之后图形元素不能被索引,它自身没有属性或事件的概念,因此这种方式适用于“一次绘制好后,只供用户观看”的场合,例如背景图的绘制、示意曲线的绘制等;另一种是类似Silverlight中的图形绘制方式,各图形元素是一个真正的类,自身有属性或事件,可以被索引,相比第一种情况,这是一种“重量级”的绘图方式,适用于“随时捕捉图形,并对其施加操作”的场合,例如绘制工作流图等。本文称第一种库为图形绘制库,称第二种库为图形元素库。本文只关注图形绘制库的建立。
本文还有一个目的,尽量消除在WinForm和Silverlight中绘制图形的不同,同一套代码,几乎不用修改就能在WinForm和Silverlight中绘制出相同的图形。由于Silverlight应用中不能随便引用其他C#类库,所以Silverlight应用与其他应用中的通用功能,只能通过代码共用。
Graphics类是一个“天然”的编制图形绘制库,本文将以它为基础,主要对Silverlight中的绘图元素进行改造。由于Silverlight独立部署的特性,使Silverlight与WinForm的绘图类之间无任何共有部分,但是为达到“同一代码,两处通用”的目的,两者的绘图类都不能使用,必须重新定义一套接口及相关辅助类。下图是本文图形绘制库中所涉及的类。
IGraphBase是一个接口类,它定义了类似Graphics类中的各类图形绘制方法,LinePen、PaintBrush等类是图形绘制过程中用到的辅助类,例如LinePen包装了Pen类等。WinFormGraphics和SilverlightGraphics实现了IGraphBase接口,分别用于在WinForm和Silverlight中绘制基本图形。
IGraphBase和辅助绘图类放在一个文件中(Helper.cs),以下是代码。
public class DrawColor { #region Member Variables private Byte _r,_g,_b,_a; #endregion Member Variables #region Properties public Byte R { set { this._r = value; } get { return this._r; } } public Byte G { set { this._g = value; } get { return this._g; } } public Byte B { set { this._b = value; } get { return this._b; } } public Byte A { set { this._a = value; } get { return this._a; } } #endregion Properties #region Public Methods public DrawColor(Byte a=255,Byte r =0,Byte g=0,Byte b=0) { _r = r; _g = g; _b = b; _a = a; } public DrawColor(Byte r = 0,Byte g = 0,Byte b = 0) { _a = 255; _g = g; _b = b; _r = r; } public UInt32 ToArgb() { return (((UInt32)_a) << 24) + (((UInt32)_r) << 16) + (((UInt32)_g) << 8) + ((UInt32)_b); } public static DrawColor FromArgb(int red,int green,int blue) { return new DrawColor((Byte)red,(Byte)green,(Byte)blue); } public static DrawColor FromArgb(UInt32 cl) { return new DrawColor((Byte)(cl>>24),(Byte)(cl>>16),(Byte)(cl>>8),(Byte)(cl&0xff)); } #endregion Public Methods } public class DrawColors { public static DrawColor Black = DrawColor.FromArgb(0xFF000000); public static DrawColor Blue = DrawColor.FromArgb(0xFF0000FF); public static DrawColor brown = DrawColor.FromArgb(0xFFA52A2A); public static DrawColor Cyan = DrawColor.FromArgb(0xFF00FFFF); public static DrawColor DarkGray = DrawColor.FromArgb(0xFFA9A9A9); public static DrawColor Gray = DrawColor.FromArgb(0xFF808080); public static DrawColor Green = DrawColor.FromArgb(0xFF008000); public static DrawColor LightGray = DrawColor.FromArgb(0xFFD3D3D3); public static DrawColor magenta = DrawColor.FromArgb(0xFFFF00FF); public static DrawColor Orange = DrawColor.FromArgb(0xFFFFA500); public static DrawColor Purple = DrawColor.FromArgb(0xFF800080); public static DrawColor Red = DrawColor.FromArgb(0xFFFF0000); public static DrawColor Transparent = DrawColor.FromArgb(0x00FFFFFF); public static DrawColor White = DrawColor.FromArgb(0xFFFFFFFF); public static DrawColor Yellow = DrawColor.FromArgb(0xFFFFFF00); } public class LinePen { public enum StyleEnum { SOLID,DOT,DASH,DASHDOT,DASHDOTDOT,CUSTOM } #region Member Variables private Single[] _customDashGapArray = null; #endregion Member Variables #region Properties public StyleEnum Style { get; set; } public DrawColor Color { get; set; } public Single Width { get; set; } public Single[] CustomDashGapArray { get { return _customDashGapArray; } set { if (value != null) { _customDashGapArray = new Single[value.Length]; value.copyTo(_customDashGapArray,0); } } } #endregion Properties public LinePen(DrawColor color,Single width = 1.0f,StyleEnum style = LinePen.StyleEnum.soLID,Single[] customDashGap = null) { Color = color; Width = width; Style = style; CustomDashGapArray = customDashGap; } public LinePen Clone() { return new LinePen(this.Color,this.Width,this.Style,this._customDashGapArray); } } public abstract class PaintBrush { #region Member Variables #endregion Member Variables #region Properties #endregion Properties public PaintBrush() { } } public class SolidPaintBrush: PaintBrush { #region Properties public DrawColor Color { get; set; } #endregion Properties public SolidPaintBrush(DrawColor color) { Color = color; } } public class TextFont { public enum StyleEnum { REGULAR,BOLD,ITALIC } public enum AlignmentEnum { LEFT,RIGHT,CENTER,JUSTIFY } #region Member Variables private string _family; #endregion Member Variables #region Properties public bool Clip { get; set; } public bool Wrap { get; set; } public float Size {get; set; } public StyleEnum Style { get; set; } public AlignmentEnum Alignment { get; set; } public string Family { set { this._family = value; } get { return this._family; } } #endregion Properties #region Public Methods public TextFont(string family="宋体",float size=10.0f,TextFont.StyleEnum style = StyleEnum.REGULAR,TextFont.AlignmentEnum alignment = AlignmentEnum.LEFT,bool wrap= false,bool clip =false) { _family = family; Size = size; Style = style; Alignment = alignment; Wrap = wrap; Clip = clip; } public TextFont(float size) { _family = "宋体"; Size = size; Style = StyleEnum.REGULAR; Alignment = AlignmentEnum.LEFT; Wrap = false; Clip = false; } #endregion Public Methods } public class Dot { public Int32 X=0,Y=0; public Dot(Int32 x,Int32 y) { this.X = x; this.Y = y; } } public class DotF { public Single X=0.0f,Y=0.0f; public DotF(Single x,Single y) { this.X = x; this.Y = y; } } public class Area { public Int32 X1,Y1,X2,Y2; public Area() { X1 = Y1 = X2 = Y2 = 0; } public Area(Int32 x1,Int32 y1,Int32 x2,Int32 y2) { this.X1 = x1; this.Y1 = y1; this.X2 = x2; this.Y2 = y2; } public Int32 Width { get { return X2 - X1; } set { X2 = X1 + value; } } public Int32 Height { get { return Y2 - Y1; } set { Y2 = Y1 + value; } } public void Reset() { int s; if (X2 < X1) { s = X2; X2 = X1; X1 = s; } if (Y2 < Y1) { s = Y2; Y2 = Y1; Y1 = s; } } public static Area Fromrange(Int32 x,Int32 y,Int32 width,Int32 height) { return new Area(x,y,x + width,y + height); } } public class AreaF { public Single X1,Y2; public AreaF() { X1 = Y1 = X2 = Y2 = 0.0f; } public AreaF(Single x1,Single y1,Single x2,Single y2) { this.X1 = x1; this.Y1 = y1; this.X2 = x2; this.Y2 = y2; } public Single Width { get { return X2 - X1; } set { X2 = X1 + value; } } public Single Height { get { return Y2 - Y1; } set { Y2 = Y1 + value; } } public void Reset() { Single s; if (X2 < X1) { s = X2; X2 = X1; X1 = s; } if (Y2 < Y1) { s = Y2; Y2 = Y1; Y1 = s; } } public static AreaF Fromrange(Single x,Single y,Single width,Single height) { return new AreaF(x,y + height); } } public enum ImageStretch { NONE,FILL,UNIFORM,UNIFORMTOFILL } public interface IGraphBase { void Clear(DrawColor cl); void SetClip(AreaF area ); void ClearClip(); void SetLinePen(LinePen pen); void DrawLine(LinePen pen,Int32 x1,Int32 y2); void DrawLine(LinePen pen,Single x1,Single y2); void Startpolyline(LinePen pen); void AddpolylinePoint(Single x,Single y); void AddpolylinePoint(Int32 x,Int32 y); void Endpolyline(); void DrawRectangle(LinePen pen,PaintBrush brush,Area area); void DrawRectangle(LinePen pen,AreaF area); void DrawRectangle(LinePen pen,Int32 y2); void DrawRectangle(LinePen pen,Single y2); void Drawpolygon(LinePen pen,ICollection<Dot> edges); void Drawpolygon(LinePen pen,ICollection<DotF> edges); void DrawCircle(LinePen pen,Int32 x,Int32 y,Int32 radius); void DrawCircle(LinePen pen,Single x,Single radius); void DrawEllipse(LinePen pen,Area area); void DrawEllipse(LinePen pen,AreaF area); void DrawEllipse(LinePen pen,Int32 y2); void DrawEllipse(LinePen pen,Single y2); void DrawString(Single x,string text,DrawColor fontcolor,float fontsize,string fontname); void DrawString(string text,TextFont font,AreaF area); void DrawImage(Area area,string sourceUrl,ImageStretch st); void DrawImage(AreaF area,ImageStretch st); } }SilverlightGraphics的源代码。
public class SilverlightGraphics : IGraphBase { #region Consts & Enum #endregion Consts & Enum #region Member Variables private Canvas _slCanvas; private UInt32 _elementCount = 0; private LinePen _defaultPen = new LinePen(DrawColors.Black); private LinePen _polylinePen = null; private PointCollection _polylinePoints = null; private DoubleCollection _dotLinestrokeArray = new DoubleCollection(); private DoubleCollection _dashLinestrokeArray = new DoubleCollection(); private DoubleCollection _dashdotLinestrokeArray = new DoubleCollection(); private DoubleCollection _dashdotdotLinestrokeArray = new DoubleCollection(); private Brush _defaultTextBrush = new SolidColorBrush(Colors.Black); private System.Windows.FrameworkElement _lastAddedShape = null; #endregion Member Variables #region Properties public Canvas GraphObject { get { return _slCanvas; } } public System.Windows.FrameworkElement LastAddedShape { get { return _lastAddedShape; } } #endregion Properties #region Pulbic Methods public SilverlightGraphics(Canvas cs) { _slCanvas = cs; _dotLinestrokeArray.Add(1.0); _dotLinestrokeArray.Add(1.0); _dashLinestrokeArray.Add(3.0); _dashLinestrokeArray.Add(1.0); _dashdotLinestrokeArray.Add(3.0); _dashdotLinestrokeArray.Add(1.0); _dashdotLinestrokeArray.Add(1.0); _dashdotLinestrokeArray.Add(1.0); _dashdotdotLinestrokeArray.Add(3.0); _dashdotdotLinestrokeArray.Add(1.0); _dashdotdotLinestrokeArray.Add(1.0); _dashdotdotLinestrokeArray.Add(1.0); _dashdotdotLinestrokeArray.Add(1.0); _dashdotdotLinestrokeArray.Add(1.0); } public void SetLinePen(LinePen pen) { _defaultPen = pen.Clone(); } public void Clear(DrawColor cl) { _slCanvas.Children.Clear(); _slCanvas.Background = new SolidColorBrush(converttoColor(cl)); } public void SetClip(AreaF area = null) { Rect rt = (area == null) ? new Rect(0,_slCanvas.Width,_slCanvas.Height) : new Rect(area.X1,area.Y1,area.Width,area.Height); _slCanvas.Clip = new RectangleGeometry() { Rect = rt }; } public void ClearClip() { _slCanvas.Clip = null; } public void DrawLine(LinePen pen,Int32 y2) { DrawLine(pen,(Single)x1,(Single)y1,(Single)x2,(Single)y2); } public void DrawLine(LinePen pen,Single y2) { Line shp = new System.Windows.Shapes.Line(); prepareLinePen(shp,(pen==null)?_defaultPen.Clone() :pen); shp.X1 = x1; shp.Y1 = y1; shp.X2 = x2; shp.Y2 = y2; addShape(shp,"Line"); } public void Startpolyline(LinePen pen) { if(_polylinePoints!=null) _polylinePoints.Clear(); // need new ?????? _polylinePen = (pen == null) ? _defaultPen.Clone() : pen; } public void AddpolylinePoint(Single x,Single y) { if (_polylinePoints == null) { _polylinePoints = new PointCollection(); } _polylinePoints.Add(new Point(x,y)); } public void AddpolylinePoint(Int32 x,Int32 y) { AddpolylinePoint((Single)x,(Single)y); } public void Endpolyline() { polyline shp = new System.Windows.Shapes.polyline(); prepareLinePen(shp,_polylinePen); shp.Points = _polylinePoints; addShape(shp,"Pyln"); } public void DrawRectangle(LinePen pen,Area area) { DrawRectangle(pen,brush,(Single)area.X1,(Single)area.Y1,(Single)area.Width,(Single)area.Height); } public void DrawRectangle(LinePen pen,AreaF area) { DrawRectangle(pen,area.X1,area.Height); } public void DrawRectangle(LinePen pen,Int32 height) { DrawRectangle(pen,(Single)x,(Single)y,(Single)width,(Single)height); } public void DrawRectangle(LinePen pen,Single height) { Rectangle shp = new System.Windows.Shapes.Rectangle(); prepareLinePen(shp,(pen == null) ? _defaultPen.Clone() : pen); prepareFillBrush(shp,brush); setRectValue(shp,x,width,height); addShape(shp,"Rect"); } public void Drawpolygon(LinePen pen,ICollection<Dot> edges) { polygon tmpgon = new System.Windows.Shapes.polygon(); prepareLinePen(tmpgon,(pen == null) ? _defaultPen.Clone() : pen); prepareFillBrush(tmpgon,brush); PointCollection points = new PointCollection(); foreach (Dot dt in edges) { points.Add(new Point(dt.X,dt.Y)); } tmpgon.Points = points; addShape(tmpgon,"Pygn"); } public void Drawpolygon(LinePen pen,ICollection<DotF> edges) { polygon tmpgon = new System.Windows.Shapes.polygon(); prepareLinePen(tmpgon,brush); PointCollection points = new PointCollection(); foreach (DotF dot in edges) { points.Add(new Point(dot.X,dot.Y)); } tmpgon.Points = points; addShape(tmpgon,"Pygn"); } public void DrawCircle(LinePen pen,Int32 radius) { DrawCircle(pen,(Single)radius); } public void DrawCircle(LinePen pen,Single radius) { Ellipse shp = new System.Windows.Shapes.Ellipse(); prepareLinePen(shp,brush); setRectValue(shp,x - radius,y - radius,radius,radius); addShape(shp,"Crcl"); } public void DrawEllipse(LinePen pen,Area area) { DrawEllipse(pen,(Single)area.Height); } public void DrawEllipse(LinePen pen,AreaF area) { DrawEllipse(pen,area.Height); } public void DrawEllipse(LinePen pen,Int32 height) { DrawEllipse(pen,(Single)height); } public void DrawEllipse(LinePen pen,Single height) { Ellipse shp = new System.Windows.Shapes.Ellipse(); prepareLinePen(shp,height); addShape(shp,"Elps"); } public void DrawString(string text,PaintBrush brush,AreaF area) { System.Windows.Controls.TextBlock shp = new TextBlock(); switch (font.Alignment) { case TextFont.AlignmentEnum.LEFT: shp.TextAlignment = TextAlignment.Left; break; case TextFont.AlignmentEnum.RIGHT: shp.TextAlignment = TextAlignment.Right; break; case TextFont.AlignmentEnum.CENTER: shp.TextAlignment = TextAlignment.Center; break; case TextFont.AlignmentEnum.JUSTIFY: shp.TextAlignment = TextAlignment.Justify; break; } switch (font.Style) { case TextFont.StyleEnum.REGULAR: break; case TextFont.StyleEnum.BOLD: shp.FontWeight = FontWeights.Bold; break; case TextFont.StyleEnum.ITALIC: shp.FontStyle = FontStyles.Italic; break; } if (font.Clip) { shp.Clip = new RectangleGeometry() { Rect = new Rect(0,area.Height) }; } shp.textwrapping = (font.Wrap) ? textwrapping.Wrap : textwrapping.Nowrap; shp.Foreground = (brush == null) ? _defaultTextBrush : converttoBrush(brush); shp.Text = text; setRectValue(shp,area.Height); shp.FontSize = font.Size; shp.FontFamily = new FontFamily(font.Family); addShape(shp,"Text"); } public void DrawString(Single x,float fontsize=10.0f,string fontname = "宋体") { AreaF area = new AreaF(){ X1 = x,Y1= y,X2=x+10,Y2= y+10}; TextFont font = new TextFont(fontname,fontsize); SolidPaintBrush brush = new SolidPaintBrush (fontcolor); DrawString(text,font,area); } public void DrawImage(Area area,ImageStretch st) { DrawImage(area.X1,area.Height,sourceUrl,st); } public void DrawImage(AreaF area,st); } public void DrawImage(Single x,Single height,ImageStretch st) { Image shp = new System.Windows.Controls.Image(); setRectValue(shp,height); shp.Stretch = converttoStretch(st); shp.source = new BitmapImage(new Uri(sourceUrl,UriKind.RelativeOrAbsolute)); addShape(shp,"Imag"); } #endregion Pulbic Methods #region Private Methods private Color converttoColor(DrawColor cl) { Color clr= new Color(); clr.A = cl.A; clr.B = cl.B; clr.G = cl.G; clr.R = cl.R; return clr; } private Brush converttoBrush(PaintBrush pbr) { if (pbr is SolidPaintBrush) { return new SolidColorBrush(converttoColor((((SolidPaintBrush)pbr).Color))); } return null; } private Stretch converttoStretch(ImageStretch st) { switch(st) { case ImageStretch.NONE: return Stretch.None; case ImageStretch.FILL: return Stretch.Fill; case ImageStretch.UNIFORM: return Stretch.Uniform; case ImageStretch.UNIFORMTOFILL: return Stretch.UniformToFill; } return Stretch.None; } private void prepareLinePen(System.Windows.Shapes.Shape shp,LinePen pen) { switch (pen.Style) { case LinePen.StyleEnum.soLID: shp.stroke = new SolidColorBrush(converttoColor(pen.Color)); break; case LinePen.StyleEnum.DOT: shp.stroke = new SolidColorBrush(converttoColor(pen.Color)); shp.strokeDashArray = _dotLinestrokeArray; break; case LinePen.StyleEnum.DASH: shp.stroke = new SolidColorBrush(converttoColor(pen.Color)); shp.strokeDashArray = _dashLinestrokeArray; break; case LinePen.StyleEnum.DASHDOT: shp.stroke = new SolidColorBrush(converttoColor(pen.Color)); shp.strokeDashArray = _dashdotdotLinestrokeArray; break; case LinePen.StyleEnum.DASHDOTDOT: shp.stroke = new SolidColorBrush(converttoColor(pen.Color)); shp.strokeDashArray = _dashdotdotLinestrokeArray; break; case LinePen.StyleEnum.CUSTOM: shp.stroke = new SolidColorBrush(converttoColor(pen.Color)); Single[] dashgapArray = pen.CustomDashGapArray; DoubleCollection customLinestrokeArray = new DoubleCollection(); foreach (Single i in dashgapArray) { customLinestrokeArray.Add(i); } shp.strokeDashArray = customLinestrokeArray; break; } shp.strokeThickness = pen.Width; } private void prepareFillBrush(System.Windows.Shapes.Shape shp,PaintBrush brh) { if (brh != null) { shp.Fill = converttoBrush(brh); } } private void setRectValue(System.Windows.FrameworkElement shp,double x,double y,double width,double height) { shp.Width = width; shp.Height = height; shp.SetValue(Canvas.LeftProperty,x); shp.SetValue(Canvas.TopProperty,y); } private void addShape(System.Windows.FrameworkElement tmpshape,string namePrefix) { tmpshape.Name = namePrefix + _elementCount.ToString(); _slCanvas.Children.Add(tmpshape); _elementCount++; _lastAddedShape = tmpshape; } #endregion Private Methods }
WinFormGraphics的源代码。
public class WinFormGraphics:IGraphBase { #region Consts & Enum #endregion Consts & Enum #region Member Variables private Graphics _canvas; private UInt32 _elementCount = 0; private Pen _defaultPen = new Pen(Color.Black); private Pen _polylinePen = null; private List<PointF> _polylinePoints = null; //private Brush _defaultTextBrush = new SolidColorBrush(Colors.Black); //private System.Windows.FrameworkElement _lastAddedShape = null; #endregion Member Variables #region Properties public Graphics GraphObject { get { return _canvas; } } //public System.Windows.FrameworkElement LastAddedShape //{ // get { return _lastAddedShape; } //} #endregion Properties #region Pulbic Methods public WinFormGraphics(Graphics cs) { _canvas = cs; } public void SetLinePen(LinePen pen) { _defaultPen = (pen==null)?null: converttoPen(pen); } public void Clear(DrawColor cl) { _canvas.Clear(converttoColor(cl)); } public void SetClip(AreaF area) { if(area != null) { _canvas.SetClip(new RectangleF(area.X1,area.Height)); } } public void ClearClip() { _canvas.ResetClip(); } public void DrawLine(LinePen pen,Single y2) { Pen pp = converttoPen(pen); _canvas.DrawLine(pp,x1,y1,x2,y2); _elementCount++; } public void Startpolyline(LinePen pen) { if(_polylinePoints!=null) _polylinePoints.Clear(); // need new ?????? _polylinePen = (pen == null) ? _defaultPen : converttoPen(pen); } public void AddpolylinePoint(Single x,Single y) { if (_polylinePoints == null) { _polylinePoints = new List<PointF>(); } _polylinePoints.Add(new PointF(x,(Single)y); } public void Endpolyline() { _canvas.DrawLines(_polylinePen,_polylinePoints.ToArray()); _elementCount++; } public void DrawRectangle(LinePen pen,Int32 height) { if (brush == null) { Pen pp = (pen == null) ? _defaultPen : converttoPen(pen); _canvas.DrawRectangle(pp,height); } else { Brush bb = converttoBrush(brush); _canvas.FillRectangle(bb,height); } _elementCount++; } public void DrawRectangle(LinePen pen,Single height) { if (brush == null) { Pen pp = (pen == null) ? _defaultPen : converttoPen(pen); _canvas.DrawRectangle(pp,height); } _elementCount++; } public void Drawpolygon(LinePen pen,ICollection<Dot> edges) { Point[] points = new Point[edges.Count]; int i=0; foreach(Dot dot in edges) { points[i].X = dot.X; points[i].Y = dot.Y; i++; } if (brush == null) { Pen pp = (pen == null) ? _defaultPen : converttoPen(pen); _canvas.Drawpolygon(pp,points); } else { Brush bb = converttoBrush(brush); _canvas.Fillpolygon (bb,points); } _elementCount++; } public void Drawpolygon(LinePen pen,ICollection<DotF> edges) { PointF[] points = new PointF[edges.Count]; int i = 0; foreach (DotF dot in edges) { points[i].X = dot.X; points[i].Y = dot.Y; i++; } if (brush == null) { Pen pp = (pen == null) ? _defaultPen : converttoPen(pen); _canvas.Drawpolygon(pp,points); } else { Brush bb = converttoBrush(brush); _canvas.Fillpolygon(bb,points); } _elementCount++; } public void DrawCircle(LinePen pen,Single radius) { DrawEllipse(pen,radius); } public void DrawEllipse(LinePen pen,Int32 height) { if (brush == null) { Pen pp = (pen == null) ? _defaultPen : converttoPen(pen); _canvas.DrawEllipse(pp,height); } else { Brush bb = converttoBrush(brush); _canvas.FillEllipse(bb,height); } _elementCount++; } public void DrawEllipse(LinePen pen,Single height) { if (brush == null) { Pen pp = (pen == null) ? _defaultPen : converttoPen(pen); _canvas.DrawEllipse(pp,height); } _elementCount++; } public void DrawString(string text,AreaF area) { StringFormat ft = new StringFormat(); if (!font.Wrap) ft.FormatFlags = StringFormatFlags.Nowrap; if (!font.Clip) ft.FormatFlags = ft.FormatFlags|StringFormatFlags.NoClip ; switch (font.Alignment) { case TextFont.AlignmentEnum.LEFT: ft.Alignment = Stringalignment.Near; break; case TextFont.AlignmentEnum.RIGHT: ft.Alignment = Stringalignment.Far; break; case TextFont.AlignmentEnum.CENTER: ft.Alignment = Stringalignment.Center; break; case TextFont.AlignmentEnum.JUSTIFY: ft.Alignment = Stringalignment.Near; break; } FontStyle ftstyle = FontStyle.Regular; switch (font.Style) { case TextFont.StyleEnum.REGULAR: break; case TextFont.StyleEnum.BOLD: ftstyle = FontStyle.Bold; break; case TextFont.StyleEnum.ITALIC: ftstyle = FontStyle.Italic; break; } Font fot = new Font(new FontFamily(font.Family),font.Size,ftstyle); RectangleF rt = new RectangleF(area.X1,area.Height); if (!font.Clip) //it seems that StringFormatFlags.NoClip does not work! here donot use that flag. { Sizef stringSize = new Sizef(); if (font.Wrap) { stringSize = _canvas.MeasureString(text,fot,(int)area.Width,ft); } else { stringSize = _canvas.MeasureString(text,new PointF(area.X1,area.Y1),ft); } rt.Width = (area.Width > stringSize.Width) ? area.Width : stringSize.Width; rt.Height= (area.Height>stringSize.Height)?area.Height:stringSize.Height; } _canvas.DrawString(text,converttoBrush(brush),rt,ft); _elementCount++; } public void DrawString(Single x,string fontname = "宋体") { Font fot = new Font(new FontFamily(fontname),fontsize,FontStyle.Regular); _canvas.DrawString(text,new SolidBrush(converttoColor(fontcolor)),new PointF(x,y)); _elementCount++; } public void DrawImage(Area area,ImageStretch st) { Image newImage = Image.FromFile(sourceUrl); switch (st) { case ImageStretch.UNIFORMTOFILL: case ImageStretch.NONE: _canvas.DrawImage(newImage,y); break; case ImageStretch.FILL: //to be stretched to the size of the holder _canvas.DrawImage(newImage,new RectangleF(x,height)); break; case ImageStretch.UNIFORM: //to be stretched according to the proportion of the image if (height / newImage.Size.Height > width / newImage.Size.Width) { _canvas.DrawImage(newImage,newImage.Size.Height * width / newImage.Size.Width)); } else { _canvas.DrawImage(newImage,newImage.Size.Width * height / newImage.Size.Height,height)); } break; } _elementCount++; } #endregion Pulbic Methods #region Private Methods private Color converttoColor(DrawColor cl) { return Color.FromArgb(cl.A,cl.R,cl.G,cl.B); } private Pen converttoPen(LinePen pen) { Pen pp = new Pen(converttoColor(pen.Color),pen.Width); switch (pen.Style) { case LinePen.StyleEnum.soLID: pp.DashStyle = System.Drawing.drawing2d.DashStyle.solid; break; case LinePen.StyleEnum.DOT: pp.DashStyle = System.Drawing.drawing2d.DashStyle.Dot; break; case LinePen.StyleEnum.DASH: pp.DashStyle = System.Drawing.drawing2d.DashStyle.Dash; break; case LinePen.StyleEnum.DASHDOT: pp.DashStyle = System.Drawing.drawing2d.DashStyle.DashDot; break; case LinePen.StyleEnum.DASHDOTDOT: pp.DashStyle = System.Drawing.drawing2d.DashStyle.DashDotDot; break; case LinePen.StyleEnum.CUSTOM: pp.DashPattern = pen.CustomDashGapArray; break; } return pp; } private Brush converttoBrush(PaintBrush pbr) { if (pbr is SolidPaintBrush) { return new SolidBrush(converttoColor((((SolidPaintBrush)pbr).Color))); } return null; } #endregion Private Methods }
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。