Skip to content

Commit

Permalink
Allow to skip TextRenderer asserts (#4901)
Browse files Browse the repository at this point in the history
While painting LinkedLabel we modify device context before drawing the
label's text. Because of that we hit the asserts in TextRenderer.GetApplyStateFlags.
Since the DC state is expected, skip the assertions.

Closes #4857
  • Loading branch information
RussKie committed May 13, 2021
1 parent 1b34a2b commit e9e8d8f
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 43 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1506,7 +1506,12 @@ protected override void OnTextAlignChanged(EventArgs e)
font,
clientRectWithPadding,
brushColor,
CreateTextFormatFlags(clientRectWithPadding.Size));
CreateTextFormatFlags(clientRectWithPadding.Size)
#if DEBUG
// Skip the asserts in TextRenderer because the DC has been modified
| TextRenderer.SkipAssertFlag
#endif
);
}

if (Focused && ShowFocusCues && FocusLink == link)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,59 +15,58 @@ namespace System.Windows.Forms
[Flags]
public enum TextFormatFlags
{
Bottom = (int)User32.DT.BOTTOM,
EndEllipsis = (int)User32.DT.END_ELLIPSIS,
ExpandTabs = (int)User32.DT.EXPANDTABS,
ExternalLeading = (int)User32.DT.EXTERNALLEADING,
Default = (int)User32.DT.DEFAULT,
HidePrefix = (int)User32.DT.HIDEPREFIX,
HorizontalCenter = (int)User32.DT.CENTER,
Internal = (int)User32.DT.INTERNAL,
Bottom = (int)User32.DT.BOTTOM,
EndEllipsis = (int)User32.DT.END_ELLIPSIS,
ExpandTabs = (int)User32.DT.EXPANDTABS,
ExternalLeading = (int)User32.DT.EXTERNALLEADING,
Default = (int)User32.DT.DEFAULT,
HidePrefix = (int)User32.DT.HIDEPREFIX,
HorizontalCenter = (int)User32.DT.CENTER,
Internal = (int)User32.DT.INTERNAL,

/// <remarks>
/// This is the default.
/// </remarks>
Left = (int)User32.DT.LEFT,
Left = (int)User32.DT.LEFT,

[Obsolete("ModifyString mutates strings and should be avoided. It will be blocked in a future release.")]
ModifyString = (int)User32.DT.MODIFYSTRING,
NoClipping = (int)User32.DT.NOCLIP,
NoPrefix = (int)User32.DT.NOPREFIX,
NoFullWidthCharacterBreak = (int)User32.DT.NOFULLWIDTHCHARBREAK,
PathEllipsis = (int)User32.DT.PATH_ELLIPSIS,
PrefixOnly = (int)User32.DT.PREFIXONLY,
Right = (int)User32.DT.RIGHT,
RightToLeft = (int)User32.DT.RTLREADING,
SingleLine = (int)User32.DT.SINGLELINE,
TextBoxControl = (int)User32.DT.EDITCONTROL,
ModifyString = (int)User32.DT.MODIFYSTRING,
NoClipping = (int)User32.DT.NOCLIP,
NoPrefix = (int)User32.DT.NOPREFIX,
NoFullWidthCharacterBreak = (int)User32.DT.NOFULLWIDTHCHARBREAK,
PathEllipsis = (int)User32.DT.PATH_ELLIPSIS,
PrefixOnly = (int)User32.DT.PREFIXONLY,
Right = (int)User32.DT.RIGHT,
RightToLeft = (int)User32.DT.RTLREADING,
SingleLine = (int)User32.DT.SINGLELINE,
TextBoxControl = (int)User32.DT.EDITCONTROL,

/// <remarks>
/// This is the default.
/// </remarks>
Top = (int)User32.DT.TOP,
Top = (int)User32.DT.TOP,

VerticalCenter = (int)User32.DT.VCENTER,
WordBreak = (int)User32.DT.WORDBREAK,
WordEllipsis = (int)User32.DT.WORD_ELLIPSIS,
VerticalCenter = (int)User32.DT.VCENTER,
WordBreak = (int)User32.DT.WORDBREAK,
WordEllipsis = (int)User32.DT.WORD_ELLIPSIS,

/// <summary>
/// The following flags are exclusive of TextRenderer (no Windows native flags)
/// and apply to methods receiving a Graphics as the IDeviceContext object, and
/// specify whether to reapply clipping and coordintate transformations to the hdc
/// obtained from the Graphics object, which returns a clean hdc.
/// </summary>
PreserveGraphicsClipping = 0x01000000,
PreserveGraphicsTranslateTransform = 0x02000000,
///
/// These get stripped off by TextExtensions before we call DrawText or MeasureText
/// (see: GdiUnsupportedFlagMask).

PreserveGraphicsClipping = 0x0100_0000,
PreserveGraphicsTranslateTransform = 0x0200_0000,

/// <summary>
/// Adds padding related to the drawing binding box, computed according to the font size.
/// Match the System.Internal.GDI.TextPaddingOptions.
/// </summary>
/// <remarks>
/// This is the default.
/// </remarks>
GlyphOverhangPadding = 0x00000000,
NoPadding = 0x10000000,
LeftAndRightPadding = 0x20000000
GlyphOverhangPadding = 0x0000_0000,
NoPadding = 0x1000_0000,
LeftAndRightPadding = 0x2000_0000
}
}
30 changes: 21 additions & 9 deletions src/System.Windows.Forms/src/System/Windows/Forms/TextRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,13 @@ namespace System.Windows.Forms
/// </summary>
public static class TextRenderer
{
#if DEBUG
// In various cases the DC may have already been modified, and we don't pass TextFormatFlags.PreserveGraphicsClipping
// or TextFormatFlags.PreserveGraphicsTranslateTransform flags, that set off the asserts in GetApplyStateFlags
// method. This flags allows us to skip those assert for the cases we know we don't need these flags.
internal static TextFormatFlags SkipAssertFlag = (TextFormatFlags)0x4000_0000;
#endif

internal static Gdi32.QUALITY DefaultQuality { get; } = GetDefaultFontQuality();

internal static Size MaxSize { get; } = new Size(int.MaxValue, int.MaxValue);
Expand Down Expand Up @@ -620,15 +627,20 @@ private static ApplyGraphicsProperties GetApplyStateFlags(IDeviceContext deviceC
apply |= ApplyGraphicsProperties.TranslateTransform;
}

Debug.Assert(apply.HasFlag(ApplyGraphicsProperties.Clipping)
|| graphics.Clip is null
|| graphics.Clip.GetHrgn(graphics) == IntPtr.Zero,
"Must preserve Graphics clipping region!");

Debug.Assert(apply.HasFlag(ApplyGraphicsProperties.TranslateTransform)
|| graphics.Transform is null
|| graphics.Transform.IsIdentity,
"Must preserve Graphics transformation!");
#if DEBUG
if ((textFormatFlags & SkipAssertFlag) == 0)
{
Debug.Assert(apply.HasFlag(ApplyGraphicsProperties.Clipping)
|| graphics.Clip is null
|| graphics.Clip.GetHrgn(graphics) == IntPtr.Zero,
"Must preserve Graphics clipping region!");

Debug.Assert(apply.HasFlag(ApplyGraphicsProperties.TranslateTransform)
|| graphics.Transform is null
|| graphics.Transform.IsIdentity,
"Must preserve Graphics transformation!");
}
#endif

return apply;
}
Expand Down

0 comments on commit e9e8d8f

Please sign in to comment.