Ejemplo n.º 1
0
        public static void GetGlyphShape(Font font, Char c)
        {
            GLYPHMETRICS metrics = new GLYPHMETRICS();
            MAT2 matrix = new MAT2();
            matrix.eM11.value = 1;
            matrix.eM12.value = 0;
            matrix.eM21.value = 0;
            matrix.eM22.value = 1;

            using (Bitmap b = new Bitmap(1, 1))
            {
                using (Graphics g = Graphics.FromImage(b))
                {
                    IntPtr hdc = g.GetHdc();
                    IntPtr prev = SelectObject(hdc, font.ToHfont());
                    int bufferSize = (int)GetGlyphOutline(hdc, (uint)c, (uint)2, out metrics, 0, IntPtr.Zero, ref matrix);
                    IntPtr buffer = Marshal.AllocHGlobal(bufferSize);
                    try
                    {
                        uint ret;
                        if ((ret = GetGlyphOutline(hdc, (uint)c, (uint)2, out metrics, (uint)bufferSize, buffer, ref matrix)) > 0)
                            if ((ret = GetGlyphOutline(hdc, (uint)c, (unit)2, out metrics, (uint)bufferSize, buffer, ref matrix)) > 0)
                            {
                                int polygonHeaderSize = Marshal.SizeOf(typeof(TTPOLYGONHEADER));
                                int curveHeaderSize = Marshal.SizeOf(typeof(TTPOLYCURVEHEADER));
                                int pointFxSize = Marshal.SizeOf(typeof(POINTFX));

                                int index = 0;
                                while (index < bufferSize)
                                {
                                    TTPOLYGONHEADER header = (TTPOLYGONHEADER)Marshal.PtrToStructure(new IntPtr(buffer.ToInt32() + index), typeof(TTPOLYGONHEADER));

                                    int startX = header.pfxStart.x.value;
                                    int startY = -header.pfxStart.y.value;

                                    int endCurvesIndex = index + header.cb;
                                    index += polygonHeaderSize;

                                    while (index < endCurvesIndex)
                                    {
                                        TTPOLYCURVEHEADER curveHeader = (TTPOLYCURVEHEADER)Marshal.PtrToStructure(new IntPtr(buffer.ToInt32() + index), typeof(TTPOLYCURVEHEADER));
                                        index += curveHeaderSize;

                                        POINTFX[] curvePoints = new POINTFX[curveHeader.cpfx];

                                        for (int i = 0; i < curveHeader.cpfx; i++)
                                        {
                                            curvePoints[i] = (POINTFX)Marshal.PtrToStructure(new IntPtr(buffer.ToInt32() + index), typeof(POINTFX));
                                            index += pointFxSize;
                                        }

                                        if (curveHeader.wType == (int)1)
                                        {
                                            // POLYLINE
                                            for (int i = 0; i < curveHeader.cpfx; i++)
                                            {
                                                short x = curvePoints[i].x.value;
                                                short y = (short)-curvePoints[i].y.value;
                                            }
                                        }
                                        else
                                        {
                                            // CURVE
                                            for (int i = 0; i < curveHeader.cpfx - 1; i++)
                                            {
                                                POINTFX pfxB = curvePoints[i];
                                                POINTFX pfxC = curvePoints[i + 1];

                                                short cx = pfxB.x.value;
                                                short cy = (short)-pfxB.y.value;

                                                short ax;
                                                short ay;

                                                if (i < curveHeader.cpfx - 2)
                                                {
                                                    ax = (short)((pfxB.x.value + pfxC.x.value) / 2);
                                                    ay = (short)-((pfxB.y.value + pfxC.y.value) / 2);
                                                }
                                                else
                                                {
                                                    ax = pfxC.x.value;
                                                    ay = (short)-pfxC.y.value;
                                                }

                                            }
                                        }
                                    }
                                }
                            }
                            else
                            {
                                throw new Exception("Could not retrieve glyph (GDI Error: 0x" + ret.ToString("X") + ")");
                            }

                        g.ReleaseHdc(hdc);
                    }
                    finally
                    {
                        Marshal.FreeHGlobal(buffer);
                    }
                }
            }
            return shape;
        }
Ejemplo n.º 2
0
 static extern uint GetGlyphOutline(IntPtr hdc, uint uChar, uint uFormat,
     out GLYPHMETRICS lpgm, uint cbBuffer, IntPtr lpvBuffer, ref MAT2 lpmat2);