PDF-export: de kolombreedtefix van #1727 dekt een tabel met zeven kolommen niet #1794

Closed
opened 2026-08-26 12:00:51 +00:00 by brenno · 2 comments
Owner

Vervolg op #1727. Die issue is gesloten en de fix (836197ca9, PR #1728) zit in v0.4.10. Toch vertoont een verse export met OciDeck 0.4.10 het probleem onverminderd zodra een tabel zeven kolommen heeft.

Waarom dit niet "oude build" is

De fix ging in op 22-08-2026, toen pubspec.yaml nog version: 0.4.8+22 droeg. De versie werd pas 0.4.10 bij 3f2b51ef3, en 836197ca9 is aantoonbaar voorouder daarvan:

$ git merge-base --is-ancestor 836197ca9 3f2b51ef3 && echo JA
JA

Elke build die zich "OciDeck 0.4.10" noemt, draagt de fix dus. De onderzochte PDF is op 26-08-2026 geëxporteerd en meldt in de metadata Producer: OciDeck 0.4.10.

Werkelijk gedrag

In Incidentrapport-RWM-aanval-op-de-externe-werkomgeving-RDWebRD-Gateway-volledig.pdf, §18 Aanbevelingenregister (7 kolommen, 17 rijen, pagina's 55–61):

  • 119 afgebroken woordfragmenten (63 uniek), geteld door de woorden uit de PDF te vergelijken met de woordenschat van het bronbestand;
  • de kop Veiligheidsvraagstuk staat als Veiligheidsvraagstu / k, Geadresseerde als Geadresseer / de, Prioriteit als Priori / teit, Richttermijn als Richtter / mijn;
  • in de cellen: Kritie / k, Midd / el, bij afrondin / g onderzo / ek, verantwoordeli / jken, restrisicobeoor / deling, MFA/rollenove / rzicht;
  • de ID-kolom is zo smal dat R-01 over drie regels valt: R / -0 / 1.

Ter vergelijking: de vier- en vijfkoloms tabellen in hetzelfde document (§11.2, §11.3, §15.3, §16.1) renderen sinds de fix wél netjes. De grens ligt ergens tussen vijf en zeven kolommen.

Waarom de huidige aanpak hier niet toereikend is

pdfTableColumnWidths verdeelt de flex-ruimte evenredig met de breedte van het langste woord per kolom. Dat werkt zolang de som van die langste woorden op het blad past. Bij zeven kolommen met prozacellen is dat niet zo, en de doc-comment van de functie erkent dat ook:

Loopt de tabel over zelfs als alle kolommen flex zijn, dan is afbreken onvermijdelijk.

Meer rekenwerk aan de kolomverdeling lost dit dus niet op. Zeven prozakolommen passen niet op A4-staand — dat is een eigenschap van het blad, niet van de verdeelsleutel.

Richting voor een oplossing

Niet één van deze, maar een keuze:

  1. Corpsverkleining voor brede tabellen. Zakt de beschikbare breedte per kolom onder wat het langste woord nodig heeft, verklein dan de corpsgrootte van die tabel tot het wél past, met een ondergrens.
  2. Liggende tabelpagina. Een tabel die niet op staand formaat past, op een eigen liggend blad zetten.
  3. Waarschuwen in plaats van stilzwijgend verminken. OciDeck heeft een kwaliteitspaneel; "deze tabel heeft zeven kolommen en past niet — splits hem" is een betere uitkomst dan een onleesbare tabel. Dit sluit aan bij #1280 en #1164.

De eerste twee helpen de auteur die niets verandert; de derde is de eerlijkste. Mogelijk alle drie: verklein waar het kan, waarschuw waar het niet kan.

Nevenwaarneming: rendertijd

Bij een poging deze tabel los te renderen (buildDocumentPdf op alleen de tabelregels van §18) draaide flutter_tester meer dan twaalf minuten op 136% CPU zonder te voltooien. Bij de vier- en vijfkoloms tabellen uit hetzelfde document treedt dat niet op. Dit is een losse waarneming uit een wegwerptest, geen afgeronde diagnose — maar het is de moeite waard om na te gaan of de kolomverdeling bij overloop in een herhaalpoging blijft hangen.

Vervolg op #1727. Die issue is gesloten en de fix (`836197ca9`, PR #1728) zit in v0.4.10. Toch vertoont een verse export met OciDeck 0.4.10 het probleem onverminderd zodra een tabel zeven kolommen heeft. ## Waarom dit niet "oude build" is De fix ging in op 22-08-2026, toen `pubspec.yaml` nog `version: 0.4.8+22` droeg. De versie werd pas `0.4.10` bij `3f2b51ef3`, en `836197ca9` is aantoonbaar voorouder daarvan: ``` $ git merge-base --is-ancestor 836197ca9 3f2b51ef3 && echo JA JA ``` Elke build die zich "OciDeck 0.4.10" noemt, draagt de fix dus. De onderzochte PDF is op 26-08-2026 geëxporteerd en meldt in de metadata `Producer: OciDeck 0.4.10`. ## Werkelijk gedrag In `Incidentrapport-RWM-aanval-op-de-externe-werkomgeving-RDWebRD-Gateway-volledig.pdf`, §18 Aanbevelingenregister (7 kolommen, 17 rijen, pagina's 55–61): - **119 afgebroken woordfragmenten** (63 uniek), geteld door de woorden uit de PDF te vergelijken met de woordenschat van het bronbestand; - de kop `Veiligheidsvraagstuk` staat als `Veiligheidsvraagstu` / `k`, `Geadresseerde` als `Geadresseer` / `de`, `Prioriteit` als `Priori` / `teit`, `Richttermijn` als `Richtter` / `mijn`; - in de cellen: `Kritie` / `k`, `Midd` / `el`, `bij afrondin` / `g onderzo` / `ek`, `verantwoordeli` / `jken`, `restrisicobeoor` / `deling`, `MFA/rollenove` / `rzicht`; - de ID-kolom is zo smal dat `R-01` over drie regels valt: `R` / `-0` / `1`. Ter vergelijking: de vier- en vijfkoloms tabellen in hetzelfde document (§11.2, §11.3, §15.3, §16.1) renderen sinds de fix wél netjes. De grens ligt ergens tussen vijf en zeven kolommen. ## Waarom de huidige aanpak hier niet toereikend is `pdfTableColumnWidths` verdeelt de flex-ruimte evenredig met de breedte van het langste woord per kolom. Dat werkt zolang de som van die langste woorden op het blad past. Bij zeven kolommen met prozacellen is dat niet zo, en de doc-comment van de functie erkent dat ook: > Loopt de tabel over zelfs als alle kolommen flex zijn, dan is afbreken onvermijdelijk. Meer rekenwerk aan de kolomverdeling lost dit dus niet op. Zeven prozakolommen passen niet op A4-staand — dat is een eigenschap van het blad, niet van de verdeelsleutel. ## Richting voor een oplossing Niet één van deze, maar een keuze: 1. **Corpsverkleining voor brede tabellen.** Zakt de beschikbare breedte per kolom onder wat het langste woord nodig heeft, verklein dan de corpsgrootte van die tabel tot het wél past, met een ondergrens. 2. **Liggende tabelpagina.** Een tabel die niet op staand formaat past, op een eigen liggend blad zetten. 3. **Waarschuwen in plaats van stilzwijgend verminken.** OciDeck heeft een kwaliteitspaneel; "deze tabel heeft zeven kolommen en past niet — splits hem" is een betere uitkomst dan een onleesbare tabel. Dit sluit aan bij #1280 en #1164. De eerste twee helpen de auteur die niets verandert; de derde is de eerlijkste. Mogelijk alle drie: verklein waar het kan, waarschuw waar het niet kan. ## Nevenwaarneming: rendertijd Bij een poging deze tabel los te renderen (`buildDocumentPdf` op alleen de tabelregels van §18) draaide `flutter_tester` meer dan twaalf minuten op 136% CPU zonder te voltooien. Bij de vier- en vijfkoloms tabellen uit hetzelfde document treedt dat niet op. Dit is een losse waarneming uit een wegwerptest, geen afgeronde diagnose — maar het is de moeite waard om na te gaan of de kolomverdeling bij overloop in een herhaalpoging blijft hangen.
Author
Owner

Opgepakt, samen met #1789 — beide zitten in pdfTableColumnWidths. Tak fix/pdf-tabelbreedte-1789-1794.

Let op: lib/services/pdf/document_pdf_widgets.dart telt 1025 regels tegen een plafond van 1026, dus er is één regel lucht. De kolombreedte-logica (regels 847-1025) gaat daarom eerst als part naar een eigen bestand; dat verlaagt het plafond en maakt ruimte voor de fix.

Opgepakt, samen met #1789 — beide zitten in `pdfTableColumnWidths`. Tak `fix/pdf-tabelbreedte-1789-1794`. Let op: `lib/services/pdf/document_pdf_widgets.dart` telt 1025 regels tegen een plafond van 1026, dus er is één regel lucht. De kolombreedte-logica (regels 847-1025) gaat daarom eerst als `part` naar een eigen bestand; dat verlaagt het plafond en maakt ruimte voor de fix.
Author
Owner

Opgelost in aa6d43bf2 (PR #1795). De letter van een tabel krimpt nu tot elke kolom haar langste woord op één regel draagt — dat maakt élk langste woord evenredig smaller en herstelt de pasvorm zonder aan de verdeelsleutel te tornen.

Twee dingen die het meten leerde:

  • De schatting is stelselmatig te optimistisch: _charWidthFactor meet in kleine letters (een kapitale G telt als 0,55 em in plaats van ~0,72) en is geijkt op een schreefloze letter, terwijl een rapport vaak een schreefletter zet. Zonder marge kwam elke kolom één teken tekort en brak er alsnog een woord af.
  • De standaardmaat voor documenten was 15,5 punt; de RWM-rapporten zetten 11. Op 15,5 passen zeven prozakolommen ook gekrompen niet. Die standaard is in dezelfde PR naar 12 gegaan.

De nevenwaarneming over de rendertijd is niet gereproduceerd: de zeven-koloms tabel rendert in de toetsen binnen een seconde. Wat ik toen zag was vermoedelijk de bedorven testcache na een afgebroken run, niet de tabel.

Opgelost in aa6d43bf2 (PR #1795). De letter van een tabel krimpt nu tot elke kolom haar langste woord op één regel draagt — dat maakt élk langste woord evenredig smaller en herstelt de pasvorm zonder aan de verdeelsleutel te tornen. Twee dingen die het meten leerde: - De schatting is stelselmatig te optimistisch: `_charWidthFactor` meet in kleine letters (een kapitale G telt als 0,55 em in plaats van ~0,72) en is geijkt op een schreefloze letter, terwijl een rapport vaak een schreefletter zet. Zonder marge kwam elke kolom één teken tekort en brak er alsnog een woord af. - De standaardmaat voor documenten was 15,5 punt; de RWM-rapporten zetten 11. Op 15,5 passen zeven prozakolommen ook gekrompen niet. Die standaard is in dezelfde PR naar 12 gegaan. De nevenwaarneming over de rendertijd is niet gereproduceerd: de zeven-koloms tabel rendert in de toetsen binnen een seconde. Wat ik toen zag was vermoedelijk de bedorven testcache na een afgebroken run, niet de tabel.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
LibreKAT/Ocideck#1794
No description provided.