Ограниченное редактирование абзацев

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

Приёмочный профиль покрывает Delphi Win32/Win64 и Windows FPC/Lazarus; генерация измеренных шрифтов использует существующий построитель appearance документа и его поддержку установленных шрифтов

Выбор, раскладка и сохранение

Координаты — точки пользовательского пространства страницы PDF без поворота, ось y направлена вверх; оба прямоугольника должны быть конечными, иметь положительные размеры не больше 14400 пунктов и помещаться в MediaBox страницы

Выборка может охватывать несколько исходных базовых линий и несколько потоков содержимого страницы; текстовые операнды literal, hexadecimal, TJ, одинарных и двойных кавычек переписываются по границам выбранных кодов символов

Сохранённые префиксы, суффиксы, текстовые метрики и исходные числовые кернинг-поправки остаются на месте; исходный текст удаляется из реальных операндов, а не прячется за фоновым прямоугольником

Вложенные Form XObjects используют свои Matrix и BBox; каждая выбранная инвокация и ресурсы её предков копируются приватно, сохраняя другие инвокации и другие страницы, использующие те же исходные Forms

Центры глифов вне Form BBox исключаются; частично попавшие в выборку границы глифов-источников по умолчанию приводят к отказу, а RejectPartialSourceGlyphs = False явно разрешает удаление целого кода символа, если выбран его центр

Appearance задаёт установленный шрифт, стиль, размер, цвет, отступы, выравнивание и политику переполнения; ширина цели управляет переносами, а shrink-to-fit сообщает фактический EffectiveFontSize

Сгенерированная геометрия глифов независимо интерпретируется и сверяется с прямоугольником-целью; поворот для этого ограниченного хелпера зафиксирован нулём, непрозрачность — единицей

Пустая замена удаляет выбранный исходный текст; поставьте RequireSourceText = False, чтобы вставить абзац в пустую исходную область

Свидетельства коллизий

Невыбранный непробельный текст, изображения XObject и inline, границы отрисованных путей и прямоугольники аннотаций сравниваются с границами сгенерированных глифов замены

Каждая коллизия указывает свой тип, границы в пространстве страницы, опциональный соседний текст и индекс глифа замены; общее количество сохраняется, даже когда возвращаемый список коллизий упирается в потолок

Контрольные точки путей, трансформированные границы клипа Form, толщина обводки и пределы miter дают консервативные боксы; затенение (shading) с неизвестной областью рисования консервативно занимает весь прямоугольник-цель

Этот геометрический тест может давать ложные срабатывания на прозрачных изображениях, нерисованных областях аннотаций, кривых, клипнутых путях и повёрнутых конвертах Form; он не доказывает попиксельное разделение чернил и не исследует произвольные клип-пути, блендинг-композитинг или контуры шрифтов

RejectCollisions = True отвергает перекрывающиеся замены без мутаций; false сохраняет отчёт, позволяя осознанную политику перекрытия вызывающего

Предпросмотр, фиксация и откат

HPDFPreviewParagraphReflow возвращает запечатанный план во владении вызывающего, семантическую раскладку замены, отпечатки и свидетельства коллизий, затем откатывает сгенерированные объекты документа

HPDFCommitParagraphReflow повторяет ограниченный анализ и атомарно применяет план, только если содержимое источника, границы Form, геометрия аннотаций и геометрия шрифта замены всё ещё совпадают с предпросмотром

План принадлежит тому же живому экземпляру документа; освободите его по завершении, держите документ живым всё время и пересоздавайте предпросмотр после загрузки другого документа или изменения выбранного содержимого

THPDFParagraphReflowSession добавляет применённое состояние ревью: Apply открывает отредактированный документ для извлечения или рендеринга, Commit публикует его, а Rollback или уничтожение восстанавливает исходный граф

Используйте сессии последовательно; документ должен переживать сессию, и другие графовые транзакции или вызовы редактирования нельзя перемешивать, пока Pending истинен

Rollback восстанавливает состояние документа в памяти; уже сохранённые внешние файлы остаются ответственностью вызывающего

Конечная работа и поведение при сбоях

Умолчания: 64 МиБ декодированного содержимого, 64 МиБ сгенерированных потоков, 100000000 единиц работы, 100000 глифов, 250000 токенов, 12 уровней Form, 256 инвокаций Form, 256 возвращаемых коллизий и 100000 клонированных узлов ресурсов

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

Лимиты декодированного и сгенерированного покрывают содержимое, обрабатываемое хелпером; размер сгенерированного потока проверяется до публикации и не является пределом пиковой памяти процесса и не ограничивает все аллокации построителя установленных шрифтов

Отмена кооперативная — через токенизацию содержимого и циклы хелпера, с проверками вокруг существующих вызовов генерации шрифтов; держите токен до завершения вызова

Отсутствующий источник, неверный ввод, коллизии, устаревшие планы, неподдерживаемое содержимое, исчерпанные бюджеты, отмена и обычные сбои возвращают false с явным статусом и сохраняют исходный граф объектов

Выбранный вертикальный или вырожденный (singular) текст, циклические или неразрешённые Forms, неподдерживаемые типы отрисованных XObject и документы с полями подписи отвергаются; инкрементальное редактирование с сохранением подписей требует отдельного workflow

Пример

Options := HPDFDefaultParagraphReflowOptions;
Options.Appearance.FontName := 'Arial';
Options.Appearance.FontSize := 11;
Source.Left := 55; Source.Bottom := 659;
Source.Right := 350; Source.Top := 714;
Target := Source;
Plan := nil;
try
  if HPDFPreviewParagraphReflow(Document, 0, Source, Target,
    'The Supplier must deliver signed monthly reports.', Options,
    Plan, Report, CancellationToken) then
    if HPDFCommitParagraphReflow(Document, Plan, Report, CancellationToken) then
      Document.SaveLoadedDocument('reviewed-contract.pdf');
finally
  Plan.Free;
end;

Приёмка и сохранённый вывод

Выделенные раннеры Delphi и FPC используют реальные фикстуры загруженных PDF для многострочных абзацев, частичных операндов, вложенных общих Forms, клипнутого текста Form, изменений ширины и шрифта, типов коллизий, отмены и отката графа

Повторные сохранения file/file и stream/file сохраняют отредактированный граф; свежие неизменённые загруженные документы держат точные исходные байты, а после инъецированного сбоя записи вывода возможна успешная повторная попытка

Tests/Fixtures/ParagraphReflow/loaded-repeat-save.pdf изолирует регрессию сохранения без параграфового хелпера: загрузите, вставьте маркер, сохраните дважды и независимо прочитайте второй файл

Запустите Tests/Delphi/Run-ParagraphReflowTests.ps1 -Platform Win64 или Tests/FPC/Run-ParagraphReflowTests.ps1 -Platform Win64, для другой архитектуры выберите Win32

Опциональный Python-верификатор Tests/Fixtures/ParagraphReflow/verify_output.py использует PyMuPDF, чтобы извлечь реально сохранённый текст Unicode и отрендерить отредактированные страницы; каждый раннер подавляет автоматический запуск просмотрщика

Смежные темы

Ограниченное редактирование абзацев · Опции · Отчёт