File: winforms\Managed\System\WinForms\ToolStripRenderer.cs
Project: ndp\fx\src\System.Windows.Forms.csproj (System.Windows.Forms)
//------------------------------------------------------------------------------
// <copyright file="ToolStripRenderer.cs" company="Microsoft">
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// </copyright>                                                                
//------------------------------------------------------------------------------
 
namespace System.Windows.Forms {
 
    using System.Windows.Forms.VisualStyles;
    using System.Drawing;
    using System.Drawing.Text;
    using System.Windows.Forms.Internal;
    using System.Drawing.Imaging;
    using System.ComponentModel;
    using System.Windows.Forms.Layout;
    using System.Security;
    using System.Security.Permissions;
    
    /// <include file='doc\ToolStripRenderer.uex' path='docs/doc[@for="ToolStripRenderer"]/*' />
    public abstract class ToolStripRenderer {
    
        private static readonly object EventRenderSplitButtonBackground             = new object();
        private static readonly object EventRenderItemBackground                    = new object();
        private static readonly object EventRenderItemImage                         = new object();
        private static readonly object EventRenderItemText                          = new object();
        private static readonly object EventRenderToolStripBackground               = new object();
        private static readonly object EventRenderGrip                              = new object();
        private static readonly object EventRenderButtonBackground                  = new object();
        private static readonly object EventRenderLabelBackground                   = new object();
        private static readonly object EventRenderMenuItemBackground                = new object();
        private static readonly object EventRenderDropDownButtonBackground          = new object();
        private static readonly object EventRenderOverflowButtonBackground          = new object();
        private static readonly object EventRenderImageMargin                       = new object();
        private static readonly object EventRenderBorder                            = new object();
        private static readonly object EventRenderArrow                             = new object();
        private static readonly object EventRenderStatusStripPanelBackground        = new object();
        private static readonly object EventRenderToolStripStatusLabelBackground    = new object();
        private static readonly object EventRenderSeparator                         = new object();
        private static readonly object EventRenderItemCheck                         = new object();
        private static readonly object EventRenderToolStripPanelBackground          = new object();
        private static readonly object EventRenderToolStripContentPanelBackground   = new object();
       
        private static readonly object EventRenderStatusStripSizingGrip             = new object();
 
        private static ColorMatrix disabledImageColorMatrix;
 
        private EventHandlerList events;
        private bool isAutoGenerated = false;
 
        private static bool isScalingInitialized = false;
        internal int previousDeviceDpi = DpiHelper.DeviceDpi;
        
        // arrows are rendered as isosceles triangles, whose heights are half the base in order to have 45 degree angles
        // Offset2X is half of the base
        // Offset2Y is height of the isosceles triangle
        private static int OFFSET_2PIXELS = 2;
        private static int OFFSET_4PIXELS = 4;
        protected static int Offset2X = OFFSET_2PIXELS;
        protected static int Offset2Y = OFFSET_2PIXELS;
        private static int offset4X = OFFSET_4PIXELS;
        private static int offset4Y = OFFSET_4PIXELS;
 
        // this is used in building up the half pyramid of rectangles that are drawn in a 
        // status strip sizing grip.
        private static Rectangle[] baseSizeGripRectangles = new Rectangle[] { new Rectangle(8,0,2,2),
                                                                                new Rectangle(8,4,2,2),
                                                                                new Rectangle(8,8,2,2),
                                                                                new Rectangle(4,4,2,2),
                                                                                new Rectangle(4,8,2,2),
                                                                                new Rectangle(0,8,2,2) };
                                
        protected ToolStripRenderer() {
        }
 
        internal ToolStripRenderer(bool isAutoGenerated) {
            this.isAutoGenerated = isAutoGenerated;
        }
        // this is used in building disabled images.
        private static ColorMatrix DisabledImageColorMatrix {
            get {
                if (disabledImageColorMatrix == null) {
                    // VSWhidbey 233470
                    // this is the result of a GreyScale matrix multiplied by a transparency matrix of .5
                 
 
    
                    float[][] greyscale = new float[5][];
                    greyscale[0] = new float[5] {0.2125f, 0.2125f, 0.2125f, 0, 0};
                    greyscale[1] = new float[5] {0.2577f, 0.2577f, 0.2577f, 0, 0};
                    greyscale[2] = new float[5] {0.0361f, 0.0361f, 0.0361f, 0, 0};
                    greyscale[3] = new float[5] {0,       0,       0,       1, 0};
                    greyscale[4] = new float[5] {0.38f,   0.38f,   0.38f,   0, 1};
 
                    float[][] transparency = new float[5][];
                    transparency[0] = new float[5] {1, 0,  0,  0,  0};
                    transparency[1] = new float[5] {0, 1,  0,  0,  0};
                    transparency[2] = new float[5] {0, 0,  1,  0,  0};
                    transparency[3] = new float[5] {0, 0,  0, .7F, 0};
                    transparency[4] = new float[5] {0, 0,  0,  0,  0};
 
 
                    disabledImageColorMatrix = ControlPaint.MultiplyColorMatrix(transparency, greyscale);
 
                }
  
                return disabledImageColorMatrix;
            }
        }
 
      
        /// <devdoc>
        ///    <para>Gets the list of event handlers that are attached to this component.</para>
        /// </devdoc>
        private EventHandlerList Events {
            get {
                if (events == null) {
                    events = new EventHandlerList();
                }
                return events;
            }
        }
 
        internal bool IsAutoGenerated {
            get { return isAutoGenerated; }
        }
            
        // if we're in a low contrast, high resolution situation, use this renderer under the covers instead.
        internal virtual ToolStripRenderer RendererOverride {
            get {
                return null;
            }
        }
 
        /// -----------------------------------------------------------------------------
        /// SECREVIEW VSWhidbey 250785 - all stock renderer events require AllWindowsPermission
        ///    use the private AddHandler/RemoveHandler to ensure that security checks are
        ///    made.
        /// -----------------------------------------------------------------------------
 
 
        /// <include file='doc\WinBarRenderer.uex' path='docs/doc[@for="ToolStripRenderer.RenderArrow"]/*' />
        public event ToolStripArrowRenderEventHandler RenderArrow {
            add { 
                AddHandler(EventRenderArrow, value); 
            }
            remove {
                RemoveHandler(EventRenderArrow, value);
            }
        }
            
        /// <include file='doc\ToolStripRenderer.uex' path='docs/doc[@for="ToolStripRenderer.RenderToolStripBackground"]/*' />
        /// <devdoc>
        /// <para>Occurs when the display style has changed</para>
        /// </devdoc>
        public event ToolStripRenderEventHandler RenderToolStripBackground {
            add { 
                AddHandler(EventRenderToolStripBackground, value); 
            }
            remove {
                RemoveHandler(EventRenderToolStripBackground, value);
            }
        }
 
        
        public event ToolStripPanelRenderEventHandler RenderToolStripPanelBackground {
            add { 
                AddHandler(EventRenderToolStripPanelBackground, value); 
            }
            remove {
                RemoveHandler(EventRenderToolStripPanelBackground, value);
            }
        }
 
        public event ToolStripContentPanelRenderEventHandler RenderToolStripContentPanelBackground {
             add { 
                 AddHandler(EventRenderToolStripContentPanelBackground, value); 
             }
             remove {
                 RemoveHandler(EventRenderToolStripContentPanelBackground, value);
             }
         }
 
        /// <include file='doc\ToolStripRenderer.uex' path='docs/doc[@for="ToolStripRenderer.RenderBorder"]/*' />
        /// <devdoc>
        /// <para>Occurs when the display style has changed</para>
        /// </devdoc>
        public event ToolStripRenderEventHandler RenderToolStripBorder {
            add { 
                AddHandler(EventRenderBorder, value); 
            }
            remove {
                RemoveHandler(EventRenderBorder, value);
            }
        }
 
        /// <include file='doc\ToolStripRenderer.uex' path='docs/doc[@for="ToolStripRenderer.RenderButtonBackground"]/*' />
        /// <devdoc>
        /// <para>Occurs when the display style has changed</para>
        /// </devdoc>
        public event ToolStripItemRenderEventHandler RenderButtonBackground {
            add { 
                AddHandler(EventRenderButtonBackground, value); 
            }
            remove {
                RemoveHandler(EventRenderButtonBackground, value);
            }
        }    
        /// <include file='doc\ToolStripRenderer.uex' path='docs/doc[@for="ToolStripRenderer.RenderDropDownButtonBackground"]/*' />
        /// <devdoc>
        /// <para>Occurs when the display style has changed</para>
        /// </devdoc>
        public event ToolStripItemRenderEventHandler RenderDropDownButtonBackground {
            add { 
                AddHandler(EventRenderDropDownButtonBackground, value); 
            }
            remove {
                RemoveHandler(EventRenderDropDownButtonBackground, value);
            }
        }  
 
        /// <include file='doc\ToolStripRenderer.uex' path='docs/doc[@for="ToolStripRenderer.RenderOverflowButtonBackground"]/*' />
        /// <devdoc>
        /// <para>Occurs when the display style has changed</para>
        /// </devdoc>
        public event ToolStripItemRenderEventHandler RenderOverflowButtonBackground {
            add { 
                AddHandler(EventRenderOverflowButtonBackground, value); 
            }
            remove {
                RemoveHandler(EventRenderOverflowButtonBackground, value);
            }
        }  
        /// <include file='doc\ToolStripRenderer.uex' path='docs/doc[@for="ToolStripRenderer.RenderGrip"]/*' />
        /// <devdoc>
        /// <para>Occurs when the display style has changed</para>
        /// </devdoc>
        public event ToolStripGripRenderEventHandler RenderGrip {
            add { 
                AddHandler(EventRenderGrip, value); 
            }
            remove {
                RemoveHandler(EventRenderGrip, value);
            }
        }        
        /// <include file='doc\ToolStripRenderer.uex' path='docs/doc[@for="ToolStripRenderer.RenderItem"]/*' />
        /// <devdoc>
        /// <para>Occurs when the display style has changed</para>
        /// </devdoc>
        public event ToolStripItemRenderEventHandler RenderItemBackground {
            add { 
                AddHandler(EventRenderItemBackground, value); 
            }
            remove {
                RemoveHandler(EventRenderItemBackground, value);
            }
        }               
        /// <include file='doc\ToolStripRenderer.uex' path='docs/doc[@for="ToolStripRenderer.RenderItemImage"]/*' />
        /// <devdoc>
        /// Draws the split button
        /// </devdoc>
        public event ToolStripItemImageRenderEventHandler RenderItemImage {
            add { 
                AddHandler(EventRenderItemImage, value); 
            }
            remove {
                RemoveHandler(EventRenderItemImage, value);
            }
        }        
        /// <include file='doc\WinBarRenderer.uex' path='docs/doc[@for="ToolStripRenderer.RenderItemCheck"]/*' />
        /// <devdoc>
        /// Draws the checkmark
        /// </devdoc>
        public event ToolStripItemImageRenderEventHandler RenderItemCheck {
            add { 
                AddHandler(EventRenderItemCheck, value); 
            }
            remove {
                RemoveHandler(EventRenderItemCheck, value);
            }
        }        
        /// <include file='doc\ToolStripRenderer.uex' path='docs/doc[@for="ToolStripRenderer.RenderItemText"]/*' />
        /// <devdoc>
        /// Draws the split button
        /// </devdoc>
        public event ToolStripItemTextRenderEventHandler RenderItemText {
            add { 
                AddHandler(EventRenderItemText, value); 
            }
            remove {
                RemoveHandler(EventRenderItemText, value);
            }
        }    
 
        public event ToolStripRenderEventHandler RenderImageMargin {
            add { 
                AddHandler(EventRenderImageMargin, value); 
            }
            remove {
                RemoveHandler(EventRenderImageMargin, value);
            }
        }
        /// <include file='doc\ToolStripRenderer.uex' path='docs/doc[@for="ToolStripRenderer.RenderLabelBackground"]/*' />
        /// <devdoc>
        /// <para>Occurs when the display style has changed</para>
        /// </devdoc>
        public event ToolStripItemRenderEventHandler RenderLabelBackground {
            add { 
                AddHandler(EventRenderLabelBackground, value); 
            }
            remove {
                RemoveHandler(EventRenderLabelBackground, value);
            }
        }   
        /// <include file='doc\ToolStripRenderer.uex' path='docs/doc[@for="ToolStripRenderer.RenderMenuItemBackground"]/*' />
        /// <devdoc>
        /// <para>Occurs when the display style has changed</para>
        /// </devdoc>
        public event ToolStripItemRenderEventHandler RenderMenuItemBackground {
            add { 
                AddHandler(EventRenderMenuItemBackground, value); 
            }
            remove {
                RemoveHandler(EventRenderMenuItemBackground, value);
            }
        }   
 
        /// <include file='doc\WinBarRenderer.uex' path='docs/doc[@for="ToolStripRenderer.RenderStatusStripPanelBackground"]/*' />
        /// <devdoc>
        /// Draws the split button
        /// </devdoc>
        public event ToolStripItemRenderEventHandler RenderToolStripStatusLabelBackground {
            add { 
                AddHandler(EventRenderToolStripStatusLabelBackground, value); 
            }
            remove {
                RemoveHandler(EventRenderToolStripStatusLabelBackground, value);
            }
        }
        
        /// <include file='doc\ToolStripRenderer.uex' path='docs/doc[@for="ToolStripRenderer.RenderToolStripBackground"]/*' />
        /// <devdoc>
        /// <para>Occurs when the display style has changed</para>
        /// </devdoc>
        public event ToolStripRenderEventHandler RenderStatusStripSizingGrip {
            add { 
                AddHandler(EventRenderStatusStripSizingGrip, value); 
            }
            remove {
                RemoveHandler(EventRenderStatusStripSizingGrip, value);
            }
        }
            
        /// <include file='doc\ToolStripRenderer.uex' path='docs/doc[@for="ToolStripRenderer.RenderSplitButtonBackground"]/*' />
        /// <devdoc>
        /// Draws the split button
        /// </devdoc>
        public event ToolStripItemRenderEventHandler RenderSplitButtonBackground {
            add { 
                AddHandler(EventRenderSplitButtonBackground, value); 
            }
            remove {
                RemoveHandler(EventRenderSplitButtonBackground, value);
            }
        }        
      
    
       /// <include file='doc\WinBarRenderer.uex' path='docs/doc[@for="ToolStripRenderer.RenderSeparator"]/*' />
       public event ToolStripSeparatorRenderEventHandler RenderSeparator {
           add { 
               AddHandler(EventRenderSeparator, value); 
           }
           remove {
               RemoveHandler(EventRenderSeparator, value);
           }
       }     
 
#region EventHandlerSecurity
      /// -----------------------------------------------------------------------------
      /// SECREVIEW VSWhidbey 250785 - all stock renderer events require AllWindowsPermission
      ///    use the private AddHandler/RemoveHandler to ensure that security checks are
      ///    made.
      /// -----------------------------------------------------------------------------
 
       [UIPermission(SecurityAction.Demand, Window=UIPermissionWindow.AllWindows)]
       private void AddHandler(object key, Delegate value) {
            Events.AddHandler(key, value);
       }
 
       [UIPermission(SecurityAction.Demand, Window=UIPermissionWindow.AllWindows)]
       private void RemoveHandler(object key, Delegate value) {
            Events.RemoveHandler(key, value);
       }
#endregion
    
       /// <include file='doc\ToolStripRenderer.uex' path='docs/doc[@for="ToolStripRenderer.CreateDisabledImage"]/*' />
       public static Image CreateDisabledImage(Image normalImage) {
            return CreateDisabledImage(normalImage, null);
       }
 
        /// <include file='doc\WinBarRenderer.uex' path='docs/doc[@for="ToolStripRenderer.DrawArrow"]/*' />
        public void DrawArrow(ToolStripArrowRenderEventArgs e) {            
            OnRenderArrow(e);
            
            ToolStripArrowRenderEventHandler eh = Events[EventRenderArrow] as ToolStripArrowRenderEventHandler;
            if (eh != null) {
                eh(this, e);
            }        
        }
 
        /// <include file='doc\ToolStripRenderer.uex' path='docs/doc[@for="ToolStripRenderer.DrawBackground"]/*' />
        /// <devdoc>
        /// Draw the background color
        /// </devdoc>
        public void DrawToolStripBackground(ToolStripRenderEventArgs e) {            
            OnRenderToolStripBackground(e);
            
            ToolStripRenderEventHandler eh = Events[EventRenderToolStripBackground] as ToolStripRenderEventHandler;
            if (eh != null) {
                eh(this, e);
            }        
        }
 
 
        
        /// <include file='doc\ToolStripRenderer.uex' path='docs/doc[@for="ToolStripRenderer.DrawGrip"]/*' />
        /// <devdoc>
        /// Draw the background color
        /// </devdoc>
        public void DrawGrip(ToolStripGripRenderEventArgs e) {   
            OnRenderGrip(e);
            ToolStripGripRenderEventHandler eh = Events[EventRenderGrip] as ToolStripGripRenderEventHandler;
            if (eh != null) {
               eh(this, e);
             }   
        }   
 
        
        /// <include file='doc\ToolStripRenderer.uex' path='docs/doc[@for="ToolStripRenderer.DrawItem"]/*' />
        /// <devdoc>
        /// Draw the item's background.
        /// </devdoc>
        public void DrawItemBackground(ToolStripItemRenderEventArgs e)
        {     
            OnRenderItemBackground(e);             
 
            ToolStripItemRenderEventHandler eh = Events[EventRenderItemBackground] as ToolStripItemRenderEventHandler;
             if (eh != null) {
                 eh(this, e);
             }
            
        }   
 
        /// <include file='doc\ToolStripRenderer.uex' path='docs/doc[@for="ToolStripRenderer.DrawImageMargin"]/*' />
        /// <devdoc>
        /// Draw the background color
        /// </devdoc>
        public void DrawImageMargin(ToolStripRenderEventArgs e) {            
            OnRenderImageMargin(e);
            
            ToolStripRenderEventHandler eh = Events[EventRenderImageMargin] as ToolStripRenderEventHandler;
            if (eh != null) {
                eh(this, e);
            }        
        }
 
        /// <include file='doc\ToolStripRenderer.uex' path='docs/doc[@for="ToolStripRenderer.DrawLabel"]/*' />
        /// <devdoc>
        /// Draw the background color
        /// </devdoc>
        public void DrawLabelBackground(ToolStripItemRenderEventArgs e)
        {
            OnRenderLabelBackground(e);
            ToolStripItemRenderEventHandler eh = Events[EventRenderLabelBackground] as ToolStripItemRenderEventHandler;
            if (eh != null) {
                eh(this, e);
            }   
        }
 
        /// <include file='doc\ToolStripRenderer.uex' path='docs/doc[@for="ToolStripRenderer.DrawButton"]/*' />
        /// <devdoc>
        /// Draw the item's background.
        /// </devdoc>
        public void DrawButtonBackground(ToolStripItemRenderEventArgs e)
        {     
            OnRenderButtonBackground(e);             
 
            ToolStripItemRenderEventHandler eh = Events[EventRenderButtonBackground] as ToolStripItemRenderEventHandler;
            if (eh != null) {
                eh(this, e);
            }
        }    
 
        /// <include file='doc\ToolStripRenderer.uex' path='docs/doc[@for="ToolStripRenderer.DrawBorder"]/*' />
        public void DrawToolStripBorder(ToolStripRenderEventArgs e)
        {     
           OnRenderToolStripBorder(e);             
 
           ToolStripRenderEventHandler eh = Events[EventRenderBorder] as ToolStripRenderEventHandler;
           if (eh != null) {
               eh(this, e);
           }
        }    
 
 
        /// <include file='doc\ToolStripRenderer.uex' path='docs/doc[@for="ToolStripRenderer.DrawDropDownButton"]/*' />
        /// <devdoc>
        /// Draw the item's background.
        /// </devdoc>
        public void DrawDropDownButtonBackground(ToolStripItemRenderEventArgs e)
        {     
            OnRenderDropDownButtonBackground(e);             
 
            ToolStripItemRenderEventHandler eh = Events[EventRenderDropDownButtonBackground] as ToolStripItemRenderEventHandler;
            if (eh != null) {
                eh(this, e);
            }
        }    
 
        /// <include file='doc\ToolStripRenderer.uex' path='docs/doc[@for="ToolStripRenderer.DrawOverflowButton"]/*' />
        /// <devdoc>
        /// Draw the item's background.
        /// </devdoc>
        public void DrawOverflowButtonBackground(ToolStripItemRenderEventArgs e)
        {     
            OnRenderOverflowButtonBackground(e);             
 
            ToolStripItemRenderEventHandler eh = Events[EventRenderOverflowButtonBackground] as ToolStripItemRenderEventHandler;
            if (eh != null) {
                eh(this, e);
            }
        }   
        
        /// <include file='doc\ToolStripRenderer.uex' path='docs/doc[@for="ToolStripRenderer.DrawItemImage"]/*' />
        /// <devdoc>
        /// Draw image
        /// </devdoc>
        public void DrawItemImage(ToolStripItemImageRenderEventArgs e) {
            OnRenderItemImage(e);
            
            ToolStripItemImageRenderEventHandler eh = Events[EventRenderItemImage] as ToolStripItemImageRenderEventHandler;
            if (eh != null) {
                eh(this, e);
            }
        }
 
        /// <include file='doc\WinBarRenderer.uex' path='docs/doc[@for="ToolStripRenderer.DrawItemCheck"]/*' />
        /// <devdoc>
        /// Draw image
        /// </devdoc>
        public void DrawItemCheck(ToolStripItemImageRenderEventArgs e) {
              OnRenderItemCheck(e);
              
              ToolStripItemImageRenderEventHandler eh = Events[EventRenderItemCheck] as ToolStripItemImageRenderEventHandler;
              if (eh != null) {
                  eh(this, e);
              }
        }
 
        /// <include file='doc\ToolStripRenderer.uex' path='docs/doc[@for="ToolStripRenderer.DrawItemText"]/*' />
        /// <devdoc>
        /// Draw text 
        /// </devdoc>
        public void DrawItemText(ToolStripItemTextRenderEventArgs e) {
            OnRenderItemText(e);
            
            ToolStripItemTextRenderEventHandler eh = Events[EventRenderItemText] as ToolStripItemTextRenderEventHandler;
            if (eh != null) {
                eh(this, e);
            }
        }
 
        /// <include file='doc\ToolStripRenderer.uex' path='docs/doc[@for="ToolStripRenderer.DrawMenuItem"]/*' />
        /// <devdoc>
        /// Draw the item's background.
        /// </devdoc>
        public void DrawMenuItemBackground(ToolStripItemRenderEventArgs e)
        {     
            OnRenderMenuItemBackground(e);             
 
            ToolStripItemRenderEventHandler eh = Events[EventRenderMenuItemBackground] as ToolStripItemRenderEventHandler;
            if (eh != null) {
                eh(this, e);
            }
        }    
      
      
        /// <include file='doc\ToolStripRenderer.uex' path='docs/doc[@for="ToolStripRenderer.DrawSplitButton"]/*' />
        /// <devdoc>
        /// Draw the background color
        /// </devdoc>
        public void DrawSplitButton(ToolStripItemRenderEventArgs e) {
           
            OnRenderSplitButtonBackground(e);             
 
            ToolStripItemRenderEventHandler eh = Events[EventRenderSplitButtonBackground] as ToolStripItemRenderEventHandler;
            if (eh != null) {
                eh(this, e);
            }
                  
        }
 
        /// <include file='doc\WinBarRenderer.uex' path='docs/doc[@for="ToolStripRenderer.DrawToolStripStatusLabel"]/*' />
        /// <devdoc>
        /// Draw the background color
        /// </devdoc>
        public void DrawToolStripStatusLabelBackground(ToolStripItemRenderEventArgs e) {
           
            OnRenderToolStripStatusLabelBackground(e);             
 
            ToolStripItemRenderEventHandler eh = Events[EventRenderToolStripStatusLabelBackground] as ToolStripItemRenderEventHandler;
            if (eh != null) {
                eh(this, e);
            }
                  
        }
        
        // 
        public void DrawStatusStripSizingGrip(ToolStripRenderEventArgs e) {
                     
            OnRenderStatusStripSizingGrip(e);
 
            ToolStripRenderEventHandler eh = Events[EventRenderStatusStripSizingGrip] as ToolStripRenderEventHandler;
            if (eh != null) {
                eh(this, e);
            }
        }
        /// <include file='doc\ToolStripRenderer.uex' path='docs/doc[@for="ToolStripRenderer.DrawSeparator"]/*' />
        /// <devdoc>
        /// Draw the separator
        /// </devdoc>
        public void DrawSeparator(ToolStripSeparatorRenderEventArgs e) {
            OnRenderSeparator(e);
            ToolStripSeparatorRenderEventHandler eh = Events[EventRenderSeparator] as ToolStripSeparatorRenderEventHandler;
            if (eh != null) {
                eh(this, e);
            }
        }
 
        public void DrawToolStripPanelBackground(ToolStripPanelRenderEventArgs e) {
            OnRenderToolStripPanelBackground(e);
            ToolStripPanelRenderEventHandler eh = Events[EventRenderToolStripPanelBackground] as ToolStripPanelRenderEventHandler;
            if (eh != null) {
                eh(this, e);
            }
        }
 
        public void DrawToolStripContentPanelBackground(ToolStripContentPanelRenderEventArgs e) {
            OnRenderToolStripContentPanelBackground(e);
            ToolStripContentPanelRenderEventHandler eh = Events[EventRenderToolStripContentPanelBackground] as ToolStripContentPanelRenderEventHandler;
            if (eh != null) {
                eh(this, e);
            }
        }
 
        // consider make public
        internal virtual Region GetTransparentRegion(ToolStrip toolStrip) {
             return null;
        }
 
      
        /// <include file='doc\ToolStripRenderer.uex' path='docs/doc[@for="ToolStripRenderer.Initialize"]/*' />
        protected internal virtual void Initialize(ToolStrip toolStrip){
        }
 
        /// <include file='doc\ToolStripRenderer.uex' path='docs/doc[@for="ToolStripRenderer.Initialize"]/*' />
        protected internal virtual void InitializePanel(ToolStripPanel toolStripPanel){
        }
 
        /// <include file='doc\ToolStripRenderer.uex' path='docs/doc[@for="ToolStripRenderer.Initialize"]/*' />
        protected internal virtual void InitializeContentPanel(ToolStripContentPanel contentPanel){
        }
 
 
        /// <include file='doc\ToolStripRenderer.uex' path='docs/doc[@for="ToolStripRenderer.InitializeItem"]/*' />
        protected internal virtual void InitializeItem (ToolStripItem item){
        }
 
        protected static void ScaleArrowOffsetsIfNeeded() {
            if (isScalingInitialized) {
                return;
            }
       
            if (DpiHelper.IsScalingRequired) {
                Offset2X = DpiHelper.LogicalToDeviceUnitsX(OFFSET_2PIXELS);
                Offset2Y = DpiHelper.LogicalToDeviceUnitsY(OFFSET_2PIXELS);
                offset4X = DpiHelper.LogicalToDeviceUnitsX(OFFSET_4PIXELS);
                offset4Y = DpiHelper.LogicalToDeviceUnitsY(OFFSET_4PIXELS);
            }
            isScalingInitialized = true;
 
        }
 
        protected static void ScaleArrowOffsetsIfNeeded(int dpi) {
            Offset2X = DpiHelper.LogicalToDeviceUnits(OFFSET_2PIXELS, dpi);
            Offset2Y = DpiHelper.LogicalToDeviceUnits(OFFSET_2PIXELS, dpi);
            offset4X = DpiHelper.LogicalToDeviceUnits(OFFSET_4PIXELS, dpi);
            offset4Y = DpiHelper.LogicalToDeviceUnits(OFFSET_4PIXELS, dpi);
        }
 
        /// <include file='doc\WinBarRenderer.uex' path='docs/doc[@for="ToolStripRenderer.OnRenderArrow"]/*' />
        protected virtual void OnRenderArrow(ToolStripArrowRenderEventArgs e){
 
            if (RendererOverride != null) {
               RendererOverride.OnRenderArrow(e);
               return;
            }
            Graphics g = e.Graphics;
            Rectangle dropDownRect = e.ArrowRectangle;
            using (Brush brush = new SolidBrush(e.ArrowColor)) {
 
                Point middle = new Point(dropDownRect.Left + dropDownRect.Width / 2, dropDownRect.Top + dropDownRect.Height / 2);
                // if the width is odd - favor pushing it over one pixel right.
                //middle.X += (dropDownRect.Width % 2);
 
                Point[] arrow = null;
 
                // We need the Elvis operator here, since at design time at this point Item can be null.
                if (e.Item?.DeviceDpi != previousDeviceDpi && DpiHelper.EnableToolStripPerMonitorV2HighDpiImprovements) {
                    previousDeviceDpi = e.Item.DeviceDpi;
                    ScaleArrowOffsetsIfNeeded(e.Item.DeviceDpi);
                }
                else {
                    ScaleArrowOffsetsIfNeeded();
                }
 
                // using (offset4X - Offset2X) instead of (Offset2X) to compensate for rounding error in scaling
                int horizontalOffset = DpiHelper.EnableToolStripHighDpiImprovements ? offset4X - Offset2X : Offset2X;
 
                 switch (e.Direction) {
                     case ArrowDirection.Up:
                         
                         arrow = new Point[] {
                                 new Point(middle.X - Offset2X, middle.Y + 1),
                                 new Point(middle.X + Offset2X + 1, middle.Y + 1),
                                 new Point(middle.X, middle.Y - Offset2Y)};
                             
                         break;
                     case ArrowDirection.Left:
                         arrow = new Point[] {
                                 new Point(middle.X + Offset2X, middle.Y - offset4Y),
                                 new Point(middle.X + Offset2X, middle.Y + offset4Y),
                                 new Point(middle.X - horizontalOffset, middle.Y)};
                                 
                         break;
                     case ArrowDirection.Right:
                         arrow = new Point[] {
                                 new Point(middle.X - Offset2X, middle.Y - offset4Y),
                                 new Point(middle.X - Offset2X, middle.Y + offset4Y),
                                 new Point(middle.X + horizontalOffset, middle.Y)};
                                     
                         break;
                     case ArrowDirection.Down:
                     default:
                         arrow = new Point[] {
                             new Point(middle.X - Offset2X, middle.Y - 1),
                             new Point(middle.X + Offset2X + 1, middle.Y - 1),
                             new Point(middle.X, middle.Y + Offset2Y) };
                         break;
                 }
                 g.FillPolygon(brush, arrow);
            }
        }
         
        /// <include file='doc\ToolStripRenderer.uex' path='docs/doc[@for="ToolStripRenderer.OnRenderToolStripBackground"]/*' />
        /// <devdoc>
        /// Draw the winbar background.  ToolStrip users should override this if they want to draw differently.
        /// </devdoc>
        protected virtual void OnRenderToolStripBackground(ToolStripRenderEventArgs e) {         
            if (RendererOverride != null) {
               RendererOverride.OnRenderToolStripBackground(e);
               return;
            }
        }
        
        /// <include file='doc\ToolStripRenderer.uex' path='docs/doc[@for="ToolStripRenderer.OnRenderBorder"]/*' />
        /// <devdoc>
        /// Draw the border around the ToolStrip.  This should be done as the last step.
        /// </devdoc>
        protected virtual void OnRenderToolStripBorder(ToolStripRenderEventArgs e) {  
            if (RendererOverride != null) {
                RendererOverride.OnRenderToolStripBorder(e);
                return;
            }
        }
        
        /// <include file='doc\ToolStripRenderer.uex' path='docs/doc[@for="ToolStripRenderer.OnRenderGrip"]/*' />
        /// <devdoc>
        /// Draw the grip.  ToolStrip users should override this if they want to draw differently.
        /// </devdoc>
        protected virtual void OnRenderGrip(ToolStripGripRenderEventArgs e) {
            if (RendererOverride != null) {
                RendererOverride.OnRenderGrip(e);
                return;
            }
        }
 
        /// <include file='doc\ToolStripRenderer.uex' path='docs/doc[@for="ToolStripRenderer.OnRenderItem"]/*' />
        /// <devdoc>
        /// Draw the items background
        /// </devdoc>
        protected virtual void OnRenderItemBackground(ToolStripItemRenderEventArgs e) {
            if (RendererOverride != null) {
                RendererOverride.OnRenderItemBackground(e);
                return;
            }
 
        }
 
        /// <include file='doc\ToolStripRenderer.uex' path='docs/doc[@for="ToolStripRenderer.OnRenderImageMargin"]/*' />
        /// <devdoc>
        /// Draw the items background
        /// </devdoc>
        protected virtual void OnRenderImageMargin(ToolStripRenderEventArgs e) {
            if (RendererOverride != null) {
                RendererOverride.OnRenderImageMargin(e);
                return;
            }
 
        }
        /// <include file='doc\ToolStripRenderer.uex' path='docs/doc[@for="ToolStripRenderer.OnRenderButtonBackground"]/*' />
        /// <devdoc>
        /// Draw the button background
        /// </devdoc>
        protected virtual void OnRenderButtonBackground(ToolStripItemRenderEventArgs e) {
            if (RendererOverride != null) {
                RendererOverride.OnRenderButtonBackground(e);
                return;
            }
 
        }
   
        /// <include file='doc\ToolStripRenderer.uex' path='docs/doc[@for="ToolStripRenderer.OnRenderDropDownButtonBackground"]/*' />
        /// <devdoc>
        /// Draw the button background
        /// </devdoc>
        protected virtual void OnRenderDropDownButtonBackground(ToolStripItemRenderEventArgs e) {
            if (RendererOverride != null) {
                RendererOverride.OnRenderDropDownButtonBackground(e);
                return;
            }
 
        }
 
        /// <include file='doc\ToolStripRenderer.uex' path='docs/doc[@for="ToolStripRenderer.OnRenderOverflowButtonBackground"]/*' />
        /// <devdoc>
        /// Draw the button background
        /// </devdoc>
        protected virtual void OnRenderOverflowButtonBackground(ToolStripItemRenderEventArgs e) {
            if (RendererOverride != null) {
                RendererOverride.OnRenderOverflowButtonBackground(e);
                return;
            }
        }
        /// <include file='doc\ToolStripRenderer.uex' path='docs/doc[@for="ToolStripRenderer.OnRenderItemImage"]/*' />
        /// <devdoc>
        /// Draw the item'si mage.  ToolStrip users should override this function to change the 
        /// drawing of all images.
        /// </devdoc>
        protected virtual void OnRenderItemImage(ToolStripItemImageRenderEventArgs e)  {
            if (RendererOverride != null) {
                RendererOverride.OnRenderItemImage(e);
                return;
            }
 
            Rectangle imageRect = e.ImageRectangle;
            Image image = e.Image;
                   
            if (imageRect != Rectangle.Empty && image != null) {
                bool disposeImage = false;
                if (e.ShiftOnPress && e.Item.Pressed) {
                   imageRect.X +=1;
                }
                if (!e.Item.Enabled) {
                    image = CreateDisabledImage(image, e.ImageAttributes);
                    disposeImage = true;
                }
                if (e.Item.ImageScaling == ToolStripItemImageScaling.None) {
                   e.Graphics.DrawImage(image, imageRect, new Rectangle(Point.Empty,imageRect.Size), GraphicsUnit.Pixel);
 
                }
                else {
                    e.Graphics.DrawImage(image, imageRect);
                }
 
                if (disposeImage) {
                    image.Dispose();
                }
            }
        }
 
        
        /// <include file='doc\WinBarRenderer.uex' path='docs/doc[@for="ToolStripRenderer.OnRenderItemCheck"]/*' />
        protected virtual void OnRenderItemCheck(ToolStripItemImageRenderEventArgs e)  {
            if (RendererOverride != null) {
                RendererOverride.OnRenderItemCheck(e);
                return;
            }
 
           Rectangle imageRect = e.ImageRectangle;
           Image image = e.Image;
                  
           if (imageRect != Rectangle.Empty && image != null) {
               if (!e.Item.Enabled) {
                   image = CreateDisabledImage(image, e.ImageAttributes);
               }
               
               e.Graphics.DrawImage(image, imageRect, 0, 0, imageRect.Width, 
                   imageRect.Height, GraphicsUnit.Pixel, e.ImageAttributes);
           }
       }
 
  
        /// <include file='doc\ToolStripRenderer.uex' path='docs/doc[@for="ToolStripRenderer.OnRenderItemText"]/*' />
        /// <devdoc>
        /// Draw the item's text.  ToolStrip users should override this function to change the 
        /// drawing of all text.
        /// </devdoc>
        protected virtual void OnRenderItemText(ToolStripItemTextRenderEventArgs e) {
            if (RendererOverride != null) {
                RendererOverride.OnRenderItemText(e);
                return;
            }
            
            ToolStripItem item         = e.Item;
            Graphics g                 = e.Graphics;
            Color textColor            = e.TextColor;
            Font textFont              = e.TextFont;
            string text                = e.Text;
            Rectangle textRect         = e.TextRectangle;
            TextFormatFlags textFormat = e.TextFormat;
            // if we're disabled draw in a different color.
            textColor = (item.Enabled) ? textColor : SystemColors.GrayText;
 
            if (e.TextDirection != ToolStripTextDirection.Horizontal && textRect.Width > 0 && textRect.Height > 0) {
                // Perf: this is a bit heavy handed.. perhaps we can share the bitmap.
                Size textSize = LayoutUtils.FlipSize(textRect.Size);
                using (Bitmap textBmp = new Bitmap(textSize.Width, textSize.Height,PixelFormat.Format32bppPArgb)) {
                    
                    using (Graphics textGraphics = Graphics.FromImage(textBmp)) {
                        // now draw the text..
                        textGraphics.TextRenderingHint = TextRenderingHint.AntiAlias;
                        TextRenderer.DrawText(textGraphics, text, textFont, new Rectangle(Point.Empty, textSize), textColor, textFormat);
                        textBmp.RotateFlip((e.TextDirection == ToolStripTextDirection.Vertical90) ? RotateFlipType.Rotate90FlipNone :  RotateFlipType.Rotate270FlipNone);
                        g.DrawImage(textBmp, textRect);
                    }
                }
            }
            else {
                TextRenderer.DrawText(g, text, textFont, textRect, textColor, textFormat);
            }
        }
 
        /// <include file='doc\ToolStripRenderer.uex' path='docs/doc[@for="ToolStripRenderer.OnRenderLabelBackground"]/*' />
        /// <devdoc>
        /// Draw the button background
        /// </devdoc>
        protected virtual void OnRenderLabelBackground(ToolStripItemRenderEventArgs e) {
            if (RendererOverride != null) {
                RendererOverride.OnRenderLabelBackground(e);
                return;
            }
       
 
        }
        /// <include file='doc\ToolStripRenderer.uex' path='docs/doc[@for="ToolStripRenderer.OnRenderMenuItemBackground"]/*' />
        /// <devdoc>
        /// Draw the items background
        /// </devdoc>
        protected virtual void OnRenderMenuItemBackground(ToolStripItemRenderEventArgs e) {
             if (RendererOverride != null) {
                 RendererOverride.OnRenderMenuItemBackground(e);
                 return;
             }
        }
        
        /// <include file='doc\ToolStripRenderer.uex' path='docs/doc[@for="ToolStripRenderer.OnRenderSeparator"]/*' />
        /// <devdoc>
        /// Draws a toolbar separator. ToolStrip users should override this function to change the 
        /// drawing of all separators.
        /// </devdoc>
        protected virtual void OnRenderSeparator(ToolStripSeparatorRenderEventArgs e) {
            if (RendererOverride != null) {
                RendererOverride.OnRenderSeparator(e);
                return;
            }
 
        }
 
        protected virtual void OnRenderToolStripPanelBackground(ToolStripPanelRenderEventArgs e) {
            if (RendererOverride != null) {
                RendererOverride.OnRenderToolStripPanelBackground(e);
                return;
            }
        }
 
        protected virtual void OnRenderToolStripContentPanelBackground(ToolStripContentPanelRenderEventArgs e) {
            if (RendererOverride != null) {
                RendererOverride.OnRenderToolStripContentPanelBackground(e);
                return;
            }
        }
 
        /// <include file='doc\WinBarRenderer.uex' path='docs/doc[@for="ToolStripRenderer.OnRenderStatusStripPanelBackground"]/*' />
        protected virtual void OnRenderToolStripStatusLabelBackground(ToolStripItemRenderEventArgs e) {
            if (RendererOverride != null) {
                RendererOverride.OnRenderToolStripStatusLabelBackground(e);
                return;
            }
        }
        
        protected virtual void OnRenderStatusStripSizingGrip(ToolStripRenderEventArgs e) {
            if (RendererOverride != null) {
                RendererOverride.OnRenderStatusStripSizingGrip(e);
                return;
            }
               
            Graphics g = e.Graphics;
            StatusStrip statusStrip = e.ToolStrip as StatusStrip;
 
            // we have a set of stock rectangles.  Translate them over to where the grip is to be drawn
            // for the white set, then translate them up and right one pixel for the grey.
   
 
            if (statusStrip != null) {
                Rectangle sizeGripBounds = statusStrip.SizeGripBounds;
 
                if (!LayoutUtils.IsZeroWidthOrHeight(sizeGripBounds)) {
                    Rectangle[] whiteRectangles = new Rectangle[baseSizeGripRectangles.Length];
                    Rectangle[] greyRectangles = new Rectangle[baseSizeGripRectangles.Length];
                    
                    for (int i = 0; i < baseSizeGripRectangles.Length; i++) {
                        Rectangle baseRect = baseSizeGripRectangles[i];
                        if (statusStrip.RightToLeft == RightToLeft.Yes) {
                            baseRect.X = sizeGripBounds.Width - baseRect.X - baseRect.Width;
                        }
                        baseRect.Offset(sizeGripBounds.X, sizeGripBounds.Bottom - 12 /*height of pyramid (10px) + 2px padding from bottom*/);
                        whiteRectangles[i] = baseRect;
                        if (statusStrip.RightToLeft == RightToLeft.Yes) {
                            baseRect.Offset(1, -1);
                        }
                        else {
                            baseRect.Offset(-1, -1);
                        }
                        greyRectangles[i] = baseRect;
                    
                    }
                    
                    g.FillRectangles(SystemBrushes.ButtonHighlight, whiteRectangles);
                    g.FillRectangles(SystemBrushes.ButtonShadow, greyRectangles);
                }
            }
     
        }
        /// <include file='doc\ToolStripRenderer.uex' path='docs/doc[@for="ToolStripRenderer.OnRenderSplitButtonBackground"]/*' />
        /// <devdoc>
        /// Draw the item's background.
        /// </devdoc>
        protected virtual void OnRenderSplitButtonBackground(ToolStripItemRenderEventArgs e) {
            if (RendererOverride != null) {
                RendererOverride.OnRenderSplitButtonBackground(e);
                return;
            }
        }
 
        // VSWhidbey 252459: only paint background effects if no backcolor has been set or no background image has been set.
        internal bool ShouldPaintBackground (Control control) {
            return (control.RawBackColor == Color.Empty && control.BackgroundImage == null);
        }
 
        private static Image CreateDisabledImage(Image normalImage, ImageAttributes imgAttrib) {
            if (imgAttrib == null) {
                imgAttrib = new ImageAttributes();
            }
 
            imgAttrib.ClearColorKey();
            imgAttrib.SetColorMatrix(DisabledImageColorMatrix);
 
            Size size = normalImage.Size;
            Bitmap disabledBitmap = new Bitmap(size.Width, size.Height);
            using (Graphics graphics = Graphics.FromImage(disabledBitmap)) {
 
                graphics.DrawImage(normalImage,
                                   new Rectangle(0, 0, size.Width, size.Height),
                                   0, 0, size.Width, size.Height,
                                   GraphicsUnit.Pixel,
                                   imgAttrib);
            }
 
            return disabledBitmap;
        }
 
        }
}