internal void UpdateFont(WindowsFont font) { if (this.LastUsedFont != font) { this.LastUsedFont = font; this.LeftTextMargin = -1; this.RightTextMargin = -1; } }
internal static bool IsFontInUse(WindowsFont wf) { if (wf != null) { for (int i = 0; i < activeDeviceContexts.Count; i++) { DeviceContext context = activeDeviceContexts[i] as DeviceContext; if ((context != null) && ((context.ActiveFont == wf) || context.IsFontOnContextStack(wf))) { return true; } } } return false; }
internal static IntNativeMethods.DRAWTEXTPARAMS GetTextMargins(WindowsGraphics wg, WindowsFont font) { CachedInfo cachedMeasurementDCInfo = MeasurementDCInfo.cachedMeasurementDCInfo; if (((cachedMeasurementDCInfo == null) || (cachedMeasurementDCInfo.LeftTextMargin <= 0)) || ((cachedMeasurementDCInfo.RightTextMargin <= 0) || (font != cachedMeasurementDCInfo.LastUsedFont))) { if (cachedMeasurementDCInfo == null) { cachedMeasurementDCInfo = new CachedInfo(); MeasurementDCInfo.cachedMeasurementDCInfo = cachedMeasurementDCInfo; } IntNativeMethods.DRAWTEXTPARAMS textMargins = wg.GetTextMargins(font); cachedMeasurementDCInfo.LeftTextMargin = textMargins.iLeftMargin; cachedMeasurementDCInfo.RightTextMargin = textMargins.iRightMargin; } return new IntNativeMethods.DRAWTEXTPARAMS(cachedMeasurementDCInfo.LeftTextMargin, cachedMeasurementDCInfo.RightTextMargin); }
public void ResetFont() { MeasurementDCInfo.ResetIfIsMeasurementDC(this.Hdc); IntUnsafeNativeMethods.SelectObject(new HandleRef(this, this.Hdc), new HandleRef(null, this.hInitialFont)); this.selectedFont = null; this.hCurrentFont = this.hInitialFont; }
internal void DisposeFont(bool disposing) { if (disposing) { DeviceContexts.RemoveDeviceContext(this); } if ((this.selectedFont != null) && (this.selectedFont.Hfont != IntPtr.Zero)) { if (IntUnsafeNativeMethods.GetCurrentObject(new HandleRef(this, this.hDC), 6) == this.selectedFont.Hfont) { IntUnsafeNativeMethods.SelectObject(new HandleRef(this, this.Hdc), new HandleRef(null, this.hInitialFont)); IntPtr hInitialFont = this.hInitialFont; } this.selectedFont.Dispose(disposing); this.selectedFont = null; } }
/// <summary> /// Returns the Size in logical units of the given text using the given Font and using the specified rectangle /// as the text bounding box (see overload below for more info). /// TAB/CR/LF are taken into account. /// </summary> public Size MeasureText(string text, WindowsFont font, Size proposedSize) => MeasureText(text, font, proposedSize, User32.DT.BOTTOM);
/// <summary> /// Draws the text centered in the given rectangle and using the given Font, foreColor and backColor. /// </summary> public void DrawText(string text, WindowsFont font, Rectangle bounds, Color foreColor, Color backColor) => DrawText(text, font, bounds, foreColor, backColor, User32.DT.CENTER | User32.DT.VCENTER);
/// <summary> /// Draws the text in the given bounds, using the given Font and foreColor, and according to the specified flags. /// </summary> public void DrawText(string text, WindowsFont font, Rectangle bounds, Color color, Interop.User32.TextFormatFlags flags) { DrawText(text, font, bounds, color, Color.Empty, flags); }
/// <summary> /// Draws the text at the specified point, using the given Font, foreColor and backColor. /// CR/LF are honored. /// </summary> public void DrawText(string text, WindowsFont font, Point pt, Color foreColor, Color backColor) { DrawText(text, font, pt, foreColor, backColor, Interop.User32.TextFormatFlags.DT_DEFAULT); }
/// <summary> /// Draws the text in the given bounds, using the given Font, foreColor and backColor, and according to the specified /// TextFormatFlags flags. /// If font is null, the font currently selected in the hdc is used. /// If foreColor and/or backColor are Color.Empty, the hdc current text and/or background color are used. /// </summary> public void DrawText(string text, WindowsFont font, Rectangle bounds, Color foreColor, Color backColor, IntTextFormatFlags flags) { if (string.IsNullOrEmpty(text) || foreColor == Color.Transparent) { return; } Debug.Assert(((uint)flags & GdiUnsupportedFlagMask) == 0, "Some custom flags were left over and are not GDI compliant!"); Debug.Assert((flags & IntTextFormatFlags.CalculateRectangle) == 0, "CalculateRectangle flag is set, text won't be drawn"); HandleRef hdc = new HandleRef(dc, dc.Hdc); // DrawText requires default text alignment. if (dc.TextAlignment != DeviceContextTextAlignment.Default) { dc.SetTextAlignment(DeviceContextTextAlignment.Default); } // color empty means use the one currently selected in the dc. if (!foreColor.IsEmpty && foreColor != dc.TextColor) { dc.SetTextColor(foreColor); } if (font != null) { dc.SelectFont(font); } DeviceContextBackgroundMode newBackGndMode = (backColor.IsEmpty || backColor == Color.Transparent) ? DeviceContextBackgroundMode.Transparent : DeviceContextBackgroundMode.Opaque; if (dc.BackgroundMode != newBackGndMode) { dc.SetBackgroundMode(newBackGndMode); } if (newBackGndMode != DeviceContextBackgroundMode.Transparent && backColor != dc.BackgroundColor) { dc.SetBackgroundColor(backColor); } IntNativeMethods.DRAWTEXTPARAMS dtparams = GetTextMargins(font); bounds = AdjustForVerticalAlignment(hdc, text, bounds, flags, dtparams); // Adjust unbounded rect to avoid overflow since Rectangle ctr does not do param validation. if (bounds.Width == MaxSize.Width) { bounds.Width -= bounds.X; } if (bounds.Height == MaxSize.Height) { bounds.Height -= bounds.Y; } IntNativeMethods.RECT rect = new IntNativeMethods.RECT(bounds); IntUnsafeNativeMethods.DrawTextEx(hdc, text, ref rect, (int)flags, dtparams); // No need to restore previous objects into the dc (see comments on top of the class). }
/// <summary> /// Draws the text centered in the given rectangle and using the given Font, foreColor and backColor. /// </summary> public void DrawText(string text, WindowsFont font, Rectangle bounds, Color foreColor, Color backColor) { DrawText(text, font, bounds, foreColor, backColor, IntTextFormatFlags.HorizontalCenter | IntTextFormatFlags.VerticalCenter); }
/// <summary> /// Draws the text at the specified point, using the given Font, foreColor and backColor. /// CR/LF are honored. /// </summary> public void DrawText(string text, WindowsFont font, Point pt, Color foreColor, Color backColor) { DrawText(text, font, pt, foreColor, backColor, IntTextFormatFlags.Default); }
public void DrawText(string text, WindowsFont font, Point pt, Color foreColor, Color backColor, IntTextFormatFlags flags) { Rectangle bounds = new Rectangle(pt.X, pt.Y, 0x7fffffff, 0x7fffffff); this.DrawText(text, font, bounds, foreColor, backColor, flags); }
public void DrawText(string text, WindowsFont font, Point pt, Color foreColor, IntTextFormatFlags flags) { this.DrawText(text, font, pt, foreColor, Color.Empty, flags); }
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 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); }
/// <summary> /// Returns the Size in logical units of the given text using the given Font. /// CR/LF/TAB are taken into account. /// </summary> public Size MeasureText(string text, WindowsFont font) { return(MeasureText(text, font, MaxSize, IntTextFormatFlags.Default)); }
/// <summary> /// Draws the text at the specified point, using the given Font, foreColor and backColor, and according /// to the specified flags. /// </summary> public void DrawText(string text, WindowsFont font, Point pt, Color foreColor, Color backColor, Interop.User32.TextFormatFlags flags) { Rectangle bounds = new Rectangle(pt.X, pt.Y, int.MaxValue, int.MaxValue); DrawText(text, font, bounds, foreColor, backColor, flags); }
/// <summary> /// Returns the Size in logical units of the given text using the given Font and using the specified rectangle /// as the text bounding box (see overload below for more info). /// TAB/CR/LF are taken into account. /// </summary> public Size MeasureText(string text, WindowsFont font, Size proposedSize) { return(MeasureText(text, font, proposedSize, IntTextFormatFlags.Default)); }
/// <summary> /// Draws the text at the specified point, using the given Font, foreColor and backColor, and according /// to the specified flags. /// </summary> public void DrawText(string text, WindowsFont font, Point pt, Color foreColor, Color backColor, User32.DT flags) => DrawText(text, font, new Rectangle(pt, MaxSize), foreColor, backColor, flags);
/// <summary> /// Returns the Size in logical units of the given text using the given Font, and according to the formatting flags. /// The proposed size is used to create a bounding rectangle as follows: /// - If there are multiple lines of text, DrawText uses the width of the rectangle pointed to by /// the lpRect parameter and extends the base of the rectangle to bound the last line of text. /// - If the largest word is wider than the rectangle, the width is expanded. /// - If the text is less than the width of the rectangle, the width is reduced. /// - If there is only one line of text, DrawText modifies the right side of the rectangle so that /// it bounds the last character in the line. /// If the font is null, the hdc's current font will be used. /// /// Note for vertical fonts (if ever supported): DrawTextEx uses GetTextExtentPoint32 for measuring the text and this /// function has the following limitation (from MSDN): /// - This function assumes that the text is horizontal, that is, that the escapement is always 0. This is true for both /// the horizontal and vertical measurements of the text. The application must convert it explicitly. /// </summary> public Size MeasureText(string text, WindowsFont font, Size proposedSize, IntTextFormatFlags flags) { Debug.Assert(((uint)flags & GdiUnsupportedFlagMask) == 0, "Some custom flags were left over and are not GDI compliant!"); if (string.IsNullOrEmpty(text)) { return(Size.Empty); } // // DrawText returns a rectangle useful for aligning, but not guaranteed to encompass all // pixels (its not a FitBlackBox, if the text is italicized, it will overhang on the right.) // So we need to account for this. // IntNativeMethods.DRAWTEXTPARAMS dtparams = null; #if OPTIMIZED_MEASUREMENTDC // use the cache if we've got it if (MeasurementDCInfo.IsMeasurementDC(DeviceContext)) { dtparams = MeasurementDCInfo.GetTextMargins(this, font); } #endif if (dtparams == null) { dtparams = GetTextMargins(font); } // // If Width / Height are < 0, we need to make them larger or DrawText will return // an unbounded measurement when we actually trying to make it very narrow. // int minWidth = 1 + dtparams.iLeftMargin + dtparams.iRightMargin; if (proposedSize.Width <= minWidth) { proposedSize.Width = minWidth; } if (proposedSize.Height <= 0) { proposedSize.Height = 1; } IntNativeMethods.RECT rect = IntNativeMethods.RECT.FromXYWH(0, 0, proposedSize.Width, proposedSize.Height); HandleRef hdc = new HandleRef(null, dc.Hdc); if (font != null) { dc.SelectFont(font); } // If proposedSize.Height >= MaxSize.Height it is assumed bounds needed. If flags contain SingleLine and // VerticalCenter or Bottom options, DrawTextEx does not bind the rectangle to the actual text height since // it assumes the text is to be vertically aligned; we need to clear the VerticalCenter and Bottom flags to // get the actual text bounds. if (proposedSize.Height >= MaxSize.Height && (flags & IntTextFormatFlags.SingleLine) != 0) { // Clear vertical-alignment flags. flags &= ~(IntTextFormatFlags.Bottom | IntTextFormatFlags.VerticalCenter); } if (proposedSize.Width == MaxSize.Width) { // PERF: No constraining width means no word break. // in this case, we dont care about word wrapping - there should be enough room to fit it all flags &= ~(IntTextFormatFlags.WordBreak); } flags |= IntTextFormatFlags.CalculateRectangle; IntUnsafeNativeMethods.DrawTextEx(hdc, text, ref rect, (int)flags, dtparams); /* No need to restore previous objects into the dc (see comments on top of the class). * * if( hOldFont != IntPtr.Zero ) * { * this.dc.SelectObject(hOldFont); * } */ return(rect.Size); }
/// <summary> /// Draws the text in the given bounds, using the given Font, foreColor and backColor, and according to the specified /// TextFormatFlags flags. /// /// If font is null, the font currently selected in the hdc is used. /// /// If foreColor and/or backColor are Color.Empty, the hdc current text and/or background color are used. /// </summary> public void DrawText(string text, WindowsFont font, Rectangle bounds, Color foreColor, Color backColor, User32.DT flags) { if (string.IsNullOrEmpty(text) || foreColor == Color.Transparent) { return; } Debug.Assert(((uint)flags & GdiUnsupportedFlagMask) == 0, "Some custom flags were left over and are not GDI compliant!"); Debug.Assert((flags & User32.DT.CALCRECT) == 0, "CALCRECT flag is set, text won't be drawn"); HandleRef hdc = new HandleRef(DeviceContext, DeviceContext.Hdc); // DrawText requires default text alignment. if (DeviceContext.TextAlignment != default) { DeviceContext.TextAlignment = default; } // color empty means use the one currently selected in the dc. if (!foreColor.IsEmpty && foreColor != DeviceContext.TextColor) { DeviceContext.TextColor = foreColor; } if (font != null) { DeviceContext.SelectFont(font); } Gdi32.BKMODE newBackGndMode = (backColor.IsEmpty || backColor == Color.Transparent) ? Gdi32.BKMODE.TRANSPARENT : Gdi32.BKMODE.OPAQUE; if (DeviceContext.BackgroundMode != newBackGndMode) { DeviceContext.SetBackgroundMode(newBackGndMode); } if (newBackGndMode != Gdi32.BKMODE.TRANSPARENT && backColor != DeviceContext.BackgroundColor) { DeviceContext.BackgroundColor = backColor; } User32.DRAWTEXTPARAMS dtparams = GetTextMargins(font); bounds = AdjustForVerticalAlignment(hdc, text, bounds, flags, ref dtparams); // Adjust unbounded rect to avoid overflow since Rectangle ctr does not do param validation. if (bounds.Width == MaxSize.Width) { bounds.Width -= bounds.X; } if (bounds.Height == MaxSize.Height) { bounds.Height -= bounds.Y; } var rect = new RECT(bounds); User32.DrawTextExW(hdc, text, text.Length, ref rect, flags, ref dtparams); // No need to restore previous objects into the dc (see comments on top of the class). }
/// Text rendering methods /// <summary> /// Draws the text at the specified point, using the given Font and foreColor. /// CR/LF are honored. /// </summary> public void DrawText(string text, WindowsFont font, Point pt, Color foreColor) => DrawText(text, font, pt, foreColor, Color.Empty, User32.TextFormatFlags.DT_DEFAULT);
/// <summary> /// Draws the text at the specified point, using the given Font, foreColor and backColor. /// CR/LF are honored. /// </summary> public void DrawText(string text, WindowsFont font, Point pt, Color foreColor, Color backColor) => DrawText(text, font, pt, foreColor, backColor, User32.DT.DEFAULT);
/// <summary> /// Returns the Size in logical units of the given text using the given Font. /// CR/LF/TAB are taken into account. /// </summary> public Size MeasureText(string text, WindowsFont font) => MeasureText(text, font, MaxSize, User32.TextFormatFlags.DT_BOTTOM);
public Size MeasureText(string text, WindowsFont font, Size proposedSize, IntTextFormatFlags flags) { if (string.IsNullOrEmpty(text)) { return Size.Empty; } IntNativeMethods.DRAWTEXTPARAMS lpDTParams = null; if (MeasurementDCInfo.IsMeasurementDC(this.DeviceContext)) { lpDTParams = MeasurementDCInfo.GetTextMargins(this, font); } if (lpDTParams == null) { lpDTParams = this.GetTextMargins(font); } int num = (1 + lpDTParams.iLeftMargin) + lpDTParams.iRightMargin; if (proposedSize.Width <= num) { proposedSize.Width = num; } if (proposedSize.Height <= 0) { proposedSize.Height = 1; } IntNativeMethods.RECT lpRect = IntNativeMethods.RECT.FromXYWH(0, 0, proposedSize.Width, proposedSize.Height); HandleRef hDC = new HandleRef(null, this.dc.Hdc); if (font != null) { this.dc.SelectFont(font); } if ((proposedSize.Height >= MaxSize.Height) && ((flags & IntTextFormatFlags.SingleLine) != IntTextFormatFlags.Default)) { flags &= ~(IntTextFormatFlags.Bottom | IntTextFormatFlags.VerticalCenter); } if (proposedSize.Width == MaxSize.Width) { flags &= ~IntTextFormatFlags.WordBreak; } flags |= IntTextFormatFlags.CalculateRectangle; IntUnsafeNativeMethods.DrawTextEx(hDC, text, ref lpRect, (int) flags, lpDTParams); return lpRect.Size; }
/// <summary> /// Returns the Size in logical units of the given text using the given Font and using the specified rectangle /// as the text bounding box (see overload below for more info). /// TAB/CR/LF are taken into account. /// </summary> public Size MeasureText(string text, WindowsFont font, Size proposedSize) => MeasureText(text, font, proposedSize, User32.TextFormatFlags.DT_BOTTOM);
public bool IsFontOnContextStack(WindowsFont wf) { if (this.contextStack != null) { foreach (GraphicsState state in this.contextStack) { if (state.hFont == wf.Hfont) { return true; } } } return false; }
public void DrawText(string text, WindowsFont font, Rectangle bounds, Color foreColor) { this.DrawText(text, font, bounds, foreColor, Color.Empty); }
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 void DrawText(string text, WindowsFont font, Point pt, Color foreColor, Color backColor) { this.DrawText(text, font, pt, foreColor, backColor, IntTextFormatFlags.Default); }
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); }
public void DrawText(string text, WindowsFont font, Rectangle bounds, Color foreColor, Color backColor) { this.DrawText(text, font, bounds, foreColor, backColor, IntTextFormatFlags.VerticalCenter | IntTextFormatFlags.HorizontalCenter); }
public void DrawText(string text, WindowsFont font, Rectangle bounds, Color color, IntTextFormatFlags flags) { this.DrawText(text, font, bounds, color, Color.Empty, flags); }
/// <summary> /// Draws the text at the specified point, using the given Font and foreColor, and according to the /// specified flags. /// </summary> public void DrawText(string text, WindowsFont font, Point pt, Color foreColor, Interop.User32.TextFormatFlags flags) { DrawText(text, font, pt, foreColor, Color.Empty, flags); }
/// <summary> /// Draws the text centered in the given rectangle and using the given Font, foreColor and backColor. /// </summary> public void DrawText(string text, WindowsFont font, Rectangle bounds, Color foreColor, Color backColor) { DrawText(text, font, bounds, foreColor, backColor, Interop.User32.TextFormatFlags.DT_CENTER | Interop.User32.TextFormatFlags.DT_VCENTER); }
public void DrawText(string text, WindowsFont font, Rectangle bounds, Color foreColor, Color backColor, IntTextFormatFlags flags) { if (!string.IsNullOrEmpty(text) && (foreColor != Color.Transparent)) { HandleRef hdc = new HandleRef(this.dc, this.dc.Hdc); if (this.dc.TextAlignment != DeviceContextTextAlignment.Top) { this.dc.SetTextAlignment(DeviceContextTextAlignment.Top); } if (!foreColor.IsEmpty && (foreColor != this.dc.TextColor)) { this.dc.SetTextColor(foreColor); } if (font != null) { this.dc.SelectFont(font); } DeviceContextBackgroundMode newMode = (backColor.IsEmpty || (backColor == Color.Transparent)) ? DeviceContextBackgroundMode.Transparent : DeviceContextBackgroundMode.Opaque; if (this.dc.BackgroundMode != newMode) { this.dc.SetBackgroundMode(newMode); } if ((newMode != DeviceContextBackgroundMode.Transparent) && (backColor != this.dc.BackgroundColor)) { this.dc.SetBackgroundColor(backColor); } IntNativeMethods.DRAWTEXTPARAMS textMargins = this.GetTextMargins(font); bounds = AdjustForVerticalAlignment(hdc, text, bounds, flags, textMargins); if (bounds.Width == MaxSize.Width) { bounds.Width -= bounds.X; } if (bounds.Height == MaxSize.Height) { bounds.Height -= bounds.Y; } IntNativeMethods.RECT lpRect = new IntNativeMethods.RECT(bounds); IntUnsafeNativeMethods.DrawTextEx(hdc, text, ref lpRect, (int) flags, textMargins); } }
/// <summary> /// Returns the Size in logical units of the given text using the given Font and using the specified rectangle /// as the text bounding box (see overload below for more info). /// TAB/CR/LF are taken into account. /// </summary> public Size MeasureText(string text, WindowsFont font, Size proposedSize) { return(MeasureText(text, font, proposedSize, Interop.User32.TextFormatFlags.DT_BOTTOM)); }
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> /// Draws the text centered in the given rectangle and using the given Font and foreColor. /// </summary> public void DrawText(string text, WindowsFont font, Rectangle bounds, Color foreColor) => DrawText(text, font, bounds, foreColor, Color.Empty);
public Size GetTextExtent(string text, WindowsFont font) { if (string.IsNullOrEmpty(text)) { return Size.Empty; } IntNativeMethods.SIZE size = new IntNativeMethods.SIZE(); HandleRef hDC = new HandleRef(null, this.dc.Hdc); if (font != null) { this.dc.SelectFont(font); } IntUnsafeNativeMethods.GetTextExtentPoint32(hDC, text, size); if ((font != null) && !MeasurementDCInfo.IsMeasurementDC(this.dc)) { this.dc.ResetFont(); } return new Size(size.cx, size.cy); }
/// <summary> /// Draws the text in the given bounds, using the given Font and foreColor, and according to the specified flags. /// </summary> public void DrawText(string text, WindowsFont font, Rectangle bounds, Color color, User32.DT flags) => DrawText(text, font, bounds, color, Color.Empty, flags);
public IntNativeMethods.DRAWTEXTPARAMS GetTextMargins(WindowsFont font) { int leftMargin = 0; int rightMargin = 0; float overhangPadding = 0f; switch (this.TextPadding) { case TextPaddingOptions.GlyphOverhangPadding: overhangPadding = this.GetOverhangPadding(font); leftMargin = (int) Math.Ceiling((double) overhangPadding); rightMargin = (int) Math.Ceiling((double) (overhangPadding * 1.5f)); break; case TextPaddingOptions.LeftAndRightPadding: overhangPadding = this.GetOverhangPadding(font); leftMargin = (int) Math.Ceiling((double) (2f * overhangPadding)); rightMargin = (int) Math.Ceiling((double) (overhangPadding * 2.5f)); break; } return new IntNativeMethods.DRAWTEXTPARAMS(leftMargin, rightMargin); }
/// <summary> /// Returns the Size in logical units of the given text using the given Font. /// CR/LF/TAB are taken into account. /// </summary> public Size MeasureText(string text, WindowsFont font) => MeasureText(text, font, MaxSize, User32.DT.BOTTOM);
public Size MeasureText(string text, WindowsFont font) { return this.MeasureText(text, font, MaxSize, IntTextFormatFlags.Default); }
/// <summary> /// Returns the Size in logical units of the given text using the given Font, and according to the formatting flags. /// The proposed size is used to create a bounding rectangle as follows: /// - If there are multiple lines of text, DrawText uses the width of the rectangle pointed to by /// the lpRect parameter and extends the base of the rectangle to bound the last line of text. /// - If the largest word is wider than the rectangle, the width is expanded. /// - If the text is less than the width of the rectangle, the width is reduced. /// - If there is only one line of text, DrawText modifies the right side of the rectangle so that /// it bounds the last character in the line. /// If the font is null, the hdc's current font will be used. /// /// Note for vertical fonts (if ever supported): DrawTextEx uses GetTextExtentPoint32 for measuring the text and this /// function has the following limitation (from MSDN): /// - This function assumes that the text is horizontal, that is, that the escapement is always 0. This is true for both /// the horizontal and vertical measurements of the text. The application must convert it explicitly. /// </summary> public Size MeasureText(string text, WindowsFont font, Size proposedSize, User32.DT flags) { Debug.Assert(((uint)flags & GdiUnsupportedFlagMask) == 0, "Some custom flags were left over and are not GDI compliant!"); if (string.IsNullOrEmpty(text)) { return(Size.Empty); } // DrawText returns a rectangle useful for aligning, but not guaranteed to encompass all // pixels (its not a FitBlackBox, if the text is italicized, it will overhang on the right.) // So we need to account for this. #if OPTIMIZED_MEASUREMENTDC User32.DRAWTEXTPARAMS dtparams; // use the cache if we've got it if (MeasurementDCInfo.IsMeasurementDC(DeviceContext)) { dtparams = MeasurementDCInfo.GetTextMargins(this, font); } else { dtparams = GetTextMargins(font); } #else User32.DRAWTEXTPARAMS dtparams = GetTextMargins(font); #endif // If Width / Height are < 0, we need to make them larger or DrawText will return // an unbounded measurement when we actually trying to make it very narrow. int minWidth = 1 + dtparams.iLeftMargin + dtparams.iRightMargin; if (proposedSize.Width <= minWidth) { proposedSize.Width = minWidth; } if (proposedSize.Height <= 0) { proposedSize.Height = 1; } var rect = new RECT(0, 0, proposedSize.Width, proposedSize.Height); if (font != null) { DeviceContext.SelectFont(font); } // If proposedSize.Height >= MaxSize.Height it is assumed bounds needed. If flags contain SINGLELINE and // VCENTER or BOTTOM options, DrawTextEx does not bind the rectangle to the actual text height since // it assumes the text is to be vertically aligned; we need to clear the VCENTER and BOTTOM flags to // get the actual text bounds. if (proposedSize.Height >= MaxSize.Height && (flags & User32.DT.SINGLELINE) != 0) { // Clear vertical-alignment flags. flags &= ~(User32.DT.BOTTOM | User32.DT.VCENTER); } if (proposedSize.Width == MaxSize.Width) { // PERF: No constraining width means no word break. // in this case, we dont care about word wrapping - there should be enough room to fit it all flags &= ~(User32.DT.WORDBREAK); } flags |= User32.DT.CALCRECT; User32.DrawTextExW(DeviceContext.Hdc, text, text.Length, ref rect, flags, ref dtparams); return(rect.Size); }
public Size MeasureText(string text, WindowsFont font, Size proposedSize) { return this.MeasureText(text, font, proposedSize, IntTextFormatFlags.Default); }
/// <summary> /// Draws the text at the specified point, using the given Font and foreColor, and according to the /// specified flags. /// </summary> public void DrawText(string text, WindowsFont font, Point pt, Color foreColor, User32.DT flags) => DrawText(text, font, pt, foreColor, Color.Empty, flags);
internal static IntNativeMethods.DRAWTEXTPARAMS GetTextMargins(WindowsGraphics wg, WindowsFont font) { CachedInfo cachedMeasurementDCInfo = MeasurementDCInfo.cachedMeasurementDCInfo; if (((cachedMeasurementDCInfo == null) || (cachedMeasurementDCInfo.LeftTextMargin <= 0)) || ((cachedMeasurementDCInfo.RightTextMargin <= 0) || (font != cachedMeasurementDCInfo.LastUsedFont))) { if (cachedMeasurementDCInfo == null) { cachedMeasurementDCInfo = new CachedInfo(); MeasurementDCInfo.cachedMeasurementDCInfo = cachedMeasurementDCInfo; } IntNativeMethods.DRAWTEXTPARAMS textMargins = wg.GetTextMargins(font); cachedMeasurementDCInfo.LeftTextMargin = textMargins.iLeftMargin; cachedMeasurementDCInfo.RightTextMargin = textMargins.iRightMargin; } return(new IntNativeMethods.DRAWTEXTPARAMS(cachedMeasurementDCInfo.LeftTextMargin, cachedMeasurementDCInfo.RightTextMargin)); }