HotPDF exporta e importa anotaciones PDF como XFDF a través de dos funciones que actúan sobre el documento cargado actualmente: ExportLoadedAnnotationsToXFDF e ImportLoadedAnnotationsFromXFDF. XFDF es el formato XML de intercambio de anotaciones estandarizado como ISO 19444-1, y este par permite que un programa en Delphi o C++Builder entregue sus comentarios a Acrobat o a una herramienta de revisión externa y recupere los resultados marcados, todo esto sin necesidad de reescribir el contenido de la página donde se ubican las anotaciones
Imagine las dos direcciones que esto resuelve. Un revisor abre su reporte 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, luego exporta los comentarios to a un pequeño archivo XFDF. O al revés: su programa genera las anotaciones por sí mismo y usted requiere enviárselas a alguien cuya herramienta no sea HotPDF. En cualquier caso, las anotaciones viajan como un XML que ambas partes entienden, y las páginas del PDF se mantienen exactamente idénticas a nivel de bytes
¿Cuál es la diferencia entre FDF y XFDF?
FDF y XFDF transportan el mismo contenido en dos sintaxis diferentes, y la distinción cobra importancia en el momento en que usted decide qué archivo entregar a otra herramienta. FDF es el formato de datos de formularios (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 se ve como un PDF simplificado y requiere 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>, el cual se rige por la cláusula 6.3 de la norma ISO 19444-1, y anotaciones en un árbol <annots>; HotPDF divide esas responsabilidades, enrutando los datos del formulario a través de ExportLoadedFormToXFDF y reservando ExportLoadedAnnotationsToXFDF para el área de <annots>. Cuando intercambia comentarios con un servicio web, un servidor de revisión de Java o un script, XFDF es el formato que evita que la otra parte tenga que integrar un analizador de PDF
¿Cómo se exportan anotaciones PDF como XFDF en Delphi?
HotPDF exporta anotaciones recorriendo cada página del documento cargado, emitiendo un elemento XFDF por cada anotación compatible y devolviendo el número de anotaciones escritas. Cargue el PDF primero, luego llame a ExportLoadedAnnotationsToXFDF con una ruta de destino. El resultado entero es la cantidad de anotaciones serializadas; un resultado igual o inferior a cero significa que no se exportó nada y no se escribió ningún archivo, lo cual le indica 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 que resulta es un XML simple y legible. HotPDF escribe una raíz <xfdf> en el espacio de nombres de ISO 19444-1, un contenedor <annots>, y un hijo por anotación con su índice de página basado en cero, color y geometría como atributos o elementos hijo. Una línea con un relleno amarillo y una punta de flecha abierta, ubicada 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 mapean los subtipos de anotaciones a elementos XFDF
Cada subtipo de anotación se asocia 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 contienen un atributo start y otro end que guardan los dos pares de coordenadas de los extremos, tomados directamente del arreglo L de la anotación, mientras que los estilos de terminación de línea LE se convierten en atributos head y tail. Las anotaciones de tipo polígono y polilínea mueven su lista de puntos a un elemento hijo <vertices> como pares x,y separados por punto y coma, no a un atributo, porque un lector que espere el elemento hijo descartará silenciosamente los puntos ocultos en cualquier otra parte. Las anotaciones de tinta (ink), que pueden contener varios trazos separados, anidan un elemento <inklist> con un hijo <gesture> por cada trazo, por lo que una firma de múltiples trazos sobrevive al proceso como gestos distintos en lugar de un solo bloque fusionado
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 hijo <contents-richtext>; el relleno interior que el PDF almacena en el arreglo IC (la pintura dentro de un círculo, cuadrado, polígono o punta de flecha de línea y el relleno de un cuadro de redacción) se transmite 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 asocian a los atributos width, dashes, style e intensity, por lo que una llamada con contorno nublado se seguirá viendo nublada en el destino. HotPDF también conserva la ventana emergente asociada a una anotación de marcado, importando la geometría del hijo emergente (popup) y su estado abierto o cerrado en el diccionario Popup de la anotación, y transporta los estados abierto y de revisión de la anotación de texto, por lo que un documento revisado conserva no solo sus formas sino también los metadatos de 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, asociándola a la página que el elemento especifica, y devolviendo la cantidad de anotaciones que agregó. 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 conservar las nuevas anotaciones. Si el archivo no existe o el XML no se puede analizar, la función devuelve cero y el documento cargado se mantiene sin cambios
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;
Debido a que cada elemento XFDF nombra su propio índice de página, las anotaciones se colocan en las páginas para las que fueron creadas incluso cuando se importan varios archivos en secuencia, lo que hace seguro recopilar comentarios de más de un revisor en el mismo documento cargado antes de guardarlo una sola vez. El siguiente ejemplo une a dos revisores en una sola copia combinada. Para compilar y editar los objetos de anotación por sí mismos en el 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 el viaje de ida y vuelta de manera limpia y qué no
HotPDF realiza el viaje de ida y vuelta de los comentarios de anotaciones compatibles con 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 (stamp), tinta (ink) y careta (caret), además de archivos adjuntos, sonido, redacción y enlaces, dieciocho subtipos en total. Una anotación cuyo subtipo quede fuera de esa lista se omite al exportar, y debido a que se ignora en lugar de escribirse vacía, no aumenta el conteo que devuelve la función
El texto enriquecido es la advertencia real. HotPDF conserva el cuerpo de <contents-richtext> para que el texto estilizado y el contenido simple 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 viaje de ida y vuelta como fiel al contenido y la intención, no a la renderización en pantalla al nivel del píxel. Si su contenido estilizado se aloja en datos de formularios XFA en lugar de flujos de anotaciones, las reglas difieren, y cómo maneja HotPDF XFA exData, texto enriquecido y enlaces de hipertexto cubre esa ruta separada
El manejo a nivel de caracteres es más estricto de lo que parece, que es exactamente lo que usted desea. HotPDF aplica las reglas de escapado de la cláusula 5.8.2 de la norma ISO 19444-1 cuando escribe texto, codificando los caracteres significativos de XML y los bytes de control para que un comentario que contenga un símbolo de et (ampersand), un corchete angular o un salto de línea procuza un XML bien formado que cualquier analizador compatible acepte, e invierte las mismas reglas en la importación. Es por esto que una nota pegada desde una hoja de cálculo, con todo y su puntuación, regresa intacta en lugar de dañar el archivo
El intercambio de anotaciones es una parte de lo que realiza la API de documentos cargados, y se combina 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 nuevo XFDF para el siguiente ciclo. Todo esto se incluye en la versión estándar de HotPDF Component para Delphi y C++Builder, cuya referencia documenta la cobertura completa del subtipo de anotación y las funciones complementarias XFDF para datos de formularios