HotPDF exporta e importa anotaciones de PDF como XFDF a través de dos funciones que actúan sobre el documento cargado actualmente: ExportLoadedAnnotationsToXFDF y ImportLoadedAnnotationsFromXFDF. XFDF es el formato XML de intercambio de anotaciones estandarizado como ISO 19444-1, y este par de funciones permite que un programa en Delphi o C++Builder entregue sus comentarios a Acrobat o a una herramienta de revisión de terceros y reciba de vuelta los resultados marcados, todo ello sin reescribir el contenido de la página donde se ubican las anotaciones
Imagine las dos direcciones que esto resuelve. Un revisor abre su informe generado en Acrobat, coloca una flecha roja sobre una figura desalineada, encierra en un círculo un total incorrecto y escribe una nota en el margen, y luego exporta los comentarios a un pequeño archivo XFDF. O al revés: su programa produce los marcados por sí mismo y usted necesita enviarlos a alguien cuya herramienta no sea HotPDF. En ambos casos, las anotaciones viajan como XML que ambas partes entienden, y las páginas PDF se mantienen byte por byte tal como estaban
¿Cuál es la diferencia entre FDF y XFDF?
FDF y XFDF transportan la misma carga útil en dos sintaxis diferentes, y la distinción es importante en el momento en que decide qué archivo entregar a otra herramienta. FDF es el formato de datos de formulario (Forms Data Format) más antiguo definido dentro de la propia especificación PDF: utiliza la sintaxis de objetos PDF, por lo que un archivo FDF parece un PDF simplificado y necesita un analizador compatible con PDF para leerse. XFDF es la expresión XML de esos mismos datos, estandarizada de forma independiente como ISO 19444-1, lo que significa que cualquier biblioteca XML en cualquier plataforma puede abrirlo, compararlo (diff) o generarlo. Ambos formatos pueden contener valores de campos de formulario en un árbol <fields>, regulado por la cláusula 6.3 de ISO 19444-1, y anotaciones en un árbol <annots>; HotPDF divide esas responsabilidades, enrutando los datos de formulario a través de ExportLoadedFormToXFDF y reservando ExportLoadedAnnotationsToXFDF para el lado de <annots>. Cuando intercambia comentarios con un servicio web, un servidor de revisión en Java o un script, XFDF es el formato que evita que la otra parte tenga que incrustar un analizador de PDF
¿Cómo exportar anotaciones PDF como XFDF en Delphi?
HotPDF exporta anotaciones recorriendo cada página del documento cargado, emitiendo un elemento XFDF para cada anotación compatible y devolviendo el número de anotaciones escritas. Cargue primero el PDF y luego llame a ExportLoadedAnnotationsToXFDF con una ruta de destino. El resultado entero es el recuento de anotaciones serializadas; un resultado de cero o inferior significa que no se exportó nada y no se escribió ningún archivo, lo que es su señal de que el documento no contenía anotaciones de un subtipo compatible
var
Pdf: THotPDF;
Written: Integer;
begin
Pdf := THotPDF.Create(nil);
try
if Pdf.LoadFromFile('report-reviewed.pdf', '') > 0 then
begin
// Write one XFDF element per supported annotation on every page
Written := Pdf.ExportLoadedAnnotationsToXFDF('comments.xfdf');
if Written <= 0 then
ShowMessage('No supported annotations were found');
end;
finally
Pdf.Free;
end;
end;
El XFDF resultante es XML simple y legible. HotPDF escribe una raíz <xfdf> en el espacio de nombres de ISO 19444-1, un contenedor <annots> y un elemento secundario por anotación con su índice de página basado en cero, color y geometría como atributos o elementos secundarios. Una línea con un relleno amarillo y una punta de flecha abierta, situada junto a un polígono relleno, se serializa de esta manera
<?xml version="1.0" encoding="UTF-8"?>
<xfdf xmlns="http://ns.adobe.com/xfdf/">
<annots>
<line page="0" start="72,700" end="220,700"
color="#FF0000" interior-color="#FFFF00"
head="OpenArrow" tail="None">
<contents-richtext>Baseline looks off</contents-richtext>
</line>
<polygon page="0" color="#0000FF" interior-color="#CCE5FF">
<vertices>72,120;180,120;180,200;72,200</vertices>
</polygon>
</annots>
</xfdf>
Cómo se asignan los subtipos de anotaciones a los elementos XFDF
Cada subtipo de anotación se asigna a un elemento específico de ISO 19444-1 con su propia convención geométrica, y HotPDF sigue esas estructuras en lugar de inventar las suyas propias. Las anotaciones de línea llevan un atributo start y otro end que contienen los dos pares de coordenadas de los puntos finales, tomados directamente de la matriz L de la anotación, mientras que los estilos de final de línea LE se convierten en atributos head y tail. Las anotaciones de polígono y polilínea mueven su lista de puntos a un elemento secundario <vertices> como pares x,y separados por punto y coma, no como un atributo, porque un lector que espera el elemento secundario omitirá silenciosamente los puntos que estén ocultos en cualquier otro lugar. Las anotaciones de tinta (ink), que pueden contener varios trazos separados, anidan un elemento <inklist> con un elemento secundario <gesture> por trazo, por lo que una firma de múltiples trazos sobrevive al viaje como gestos distintos en lugar de una sola mancha fusionada
El texto enriquecido, el color y el estilo del borde sobreviven junto con la geometría. El cuerpo de texto enriquecido de una nota se escribe como un elemento secundario <contents-richtext>; el relleno interior que PDF almacena en la matriz IC, la pintura dentro de un círculo, cuadrado, polígono o punta de línea y el relleno de un cuadro de redacción se presentan como un atributo interior-color en formato #RRGGBB; y el ancho del borde, el patrón de guiones y el efecto de borde nublado se asignan a los atributos width, dashes, style e intensity, por lo que una llamada con contorno de nube se sigue leyendo como nublada en el extremo receptor. HotPDF también preserva la ventana emergente conectada a una anotación de marcado, importando la geometría secundaria de la ventana emergente y su estado abierto o cerrado en el diccionario Popup de la anotación, y conserva los estados abierto y de revisión de la anotación de texto, de modo que un documento revisado conserva no solo sus formas sino también los metadatos del flujo de trabajo en los que confían los revisores
Importar XFDF de vuelta a un documento cargado
HotPDF importa XFDF analizando el XML, creando una anotación nueva para cada elemento a través de NewLoadedAnnotation, adjuntándola a la página que designa el elemento y devolviendo cuántas anotaciones añadió. El flujo de trabajo es simétrico con el de exportación: cargue el PDF base, llame a ImportLoadedAnnotationsFromXFDF con el archivo del revisor y luego guarde el documento cargado para persistir los nuevos marcados. Si falta el archivo o el XML no se puede analizar, la función devuelve cero y el documento cargado se deja intacto
var
Pdf: THotPDF;
Added: Integer;
begin
Pdf := THotPDF.Create(nil);
try
if Pdf.LoadFromFile('report.pdf', '') > 0 then
begin
Added := Pdf.ImportLoadedAnnotationsFromXFDF('comments.xfdf');
if Added > 0 then
Pdf.SaveLoadedDocument('report-annotated.pdf');
end;
finally
Pdf.Free;
end;
end;
Dado que cada elemento XFDF indica su propio índice de página, las anotaciones aterrizan en las páginas para las que fueron creadas, incluso cuando importa varios archivos en secuencia, lo que hace que sea seguro recopilar comentarios de más de un revisor en el mismo documento cargado antes de guardarlo. El siguiente ejemplo combina las aportaciones de dos revisores en una sola copia combinada. Para construir y editar los propios objetos de anotación en código en lugar de intercambiarlos como archivos, consulte cómo HotPDF crea y edita objetos de anotación PDF directamente desde Delphi
var
Pdf: THotPDF;
Total, I: Integer;
Files: array[0..1] of string;
begin
Files[0] := 'alice-comments.xfdf';
Files[1] := 'bob-comments.xfdf';
Pdf := THotPDF.Create(nil);
try
if Pdf.LoadFromFile('master.pdf', '') > 0 then
begin
Total := 0;
for I := Low(Files) to High(Files) do
Inc(Total, Pdf.ImportLoadedAnnotationsFromXFDF(Files[I]));
if Total > 0 then
Pdf.SaveLoadedDocument('master-merged.pdf');
end;
finally
Pdf.Free;
end;
end;
Qué realiza la ida y vuelta limpiamente y qué no
HotPDF realiza la ida y vuelta de los subtipos de anotaciones que acoge la norma ISO 19444-1, y omite deliberadamente el resto en lugar de emitir algo que un lector interpretaría erróneamente. El conjunto compatible abarca los tipos de marcado que dominan el trabajo de revisión real: notas de texto, texto libre, línea, cuadrado, círculo, polígono, polilínea, los cuatro tipos de marcado de texto (resaltado, subrayado, tachado y ondulado), sello, tinta y signo de intercalación (caret), además de adjuntos de archivos, sonido, redacción y enlace: dieciocho subtipos en total. Una anotación cuyo subtipo quede fuera de esa lista se descarta en la exportación, y dado que se omite en lugar de escribirse vacía, no infla el recuento que devuelve la función
El texto enriquecido es la advertencia sincera. HotPDF preserva el cuerpo <contents-richtext> para que el texto con estilo y el contenido sin formato realicen el viaje, pero XFDF transporta el texto del comentario y el marcado de estilo, no un flujo de apariencia renderizado, por lo que la aplicación receptora vuelve a dibujar la ventana emergente con sus propias fuentes y diseño en lugar de reproducir los píxeles exactos de HotPDF. Trate el proceso de ida y vuelta como fiel al contenido y a la intención, no al renderizado en pantalla al píxel exacto. Si su contenido con estilo reside en datos de formulario XFA en lugar de flujos de anotaciones, las reglas difieren, y el artículo sobre cómo maneja HotPDF XFA exData, texto enriquecido e hipervínculos cubre esa ruta independiente
El manejo a nivel de caracteres es más estricto de lo que parece, que es exactamente lo que se desea. HotPDF aplica las reglas de escape de la cláusula 5.8.2 de ISO 19444-1 cuando escribe texto, codificando los caracteres significativos para XML y los bytes de control para que un comentario que contenga un símbolo de et (&), un paréntesis angular o un salto de línea produzca un XML bien formado que cualquier analizador compatible acepte, y revierte las mismas reglas en la importación. Es por eso que una nota pegada de una hoja de cálculo, con puntuación y todo, regresa intacta en lugar de corromper el archivo
El intercambio de anotaciones es una parte de lo que hace la API de documentos cargados y se compone con el resto: importe el XFDF de un revisor, ajuste las páginas o edite los metadatos del documento, aplane o vuelva a dar permisos al archivo, y luego exporte un XFDF nuevo para la siguiente ronda. Todo ello se incluye en la versión estándar de HotPDF Component para Delphi y C++Builder, cuya referencia documenta la cobertura completa de subtipos de anotaciones y las funciones XFDF de datos de formulario complementarias