/// <summary> /// Pixel accurate measure of the specified string when drawn with the specified Font object. /// </summary> /// <param name="g">Graphics instance used to measure text.</param> /// <param name="rtl">Right to left setting for control.</param> /// <param name="text">String to measure.</param> /// <param name="font">Font object that defines the text format of the string.</param> /// <param name="trim">How to trim excess text.</param> /// <param name="align">How to align multi-line text.</param> /// <param name="prefix">How to process prefix characters.</param> /// <param name="hint">Rendering hint.</param> /// <param name="composition">Should draw on a composition element.</param> /// <param name="glowing">When on composition draw with glowing.</param> /// <param name="disposeFont">Dispose of font when finished with it.</param> /// <exception cref="ArgumentNullException"></exception> /// <returns>A memento used to draw the text.</returns> public static AccurateTextMemento MeasureString(Graphics g, RightToLeft rtl, string text, Font font, PaletteTextTrim trim, PaletteRelativeAlign align, PaletteTextHotkeyPrefix prefix, TextRenderingHint hint, bool composition, bool glowing, bool disposeFont) { Debug.Assert(g != null); Debug.Assert(text != null); Debug.Assert(font != null); if (g == null) { throw new ArgumentNullException(nameof(g)); } if (text == null) { throw new ArgumentNullException(nameof(text)); } if (font == null) { throw new ArgumentNullException(nameof(font)); } // An empty string cannot be drawn, so uses the empty memento if (text.Length == 0) { return(AccurateTextMemento.Empty); } // Create the format object used when measuring and drawing StringFormat format = new StringFormat { FormatFlags = StringFormatFlags.NoClip }; // Ensure that text reflects reversed RTL setting if (rtl == RightToLeft.Yes) { format.FormatFlags |= StringFormatFlags.DirectionRightToLeft; } // How do we position text horizontally? switch (align) { case PaletteRelativeAlign.Near: format.Alignment = (rtl == RightToLeft.Yes) ? StringAlignment.Far : StringAlignment.Near; break; case PaletteRelativeAlign.Center: format.Alignment = StringAlignment.Center; break; case PaletteRelativeAlign.Far: format.Alignment = (rtl == RightToLeft.Yes) ? StringAlignment.Near : StringAlignment.Far; break; default: // Should never happen! Debug.Assert(false); break; } // Do we need to trim text that is too big? switch (trim) { case PaletteTextTrim.Character: format.Trimming = StringTrimming.Character; break; case PaletteTextTrim.EllipsisCharacter: format.Trimming = StringTrimming.EllipsisCharacter; break; case PaletteTextTrim.EllipsisPath: format.Trimming = StringTrimming.EllipsisPath; break; case PaletteTextTrim.EllipsisWord: format.Trimming = StringTrimming.EllipsisWord; break; case PaletteTextTrim.Word: format.Trimming = StringTrimming.Word; break; case PaletteTextTrim.Hide: format.Trimming = StringTrimming.None; break; default: // Should never happen! Debug.Assert(false); break; } // Setup the correct prefix processing switch (prefix) { case PaletteTextHotkeyPrefix.None: format.HotkeyPrefix = HotkeyPrefix.None; break; case PaletteTextHotkeyPrefix.Hide: format.HotkeyPrefix = HotkeyPrefix.Hide; break; case PaletteTextHotkeyPrefix.Show: format.HotkeyPrefix = HotkeyPrefix.Show; break; default: // Should never happen! Debug.Assert(false); break; } // Replace tab characters with a fixed four spaces text = text.Replace("\t", " "); // Perform actual measure of the text using (GraphicsTextHint graphicsHint = new GraphicsTextHint(g, hint)) { SizeF textSize = Size.Empty; try { textSize = g.MeasureString(text, font, int.MaxValue, format); if (composition && glowing) //Seb { textSize.Width += GLOW_EXTRA_WIDTH; } } catch { // ignored } // Return a memento with drawing details return(new AccurateTextMemento(text, font, textSize, format, hint, disposeFont)); } }
/// <summary> /// Perform draw of content using provided memento. /// </summary> /// <param name="context">Render context.</param> /// <param name="displayRect">Display area available for drawing.</param> /// <param name="palette">Content palette details.</param> /// <param name="memento">Cached values from layout call.</param> /// <param name="orientation">Visual orientation of the content.</param> /// <param name="state">State associated with rendering.</param> /// <param name="composition">Drawing onto a composition element.</param> /// <param name="glowing">If composition should glowing be drawn.</param> /// <param name="allowFocusRect">Allow drawing of focus rectangle.</param> public override void DrawContent(RenderContext context, Rectangle displayRect, IPaletteContent palette, IDisposable memento, VisualOrientation orientation, PaletteState state, bool composition, bool glowing, bool allowFocusRect) { Debug.Assert(context != null); Debug.Assert(memento != null); Debug.Assert(memento is StandardContentMemento); // Validate parameter references if (context == null) throw new ArgumentNullException("context"); if (palette == null) throw new ArgumentNullException("palette"); Debug.Assert(context.Control != null); Debug.Assert(!context.Control.IsDisposed); // Cast the incoming memento to the correct type StandardContentMemento standard = (StandardContentMemento)memento; if (standard.DrawImage) { DrawImageHelper(context, standard.Image, standard.ImageTransparentColor, standard.ImageRect, orientation, palette.GetContentImageEffect(state), palette.GetContentImageColorMap(state), palette.GetContentImageColorTo(state)); } if (standard.DrawShortText) { using (GraphicsTextHint hint = new GraphicsTextHint(context.Graphics, standard.ShortTextHint)) { // Get the rectangle to use when dealing with gradients Rectangle gradientRect = context.GetAlignedRectangle(palette.GetContentShortTextColorAlign(state), standard.ShortTextRect); // Use standard helper routine to create appropriate color brush Color color1 = palette.GetContentShortTextColor1(state); PaletteColorStyle colorStyle = palette.GetContentShortTextColorStyle(state); using (Brush colorBrush = CreateColorBrush(gradientRect, color1, palette.GetContentShortTextColor2(state), colorStyle, palette.GetContentShortTextColorAngle(state), orientation)) { if (!AccurateText.DrawString(context.Graphics, colorBrush, standard.ShortTextRect, context.Control.RightToLeft, standard.Orientation, composition, glowing, state, standard.ShortTextMemento)) { // Failed to draw means the font is likely to be invalid, get a fresh font standard.ShortTextMemento.Font = palette.GetContentShortTextNewFont(state); // Try again using the new font AccurateText.DrawString(context.Graphics, colorBrush, standard.ShortTextRect, context.Control.RightToLeft, standard.Orientation, composition, glowing, state, standard.ShortTextMemento); } } Image shortImage = palette.GetContentShortTextImage(state); PaletteImageStyle shortImageStyle = palette.GetContentShortTextImageStyle(state); // Do we need to draw the image? if (ShouldDrawImage(shortImage)) { // Get the rectangle to use when dealing with gradients Rectangle imageRect = context.GetAlignedRectangle(palette.GetContentShortTextImageAlign(state), standard.ShortTextRect); // Use standard helper routine to create appropriate image brush using (Brush imageBrush = CreateImageBrush(imageRect, shortImage, shortImageStyle)) { if (!AccurateText.DrawString(context.Graphics, imageBrush, standard.ShortTextRect, context.Control.RightToLeft, standard.Orientation, composition, glowing, state, standard.ShortTextMemento)) { // Failed to draw means the font is likely to be invalid, get a fresh font standard.ShortTextMemento.Font = palette.GetContentShortTextNewFont(state); AccurateText.DrawString(context.Graphics, imageBrush, standard.ShortTextRect, context.Control.RightToLeft, standard.Orientation, composition, glowing, state, standard.ShortTextMemento); } } } } } if (standard.DrawLongText) { using (GraphicsTextHint hint = new GraphicsTextHint(context.Graphics, standard.LongTextHint)) { // Get the rectangle to use when dealing with gradients Rectangle gradientRect = context.GetAlignedRectangle(palette.GetContentLongTextColorAlign(state), standard.LongTextRect); // Use standard helper routine to create appropriate color brush Color color1 = palette.GetContentLongTextColor1(state); PaletteColorStyle colorStyle = palette.GetContentLongTextColorStyle(state); using (Brush colorBrush = CreateColorBrush(gradientRect, color1, palette.GetContentLongTextColor2(state), colorStyle, palette.GetContentLongTextColorAngle(state), orientation)) { if (!AccurateText.DrawString(context.Graphics, colorBrush, standard.LongTextRect, context.Control.RightToLeft, standard.Orientation, composition, glowing, state, standard.LongTextMemento)) { // Failed to draw means the font is likely to be invalid, get a fresh font standard.LongTextMemento.Font = palette.GetContentLongTextNewFont(state); AccurateText.DrawString(context.Graphics, colorBrush, standard.LongTextRect, context.Control.RightToLeft, standard.Orientation, composition, glowing, state, standard.LongTextMemento); } } Image longImage = palette.GetContentLongTextImage(state); PaletteImageStyle longImageStyle = palette.GetContentLongTextImageStyle(state); // Do we need to draw the image? if (ShouldDrawImage(longImage)) { // Get the rectangle to use when dealing with gradients Rectangle imageRect = context.GetAlignedRectangle(palette.GetContentLongTextImageAlign(state), standard.LongTextRect); // Use standard helper routine to create appropriate image brush using (Brush imageBrush = CreateImageBrush(imageRect, longImage, longImageStyle)) { if (!AccurateText.DrawString(context.Graphics, imageBrush, standard.LongTextRect, context.Control.RightToLeft, standard.Orientation, composition, glowing, state, standard.LongTextMemento)) { // Failed to draw means the font is likely to be invalid, get a fresh font standard.LongTextMemento.Font = palette.GetContentLongTextNewFont(state); AccurateText.DrawString(context.Graphics, imageBrush, standard.LongTextRect, context.Control.RightToLeft, standard.Orientation, composition, glowing, state, standard.LongTextMemento); } } } } } // Do we need to show this content has the focus? if (allowFocusRect && (palette.GetContentDrawFocus(state) == InheritBool.True)) { // Place the rectangle 1 pixel inside the content display area displayRect.Inflate(-1, -1); // Use window forms provided helper class for drawing ControlPaint.DrawFocusRectangle(context.Graphics, displayRect); } }
/// <summary> /// Raises the RenderItemText event. /// </summary> /// <param name="e">A ToolStripItemTextRenderEventArgs that contains the event data.</param> protected override void OnRenderItemText(ToolStripItemTextRenderEventArgs e) { if ((e.ToolStrip is ToolStrip) || (e.ToolStrip is ContextMenuStrip) || (e.ToolStrip is ToolStripDropDownMenu)) { if (!e.Item.Enabled) e.TextColor = _disabled; else { if ((e.ToolStrip is MenuStrip) && !e.Item.Pressed) e.TextColor = KCT.MenuStripText; else if ((e.ToolStrip is MenuStrip) && (e.Item.Pressed || e.Item.Selected)) e.TextColor = KCT.MenuItemText; else if ((e.ToolStrip is StatusStrip) && !e.Item.Pressed && !e.Item.Selected) e.TextColor = KCT.StatusStripText; else if ((e.ToolStrip is ContextMenuStrip) || (e.ToolStrip is ToolStripDropDownMenu)) e.TextColor = KCT.MenuItemText; else if (((e.ToolStrip is ToolStripDropDownMenu) || (e.ToolStrip is ToolStripOverflow)) && !e.Item.Selected) e.TextColor = KCT.MenuItemText; else if ((e.ToolStrip is ToolStrip) && ((e.Item is ToolStripSplitButton) || (e.Item is ToolStripDropDownButton)) && e.Item.Pressed) e.TextColor = KCT.MenuItemText; else e.TextColor = KCT.ToolStripText; } // Status strips under XP cannot use clear type because it ends up being cut off at edges if ((e.ToolStrip is StatusStrip) && (Environment.OSVersion.Version.Major < 6)) base.OnRenderItemText(e); else { using (GraphicsTextHint clearTypeGridFit = new GraphicsTextHint(e.Graphics, TextRenderingHint.ClearTypeGridFit)) base.OnRenderItemText(e); } } else base.OnRenderItemText(e); }
/// <summary> /// Pixel accurate measure of the specified string when drawn with the specified Font object. /// </summary> /// <param name="g">Graphics instance used to measure text.</param> /// <param name="rtl">Right to left setting for control.</param> /// <param name="text">String to measure.</param> /// <param name="font">Font object that defines the text format of the string.</param> /// <param name="trim">How to trim excess text.</param> /// <param name="align">How to align multine text.</param> /// <param name="prefix">How to process prefix characters.</param> /// <param name="hint">Rendering hint.</param> /// <param name="composition">Should draw on a composition element.</param> /// <param name="disposeFont">Dispose of font when finished with it.</param> /// <returns>A memento used to draw the text.</returns> public static AccurateTextMemento MeasureString(Graphics g, RightToLeft rtl, string text, Font font, PaletteTextTrim trim, PaletteRelativeAlign align, PaletteTextHotkeyPrefix prefix, TextRenderingHint hint, bool composition, bool disposeFont) { Debug.Assert(g != null); Debug.Assert(text != null); Debug.Assert(font != null); if (g == null) throw new ArgumentNullException("g"); if (text == null) throw new ArgumentNullException("text"); if (font == null) throw new ArgumentNullException("font"); // An empty string cannot be drawn, so uses the empty memento if (text.Length == 0) return AccurateTextMemento.Empty; // Create the format object used when measuring and drawing StringFormat format = new StringFormat(); format.FormatFlags = StringFormatFlags.NoClip; // Ensure that text reflects reversed RTL setting if (rtl == RightToLeft.Yes) format.FormatFlags = StringFormatFlags.DirectionRightToLeft; // How do we position text horizontally? switch (align) { case PaletteRelativeAlign.Near: format.Alignment = (rtl == RightToLeft.Yes) ? StringAlignment.Far : StringAlignment.Near; break; case PaletteRelativeAlign.Center: format.Alignment = StringAlignment.Center; break; case PaletteRelativeAlign.Far: format.Alignment = (rtl == RightToLeft.Yes) ? StringAlignment.Near : StringAlignment.Far; break; default: // Should never happen! Debug.Assert(false); break; } // Do we need to trim text that is too big? switch (trim) { case PaletteTextTrim.Character: format.Trimming = StringTrimming.Character; break; case PaletteTextTrim.EllipsisCharacter: format.Trimming = StringTrimming.EllipsisCharacter; break; case PaletteTextTrim.EllipsisPath: format.Trimming = StringTrimming.EllipsisPath; break; case PaletteTextTrim.EllipsisWord: format.Trimming = StringTrimming.EllipsisWord; break; case PaletteTextTrim.Word: format.Trimming = StringTrimming.Word; break; case PaletteTextTrim.Hide: format.Trimming = StringTrimming.None; break; default: // Should never happen! Debug.Assert(false); break; } // Setup the correct prefix processing switch (prefix) { case PaletteTextHotkeyPrefix.None: format.HotkeyPrefix = HotkeyPrefix.None; break; case PaletteTextHotkeyPrefix.Hide: format.HotkeyPrefix = HotkeyPrefix.Hide; break; case PaletteTextHotkeyPrefix.Show: format.HotkeyPrefix = HotkeyPrefix.Show; break; default: // Should never happen! Debug.Assert(false); break; } // Replace tab characters with a fixed four spaces text = text.Replace("\t", " "); // Perform actual measure of the text using (GraphicsTextHint graphicsHint = new GraphicsTextHint(g, hint)) { SizeF textSize = Size.Empty; try { textSize = g.MeasureString(text, font, int.MaxValue, format); if (composition) textSize.Width += GLOW_EXTRA_WIDTH; } catch {} // Return a memento with drawing details return new AccurateTextMemento(text, font, textSize, format, hint, disposeFont); } }
/// <summary> /// Raises the RenderItemText event. /// </summary> /// <param name="e">A ToolStripItemTextRenderEventArgs that contains the event data.</param> protected override void OnRenderItemText(ToolStripItemTextRenderEventArgs e) { if ((e.ToolStrip is ToolStrip) || (e.ToolStrip is ContextMenuStrip) || (e.ToolStrip is ToolStripDropDownMenu)) { if (!e.Item.Enabled) { e.TextColor = _disabled; } else { if ((e.ToolStrip is MenuStrip) && !e.Item.Pressed && !e.Item.Selected) { e.TextColor = KCT.MenuStripText; } else if (e.ToolStrip is MenuStrip) { e.TextColor = KCT.MenuItemText; } else if ((e.ToolStrip is StatusStrip) && !e.Item.Pressed && !e.Item.Selected) { e.TextColor = KCT.StatusStripText; } else if ((e.ToolStrip is StatusStrip) && !e.Item.Pressed && e.Item.Selected) { e.TextColor = KCT.MenuItemText; } else if ((e.ToolStrip is ToolStrip) && !e.Item.Pressed && e.Item.Selected) { e.TextColor = KCT.MenuItemText; } else if ((e.ToolStrip is ContextMenuStrip) && !e.Item.Pressed && !e.Item.Selected) { e.TextColor = KCT.MenuItemText; } else if (e.ToolStrip is ToolStripDropDownMenu) { e.TextColor = KCT.MenuItemText; } else if ((e.Item is ToolStripButton) && (((ToolStripButton)e.Item).Checked)) { e.TextColor = KCT.MenuItemText; } else { e.TextColor = KCT.ToolStripText; } } // Status strips under XP cannot use clear type because it ends up being cut off at edges if ((e.ToolStrip is StatusStrip) && (Environment.OSVersion.Version.Major < 6)) { base.OnRenderItemText(e); } else { using (GraphicsTextHint clearTypeGridFit = new GraphicsTextHint(e.Graphics, TextRenderingHint.ClearTypeGridFit)) base.OnRenderItemText(e); } } else { base.OnRenderItemText(e); } }