[comp.lang.postscript] Composite characters

noid@athena.mit.edu (Adam G. Mellis) (01/04/89)

Could someone tell me the right way to create a composite
character in a user-defined font.  Say I have two chars, z
and caron, both defined in my CharacterDefs dict, and I want
a new char, zcaron, that has a caron above the z: simply
calling the caron procedure within zcaron fails as the caron
procedure is apparently undefined.  Why? (It's in the same
dictionary, preceeding the zcaron def ...)  Also, is there a
canonical way of doing this?

Thanks,

Adam

rgrove@pogo.GPID.TEK.COM (Robert Grove) (01/17/89)

In article <8600@bloom-beacon.MIT.EDU> noid@athena.mit.edu (Adam G. Mellis) writes:
>Could someone tell me the right way to create a composite
>character in a user-defined font.  Say I have two chars, z
>and caron, both defined in my CharacterDefs dict, and I want
>a new char, zcaron, that has a caron above the z: simply
>calling the caron procedure within zcaron fails as the caron
>procedure is apparently undefined.  Why?...

I sent mail but, I am not sure it got through.

I suspect the reason to be that you have set the current directory
to be your font directory within the BuildChar procedure. The character
definitions are in another dictionary, probably CharacterDefs, which is
a dictionary contained within your fontdict.

Usually, the procedure to draw your character is put on the stack and
executed by something like:
   CharacterDefs Charname get exec  % Charname is the name of the character
within BuildChar. If your CharacterDef entry for your combined character,
/zcaron, simply tries to execute the procedure for /z and /caron, it won't
find them in the current dictionary (Your font dict).

There are several solutions to the problem. One technique I have used 
sucessfully for combined user defined characters would have an entry for the
zcaron character in CharacterDefs something like the following:

/zcaron { CharacterDefs /z get exec
          CharacterDefs /caron get exec
        } def

Another solution which should work, although I have not tried it, would
be to make Characterdefs the currentdict with begin ... end within the
procedure for zcaron.

Don't forget to have a BBox entry for zcaron which will hold both of the
characters from which it is derived as well as an appropriate Metrics
entry.

-- 
Robert Grove
rgrove@pogo.gpid.tek.com | {anybackbone}!tektronix!pogo.gpid.tek.com!rgrove

coleman@lll-lcc.UUCP (Sam Coleman) (01/04/90)

There was some discussion recently about composite characters.  Composites
are mentioned in sections 7.8 and 7.9 of the Green Book, but there's no
explanation of how to do it.

The Postscript code below represents one way to create composites, with two
or more standard characters or combinations of standard characters and
custom characters.  The sample below includes some accented characters and
some characters used in medieval texts.  There are actually four fonts,
with italic, bold, etc.  The code is loosely based on the sample on page
145 of the Green Book.  Incidently, the fonts also include some fractions.
It seems that within a font fractions are easier than program 8 in the Blue
Book.  I suppose that News will fold the lines that exceed 80 characters,
but hopefully it will still be readable.

I'd appreciate comments on other ways to create composites or improvements
to this code.

Sam Coleman
coleman@lll-lcc.llnl.gov

-------------------------------------------------------------------------

%!PS-Adobe-2.0
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%  Create base dictionaries for special CCRH  %
%  fonts including definitions common to all  %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
/Widths 36 dict def Widths begin
   /.notdef    1000 def
   /eacute      449 def
   /ecircumflex 449 def
   /egrave      449 def
   /ellipsis   1750 def
   /llslash     601 def
   /ocircumflex 505 def
   /odieresis   505 def
   /dblspace    510 def
   /1half       828 def
   /1quarter    828 def
   /3quarters   828 def
   /3dot        505 def
   end

/NewFont 53 dict def NewFont begin
   /FontBBox   [-1000 -1000 1750 1000] def
   /FontMatrix [.001 0 0 .001 0 0]     def
   /FontType   3                       def

   /Encoding 256 array
      dup  0 1 255 {/.notdef put dup} for pop
      dup  8#143  /cbar          put   % c  (encoding character)
      dup  8#144  /dtail         put   % d
      dup  8#322  /eacute        put   % \322
      dup  8#323  /ecircumflex   put   % \323
      dup  8#325  /egrave        put   % \325
      dup  8#274  /ellipsis      put   % \274
      dup  8#146  /fbar          put   % f
      dup  8#246  /ff            put   % \246
      dup  8#256  /ffi           put   % \256
      dup  8#257  /ffl           put   % \257
      dup  8#147  /gbar          put   % g
      dup  8#150  /hbar          put   % h
      dup  8#153  /kbar          put   % k
      dup  8#370  /llslash       put   % \370
      dup  8#155  /mtail         put   % m
      dup  8#376  /nmacron       put   % \376
      dup  8#156  /ntail         put   % n
      dup  8#334  /ocircumflex   put   % \334
      dup  8#335  /odieresis     put   % \335
      dup  8#160  /pmacron       put   % p
      dup  8#162  /rtail         put   % r
      dup  8#040  /dblspace      put   % space
      dup  8#164  /tbar          put   % t
      dup  8#301  /thorn         put   % \301
      dup  8#302  /Thorn         put   % \302
      dup  8#305  /umacron       put   % \305
      dup  8#344  /ucircumflex   put   % \344
      dup  8#345  /udieresis     put   % \345
      dup  8#165  /utail         put   % u
      dup  8#303  /yogh          put   % \303
      dup  8#304  /Yogh          put   % \304
      dup  8#062  /1half         put   % 2
      dup  8#061  /1quarter      put   % 1
      dup  8#064  /3quarters     put   % 4
      dup  8#063  /3dot          put   % 3
   def

   /BuildChar {exch begin Encoding exch get dup Metrics exch get
      0 -1000 -1000 1750 1000 setcachedevice load exec end} bind def

   /f {gsave 0 0 m basefont findfont 1000 scalefont setfont show} bind def

   /fr {gsave 320 0 m basefont findfont dup 1000 scalefont setfont
       (\244) show [650 0 0 600 0 0] makefont setfont
       0 275 m show 505 0 m show r} bind def

   /c  {curveto}      bind def
   /l  {lineto}       bind def
   /m  {moveto}       bind def
   /r  {grestore}     bind def
   /s  {stroke}       bind def
   /sl {setlinewidth} bind def

   /.notdef   {gsave 100 0 m 800 0 l 800 800 l 100 800 l fill r} bind def
   /ellipsis  {( . . .) f r} bind def
   /dblspace  {            } bind def
   /1half     {(2) (1) fr  } bind def
   /1quarter  {(4) (1) fr  } bind def
   /3quarters {(4) (3) fr  } bind def
   /cbar      {(c)  f  30 sl 334 434 m 529 434 l s 529 550 m 529 300 l s r} bind def
   /ff        {(f)  f -95 0 rmoveto (f)    show r} bind def
   /ffi       {(f)  f -95 0 rmoveto (\256) show r} bind def
   /ffl       {(f)  f -95 0 rmoveto (\257) show r} bind def
   /llslash   {(ll) f  30 sl 0 250 m 250 450 400 250 550 450 c s r} bind def
   /nmacron   {(n)  f  60 0 m       (\305) show r} bind def
   /pmacron   {(p)  f  60 0 m       (\305) show r} bind def
   /umacron   {(u)  f  60 0 m       (\305) show r} bind def
%
%%%%%%%%%%%%%%%%%%%%%%%
%  Create Roman font  %
%%%%%%%%%%%%%%%%%%%%%%%
%
   currentdict 53 dict copy begin currentdict
   /FontName /CCRHRoman   put
   /basefont /Times-Roman def

   /Metrics Widths 36 dict copy def Metrics begin
      /cbar        600 def
      /dtail       635 def
      /fbar        535 def
      /ff          581 def
      /ffi         800 def
      /ffl         790 def
      /gbar        570 def
      /hbar        505 def
      /kbar        640 def
      /mtail       963 def
      /nmacron     505 def
      /ntail       675 def
      /pmacron     505 def
      /rtail       443 def
      /tbar        480 def
      /thorn       455 def
      /Thorn       525 def
      /umacron     500 def
      /ucircumflex 505 def
      /udieresis   505 def
      /utail       685 def
      /yogh        325 def
      /Yogh        415 def
   end

   /dtail       {(d) f 30 sl 420 640 m 690 600 400 450 600 250 c s r} bind def
   /eacute      {(e) f 55 0 m (\302) show r} bind def
   /ecircumflex {(e) f 55 0 m (\303) show r} bind def
   /egrave      {(e) f 55 0 m (\301) show r} bind def
   /fbar        {(f) f 30 sl 244 434 m 439 434 l s 449 550 m 449 300 l s r} bind def
   /gbar        {(g) f 30 sl 354 414 m 549 414 l s 559 530 m 559 280 l s r} bind def
   /hbar        {(h) f 20 sl -20 560 m 400 560 l s r} bind def
   /kbar        {(k) f 30 sl 384 434 m 579 434 l s 589 550 m 589 300 l s r} bind def
   /mtail       {(m) f 30 sl 180 560 m 690 560 l 960 600 960 30 750 20 c s r} bind def
   /ntail       {(n) f 30 sl 150 560 m 390 560 l 660 600 660 30 450 20 c s r} bind def
   /ocircumflex {(o) f 83 0 m (\303) show r} bind def
   /odieresis   {(o) f 83 0 m (\310) show r} bind def
   /rtail       {(r) f 30 sl 330 400 m 400 450 400 550 330 650 c s r} bind def
   /tbar        {(t) f 30 sl 195 434 m 390 434 l s 400 550 m 400 300 l s r} bind def
   /thorn       {30 sl 0 498 m 143 543 l s 105 536 m 105 -163 l -24 -207 l s 114 331 m 440 673 539  49 112 49 c s} bind def
   /Thorn       {45 sl 8 613 m 143 664 l s 126 655 m 126 -118 l -17 -165 l s 136 428 m 497 806 605 118 260 59 c s} bind def
   /ucircumflex {(u) f 83 0 m (\303) show r} bind def
   /udieresis   {(u) f 83 0 m (\310) show r} bind def
   /utail       {(u) f 30 sl 150 560 m 390 560 l 660 600 660 30 450 20  c s r} bind def
   /yogh        {30 sl 33 386 m 206 534 416 303 33 142 c s 35 116 m 210 204 405  -24 -16 -198 c s} bind def
   /Yogh        {30 sl 50 410 m 293 616 587 292 50  67 c s 50  20 m 299 154 572 -166 -20 -410 c s} bind def
   /3dot        {gsave 85 0 m basefont findfont 1000 scalefont setfont (\307) show 0 -225 m (3) show r} bind def

   FontName currentdict definefont pop end
%
%%%%%%%%%%%%%%%%%%%%%%%%
%  Create Italic font  %
%%%%%%%%%%%%%%%%%%%%%%%%
%
   currentdict 53 dict copy begin currentdict
   /FontName /CCRHItalic   put
   /basefont /Times-Italic def

   /Metrics Widths 36 dict copy def Metrics begin
      /cbar        560 def
      /dtail       650 def
      /fbar        488 def
      /ff          471 def
      /ffi         693 def
      /ffl         693 def
      /gbar        570 def
      /hbar        505 def
      /kbar        600 def
      /mtail       840 def
      /nmacron     505 def
      /ntail       600 def
      /pmacron     505 def
      /rtail       480 def
      /tbar        470 def
      /thorn       455 def
      /Thorn       525 def
      /umacron     505 def
      /ucircumflex 505 def
      /udieresis   505 def
      /utail       660 def
      /yogh        325 def
      /Yogh        415 def
   end

   /dtail       {(d) f 30 sl 470 640 m 740 600 450 450 650 250 c s r} bind def
   /eacute      {(e) f 68 0 m (\302) show r} bind def
   /ecircumflex {(e) f 68 0 m (\303) show r} bind def
   /egrave      {(e) f 68 0 m (\301) show r} bind def
   /fbar        {(f) f 30 sl 244 414 m 439 414 l s 449 530 m 449 280 l s r} bind def
   /gbar        {(g) f 30 sl 354 384 m 549 384 l s 559 500 m 559 250 l s r} bind def
   /hbar        {(h) f 20 sl 120 560 m 540 560 l s r} bind def
   /kbar        {(k) f 30 sl 354 434 m 549 434 l s 559 550 m 559 300 l s r} bind def
   /mtail       {(m) f 30 sl  40 560 m 550 560 l 820 600 820 30 610 20 c s r} bind def
   /ntail       {(n) f 30 sl 100 560 m 340 560 l 610 600 610 30 400 20 c s r} bind def
   /ocircumflex {(o) f 89 0 m (\303) show r} bind def
   /odieresis   {(o) f 89 0 m (\310) show r} bind def
   /rtail       {(r) f 30 sl 380 400 m 450 450 450 550 380 650 c s r} bind def
   /tbar        {(t) f 30 sl 195 434 m 390 434 l s 400 550 m 400 300 l s r} bind def
   /thorn       {30 sl 0 498 m 143 543 l s 105 536 m 105 -163 l -24 -207 l s 114 331 m 440 673 539  49 112 49 c s} bind def
   /Thorn       {45 sl 8 613 m 143 664 l s 126 655 m 126 -118 l -17 -165 l s 136 428 m 497 806 605 118 260 59 c s} bind def
   /ucircumflex {(u) f 83 0 m (\303) show r} bind def
   /udieresis   {(u) f 83 0 m (\310) show r} bind def
   /utail       {(u) f 30 sl 150 560 m 390 560 l 660 600 660 30 450 20  c s r} bind def
   /yogh        {30 sl 33 386 m 206 534 416 303 33 142 c s 35 116 m 210 204 405  -24 -16 -198 c s} bind def
   /Yogh        {30 sl 50 410 m 293 616 587 292 50  67 c s 50  20 m 299 154 572 -166 -20 -410 c s} bind def
   /3dot        {gsave 140 0 m basefont findfont 1000 scalefont setfont (\307) show 0 -225 m (3) show r} bind def

   FontName currentdict definefont pop end
%
%%%%%%%%%%%%%%%%%%%%%%
%  Create Bold font  %
%%%%%%%%%%%%%%%%%%%%%%
%
   currentdict 53 dict copy begin currentdict
   /FontName /CCRHBold   put
   /basefont /Times-Bold def

   /Metrics Widths 36 dict copy def Metrics begin
      /cbar        600 def
      /dtail       690 def
      /fbar        535 def
      /ff          581 def
      /ffi         780 def
      /ffl         780 def
      /gbar        650 def
      /hbar        561 def
      /kbar        680 def
      /mtail       970 def
      /nmacron     561 def
      /ntail       700 def
      /pmacron     561 def
      /rtail       480 def
      /tbar        530 def
      /thorn       460 def
      /Thorn       545 def
      /umacron     561 def
      /ucircumflex 561 def
      /udieresis   561 def
      /utail       700 def
      /yogh        335 def
      /Yogh        425 def
   end

   /dtail       {(d) f 30 sl 480 640 m 750 600 460 450 660 250 c s r} bind def
   /eacute      {(e) f 61 0 m (\302) show r} bind def
   /ecircumflex {(e) f 61 0 m (\303) show r} bind def
   /egrave      {(e) f 61 0 m (\301) show r} bind def
   /fbar        {(f) f 30 sl 244 434 m 439 434 l s 449 550 m 449 300 l s r} bind def
   /gbar        {(g) f 30 sl 404 434 m 599 434 l s 609 550 m 609 300 l s r} bind def
   /hbar        {(h) f 50 sl -20 560 m 400 560 l s r} bind def
   /kbar        {(k) f 30 sl 384 434 m 579 434 l s 589 550 m 589 300 l s r} bind def
   /mtail       {(m) f 30 sl 180 560 m 690 560 l 960 600 960 30 750 20 c s r} bind def
   /ntail       {(n) f 40 sl 150 560 m 390 560 l 660 600 660 30 450 20 c s r} bind def
   /ocircumflex {(o) f 83 0 m (\303) show r} bind def
   /odieresis   {(o) f 83 0 m (\310) show r} bind def
   /rtail       {(r) f 30 sl 380 400 m 450 450 450 550 380 650 c s r} bind def
   /tbar        {(t) f 30 sl 245 434 m 440 434 l s 450 550 m 450 300 l s r} bind def
   /thorn       {60 sl 0 498 m 143 543 l s 105 536 m 105 -163 l -24 -207 l s 114 331 m 440 673 539  49 112 49 c s} bind def
   /Thorn       {80 sl 8 613 m 143 664 l s 126 655 m 126 -118 l -17 -165 l s 136 428 m 497 806 605 118 260 59 c s} bind def
   /ucircumflex {(u) f 104 0 m (\303) show r} bind def
   /udieresis   {(u) f 104 0 m (\310) show r} bind def
   /utail       {(u) f 40 sl 150 560 m 390 560 l 660 600 660 30 450 20  c s r} bind def
   /yogh        {60 sl 33 386 m 206 534 416 303 33 142 c s 35 116 m 210 204 405  -24 -16 -198 c s} bind def
   /Yogh        {60 sl 50 410 m 293 616 587 292 50  67 c s 50  20 m 299 154 572 -166 -20 -410 c s} bind def
   /3dot        {gsave 130 0 m basefont findfont 1000 scalefont setfont (\307) show 0 -225 m (3) show r} bind def

   FontName currentdict definefont pop end
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%  Create BoldItalic font  %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
   currentdict begin currentdict
   /FontName /CCRHBoldItalic   put
   /basefont /Times-BoldItalic def

   /Metrics Widths def Metrics begin
      /cbar        580 def
      /dtail       645 def
      /fbar        540 def
      /ff          581 def
      /ffi         804 def
      /ffl         804 def
      /gbar        630 def
      /hbar        561 def
      /kbar        650 def
      /mtail       973 def
      /nmacron     561 def
      /ntail       650 def
      /pmacron     505 def
      /rtail       450 def
      /tbar        488 def
      /thorn       460 def
      /Thorn       545 def
      /umacron     561 def
      /ucircumflex 561 def
      /udieresis   561 def
      /utail       700 def
      /yogh        335 def
      /Yogh        425 def
   end

   /dtail       {(d) f 30 sl 480 640 m 750 600 460 450 660 250 c s r} bind def
   /eacute      {(e) f 55 0 m (\302) show r} bind def
   /ecircumflex {(e) f 55 0 m (\303) show r} bind def
   /egrave      {(e) f 55 0 m (\301) show r} bind def
   /fbar        {(f) f 30 sl 244 434 m 439 434 l s 449 550 m 449 300 l s r} bind def
   /gbar        {(g) f 30 sl 404 434 m 599 434 l s 609 550 m 609 300 l s r} bind def
   /hbar        {(h) f 50 sl -20 560 m 400 560 l s r} bind def
   /kbar        {(k) f 30 sl 384 434 m 579 434 l s 589 550 m 589 300 l s r} bind def
   /mtail       {(m) f 30 sl 180 560 m 690 560 l 960 600 960 30 750 20 c s r} bind def
   /ntail       {(n) f 40 sl 150 560 m 390 560 l 660 600 660 30 450 20 c s r} bind def
   /ocircumflex {(o) f 83 0 m (\303) show r} bind def
   /odieresis   {(o) f 83 0 m (\310) show r} bind def
   /rtail       {(r) f 30 sl 380 400 m 450 450 450 550 380 650 c s r} bind def
   /tbar        {(t) f 30 sl 245 434 m 440 434 l s 450 550 m 450 300 l s r} bind def
   /thorn       {60 sl 0 498 m 143 543 l s 105 536 m 105 -163 l -24 -207 l s 114 331 m 440 673 539  49 112 49 c s} bind def
   /Thorn       {80 sl 8 613 m 143 664 l s 126 655 m 126 -118 l -17 -165 l s 136 428 m 497 806 605 118 260 59 c s} bind def
   /ucircumflex {(u) f 111 0 m (\303) show r} bind def
   /udieresis   {(u) f 111 0 m (\310) show r} bind def
   /utail       {(u) f 40 sl 150 560 m 390 560 l 660 600 660 30 450 20  c s r} bind def
   /yogh        {60 sl 33 386 m 206 534 416 303 33 142 c s 35 116 m 210 204 405  -24 -16 -198 c s} bind def
   /Yogh        {60 sl 50 410 m 293 616 587 292 50  67 c s 50  20 m 299 154 572 -166 -20 -410 c s} bind def
   /3dot        {gsave 60 0 m basefont findfont 1000 scalefont setfont (\307) show 0 -225 m (3) show r} bind def

   FontName currentdict definefont pop end

% ----------------------------------------

   /CCRHRoman findfont 20 scalefont setfont
   60 700 moveto
   (cd\322\323\325\274f\246\256\257ghk\370m\376n\334\335pr t\301\302\305\344\345u\303\3042143x) show

   /CCRHItalic findfont 20 scalefont setfont
   60 650 moveto
   (cd\322\323\325\274f\246\256\257ghk\370m\376n\334\335pr t\301\302\305\344\345u\303\3042143x) show

   /CCRHBold findfont 20 scalefont setfont
   60 600 moveto
   (cd\322\323\325\274f\246\256\257ghk\370m\376n\334\335pr t\301\302\305\344\345u\303\3042143x) show

   /CCRHBoldItalic findfont 20 scalefont setfont
   60 550 moveto
   (cd\322\323\325\274f\246\256\257ghk\370m\376n\334\335pr t\301\302\305\344\345u\303\3042143x) show

showpage