simply4you.it simply4you.it

   Home
     Articoli, Tutorial...
       Visual Basic
         Generare PDF 1


Prima parte
Seconda parte

Autore
Luigi Micco

E-Mail
l.micco@tiscali.it



 Articoli correlati :

 Creare PDF con
 Visual Basic e l'FDF Toolkit




Commenta anche tu !  


LINK Visual Basic













   Invia il link di questo articolo ad un amico  Invia ad un amico Visualizza la versione stampabile di questo articolo  Stampa Commenta questo Articolo  Commenta Parlane in Chat  Chat   Parlane sul Forum  Forum

Generare documenti PDF con Visual Basic - Parte Prima

Premessa

Lo scopo del presente articolo è di affrontare le problemiche connesse alla generazione di documenti in formo PDF con MS Visual Basic, senza l'ausilio di nessun controllo OCX, libreria DLL o software di terze parti.

Nella prima parte procederemo ad una breve analisi di un documento PDF, evidenziandone la struttura e gli elementi costitutivi. Affronteremo quindi le problemiche relive alla gestione dei font, della grafica vettoriale e delle immagini raster.

Nella seconda parte vedremo come queste conoscenze possono essere utilizze per sviluppare una serie di funzione, in particolare sarà presenta una classe di esempio, di libero utilizzo ed implementazione.

Per brevità, non affronteremo il problema della compressione dei di, della revisione o modifica di un file creo in precedenza, né vedremo come realizzare le miniure o la struttura ad indice del documento. Inoltre nell'articolo non saranno affronti alcuni dettagli dell'implementazione, lasciando al pubblico "avanzo" la possibilità di autoreferenziare l'esempio proposto.


Gli elementi di base

Un file PDF è sostanzialmente un file di testo, inteso come sequenza di carteri e separori di linea (Chr(13)), di tipo strutturo, ovvero in cui le informazioni assumono un particolare significo in quanto inserite in strutture che rispettano una particolare sintassi.

Gli elementi di base sono gli oggetti "obj", che all'occorrenza possono contenere sequenze "stream", dizionari "dictonary" o altro. Un oggetto può rappresentare una pagina, un'immagine, una sequenza grafica, ecc.

Ogni oggetto, racchiuso tra le parole chiavi obj e endobj è identifico da un numero e da una revisione. Visto che non prenderemo in considerazione le modifiche di file crei in precedenza, tutti i nostri oggetti avranno come numero di revisione 0 (zero).


	2 0 obj
	.. .. .. .. ..
	endobj 

Gli oggetti non devono necessariamente presentarsi in ordine numerico ed è possibile fare riferimento ad un oggetto "futuro", ovvero non ancora definito; ciò risulta particolarmente utile e forse indispensabile in alcuni casi (ad esempio quando nel file è necessario indicare la lunghezza di un testo prima che il testo stesso sia sto inserito). Quando è necessario effettuare un riferimento ad un oggetto, basta indicare il suo numero e la revisione seguiti dalla lettera "R".


	.. ..
	/Parent 3 0 R
	.. ..

In generale ogni qualvolta è necessario utilizzare più volte lo stesso oggetto in più punti del documento, sia esso una immagine, sia esso una generica risorsa, ai fini dell'occupazione di memoria e della velocità di visualizzazione, conviene creare un oggetto che contenga la risorsa e utilizzare un riferimento a questo ogni qualvolta si rende necessario.

Le sequenze di di sono racchiusi tra le parole chiavi stream e endstream. Possono contenere qualsiasi sequenza di carteri (anche quelli non stampabili) e servono a descrivere un testo, un'immagine o altro.


	stream
	.. sequenza di carteri ..
	endstream

I dizionari sono coppie variabile/valore racchiuse tra i delimitori << e >>. Vengono utilizzi per carterizzare particolari oggetti, definendone gli tributi. Un valore può essere espresso con una costante numerica (la parte decimale prevede il punto e non la virgola), una stringa alfanumerica (delimita da una coppia di parentesi tonde), con un ulteriore dizionario, con un riferimento ad un oggetto o con un array (delimito da una coppia dei parentesi quadre).


	<<
	/Type /Page
	/Parent 3 0 R
	/Resources << /ProcSet 6 0 R >>
	/MediaBox [0 0 612 792]
	.. .. ..
	>>

Un file PDF non è altro che una opportuna sequenza di oggetti, costruiti rispettando una sintassi abbastanza semplice (tenzione alle maiuscole e minuscole), legi fra loro da riferimenti specifici, corredo da quanto necessario all'applicivo che legge il file (ad esempio Acrob Reader) per sapere dove recuperare le informazioni ed in quale ordine.


Struttura fisica di un file PDF

La struttura fisica di file PDF può essere riassunta nel seguente schema.

HEADER


BODY


CROSS-REFERENCE TABLE
TRAILER

La sezione HEADER contiene informazioni utili al software Reader per identificare il tipo di file e lo standard PDF utilizzo. E' rappresenta dalla prima riga del file ed è del tipo


	%PDF-1.3

ove il simbolo % indica in genere una riga di commento e 1.3 indica che per leggere correttamente le informazioni contenute nel file è necessario Acrob Reader 4.0 (piuttosto che 1.4 per il quale è necessario Acrob Reader 5.0, piuttosto che 1.5 per Acrob Reader 6.0). Nel prosieguo, noi considereremo di operare sempre con formi compibili con Acrob Reader 4.0 ovvero con una specifica %PDF-1.3.

La sezione BODY contiene gli oggetti che saranno rappresenti sulle pagine e sui quali ci soffermeremo in seguito.

La sezione CROSS-REFERENCE TABLE è una tabella che riporta un riferimento ad ogni oggetto presente nella sezione BODY e alla sua eventuale revisione; in particolare indica la posizione del primo cartere della definizione di un oggetto rispetto all'inizio del file e il numero di revisione a cui si riferisce.


	xref
	0 23
	0000000019 65535 f
	0000000009 00000 n
	.. .. ..
	0000000300 00000 n
	0000000384 00000 n

La sezione TRAILER indica al Reader quanti oggetti sono presenti nella sezione BODY (/Size), qual è l'oggetto iniziale (/Root), quale oggetto contiene le informazioni generali del documento quali autore, titolo, da di creazione (/Info), dove trovare la CROSS-REFERENCE TABLE ed inoltre segna la fine del file (%%EOF).


	trailer
	<<
	/Size 7
	/Root 1 0 R
	/Info 2 0 R
	>>
	startxref
	408
	%%EOF

Struttura logica di un documento PDF

La struttura logica di un documento PDF può essere riassunta nel seguente schema.

La struttura logica di un documento PDF

L'oggetto CALOG rappresenta la radice dell'intero documento e deve essere quello a cui punta il riferimento /Root presente nella sezione TRAILER.


	1 0 obj
	<<
	/Type /Calog
	/Pages 3 0 R
	/Outlines 20 0 R
	>>
	endobj

A sua volta, contiene un riferimento alla radice delle pagine (/Pages) e un riferimento alla radice della struttura ad albero che fa da indice (/Outlines), quello che di solito quando si apre un documento con Acrob Reader, appare a sinistra della pagina e permette di muoversi velocemente nel documento, e che noi per semplicità non analizzeremo.

L'oggetto PAGES rappresenta la radice delle pagine, indica il numero complessivo delle pagine del documento (/Count) e riporta un riferimento all'oggetto che contiene ogni pagina (/Kids).


	3 0 obj
	<<
	/Type /Pages
	/Count 3
	/Kids [4 0 R 8 0 R 10 0 R]
	>>
	endobj

L'oggetto PAGE riporta un riferimento alla propria radice (/Parent), un elenco delle risorse utilizze nella pagina (/Resources) (vedremo in seguito cosa sono), un array con le dimensione del formo di stampa previsto (/MediaBox) ed infine un riferimento all'oggetto che contiene gli elementi da rappresentare sulla pagina (/Contents).


	4 0 obj
	<<
	/Type /Page
	/Parent 3 0 R
	/Resources
	<<
	/ProcSet [/PDF /Text]
	>>
	/MediaBox [0 0 595.2 842]
	/Contents 5 0 R
	>>
	endobj

Se nel documento si vogliono riportare informazioni relive all'autore, all'applicivo che ha genero il file o la da di creazione, si può utilizzare il seguente oggetto (tenzione alle parentesi che fanno parte della sintassi). Queste informazioni appaiono se dal Reader si visualizzano le proprietà del documento.


	2 0 obj
	<<
	/Title (titolo_del_documento)"
	/Author (autore_del_documento)"
	/Creor  (applicivo_generore)"
	/Producer (info_copyright)"
	/CreionDe (D:yyyymmddhhmmss+01'00')
	>>

Il sistema di coordine

Il sistema di coordine predefinite in documento PDF ha come unità di misura il punto, definito come 1/72 di pollice. L'origine degli assi è posta nell'angolo in basso a sinistra. In questo sistema, il normale foglio A4 (21x29.7 cm) ha dimensione 595.2x842 punti. Per default tutte le immagini, a meno di una esplicita traslazione/scalura/rotazione, hanno dimensione 1x1 e sono poste con lo spigolo inferiore sinistro nell'origine (0,0).


Gli operori

Per la definizione degli elementi contenuti in ogni pagina, la sintassi dello standard PDF prevede l'uso di alcuni operori. Di seguito vedremo quelli necessari ai fini di questo articolo, rimandando ai testi in bibliografia per una descrizione più dettaglia. In particolare, bisogna tener conto che gli operori grafici descrivono solo un percorso (ph) che verrà traccio fisicamente solo quando verrà utilizzo un apposito operore e che le componenti di colore vanno da 0 a 1 e non da 0 a 255.

OPERORE DESCRIZIONE
X Y m Muove il punto di inserimento grafico alle coordine (X,Y)
X Y l Aggiunge una linea dal punto corrente al punto (X,Y) alla ph
X w Imposta la larghezza della linea a X punti
h Chiude una ph, disegnandone il traccio
n Termina un ph
f Chiude una ph e colora la regione delimita
r g b RG Imposta il colore per i contorni
r g b rg Imposta il colore per le aree
gray G Imposta un tono di grigio per i contorni
gray g Imposta un tono di grigio per le aree
x1 y1 x2 y2 x3 y3 c Aggiunge una curva Bezier alla ph
x y width height re Aggiunge un rettangolo alla ph
W 0 0 H X Y cm Mrice di trasformazione grafica di coordine
S Traccia la ph
s Chiude e traccia la ph
B Traccia la ph e colora la regione
BT Inizia una sequenza di testo
ET Termina una sequenza di testo
space Tc Imposta la spaziura tra carteri in millesimi di punto
space Tw Imposta la spaziura tra parole in millesimi di punto
scale Tz Imposta la scalura percentuale dei carteri
space TL Imposta l'interlinea
X Y Td Imposta il punto di inserimento del testo
fontname size Tf Imposta il font e la dimensione del cartere
string Tj Visualizza la stringa con il font corrente
/name Do Esegue l'oggetto name


Gli elementi di uso comune - Font e testo

Uno dei primi oggetti che analizziamo è l'oggetto necessario a descrivere un font. In questa fase vedremo come utilizzare uno dei 14 fonti TYPE1 predefiniti nel linguaggio PDF, ovvero font che il Reader conosce già e che non necessitano di particolari informazioni (viceversa, per altri tipi di font TrueType occorre fornire informazioni dettaglie, come ad esempio la larghezza in punti di ogni singolo cartere).
I 14 font predefiniti TYPE1 sono :


	CourierNew (.Italic, .Bold, .BoldItalic)
	Arial (.Italic, .Bold, .BoldItalic)
	TimesNewRoman  (.Italic, .Bold, .BoldItalic)
	ZapfDingbs
	Symbol

Per poterne utilizzare uno, occorre creare un oggetto che lo contenga. Nell'esempio che segue, l'oggetto 7, contiene il font Arial con tributi Grassetto e Corsivo, al font viene do il nome Fn1 e come tabella carteri viene indica quella ANSI.


	7 0 obj
	<<
	/Type /Font
	/Subtype /Type1
	/Name /Fn1
	/BaseFont /Arial.BoldItalic
	/Encoding /WinAnsiEncoding
	>>
	endobj

Quindi volendo scrivere il classico "Hello World" alla posizione di coordine (100,400) con il font definito in precedenza di nome Fn1, basterà inserire in un oggetto la sequenza


	% Scrive Hello World in Arial Bold Italic 24 punti
	BT
	/Fn1 24 Tf
	100 400 Td
	(Hello World) Tj
	ET

Gli elementi di uso comune - Grafica vettoriale

Se vogliamo inserire degli elementi grafici, basterà inserire una sequenza del tipo


	% Traccia un rettangolo rosso pieno con contorno blue
	.5 .75 1 rg
	1 0 0 RG
	200 300 50 75 re
	B

	% Traccia una linea con spessone 2 punti
	2 w 
	150 250 m
	150 350 l
	S

Gli elementi di uso comune - Immagini raster

Un altro oggetto di uso comune è quello necessario per rappresentare delle immagini di tipo raster (BMP). Per le immagini è possibile optare per due modalità: creare un oggetto che può essere richiamo ogni volta che la stessa immagine deve essere visualizza, anche se con dimensioni diverse (ed è questo il caso che noi analizzeremo) o definire l'immagine all'interno della pagina senza la possibilità di poterla riutilizzare. Ad esempio se si definisce una immagine Img1, 10 pixel per 5, 24 bit colore (8 x 3 componenti colore RGB), utilizzando una rappresentazione esadecimale, sono necessari 150 campioni, ovvero 10 x 5 x 3.


	12 0 obj
	<<
	/Type /XObject
	/Subtype /Image
	/Name /Img1
	/Width 10
	/Height 5
	/BitsPerComponent 8
	/ColorSpace /DeviceRGB
	/Filter /ASCIIHexDecode"
	/Length 13 0 R
	>>
	stream
	80 A1 2F .. .. %150 campioni esadecimali 
	endstream
	endobj

	13 0 obj
	150
	endobj

Notare come al posto della lunghezza dello stream è sto utilizzo un riferimento ad un oggetto (13 0) che contiene (solo) il valore 150. Se vogliamo visualizzare l'immagine con l'angolo inferiore sinistro nel punto (100, 80), con una dimensione orizzontale 200 e una verticale di 300, sarà sufficiente inserire la sequenza


q                          % salva lo sto grafico corrente
200 0 0 300 100 80 cm      % mrice di trasformazione di coordine
                           % necessaria per spostare/ingrandire l'immagine
/Img1 Do                   % visualizza l'immagine Img1
Q                          % ripristina lo sto grafico precedente

Analogamente la sequenza


.. ..
/BitsPerComponent 8
/ColorSpace /DeviceGray
/Length 50
>>
stream
$-#etT .. .. %50 carteri  
endstream
endobj

individua un'immagine in toni di grigio (1 sola componente colore), rappresenta con una sequenza di 50 campioni (10x5x1)


Gli elementi di uso comune - Le Form

Capita spesso che porzioni di documenti, vadano riprodotte più volte, come ad esempio le intestazioni, i piè di pagina, i wermark (quelle scritte oblique sotto al testo tipo bozza, uso interno, …). Lo standard PDF prevede l'uso di un particolare oggetto, appunto le form, che chiariamo subito, non hanno nulla a che fare con le form di Visual Basic. Ad esempio tutto ciò che è contenuto nello stream dell'oggetto 13 con nome Frm1 (il significo degli altri tributi lo vedremo la prossima volta),


	13 0 obj
	<<
	/Type /XObject
	/Subtype /Form
	/FormType 1
	/Name /Frm1
	/BBox [0 0 595.2 842]
	/Mrix [1 0 0 1 0 0]
	/Length 14 0 R >>
	stream
	.. .. .. .. .. 
	endstream
	endobj

può essere riprodotto, ovunque, con la sequenza


	/Frm1 Do

Conclusioni

Quanto descritto è un buon punto di partenza per la realizzazione di una propria libreria per creazione di documenti PDF, indipendentemente dal linguaggio utilizzo. Nella seconda parte vedremo come applicare e sfruttare il tutto in Visual Basic 6.0, commentando e realizzando un esempio completo. Per chi non riesce a resistere fino alla prossima punta, consiglio di iniziare a smanettare con un documento PDF (piccolo, magari da 1 sola pagina), aprendolo con un elaborore di testi (ad esempio WordPad) e provare a riconoscere le strutture descritte.


Bibliografia

Per maggiori informazioni e approfondimenti sugli argomenti trti in questo articolo, consiglio le seguenti letture:

"PDF Reference 15"
http://partners.adobe.com/asn/tech/pdf/specificions.jsp

"Documentazione ed editoria elettronica mediante tecnologia PDF" - Tesi di laurea
http://elite.polito.it/tesi/bertoghisio.pdf



   Invia il link di questo articolo ad un amico  Invia ad un amico Visualizza la versione stampabile di questo articolo  Stampa Commenta questo Articolo  Commenta Parlane in Chat  Chat   Parlane sul Forum  Forum