[tex-k] dvitomp update: support \Black, \Red, and similar colordvi commands

Olaf Weber olaf at infovore.xs4all.nl
Sun Aug 29 17:56:29 CEST 2004


Eddie Kohler writes:

> The following patch, against the dvitomp.ch in
> tetex-src-beta-2.96.7.20040721, changes the color support to parse
> "color push rgb", "color push cmyk", and "color push gray" specials --
> all the specials understood by dvips -- as well as the existing named
> colors.  I think dvitomp is now as smart as dvips as far as colors are
> concerned.

[...]

> Olaf/Thomas, any comments?

You may want to play with this version and let me know whether it
works as it should.  It is derived from your code by using c_strings
in the color stack itself.

Index: dvitomp.ch
===================================================================
RCS file: /usr/local/cvsroot/texk/texk/web2c/dvitomp.ch,v
retrieving revision 1.17
diff -u -r1.17 dvitomp.ch
--- dvitomp.ch	14 Jul 2004 06:45:56 -0000	1.17
+++ dvitomp.ch	29 Aug 2004 15:53:28 -0000
@@ -523,19 +523,19 @@
 name, and decorate the relevant drawing commands with ``\.{withcolor
 (r,g,b)}'' specifiers while a color is defined.
 
-@ First we declare a record for color types.
+@ A constant bounding the size of the named-color array.
+
+@<Constants...@> =
+@!max_named_colors=100; {maximum number of distinct named colors}
+
+@ Then we declare a record for color types.
 
 @<Types...@> =
 @!named_color_record=record@;@/
   @!name:c_string; {color name}
-  @!red,green,blue:real; {red, green, blue components}
+  @!value:c_string; {text to pass to MetaPost}
   end;
 
-@ A constant bounding the size of the named-color array.
-
-@<Constants...@> =
-@!max_named_colors=100; {maximum number of distinct named colors}
-
 @ Declare the named-color array itself.
 
 @<Globals...@> =
@@ -546,17 +546,17 @@
 @ This function, used only during initialization, defines a named color.
 
 @<Define |parse_arguments|@> =
-procedure def_named_color(n: c_string; r,g,b: real);
+procedure def_named_color(n,v: c_string);
   begin
     if num_named_colors = max_named_colors then
       abort('too many named color definitions')
-    else if (num_named_colors > 0) and (strcmp(n, named_colors[num_named_colors].name) <= 0) then
+    else if (num_named_colors > 0)
+            and (strcmp(n, named_colors[num_named_colors].name) <= 0)
+    then
       abort('named colors added out of alphabetical order');
     incr(num_named_colors);
     named_colors[num_named_colors].name := n;
-    named_colors[num_named_colors].red := r;
-    named_colors[num_named_colors].green := g;
-    named_colors[num_named_colors].blue := b;
+    named_colors[num_named_colors].value := v
   end;
 
 @ During the initialization phase, we define values for all the named
@@ -564,74 +564,74 @@
 
 @<Set initial values@> =
 num_named_colors := 0;
-def_named_color('Apricot', 1.0, 0.680006, 0.480006);
-def_named_color('Aquamarine', 0.180006, 1.0, 0.7);
-def_named_color('Bittersweet', 0.760012, 0.0100122, 0.0);
-def_named_color('Black', 0.0, 0.0, 0.0);
-def_named_color('Blue', 0.0, 0.0, 1.0);
-def_named_color('BlueGreen', 0.15, 1.0, 0.669994);
-def_named_color('BlueViolet', 0.1, 0.05, 0.960012);
-def_named_color('BrickRed', 0.719994, 0.0, 0.0);
-def_named_color('Brown', 0.4, 0.0, 0.0);
-def_named_color('BurntOrange', 1.0, 0.489988, 0.0);
-def_named_color('CadetBlue', 0.380006, 0.430006, 0.769994);
-def_named_color('CarnationPink', 1.0, 0.369994, 1.0);
-def_named_color('Cerulean', 0.0600122, 0.889988, 1.0);
-def_named_color('CornflowerBlue', 0.35, 0.869994, 1.0);
-def_named_color('Cyan', 0.0, 1.0, 1.0);
-def_named_color('Dandelion', 1.0, 0.710012, 0.160012);
-def_named_color('DarkOrchid', 0.6, 0.2, 0.8);
-def_named_color('Emerald', 0.0, 1.0, 0.5);
-def_named_color('ForestGreen', 0.0, 0.880006, 0.0);
-def_named_color('Fuchsia', 0.45, 0.00998169, 0.919994);
-def_named_color('Goldenrod', 1.0, 0.9, 0.160012);
-def_named_color('Gray', 0.5, 0.5, 0.5);
-def_named_color('Green', 0.0, 1.0, 0.0);
-def_named_color('GreenYellow', 0.85, 1.0, 0.310012);
-def_named_color('JungleGreen', 0.0100122, 1.0, 0.480006);
-def_named_color('Lavender', 1.0, 0.519994, 1.0);
-def_named_color('LimeGreen', 0.5, 1.0, 0.0);
-def_named_color('Magenta', 1.0, 0.0, 1.0);
-def_named_color('Mahogany', 0.65, 0.0, 0.0);
-def_named_color('Maroon', 0.680006, 0.0, 0.0);
-def_named_color('Melon', 1.0, 0.539988, 0.5);
-def_named_color('MidnightBlue', 0.0, 0.439988, 0.569994);
-def_named_color('Mulberry', 0.640018, 0.0800061, 0.980006);
-def_named_color('NavyBlue', 0.0600122, 0.460012, 1.0);
-def_named_color('OliveGreen', 0.0, 0.6, 0.0);
-def_named_color('Orange', 1.0, 0.389988, 0.130006);
-def_named_color('OrangeRed', 1.0, 0.0, 0.5);
-def_named_color('Orchid', 0.680006, 0.360012, 1.0);
-def_named_color('Peach', 1.0, 0.5, 0.3);
-def_named_color('Periwinkle', 0.430006, 0.45, 1.0);
-def_named_color('PineGreen', 0.0, 0.75, 0.160012);
-def_named_color('Plum', 0.5, 0.0, 1.0);
-def_named_color('ProcessBlue', 0.0399878, 1.0, 1.0);
-def_named_color('Purple', 0.55, 0.139988, 1.0);
-def_named_color('RawSienna', 0.55, 0.0, 0.0);
-def_named_color('Red', 1.0, 0.0, 0.0);
-def_named_color('RedOrange', 1.0, 0.230006, 0.130006);
-def_named_color('RedViolet', 0.590018, 0.0, 0.660012);
-def_named_color('Rhodamine', 1.0, 0.180006, 1.0);
-def_named_color('RoyalBlue', 0.0, 0.5, 1.0);
-def_named_color('RoyalPurple', 0.25, 0.1, 1.0);
-def_named_color('RubineRed', 1.0, 0.0, 0.869994);
-def_named_color('Salmon', 1.0, 0.469994, 0.619994);
-def_named_color('SeaGreen', 0.310012, 1.0, 0.5);
-def_named_color('Sepia', 0.3, 0.0, 0.0);
-def_named_color('SkyBlue', 0.380006, 1.0, 0.880006);
-def_named_color('SpringGreen', 0.739988, 1.0, 0.239988);
-def_named_color('Tan', 0.860012, 0.580006, 0.439988);
-def_named_color('TealBlue', 0.119994, 0.980006, 0.640018);
-def_named_color('Thistle', 0.880006, 0.410012, 1.0);
-def_named_color('Turquoise', 0.15, 1.0, 0.8);
-def_named_color('Violet', 0.210012, 0.119994, 1.0);
-def_named_color('VioletRed', 1.0, 0.189988, 1.0);
-def_named_color('White', 1.0, 1.0, 1.0);
-def_named_color('WildStrawberry', 1.0, 0.0399878, 0.610012);
-def_named_color('Yellow', 1.0, 1.0, 0.0);
-def_named_color('YellowGreen', 0.560012, 1.0, 0.260012);
-def_named_color('YellowOrange', 1.0, 0.580006, 0.0);
+def_named_color('Apricot', '(1.0, 0.680006, 0.480006)');
+def_named_color('Aquamarine', '(0.180006, 1.0, 0.7)');
+def_named_color('Bittersweet', '(0.760012, 0.0100122, 0.0)');
+def_named_color('Black', '(0.0, 0.0, 0.0)');
+def_named_color('Blue', '(0.0, 0.0, 1.0)');
+def_named_color('BlueGreen', '(0.15, 1.0, 0.669994)');
+def_named_color('BlueViolet', '(0.1, 0.05, 0.960012)');
+def_named_color('BrickRed', '(0.719994, 0.0, 0.0)');
+def_named_color('Brown', '(0.4, 0.0, 0.0)');
+def_named_color('BurntOrange', '(1.0, 0.489988, 0.0)');
+def_named_color('CadetBlue', '(0.380006, 0.430006, 0.769994)');
+def_named_color('CarnationPink', '(1.0, 0.369994, 1.0)');
+def_named_color('Cerulean', '(0.0600122, 0.889988, 1.0)');
+def_named_color('CornflowerBlue', '(0.35, 0.869994, 1.0)');
+def_named_color('Cyan', '(0.0, 1.0, 1.0)');
+def_named_color('Dandelion', '(1.0, 0.710012, 0.160012)');
+def_named_color('DarkOrchid', '(0.6, 0.2, 0.8)');
+def_named_color('Emerald', '(0.0, 1.0, 0.5)');
+def_named_color('ForestGreen', '(0.0, 0.880006, 0.0)');
+def_named_color('Fuchsia', '(0.45, 0.00998169, 0.919994)');
+def_named_color('Goldenrod', '(1.0, 0.9, 0.160012)');
+def_named_color('Gray', '(0.5, 0.5, 0.5)');
+def_named_color('Green', '(0.0, 1.0, 0.0)');
+def_named_color('GreenYellow', '(0.85, 1.0, 0.310012)');
+def_named_color('JungleGreen', '(0.0100122, 1.0, 0.480006)');
+def_named_color('Lavender', '(1.0, 0.519994, 1.0)');
+def_named_color('LimeGreen', '(0.5, 1.0, 0.0)');
+def_named_color('Magenta', '(1.0, 0.0, 1.0)');
+def_named_color('Mahogany', '(0.65, 0.0, 0.0)');
+def_named_color('Maroon', '(0.680006, 0.0, 0.0)');
+def_named_color('Melon', '(1.0, 0.539988, 0.5)');
+def_named_color('MidnightBlue', '(0.0, 0.439988, 0.569994)');
+def_named_color('Mulberry', '(0.640018, 0.0800061, 0.980006)');
+def_named_color('NavyBlue', '(0.0600122, 0.460012, 1.0)');
+def_named_color('OliveGreen', '(0.0, 0.6, 0.0)');
+def_named_color('Orange', '(1.0, 0.389988, 0.130006)');
+def_named_color('OrangeRed', '(1.0, 0.0, 0.5)');
+def_named_color('Orchid', '(0.680006, 0.360012, 1.0)');
+def_named_color('Peach', '(1.0, 0.5, 0.3)');
+def_named_color('Periwinkle', '(0.430006, 0.45, 1.0)');
+def_named_color('PineGreen', '(0.0, 0.75, 0.160012)');
+def_named_color('Plum', '(0.5, 0.0, 1.0)');
+def_named_color('ProcessBlue', '(0.0399878, 1.0, 1.0)');
+def_named_color('Purple', '(0.55, 0.139988, 1.0)');
+def_named_color('RawSienna', '(0.55, 0.0, 0.0)');
+def_named_color('Red', '(1.0, 0.0, 0.0)');
+def_named_color('RedOrange', '(1.0, 0.230006, 0.130006)');
+def_named_color('RedViolet', '(0.590018, 0.0, 0.660012)');
+def_named_color('Rhodamine', '(1.0, 0.180006, 1.0)');
+def_named_color('RoyalBlue', '(0.0, 0.5, 1.0)');
+def_named_color('RoyalPurple', '(0.25, 0.1, 1.0)');
+def_named_color('RubineRed', '(1.0, 0.0, 0.869994)');
+def_named_color('Salmon', '(1.0, 0.469994, 0.619994)');
+def_named_color('SeaGreen', '(0.310012, 1.0, 0.5)');
+def_named_color('Sepia', '(0.3, 0.0, 0.0)');
+def_named_color('SkyBlue', '(0.380006, 1.0, 0.880006)');
+def_named_color('SpringGreen', '(0.739988, 1.0, 0.239988)');
+def_named_color('Tan', '(0.860012, 0.580006, 0.439988)');
+def_named_color('TealBlue', '(0.119994, 0.980006, 0.640018)');
+def_named_color('Thistle', '(0.880006, 0.410012, 1.0)');
+def_named_color('Turquoise', '(0.15, 1.0, 0.8)');
+def_named_color('Violet', '(0.210012, 0.119994, 1.0)');
+def_named_color('VioletRed', '(1.0, 0.189988, 1.0)');
+def_named_color('White', '(1.0, 1.0, 1.0)');
+def_named_color('WildStrawberry', '(1.0, 0.0399878, 0.610012)');
+def_named_color('Yellow', '(1.0, 1.0, 0.0)');
+def_named_color('YellowGreen', '(0.560012, 1.0, 0.260012)');
+def_named_color('YellowOrange', '(1.0, 0.580006, 0.0)');
 
 @ Color commands get a separate warning procedure. |warn| sets |history :=
 warning_given|, which causes a nonzero exit status; but color errors are
@@ -645,7 +645,7 @@
 @<Declare procedures to handle color commands@> =
 procedure do_xxx(p: integer);
 label 9999; {exit procedure}
-const bufsiz = 256;
+const bufsiz = 256; {FIXME: Fixed size buffer.}
 var buf: packed array[0..bufsiz] of eight_bits;
     l, r, m, k, len: integer;
     found: boolean;
@@ -670,8 +670,13 @@
 @ 
 
 @<Check whether |buf| contains a color command; if not, |goto 9999|@> =
-if (len <= 5) or (buf[0] <> "c") or (buf[1] <> "o") or (buf[2] <> "l")
-  or (buf[3] <> "o") or (buf[4] <> "r") or (buf[5] <> " ")
+if (len <= 5)
+   or (buf[0] <> "c")
+   or (buf[1] <> "o")
+   or (buf[2] <> "l")
+   or (buf[3] <> "o")
+   or (buf[4] <> "r")
+   or (buf[5] <> " ")
   then goto 9999;
 
 @ 
@@ -694,7 +699,7 @@
 
 @<Globals...@> =
 color_stack_depth: integer; {current depth of saved color stack}
-color_stack: array[1..max_color_stack_depth] of named_color_record; {saved color stack}
+color_stack: array[1..max_color_stack_depth] of c_string; {saved color stack}
 
 @ Initialize the stack to empty.
 
@@ -705,13 +710,15 @@
 
 @<Handle a color pop command@> =
 finish_last_char;
-if color_stack_depth > 0 then
+if color_stack_depth > 0 then begin
+  free(color_stack[color_stack_depth]);
   decr(color_stack_depth)
-else
-  color_warn('more "color pop" specials than "color push" specials');
+end
+else begin
+  color_warn('more "color pop" specials than "color push" specials')
+end;
 
-@ \.{color push} pushes a color onto the stack. We binary-search the
-|named_colors| array, then push the found color onto the stack.
+@ \.{color push} pushes a color onto the stack.
 
 @<Handle a color push command@> =
 finish_last_char;
@@ -719,19 +726,117 @@
   abort('color stack overflow');
 incr(color_stack_depth);
 { I don't know how to do string operations in Pascal. }
-for k := 11 to len - 1 do begin
-  buf[k - 11] := xchr[buf[k]];
+{ Skip over extra spaces after 'color push'. }
+l := 11;
+while (l < len - 1) and (buf[l] = " ") do incr(l);
+if @<|buf[l]| contains an rgb command@> then begin
+  @<Handle a color push rgb command@>
+end else if @<|buf[l]| contains a cmyk command@> then begin
+  @<Handle a color push cmyk command@>
+end else if @<|buf[l]| contains a gray command@> then begin
+  @<Handle a color push gray command@>
+end else begin
+  @<Handle a named color push command@>
+end;
+
+@ 
+
+@<|buf[l]| contains an rgb command@> =
+(l + 4 < len)
+and (buf[l]   = "r")
+and (buf[l+1] = "g")
+and (buf[l+2] = "b")
+and (buf[l+3] = " ")
+
+@
+
+@<Handle a color push rgb command@> =
+l := l + 4;
+while (l < len) and (buf[l] = " ") do incr(l);
+{ Remove spaces at end of buf }
+while (len > l) and (buf[len - 1] = " ") do decr(len);
+color_stack[color_stack_depth]:=xmalloc_array(char,len-l+3);
+k := 0;
+@<Copy |buf[l]| to |color_stack[color_stack_depth][k]| in tuple form@>
+
+@ 
+
+@<|buf[l]| contains a gray command@> =
+(l + 5 < len)
+and (buf[l]   = "g")
+and (buf[l+1] = "r")
+and (buf[l+2] = "a")
+and (buf[l+3] = "y")
+and (buf[l+4] = " ")
+
+@
+
+@<Handle a color push gray command@> =
+l := l + 5;
+while (l < len) and (buf[l] = " ") do incr(l);
+{ Remove spaces at end of buf }
+while (len > l) and (buf[len - 1] = " ") do decr(len);
+color_stack[color_stack_depth]:=xmalloc_array(char,len-l+9);
+strcpy(color_stack[color_stack_depth],'white*');
+k := 6;
+@<Copy |buf[l]| to |color_stack[color_stack_depth][k]| in tuple form@>
+
+@ 
+
+@<|buf[l]| contains a cmyk command@> =
+(l + 5 < len)
+and (buf[l]   = "c")
+and (buf[l+1] = "m")
+and (buf[l+2] = "y")
+and (buf[l+3] = "k")
+and (buf[l+4] = " ")
+
+@
+
+@<Handle a color push cmyk command@> =
+l := l + 5;
+while (l < len) and (buf[l] = " ") do incr(l);
+{ Remove spaces at end of buf }
+while (len > l) and (buf[len - 1] = " ") do decr(len);
+color_stack[color_stack_depth]:=xmalloc_array(char,len-l+7);
+strcpy(color_stack[color_stack_depth],'cmyk');
+k := 4;
+@<Copy |buf[l]| to |color_stack[color_stack_depth][k]| in tuple form@>
+
+@
+
+@<Copy |buf[l]| to |color_stack[color_stack_depth][k]| in tuple form@> =
+color_stack[color_stack_depth][k] := "(";
+incr(k);
+while l < len do
+  if buf[l] = " " then begin
+    color_stack[color_stack_depth][k] := ",";
+    while (l < len) and (buf[l] = " ") do incr(l);
+    incr(k);
+  end else begin
+    color_stack[color_stack_depth][k] := buf[l];
+    incr(l);
+    incr(k);
+  end;
+color_stack[color_stack_depth][k] := ")";
+color_stack[color_stack_depth][k+1] := chr(0)
+
+@ Binary-search the |named_colors| array, then push the found color onto
+the stack.
+
+@<Handle a named color push command@> =
+for k := l to len - 1 do begin
+  buf[k - l] := xchr[buf[k]];
 end;
-buf[len - 11] := 0;
+buf[len - l] := 0;
+len := len - l;
 l := 1; r := num_named_colors;
 found := false;
 while (l <= r) and not found do begin
   m := (l + r) / 2;
   k := strcmp(buf, named_colors[m].name);
   if k = 0 then begin
-    color_stack[color_stack_depth].red := named_colors[m].red;
-    color_stack[color_stack_depth].green := named_colors[m].green;
-    color_stack[color_stack_depth].blue := named_colors[m].blue;
+    color_stack[color_stack_depth]:=xstrdup(named_colors[m].value);
     found := true;
   end else if k < 0 then
     r := m - 1
@@ -739,10 +844,8 @@
     l := m + 1;
 end;
 if not found then begin
-   color_warn('unknown color in "color push" command, pushing black');
-   color_stack[color_stack_depth].red := 0;
-   color_stack[color_stack_depth].green := 0;
-   color_stack[color_stack_depth].blue := 0;
+   color_warn('unknown color in "color push" command');
+   color_stack[color_stack_depth]:=xstrdup(buf);
 end;
 
 @ Last but not least, this code snippet prints a \.{withcolor} specifier
@@ -750,13 +853,8 @@
 
 @<Print a \.{withcolor} specifier if appropriate@> =
 if color_stack_depth > 0 then begin
-  print(' withcolor ('); 
-  fprint_real(mpx_file, color_stack[color_stack_depth].red,1,4);
-  print(', ');
-  fprint_real(mpx_file, color_stack[color_stack_depth].green,1,4);
-  print(', ');
-  fprint_real(mpx_file, color_stack[color_stack_depth].blue,1,4);
-  print(')');
+  print(' withcolor ');
+  fputs(color_stack[color_stack_depth], mpx_file);
 end;
 
 @z

-- 
Olaf Weber

               (This space left blank for technical reasons.)



More information about the tex-k mailing list