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

Re-enable the setting to adjust the colors of indistinguishable text #13343

Merged
9 commits merged into from
Jul 14, 2022

Conversation

PankajBhojwani
Copy link
Contributor

@PankajBhojwani PankajBhojwani commented Jun 20, 2022

Summary of the Pull Request

Re-enable the setting to adjust indistinguishable text, with some changes:

  • We now pre-calculate the nudged values for 'default bright foreground' as well
  • When a color table entry is manually set (i.e. via VT sequences) we re-calculate the nudged values

References

#11095 #12160

PR Checklist

Validation Steps Performed

Indistinguishable text gets adjusted again

@PankajBhojwani
Copy link
Contributor Author

PankajBhojwani commented Jun 20, 2022

In a follow-up, we will change the setting from a boolean value to an enum with 3 possible values: 'Never' to never adjust the text, 'Indexed' to only adjust the text if both the foreground/background are part of the current color scheme's color table (this is today's behaviour when the setting is set to "true"), and "Always" to always adjust the text if it is indistinguishable (this will be somewhat performance intensive since we will be calculating this at render time, but that is why it will be opt-in only)

lhecker
lhecker previously approved these changes Jun 21, 2022
Copy link
Member

@lhecker lhecker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't quite understand why we shouldn't nudge brightened colors. 🤔

@lhecker
Copy link
Member

lhecker commented Jun 21, 2022

this will be somewhat performance intensive since we will be calculating this at render time, but that is why it will be opt-in only

If performance turns out to be a problem we can use "redmean" still as I suggested offhand a while ago. I suspect it would work sufficiently well to determine a JND, since always nudging colors by 5 lightness is in a way a lot less "scientific" than the DeltaE algorithm itself, defeating its purpose a bit. This is the entire algorithm btw (output range 0-765):

double redmean(COLORREF c1, COLORREF c2) {
    int r1 = GetRValue(c1), g1 = GetGValue(c1), b1 = GetBValue(c1);
    int r2 = GetRValue(c2), g2 = GetGValue(c2), b2 = GetBValue(c2);
    int dr = r1 - r2;
    int dg = g1 - g2;
    int db = b1 - b2;
    int rmean = (r1 + r2) / 2;
    return sqrt((512 + rmean) * dr * dr / 256 + 4 * dg * dg + (767 - rmean) * db * db / 256);
}

@PankajBhojwani
Copy link
Contributor Author

I don't quite understand why we shouldn't nudge brightened colors. 🤔

The issue arises when the colors are reversed and the foreground is bright - we will need to calculate what 'bright background' means but we don't have an easy way to do that

@zadjii-msft zadjii-msft added this to the Terminal v1.16 milestone Jun 21, 2022
zadjii-msft
zadjii-msft previously approved these changes Jun 22, 2022
@PankajBhojwani PankajBhojwani marked this pull request as draft June 24, 2022 20:47
@PankajBhojwani PankajBhojwani marked this pull request as ready for review June 24, 2022 22:05
@PankajBhojwani PankajBhojwani dismissed stale reviews from zadjii-msft and lhecker June 24, 2022 22:06

PR has changed a little (sorry!!)

src/cascadia/TerminalSettingsModel/MTSMSettings.h Outdated Show resolved Hide resolved
src/renderer/base/RenderSettings.cpp Show resolved Hide resolved
@DHowett
Copy link
Member

DHowett commented Jun 24, 2022

(Noting @j4james here, as he said "Finally, I think having bold in the color table is an essential prerequisite for getting the bold color to work when the option to Automaticaly adjust lightness of indistinguishable text is enabled (see #11917).". We did not end up choosing to fix 11939 beforehand, but may take the fix introduced here as a TODO on landing #11939. I would rather totally get rid of GetColor, given that 90% of its purpose is this weird brightness hack, which would necessitate breaking the workaround in this code. We could localize its implementation in RenderSettings.)

@j4james
Copy link
Collaborator

j4james commented Jun 25, 2022

I think having bold in the color table is an essential prerequisite for getting the bold color to work

LOL. Clearly I was wrong, since the bold seems to working fine in this PR as far as I can tell.

That said, I still think this functionality should probably not be enabled by default, because there are going to be edges cases that don't work, and that's kind of inevitable when we're deliberately choosing to alter the colors that were requested.

As one example, if you're using a "standard" color scheme, like Campbell, where the default background is identical to black, and the default foreground is identical to white, then both these sequences should be invisible, but they aren't:

printf "\e[0;30mHIDDEN\e[m\n"
printf "\e[0;47mHIDDEN\e[m\n"

That particular case may be fixable, but there'll always be something. Having the default behavior be technically incorrect feels like we're asking for bug reports.

@j4james
Copy link
Collaborator

j4james commented Jun 25, 2022

I don't know how well this would work in practice, but one idea I had for improving the performance was to move the color remapping from the renderer to the SetGraphicsRendition method in AdaptDispatch. It wouldn't work in quite the same way, but I think it should still produce a similar effect. Not suggesting that for this PR, though - just a thought for a potential future enhancement.

@lhecker
Copy link
Member

lhecker commented Jun 27, 2022

I've had a think about this over the weekend. 🧠🤔
Not because I want to rudely intrude on other people's work more than necessary, but rather because I personally find this topic (rendering and thus the color topic) fascinating.

If we picture RGB colors as a 3D space and simplify things a bit, then the area below the JND (just-noticeable-difference of color) forms a simple sphere around our reference color. Within this coordinate system grayscale is the unit vector (1, 1, 1). Thus the question how much we need to brighten or darken the color of a point (= add or subtract such gray) so that it leaves the sphere of JND, becomes the calculation of a line-sphere intersection. This not just yields us immediately the 2 possible corrected colors, but also whether the line is within the sphere or not (= whether any adjustment needs to be done).

Of course the problem is that the MacAdam ellipse (the range of colors within the JND) is an ellipse/ellipsoid and not a sphere, but as mentioned before, redmean is a simple algorithm that apparently works sufficiently well and would allow us to scale the RGB axes to get an ellipsoid. The 3 scales would be, where R_0 is the red coordinate of the reference point (sphere center):

r = (2 + R_0 / 256) / 9
g = 4 / 9
b = (3 - R_0 / 256) / 9

Scaling the coordinates down by these factors ("squishing" the coordinate space), doing the line-sphere intersection and then scaling it back up should yield us appropriate results I believe.

In either case, in my testing this calculation can be done without any caching at all in real time (it wouldn't even show up in a perf trace) and (in a more limited testing) it seems to produce equally well adjusted colors. (Only the sqrt is a bit "problematic" but even that can be replaced with FRSQRTE/FRSQRTS on ARM64 and RSQRTSS on x86.)

@PankajBhojwani PankajBhojwani added the Needs-Discussion Something that requires a team discussion before we can proceed label Jun 27, 2022
@PankajBhojwani
Copy link
Contributor Author

Had a chat with @lhecker, turns out the red-mean algorithm is not quite robust enough and just doesn't work as well as the delta e one. So we will stick to this algorithm for now and in the future come back to optimizing the delta e algorithm (Leonard has several ideas for how we can do this).

I've also switched the setting back to default off as per James' suggestion

@PankajBhojwani PankajBhojwani removed the Needs-Discussion Something that requires a team discussion before we can proceed label Jun 29, 2022
@ghost ghost added the Product-Terminal The new Windows Terminal. label Jul 1, 2022
DHowett added a commit that referenced this pull request Jul 8, 2022
Copy link
Member

@zadjii-msft zadjii-msft left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm cool with this, but I'm gonna leave automerge off to give Dustin a last chance at it.

DHowett added a commit that referenced this pull request Jul 12, 2022
DHowett added a commit that referenced this pull request Jul 12, 2022
@zadjii-msft zadjii-msft added the AutoMerge Marked for automatic merge by the bot when requirements are met label Jul 14, 2022
@ghost
Copy link

ghost commented Jul 14, 2022

Hello @zadjii-msft!

Because this pull request has the AutoMerge label, I will be glad to assist with helping to merge this pull request once all check-in policies pass.

p.s. you can customize the way I help with merging this pull request, such as holding this pull request until a specific person approves. Simply @mention me (@msftbot) and give me an instruction to get started! Learn more here.

@ghost ghost merged commit 2c6cdc2 into main Jul 14, 2022
@ghost ghost deleted the dev/pabhoj/delta_e branch July 14, 2022 15:58
ghost pushed a commit that referenced this pull request Jul 22, 2022
…boolean setting (#13512)

## Summary of the Pull Request
`AdjustIndistinguishableColors` can now be set to:

- `Never`: Never adjust the colors
- `Indexed`: Only adjust colors that are part of the color scheme
- `Always`: Always adjust the colors

## References
#13343

## PR Checklist
* [ ] Closes #xxx
* [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
* [ ] Tests added/passed
* [ ] Documentation updated. If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/terminal) and link it here: #xxx
* [ ] Schema updated.
* [x] I've discussed this with core contributors already. If not checked, I'm ready to accept this work might be rejected in favor of a different grand plan. Issue number where discussion took place: #xxx

## Detailed Description of the Pull Request / Additional comments
For legacy purposes, `true` and `false` map to `Indexed` and `Never` respectively

## Validation Steps Performed
Setting still works
@ghost
Copy link

ghost commented Sep 13, 2022

🎉Windows Terminal Preview v1.16.252 has been released which incorporates this pull request.:tada:

Handy links:

@mailinglists35
Copy link

Hi, could you show an example of the relevant section of settings file where to enable this feature?
thanks

@mailinglists35
Copy link

Hi, could you show an example of the relevant section of settings file where to enable this feature? thanks

aha, figured out.

scroll to "profiles" to add it

    "profiles": 
    {
        "defaults": 
        {
            "adjustIndistinguishableColors": "always",
        },

This pull request was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
AutoMerge Marked for automatic merge by the bot when requirements are met Product-Terminal The new Windows Terminal.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

SGR 1 and SGR 8 don't work when adjusting lightness of indistinguishable text
6 participants