Skip to content

Журнал змін

Тут задокументовано всі суттєві зміни в PDF Oxide.


v0.3.38 – 2026-04-22

DocumentBuilder з’являється в кожній прив’язці; AES-256 на шляху запису; перевірка підписів; багатоцільовий WASM; бекенд Go purego

Паритет API запису в усіх прив’язках (#384)

  • DocumentBuilder + FluentPageBuilder + EmbeddedFont тепер постачаються в Python, Node/TypeScript, C#, Go та WASM поряд із Rust. Багатосторінкова побудова з повною підтримкою CJK / кирилиці / грецької через вбудовані шрифти. Закриває #382 на рівні всіх мов.
  • 15 методів анотацій у кожній прив’язці: link_url / link_page / link_named, highlight, underline, strikeout, squiggly, нотатка-стікер, штамп (14 стандартних + власний), вільний текст, watermark (власний / DRAFT / CONFIDENTIAL).
  • 5 типів віджетів AcroForm у кожній прив’язці: text_field, checkbox, combo_box, radio_group, push_button.
  • Графічні примітиви в кожній прив’язці: rect, filled_rect, line.
  • Конвеєр HTML+CSSPdf.from_html_css(...) та from_html_css_with_fonts(...) для каскадів із кількома шрифтами в кожній прив’язці.

Шифрування AES-256 на шляху запису (#386)

  • save_encrypted(path, user_pw, owner_pw) / to_bytes_encrypted(user_pw, owner_pw) на DocumentBuilder у кожній прив’язці.
  • save_with_encryption у Rust для власного алгоритму + дозволів.

Справжнє формування підмножини шрифтів (#385 / FONT-3b)

  • Накреслення CJK тепер вбудовуються як підмножина, а не як повне накреслення. PDF із 5 символів, побудований із CJK-шрифту обсягом ~17 МБ, зазвичай постачається менш ніж 100 КБ. Потоки вмісту, ширини /W та CMap ToUnicode перепризначаються на простір GID підмножини; кругообіг extract_text лишається незмінним.
  • Зміна внутрішнього API записувача: EmbeddedFont::encode_string / encode_shaped_run повертають Vec<u16>, а build_embedded_font_objects повертає GlyphRemapper, який викликачі передають у ContentStreamBuilder::build_with_remappers. Без змін у високорівневих API.

Перевірка цифрових підписів (#208, частина перевірки)

  • Signature.verify() та Signature.verify_detached(pdf_bytes) (і нативні еквіваленти прив’язок) у кожній прив’язці. Перевірки атрибутів підписувача за RFC 5652 §5.4 + messageDigest за §11.2.
  • RSA-PKCS#1 v1.5 над SHA-1 / SHA-256 / SHA-384 / SHA-512 повертає Valid / Invalid. RSA-PSS та ECDSA проявляються як Unknown / UnsupportedFeatureException; викликачі все ще можуть прочитати сертифікат і виконати власну перевірку.
  • Certificate — інспекція DER (subject, issuer, серійний номер, чинність, is_valid) через x509-parserкожна прив’язка.
  • Signature — перелічення + інспекція + .get_certificate()кожна прив’язка.
  • Timestamp — розбір TSTInfo за RFC 3161 (час, серійний номер, політика, ім’я TSA, алгоритм хешування, відбиток повідомлення) — кожна прив’язка.
  • TsaClient — HTTP POST за RFC 3161 з nonce та базовою HTTP-автентифікацією за Cargo-фічею tsa-clientкожна прив’язка, крім WASM. Навмисно не під’єднано у WASM (ureq несумісний із wasm).
  • Записувачі метаданих DocumentEditor::set_producer / set_creation_date.
  • render_page_region та render_page_fit — обрізана та припасована поверхня рендерингу.
  • Бікубічна фільтрація зображень (паритет із pdf.js #19978) — відскановані / дворівневі сторінки з накладеннями в режимі Multiply більше не схлопують свій діапазон відтінків сірого під час зменшення масштабу.

Саме підписування (на відміну від перевірки) не охоплено; #208 лишається відкритим для цієї частини.

Багатоцільове пакування WASM (#392)

  • pdf-oxide-wasm тепер постачає три збірки поряд із умовними експортами в package.json: nodejs/, bundler/ (Vite / webpack / Rollup / esbuild / Bun) та web/ (браузери / Deno / Cloudflare Workers).
  • Виправляє ReferenceError: Can't find variable: __dirname, що виникав під браузерними збирачами.
  • Доступні імпорти за підшляхами (pdf-oxide-wasm/web, /nodejs, /bundler) для ручного маршрутизування.

Прив’язка Go — бекенд purego + встановлення в каталог кешу

  • Другий бекенд через ebitengine/purego виконує dlopen для libpdf_oxide.{so,dylib,dll} під час виконання. Збірки з CGO_ENABLED=0 тепер працюють. Вибір бекенда відбувається автоматично — //go:build cgo → повний CGo API, //go:build !cgo → purego.
  • Поверхня purego: відкриття PdfDocument (шлях / байти / пароль), кількість сторінок, версія, вилучення тексту / Markdown / HTML / простого тексту, шрифти, анотації, елементи сторінки, пошук, розміри сторінки, журналювання, а також PdfCreator.FromMarkdown для тестових фікстур.
  • Лише CGo (помилка компіляції за !cgo): DocumentEditor, DocumentBuilder, штрихкоди, підписи, TSA, рендеринг, OCR, мутація форм.
  • Інсталятор: новий прапорець -shared отримує cdylib замість staticlib і виводить CGO_ENABLED=0 + PDF_OXIDE_LIB_PATH=… для експорту.
  • Каталог встановлення переміщено до os.UserCacheDir()~/.cache/pdf_oxide (Linux), ~/Library/Caches/pdf_oxide (macOS), %LocalAppData%\pdf_oxide (Windows). Відповідає власній конвенції Go GOCACHE.
  • Релізні ассети тепер містять pdf_oxide-go-ffi-shared-<platform>.tar.gz для кожної платформи Tier-1 поряд із наявними архівами staticlib.

Виправлення помилок

  • #395RenderPage більше не викликає SignatureException, коли сторінка містить нерозбірні метадані поля підпису, але не має інтерактивного віджета підпису. Повідомлено @gevorgter.

Подяки

  • @sparkyandrew – #382 (CJK через DocumentBuilder), #385 (формувач підмножини).
  • @arthurlassagne – #392 (поломка браузерної збірки).
  • @gevorgter – #395 (виняток підпису в RenderPage).

v0.3.37 – 2026-04-20

HTML + CSS → PDF (#248) — перший вартий довіри конвеєр на чистому Rust

Новий API — Pdf::from_html_css

let font = std::fs::read("DejaVuSans.ttf")?;
let pdf = Pdf::from_html_css(
    "<h1>Hello</h1><p>World</p>",
    "h1 { color: blue; font-size: 24pt }",
    font,
)?;
pdf.save("out.pdf")?;

Передайте HTML + CSS + байти шрифту — отримайте назад розбитий на сторінки PDF. Чистий Rust, лише MIT/Apache (без транзитивних залежностей MPL), кругообіг extract_text збігається побайтово, тож вироблені PDF беруть участь у наявній тестовій інфраструктурі.

Що ввійшло до релізу

  • Підсистема шрифтів — вбудовування TTF/OTF з емісією Type 0 / CIDFontType2 / Identity-H / ToUnicode; латиниця, кирилиця, грецька, іврит, арабська проходять кругообіг через extract_text. Виявлення системних шрифтів через fontdb, формування тексту (shaping) через rustybuzz.
  • Власноруч написаний рушій CSS (~6 500 рядків коду, нуль залежностей MPL) – токенізатор, парсер, селектори L3+L4 (:is/:where/:not/:has), зіставлювач, каскад, calc() / min() / max() / clamp(), var() із виявленням циклів, типізовані значення властивостей, at-правила (@media print, @page з :first/:left/:right/:blank, @font-face, @import, @supports), лічильники, вміст псевдоелементів.
  • HTML – токенізатор HTML5, плаский arena-DOM, вилучення таблиць стилів (<style>, <link rel="stylesheet">, вбудований style=""), вилучення ресурсів (<img> + srcset, <picture>/<source>, <a href>).
  • Розкладка – block / flex / grid на основі Taffy, перенесення рядків за UAX #14, схлопування полів, багатоколонковість, таблиці (auto + fixed).
  • Малювання – текст + рамки, RTL через rustybuzz, <a href> → анотація /Link, data-URI з <img>/XObject, ::before / ::after, page-break-{before,after}: always, opacity, transform: translate*(), маркери списків <ul> / <ol>, вбудовані шрифти через DocumentBuilder::register_embedded_font (#382).

Каскад із кількома шрифтами

  • Pdf::from_html_css_with_fonts(html, css, Vec<(family, bytes)>) — властивість CSS font-family на будь-якому елементі розв’язується щодо зареєстрованих родин (без урахування регістру, з лапками й без них, багатослівні без лапок).

Виправлення помилок у проході крайових випадків

  • Напівжирний текст Base-14 тепер рендериться напівжирним (невідповідність ключа словника ресурсів щодо Tf /Helvetica-Bold).
  • Системні шрифти TTC (Helvetica.ttc, msgothic.ttc) тепер розв’язуються через Source::SharedFile з fontdb.
  • Багатослівний font-family без лапок тепер коректно токенізується.
  • Закрито витік пам’яті у фабриках Pdf::from_html_css (чотири місця Box::leak замінено на локальні змінні з областю видимості).
  • PNG alpha / м’яка маска (SMask) тепер рендеряться.
  • Сформований (shaped) текст проходить кругообіг через extract_text (encode_shaped_run відображає кластери гліфів назад на вихідні кодові точки).
  • PdfWriter::finish вбудовує шрифти в порядку реєстрації (раніше — у випадковому порядку HashMap).
  • Колізії імен вбудованих шрифтів ізольовано через монотонно зростаючі імена ресурсів EFn.
  • Mutex fontdb більше не утримується протягом fs::read байтів шрифту.

Поза межами охоплення

CSS-фільтри, 3D-трансформації, анімації, SVG всередині HTML (кожен життєздатний Rust-крейт SVG має ліцензію MPL), MathML, hyphens: auto, shape-outside, JavaScript, повноматричний transform (scale/rotate), градієнти, box-shadow.

Аудит ліцензій

cargo deny check licenses проходить із нулем транзитивних залежностей MPL. CSS-стек Mozilla (cssparser, selectors, html5ever, lightningcss, stylo) повністю під MPL-2.0; v0.3.37 власноруч реалізує еквіваленти, щоб pdf_oxide лишався цілковито під MIT/Apache.

Подяки

  • @jmriebold – #248 («підтримка CSS») є коренем усього конвеєра HTML+CSS→PDF цього релізу.

v0.3.36 – 2026-04-19

Структурне вилучення Markdown — емісія заголовків/списків із тегованого PDF, багатоколонковий порядок читання, безпечніше оброблення RTL

Структурне вилучення Markdown (#377)

to_markdown() тепер під’єднує /StructTreeRoot безпосередньо до конвеєра Markdown замість повторного виведення рівнів заголовків з евристик розміру шрифту та маркерів списків із виявлення гліфів:

  • Емісія заголовків і списків із /StructTreeRoot. Нова StructRole (Heading(1..6), ListItem, ListItemLabel, ListItemBody), прикріплена до кожного фрагмента. Документи з тегами Word відновлюють свою повну ієрархію заголовків; списки видають - item із розривами абзаців на кожному переході ролі.
  • Роль поширюється крізь вкладені MCR. Шаблони H1 → Span → MCR та LI → LBody → Span → MCR тепер несуть правильну семантичну роль через InheritedContext { heading_level, list_role }.
  • Межа блоку на кожен /StructTreeRoot примусово створює розрив абзацу. OrderedContent.block_id інкрементується на кожному вході до /P, /H1..6, /LI, /Lbl, /LBody, /Sect, /Div, /Art, /TR, /TH, /TD, /Note, /Reference, /BibEntry, /Code; розкладки зі щільними проміжками більше не зливаються.
  • Шлюз однієї базової лінії проти надмірної фрагментації заголовків форм — фрагменти на одній базовій лінії знову об’єднуються в один заголовок.
  • Виявлення міжколонкового проміжку — фрагменти на одній базовій лінії, розділені > max(3 × font_size, 30 pt), трактуються як міжколонкові.
  • Виявлення перенесення порядку читання за зворотним x — порядок читання за колонками (останній фрагмент колонки 1 на x=976 → перший фрагмент колонки 2 на x=192 на тій самій базовій лінії) тепер розриває абзаци замість їх з’єднання.
  • Геометричне виявлення заголовків + префіксів списків для нетегованих документів. Напівжирний + приріст розміру на 5 % підвищує до H4. Нова is_ordered_list_marker розпізнає 1. / 12. / a) / iv. / A., водночас відхиляючи підписи до рисунків та роки.

RTL-текст — безпечно за замовчуванням

  • Хибні маркери **bold** навколо контекстних гліфів арабської тепер видаляються (переходи формування збивали детектор насиченості шрифту).
  • Переупорядкування bidi вимкнено за замовчуванням. Раніший чернетковий варіант виконував візуально→логічне переупорядкування unicode-bidi на кожному RTL-рядку, що ламало раніше коректні PDF із логічним порядком (єврейське ім’я בנימין інвертувалося). Помічник переупорядкування лишається в text::bidi::reorder_visual_to_logical для викликачів, чий ввід має візуальний порядок.

Вивід Markdown

  • Вбудовані data-URI зображень у base64 обмежено 200 КБ. PDF із діаграмами високої роздільності раніше роздували вивід markdown у 10–20 разів (стаття на 1,9 МБ давала 11,3 МБ markdown). Зображення понад ліміт видають HTML-коментар-заповнювач із вихідним розміром. Файловий вивід зображень (image_output_dir) не зачеплено.

Емпіричний вплив

Перевірено щодо v0.3.35 на регресії з 369 PDF, що охоплює підмножини академічних, державних, форм, газет, технічних, дисертацій, IRS, pdfium, pdfjs, safedocs та повільного корпусу:

  • 0 катастрофічних регресій.
  • Token Jaccard щодо pdfium та pdftotext: медіана 1,000, ≥0,95 на 95 зі 106 фікстур.
  • Token Jaccard щодо pymupdf4llm: медіана 0,978, ≥0,95 на 65 зі 106 фікстур.
  • Приблизно вдвічі більше виданих заголовків, ніж у pymupdf4llm, по всьому корпусу.

Подяки

  • @Goldziher (kreuzberg) – завів #377 із методологією бенчмарку на 727 документів плюс 9 відтворювальних PDF. Формулювання («TF1 у межах ±3 %, тож текстовий вміст у порядку, проблема в структурі») зробило все дослідження посильним.

v0.3.35 – 2026-04-19

Збереження дублетів вузьких гліфів під час вилучення тексту

Коректність вилучення тексту

  • Сусідні дублети вузьких гліфів більше не схлопуються за малих розмірів шрифту (#378, PR #379). TextExtractor::deduplicate_overlapping_chars та deduplicate_overlapping_spans використовували жорстко закодований абсолютний поріг 2 pt; для вузьких гліфів (l, r, I, i) у компактних шрифтах малих розмірів ширина просування на гліф падає до ≤ 2 pt (l у Helvetica ≈ 2,5 pt за 9 pt), тож законні сусідні дублети, віддалені рівно на одне просування, потрапляли в вікно дедуплікації, і один із двох гліфів мовчки відкидався. Видиме псування включало controller → controler, billed → biled, warranty → warrnty, following → folowing, VIII → VII. Поріг тепер масштабується з власною advance_width кожного гліфа як min(advance_width * 0.30, 2.0). Налаштовувані параметри піднесено до асоційованих констант TextExtractor::DEDUP_OVERLAP_RATIO / DEDUP_OVERLAP_CAP_PT.

Подяки

  • @Hugues-DTANKOUO – повідомив про #378 з точним аналізом першопричини та написав PR #379 із порогом, масштабованим за просуванням, і параметризованою регресійною матрицею (4 вузькі гліфи × 3 розміри основного тексту).

v0.3.34 – 2026-04-17

Ідіоматичний API сторінок у всіх прив’язках; структуроване вилучення таблиць

Нові можливості

  • API сторінок (#371) – Python, Node.js, C# та Go тепер надають об’єкт PdfPage. Ітеруйте через for page in doc, for (const p of doc), foreach (var p in doc.Pages) або doc.Pages(); індексуйте через doc[i], doc.page(i), doc[i] або doc.Page(i). Кожна сторінка надає ліниві text, markdown(), html(), words, lines, tables, images, paths, annotations, search() тощо.
  • Структуроване вилучення таблиць (#289)extract_tables() (Python), ExtractTables() (C#/Go) та extractTables() (Node.js) тепер повертають рядки та клітинки з текстом плюс обмежувальні прямокутники, а не лише Markdown. Доступно як на PdfDocument, так і на новій PdfPage.
  • Паритет Node.jsextractWords, extractTextLines, extractTables, extractPaths, getEmbeddedImages, ocrExtractText під’єднано до шару TypeScript (раніше лише нативні).
  • ExtractedTableTable – перейменування в ядрі Rust; надлишковий префікс Extracted видалено. Типи, звернені до FFI, оновлено.

Якість вилучення тексту

  • Виявлення колонок XY-cut на сторінках змішаної розкладки (#319) – захист is_multi_column_page посилено, щоб вимагати щонайменше 15 фрагментів на колонку; фрагменти, упорядковані за колонками, більше не пересортовуються рядково-обізнаним сортуванням у extract_text.

Подяки

  • @SeanPedersen за пропозицію API «сторінка передусім» (#371). @pdenapo за запит структурованого вилучення таблиць (#289).

v0.3.33 – 2026-04-16

Виправлення вилучення тексту, коректності зображень та безпеки пам’яті

Виправлення помилок

  • Промах CMap ToUnicode (#363) – підмножини шрифтів Type0 тепер видають U+FFFD, коли CID відсутній у CMap ToUnicode, замість провалювання в шифротекст Identity-H (наприклад, %B+$%8A//$2*%01*1%6APP).
  • Внутрішньослівний кернінг TJ більше не розбиває слова (#365) – кернінг пар літер 0,10–0,20 em усередині поодиноких слів ([(diffe) -150 (rent)]) більше не спричиняє вставлення пробілу.
  • Відновлено кириличне UTF-8 кракозябра (#317) – шрифти з лише латинським кодуванням і сирими послідовностями байтів UTF-8 тепер декодуються коректно.
  • Часткове відновлення FlateDecode відхиляє сміттєвий вивід (#364) – PDF від MS Reporting Services, чиї потоки вмісту дають збій посеред розпакування, більше не повертають 128 байтів псевдовипадкових даних.
  • Палітра Indexed + ICCBased (#373) – нерозв’язані посилання на ICC-потоки всередині базового масиву Indexed більше не встановлюють /N за замовчуванням у 3 замість 4 для CMYK, що виправляє артефакти діагональних смуг. Повідомлено @Charltsing.
  • Палітри Indexed на основі Lab → sRGB (#337) – байти палітри CIE L*a*b* тепер конвертуються Lab→XYZ→sRGB замість переінтерпретації як сирий RGB.

Пам’ять та продуктивність

  • Усі внутрішні кеші обмежено (PR #369, #354) – кеш об’єктів (64 МБ), кеші шрифтів (256–512 записів), кеші фрагментів/зображень XObject (1024 записи) та глобальний кеш CMap (1024 записи) тепер використовують витіснення FIFO.
  • Виправлено OOM під час вилучення шляхів на PDF із великою кількістю діаграм (#369) – додано дедуплікацію XObject з урахуванням CTM, тож той самий XObject у тій самій позиції дедуплікується, але той самий XObject у різних позиціях обробляється окремо.
  • Стійкість до отруєння MutexMutexExt::lock_or_recover() замінює 72 місця виклику .lock().unwrap().

Залежності

  • Екосистема RustCrypto cipher 0.5 (PR #352, #295, #291): aes 0.8→0.9, cbc 0.1→0.2, sha2/sha1/md-5 0.10→0.11.

Набір тестів

  • Видалено 13 мертвих/застарілих ігнорованих тестів; виправлено 3 раніше ігнорованих тести. Додано регресійні тести на кожне виправлення вище. Набір тепер: 6 300 пройдено, 0 провалено, 228 проігноровано.

Подяки

  • @Charltsing за звіт про помилку вилучення зображень Indexed + CMYK (#373).
  • @ddxtanx за профілювання необмеженого зростання пам’яті під час багатосторінкового вилучення (#354).
  • @andrewjradcliffe за PR #369: обмежені FIFO-кеші, дедуплікація XObject з урахуванням CTM, трейт відновлення після отруєння MutexExt, посилення прив’язки Python.

v0.3.32 – 2026-04-15

Виправлення релізного конвеєра для tarball Go FFI під Windows-x64

Релізний конвеєр

  • Виправляє збій збірки нативної бібліотеки x86_64-pc-windows-gnu, що провалював реліз v0.3.31scripts/shrink-staticlib.sh запускав objcopy --strip-debug на кожному члені архіву, але крос-компілювальний тулчейн MinGW видає розділені налагоджувальні члени .dwo, що містять лише секції DWARF; після стрипінгу в члена не лишалося секцій, і objcopy переривав увесь архів. Виправлення: видалити члени архіву .dwo через ar d перед викликом objcopy. Жодних функціональних змін в артефактах Rust, Python, Node, WASM чи C# – цей реліз існує винятково для розблокування шляху встановлення Go під Windows-x64.

v0.3.31 – 2026-04-13

Виправлення помилок, зміни збірки Go, покращення релізної інфраструктури

Виправлення помилок

  • Відновлення Xref – виправлено відновлення для неправильно позначених вільних об’єктів сторінок і записів зміщення xref, що збиваються на кілька байтів.

Зміни, що порушують сумісність

  • Нативні бібліотеки Go – нативні бібліотеки більше не комітяться в go/lib/. Споживачі мають один раз на машину виконати go run github.com/yfedoseev/pdf_oxide/go/cmd/install@latest.

Релізна інфраструктура

  • Зменшено staticlib Rust на 63% (з 71 МБ до 26 МБ), знято налагоджувальну інформацію з аддона npm .node, прибрано sourcemap з npm, виправлено витік sdist крейта, посилено пакування NuGet snupkg.

v0.3.27 – 2026-04-12

Staticlib Go, нативні прив’язки Node.js, C# NativeAOT, OCR FFI, великі виправлення помилок

Нові можливості

  • Міграція Go на staticlib – перехід із cdylib на staticlib заради самодостатніх бінарників Go.
  • Нативні прив’язки Node.js – попередньо зібрані платформні підпакети через розповсюдження у стилі napi-rs.
  • C# LibraryImport – мігровано 881 оголошення P/Invoke з DllImport на LibraryImport заради сумісності з NativeAOT.
  • Міст OCR FFI – підтримка OCR тепер доступна в прив’язках Go, C# та Node.js.
  • Регресійна оснастка – курований корпус із 60 PDF для автоматизованого тестування якості.

Виправлення помилок

  • Зображення з колірним простором Indexed, шифрування AES-256 (V=5, R=6), порядок читання для одноколонкового та табличного вмісту, вилучення арабського тексту, розділення слів, запасний варіант ширини шрифту, інвалідація кешу об’єктів, покращення рендерингу.

v0.3.24 – 2026-04-09

Офіційні прив’язки для JavaScript/TypeScript, Go та C#

Нові можливості

  • Прив’язки JavaScript/TypeScript – опубліковано на npm із повним покриттям API.
  • Прив’язки Go – нативний пакет Go з повною поверхнею API.
  • Прив’язки C# – пакет .NET, опублікований на NuGet.
  • Шар C FFI – понад 270 функцій extern "C" зі спільним заголовком pdf_oxide.h.
  • Глобальний контроль рівня журналювання – налаштовується в усіх прив’язках.

v0.3.23 – 2026-04-09

Критичні виправлення стабільності

Виправлення помилок

  • Виправлено SIGABRT на сторінках із виродженою CTM із повернутих PDF від dvips.
  • Виправлено видалення зображень/XObject під час збереження.
  • Виправлено спотворений рендеринг на системах без поширених шрифтів.
  • Виправлено, що індекс сторінки поля форми завжди повертав 0.

v0.3.22 – 2026-04-08

Потокобезпечні документи, асинхронний Python, Python без GIL, тонке налаштування сегментації слів/рядків

Нові можливості

  • Потокобезпечний PdfDocumentSend + Sync через Mutex (замінив RefCell).
  • Асинхронний API PythonAsyncPdfDocument, AsyncPdf, AsyncOfficeConverter.
  • Python без GIL – підтримка cp314t (збірки без GIL).
  • Пороги сегментаціїword_gap_threshold, line_gap_threshold, profile для налаштування виявлення слів/рядків.

Виправлення помилок

  • Порожні сторінки під час split/merge у CLI, пропуск рендерингу для некоректних зображень, SIGSEGV через цикл у дереві структури, шлюзування стратегії таблиць.

Продуктивність

  • Кешовані дерево структури та розпаковані потоки вмісту, пошук MCID за O(1), обхід дерева сторінок за O(log n), ліниве заповнення дерева сторінок.

v0.3.21 – 2026-04-04

Багатоархітектурні колеса Python, виправлення рівня журналювання

Виправлення помилок

  • Рівень журналювання тепер повністю враховується в Python (макроси перенаправляються до крейта log).

Нові можливості

  • Багатоархітектурні колеса Python – Linux aarch64, musl x86_64/aarch64, Windows ARM64; вимогу до glibc знижено до 2_28.

v0.3.20 – 2026-04-04

Велике переписування вилучення таблиць, покращення якості тексту, тихе журналювання за замовчуванням

Нові можливості

  • Переписування рушія вилучення таблиць – конвеєр перетинів, виявлення країв тексту, розширена сітка, виявлення тексту з урахуванням колонок, реконституція пунктирних/штрихових ліній, гібридне виявлення рядків.
  • Якість вилучення тексту – проміжки між сусідніми значеннями, злиття розділених десяткових, консолідація напівжирних фрагментів, ієрархія заголовків HTML, парування міток і значень, злиття колонкових груп.
  • Тихе журналювання – журналювання тепер тихе за замовчуванням в усіх прив’язках; журнали Python течуть через модуль logging за допомогою pyo3-log.

Виправлення помилок

  • Зрозуміле повідомлення про помилку для зашифрованого PDF, дешифрування потоків ObjStm/XRef, оброблення кінцевого переходу рядка парсером потоків.

v0.3.19 – 2026-04-02

Вилучення сторінки одним викликом, порядок читання з урахуванням колонок, посимвольні обмежувальні прямокутники

Нові можливості

  • extract_page_text() – DTO з одним викликом для спрощеного вилучення сторінки.
  • Порядок читання з урахуванням колонок – просторове розбиття XY-Cut для багатоколонкових документів.
  • Посимвольні обмежувальні прямокутники – виведені з метрик шрифту для точного позиціонування символів.
  • Прапорець is_monospace – доступний на TextSpan та TextChar.
  • Pdf::from_bytes() – новий конструктор у всіх прив’язках.
  • Операції зі шляхамиextract_paths() у прив’язках Python.

Виправлення помилок

  • UTF-8 паніка в багатобайтовому налагоджувальному журналі, проміжки Markdown, /Matrix у Form XObject, матриця повернутого тексту, втрата CTM під час передсканування, дедуплікація, втрата тексту за масштабу Tm, злиття слів у Markdown, порожні документи під час merge у CLI.

Зміни, що порушують сумісність

  • WASM – імена полів JSON тепер використовують camelCase.

v0.3.18 – 2026-04-01

Капітальне перероблення рушія рендерингу, нові API Python та WASM, Python «із батарейками»

Нові можливості

  • Капітальне перероблення рушія рендерингу – коректний міжсимвольний інтервал, підтримка вбудованих шрифтів, метрики стандартних шрифтів, заливання-і-обведення, шлях обтинання, градієнтне затінення, альфа-прозорість, трафаретні маски зображень, поворот сторінки, плашкові колірні простори.
  • Нові API Pythonvalidate_pdf_a, validate_pdf_ua, validate_pdf_x, extract_pages, delete_page, move_page, flatten_to_images, конструктор із паролем, merge.
  • Нові API WASMvalidatePdfA, deletePage, extractPages, save, конструктор із паролем, merge.
  • Python «із батарейками» – рендеринг, паралелізм, підписи та конвертація Office увімкнено за замовчуванням.

Виправлення помилок

  • Переривання за виродженої CTM, захист від flate-бомби у FlateDecode (ліміт 256 МБ), синхронізація стека обтинання.

v0.3.17 – 2026-03-08

Уточнення виявлення таблиць, оптимізація тегованого PDF

Покращення

  • Уточнене виявлення таблиць – вимагає 2+ колонки, зменшуючи хибні спрацювання.
  • Оптимізований конвеєр вилучення тегованого PDF.

Виправлення помилок

  • Виправлено паніку RefCell already borrowed під час рекурсивного оброблення Form XObject.

v0.3.16 – 2026-03-08

Розумне гібридне вилучення таблиць, заглушки типів Python, підтримка pathlib

Нові можливості

  • Розумне гібридне вилучення таблиць – кластеризація Union-Find, аналіз візуальних ліній, візуальні фрагменти/заголовки.
  • Професійні ASCII-таблиці – багаторядкове перенесення для виводу в термінал.
  • Заглушки типів Python – автоматично генеруються через mypy stubgen.
  • Python PdfDocument – приймає pathlib.Path і підтримує контекстний менеджер.

Виправлення помилок

  • Segfault у вкладеному Form XObject, масштабування координат у Python, UTF-8 паніка в ASCII-таблиці.

v0.3.15 – 2026-03-06

Керування колонтитулами, шаблони сторінок, вилучення з областю

Нові можливості

  • API керування колонтитулами – додавання, видалення та редагування артефактів PDF.
  • Шаблони сторінок – динамічні заповнювачі для нумерації сторінок, дат тощо.
  • Вилучення з областю – враховує erase_regions для відфільтрованого виводу.
  • PdfDocument.from_bytes() – новий конструктор Python.

Виправлення помилок

  • Багатоколонковий порядок читання (XY-Cut), колізії ідентичності шрифтів, хибні спрацювання стратегії таблиць Lines.

v0.3.14 – 2026-03-03

Високорівневий рендеринг, вилучення слів/рядків, геометричні примітиви, гібридні таблиці

Нові можливості

  • Високорівневий API рендерингуPdf::render_page у Rust, Python та WASM.
  • Вилучення слів та рядківextract_words, extract_text_lines у всіх прив’язках.
  • Вилучення геометричних примітивівextract_rects, extract_lines.
  • Гібридне виявлення таблиць – підказки векторних ліній покращують виявлення меж таблиць.
  • Гармонізація API – плавний патерн .within(page, rect).
  • Команди CLI – команди render та paths із фільтрацією --area.

Виправлення помилок

  • Виявлення шлюзування фічі OCR, отруєння кешу фрагментів XObject, крипто-фільтри V=4, зашифрований CIDToGIDMap.

v0.3.13 – 2026-03-02

Виправлення вилучення тексту CJK

Виправлення помилок

  • Багатобайтове декодування в extract_chars для шрифтів CJK/Type0, покращена точність позиціонування символів, масштабування міжсимвольного інтервалу.

v0.3.12 – 2026-03-01

Якість вилучення тексту, конвертація markdown, продуктивність

Покращення

  • Якість вилучення тексту – обчислення ширини CID-шрифтів, виявлення меж слів під час зміни шрифту, запасний варіант для нестандартного відображення CID, спрямованість RTL-тексту.
  • Конвертація markdown – рекурсивне просторове розбиття XY-Cut, виявлення заголовків, реконструкція списків.

Продуктивність

  • Обхід дерева сторінок без копіювання, кешування дерева структури, ранній вихід за оператором BT, більший буфер вводу-виводу, видалено поріг реконструкції xref.

v0.3.10 – 2026-02-26

Паралельне вилучення, підтримка WASM/JavaScript, пакетне оброблення, покращення якості тексту

Нові можливості

  • Підтримка WASM/JavaScript – прив’язки WebAssembly через wasm-bindgen. Повне вилучення тексту, створення PDF, редагування, поля форм і пошук доступні у браузері та Node.js. Опубліковано як pdf-oxide-wasm на npm.

  • Паралельне вилучення сторінок – новий прапорець фічі parallel із багатопотоковим вилученням на основі rayon. ParallelExtractor розподіляє сторінки між робочими потоками. Глобальний кеш шрифтів гарантує, що шрифти розбираються лише один раз.

  • API пакетного оброблення – новий BatchProcessor для робочих процесів із кількома PDF, зі зворотними викликами прогресу та збором помилок. Підтримує як послідовне, так і паралельне оброблення.

  • Гібридне виявлення OCR – новий перелік PageType (NativeText, ScannedPage, HybridPage) з мультиевристичним виявленням для інтелектуального запасного OCR.

  • Повний паритет API WASM/Python – 10 нових груп методів у прив’язках WASM та Python: get/set полів форм, вилучення байтів зображень, PDF із зображень, сплощення форм, злиття PDF, вбудовування файлів, мітки сторінок, метадані XMP.

Виправлення помилок

  • Segfault циклічного XObject – виправлено segfault від циклічних посилань Form XObject під час вилучення зображень
  • Переповнення ланцюжка XRef /Prev – розбір ланцюжка XRef /Prev переписано з рекурсивного на ітеративний із виявленням циклів
  • Зламаний текст із лігатурами – постпроцесор repair_ligatures() виправляє пошкоджений текст із LaTeX-PDF
  • Якість вилучення тексту – вилучення тексту анотацій, нормалізація провідних крапок, підтримка CMap Priority 3
  • Вилучення таблиць – об’єднані клітинки, багаторядковий вміст клітинок, виявлення заголовків на основі шрифту
  • Збереження полів форм – інкрементне збереження тепер коректно зберігає зміни значень полів форм

Продуктивність

  • Пропуск сторінок лише із зображеннями – попередня перевірка page_cannot_have_text() пропускає розпакування для сторінок без шрифтів
  • Операнди оператора SmallVec – розміщені на стеку операнди усувають виділення в купі на кожен оператор
  • Міждокументний кеш шрифтів – кеш шрифтів LRU на рівні процесу, спільний для всіх екземплярів PdfDocument

v0.3.9 – 2026-02-24

20+ мікрооптимізацій – вилучення тексту на 40% швидше

Продуктивність

  • Виправлення конкатенації рядків за O(n^2) – попередньо виділений Vec<&str>, з’єднаний у кінці, замінює квадратичне накопичення String::push_str()
  • Парсер потоку вмісту лише із зображеннями – новий швидкий шлях для extract_images(), що пропускає оператори тексту та графіки (у 3-5 разів швидше)
  • Кеш шрифтів на основі відбитка – ідентифікація шрифту хешуванням encoding+widths+flags замість повного порівняння структури
  • Потоковий парсер – оператори потоку вмісту передаються потоком замість збирання в Vec
  • Швидкий вбудований парсер для BT/ET – пряме побайтове зіставлення для поширених текстових операторів
  • Таблиця пошуку байт-у-символ – 256-елементна таблиця пошуку замінює HashMap на гарячому шляху
  • Таблиця пошуку ширин – масив фіксованого розміру замінює HashMap для ширин гліфів
  • Зменшення переліку Operator – зі 112 до 40 байтів через боксинг великих варіантів (на 64% менше)
  • Бекенд zlib-rs – розпакування потоків на 15-25% швидше через порт zlib-ng

Виправлення помилок

  • Кодування шрифтів із вбудованими програмами – коректне розв’язання базового кодування згідно зі специфікацією PDF
  • Додатковий Unicode (U+10000+) – виправлено усічення додаткових кодових точок
  • Відображення лігатур StandardEncoding – коректне відображення fi, fl, ff, ffi, ffl через Adobe Glyph List
  • Нормалізація радикалів Кансі – повна таблиця відображення U+2F00-U+2FD5
  • Порядок символів RTL-тексту – арабська/іврит вилучаються в логічному порядку читання
  • Розділення багатоколонкового тексту – покращене виявлення колонок через аналіз проміжків

Можливості

  • extract_all_text() – новий зручний метод для вилучення тексту всіх сторінок
  • source_role для StructElem – зберігає вихідне ім’я ролі PDF до відображення ролей

v0.3.8 – 2026-02-20

Парсер лише тексту – сторінки з великою кількістю графіки у 10-30 разів швидші

Продуктивність

  • Парсер потоку вмісту лише тексту – новий швидкий шлях parse_content_stream_text_only() пропускає графічні оператори поза блоками BT/ET, використовуючи сканування на рівні байтів замість повного розбору nom
  • Графічний сканер на рівні байтів – сира індексна арифметика замінює цикл операндів на основі nom, обробляючи зі швидкістю, близькою до memcpy
  • Пропуск операторів кольору – 12 операторів кольору додано до списку пропуску на рівні байтів
  • Відкладена емісія q/cm/Q – операції стану графіки відкладаються до підтвердження тексту, усуваючи ~75% накладних витрат на повернення
  • Кеш FontInfo в обгортці Arc – уникає клонування повних структур FontInfo під час влучань у кеш
  • Побудова карти сторінок за O(n) – однопрохідний обхід замінює рекурсивний спуск
  • Кеш ім’я-у-посилання для XObject – усуває клонування словників за O(n^2) на сторінках із великою кількістю XObject

v0.3.7 – 2026-02-19

Якість вилучення тексту: з 95,7% до 99,6% чистоти

Перевірено – Корпус із 3 829 PDF

Метрика v0.3.6 v0.3.7 Зміна
Чистота 95,7% 99,6% 3 812 із 3 829 PDF
Брудні PDF 165 17 -90%

Додано – Парсер та декодери

  • Потоковий фільтр BrotliDecode (PDF 2.0) – новий декодер для потоків, стиснених Brotli
  • Вибір трейлера Xref – коректний вибір трейлера за наявності кількох трейлерів
  • Відновлення PDF без заголовка – пошук першого маркера об’єкта за відсутності заголовка %PDF-

Додано – Кодування шрифтів

  • Парсер кодування шрифтів CFF – розбирає програми шрифтів CFF/OpenType для кодування символів
  • Парсер кодування шрифтів Type1 – розбирає вбудовані програми шрифтів Type 1 для відображень гліфів
  • 80K+ відображень CID-у-Unicode – розширено Adobe-CNS1, Adobe-GB1, Adobe-Japan1, Adobe-Korea1
  • Декодування Shift-JIS/RKSJ – підтримка потоків CMap у японському кодуванні Shift-JIS
  • Поширення cmap Identity-H – поширює таблиці cmap TrueType від нащадків CIDFont

Виправлено – Конвеєр вилучення тексту

  • Скидання буфера Tf – скидає очікуваний текст під час зміни шрифту, щоб запобігти втраті тексту
  • Адаптивний поріг пробілу – замінює фіксований поріг 0,25em на інтервал на основі bbox
  • Дедуплікація фрагментів – дедуплікує перекривні фрагменти, відрендерені для ефектів напівжирного/тіні
  • Дедуплікація символів – видаляє дублікати символів у межах 2pt на одному рядку
  • Видалення перевірки оператора BT – виправляє некоректну валідацію, що пропускала чинні текстові блоки
  • Декодування ByteMode – коректне декодування 1-байтових, 2-байтових та змінної ширини кодів символів
  • Вилучення тексту анотацій – вилучає текст із Widget, FreeText та потоків вигляду

v0.3.6 – 2026-02-16

У 10 разів швидше – усунено два вузькі місця O(n)

Продуктивність

  • Масовий кеш дерева сторінок – під час першого доступу до сторінки все дерево сторінок обходиться один раз, і всі сторінки кешуються. Раніше get_page() обходив від кореня для кожної некешованої сторінки, що давало O(n) на сторінку та O(n^2) загалом для послідовного доступу. Тепер O(1) на сторінку після єдиного обходу за O(n). Тестовий файл veraPDF на 10 000 сторінок пройшов з 55 667мс до 332мс (у 168 разів швидше).

  • Кеш зміщень сканування об’єктів – коли об’єкти відсутні в таблиці xref, scan_for_object() раніше читав увесь PDF-файл для кожного відсутнього об’єкта. Теговані PDF із сотнями елементів дерева структури поза xref спричиняли сотні повних читань файлу. Тепер файл сканується один раз, і всі зміщення об’єктів кешуються. Тегований PDF на 10 сторінок пройшов з ~10с до 68мс (у 146 разів швидше). Академічний PDF на 154 сторінки з 571 шрифтом пройшов з ~18с до 405мс (у 44 рази швидше).

  • Однопрохідне вилучення текстуextract_spans() більше не виконує два проходи (класифікація типу документа, потім вилучення). Прохід класифікації повністю усунено; адаптивні пороги з урахуванням шрифту тепер дають рівні або кращі результати за один прохід.

  • Попереднє виділення Vec потоку вмістуparse_content_stream() попередньо виділяє ємність Vec операторів на основі розміру потоку, зменшуючи переалокації для великих потоків вмісту.

Перевірено – Корпус із 3 830 PDF (з v0.3.5 до v0.3.6)

Метрика v0.3.5 v0.3.6 Зміна
Частка проходження 99,8% 99,8% 3 823 із 3 830 дійсних PDF
Повільні (>5s) 2 0 Усунено
Середнє 23,3ms 2,1ms -91%
p50 0,6ms 0,6ms
p90 3,0ms 2,6ms -13%
p99 33,2ms 18,0ms -46%
Макс 68 722ms 625ms -99%
Сума (усі PDF) 89,1s 8,0s -91%

Текстовий вивід перевірено як побайтово ідентичний на 11 PDF (862 КБ вилученого тексту). 4 PDF показали покращену якість вилучення завдяки адаптивним інтервалам.


v0.3.5 – 2026-02-15

Продуктивність, стабільність на 3 830 PDF та відновлення після помилок

Продуктивність

  • Кешування шрифтів між сторінками – кеш шрифтів на рівні документа, індексований за ObjectRef, уникає повторного розбору спільних шрифтів на кожній сторінці
  • Кешування об’єктів сторінокget_page() кешує розв’язані об’єкти сторінок, усуваючи повторний обхід дерева сторінок під час багатосторінкового вилучення
  • Кешування дерева структури – результат дерева структури кешується після першого доступу, уникаючи надлишкового розбору під час кожного виклику extract_text()
  • Ранній вихід за оператором BT – вилучення тексту пропускає повний конвеєр для сторінок лише із зображеннями, що не містять операторів BT (Begin Text)
  • Більший буфер вводу-виводу для великих файлів – ємність BufReader для файлів понад 100 МБ збільшено з 8 КБ до 256 КБ
  • Видалено поріг реконструкції Xref – усунено евристику, що спричиняла повну реконструкцію файлу на дійсних portfolio-PDF із малою кількістю об’єктів

Перевірено – Корпус із 3 830 PDF

  • 100% проходження на 3 830 PDF із veraPDF (2 907), Mozilla pdf.js (897), SafeDocs (26)
  • Нуль тайм-аутів, нуль панік
  • p50 = 0,6ms, p90 = 3,0ms, p99 = 33ms

Додано – Шифрування

  • Автентифікація паролем власника – Алгоритм 7 для R<=4, Алгоритм 12 для R>=5
  • Перевірка користувацького пароля R>=5 із SASLprep – повна перевірка пароля AES-256 з використанням SHA-256
  • Публічний API автентифікації за паролемPdf::authenticate(password) та PdfDocument::authenticate(password)

Додано – Перевірка відповідності PDF/A

  • Перевірка метаданих XMP – перевіряє записи pdfaid:part та pdfaid:conformance
  • Перевірка колірного простору – сканує потоки вмісту сторінок на наявність залежних від пристрою операторів кольору без output intent
  • Перевірка AFRelationship – перевірка специфікації вбудованих файлів PDF/A-3

Додано – Перевірка відповідності PDF/X

  • Ідентифікація XMP PDF/X – перевіряє pdfxid:GTS_PDFXVersion
  • Перевірка відношень рамок сторінки – TrimBox усередині BleedBox усередині MediaBox
  • Виявлення прозорості ExtGState – перевірки SMask, CA/ca, BM
  • Виявлення залежного від пристрою кольору – позначає непідтримувані колірні простори
  • Перевірка профілю ICC – перевіряє потоки ICCBased-профілів

Додано – Рендеринг

  • Коректне за специфікацією обтинання – стан обтинання з областю в межах збереження/відновлення q/Q
  • Обчислення ширини просування гліфа – згідно з розділом 9.4.4 специфікації PDF
  • Рендеринг Form XObject – розбирає трансформацію /Matrix, використовує /Resources форми

Виправлено – Відновлення після помилок (28+ реальних PDF)

  • Відсутні об’єкти розв’язуються в Null згідно з розділом 7.3.10 специфікації PDF
  • Поблажливий розбір версії заголовка для незвичних рядків версії
  • Зіставлення нестандартних алгоритмів шифрування (комбінації V=1, R=3)
  • Resources, що не є словником, трактуються як порожні замість генерації помилки
  • Null-вузли в дереві сторінок витончено пропускаються
  • Пошкоджені потоки вмісту повертають порожній вміст замість помилок
  • Покращене сканування дерева сторінок із евристикою /Resources+/Parent

Виправлено – Захист від DoS

  • Кількість сторінок перевіряється щодо ліміту Додатка C.2 специфікації PDF (8 388 607)

Виправлено – Вилучення зображень

  • Вилучення зображень із потоку вмісту через оператори Do
  • Вкладені зображення Form XObject із виявленням циклів
  • Вбудовані зображення (послідовності BI…ID…EI)
  • Трансформації CTM для позиціонування зображень
  • Розв’язання непрямих посилань ColorSpace

Виправлено – Надійність парсера

  • Багаторядкові заголовки об’єктів (формат 1 0\nobj, що використовується PDF, згенерованими Google)
  • Пошук заголовка розширено з 1024 до 8192 байтів
  • Поблажливий розбір версії для некоректних заголовків

Виправлено – Надійність доступу до сторінок

  • Сторінки без /Contents повертають порожній вміст
  • Виявлення циклічного дерева сторінок запобігає переповненню стека
  • Null-посилання на потоки обробляються витончено
  • Сторінки без запису /Type знаходяться за ключами /MediaBox або /Contents

Виправлено – Надійність шифрування

  • Дешифрування AES із замалими ключами повертає помилку замість паніки
  • Розбір потоку Xref посилено проти некоректних записів
  • Непрямі посилання /Encrypt розв’язуються до розбору

Виправлено – Оброблення потоку вмісту

  • Запасний варіант Dictionary-as-Stream для голих словників
  • Скорочені імена фільтрів (AHx, A85, LZW, Fl, RL, CCF, DCT)
  • Ліміт операторів потоку вмісту (за замовчуванням 1 000 000)

Виправлено – Якість коду

  • Непрямі посилання на об’єкти дерева структури розв’язуються під час розбору
  • Усунення неоднозначності токенів R/RG у лексері
  • Обрізання пробілів потоку більше не видаляє байти NUL або пробіли з бінарних даних

Тести

  • 8 раніше ігнорованих тестів розігноровано та виправлено

Видалено

  • Порожня заглушка PdfImage (вилучення використовує ImageInfo)
  • Закоментований тестовий блок DocumentType::detect()

v0.3.4 – 2026-02-12

Надійність розбору, вилучення символів та шляхи XObject

Зміни, що порушують сумісність

  • Сигнатуру parse_header() змінено з (u8, u8) на (u8, u8, u64) для включення зміщення байта

Виправлено – Надійність розбору PDF (Issue #41)

  • PDF із бінарними префіксами або заголовками BOM тепер відкриваються успішно
  • Пошук заголовка сканує перші 1024 байти на маркер %PDF-
  • Підтримує UTF-8 BOM, заголовки електронної пошти та інші провідні бінарні дані
  • Поблажливий режим обробляє реальні некоректні PDF; суворий режим для тестування відповідності

Додано – Вилучення тексту на рівні символів (Issue #39)

  • extract_chars() повертає Vec<TextChar> із позиціонуванням посимвольно
  • Включає матрицю трансформації, кут повороту, ширину просування
  • Відсортовано в порядку читання з дедуплікацією перекривних символів
  • На 30-50% швидше за вилучення фрагментів для випадків лише із символами
  • Доступно в API як Rust, так і Python

Додано – Вилучення шляхів XObject (Issue #40)

  • extract_paths() рекурсивно обробляє Form XObject через оператор Do
  • Трансформації координат через /Matrix застосовуються коректно
  • Стан графіки належно ізолюється (збереження/відновлення)
  • Виявлення дублікатів XObject запобігає нескінченним циклам
  • Вкладені XObject підтримуються

Змінено

  • Бібліотеку парсера nom оновлено з 7.1 до 8.0

v0.3.3 – 2026-02-11

Підтримка CJK, покращення дерева структури та основи відповідності

Містить усі зміни з v0.2.5 та v0.2.6 як консолідований реліз.

Основні моменти

  • Підтримка TagSuspect/MarkInfo – розбирає словник MarkInfo з каталогу документа
  • Структурний елемент Word Break /WB для тексту CJK
  • Підтримка наперед визначених CMap для Adobe-GB1 (спрощена китайська), Adobe-Japan1 (японська), Adobe-CNS1 (традиційна китайська), Adobe-Korea1 (корейська)
  • Підтримка розгортання скорочень /E
  • Розбір масиву Type 0 /W для ширин гліфів CIDFont
  • Виправлення оброблення м’якого переносу (U+00AD)
  • Покращена фільтрація артефактів із підтримкою підтипів
  • Вбудовування зображень у вивід HTML та Markdown (data-URI у base64)
  • Експорт файлів зображень із embed_images=false та image_output_dir
  • Методи PdfImage::to_base64_data_uri() та to_png_bytes()

v0.3.2 – 2026-02-01

Редагування, шифрування та безпека документів

Додано – Редагування PDF

  • DocumentEditor для модифікації наявних PDF
  • Повна підтримка анотацій (текстова розмітка, фігури, штампи, чорнило, вкладення файлів, редагування)
  • Створення інтерактивних полів форм (текст, checkbox, radio, випадний список, список, кнопка)
  • Сплощення форм
  • Анотації-посилання (URL, внутрішня навігація сторінками)
  • Конструктор змісту/закладок
  • Шари PDF (Optional Content Groups)

Додано – Шифрування

  • Шифрування під час запису (AES-256, AES-128, RC4-128, RC4-40)
  • Контроль дозволів (друк, копіювання, зміна, анотування)
  • Конструктор EncryptionConfig із EncryptionAlgorithm та Permissions
  • Основа для цифрового підпису

v0.3.1 – 2026-01-14

Поля форм, мультимедіа, інструменти створення та пошук

Додано – Створення PDF

  • Pdf::from_markdown(), Pdf::from_html(), Pdf::from_text(), Pdf::from_image()
  • Плавний патерн PdfBuilder для конфігурації метаданих та розкладки
  • DocumentBuilder для програмної генерації PDF
  • Рендеринг таблиць із TableRenderer
  • Графічний API: кольори, градієнти, патерни, режими накладання, прозорість
  • Шаблони сторінок із колонтитулами, нумерацією сторінок, водяними знаками
  • Генерація штрихкодів (QR, Code128, EAN-13, UPC-A, Code39, ITF)

Додано – Пошук

  • Пошук тексту з регулярними виразами, з урахуванням/без урахування регістру, за цілими словами, за діапазонами сторінок
  • Типи SearchOptions та SearchResult
  • Відстеження позиції зі сторінкою/координатами

Додано – Покриття полів форм (95%)

  • Ієрархічне створення полів (батьківські/дочірні структури з крапковими іменами)
  • Зміна властивостей полів (лише читання, обов’язковість, прямокутник, спливна підказка, макс. довжина, вирівнювання, значення за замовчуванням)
  • Експорт FDF/XFDF для обміну даними форм

Додано – Мультимедійні анотації

  • MovieAnnotation, SoundAnnotation, ScreenAnnotation, RichMediaAnnotation
  • ThreeDAnnotation із підтримкою форматів U3D та PRC

Додано – Підтримка форм XFA

  • XfaExtractor, XfaParser, XfaConverter (конвертація XFA в AcroForm)

Змінено – Прив’язки Python

  • Справжня підтримка Python 3.8-3.14 через abi3-py38
  • Сучасний інструментарій: інтеграція uv, pdm, ruff

v0.3.0 – 2026-01-10

Основа вилучення – уніфікований API та базові можливості

Додано – Уніфікований API Pdf

  • Pdf::open() для читання наявних PDF
  • DOM-подібна навігація сторінками з pdf.page(0)
  • Низькорівневий дескриптор PdfDocument для просунутих випадків

Додано – Вилучення тексту

  • extract_text() – простий текст усієї сторінки
  • extract_spans() – стилізовані текстові прогони з метаданими шрифту
  • Порядок читання на основі дерева структури для тегованих PDF
  • Інтелектуальне виявлення розривів рядків та пробілів для нетегованих PDF

Додано – Вилучення зображень

  • extract_images() – вилучає всі зображення зі сторінки
  • Виявлення формату (JPEG, PNG, TIFF, JBIG2, CCITT)
  • Оброблення колірних просторів (DeviceRGB, DeviceCMYK, DeviceGray, ICCBased)

Додано – Вилучення метаданих

  • Словник інформації про документ (заголовок, автор, тема, ключові слова)
  • Читання/запис метаданих XMP
  • Інформація про сторінку (розміри, поворот, рамки media/crop/trim)

Додано – Вилучення форм

  • extract_form_fields() для перелічення полів AcroForm
  • Типи полів: текст, кнопка, вибір та підпис

Додано – Конвертація

  • to_markdown() – конвертація в Markdown на рівні сторінки
  • to_html() – конвертація в HTML на рівні сторінки
  • to_plain_text() – налаштовуваний вивід простого тексту

Додано – Відповідність

  • Перевірка PDF/A (ISO 19005, рівні від 1a до 3b)
  • Перевірка PDF/X (ISO 15930, рівні від X-1a до X-6p)
  • Перевірка PDF/UA (ISO 14289, рівні UA-1 та UA-2)

Додано – Рендеринг (потребує фічі rendering)

  • Рендеринг сторінок у PNG/JPEG через tiny-skia
  • Налаштовувані DPI та масштаб

Додано – Прив’язки Python

  • Клас PdfDocument із повним API вилучення
  • Клас Pdf з API створення та високорівневим API
  • На основі PyO3, опубліковано на PyPI як pdf_oxide

v0.2.4 – 2026-01-09

  • Виправлення трансформації CTM для позиціонування тексту
  • Розбір /Alt та /Pg дерева структури
  • FormulaRenderer для зображень формул

v0.2.3 – 2026-01-07

  • Скидання матриці BT/ET згідно зі специфікацією PDF
  • Виявлення геометричних інтервалів у конвертері Markdown
  • apply_intelligent_text_processing() для лігатур та перенесення слів

v0.2.2 – 2025-12-15

  • Оптимізація ключових слів для виявлюваності

v0.2.1 – 2025-12-15

  • Покращення декодування зашифрованих потоків

v0.1.4 – 2025-12-12

  • Виправлення декодування зашифрованих потоків

v0.1.0 – 2025-11-06

  • Початковий реліз
  • Вилучення тексту з PDF із відповідним специфікації відображенням Unicode
  • Інтелектуальне виявлення порядку читання
  • Прив’язки Python через PyO3
  • Підтримка зашифрованих PDF
  • Вилучення полів форм
  • Вилучення зображень