1 module magicalrainbows.properties;
2 
3 import magicalrainbows.utils;
4 
5 Precision relativeLuminosity(Precision = double, Colour)(const Colour colour) if(isColourFormat!Colour) {
6 	const linear = colour.asLinearRGB!Precision;
7 	return 0.2126 * linear.red +
8 		0.7152 * linear.green +
9 		0.0722 * linear.blue;
10 }
11 ///
12 @safe pure unittest {
13 	import magicalrainbows.formats : BGR555, RGB888;
14 	import std.math : isClose;
15 	assert(RGB888(0, 0, 0).relativeLuminosity.isClose(0.0));
16 	assert(RGB888(255, 255, 255).relativeLuminosity.isClose(1.0));
17 	assert(RGB888(250, 112, 20).relativeLuminosity.isClose(0.3196284130));
18 	assert(BGR555(0, 16, 31).relativeLuminosity.isClose(0.2361773154));
19 }
20 
21 Precision contrast(Precision = double, Colour1, Colour2)(const Colour1 colour1, const Colour2 colour2) if (isColourFormat!Colour1 && isColourFormat!Colour2) {
22 	import std.algorithm.comparison : max, min;
23 	const L1 = colour1.relativeLuminosity!Precision;
24 	const L2 = colour2.relativeLuminosity!Precision;
25 	return (max(L1, L2) + 0.05) / (min(L1, L2) + 0.05);
26 }
27 ///
28 @safe pure unittest {
29 	import magicalrainbows.formats : RGB888;
30 	import std.math : isClose;
31 	assert(contrast(RGB888(0, 0, 0), RGB888(0, 0, 0)).isClose(1.0));
32 	assert(contrast(RGB888(0, 0, 0), RGB888(255, 255, 255)).isClose(21.0));
33 	assert(contrast(RGB888(255, 255, 255), RGB888(0, 0, 0)).isClose(21.0));
34 	assert(contrast(RGB888(255, 255, 255), RGB888(250, 112, 20)).isClose(2.8406907130));
35 }
36 
37 Colour complementary(Colour)(const Colour colour) if (isColourFormat!Colour) {
38 	Colour result;
39 	static if (hasRed!Colour) {
40 		result.red = colour.red^maxRed!Colour;
41 	}
42 	static if (hasGreen!Colour) {
43 		result.green = colour.green^maxGreen!Colour;
44 	}
45 	static if (hasBlue!Colour) {
46 		result.blue = colour.blue^maxBlue!Colour;
47 	}
48 	return result;
49 }
50 ///
51 @safe pure unittest {
52 	import magicalrainbows.formats : RGB888;
53 	assert(RGB888(0, 0, 0).complementary == RGB888(255, 255, 255));
54 	assert(RGB888(255, 255, 255).complementary == RGB888(0, 0, 0));
55 	assert(RGB888(0, 255, 255).complementary == RGB888(255, 0, 0));
56 	assert(RGB888(0, 128, 0).complementary == RGB888(255, 127, 255));
57 }