This function calculates the contrast ratio of a foreground to a background color by the W3.org algorithm. To verfify the function operates correctly the demo does two ratios to compare with Internet results. For white on gray Google.com replied with #767676 as the light shade for a ratio of 4.5:1. The result of this function called by the demo is 4.5422249560525. The second test was black on red background. webaim.org/resources/contrastchecker resulted in 5.25. The result of this function is 5.252. (note - Internet RGB is big endian ((RRGGBB)), while PB is little endian ((&h00BBGGRR.))red is first in binary here.)
The W3.org algorithm starts at www.w3.org/TR/WCAG21/#dfn-contrast-ratio with link to
www.w3.org/TR/WCAG21/#dfn-relative-luminance. That is reverse of the code
flow. Shown as they did, the algorithm is:
contrast ratio = (L1 + 0.05) / (L2 + 0.05) ''4.5:1 min enhanced 7:1
L1 is relative luminance of the lighter
L2 is relative luminance of the darker
on second W3 page
L = 0.2126 * R + 0.7152 * G + 0.0722 * B where
IF Rsrgb <= 0.04045 THEN
R = Rsrgb / 12.92
ELSE
R = ((Rsrgb + 0.055) / 1.055) ^ 2.4
END IF
Repeat the IF for G and B.
And, Rsrgb, Gsrgb and Bsrgb used above are:
RsRGB = R8bit /255
repeated for G & B.
The lower case s in RsRGB, GsRGB and BsRGB
stands for "standard"; just remember that was not my choice. That definition
was found at /www.tomshardware.com/reference...the%20colors%20portrayed%20by%20electronics
(who I never heard of, but looks reasonable)
W3.org used 12 variables in their text pseudocode. Here 2 input parameters, an optional third for output, the function result, and only two variables inside the function are used; half the number. L1 and L2 for lighter and darker, respectively, are replaced by L_Fore and L_Back. An IF/ELSE block insures the ration is always 1 or greater.
The function has no GUI or console specific statements, so can be used with either PBWin or PBCC. The demo/test has a TXT.WINDOW so it too may be compiled and run in PBWin or PBCC.
' filename W3_ContrastRatioSLL.bas #compile sll "W3_ContrastRatio.sll" #dim all ' function ContrastRatio(byval RGB_Fore as long, _ byval RGB_Back as long, _ opt byref ForeMoreLum as long) common as extended local SCRL as extended 'SingleColorRelativeLuminance, reused vs. 6 variables. local L_Fore, L_Back as extended 'Relative luminances, whether foreground or 'backgound is lighter reported in optional 'input parameter. '----------------------------------------------------------------------------- 'Color-by-color relative luminance to combined relative luminance. 'foreground red SCRL = (RGB_Fore and &h000000FF&) / 255## gosub RelLum L_Fore = (0.2126## * SCRL) 'foreground green shift right RGB_Fore, 8 SCRL = (RGB_Fore and &h000000FF&) / 255## gosub RelLum L_Fore += (0.7152## * SCRL) 'forground blue shift right RGB_Fore, 8 SCRL = (RGB_Fore and &h000000FF&) / 255## gosub RelLum L_Fore += (0.0722## * SCRL) 'background red ······························································ SCRL = (RGB_Back and &h000000FF&) / 255## gosub RelLum L_Back = (0.2126## * SCRL) 'background green shift right RGB_Back, 8 SCRL = (RGB_Back and &h000000FF&) / 255## gosub RelLum L_Back += (0.7152## * SCRL) 'background blue shift right RGB_Back, 8 SCRL = (RGB_Back and &h000000FF&) / 255## gosub RelLum L_Back += (0.0722## * SCRL) 'Ratio and optional foreground lighter than background. ······················ L_Fore += 0.05## 'Same both, no matter which is lighter; so why L_Back += 0.05## 'repeat addition code 4 time?. if L_Fore > L_Back then function = L_Fore / L_Back if varptr(ForeMoreLum) then ForeMoreLum = -1 end if else 'L_Fore is < or = function = L_Back / L_Fore if varptr(ForeMoreLum) then ForeMoreLum = 0 end if end if exit function 'don't "fall" into subroutine 'Calculate single color relative luminance - - - - - - - - - - - - - - - - - - RelLum: if SCRL <= 0.04045## then SCRL = SCRL / 12.92## else SCRL = ((SCRL + 0.055##) / 1.055##) ^ 2.4## end if return end function '
#compile exe #dim all %UNICODE = 1 #if %def(%pb_cc32) #console off #endif #link "./W3_ContrastRatio.sll" function pbmain () as long local hTWin as dword local ForeMoreLum as long local Ratio as extended txt.window "Demo of Contrast Ratio Function"$$, 200, 150, 12, 50 to hTWin ' '1st test txt.print "White foreground on gray background."$$ Ratio = ContrastRatio(&h00FFFFFF&, &h00767676&, ForeMoreLum) txt.print format$(Ratio) if ForeMoreLum then txt.print "Foreground is lighter."$$ else txt.print "Background is lighter."$$ end if txt.print string$$(50, &h2501) '2nd test txt.print "Black foreground on red background."$$ Ratio = ContrastRatio(&h00000000&, &h000000FF&, ForeMoreLum) txt.print format$(Ratio) if ForeMoreLum then txt.print "Foreground is lighter."$$ else txt.print "Background is lighter."$$ end if txt.print string$$(50, &h2501) txt.print txt.print "Any key to exit."$$ txt.waitkey$ txt.end end function
Full copyleft (ɔ), 2024 by Dale Yarker in source or compiled form. Complete license in new tab or window.
Created on 09 June 2024, updated 10 June 2024.
Done with this window?