[comp.lang.postscript] Reverse video font?

hougland@osiris.cso.uiuc.edu (01/18/90)

I am interested in printing characters in a 'reverse video' format, that
is white characters on a dark background.  I am afraid I may have to 
create my own font to do this, but can find no other way so far.  Any
suggestions would be welcome.

hougland
 

batcheldern@hannah.enet.dec.com (01/18/90)

> I am interested in printing characters in a 'reverse video' format, that
> is white characters on a dark background.  I am afraid I may have to 
> create my own font to do this, but can find no other way so far.  Any
> suggestions would be welcome.

The other way is to draw a black rectangle, and then show text in white
on top of it. The only problem is figuring out the size and position of
the black rectangle, but you'll have to figure that out if you create
your own font anyway.

A good height for the rectangle would be the point-size of the text,
although you'll have to do some experimentation to determine the right
place within that height to put the baseline. The width of the rectangle
could simply be the width of the text; if you wanted a little bit of
extra width on the ends, a good first guess might be half the width of a
space on either end.

Ned Batchelder, Digital Equipment Corp., BatchelderN@Hannah.enet.DEC.com

ttl@astroatc.UUCP (Tony Laundrie) (01/18/90)

Well, here's the quickest way I can think of:

%!
/reverseshow { % stack:  fontscale string
dup currentpoint 3 -1 roll
stringwidth pop 5 -1 roll
1.3 mul dup -4 div % depending on the font, you may want to adjust these
0 exch rmoveto currentpoint newpath moveto
dup neg 3 1 roll 0 exch rlineto
0 rlineto 0 exch rlineto closepath fill
1 setgray moveto show 0 setgray } def

/fontscale 40 def
/Times-Bold findfont fontscale scalefont setfont
72 72 moveto
(Hello) show
20 143 moveto
fontscale (aAbBcCdDeEfFgGhHiIjJkKlLmM) reverseshow
20 543 moveto
fontscale (nNoOpPqQrRsStTuUvVwWxXyYzZ) reverseshow
300 72 moveto (Yikes) show
showpage


While writing this, I was wondering:  Is there a way to find out the
current font scale?  Or the current X Y scaling factors?

ttl@astroatc.UUCP  ...uwvax!astroatc!ttl

bobs (Bob Stayton, Yoyodoc) (01/19/90)

In article <37700001@osiris.cso.uiuc.edu> hougland@osiris.cso.uiuc.edu writes:
>
>I am interested in printing characters in a 'reverse video' format, that
>is white characters on a dark background.  I am afraid I may have to 
>create my own font to do this, but can find no other way so far.  Any
>suggestions would be welcome.
>
>hougland
> 
I had the same problem awhile back and did exactly that:
create a reverse video font.  I learned a lot about
about coding fonts in the process |).

I started with Courier, and then switched to Courier-Bold
when I realized that the thin white lines of Courier
didn't print well.  My routines read the character width
of Courier-Bold, drew a box, filled it with black,
turned on white, and printed a Courier-Bold character in the
box.

It worked fine except for one problem: my software
(troff) refused to output a "space" character in Postscript, it just
repositioned for the next word.  This meant I got reverse
type with white spaces between the words.  Ugly.  So I had
to kludge a filter to convert the spaces in that font to another
character that printed as a black box.  Not elegant, but it
has worked well for two years now.

I will clean up the code and post it shortly.

bobs

woody@rpp386.cactus.org (Woodrow Baker) (01/19/90)

In article <7562@shlump.nac.dec.com>, batcheldern@hannah.enet.dec.com writes:
> 
> > I am interested in printing characters in a 'reverse video' format, that
> > is white characters on a dark background.  I am afraid I may have to 
> > create my own font to do this, but can find no other way so far.  Any
> > suggestions would be welcome.
> 
> The other way is to draw a black rectangle, and then show text in white
> on top of it. The only problem is figuring out the size and position of
> the black rectangle, but you'll have to figure that out if you create
> your own font anyway.
> 
> A good height for the rectangle would be the point-size of the text,
> although you'll have to do some experimentation to determine the right
> place within that height to put the baseline. The width of the rectangle
> could simply be the width of the text; if you wanted a little bit of
> extra width on the ends, a good first guess might be half the width of a
> space on either end.

Alternatly, you could do a flattenpath on say the letter 'l', then take
the bounding box, and use the resultant coordinates to determine the box.
If you don't mind wasting toner, you could do an entire blackfill of the
whole page, then set the color to white, and print away.....
Cheers
Woody

> 

bobs (Bob Stayton, Yoyodoc) (01/20/90)

As promised, here is my routine for creating a reverse
video font. It allows you to create a reverse font in your prolog
from an existing Postscript font, and then use the reverse
font like any other font in your document.   At the end
of this is a short demo program that uses the routine.
You should delete that demo program if you just want the
font definition machinery.

Have fun with this.

========== cut here ======================================
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%  reverse.ps
% 
% 18 Jan 1990
% Created by:
%  Bob Stayton
%  Technical Publications
%  The Santa Cruz Operation, Inc.
%  425 Encinal Street
%  Santa Cruz, CA  95060
%  (408) 425-7222
%  ...!uunet!sco!bobs
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% This program creates a reversed font (white type on black
% background) from an existing Postscript font and prints
% an example.
%
% It defines one procedure: reversefont
% Its syntax is:
%
%         /oldfontname reversefont  ==> (reversed font dictionary)
%
%     where:   /oldfontname is the name of an existing Postscript font
%
%  It is typically used this way:
%
%    % Define the reversed font with name Reverse-Courier:
%        /Reverse-Courier /Courier reversefont definefont pop
%    % Set and scale the reverse font as the current font:
%        /Reverse-Courier findfont 12 scalefont setfont
%

/reversefont {			% procedure to make reverse font

/basefontname exch def		% stores the old name
/basefontdict basefontname findfont def  % gets the old font

/numentries basefontdict maxlength 20 add def   
basefontdict /UniqueID known not
	{ /numentries numentries 1 add def } if

/newfont numentries dict def	% defines the empty new font dictionary

   basefontdict					% copy it
	{ exch dup /FID ne			% except for FID
	   { exch newfont 3 1 roll put }
	   { pop pop }
	   ifelse
	} forall

% The following statement can be modified to give the new
% font an internal name other than "Reverse-Font".
% The internal name is not usually used by a Postscript
% program.  Rather, the name in the font dictionary
% established with definefont is used to call a font.
   newfont /FontName /Reverse-Font put		% new font name

/uniqueid 
	basefontdict dup
	/UniqueID known
	{ /UniqueID get 1 add }
	{ pop 1 }
	ifelse
	def

   newfont /UniqueID uniqueid put


newfont begin

/concatproc {				% concatenates the two
					% processes on the stack
	3 dict begin
	/proc2 exch cvlit def
	/proc1 exch cvlit def
	/newproc proc1 length proc2 length add
	   array def
	newproc 0 proc1 putinterval
	newproc proc1 length proc2 putinterval
	newproc cvx
	end
} def

/concatproc2 {				% concatenates a
					% string and process
	3 dict begin
	/proc2 exch cvlit def
	/proc1 exch cvlit def
	/newproc proc1 length proc2 length add
	   array def
	newproc 0 proc1 put
	newproc proc1 length proc2 putinterval
	newproc cvx
	end
} def

/temp 1 dict def
/box {			% stack: xwidth
	temp begin
	/cwidth exch def
  	0 ly moveto
  	cwidth 0  rlineto
  	0 uy ly sub rlineto
  	cwidth neg 0 rlineto
  	closepath
  	fill end } def

/str 1 string def
/intostring {			% stack: integer 
	str 0 3 -1 roll		% str 0 int
	put
	str			% returns a string
	} def

newfont /FontBBox get			% bounding box: [lx ly ux uy]
dup					% 2 copies of the array
dup					% 3 copies of the array
/uy exch 3 get def			% last number is upper-right y
/ux exch 2 get def			% next down is upper-right x
/ly exch 1 get def			% 2nd number is lower-left y

/FontType 3 def
/PaintType 3 def		% characters draw themselves

basefontdict setfont 
/Metrics 100 dict def
32 1 127 {
	dup
	Encoding exch get 	% stack: code /name
	dup			% stack: code /name /name
	/.notdef ne {		% stack: code /name true
		exch		% stack: /name code
		intostring		% stack: /name str
		stringwidth		% stack: /name x y
		pop	 		% stack: /name x
		% end
		1000 mul		% stack: /name 1000x
		newfont /Metrics get	% stack: /name 1000x Metrics
		3 1 roll		% stack: Metrics /name 1000x
		put } { pop pop } ifelse
	} for

/CharProcs 106 dict def
CharProcs begin
	32 1 127 { 
		/code exch def		% used to create proc
		/name Encoding code get def	% stack: nothing
		name /.notdef ne {    	% don't do for notdefs
		name 
		{ dup			 % proc called with integer
		Encoding exch get	% integer name
		Metrics exch get	 % integer xwidth
		  box			% box needs xwidth, leaves integer
		  0 0 moveto 1 setgray
		  basefontdict 1000 scalefont setfont
		  intostring
		  basefontdict /PaintType get 	% stroke or filled font?
		  0 eq				% 0 = filled font
		  {show} 			% if filled font
		  {40 setlinewidth false charpath stroke} % if stroked
		  ifelse
		  } def 
		  } if		% end "don't do for .notdef"
	} for
/.notdef { } def
end

/BuildChar {
	/char exch def		% integer
	/fontdict exch def	% font dictionary
	% /charname
	fontdict begin
	Encoding char get 	% name
	fontdict /Metrics get exch get 0  	% xwidth 0
	% 4 { pop } repeat
	setcharwidth
	char			% integer
	Encoding char get	% integer name
	CharProcs exch get	% integer {}
	exec
	end
} def

end		% end of newfont use
newfont 	% push the new font dictionary onto stack

} def				% end reversefont def

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% These lines demonstrate reverse Times-Roman
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Define the reverse font:
   /Reverse-Times /Times-Roman reversefont definefont pop
% First show the regular font
   /Times-Roman findfont 12 scalefont setfont
   74 740 moveto (qwertyuiop][asdfghsdfjkl;'zxcvbnm,./) show
% Now show the reversed font
   /Reverse-Times findfont 12 scalefont setfont
   74 720 moveto (qwertyuiop][asdfghsdfjkl;'zxcvbnm,./) show

showpage
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% End of demo program
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

prs@tcsc3b2.tcsc.com (Paul Stath) (01/20/90)

hougland@osiris.cso.uiuc.edu writes:


>I am interested in printing characters in a 'reverse video' format, that
>is white characters on a dark background.  I am afraid I may have to 
>create my own font to do this, but can find no other way so far.  Any
>suggestions would be welcome.

Why not just dup the string on the stack, and use the first instance to
get the bounding box of the string.  Then use this to draw a filled rectangle
in the background color, then print the remaining string in white over the
filled bounding box?

Something along this line:

% Rvideo - expects the string to display in "reverse video" to be on
%          the top of the stack.  You must have a currentpoint
/Rvideo {
gsave
	dup		% Make two copies of the string on the stack
	0 setgray	% Set background video color
	currentpoint	% Save current point on stack
	false charpath flattenpath pathbbox	% get Bounding box of string
	newpath		% Start newpath
	0 exch rlineto	% line to UL-hand corner of bounding box
	0 rlineto	% line to UR-hand corner of bounding box
	0 exch rlineto	% line to LR-hand corner of bounding box
	closepath fill	% close path and fill with background color
	moveto		% Move to point saved with currentpoint
	1 setgray	% Switch to "reverse" video color
	show		% Show string
grestore
} def

Disclaimer:  This is untested code written off the top of my head.
	I don't claim that this would even come CLOSE to working "as is."
	The good thing about this is that it will work with ANY font.
	The problem is that the bounding box may only be as big as the
	edges of the text.  If this is the case, you could try adding
	distance to the x and y coordinate placed on the stack by pathbbox,
	or you could try changing the scale slightly after getting the
	x/y corners of the bounding box.  This could be a handy tool to
	have in my PostScript toolkit, so if you get it working, send me
	a copy.  And since this is a followup instead of E-mail, if anyone
	else has a different or better idea, I would enjoy seeing it.
	I will test this code this week-end and see it I can come up with
	some corrected, tested code.

         ---- What I wouldn't give for a PostScript signature!!! ----
-- 
===============================================================================
Paul R. Stath       The Computer Solution Co., Inc.       Voice: 804-794-3491
------------------------------------------------+------------------------------
INTERNET:	prs@tcsc3b2.tcsc.com		| "There was no diety involved,

prs@tcsc3b2.tcsc.com (Paul Stath) (01/20/90)

Well, I got around to testing this sooner than I thought.  So here is the
tested version of rVideo.ps!  This program prints "Hello World!" in
"reverse video."  I forgot about little things like "nocurrentpoit"
problems and such, but this works great.  The letters do NOT "leak" out
of the edges of the inverse bounding box, but you might want to play with
the assignment of LLx LLy URx URy to produce larger borders.  Have fun,
I know I did!!

-------------------------------------------------------------------------------
%!
%%Title: rVideo.ps

% Rvideo - expects the string to display in "reverse video" to be on
%          the top of the stack.  You must also have a currentpoint.
/Rvideo {
gsave
	dup		% Make two copies of the string on the stack
	currentpoint	% Save current point on stack
	3 -1 roll	% bring one string to top of stack
	0 setgray	% Set background video color
	false charpath flattenpath pathbbox	% get Bounding box of string
	/URy exch def	% These can be added or subtracted
	/URx exch def	% 	from in order to get thicker
	/LLy exch def	% 	borders around the inverse text
	/LLx exch def
	LLx LLy moveto	% move to lower left hand corner of box
	LLx URy lineto	% line to UL-hand corner of bounding box
	URx URy lineto	% line to UR-hand corner of bounding box
	URx LLy lineto	% line to LR-hand corner of bounding box
	closepath fill	% close path and fill with background color
	moveto		% Move to point saved with currentpoint
	1 setgray	% Switch to "reverse" video color
	show		% Show string
grestore
} def

%%----Global Variables---------------------------------------------------
/Times-Bold findfont 44 scalefont
/Times-Roman44 exch def

%%----Program Script-----------------------------------------------------
Times-Roman44 setfont
72 72 moveto
(Hello World!) Rvideo
showpage
-------------------------------------------------------------------------------
-- 
===============================================================================
Paul R. Stath       The Computer Solution Co., Inc.       Voice: 804-794-3491
------------------------------------------------+------------------------------
INTERNET:	prs@tcsc3b2.tcsc.com		| "There was no diety involved,

batcheldern@hannah.enet.dec.com (Ned Batchelder) (01/22/90)

In article <1544@scorn.sco.COM>, bobs (Bob Stayton, Yoyodoc) writes...
>As promised, here is my routine for creating a reverse
>video font. It allows you to create a reverse font in your prolog
>from an existing Postscript font, and then use the reverse
>font like any other font in your document.  

Keep in mind that this font will be much slower than other fonts for large
amounts of text, since it uses setcharwidth rather than setcachedevice. The
font cache is not used at all, so every character must be built fresh.

An alternate technique for building a reverse video font is to use charpath to
put the character's outline in the current path, then put a rectanlge around it
(see other articles on this topic for how to compute the size of this
rectangle), and then fill the composite. If you get the directions right, you
will end up filling the space between the character and the rectangle. No "1
setgray" is involved, so you can use setcachedevice, and get cached reverse
video.

Ned Batchelder, Digital Equipment Corp., BatchelderN@Hannah.enet.DEC.com

bill@chelgraph.CO.UK (bill davy) (01/22/90)

In article <37700001@osiris.cso.uiuc.edu> hougland@osiris.cso.uiuc.edu writes:
>
>I am interested in printing characters in a 'reverse video' format, that
>is white characters on a dark background.  I am afraid I may have to 
>create my own font to do this, but can find no other way so far.  Any
>suggestions would be welcome.
>
>hougland
> 

Wot, no reverse video or xor command?  Tut, tut!