// transforms the page tree from the file into an array of pages func getPages(file *pdf.File, ref pdf.ObjectReference) []pdf.IndirectObject { pages := []pdf.IndirectObject{} page_node := file.Get(ref).(pdf.Dictionary) switch page_node["Type"] { case pdf.Name("Pages"): for _, kid_ref := range page_node["Kids"].(pdf.Array) { kid_pages := getPages(file, kid_ref.(pdf.ObjectReference)) pages = append(pages, kid_pages...) } case pdf.Name("Page"): pages = append(pages, pdf.IndirectObject{ ObjectReference: ref, Object: page_node, }) default: panic(string(page_node["Type"].(pdf.Name))) } return pages }
func mergePageTrees(file *pdf.File, catalogs []pdf.Dictionary) pdf.ObjectReference { // reserve a reference for the new page tree root // needed to set the parent for the old page tree roots pageTreeRef, err := file.Add(pdf.Null{}) if err != nil { log.Fatalln(err) } // use the old page tree roots as our page tree kids kids := pdf.Array{} pageCount := pdf.Integer(0) for _, catalog := range catalogs { // add the old page tree root to our list of kids pagesRef := catalog["Pages"].(pdf.ObjectReference) kids = append(kids, pagesRef) // now that the old page tree root is a kid, it needs a parent pages := file.Get(pagesRef).(pdf.Dictionary) pages["Parent"] = pageTreeRef _, err = file.Add(pdf.IndirectObject{ ObjectReference: pagesRef, Object: pages, }) if err != nil { log.Fatalln(err) } pageCount += pages["Count"].(pdf.Integer) } // create the merged page tree _, err = file.Add(pdf.IndirectObject{ ObjectReference: pageTreeRef, Object: pdf.Dictionary{ "Type": pdf.Name("Pages"), "Kids": kids, "Count": pageCount, }, }) if err != nil { log.Fatalln(err) } return pageTreeRef }
// transforms the page tree from the file into an array of pages func getPages(file *pdf.File, ref pdf.ObjectReference) []pdf.Dictionary { pages := []pdf.Dictionary{} pageNode := file.Get(ref).(pdf.Dictionary) switch pageNode["Type"] { case pdf.Name("Pages"): for _, kidRef := range pageNode["Kids"].(pdf.Array) { kidPages := getPages(file, kidRef.(pdf.ObjectReference)) pages = append(pages, kidPages...) file.Free(kidRef.(pdf.ObjectReference).ObjectNumber) } case pdf.Name("Page"): pages = append(pages, pageNode) file.Free(ref.ObjectNumber) default: panic(string(pageNode["Type"].(pdf.Name))) } return pages }
func copyReferencedObjects(refs map[pdf.ObjectReference]pdf.ObjectReference, dst, src *pdf.File, obj pdf.Object) (map[pdf.ObjectReference]pdf.ObjectReference, pdf.Object) { var merge = func(newRefs map[pdf.ObjectReference]pdf.ObjectReference) { for k, v := range newRefs { refs[k] = v } } switch t := obj.(type) { case pdf.ObjectReference: if _, ok := refs[t]; ok { obj = refs[t] break } // get an object reference for the copied obj // needed to break reference cycles ref, err := dst.Add(pdf.Null{}) if err != nil { log.Fatalln(err) } refs[t] = ref newRefs, newObj := copyReferencedObjects(refs, dst, src, src.Get(t)) merge(newRefs) // now actually add the object to dst refs[t], err = dst.Add(pdf.IndirectObject{ ObjectReference: ref, Object: newObj, }) if err != nil { log.Fatalln(err) } obj = refs[t] case pdf.Dictionary: for k, v := range t { var newRefs map[pdf.ObjectReference]pdf.ObjectReference newRefs, t[k] = copyReferencedObjects(refs, dst, src, v) merge(newRefs) } obj = t case pdf.Array: for i, v := range t { var newRefs map[pdf.ObjectReference]pdf.ObjectReference newRefs, t[i] = copyReferencedObjects(refs, dst, src, v) merge(newRefs) } obj = t case pdf.Stream: for k, v := range t.Dictionary { var newRefs map[pdf.ObjectReference]pdf.ObjectReference newRefs, t.Dictionary[k] = copyReferencedObjects(refs, dst, src, v) merge(newRefs) } obj = t case pdf.Name, pdf.Integer, pdf.String, pdf.Real: // these types can't have references default: log.Fatalf("unhandled %T", obj) } return refs, obj }