예제 #1
0
        public static ushort GetOutline(UnmanagedPointer ipHeader, int size, out float2[] pnts, out sbyte[] onCurve)
        {
            ushort cTotal = 0;
            UnmanagedPointer endPtr = ipHeader + size;
            UnmanagedPointer ipCurve;

            int MaxPts = size / Marshal.SizeOf(typeof(POINTFX));

            TTPOLYGONHEADER Header;
            TTPOLYCURVE Curve;
            POINTFX pntfx = new POINTFX();

            pnts = new float2[MaxPts];
            onCurve = new sbyte[MaxPts];

            while (ipHeader < endPtr && pnts != null)
            {
                Header = (TTPOLYGONHEADER)Marshal.PtrToStructure(ipHeader, typeof(TTPOLYGONHEADER));

                if (Header.dwType == GDI32.TT_POLYGON_TYPE)
                {
                    pnts[cTotal].x = Header.pfxStart.x.ToSingle();
                    pnts[cTotal].y = Header.pfxStart.y.ToSingle();
                    onCurve[cTotal++] = -1; // new contour

                    ipCurve = ipHeader + Marshal.SizeOf(typeof(TTPOLYGONHEADER));

                    while (ipCurve < ipHeader + Header.cb)
                    {
                        Curve = (TTPOLYCURVE)Marshal.PtrToStructure(ipCurve, typeof(TTPOLYCURVE));
                        ipCurve = ipCurve + Marshal.SizeOf(typeof(TTPOLYCURVE));

                        for (int i = 0; i < Curve.cpfx; i++)
                        {
                            pntfx = (POINTFX)Marshal.PtrToStructure(ipCurve, typeof(POINTFX));

                            pnts[cTotal].x = pntfx.x.ToSingle();
                            pnts[cTotal].y = pntfx.y.ToSingle();

                            onCurve[cTotal++] = (sbyte)((i == Curve.cpfx - 1) ? 1 : (Curve.wType == GDI32.TT_PRIM_LINE) ? 1 : 0);

                            ipCurve = ipCurve + Marshal.SizeOf(typeof(POINTFX));
                        }
                    }
                    // check to see if first contour point is repeated and remove it
                    if (Header.pfxStart == pntfx)
                        cTotal--;
                }

                ipHeader = ipHeader + Header.cb;
            }

            return cTotal;
        }
예제 #2
0
        public static GDIRegion CreateFromRectangles(RectangleI[] rects, Guid uniqueID)
        {
            // 1.  Create a header
            RGNDATAHEADER header = new RGNDATAHEADER();
            header.dwSize = Marshal.SizeOf(header);
            header.iType = 1;
            header.nCount = (uint)rects.Length;
            header.nRgnSize = (uint)Marshal.SizeOf(typeof(RECT)) * header.nCount;
            //header.rcBound = 

            // 2. Allocate memory to hold the header plus the data for the rectangles
            int dataLengthNeeded = (int)(header.dwSize + header.nRgnSize);
            IntPtr memoryPtr = Marshal.AllocCoTaskMem((int)dataLengthNeeded);
            UnmanagedPointer structPtr = new UnmanagedPointer(memoryPtr);

            // 4. Copy the Header into the memory buffer
            Marshal.StructureToPtr(header, structPtr, false);

            // 5. Increment the memory buffer pointer to write the rectangles
            structPtr = structPtr + header.dwSize;

            // The nRgnSize / nCount will tell us how many bytes per rectangle structure
            // and therefore how much to advance the pointer as we turn the buffer
            // into a set of rectangles using PtrToStructure.
            int structIncrement = (int)(header.nRgnSize / header.nCount);

            // 6. Write the rectangles
            for (int i = 0; i < header.nCount; i++)
            {
                RECT aRect = new RECT(rects[i].Left, rects[i].Top, rects[i].Width, rects[i].Height);
                Marshal.StructureToPtr(aRect, structPtr, false);

                // Increment the structure pointer to the next position
                structPtr = structPtr + structIncrement;
            }

            // 7. Create the region
            IntPtr regionHandle = GDI32.ExtCreateRegion(IntPtr.Zero, (uint)rects.Length, memoryPtr);
            GDIRegion newRegion = new GDIRegion(regionHandle, true, uniqueID);

            // 8. Free the memory
            Marshal.FreeCoTaskMem(memoryPtr);
        
            return newRegion;
        }
예제 #3
0
        public RectangleI[] GetRectangles()
        {

            // If the region is empty, return a single empty rectangle
            if (IsEmpty)
            {
                return new RectangleI[1];
            }

            // 1. Call GetRgnData with null to get size
            uint dataLengthNeeded = GDI32.GetRegionData(DangerousGetHandle(), 0, IntPtr.Zero);

            // 2. allocate some memory to hold the data
            UnmanagedMemory uMem = new UnmanagedMemory((int)dataLengthNeeded);
            IntPtr memoryPtr = uMem.MemoryPointer;
            UnmanagedPointer structPtr = new UnmanagedPointer(memoryPtr);

            // 3. call again passing in memory
            uint bytesFilled = GDI32.GetRegionData(DangerousGetHandle(), dataLengthNeeded, structPtr);
            
            // If the return value is 0, then the call failed.
            if (0 == bytesFilled)
                return null;

            // 4. convert memory to data structures
            // First get the RGNDATAHEADER
            RGNDATAHEADER dataHeader;
            dataHeader = (RGNDATAHEADER)Marshal.PtrToStructure(structPtr, typeof(RGNDATAHEADER));

            // dataHeader.dwSize    - tells us how big the header is, and thus how many bytes to skip to get
            //                          to the rectangle information
            // dataHeader.nRgnSize  - tells us how many bytes are needed for the rectangle information
            // dataHeader.nCount    - tells us how many rectangles there are


            structPtr = structPtr + dataHeader.dwSize;

            // The nRgnSize / nCount will tell us how many bytes per rectangle structure
            // and therefore how much to advance the pointer as we turn the buffer
            // into a set of rectangles using PtrToStructure.
            int structIncrement = (int)(dataHeader.nRgnSize / dataHeader.nCount);

            // Create a list to add the rectangles to.  This is simply convenient.
            RectangleI[] rects = new RectangleI[dataHeader.nCount];

            // Loop through creating as many rectangles as indicated by the dataheader nCount field
            for (int i = 0; i < dataHeader.nCount; i++)
            {
                RECT rect = (RECT)Marshal.PtrToStructure(structPtr, typeof(RECT));
                rects[i].x1 = rect.X;
                rects[i].y1 = rect.Y;
                rects[i].x2 = rect.X + rect.Width;
                rects[i].y2 = rect.Y + rect.Height;
                rects[i].Normalize();

                structPtr = structPtr + structIncrement;
            }


            // 5. free memory
            uMem.Dispose();

            return rects;
        }
예제 #4
0
        public UnmanagedMemory(int size)
        {
            this.fSize = size;
            fMemoryPtr = new UnmanagedPointer(Marshal.AllocCoTaskMem((int)size));

        }