summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/l3kernel/l3color.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'macros/latex/contrib/l3kernel/l3color.dtx')
-rw-r--r--macros/latex/contrib/l3kernel/l3color.dtx178
1 files changed, 173 insertions, 5 deletions
diff --git a/macros/latex/contrib/l3kernel/l3color.dtx b/macros/latex/contrib/l3kernel/l3color.dtx
index 176594a3f4..cef2e7bef1 100644
--- a/macros/latex/contrib/l3kernel/l3color.dtx
+++ b/macros/latex/contrib/l3kernel/l3color.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2021-10-17}
+% \date{Released 2021-10-18}
%
% \maketitle
%
@@ -393,6 +393,7 @@
% The latter should be one of
% \begin{itemize}
% \item \texttt{DeviceN}
+% \item \texttt{ICCBased}
% \item \texttt{Separation}
% \end{itemize}
% (The \meta{family} may be given in mixed case as-in the PDF reference:
@@ -436,6 +437,28 @@
% a process color name (\texttt{cyan}, etc.) or the special name \texttt{none}.
% \end{itemize}
%
+% For a \texttt{ICCBased} space, there is one \emph{compulsory} key.
+% \begin{itemize}
+% \item \texttt{file} The name of the file containing the profile.
+% \end{itemize}
+%
+% \subsection{Color profiles}
+%
+% Color profiles are used to ensure color accuracy by linking to collaboration.
+% Applying a profile can be used to standardise color which is otherwise
+% device-dependence.
+%
+% \begin{function}[added = 2021-02-23]{\color_profile_apply:nn}
+% \begin{syntax}
+% \cs{color_profile_apply:nn} \Arg{profile} \Arg{model}
+% \end{syntax}
+% This function applies a \meta{profile} to one of the device \meta{models}.
+% The profile will then apply to all color of the selected \meta{model}. The
+% \meta{profile} should specify an ICC profile file. The \meta{model} has to
+% be one the standard device models: \texttt{cmyk}, \texttt{gray} or
+% \texttt{rgb}.
+% \end{function}
+%
% \end{documentation}
%
% \begin{implementation}
@@ -1781,11 +1804,10 @@
% A shared auxiliary to do the basics of setting up a new model: reserve a
% number, create a fallback and white-equivalent, set up links to the backend.
% \begin{macrocode}
-\cs_new_protected:Npn \@@_model_init:nnn #1#2#3
+\cs_new_protected:Npn \@@_model_init:nnnnn #1#2#3#4#5
{
\int_gincr:N \g_@@_model_int
- \tl_const:cx { c_@@_fallback_ #1 _tl }
- { 1 \prg_replicate:nn { #2 - 1 } { ~ 1 } }
+ \tl_const:cn { c_@@_fallback_ #1 _tl } { #4 }
\clist_map_inline:nn { fill , stroke , select }
{
\cs_new_protected:cpx { @@_backend_ ##1 _ #1 :n } ####1
@@ -1797,12 +1819,23 @@
\cs_new_protected:cpx { @@_model_ #1 _white: }
{
\prop_put:Nnn \exp_not:N \l_@@_named_white_prop {#1}
- { 0 \prg_replicate:nn { #2 - 1 } { ~ 0 } }
+ { \exp_not:n {#5} }
\exp_not:N \int_compare:nNnF { \tex_currentgrouplevel:D } = 0
{ \group_insert_after:N \exp_not:c { @@_model_ #1 _ white: } }
}
\use:c { @@_model_ #1 _white: }
}
+\cs_generate_variant:Nn \@@_model_init:nnnnn { nnnxx }
+\cs_new_protected:Npn \@@_model_init:nnn #1#2#3
+ {
+ \@@_model_init:nnnxx { #1 } { #2 } { #3 }
+ {
+ 1 \prg_replicate:nn { #2 - 1 } { ~ 1 }
+ }
+ {
+ 0 \prg_replicate:nn { #2 - 1 } { ~ 0 }
+ }
+ }
% \end{macrocode}
% \end{macro}
%
@@ -2513,6 +2546,118 @@
% \end{macro}
% \end{macro}
%
+% \begin{variable}{\c_@@_icc_colorspace_signatures_prop}
+% The signatures in the ICC file header indicating the underlying
+% colorspace. We map it to three values: The number of components,
+% the values corresponding to white, and the range.
+% \begin{macrocode}
+\prop_const_from_keyval:Nn \c_@@_icc_colorspace_signatures_prop
+ {
+% Gray
+ 47524159 = {1} {1} {0} {},
+% RGB
+ 52474220 = {3} {0~0~0} {1~1~1} {},
+% CMYK
+ 434D594B = {4} {0~0~0~1} {0~0~0~0} {},
+% Lab
+ 4C616220 = {3} {0~0~0} {100~0~0} {0~100~-128~127~-128~127}
+ }
+% \end{macrocode}
+% \end{variable}
+% \begin{macro}{\@@_model_iccbased:n}
+% \begin{macro}{\@@_model_iccbased:nn}
+% \begin{macro}{\@@_model_iccbased:nnn, \@@_model_iccbased_aux:nnn}
+% For an ICC profile, we need a file name and a number of components. The
+% file name is processed here so the backend can treat it as a string.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_model_iccbased:n #1
+ {
+ \prop_get:NnNTF \l_@@_internal_prop { file }
+ \l_@@_internal_tl
+ {
+ \exp_args:NV \@@_model_iccbased:nn
+ \l_@@_internal_tl {#1}
+ }
+ {
+ \msg_error:nnn { color }
+ { ICCBased-requires-file } {#1}
+ }
+ }
+\cs_new_protected:Npn \@@_model_iccbased:nn #1#2
+ {
+ \exp_args:NNx \prop_get:NnNTF \c_@@_icc_colorspace_signatures_prop
+ { \file_hex_dump:nnn { #1 } { 17 } { 20 } } \l_@@_internal_tl
+ {
+ \exp_last_unbraced:NV \@@_model_iccbased_aux:nnnnnn
+ \l_@@_internal_tl { #2 } { #1 }
+ }
+ {
+ \msg_error:nnn { color }
+ { ICCBased-unsupported-colorspace } {#2}
+ }
+ }
+% \end{macrocode}
+% Here, we can use the same internals as for DeviceN approach as we know the
+% number of components. No conversion is possible, so there is no need
+% to worry about that at all.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_model_iccbased_aux:nnnnnn #1#2#3#4#5#6
+ {
+ \@@_model_init:nnnnn {#5} {#1} { iccbased } {#2} {#3}
+ \use:c { @@_model_devicen_parse_ #1 :nn } {#5} {#1}
+ \exp_args:Nx \@@_backend_iccbased_init:nnn
+ { \file_full_name:n {#6} } {#1} {#4}
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Applying profiles}
+%
+% \begin{macro}{\color_profile_apply:nn, \@@_profile_apply:nn}
+% \begin{macro}
+% {
+% \@@_profile_apply_gray:n ,
+% \@@_profile_apply_rgb:n ,
+% \@@_profile_apply_cmyk:n
+% }
+% With a limited range of outcomes, this is largely about getting data to the
+% backend.
+% \begin{macrocode}
+\cs_new_protected:Npn \color_profile_apply:nn #1#2
+ {
+ \exp_args:Ne \@@_profile_apply:nn
+ { \file_full_name:n {#1} } {#2}
+ }
+\cs_new_protected:Npn \@@_profile_apply:nn #1#2
+ {
+ \cs_if_exist_use:cF { @@_profile_apply_ \tl_to_str:n {#2} :n }
+ {
+ \msg_error:nnn { color } { ICC-Device-unknown } {#2}
+ \use_none:n
+ }
+ {#1}
+ }
+\cs_new_protected:Npn \@@_profile_apply_gray:n #1
+ {
+ \int_gincr:N \g_@@_model_int
+ \@@_backend_iccbased_device:nnn {#1} { Gray } { 1 }
+ }
+\cs_new_protected:Npn \@@_profile_apply_rgb:n #1
+ {
+ \int_gincr:N \g_@@_model_int
+ \@@_backend_iccbased_device:nnn {#1} { RGB } { 3 }
+ }
+\cs_new_protected:Npn \@@_profile_apply_cmyk:n #1
+ {
+ \int_gincr:N \g_@@_model_int
+ \@@_backend_iccbased_device:nnn {#1} { CMYK } { 4 }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
% \subsection{Diagnostics}
%
% \begin{macro}{\color_show:n, \color_log:n, \@@_show:Nn}
@@ -2589,6 +2734,29 @@
\\ \\
key~was~given~with~the~correct~information.
}
+\msg_new:nnnn { color } { ICC-Device-unknown }
+ { Unknown~device~color~space~'#1'. }
+ {
+ LaTeX~has~been~asked~to~apply~an~ICC~profile~but~the~device~color~space~
+ '#1'~is~unknown.
+ }
+\msg_new:nnnn { color } { ICCBased-unsupported-colorspace }
+ { ICCBased~color~space~'#1'~uses~an~unsupported~data~color~space. }
+ {
+ LaTeX~has~been~asked~to~create~a~ICCBased~colorspace,~but~the~
+ used~data~colorspace~is~not~supported.~ICC~profiles~used~for~
+ defining~a~ICCBased~colorspace~should~use~a~Lab,~RGB,~or~
+ CMYK~data~colorspace.~LaTeX~will~ignore~this~request.
+ }
+\msg_new:nnnn { color } { ICCBased-requires-file }
+ { ICCBased~color~space~'#1'~require~an~file. }
+ {
+ LaTeX~has~been~asked~to~create~an~ICCBased~color~space,~but~no~\\ \\
+ \iow_indent:n { file~=~<name> }
+ \\ \\
+ key~was~given~with~the~correct~information.~LaTeX~will~ignore~this~
+ request.
+ }
\msg_new:nnnn { color } { model-already-defined }
{ Color~model~'#1'~already~defined. }
{