[comp.lang.postscript] font question

liam@cs.qmc.ac.uk (William Roberts) (01/11/89)

I am trying to provide the characters W-circumflex and
Y-circumflex for a user who deals with Welsh (Funny, this seems
to have been overlooked by all the ISO font work...)

I have been playing with the Times fonts and the associated afm
files, and I know correct looking offsets for printing the
circumflex character on top of the W,Y,w and y characters (in
the non-italic fonts), so all is looking fine for making these
composite characters out of existing Times characters.

But....

How do I define a new font that extends the existing
Times-Roman by the new composite definitions?  Times-Roman is a
builtin font, so it doesn't have a BuildChar routine, so I
can't just stuff in some extra defs and a new Encoding vector.

Times-Roman also lacks a CharBBox directory, so I won't know
what to say for the bounding box of each of the unchanged
Times-Roman characters (though I do know my new ones, of
course). Will I really have to go through the grotesque process
of "charpath pathbbox" on each one (it would be easier to copy
in the data from the afm file)?  Do I have to do a

        /Times-Roman findfont 1000 scalefont setfont

for every call to BuildChar?

Once I have created this font (I'll manage it somehow, even if
the answer is totally gruesome!), I want to make it useable by
A.N.Other Wordprocessing package, so I will also need to know
a format I can use to get the same treatment as the Adobe
downloadable fonts - where can I get this information?


All assistance gratefully received - I promise to post the
resulting font to comp.fonts so any other Cymruphiles out there
can use it.
-- 

William Roberts         ARPA: liam@cs.qmc.ac.uk  (gw: cs.ucl.edu)
Queen Mary College      UUCP: liam@qmc-cs.UUCP
LONDON, UK              Tel:  01-975 5250

ws@linod.UUCP (Wilfried Soeker) (02/08/89)

Composite Characters in PostScript
(C) Copyright Dipl.-Ing. Wilfried Soeker
    All Rights reserved

Extending the internal characterset with characters composed of standard
characters and/or any graphic seems to be difficult, especially if you
want to make use of the internal fonts.  The solution of this problem is
easy: use userfonts.

The basic idea behind the programs supplied with this text is the fact,
that there are not many things you can't do inside the "BuildChar"-
procedure of the userfonts, e.g.  it is possible to print characters
in another font!

What we want "BuildChar" to do is the following:
    1) select the basic font for the composite character
    2) print the basic character
    3) move the current point to whereever you want
    4) print a second character

With this program you can construct your own composite font with internal
fonts (and their quality!!) and use them with the standard encoding scheme.

Program 1 does the composition and reencoding. An example for the usage is
          included.

Program 2 is a program to help justifing the character positions. It prints
          the characters in 500 pt with a coordinate system in the background.
		  Note that the data used here is exact the same needed for program 1.

Some of the older PostScript versions may have problems with the "stringwidth"
operator. The effect is that the "show"s in BuildChar are not suppressed and
so they are printed.  There are several ways to solve this problem:

/stringwidth {gsave nulldevice stringwidth grestore} bind def
   or
/stringwidth {
    currentpoint 1e10 dup moveto stringwidth 4 2 roll moveto} bind def

The second solution is a bit "quick and dirty", but I think, it will be faster
than the first one. Both of them will work.

The processing speed is a bit slower than the original fonts, but the fact,
that the used basic and accent characters are cached, will give you acceptable
results. 

This article shows you just the tip of the iceberg. There are so many things
you can do with userfonts.

Some knowledge about programming in PostScript is necessary to understand the
following programs. I published a similar article in the german journal "PAGE",
issue 1/89.

If you have problems with the programs or have any suggestions please do not
hesitate to contact me.

                W. Soeker

Note:
    I am working as a consultant for the Linotype PostScript Support Group
    in Eschborn, West-Germany, but no part of this articles represents the
    opinion of Linotype.

PS: PostScript is a registered trademark of Adobe Systems Incorporated.

###########################################################################
#            Program 1                                                    #
###########################################################################

% Program for installation of fonts with userdefined accents.
% (C) Dipl.-Ing. Wilfried Soeker, February 1989
% Alpenroder Str. 14, D-6230 Frankfurt 80, West-Germany
% This program may be used or copied for non-commercial use
% only if this header with the copyright note is included.
% Commercial use of this program without written permission is prohibited!
%
/Neue-Akzente {         % Arguments: Basisfont New-Fontname Accenttable.
   10 dict dup begin               % This Dictionary is the new Font.
   /FontType 3 def                      % 3 = Userfont.
   /FontMatrix [0.01 0 0 0.01 0 0] def  % For internal use.
   /FontBBox [0 0 100 100] def          % Working area.
   /Basis_Font 5 -1 roll findfont def   % Store original font.
   /Encoding 256 array def         % Mark special character positions.
   0 1 255 {                       % All Positions 
      Encoding exch false put      % are initialised with "false".
      } for 

   exch aload length 2 idiv        % Get the amount of chars.
      { Encoding 3 1 roll put      % 
      } repeat                     %

   /BuildChar {                    % 
      exch begin                   % Open Font.
      Basis_Font 100 scalefont setfont % Aktivate basicfont.
      dup Encoding exch get          % Look into the table.
      dup false eq                 % Is this a special character?
         {   pop                   % NO!! It's a 'normal' one.
           ( ) dup 0 4 -1 roll put % Put chat in a string.
           dup stringwidth         % Get charwidth
           setcharwidth            % and use it.
           0 0 moveto              % 
           show                    % Print out this char!
           }
         {                          % Yes, this was a special char!
            exch pop aload pop      % Get the special char description.
            3 -1 roll               % Get the basic-char
            ( ) dup 0 4 -1 roll put  % and put it in a string.
            dup stringwidth         % Get the charwidth of the basic char
            setcharwidth            % and use it for the composite char.
            0 0 moveto              % Set the position
            show                    % and print it.
            0 0 moveto              % Set the position for the accent.
            exch                    % Get the accent procedure
            exec                    % and execute it.
            ( ) dup 0 4 -1 roll put   % Get the accent char 
            show                    % and print it.
            }
         ifelse
      end                           % That's all.
      } bind def
   end

   definefont pop                   % Registation of the new font.
   } def                            % End of "Neue-Akzente"

% Let's try a Czech font
% 
/Times-Roman                        % Name of the basicfont.
/Times-Tschech                      % Name of the new font.
[                                   % The description the special chars.
8#321                               % First the position in the encoding.
[                                   % The Array with the description of
                                    % a single composite char.
   8#143                            % Basicchar (c).
 {                                  % Procedure for position correction.
  6                                 % Correction in X-direction.
  0                                 %     "         Y-   "    .
   rmoveto                          % Move to this position.
   }                                % End of correction.
  8#317                             % Accent-Character.
                                    % (see PostScript referece manual p.254)
  ]                                 % End of this composite char.
% 
8#322 [ 8#156 {7 0 rmoveto } 8#317 ]             % n with \317
8#323 [ 8#172 {0 -2 rmoveto } 8#302 ]            % y with \302
8#324 [ 8#165 {6 0 rmoveto } 8#312 ]             % u with \312
8#325 [ 8#162 {0 0 rmoveto } 8#317 ]             % r with \317
8#326 [ 8#122 {10 32 rmoveto 1 0.5 scale } 8#317 ] % R with \317
8#327 [ 8#105 {13 18 rmoveto } 8#317 ]           % E with \317
8#330 [ 8#145 {6 -3 rmoveto } 8#302 ]            % e with \302
8#331 [ 8#105 {20 18 rmoveto } 8#302 ]           % E with \302
8#332 [ 8#144 {35 5 rmoveto } 8#047 ]            % d with \047
8#333 [ 8#164 { 6 5 rmoveto } 8#047 ]            % t with \047
] Neue-Akzente                      % Build a new font with composite chars.


/Times-Tschech findfont             % Find the new font
       12 scalefont setfont         % and activate it .
100 250 moveto
(The following characters are composed) show
100 200 moveto
(\322\323\324\325\326\327\330\331\332\332) show

showpage


###########################################################################
#            Program 2                                                    #
###########################################################################



% (c) Dipl.-Ing. Wilfried Soeker, February 1989
%
/xl 50 def   /yu 100 def            % lower left corner
/delta 5 def
/size 500 def
/showpair {                         % Arguments: Basicchar, procedur and Accent
                                    % (the same as needed by Neue-Akzente)
% Print the background first
     /Helvetica findfont 8 scalefont setfont
% The vertical lines
     xl yu moveto
     0 1 size delta idiv
          { dup 5 mod 0 eq
               { 0.7 setlinewidth currentpoint
                 3 -1 roll (   ) cvs dup
                 stringwidth pop 2 div neg -10 rmoveto show moveto
                 }
               { pop 0.1 setlinewidth }
               ifelse
            currentpoint 2 copy
            transform round exch round exch itransform moveto
            0 size rlineto stroke   
            moveto                 
            delta 0 rmoveto       
            } for

% The horizontal lines
     xl yu moveto
     0 1 size delta idiv
          { dup 5 mod 0 eq
               { 0.7 setlinewidth currentpoint
                 3 -1 roll (   ) cvs dup
                 stringwidth pop 3 add neg -3 rmoveto show
                 moveto
                 }
               { pop 0.1 setlinewidth }
               ifelse
            currentpoint 2 copy
            transform round exch round exch itransform moveto
            size 0 rlineto stroke   
            moveto                  
            0 delta rmoveto
            } for

% The composite character
     xl yu moveto
     /Times-Roman                            % Basic font
     findfont size scalefont setfont
     xl yu moveto
     3 -1 roll ( ) dup 0 4 -1 roll put show  % print the basic char.
     xl yu moveto
     delta dup scale                         % scaling inside the procedure
     currentpoint translate                  % for absolute positioning.
     exch exec                               % execute the procedure.
     1 delta div dup scale                   % reset the scaling.
     ( ) dup 0 4 -1 roll put show            % print accent char.
     showpage
     } def                                   % end of "showpair".



% now some example for the use of showpair
% 
% First a R with \317 and no correction.
(R) 0 get { } 8#317 showpair
% 
% The same with corrected position.
(R) 0 get { 10 15 rmoveto } 8#317 showpair
% 
% And the same pair again, but the \317 scaled down to half height.
(R) 0 get { 10 40 rmoveto 1 0.5 scale } 8#317 showpair
% 
% Now something special: an icelandic D with a horizontal line.
(D) 0 get { 2 34 moveto 30 0 rlineto 3.5 setlinewidth stroke
            0 0 moveto} ( ) 0 get showpair
###########################
#        End of Text      #
###########################

aes@laisagna.i88.isc.com (Andy Schweig) (09/08/89)

I'm trying to define a character in a user-defined font that consists of
characters from a builtin font.  Specifically, I would like the INTERACTIVE
logo to be produced by \(bs from troff.  The logo consists of the word
INTERACTIVE in Helvetica, a row of filled boxes below that, and the words
"A Kodak Company", also in Helvetica (Kodak is in Helvetica-Bold), below
that.  I have a PostScript procedure that produces the logo which works
fine by itself but only partially works when executed as the procedure
defining a particular character in a user-defined font.  I seem to get
different wacky behavior depending on the size of the logo.  For example,
one particular size (26) produces the logo but has the annoying side effect
of producing a little mark at the very top of the page, the position
apparently not depending on the position of the logo.  After a little
experimentation, I discovered that the little mark is apparently the very
bottom of the "C" in INTERACTIVE (changing the C to an X causes the mark to
go away).  Any ideas?

Andy Schweig			|  Monkey heads?
Interactive Systems		|  Really?  We're having monkey heads?
aes@i88.isc.com			|  We are not...Are those really monkey heads?
...!laidbak!aes			|  Wow!  Monkey heads!

graham@gestetner.oz (graham) (09/10/90)

Page 95 of Postscript Language Reference Manual:
"All unused positions in an encoding vector must be filled with the name
'.notdef'. Printing one of these unused characters produces no marks on 
the page and no side-effects".

Builtin fonts, which use the StandardEncoding vector, do not seem to agree.
Characters that index to a ".notdef" name, seem to cause the same
side-effect as produced by "space".
Is this implementaion/version specific ?
What does the latest documentation have to say ?

kevina@apple.com (This space for rent) (09/12/90)

In article <564@gestetner.oz> graham@gestetner.oz (graham) writes:
> Page 95 of Postscript Language Reference Manual:
> "All unused positions in an encoding vector must be filled with the name
> '.notdef'. Printing one of these unused characters produces no marks on 
> the page and no side-effects".
> 
> Builtin fonts, which use the StandardEncoding vector, do not seem to 
agree.
> Characters that index to a ".notdef" name, seem to cause the same
> side-effect as produced by "space".
> Is this implementaion/version specific ?
> What does the latest documentation have to say ?

Depending on how you interpret "side-effects", the space character fits 
the Adobe definition:  a) it doesn't leave any marks on the page, and b) 
the side-effects talked about probably refer to VM and interpreter state rather than currentpoint (I agree that it is confusing!)  I understand 
that the Redder Book will clarify this for Type 1 fonts and leave the 
behavior of .notdef up to the designer for others.

The reason that .notdef must exist is that most Adobe font types quietly 
substitute it rather than raise an undefined error if a character name 
from the Encoding vector is not found in the CharStrings dictionary.

--Kevin Andresen [kevina@apple.com]
"The first time I read the dictionary I thought it was a poem about
everything."