Пример #1
0
        public static uint SelectFont(GDIContext hdc, System.Drawing.Font font)
        {
            GDI32.SelectObject(hdc, font.ToHfont());

            uint size = GDI32.GetOutlineTextMetrics(hdc, 0, IntPtr.Zero);

            if (size != uint.MaxValue)
            {
                UnmanagedMemory otm = new UnmanagedMemory((int)size);
                uint err = GDI32.GetOutlineTextMetrics(hdc, size, otm.MemoryPointer);
                uint otmEMSquare = (uint)Marshal.ReadInt32(otm, 92);
                otm.Dispose();

                LOGFONT log = new LOGFONT();
                font.ToLogFont(log);
                log.lfHeight = -(int)otmEMSquare;

                font = System.Drawing.Font.FromLogFont(log);
                GDI32.SelectObject(hdc, font.ToHfont());
            }

            return size;
        }
Пример #2
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;
        }
Пример #3
0
        public static bool IsTrueType(GDIContext hdc, System.Drawing.Font font)
        {
            GDI32.SelectObject(hdc, font.ToHfont());

            UnmanagedMemory tmPtr = new UnmanagedMemory(Marshal.SizeOf(typeof(TEXTMETRIC)));
            uint err = GDI32.GetTextMetrics(hdc, tmPtr.MemoryPointer);
            TEXTMETRIC tm = (TEXTMETRIC)Marshal.PtrToStructure(tmPtr.MemoryPointer, typeof(TEXTMETRIC));
            tmPtr.Dispose();

            return (tm.tmPitchAndFamily & 4) != 0;
        }