public IntPtr SelectFont(WindowsFont font) { if (font.Equals(this.Font)) { return(IntPtr.Zero); } IntPtr ptr = this.SelectObject(font.Hfont, GdiObjectType.Font); WindowsFont selectedFont = this.selectedFont; this.selectedFont = font; this.hCurrentFont = font.Hfont; if ((selectedFont != null) && MeasurementDCInfo.IsMeasurementDC(this)) { selectedFont.Dispose(); } if (MeasurementDCInfo.IsMeasurementDC(this)) { if (ptr != IntPtr.Zero) { MeasurementDCInfo.LastUsedFont = font; return(ptr); } MeasurementDCInfo.Reset(); } return(ptr); }
public void RestoreHdc() { IntUnsafeNativeMethods.RestoreDC(new HandleRef(this, this.hDC), -1); if (this.contextStack != null) { GraphicsState state = (GraphicsState)this.contextStack.Pop(); this.hCurrentBmp = state.hBitmap; this.hCurrentBrush = state.hBrush; this.hCurrentPen = state.hPen; this.hCurrentFont = state.hFont; if ((state.font != null) && state.font.IsAlive) { this.selectedFont = state.font.Target as WindowsFont; } else { WindowsFont selectedFont = this.selectedFont; this.selectedFont = null; if ((selectedFont != null) && MeasurementDCInfo.IsMeasurementDC(this)) { selectedFont.Dispose(); } } } MeasurementDCInfo.ResetIfIsMeasurementDC(this.hDC); }
public float GetOverhangPadding(WindowsFont font) { WindowsFont font2 = font; if (font2 == null) { font2 = this.dc.Font; } float num = ((float)font2.Height) / 6f; if (font2 != font) { font2.Dispose(); } return(num); }
/// <summary> /// Selects the specified object into the dc. If the specified object is the same as the one currently selected /// in the dc, the object is not set and a null value is returned. /// </summary> public IntPtr SelectFont(WindowsFont font) { // Fonts are one of the most expensive objects to select in an hdc and in many cases we are passed a Font that is the // same as the one already selected in the dc so to avoid a perf hit we get the hdc font's log font and compare it // with the one passed in before selecting it in the hdc. // Also, we avoid performing GDI operations that if done on an enhanced metafile DC would add an entry to it, hence // reducing the size of the metafile. if (font.Equals(Font)) { return(IntPtr.Zero); } IntPtr result = SelectObject(font.Hfont, GdiObjectType.Font); WindowsFont previousFont = selectedFont; selectedFont = font; hCurrentFont = font.Hfont; // the measurement DC always leaves fonts selected for pref reasons. // in this case, we need to diposse the font since the original // creator didn't fully dispose. if (previousFont != null) { if (MeasurementDCInfo.IsMeasurementDC(this)) { previousFont.Dispose(); } } #if OPTIMIZED_MEASUREMENTDC // once we've changed the font, update the last used font. if (MeasurementDCInfo.IsMeasurementDC(this)) { if (result != IntPtr.Zero) { MeasurementDCInfo.LastUsedFont = font; } else { // there was an error selecting the Font into the DC, we dont know anything about it. MeasurementDCInfo.Reset(); } } #endif return(result); }
/// <summary> /// Restores the device context to the specified state. The DC is restored by popping state information off a /// stack created by earlier calls to the SaveHdc function. /// The stack can contain the state information for several instances of the DC. If the state specified by the /// specified parameter is not at the top of the stack, RestoreDC deletes all state information between the top /// of the stack and the specified instance. /// Specifies the saved state to be restored. If this parameter is positive, nSavedDC represents a specific /// instance of the state to be restored. If this parameter is negative, nSavedDC represents an instance relative /// to the current state. For example, -1 restores the most recently saved state. /// See MSDN for more info. /// </summary> public void RestoreHdc() { #if TRACK_HDC bool result = #endif // Note: Don't use the Hdc property here, it would force handle creation. Gdi32.RestoreDC(new HandleRef(this, _hDC), -1); #if TRACK_HDC // Note: Winforms may call this method during app exit at which point the DC may have been finalized already causing this assert to popup. Debug.WriteLine(DbgUtil.StackTraceToStr(String.Format("ret[0]=DC.RestoreHdc(hDc=0x{1:x8})", result, unchecked ((int)this.hDC)))); #endif Debug.Assert(_contextStack != null, "Someone is calling RestoreHdc() before SaveHdc()"); if (_contextStack != null) { GraphicsState g = (GraphicsState)_contextStack.Pop(); _hCurrentBmp = g.hBitmap; _hCurrentBrush = g.hBrush; _hCurrentPen = g.hPen; _hCurrentFont = g.hFont; if (g.font != null && g.font.IsAlive) { ActiveFont = g.font.Target as WindowsFont; } else { WindowsFont previousFont = ActiveFont; ActiveFont = null; if (previousFont != null && MeasurementDCInfo.IsMeasurementDC(this)) { previousFont.Dispose(); } } } #if OPTIMIZED_MEASUREMENTDC // in this case, GDI will copy back the previously saved font into the DC. // we dont actually know what the font is in our measurement DC so // we need to clear it off. MeasurementDCInfo.ResetIfIsMeasurementDC(_hDC); #endif }
/// <summary> /// Calculates the spacing required for drawing text w/o clipping parts of a glyph. /// </summary> public float GetOverhangPadding(WindowsFont font) { // Some parts of a glyphs may be clipped depending on the font & font style, GDI+ adds 1/6 of tmHeight // to each size of the text bounding box when drawing text to account for that; we do it here as well. WindowsFont tmpfont = font; if (tmpfont == null) { tmpfont = DeviceContext.Font; } float overhangPadding = tmpfont.Height / 6f; if (tmpfont != font) { tmpfont.Dispose(); } return(overhangPadding); }
internal void DisposeFont(bool disposing) { if (disposing) { DeviceContexts.RemoveDeviceContext(this); } if (selectedFont != null && selectedFont.Hfont != IntPtr.Zero) { IntPtr hCurrentFont = Interop.Gdi32.GetCurrentObject(new HandleRef(this, hDC), Interop.Gdi32.ObjectType.OBJ_FONT); if (hCurrentFont == selectedFont.Hfont) { // select initial font back in Interop.Gdi32.SelectObject(new HandleRef(this, Hdc), hInitialFont); hCurrentFont = hInitialFont; } selectedFont.Dispose(disposing); selectedFont = null; } }
public static WindowsFont GetWindowsFont(Font font, Interop.Gdi32.QUALITY 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); }
public static WindowsFont GetWindowsFont(Font font, WindowsFontQuality fontQuality) { if (font == null) { return(null); } int num = 0; int currentIndex = WindowsGraphicsCacheManager.currentIndex; while (num < WindowsFontCache.Count) { KeyValuePair <Font, WindowsFont> pair2 = WindowsFontCache[currentIndex]; if (pair2.Key.Equals(font)) { KeyValuePair <Font, WindowsFont> pair3 = WindowsFontCache[currentIndex]; WindowsFont font2 = pair3.Value; if (font2.Quality == fontQuality) { return(font2); } } currentIndex--; num++; if (currentIndex < 0) { currentIndex = 9; } } WindowsFont font3 = WindowsFont.FromFont(font, fontQuality); KeyValuePair <Font, WindowsFont> item = new KeyValuePair <Font, WindowsFont>(font, font3); WindowsGraphicsCacheManager.currentIndex++; if (WindowsGraphicsCacheManager.currentIndex == 10) { WindowsGraphicsCacheManager.currentIndex = 0; } if (WindowsFontCache.Count != 10) { font3.OwnedByCacheManager = true; WindowsFontCache.Add(item); return(font3); } WindowsFont wf = null; bool flag = false; int num3 = WindowsGraphicsCacheManager.currentIndex; int num4 = num3 + 1; while (!flag) { if (num4 >= 10) { num4 = 0; } if (num4 == num3) { flag = true; } KeyValuePair <Font, WindowsFont> pair4 = WindowsFontCache[num4]; wf = pair4.Value; if (!DeviceContexts.IsFontInUse(wf)) { WindowsGraphicsCacheManager.currentIndex = num4; flag = true; break; } num4++; wf = null; } if (wf != null) { WindowsFontCache[WindowsGraphicsCacheManager.currentIndex] = item; font3.OwnedByCacheManager = true; wf.OwnedByCacheManager = false; wf.Dispose(); return(font3); } font3.OwnedByCacheManager = false; return(font3); }
public IntPtr SelectFont(WindowsFont font) { if (font.Equals(this.Font)) { return IntPtr.Zero; } IntPtr ptr = this.SelectObject(font.Hfont, GdiObjectType.Font); WindowsFont selectedFont = this.selectedFont; this.selectedFont = font; this.hCurrentFont = font.Hfont; if ((selectedFont != null) && MeasurementDCInfo.IsMeasurementDC(this)) { selectedFont.Dispose(); } if (MeasurementDCInfo.IsMeasurementDC(this)) { if (ptr != IntPtr.Zero) { MeasurementDCInfo.LastUsedFont = font; return ptr; } MeasurementDCInfo.Reset(); } return ptr; }
public void RestoreHdc() { IntUnsafeNativeMethods.RestoreDC(new HandleRef(this, this.hDC), -1); if (this.contextStack != null) { GraphicsState state = (GraphicsState) this.contextStack.Pop(); this.hCurrentBmp = state.hBitmap; this.hCurrentBrush = state.hBrush; this.hCurrentPen = state.hPen; this.hCurrentFont = state.hFont; if ((state.font != null) && state.font.IsAlive) { this.selectedFont = state.font.Target as WindowsFont; } else { WindowsFont selectedFont = this.selectedFont; this.selectedFont = null; if ((selectedFont != null) && MeasurementDCInfo.IsMeasurementDC(this)) { selectedFont.Dispose(); } } } MeasurementDCInfo.ResetIfIsMeasurementDC(this.hDC); }