Display list и печатное производство
HotPDF компилирует загруженные stream страниц в переиспользуемые экземпляры THPDFPageDisplayList с метриками THPDFDisplayListInfo и bounding box объектов содержимого
Рендеринг документа кэширует скомпилированные списки, а вызывающий код может запросить независимый список для повторного проигрывания или запросов объектов по области
Общий production-интерпретатор
Непрогрессивный bitmap, direct-DC, Form и проигрывание display list передают претокенизированное содержимое через HPDFInterpretContentTokensDevice, который владеет обходом операторов и границами отмены
THPDFPageRenderer реализует IHPDFContentOperatorDevice, поэтому общий обход задействует его полный конечный автомат графики, текста, ресурсов, clipping, pattern, прозрачности, marked-content и изображений, не сводя production-рендеринг к урезанному семантическому callback-интерфейсу
Display list кэшируют индексы токенов операторов при компиляции stream и при проигрывании используют только эти индексы, избегая повторного сканирования операндов; THPDFPageDisplayList.OperatorCount и THPDFDisplayListInfo.OperatorCount возвращают количество закэшированных команд
Семантические устройства, реализующие только IHPDFContentDevice, сохраняют callback'и с фильтрацией по возможностям, а полные операторные устройства получают по одному проверенному оператору за раз с одной контрольной точкой отмены на оператор
Ограниченный и параллельный рендеринг
THPDFRenderTileEvent получает за раз один tile или горизонтальную band размера, заданного вызывающим кодом, так что пиковое потребление растровой памяти не зависит от размера всей страницы
RenderLoadedPagesParallel совмещает компиляцию display list с проигрыванием, запускает первую готовую страницу, не дожидаясь полного барьера компиляции, динамически балансирует оба этапа между ограниченным числом workers и возвращает THPDFBitmapArray в порядке входа
Компиляция идёт вне блокировки кэша display list, а допуски с двойной проверкой и защищённые счётчики использования позволяют компилировать несвязанные страницы параллельно, не дублируя опубликованные записи и не выселяя список во время проигрывания
THPDFParallelRenderPipelineInfo раскрывает попадания в кэш, компиляции, завершения, пиковую конкурентность компиляции и рендеринга, число страниц, скомпилированных к моменту первого результата, задержку первого результата и общее время выполнения
RenderLoadedPagesParallelOrdered доставляет callback'и в порядке входа в потоке вызывающего и освобождает каждый заимствованный bitmap после возврата callback, а выбранная вызывающим глубина вывода создаёт backpressure для производителя и резервирует один слот под следующую нужную страницу, чтобы медленная ранняя страница не попадала в deadlock за поздними результатами
Упорядоченный streaming удерживает на каждый worker не больше одного display list и одного активного рендера плюс ограниченную очередь готовых bitmap вместо того, чтобы держать в памяти весь вывод задания
Подключаемые render backend'ы потребляют те же скомпилированные списки через невладеющее представление ресурсов документа, поэтому синхронный и параллельный пути избегают повторного разбора содержимого страницы, а возможности backend определяют, могут ли вызовы перекрываться или требуют последовательной диспетчеризации
Общепроцессный планировщик пиковой памяти теперь ограничивает оба параллельных API: оценка самой большой страницы уменьшает начальное число workers, каждая взятая в работу страница резервирует весь расчётный рабочий набор, а упорядоченный вывод сохраняет этот резерв до доставки callback
Отмена в планировщике будит ожидающих бюджета при отмене callback или сбое worker, а телеметрия раскрывает запрошенных и фактических workers, пиковый вес резервирования, отложенные страницы и суммарное время ожидания
RenderLoadedPageTilesParallel и RenderLoadedPageBandsParallel доставляют заимствованные tile в построчном порядке или band сверху вниз через изолированные workers, причём каждый worker владеет максимум одним tile, а заданный вызывающим лимит рабочей памяти снижает конкурентность ещё до первого захвата
Параллельные контексты рендеринга копируют неизменяемые последовательности токенов глифов Type 3 и halftone threshold screen из одного ограниченного LRU cache, сохраняя владение изменяемым графическим состоянием и GDI-ресурсами на уровне рендерера
SaveLoadedPageToPng, SaveLoadedPageToPngStream, SaveLoadedPagesToTiffBanded и SaveLoadedPagesToTiffStreamBanded используют тот же band-рендерер через потоковые кодировщики PNG или TIFF, поэтому очень большие страницы выдают сжатый вывод строка за строкой, не удерживая полный framebuffer, а THPDFBandImageExportInfo сообщает об отрендеренных band, закодированных строках, workers, пиковых байтах резервирования, байтах вывода, времени выполнения и отмене
Общее декодирование изображений координируется отдельно, поэтому векторная работа по страницам остаётся параллельной без повреждения записей кэша декодированных изображений
PrefetchLoadedPages прогревает растровые записи с выделенным cancellation token, компилируя и рендеря вне блокировки кэша, а рендеринг страницы на переднем плане вытесняет worker до начала чувствительной к задержкам работы
THPDFLoadedPagePrefetchInfo сообщает о запланированной, начатой, завершённой, закэшированной, отрендеренной, неудавшейся, отменённой и вытесненной передним планом работе, а также о последней и пиковой задержке отмены
Прозрачность и печатные настройки
Сведение прозрачности сначала проверяет счётчик прозрачности display list и заданный вызывающим потолок пикселей, затем заменяет отрисовку страницы на калиброванное RGB-изображение, сжатое Flate без потерь
Страницы с красками Separation или DeviceN остаются векторным содержимым, а обнаруженные краски и статус сохранения передаются вызывающему
Рендерер исполняет transfer functions и словари halftone Type 1, 5, 6, 10 или 16 из ExtGState, сохраняя независимые RGB screen и их переопределения transfer через q и Q
THPDFInkCoverageInfo сообщает среднее покрытие CMYK, максимальное суммарное покрытие площади и число пикселей выше выбранного порога
Вывод process- и spot-форм поддерживает краски DeviceCMYK, Separation и DeviceN
Переписывание цветов загруженной страницы использует тот же полный рендерер, чтобы конвертировать сложные страницы в Gray, RGB или CMYK, оставляя простой device-colour контент векторами и применяя явную политику spot-форм
THPDFTrappingInfo объединяет trapping-объявления документа, метаданные страницы и структурную диагностику TrapNet
ICC workflow
Трансформация рендеринга может объединять исходный профиль PDF, цветовое пространство смешивания, proof-профиль, выходной профиль и растровую цель sRGB
Все четыре ICC rendering intent и полноценная компенсация точки чёрного согласованно применяются к векторным цветам и отсчётам изображений по всему конвейеру
Полные трансформации переиспользуются в векторном, растровом, постраничном и параллельном путях рендеринга через потокобезопасный LRU cache на 64 MiB с ключом по содержимому исходного, proof- и выходного профилей, фактическому rendering intent и компенсации точки чёрного
Сведение прозрачности переиспользует тот же конвейер трансформаций, а затем выдаёт бесшовные D65 CalRGB tile в рамках заданных вызывающим бюджетов на общий растр и на пиксели каждого tile
Основные API
- Подключаемые render backend'ы
IHPDFContentOperatorDeviceHPDFInterpretContentTokensDeviceTHotPDF.CompileLoadedPageDisplayListTHPDFPageDisplayList.GetTokenTHPDFPageDisplayList.GetObjectTHPDFPageDisplayList.QueryObjectIndexesTHPDFPageDisplayList.PageObjectTHPDFPageDisplayList.ResourcesTHPDFPageDisplayList.MediaBoxTHotPDF.RenderLoadedPageTilesиRenderLoadedPageBandsTHotPDF.RenderLoadedPageTilesParallelиRenderLoadedPageBandsParallelTHPDFParallelTileRenderInfoTHotPDF.SaveLoadedPageToPngTHotPDF.SaveLoadedPageToPngStreamTHotPDF.SaveLoadedPagesToTiffBandedTHotPDF.SaveLoadedPagesToTiffStreamBandedTHPDFBandImageExportInfoTHotPDF.RendererSharedCacheMaxBytesTHotPDF.RenderLoadedPagesParallelTHotPDF.RenderLoadedPagesParallelOrderedTHPDFParallelRenderPipelineInfoTHotPDF.PrefetchLoadedPagesTHotPDF.GetLoadedPagePrefetchInfoTHPDFLoadedPagePrefetchInfoTHotPDF.FlattenLoadedPageTransparencyTHotPDF.FlattenLoadedPageComplexGraphicsTHotPDF.RenderLoadedPageSeparationPlateTHotPDF.GetLoadedPageSpotColorantsTHotPDF.RewriteLoadedPageColorsTHotPDF.AnalyzeLoadedPageInkCoverageTHotPDF.InspectLoadedPageTrappingTHotPDF.ConfigureRenderICCWorkflow