Füllmuster


%!PS-Adobe-1.0
%%Creator: Holger Gehringer
%%Title: Beispiel fuer Fuellmuster
%%CreationDate: Mo, 23.11.1998
%%DocumentMedia: A4 595 842 0 () ()
%%Orientation: Portrait
%%Pages: (atend)
%%DocumentFonts: Times-Roman Helvetica
%%EndComments

% Dieses Programm zeigt wie ein Gebiet mit einem regelmaessigen Muster gefuel-
% lt werden kann. Der setscreen-Operator ist eigentlich fuer die Definition
% eigener Halbton-Raster gedacht - er kann aber auch zur Erzeugung von Mustern
% benutzt werden. Da der setscreen-Operator naturgemaess sehr geraeteabhaengig
% ist, wird mit der Prozedur SetUserScreen eine unabhaengige Schnittstelle
% geschaffen, die dafuer sorgt, dass die Ergebnisse auf verschiedenen Ausgabe-
% geraeten gleich ausfallen.
% Anmerkung: Muster mit niedriger Frequenz (weniger als 60 Wiederholungen je
% Zoll) benoetigen sehr viel Speicherplatz. Auf Ausgabegeraeten mit beschraenk-
% tem Speicher (wie z.B. dem Apple Laserwriter) kommt es zu der Fehlermeldung
% 'limitcheck', wenn der Speicher nicht mehr ausreicht. In diesem Fall ist es
% zweckmaessig, sich auf Muster zu beschraenken, die ein Vielfaches von 16 Bit
% breit sind und keine Drehung (Winkel 0) aufweisen.

/SetUserScreenDict               % Lokaler Speicher fuer SetUserScreen
22 dict def
SetUserScreenDict begin
  /FindResolution                % ermittelt die Aufloesung des Augabegeraetes
  { 72 0 matrix defaultmatrix    % in Punkte pro Zoll:
    dtransform
    /YRes exch def               % Koordinaten eines Vektors von 72 pt Laenge
    /XRes exch def               % (=1 Zoll) werden in Geraetekoordinaten umge-
    XRes dup mul                 % rechnet und die neue Laenge nach Pythagoras
    YRes dup mul add sqrt        % ermittelt.
  } def
end

/SetUserScreen                   % definiert neue Halbton-Funktion; braucht 3
{ SetUserScreenDict begin        % Parameter:
    /Spotfunction exch def       % Die neue Spot-Funktion
    /Screenangle exch def        % Winkel relativ zum aktuellen Benutzer-K.s.
    /Cellsize exch def           % Zellgroesse in Benutzer-Koordinaten.
    gsave
    Screenangle rotate
    Cellsize dup scale           % Laenge des Einheitsvektors im Geraete-K.s.
    1 0 dtransform
    grestore
    /Y1 exch def
    /X1 exch def
    /Veclength X1 dup mul        % Breite des Musters in Geraete-Pixeln
    Y1 dup mul add sqrt def
    
    /Frequency FindResolution    % Frequenz des Musters = Aufloesung / Breite
    Veclength div def
    
    /NewScreenangle              % neuer Winkel ergibt sich aus den Geraete-
    Y1 X1 atan def               % Koordinaten des Einheitsvektors
    
    Frequency NewScreenangle
    /Spotfunction load
    setscreen                    % Neue Halbtonfunktion einrichten
  end
} def

/SetPatternDict 18 dict def      % Lokaler Speicher fuer Setpattern
SetPatternDict begin
  /BitIsOn                       % stellt fest, ob Pixel X,Y gesetzt ist
  { /YBit exch def               % X und Y liegen zwischen 0 und BPSide-1
    /XBit exch def
    /Bytevalue Bstring
    YBit Bwidth mul              % Bwidth gibt Kantenlaenge des Musters in Byte
    XBit 8 idiv                  % an (s. Kommentar zu SetPattern)
    add get def
    /Mask 1 7 XBit 8 mod         % Mask waehlt das Bit innerhalb des Bytes
    sub bitshift def
    Bytevalue Mask and 0 ne      % hinterlaesst 'true', wenn Bit gesetzt ist.
  } def
end

/BitpatternSpotfunction          % die Prozedur wird an SetUserScreen als Spot-
{ SetPatternDict begin           % Funktion uebergeben.
    /Y exch def
    /X exch def
    /XIndex X 1 add 2 div        % Zell-Koordinaten (zwischen -1 und 1, s. PS
    BPSide mul cvi def           % Language Reference Manual) muessen in Int
    /YIndex Y 1 add 2 div        % zwischen 0 und (BPSide-1) umgerechnet werden.
    BPSide mul cvi def
    XIndex YIndex BitIsOn        % ist Bit gesetzt, erhoehe OnBits; return 1
    { /OnBits OnBits
      1 add def 1
    }
    { /OffBits OffBits           % ist Bit nicht gesetzt, erhoehe OffBits;
      1 add def 0                % return 0  
    } ifelse
  end
} def

/SetPattern                      % setzt Halbtonfunktion, so dass ein Muster
{ SetPatternDict begin           % fuer das Fuellen von Gebieten benutzt werden
                                 % kann. Die Prozedur benoetigt 5 Parameter:
    /Cellsz exch def             % Zellgroesse
    /Angle exch def              % Winkel
    /Bwidth exch def             % Anzahl der Bytes je Zeile im Muster-String;
                                 % Immer ganze Zahl, auch wenn BPSide kein Viel-
                                 % faches von 8 ist. Unbenutzte Bits im letzten
                                 % Byte werden ignoriert
    /BPSide exch def             % Bits je Muster-Zeile (das Muster muss qua-
                                 % dratisch sein!)
    /Bstring exch def            % Muster-String
    /OnBits 0 def                % OnBits, OffBits muessen mit 0 initialisiert
    /OffBits 0 def               % werden, bevor setscreen (in SetUserScreen)
                                 % aufgerufen wird.
    Cellsz Angle
    /BitpatternSpotfunction load
    SetUserScreen
    {} settransfer               % Keine Korrektur der Grauwerte
    OffBits OffBits OnBits       % Grauwert wird entsprechend dem Verhaeltnis
    add div setgray              % von OffBits zur Pixel-Gesamtanzahl gesetzt
  end
} def

% EnlargeBits gibt ein vergroessertes Bild des Musters aus. Fuer jedes 'On'-Bit
% wird ein kleines schwarzes Quadrat gezeichnet. Diese Quadrate haben eine Kan-
% tenlaenge von 1 - das Koord.s. muss deshalb entsprechend skaliert werden, be-
% vor die Prozedur aufgerufen wird.
/EnlargeBits
{ /Bwidth exch def               % Bedeutung der Parameter s. SetPattern
  /BPSide exch def
  /Bstring exch def
  0.08 setlinewidth
  0 1 BPSide 1 sub               % Fuer jedes Bit in y-Richtung ...
  { /Y exch def
    0 1 BPSide 1 sub             % Fuer jedes Bit in x-Richtung ...
    { /X exch def
      X Y SetPatternDict
      /BitIsOn get cvx exec      % Bit ist 'On' -> kleines Quadrat zeichnen
      { gsave
        X Y translate
   newpath                       % Umriss des Quadrats
   0 0 moveto 0 1 lineto
   1 1 lineto 1 0 lineto
   closepath
   gsave 0 setgray
   fill grestore                 % Schwarz fuellen
   1 setgray stroke              % und einen weissen Umriss zeichnen
   grestore
      } if
    } for
  } for
  newpath                        % Um das Ganze einen schwarzen Rahmen zeichnen
  0 0 moveto
  0 BPSide lineto
  BPSide dup lineto
  BPSide 0 lineto
  closepath 0 setgray stroke
} def

/Inch { 72 mul } def

/ShowPattern                     % demonstriert Benutzung der Prozeduren. Als
{ /Ang exch def                  % Parameter werden der Winkel und
  /Pat exch def                  % der String mit dem Muster uebergeben.
  gsave
  0 3.5 Inch translate
  3 8 div Inch dup scale
  Pat 8 1 EnlargeBits            % Muster vergroessert ausgeben
  grestore
  Pat 8 1 Ang
  72 300 32 div div              % Zellgroesse wird so berechnet, dass das Mus-
  SetPattern                     % ter auf Laserdrucker mit 300 dpi genau eine
                                 % Breite von 32 Pixeln hat. (= Vielfaches von
                                 % 16, wie im Kommentar zum Programmanfang er-
                                 % laeutert)
  newpath
  0 0 moveto
  3 Inch 0 lineto
  3 Inch dup lineto
  0 3 Inch lineto                % Ein Quadrat von 3 x 3 Zoll wird mit dem Mus-
  closepath fill                 % ter gefuellt.
} def

/Pat1  def     % Hex-Darstellung der Muster-Strings. Je 2 Hex-
/Pat2 <3E418080E3140808> def     % Ziffern beschreiben eine Zeile des Musters.

%%EndProlog

%%Page: 1 1
/Helvetica findfont
12 scalefont setfont

gsave
1 Inch 1.25 Inch translate
Pat1 0 ShowPattern               % Ausgabe des Flechtmusters
grestore
1 Inch dup moveto
(Flechtmuster, keine Rotation) show
gsave
4.5 Inch 1.25 Inch translate
Pat2 90 ShowPattern              % Ausgabe des Schuppenmusters
grestore
4.5 Inch 1 Inch moveto
(Schuppenmuster, 90 Grad Rotation) show

showpage

%%Trailer
%%Pages: 1


Vorschau:

Download PostScript-File

© Holger Gehringer, Dezember 1998