colorutils_rs/
routines.rs1#[macro_export]
9macro_rules! color_dodge {
10 ($base: expr, $other: expr) => {{
11 if $other == 1.0 {
12 $other
13 } else {
14 ($base / (1.0 - $other)).min(1.)
15 }
16 }};
17}
18
19#[macro_export]
20macro_rules! color_linear_burn {
21 ($base: expr, $other: expr) => {{
22 ($base + $other - 1.).max(0.)
23 }};
24}
25
26#[macro_export]
27macro_rules! color_burn {
28 ($base: expr, $other: expr) => {{
29 if $other == 0.0 {
30 $other
31 } else {
32 (1.0 - ((1.0 - $base) / $other)).max(0.)
33 }
34 }};
35}
36
37#[macro_export]
38macro_rules! color_darken {
39 ($base: expr, $other: expr) => {{
40 $base.min($other)
41 }};
42}
43
44#[macro_export]
45macro_rules! color_lighten {
46 ($base: expr, $other: expr) => {{
47 $base.max($other)
48 }};
49}
50
51#[macro_export]
52macro_rules! color_screen {
53 ($base: expr, $other: expr) => {{
54 $base + $other - $base * $other
55 }};
56}
57
58#[macro_export]
59macro_rules! color_add {
60 ($base: expr, $other: expr) => {{
61 ($base + $other).min(1.)
62 }};
63}
64
65#[macro_export]
66macro_rules! color_linear_light {
67 ($base: expr, $other: expr) => {{
68 if $other < 0.5 {
69 color_linear_burn!($base, (2.0 * $other))
70 } else {
71 color_add!($base, (2.0 * ($other - 0.5)))
72 }
73 }};
74}
75
76#[macro_export]
77macro_rules! color_vivid_light {
78 ($base: expr, $other: expr) => {{
79 if $other < 0.5 {
80 color_burn!($base, (2.0 * $other))
81 } else {
82 color_dodge!($base, (2.0 * ($other - 0.5)))
83 }
84 }};
85}
86
87#[macro_export]
88macro_rules! color_pin_light {
89 ($base: expr, $other: expr) => {{
90 if $other < 0.5 {
91 color_darken!($base, (2.0 * $other))
92 } else {
93 color_lighten!($base, (2.0 * ($other - 0.5)))
94 }
95 }};
96}
97
98#[macro_export]
99macro_rules! color_hard_mix {
100 ($base: expr, $other: expr) => {{
101 if color_vivid_light!($base, $other) < 0.5 {
102 0.
103 } else {
104 1.
105 }
106 }};
107}
108
109#[macro_export]
110macro_rules! color_reflect {
111 ($base: expr, $other: expr) => {{
112 if $other == 1.0 {
113 $other
114 } else {
115 ($base * $base / (1.0 - $other)).min(1.)
116 }
117 }};
118}
119
120#[macro_export]
121macro_rules! color_difference {
122 ($base: expr, $other: expr) => {{
123 ($base - $other).abs()
124 }};
125}
126
127#[macro_export]
128macro_rules! pdf_lum {
129 ($base: expr) => {{
130 0.3 * $base.r + 0.59 * $base.g + 0.11 * $base.g
131 }};
132}
133
134#[macro_export]
135macro_rules! clip_color {
136 ($base: expr) => {{
137 let l = pdf_lum!($base);
138 let n = $base.r.min($base.g).min($base.b);
139 let x = $base.r.max($base.g).max($base.b);
140 let (mut r, mut g, mut b) = ($base.r, $base.g, $base.b);
141 if n < 0.0 {
142 let recip = 1. / (l - n);
143 r = l + (((r - l) * l) * recip);
144 g = l + (((g - l) * l) * recip);
145 b = l + (((b - l) * l) * recip);
146 }
147 if x > 1.0 {
148 let recip = 1. / (x - l);
149 r = l + (((r - l) * (1. - l)) * recip);
150 g = l + (((g - l) * (1. - l)) * recip);
151 b = l + (((b - l) * (1. - l)) * recip);
152 }
153 (r, g, b)
154 }};
155}
156
157#[macro_export]
158macro_rules! color_hard_light {
159 ($base: expr, $other: expr) => {{
160 if $base <= 0.5 {
161 2. * $base * $other
162 } else {
163 1. - 2. * (1. - $base) * (1. - $other)
164 }
165 }};
166}
167
168#[macro_export]
169macro_rules! color_soft_light_weight {
170 ($x: expr) => {{
171 if ($x <= 0.25) {
172 ((16. * $x - 12.) * $x + 4.) * $x
173 } else {
174 $x.sqrt()
175 }
176 }};
177}
178
179#[macro_export]
180macro_rules! color_soft_light {
181 ($base: expr, $other: expr) => {{
182 if ($base <= 0.5) {
183 $other - (1. - 2. * $base) * $other * (1. - $other)
184 } else {
185 $other + (2.0 * $base - 1.) * (color_soft_light_weight!($other) - $other)
186 }
187 }};
188}
189
190#[macro_export]
191macro_rules! color_exclusion {
192 ($base: expr, $other: expr) => {{
193 $base + $other - 2. * $base * $other
194 }};
195}
196
197#[macro_export]
198macro_rules! adjust_saturation {
199 ($store: expr, $saturation: expr) => {{
200 let c1 = 0.213 + 0.787 * $saturation;
201 let c2 = 0.715 - 0.715 * $saturation;
202 let c3 = 0.072 - 0.072 * $saturation;
203
204 let c4 = 0.213 - 0.213 * $saturation;
205 let c5 = 0.715 + 0.285 * $saturation;
206 let c6 = 0.072 - 0.072 * $saturation;
207
208 let c7 = 0.213 - 0.213 * $saturation;
209 let c8 = 0.715 - 0.715 * $saturation;
210 let c9 = 0.072 + 0.928 * $saturation;
211 let r1 = $store.r * c1 + $store.g * c2 + $store.b * c3;
212 let g1 = $store.r * c4 + $store.g * c5 + $store.b * c6;
213 let b1 = $store.r * c7 + $store.g * c8 + $store.b * c9;
214 (r1, g1, b1)
215 }};
216}
217
218#[inline]
219pub(crate) fn op_color_dodge(a: f32, b: f32) -> f32 {
220 if b == 1.0 {
221 b
222 } else {
223 (a / (1.0 - b)).min(1.)
224 }
225}
226
227#[inline]
228pub(crate) fn op_screen(a: f32, b: f32) -> f32 {
229 color_screen!(a, b)
230}
231
232#[inline]
233pub(crate) fn op_color_burn(a: f32, b: f32) -> f32 {
234 color_burn!(a, b)
235}
236
237#[inline]
238pub(crate) fn op_darken(a: f32, b: f32) -> f32 {
239 a.min(b)
240}
241
242#[inline]
243pub(crate) fn op_lighten(a: f32, b: f32) -> f32 {
244 a.max(b)
245}
246
247#[inline]
248pub(crate) fn op_linear_burn(a: f32, b: f32) -> f32 {
249 color_linear_burn!(a, b)
250}
251
252#[inline]
253pub(crate) fn op_reflect(a: f32, b: f32) -> f32 {
254 color_reflect!(a, b)
255}
256
257#[inline]
258pub(crate) fn op_overlay(a: f32, b: f32) -> f32 {
259 if b < 0.5 {
260 2.0 * a * b
261 } else {
262 1.0 - 2.0 * (1.0 - a) * (1.0 - b)
263 }
264}
265
266#[inline]
267pub(crate) fn op_difference(a: f32, b: f32) -> f32 {
268 color_difference!(a, b)
269}
270
271#[inline]
272pub(crate) fn op_exclusion(a: f32, b: f32) -> f32 {
273 color_exclusion!(a, b)
274}
275
276#[inline]
277pub(crate) fn op_linear_light(a: f32, b: f32) -> f32 {
278 color_linear_light!(a, b)
279}
280
281#[inline]
282pub(crate) fn op_vivid_light(a: f32, b: f32) -> f32 {
283 color_vivid_light!(a, b)
284}
285
286#[inline]
287pub(crate) fn op_pin_light(a: f32, b: f32) -> f32 {
288 color_pin_light!(a, b)
289}
290
291#[inline]
292pub(crate) fn op_hard_mix(a: f32, b: f32) -> f32 {
293 color_hard_mix!(a, b)
294}
295
296#[inline]
297pub(crate) fn op_hard_light(a: f32, b: f32) -> f32 {
298 color_hard_light!(a, b)
299}
300
301#[inline]
302pub(crate) fn op_soft_light(a: f32, b: f32) -> f32 {
303 color_soft_light!(a, b)
304}