Tìm kiếm Blog này

Thứ Ba, 31 tháng 7, 2012

A Hatch Drawing Brush for WPF in Visual

The original post in VB.NET is here

We've now come to the conclusion that different groups of people are in charge of developing different technologies over at Microsoft. The WPF (Windows Presentation Foundation) development team made a significant number of improvements over Windows Forms and GDI+, but in the process missed a couple of things.
One very important item is the System.Drawing.HatchBrush from System.Drawing.Drawing2D which was very useful in Windows Forms but is now totally absent in WPF. We have made an interim replacement, which although does not use the win32 API directly should provide a remedy for most situations.
If used conservatively it should not have that much of an impact on the performance of your WPF applications.
WPF does not use the OnPaint override like GDI+. Instead you have to override the OnRender method. One important thing to note however is that WPF will disregard any drawing made to the DrawingContext unless the background mode is set to transparent, so the XAML for the Window should look like this:
<Window x:Class="Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="404" Width="727" Background="Transparent">
</Window>
public partial class Window1: Window
    {

        private DrawingContext mp_oGraphics;

        public FillPattern()
        {
            InitializeComponent();
        }

        protected override void OnRender(DrawingContext drawingContext)
        {
            base.OnRender(drawingContext);
            mp_oGraphics = drawingContext;
            mp_oGraphics.DrawRectangle(Brushes.DarkGray, null, new Rect(new Point(0, 0), new Point(this.Width, this.Height)));
            int i;
            int j;
            j = 0;
            for (i = 0; i <= 9; i++)
            {
                HatchFill(0, j * 30, 100, (j * 30) + 20, Colors.Black, Colors.White, (HatchEnum.HatchStyle)(HatchEnum.HatchStyle)i);
                j = j + 1;
            }
            j = 0;
            for (i = 10; i <= 19; i++)
            {
                HatchFill(120, j * 30, 220, (j * 30) + 20, Colors.Black, Colors.White, (HatchEnum.HatchStyle)i);
                j = j + 1;
            }

            j = 0;
            for (i = 20; i <= 29; i++)
            {
                HatchFill(240, j * 30, 340, (j * 30) + 20, Colors.Black, Colors.White, (HatchEnum.HatchStyle)i);
                j = j + 1;
            }
            j = 0;
            for (i = 30; i <= 39; i++)
            {
                HatchFill(360, j * 30, 460, (j * 30) + 20, Colors.Black, Colors.White, (HatchEnum.HatchStyle)i);
                j = j + 1;
            }
            j = 0;
            for (i = 40; i <= 49; i++)
            {
                HatchFill(480, j * 30, 580, (j * 30) + 20, Colors.Black, Colors.White, (HatchEnum.HatchStyle)i);
                j = j + 1;
            }
            j = 0;
            for (i = 50; i <= 52; i++)
            {
                HatchFill(600, j * 30, 700, (j * 30) + 20, Colors.Black, Colors.White, (HatchEnum.HatchStyle)i);
                j = j + 1;
            }
        }

        public void HatchFill(int v_X1, int v_Y1, int v_X2, int v_Y2, Color clrForeColor, Color clrBackColor, HatchEnum.HatchStyle yHatchStyle)
        {
            DrawingBrush mp_ucBrush;
            mp_ucBrush = GetHatchBrush(yHatchStyle, clrForeColor, clrBackColor);
            int iBuff = 0;
            if ((v_X2 - v_X1) <= 0)
            {
                iBuff = v_X1;
                v_X1 = v_X2;
                v_X2 = iBuff;
            }
            if ((v_Y2 - v_Y1) <= 0)
            {
                iBuff = v_Y1;
                v_Y1 = v_Y2;
                v_Y2 = iBuff;
            }
            mp_oGraphics.DrawRectangle(mp_ucBrush, null, new Rect(v_X1, v_Y1, v_X2 - v_X1 + 1, v_Y2 - v_Y1 + 1));
        }


        private DrawingBrush GetHatchBrush(HatchEnum.HatchStyle yHatchStyle, Color clrForeColor, Color clrBackColor)
        {
            DrawingBrush oReturnBrush = new DrawingBrush();
            GeometryGroup oHatchGroup = new GeometryGroup();
            GeometryGroup oHatchCtrlGroup = new GeometryGroup();
            int lWidth = 0;
            int lHeight = 0;
            HatchEnum.HatchType yType = HatchEnum.HatchType.HT_LINE;
            bool bAliased = true;
            switch (yHatchStyle)
            {
                case HatchEnum.HatchStyle.HS_HORIZONTAL:
                    lWidth = 8;
                    lHeight = 8;
                    oHatchGroup.Children.Add(mp_GLine(0, 0, 7, 0));
                    yType = HatchEnum.HatchType.HT_LINE; break;
                case HatchEnum.HatchStyle.HS_VERTICAL:
                    lWidth = 8;
                    lHeight = 8;
                    oHatchGroup.Children.Add(mp_GLine(0, 0, 0, 7));
                    yType = HatchEnum.HatchType.HT_LINE; break;
                case HatchEnum.HatchStyle.HS_FORWARDDIAGONAL:
                    lWidth = 16;
                    lHeight = 16;
                    oHatchGroup.Children.Add(mp_GLine(0, 12, 3, 15));
                    oHatchGroup.Children.Add(mp_GLine(0, 4, 11, 15));
                    oHatchGroup.Children.Add(mp_GLine(4, 0, 15, 11));
                    oHatchGroup.Children.Add(mp_GLine(12, 0, 15, 3));
                    System.Diagnostics.Debug.Write(oHatchGroup);
                    yType = HatchEnum.HatchType.HT_LINE; break;
                case HatchEnum.HatchStyle.HS_BACKWARDDIAGONAL:
                    lWidth = 16;
                    lHeight = 16;
                    oHatchGroup.Children.Add(mp_GLine(0, 12, 3, 15));
                    oHatchGroup.Children.Add(mp_GLine(0, 4, 11, 15));
                    oHatchGroup.Children.Add(mp_GLine(4, 0, 15, 11));
                    oHatchGroup.Children.Add(mp_GLine(12, 0, 15, 3));
                    oHatchGroup.Transform = new RotateTransform(90, 8, 8);
                    yType = HatchEnum.HatchType.HT_LINE; break;
                case HatchEnum.HatchStyle.HS_LARGEGRID:
                    lWidth = 8;
                    lHeight = 8;
                    oHatchGroup.Children.Add(mp_GLine(0, 0, 7, 0));
                    oHatchGroup.Children.Add(mp_GLine(0, 0, 0, 7));
                    yType = HatchEnum.HatchType.HT_LINE; break;
                case HatchEnum.HatchStyle.HS_DIAGONALCROSS:
                    lWidth = 7;
                    lHeight = 7;
                    oHatchGroup.Children.Add(mp_GRect(1, 1, 5, 5));
                    oHatchGroup.Transform = new RotateTransform(45, 3, 3);
                    yType = HatchEnum.HatchType.HT_LINE; break;
                    bAliased = false;
                case HatchEnum.HatchStyle.HS_PERCENT05:
                    lWidth = 8;
                    lHeight = 8;
                    oHatchGroup.Children.Add(mp_GPoint(0, 4));
                    oHatchGroup.Children.Add(mp_GPoint(4, 0));
                    yType = HatchEnum.HatchType.HT_LINE; break;
                case HatchEnum.HatchStyle.HS_PERCENT10:
                    lWidth = 8;
                    lHeight = 8;
                    oHatchGroup.Children.Add(mp_GPoint(0, 2));
                    oHatchGroup.Children.Add(mp_GPoint(4, 0));
                    oHatchGroup.Children.Add(mp_GPoint(0, 6));
                    oHatchGroup.Children.Add(mp_GPoint(4, 4));
                    yType = HatchEnum.HatchType.HT_LINE; break;
                case HatchEnum.HatchStyle.HS_PERCENT20:
                    lWidth = 4;
                    lHeight = 4;
                    oHatchGroup.Children.Add(mp_GPoint(0, 0));
                    oHatchGroup.Children.Add(mp_GPoint(2, 2));
                    yType = HatchEnum.HatchType.HT_LINE; break;
                case HatchEnum.HatchStyle.HS_PERCENT25:
                    lWidth = 4;
                    lHeight = 4;
                    oHatchGroup.Children.Add(mp_GPoint(0, 0));
                    oHatchGroup.Children.Add(mp_GPoint(0, 2));
                    oHatchGroup.Children.Add(mp_GPoint(2, 1));
                    oHatchGroup.Children.Add(mp_GPoint(2, 3));
                    yType = HatchEnum.HatchType.HT_LINE; break;
                case HatchEnum.HatchStyle.HS_PERCENT30:
                    lWidth = 4;
                    lHeight = 4;
                    oHatchGroup.Children.Add(mp_GPoint(0, 0));
                    oHatchGroup.Children.Add(mp_GPoint(1, 1));
                    oHatchGroup.Children.Add(mp_GPoint(2, 2));
                    oHatchGroup.Children.Add(mp_GPoint(3, 3));
                    oHatchGroup.Children.Add(mp_GPoint(2, 0));
                    oHatchGroup.Children.Add(mp_GPoint(0, 2));
                    yType = HatchEnum.HatchType.HT_LINE; break;
                case HatchEnum.HatchStyle.HS_PERCENT40:
                    lWidth = 8;
                    lHeight = 8;
                    oHatchGroup.Children.Add(mp_GPoint(0, 0));
                    oHatchGroup.Children.Add(mp_GPoint(2, 0));
                    oHatchGroup.Children.Add(mp_GPoint(4, 0));
                    oHatchGroup.Children.Add(mp_GPoint(6, 0));

                    oHatchGroup.Children.Add(mp_GPoint(3, 1));
                    oHatchGroup.Children.Add(mp_GPoint(5, 1));
                    oHatchGroup.Children.Add(mp_GPoint(7, 1));

                    oHatchGroup.Children.Add(mp_GPoint(0, 2));
                    oHatchGroup.Children.Add(mp_GPoint(2, 2));
                    oHatchGroup.Children.Add(mp_GPoint(4, 2));
                    oHatchGroup.Children.Add(mp_GPoint(6, 2));

                    oHatchGroup.Children.Add(mp_GPoint(1, 3));
                    oHatchGroup.Children.Add(mp_GPoint(3, 3));
                    oHatchGroup.Children.Add(mp_GPoint(5, 3));
                    oHatchGroup.Children.Add(mp_GPoint(7, 3));

                    oHatchGroup.Children.Add(mp_GPoint(0, 4));
                    oHatchGroup.Children.Add(mp_GPoint(2, 4));
                    oHatchGroup.Children.Add(mp_GPoint(4, 4));
                    oHatchGroup.Children.Add(mp_GPoint(6, 4));
                    oHatchGroup.Children.Add(mp_GPoint(1, 5));
                    oHatchGroup.Children.Add(mp_GPoint(3, 5));
                    oHatchGroup.Children.Add(mp_GPoint(7, 5));
                    oHatchGroup.Children.Add(mp_GPoint(0, 6));
                    oHatchGroup.Children.Add(mp_GPoint(2, 6));
                    oHatchGroup.Children.Add(mp_GPoint(4, 6));
                    oHatchGroup.Children.Add(mp_GPoint(6, 6));
                    oHatchGroup.Children.Add(mp_GPoint(1, 7));
                    oHatchGroup.Children.Add(mp_GPoint(3, 7));
                    oHatchGroup.Children.Add(mp_GPoint(5, 7));
                    oHatchGroup.Children.Add(mp_GPoint(7, 7));
                    yType = HatchEnum.HatchType.HT_LINE; break;
                case HatchEnum.HatchStyle.HS_PERCENT50:
                    lWidth = 2;
                    lHeight = 2;
                    oHatchGroup.Children.Add(mp_GPoint(0, 0));
                    oHatchGroup.Children.Add(mp_GPoint(1, 1));
                    yType = HatchEnum.HatchType.HT_LINE; break;
                case HatchEnum.HatchStyle.HS_PERCENT60:
                    lWidth = 4;
                    lHeight = 4;
                    oHatchGroup.Children.Add(mp_GPoint(0, 0));
                    oHatchGroup.Children.Add(mp_GPoint(2, 0));
                    oHatchGroup.Children.Add(mp_GPoint(3, 0));
                    oHatchGroup.Children.Add(mp_GPoint(1, 1));
                    oHatchGroup.Children.Add(mp_GPoint(3, 1));
                    oHatchGroup.Children.Add(mp_GPoint(0, 2));
                    oHatchGroup.Children.Add(mp_GPoint(1, 2));
                    oHatchGroup.Children.Add(mp_GPoint(2, 2));
                    oHatchGroup.Children.Add(mp_GPoint(1, 3));
                    oHatchGroup.Children.Add(mp_GPoint(3, 3));
                    yType = HatchEnum.HatchType.HT_LINE; break;
                case HatchEnum.HatchStyle.HS_PERCENT70:
                    lWidth = 4;
                    lHeight = 4;
                    oHatchGroup.Children.Add(mp_GPoint(1, 0));
                    oHatchGroup.Children.Add(mp_GPoint(2, 0));
                    oHatchGroup.Children.Add(mp_GPoint(3, 0));
                    oHatchGroup.Children.Add(mp_GPoint(0, 1));
                    oHatchGroup.Children.Add(mp_GPoint(1, 1));
                    oHatchGroup.Children.Add(mp_GPoint(3, 1));
                    oHatchGroup.Children.Add(mp_GPoint(1, 2));
                    oHatchGroup.Children.Add(mp_GPoint(2, 2));
                    oHatchGroup.Children.Add(mp_GPoint(3, 2));
                    oHatchGroup.Children.Add(mp_GPoint(0, 3));
                    oHatchGroup.Children.Add(mp_GPoint(1, 3));
                    oHatchGroup.Children.Add(mp_GPoint(3, 3));
                    yType = HatchEnum.HatchType.HT_LINE; break;
                case HatchEnum.HatchStyle.HS_PERCENT75:
                    lWidth = 4;
                    lHeight = 4;
                    oHatchGroup.Children.Add(mp_GPoint(2, 0));
                    oHatchGroup.Children.Add(mp_GPoint(0, 2));
                    InvertColors(ref clrForeColor, ref clrBackColor);
                    yType = HatchEnum.HatchType.HT_LINE; break;
                case HatchEnum.HatchStyle.HS_PERCENT80:
                    lWidth = 8;
                    lHeight = 7;
                    oHatchGroup.Children.Add(mp_GPoint(3, 0));
                    oHatchGroup.Children.Add(mp_GPoint(3, 4));
                    oHatchGroup.Children.Add(mp_GPoint(7, 2));
                    oHatchGroup.Children.Add(mp_GPoint(7, 6));
                    InvertColors(ref clrForeColor, ref clrBackColor);
                    yType = HatchEnum.HatchType.HT_LINE; break;
                case HatchEnum.HatchStyle.HS_PERCENT90:
                    lWidth = 8;
                    lHeight = 8;
                    oHatchGroup.Children.Add(mp_GPoint(0, 5));
                    oHatchGroup.Children.Add(mp_GPoint(4, 1));
                    InvertColors(ref clrForeColor, ref clrBackColor);
                    yType = HatchEnum.HatchType.HT_LINE; break;
                case HatchEnum.HatchStyle.HS_LIGHTDOWNWARDDIAGONAL:
                    lWidth = 4;
                    lHeight = 4;
                    oHatchGroup.Children.Add(mp_GPoint(0, 0));
                    oHatchGroup.Children.Add(mp_GPoint(1, 1));
                    oHatchGroup.Children.Add(mp_GPoint(2, 2));
                    oHatchGroup.Children.Add(mp_GPoint(3, 3));
                    yType = HatchEnum.HatchType.HT_LINE; break;
                case HatchEnum.HatchStyle.HS_LIGHTUPWARDDIAGONAL:
                    lWidth = 4;
                    lHeight = 4;
                    oHatchGroup.Children.Add(mp_GPoint(0, 3));
                    oHatchGroup.Children.Add(mp_GPoint(1, 2));
                    oHatchGroup.Children.Add(mp_GPoint(2, 1));
                    oHatchGroup.Children.Add(mp_GPoint(3, 0));
                    yType = HatchEnum.HatchType.HT_LINE; break;
                case HatchEnum.HatchStyle.HS_DARKDOWNWARDDIAGONAL:
                    lWidth = 4;
                    lHeight = 4;
                    oHatchGroup.Children.Add(mp_GPoint(0, 3));
                    oHatchGroup.Children.Add(mp_GPoint(0, 0));
                    oHatchGroup.Children.Add(mp_GPoint(1, 1));
                    oHatchGroup.Children.Add(mp_GPoint(2, 2));
                    oHatchGroup.Children.Add(mp_GPoint(3, 3));
                    oHatchGroup.Children.Add(mp_GPoint(1, 0));
                    oHatchGroup.Children.Add(mp_GPoint(2, 1));
                    oHatchGroup.Children.Add(mp_GPoint(3, 2));
                    yType = HatchEnum.HatchType.HT_LINE; break;
                case HatchEnum.HatchStyle.HS_DARKUPWARDDIAGONAL:
                    lWidth = 4;
                    lHeight = 4;
                    oHatchGroup.Children.Add(mp_GPoint(0, 0));
                    oHatchGroup.Children.Add(mp_GPoint(0, 1));
                    oHatchGroup.Children.Add(mp_GPoint(1, 0));
                    oHatchGroup.Children.Add(mp_GPoint(1, 3));
                    oHatchGroup.Children.Add(mp_GPoint(2, 2));
                    oHatchGroup.Children.Add(mp_GPoint(3, 1));
                    oHatchGroup.Children.Add(mp_GPoint(2, 3));
                    oHatchGroup.Children.Add(mp_GPoint(3, 2));
                    yType = HatchEnum.HatchType.HT_LINE; break;
                case HatchEnum.HatchStyle.HS_WIDEDOWNWARDDIAGONAL:
                    lWidth = 8;
                    lHeight = 8;
                    oHatchGroup.Children.Add(mp_GLine(3, 0, 5, 0));
                    oHatchGroup.Children.Add(mp_GLine(4, 1, 6, 1));
                    oHatchGroup.Children.Add(mp_GLine(5, 2, 7, 2));
                    oHatchGroup.Children.Add(mp_GPoint(0, 3));
                    oHatchGroup.Children.Add(mp_GLine(6, 3, 7, 3));
                    oHatchGroup.Children.Add(mp_GLine(0, 4, 1, 4));
                    oHatchGroup.Children.Add(mp_GPoint(7, 4));
                    oHatchGroup.Children.Add(mp_GLine(0, 5, 2, 5));
                    oHatchGroup.Children.Add(mp_GLine(1, 6, 3, 6));
                    oHatchGroup.Children.Add(mp_GLine(2, 7, 4, 7));
                    oHatchCtrlGroup.Children.Add(mp_GPoint(7, 7));
                    yType = HatchEnum.HatchType.HT_LINE; break;
                case HatchEnum.HatchStyle.HS_WIDEUPWARDDIAGONAL:
                    lWidth = 8;
                    lHeight = 8;
                    oHatchGroup.Children.Add(mp_GLine(4, 0, 6, 0));
                    oHatchGroup.Children.Add(mp_GLine(3, 1, 5, 1));
                    oHatchGroup.Children.Add(mp_GLine(2, 2, 4, 2));
                    oHatchGroup.Children.Add(mp_GLine(1, 3, 3, 3));
                    oHatchGroup.Children.Add(mp_GLine(0, 4, 2, 4));
                    oHatchGroup.Children.Add(mp_GLine(0, 5, 1, 5));
                    oHatchGroup.Children.Add(mp_GPoint(7, 5));
                    oHatchGroup.Children.Add(mp_GPoint(0, 6));
                    oHatchGroup.Children.Add(mp_GLine(6, 6, 7, 6));
                    oHatchGroup.Children.Add(mp_GLine(5, 7, 7, 7));
                    oHatchCtrlGroup.Children.Add(mp_GLine(0, 0, 7, 7));
                    yType = HatchEnum.HatchType.HT_LINE; break;
                case HatchEnum.HatchStyle.HS_LIGHTVERTICAL:
                    lWidth = 4;
                    lHeight = 4;
                    oHatchGroup.Children.Add(mp_GLine(0, 0, 0, 3));
                    yType = HatchEnum.HatchType.HT_LINE; break;
                case HatchEnum.HatchStyle.HS_LIGHTHORIZONTAL:
                    lWidth = 4;
                    lHeight = 4;
                    oHatchGroup.Children.Add(mp_GLine(0, 0, 3, 0));
                    yType = HatchEnum.HatchType.HT_LINE; break;
                case HatchEnum.HatchStyle.HS_NARROWVERTICAL:
                    lWidth = 2;
                    lHeight = 2;
                    oHatchGroup.Children.Add(mp_GLine(1, 0, 1, 1));
                    yType = HatchEnum.HatchType.HT_LINE; break;
                case HatchEnum.HatchStyle.HS_NARROWHORIZONTAL:
                    lWidth = 2;
                    lHeight = 2;
                    oHatchGroup.Children.Add(mp_GLine(0, 1, 1, 1));
                    yType = HatchEnum.HatchType.HT_LINE; break;
                case HatchEnum.HatchStyle.HS_DARKVERTICAL:
                    lWidth = 4;
                    lHeight = 4;
                    oHatchGroup.Children.Add(mp_GLine(0, 0, 0, 3));
                    oHatchGroup.Children.Add(mp_GLine(1, 0, 1, 3));
                    yType = HatchEnum.HatchType.HT_LINE; break;
                case HatchEnum.HatchStyle.HS_DARKHORIZONTAL:
                    lWidth = 4;
                    lHeight = 4;
                    oHatchGroup.Children.Add(mp_GLine(0, 0, 3, 0));
                    oHatchGroup.Children.Add(mp_GLine(0, 1, 3, 1));
                    yType = HatchEnum.HatchType.HT_LINE; break;
                case HatchEnum.HatchStyle.HS_DASHEDDOWNWARDDIAGONAL:
                    lWidth = 8;
                    lHeight = 8;
                    oHatchGroup.Children.Add(mp_GPoint(0, 2));
                    oHatchGroup.Children.Add(mp_GPoint(1, 3));
                    oHatchGroup.Children.Add(mp_GPoint(2, 4));
                    oHatchGroup.Children.Add(mp_GPoint(3, 5));
                    oHatchGroup.Children.Add(mp_GPoint(4, 2));
                    oHatchGroup.Children.Add(mp_GPoint(5, 3));
                    oHatchGroup.Children.Add(mp_GPoint(6, 4));
                    oHatchGroup.Children.Add(mp_GPoint(7, 5));
                    yType = HatchEnum.HatchType.HT_LINE; break;
                case HatchEnum.HatchStyle.HS_DASHEDUPWARDDIAGONAL:
                    lWidth = 8;
                    lHeight = 8;
                    oHatchGroup.Children.Add(mp_GPoint(0, 7));
                    oHatchGroup.Children.Add(mp_GPoint(1, 6));
                    oHatchGroup.Children.Add(mp_GPoint(2, 5));
                    oHatchGroup.Children.Add(mp_GPoint(3, 4));
                    oHatchGroup.Children.Add(mp_GPoint(4, 7));
                    oHatchGroup.Children.Add(mp_GPoint(5, 6));
                    oHatchGroup.Children.Add(mp_GPoint(6, 5));
                    oHatchGroup.Children.Add(mp_GPoint(7, 4));
                    yType = HatchEnum.HatchType.HT_LINE; break;
                case HatchEnum.HatchStyle.HS_DASHEDHORIZONTAL:
                    lWidth = 8;
                    lHeight = 8;
                    oHatchGroup.Children.Add(mp_GLine(4, 0, 7, 0));
                    oHatchGroup.Children.Add(mp_GLine(0, 4, 3, 4));
                    oHatchCtrlGroup.Children.Add(mp_GPoint(7, 7));
                    yType = HatchEnum.HatchType.HT_LINE; break;
                case HatchEnum.HatchStyle.HS_DASHEDVERTICAL:
                    lWidth = 8;
                    lHeight = 8;
                    oHatchGroup.Children.Add(mp_GLine(0, 0, 0, 1));
                    oHatchGroup.Children.Add(mp_GLine(0, 6, 0, 7));
                    oHatchGroup.Children.Add(mp_GLine(4, 2, 4, 5));
                    oHatchCtrlGroup.Children.Add(mp_GPoint(7, 7));
                    yType = HatchEnum.HatchType.HT_LINE; break;
                case HatchEnum.HatchStyle.HS_SMALLCONFETTI:
                    lWidth = 8;
                    lHeight = 8;
                    oHatchGroup.Children.Add(mp_GPoint(0, 0));
                    oHatchGroup.Children.Add(mp_GPoint(4, 1));
                    oHatchGroup.Children.Add(mp_GPoint(1, 2));
                    oHatchGroup.Children.Add(mp_GPoint(6, 3));
                    oHatchGroup.Children.Add(mp_GPoint(3, 4));
                    oHatchGroup.Children.Add(mp_GPoint(7, 5));
                    oHatchGroup.Children.Add(mp_GPoint(2, 6));
                    oHatchGroup.Children.Add(mp_GPoint(5, 7));
                    oHatchCtrlGroup.Children.Add(mp_GPoint(7, 7));
                    yType = HatchEnum.HatchType.HT_LINE; break;
                case HatchEnum.HatchStyle.HS_LARGECONFETTI:
                    lWidth = 8;
                    lHeight = 8;
                    oHatchGroup.Children.Add(mp_GLine(0, 1, 0, 2));
                    oHatchGroup.Children.Add(mp_GLine(0, 6, 0, 7));
                    oHatchGroup.Children.Add(mp_GLine(1, 6, 1, 7));
                    oHatchGroup.Children.Add(mp_GLine(2, 2, 2, 3));
                    oHatchGroup.Children.Add(mp_GLine(3, 2, 3, 3));
                    oHatchGroup.Children.Add(mp_GLine(3, 5, 3, 6));
                    oHatchGroup.Children.Add(mp_GLine(4, 0, 4, 1));
                    oHatchGroup.Children.Add(mp_GLine(4, 5, 4, 6));
                    oHatchGroup.Children.Add(mp_GLine(5, 0, 5, 1));
                    oHatchGroup.Children.Add(mp_GLine(6, 4, 6, 5));
                    oHatchGroup.Children.Add(mp_GLine(7, 1, 7, 2));
                    oHatchGroup.Children.Add(mp_GLine(7, 4, 7, 5));
                    oHatchCtrlGroup.Children.Add(mp_GPoint(7, 7));
                    yType = HatchEnum.HatchType.HT_LINE; break;
                case HatchEnum.HatchStyle.HS_ZIGZAG:
                    lWidth = 8;
                    lHeight = 8;
                    oHatchGroup.Children.Add(mp_GPoint(0, 0));
                    oHatchGroup.Children.Add(mp_GPoint(1, 1));
                    oHatchGroup.Children.Add(mp_GPoint(2, 2));
                    oHatchGroup.Children.Add(mp_GLine(3, 3, 4, 3));
                    oHatchGroup.Children.Add(mp_GPoint(5, 2));
                    oHatchGroup.Children.Add(mp_GPoint(6, 1));
                    oHatchGroup.Children.Add(mp_GPoint(7, 0));

                    oHatchGroup.Children.Add(mp_GPoint(0, 4));
                    oHatchGroup.Children.Add(mp_GPoint(1, 5));
                    oHatchGroup.Children.Add(mp_GPoint(2, 6));
                    oHatchGroup.Children.Add(mp_GLine(3, 7, 4, 7));
                    oHatchGroup.Children.Add(mp_GPoint(5, 6));
                    oHatchGroup.Children.Add(mp_GPoint(6, 5));
                    oHatchGroup.Children.Add(mp_GPoint(7, 4));
                    yType = HatchEnum.HatchType.HT_LINE; break;
                case HatchEnum.HatchStyle.HS_WAVE:
                    lWidth = 8;
                    lHeight = 8;
                    oHatchGroup.Children.Add(mp_GPoint(2, 0));
                    oHatchGroup.Children.Add(mp_GPoint(5, 0));
                    oHatchGroup.Children.Add(mp_GPoint(7, 0));
                    oHatchGroup.Children.Add(mp_GLine(0, 2, 1, 2));

                    oHatchGroup.Children.Add(mp_GLine(3, 4, 4, 4));
                    oHatchGroup.Children.Add(mp_GPoint(2, 4));
                    oHatchGroup.Children.Add(mp_GPoint(5, 4));
                    oHatchGroup.Children.Add(mp_GPoint(7, 4));

                    oHatchGroup.Children.Add(mp_GLine(0, 6, 1, 6));
                    oHatchGroup.Children.Add(mp_GLine(3, 8, 4, 8));
                    oHatchCtrlGroup.Children.Add(mp_GPoint(0, 0));
                    oHatchCtrlGroup.Children.Add(mp_GPoint(7, 7));
                    yType = HatchEnum.HatchType.HT_LINE; break;
                case HatchEnum.HatchStyle.HS_DIAGONALBRICK:
                    lWidth = 8;
                    lHeight = 8;
                    oHatchGroup.Children.Add(mp_GPoint(0, 7));
                    oHatchGroup.Children.Add(mp_GPoint(1, 6));
                    oHatchGroup.Children.Add(mp_GPoint(2, 5));
                    oHatchGroup.Children.Add(mp_GPoint(3, 4));
                    oHatchGroup.Children.Add(mp_GPoint(4, 3));
                    oHatchGroup.Children.Add(mp_GPoint(5, 2));
                    oHatchGroup.Children.Add(mp_GPoint(6, 1));
                    oHatchGroup.Children.Add(mp_GPoint(7, 0));
                    oHatchGroup.Children.Add(mp_GPoint(4, 4));
                    oHatchGroup.Children.Add(mp_GPoint(5, 5));
                    oHatchGroup.Children.Add(mp_GPoint(6, 6));
                    oHatchGroup.Children.Add(mp_GPoint(7, 7));
                    yType = HatchEnum.HatchType.HT_LINE; break;
                case HatchEnum.HatchStyle.HS_HORIZONTALBRICK:
                    lWidth = 8;
                    lHeight = 8;
                    oHatchGroup.Children.Add(mp_GPoint(4, 0));
                    oHatchGroup.Children.Add(mp_GPoint(4, 1));
                    oHatchGroup.Children.Add(mp_GLine(0, 1, 0, 5));
                    oHatchGroup.Children.Add(mp_GPoint(4, 6));
                    oHatchGroup.Children.Add(mp_GPoint(4, 7));

                    oHatchGroup.Children.Add(mp_GLine(1, 2, 7, 2));
                    oHatchGroup.Children.Add(mp_GLine(1, 6, 7, 6));
                    yType = HatchEnum.HatchType.HT_LINE; break;
                case HatchEnum.HatchStyle.HS_WEAVE:
                    lWidth = 8;
                    lHeight = 8;
                    oHatchGroup.Children.Add(mp_GPoint(0, 0));
                    oHatchGroup.Children.Add(mp_GPoint(1, 1));
                    oHatchGroup.Children.Add(mp_GPoint(2, 2));
                    oHatchGroup.Children.Add(mp_GPoint(0, 4));
                    oHatchGroup.Children.Add(mp_GPoint(1, 3));
                    oHatchGroup.Children.Add(mp_GPoint(3, 1));
                    oHatchGroup.Children.Add(mp_GPoint(4, 0));
                    oHatchGroup.Children.Add(mp_GPoint(5, 1));
                    oHatchGroup.Children.Add(mp_GPoint(6, 2));
                    oHatchGroup.Children.Add(mp_GPoint(7, 3));
                    oHatchGroup.Children.Add(mp_GPoint(5, 3));
                    oHatchGroup.Children.Add(mp_GPoint(4, 4));
                    oHatchGroup.Children.Add(mp_GPoint(3, 5));
                    oHatchGroup.Children.Add(mp_GPoint(2, 6));
                    oHatchGroup.Children.Add(mp_GPoint(1, 7));
                    oHatchGroup.Children.Add(mp_GPoint(3, 7));
                    oHatchGroup.Children.Add(mp_GPoint(5, 5));
                    oHatchGroup.Children.Add(mp_GPoint(6, 6));
                    oHatchGroup.Children.Add(mp_GPoint(7, 7));
                    yType = HatchEnum.HatchType.HT_LINE; break;
                case HatchEnum.HatchStyle.HS_PLAID:
                    lWidth = 8;
                    lHeight = 8;
                    oHatchGroup.Children.Add(mp_GLine(0, 0, 3, 0));
                    oHatchGroup.Children.Add(mp_GLine(0, 1, 3, 1));

                    oHatchGroup.Children.Add(mp_GPoint(0, 2));
                    oHatchGroup.Children.Add(mp_GPoint(2, 2));
                    oHatchGroup.Children.Add(mp_GPoint(4, 2));
                    oHatchGroup.Children.Add(mp_GPoint(6, 2));

                    oHatchGroup.Children.Add(mp_GPoint(1, 3));
                    oHatchGroup.Children.Add(mp_GPoint(3, 3));
                    oHatchGroup.Children.Add(mp_GPoint(5, 3));
                    oHatchGroup.Children.Add(mp_GPoint(7, 3));


                    oHatchGroup.Children.Add(mp_GPoint(0, 4));
                    oHatchGroup.Children.Add(mp_GPoint(2, 4));
                    oHatchGroup.Children.Add(mp_GPoint(4, 4));
                    oHatchGroup.Children.Add(mp_GPoint(6, 4));

                    oHatchGroup.Children.Add(mp_GPoint(1, 5));
                    oHatchGroup.Children.Add(mp_GPoint(3, 5));
                    oHatchGroup.Children.Add(mp_GPoint(5, 5));
                    oHatchGroup.Children.Add(mp_GPoint(7, 5));

                    oHatchGroup.Children.Add(mp_GLine(0, 6, 3, 6));
                    oHatchGroup.Children.Add(mp_GLine(0, 7, 3, 7));
                    oHatchCtrlGroup.Children.Add(mp_GPoint(7, 7));
                    yType = HatchEnum.HatchType.HT_LINE; break;
                case HatchEnum.HatchStyle.HS_DIVOT:
                    lWidth = 8;
                    lHeight = 8;
                    oHatchGroup.Children.Add(mp_GPoint(0, 1));
                    oHatchGroup.Children.Add(mp_GPoint(0, 3));
                    oHatchGroup.Children.Add(mp_GPoint(3, 5));
                    oHatchGroup.Children.Add(mp_GPoint(3, 7));
                    oHatchGroup.Children.Add(mp_GPoint(4, 6));
                    oHatchGroup.Children.Add(mp_GPoint(7, 2));
                    oHatchCtrlGroup.Children.Add(mp_GPoint(7, 7));
                    yType = HatchEnum.HatchType.HT_LINE; break;
                case HatchEnum.HatchStyle.HS_DOTTEDGRID:
                    lWidth = 8;
                    lHeight = 8;
                    oHatchGroup.Children.Add(mp_GPoint(1, 6));
                    oHatchGroup.Children.Add(mp_GPoint(3, 6));
                    oHatchGroup.Children.Add(mp_GPoint(5, 6));
                    oHatchGroup.Children.Add(mp_GPoint(7, 6));
                    oHatchGroup.Children.Add(mp_GPoint(7, 4));
                    oHatchGroup.Children.Add(mp_GPoint(7, 2));
                    oHatchGroup.Children.Add(mp_GPoint(7, 0));
                    oHatchCtrlGroup.Children.Add(mp_GPoint(7, 7));
                    yType = HatchEnum.HatchType.HT_LINE; break;
                case HatchEnum.HatchStyle.HS_DOTTEDDIAMOND:
                    lWidth = 8;
                    lHeight = 8;
                    oHatchGroup.Children.Add(mp_GPoint(0, 0));
                    oHatchGroup.Children.Add(mp_GPoint(2, 2));
                    oHatchGroup.Children.Add(mp_GPoint(4, 4));
                    oHatchGroup.Children.Add(mp_GPoint(6, 6));
                    oHatchGroup.Children.Add(mp_GPoint(2, 6));
                    oHatchGroup.Children.Add(mp_GPoint(6, 2));
                    yType = HatchEnum.HatchType.HT_LINE; break;
                case HatchEnum.HatchStyle.HS_SHINGLE:
                    lWidth = 8;
                    lHeight = 8;
                    oHatchGroup.Children.Add(mp_GPoint(0, 3));
                    oHatchGroup.Children.Add(mp_GPoint(1, 4));
                    oHatchGroup.Children.Add(mp_GPoint(2, 5));
                    oHatchGroup.Children.Add(mp_GPoint(3, 5));
                    oHatchGroup.Children.Add(mp_GPoint(4, 6));
                    oHatchGroup.Children.Add(mp_GPoint(5, 6));
                    oHatchGroup.Children.Add(mp_GPoint(6, 7));
                    oHatchGroup.Children.Add(mp_GPoint(4, 4));
                    oHatchGroup.Children.Add(mp_GPoint(5, 3));
                    oHatchGroup.Children.Add(mp_GPoint(6, 2));
                    oHatchGroup.Children.Add(mp_GPoint(7, 2));
                    oHatchGroup.Children.Add(mp_GPoint(7, 0));
                    oHatchGroup.Children.Add(mp_GPoint(7, 1));
                    yType = HatchEnum.HatchType.HT_LINE; break;
                case HatchEnum.HatchStyle.HS_TRELLIS:
                    lWidth = 4;
                    lHeight = 4;
                    oHatchGroup.Children.Add(mp_GLine(0, 0, 3, 0));
                    oHatchGroup.Children.Add(mp_GLine(1, 1, 2, 1));
                    oHatchGroup.Children.Add(mp_GLine(0, 2, 3, 2));
                    oHatchGroup.Children.Add(mp_GPoint(0, 3));
                    oHatchGroup.Children.Add(mp_GPoint(3, 3));
                    yType = HatchEnum.HatchType.HT_LINE; break;
                case HatchEnum.HatchStyle.HS_SPHERE:
                    lWidth = 8;
                    lHeight = 8;
                    oHatchGroup.Children.Add(mp_GLine(1, 0, 3, 0));
                    oHatchGroup.Children.Add(mp_GLine(1, 1, 3, 1));
                    oHatchGroup.Children.Add(mp_GPoint(0, 2));
                    oHatchGroup.Children.Add(mp_GPoint(4, 2));
                    oHatchGroup.Children.Add(mp_GLine(1, 3, 2, 3));
                    oHatchGroup.Children.Add(mp_GPoint(0, 6));
                    oHatchGroup.Children.Add(mp_GPoint(4, 6));
                    oHatchGroup.Children.Add(mp_GLine(1, 7, 3, 7));
                    oHatchGroup.Children.Add(mp_GLine(5, 7, 6, 7));
                    oHatchGroup.Children.Add(mp_GLine(5, 3, 7, 3));
                    oHatchGroup.Children.Add(mp_GLine(5, 4, 7, 4));
                    oHatchGroup.Children.Add(mp_GLine(5, 5, 7, 5));
                    oHatchCtrlGroup.Children.Add(mp_GPoint(7, 7));
                    InvertColors(ref clrForeColor, ref clrBackColor);
                    yType = HatchEnum.HatchType.HT_LINE; break;
                case HatchEnum.HatchStyle.HS_SMALLGRID:
                    lWidth = 4;
                    lHeight = 4;
                    oHatchGroup.Children.Add(mp_GLine(0, 0, 3, 0));
                    oHatchGroup.Children.Add(mp_GLine(0, 0, 0, 3));
                    yType = HatchEnum.HatchType.HT_LINE; break;
                case HatchEnum.HatchStyle.HS_SMALLCHECKERBOARD:
                    lWidth = 4;
                    lHeight = 4;
                    oHatchGroup.Children.Add(mp_GRect(0, 0, 2, 2));
                    oHatchGroup.Children.Add(mp_GRect(2, 2, 2, 2));
                    yType = HatchEnum.HatchType.HT_RECTANGLE; break;
                case HatchEnum.HatchStyle.HS_LARGECHECKERBOARD:
                    lWidth = 8;
                    lHeight = 8;
                    oHatchGroup.Children.Add(mp_GRect(0, 0, 4, 4));
                    oHatchGroup.Children.Add(mp_GRect(4, 4, 4, 4));
                    yType = HatchEnum.HatchType.HT_RECTANGLE; break;
                case HatchEnum.HatchStyle.HS_OUTLINEDDIAMOND:
                    lWidth = 8;
                    lHeight = 8;

                    oHatchGroup.Children.Add(mp_GPoint(0, 4));
                    oHatchGroup.Children.Add(mp_GPoint(1, 3));
                    oHatchGroup.Children.Add(mp_GPoint(2, 2));
                    oHatchGroup.Children.Add(mp_GPoint(3, 1));
                    oHatchGroup.Children.Add(mp_GPoint(4, 0));

                    oHatchGroup.Children.Add(mp_GPoint(5, 1));
                    oHatchGroup.Children.Add(mp_GPoint(6, 2));
                    oHatchGroup.Children.Add(mp_GPoint(7, 3));

                    oHatchGroup.Children.Add(mp_GPoint(7, 5));
                    oHatchGroup.Children.Add(mp_GPoint(6, 6));
                    oHatchGroup.Children.Add(mp_GPoint(5, 7));

                    oHatchGroup.Children.Add(mp_GPoint(3, 7));
                    oHatchGroup.Children.Add(mp_GPoint(2, 6));
                    oHatchGroup.Children.Add(mp_GPoint(1, 5));
                    yType = HatchEnum.HatchType.HT_LINE; break;
                case HatchEnum.HatchStyle.HS_SOLIDDIAMOND:
                    lWidth = 7;
                    lHeight = 7;
                    oHatchGroup.Children.Add(mp_GRect(1, 1, 5, 5));
                    oHatchGroup.Transform = new RotateTransform(45, 3, 3);
                    yType = HatchEnum.HatchType.HT_RECTANGLE; break;
            }

            GeometryDrawing oBackgroundSquare = new GeometryDrawing(new SolidColorBrush(clrBackColor), null, new RectangleGeometry(new Rect(0, 0, lWidth, lHeight)));
            SolidColorBrush oHatchBrush = new SolidColorBrush(clrForeColor);
            Pen oHatchPen = new Pen(oHatchBrush, 1);
            oHatchBrush.Freeze();
            oHatchPen.Freeze();
            SolidColorBrush oHatchCtrlBrush = new SolidColorBrush(Colors.Red);
            Pen oHatchCtrlPen = new Pen(oHatchCtrlBrush, 1);
            oHatchCtrlBrush.Freeze();
            oHatchCtrlPen.Freeze();
            GeometryDrawing oHatch = null;
            GeometryDrawing oHatchCtrl = null;
            switch (yType)
            {
                case HatchEnum.HatchType.HT_RECTANGLE:
                    oHatch = new GeometryDrawing(oHatchBrush, null, oHatchGroup);
                    if (oHatchCtrlGroup.Children.Count > 0)
                    {
                        oHatchCtrl = new GeometryDrawing(oHatchCtrlBrush, null, oHatchCtrlGroup);
                    }
                    break;
                case HatchEnum.HatchType.HT_LINE:
                    oHatch = new GeometryDrawing(null, oHatchPen, oHatchGroup);
                    if (oHatchCtrlGroup.Children.Count > 0)
                    {
                        oHatchCtrl = new GeometryDrawing(null, oHatchCtrlPen, oHatchCtrlGroup);
                    }
                    break;

            }
            DrawingGroup oDrawingGroup = new DrawingGroup();
            if (bAliased)
            {
                oDrawingGroup.SetValue(RenderOptions.EdgeModeProperty, EdgeMode.Aliased);
            }
            if (oHatchCtrl != null)
            {
                oDrawingGroup.Children.Add(oHatchCtrl);
            }
            oDrawingGroup.Children.Add(oBackgroundSquare);
            oDrawingGroup.Children.Add(oHatch);
            oReturnBrush.Drawing = oDrawingGroup;
            oReturnBrush.Stretch = Stretch.None;
            oReturnBrush.ViewportUnits = BrushMappingMode.Absolute;
            oReturnBrush.Viewport = new Rect(0, 0, lWidth, lHeight);
            oReturnBrush.TileMode = TileMode.Tile;
            oReturnBrush.Freeze();
            return oReturnBrush;
        }

        private LineGeometry mp_GLine(int X1, int Y1, int X2, int Y2)
        {
            if (X1 != X2)
            {
                X2 = X2 + 1;
            }
            if (Y1 != Y2)
            {
                Y2 = Y2 + 1;
            }
            LineGeometry oReturn = new LineGeometry(new Point(X1, Y1), new Point(X2, Y2)); ;
            return oReturn;
        }

        private LineGeometry mp_GPoint(int X1, int Y1)
        {
            LineGeometry oReturn = new LineGeometry(new Point(X1, Y1), new Point(X1 + 1, Y1 + 1)); ;
            return oReturn;
        }

        private RectangleGeometry mp_GRect(int X, int Y, int Width, int Height)
        {
            RectangleGeometry oReturn = new RectangleGeometry(new Rect(X, Y, Width, Height)); ;
            return oReturn;
        }

        private void InvertColors(ref Color clrForeColor, ref Color clrBackColor)
        {
            Color clrBuff;
            clrBuff = clrBackColor;
            clrBackColor = clrForeColor;
            clrForeColor = clrBuff;
        }
    }
The HatchType and HatchStyle should look like this:

/// <summary>
        /// Defines hatch type
        /// </summary>
        public enum HatchType
        {
            HT_RECTANGLE ,
        HT_LINE ,
        };

         /// <summary>
        /// Defines hatch style
        /// </summary>
        public enum HatchStyle
        {
             HS_HORIZONTAL ,
        HS_VERTICAL ,
        HS_FORWARDDIAGONAL ,
        HS_BACKWARDDIAGONAL ,
        HS_LARGEGRID ,
        HS_DIAGONALCROSS ,
        HS_PERCENT05 ,
        HS_PERCENT10 ,
        HS_PERCENT20 ,
        HS_PERCENT25,
        HS_PERCENT30 ,
        HS_PERCENT40 ,
        HS_PERCENT50 ,
        HS_PERCENT60 ,
        HS_PERCENT70 ,
        HS_PERCENT75 ,
        HS_PERCENT80 ,
        HS_PERCENT90 ,
        HS_LIGHTDOWNWARDDIAGONAL ,
        HS_LIGHTUPWARDDIAGONAL ,
        HS_DARKDOWNWARDDIAGONAL ,
        HS_DARKUPWARDDIAGONAL ,
        HS_WIDEDOWNWARDDIAGONAL ,
        HS_WIDEUPWARDDIAGONAL ,
        HS_LIGHTVERTICAL ,
        HS_LIGHTHORIZONTAL ,
        HS_NARROWVERTICAL ,
        HS_NARROWHORIZONTAL ,
        HS_DARKVERTICAL ,
        HS_DARKHORIZONTAL ,
        HS_DASHEDDOWNWARDDIAGONAL ,
        HS_DASHEDUPWARDDIAGONAL ,
        HS_DASHEDHORIZONTAL ,
        HS_DASHEDVERTICAL ,
        HS_SMALLCONFETTI ,
        HS_LARGECONFETTI ,
        HS_ZIGZAG ,
        HS_WAVE ,
        HS_DIAGONALBRICK ,
        HS_HORIZONTALBRICK ,
        HS_WEAVE ,
        HS_PLAID ,
        HS_DIVOT ,
        HS_DOTTEDGRID ,
        HS_DOTTEDDIAMOND ,
        HS_SHINGLE ,
        HS_TRELLIS ,
        HS_SPHERE ,
        HS_SMALLGRID ,
        HS_SMALLCHECKERBOARD ,
        HS_LARGECHECKERBOARD ,
        HS_OUTLINEDDIAMOND ,
        HS_SOLIDDIAMOND ,
        };


The Window1 would produce the following output:

Every effort has been made to ensure pixel by pixel accuracy in the WPF hatches, but this was not possible in all cases. In those cases where we could not achieve this, the best possible approximation was used.

1 nhận xét: