From ca0b703526151149d060d6d38f307e9e38c3dcd2 Mon Sep 17 00:00:00 2001 From: Lukasz Kasprzak Date: Thu, 17 Sep 2026 00:40:46 +0200 Subject: gui: the preview is as big as you drag it, and PDFs render to suit --- gui/internal/model/preview.go | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) (limited to 'gui/internal/model/preview.go') diff --git a/gui/internal/model/preview.go b/gui/internal/model/preview.go index d2a2830..4ec0569 100644 --- a/gui/internal/model/preview.go +++ b/gui/internal/model/preview.go @@ -8,6 +8,7 @@ import ( "os" "os/exec" "path/filepath" + "strconv" "strings" "unicode/utf8" @@ -47,9 +48,11 @@ const ( ) // MakePreview looks at one file. tmp is a directory the caller owns, where -// a rendered PDF page is written; the caller removes it. Nothing is written -// anywhere else, and the file itself is only read. -func MakePreview(ctx context.Context, path, tmp string) Preview { +// a rendered PDF page is written; the caller removes it. px is how tall the +// preview will be shown, so a page is rendered to suit it rather than to a +// fixed size - 0 takes the default. Nothing is written anywhere else, and +// the file itself is only read. +func MakePreview(ctx context.Context, path, tmp string, px int) Preview { fi, err := os.Stat(path) if err != nil { return Preview{Note: err.Error()} @@ -65,7 +68,7 @@ func MakePreview(ctx context.Context, path, tmp string) Preview { } return Preview{Kind: PreviewImage, Image: path, Note: fmt.Sprintf("image, %s", size(fi.Size()))} case ext == "pdf": - return pdfPreview(ctx, path, tmp, fi.Size()) + return pdfPreview(ctx, path, tmp, fi.Size(), px) } text, ok := textHead(path) if !ok { @@ -82,7 +85,7 @@ func MakePreview(ctx context.Context, path, tmp string) Preview { // called page-1.png and the wrong one could be picked up - which is what // happened: a preview showed the page of a PDF looked at earlier (his // report, 2026-09-17). -func pdfPreview(ctx context.Context, path, tmp string, sz int64) Preview { +func pdfPreview(ctx context.Context, path, tmp string, sz int64, px int) Preview { if _, err := exec.LookPath("pdftoppm"); err == nil { dir, err := os.MkdirTemp(tmp, "page-") if err != nil { @@ -90,7 +93,7 @@ func pdfPreview(ctx context.Context, path, tmp string, sz int64) Preview { } out := filepath.Join(dir, "page") cmd := exec.CommandContext(ctx, "pdftoppm", "-png", "-f", "1", "-l", "1", - "-scale-to", "700", "--", path, out) + "-scale-to", strconv.Itoa(renderPixels(px)), "--", path, out) if err := cmd.Run(); err == nil { if rendered := firstMatch(out + "*.png"); rendered != "" { return Preview{Kind: PreviewImage, Image: rendered, Dir: dir, @@ -111,6 +114,20 @@ func pdfPreview(ctx context.Context, path, tmp string, sz int64) Preview { Note: fmt.Sprintf("text of the first pages, %s", size(sz))} } +// renderPixels is how large a page is rendered for a preview px tall: twice +// the size it is shown at, so it stays sharp when the pane is dragged a +// little wider, within limits that keep the render quick. +func renderPixels(px int) int { + n := px * 2 + switch { + case n < 700: + return 700 + case n > 2400: + return 2400 + } + return n +} + // firstMatch is the first file matching a glob, "" when there is none. func firstMatch(glob string) string { names, err := filepath.Glob(glob) -- cgit v1.3