You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

230 lines
6.3 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE muclient>
<!-- Saved on Saturday, May 12, 2018, 12:51 AM -->
<!-- MuClient version 5.06-pre -->
<!-- Plugin "Contrast_Picker" generated by Plugin Wizard -->
<muclient>
<plugin
name="Contrast_Picker"
author="Crowley"
id="977138a7afb5ab493795edb7"
language="Lua"
purpose="Checks contrast ratios to pick better contrasting colors."
save_state="y"
date_written="2018-05-12 00:48:25"
requires="4.80"
version="1.0"
>
</plugin>
<!-- Aliases -->
<aliases>
<alias
script="onCommand"
match="^contrast (.*?)(?:\s(.*?))?(?:\s(.*?))?$"
enabled="y"
group="ContrastChecker"
regexp="y"
send_to="12"
sequence="100"
>
</alias>
</aliases>
<!-- Script -->
<script>
<![CDATA[
-- APCA Contrast Plugin
--[[ 1) HTML color list ]]
local color_table = {
"black","navy","darkblue","mediumblue","blue","royalblue","cornflowerblue",
"deepskyblue","lightskyblue","skyblue","lightblue","powderblue","lightsteelblue",
"steelblue","cadetblue","darkcyan","teal","aqua","cyan","lightcyan",
"mediumspringgreen","springgreen","mediumseagreen","seagreen","forestgreen",
"green","darkgreen","lawngreen","chartreuse","greenyellow","lime","limegreen",
"palegreen","lightgreen","darkolivegreen","olivedrab","yellow","lightyellow",
"lemonchiffon","lightgoldenrodyellow","papayawhip","moccasin","peachpuff",
"palegoldenrod","khaki","darkkhaki","gold","orange","darkorange","coral",
"tomato","orangered","red","darkred","firebrick","crimson","indianred",
"lightcoral","darksalmon","salmon","lightsalmon","sandybrown","peru","chocolate",
"darkgoldenrod","goldenrod","lightgray","silver","gray","darkgray","dimgray",
"lightslategray","slategray","darkslategray","white","snow","ghostwhite",
"whitesmoke","gainsboro","floralwhite","oldlace","linen","antiquewhite","beige",
"ivory","azure","aliceblue","lavender","lavenderblush","mistyrose","thistle",
"plum","violet","orchid","fuchsia","magenta","mediumorchid","darkorchid",
"darkviolet","blueviolet","purple","indigo"
}
--[[ 2) APCA constants & helpers ]]
local SA98G = {
mainTRC = 2.4,
sRco = 0.2126729,
sGco = 0.7151522,
sBco = 0.0721750,
normBG = 0.56,
normTXT = 0.57,
revBG = 0.62,
revTXT = 0.65,
loBoWoffset = 0.027,
loWoBoffset = 0.027,
deltaYmin = 0.0005,
loClip = 0.1,
scaleBoW = 1.14,
scaleWoB = 1.14,
}
local function clamp(x, lo, hi)
if x < lo then return lo end
if x > hi then return hi end
return x
end
-- unpack a 24-bit ColourNameToRGB() integer into r,g,b
local function unpackRGB(n)
local b = n % 256; n = math.floor(n/256)
local g = n % 256; n = math.floor(n/256)
local r = n % 256
return r, g, b
end
-- sRGB int or {r,g,b,a} → perceptual Y [0..1]
local function sRGBtoY(c)
local r,g,b
if type(c) == "table" then
r,g,b = c[1], c[2], c[3]
else
r,g,b = unpackRGB(tonumber(c))
end
local rn = (r/255)^SA98G.mainTRC
local gn = (g/255)^SA98G.mainTRC
local bn = (b/255)^SA98G.mainTRC
return SA98G.sRco*rn + SA98G.sGco*gn + SA98G.sBco*bn
end
-- blend fg {r,g,b,a} over bg {r,g,b,a}
local function alphaBlend(fg,bg)
local a = clamp(fg[4] or 1,0,1)
return {
fg[1]*a + bg[1]*(1-a),
fg[2]*a + bg[2]*(1-a),
fg[3]*a + bg[3]*(1-a),
1
}
end
-- APCA contrast: txtY & bgY in [0..1], returns signed Lᶜ
local function APCAcontrast(txtY, bgY, places)
txtY, bgY = clamp(txtY,0,1.1), clamp(bgY,0,1.1)
if math.abs(bgY - txtY) < SA98G.deltaYmin then return 0 end
local out
if bgY > txtY then
out = (bgY^SA98G.normBG - txtY^SA98G.normTXT) * SA98G.scaleBoW
if bgY < SA98G.loClip then out = out - SA98G.loBoWoffset end
else
out = (bgY^SA98G.revBG - txtY^SA98G.revTXT) * SA98G.scaleWoB
if txtY < SA98G.loClip then out = out + SA98G.loWoBoffset end
out = -out
end
if places and places >= 0 then
out = tonumber(string.format("%."..places.."f", out))
end
return out
end
-- convenience: takes two 24-bit ints or RGBA tables, handles alpha, returns Lᶜ
local function calcAPCA(fg, bg, places)
local fgC, bgC = fg, bg
if type(fgC)=="table" and fgC[4] then fgC = alphaBlend(fgC, bgC) end
return APCAcontrast( sRGBtoY(fgC), sRGBtoY(bgC), places or -1 )
end
--[[ 3) Precompute color codes ]]
local contrast_colors = {}
for _, name in ipairs(color_table) do
contrast_colors[#contrast_colors+1] = {
name = name,
code = ColourNameToRGB(name)
}
end
--[[ 4) The improved contrast command ]]
local function checkColorAPCA(fg_name, start_i, end_i)
local fg = (fg_name or ""):lower()
local fg_code = ColourNameToRGB(fg)
if fg == "" or fg_code == 0 then
Note("Unknown or missing color: "..tostring(fg_name))
return
end
-- build list with signed contrast and absolute score
local list = {}
for _, entry in ipairs(contrast_colors) do
local c = calcAPCA(fg_code, entry.code, 2)
list[#list+1] = {
bg_name = entry.name,
contrast = c,
score = math.abs(c),
}
end
-- sort by descending absolute contrast
table.sort(list, function(a,b) return a.score > b.score end)
-- sanitize slice bounds
local cnt = #list
start_i = clamp(tonumber(start_i) or 1, 1, cnt)
end_i = clamp(tonumber(end_i) or math.min(20, cnt), start_i, cnt)
Note("APCA contrast rankings for “"..fg.."”:")
for i = start_i, end_i do
local e = list[i]
local mode = (e.contrast > 0) and "dark-on-light" or "light-on-dark"
-- report the background name explicitly:
ColourNote(
fg,
e.bg_name,
string.format(
"%2d) on %-20s L = %6.2f (%s)",
i, e.bg_name, e.contrast, mode
)
)
end
end
--[[ 5) Hook up to MUSHClient ]]
function onCommand(name, line, args)
if args[1] and args[1]:upper()=="HELP" then
Note("APCA Contrast Help:")
Note(" contrast help this text")
Note(" contrast <fg> top 20 backgrounds")
Note(" contrast <fg> <start> <end> show ranks startend")
Note("* <fg> must be a standard HTML color name")
else
checkColorAPCA(args[1], args[2], args[3])
end
end
function OnPluginInstall()
if not GetVariable("apca_shown") then
Note("Type “contrast help” for next-gen APCA-based contrast rankings.")
SetVariable("apca_shown", "1")
end
end
]]>
</script>
</muclient>