Skip to content

Zooom / Pan and smooth scroll support for PDFs#51

Open
r-menezes wants to merge 3 commits into
dsanson:masterfrom
r-menezes:master
Open

Zooom / Pan and smooth scroll support for PDFs#51
r-menezes wants to merge 3 commits into
dsanson:masterfrom
r-menezes:master

Conversation

@r-menezes

Copy link
Copy Markdown

This seems easily to be one of the most developed solutions to read PDFs in the terminal. But I was missing the ability to zoom in, so I tried to implement something rough myself.

Disclaimer: It was written with the assistance of Claude/Gemini, but I reviewed the entire code.

How it works:

Pressing + now zooms in the PDF, and hjkl pans the zoomed PDF around. When you find the top/end of a page while moving up/down, it naturally loads and moves to the bottom/top of the previous/following page.
To improve the FPS, there is some logic to allow faster updates if there is not an expensive operation going on.

This was made possible by slightly changing the Kitty protocol command to include additional info of pixel offsets and crop dimensions.

Key bindings summary

Key Behaviour
+ / - zoom in / out (×1.25 steps)
W reset zoom to fit-to-window
j / k pan vertically when zoomed; page-flip otherwise
h / l pan horizontally when zoomed; chapter-jump otherwise
J / K always page-flip, regardless of zoom
L / H always chapter-jump, regardless of zoom

r-menezes added 3 commits May 31, 2026 14:32
Before, the viewport was always fixed to the top-left of the rendered
bitmap. This commit adds full pan and scroll support by using modifing
the Kitty place command.

Core rendering fix (display_page):
  - Track pan_x/pan_y (center of viewport in PDF points) on Document;
  - Compute img_off_x/img_off_y (pixel crop offsets into the bitmap) and
    visible_w/visible_h (clipped display dimensions) from the pan
position
  - Pass x/y/w/h/c/r to the Kitty place command so the terminal crops
the
    stored bitmap to the visible region instead of always showing pixel
(0,0)
  - Guard swallow_keys() behind was_stale so the 100ms input drain only
    fires after a slow full pixmap transfer, not after a cheap pan
update (this also makes navigating the PDF faster when it is loaded)

Navigation (view loop):
  - j/k/h/l pan the viewport when zoomed; crossing the page boundary
    triggers a page change and carries the overflow distance forward,
    giving continuous scroll across pages
  - J/K always change page (no pan), L/H always change chapter
  - Pan step is time-proportional (elapsed * 10 normalised to 100 ms
    baseline) when no explicit count prefix is given, so scroll velocity
    stays constant regardless of render frame rate
  - W (zoom reset) also clears pan_x/pan_y to re-center the page
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant