From 642428cd0e23a9792acfcb073156fe0b72eb142f Mon Sep 17 00:00:00 2001 From: Kurt Jung Date: Sun, 8 Sep 2013 09:31:34 -0400 Subject: Bookmark outline support submitted by Manuel Cornes --- fpdf.go | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) (limited to 'fpdf.go') diff --git a/fpdf.go b/fpdf.go index a7fb350..2a15310 100644 --- a/fpdf.go +++ b/fpdf.go @@ -1381,6 +1381,20 @@ func (f *Fpdf) LinkString(x, y, w, h float64, linkStr string) { f.newLink(x, y, w, h, 0, linkStr) } +// Sets a bookmark that will be displayed in a sidebar outline. txtStr is the +// title of the bookmark. level specifies the level of the bookmark in the +// outline; 0 is the top level, 1 is just below, and so on. y specifies the +// vertical position of the bookmark destination in the current page; -1 +// indicates the current position. +// +// See tutorial 16 for an bookmark example. +func (f *Fpdf) Bookmark(txtStr string, level int, y float64) { + if y == -1 { + y = f.y + } + f.outlines = append(f.outlines, outlineType{text: txtStr, level: level, y: y, p: f.PageNo(), prev: -1, last: -1, next: -1, first: -1}) +} + // Prints a character string. The origin (x, y) is on the left of the first // character at the baseline. This method allows to place a string precisely on // the page, but it is usually easier to use Cell(), MultiCell() or Write() @@ -2844,6 +2858,11 @@ func (f *Fpdf) putcatalog() { case "two": f.out("/PageLayout /TwoColumnLeft") } + // Bookmarks + if len(f.outlines) > 0 { + f.outf("/Outlines %d 0 R", f.outlineRoot) + f.out("/PageMode /UseOutlines") + } } func (f *Fpdf) putheader() { @@ -2859,6 +2878,59 @@ func (f *Fpdf) puttrailer() { f.outf("/Info %d 0 R", f.n-1) } +func (f *Fpdf) putbookmarks() { + nb := len(f.outlines) + if nb > 0 { + lru := make(map[int]int) + level := 0 + for i, o := range f.outlines { + if o.level > 0 { + parent := lru[o.level-1] + f.outlines[i].parent = parent + f.outlines[parent].last = i + if o.level > level { + f.outlines[parent].first = i + } + } else { + f.outlines[i].parent = nb + } + if o.level <= level && i > 0 { + prev := lru[o.level] + f.outlines[prev].next = i + f.outlines[i].prev = prev + } + lru[o.level] = i + level = o.level + } + n := f.n + 1 + for _, o := range f.outlines { + f.newobj() + f.outf("<>") + f.out("endobj") + } + f.newobj() + f.outlineRoot = f.n + f.outf("<>", n+lru[0]) + f.out("endobj") + } +} + func (f *Fpdf) enddoc() { if f.err != nil { return @@ -2869,6 +2941,8 @@ func (f *Fpdf) enddoc() { if f.err != nil { return } + // Bookmarks + f.putbookmarks() // Info f.newobj() f.out("<<") -- cgit v1.2.1-24-ge1ad