A speech reader pauses at a PDF page break even though the sentence continues on the next page. PDFium Component can join suitable fragments for document-level reading while retaining their source positions, so speech and selection can still point back to the original page text
A joined sentence has two coordinate systems
Suppose page 4 ends with “the data is” and page 5 begins “written to disk.” The joined sentence gives a speech engine one sequence of UTF-16 positions, but those positions do not all belong to page 4's native text. Each SourceParts entry records its source page, original text, the slice used in the combined fragment and its offset in that combined text; MCIDs and page-space geometry travel with the entry. That information connects a selected range back to the page that actually contains the words. A reading unit whose first part is on page 4 can include another part from page 5, and a later sentence in that unit may lie entirely on page 5. Examine the source parts before assigning a page number to your highlight
procedure DumpReadingSources(Pdf: TPdf);
var
Units: TPdfReadingUnits;
I, J: Integer;
begin
Units := Pdf.DocumentReadingUnits;
for I := 0 to High(Units) do
begin
Writeln(Units[I].Text);
for J := 0 to High(Units[I].SourceFragment.SourceParts) do
Writeln(' Source page: ',
Units[I].SourceFragment.SourceParts[J].Page);
end;
end;
The page returned for a range is its source location; the host application decides whether and when to navigate there. There is also a character in the joined sentence that may not exist as a PDF glyph: the inserted space between the two page fragments. The reader records that separator as context so the text is readable, while a page highlight can still target the actual source characters. Select only “written to disk” in the example and the source lies on page 5, even though the reading unit began on page 4. Returning page 4 for every range would leave the transcript looking right while sending the viewer to the wrong page. The mapping makes the page transition usable for selection as well as speech
Enable document-level continuation
TPdf.ParagraphContinuation is disabled by default. Set the desired options before you request document-level readable content or reading units; the Delphi example assumes that Pdf already has a document open
uses
PDFium;
procedure EnableParagraphContinuation(Pdf: TPdf);
var
Options: TPdfParagraphContinuationOptions;
begin
Options := TPdfParagraphContinuationOptions.Default;
Options.Enabled := True;
Options.Dehyphenate := False;
Pdf.ParagraphContinuation := Options;
end;
The joined view is available through DocumentReadableContent or DocumentReadingUnits. Page-level snapshots remain available to a page-only display and are not rewritten by that document-level join. If you change the application's continuation settings, rebuild the document reading units that depend on those settings before using the new result
When does a page break look like a continuation?
PDFium Component considers the last ordinary paragraph or plain-text fragment on one page and the first on the next. Their positions need to be near the relevant page edges, with compatible horizontal alignment, line heights and language. The default edge band is 72 points; the default alignment tolerance is 18 points. Those values give the reader a starting point, not knowledge of every author's intent. A heading, table, list, blank page or terminal sentence boundary can justify leaving fragments apart. A page footer followed by a new heading is a particularly important case: physical proximity across a page break does not make the two pieces one paragraph
The right default depends on the documents. Continuous prose in a legal document is a different input from a catalog of independent cards, so test the option on both before enabling it globally. A general reader with mixed input can expose the setting to its users. Include a page number or confidentiality label at the bottom of one page followed by a new heading on the next; both may be close to the page edges even though the footer is not the start of the heading. Before you judge the join from the physical rectangles, read the resulting units and their source parts to establish which text was joined
What happens to hyphens and CJK text?
A word broken by a hyphen at the page boundary introduces another choice. With the hyphen retained, continuation joins the next part without adding an extra space after it. With Dehyphenate enabled, the reader can remove the boundary hyphen from the joined text so speech or copying receives the combined word. The original PDF still contains the drawn glyphs. Adjacent CJK parts are joined without an artificial space. A copied word may therefore have a different character sequence from the visible page, while a highlight still needs the original source geometry. We would make dehyphenation a deliberate application choice when both speech and selection matter, then check the joined text and the page highlight on a word that crosses the boundary
Do not use the first page for every character
The primary Page on a reading unit identifies its first source page. It does not assign every sentence in that unit to that page. Use the reading-unit helpers and SourceParts for selection or speech mapping: they validate source slices and can map a range that spans pages or occurs entirely in a later part. Viewer navigation remains the host application's decision. That separation matters when a user has manually moved the viewer elsewhere while speech continues; the source page describes where the selected text came from without forcing a page change on its own
Make the test expose the page boundary
Build a two-page document with one sentence crossing the break and another complete sentence entirely on page 2. Check the joined text as you select each sentence, then verify the source page and highlight for both. Add a boundary with a table or heading that should remain apart. A boundary hyphen with Dehyphenate enabled and disabled, plus adjacent CJK text, exercises the joining choices described above. Reopen the original PDF after the reading operation to confirm that the reader-only transformation has not edited page content. For navigation, the source parts are the evidence that a correct transcript still points to the original glyphs
If you select a range and land on an unexpected page, retain the joined text, selected offsets and source page numbers together. Also record whether the viewer was already displaying the later page: that makes a mapping result distinguishable from a navigation decision made by the host. Change the continuation option and rebuild the document-level units, while keeping the page-level snapshots for a page-only view. The two views let the application examine extraction on each page and the later decision to join fragments across the boundary without treating them as a single operation. For a selection crossing the boundary, follow both source parts and their offsets in the joined text. A selection entirely after the break should lead back to the later source page; the unit's primary page still identifies where that reading unit began. A combined range can cover characters from both sides of a page break. Map each covered slice to its source page and geometry before asking the host to highlight it, and leave navigation policy to the application that owns the viewer
For the surrounding navigation workflow, see accessible reader workflows and word and speech cursors. The Delphi APIs discussed here belong to PDFium Component