- C++ 96.2%
- CMake 3.8%
Qt 6 Widgets statt QML, damit Vorschau, SVG-Export, PDF und Drucker denselben QPainterPath verwenden und nicht auseinanderlaufen können. Der SVG-Export wandelt Glyphen in Umrisse: QSvgRenderer -- den gLabels benutzt -- ignoriert <textPath> vollständig und meldet dabei trotzdem isValid() == true. Das Dokument wird von Hand geschrieben statt über QSvgGenerator, weil der Pixel statt Millimeter ausgibt und der Import dadurch um ein Drittel verzerrt würde. Textplatzierung über Graphemcluster, damit Umlaute, kombinierende Zeichen und Surrogatpaare zusammenbleiben. Kerning wird über die Differenz aufeinanderfolgender Präfixbreiten mitgenommen. Die Glyphen entstehen achtfach überabgetastet, da QFont::setPixelSize nur ganze Zahlen annimmt und krumme Punktgrößen sonst einrasten würden. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|---|---|---|
| .vscode | ||
| src | ||
| .gitignore | ||
| CMakeLists.txt | ||
| README.md | ||
ngenArcText
Bogentext für CD/DVD-Label: Live-Vorschau, SVG-/PDF-Export und Direktdruck auf das Disc-Fach.
Entstanden, weil Canons CD-LabelPrint sich an Canon-Drucker klammert und es unter Linux kein gepflegtes freies Werkzeug für gekrümmten Text auf Discs gibt. gLabels kann Disc-Direktdruck, aber keinen Bogentext.
Aufbau
Qt 6 Widgets, C++20, CMake. Kein QML — die Vorschau ist ein QWidget
mit paintEvent, damit Bildschirm, SVG, PDF und Drucker denselben
QPainterPath verwenden und nicht auseinanderlaufen können.
| Datei | Aufgabe |
|---|---|
src/ArcTextRenderer.{hpp,cpp} |
Kern: Text → Kreisbogen → QPainterPath, dazu SVG-Serialisierung |
src/PreviewWidget.{hpp,cpp} |
Vorschau mit Disc-Attrappe und Grundlinie |
src/MainWindow.{hpp,cpp} |
Bedienoberfläche, Export, Druck |
Die einzige Abhängigkeit ist Qt 6 (Widgets, Gui, Svg, PrintSupport).
Bauen
cmake -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build -j$(nproc)
./build/ngenArcText
Debian/Ubuntu:
sudo apt install build-essential cmake qt6-base-dev qt6-svg-dev qt6-tools-dev
In VS Code
.vscode/ ist eingerichtet:
Ctrl+Shift+B |
Release-Build nach build/ |
F5 |
Debug-Build nach build-debug/, Start unter CodeLLDB |
Die Build-Verzeichnisse sind bewusst getrennt, damit Debuggen und
Ausliefern sich nicht überschreiben. Beide configure-Tasks schreiben
compile_commands.json; darüber findet IntelliSense die Qt-Header, ohne
dass c_cpp_properties.json gepflegt werden muss.
Unter den Startkonfigurationen gibt es zusätzlich (Debug, offscreen) —
startet mit -platform offscreen, praktisch für Fernsitzungen ohne
X/Wayland oder wenn nur die Renderlogik interessiert.
Warum die Glyphen als Pfade exportiert werden
Der SVG-Export wandelt jeden Buchstaben in einen Umriss um, statt <text>
oder <textPath> zu schreiben. Das ist kein Selbstzweck:
| Renderer | <textPath> |
Pfade |
|---|---|---|
| Inkscape | ✓ | ✓ |
| librsvg | ✗ | ✓ |
| QSvgRenderer (gLabels, Qt) | ✗ | ✓ |
QSvgRenderer meldet bei <textPath> isValid() == true und zeichnet
nichts. Ein so erzeugtes SVG landet in gLabels als unsichtbares Bildobjekt,
ohne Fehlermeldung. Mit Umrissen kann das nicht passieren, und die Schrift
muss auf dem Zielsystem nicht vorhanden sein.
Aus demselben Grund wird das SVG von Hand geschrieben statt über
QSvgGenerator: der gibt die Abmessungen in Pixeln aus, was beim Import je
nach angenommener Auflösung (72 vs. 96 dpi) einen Maßstabsfehler von einem
Drittel ergäbe. Hier stehen Millimeter drin.
Direktdruck auf die Disc
Die Leinwand ist standardmäßig 120 × 120 mm und disc-zentriert, das Bild wird beim Druck mittig auf die Seite gelegt.
Linux (CUPS + Gutenprint): Gutenprint stellt die nötigen Optionen
bereit — Canons eigener Treiber cnijfilter2 kann kein Disc-Printing.
sudo apt install cups printer-driver-gutenprint
Im Druckdialog dann:
| Option | Wert |
|---|---|
| Media Size | CD - 5 inch (116 mm) bzw. CD - 3 inch (65 mm) |
| Media Type | CD |
| Media Source | CD Tray |
Windows: Der Canon-Treiber legt das Disc-Fach als gewöhnliches Papierformat offen, jede Anwendung kommt heran:
| Option | Wert |
|---|---|
| Medientyp | Bedruckbare Disc (empfohlen) |
| Papierformat | Disc-Fach J — Buchstabe steht auf dem Plastikfach |
| Papierzufuhr | Disc-Fach |
Der Fachbuchstabe ist modellabhängig (A bis L). Er entspricht der
Taxonomie, die Gutenprint reverse-engineered hat: Tray J ist intern 0x5b.
Druckversatz
Jedes Gerät druckt leicht versetzt. Die Felder unter Druckversatz
verschieben das Bild in Millimetern und entsprechen Canons
Positionskorrektur bzw. Gutenprints CDXAdjustment/CDYAdjustment. Sie
wirken auf Druck und PDF, nicht auf den SVG-Export.
Vor dem ersten Echtdruck auf einer Ausschuss-Disc testen.
Bekannte Grenzen
Die Buchstaben werden einzeln auf dem Bogen platziert. Kerningpaare werden über die Differenz aufeinanderfolgender Präfixbreiten mitgenommen, echtes Shaping über den kompletten Textlauf findet aber nicht statt. Für lateinische Schrift ist das unauffällig; für Arabisch oder Devanagari taugt es nicht. Graphemcluster (Umlaute, kombinierende Zeichen, Surrogatpaare) werden korrekt als Einheit behandelt.
Mehrzeiliger Text ist nicht vorgesehen — für zwei Bögen zweimal exportieren und im Label-Programm übereinanderlegen.