Bug 161766 - [UI] Cell background color #00FF00 (green) with font color set to Automatic gives a white font that is nearly unreadable
Summary: [UI] Cell background color #00FF00 (green) with font color set to Automatic g...
Status: RESOLVED FIXED
Alias: None
Product: LibreOffice
Classification: Unclassified
Component: Calc (show other bugs)
Version:
(earliest affected)
24.2.4.2 release
Hardware: All All
: medium normal
Assignee: Not Assigned
URL:
Whiteboard: target:25.2.0
Keywords: accessibility
: 162269 163143 (view as bug list)
Depends on:
Blocks: Color-Palettes
  Show dependency treegraph
 
Reported: 2024-06-24 18:36 UTC by LeroyG
Modified: 2024-09-25 11:02 UTC (History)
10 users (show)

See Also:
Crash report or crash signature:


Attachments
Sample file to test (13.27 KB, application/vnd.oasis.opendocument.spreadsheet)
2024-06-24 18:37 UTC, LeroyG
Details
Screenshot from version 24.2 (6.82 KB, image/png)
2024-06-24 18:37 UTC, LeroyG
Details
Screenshot from version 7.6 (5.19 KB, image/png)
2024-06-24 18:37 UTC, LeroyG
Details

Note You need to log in before you can comment on or make changes to this bug.
Description LeroyG 2024-06-24 18:36:41 UTC
Description:
As in Summary.
There is no problem if the background is set to #FF0000 (red) or #0000FF (blue)

Version 7.6.7.2 don't show this behaviour.

Steps to Reproduce:
1. Set the cell background color to #00FF00 (green)
2. Leave font color in Automatic

Actual Results:
Font is shown in white, that renders it nearly unreadable.

Expected Results:
Show the font in a dark color.


Reproducible: Always


User Profile Reset: No

Additional Info:
Reproducible with:
Version: 24.2.4.2 (x86) / LibreOffice Community
Build ID: 51a6219feb6075d9a4c46691dcfe0cd9c4fff3c2
CPU threads: 4; OS: Windows 6.1 Service Pack 1 Build 7601; UI render: Skia/Raster; VCL: win
Locale: es-MX (es_MX); UI: es-ES
Calc: threaded
Comment 1 LeroyG 2024-06-24 18:37:06 UTC
Created attachment 194931 [details]
Sample file to test
Comment 2 LeroyG 2024-06-24 18:37:28 UTC
Created attachment 194932 [details]
Screenshot from version 24.2
Comment 3 LeroyG 2024-06-24 18:37:49 UTC
Created attachment 194933 [details]
Screenshot from version 7.6
Comment 4 m_a_riosv 2024-06-24 22:50:49 UTC
Could be a duplicate?
https://bugs.documentfoundation.org/show_bug.cgi?id=157618
Comment 5 Regina Henschel 2024-06-24 23:57:52 UTC
Black would be better readable.

There exist calculation rules in https://www.w3.org/TR/WCAG21. Perhaps it should be considered to use that rules to determine the threshold for switching between white and black text color?

(In reply to m_a_riosv from comment #4)
> Could be a duplicate?
> https://bugs.documentfoundation.org/show_bug.cgi?id=157618

I don't think so. The switch between white and black text color works in principle in Version: 25.2.0.0.alpha0+ (X86_64) / LibreOffice Community
Build ID: aaf2967d74a9a7ba2d28433e1872422ce38b6244
CPU threads: 32; OS: Windows 11 X86_64 (10.0 build 22631); UI render: default; VCL: win
Locale: de-DE (de_DE); UI: en-US
Calc: default
However, the threshold value for the switch could be set better for greenish colors.
Comment 6 ady 2024-06-25 00:29:46 UTC
Let's CC Heiko, since he is responsible of the changed threshold (not so long ago, IIRC).
Comment 7 Heiko Tietze 2024-06-25 08:56:12 UTC
The calculation (actually only the threshold) was changed for bug 156182. Tinkering with this breaks existing documents and affects compatibility. But it might be necessary.
Comment 8 LeroyG 2024-06-25 12:09:39 UTC
Related Q&A in Portuguese:
https://ask.libreoffice.org/t/fonte-mudando-de-cor-ao-mudar-a-cor-do-fundo-da-celula/107080
Setting the background color to #11FF11 is a workaround.
Comment 9 Myndex 2024-06-27 01:01:55 UTC
I get the impression here that the issue is not with the threshold, but some other issue in how an automatic text color is chosen?

I do recall from #156182 that only the threshold was changed, as a compromise solution. It was a compromise as still the incorrect coefficients (and lack of linearization) were being used to calculate lightness. As I understand it, the calculation is still:

aLum = (Red(aColor) * 76 + Green(aColor) * 151 + Blue(aColor) * 29) / 256

Which is incorrect but has the advantage of some computational simplicity. The coefficients 76,151,29 relate to the obsolete NTSC system, which has been dead for about two decades. These are still used for some "standard def" video for legacy reasons, but don't relate to modern displays.

The incorrectness here is most visible in saturated green. An immediate improvement can be had by swapping out the coefficients with those more related to modern sRGB displays:

aLum = (Red(aColor) * 56 + Green(aColor) * 182 + Blue(aColor) * 18) / 256

Threshold = 154



And if saving cycles is important, this can be simplified to remove the division:


aLum = (Red(aColor) * 2 + Green(aColor) * 7 + Blue(aColor))

Threshold = 1540


MORE ACCURATE METHODS AVAILABLE

We've done a lot of research here and it's not necessary to re-invent anything, but real improvements make it necessary to incorporate more correct color science into this project. If you want a finer and more accurate way to set text either black or white, we have a "most simple but correct" version of a text color flipper at the MaxContrast repo:

https://github.com/Myndex/max-contrast

This addresses lightness contrast only, and does not address the font weight (which is  also important, but hey, baby steps...)

A key factor missing in the LibreOffice calculation is that gamma encoded colors need to be linearized before applying the coefficients. If linearization is not performed, then you'll experiences the kinds of errors noted in this bug.


-----

@Regina: the calculation rules listed in WCAG 2.x are incorrect, and fail badly for dark color pairs. WCAG 2.x contrast math should not be used, and the results from WCAG 2.x math have been shown to be harmful to readability for those with color vision deficiencies.



-----


SUMMARY OF THE COLOR SCIENCE

#00ff00 should calculate so that it is paired with black. In fact, from about #0b0 up to #0f0 should pair with black. Darker than #0b0 can pair with white.

All red-only #n00 or blue-only #00n should pair with white.

Reason: the majority of luminance (lightness) is "green" and comes from the green primary on a display. Blue makes up 7% at most, and red about 22%.

Luminance/lightness contrast is what is needed to view text. Contrast middle is about #a2a2a2, though there are a number of factors at play, and the actual perceptual middle can vary between about #999 and #b0b0b0.

#a2a2a2 is a reasonable flip point. For saturated colors, the equivalent luminance is 0.36 Y, and this requires that the appropriate coefficients are used to weight the R,G, and B primaries.

This was discussed in the original bug:
https://bugs.documentfoundation.org/show_bug.cgi?id=156182


----

The JS code from the Max Contrast repo https://github.com/Myndex/max-contrast.
Send it RGB ints, it returns a string (or however you want to define black/white)


function maxContrast (sR = 0xa4, sG = 0xa4, sB = 0xa4) {
  
  const trc = 2.4, sRco = 0.2126729, sGco = 0.7151522, sBco = 0.0721750; 
  const flipY = 0.342; // based on APCA™ 0.98G-4g middle BG color

  let screenY = (sR/255.0)**trc*sRco + (sG/255.0)**trc*sGco + (sB/255.0)**trc*sBco; 

  return screenY < flipY ? 'white' : 'black'
}

Alternately, of course:

   return screenY < flipY ? 1 : 0  // return 1 for white 0 for black
or
   return screenY < flipY ? 0xffffffff : 0xff000000    // return ARGB hex value


And the ** is the JS exponent operator, so for other languages:

  screenY = pow((sR/255.0),trc) * sRco + (pow((sG/255.0),trc) * sGco + pow((sB/255.0),trc) * sBco; 



The MaxContrast function is the simplest but accurate, color-only model. Further accuracy can be had by also incorporating spatial contexts (such as font weight) and surrounding contexts, but that is a much bigger fish to fry.


Thank you for reading,

Andy


Andrew Somers
Director of Research
Inclusive Reading Technologies, Inc.

https://readtech.org/ARC/
Comment 10 bchemnet 2024-06-28 15:10:29 UTC
While I understand the rationale for this change in behavior with version 24, could we please have an option to disable it?  I don't want white text, ever.  If the cell text spills over into an adjacent cell which has not been formatted, that text is no longer visible (white on white).  And frankly, the white looks pretty terrible/unreadable most of the time when it is triggered automatically, even in the highlighted cells.

This change has visually broken many of my documents now that I recently updated.  Obviously I can solve it by changing all of the text in all the documents to "black" instead of "automatic", except that some of those documents do have specific font color changes and so it becomes a real headache to have to manually recreate all those specific changes after a blanket change to stop this annoying behavior.
Comment 11 Mike Kaganski 2024-07-02 07:51:28 UTC
(In reply to Myndex from comment #9)
> We've done a lot of research here and it's not necessary to re-invent
> anything, but real improvements make it necessary to incorporate more
> correct color science into this project. If you want a finer and more
> accurate way to set text either black or white, we have a "most simple but
> correct" version of a text color flipper at the MaxContrast repo:
> 
> https://github.com/Myndex/max-contrast

Note, that we can't use the (derivatives of) max-contrast in our project, because it's GPLv3.
Comment 12 Heiko Tietze 2024-07-02 07:54:55 UTC
Looked into the topic. While changing the calculation is simple, and adding an option to return to the legacy calculation would be possible too, it has a lot of impacts: RGB(128,128,128) previously being at the exact mid luminance now clear below, disabled objects become colored slightly different, SVG export of semi-transparent shapes is different, etc.

We test as many functions as possible to ensure the application to be stable. Don't know how many of those unit tests need to be modified, or where it rather makes sense to adjust the processing.
Comment 13 Mike Kaganski 2024-07-02 07:58:33 UTC
(In reply to bchemnet from comment #10)
> While I understand the rationale for this change in behavior with version
> 24, could we please have an option to disable it?  I don't want white text,
> ever.

You had always had this option. Use explicit colors, not auto. The automatic color of text is, *by definition*, the color that is black on light backgrounds, and white on dark. No option is needed to change that. Users who don't need automatic behavior must not use automatic colors.
Comment 14 Mike Kaganski 2024-07-02 08:00:20 UTC
(In reply to Heiko Tietze from comment #12)

We may change unit tests, it the change is reasonable (it really seems so). Also, we need to add more unit tests to check the legacy mode.

Of course, such a change is a big one, and is not just a bugfix (so it's for release notes of a new version).
Comment 15 Mike Kaganski 2024-07-02 08:04:49 UTC
(In reply to Mike Kaganski from comment #14)

Note also, that this change needs a compatibility option in documents, not a setting in user preferences. Old documents must retain their look. New documents need to use the new algorithm. This BTW allows to keep old unit tests pass without modifications.
Comment 16 Heiko Tietze 2024-07-30 15:41:53 UTC
*** Bug 162269 has been marked as a duplicate of this bug. ***
Comment 17 Commit Notification 2024-08-16 06:56:37 UTC
Heiko Tietze committed a patch related to this issue.
It has been pushed to "master":

https://git.libreoffice.org/core/commit/74d910231c5591f5e497fc52f2a0132c8f41a271

Resolves tdf#161766 - WCAG 2.1 compliant luminance for isDark()

It will be available in 25.2.0.

The patch should be included in the daily builds available at
https://dev-builds.libreoffice.org/daily/ in the next 24-48 hours. More
information about daily builds can be found at:
https://wiki.documentfoundation.org/Testing_Daily_Builds

Affected users are encouraged to test the fix and report feedback.
Comment 18 Heiko Tietze 2024-09-25 11:02:30 UTC
*** Bug 163143 has been marked as a duplicate of this bug. ***