Skip to content

변경 이력

PDF Oxide의 모든 주목할 만한 변경 사항을 여기에 기록합니다.


v0.3.38 – 2026-04-22

DocumentBuilder가 모든 바인딩에 도착; 쓰기 경로의 AES-256; 서명 검증; 다중 타깃 WASM; Go purego 백엔드

모든 바인딩에 걸친 쓰기 측 API 동등성 (#384)

  • **DocumentBuilder + FluentPageBuilder + EmbeddedFont**가 이제 Rust와 함께 Python, Node/TypeScript, C#, Go, WASM에서도 제공됩니다. 임베디드 폰트를 통해 CJK / 키릴 / 그리스 문자를 완전히 지원하는 다중 페이지 구성이 가능합니다. #382를 언어 전반에 걸쳐 종결합니다.
  • 모든 바인딩의 주석 메서드 15종: link_url / link_page / link_named, highlight, underline, strikeout, squiggly, 스티키 노트, 스탬프(표준 14종 + 커스텀), 자유 텍스트, watermark(커스텀 / DRAFT / CONFIDENTIAL).
  • 모든 바인딩의 AcroForm 위젯 타입 5종: text_field, checkbox, combo_box, radio_group, push_button.
  • 모든 바인딩의 그래픽 프리미티브: rect, filled_rect, line.
  • HTML+CSS 파이프라인 — 모든 바인딩에서 다중 폰트 캐스케이드를 위한 Pdf.from_html_css(...)from_html_css_with_fonts(...).

쓰기 경로의 AES-256 암호화 (#386)

  • 모든 바인딩의 DocumentBuilder에 있는 save_encrypted(path, user_pw, owner_pw) / to_bytes_encrypted(user_pw, owner_pw).
  • 커스텀 알고리즘 + 권한을 위한 Rust의 save_with_encryption.

실제 폰트 서브셋화 (#385 / FONT-3b)

  • CJK 글꼴이 이제 전체 글꼴이 아닌 서브셋으로 임베드됩니다. 약 17MB CJK 폰트로 구성된 5자 PDF는 일반적으로 100KB 미만으로 출력됩니다. 콘텐츠 스트림, /W 너비, ToUnicode CMap이 서브셋 GID 공간에 다시 매핑되며, extract_text 왕복은 변하지 않습니다.
  • 내부 라이터 API 변경: EmbeddedFont::encode_string / encode_shaped_runVec<u16>을 반환하고, build_embedded_font_objects는 호출 측이 ContentStreamBuilder::build_with_remappers에 전달하는 GlyphRemapper를 반환합니다. 고수준 API에는 변경이 없습니다.

디지털 서명 검증 (#208, 검증 부분)

  • 모든 바인딩Signature.verify()Signature.verify_detached(pdf_bytes)(및 바인딩 네이티브 등가물). RFC 5652 §5.4 서명자 속성 + §11.2 messageDigest 검사.
  • SHA-1 / SHA-256 / SHA-384 / SHA-512 상의 RSA-PKCS#1 v1.5Valid / Invalid를 반환합니다. RSA-PSSECDSAUnknown / UnsupportedFeatureException으로 나타나며, 호출 측은 여전히 인증서를 읽고 자체 검사를 실행할 수 있습니다.
  • Certificatex509-parser를 통한 DER 검사(subject, issuer, 일련번호, 유효성, is_valid) — 모든 바인딩.
  • Signature — 열거 + 검사 + .get_certificate()모든 바인딩.
  • Timestamp — RFC 3161 TSTInfo 파싱(시각, 일련번호, 정책, TSA 이름, 해시 알고리즘, 메시지 임프린트) — 모든 바인딩.
  • TsaClienttsa-client Cargo 기능 뒤에서 nonce와 HTTP Basic 인증을 동반한 RFC 3161 HTTP POST — WASM을 제외한 모든 바인딩. WASM에서는 의도적으로 연결하지 않았습니다(ureq가 wasm과 비호환).
  • DocumentEditor::set_producer / set_creation_date 메타데이터 라이터.
  • render_page_regionrender_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를 통한 두 번째 백엔드가 런타임에 libpdf_oxide.{so,dylib,dll}dlopen합니다. 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 플래그가 staticlib 대신 cdylib을 가져오고, 익스포트할 CGO_ENABLED=0 + PDF_OXIDE_LIB_PATH=…를 출력합니다.
  • 설치 디렉터리가 os.UserCacheDir()로 이동했습니다 — ~/.cache/pdf_oxide(Linux), ~/Library/Caches/pdf_oxide(macOS), %LocalAppData%\pdf_oxide(Windows). Go 자체의 GOCACHE 관례와 일치합니다.
  • 릴리스 자산에는 이제 기존 staticlib 아카이브와 함께 모든 Tier-1 플랫폼용 pdf_oxide-go-ffi-shared-<platform>.tar.gz가 포함됩니다.

버그 수정

  • #395RenderPage가 페이지에 파싱할 수 없는 서명 필드 메타데이터가 있지만 대화형 서명 위젯이 없을 때 더 이상 SignatureException을 발생시키지 않습니다. @gevorgter가 보고했습니다.

감사의 말


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는 기존 테스트 인프라에 참여합니다.

이번에 출시된 내용

  • 폰트 하위 시스템Type 0 / CIDFontType2 / Identity-H / ToUnicode 방출을 동반한 TTF/OTF 임베딩. 라틴, 키릴, 그리스, 히브리, 아랍 문자가 extract_text를 통해 왕복합니다. fontdb를 통한 시스템 폰트 검색, rustybuzz를 통한 텍스트 셰이핑.
  • 직접 작성한 CSS 엔진(약 6,500줄, MPL 의존성 제로) – 토크나이저, 파서, L3+L4 셀렉터(:is/:where/:not/:has), 매처, 캐스케이드, calc() / min() / max() / clamp(), 순환 감지를 동반한 var(), 타입이 지정된 프로퍼티 값, at 규칙(@media print, :first/:left/:right/:blank를 동반한 @page, @font-face, @import, @supports), 카운터, 의사 요소 콘텐츠.
  • HTML – HTML5 토크나이저, 평면 arena DOM, 스타일시트 추출(<style>, <link rel="stylesheet">, 인라인 style=""), 리소스 추출(<img> + srcset, <picture>/<source>, <a href>).
  • 레이아웃 – Taffy 기반 block / flex / grid, UAX #14 줄바꿈, 마진 병합, 다중 컬럼, 표(auto + fixed).
  • 페인트 – 텍스트 + 테두리, rustybuzz를 통한 RTL, <a href>/Link 주석, <img> data-URI → /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)가 이제 fontdbSource::SharedFile을 통해 해석됩니다.
  • 따옴표 없는 다중 단어 font-family가 올바르게 토큰화됩니다.
  • Pdf::from_html_css 팩토리의 메모리 누수를 해결했습니다(네 곳의 Box::leak을 스코프 지정 로컬로 교체).
  • PNG 알파 / 소프트 마스크(SMask)가 이제 렌더링됩니다.
  • 셰이핑된 텍스트가 extract_text를 통해 왕복합니다(encode_shaped_run이 글리프 클러스터를 소스 코드 포인트로 다시 매핑).
  • PdfWriter::finish가 등록 순서대로 폰트를 임베드합니다(이전에는 HashMap 무작위 순서).
  • 임베디드 폰트 이름 충돌을 단조 증가하는 EFn 리소스 이름으로 격리했습니다.
  • fontdb Mutex가 폰트 바이트의 fs::read 동안 더 이상 보유되지 않습니다.

범위 외

CSS 필터, 3D 변환, 애니메이션, HTML 내 SVG(실용적인 Rust SVG 크레이트는 모두 MPL), MathML, hyphens: auto, shape-outside, JavaScript, 전체 행렬 transform(scale/rotate), 그라디언트, box-shadow.

라이선스 감사

cargo deny check licenses가 MPL 전이 의존성 제로로 통과합니다. Mozilla의 CSS 스택(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 → MCRLI → 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 재정렬은 기본적으로 꺼져 있습니다. 이전 초안은 모든 RTL 줄에 대해 unicode-bidi의 시각→논리 재정렬을 실행했는데, 이는 이전에 올바르던 논리 순서 PDF를 손상시켰습니다(히브리어 이름 בנימין이 뒤집혔습니다). 재정렬 헬퍼는 입력이 시각 순서인 호출 측을 위해 text::bidi::reorder_visual_to_logical에 남아 있습니다.

Markdown 출력

  • 인라인 이미지 base64 data URI를 200KB로 제한. 고해상도 다이어그램이 있는 PDF는 이전에 Markdown 출력을 10~20배로 부풀렸습니다(1.9MB 논문이 11.3MB Markdown을 생성). 한도를 초과하는 이미지는 원본 크기를 담은 HTML 주석 플레이스홀더를 방출합니다. 파일 기반 이미지 출력(image_output_dir)은 영향을 받지 않습니다.

실증적 영향

학술, 정부, 폼, 신문, 기술, 학위논문, IRS, pdfium, pdfjs, safedocs, 저속 코퍼스 하위 집합에 걸친 369개 PDF 회귀에 대해 v0.3.35 대비 검증했습니다:

  • 0개의 치명적 회귀.
  • pdfium 및 pdftotext 대비 Token Jaccard: 중앙값 1.000, 106개 픽스처 중 95개에서 ≥0.95.
  • pymupdf4llm 대비 Token Jaccard: 중앙값 0.978, 106개 픽스처 중 65개에서 ≥0.95.
  • 코퍼스 전체에서 pymupdf4llm보다 약 2배 많은 제목을 방출.

감사의 말

  • @Goldziher (kreuzberg) – 727개 문서 벤치마크 방법론과 9개의 재현용 PDF와 함께 #377을 제출. 그 프레이밍(“TF1이 ±3 % 이내라 텍스트 콘텐츠는 괜찮고, 구조가 문제다”)이 조사 전체를 다룰 수 있게 만들었습니다.

v0.3.35 – 2026-04-19

텍스트 추출에서 좁은 글리프 더블릿 보존

텍스트 추출 정확성

  • 작은 폰트 크기에서 인접한 좁은 글리프 더블릿이 더 이상 붕괴되지 않습니다 (#378, PR #379). TextExtractor::deduplicate_overlapping_charsdeduplicate_overlapping_spans는 하드코딩된 2 pt 절대 임계값을 사용했습니다. 작은 크기의 압축 폰트에서 좁은 글리프(l, r, I, i)의 경우 글리프당 전진 너비가 ≤ 2 pt로 떨어지며(Helvetica l은 9 pt에서 약 2.5 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을 보고하고, 전진 스케일 임계값과 매개변수화된 회귀 매트릭스(좁은 글리프 4종 × 본문 크기 3종)를 갖춘 PR #379를 작성.

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.js 동등성extractWords, extractTextLines, extractTables, extractPaths, getEmbeddedImages, ocrExtractText가 TypeScript 계층에 연결되었습니다(이전에는 네이티브 전용).
  • ExtractedTableTable – Rust 코어 이름 변경; 불필요한 Extracted 접두사가 제거되었습니다. FFI 대상 타입이 업데이트되었습니다.

텍스트 추출 품질

  • 혼합 레이아웃 페이지에서의 XY-cut 컬럼 감지 (#319)is_multi_column_page 가드가 컬럼당 최소 15개 스팬을 요구하도록 강화되었습니다. 컬럼 순으로 정렬된 스팬은 extract_text의 행 인식 정렬로 다시 정렬되지 않습니다.

감사의 말

  • 페이지 우선 API(#371)를 제안한 @SeanPedersen. 구조화된 표 추출(#289)을 요청한 @pdenapo.

v0.3.33 – 2026-04-16

텍스트 추출, 이미지 정확성, 메모리 안전성 수정

버그 수정

  • ToUnicode CMap 누락 (#363) – 서브셋 Type0 폰트는 이제 ToUnicode CMap에 CID가 누락된 경우 Identity-H 암호문(예: %B+$%8A//$2*%01*1%6APP)으로 떨어지는 대신 U+FFFD를 방출합니다.
  • 단어 내 TJ 커닝이 더 이상 단어를 분할하지 않습니다 (#365) – 단일 단어 내 0.10~0.20 em 글자 쌍 커닝([(diffe) -150 (rent)])이 더 이상 공백 삽입을 유발하지 않습니다.
  • 키릴 UTF-8 깨짐 복구 (#317) – 라틴 전용 인코딩과 원시 UTF-8 바이트 시퀀스를 가진 폰트가 이제 올바르게 디코딩됩니다.
  • FlateDecode 부분 복구가 쓰레기 출력을 거부 (#364) – 콘텐츠 스트림이 압축 해제 도중 실패하는 MS Reporting Services PDF가 더 이상 128바이트의 의사 난수 데이터를 반환하지 않습니다.
  • Indexed + ICCBased 팔레트 (#373) – Indexed 기본 배열 내의 해석되지 않은 ICC 스트림 참조가 더 이상 /N을 CMYK의 4 대신 3으로 기본 설정하지 않아 대각선 줄무늬 아티팩트를 수정합니다. @Charltsing이 보고했습니다.
  • Lab 기반 Indexed 팔레트 → sRGB (#337) – CIE L*a*b* 팔레트 바이트가 이제 원시 RGB로 재해석되는 대신 Lab→XYZ→sRGB로 변환됩니다.

메모리 및 성능

  • 모든 내부 캐시에 상한 설정 (PR #369, #354) – 객체 캐시(64MB), 폰트 캐시(256~512개 항목), XObject 스팬/이미지 캐시(1024개 항목), 전역 CMap 캐시(1024개 항목)가 이제 FIFO 제거를 사용합니다.
  • 차트가 많은 PDF에서의 경로 추출 OOM 수정 (#369) – CTM 인식 XObject 중복 제거를 추가하여 동일 위치의 동일 XObject는 중복 제거되지만 다른 위치의 동일 XObject는 별도로 처리됩니다.
  • Mutex 오염 복원력MutexExt::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개 무시입니다.

감사의 말

  • Indexed + CMYK 이미지 추출 버그 보고(#373)를 해준 @Charltsing.
  • 다중 페이지 추출 중 무한 메모리 증가(#354)를 프로파일링해준 @ddxtanx.
  • PR #369(상한 있는 FIFO 캐시, CTM 인식 XObject 중복 제거, MutexExt 오염 복구 트레이트, Python 바인딩 강화)를 해준 @andrewjradcliffe.

v0.3.32 – 2026-04-15

Windows-x64 Go FFI tarball을 위한 릴리스 파이프라인 수정

릴리스 파이프라인

  • v0.3.31 릴리스를 실패시키던 x86_64-pc-windows-gnu 네이티브 라이브러리 빌드 수정scripts/shrink-staticlib.sh는 모든 아카이브 멤버에 대해 objcopy --strip-debug를 실행했지만, MinGW 크로스 컴파일 툴체인은 DWARF 섹션 포함하는 분리 디버그 .dwo 멤버를 방출합니다. 스트립 후 멤버에는 섹션이 남지 않아 objcopy가 전체 아카이브를 중단했습니다. 수정: objcopy를 호출하기 전에 ar d.dwo 아카이브 멤버를 제거합니다. Rust, Python, Node, WASM, C# 아티팩트에는 기능적 변경이 없으며, 이 릴리스는 오직 Windows-x64 Go 설치 경로를 풀기 위해서만 존재합니다.

v0.3.31 – 2026-04-13

버그 수정, Go 빌드 변경, 릴리스 인프라 개선

버그 수정

  • Xref 복구 – 잘못 플래그된 빈 페이지 객체와 몇 바이트 어긋난 xref 오프셋 항목의 복구를 수정했습니다.

호환성 깨짐 변경

  • Go 네이티브 라이브러리 – 네이티브 라이브러리가 더 이상 go/lib/에 커밋되지 않습니다. 사용자는 머신당 한 번 go run github.com/yfedoseev/pdf_oxide/go/cmd/install@latest를 실행해야 합니다.

릴리스 인프라

  • Rust staticlib을 63% 축소(71MB에서 26MB), npm .node 애드온 스트립, npm에서 소스맵 제거, 크레이트 sdist 유출 수정, NuGet snupkg 패키징 강화.

v0.3.27 – 2026-04-12

Go staticlib, Node.js 네이티브 바인딩, C# NativeAOT, OCR FFI, 주요 버그 수정

새 기능

  • Go staticlib 마이그레이션 – 자체 완결형 Go 바이너리를 위해 cdylib에서 staticlib으로 전환.
  • Node.js 네이티브 바인딩 – napi-rs 스타일 배포를 통한 사전 빌드된 플랫폼 하위 패키지.
  • C# LibraryImport – NativeAOT 호환성을 위해 881개의 P/Invoke 선언을 DllImport에서 LibraryImport로 마이그레이션.
  • 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 바인딩 – 전체 API 커버리지로 npm에 게시.
  • Go 바인딩 – 완전한 API 표면을 갖춘 네이티브 Go 패키지.
  • C# 바인딩 – NuGet에 게시된 .NET 패키지.
  • C FFI 계층 – 공유 pdf_oxide.h 헤더를 동반한 270개 이상의 extern "C" 함수.
  • 전역 로그 레벨 제어 – 모든 바인딩에서 구성 가능.

v0.3.23 – 2026-04-09

중요 안정성 수정

버그 수정

  • 회전된 dvips PDF의 퇴화된 CTM이 있는 페이지에서의 SIGABRT 수정.
  • 저장 시 이미지/XObject가 제거되는 문제 수정.
  • 일반 폰트가 없는 시스템에서의 깨진 렌더링 수정.
  • 폼 필드 페이지 인덱스가 항상 0을 반환하는 문제 수정.

v0.3.22 – 2026-04-08

스레드 안전 문서, 비동기 Python, 프리스레드 Python, 단어/줄 분할 튜닝

새 기능

  • 스레드 안전 PdfDocument – Mutex를 통한 Send + Sync(RefCell 대체).
  • 비동기 Python APIAsyncPdfDocument, AsyncPdf, AsyncOfficeConverter.
  • 프리스레드 Pythoncp314t(no-GIL 빌드) 지원.
  • 분할 임계값 – 단어/줄 감지 튜닝을 위한 word_gap_threshold, line_gap_threshold, profile.

버그 수정

  • CLI split/merge 빈 페이지, 잘못된 형식의 이미지에 대한 렌더링 건너뛰기, 구조 트리 순환 SIGSEGV, 표 전략 게이팅.

성능

  • 구조 트리와 압축 해제된 콘텐츠 스트림 캐싱, O(1) MCID 조회, 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 로그는 pyo3-log를 통해 logging 모듈로 흐릅니다.

버그 수정

  • 암호화된 PDF의 명확한 오류 메시지, ObjStm/XRef 스트림 복호화, 스트림 파서의 후행 개행 처리.

v0.3.19 – 2026-04-02

단일 호출 페이지 추출, 컬럼 인식 읽기 순서, 문자별 경계 상자

새 기능

  • extract_page_text() – 간소화된 페이지 추출을 위한 단일 호출 DTO.
  • 컬럼 인식 읽기 순서 – 다중 컬럼 문서를 위한 XY-Cut 공간 분할.
  • 문자별 경계 상자 – 정밀한 문자 위치 지정을 위해 폰트 메트릭에서 도출.
  • is_monospace 플래그TextSpanTextChar에서 사용 가능.
  • Pdf::from_bytes() – 모든 바인딩에 걸친 새 생성자.
  • 경로 연산 – Python 바인딩의 extract_paths().

버그 수정

  • 멀티바이트 디버그 로그의 UTF-8 패닉, Markdown 간격, Form XObject /Matrix, 회전 텍스트 행렬, 사전 스캔 CTM 손실, 중복 제거, Tm 스케일 텍스트 누락, Markdown 단어 병합, CLI 병합 빈 문서.

호환성 깨짐 변경

  • WASM – JSON 필드 이름이 이제 camelCase를 사용합니다.

v0.3.18 – 2026-04-01

렌더링 엔진 정비, 새로운 Python 및 WASM API, 배터리 포함 Python

새 기능

  • 렌더링 엔진 정비 – 올바른 문자 간격, 임베디드 폰트 지원, 표준 폰트 메트릭, 채우기-및-스트로크, 클립 경로, 그라디언트 셰이딩, 알파 투명도, 스텐실 이미지 마스크, 페이지 회전, 별색 색 공간.
  • 새로운 Python APIvalidate_pdf_a, validate_pdf_ua, validate_pdf_x, extract_pages, delete_page, move_page, flatten_to_images, 비밀번호 생성자, merge.
  • 새로운 WASM APIvalidatePdfA, deletePage, extractPages, save, 비밀번호 생성자, merge.
  • 배터리 포함 Python – 렌더링, 병렬, 서명, Office 변환이 기본적으로 활성화.

버그 수정

  • 퇴화된 CTM 중단, FlateDecode flate 폭탄 보호(256MB 상한), 클리핑 스택 동기화.

v0.3.17 – 2026-03-08

표 감지 개선, 태그된 PDF 최적화

개선

  • 개선된 표 감지 – 2개 이상의 컬럼을 요구하여 오탐을 줄임.
  • 최적화된 태그된 PDF 추출 파이프라인.

버그 수정

  • 재귀적 Form XObject 처리에서의 RefCell already borrowed 패닉 수정.

v0.3.16 – 2026-03-08

스마트 하이브리드 표 추출, Python 타입 스텁, pathlib 지원

새 기능

  • 스마트 하이브리드 표 추출 – Union-Find 클러스터링, 시각적 선 분석, 시각적 스팬/헤더.
  • 전문 ASCII 표 – 터미널 출력을 위한 다중 줄 줄바꿈.
  • Python 타입 스텁 – mypy stubgen을 통해 자동 생성.
  • Python PdfDocumentpathlib.Path를 받고 컨텍스트 관리자를 지원.

버그 수정

  • 중첩 Form XObject의 세그폴트, Python 좌표 스케일링, ASCII 표 UTF-8 패닉.

v0.3.15 – 2026-03-06

머리글/바닥글 관리, 페이지 템플릿, 범위 지정 추출

새 기능

  • 머리글/바닥글 관리 API – PDF 아티팩트 추가, 제거, 편집.
  • 페이지 템플릿 – 페이지 번호 매기기, 날짜 등을 위한 동적 플레이스홀더.
  • 범위 지정 추출 – 필터링된 출력을 위해 erase_regions를 존중.
  • PdfDocument.from_bytes() – 새 Python 생성자.

버그 수정

  • 다중 컬럼 읽기 순서(XY-Cut), 폰트 식별 충돌, Lines 표 전략 오탐.

v0.3.14 – 2026-03-03

고수준 렌더링, 단어/줄 추출, 기하학적 프리미티브, 하이브리드 표

새 기능

  • 고수준 렌더링 API – Rust, Python, WASM의 Pdf::render_page.
  • 단어 및 줄 추출 – 모든 바인딩에 걸친 extract_words, extract_text_lines.
  • 기하학적 프리미티브 추출extract_rects, extract_lines.
  • 하이브리드 표 감지 – 벡터 선 힌트가 표 경계 감지를 개선.
  • API 조화 – 유창한 .within(page, rect) 패턴.
  • CLI 명령--area 필터링을 동반한 renderpaths 명령.

버그 수정

  • OCR 기능 게이팅 발견, XObject 스팬 캐시 오염, V=4 암호 필터, 암호화된 CIDToGIDMap.

v0.3.13 – 2026-03-02

CJK 텍스트 추출 수정

버그 수정

  • CJK/Type0 폰트의 extract_chars에서의 멀티바이트 디코딩, 개선된 문자 위치 정확도, 문자 간격 스케일링.

v0.3.12 – 2026-03-01

텍스트 추출 품질, Markdown 변환, 성능

개선

  • 텍스트 추출 품질 – CID 폰트 너비 계산, 폰트 변경 시 단어 경계 감지, 비표준 CID 매핑 폴백, RTL 텍스트 방향성.
  • Markdown 변환 – XY-Cut 재귀 공간 분할, 제목 감지, 리스트 재구성.

성능

  • 제로 카피 페이지 트리 순회, 구조 트리 캐싱, BT 연산자 조기 종료, 더 큰 I/O 버퍼, xref 재구성 임계값 제거.

v0.3.10 – 2026-02-26

병렬 추출, WASM/JavaScript 지원, 배치 처리, 텍스트 품질 개선

새 기능

  • WASM/JavaScript 지원 – wasm-bindgen을 통한 WebAssembly 바인딩. 완전한 텍스트 추출, PDF 생성, 편집, 폼 필드, 검색을 브라우저와 Node.js에서 사용 가능. pdf-oxide-wasm으로 npm에 게시.

  • 병렬 페이지 추출 – rayon 기반 멀티스레드 추출을 동반한 새로운 parallel 기능 플래그. ParallelExtractor가 페이지를 워커 스레드에 분배합니다. 전역 폰트 캐시가 폰트를 한 번만 파싱하도록 보장합니다.

  • 배치 처리 API – 진행 콜백과 오류 수집을 동반한 다중 PDF 워크플로를 위한 새로운 BatchProcessor. 순차 및 병렬 처리를 모두 지원합니다.

  • OCR 하이브리드 감지 – 지능형 OCR 폴백을 위한 다중 휴리스틱 감지를 동반한 새로운 PageType 열거형(NativeText, ScannedPage, HybridPage).

  • 완전한 WASM/Python API 동등성 – WASM 및 Python 바인딩에 걸친 10개의 새 메서드 그룹: 폼 필드 get/set, 이미지 바이트 추출, 이미지에서 PDF, 폼 평면화, PDF 병합, 파일 임베딩, 페이지 레이블, XMP 메타데이터.

버그 수정

  • 순환 XObject 세그폴트 – 이미지 추출 중 순환 Form XObject 참조로 인한 세그폴트 수정
  • XRef /Prev 체인 오버플로 – XRef /Prev 체인 파싱을 재귀에서 순환 감지를 동반한 반복으로 재작성
  • 깨진 합자 텍스트repair_ligatures() 후처리기가 LaTeX PDF의 손상된 텍스트를 수정
  • 텍스트 추출 품질 – 주석 텍스트 추출, 리더 점 정규화, Priority 3 CMap 지원
  • 표 추출 – 병합된 셀, 다중 줄 셀 콘텐츠, 폰트 기반 헤더 감지
  • 폼 필드 영속성 – 증분 저장이 이제 폼 필드 값 변경을 올바르게 영속화

성능

  • 이미지 전용 페이지 건너뛰기page_cannot_have_text() 사전 검사가 폰트가 없는 페이지의 압축 해제를 건너뜀
  • SmallVec 연산자 피연산자 – 스택 할당 피연산자가 연산자별 힙 할당을 제거
  • 크로스 문서 폰트 캐시 – 모든 PdfDocument 인스턴스에서 공유되는 프로세스 수준 LRU 폰트 캐시

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 백엔드 – zlib-ng 포팅을 통해 스트림 압축 해제 15-25% 빨라짐

버그 수정

  • 임베디드 프로그램을 동반한 폰트 인코딩 – PDF 사양에 따른 올바른 기본 인코딩 해석
  • 보충 Unicode(U+10000+) – 보충 코드 포인트의 잘림 수정
  • StandardEncoding 합자 매핑 – Adobe Glyph List를 통한 올바른 fi, fl, ff, ffi, ffl 매핑
  • 강희 부수 정규화 – 완전한 U+2F00-U+2FD5 매핑 테이블
  • RTL 텍스트 문자 순서 – 아랍어/히브리어가 논리적 읽기 순서로 추출
  • 다중 컬럼 텍스트 분리 – 간격 분석을 통한 개선된 컬럼 감지

기능

  • extract_all_text() – 전체 페이지 텍스트 추출을 위한 새 편의 메서드
  • StructElem의 source_role – 역할 매핑 전 원본 PDF 역할 이름 보존

v0.3.8 – 2026-02-20

텍스트 전용 파서 – 그래픽이 많은 페이지가 10-30배 빨라짐

성능

  • 텍스트 전용 콘텐츠 스트림 파서 – 새로운 parse_content_stream_text_only() 빠른 경로가 전체 nom 파싱 대신 바이트 수준 스캐닝을 사용하여 BT/ET 블록 밖의 그래픽 연산자를 건너뜀
  • 바이트 수준 그래픽 스캐너 – 원시 인덱스 산술이 nom 기반 피연산자 루프를 대체하여 거의 memcpy 속도로 처리
  • 색상 연산자 건너뛰기 – 12개의 색상 연산자를 바이트 수준 건너뛰기 목록에 추가
  • q/cm/Q 방출 지연 – 텍스트가 확인될 때까지 그래픽 상태 연산을 지연하여 백트래킹 오버헤드의 약 75% 제거
  • Arc 래핑 FontInfo 캐시 – 캐시 적중 시 전체 FontInfo 구조체 복제를 회피
  • O(n) 페이지 맵 구성 – 단일 패스 순회가 재귀 하강을 대체
  • XObject 이름-참조 캐시 – XObject가 많은 페이지에서 O(n^2) 딕셔너리 복제를 제거

v0.3.7 – 2026-02-19

텍스트 추출 품질: 95.7%에서 99.6% 클린율로

검증됨 – 3,829-PDF 코퍼스

메트릭 v0.3.6 v0.3.7 변화
클린율 95.7% 99.6% 3,829개 중 3,812개 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 디코딩 – 일본어 Shift-JIS 인코딩 CMap 스트림 지원
  • Identity-H cmap 전파 – CIDFont 자손에서 TrueType cmap 테이블 전파

수정됨 – 텍스트 추출 파이프라인

  • 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(n) 순회 후 페이지당 O(1)입니다. 10,000 페이지 veraPDF 테스트 파일이 55,667ms에서 332ms로(168배 빠름) 변경되었습니다.

  • 객체 스캔 오프셋 캐시 – 객체가 xref 테이블에서 누락되면 scan_for_object()는 이전에 누락된 각 객체에 대해 전체 PDF 파일을 읽었습니다. xref에 없는 수백 개의 구조 트리 요소가 있는 태그된 PDF는 수백 번의 전체 파일 읽기를 유발했습니다. 이제 파일이 한 번 스캔되고 모든 객체 오프셋이 캐시됩니다. 10페이지 태그된 PDF가 약 10초에서 68ms로(146배 빠름) 변경되었습니다. 571개 폰트가 있는 154페이지 학술 PDF가 약 18초에서 405ms로(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,830개 유효 PDF 중 3,823개
느림(>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(추출된 텍스트 862KB)에서 바이트 단위로 동일함이 검증되었습니다. 4개 PDF가 적응형 간격으로 인한 추출 품질 향상을 보였습니다.


v0.3.5 – 2026-02-15

성능, 3,830-PDF 안정성, 오류 복구

성능

  • 페이지 간 폰트 캐싱 – ObjectRef로 키가 지정된 문서 수준 폰트 캐시가 모든 페이지에서 공유 폰트의 재파싱을 회피
  • 페이지 객체 캐싱get_page()가 해석된 페이지 객체를 캐시하여 다중 페이지 추출에 대한 반복적인 페이지 트리 순회를 제거
  • 구조 트리 캐싱 – 구조 트리 결과가 첫 접근 후 캐시되어 모든 extract_text() 호출에서의 중복 파싱을 회피
  • BT 연산자 조기 종료 – 텍스트 추출이 BT(Begin Text) 연산자를 포함하지 않는 이미지 전용 페이지에 대해 전체 파이프라인을 건너뜀
  • 큰 파일을 위한 더 큰 I/O 버퍼 – 100MB를 초과하는 파일에 대해 BufReader 용량을 8KB에서 256KB로 증가
  • Xref 재구성 임계값 제거 – 객체가 적은 유효한 포트폴리오 PDF에서 전체 파일 재구성을 유발하던 휴리스틱 제거

검증됨 – 3,830-PDF 코퍼스

  • veraPDF(2,907), Mozilla pdf.js(897), SafeDocs(26)에 걸친 3,830개 PDF에서 100% 통과율
  • 타임아웃 제로, 패닉 제로
  • p50 = 0.6ms, p90 = 3.0ms, p99 = 33ms

추가됨 – 암호화

  • 소유자 비밀번호 인증 – R<=4용 알고리즘 7, R>=5용 알고리즘 12
  • SASLprep을 동반한 R>=5 사용자 비밀번호 검증 – SHA-256을 사용한 완전한 AES-256 비밀번호 검증
  • 공개 비밀번호 인증 APIPdf::authenticate(password)PdfDocument::authenticate(password)

추가됨 – PDF/A 준수 검증

  • XMP 메타데이터 검증pdfaid:partpdfaid:conformance 항목 확인
  • 색 공간 검증 – output intent 없이 장치 종속 색상 연산자에 대해 페이지 콘텐츠 스트림 스캔
  • AFRelationship 검증 – PDF/A-3 임베디드 파일 사양 검증

추가됨 – PDF/X 준수 검증

  • XMP PDF/X 식별pdfxid:GTS_PDFXVersion 검증
  • 페이지 박스 관계 검증 – BleedBox 내의 TrimBox, MediaBox 내의 BleedBox
  • ExtGState 투명도 감지 – SMask, CA/ca, BM 검사
  • 장치 종속 색상 감지 – 지원되지 않는 색 공간 플래그 지정
  • ICC 프로필 검증 – ICCBased 프로필 스트림 검증

추가됨 – 렌더링

  • 사양에 맞는 클리핑 – 클립 상태가 q/Q 저장/복원으로 범위 지정됨
  • 글리프 전진 너비 계산 – PDF 사양 섹션 9.4.4에 따름
  • Form XObject 렌더링 – /Matrix 변환 파싱, 폼의 /Resources 사용

수정됨 – 오류 복구(28개 이상의 실제 PDF)

  • 누락된 객체가 PDF 사양 섹션 7.3.10에 따라 Null로 해석됨
  • 특이한 버전 문자열에 대한 관대한 헤더 버전 파싱
  • 비표준 암호화 알고리즘 매칭(V=1, R=3 조합)
  • 딕셔너리가 아닌 Resources를 오류 대신 빈 것으로 취급
  • 페이지 트리의 Null 노드를 우아하게 건너뜀
  • 손상된 콘텐츠 스트림이 오류 대신 빈 콘텐츠 반환
  • /Resources+/Parent 휴리스틱을 동반한 향상된 페이지 트리 스캔

수정됨 – DoS 보호

  • 페이지 수가 PDF 사양 부록 C.2 한도(8,388,607)에 대해 검증됨

수정됨 – 이미지 추출

  • Do 연산자를 통한 콘텐츠 스트림 이미지 추출
  • 순환 감지를 동반한 중첩 Form XObject 이미지
  • 인라인 이미지(BI…ID…EI 시퀀스)
  • 이미지 위치 지정을 위한 CTM 변환
  • ColorSpace 간접 참조 해석

수정됨 – 파서 견고성

  • 다중 줄 객체 헤더(Google 생성 PDF에서 사용하는 1 0\nobj 형식)
  • 헤더 검색을 1024에서 8192바이트로 확장
  • 잘못된 형식의 헤더에 대한 관대한 버전 파싱

수정됨 – 페이지 접근 견고성

  • /Contents가 없는 페이지가 빈 콘텐츠 반환
  • 순환 페이지 트리 감지가 스택 오버플로 방지
  • Null 스트림 참조를 우아하게 처리
  • /Type 항목이 없는 페이지가 /MediaBox 또는 /Contents 키로 발견됨

수정됨 – 암호화 견고성

  • 너무 작은 키를 사용한 AES 복호화가 패닉 대신 오류 반환
  • 잘못된 형식의 항목에 대해 Xref 스트림 파싱 강화
  • 간접 /Encrypt 참조가 파싱 전에 해석됨

수정됨 – 콘텐츠 스트림 처리

  • 맨 딕셔너리를 위한 Dictionary-as-Stream 폴백
  • 축약된 필터 이름(AHx, A85, LZW, Fl, RL, CCF, DCT)
  • 콘텐츠 스트림 연산자 한도(기본 1,000,000)

수정됨 – 코드 품질

  • 구조 트리 간접 객체 참조가 파싱 시점에 해석됨
  • Lexer 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)

  • 바이너리 접두사나 BOM 헤더가 있는 PDF가 이제 성공적으로 열림
  • 헤더 검색이 첫 1024바이트에서 %PDF- 마커를 스캔
  • UTF-8 BOM, 이메일 헤더 및 기타 선행 바이너리 데이터 지원
  • 관대한 모드는 실제 잘못된 형식의 PDF를 처리하고, 엄격 모드는 준수 테스트용

추가됨 – 문자 수준 텍스트 추출(Issue #39)

  • extract_chars()가 문자별 위치 지정을 동반한 Vec<TextChar> 반환
  • 변환 행렬, 회전 각도, 전진 너비 포함
  • 겹치는 문자 중복 제거를 동반하여 읽기 순서로 정렬
  • 문자 전용 사용 사례에 대해 스팬 추출보다 30-50% 빠름
  • Rust와 Python API 모두에서 노출

추가됨 – XObject 경로 추출(Issue #40)

  • extract_paths()가 Do 연산자를 통해 Form XObject를 재귀적으로 처리
  • /Matrix를 통한 좌표 변환이 올바르게 적용됨
  • 그래픽 상태가 올바르게 격리됨(저장/복원)
  • 중복 XObject 감지가 무한 루프 방지
  • 중첩 XObject 지원

변경됨

  • nom 파서 라이브러리를 7.1에서 8.0으로 업그레이드

v0.3.3 – 2026-02-11

CJK 지원, 구조 트리 향상, 준수 기반

v0.2.5와 v0.2.6의 모든 변경 사항을 통합 릴리스로 포함합니다.

주요 사항

  • TagSuspect/MarkInfo 지원 – 문서 카탈로그에서 MarkInfo 딕셔너리 파싱
  • CJK 텍스트를 위한 Word Break /WB 구조 요소
  • Adobe-GB1(중국어 간체), Adobe-Japan1(일본어), Adobe-CNS1(중국어 번체), Adobe-Korea1(한국어)을 위한 사전 정의된 CMap 지원
  • 축약 확장 /E 지원
  • CIDFont 글리프 너비를 위한 Type 0 /W 배열 파싱
  • 소프트 하이픈(U+00AD) 처리 수정
  • 서브타입 지원을 동반한 향상된 아티팩트 필터링
  • HTML 및 Markdown 출력에서의 이미지 임베딩(base64 data URI)
  • embed_images=falseimage_output_dir을 동반한 이미지 파일 익스포트
  • PdfImage::to_base64_data_uri()to_png_bytes() 메서드

v0.3.2 – 2026-02-01

편집, 암호화, 문서 보안

추가됨 – PDF 편집

  • 기존 PDF 수정을 위한 DocumentEditor
  • 완전한 주석 지원(텍스트 마크업, 도형, 스탬프, 잉크, 파일 첨부, 삭제)
  • 대화형 폼 필드 생성(텍스트, 체크박스, 라디오, 드롭다운, 리스트, 버튼)
  • 폼 평면화
  • 링크 주석(URL, 내부 페이지 탐색)
  • 개요/북마크 빌더
  • PDF 레이어(Optional Content Groups)

추가됨 – 암호화

  • 쓰기 시 암호화(AES-256, AES-128, RC4-128, RC4-40)
  • 권한 제어(인쇄, 복사, 수정, 주석)
  • EncryptionAlgorithmPermissions를 동반한 EncryptionConfig 빌더
  • 디지털 서명 기반

v0.3.1 – 2026-01-14

폼 필드, 멀티미디어, 생성 도구, 검색

추가됨 – PDF 생성

  • Pdf::from_markdown(), Pdf::from_html(), Pdf::from_text(), Pdf::from_image()
  • 메타데이터 및 레이아웃 구성을 위한 PdfBuilder 유창 패턴
  • 프로그래밍 방식 PDF 생성을 위한 DocumentBuilder
  • TableRenderer를 사용한 표 렌더링
  • 그래픽 API: 색상, 그라디언트, 패턴, 블렌드 모드, 투명도
  • 머리글, 바닥글, 페이지 번호 매기기, 워터마크를 동반한 페이지 템플릿
  • 바코드 생성(QR, Code128, EAN-13, UPC-A, Code39, ITF)

추가됨 – 검색

  • 정규식, 대소문자 구분/미구분, 전체 단어, 페이지 범위를 동반한 텍스트 검색
  • SearchOptionsSearchResult 타입
  • 페이지/좌표를 동반한 위치 추적

추가됨 – 폼 필드 커버리지(95%)

  • 계층적 필드 생성(점 표기 이름을 동반한 부모/자식 구조)
  • 필드 속성 수정(읽기 전용, 필수, 사각형, 툴팁, 최대 길이, 정렬, 기본값)
  • 폼 데이터 교환을 위한 FDF/XFDF 익스포트

추가됨 – 멀티미디어 주석

  • MovieAnnotation, SoundAnnotation, ScreenAnnotation, RichMediaAnnotation
  • U3D 및 PRC 형식 지원을 동반한 ThreeDAnnotation

추가됨 – XFA 폼 지원

  • XfaExtractor, XfaParser, XfaConverter(XFA를 AcroForm으로 변환)

변경됨 – Python 바인딩

  • abi3-py38을 통한 진정한 Python 3.8-3.14 지원
  • 현대적 도구: uv, pdm, ruff 통합

v0.3.0 – 2026-01-10

추출 기반 – 통합 API 및 핵심 기능

추가됨 – 통합 Pdf API

  • 기존 PDF 읽기를 위한 Pdf::open()
  • pdf.page(0)을 통한 DOM 유사 페이지 탐색
  • 고급 사용 사례를 위한 PdfDocument 저수준 핸들

추가됨 – 텍스트 추출

  • extract_text() – 전체 페이지 일반 텍스트
  • extract_spans() – 폰트 메타데이터를 동반한 스타일화된 텍스트 런
  • 태그된 PDF를 위한 구조 트리 기반 읽기 순서
  • 태그되지 않은 PDF를 위한 지능형 줄바꿈 및 공백 감지

추가됨 – 이미지 추출

  • extract_images() – 페이지에서 모든 이미지 추출
  • 형식 감지(JPEG, PNG, TIFF, JBIG2, CCITT)
  • 색 공간 처리(DeviceRGB, DeviceCMYK, DeviceGray, ICCBased)

추가됨 – 메타데이터 추출

  • 문서 정보 딕셔너리(제목, 작성자, 주제, 키워드)
  • XMP 메타데이터 읽기/쓰기
  • 페이지 정보(치수, 회전, media/crop/trim 박스)

추가됨 – 폼 추출

  • AcroForm 필드 열거를 위한 extract_form_fields()
  • 텍스트, 버튼, 선택, 서명 필드 타입

추가됨 – 변환

  • 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 기능 필요)

  • tiny-skia를 통해 페이지를 PNG/JPEG로 렌더링
  • 구성 가능한 DPI 및 스케일

추가됨 – Python 바인딩

  • 완전한 추출 API를 갖춘 PdfDocument 클래스
  • 생성 및 고수준 API를 갖춘 Pdf 클래스
  • PyO3 기반, pdf_oxide로 PyPI에 게시

v0.2.4 – 2026-01-09

  • 텍스트 위치 지정을 위한 CTM 변환 수정
  • 구조 트리 /Alt/Pg 파싱
  • 수식 이미지를 위한 FormulaRenderer

v0.2.3 – 2026-01-07

  • PDF 사양에 따른 BT/ET 행렬 재설정
  • 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

  • 최초 릴리스
  • 사양에 맞는 Unicode 매핑을 동반한 PDF 텍스트 추출
  • 지능형 읽기 순서 감지
  • PyO3를 통한 Python 바인딩
  • 암호화된 PDF 지원
  • 폼 필드 추출
  • 이미지 추출