Техническая статья

PDFlibPas: tagged PDF accessibility structure в Delphi

losLab PDF Library предоставляет командам Delphi и C++Builder PDF-движок с доступным исходным кодом для настольных, серверных, DLL, ActiveX и Dylib процессов, включая встроенные проверки PDF/A и PDF/UA, подписи PAdES и выбор рендерера без отправки документов во внешний PDF-сервис.

Эта статья предназначена для developers generating accessible reports, statements, manuals, or public documents from Delphi. Она рассматривает tagged PDF accessibility structure как промышленную инженерию документов, а не как одиночный вызов компонента.

Практический риск состоит в том, что a PDF can contain text and still be inaccessible if headings, tables, artifacts, alternate text, and reading order are missing or wrong. Поэтому процессу нужны письменный контракт, наблюдаемая диагностика и реалистичные регрессионные файлы.

Архитектурные решения

Design semantic structure while generating content. heading levels, paragraphs, lists, tables, figures, artifacts, and role mapping / alternate text ownership for charts, logos, signatures, and decorative images

  • heading levels, paragraphs, lists, tables, figures, artifacts, and role mapping
  • alternate text ownership for charts, logos, signatures, and decorative images
  • reading order for multi-column, repeated-header, and mixed-language content
  • validation profile and manual review process for generated samples

Порядок реализации

Treat tags as document data, not decoration. The order below keeps the workflow reviewable for Delphi and C++Builder teams.

  1. build a semantic outline in parallel with visual layout
  2. tag content as it is emitted so page geometry and structure stay aligned
  3. mark decorative elements as artifacts and supply alternate text for meaningful images
  4. validate PDF/UA-related diagnostics and inspect reading order manually
  5. keep accessible reference samples for every report template family

Доказательства проверки

Accessibility evidence for generated PDFs. Keep these fields with the output or support record.

  • structure tree summary, role map, heading order, table structure, and artifact count
  • alternate text coverage for figures and chart-like content
  • reading-order review notes for representative pages
  • PDF/UA diagnostic report and remediation decisions

Reading order is an authoring responsibility

Tagged PDF output requires a structure tree, role mapping, alternate text, table relationships, artifacts, and reading order that match the visual document. Retrofitting those semantics after layout is far harder.

Decision table for tagged PDF accessibility structure

A decision table keeps product ownership visible when the same workflow is reused by a desktop tool, service job, and support utility.

DecisionEngineering reasonEvidence
heading levels, paragraphs, lists, tables, figures, artifacts, and role mappingbuild a semantic outline in parallel with visual layoutstructure tree summary, role map, heading order, table structure, and artifact count
alternate text ownership for charts, logos, signatures, and decorative imagestag content as it is emitted so page geometry and structure stay alignedalternate text coverage for figures and chart-like content
reading order for multi-column, repeated-header, and mixed-language contentmark decorative elements as artifacts and supply alternate text for meaningful imagesreading-order review notes for representative pages

Замечания для инженерного ревью по tagged PDF accessibility structure

Используйте эти замечания, чтобы убедиться, что функция вышла за рамки демо и может быть обоснована на релизе, в поддержке и при эскалации клиента

  • Решение: heading levels, paragraphs, lists, tables, figures, artifacts, and role mapping. Точка приложения при реализации: tag content as it is emitted so page geometry and structure stay aligned. Доказательство приемки: reading-order review notes for representative pages. Триггер регрессии: images with text may need both alternate text and source-data access
  • Решение: alternate text ownership for charts, logos, signatures, and decorative images. Точка приложения при реализации: mark decorative elements as artifacts and supply alternate text for meaningful images. Доказательство приемки: PDF/UA diagnostic report and remediation decisions. Триггер регрессии: visual headers repeated on every page should often be artifacts
  • Решение: reading order for multi-column, repeated-header, and mixed-language content. Точка приложения при реализации: validate PDF/UA-related diagnostics and inspect reading order manually. Доказательство приемки: structure tree summary, role map, heading order, table structure, and artifact count. Триггер регрессии: tables need header relationships, not only drawn grid lines
  • Решение: validation profile and manual review process for generated samples. Точка приложения при реализации: keep accessible reference samples for every report template family. Доказательство приемки: alternate text coverage for figures and chart-like content. Триггер регрессии: multi-column pages can read incorrectly if tags follow drawing order
  • Решение: heading levels, paragraphs, lists, tables, figures, artifacts, and role mapping. Точка приложения при реализации: build a semantic outline in parallel with visual layout. Доказательство приемки: reading-order review notes for representative pages. Триггер регрессии: images with text may need both alternate text and source-data access
  • Решение: alternate text ownership for charts, logos, signatures, and decorative images. Точка приложения при реализации: tag content as it is emitted so page geometry and structure stay aligned. Доказательство приемки: PDF/UA diagnostic report and remediation decisions. Триггер регрессии: visual headers repeated on every page should often be artifacts

Пограничные случаи

  • visual headers repeated on every page should often be artifacts
  • tables need header relationships, not only drawn grid lines
  • multi-column pages can read incorrectly if tags follow drawing order
  • images with text may need both alternate text and source-data access

Примечания по Delphi / C++Builder

PDFlibPas should sit behind a small service boundary that receives files, streams, profiles, and credentials, then returns output paths, warnings, metrics, and validation status. Важные термины включают tagged PDF, structure tree, role map, alternate text, artifact, reading order.

Пример кода Delphi

Следующий эскиз Delphi показывает практическую границу сервиса для этой темы. Оставляйте проверки политики, журналирование и валидацию вне узкого блока вызова продукта, чтобы сценарий было проще тестировать.

procedure InspectTaggedStructure(const FileName: string);
var
  Pdf: TPDFlib;
begin
  Pdf := TPDFlib.Create;
  try
    Pdf.LoadFromFile(FileName, '');
    FTagReport := BuildStructureTreeReport(Pdf);
    RequireAltTextForFigures(FTagReport);
    RequireLogicalReadingOrder(FTagReport);
  finally
    Pdf.Free;
  end;
end;

Производственный чек-лист

  • Запускайте сценарий на пустом файле, обычном клиентском файле и файле худшего случая
  • Открывайте сгенерированный PDF в целевом просмотрщике, валидаторе, принтере или downstream-приложении
  • Записывайте версию продукта, версию профиля, хэш входа, путь вывода, затраченное время и число предупреждений
  • Храните пароли, сертификаты, временные файлы и данные клиентов по явным правилам хранения
  • Добавляйте регрессионные документы, когда клиентский файл выявляет новый граничный случай

Документация по продукту

PDFlibPas

Дополнительные примеры кода

Lib.BeginTag('Table', '', '');
Lib.BeginTag('TR', '', '');
Lib.BeginTagEx2('TH', '', '', '', '', 'col-part', '');
Lib.SetStructElemScope('Column');          // valid only while this TH is open
Lib.DrawText(72, 120, 'Part');
Lib.EndTag;
Lib.BeginTagEx2('TH', '', '', '', '', 'col-torque', '');
Lib.SetStructElemScope('Column');
Lib.SetStructElemColSpan(2);               // header spans the value and unit columns
Lib.DrawText(200, 120, 'Tightening torque');
Lib.EndTag;
Lib.EndTag;
Lib.BeginTag('TR', '', '');
Lib.BeginTag('TD', '', '');
Lib.SetStructElemHeaders('col-part');      // explicit binding for irregular tables
Lib.DrawText(72, 140, 'M8 flange bolt');
Lib.EndTag;
Lib.EndTag;
Lib.EndTag; // Table