Objekte ausgeben
Es gibt zwei Befehle, Objekte auszugeben.
Der eine heißt <Output> und wird nur für Text benutzt, der auf mehrere Seiten umbrechen soll.
Alle anderen Objekte (Bilder, Tabellen, Barcodes, …) werden über den Befehl <PlaceObject> ausgegeben.
Die Parameter werden im Detail in der Befehlsreferenz (siehe Befehl <PlaceObject>) aufgeführt.
Hier folgen einige Beispiele und Anwendungsmöglichkeiten.
Im einfachsten Fall ist der Befehl wie folgt zu benutzen:
<Record element="data">
<PlaceObject>
<Image file="_samplea.pdf" width="5"/>
</PlaceObject>
</Record>
Hier wird ein Bild eingebunden mit dem angegebenen Dateinamen und einer vorgegebenen Breite.
Das Bild _samplea.pdf (mit Unterstrich am Anfang) ist in der Distribution enthalten und kann als Platzhalter benutzt werden.
Rasterbasierte Platzierung von Objekten
Mit den Attributen row und column wird ein Objekt an einer festen Position im Seitenraster platziert; die linke obere Ecke ist die Position 1,1.
<PlaceObject row="4" column="5">
<Image file="_samplea.pdf" width="5"/>
</PlaceObject>
Das Gestaltungsraster und seine Rolle beim Platzieren (Belegung der Rasterzellen, Suche nach freiem Platz) beschreibt ausführlich der Abschnitt Raster.
Reihenfolge der Objekte
Die Reihenfolge der Ausgabe der einzelnen Objekte ist wichtig: die Objekte werden übereinander gezeichnet. Das heißt, Objekte, die später ausgegeben werden, überdecken die vorhergehenden Objekte.
Das kann man sich bei Hintergrundbildern zunutze machen.
In <AtPageCreation> kann man ein Briefpapier oder Seitenkopf ausgeben, der dann in der eigentlichen Datenverarbeitung mit echtem Inhalt überschrieben wird.
Oder man kann eine vorgefertigte Seite einbinden und mit der korrekten Seitenzahl versehen:
<Layout xmlns="urn:speedata.de:2009/publisher/en"
xmlns:sd="urn:speedata:2009/publisher/functions/en">
<Record element="data">
<PlaceObject row="1" column="1">
<Image file="agb.pdf" width="180mm" height="280mm"/>
</PlaceObject>
<PlaceObject
column="1"
row="{sd:number-of-rows()}">
<Textblock textformat="right">
<Paragraph>
<Value select="sd:current-page()"/>
</Paragraph>
</Textblock>
</PlaceObject>
</Record>
</Layout>
Hier wird erst die Seite eingebunden und dann in der letzten Zeile rechtsbündig die aktuelle Seitenzahl »eingedruckt«.
Höhe und Breite der Objekte
Bilder, Barcodes, Boxen etc. haben feste Breiten und Höhen. Texte und Tabellen nutzen die noch vorhandene Breite aus. D. h. die Breite ist die Differenz zwischen Anzahl der Rasterzellen und der Startspalte plus 1. Bei einer exemplarischen Breite von 15 Rasterkästchen und einer Startspalte von 6 ist die Textbreite 10, sofern keine andere Angabe gemacht wird.
Benötigt ein Objekt (wie z. B. Bilder) eine Breiten- oder Höhenangabe, kann diese entweder absolut (z. B. 5cm) gegeben werden oder in Rasterzellen.
Textblock
Das ist ein rechteckiger Textbereich, der nicht auf mehrere Seiten umbrochen wird. Textblöcke sind ideal für Seitenzahlen, kurze Beschreibungen, Kolumnentitel und alle anderen Einheiten, wo ein Seitenumbruch nicht erwünscht ist.
Ein <Textblock> kann einen oder mehrere Absätze (<Paragraph>) enthalten.
Sowohl der Textblock selbst als auch Absätze können Informationen über die benutzte Schriftart, Farben und Textformate enthalten.
Sind diese in den Absätzen deklariert, so haben die Vorrang vor denen, die im Textblock angegeben sind.
<Textblock color="blue">
<Paragraph color="green">
<Value>green text</Value>
</Paragraph>
<Paragraph>
<Value>this text is in blue (given by Textblock)</Value>
</Paragraph>
</Textblock>
Weitere Formatierungsmöglichkeiten sind im Abschnitt Schriften verwenden und Textformatierung beschrieben.
Die vollständige Beschreibung von <Textblock> ist in der Referenz (Abschnitt Textblock) zu finden.
Für Texte, die über Seitengrenzen hinweg umbrechen dürfen, gibt es den Befehl <Text> als Kindelement von <Output>, beschrieben im nächsten Abschnitt.
Texte mit Seitenumbruch
Texte mit Seitenumbruch werden nicht wie die anderen Objekte mit <PlaceObject>, sondern mit <Output> ausgegeben.
Die Syntax dafür ist
<Output>
<Text>
<Paragraph>
<Value>...</Value>
</Paragraph>
<Paragraph>
<Value>...</Value>
</Paragraph>
</Text>
</Output>
Neben der Besonderheit, dass dieser Text auf mehrere Seiten umbrechen kann, ist er auch in der Lage, Objekte zu umfließen. Eine detaillierte Beschreibung dieser Eigenschaft ist im Abschnitt Umfließen von Bildern gegeben.
HTML
HTML-Inhalte können mit dem Befehl <HTML> direkt innerhalb von <Output> oder als Markup in Absätzen ausgegeben werden:
<Output>
<HTML>
<p>Ein Absatz mit <b>fettem</b> und <i>kursivem</i> Text.</p>
</HTML>
</Output>
Die verschiedenen Einbindungswege, die unterstützten Elemente und das CSS-Styling beschreibt das Kapitel HTML.
Einführung in Tabellen
Das im Publisher benutzte Tabellenmodell entspricht in etwa dem von HTML bekannten Modell: Zeilen werden mit <Tr> angegeben, die einzelnen Zellen mit <Td>.
In den Zellen kann alles stehen, was auch in <PlaceObject> enthalten sein kann.
<PlaceObject>
<Table>
<Tr>
<Td>...</Td>
<Td>...</Td>
</Tr>
</Table>
</PlaceObject>
Tabellen können über mehrere Seiten laufen, auch mit wiederholenden Kopf- und Fußzeilen.
Dem Thema Tabellen ist ein eigenes Kapitel gewidmet.
Bilder
Bilder einbinden ist, wie schon eingangs gezeigt, sehr leicht. Der Befehl dafür lautet <Image>:
<PlaceObject>
<Image file="_samplea.pdf" width="5cm"/>
</PlaceObject>
Der Befehl zum Einbinden der Bilder ist sehr mächtig und wird ausführlich im Kapitel Bilder & Grafiken beschrieben (dort stehen auch die unterstützten Dateiformate). Die Referenz enthält eine kurze Beschreibung aller Möglichkeiten.
Rechteckige Flächen (<Box>)
Rechteckige Flächen werden mit dem Befehl <Box> erzeugt.
<PlaceObject>
<Box width="4" height="3" background-color="limegreen"/>
</PlaceObject>
Oftmals werden Kästchen für farbige Flächen hinter einem Text oder einer Tabelle benutzt.
Dann muss die Belegung der Rasterzellen ausgeschaltet werden (allocate="no" bei <PlaceObject>), sonst kommt es zu einer Warnung wegen der doppelt belegten Fläche im PDF (siehe Abschnitt Raster).
Ein Beispiel für die Nutzung von Boxen als Hintergrund ist im Abschnitt über Griffmarken zu finden.
Dort wird auch der Parameter bleed erläutert, der dazu dient, den Kasten in eine oder mehrere Richtungen zu vergrößern, sofern sich diese am Seitenrand befinden.
Kreis
Kreise werden mit dem Befehl <Circle> ausgegeben:
<Record element="data">
<PlaceObject column="5" row="5">
<Circle radiusx="3" background-color="goldenrod"/>
</PlaceObject>
<PlaceObject column="5" row="5">
<Circle radiusx="1pt" background-color="black"/>
</PlaceObject>
</Record>
In diesem Beispiel ist der Radius des großen Kreises 3 Rasterkästchen und der Mittelpunkt des Kreises liegt in der linken oberen Ecke des Kästchens (5,5). Damit fängt er in der zweiten Spalte und in der zweiten Zeile an und erstreckt sich bis zur siebten Spalte und Zeile. Kreise haben die besondere Eigenschaft, dass keine Rasterzellen als belegt markiert werden.
Linien (<Rule>)
Es gibt horizontale und vertikale Linien. Diese können eine Liniendicke haben, eine Farbe und eine Länge. Linien können durchgezogen und gestrichelt sein:
<PlaceObject column="2" row="2">
<Rule direction="horizontal" length="4" dashed="yes"/>
</PlaceObject>
Linien werden immer oben links im Kästchen ausgerichtet.
Rahmen
Der Rahmen (wie die Transformation weiter unten) ist ein besonderes Objekt, das man über ein anderes Objekt legt.
Ein Rahmen (<Frame>) beinhaltet immer ein anderes Objekt, beispielsweise ein Bild.
<PlaceObject>
<Frame
border-bottom-left-radius="8pt"
border-bottom-right-radius="8pt"
border-top-left-radius="8pt"
border-top-right-radius="8pt"
framecolor="darkseagreen"
rulewidth="2pt">
<Image file="_samplea.pdf" width="4"/>
</Frame>
</PlaceObject>
Man sieht, dass der Rahmen als Clipping-Pfad funktioniert, die Teile außerhalb werden ausgeblendet.
Den Rahmen (rulewidth) kann man auch auf Null setzen und somit unsichtbar machen, dann wird nur der Inhalt beschnitten.
Transformation
Wie der Rahmen ist die Transformation ein umschließendes Element. Das bedeutet, dass das Element noch einen Inhalt haben muss, wie z. B. ein Bild.
Man gibt bei der Transformation eine Matrix an, die aus sechs Zahlen besteht in der Form »a b c d e f«. Die Transformation von einem Koordinatensystem in ein anderes wird über folgende 3x3 Matrix abgebildet:
$$ \begin{bmatrix} x' & y' & 1 \end{bmatrix} = \begin{bmatrix} x & y & 1 \end{bmatrix} \times \begin{bmatrix} a & b & 0 \\ c & d & 0 \\ e & f & 1 \end{bmatrix} $$Wenn man aus den Koordinaten x und y die neuen Koordinaten x’ und y’ errechnen will, kann man das auch über die folgende Formeln machen:
$$ \begin{aligned} x' &= a \times x + c \times y + e \\ y' &= b \times x + d \times y + f \end{aligned} $$Es gibt folgende grundlegende Transformationsarten (siehe Abbildung):
- Verschiebungen (translation) werden mit den Werten \(1\; 0\; 0\; 1\; t_x\; t_y\) beschrieben
- Die Skalierung (scaling) wird mit \(s_x\; 0\; 0\; s_y\; 0\; 0\) angegeben
- Drehungen (rotation) können mit \(\cos\theta\; \sin\theta\; {-\sin\theta}\; \cos\theta\; 0\; 0\) erreicht werden
- Scherungen (skew) sind durch \(1\; \tan\alpha\; \tan\beta\; 1\; 0\; 0\) beschrieben.
- Die unverändernde Transformation ist \(1\; 0\; 0\; 1\; 0\; 0\) (identische Abbildung).
<PlaceObject>
<Transformation matrix="1.8 0.2 0.2 0.8 0 0 ">
<Image file="ocean.pdf" width="4"/>
</Transformation>
</PlaceObject>
Spiegeln von Objekten
Mit dem Befehl Transformation können Objekte auch gespiegelt werden. Das kann man entweder mit der Transformationsmatrix oder mit dem Attribut flip steuern:
<PlaceObject>
<Transformation flip="vertical">
<Image width="3cm" file="ocean.pdf" />
</Transformation>
</PlaceObject>
Erlaubt sind die Werte none, horizontal, vertical und both.
Barcodes, QR-Codes PRO
Barcodes bzw. QR-Codes werden über den Befehl <Barcode> eingebunden:
<PlaceObject>
<Barcode select="'Hello world'" type="QRCode" width="5"/>
</PlaceObject>
Die Ausgabe ist wie erwartet
Es lassen sich Barcodes in der Kodierung »EAN13« und »Code 128« ausgeben.
Beschneiden von Bildern
Seit Version 4.11.3 kann der speedata Publisher Bilder und andere Objekte beschneiden. Das resultierende Objekt ist kleiner als das Original, sofern die Methode clip (Voreinstellung) gewählt ist. Andernfalls (Methode frame) ist das resultierende Objekt genau so groß wie das Original, es wird nur ein kleinerer Ausschnitt ausgegeben.
Ein Benutzer hat eine schöne Erklärung der Unterschiede zwischen den Methoden clip und frame:
Wenn der Publisher eine Schere hätte, würde clip das Bild selber beschneiden und frame würde einen Rahmen (Passepartout) mit der Öffnung der angegebenen Werte schneiden und über das Bild legen.
<Layout xmlns="urn:speedata.de:2009/publisher/en"
xmlns:sd="urn:speedata:2009/publisher/functions/en">
<Pageformat height="14cm" width="11cm" />
<Record element="data">
<PlaceObject>
<Clip left="1cm" right="1cm" top="1cm" bottom="2cm" method="clip">
<Image width="5cm" file="_sampleb.pdf" />
</Clip>
</PlaceObject>
<PlaceObject column="5" >
<Image width="5cm" file="_sampleb.pdf" />
</PlaceObject>
</Record>
</Layout>