W3 Contrast Ratio Function

  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.


Function Source Code
' 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
'
Demo Source Code
#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?