Skip to content

Registro de cambios

Todos los cambios notables de PDF Oxide están documentados aquí.


v0.3.38 – 2026-04-22

DocumentBuilder llega a cada binding; AES-256 en la ruta de escritura; verificación de firmas; WASM multidestino; backend purego de Go

Paridad de la API de escritura en todos los bindings (#384)

  • DocumentBuilder + FluentPageBuilder + EmbeddedFont ahora se incluyen en Python, Node/TypeScript, C#, Go y WASM, junto con Rust. Construcción de múltiples páginas con soporte completo de CJK / cirílico / griego mediante fuentes incrustadas. Cierra #382 a nivel multilenguaje.
  • 15 métodos de anotación en cada binding: link_url / link_page / link_named, highlight, underline, strikeout, squiggly, nota adhesiva, sello (14 estándar + personalizado), texto libre, watermark (personalizado / DRAFT / CONFIDENTIAL).
  • 5 tipos de widget de AcroForm en cada binding: text_field, checkbox, combo_box, radio_group, push_button.
  • Primitivas gráficas en cada binding: rect, filled_rect, line.
  • Canalización HTML+CSSPdf.from_html_css(...) y from_html_css_with_fonts(...) para cascadas multifuente en cada binding.

Cifrado AES-256 en la ruta de escritura (#386)

  • save_encrypted(path, user_pw, owner_pw) / to_bytes_encrypted(user_pw, owner_pw) en DocumentBuilder en cada binding.
  • save_with_encryption en Rust para algoritmo + permisos personalizados.

Subconjunto real de fuentes (#385 / FONT-3b)

  • Las tipografías CJK ahora se incrustan como un subconjunto en lugar de la tipografía completa. Un PDF de 5 caracteres construido a partir de una fuente CJK de ~17 MB normalmente se entrega por debajo de 100 KB. Los flujos de contenido, los anchos /W y el CMap ToUnicode se reasignan al espacio de GID del subconjunto; el ida y vuelta de extract_text no cambia.
  • Cambio en la API interna de escritura: EmbeddedFont::encode_string / encode_shaped_run devuelven Vec<u16> y build_embedded_font_objects devuelve un GlyphRemapper que los llamadores pasan a ContentStreamBuilder::build_with_remappers. Sin cambios en las API de alto nivel.

Verificación de firmas digitales (#208, mitad de verificación)

  • Signature.verify() y Signature.verify_detached(pdf_bytes) (y equivalentes nativos del binding) en cada binding. Verificaciones de atributos del firmante de la RFC 5652 §5.4 + messageDigest de la §11.2.
  • RSA-PKCS#1 v1.5 sobre SHA-1 / SHA-256 / SHA-384 / SHA-512 devuelve Valid / Invalid. RSA-PSS y ECDSA aparecen como Unknown / UnsupportedFeatureException; los llamadores aún pueden leer el certificado y ejecutar su propia verificación.
  • Certificate — inspección DER (subject, issuer, número de serie, validez, is_valid) mediante x509-parsercada binding.
  • Signature — enumerar + inspeccionar + .get_certificate()cada binding.
  • Timestamp — análisis de TSTInfo de la RFC 3161 (hora, número de serie, política, nombre de la TSA, algoritmo de hash, message imprint) — cada binding.
  • TsaClient — HTTP POST de la RFC 3161 con nonce y autenticación HTTP Basic detrás de una feature tsa-client de Cargo — cada binding excepto WASM. Intencionadamente no conectado en WASM (ureq es incompatible con wasm).
  • Escritores de metadatos DocumentEditor::set_producer / set_creation_date.
  • render_page_region y render_page_fit — superficie de renderizado recortada y ajustada.
  • Filtrado bicúbico de imágenes (paridad con pdf.js #19978) — las páginas escaneadas / de dos niveles con superposiciones mezcladas en modo Multiply ya no colapsan su rango de escala de grises al reducir la escala.

La firma en sí (a diferencia de la verificación) no está cubierta; #208 permanece abierto para esa mitad.

Empaquetado WASM multidestino (#392)

  • pdf-oxide-wasm ahora entrega tres builds en paralelo con exportaciones condicionales en package.json: nodejs/, bundler/ (Vite / webpack / Rollup / esbuild / Bun) y web/ (navegadores / Deno / Cloudflare Workers).
  • Corrige el ReferenceError: Can't find variable: __dirname que se lanzaba bajo los bundlers de navegador.
  • Importaciones por subruta (pdf-oxide-wasm/web, /nodejs, /bundler) disponibles para enrutamiento manual.

Binding de Go — backend purego + instalación en el directorio de caché

  • Un segundo backend mediante ebitengine/purego hace dlopen de libpdf_oxide.{so,dylib,dll} en tiempo de ejecución. Los builds con CGO_ENABLED=0 ahora funcionan. La selección del backend es automática — //go:build cgo → API completa de CGo, //go:build !cgo → purego.
  • Superficie de purego: apertura de PdfDocument (ruta / bytes / contraseña), recuento de páginas, versión, extracción de texto / Markdown / HTML / texto plano, fuentes, anotaciones, elementos de página, búsqueda, dimensiones de página, registro, además de PdfCreator.FromMarkdown para fixtures de prueba.
  • Solo CGo (error en tiempo de compilación bajo !cgo): DocumentEditor, DocumentBuilder, códigos de barras, firmas, TSA, renderizado, OCR, mutación de formularios.
  • Instalador: el nuevo flag -shared obtiene la cdylib en lugar de la staticlib e imprime CGO_ENABLED=0 + PDF_OXIDE_LIB_PATH=… para exportar.
  • El directorio de instalación se movió a os.UserCacheDir()~/.cache/pdf_oxide (Linux), ~/Library/Caches/pdf_oxide (macOS), %LocalAppData%\pdf_oxide (Windows). Coincide con la propia convención GOCACHE de Go.
  • Los assets de la versión ahora incluyen pdf_oxide-go-ffi-shared-<platform>.tar.gz para cada plataforma Tier-1, junto con los archivos staticlib existentes.

Correcciones de errores

  • #395RenderPage ya no lanza SignatureException cuando una página contiene metadatos de campo de firma imposibles de analizar pero ningún widget de firma interactivo. Reportado por @gevorgter.

Agradecimientos

  • @sparkyandrew – #382 (CJK mediante DocumentBuilder), #385 (generador de subconjuntos).
  • @arthurlassagne – #392 (rotura del build de navegador).
  • @gevorgter – #395 (excepción de firma en RenderPage).

v0.3.37 – 2026-04-20

HTML + CSS → PDF (#248) — la primera canalización creíble en Rust puro

Nueva 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")?;

Pasa HTML + CSS + bytes de fuente y recibe de vuelta un PDF paginado. Rust puro, solo MIT/Apache (sin dependencias transitivas MPL), el ida y vuelta de extract_text es idéntico byte a byte, así que los PDF producidos participan en la infraestructura de pruebas existente.

Lo que se incluyó

  • Subsistema de fuentes — incrustación de TTF/OTF con emisión de Type 0 / CIDFontType2 / Identity-H / ToUnicode; latino, cirílico, griego, hebreo, árabe hacen el ida y vuelta mediante extract_text. Descubrimiento de fuentes del sistema mediante fontdb, modelado de texto (shaping) mediante rustybuzz.
  • Motor CSS hecho a mano (~6.500 líneas de código, cero dependencias MPL) – tokenizador, parser, selectores L3+L4 (:is/:where/:not/:has), matcher, cascada, calc() / min() / max() / clamp(), var() con detección de ciclos, valores de propiedad tipados, at-rules (@media print, @page con :first/:left/:right/:blank, @font-face, @import, @supports), contadores, contenido de pseudoelementos.
  • HTML – tokenizador HTML5, DOM en arena plana, extracción de hojas de estilo (<style>, <link rel="stylesheet">, style="" en línea), extracción de recursos (<img> + srcset, <picture>/<source>, <a href>).
  • Diseño – block / flex / grid respaldados por Taffy, salto de línea UAX #14, colapso de márgenes, multicolumna, tablas (auto + fixed).
  • Pintado – texto + bordes, RTL mediante rustybuzz, <a href> → anotación /Link, data-URI de <img>/XObject, ::before / ::after, page-break-{before,after}: always, opacity, transform: translate*(), marcadores de lista <ul> / <ol>, fuentes incrustadas mediante DocumentBuilder::register_embedded_font (#382).

Cascada multifuente

  • Pdf::from_html_css_with_fonts(html, css, Vec<(family, bytes)>) — el font-family CSS en cualquier elemento se resuelve frente a las familias registradas (sin distinción de mayúsculas/minúsculas, con/sin comillas, multipalabra sin comillas).

Correcciones de errores en la pasada de casos límite

  • El texto en negrita Base-14 ahora se renderiza en negrita (discordancia de la clave del diccionario de recursos frente a Tf /Helvetica-Bold).
  • Las fuentes de sistema TTC (Helvetica.ttc, msgothic.ttc) ahora se resuelven mediante Source::SharedFile de fontdb.
  • El font-family multipalabra sin comillas ahora se tokeniza correctamente.
  • Se cerró la fuga de memoria en las factorías de Pdf::from_html_css (cuatro puntos de Box::leak reemplazados por locales con ámbito).
  • El alfa de PNG / la máscara suave (SMask) ahora se renderizan.
  • El texto modelado (shaped) hace el ida y vuelta mediante extract_text (encode_shaped_run mapea los clústeres de glifos de vuelta a los puntos de código de origen).
  • PdfWriter::finish incrusta las fuentes en orden de registro (antes era en orden aleatorio del HashMap).
  • Las colisiones de nombres de fuentes incrustadas se aíslan mediante nombres de recurso EFn monotónicos.
  • El Mutex de fontdb ya no se mantiene durante el fs::read de los bytes de la fuente.

Fuera del alcance

Filtros CSS, transformaciones 3D, animaciones, SVG dentro de HTML (toda crate de SVG viable en Rust es MPL), MathML, hyphens: auto, shape-outside, JavaScript, transform de matriz completa (scale/rotate), gradientes, box-shadow.

Auditoría de licencias

cargo deny check licenses pasa con cero dependencias transitivas MPL. La pila CSS de Mozilla (cssparser, selectors, html5ever, lightningcss, stylo) es toda MPL-2.0; la v0.3.37 escribe a mano los equivalentes para mantener pdf_oxide enteramente bajo MIT/Apache.

Agradecimientos

  • @jmriebold – el #248 (“soporte de CSS”) es la raíz de toda la canalización HTML+CSS→PDF de esta versión.

v0.3.36 – 2026-04-19

Extracción estructural de Markdown — emisión de encabezados/listas desde PDF etiquetado, orden de lectura multicolumna, manejo de RTL más seguro

Extracción estructural de Markdown (#377)

to_markdown() ahora conecta /StructTreeRoot directamente a la canalización de markdown en lugar de volver a derivar los niveles de encabezado a partir de heurísticas de tamaño de fuente y los marcadores de lista a partir de la detección de glifos:

  • Emisión de encabezados y listas desde /StructTreeRoot. Nuevo StructRole (Heading(1..6), ListItem, ListItemLabel, ListItemBody) adjunto a cada span. Los documentos etiquetados por Word recuperan toda su jerarquía de encabezados; las listas emiten - item con saltos de párrafo en cada transición de rol.
  • El rol se propaga a través de MCR anidados. Los patrones H1 → Span → MCR y LI → LBody → Span → MCR ahora transportan el rol semántico correcto mediante InheritedContext { heading_level, list_role }.
  • El límite de bloque por /StructTreeRoot fuerza un salto de párrafo. OrderedContent.block_id se incrementa en cada entrada a /P, /H1..6, /LI, /Lbl, /LBody, /Sect, /Div, /Art, /TR, /TH, /TD, /Note, /Reference, /BibEntry, /Code; los diseños con espaciado ajustado ya no se fusionan.
  • Compuerta de misma línea base contra la sobrefragmentación de encabezados de formulario — los spans en la misma línea base se vuelven a unir en un único encabezado.
  • Detección de canaleta multicolumna — los spans en la misma línea base separados por > max(3 × font_size, 30 pt) se tratan como entre columnas.
  • Detección de envoltura de orden de lectura por x inverso — el orden de lectura por columnas (último span de la columna 1 en x=976 → primer span de la columna 2 en x=192 en la misma línea base) ahora rompe párrafos en lugar de unirlos.
  • Detección geométrica de encabezados + prefijos de lista para documentos sin etiquetar. Negrita + un aumento de tamaño del 5 % asciende a H4. El nuevo is_ordered_list_marker reconoce 1. / 12. / a) / iv. / A. a la vez que rechaza pies de figura y años.

Texto RTL — seguro por defecto

  • Los marcadores **bold** espurios alrededor de glifos contextuales del árabe ahora se eliminan (las transiciones de modelado confundían al detector de peso de fuente).
  • El reordenamiento bidi está DESACTIVADO por defecto. Un borrador anterior ejecutaba el reordenamiento visual→lógico de unicode-bidi en cada línea RTL, lo que rompía PDF antes correctos en orden lógico (el nombre hebreo בנימין se invertía). El ayudante de reordenamiento permanece en text::bidi::reorder_visual_to_logical para los llamadores cuya entrada está en orden visual.

Salida de Markdown

  • Las data URI base64 de imágenes en línea se limitan a 200 KB. Los PDF con diagramas de alta resolución antes inflaban la salida de markdown entre 10 y 20 veces (un artículo de 1,9 MB producía 11,3 MB de markdown). Las imágenes por encima del límite emiten un marcador de posición en comentario HTML con el tamaño original. La salida de imágenes basada en archivos (image_output_dir) no se ve afectada.

Impacto empírico

Validado frente a la v0.3.35 sobre una regresión de 369 PDF que abarca subconjuntos académicos, gubernamentales, de formularios, periódicos, técnicos, tesis, IRS, pdfium, pdfjs, safedocs y del corpus lento:

  • 0 regresiones catastróficas.
  • Token Jaccard frente a pdfium y pdftotext: mediana 1,000, ≥0,95 en 95/106 fixtures.
  • Token Jaccard frente a pymupdf4llm: mediana 0,978, ≥0,95 en 65/106 fixtures.
  • ~2× más encabezados emitidos que pymupdf4llm a lo largo del corpus.

Agradecimientos

  • @Goldziher (kreuzberg) – abrió el #377 con una metodología de benchmark de 727 documentos más 9 PDF reproductores. El enfoque (“TF1 dentro de ±3 %, así que el contenido textual está bien, la estructura es el problema”) hizo que toda la investigación fuera abordable.

v0.3.35 – 2026-04-19

Preservación de dobletes de glifos estrechos en la extracción de texto

Corrección de la extracción de texto

  • Los dobletes adyacentes de glifos estrechos ya no colapsan en tamaños de fuente pequeños (#378, PR #379). TextExtractor::deduplicate_overlapping_chars y deduplicate_overlapping_spans usaban un umbral absoluto fijo de 2 pt; para glifos estrechos (l, r, I, i) en fuentes compactas a tamaños pequeños, el ancho de avance por glifo cae a ≤ 2 pt (la l de Helvetica ≈ 2,5 pt a 9 pt), de modo que dobletes adyacentes legítimos separados por un avance completo caían dentro de la ventana de deduplicación y uno de los dos glifos se descartaba silenciosamente. La corrupción visible incluía controller → controler, billed → biled, warranty → warrnty, following → folowing, VIII → VII. El umbral ahora escala con el propio advance_width de cada glifo como min(advance_width * 0.30, 2.0). Los parámetros ajustables se elevaron a las constantes asociadas TextExtractor::DEDUP_OVERLAP_RATIO / DEDUP_OVERLAP_CAP_PT.

Agradecimientos

  • @Hugues-DTANKOUO – reportó el #378 con un análisis preciso de causa raíz y escribió el PR #379 con el umbral escalado por avance y una matriz de regresión parametrizada (4 glifos estrechos × 3 tamaños de texto corrido).

v0.3.34 – 2026-04-17

API de página idiomática en todos los bindings; extracción estructurada de tablas

Nuevas funciones

  • API de página (#371) – Python, Node.js, C# y Go ahora exponen un objeto PdfPage. Itera con for page in doc, for (const p of doc), foreach (var p in doc.Pages) o doc.Pages(); indexa con doc[i], doc.page(i), doc[i] o doc.Page(i). Cada página expone de forma perezosa text, markdown(), html(), words, lines, tables, images, paths, annotations, search() y más.
  • Extracción estructurada de tablas (#289)extract_tables() (Python), ExtractTables() (C#/Go) y extractTables() (Node.js) ahora devuelven filas y celdas con texto más cajas delimitadoras, no solo Markdown. Disponible tanto en PdfDocument como en la nueva PdfPage.
  • Paridad de Node.jsextractWords, extractTextLines, extractTables, extractPaths, getEmbeddedImages, ocrExtractText conectados a la capa TypeScript (antes solo nativos).
  • ExtractedTableTable – renombrado en el núcleo de Rust; se elimina el prefijo redundante Extracted. Tipos orientados a FFI actualizados.

Calidad de la extracción de texto

  • Detección de columnas XY-cut en páginas de diseño mixto (#319) – la protección is_multi_column_page se endureció para exigir al menos 15 spans por columna; los spans ordenados por columna ya no se reordenan con la ordenación consciente de filas en extract_text.

Agradecimientos

  • @SeanPedersen por proponer la API centrada en la página (#371). @pdenapo por solicitar la extracción estructurada de tablas (#289).

v0.3.33 – 2026-04-16

Correcciones de extracción de texto, corrección de imágenes y seguridad de memoria

Correcciones de errores

  • Fallo de CMap ToUnicode (#363) – las fuentes Type0 en subconjunto ahora emiten U+FFFD cuando falta un CID en el CMap ToUnicode, en lugar de caer en texto cifrado Identity-H (por ejemplo, %B+$%8A//$2*%01*1%6APP).
  • El kerning TJ intrapalabra ya no divide palabras (#365) – el kerning de pares de letras de 0,10–0,20 em dentro de palabras únicas ([(diffe) -150 (rent)]) ya no dispara la inserción de espacios.
  • Mojibake UTF-8 en cirílico recuperado (#317) – las fuentes con codificación solo latina y secuencias brutas de bytes UTF-8 ahora se decodifican correctamente.
  • La recuperación parcial de FlateDecode rechaza salida basura (#364) – los PDF de MS Reporting Services cuyos flujos de contenido fallan a mitad de la descompresión ya no devuelven 128 bytes de datos pseudoaleatorios.
  • Paleta Indexed + ICCBased (#373) – las referencias de stream ICC no resueltas dentro del array base Indexed ya no establecen /N por defecto en 3 en lugar de 4 de CMYK, lo que corrige los artefactos de franjas diagonales. Reportado por @Charltsing.
  • Paletas Indexed basadas en Lab → sRGB (#337) – los bytes de paleta CIE L*a*b* ahora se convierten Lab→XYZ→sRGB en lugar de reinterpretarse como RGB bruto.

Memoria y rendimiento

  • Todas las cachés internas acotadas (PR #369, #354) – la caché de objetos (64 MB), las cachés de fuentes (256–512 entradas), las cachés de span/imagen de XObject (1024 entradas) y la caché global de CMap (1024 entradas) ahora usan desalojo FIFO.
  • OOM de extracción de rutas en PDF con muchos gráficos corregido (#369) – se añadió deduplicación de XObject consciente de CTM, de modo que el mismo XObject en la misma posición se deduplica, pero el mismo XObject en posiciones distintas se procesa por separado.
  • Resiliencia ante el envenenamiento de MutexMutexExt::lock_or_recover() reemplaza 72 puntos de llamada .lock().unwrap().

Dependencias

  • Ecosistema 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.

Suite de pruebas

  • Se eliminaron 13 pruebas ignoradas muertas/obsoletas; se corrigieron 3 pruebas antes ignoradas. Se añadieron pruebas de regresión para cada corrección de error anterior. La suite ahora cuenta con 6.300 aprobadas, 0 fallidas, 228 ignoradas.

Agradecimientos

  • @Charltsing por el reporte de error de extracción de imágenes Indexed + CMYK (#373).
  • @ddxtanx por perfilar el crecimiento ilimitado de memoria durante la extracción de múltiples páginas (#354).
  • @andrewjradcliffe por el PR #369: cachés FIFO acotadas, deduplicación de XObject consciente de CTM, trait de recuperación de envenenamiento MutexExt, endurecimiento del binding de Python.

v0.3.32 – 2026-04-15

Corrección de la canalización de versiones para el tarball Go FFI de Windows-x64

Canalización de versiones

  • Corrige el fallo del build de la biblioteca nativa x86_64-pc-windows-gnu que hacía fallar la versión v0.3.31scripts/shrink-staticlib.sh ejecutaba objcopy --strip-debug en cada miembro del archivo, pero la cadena de herramientas de compilación cruzada MinGW emite miembros de depuración dividida .dwo que contienen solo secciones DWARF; tras el strip, el miembro no tenía secciones restantes y objcopy abortaba todo el archivo. Corrección: eliminar los miembros de archivo .dwo mediante ar d antes de invocar objcopy. Sin cambios funcionales en los artefactos de Rust, Python, Node, WASM o C# – esta versión existe únicamente para desbloquear la ruta de instalación de Go en Windows-x64.

v0.3.31 – 2026-04-13

Correcciones de errores, cambios en el build de Go, mejoras de la infraestructura de versiones

Correcciones de errores

  • Recuperación de Xref – se corrigió la recuperación de objetos de página libre marcados incorrectamente y de entradas de offset de xref desviadas por unos pocos bytes.

Cambios incompatibles

  • Bibliotecas nativas de Go – las bibliotecas nativas ya no se hacen commit en go/lib/. Los consumidores deben ejecutar go run github.com/yfedoseev/pdf_oxide/go/cmd/install@latest una vez por máquina.

Infraestructura de versiones

  • Se redujeron las staticlibs de Rust en un 63 % (de 71 MB a 26 MB), se hizo strip del addon .node de npm, se eliminaron los sourcemaps de npm, se corrigió la fuga de sdist de la crate, se endureció el empaquetado snupkg de NuGet.

v0.3.27 – 2026-04-12

Staticlib de Go, bindings nativos de Node.js, NativeAOT de C#, OCR FFI, grandes correcciones de errores

Nuevas funciones

  • Migración a staticlib de Go – cambio de cdylib a staticlib para binarios de Go autocontenidos.
  • Bindings nativos de Node.js – subpaquetes de plataforma precompilados mediante distribución al estilo napi-rs.
  • C# LibraryImport – se migraron 881 declaraciones P/Invoke de DllImport a LibraryImport por compatibilidad con NativeAOT.
  • Puente OCR FFI – el soporte de OCR ahora está disponible en los bindings de Go, C# y Node.js.
  • Arnés de regresión – corpus curado de 60 PDF para pruebas automatizadas de calidad.

Correcciones de errores

  • Imágenes en espacio de color Indexed, cifrado AES-256 (V=5, R=6), orden de lectura para contenido de una sola columna y tabular, extracción de texto en árabe, separación de palabras, respaldo de ancho de fuente, invalidación de la caché de objetos, mejoras de renderizado.

v0.3.24 – 2026-04-09

Bindings oficiales para JavaScript/TypeScript, Go y C#

Nuevas funciones

  • Bindings de JavaScript/TypeScript – publicados en npm con cobertura completa de la API.
  • Bindings de Go – paquete Go nativo con superficie de API completa.
  • Bindings de C# – paquete .NET publicado en NuGet.
  • Capa C FFI – más de 270 funciones extern "C" con cabecera pdf_oxide.h compartida.
  • Control global del nivel de registro – configurable en todos los bindings.

v0.3.23 – 2026-04-09

Correcciones críticas de estabilidad

Correcciones de errores

  • Se corrigió el SIGABRT en páginas con CTM degenerada de PDF dvips rotados.
  • Se corrigió que las imágenes/XObjects se eliminaran al guardar.
  • Se corrigió el renderizado distorsionado en sistemas sin fuentes comunes.
  • Se corrigió que el índice de página de campo de formulario siempre devolviera 0.

v0.3.22 – 2026-04-08

Documentos seguros para hilos, Python asíncrono, Python free-threaded, ajuste fino de la segmentación de palabras/líneas

Nuevas funciones

  • PdfDocument seguro para hilosSend + Sync mediante Mutex (reemplazó a RefCell).
  • API Python asíncronaAsyncPdfDocument, AsyncPdf, AsyncOfficeConverter.
  • Python free-threaded – soporte para cp314t (builds sin GIL).
  • Umbrales de segmentaciónword_gap_threshold, line_gap_threshold, profile para ajustar la detección de palabras/líneas.

Correcciones de errores

  • Páginas en blanco en split/merge de la CLI, omisión de renderizado para imágenes mal formadas, SIGSEGV por ciclo en el árbol de estructura, compuerta de la estrategia de tablas.

Rendimiento

  • Árbol de estructura y flujos de contenido descomprimidos en caché, búsqueda de MCID en O(1), recorrido del árbol de páginas en O(log n), poblamiento perezoso del árbol de páginas.

v0.3.21 – 2026-04-04

Wheels de Python multiarquitectura, corrección del nivel de registro

Correcciones de errores

  • El nivel de registro ahora se respeta plenamente en Python (las macros se reenvían a la crate log).

Nuevas funciones

  • Wheels de Python multiarquitectura – Linux aarch64, musl x86_64/aarch64, Windows ARM64; requisito de glibc reducido a 2_28.

v0.3.20 – 2026-04-04

Gran reescritura de la extracción de tablas, mejoras en la calidad del texto, registro silencioso por defecto

Nuevas funciones

  • Reescritura del motor de extracción de tablas – canalización de intersección, detección de bordes de texto, cuadrícula extendida, detección de texto consciente de columnas, reconstitución de líneas punteadas/discontinuas, detección híbrida de filas.
  • Calidad de la extracción de texto – espaciado entre valores adyacentes, fusión de decimales divididos, consolidación de spans en negrita, jerarquía de encabezados HTML, emparejamiento etiqueta-valor, fusión de grupos columnares.
  • Registro silencioso – el registro ahora es silencioso por defecto en todos los bindings; los logs de Python fluyen a través del módulo logging mediante pyo3-log.

Correcciones de errores

  • Mensaje de error claro para PDF cifrado, descifrado de flujos ObjStm/XRef, manejo del salto de línea final por el parser de flujos.

v0.3.19 – 2026-04-02

Extracción de página en una sola llamada, orden de lectura consciente de columnas, cajas delimitadoras por carácter

Nuevas funciones

  • extract_page_text() – DTO de una sola llamada para una extracción de página simplificada.
  • Orden de lectura consciente de columnas – particionamiento espacial XY-Cut para documentos multicolumna.
  • Cajas delimitadoras por carácter – derivadas de las métricas de fuente para un posicionamiento preciso de caracteres.
  • Flag is_monospace – disponible en TextSpan y TextChar.
  • Pdf::from_bytes() – nuevo constructor en todos los bindings.
  • Operaciones de rutaextract_paths() en los bindings de Python.

Correcciones de errores

  • Pánico UTF-8 en log de depuración multibyte, espaciado de markdown, /Matrix de Form XObject, matriz de texto rotado, pérdida de CTM en el prescan, deduplicación, caída de texto en escala Tm, fusión de palabras en markdown, documentos en blanco en el merge de la CLI.

Cambios incompatibles

  • WASM – los nombres de campo JSON ahora usan camelCase.

v0.3.18 – 2026-04-01

Revisión completa del motor de renderizado, nuevas API de Python y WASM, Python con todo incluido

Nuevas funciones

  • Revisión completa del motor de renderizado – espaciado de caracteres correcto, soporte de fuentes incrustadas, métricas de fuentes estándar, relleno-y-trazo, ruta de recorte, sombreado por gradiente, transparencia alfa, máscaras de imagen por plantilla, rotación de página, espacios de color de separación.
  • Nuevas API de Pythonvalidate_pdf_a, validate_pdf_ua, validate_pdf_x, extract_pages, delete_page, move_page, flatten_to_images, constructor con contraseña, merge.
  • Nuevas API de WASMvalidatePdfA, deletePage, extractPages, save, constructor con contraseña, merge.
  • Python con todo incluido – renderizado, paralelismo, firmas y conversión Office habilitados por defecto.

Correcciones de errores

  • Aborto por CTM degenerada, protección contra flate-bomb en FlateDecode (límite de 256 MB), sincronización de la pila de recorte.

v0.3.17 – 2026-03-08

Refinamiento de la detección de tablas, optimización de PDF etiquetado

Mejoras

  • Detección de tablas refinada – requiere 2+ columnas, reduciendo los falsos positivos.
  • Canalización de extracción de PDF etiquetado optimizada.

Correcciones de errores

  • Se corrigió el pánico RefCell already borrowed en el procesamiento recursivo de Form XObject.

v0.3.16 – 2026-03-08

Extracción inteligente de tablas híbridas, stubs de tipo de Python, soporte de pathlib

Nuevas funciones

  • Extracción inteligente de tablas híbridas – clustering Union-Find, análisis de líneas visuales, spans/encabezados visuales.
  • Tablas ASCII profesionales – ajuste en múltiples líneas para la salida de terminal.
  • Stubs de tipo de Python – generados automáticamente mediante mypy stubgen.
  • PdfDocument de Python – acepta pathlib.Path y soporta gestor de contexto.

Correcciones de errores

  • Segfault en Form XObject anidado, escalado de coordenadas en Python, pánico UTF-8 en tabla ASCII.

v0.3.15 – 2026-03-06

Gestión de encabezados/pies de página, plantillas de página, extracción con ámbito

Nuevas funciones

  • API de gestión de encabezados/pies de página – añadir, eliminar y editar artefactos de PDF.
  • Plantillas de página – marcadores de posición dinámicos para numeración de páginas, fechas, etc.
  • Extracción con ámbito – respeta erase_regions para una salida filtrada.
  • PdfDocument.from_bytes() – nuevo constructor de Python.

Correcciones de errores

  • Orden de lectura multicolumna (XY-Cut), colisiones de identidad de fuente, falsos positivos de la estrategia de tablas Lines.

v0.3.14 – 2026-03-03

Renderizado de alto nivel, extracción de palabras/líneas, primitivas geométricas, tablas híbridas

Nuevas funciones

  • API de renderizado de alto nivelPdf::render_page en Rust, Python y WASM.
  • Extracción de palabras y líneasextract_words, extract_text_lines en todos los bindings.
  • Extracción de primitivas geométricasextract_rects, extract_lines.
  • Detección de tablas híbridas – las pistas de líneas vectoriales mejoran la detección de límites de tabla.
  • Armonización de la API – patrón fluido .within(page, rect).
  • Comandos de la CLI – comandos render y paths con filtrado --area.

Correcciones de errores

  • Descubrimiento de la compuerta de la feature de OCR, envenenamiento de la caché de span de XObject, filtros de cifrado V=4, CIDToGIDMap cifrado.

v0.3.13 – 2026-03-02

Correcciones de extracción de texto CJK

Correcciones de errores

  • Decodificación multibyte en extract_chars para fuentes CJK/Type0, precisión mejorada del posicionamiento de caracteres, escalado del espaciado de caracteres.

v0.3.12 – 2026-03-01

Calidad de la extracción de texto, conversión de markdown, rendimiento

Mejoras

  • Calidad de la extracción de texto – cálculo del ancho de fuente CID, detección de límites de palabra al cambiar de fuente, respaldo de mapeo CID no estándar, direccionalidad de texto RTL.
  • Conversión de markdown – particionamiento espacial recursivo XY-Cut, detección de encabezados, reconstrucción de listas.

Rendimiento

  • Recorrido del árbol de páginas sin copia, caché del árbol de estructura, salida temprana por operador BT, búfer de E/S más grande, eliminación del umbral de reconstrucción de xref.

v0.3.10 – 2026-02-26

Extracción paralela, soporte de WASM/JavaScript, procesamiento por lotes, mejoras en la calidad del texto

Nuevas funciones

  • Soporte de WASM/JavaScript – bindings de WebAssembly mediante wasm-bindgen. Extracción completa de texto, creación de PDF, edición, campos de formulario y búsqueda disponibles en el navegador y en Node.js. Publicado como pdf-oxide-wasm en npm.

  • Extracción paralela de páginas – nuevo flag de feature parallel con extracción multihilo basada en rayon. El ParallelExtractor distribuye las páginas entre hilos de trabajo. Una caché global de fuentes garantiza que las fuentes se analicen una sola vez.

  • API de procesamiento por lotes – nuevo BatchProcessor para flujos de trabajo con múltiples PDF, con callbacks de progreso y recolección de errores. Soporta procesamiento secuencial y paralelo.

  • Detección híbrida de OCR – nuevo enum PageType (NativeText, ScannedPage, HybridPage) con detección multiheurística para un respaldo inteligente de OCR.

  • Paridad completa de la API WASM/Python – 10 nuevos grupos de métodos en los bindings de WASM y Python: get/set de campos de formulario, extracción de bytes de imagen, PDF a partir de imágenes, aplanado de formularios, fusión de PDF, incrustación de archivos, etiquetas de página, metadatos XMP.

Correcciones de errores

  • Segfault de XObject circular – se corrigió el segfault por referencias circulares de Form XObject durante la extracción de imágenes
  • Desbordamiento de la cadena XRef /Prev – el análisis de la cadena XRef /Prev se reescribió de recursivo a iterativo con detección de ciclos
  • Texto con ligaduras rotas – el posprocesador repair_ligatures() corrige el texto corrupto de PDF de LaTeX
  • Calidad de la extracción de texto – extracción de texto de anotaciones, normalización de puntos de relleno (leader dots), soporte de CMap Priority 3
  • Extracción de tablas – celdas fusionadas, contenido de celda en múltiples líneas, detección de encabezados basada en fuente
  • Persistencia de campos de formulario – el guardado incremental ahora persiste correctamente los cambios de valor de los campos de formulario

Rendimiento

  • Omisión de páginas solo con imágenes – la comprobación previa page_cannot_have_text() omite la descompresión para páginas sin fuentes
  • Operandos de operador SmallVec – los operandos asignados en la pila eliminan la asignación en el heap por operador
  • Caché de fuentes entre documentos – caché de fuentes LRU a nivel de proceso compartida entre todas las instancias de PdfDocument

v0.3.9 – 2026-02-24

Más de 20 microoptimizaciones – extracción de texto un 40 % más rápida

Rendimiento

  • Corrección de la concatenación de cadenas O(n^2) – un Vec<&str> preasignado y unido al final reemplaza la acumulación cuadrática de String::push_str()
  • Parser de flujo de contenido solo de imágenes – nueva ruta rápida para extract_images() que omite los operadores de texto y gráficos (3-5x más rápido)
  • Caché de fuentes basada en huella digital – identidad de fuente mediante hashing de encoding+widths+flags en lugar de comparación completa de struct
  • Parser en streaming – los operadores del flujo de contenido se transmiten en streaming en lugar de recopilarse en un Vec
  • Parser en línea rápido para BT/ET – coincidencia directa de bytes para operadores de texto comunes
  • Tabla de búsqueda byte-a-char – una tabla de búsqueda de 256 entradas reemplaza al HashMap en la ruta caliente
  • Tabla de búsqueda de anchos – un array de tamaño fijo reemplaza al HashMap para los anchos de glifos
  • Reducción del enum Operator – de 112 a 40 bytes mediante boxing de las variantes grandes (64 % más pequeño)
  • Backend zlib-rs – descompresión de flujos un 15-25 % más rápida mediante un port de zlib-ng

Correcciones de errores

  • Codificación de fuentes con programas incrustados – resolución correcta de la codificación base según la especificación PDF
  • Unicode suplementario (U+10000+) – se corrigió el truncamiento de puntos de código suplementarios
  • Mapeo de ligaduras de StandardEncoding – mapeo correcto de fi, fl, ff, ffi, ffl mediante Adobe Glyph List
  • Normalización de radicales Kangxi – tabla de mapeo completa U+2F00-U+2FD5
  • Orden de caracteres de texto RTL – árabe/hebreo extraídos en orden de lectura lógico
  • Separación de texto multicolumna – detección de columnas mejorada mediante análisis de espaciado

Funciones

  • extract_all_text() – nuevo método de conveniencia para la extracción de texto de todas las páginas
  • source_role para StructElem – preserva el nombre de rol original del PDF antes del mapeo de roles

v0.3.8 – 2026-02-20

Parser solo de texto – páginas con muchos gráficos 10-30x más rápidas

Rendimiento

  • Parser de flujo de contenido solo de texto – la nueva ruta rápida parse_content_stream_text_only() omite los operadores gráficos fuera de los bloques BT/ET usando escaneo a nivel de byte en lugar de un análisis nom completo
  • Escáner de gráficos a nivel de byte – la aritmética de índices bruta reemplaza al bucle de operandos basado en nom, procesando a una velocidad cercana a memcpy
  • Omisión de operadores de color – 12 operadores de color añadidos a la lista de omisión a nivel de byte
  • Emisión diferida de q/cm/Q – las operaciones de estado gráfico se difieren hasta que se confirma el texto, eliminando ~75 % de la sobrecarga de backtrack
  • Caché de FontInfo envuelto en Arc – evita clonar structs FontInfo completos en los aciertos de caché
  • Construcción del mapa de páginas en O(n) – un recorrido en una sola pasada reemplaza al descenso recursivo
  • Caché de nombre-a-referencia de XObject – elimina la clonación de diccionarios en O(n^2) en páginas con muchos XObject

v0.3.7 – 2026-02-19

Calidad de la extracción de texto: del 95,7 % al 99,6 % de tasa limpia

Verificado – Corpus de 3.829 PDF

Métrica v0.3.6 v0.3.7 Cambio
Tasa limpia 95,7 % 99,6 % 3.812 de 3.829 PDF
PDF sucios 165 17 -90 %

Añadido – Parser y decodificadores

  • Filtro de flujo BrotliDecode (PDF 2.0) – nuevo decodificador para flujos comprimidos con Brotli
  • Selección de trailer Xref – selección correcta del trailer cuando existen múltiples trailers
  • Recuperación de PDF sin cabecera – búsqueda del primer marcador de objeto cuando falta la cabecera %PDF-

Añadido – Codificación de fuentes

  • Parser de codificación de fuentes CFF – analiza programas de fuente CFF/OpenType para la codificación de caracteres
  • Parser de codificación de fuentes Type1 – analiza programas de fuente Type 1 incrustados para los mapeos de glifos
  • Más de 80K mapeos CID-a-Unicode – ampliados Adobe-CNS1, Adobe-GB1, Adobe-Japan1, Adobe-Korea1
  • Decodificación Shift-JIS/RKSJ – soporte de flujos CMap codificados en Shift-JIS japonés
  • Propagación de cmap Identity-H – propaga las tablas cmap de TrueType desde los descendientes CIDFont

Corregido – Canalización de extracción de texto

  • Volcado del búfer Tf – vuelca el texto pendiente al cambiar de fuente para evitar la pérdida de texto
  • Umbral de espacio adaptativo – reemplaza el umbral fijo de 0,25em por un espaciado basado en bbox
  • Deduplicación de spans – deduplica los spans superpuestos renderizados para efectos de negrita/sombra
  • Deduplicación de caracteres – elimina los caracteres duplicados dentro de 2pt en la misma línea
  • Eliminación de la comprobación del operador BT – corrige la validación incorrecta que omitía bloques de texto válidos
  • Decodificación ByteMode – decodificación correcta de códigos de carácter de 1 byte, 2 bytes y ancho variable
  • Extracción de texto de anotaciones – extrae texto de Widget, FreeText y flujos de apariencia

v0.3.6 – 2026-02-16

10x más rápido – dos cuellos de botella O(n) eliminados

Rendimiento

  • Caché masiva del árbol de páginas – en el primer acceso a una página, todo el árbol de páginas se recorre una vez y todas las páginas se almacenan en caché. Antes, get_page() recorría desde la raíz para cada página no cacheada, resultando en O(n) por página y O(n^2) en total para el acceso secuencial. Ahora es O(1) por página tras un único recorrido O(n). Un archivo de prueba veraPDF de 10.000 páginas pasó de 55.667ms a 332ms (168x más rápido).

  • Caché de offset de escaneo por objeto – cuando faltan objetos en la tabla xref, scan_for_object() antes leía todo el archivo PDF por cada objeto faltante. Los PDF etiquetados con cientos de elementos del árbol de estructura fuera de la xref disparaban cientos de lecturas completas del archivo. Ahora el archivo se escanea una vez y todos los offsets de objeto se almacenan en caché. Un PDF etiquetado de 10 páginas pasó de ~10s a 68ms (146x más rápido). Un PDF académico de 154 páginas con 571 fuentes pasó de ~18s a 405ms (44x más rápido).

  • Extracción de texto en una sola pasadaextract_spans() ya no ejecuta dos pasadas (clasificar el tipo de documento y luego extraer). La pasada de clasificación se eliminó por completo; los umbrales adaptativos conscientes de la fuente ahora producen resultados iguales o mejores en una sola pasada.

  • Preasignación del Vec del flujo de contenidoparse_content_stream() preasigna la capacidad del Vec de operadores en función del tamaño del flujo, reduciendo las reasignaciones para flujos de contenido grandes.

Verificado – Corpus de 3.830 PDF (de v0.3.5 a v0.3.6)

Métrica v0.3.5 v0.3.6 Cambio
Tasa de aprobación 99,8 % 99,8 % 3.823 de 3.830 PDF válidos
Lentos (>5s) 2 0 Eliminados
Media 23,3ms 2,1ms -91 %
p50 0,6ms 0,6ms
p90 3,0ms 2,6ms -13 %
p99 33,2ms 18,0ms -46 %
Máx 68.722ms 625ms -99 %
Suma (todos los PDF) 89,1s 8,0s -91 %

La salida de texto se verificó como idéntica byte a byte en 11 PDF (862 KB de texto extraído). 4 PDF mostraron una calidad de extracción mejorada por el espaciado adaptativo.


v0.3.5 – 2026-02-15

Rendimiento, estabilidad en 3.830 PDF y recuperación de errores

Rendimiento

  • Caché de fuentes entre páginas – una caché de fuentes a nivel de documento, indexada por ObjectRef, evita volver a analizar las fuentes compartidas en cada página
  • Caché de objetos de páginaget_page() almacena en caché los objetos de página resueltos, eliminando el recorrido repetido del árbol de páginas en la extracción de múltiples páginas
  • Caché del árbol de estructura – el resultado del árbol de estructura se almacena en caché tras el primer acceso, evitando un análisis redundante en cada llamada a extract_text()
  • Salida temprana por operador BT – la extracción de texto omite la canalización completa para páginas solo con imágenes que no contienen operadores BT (Begin Text)
  • Búfer de E/S más grande para archivos grandes – la capacidad del BufReader aumentada de 8 KB a 256 KB para archivos de más de 100 MB
  • Umbral de reconstrucción de Xref eliminado – se eliminó la heurística que disparaba la reconstrucción completa del archivo en PDF de portafolio válidos con pocos objetos

Verificado – Corpus de 3.830 PDF

  • 100 % de tasa de aprobación en 3.830 PDF que abarcan veraPDF (2.907), Mozilla pdf.js (897), SafeDocs (26)
  • Cero timeouts, cero pánicos
  • p50 = 0,6ms, p90 = 3,0ms, p99 = 33ms

Añadido – Cifrado

  • Autenticación con contraseña de propietario – Algoritmo 7 para R<=4, Algoritmo 12 para R>=5
  • Verificación de contraseña de usuario R>=5 con SASLprep – verificación completa de contraseña AES-256 usando SHA-256
  • API pública de autenticación por contraseñaPdf::authenticate(password) y PdfDocument::authenticate(password)

Añadido – Validación de conformidad PDF/A

  • Validación de metadatos XMP – comprueba las entradas pdfaid:part y pdfaid:conformance
  • Validación de espacio de color – escanea los flujos de contenido de la página en busca de operadores de color dependientes del dispositivo sin output intent
  • Validación de AFRelationship – validación de la especificación de archivos incrustados PDF/A-3

Añadido – Validación de conformidad PDF/X

  • Identificación XMP PDF/X – valida pdfxid:GTS_PDFXVersion
  • Validación de relación de cajas de página – TrimBox dentro de BleedBox dentro de MediaBox
  • Detección de transparencia ExtGState – comprobaciones de SMask, CA/ca, BM
  • Detección de color dependiente del dispositivo – marca los espacios de color no soportados
  • Validación de perfil ICC – valida los flujos de perfil ICCBased

Añadido – Renderizado

  • Recorte correcto según la especificación – estado de recorte con ámbito en guardar/restaurar q/Q
  • Cálculo del ancho de avance del glifo – según la sección 9.4.4 de la especificación PDF
  • Renderizado de Form XObject – analiza la transformación /Matrix, usa los /Resources del formulario

Corregido – Recuperación de errores (28+ PDF del mundo real)

  • Los objetos faltantes se resuelven a Null según la sección 7.3.10 de la especificación PDF
  • Análisis indulgente de la versión de la cabecera para cadenas de versión inusuales
  • Coincidencia de algoritmos de cifrado no estándar (combinaciones V=1, R=3)
  • Los Resources que no son un diccionario se tratan como vacíos en lugar de generar un error
  • Los nodos Null en el árbol de páginas se omiten con elegancia
  • Los flujos de contenido corruptos devuelven contenido vacío en lugar de errores
  • Escaneo mejorado del árbol de páginas con la heurística /Resources+/Parent

Corregido – Protección contra DoS

  • El recuento de páginas se valida frente al límite del Anexo C.2 de la especificación PDF (8.388.607)

Corregido – Extracción de imágenes

  • Extracción de imágenes del flujo de contenido mediante operadores Do
  • Imágenes de Form XObject anidados con detección de ciclos
  • Imágenes en línea (secuencias BI…ID…EI)
  • Transformaciones CTM para el posicionamiento de imágenes
  • Resolución de referencias indirectas de ColorSpace

Corregido – Robustez del parser

  • Cabeceras de objeto en múltiples líneas (formato 1 0\nobj usado por los PDF generados por Google)
  • Búsqueda de cabecera ampliada de 1024 a 8192 bytes
  • Análisis indulgente de la versión para cabeceras mal formadas

Corregido – Robustez del acceso a páginas

  • Las páginas sin /Contents devuelven contenido vacío
  • La detección de árbol de páginas cíclico previene el desbordamiento de pila
  • Las referencias de stream Null se manejan con elegancia
  • Las páginas sin entrada /Type se encuentran mediante las claves /MediaBox o /Contents

Corregido – Robustez del cifrado

  • El descifrado AES con claves de tamaño insuficiente devuelve un error en lugar de un pánico
  • El análisis del flujo Xref endurecido contra entradas mal formadas
  • Las referencias /Encrypt indirectas se resuelven antes del análisis

Corregido – Procesamiento del flujo de contenido

  • Respaldo Dictionary-as-Stream para diccionarios desnudos
  • Nombres de filtro abreviados (AHx, A85, LZW, Fl, RL, CCF, DCT)
  • Límite de operadores del flujo de contenido (por defecto 1.000.000)

Corregido – Calidad del código

  • Las referencias de objeto indirectas del árbol de estructura se resuelven en tiempo de análisis
  • Desambiguación de los tokens R/RG en el lexer
  • El recorte de espacios en blanco del flujo ya no elimina bytes NUL ni espacios de los datos binarios

Pruebas

  • 8 pruebas antes ignoradas fueron designoradas y corregidas

Eliminado

  • Stub vacío PdfImage (la extracción usa ImageInfo)
  • Bloque de prueba comentado DocumentType::detect()

v0.3.4 – 2026-02-12

Robustez del análisis, extracción de caracteres y rutas de XObject

Cambios incompatibles

  • La firma de parse_header() cambió de (u8, u8) a (u8, u8, u64) para incluir el offset de byte

Corregido – Robustez del análisis de PDF (Issue #41)

  • Los PDF con prefijos binarios o cabeceras BOM ahora se abren con éxito
  • La búsqueda de cabecera escanea los primeros 1024 bytes en busca del marcador %PDF-
  • Soporta BOM UTF-8, cabeceras de correo electrónico y otros datos binarios iniciales
  • El modo indulgente maneja PDF mal formados del mundo real; el modo estricto para pruebas de conformidad

Añadido – Extracción de texto a nivel de carácter (Issue #39)

  • extract_chars() devuelve Vec<TextChar> con posicionamiento por carácter
  • Incluye matriz de transformación, ángulo de rotación, ancho de avance
  • Ordenado en orden de lectura con deduplicación de caracteres superpuestos
  • 30-50 % más rápido que la extracción de spans para casos de uso solo de caracteres
  • Expuesto tanto en la API de Rust como en la de Python

Añadido – Extracción de rutas de XObject (Issue #40)

  • extract_paths() procesa Form XObjects de forma recursiva mediante el operador Do
  • Las transformaciones de coordenadas mediante /Matrix se aplican correctamente
  • El estado gráfico se aísla adecuadamente (guardar/restaurar)
  • La detección de XObject duplicado previene bucles infinitos
  • Los XObjects anidados se soportan

Cambiado

  • La biblioteca del parser nom actualizada de 7.1 a 8.0

v0.3.3 – 2026-02-11

Soporte de CJK, mejoras del árbol de estructura y fundamentos de conformidad

Incluye todos los cambios de la v0.2.5 y la v0.2.6 como una versión consolidada.

Destacados

  • Soporte de TagSuspect/MarkInfo – analiza el diccionario MarkInfo del catálogo del documento
  • Elemento de estructura Word Break /WB para texto CJK
  • Soporte de CMap predefinidos para Adobe-GB1 (chino simplificado), Adobe-Japan1 (japonés), Adobe-CNS1 (chino tradicional), Adobe-Korea1 (coreano)
  • Soporte de expansión de abreviaturas /E
  • Análisis de array Type 0 /W para los anchos de glifo de CIDFont
  • Corrección del manejo del guion suave (U+00AD)
  • Filtrado mejorado de artefactos con soporte de subtipo
  • Incrustación de imágenes en la salida HTML y Markdown (data URI base64)
  • Exportación de archivos de imagen con embed_images=false y image_output_dir
  • Métodos PdfImage::to_base64_data_uri() y to_png_bytes()

v0.3.2 – 2026-02-01

Edición, cifrado y seguridad de documentos

Añadido – Edición de PDF

  • DocumentEditor para modificar PDF existentes
  • Soporte completo de anotaciones (marcado de texto, formas, sellos, tinta, archivos adjuntos, redacciones)
  • Creación de campos de formulario interactivos (texto, checkbox, radio, desplegable, lista, botón)
  • Aplanado de formularios
  • Anotaciones de enlace (URL, navegación interna de páginas)
  • Constructor de esquema/marcadores
  • Capas de PDF (Optional Content Groups)

Añadido – Cifrado

  • Cifrado en la escritura (AES-256, AES-128, RC4-128, RC4-40)
  • Controles de permisos (imprimir, copiar, modificar, anotar)
  • Constructor EncryptionConfig con EncryptionAlgorithm y Permissions
  • Fundamento de firma digital

v0.3.1 – 2026-01-14

Campos de formulario, multimedia, herramientas de creación y búsqueda

Añadido – Creación de PDF

  • Pdf::from_markdown(), Pdf::from_html(), Pdf::from_text(), Pdf::from_image()
  • Patrón fluido PdfBuilder para la configuración de metadatos y diseño
  • DocumentBuilder para la generación programática de PDF
  • Renderizado de tablas con TableRenderer
  • API de gráficos: colores, gradientes, patrones, modos de mezcla, transparencia
  • Plantillas de página con encabezados, pies de página, numeración de páginas, marcas de agua
  • Generación de códigos de barras (QR, Code128, EAN-13, UPC-A, Code39, ITF)

Añadido – Búsqueda

  • Búsqueda de texto con regex, sensible/insensible a mayúsculas, palabra completa, rangos de página
  • Tipos SearchOptions y SearchResult
  • Seguimiento de posición con página/coordenadas

Añadido – Cobertura de campos de formulario (95 %)

  • Creación jerárquica de campos (estructuras padre/hijo con nombres punteados)
  • Modificación de propiedades de campo (solo lectura, requerido, rectángulo, tooltip, longitud máxima, alineación, valor por defecto)
  • Exportación FDF/XFDF para el intercambio de datos de formulario

Añadido – Anotaciones multimedia

  • MovieAnnotation, SoundAnnotation, ScreenAnnotation, RichMediaAnnotation
  • ThreeDAnnotation con soporte de los formatos U3D y PRC

Añadido – Soporte de formularios XFA

  • XfaExtractor, XfaParser, XfaConverter (conversión de XFA a AcroForm)

Cambiado – Bindings de Python

  • Soporte verdadero de Python 3.8-3.14 mediante abi3-py38
  • Herramientas modernas: integración con uv, pdm, ruff

v0.3.0 – 2026-01-10

Fundamento de extracción – API unificada y capacidades centrales

Añadido – API Pdf unificada

  • Pdf::open() para leer PDF existentes
  • Navegación de páginas estilo DOM con pdf.page(0)
  • Handle de bajo nivel PdfDocument para casos de uso avanzados

Añadido – Extracción de texto

  • extract_text() – texto plano de toda la página
  • extract_spans() – ejecuciones de texto con estilo y metadatos de fuente
  • Orden de lectura basado en el árbol de estructura para PDF etiquetados
  • Detección inteligente de saltos de línea y espacios para PDF sin etiquetar

Añadido – Extracción de imágenes

  • extract_images() – extrae todas las imágenes de una página
  • Detección de formato (JPEG, PNG, TIFF, JBIG2, CCITT)
  • Manejo de espacios de color (DeviceRGB, DeviceCMYK, DeviceGray, ICCBased)

Añadido – Extracción de metadatos

  • Diccionario de información del documento (título, autor, asunto, palabras clave)
  • Lectura/escritura de metadatos XMP
  • Información de página (dimensiones, rotación, cajas media/crop/trim)

Añadido – Extracción de formularios

  • extract_form_fields() para la enumeración de campos AcroForm
  • Tipos de campo de texto, botón, elección y firma

Añadido – Conversión

  • to_markdown() – conversión a Markdown a nivel de página
  • to_html() – conversión a HTML a nivel de página
  • to_plain_text() – salida de texto plano configurable

Añadido – Conformidad

  • Validación PDF/A (ISO 19005, niveles 1a a 3b)
  • Validación PDF/X (ISO 15930, niveles X-1a a X-6p)
  • Validación PDF/UA (ISO 14289, niveles UA-1 y UA-2)

Añadido – Renderizado (requiere la feature rendering)

  • Renderiza páginas a PNG/JPEG mediante tiny-skia
  • DPI y escala configurables

Añadido – Bindings de Python

  • Clase PdfDocument con API de extracción completa
  • Clase Pdf con API de creación y de alto nivel
  • Basado en PyO3, publicado en PyPI como pdf_oxide

v0.2.4 – 2026-01-09

  • Corrección de la transformación CTM para el posicionamiento de texto
  • Análisis de /Alt y /Pg del árbol de estructura
  • FormulaRenderer para imágenes de fórmulas

v0.2.3 – 2026-01-07

  • Reset de matriz BT/ET según la especificación PDF
  • Detección de espaciado geométrico en el conversor de Markdown
  • apply_intelligent_text_processing() para ligaduras y separación de sílabas

v0.2.2 – 2025-12-15

  • Optimización de palabras clave para la descubribilidad

v0.2.1 – 2025-12-15

  • Mejoras en la decodificación de flujos cifrados

v0.1.4 – 2025-12-12

  • Correcciones en la decodificación de flujos cifrados

v0.1.0 – 2025-11-06

  • Versión inicial
  • Extracción de texto de PDF con mapeo Unicode conforme a la especificación
  • Detección inteligente del orden de lectura
  • Bindings de Python mediante PyO3
  • Soporte de PDF cifrado
  • Extracción de campos de formulario
  • Extracción de imágenes