This commit is contained in:
@@ -1,5 +1,86 @@
|
||||
# LehrerApp Templating
|
||||
|
||||
## Dynamische Zeichenflächen für externe Apps
|
||||
|
||||
Externe `ITemplateDataProvider` können einen Platzhalter vom Typ `Drawing` mit einem
|
||||
`DrawingValue` befüllen. Dabei wird kein QuestPDF-/Skia-Canvas nach außen gegeben. Die portable
|
||||
Form besteht stattdessen aus einer geprüften, serialisierbaren Befehlsliste:
|
||||
|
||||
```csharp
|
||||
var drawing = new DrawingValue(
|
||||
[
|
||||
new DrawRectangle(0, 0, 160, 24, "#2563EB", 0.8f, "#EFF6FF"),
|
||||
new DrawString(4, 4, "Dynamischer Bericht", 11, "#1E3A8A", Bold: true),
|
||||
new MoveTo(4, 19),
|
||||
new LineTo(156, 19, "#93C5FD", 0.6f),
|
||||
new DrawImage(120, 2, 30, 18, pngBytes, "image/png")
|
||||
],
|
||||
ContentHeight: 24);
|
||||
```
|
||||
|
||||
Koordinaten und Längen verwenden die Einheit des Layouts; `DrawString.FontSize` wird wie bei
|
||||
`TEXT` in Punkt angegeben. Unterstützt werden `DrawString`, `MoveTo`, `LineTo`, `DrawLine`,
|
||||
`DrawRectangle` und `DrawImage` (PNG/JPEG). Die Befehle gelangen über den normalen
|
||||
`ITemplateDataProvider`, beispielsweise als `values["ExternerBericht"] = drawing`.
|
||||
|
||||
`DrawStringEx(x, y, height, width, ...)` ergänzt eine geclippte Textbox mit `AlignLeft`,
|
||||
`AlignCenter` oder `AlignRight`. Farbe und Schriftfamilie können bei beiden Textbefehlen gesetzt
|
||||
werden. Ohne Schriftangabe wird `sans-serif` verwendet. Für portable Schriften registriert die
|
||||
integrierende App TTF-/OTF-Daten einmal vor dem Rendern:
|
||||
|
||||
```csharp
|
||||
DrawingFontRegistry.RegisterFont("MeineSchulschrift", fontBytes);
|
||||
canvas.DrawStringEx(0, 0, 12, context.Width, "Zentrierte Überschrift",
|
||||
DrawingTextAlignment.AlignCenter, 11, "MeineSchulschrift", "#1E3A8A", bold: true);
|
||||
```
|
||||
|
||||
Explizite Zeilenumbrüche werden berücksichtigt; Text außerhalb von `height`/`width` wird
|
||||
abgeschnitten. Eine automatische Worttrennung findet in dieser elementaren Zeichenfunktion nicht
|
||||
statt.
|
||||
|
||||
Im Layout stehen zwei Varianten zur Verfügung:
|
||||
|
||||
```text
|
||||
DRAWBOX 20 40 170 80 $ExternerBericht
|
||||
FLOWDRAWBOX 20 40 170 237 $LangesProtokoll
|
||||
```
|
||||
|
||||
`DRAWBOX` ist ein fester, geclippter Viewport. Inhalte außerhalb seiner Breite oder Höhe werden
|
||||
nicht angezeigt. `FLOWDRAWBOX` zerlegt den vertikalen Zeichenraum anhand von `ContentHeight` in
|
||||
gleich hohe Seitenfenster und setzt ihn auf Folgeseiten fort. Wie bei `FLOWBOX` darf ein Layout
|
||||
höchstens ein fließendes Element enthalten; bei einem eigenen Folgeseitenlayout müssen Typ,
|
||||
Position und Größe übereinstimmen.
|
||||
|
||||
Ein Vorlagenpaket kann keinen Callback und keinen Typ aus einer fremden Assembly einschleusen.
|
||||
Farben, Zahlen, Bildformate, Bildgröße und Gesamtzahl der portablen Befehle werden validiert.
|
||||
Damit bleibt die paketfähige Schnittstelle deterministisch. Ein `PagedDrawingValue` ist dagegen
|
||||
ein ausdrücklich vom vertrauenswürdigen In-Process-`ITemplateDataProvider` übergebener Delegate.
|
||||
|
||||
Für umfangreiche In-Process-Integrationen gibt es zusätzlich den klassischen seitenweisen
|
||||
Callback `PagedDrawingValue`. Er wird vor QuestPDFs Layout vollständig in deklarative Seitenlisten
|
||||
aufgezeichnet und daher nicht durch interne Layoutdurchläufe mehrfach ausgeführt:
|
||||
|
||||
```csharp
|
||||
var value = new PagedDrawingValue(context =>
|
||||
{
|
||||
var nextRow = context.State is int row ? row : 0;
|
||||
|
||||
// Nur vollständige Strukturen zeichnen, die noch in die zugewiesene Box passen.
|
||||
while (nextRow < rows.Count && PasstNochVollstaendig(rows[nextRow], context))
|
||||
ZeichneZeile(context.Canvas, rows[nextRow++]);
|
||||
|
||||
context.State = nextRow;
|
||||
return nextRow == rows.Count; // true = fertig, false = weitere FLOWDRAWBOX
|
||||
}, InitialState: 0);
|
||||
```
|
||||
|
||||
`DrawingPageContext` stellt `Width`, `Height`, `PageNumber`, `Canvas` und ein über alle Aufrufe
|
||||
weitergereichtes `State`-Objekt bereit. So kann der Zeichner Tabellenzeilen, Diagrammgruppen oder
|
||||
andere unteilbare Strukturen bewusst auf die nächste Seite verschieben. Ein `DRAWBOX`-Callback
|
||||
wird genau einmal aufgerufen; bei `FLOWDRAWBOX` fordert `false` eine weitere Seite an. `MaxPages`
|
||||
verhindert Endlosschleifen. Delegates funktionieren nur innerhalb desselben .NET-Prozesses;
|
||||
prozessübergreifend bleibt `DrawingValue` die Übergabeform.
|
||||
|
||||
## PDF-Import im TemplateDesigner
|
||||
|
||||
Der Menüpunkt **Einfügen → PDF als Vorlage importieren** rekonstruiert einseitige PDF-Vorlagen.
|
||||
|
||||
Reference in New Issue
Block a user