Skip to main content
Participant
August 9, 2011
Answered

setrgbcolor via index

  • August 9, 2011
  • 2 replies
  • 1765 views

I'm trying to add color to an existing text to ps C program. It currently translates a few esc sequences to postscript "cmds" that are in an included .ps file for bold/italics and shading...

I've added a new cmd for color, but I'd rather not have the 3 separate rgb values in the C program, but just pass an index (then translate the index to rgb values in the included .ps file (which also defines the new cmd)

I'm having trouble with the included .ps file getting just the first rgb value rather than the triplet.

here's my ps code...

/color_black { 0 0 0 } def

/color_red { 1 0 0 } def

/color_blue { 0 1 0 } def

/color_green { 0 0 1 } def

/color_mag { 0.83 0.83 0 } def

/color_dict [ color_black color_red color_blue color_green color_mag ] def

/srgb {color_dict exch get setrgbcolor} bind def

% usage

20 20  moveto

0 srgb (black )

1 srgb (red )

show

showpage

please show me the error of my ways!

This topic has been closed for replies.
Correct answer Mr__Horton

One of several ways to do it:

/Courier findfont 12 scalefont setfont

%% here you were defining named procedures that each contain three individual numeric values, instead I have made them arrays -

%% and adjusted/corrected the blue, green, and magenta.
/color_black [ 0 0 0 ] def
/color_red [ 1 0 0 ] def
/color_blue [ 0 0 1 ] def
/color_green [ 0 1 0 ] def
/color_mag [ 0.83 0 0.83] def

%% here you are defining an array called "color_dict" that will now have 5 individual objects (arrays) in it, instead of 15 values.
/color_dict [ color_black color_red color_blue color_green color_mag ] def

%% here you were using the index directly to point to the first and then the second objects in the array -

%% which were actually the r and g values of your first color.
%% /srgb {color_dict exch get setrgbcolor} bind def

%% here I am still using the index to point to the first and then the second array objects in the array, and then getting their rgb triplets.
/srgb {color_dict exch get dup 0 get exch dup 1 get exch 2 get setrgbcolor} bind def

% usage

20 20  moveto
0 srgb (black )
%% You need a show after black so that the string will be displayed in the rgb color you set before you change the rgb color to red.
show

1 srgb (red )
show

2 srgb (blue )
show

3 srgb (green )
show

4 srgb (magenta )
show

showpage

Hope you find this helpful!

- Marvin

2 replies

Participant
August 10, 2011

Others ways to do it...

/color_black { 0 0 0 } def

/color_red   { 1 0 0 } def

/color_blue  { 0 0 1 } def

/color_green { 0 1 0 } def

/color_mag   { 0.83 0.83 0 } def


/color_dict [ {color_black} {color_red} {color_blue} {color_green} {color_mag} ] def   % <<< enclose with {...}


/srgb  {color_dict  exch get exec setrgbcolor}  def    % <<< exec


% usage


/Helvetica 30 selectfont  % <<< You must define a font

20 700  moveto


0 srgb (black ) show

1 srgb  (red )  show

2 srgb  (blue ) show

3 srgb  (green )show

4 srgb  (mag )  show


% another way ...


/black 0 def

/red   1 def

/blue  2 def

/green 3 def

/mag   4 def

/color_tab [{0 0 0}{1 0 0}{0 0 1}{0 1 0}{.13 .63 .74}]def

/srgb2 {color_tab   exch get exec   setrgbcolor}  def


20 600  moveto


black srgb2 (black )show

red   srgb2 (red )  show

blue  srgb2 (blue ) show

green srgb2 (green )show

mag   srgb2 (mag )  show

showpage

Roland.

 

Mr__Horton
Inspiring
August 9, 2011

Firstly, there are several ways to accomplish what you want to do, depending on the number of unique color triplets and the text strings used, some will work better than others. I included a pretty simple example below for clarity, but it doesn't scale well for large sets of color indexes.

Since you are passing the name of the color as a text string you could presumably define procedures of the same name with their corresponding rgb values instead of using a numeric reference and a text string as well:

The render named procedure below takes the string on the stack and duplicates it (dup) then converts the topmost string to an executable (cvx) then to a name (cvn) which populates the stack with its corresponding values that are processed with the setrgbcolor procedure and finally the original text string is applied to the page with show each time the procedure is called.

/black { 0 0 0 } def

/red { 1 0 0 } def

/blue { 0 1 0 } def

/green { 0 0 1 } def

/mag { 0.83 0.83 0 } def

/render {dup cvx cvn setrgbcolor show} def

% usage

20 20  moveto

(black ) render

(red ) render

showpage

or you could pass an index value and a string, like you were, and use an array of rgb values.

I didn't wrap the definitions in their own dictionary for simplicity's sake, not because it isn't a good idea.

dtkernsAuthor
Participant
August 9, 2011

as far as scaling, I anticipate < 10 colors...

In my usage, I only pass the string to be a visiual conformation that the text is in the expected color... the index should be what ultimately determines the color. since I'm a postscript noob, can you show me the (a)  "correct" way to implement my srgb command?

thanks!

Mr__Horton
Mr__HortonCorrect answer
Inspiring
August 9, 2011

One of several ways to do it:

/Courier findfont 12 scalefont setfont

%% here you were defining named procedures that each contain three individual numeric values, instead I have made them arrays -

%% and adjusted/corrected the blue, green, and magenta.
/color_black [ 0 0 0 ] def
/color_red [ 1 0 0 ] def
/color_blue [ 0 0 1 ] def
/color_green [ 0 1 0 ] def
/color_mag [ 0.83 0 0.83] def

%% here you are defining an array called "color_dict" that will now have 5 individual objects (arrays) in it, instead of 15 values.
/color_dict [ color_black color_red color_blue color_green color_mag ] def

%% here you were using the index directly to point to the first and then the second objects in the array -

%% which were actually the r and g values of your first color.
%% /srgb {color_dict exch get setrgbcolor} bind def

%% here I am still using the index to point to the first and then the second array objects in the array, and then getting their rgb triplets.
/srgb {color_dict exch get dup 0 get exch dup 1 get exch 2 get setrgbcolor} bind def

% usage

20 20  moveto
0 srgb (black )
%% You need a show after black so that the string will be displayed in the rgb color you set before you change the rgb color to red.
show

1 srgb (red )
show

2 srgb (blue )
show

3 srgb (green )
show

4 srgb (magenta )
show

showpage

Hope you find this helpful!

- Marvin