summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/l3experimental/l3color.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'macros/latex/contrib/l3experimental/l3color.dtx')
-rw-r--r--macros/latex/contrib/l3experimental/l3color.dtx130
1 files changed, 116 insertions, 14 deletions
diff --git a/macros/latex/contrib/l3experimental/l3color.dtx b/macros/latex/contrib/l3experimental/l3color.dtx
index 9438e8110f..c7addda60b 100644
--- a/macros/latex/contrib/l3experimental/l3color.dtx
+++ b/macros/latex/contrib/l3experimental/l3color.dtx
@@ -46,7 +46,7 @@
% }^^A
% }
%
-% \date{Released 2020-05-18}
+% \date{Released 2020-06-03}
%
% \maketitle
%
@@ -61,7 +61,9 @@
% space. In contrast, various proprietary models are available which define
% \emph{spot} colors.
%
-% The models supported here are
+% Core models are used to pass color information to output; these are
+% \enquote{native} to \pkg{l3color}. Core models use real numbers in the range
+% $[0,1]$ to represent values. The core models supported here are
% \begin{itemize}
% \item \texttt{gray} Grayscale color, with a single axis running from
% $0$ (fully black) to $1$ (fully white)
@@ -73,7 +75,24 @@
% (see \url{https://helpx.adobe.com/indesign/using/spot-process-colors.html}
% for details of the use of spot colors in print)
% \end{itemize}
-%
+% There are also interface models: these are convenient for users but have
+% to be manipulated before storing/passing to the backend. Interface models
+% are primarily integer-based: see below for more detail. The supported
+% interface models are
+% \begin{itemize}
+% \item \texttt{Hsb} Hue-saturation-brightness color, with three axes, integer
+% in the range $[0,360]$ for hue, real values in the range $[0,1]$ for
+% saturation and brightness
+% \item \texttt{HSB} Hue-saturation-brightness color, with three axes, integer
+% in the range $[0,360]$ for hue, integer values in the range $[0,255]$ for
+% saturation and brightness
+% \item \texttt{HTML} HTML format representation of RGB color given as a
+% single six-digit hexadecimal number
+% \item \texttt{RGB} Red-green-blue color, with three axes, one for each of
+% the components, values as integers from $0$ to $255$
+% \end{itemize}
+% All interface models are internally stored as |rgb|.
+%
% Additional models may be created to allow mixing of spot colors
% with each other or with those from other models. See
% Section~\ref{l3color:sec:spot} for more detail of spot color support.
@@ -267,7 +286,7 @@
%
% \begin{macrocode}
%<*package>
-\ProvidesExplPackage{l3color}{2020-05-18}{}
+\ProvidesExplPackage{l3color}{2020-06-03}{}
{L3 Experimental color support}
%</package>
% \end{macrocode}
@@ -643,22 +662,28 @@
% \begin{macro}[EXP]{\@@_parse_spot_aux:w}
% Turn the input into internal form, also tidying up the number quickly.
% \begin{macrocode}
-\cs_new:Npn \@@_parse_model_gray:w #1 , #2 \s_@@_stop { \@@_parse_number:n {#1} }
+\cs_new:Npn \@@_parse_model_gray:w #1 , #2 \s_@@_stop
+ { gray ~ \@@_parse_number:n {#1} }
\cs_new:Npn \@@_parse_model_rgb:w #1 , #2 , #3 , #4 \s_@@_stop
{
+ rgb ~
\@@_parse_number:n {#1} ~
\@@_parse_number:n {#2} ~
\@@_parse_number:n {#3}
}
\cs_new:Npn \@@_parse_model_cmyk:w #1 , #2 , #3 , #4 , #5 \s_@@_stop
{
+ cmyk ~
\@@_parse_number:n {#1} ~
\@@_parse_number:n {#2} ~
\@@_parse_number:n {#3} ~
\@@_parse_number:n {#4}
}
\cs_new:Npn \@@_parse_model_spot:w #1 , #2 \s_@@_stop
- { \@@_parse_spot_aux:w #1 ! 100 ! \s_@@_stop }
+ {
+ spot ~
+ \@@_parse_spot_aux:w #1 ! 100 ! \s_@@_stop
+ }
\cs_new:Npn \@@_parse_spot_aux:w #1 ! #2 ! #3 \s_@@_stop
{ #1 ~ \fp_eval:n { #2 / 100 } }
\cs_new:Npn \@@_parse_number:n #1
@@ -671,6 +696,83 @@
% \end{macro}
% \end{macro}
%
+% \begin{macro}[EXP]
+% {
+% \@@_parse_model_Hsb:w, \@@_parse_model_HSB:w,
+% \@@_parse_model_HTML:w, \@@_parse_model_RGB:w
+% }
+% \begin{macrocode}
+\cs_new:Npn \@@_parse_model_Hsb:w #1 , #2 , #3 , #4 \s_@@_stop
+ {
+ \exp_args:Ne \@@_parse_model_hsb:nnn { \fp_eval:n { #1 / 360 } }
+ {#2} {#3}
+ }
+% \end{macrocode}
+% The conversion here is non-trivial but is described at length
+% in the \pkg{xcolor} manual. For ease, we calculate the integer
+% and fractional parts of the hue first, then use them to work out the
+% possible values for $r$, $g$ and $b$ before putting them in the correct
+% places.
+% \begin{macrocode}
+\cs_new:Npn \@@_parse_model_hsb:nnn #1#2#3
+ {
+ rgb ~
+ \exp_args:Ne \@@_parse_model_hsb_aux:nnn
+ { \fp_eval:n { 6 * #1 } } {#2} {#3}
+ }
+\cs_new:Npn \@@_parse_model_hsb_aux:nnn #1#2#3
+ {
+ \exp_args:Nee \@@_parse_model_hsb_aux:nnnn
+ { \fp_eval:n { floor(#1) } } { \fp_eval:n { #1 - floor(#1) } }
+ {#2} {#3}
+ }
+\cs_new:Npn \@@_parse_model_hsb_aux:nnnn #1#2#3#4
+ {
+ \use:e
+ {
+ \exp_not:N \@@_parse_model_hsb_aux:nnnnn
+ { \@@_parse_number:n {#4} }
+ { \fp_eval:n { round(#4 * (1 - #3) ,5) } }
+ { \fp_eval:n { round(#4 * ( 1 - #3 * #2 ) ,5) } }
+ { \fp_eval:n { round(#4 * ( 1 - #3 * (1 - #2) ) ,5) } }
+ {#1}
+ }
+ }
+\cs_new:Npn \@@_parse_model_hsb_aux:nnnnn #1#2#3#4#5
+ { \use:c { @@_parse_model_hsb_ #5 :nnnn } {#1} {#2} {#3} {#4} }
+\cs_new:cpn { @@_parse_model_hsb_0:nnnn } #1#2#3#4 { #1 ~ #4 ~ #2 }
+\cs_new:cpn { @@_parse_model_hsb_1:nnnn } #1#2#3#4 { #3 ~ #1 ~ #2 }
+\cs_new:cpn { @@_parse_model_hsb_2:nnnn } #1#2#3#4 { #2 ~ #1 ~ #4 }
+\cs_new:cpn { @@_parse_model_hsb_3:nnnn } #1#2#3#4 { #2 ~ #3 ~ #1 }
+\cs_new:cpn { @@_parse_model_hsb_4:nnnn } #1#2#3#4 { #4 ~ #2 ~ #1 }
+\cs_new:cpn { @@_parse_model_hsb_5:nnnn } #1#2#3#4 { #1 ~ #2 ~ #3 }
+\cs_new:cpn { @@_parse_model_hsb_6:nnnn } #1#2#3#4 { #1 ~ #2 ~ #2 }
+\cs_new:Npn \@@_parse_model_HSB:w #1 , #2 , #3 , #4 \s_@@_stop
+ {
+ \exp_args:Neee \@@_parse_model_hsb:nnn
+ { \fp_eval:n {#1 / 360} }
+ { \fp_eval:n {#2 / 255} }
+ { \fp_eval:n {#3 / 255} }
+ }
+\cs_new:Npn \@@_parse_model_HTML:w #1 , #2 \s_@@_stop
+ { \@@_parse_model_HTML_aux:w #1 0 0 0 0 0 0 \s_@@_stop }
+\cs_new:Npn \@@_parse_model_HTML_aux:w #1#2#3#4#5#6#7 \s_@@_stop
+ {
+ rgb ~
+ \fp_eval:n { round(\int_from_hex:n {#1#2} / 255,5) } ~
+ \fp_eval:n { round(\int_from_hex:n {#3#4} / 255,5) } ~
+ \fp_eval:n { round(\int_from_hex:n {#5#6} / 255,5) }
+ }
+\cs_new:Npn \@@_parse_model_RGB:w #1 , #2 , #3 , #4 \s_@@_stop
+ {
+ rgb ~
+ \fp_eval:n { round(#1 / 255,5) } ~
+ \fp_eval:n { round(#2 / 255,5) } ~
+ \fp_eval:n { round(#3 / 255,5) }
+ }
+% \end{macrocode}
+% \end{macro}
+%
% \subsection{Selecting colors (and color models)}
%
% \begin{variable}{\l_color_fixed_model_tl}
@@ -750,11 +852,11 @@
\cs_if_exist:cTF { @@_parse_model_ #1 :w }
{
\tl_set:Nx #3
- { #1 ~ \use:c { @@_parse_model_ #1 :w } #2 , 0 , 0 , 0 , 0 \s_@@_stop }
+ { \use:c { @@_parse_model_ #1 :w } #2 , 0 , 0 , 0 , 0 \s_@@_stop }
\@@_check_model:N #3
}
{
- \__kernel_msg_error:nnn { color } { invalid-model } {#1}
+ \__kernel_msg_error:nnn { color } { unknown-model } {#1}
}
}
% \end{macrocode}
@@ -878,18 +980,18 @@
% \subsection{Messages}
%
% \begin{macrocode}
-\__kernel_msg_new:nnnn { color } { invalid-model }
- { Invalid~color~model~'#1'. }
- {
- LaTeX~has~been~asked~to~use~a~color~model~called~'#1',~
- but~this~model~is~not~set~up.
- }
\__kernel_msg_new:nnnn { color } { unknown-color }
{ Unknown~color~'#1'. }
{
LaTeX~has~been~asked~to~use~a~color~named~'#1',~
but~this~has~never~been~defined.
}
+\__kernel_msg_new:nnnn { color } { unknown-model }
+ { Unknown~color~model~'#1'. }
+ {
+ LaTeX~has~been~asked~to~use~a~color~model~called~'#1',~
+ but~this~model~is~not~set~up.
+ }
% \end{macrocode}
%
% \begin{macrocode}