/// <summary>
 /// The GradientFill function fills rectangle and triangle structures
 /// </summary>
 /// <param name="hdc">Handle to the destination device contex</param>
 /// <param name="pVertex">Array of TRIVERTEX structures that each define a triangle vertex</param>
 /// <param name="nVertex">The number of vertices in pVertex</param>
 /// <param name="pMesh">Array of GRADIENT_TRIANGLE structures in triangle mode</param>
 /// <param name="nMesh">The number of elements in pMesh</param>
 /// <param name="ulMode">Specifies gradient fill mode</param>
 /// <returns>If the function succeeds, the return value is true, false</returns>
 public static bool GradientFill([In] IntPtr hdc, TriVertex[] pVertex, uint nVertex, GradientTriangle[] pMesh,
                                 uint nMesh, GradientFillMode ulMode)
 {
     return Native.GradientFill(hdc, pVertex, nVertex, pMesh, nMesh, ulMode);
 }
 public static extern bool GradientFill([In] IntPtr hdc,
     [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.Struct, SizeParamIndex = 2)] TriVertex[] pVertex,
     uint nVertex, GradientTriangle[] pMesh, uint nMesh, GradientFillMode ulMode);
        private void Create(IRenderLayer layer)
        {
            var zoom = Context.Zoom;
            var colors = layer.Colors.Data;

            int length = colors.Length;

            int size = layer.Points.Size;
            var data = layer.Points.Data;

            if (length != data.Length / size)
            {
                throw new Exception();
            }

            this.points = new TriVertex[length];

            TriVertex vertex;
            Color color;
            PointF p = new PointF((float)data[0], (float)data[1]);

            zoom.WorldToScreen(ref p);

            // Get correction distance
            float dx = (p.X - (int)p.X) * 2.0f;
            float dy = (p.Y - (int)p.Y) * 2.0f;

            // Create vertices.
            for (int i = 0; i < length; i++)
            {
                p.X = (float)data[size * i];
                p.Y = (float)data[size * i + 1];

                zoom.WorldToScreen(ref p);

                color = colors[i];

                vertex = new TriVertex();

                vertex.x = (int)(p.X + dx);
                vertex.y = (int)(p.Y + dy);

                vertex.Red = (ushort)(color.R << 8);
                vertex.Green = (ushort)(color.G << 8);
                vertex.Blue = (ushort)(color.B << 8);
                vertex.Alpha = (ushort)(color.A << 8);

                this.points[i] = vertex;
            }

            var triangles = layer.Indices.Data;

            length = triangles.Length / 3;

            this.elements = new GradientTriangle[length];

            GradientTriangle e;

            // Create triangles.
            for (int i = 0; i < length; i++)
            {
                e = new GradientTriangle();

                e.Vertex1 = (uint)triangles[3 * i];
                e.Vertex2 = (uint)triangles[3 * i + 1];
                e.Vertex3 = (uint)triangles[3 * i + 2];

                this.elements[i] = e;
            }
        }