Statt mit einer fixen Farbe kann man Flächen auch mit Farbverläufen füllen. PDF bietet hierfür ein enorm flexibles System mit unzähligen Möglichkeiten. Leider wird es damit auch äusserst komplex, wenn man alle Möglichkeiten ausschöpfen will. Ich demonstriere hier nur die zwei einfachsten, bekanntesten und häufigsten Varianten: Axiale Farbübergänge und radiale Farbübergänge.
Axiale Farbübergänge verlaufen entlang einer Achse von einem Punkt zum anderen. Alle Punkte auf einer Querlinie zur Achse haben dabei dieselbe Farbe.
Radiale Farbübergänge verlaufen von einem Kreis zu einem anderen Kreis, von einem Punkt zu einem Kreis oder von einem Kreis zu einem Punkt. Meist wir der Übergang von einem Kreis zum Mittelpunkt des Kreises definiert, oder umgekehrt.
Farbverläufe gelten als Muster. Darum sind Definition, Einbindung und Verhalten ähnlich wie bei Kachelmustern. Die Koordinaten sind jeweils relativ zur linken, unteren Ecke der Seite bzw. der Form. Transformationen innerhalb der Seite oder Form, in der der Farbverlauf benutzt wird, haben keinen Einfluss auf die Positionierung. Transformationen vor Anwendung einer Form, die Farbverläufe verwendet, hingegen schon. Aus diesem Grund werden Farbverläufe und die damit gefüllte Figur häufig in Formen definiert, die dann per Transformation gesamthaft an die richtige Stelle geschoben werden (sowie allenfalls skaliert, rotiert oder geschrägt).
Farbverlaufsmusterkobjekte sind Dictionaryobjekte (nicht Streamobjekte wie bei Kachelmustern), und folgendermassen aufgebaut:
/Type | immer /Pattern |
---|---|
/PatternType | immer 2 |
/Shading | Farbverlaufsdictionary |
Der eigentliche Farbverlauf ist also in einem Unterdictionary definiert. Dessen genauer Inhalt hängt von der Art des Farbverlaufs ab. Für axiale und radiale Farbübergänge ist der Aufbau folgendermassen:
/ShadingType | axial oder radial |
---|---|
/ColorSpace | Farbraum |
/Coords | Start- und Endkoordinaten |
/Function | Funktionsdictionary |
/Extend | Verlaufsweiterführung |
/Background | Hintergrundfarbe |
/ShadingType
ist 2
für axiale, 3
für radiale Übergänge.
/ColorSpace
gibt an, in welchem Farbraum wir die Farben definieren wollen (z.B. /DeviceRGB
).
/Coords
gibt an, von wo nach wo auf der Seite der Übergang erfolgen soll. Bei axialen Farbübergängen ist dies ein Array mit vier Zahlen: Die X- und Y-Koordinate des Startpunkts, sowie die X- und Y- Koordinate des Endpunkts. Bei radialen Übergängen ist es ein Array mit sechs Zahlen: Die X- und Y-Koordinate des Mittelpunkts sowie der Radius des Startkreises, und die X- und Y-Koordinate des Mittelpunkts sowie der Radius des Endkreises. Ein Radius von 0 definiert einen Punkt anstelle eines Kreises.
Das Funktionsdictionary definiert das Farbverhalten. Ich komme gleich darauf zurück.
Die übrigen Eintrag sind optional, können aber nützlich sein:
Mit /Extend
kann man angegeben, dass der Verlauf über den Start und/oder das Ende hinaus gezeichnet werden soll (was standardmässig nicht der Fall ist). Dabei wird aber nicht der Farbverlauf forgesetzt, sondern die Start- bzw. Endfarbe verwendet. Der Wert ist ein Array mit zwei Einträgen, die true
oder false
sein können. Ist der erste Wert true
, so wird über den Start hinaus gezeichnet. Ist der zweite Wert true
, so wird über das Ende hinaus gezeichnet.
/Background
legt die Hintergrundfarbe fest, die für alle nicht vom Verlauf bemalten Teile der Fläche gilt. Der Wert ist ein Array mit einer Zahl für jede Farbkomponente. Wird der Eintrag weggelassen, so werden unbemalte Teile der Fläche als durchsichtig gewertet.
Das Funktionsdictionary schliesslich sieht für einfache Übergänge zwischen zwei Farben folgendermassen aus:
/FunctionType | immer 2 |
---|---|
/Domain | immer [0 1] |
/C0 | Startfarbe |
/C1 | Endfarbe |
/N | Exponent |
/C0
und /C1
sind die Farben auf dem Start- und Enpunkt bzw. Start- und Endkreis. Als Wert wird je ein Array mit einer Zahl pro Farbkomponente erwartet.
/N
sollte normalerweise 1
sein, was einen gleichmässigen Übergang bewirkt. Zahlen grösser 1 bewirken, dass der Übergang langsam beginnt und schneller wird, während Zahlen kleiner 1 bewirken, dass der Übergang schnell beginnt und langsamer wird.
Beispiel:
10 0 obj << /Type /Pattern /PatternType 2 /Shading << /ShadingType 2 /ColorSpace /DeviceRGB /Coords [100 0 200 0] /Function << /FunctionType 2 /Domain [0 1] /C0 [1 0 0] /C1 [0 0 1] /N 1 >> >> >> endobj 11 0 obj << /Type /Pattern /PatternType 2 /Shading << /ShadingType 3 /ColorSpace /DeviceRGB /Coords [250 150 0 250 150 50] /Function << /FunctionType 2 /Domain [0 1] /C0 [1 0 0] /C1 [0 0 1] /N 1 >> >> >> endobj
Objekt 10 ist ein axialer Farbverlauf von links nach rechts, der im Bereich 100pt – 200pt von Rot nach Blau wechselt. Objekt 11 ist ein radialer Farbverlauf in einer Kreisfläche mit Zentrum 250pt/150pt und Radius 50pt, der von innen nach aussen von Rot nach Blau wechselt.
Dies funktioniert exakt gleich wie die Einbindung von Kachelmustern als Resource.
Beispiel:
/Resources << /ProcSet [/PDF /Text /ImageB /ImageC /ImageI] /Font << /F1 4 0 R >> /Pattern << /P1 10 0 R /P2 11 0 R >> >>
Dies funktioniert exakt gleich wie die Einbindung von Kachelmustern in die Seite/Form.
Beispiel:
/Pattern cs /P1 scn 200 150 m 150 200 l 100 150 l 150 100 l f /P2 scn 300 150 m 250 200 l 200 150 l 250 100 l f
Dies zeichnet zwei Rhomben nebeneinander. Einen mit unserem axialen Verlauf, und einen mit dem radialen Verlauf.
Diskussion