lout-users
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Another way of tweaking lout to support alien characters?


From: Michael Piotrowski
Subject: Re: Another way of tweaking lout to support alien characters?
Date: 10 Dec 1998 09:41:18 +0100

Hi,

"Valeriy E. Ushakov" <address@hidden> writes:

> [...]
> 
> The idea is (like with encoding vector) is to clone the font
> dictionary and add new entries to CharStrings dictionary (charstrings
> themselves are executeonly, but the dictionary is public).  Refer to
> section 5.6.3 of the Big Red Book (page 277) for details.
> 
> [...]
> 
> Having said all this, I have to add that I don't know when I'll have
> enough time to actually do it.  Most likely, in between the Xmases [or
> whatever the correct plural for Xmas is; in case the plural puzzles
> you - Russian Orthodox Church uses Julian calendar, so it celebrates
> Xmas on Gregorian Jan 7].

Since I also wanted to do this some time ago, I have some PostScript
code I can offer, which might serve as a starting point.  It works
fine---but unfortunately only with Ghostscript, not with Adobe
interpreters.  Because I didn't have the time to find what the problem
is, I didn't persue it further.  So, if someone knows what's wrong I
might even finish it myself.

The following program creates compound glyphs from a base character
and an accent, you just have to give it the name of the desired
combination.  It uses Level 2 features including filters.

----------------------------------------------------------------------------
%!PS

% Procedure to find the character code to a character name in the
% current encoding

/findCharCode {
  /count 0 def
  /Encoding load
  {
    exch dup 3 1 roll
    eq
    {exit} if
    /count count 1 add def
  } forall
  pop
  count 16 3 string cvrs /ASCIIHexDecode filter 1 string readstring pop
} def

% General charstring procedure to combine a base glyph with an accent.
% See section 5.6.3 of the PostScript Language Reference Manual for details.
/compoundChar {
  % A charstring procedure gets either the character code or the
  % character number on the operand stack.  The following line is
  % recommended to ensure it's always a name.

  dup type /integertype eq {/Encoding load exch get} if

  % Because CharStrings is the current dictionary, we have to switch
  % to userdict explicitly to be able to define things.

  userdict begin
    15 string cvs dup                        % convert the charname to a string
    0 1 getinterval                          % we assume that the first char
                                             % is the base character
    dup (i) eq                               
    {
      pop
      (dotlessi) cvn
      findCharCode
    } if

    /base exch def
                                             
    dup length 1 sub 1 exch getinterval cvn

    findCharCode
    /accent exch def
  end
  
  % we need to scale the font by 1000 in here
  currentfont 1000 scalefont
  % move for the y and show it
  base   stringwidth pop
  accent stringwidth pop
  sub dup
  0 gt
  {
    abs 2 div

    % get the width of the letter y to keep the same metrics
    base stringwidth
    % use setcachedevice to cache the character
    0 0 1000 1000 setcachedevice

    newpath 0 0 moveto base   false charpath pathbbox 4 1 roll pop pop pop
    newpath 0 0 moveto accent false charpath pathbbox 4 1 roll pop pop pop

    newpath
    sub 0 gt
    {
      % move for the circumflex and show it
      212 moveto
      accent show
    }
    {
      % move for the circumflex and show it
      % move accent up
      0 moveto
      accent show
    } ifelse
    % move for the y and show it
    0 0 moveto
    base show
  }
  {
    abs 2 div

    % get the width of the letter y to keep the same metrics
    accent stringwidth
    % use setcachedevice to cache the character
    0 0 1000 1000 setcachedevice

    newpath 0 0 moveto base   false charpath pathbbox 4 1 roll pop pop pop
    newpath 0 0 moveto accent false charpath pathbbox 4 1 roll pop pop pop

    newpath 
    sub 0 gt
    {
      % move for the circumflex and show it
      0 212 moveto
      accent show
    }
    {
      % move for the circumflex and show it
      0 0 moveto
      accent show
    } ifelse
    % move for the y and show it
    0 moveto
    base show
  } ifelse
  
  pop
} def

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% sample application

% find the font you want
/Times-Roman findfont

% create a new dict of the correct length and push onto dict stack
dup length dict begin

  % copy the font dict
  {1 index /FID ne {def}{pop pop} ifelse} forall

  % use ISOLatin1 encoding (must copy this to a new array)
  /Encoding ISOLatin1Encoding 256 array copy def

  % add the new entries
  Encoding 252 /Amacron put
  Encoding 253 /icircumflex put
  Encoding 254 /xacute put
  Encoding 255 /amacron put

  /CharStrings
  % create a new dictionary for the CharStrings
  CharStrings length dict begin
    % copy the old charstrings
    CharStrings {def} forall
    % define the new glyphs via procedures
    /Amacron     {compoundChar} def
    /icircumflex {compoundChar} def
    /xacute      {compoundChar} def
    /amacron     {compoundChar} def
    % put the CharStrings dict onto the stack, end it, and def it
    currentdict
  end def
  % put the font dict on the stack, end it, and define the font
  currentdict
end
/NewFont exch definefont pop

% example use

/NewFont findfont 100 scalefont setfont
newpath 40 400 moveto (\374\375\376\377Ü) show
/Amacron glyphshow
/icircumflex glyphshow
/xacute glyphshow
/amacron glyphshow
showpage
----------------------------------------------------------------------------

-- 
Michael Piotrowski, M.A. <address@hidden>
Electronic Technologies
Springer-Verlag Heidelberg


reply via email to

[Prev in Thread] Current Thread [Next in Thread]