2010-12-12 4 views
8

Sto costruendo un'applicazione per iPad che visualizza PDF e mi piacerebbe poter visualizzare il sommario e consentire all'utente di navigare nelle pagine pertinenti.Come ottenere i dati del sommario (schema) PDF in iOS (iPad)?

Ho investito parecchie ore nella ricerca a questo punto, e sembra che dal momento che PDFKit è [non supportato in iOS], la mia unica opzione è quella di analizzare manualmente i metadati PDF.

Ho esaminato diverse soluzioni, ma tutte sono silenziose su un punto: come associare una pagina nei metadati "struttura" con il numero di pagina reale dell'elemento. Ho esaminato il mio documento PDF con [lo strumento Voyeur] e posso vedere il contorno dell'albero.

[Questa soluzione] mi ha aiutato a capire come navigare lungo l'albero Outline/A/S/D per trovare l'oggetto "Dest", ma esegue una sorta di confronto degli oggetti usando [self.pages indexOfObjectIdenticalTo: destPageDic] che non capisco

Ho letto il [spec ufficiale PDF da Adobe], e la sezione "12.3.2.3 Meta Named" descrive il modo in cui una voce dello schema può puntare a una pagina:

Invece di essere definito direttamente con la sintassi esplicita mostrata nella Tabella 151, una destinazione può essere indirizzata a indirettamente tramite un oggetto nome (PDF 1.1) o una stringa di byte (PDF 1.2).

e continua con questa linea, che è del tutto incomprensibile per me:

Il valore di questa voce sarà un dizionario in cui ogni tasto è un nome di destinazione ed il corrispondente valore è o un array che definisce la destinazione , usando la sintassi mostrata in Tabella 151, o un dizionario con una voce D il cui valore è una tale matrice.

Questo si riferisce alla pagina 366, "12.3.2.2 Meta espliciti", in cui una tabella descrive una pagina: "In ogni caso, la pagina è un riferimento indiretto a un oggetto pagina"

Così è il risultato di CGPDFDocumentGetPage o CGPDFPageGetDictionary un "riferimento indiretto a un oggetto di pagina"?

Ho trovato un [thread su lists.apple.com] che discute. [Questo commento] implica che è possibile confrontare l'indirizzo (in memoria?) Di un oggetto CGPDFPageGetDictionary per una determinata pagina e confrontarlo con le pagine nell'albero "Struttura" dei metadati PDF.

Tuttavia, quando guardo l'indirizzo degli oggetti della pagina nell'albero Struttura e li confronta con gli indirizzi non sono mai gli stessi. La linea utilizzata in quel thread "TTDPRINT (@"% d =>% p ", k + 1, dict);" sta stampando "dict" come un puntatore nella memoria .. non c'è motivo di credere che un oggetto ritornato sarebbe lo stesso di quello restituito da qualche altra parte ... sarebbero in posti diversi nella memoria!

La mia ultima speranza era di guardare il codice sorgente dallo strumento "outline" della riga di comando di Apple [menzionato in questo libro] (come [suggerito da questa discussione]), ma non riesco a trovarlo da nessuna parte.

Bottom line: qualcuno ha qualche idea su come funzionano i profili PDF, o conosce qualche codice open source (preferibilmente l'obiettivo-c) che legge i contorni PDF?

ARGG: avevo tutti i tipi di link postato qui, ma a quanto pare un nuovo utente può inviare un solo collegamento alla volta

risposta

3

Il risultato CGPDFDocumentGetPage è lo stesso di un riferimento pagina indiretta che si ottiene quando la risoluzione una destinazione in un elemento del contorno. Entrambi sono essenzialmente dizionari e puoi confrontarli usando ==. Quando si ha un CGPDFDictionaryRef che volete sapere il numero di pagina, si può fare qualcosa di simile:

CGPDFDocumentRef doc = ...; 
CGPDFDictionaryRef outlinePageRef = ...; 
for (int p=1; p<=CGPDFDocumentGetNumberOfPages(doc); p++) { 
    CGPDFPageRef page = CGPDFDocumentGetPage(doc, p); 
    if (page == outlinePageRef) { 
    printf("found the page number: %i", p); 
    break; 
    } 
} 

Una destinazione esplicito, tuttavia, non è una pagina, ma un array con il primo elemento è la pagina. Gli altri elementi sono la posizione di scorrimento sulla pagina ecc.

+0

Questa è una risposta eccellente. Il tuo obiettivo alla fine dovrebbe essere quello di creare un nsdictionary che contenga coppie chiave/val per titolo-> numero di pagina. Questo costituirà il TOC. – shawnwall

+1

In realtà, non è possibile confrontare outlinePageRef direttamente con CGPDFPageRef, ma è possibile confrontarlo con 'CGPDFPageGetDictionary (pagina)'. – 0xced

Problemi correlati