Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Correct System.Windows.Forms.ControlPaint.HSLColor.Darker function #12586

Open
paulthegreat opened this issue Dec 4, 2024 · 0 comments
Open
Assignees
Labels
api-suggestion (1) Early API idea and discussion, it is NOT ready for implementation untriaged The team needs to look at this issue in the next triage

Comments

@paulthegreat
Copy link

Background and motivation

At least since .NET Framework 4, the System.WIndows.Forms.ControlPaint.HSLColor.Darker function (which is called by System.Windows.Forms.ControlPaint.Dark()) has been wrong for non-system colors.

The Lighter function logically interpolates, based on the passed percentage value, from the current luminosity towards a luminosity value 50% higher. The Darker function illogically interpolates, based on the passed percentage value, from a luminosity value 33% lower than the current luminosity towards zero.

A call to Lighter(0) reasonably returns the same color. A call to Darker(0) unreasonably returns a color 33% darker. Lighter(0.5) returns a color 25% lighter; Darker(0.5) returns a color 67% darker. Lighter(1) returns a color 50% lighter; Darker(1) returns black.

API Proposal

namespace System.Windows.Forms;

public static partial class ControlPaint
{
    private readonly struct HLSColor : IEquatable<HLSColor>
    {
        public Color Darker(float percDarker)
        {
            if (!_isSystemColors_Control)
            {
                // *** this block is the only changed code ***
                // match the Lighter function and use current luminosity as a baseline instead of zero
                int zeroLum = luminosity;
                int oneLum = NewLuma(ShadowAdjustment, true);
                return ColorFromHLS(_hue, zeroLum + (int)((oneLum - zeroLum) * percDarker), _saturation);
            }
            else
            {
                // With the usual color scheme, ControlDark/DarkDark is not exactly
                // what we would otherwise calculate
                if (percDarker == 0.0f)
                {
                    return SystemColors.ControlDark;
                }
                else if (percDarker == 1.0f)
                {
                    return SystemColors.ControlDarkDark;
                }
                else
                {
                    ARGB dark = SystemColors.ControlDark;
                    ARGB darkDark = SystemColors.ControlDarkDark;

                    return Color.FromArgb(
                        (byte)(dark.R - (byte)((dark.R - darkDark.R) * percDarker)),
                        (byte)(dark.G - (byte)((dark.G - darkDark.G) * percDarker)),
                        (byte)(dark.B - (byte)((dark.B - darkDark.B) * percDarker)));
                }
            }
        }
    }
}

API Usage

using System.Drawing.Color;

Color c = Color.FromArgb(128, 128, 128);
Color sameColor = System.Windows.Forms.ControlPaint.Dark(c, 0.0);
Color darkColor = System.Windows.Forms.ControlPaint.Dark(c, 0.5);
Color darkerColor = System.Windows.Forms.ControlPaint.Dark(c, 1.0);

Color approxSameColor = System.Windows.Forms.ControlPaint.Light(System.Windows.Forms.ControlPaint.Dark(c));
Color approxSameColor2 = System.Windows.Forms.ControlPaint.Dark(System.Windows.Forms.ControlPaint.Light(c));

Alternative Designs

No response

Risks

No response

Will this feature affect UI controls?

Yes.

  • no
  • none
  • no
@paulthegreat paulthegreat added api-suggestion (1) Early API idea and discussion, it is NOT ready for implementation untriaged The team needs to look at this issue in the next triage labels Dec 4, 2024
@paulthegreat paulthegreat changed the title Correct System.WIndows.Forms.ControlPaint.HSLColor.Darker function Correct System.Windows.Forms.ControlPaint.HSLColor.Darker function Dec 4, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api-suggestion (1) Early API idea and discussion, it is NOT ready for implementation untriaged The team needs to look at this issue in the next triage
Projects
None yet
Development

No branches or pull requests

2 participants