internal void Dispose(bool disposing) { bool deletedHandle = false; if (ownHandle) { if (!ownedByCacheManager || !disposing) { // If we were ever owned by the CacheManger and we're being disposed // we can be sure that we're not in use by any DC's (otherwise Dispose() wouldn't have been called) // skip the check IsFontInUse check in this case. // Also skip the check if disposing == false, because the cache is thread-static // and that means we're being called from the finalizer. if (everOwnedByCacheManager || !disposing || !DeviceContexts.IsFontInUse(this)) { Debug.Assert(hFont != IntPtr.Zero, "Unexpected null hFont."); DbgUtil.AssertFinalization(this, disposing); IntUnsafeNativeMethods.DeleteObject(new HandleRef(this, hFont)); #if TRACK_HFONT Debug.WriteLine(DbgUtil.StackTraceToStr(String.Format("DeleteObject(HFONT[0x{0:x8}]))", (int)this.hFont))); #endif hFont = IntPtr.Zero; ownHandle = false; deletedHandle = true; } } } if (disposing && (deletedHandle || !ownHandle)) { GC.SuppressFinalize(this); } }
/// <summary> /// 创建指定页的图元数据 /// </summary> /// <param name="page">页面对象</param> /// <param name="DrawMargin">是否绘制边距线</param> /// <returns>包含图元数据的字节数组</returns> public byte[] GetMetafile(PrintPage page, bool DrawMargin) { XPageSettings pageSettings = page.PageSettings; System.Drawing.Imaging.Metafile meta = null; using (DeviceContexts dc = DeviceContexts.CreateCompatibleDC(IntPtr.Zero)) { System.IO.MemoryStream stream = new System.IO.MemoryStream(); meta = new System.Drawing.Imaging.Metafile( stream, dc.HDC, new System.Drawing.Rectangle( 0, 0, (int)page.PageSettings.ViewPaperWidth, (int)page.PageSettings.ViewPaperHeight), //System.Drawing.Imaging.MetafileFrameUnit.Document ); PrintUtil.ConvertUnit(myDocument.DocumentGraphicsUnit)); using (System.Drawing.Graphics g2 = System.Drawing.Graphics.FromImage(meta)) { if (intBackColor.A != 0) { g2.Clear(this.intBackColor); } g2.PageUnit = myDocument.DocumentGraphicsUnit; PageFrameDrawer drawer = new PageFrameDrawer(); drawer.DrawMargin = DrawMargin; drawer.BackColor = System.Drawing.Color.Transparent; drawer.BorderColor = this.intBorderColor; drawer.BorderWidth = 1; drawer.LeftMargin = (int)page.ViewLeftMargin; drawer.TopMargin = (int)page.ViewTopMargin; drawer.RightMargin = (int)page.ViewRightMargin; drawer.BottomMargin = (int)page.ViewBottomMargin; drawer.Bounds = new System.Drawing.Rectangle( 0, 0, (int)pageSettings.ViewPaperWidth, (int)pageSettings.ViewPaperHeight); drawer.BackgroundImage = this.PageBackgroundImage; g2.ScaleTransform(this.XZoomRate, this.YZoomRate); drawer.DrawPageFrame(g2, System.Drawing.Rectangle.Empty); DrawPage(page, g2, page.Bounds, true); } meta.Dispose(); dc.Dispose(); return(stream.ToArray()); } }
// // object construction API. Publicly constructable from static methods only. // /// <devdoc> /// Constructor to contruct a DeviceContext object from an window handle. /// </devdoc> private DeviceContext(IntPtr hWnd) { this.hWnd = hWnd; this.dcType = DeviceContextType.Display; DeviceContexts.AddDeviceContext(this); // the hDc will be created on demand. #if TRACK_HDC Debug.WriteLine(DbgUtil.StackTraceToStr(String.Format("DeviceContext( hWnd=0x{0:x8} )", unchecked ((int)hWnd)))); #endif }
/// <devdoc> /// Constructor to contruct a DeviceContext object from an existing Win32 device context handle. /// </devdoc> private DeviceContext(IntPtr hDC, DeviceContextType dcType) { this.hDC = hDC; this.dcType = dcType; CacheInitialState(); DeviceContexts.AddDeviceContext(this); if (dcType == DeviceContextType.Display) { this.hWnd = IntUnsafeNativeMethods.WindowFromDC(new HandleRef(this, this.hDC)); } #if TRACK_HDC Debug.WriteLine(DbgUtil.StackTraceToStr(String.Format("DeviceContext( hDC=0x{0:X8}, Type={1} )", unchecked ((int)hDC), dcType))); #endif }
internal void DisposeFont(bool disposing) { if (disposing) { DeviceContexts.RemoveDeviceContext(this); } if (selectedFont != null && selectedFont.Hfont != IntPtr.Zero) { IntPtr hCurrentFont = IntUnsafeNativeMethods.GetCurrentObject(new HandleRef(this, hDC), IntNativeMethods.OBJ_FONT); if (hCurrentFont == selectedFont.Hfont) { // select initial font back in IntUnsafeNativeMethods.SelectObject(new HandleRef(this, this.Hdc), new HandleRef(null, hInitialFont)); hCurrentFont = hInitialFont; } selectedFont.Dispose(disposing); selectedFont = null; } }
public static WindowsFont GetWindowsFont(Font font, WindowsFontQuality fontQuality) { if (font == null) { return(null); } // First check if font is in the cache. int count = 0; int index = currentIndex; // Search by index of most recently added object. while (count < WindowsFontCache.Count) { if (WindowsFontCache[index].Key.Equals(font)) // don't do shallow comparison, we could miss cloned fonts. { // We got a Font in the cache, let's see if we have a WindowsFont with the same quality as required by the caller. // WARNING: It is not expected that the WindowsFont is disposed externally since it is created by this class. Debug.Assert(WindowsFontCache[index].Value.Hfont != IntPtr.Zero, "Cached WindowsFont was disposed, enable GDI_FINALIZATION_WATCH to track who did it!"); WindowsFont wf = WindowsFontCache[index].Value; if (wf.Quality == fontQuality) { return(wf); } } index--; count++; if (index < 0) { index = CacheSize - 1; } } // Font is not in the cache, let's add it. WindowsFont winFont = WindowsFont.FromFont(font, fontQuality); KeyValuePair <Font, WindowsFont> newEntry = new KeyValuePair <Font, WindowsFont>(font, winFont); currentIndex++; if (currentIndex == CacheSize) { currentIndex = 0; } if (WindowsFontCache.Count == CacheSize) // No more room, update current index. { WindowsFont wfont = null; // Go through the existing fonts in the cache, and see if any // are not in use by a DC. If one isn't, replace that. If // all are in use, new up a new font and do not cache it. bool finished = false; int startIndex = currentIndex; int loopIndex = startIndex + 1; while (!finished) { if (loopIndex >= CacheSize) { loopIndex = 0; } if (loopIndex == startIndex) { finished = true; } wfont = WindowsFontCache[loopIndex].Value; if (!DeviceContexts.IsFontInUse(wfont)) { currentIndex = loopIndex; finished = true; break; } else { loopIndex++; wfont = null; } } if (wfont != null) { WindowsFontCache[currentIndex] = newEntry; winFont.OwnedByCacheManager = true; #if GDI_FONT_CACHE_TRACK Debug.WriteLine("Removing from cache: " + wfont); Debug.WriteLine("Adding to cache: " + winFont); #endif wfont.OwnedByCacheManager = false; wfont.Dispose(); } else { // do not cache font - caller is ALWAYS responsible for // disposing now. If it is owned by the CM, it will not // disposed. winFont.OwnedByCacheManager = false; #if GDI_FONT_CACHE_TRACK Debug.WriteLine("Creating uncached font: " + winFont); #endif } } else { winFont.OwnedByCacheManager = true; WindowsFontCache.Add(newEntry); #if GDI_FONT_CACHE_TRACK Debug.WriteLine("Adding to cache: " + winFont); #endif } return(winFont); }