public RectangleValidator( RECT bounds, Color penColor, Color brushColor, int penWidth = 1, Gdi32.PS penStyle = default, Gdi32.R2 rop2 = Gdi32.R2.COPYPEN, Gdi32.BKMODE backgroundMode = Gdi32.BKMODE.TRANSPARENT, Gdi32.BS brushStyle = default, Flags validate = default) { _bounds = bounds; _brushColor = brushColor; _brushStyle = brushStyle; _penWidth = penWidth; _penColor = penColor; _penStyle = penStyle; _rop2 = rop2; _backgroundMode = backgroundMode; if (validate != default) { _validate = validate; return; } // Default values for all of these are valid expectations so we always turn them on. _validate = Flags.Bounds | Flags.PenStyle | Flags.BrushStyle; if (penWidth != 0) { _validate |= Flags.PenWidth; } if (!penColor.IsEmpty) { _validate |= Flags.PenColor; } if (!brushColor.IsEmpty) { _validate |= Flags.BrushColor; } if (backgroundMode != default) { _validate |= Flags.BackgroundMode; } if (_rop2 != default) { _validate |= Flags.RopMode; } }
internal static IEmfValidator TextOut( string text, Gdi32.MM mapMode = Gdi32.MM.TEXT, Gdi32.BKMODE backgroundMode = Gdi32.BKMODE.TRANSPARENT, string?fontFace = null, TextOutValidator.Flags validate = default) => new TextOutValidator( text, textColor: Color.Empty, mapMode, backgroundMode, fontFace, validate);
/// <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 static void DrawText( this Gdi32.HDC hdc, ReadOnlySpan <char> text, FontCache.Scope font, Rectangle bounds, Color foreColor, User32.DT flags, Color backColor = default, TextPaddingOptions padding = default) { if (text.IsEmpty || foreColor == Color.Transparent) { return; } ValidateFlags(flags); // DrawText requires default text alignment. using var alignment = new Gdi32.SetTextAlignmentScope(hdc, default); // Color empty means use the one currently selected in the dc. using var textColor = foreColor.IsEmpty ? default : new Gdi32.SetTextColorScope(hdc, foreColor); using var fontSelection = new Gdi32.SelectObjectScope(hdc, (Gdi32.HFONT)font); Gdi32.BKMODE newBackGroundMode = (backColor.IsEmpty || backColor == Color.Transparent) ? Gdi32.BKMODE.TRANSPARENT : Gdi32.BKMODE.OPAQUE; using var backgroundMode = new Gdi32.SetBkModeScope(hdc, newBackGroundMode); using var backgroundColor = newBackGroundMode != Gdi32.BKMODE.TRANSPARENT ? new Gdi32.SetBackgroundColorScope(hdc, backColor) : default; User32.DRAWTEXTPARAMS dtparams = GetTextMargins(font, padding); 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 == TextRenderer.MaxSize.Width) { bounds.Width -= bounds.X; } if (bounds.Height == TextRenderer.MaxSize.Height) { bounds.Height -= bounds.Y; } RECT rect = bounds; User32.DrawTextExW(hdc, text, ref rect, flags, ref dtparams); }
public TextOutValidator( string text, Color textColor, Rectangle?bounds, Gdi32.MM mapMode = default, Gdi32.BKMODE backgroundMode = default, string?fontFace = null, Flags validate = default) { _text = text; _textColor = textColor; _mapMode = mapMode; _backgroundMode = backgroundMode; _fontFace = fontFace; _bounds = bounds.HasValue ? bounds.Value : default; if (validate != default) { _validate = validate; } else { _validate = Flags.Text; if (bounds.HasValue) { _validate |= Flags.Bounds; } if (!textColor.IsEmpty) { _validate |= Flags.TextColor; } if (mapMode != default) { _validate |= Flags.MapMode; } if (backgroundMode != default) { _validate |= Flags.BackgroundMode; } if (!string.IsNullOrEmpty(fontFace)) { _validate |= Flags.FontFace; } } }
public LineToValidator( Point from, Point to, Color penColor, int penWidth = 1, Gdi32.PS penStyle = default, Gdi32.R2 rop2 = Gdi32.R2.COPYPEN, Gdi32.BKMODE backgroundMode = Gdi32.BKMODE.TRANSPARENT, Flags validate = default) { _from = from; _to = to; _penWidth = penWidth; _penColor = penColor; _penStyle = penStyle; _rop2 = rop2; _backgroundMode = backgroundMode; if (validate != default) { _validate = validate; return; } // Default values for all of these are valid expectations so we always turn them on. _validate = Flags.From | Flags.To | Flags.PenStyle; if (penWidth != 0) { _validate |= Flags.PenWidth; } if (!penColor.IsEmpty) { _validate |= Flags.PenColor; } if (backgroundMode != default) { _validate |= Flags.BackgroundMode; } if (_rop2 != default) { _validate |= Flags.RopMode; } }
internal static IEmfValidator LineTo( EasyPoint from, EasyPoint to, Color penColor, int penWidth = 1, Gdi32.PS penStyle = default, Gdi32.R2 rop2Mode = Gdi32.R2.COPYPEN, Gdi32.BKMODE backgroundMode = Gdi32.BKMODE.TRANSPARENT, LineToValidator.Flags validate = default) => new LineToValidator( from, to, penColor, penWidth, penStyle, rop2Mode, backgroundMode, validate);
internal static IEmfValidator Rectangle( RECT bounds, Color penColor, Color brushColor, int penWidth = 1, Gdi32.PS penStyle = default, Gdi32.R2 rop2 = Gdi32.R2.COPYPEN, Gdi32.BKMODE backgroundMode = Gdi32.BKMODE.TRANSPARENT, Gdi32.BS brushStyle = default, RectangleValidator.Flags validate = default) => new RectangleValidator( bounds, penColor, brushColor, penWidth, penStyle, rop2, backgroundMode, brushStyle, validate);
public unsafe void DrawLine(WindowsPen pen, int x1, int y1, int x2, int y2) { HandleRef hdc = new HandleRef(DeviceContext, DeviceContext.Hdc); Gdi32.R2 rasterOp = DeviceContext.BinaryRasterOperation; Gdi32.BKMODE bckMode = DeviceContext.BackgroundMode; if (rasterOp != Gdi32.R2.COPYPEN) { rasterOp = DeviceContext.SetRasterOperation(Gdi32.R2.COPYPEN); } if (bckMode != Gdi32.BKMODE.TRANSPARENT) { bckMode = DeviceContext.SetBackgroundMode(Gdi32.BKMODE.TRANSPARENT); } if (pen != null) { DeviceContext.SelectObject(pen.HPen, GdiObjectType.Pen); } Point oldPoint = new Point(); IntUnsafeNativeMethods.MoveToEx(hdc, x1, y1, &oldPoint); IntUnsafeNativeMethods.LineTo(hdc, x2, y2); if (bckMode != Gdi32.BKMODE.TRANSPARENT) { DeviceContext.SetBackgroundMode(bckMode); } if (rasterOp != Gdi32.R2.COPYPEN) { DeviceContext.SetRasterOperation(rasterOp); } IntUnsafeNativeMethods.MoveToEx(hdc, oldPoint.X, oldPoint.Y, &oldPoint); }
/// <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). }
public BackgroundModeValidator(Gdi32.BKMODE backgroundMode) => _backgroundMode = backgroundMode;
internal static IStateValidator BackgroundMode(Gdi32.BKMODE backgroundMode) => new BackgroundModeValidator(backgroundMode);