How can I replace a font color used throughout a PDF?
How can I replace a font color used throughout a PDF?
Answer |
ScenarioAdobe Acrobat does not permit raw editing of a PDF file (possibly due to font licensing concerns), so this can be a problem if you’re trying to swap a specific color shade without disrupting the content or already-performed accessibility remediation work, as Adobe Acrobat’s text editing functionality will do precisely that. An example scenario where this happens is a watermark being applied. Microsoft Word’s Accessibility Assistant does not consider the watermark when determining text color contrast, so this mistake might not be detected early in the production process. To resolve this, you can use qpdf to present the page content streams in an editable text format (called QDF form), replace the color operations to change the color, then restore the streams to a compact format. For additional background about what this process will entail, read more about using qpdf to examine a PDF (written by its creator) and An introduction to tagged PDF files: internals and the challenges of accessibility. Note that this walkthrough is written from a Windows operating system perspective by an amateur PDF engineer. WalkthroughDownload an example Word document and the converted example PDF that demonstrates this scenario for use in this walkthrough. These documents contain accessibility errors. We will replace the color used in all hyperlinks. Locating the Color OperatorConvert the PDF into QDF form:
We’ll need to determine where the hyperlink color is being assigned. To do this, we’ll use a combination of Adobe Acrobat (for the PDF) and a text editor (for the QDF form). In Adobe Acrobat, open the Content pane (View; Show/Hide; Navigation Panes; Content) and expand the treeview to the children of Page 1. In Adobe Acrobat, navigate to the Preflight feature (Tools; PDF Standards; Preflight). The Preflight window opens. In the Preflight window’s ‘Options’ menu, pick ‘Browse Internal PDF Structure…’ [sic]. The Preflight internal PDF structure window opens. (This menu might not have an accessible name or be keyboard accessible.) In the Preflight internal PDF structure window, pick the toolbar button with the green jigsaw puzzle piece labeled BMC (which is the operator for “begin marked content”). (This button might not have an accessible name or an intuitive tab order — from the ‘Find’ text field, tab 3 times to the tree view, and 3 more times to the BMC button.) In the Preflight internal PDF structure window, navigate in the tree view to (approximately):
In the content stream, align the BDC container tag names with the Content pane children in the main Acrobat window to locate the position of the first hyperlink. The Content pane Container is:
…which corresponds to this line in the internal structure window:
…and the color line in the internal structure window is:
In the QDF form file, track down the corresponding marked content ID (perhaps by searching for ‘/MCID 4’, but these IDs will reset for each page) and you get (potentially at line 1188):
…and the color line is (potentially at line 1194):
Let’s confirm whether this color matches what the hyperlink should be using ( Replacing the ColorLet’s pick a replacement hyperlink color
Using your preferred binary-safe replacement methodology (per the documented requirements of editing in QDF form), perform this replacement on the QDF form file. If you desperately need a binary-safe replacement methodology recommendationAs an alternative, first consider exploring The following methodology is discouraged as it is not specifically built for this purpose, but it is what the author personally uses from a perspective of running Windows in approximately S mode with voluntary striving for full Microsoft Store policy compliance, which means that Adobe Acrobat is being used on another device (via Remote Desktop) and qpdf is being used in Windows Sandbox. To further discourage adoption, one of the products will be anonymized as (survival kit product name). It is available in the Microsoft Store at product ID Install (survival kit product name) and PowerShell from the Microsoft Store. In (survival kit product name), launch (survival kit product name) Path Explorer in the foreground (using the ‘Launch in foreground always’), change the ‘Folder Root’ to ‘Personal TempState folder’, then pick the ‘Show Subfolder in File Explorer (Requires Foreground Step)’ radio button and then the ‘Continue’ button to have this folder handy in File Explorer. Pick the ‘Script Hard Link Creation for Picked Files to Subfolder in Windows PowerShell… (Requires Foreground Step)’ radio button and then the ‘Continue’ button. In the file picker, choose your QDF form PDF ‘ColorContrastRemediationSample.qdf.pdf’. In the resulting ‘Hard Link Creation PowerShell Script Available’ notification, combine the ‘Hard Link Creation Script’ and ‘Grant Modfy Access Pipeline Command Script’ and run it in PowerShell. (If you lack access to PowerShell or did not install it, you will have to copy the file manually in File Explorer.) If PowerShell is in Constrained Language Mode, instead run only the ‘Hard Link Creation Script’ and manually grant ‘All Application Packages’ (located from your computer name) the Modify permission. Dismiss the ‘Hard Link Creation PowerShell Script Available’ notification and open the ‘Continue in (survival kit product name)’ notification. Pick the ‘Enter Folder’ radio button and then the ‘Continue’ button. In the ‘File Address’ drop-down, pick ‘ColorContrastRemediationSample.qdf.pdf’, then pick the ‘Refresh Notification’ radio button and then the ‘Continue’ button. Copy the ‘File Address’ value to the clipboard. Launch ‘(survival kit product name) File Editor’ in the foreground. In the ‘Address’ field, paste the value. Change ‘File Encoding or Editing Format’ to ‘Binary (edit as hexadecimal)’, leave the ‘Activity’ as ‘Read’, pick the ‘Apply’ radio button, then the ‘Continue’ button. Copy the ‘File Contents’ value to the clipboard. (To prepare the search and replacement text, create text files in the TempState folder and populate them with the desired text, then have (survival kit product name) File Editor read those files in the same way to get their hexadecimal representation.) Launch ‘Text Replacer’ in the foreground. In the ‘Body Text’ field, paste the file contents hexadecimal; in the ‘Find Expression’ field, paste the find hexadecimal; in ‘Replacement Text (JavaScript)’ field, paste the replacement hexadecimal. Change ‘Find Format’ to ‘Regular expression’, leave ‘Search Settings’ as ‘g’, pick the ‘Replace’ radio button, then pick ‘Continue’. Copy the ‘Body Text’ value to the clipboard. Return to the existing ‘(survival kit product name) File Editor’ instance, paste the updated body text hexadecimal in the ‘File Contents’ field, change ‘Activity’ to ‘Write’, pick the ‘Apply’ radio button, then the ‘Continue’ button. This might break the hard link, so take the file copy in the TempState folder. Finalizing the PDFIn this case, the edits didn’t change the stream length, so we don’t need to recompute those. If we did, then you’d need to run
Finally, have qpdf convert the edited file back to a typical PDF:
|
