Перейти к содержимому
getnextpdf.com

Pro редакция

Flow Layout — глубокий справочник

Эта страница — глубокий справочник по модулю Pro Flow Layout. Она охватывает движок размещения, модель элемента, стратегии разрыва страниц, их контракты поведения и режимы отказа. StreamingLayoutEngine обходит список значений FlowElement по порядку. Каждому он назначает отсчитываемый от нуля индекс страницы и позицию внутри LayoutRegion. Результат — LayoutResult из неизменяемых записей PlacedElement. Модуль только вычисляет размещение; он ничего не рендерит и не выполняет ввод-вывод.

Эта возможность поставляется в составе NextPDF Pro (nextpdf/pro) и активируется лицензионным конвертом уровня Pro. Развёртывание без этого права доступа не загружает классы возможности. Сравнить редакции и получить лицензию.

Отдельного лицензионного флага для этой возможности нет. Это возможность редакции Pro.

Все символы находятся в пространстве имён NextPDF\Pro\FlowLayout. Все объекты-значения объявлены final и неизменяемы.

СимволПараметрыПоведение по умолчаниюВозвращаетБросает или завершается сПримечания
StreamingLayoutEngine::__constructLayoutRegion $region, PageBreakStrategy $strategy = PageBreakStrategy::GreedyСвязывает область содержимого каждой страницы со стратегией разрываStreamingLayoutEngineПо умолчанию стратегия Greedy.
StreamingLayoutEngine::layoutlist<FlowElement> $elementsОдин прямой проход; последовательное размещение с разрывами страниц по стратегииLayoutResultНикогда не бросаетПустой список даёт одну пустую страницу.
StreamingLayoutEngine::withStrategyPageBreakStrategy $strategyПорождает новый движок с той же областьюselfПолучатель не изменяется.
StreamingLayoutEngine::withRegionLayoutRegion $regionПорождает новый движок с той же стратегиейselfПолучатель не изменяется.
FlowElement::__constructFlowElementType $type, string $content, float $widthPt = 0, float $heightPt = 0, float $marginTopPt = 0, float $marginBottomPt = 0, bool $keepWithNext = falseНеизменяемый объект-значение элементаFlowElementЕдинственный способ создания элементов Table.
FlowElement::textstring $content, float $heightТекстовый элемент с высотой, измеренной вызывающей сторонойself (статический)Ширина 0 разрешается в ширину области при размещении.
FlowElement::imagestring $path, float $width, float $heightЭлемент изображения; content содержит путьself (статический)Движок никогда не открывает файл.
FlowElement::spacerfloat $heightВертикальный пробел с пустым содержимымself (статический)
FlowElement::pageBreakЯвный маркер разрываself (статический)Не создаёт PlacedElement.
FlowElement::totalHeightВысота плюс верхний и нижний отступыfloatВсе проверки помещаемости используют это значение.
FlowElementTypeварианты перечисления Text, Image, Table, Spacer, PageBreakНа основе строк: text, image, table, spacer, page_break
FlowElementType::isBreakableText и Table возвращают true; остальные — falseboolТолько классификация; см. контракт атомарного размещения ниже.
LayoutRegion::__constructfloat $x, float $y, float $width, float $heightПрямоугольник содержимого с началом в левом верхнем углу, в пунктахLayoutRegionБез проверки; значения берутся как есть.
LayoutRegion::containsfloat $px, float $pyПроверка попадания точки в область, включая границуbool
LayoutRegion::remainingHeightfloat $currentYВысота области минус израсходованное вертикальное смещениеfloatНоль или отрицательное значение после переполнения курсора.
LayoutResult::__constructlist<PlacedElement> $placements, int $pageCount, float $totalHeightPtНеизменяемый результат размещенияLayoutResult
LayoutResult::placementsOnPageint $pageIndexФильтрует размещения по отсчитываемому от нуля индексу страницыlist<PlacedElement>Возвращаемый список переиндексируется.
LayoutResult::isEmptytrue, когда ни один элемент не размещёнbooltrue для пустого ввода и ввода только из разрывов.
PageBreakStrategyварианты перечисления Greedy, AvoidOrphans, KeepTogetherНа основе строк: greedy, avoid_orphans, keep_together
PageBreakStrategy::labelЧеловекочитаемая метка стратегииstring
PlacedElement::__constructFlowElement $element, int $pageIndex, float $x, float $y, float $width, float $heightНеизменяемая запись размещенияPlacedElementКоординаты в пунктах, начало в левом верхнем углу.
public function layout(array $elements): LayoutResult
public function withStrategy(PageBreakStrategy $strategy): self
public function withRegion(LayoutRegion $region): self
public static function text(string $content, float $height): self
public static function image(string $path, float $width, float $height): self
public static function spacer(float $height): self
public static function pageBreak(): self

StreamingLayoutEngine::layout() выполняет один прямой проход по входному списку. Для каждого элемента он проверяет помещаемость, при необходимости разрывает страницу, затем записывает PlacedElement. Пустой входной список возвращает LayoutResult без размещений, с числом страниц 1 и общей высотой 0.

Геометрия размещения детерминирована:

  • x — левый край области.
  • y — текущая позиция курсора плюс верхний отступ элемента.
  • widthwidthPt элемента, если он положителен, иначе ширина области.
  • heightheightPt элемента, ровно как передано.

После каждого размещения курсор смещается на totalHeight(), включая отступы. Та же величина накапливается в LayoutResult::totalHeightPt.

Правила разрыва страниц, в порядке проверки:

  • Явный элемент PageBreak увеличивает индекс страницы и сбрасывает курсор к верху области. Он не создаёт размещения и ничего не добавляет к общей высоте.
  • Когда totalHeight() элемента превышает оставшуюся высоту, движок разрывает страницу — если только курсор уже не находится в верху страницы.
  • Greedy не добавляет дополнительных условий: помещающиеся элементы всегда размещаются.
  • AvoidOrphans разрывает страницу перед помещающимся элементом, когда пространство, остающееся после размещения, было бы положительным, но меньше половины собственной требуемой высоты элемента. Опорной единицей служит собственная высота элемента с фиксированным делителем два; никакие метрики шрифта не участвуют. Он никогда не разрывает в верху страницы.
  • KeepTogether разрывает страницу перед помещающимся элементом, когда установлен его флаг keepWithNext, существует следующий элемент, курсор не в верху страницы и суммарная totalHeight() обоих элементов превышает оставшееся пространство. Флаг на последнем элементе не действует.

Атомарное размещение: движок размещает каждый элемент как единое целое. Он никогда не разбивает содержимое элемента между страницами. FlowElementType::isBreakable() классифицирует, какие типы вызывающая сторона может заранее разбить на меньшие элементы; сам движок к нему не обращается.

Отсутствие состояния и детерминизм: движок хранит только свою область и стратегию. layout() не разделяет состояние между вызовами, и одинаковые входные данные дают одинаковые результаты. withStrategy() и withRegion() возвращают новые движки и никогда не изменяют получателя.

  • Ни один метод этого модуля не бросает исключений. Нет иерархии исключений, которую нужно перехватывать.
  • Конструкторы ничего не проверяют. Отрицательные или нулевые размеры области, отрицательные высоты элементов и отрицательные отступы принимаются и проходят через арифметику без изменений.
  • Элемент выше области всё равно размещается. В верху страницы он размещается там и выходит за пределы; в другом месте движок сначала разрывает страницу, и элемент выходит за пределы новой страницы. Следующий элемент затем всегда вызывает разрыв, поэтому переполнение ограничено одной страницей.
  • Ведущий PageBreak размещает первый содержательный элемент на странице с индексом 1, давая число страниц не менее 2.
  • Последовательные элементы PageBreak каждый увеличивают счётчик страниц, создавая пустые страницы. Завершающий оставляет в pageCount последнюю пустую страницу.
  • Keep-together действует только тогда, когда оба парных элемента помещаются на одной странице вместе. Пара, суммарная высота которой превышает целую страницу, всё же разбивается.
  • Неположительный widthPt разрешается в ширину области; проверка подстановки — строго больше нуля.
  • remainingHeight() может вернуть ноль или отрицательное значение после переполнения курсора. contains() считает границу области находящейся внутри.
  • placementsOnPage() с индексом вне диапазона возвращает пустой список.
  • Этот модуль не выполняет криптографических операций и не определяет специфичного для FIPS поведения.

Flow Layout реализует поведение размещения, определённое NextPDF. Он не нацелен на внешний стандарт макета или типографики, поэтому на этой странице нет нормативной таблицы цитирования. Стратегии разрыва страниц — это семантика NextPDF; они не являются реализациями свойств фрагментации CSS или какой-либо модели keep из XSL-FO. Все размеры выражены в пунктах, что соответствует единицам, которые потребляет модуль записи Core.

Эти утверждения описывают только возможности. NextPDF не имеет сертификации соответствия, и никакое заявление о сертификации не делается и не подразумевается.

  • Измеряйте содержимое заранее. Движок потребляет высоты, переданные вызывающей стороной; у него нет метрик шрифта, и он не измеряет текст.
  • Заранее разбивайте длинный текст или содержимое таблиц на несколько элементов до размещения. Используйте isBreakable(), чтобы решить, какие типы может разбивать разбивщик.
  • Повторно используйте один движок на каждую геометрию страницы. Дёшево порождайте варианты с помощью withStrategy() и withRegion().
  • Группируйте вывод по страницам с помощью placementsOnPage() при постраничном рендеринге.
  • Размещение — это один проход, линейный по числу элементов, и не хранит дерево документа. Результаты детерминированы, что подходит для тестов на золотых файлах.
  • Для рендеринга HTML в PDF используйте вместо этого конвейер Core HTML; этот модуль не является движком HTML или CSS.

Эта страница документирует только внешне наблюдаемое поведение и поддерживаемую публичную поверхность API. Внутренние пути пространств имён, вспомогательные классы, таблицы механизмов, имена файлов runbook и префиксы тикетов — вне области рассмотрения.