Documentation
¶
Overview ¶
Package pdf provides a PDF viewer widget for Fyne, written in pure Go.
Document is a ready-to-use viewer with a thumbnail strip and zoom controls. Source gives goroutine-safe low-level access to an opened PDF (page count, bounds, rendering, metadata), and NewImageFromMemory renders a single page without any UI.
Page indices are 0-based throughout the package.
Index ¶
- Constants
- func NewImageFromMemory(contents []byte, pageNumber int, documentCallbacks ...DocumentCallbackFn) (image.Image, error)
- type Document
- func (d *Document) ClearSearch()
- func (d *Document) Close() error
- func (d *Document) CreateRenderer() fyne.WidgetRenderer
- func (d *Document) CurrentPage() int
- func (d *Document) CurrentSearchResult() int
- func (d *Document) LoadFromMemory(contents []byte) error
- func (d *Document) NextSearchResult()
- func (d *Document) PageCount() int
- func (d *Document) PreviousSearchResult()
- func (d *Document) Refresh()
- func (d *Document) Resize(size fyne.Size)
- func (d *Document) Search(query string, opt SearchOptions)
- func (d *Document) SearchProgress() (searched, total int)
- func (d *Document) SearchQuery() string
- func (d *Document) SearchResults() []SearchResult
- func (d *Document) Searching() bool
- func (d *Document) SetViewMode(mode ViewMode)
- func (d *Document) ShowPage(page int)
- func (d *Document) ShowSearchResult(i int)
- func (d *Document) ViewMode() ViewMode
- func (d *Document) Zoom(scale float64)
- func (d *Document) ZoomToFit()
- func (d *Document) ZoomToFitHorizontal()
- func (d *Document) ZoomToFitVertical()
- type DocumentCallbackFn
- type Highlight
- type Metadata
- type Page
- type Rect
- type SearchOptions
- type SearchResult
- type Source
- func (s *Source) Bound(page int) (image.Rectangle, error)
- func (s *Source) Close() error
- func (s *Source) Metadata() Metadata
- func (s *Source) PageCount() int
- func (s *Source) PageText(ctx context.Context, page int) (string, error)
- func (s *Source) RenderPage(page int, dpi float64) (image.Image, error)
- func (s *Source) RenderPageContext(ctx context.Context, page int, dpi float64) (image.Image, error)
- func (s *Source) Search(ctx context.Context, query string, opt SearchOptions) ([]SearchResult, error)
- func (s *Source) SearchPage(ctx context.Context, page int, query string, opt SearchOptions) ([]SearchResult, error)
- type Thumbnail
- func (t *Thumbnail) CreateRenderer() fyne.WidgetRenderer
- func (t *Thumbnail) Selected() bool
- func (t *Thumbnail) SetImage(theImage image.Image)
- func (t *Thumbnail) SetMinimumSize(size fyne.Size)
- func (t *Thumbnail) SetSelected(selected bool)
- func (t *Thumbnail) SetTitle(title string)
- func (t *Thumbnail) Tapped(_ *fyne.PointEvent)
- type ViewMode
Examples ¶
Constants ¶
const ThumbnailMinimumDimension = float32(100)
ThumbnailMinimumDimension is the default width and height of a thumbnail.
Variables ¶
This section is empty.
Functions ¶
func NewImageFromMemory ¶
func NewImageFromMemory(contents []byte, pageNumber int, documentCallbacks ...DocumentCallbackFn) (image.Image, error)
NewImageFromMemory renders page pageNumber (0-based) of the PDF in contents at 144 dpi. documentCallbacks are called with the opened Source before rendering.
Example ¶
package main
import (
"fmt"
"os"
pdf "github.com/timzifer/fyne-pdf"
)
func main() {
contents, err := os.ReadFile("example.pdf")
if err != nil {
panic(err)
}
img, err := pdf.NewImageFromMemory(contents, 0)
if err != nil {
panic(err)
}
fmt.Println(img.Bounds().Size())
}
Output:
Types ¶
type Document ¶
type Document struct {
widget.BaseWidget
// BackgroundColor fills the area around the pages. If nil, the
// theme's separator color is used.
BackgroundColor color.Color
// SaveCallback, if set, shows a save button in the toolbar that calls
// it. Call Refresh after changing it.
SaveCallback func()
// OnError is called on the main goroutine when a page cannot be
// rendered. If nil, the error is logged.
OnError func(page int, err error)
// OnSearchChanged is called on the main goroutine when the search
// changes: results found, the current result, the search done or
// cleared. See [Document.Search].
OnSearchChanged func()
// HighlightColor fills the search results on the pages,
// CurrentHighlightColor the current one. If nil, translucent
// yellow and orange are used.
HighlightColor, CurrentHighlightColor color.Color
// contains filtered or unexported fields
}
Document is a PDF viewer widget: a page view with a toolbar for zooming and a thumbnail strip for navigation. Create it with NewDocument.
The page view shows one page at a time or, see Document.SetViewMode, all pages one below the other. It supports the usual viewer gestures: Ctrl+wheel (Cmd on macOS) zooms around the pointer, dragging pans, a double tap switches between the fitted page and 100 %; showing one page, scrolling on past its top or bottom turns it. Once clicked, it takes the keyboard focus: Page Up/Down and Space scroll by a screen, Home/End go to the first and last page, the arrow keys scroll (Left/Right go to the previous and next page while the pages fit horizontally), Ctrl +/-/0 zoom.
Document.Search finds text in the background and highlights the results on the pages; F3 and Shift+F3 go to the next and previous one.
Pages are rendered in the background, those in view first; the resolution of the main view follows the zoom level. Methods must be called from the Fyne main goroutine (or before the app runs).
func NewDocument ¶
func NewDocument() *Document
NewDocument creates an empty viewer. Load a PDF with Document.LoadFromMemory.
func (*Document) ClearSearch ¶ added in v0.6.0
func (d *Document) ClearSearch()
ClearSearch ends the search and removes its highlights.
func (*Document) Close ¶
Close releases the loaded PDF and stops pending renders. Pages already shown stay visible.
func (*Document) CreateRenderer ¶
func (d *Document) CreateRenderer() fyne.WidgetRenderer
func (*Document) CurrentPage ¶
CurrentPage returns the index (0-based) of the page shown in the main view. Showing all pages, it is the page at the centre of the view, or the one last gone to with Document.ShowPage or a key until the view is scrolled.
func (*Document) CurrentSearchResult ¶ added in v0.6.0
CurrentSearchResult returns the index of the current result into SearchResults, or -1 if there is none.
func (*Document) LoadFromMemory ¶
LoadFromMemory opens the PDF in contents and shows its first page. A previously loaded PDF is closed. Pages are rendered in the background.
func (*Document) NextSearchResult ¶ added in v0.6.0
func (d *Document) NextSearchResult()
NextSearchResult makes the result after the current one current, wrapping around to the first, and scrolls to it. Without a current result, it goes to the first result at or after the current page.
func (*Document) PreviousSearchResult ¶ added in v0.6.0
func (d *Document) PreviousSearchResult()
PreviousSearchResult makes the result before the current one current, wrapping around to the last, and scrolls to it. Without a current result, it goes to the last result at or before the current page.
func (*Document) Resize ¶
Resize lays out the widget. While the page is fitted to the view (after ShowPage or one of the ZoomToFit methods), the fit follows the new size.
func (*Document) Search ¶ added in v0.6.0
func (d *Document) Search(query string, opt SearchOptions)
Search finds query in the document, in the background: pages from the current one to the end first, then those before it. The results are highlighted on the pages as they are found; the first one at or after the current page becomes the current result, and the view scrolls to it. OnSearchChanged reports the progress. An empty query, like Document.ClearSearch, ends the search and removes the highlights. Loading another document ends it, too.
func (*Document) SearchProgress ¶ added in v0.6.0
SearchProgress returns the number of pages searched so far and the number of pages to search.
func (*Document) SearchQuery ¶ added in v0.6.0
SearchQuery returns the query of the last search, "" after ClearSearch.
func (*Document) SearchResults ¶ added in v0.6.0
func (d *Document) SearchResults() []SearchResult
SearchResults returns the results found so far, sorted by page and in reading order on a page. While the search runs, results of pages before the page it started at are inserted in front of those found earlier.
func (*Document) Searching ¶ added in v0.6.0
Searching reports whether the search is still going through the pages.
func (*Document) SetViewMode ¶ added in v0.5.0
SetViewMode switches between showing one page at a time (ViewSinglePage, the default) and all pages one below the other (ViewContinuous). The current page stays in view, as do the zoom and the fit. The toolbar has a button for it, too.
func (*Document) ShowPage ¶
ShowPage makes page (0-based) current. Showing one page at a time, it shows page fitted into the view. Showing all pages, it scrolls to the top of page and keeps the zoom, or the fit applied to page.
func (*Document) ShowSearchResult ¶ added in v0.6.0
ShowSearchResult makes result i (an index into SearchResults) the current result, highlighted in CurrentHighlightColor, and scrolls the view so it is visible: to its page and, unless it is in view already, with the result at the centre of the view.
func (*Document) Zoom ¶
Zoom sets the zoom factor; 1 shows the page at roughly its physical size. The factor is clamped to 0.2 to 4.
func (*Document) ZoomToFit ¶
func (d *Document) ZoomToFit()
ZoomToFit scales the current page so it fits completely into the view; showing all pages, it also scrolls to the top of that page. The fit is kept when the view is resized, until the zoom is changed otherwise; the same holds for ZoomToFitVertical and ZoomToFitHorizontal.
func (*Document) ZoomToFitHorizontal ¶
func (d *Document) ZoomToFitHorizontal()
ZoomToFitHorizontal scales the current page to the width of the view.
func (*Document) ZoomToFitVertical ¶
func (d *Document) ZoomToFitVertical()
ZoomToFitVertical scales the current page to the height of the view.
type DocumentCallbackFn ¶
type DocumentCallbackFn func(src *Source)
DocumentCallbackFn is called with the opened Source before rendering, see NewImageFromMemory.
type Highlight ¶ added in v0.6.0
Highlight marks an area of a Page, such as a search result: a rectangle in the units of Page.PageSize (at Scale 1, origin at the top left of the page), filled with Color over the page image. Use a translucent color to keep the text readable.
type Metadata ¶ added in v0.5.0
type Metadata struct {
Title, Author, Subject, Keywords, Creator, Producer string
// Created and Modified are zero when absent or not a date.
Created, Modified time.Time
// Trapped is "True", "False", "Unknown" or "".
Trapped string
// Custom holds the other string entries of /Info, by key as written
// in the document ("Department", ...).
Custom map[string]string
// XMP is the catalog's /Metadata stream, decoded but not parsed; nil if
// there is none.
XMP []byte
}
Metadata is what a document says about itself: its document information dictionary (/Info), decoded, and its XMP metadata stream.
type Page ¶
type Page struct {
widget.BaseWidget
Scale float64
BackgroundColor color.Color
// contains filtered or unexported fields
}
Page displays a single rendered page image at Page.PageSize multiplied by Scale, which is also its minimum size. A larger widget centres the page on BackgroundColor. The image is scaled to the page size, so it can be rendered at any resolution; the aspect ratio is kept. Highlights, see Page.SetHighlights, are drawn over the image.
func NewPageWithImage ¶
NewPageWithImage creates a Page showing img.
func (*Page) CreateRenderer ¶
func (p *Page) CreateRenderer() fyne.WidgetRenderer
func (*Page) Highlights ¶ added in v0.6.0
Highlights returns the highlights drawn over the page.
func (*Page) PageSize ¶
PageSize returns the size of the page at Scale 1. Unless set with Page.SetPageSize, this is the size of the page image in pixels.
func (*Page) SetHighlights ¶ added in v0.6.0
SetHighlights replaces the highlights drawn over the page; nil removes them.
func (*Page) SetPageSize ¶
SetPageSize sets the size of the page at Scale 1, independent of the resolution of the image.
type Rect ¶ added in v0.6.0
type Rect struct {
X0, Y0, X1, Y1 float64
}
Rect is a rectangle on a page in points (1/72 inch) of the page as it is displayed: origin at the top left corner, y down, /Rotate and /UserUnit applied, like Source.Bound.
type SearchOptions ¶ added in v0.6.0
type SearchOptions struct {
// MatchCase tells upper and lower case apart.
MatchCase bool
// WholeWord matches the query only where it neither continues a word
// before nor after it.
WholeWord bool
// IgnoreDiacritics finds "resume" in "résumé" and reads compatibility
// characters as what they stand for, such as "2" for "²".
IgnoreDiacritics bool
}
SearchOptions control how a query is matched. The zero value matches case-insensitively anywhere in a word.
type SearchResult ¶ added in v0.6.0
type SearchResult struct {
// Page is the index (0-based) of the page.
Page int
// Text is the text found, Prefix and Suffix up to 32 characters of the
// text before and after it, for a result list. White space in them is
// one space.
Prefix, Text, Suffix string
// Rects cover the text found, one per line it spans.
Rects []Rect
}
SearchResult is a place on a page where the query was found.
func (SearchResult) Bounds ¶ added in v0.6.0
func (r SearchResult) Bounds() Rect
Bounds returns the smallest rectangle around the rects of r.
type Source ¶
type Source struct {
// contains filtered or unexported fields
}
Source is an opened PDF. All methods are safe for concurrent use: cera only allows interpreting pages of a document from one goroutine at a time, hence the mutex. A single page is still rasterized by cera on all cores.
func OpenSource ¶
OpenSource parses the PDF in contents.
Example ¶
package main
import (
"fmt"
"os"
pdf "github.com/timzifer/fyne-pdf"
)
func main() {
contents, err := os.ReadFile("example.pdf")
if err != nil {
panic(err)
}
src, err := pdf.OpenSource(contents)
if err != nil {
panic(err)
}
defer func() { _ = src.Close() }()
fmt.Println("pages:", src.PageCount())
fmt.Println("title:", src.Metadata().Title)
img, err := src.RenderPage(0, 300)
if err != nil {
panic(err)
}
fmt.Println("size:", img.Bounds().Size())
}
Output:
func (*Source) Bound ¶
Bound returns the visible area of page (0-based) in points (72 dpi), with /Rotate and /UserUnit already applied.
func (*Source) Close ¶
Close releases the document. Afterwards all methods return an error or zero pages. Closing more than once is allowed.
func (*Source) Metadata ¶
Metadata returns the document's metadata, or the zero Metadata after Close. A missing or damaged /Info gives empty fields.
func (*Source) PageText ¶ added in v0.6.0
PageText returns the text of page (0-based) in reading order: lines separated by a line break, blocks of text by an empty line.
func (*Source) RenderPage ¶
RenderPage renders page (0-based) at the given resolution onto a white background. If rendering takes longer than 15 seconds, the partially drawn image is returned without an error.
func (*Source) RenderPageContext ¶
RenderPageContext is like Source.RenderPage, but stops early and returns ctx.Err() when ctx is cancelled.
func (*Source) Search ¶ added in v0.6.0
func (s *Source) Search(ctx context.Context, query string, opt SearchOptions) ([]SearchResult, error)
Search returns the places of query in the whole document, page by page, as Source.SearchPage finds them. Pages whose text cannot be read are skipped; their errors are returned joined, with the results of the other pages. When ctx ends, Search returns the results so far and ctx.Err().
func (*Source) SearchPage ¶ added in v0.6.0
func (s *Source) SearchPage(ctx context.Context, page int, query string, opt SearchOptions) ([]SearchResult, error)
SearchPage returns the places of query on page (0-based), in reading order and not overlapping. Runs of white space in the text and the query match one space, and words broken across lines by a hyphen are found joined. An empty query finds nothing.
type Thumbnail ¶
type Thumbnail struct {
widget.BaseWidget
OnTapped func()
// contains filtered or unexported fields
}
Thumbnail is a tappable page preview with a title below it.
func (*Thumbnail) CreateRenderer ¶
func (t *Thumbnail) CreateRenderer() fyne.WidgetRenderer
func (*Thumbnail) SetMinimumSize ¶
SetMinimumSize sets the size of the preview image area.
func (*Thumbnail) SetSelected ¶
SetSelected highlights the thumbnail, e.g. for the page currently shown.
func (*Thumbnail) Tapped ¶
func (t *Thumbnail) Tapped(_ *fyne.PointEvent)