diff --git a/lib/LaTeXML/Common/Color.pm b/lib/LaTeXML/Common/Color.pm index db1d8d041e..623101fd30 100644 --- a/lib/LaTeXML/Common/Color.pm +++ b/lib/LaTeXML/Common/Color.pm @@ -157,7 +157,7 @@ sub multiply { __END__ -=pod +=pod =head1 NAME @@ -251,4 +251,3 @@ Public domain software, produced as part of work done by the United States Government & not subject to copyright in the US. =cut - diff --git a/lib/LaTeXML/Common/Color/rgb.pm b/lib/LaTeXML/Common/Color/rgb.pm index 71706232cf..ca62d65840 100644 --- a/lib/LaTeXML/Common/Color/rgb.pm +++ b/lib/LaTeXML/Common/Color/rgb.pm @@ -51,12 +51,14 @@ sub hsb { elsif ($i == 6) { return Phi($r, $g, $b, 1, -1); } elsif ($i == 7) { return LaTeXML::Common::Color->new('hsb', 0, 0, $b); } } -my @hex = qw(0 1 2 3 4 5 6 7 8 9 A B C D E F); # [CONSTANT] - sub hex2 { - my ($n) = @_; - my $nn = LaTeXML::Common::Number::roundto($n * 255, 0); - return $hex[int($nn / 16)] . $hex[$nn % 16]; } + my ($n) = @_; + my $nn = LaTeXML::Common::Number::roundto($n * 255, 0); + my $h_full = sprintf("%.2X", $nn); + # the precision doesn't quite get enforced on larger values, + # so let's try to substring explicitly + my $h2 = substr($h_full, 0, 2); + return $h2; } sub toHex { my ($self) = @_; diff --git a/lib/LaTeXML/Package/xcolor.sty.ltxml b/lib/LaTeXML/Package/xcolor.sty.ltxml index b6cbb0b44d..71ff6bf418 100644 --- a/lib/LaTeXML/Package/xcolor.sty.ltxml +++ b/lib/LaTeXML/Package/xcolor.sty.ltxml @@ -278,8 +278,8 @@ sub DecodeColor { my $dec_re = qr/[+-]*(?:\d*\.?\d*)/; # : ,
:;...; # | :;...; - my $ext_expr_re = qr/($core_model_re)(,($div_re))?:\s* - (($expr_re|$name_re),$dec_re(?:;\s*(?:$expr_re|$name_re),$dec_re)*)/x; + my $ext_expr_re = qr/($core_model_re)(,\s*($div_re))?:\s* + (($expr_re|$name_re),\s*$dec_re(?:;\s*(?:$expr_re|$name_re),\s*$dec_re)*)/x; # : | | my $color_expr_re = qr/$expr_re|$ext_expr_re/; my $function_re = qr/wheel|twheel/; @@ -305,13 +305,17 @@ sub DecodeColor { if (defined $core_model) { # Extended color expression: combine colors as on a pallete $color = Black->convert($core_model); my $dectot = 0; - while ($exprs =~ s/($expr_re),($dec_re)//) { + while ($exprs =~ s/($expr_re),\s*($dec_re)//) { my $dec = $6; $dec =~ s/--//g; next if !$dec || $dec eq '.'; # the contribution is 0! $dectot += $dec; push(@pallete, [DecodeColor($1), $dec]); } $div = $dectot unless $div; foreach my $cp (@pallete) { + # IMPORTANT: if we need to scale, first convert to RGB, + # or we risk losing scaling precision on any zero-valued components. + $$cp[0] = $$cp[0]->convert($color->model) unless $color->model eq $$cp[0]->model; + # now it is safe to scale: $color = $color->add($$cp[0]->scale($$cp[1] / $div)); } } else { # Standard Color Expression: $color = ($postfix && ($postfix =~ /!!\[(\d+)\]/) # Note "out-of-order" effect! diff --git a/t/graphics/xcolors.pdf b/t/graphics/xcolors.pdf index a75da47827..6a81f92573 100644 Binary files a/t/graphics/xcolors.pdf and b/t/graphics/xcolors.pdf differ diff --git a/t/graphics/xcolors.tex b/t/graphics/xcolors.tex index 78362578c8..01d24f069c 100644 --- a/t/graphics/xcolors.tex +++ b/t/graphics/xcolors.tex @@ -252,4 +252,22 @@ \section{Boxes} \copy\mybox \setbox\mybox=\hbox{Should be Red!} {\color{red}\copy\mybox} + +\section{Custom rgb directives} +\color{rgb:red,4;green,2;yellow,1} Brown + +\color{rgb:red,1;green,2;blue,5} Dark blue + +\color{rgb:orange,1;yellow,2;pink,5} Light orange + +\color{rgb:black,1;white,2} Gray + +\color{rgb, 255:red, 208; green, 2; blue, 27} Brick-like Red + +\color{rgb, 255:red, 74; green, 144; blue, 226} Ocean blue + +\color{rgb, 255:red, 0; green, 116; blue, 201} Sky blue + +\color{rgb, 255:red, 0; green, 0; blue, 0} Black + \end{document} diff --git a/t/graphics/xcolors.xml b/t/graphics/xcolors.xml index 49d9d1bb2b..51179da56f 100644 --- a/t/graphics/xcolors.xml +++ b/t/graphics/xcolors.xml @@ -650,4 +650,36 @@ A=100*13 = 1300pt;

Should be Red!

+
+ + 12 + 12 + ยง12 + + <tag close=" ">12</tag>Custom rgb directives + +

Brown

+
+ +

Dark blue

+
+ +

Light orange

+
+ +

Gray

+
+ +

Brick-like Red

+
+ +

Ocean blue

+
+ +

Sky blue

+
+ +

Black

+
+