-module(sparklinekit@internal@color).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/sparklinekit/internal/color.gleam").
-export([with_alpha/2, parse_hex/1, parse_or/2, over/2, to_hex_rgb/1, to_hex_rgba/1]).
-export_type([rgba/0]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
?MODULEDOC(false).
-type rgba() :: {rgba, integer(), integer(), integer(), integer()}.
-file("src/sparklinekit/internal/color.gleam", 72).
?DOC(false).
-spec with_alpha(rgba(), float()) -> rgba().
with_alpha(Rgba, Factor) ->
{rgba, R, G, B, A} = Rgba,
Clamped = case Factor of
F when F < +0.0 ->
+0.0;
F@1 when F@1 > 1.0 ->
1.0;
F@2 ->
F@2
end,
New_a = erlang:round(erlang:float(A) * Clamped),
{rgba, R, G, B, New_a}.
-file("src/sparklinekit/internal/color.gleam", 165).
?DOC(false).
-spec parse_nibble(binary()) -> {ok, integer()} | {error, nil}.
parse_nibble(Grapheme) ->
case string:lowercase(Grapheme) of
<<"0"/utf8>> ->
{ok, 0};
<<"1"/utf8>> ->
{ok, 1};
<<"2"/utf8>> ->
{ok, 2};
<<"3"/utf8>> ->
{ok, 3};
<<"4"/utf8>> ->
{ok, 4};
<<"5"/utf8>> ->
{ok, 5};
<<"6"/utf8>> ->
{ok, 6};
<<"7"/utf8>> ->
{ok, 7};
<<"8"/utf8>> ->
{ok, 8};
<<"9"/utf8>> ->
{ok, 9};
<<"a"/utf8>> ->
{ok, 10};
<<"b"/utf8>> ->
{ok, 11};
<<"c"/utf8>> ->
{ok, 12};
<<"d"/utf8>> ->
{ok, 13};
<<"e"/utf8>> ->
{ok, 14};
<<"f"/utf8>> ->
{ok, 15};
_ ->
{error, nil}
end.
-file("src/sparklinekit/internal/color.gleam", 154).
?DOC(false).
-spec parse_byte(binary()) -> {ok, integer()} | {error, nil}.
parse_byte(Pair) ->
case gleam@string:to_graphemes(Pair) of
[Hi, Lo] ->
gleam@result:'try'(
parse_nibble(Hi),
fun(Hi_v) ->
gleam@result:'try'(
parse_nibble(Lo),
fun(Lo_v) -> {ok, (Hi_v * 16) + Lo_v} end
)
end
);
_ ->
{error, nil}
end.
-file("src/sparklinekit/internal/color.gleam", 136).
?DOC(false).
-spec long_hex(binary(), boolean()) -> {ok, rgba()} | {error, nil}.
long_hex(Body, Full_alpha) ->
case Full_alpha of
true ->
gleam@result:'try'(
parse_byte(gleam@string:slice(Body, 0, 2)),
fun(R) ->
gleam@result:'try'(
parse_byte(gleam@string:slice(Body, 2, 2)),
fun(G) ->
gleam@result:'try'(
parse_byte(gleam@string:slice(Body, 4, 2)),
fun(B) -> {ok, {rgba, R, G, B, 255}} end
)
end
)
end
);
false ->
gleam@result:'try'(
parse_byte(gleam@string:slice(Body, 0, 2)),
fun(R@1) ->
gleam@result:'try'(
parse_byte(gleam@string:slice(Body, 2, 2)),
fun(G@1) ->
gleam@result:'try'(
parse_byte(gleam@string:slice(Body, 4, 2)),
fun(B@1) ->
gleam@result:'try'(
parse_byte(
gleam@string:slice(Body, 6, 2)
),
fun(A) ->
{ok, {rgba, R@1, G@1, B@1, A}}
end
)
end
)
end
)
end
)
end.
-file("src/sparklinekit/internal/color.gleam", 187).
?DOC(false).
-spec expand(integer()) -> integer().
expand(Nibble) ->
(Nibble * 16) + Nibble.
-file("src/sparklinekit/internal/color.gleam", 117).
?DOC(false).
-spec short_hex(binary(), boolean()) -> {ok, rgba()} | {error, nil}.
short_hex(Body, Full_alpha) ->
case {gleam@string:to_graphemes(Body), Full_alpha} of
{[R, G, B], true} ->
gleam@result:'try'(
parse_nibble(R),
fun(R_v) ->
gleam@result:'try'(
parse_nibble(G),
fun(G_v) ->
gleam@result:'try'(
parse_nibble(B),
fun(B_v) ->
{ok,
{rgba,
expand(R_v),
expand(G_v),
expand(B_v),
255}}
end
)
end
)
end
);
{[R@1, G@1, B@1, A], false} ->
gleam@result:'try'(
parse_nibble(R@1),
fun(R_v@1) ->
gleam@result:'try'(
parse_nibble(G@1),
fun(G_v@1) ->
gleam@result:'try'(
parse_nibble(B@1),
fun(B_v@1) ->
gleam@result:'try'(
parse_nibble(A),
fun(A_v) ->
{ok,
{rgba,
expand(R_v@1),
expand(G_v@1),
expand(B_v@1),
expand(A_v)}}
end
)
end
)
end
)
end
);
{_, _} ->
{error, nil}
end.
-file("src/sparklinekit/internal/color.gleam", 33).
?DOC(false).
-spec parse_hex(binary()) -> {ok, rgba()} | {error, nil}.
parse_hex(Value) ->
case gleam_stdlib:string_starts_with(Value, <<"#"/utf8>>) of
false ->
{error, nil};
true ->
Body = gleam@string:drop_start(Value, 1),
case string:length(Body) of
3 ->
short_hex(Body, true);
4 ->
short_hex(Body, false);
6 ->
long_hex(Body, true);
8 ->
long_hex(Body, false);
_ ->
{error, nil}
end
end.
-file("src/sparklinekit/internal/color.gleam", 50).
?DOC(false).
-spec parse_or(binary(), rgba()) -> rgba().
parse_or(Value, Fallback) ->
case parse_hex(Value) of
{ok, Rgba} ->
Rgba;
{error, _} ->
Fallback
end.
-file("src/sparklinekit/internal/color.gleam", 199).
?DOC(false).
-spec clamp_byte(integer()) -> integer().
clamp_byte(Value) ->
case Value of
V when V < 0 ->
0;
V@1 when V@1 > 255 ->
255;
V@2 ->
V@2
end.
-file("src/sparklinekit/internal/color.gleam", 103).
?DOC(false).
-spec blend_channel(integer(), integer(), float(), float(), float()) -> integer().
blend_channel(Fg_channel, Bg_channel, Fg_alpha, Bg_alpha, Out_alpha) ->
Fc = erlang:float(Fg_channel),
Bc = erlang:float(Bg_channel),
Blended = case Out_alpha of
+0.0 -> +0.0;
-0.0 -> -0.0;
Gleam@denominator -> ((Fc * Fg_alpha) + ((Bc * Bg_alpha) * (1.0 - Fg_alpha)))
/ Gleam@denominator
end,
clamp_byte(erlang:round(Blended)).
-file("src/sparklinekit/internal/color.gleam", 85).
?DOC(false).
-spec over(rgba(), rgba()) -> rgba().
over(Fg, Bg) ->
{rgba, Fr, Fg_, Fb, Fa} = Fg,
{rgba, Br, Bg_, Bb, Ba} = Bg,
Fa_f = erlang:float(Fa) / 255.0,
Ba_f = erlang:float(Ba) / 255.0,
Out_a_f = Fa_f + (Ba_f * (1.0 - Fa_f)),
case Out_a_f =< +0.0 of
true ->
{rgba, 0, 0, 0, 0};
false ->
{rgba,
blend_channel(Fr, Br, Fa_f, Ba_f, Out_a_f),
blend_channel(Fg_, Bg_, Fa_f, Ba_f, Out_a_f),
blend_channel(Fb, Bb, Fa_f, Ba_f, Out_a_f),
clamp_byte(erlang:round(Out_a_f * 255.0))}
end.
-file("src/sparklinekit/internal/color.gleam", 191).
?DOC(false).
-spec two_hex(integer()) -> binary().
two_hex(Value) ->
S = gleam@int:to_base16(clamp_byte(Value)),
case string:length(S) of
1 ->
<<"0"/utf8, (string:lowercase(S))/binary>>;
_ ->
string:lowercase(S)
end.
-file("src/sparklinekit/internal/color.gleam", 59).
?DOC(false).
-spec to_hex_rgb(rgba()) -> binary().
to_hex_rgb(Rgba) ->
{rgba, R, G, B, _} = Rgba,
<<<<<<"#"/utf8, (two_hex(R))/binary>>/binary, (two_hex(G))/binary>>/binary,
(two_hex(B))/binary>>.
-file("src/sparklinekit/internal/color.gleam", 65).
?DOC(false).
-spec to_hex_rgba(rgba()) -> binary().
to_hex_rgba(Rgba) ->
{rgba, R, G, B, A} = Rgba,
<<<<<<<<"#"/utf8, (two_hex(R))/binary>>/binary, (two_hex(G))/binary>>/binary,
(two_hex(B))/binary>>/binary,
(two_hex(A))/binary>>.