Skip to content
This repository has been archived by the owner on May 5, 2022. It is now read-only.
Daniel Nicolai edited this page Feb 12, 2022 · 3 revisions

Welcome to the pdf-continuous-scroll-mode.el wiki!

PDF-tools is a great package but it is complex and it lacks good documentation. To assist in the maintenance (and development) of pdf-tools, this page contains some continuous scroll ‘development’ notes.

Display mechanism

PDF-tools has borrowed the basics of its display mechanism from doc-view, which in its turn heavily relies on image-mode functionalities. Both doc-view and image-mode are not very well documented, and it is certainly helpful to describe some of their workings here.

Image-mode

Image-mode is a mode that adds some functionality for viewing images within Emacs. Emacs is designed as a text-editor/processor and therefore the mechanism for showing images is a little ‘hacky’. Basically Emacs supports images only via text-properties or via overlays, where an image can be added via the display property. Image-mode is not required for displaying an image, as it can be displayed by simply adding it as a display property to some text in a buffer. However, image mode adds some functionality for managing how the image is displayed and for scrolling over images. One of the main functionalities added by image-mode is a mechanism for remembering the scroll position. When Emacs switches to a buffer, it sets the vscroll position to 0. To make image-mode remember the vscroll position, image-mode adds the image-mode-reapply-winprops function to the window-configuration-change-hook. Furthermore it creates an image-mode-winprops-alist where it stores ‘window properties’ like the vscroll position. The image-mode-reapply-winprops ‘hook’ function makes sure that Emacs ‘reapplies’ the vscroll on/after each window configuration change.

The configurations for each image-mode window are stored in the image-mode-winprops-alist variable. To obtain the winprops for a specific window you can use the image-mode-winprops function.

Doc-view display mechanism

Although doc-view does not use image-mode directly, it does use its ‘reapply’ mechanism by setting the image-mode-reapply-winprops as a window-configuration-change-hook function and accordingly storing its window-configurations in the image-mode-winprops-alist. After opening some document in doc-view, the stored properties can be viewed using

(pp (cdr (image-mode-winprops)))

or

(map-keys (cdr (image-mode-winprops)))

to see only the ‘keys’ (image info page overlay).

We find that doc-view stores a single overlay as an image mode window property. By default an overlay in a buffer applies in all windows showing that buffer. To enable showing different pages in different windows (or pages with different sizes), the overlays should apply to a single window only, which is achieved by adding a window property to the overlay (see overlay-properties). Doc-view stores some more info as overlay-properties. A list of these properties can be obtained using

(pp (overlay-properties (doc-view-current-overlay)))

or

(map-keys (overlay-properties (doc-view-current-overlay)))

to see only the ‘keys’ (help-echo before-string doc-view window display).

PDF-tools display mechanism

PDF-tools its display mechanism is similar to that of doc-view. For now we simply give the keys it uses. For winprops it uses the keys (window-size image needs-redisplay overlay page). For the overlay it uses (display before-string pdf-view window).

Making the displaying of images work correctly now is a matter of setting the correct properties/values at the appropriate times.

Continuous scroll

Doc-view and pdf-tools both usually create a single overlay over the full buffer text/contents in which they put the image of the current page (the current page is set via the image-mode window page property via the doc/pdf-view-current-page macro). However, it is possible to display multiple images in a buffer by adding multiple overlays. By adding newline characters between the overlays, the overlays are placed under/above each other. However, overlays are just data-structures that hold information for how the text it ‘overlays’ should be displayed. To give the overlay a certain ‘display size’ it should have a display property. Now continuous scrolling could be achieved by having two overlays, and adding the appropriate images and setting the appropriate scrolling at the appropriate times. However, in this way it would not be possible to use the scroll-bar to scroll over the full document. Therefore the continuous scrolling is achieved by adding overlays for each page, giving them the correct space display properties (or the empty svg images that are currently used because I did not find out yet about the space display property before) and then add and remove (put back the space display property; displaying all page images at the same time uses a lot of memory) the page image as display properties at the appropriate scroll positions.

The space display property pixel sizes can be configured as follows:

(overlay-put o1 'display '(space . (:width (400) :height (800))))

Overlays and placeholders

As explained in the previous section, overlays can only be added over some text portion, while to make them get aligned vertically they should get separated by newline characters. As the original doc-view/pdf-tools uses a single overlay over the buffer contents, it is easiest to keep the design like that and just add spaces (to ‘hold’ the overlays) separated by newline characters at the end of the ‘original’ buffer contents. By saving the end position of the ‘original’ buffer contents, new overlays can easily be added over the correct text/buffer positions, every time a new window is created.

Correct displaying

Finally, to make the displaying work correctly, it is crucial to set the correct configurations (winprops and overlay-properties, like current page (image) and scroll setting etc.) at the appropriate times, so that they have the right effect each time the image-mode-reapply-winprops function is run in the window-configuration-change-hook.

For setting the correct scroll settings, image-mode provides the function image-set-window-vscroll (which also sets the vscroll in the winprops).

To find out how to make everything work correctly (AFAIK this is not well documented anywhere), it is probably most useful to study how doc-view and pdf-tools manage things.