Private/Complete-VellumPdfPageDocument.ps1
|
function Complete-VellumPdfPageDocument { <# .SYNOPSIS Finishes every page canvas of a page-based document before it is saved. .DESCRIPTION Writes each canvas's operators into its page and collects the canvases' text-encoding warnings (characters the base-14 fonts could not encode) for Save-VellumPdfDocument to report. #> [CmdletBinding()] param([Parameter(Mandatory)] [VellumPdf.Document.PdfDocument]$Document) Write-VellumPdfPageBand -Document $Document $prop = $Document.PSObject.Properties['PSVellumCanvases'] if (-not $prop) { return } $warnings = [System.Collections.Generic.List[object]]::new() $rawCanvas = [bool]$Document.PSObject.Properties['PSVellumRawCanvas'] $unbalanced = [System.Collections.Generic.List[string]]::new() $graphicsStateProblem = $false foreach ($entry in @($prop.Value.GetEnumerator())) { $canvas = $entry.Value $canvas.Finish() foreach ($w in $canvas.TextEncodingWarnings) { $warnings.Add($w) } if ($rawCanvas) { # Invoke-VellumPdfCanvas hands out the raw canvas; a script that saves more often than it restores # (or the reverse), or leaves a text object or marked-content sequence open or closes one it did not open, # would corrupt everything drawn after it (and structure in a tagged document), so check the finished page. $balance = [PSVellumPDF.Interop.ContentStreamBalance]::Scan($entry.Key.ContentBytes) if (-not $balance.IsBalanced) { $pageNumber = $Document.Pages.IndexOf($entry.Key) + 1 $unbalanced.Add("page $pageNumber`: $($balance.Describe())") if ($balance.MinDepth -lt 0 -or $balance.FinalDepth -ne 0) { $graphicsStateProblem = $true } } } } if ($unbalanced.Count -gt 0) { $prop.Value.Clear() $what = if ($graphicsStateProblem) { 'saved and restored the graphics state unevenly' } else { 'left paired content operators unbalanced' } throw ("Invoke-VellumPdfCanvas: the script block $what on " + ($unbalanced -join ' | ') + '. Every SaveState needs a RestoreState, every BeginText an EndText and every ' + 'BeginMarkedContent an EndMarkedContent, inside the same block (and never close more than the block opened).') } $prop.Value.Clear() if ($Document.PSObject.Properties['PSVellumTextWarnings']) { $Document.PSVellumTextWarnings = $warnings } else { $Document.PSObject.Properties.Add([psnoteproperty]::new('PSVellumTextWarnings', $warnings)) } } |