2011-01-10 8 views
6

Przeczytałem w specyfikacji Adobe PDF, wraz z 2-cyfrową dokumentacją kwarcu Apple do renderowania i parsowania PDF. Pobrałem też Voyeur i sprawdziłem lokalny plik pdf, aby zobaczyć jego wewnętrzne dane. W tym momencie mogę pobrać katalog dokumentów, a następnie pobrać z niego słownik obrysów. Widzę, że zagnieżdżone w kontury słowników słownika że nie są nazywane „/ docelowy” węzły z wartościami takimi jak:Jak uzyskać numer strony lub odniesienie do strony dla miejsca docelowego konturu w pliku PDF w systemie iOS?

G1.1025588 itp

Zastanawiam się, czy istnieje sposób dla mnie do korzystania te wartości, aby uzyskać odniesienie do strony do renderowania za pomocą niektórych metod Widziałem projekty Github, takie jak Reader, wraz z udokumentowanymi przykładami Apple.

Przetwarzanie plików PDF to zdecydowanie wyzwanie, więc każda pomoc zostanie doceniona.

+0

interesujący pytanie –

Odpowiedz

3

Wpis w słowniku poz zarys /Dest może być albo nazwa, A ciąg, lub tablica.

  • W najprostszym przypadku, gdy jest to Tablica; następnie pierwszy element to obiekt strony, do którego wskazuje punkt wejścia (słownik). Aby uzyskać numer strony, musisz powtórzyć wszystkie strony w dokumencie i sprawdzić, który z nich jest równy (==) do słownika, który posiadasz (CGPDFPageRef s to w rzeczywistości CGPDFDictionaryRef s). Możesz także przejść przez drzewo stron, które jest nieco trudniejsze, ale może być szybsze (nie tak dużo, jak można się było spodziewać, nie zoptymalizowałem przedwcześnie tutaj). Pozostałe elementy w tablicy to pozycja na stronie itp., Wyszukaj "Wyraźne miejsca docelowe" w specyfikacji PDF, aby dowiedzieć się więcej.

  • Jeśli wpis jest nazwa lub ciąg, jest to nazwane miejsca przeznaczenia. Musisz zamapować nazwę do miejsca docelowego z wpisu katalogu dokumentu /Dests, który jest słownikiem zawierającym drzewo nazw. Drzewo nazw jest zasadniczo mapą drzewa, która umożliwia szybki dostęp do nazwanych wartości bez konieczności odczytywania wszystkich danych naraz (jak w przypadku zwykłego słownika). Niestety, nie ma bezpośredniego wsparcia dla drzew nazw w Quartz, więc będziesz musiał wykonać trochę więcej pracy, aby parsować tę strukturę rekurencyjnie (patrz "Drzewa nazw" w PDF spec).

pamiętać, że pozycja zarys niekoniecznie posiadają wpis /Dest, może także określić swój cel poprzez /A (Działanie) wpisu, który jest nieco bardziej skomplikowana. Jednak w większości przypadków akcja będzie działaniem "GoTo", które jest zasadniczo opakowaniem dla miejsca docelowego.

Mapowanie nazw do miejsc docelowych można również zapisać jako zwykły słownik. W takim przypadku jest to wpis /Dests słownika/Names w katalogu dokumentu. Jednak rzadko to widywałem i został wycofany po PDF 1.2 (obecny jest 1.7).

pewno trzeba spec PDF dla tego: http://www.adobe.com/content/dam/Adobe/en/devnet/pdf/pdfs/PDF32000_2008.pdf

+0

dziękuję za informacje. Dokumenty, nad którymi teraz pracuję, są odmiany/A i Goto. Obecnie jestem w punkcie, w którym mogę utworzyć jeden z tytułów stron w spisie treści. Widzę słowniki strony/A/D/0 w konturach i odpowiadających im słowników strony A/D/0 na stronach. Próbuję utworzyć słownik tytułu-> strony nvp, ale nie mogę dodać CGPDFDictionaryRef do NSDictionary ... – shawnwall

+1

Sprawdziłem równość przez porównanie wartości łańcuchów treści słowników strony toc i rzeczywiste słowniki stron na stronie ... nie wydają się czyste, ale działają. Czy istnieje lepszy sposób? – shawnwall

+0

jak uzyskać wartość ciągu strumieni treści? czy mógłbyś dać mi więcej wskazówek? W moim przypadku "/Outlines/.../A/D/0" działa dobrze, ale nie mogę sprawdzić równości z "/Annots/.../A/D/0" – Joey

0

Dzięki OMZ, oto fragment kodu do retreive numer strony dla docelowego konspektu w pliku PDF:

// Get Page Number from an array 
- (int) getPageNumberFromArray:(CGPDFArrayRef)array ofPdfDoc:(CGPDFDocumentRef)pdfDoc withNumberOfPages:(int)numberOfPages 
{ 
    int pageNumber = -1; 

    // Page number reference is the first element of array (el 0) 
    CGPDFDictionaryRef pageDic; 
    CGPDFArrayGetDictionary(array, 0, &pageDic); 

    // page searching 
    for (int p=1; p<=numberOfPages; p++) 
    { 
     CGPDFPageRef page = CGPDFDocumentGetPage(pdfDoc, p); 
     if (CGPDFPageGetDictionary(page) == pageDic) 
     { 
      pageNumber = p; 
      break; 
     } 
    } 

    return pageNumber; 
} 

// Get page number from an outline. Only support "Dest" and "A" entries 
- (int) getPageNumber:(CGPDFDictionaryRef)node ofPdfDoc:(CGPDFDocumentRef)pdfDoc withNumberOfPages:(int)numberOfPages 
{ 
    int pageNumber = -1; 

    CGPDFArrayRef destArray; 
    CGPDFDictionaryRef dicoActions; 
    if(CGPDFDictionaryGetArray(node, "Dest", &destArray)) 
    { 
     pageNumber = [self getPageNumberFromArray:destArray ofPdfDoc:pdfDoc withNumberOfPages:numberOfPages]; 
    } 
    else if(CGPDFDictionaryGetDictionary(node, "A", &dicoActions)) 
    { 
     const char * typeOfActionConstChar; 
     CGPDFDictionaryGetName(dicoActions, "S", &typeOfActionConstChar); 

     NSString * typeOfAction = [NSString stringWithUTF8String:typeOfActionConstChar]; 
     if([typeOfAction isEqualToString:@"GoTo"]) // only support "GoTo" entry. See PDF spec p653 
     { 
      CGPDFArrayRef dArray; 
      if(CGPDFDictionaryGetArray(dicoActions, "D", &dArray)) 
      { 
       pageNumber = [self getPageNumberFromArray:dArray ofPdfDoc:pdfDoc withNumberOfPages:numberOfPages]; 
      } 
     } 
    } 

    return pageNumber; 
} 
Powiązane problemy