Exemplo n.º 1
0
        /// <summary>
        /// Create the font image using GDI+ functionality.
        /// </summary>
        void CreateGdiFontImage(XFont font, XPdfFontOptions options, XPrivateFontCollection privateFontCollection)
        {
            System.Drawing.Font   gdiFont = font.RealizeGdiFont();
            NativeMethods.LOGFONT logFont;
#if DEBUG_
            logFont = new NativeMethods.LOGFONT();
            gdiFont.ToLogFont(logFont);
            Debug.WriteLine("FontData: " + logFont.lfFaceName);
#endif
            this.data = null;
            if (privateFontCollection != null)
            {
                //XPrivateFont privateFont = privateFontCollection.FindFont(logFont.lfFaceName, logFont.lfWeight >= 700, logFont.lfItalic > 0);
                XPrivateFont privateFont = privateFontCollection.FindFont(font.Name, font.Bold, font.Italic);
                if (privateFont != null)
                {
                    int size = privateFont.GetFontData(ref this.data, 0);
                    if (size > 0)
                    {
                        this.data = new byte[size];
                        privateFont.GetFontData(ref this.data, size);
                    }
                }
            }
            if (this.data == null)
            {
                int    error;
                IntPtr hfont = gdiFont.ToHfont();
                IntPtr hdc   = NativeMethods.GetDC(IntPtr.Zero);
                error = Marshal.GetLastWin32Error();
                IntPtr oldFont = NativeMethods.SelectObject(hdc, hfont);
                error = Marshal.GetLastWin32Error();
                // size is exactly the size of the font file.
                int size = NativeMethods.GetFontData(hdc, 0, 0, null, 0);
                error = Marshal.GetLastWin32Error();
                if (size > 0)
                {
                    this.data = new byte[size];
                    int effectiveSize = NativeMethods.GetFontData(hdc, 0, 0, this.data, this.data.Length);
                    Debug.Assert(size == effectiveSize);
                    NativeMethods.SelectObject(hdc, oldFont);
                    NativeMethods.ReleaseDC(IntPtr.Zero, hdc);
                    error.GetType();
                }
                else
                {
                    // Sometimes size is -1 (GDI_ERROR), but I cannot determine why. It happens only with the font 'Symbol'.
                    // The issue occurs the first time in early 2005, when I start writing PDFsharp. I could not fix it and after
                    // some code refactoring the problem disappears.
                    // There was never a report from anyone about this issue.
                    // Now I get it again (while debugging QBX 2006). Maybe it is a problem with my PC at my home office.
                    // As a work-around I create a new font handle with a different height value. This works. Maybe the
                    // font file gets locked somewhere. Very very strange.

                    // IF SOMEONE ELSE COMES HERE PLEASE LET ME KNOW!

                    // Clean up old handles
                    NativeMethods.SelectObject(hdc, oldFont);
                    NativeMethods.ReleaseDC(IntPtr.Zero, hdc);

                    // Try again with new font handle
                    logFont = new NativeMethods.LOGFONT();
                    gdiFont.ToLogFont(logFont);
                    logFont.lfHeight += 1; // force new handle
                    IntPtr hfont2 = NativeMethods.CreateFontIndirect(logFont);
                    hdc     = NativeMethods.GetDC(IntPtr.Zero);
                    error   = Marshal.GetLastWin32Error();
                    oldFont = NativeMethods.SelectObject(hdc, hfont2);
                    error   = Marshal.GetLastWin32Error();
                    // size is exactly the size of the font file.
                    size  = NativeMethods.GetFontData(hdc, 0, 0, null, 0);
                    error = Marshal.GetLastWin32Error();
                    if (size > 0)
                    {
                        this.data = new byte[size];
                        int effectiveSize = NativeMethods.GetFontData(hdc, 0, 0, this.data, this.data.Length);
                        Debug.Assert(size == effectiveSize);
                    }
                    NativeMethods.SelectObject(hdc, oldFont);
                    NativeMethods.ReleaseDC(IntPtr.Zero, hdc);
                    NativeMethods.DeleteObject(hfont2);
                    error.GetType();
                }
            }
            if (this.data == null)
            {
                throw new InvalidOperationException("Internal error. Font data could not retrieved.");
            }
        }