<!-- Supported-document-formats.md -->

# Supported document formats

SumatraPDF supports the following document types:

- PDF (.pdf, .ai)
- eBook formats:
  - unencrypted EPUB (.epub)
  - MOBI / Kindle (.mobi, and unencrypted .azw, .azw3, .prc); Print Replica (.azw4) opens as the wrapped PDF
  - FictionBook (.fb2, .fb2z, .fbz, .zfb2, .fb2.zip)
  - Palm DOC (.pdb)
  - plain text (.txt, .log, .nfo, .tcr, …)
- Markdown (.md, .markdown), rendered as GitHub Flavored Markdown
- comic book files: .cbz, .cbr, .cbt, .cb7 (and .ora) — see [Comics and manga](Comics-and-manga.md)
- archive files (.zip, .rar, .7z, .tar) containing images
- DjVu (.djvu, .djv)
- Microsoft Compiled HTML Help (.chm)
- XPS (.xps, .oxps, .xod, .dwfx)
- SVG (.svg)
- images:
  - PNG (.png)
  - JPEG (.jpg, .jpeg, .jfif)
  - GIF (.gif), including animations
  - TIFF (.tif, .tiff), including multi-page
  - BMP (.bmp, .dib)
  - ICO (.ico), including multiple sizes
  - TGA (.tga)
  - WebP (.webp) — also images inside EPUB, MOBI and HTML
  - JPEG XR (.jxr, .hdp, .wdp)
  - JPEG 2000 (.jp2, .j2k, .jpx, .jpf, .jpm, .j2c)
  - AVIF (.avif)
  - JPEG XL (.jxl)
  - HEIF / HEIC (.heic, .heif) — built-in decoder; see below

If [Ghostscript](https://ghostscript.com/) is installed, we support PostScript (.ps, .eps) and PJL (Printer Job Language) files.

DVI (.dvi) opens when pdflatex, xelatex, or lualatex is installed, or when both dvips and Ghostscript are installed. SumatraPDF converts the file to PDF (with dvipdfmx from that TeX install, or with dvips and Ghostscript) and keeps the PDF in its data folder. The same PDF is reused until the DVI's modification time changes. A cached PDF that has not been opened for a week is deleted.

## HEIF / HEIC support

SumatraPDF can open [HEIF images](https://nokiatech.github.io/heif/) (.heic, .heif) and AVIF (.avif) with a built-in decoder:

- **HEIC** (typical phone stills, HEVC-coded): decoded in-process; no Windows codec required for most files
- **AVIF** (AV1-coded): decoded in-process via [dav1d](https://code.videolan.org/videolan/dav1d)
- Grids, overlays, and common transforms (crop / rotate / mirror) are handled for still images

If built-in decode fails, on Windows we still try the system [WIC](https://learn.microsoft.com/en-us/windows/win32/wic/-wic-about-windows-imaging-codec) path (for example if a third-party HEIF codec is installed). That fallback is optional for typical HEIC/AVIF files.

You can make SumatraPDF the [default program for handling those file types](Set-as-default-pdf-viewer.md).


---

<!-- Installation.md -->

# Installation

SumatraPDF comes as an installer or as a portable single `.exe`. This page covers downloading, installing (interactive or silent), extracting without installing, where settings go, and fixing failed upgrades.

**Download the [latest release](https://www.sumatrapdfreader.org/download-free-pdf-viewer) installer and double-click it.** At a glance:

- **Installer:** `SumatraPDF-<ver>-install.exe`, registers file associations and optional preview handler.
- **Portable:** `SumatraPDF-<ver>.exe`, a single self-contained `.exe`.
- **Silent install:** `-install -silent`.
- **Extract only:** `-x -d <dir>`, no registration.
- **Custom settings directory:** `-appdata <directory>`.

## Download

- [latest release](https://www.sumatrapdfreader.org/download-free-pdf-viewer)
- [pre-release](https://www.sumatrapdfreader.org/prerelease)

SumatraPDF has two flavors: installer and portable.

**Portable** (`SumatraPDF-<ver>.exe` downloaded as `SumatraPDF-<ver>.zip`) is a single, self-contained `.exe`.

**Installer** (`SumatraPDF-<ver>-install.exe`) installs to `%LOCALAPPDATA%\SumatraPDF` (or `%PROGRAMFILES%` with `-all-users`), registers file associations, and optional preview handler.

## Install

- **Interactive:** double-click the installer.
- **Silent** (no installation UI):

  ```
  SumatraPDF-<ver>-install.exe -install -silent
  ```

Common options - full list in [Installer cmd-line arguments](Installer-cmd-line-arguments.md):

| Option                 | Meaning                                                             |
| ---------------------- | ------------------------------------------------------------------- |
| `-d <dir>`             | Install directory                                                   |
| `-all-users`           | Install to `%PROGRAMFILES%\SumatraPDF` for all users (**ver 3.4+**) |
| `-with-preview`        | Register PDF preview in File Explorer                               |
| `-with-filter`         | Register Windows Search PDF filter                                  |
| `-no-desktop-shortcut` | Don't create a desktop shortcut (**ver 3.7+**)                      |
| `-log`                 | Write log to `%LOCALAPPDATA%\sumatra-install-log.txt`               |

## Extract without installing

```
SumatraPDF-64-install.exe -x -d "C:\Temp\Sumatra"
```

Extracts `SumatraPDF.exe`, `libsumatrapdf.dll`, `sumatrapdf-tool.exe`, etc. into the target directory. Does **not** register file associations. Recent builds do not create Start Menu / desktop shortcuts when extracting only.

## Set as default viewer

After installing, follow [Set as default PDF viewer](Set-as-default-pdf-viewer.md). The portable exe alone does not register defaults.

## Use a custom settings directory (enterprise / RDP)

Launch shortcuts with:

```
SumatraPDF.exe -appdata "D:\Shared\SumatraSettings"
```

All users sharing that path use the same `SumatraPDF-settings.txt`. Ensure the directory is writable by every account that runs SumatraPDF. See [Portable vs installed settings](#portable-vs-installed-settings) for the default locations.

## Use the command-line tools

After a full install, `sumatrapdf-tool.exe` is next to `SumatraPDF.exe` and on PATH. With the portable EXE you can run the same commands as `SumatraPDF.exe <tool>` (see [Tools](Tools.md)), or extract `sumatrapdf-tool.exe` with `-x`. No install required.

## Tips

- Use `-install -silent` for unattended deployment; add `-log` to diagnose failures.
- Use `-x` to get matching `SumatraPDF.exe` and `libsumatrapdf.dll` without touching file associations.
- Close Explorer preview panes and stop Windows Search before upgrading if a DLL is locked.
- Don't run SumatraPDF as administrator for everyday reading.

## Upgrade fails: file in use (PdfFilter.dll / PdfPreview.dll / libsumatrapdf.dll)

Through **3.6** the engine DLL was named `libmupdf.dll`; from **3.7** it is `libsumatrapdf.dll`.

When upgrading, the installer renames existing DLLs aside before writing new ones. That can fail if Windows still has the old file open:

| File                  | Often locked by                                                                                 |
| --------------------- | ----------------------------------------------------------------------------------------------- |
| **PdfFilter.dll**     | **Windows Search** (`SearchIndexer.exe`, `SearchFilterHost.exe`) after PDF IFilter registration |
| **PdfPreview.dll**    | **File Explorer** preview pane / `dllhost.exe` / `prevhost.exe`                                 |
| **libsumatrapdf.dll** | Running **SumatraPDF**, Explorer preview, or Search filter hosts                                |

Typical Windows errors during install: **32** (sharing violation / file in use), **5** (access denied on replace/delete).

### What the installer does

1. Unregisters the search filter and preview handler (if installed)
2. Stops the **Windows Search** service (`WSearch`) when possible
3. Kills processes that still load install-dir modules
4. Renames `PdfFilter.dll`, `PdfPreview.dll`, and `libsumatrapdf.dll` to `*.copy`
5. If a rename stays blocked, shows a dialog and **retries every few seconds** until success or you abort

### What you can do

1. **Close** all SumatraPDF windows and other PDF apps
2. **Close** Explorer windows that show a **PDF preview** pane (or turn off the preview pane)
3. Temporarily **stop Windows Search**:
   - `Win+R` → `services.msc` → **Windows Search** → Stop
   - Or elevated: `net stop WSearch`
4. Run the installer again (as admin for “all users” under Program Files)
5. After install, start Windows Search again if you stopped it (`net start WSearch`)

If the install still fails, reboot and run the installer **before** opening PDFs or browsing folders with preview enabled.

## Corrupted or incomplete installation

If SumatraPDF reports a [corrupted installation](Corrupted-installation.md):

- `libsumatrapdf.dll` is missing next to `SumatraPDF.exe`, or
- `libsumatrapdf.dll` version does not match `SumatraPDF.exe`

**Fix:** run the official installer, use the portable exe, or extract with `-x` so both files match.

Also see [Failed to load libsumatrapdf.dll](Failed-to-load-libmupdf.md) if the app starts but cannot load the DLL (often antivirus).

## Installer runs when I open a PDF

SumatraPDF only shows the installer UI when the executable name contains `-install` (official installers rename themselves that way) or you pass `-install`. If double-clicking a PDF launches an installer:

- File association may point at the **installer .exe** instead of installed `SumatraPDF.exe`
- You may be running a copied installer from Downloads instead of the installed copy

Re-run the [official installer](https://www.sumatrapdfreader.org/download-free-pdf-viewer), then check [Set as default PDF viewer](Set-as-default-pdf-viewer.md).

## Multiple copies / old versions

An older SumatraPDF in `%LOCALAPPDATA%` or a renamed portable copy can confuse file associations. [Uninstall](Uninstalling-SumatraPDF.md) via Settings → Apps, then install fresh.

## Admin vs normal user

Do **not** run SumatraPDF as administrator for everyday reading. An elevated instance cannot open files dropped from a normal Explorer session ("running as admin and cannot open files from a non-admin process").

## Portable vs installed settings

|                 | Portable                      | Installed                                           |
| --------------- | ----------------------------- | --------------------------------------------------- |
| Settings file   | Same folder as `.exe`         | `%LOCALAPPDATA%\SumatraPDF\SumatraPDF-settings.txt` |
| Thumbnail cache | `sumatrapdfcache` next to exe | `%LOCALAPPDATA%\SumatraPDF\sumatrapdfcache`         |

Override with `-appdata <directory>` — see [Command-line arguments](Command-line-arguments.md) and [How we store settings](How-we-store-settings.md).

## See also

- [Portable vs installer](SumatraPDF-portable.md) — pre-3.7 vs 3.7 single-EXE layout, where the DLL is extracted, installer name / `-install` flag
- [FAQ](FAQ.md)
- [Corrupted installation](Corrupted-installation.md)
- [Uninstalling SumatraPDF](Uninstalling-SumatraPDF.md)
- [Installer cmd-line arguments](Installer-cmd-line-arguments.md) — every installer option


---

<!-- Command-Palette.md -->

# Command Palette

:video https://youtu.be/6pokX53orOA https://files.sumatrapdfreader.org/assets/sumatrapdf/docs/video/command-palette-4199.mp4

The Command Palette is a searchable list that runs any SumatraPDF command, and also opens files, switches tabs and jumps to pages, table of contents entries, favorites, annotations and settings. Open it with `Ctrl + K` or **View → Command Palette**.

**Available in version 3.4 or later.**

**Press `Ctrl + K`, type a few letters, press `Enter` to run a command.** Type a prefix character to switch what the list shows:

- **Commands:** all SumatraPDF functionality — the default view, or `>`
- **File history:** open a previously opened file — `#`
- **Tabs:** switch to another tab — `@`
- **Thumbnails:** navigate pages with thumbnails — `&`
- **Table of contents:** jump to an entry in the current document — `%`
- **Favorites:** jump to a favorite (current document's first, then others) — `$`
- **Annotations:** jump to an annotation in the current PDF — `*`
- **Settings:** change a setting — `=`
- **Combined view:** everything in one list — `:`

## Run a command

![Command Palette](https://files.sumatrapdfreader.org/assets/sumatrapdf/docs/img/command-palette-commands-fac9.png)

- Press `Ctrl + K`, or use **View → Command Palette** (`CmdCommandPalette`).
- Enter text to narrow down the list of matches.
- `Up` / `Down` arrows navigate between matches.
- `Page Up` / `Page Down` jump a page of matches.
- `Home` / `End` go to the first / last match when the caret is already at the start / end of the query (`Ctrl + Home` / `Ctrl + End` always do).
- `Ctrl + A` selects the query.
- `Ctrl + C` copies the selected query text (`Ctrl + V` pastes into the query).
- `Enter` executes the selected match (or double-click it with the mouse).
- `Escape` closes the window (or click outside it).

A command can be listed under more than one name so that a different wording finds it: **Navigate Files in Folder...** is also **Browse Files In Folder...**, and **Advanced Settings...** is also **Advanced Options...**.

## Switch to another tab

Type `@` to switch between open tabs:

![Command Palette](https://files.sumatrapdfreader.org/assets/sumatrapdf/docs/img/command-palette-tabs-d8e9.png)

## Open a file from history

Type `#` to open a file from the list of previously opened files:

![Command Palette](https://files.sumatrapdfreader.org/assets/sumatrapdf/docs/img/command-palette-file-history-00a0.png)

## Jump to a table of contents entry

- Type `%`.
- Press `Shift + F12` (`CmdCommandPaletteTOC`).
- Add `CmdCommandPaletteTOC` as a [toolbar button](./Customize-toolbar.md#command-palette-on-the-toolbar).

The list shows the fully expanded table of contents of the current document, indented to reflect the tree hierarchy. The entry closest to the current page is pre-selected. Type to filter, then `Enter` (or double-click) to navigate to the selected entry.

![Table of contents in the Command Palette](https://files.sumatrapdfreader.org/assets/sumatrapdf/docs/img/command-palette-toc-2600.png)

## Jump to a page with thumbnails

Type `&` to open the thumbnail grid for the current document. The current page is selected initially. Use the arrow keys, `Home`, `End`, mouse, or the scrollbar to navigate; `Enter` opens the selected page and `Escape` closes the grid.

![Thumbnails in the Command Palette](https://files.sumatrapdfreader.org/assets/sumatrapdf/docs/img/command-palette-thumbnails-665d.png)

## Jump to a favorite

- Type `$`.
- Bind a keyboard shortcut to the `CmdCommandPaletteFavorites` [command](./Commands.md) to open the palette directly in favorites mode (see [Managing favorites](./Managing-favorites.md)).
- Add the same command as a [toolbar button](./Customize-toolbar.md#command-palette-on-the-toolbar).

Favorites (bookmarks) of the current document are listed first, followed by favorites of other documents (labeled with the file name). Type to filter, then `Enter` (or double-click) to navigate to the selected favorite. Picking a favorite in another document opens that document.

![Favorites in the Command Palette](https://files.sumatrapdfreader.org/assets/sumatrapdf/docs/img/command-palette-favorites-4873.png)

## Jump to an annotation

Type `*` to jump to an annotation in the current PDF. `* Annotations` appears in the mode row once annotations have been collected and the document has at least one. Collection runs in the background the first time the Command Palette or **Find Annotation** needs them, and the result is reused (including when there are none).

Rows match the **Find Annotation** list: type, contents, page number. Filter with the same syntax (`:t=text`, `:a=kjk`, `:c+`, plain words). `Enter` or double-click selects the annotation and jumps to it.

![Annotations in the Command Palette](https://files.sumatrapdfreader.org/assets/sumatrapdf/docs/img/command-palette-annotations-f38d.png)

## Change a setting

Type `=` to change a setting without opening [Advanced Settings](./Advanced-options-settings.md).

- Every setting holding a single value is listed by its dotted name, with its current value on the right.
- A value that isn't the default is shown in bold, and those settings are listed first.
- Type to filter by name or by value.
- The selected setting's description, the same as in Advanced Settings, is shown under the list.

![Settings matching zoom in the Command Palette](https://files.sumatrapdfreader.org/assets/sumatrapdf/docs/img/command-palette-settings-105b.png)

`Enter` on a `true` / `false` setting toggles it. Any other setting asks for a value: the query becomes `=<name> = <value>`, and

- a setting restricted to a fixed set of values (`Toolbar`, `Scrollbars`, `PrintScale`, ...) lists them; type to narrow the list, `Enter` picks one
- any other setting takes what you type, starting from the current value

The change takes effect immediately, exactly as if it had been saved from Advanced Settings - no restart. The palette stays open and shows the settings again with the same setting selected, so several can be changed in a row; `Esc` closes it. `Esc` while a value is being asked for goes back to the settings instead, also with that setting selected.

You can also type the whole thing at once, e.g. `=ZoomIncrement = 25`; the name can be the last part of a dotted setting (`Units` for `FixedPageUI.PageGrid.Units`) as long as only one setting ends with it.

Note: compact settings like `WindowMargin` are only editable in Advanced Settings; settings holding a list only in the settings file (**Open Advanced Settings File...**).

## Show everything in one list

Type `:` for a combined view (replicates 3.4 and 3.5 behavior):

![Command Palette](https://files.sumatrapdfreader.org/assets/sumatrapdf/docs/img/command-palette-all-daab.png)

## Tips

- Use the palette to run commands that have no default shortcut, e.g. `Toggle Free Pan`.
- Type `=` and a value to find settings by their current value.
- Change several settings in a row: the palette stays open after each change.
- Press `Shift + F12` to go straight to the table of contents.

## Replicate 3.4 and 3.5 behavior

In 3.6, we changed the default command palette view from combined (`:`) to commands only (`>`).

You can replicate pre-3.6 behavior by adding to [advanced settings](./Advanced-options-settings.md):

```
Shortcuts [
  [
    Key = Ctrl + K
    Command = CmdCommandPalette :
  ]
]
```

The default command for the `Ctrl + K` keyboard shortcut is [`CmdCommandPalette`](./Commands.md). This changes it to `CmdCommandPalette :`, which replicates 3.4/3.5 behavior.

## See also

- [Commands](./Commands.md) — every command id, for shortcuts and toolbar buttons
- [Customize toolbar](./Customize-toolbar.md#command-palette-on-the-toolbar) — palette buttons on the toolbar
- [Managing favorites](./Managing-favorites.md)
- [Advanced settings](./Advanced-options-settings.md)


---

<!-- SumatraPDF-portable.md -->

# Portable vs installer

The portable version is a self-contained executable that does not require installation. You can copy it to any folder or new computer, put it on a USB drive, and it will just work.

The installer version also includes:

- `PdfPreview.dll` : provides OS-level previews and thumbnails (e.g. in Explorer) for supported file formats
- `PdfFilter.dll` : provides OS-level search within supported files (e.g. PDF and EPUB files)
- `libsumatrapdf.dll` : for technical reasons, the application must be split into `libsumatrapdf.dll` (core functionality) and `SumatraPDF.exe` to make `PdfPreview.dll` and `PdfFilter.dll` work
- `sumatrapdf-tool.exe` : command-line tool for [performing operations](Tools.md) on PDF files. You can also run the same commands as `SumatraPDF.exe <tool>` without extracting this file

You can extract these files with the `-x` command-line option. Use `-d <dir>` to extract them to a given directory.

Before **3.7**, the DLL was called `libmupdf.dll`.

Before **3.7**, the portable version was a separate executable that contained the engine code.

In **3.7**, we simplified the distribution: the portable version is exactly the same executable as the installer.

You can install it with the `-install` command-line option or run it as a portable executable.

When the executable has `-install` in its name, we assume it's intended to be run as an installer.

Because of technical limitations in Windows, this dual-purpose portable/installer executable must extract `libsumatrapdf.dll` to disk. The location is an implementation detail: `%LOCALAPPDATA%\SumatraPDF-data\<build-id>\libsumatrapdf.dll`. If you prefer, you can place it next to the `SumatraPDF.exe` executable.

Data storage (`SumatraPDF-settings.txt` etc.):

- in portable mode, application data is stored next to `SumatraPDF.exe`
- when installed, it is stored in `%LOCALAPPDATA%\SumatraPDF`
- you can override the location with the [`-appdata <dir>` command-line option](Command-line-arguments.md)

See also:

- [Installation](Installation.md)
- [Installer cmd-line arguments](Installer-cmd-line-arguments.md)
- [How we store settings](How-we-store-settings.md)
- [Corrupted installation](Corrupted-installation.md)
- [Failed to load libsumatrapdf.dll](Failed-to-load-libmupdf.md)


---

<!-- Set-as-default-pdf-viewer.md -->

# Set as default PDF viewer

SumatraPDF registers itself for all [supported file types](Supported-document-formats.md) (`.pdf`, `.png`, etc.).

If there are no other applications registered for a given extension, you can open the file in SumatraPDF simply by double-clicking the file in File Explorer.

If there is more than one application, you have to explicitly tell Windows 10+ to make SumatraPDF the default application.

## Using File Explorer

In File Explorer:

- find a `.pdf` file (or any other supported file type)
- right-click to open the context menu
- select `Open with` and then `Choose another app`

![Explorer Menu Open With](https://files.sumatrapdfreader.org/assets/sumatrapdf/docs/img/explorer_menu_open_with-22b7.png)

From the list, choose `SumatraPDF` and check `Always use this app to open .pdf files`:

![Choose App](https://files.sumatrapdfreader.org/assets/sumatrapdf/docs/img/choose_app-f17f.png)

## Using Default apps system settings

This is based on the latest Windows 11 build at the time of writing.

Unfortunately the details differ between Windows updates.

Open the `Default apps` section of the Settings app. For example, press the `Windows logo` key to open system-wide search, type `default apps`, and click the `Default apps` search result.

![Default apps](https://files.sumatrapdfreader.org/assets/sumatrapdf/docs/img/default-apps-3083.png)

In Default apps, type `.pdf` as the file extension:

![Default apps Settings](https://files.sumatrapdfreader.org/assets/sumatrapdf/docs/img/settings-app-c745.png)

Click the current default PDF application (`Microsoft Edge` in this example) and select `SumatraPDF`:

You can do that for other file formats.


---

<!-- FAQ.md -->

# Frequently asked questions

Quick answers to common questions from the [GitHub discussions forum](https://github.com/sumatrapdfreader/sumatrapdf/discussions). Each item links to a page with more detail.

## Opening files and windows

**I enabled tabs but every PDF opens in a new window**

Check `ReuseInstance = true` in [advanced settings](Advanced-options-settings.md). With `ReuseInstance = false`, Windows starts a separate SumatraPDF process for each file, so tabs cannot be shared. See [Tabs and windows](Tabs-and-windows.md).

**How do I open a file in a new window instead of a tab?**

Use `-new-window` on the command line, or `Ctrl + Shift + N` in the app. See [Tabs and windows](Tabs-and-windows.md).

**SumatraPDF asks to install when I double-click a PDF**

This usually means the `.exe` you are running has `-install` in its name (the installer renames itself that way) or `libsumatrapdf.dll` is missing next to the executable. Download the [official build](https://www.sumatrapdfreader.org/download-free-pdf-viewer) and run the installer, or use the portable (self-contained) version. See [Installation](Installation.md) and [Corrupted installation](Corrupted-installation.md).

**SumatraPDF is running as admin and cannot open files from a non-admin process**

Do not run SumatraPDF elevated. Run it as a normal user, or run the program that opens the file with the same privilege level.

## Settings and display

**I changed the default layout but reopening a file ignores it**

`DefaultDisplayMode` and `DefaultZoom` apply when you open a file **for the first time**. After that, [per-document state](How-we-store-settings.md) restores the layout from when you last closed the file. To reset a file, remove its entry from `FileStates` in advanced settings or delete the settings file.

**View settings from the menu don't take effect**

Some settings (for example `UseTabs`) require restarting SumatraPDF. Per-document settings override global defaults for files you have opened before. See [How we store settings](How-we-store-settings.md).

**I accidentally inverted document colors — how do I undo?**

Press `Shift + I` again (`CmdInvertColors`) — it is a session-only swap of the page colors. If the pages are recolored even without it, set `DocumentColorsFollowTheme = off` in advanced settings. See [Customize theme colors](Customize-theme-colors.md).

**How do I get dark page colors without crushing photos and figures?**

Set **`DocumentColorsFollowTheme = smart`** (or press **`Shift + I`** once from `off`). That recolors text and background but keeps images as in the file. Use **`legacy`** only if you want images recolored too (old invert-style behavior). UI chrome is separate: pick a dark **`Theme`**. Details: [Customize theme colors](Customize-theme-colors.md).

**How do I pan and zoom with the mouse like Adobe Reader?**

Hold the **right mouse button** and drag to pan; keep holding and use the **scroll wheel** to zoom at the cursor. A right-click without dragging still opens the context menu. `Ctrl + scroll wheel` also zooms. See [Scrolling and zooming](Scrolling-and-zooming.md).

**How do I get a dark background for reflowed EPUBs?**

Prefer **`DocumentColorsFollowTheme = smart`** for MuPDF page recoloring that preserves images. You can also tune `EBookUI` (`CustomCSS`, `IgnoreDocumentCSS`, `WindowBgCol`) — see [Customize eBook UI](Customize-eBook-UI.md).

## Links and navigation

**SumatraPDF turns plain-text URLs, email addresses, and DOIs into clickable links**

SumatraPDF auto-detects URLs, email addresses, and plain-text DOIs (e.g. `10.1109/WICSA.2015.29` → `https://doi.org/...`) in PDF text (a long-standing PDF viewer convention for URLs). Embedded hyperlinks in the file are separate. Set `DisableAutoLinks = true` in advanced settings to turn off auto-detection only. See [Hyperlinks](Hyperlinks.md).

**I followed an internal link (footnote) — how do I go back?**

`Alt + Left` or `Backspace` — same as browser back. See [Scrolling and zooming](Scrolling-and-zooming.md).

## Search

**Search shortcuts don't work / F3 changes volume on my laptop**

`F3` only works when keyboard focus is in the document, not in the find box. On many laptops you need `Fn + F3`. See [Finding text](Finding-text.md).

## Printing

**Command-line printing uses the wrong paper size or tray**

Use explicit `-print-settings` tokens (`paper=`, `bin=`, `paperkind=`). On Windows 11 the print dialog may hide Advanced options — CLI printing avoids that. See [Printing](Printing.md).

## Annotations

**How do I change default highlight color or size?**

Edit the `Annotations` section in advanced settings (`HighlightColor`, `FreeTextSize`, etc.). There is no global undo for annotations. See [Editing annotations](Editing-annotations.md).

## PDF tools (merge, split, delete pages)

**How do I delete the last page without knowing the page count?**

Use `sumatrapdf-tool clean` with `N` as the last-page marker, e.g. `1-N-1` keeps all pages except the last. See [Tools](Tools.md) and [Delete pages from PDF](Tool-x-delete-pages-from-pdf.md).

## Accessibility

**Can SumatraPDF read a document aloud?**

Yes — **pre-release 3.7+** adds Read Aloud (`Ctrl + K`, `Read Aloud` command in [Command Palette](Command-Palette.md)) using Windows text-to-speech. See [Read Aloud (TTS)](Read-Aloud.md).

## Default PDF viewer

**SumatraPDF doesn't appear in Windows Default apps**

Install from the [official installer](https://www.sumatrapdfreader.org/download-free-pdf-viewer) (not only the portable exe), then set defaults manually. See [Set as default PDF viewer](Set-as-default-pdf-viewer.md) and [Installation](Installation.md).

## Still stuck?

- Search [discussions](https://github.com/sumatrapdfreader/sumatrapdf/discussions) — your question may already be answered
- [Report a bug](How-to-submit-bug-reports.md) if something is broken
- [Request a feature](https://sumatrapdf.userjot.com) on the feature board


---

<!-- Version-history.md -->

# Version history

**next: 3.7**

Available in [pre-release](https://www.sumatrapdfreader.org/prerelease) builds.

- DVI (.dvi) opens when pdflatex, xelatex, or lualatex is installed, or when both dvips and Ghostscript are installed. The file is converted to PDF (dvipdfmx from that TeX install, or dvips and Ghostscript) and cached in the Sumatra data folder. The cache is reused until the DVI's modification time changes, and a cached PDF not opened for a week is deleted
- **Zoom: Fit Visible** (`CmdZoomFitVisible`, Zoom menu, command palette, `z` cycle after Fit Content): fits the width of the page content to the window, cropping the blank margins down to 2pt, and scrolls vertically, like Fit Width without the margins (Foxit's Fit Visible). Also `-zoom "fit visible"`, the `fit visible` value of the `DefaultZoom` settings, and PDF links with a FitBH destination now use it (fixes #6241)
- **Select Current Page** (`CmdSelectCurrentPage`, Selection menu, selection context menu, command palette) selects the text of the current page only, where Select All selects every page
- The **Selection** menu and the selection context menu group the web services under **Translate with** (Google, DeepL, Grok Build, Claude Code, OpenAI Codex, Antigravity) and **Search with** (Google, Bing, Wikipedia, Google Scholar) submenus
- The **File** menu has an **Open** submenu: **Open...**, **Open using Windows File Picker...**, **Open using SumatraPDF File Picker...** (`CmdOpenFileWithSumatraFilePicker`, always the in-app Navigate Files in Folder window), the **Use SumatraPDF File Picker** check (moved from the Settings menu), **Next / Previous File In Folder** and **Browse Files In Folder...**. **Delete and Open Next File** and **Save Annotations to existing PDF** are no longer in the File menu; the commands remain in the command palette and keep their shortcuts
- The **File** menu no longer lists **Convert PDF to Images...**, **Apply Redactions**, **Insert Image...** and **Sign Document...**; they remain in the right-click **Document** submenu and the command palette
- `ShowChaptersInEbooks` (off by default) shows where you are in a chaptered ebook as a chapter and a page within it: the toolbar, Go to Page, and the page-info tip. Off, those show one page number for the whole book. The saved position stays a chapter bookmark either way, and Next / Previous Page still cross chapters. Opening lays out only the chapter you were reading (the first chapter, the first time) and counts the remaining chapters in the background; the page total updates when that finishes. A debug build shows that progress at the bottom left
- The in-app manual (F1) has a theme switch in its top-right corner: light, dark, or follow the app's theme (the default), remembered in the `HelpTheme` setting. Its `Ctrl + K` search gained an **Ask a question** mode that sends the question to Grok, ChatGPT or Claude in your browser, with the SumatraPDF documentation as context, like the search on the website
- Home page thumbnails use a cover image stored next to the document with the same base name (`Book.jpg`, `.jpeg` or `.png` beside `Book.epub`), the way Calibre saves covers, or else the cover an EPUB declares in its metadata, instead of rendering page 1 (fixes #6236)
- Double-click the tip at the bottom of the home page to show another one; a single click no longer changes it
- **Navigate Files in Folder** has Back, Forward, Up and Home buttons before the folder name. Back / Forward (`Alt + Left` / `Alt + Right`) walk the folders visited in this session (kept across re-opening the window), Up (`Alt + Up`, `Backspace`, or the `..` entry) goes to the parent (from a drive root: to Home), Home lists all drives followed by Explorer's Quick access folders and files (fetched once; F5 there re-reads them). A search field under the folder name filters the list as you type, matching like the command palette (every word, case and accent insensitive); `Ctrl + F` or just typing while the list has focus goes to it, Up/Down move the selection from it, Esc clears it, and changing folder clears it. Clicking the folder path edits it in place: Enter goes to that directory (a file path opens its folder with the file selected, quotes from Explorer's Copy as path are fine), Esc or a path that doesn't exist restores the previous one (#6232)
- **Automatically Scroll** (`Ctrl + Shift + H`, View menu, command palette): hands-free continuous pan for reading, like Acrobat / Foxit. A bar at the bottom of the page shows the speed, Pause / Resume, Stop, Reverse, Focus (reading bar), and a short key list. Up/Down change speed, `0`–`9` set it (0 slowest, 9 fastest), minus reverses, Left/Right jump a page, Space pauses, Esc stops. Speed is remembered in `ReadingAutoScrollSpeed`. This is not middle-click auto-scroll (`CmdStartAutoScroll`), which still follows the cursor
- **Reading Bar** (View menu, command palette): a horizontal band on the page to keep your place while reading, like Skim. Default is a translucent highlight; **Reading Bar Invert** dims the rest of the page (a screen mask). Drag the band to move it, drag the top or bottom edge to resize. Hover shows a close button. Ctrl+Up/Down move it, Ctrl+Shift+Up/Down change its height, Esc hides it (unless Automatically Scroll is on, in which case Esc stops scrolling first). Color, invert and height are in the `ReadingBar` settings. The bar is per tab and is not shown on Home (fixes #5771, discussion #3389)
- `borderwidth` argument of `CmdCreateAnnot*` commands applies to line, polyline, polygon, square and circle, not only free text and ink (discussion #6208)
- Right-clicking a toolbar button that has a drop-down (Zoom In / Zoom Out, Edit PDF Save, Read Aloud) opens that drop-down immediately if it is not already shown
- **Go To Home Page** (`CmdGoToHomePage`, command palette) switches to the Home tab. With `NoHomeTab = true` there is none, so it adds one as the first tab; close it with its ✕ (fixes #6228)
- Building Bookmarks from numbered headings for a PDF without an outline is now opt-in: `AutoGenerateTOC = true` does it on open, **Generate Table Of Contents** (`CmdAutoGenerateTOC`, command palette) does it on demand. Badly OCRed text made the automatic scan slow and its result useless (fixes #6227)
- **Copy Location To Clipboard** (`CmdCopyLocationToClipboard`, command palette) copies where you are reading as command-line arguments that re-open it: page, zoom, scroll position and file path (discussion #6163)
- **Save Selection As Image** (`CmdSaveSelectionAsImage`): with a rectangular (Ctrl+drag) selection, export that area as PNG, JPEG or BMP at a chosen DPI (pick from the list or type any value), independent of the current zoom (fixes #6127)
- Printing at actual size (1:1): `-print-settings "dpi=<n>"` and the `PrinterDefaults.PrintDpi` advanced setting tell SumatraPDF the resolution of a scan / image whose file records none or a wrong one, so **Actual size (1:1)** (the print dialog's Advanced tab; the option was called "Use original page sizes") / `noscale` prints it at its real size. [Printing at actual size](Printing.md#printing-at-actual-size-11) explains where the size of an image comes from (fixes #6223)
- **Print Selection...** (`CmdPrintSelection`, selection context menu, command palette): with a rectangular (Ctrl+drag) selection, opens the print dialog with **Selection** already chosen so only that area prints. Printing a selection was always possible via the dialog's Selection radio button; this makes it discoverable (fixes #6222)
- The annotation **Contents** box, the free-text in-place editor, and Advanced Settings in-place value edits stay open when the Windows on-screen keyboard takes focus, so they can be used on a tablet
- Document Properties (Ctrl+D) fills Title, Author, Subject, Keywords, dates, Application and PDF Producer from the Catalog XMP metadata stream when the Info dictionary omits them
- **Global shortcuts:** prefixing `Key` with `Global ` in `Shortcuts` settings (e.g. `Key = Global PageDown`) registers a system-wide hotkey. Commands route to the most recently active open SumatraPDF window (fixes #6133)
- **Open File Without History** (`CmdOpenFileNoHistory`) opens a document without adding it to File History or Windows Recent Documents. Palette-only; bind a shortcut if you want one (fixes #6121)
- Themes can set separate `ActiveTabBackgroundColor` and `InactiveTabBackgroundColor` values; built-in themes define both to preserve their existing tab appearance
- With `EscToExit = true`, Esc in presentation or fullscreen mode leaves that mode instead of closing SumatraPDF; the next Esc closes it (fixes #6250)
- The installer has an **Install desktop shortcut** option (on by default). Upgrades keep the choice of the previous installation, so turning it off once stops every later pre-release from re-creating the shortcut (discussion #6255)
- In Edit PDF mode the arrow keys nudge the selected annotation by a pixel, `Shift + arrow` by 10 pixels. Moving an annotation no longer makes a bordered one grow a little each time
- **Text snippets:** the `TextSnippets` setting defines predefined text (`\n` for new lines) inserted as a free text annotation from right-click → **Annotations → Create Under Cursor**, the command palette, or its own shortcut. See [Insert predefined text](Editing-annotations.md#insert-predefined-text)
- **Sign With Image** (`CmdSignWithImage`) stamps your signature image, set in `Annotations.SignatureImage`, without a file picker. See [Add a signature image](Editing-annotations.md#add-a-signature-image)
- `AlwaysShowSidebar` opens every document that has bookmarks with the Bookmarks sidebar, even one last closed with it hidden
- Clicking a PDF file-attachment annotation (the paperclip / pushpin on the page) whose file Sumatra can open (PDF, and other supported types) opens it in a new tab from memory, without writing a temp file. Other attached types still use Save Attachment on the context menu, or the OS handler (discussion #4276)
- in the bookmarks and favorites trees, letter shortcuts run the command (e.g. `t` bound to Toggle Bookmarks) instead of type-ahead; arrows, Page Up/Down, Home, End, Enter and Space still navigate the tree
- Command Palette **Toggle Boolean Setting** lists the advanced settings (`=` prefix) with their current values, non-default ones in bold and listed first. Enter on a `true` / `false` setting toggles it and closes. Any other setting asks for a value: the query becomes `=<name> = <value>`, where a setting restricted to a fixed set (`Toolbar`, `Scrollbars`, `PrintScale`, …) lists them to pick from and anything else takes what you type, starting from the current value. The change takes effect immediately, no restart. The whole thing can be typed at once (`=ZoomIncrement = 25`), and the name can be the last part of a dotted setting (`Units` for `FixedPageUI.PageGrid.Units`) when only one setting ends with it. The selected setting's description is shown under the list, as in Advanced Settings. Compact settings like `WindowMargin` stay Advanced Settings only, lists stay settings-file only
- Command Palette `&` opens the current document's thumbnail grid with the current page selected
- **Thumbnails sidebar** (**View → Show Thumbnails**, command palette, or the Thumbnails icon in a sidebar panel's header): page thumbnails of the document, also for documents without bookmarks. Click a page to go there. The view is remembered per document. See [Thumbnails sidebar](Thumbnails-sidebar.md)
- **Merge PDF** (right-click → **Document** → **Merge PDF...**, command palette): a window with the PDF's pages as thumbnails. Add pages of other PDFs (**Add PDF...** or drop files from Explorer), drag pages into a new order, remove pages (the ✕ on a page, `Delete`, right-click) and restore them, select with `Ctrl` / `Shift` click or a rubber band. **Save** writes over the PDF, **Save As...** creates a new one and opens it. See [Merge PDF window](Merge-PDF-window.md) (fixes #6070)
- The sidebar has two panels, top and bottom, each showing Bookmarks, Thumbnails or Favorites, picked with icons in its header (they replace the **Bookmarks** / **Favorites** labels). **Show Bookmarks**, **Show Thumbnails** and **Show Favorites** open their view in the first hidden panel, or switch the top one; picking a view the other panel shows swaps them. The top panel is remembered per document, the bottom one app-wide (`ShowFavorites`, `SidebarBottomView`). See [Two sidebar panels](Thumbnails-sidebar.md#two-sidebar-panels)
- Closing the end-of-document "open next file" hint stops showing it; `ShowFileNavigateHint` turns it back on (fixes #6188)
- `ScrollEdgeTurnsPage` (on by default) controls whether scrolling past the top or bottom of a zoomed-in page in single page / facing / book view goes to the previous / next page. Turn it off to stay on the page and change pages only with the keyboard, toolbar or scrollbar. A page that fits the window has nothing to scroll, so a wheel notch still turns it (fixes #6201)
- the Windows 11 print dialog's **More settings** pane now offers the printer's own settings - color vs black and white, one- vs two-sided, collation, paper size and type, quality, pages per sheet, input tray, binding, stapling, hole punch - instead of only the input tray. Settings the selected printer doesn't support are left out. Unlike the classic print dialog, this one has no button that opens the driver's property sheet, so anything not offered here couldn't be reached at all (discussion #6202)
- `PrinterUI` chooses which dialog **Print** (`Ctrl + P`) opens: empty or `auto` (the Windows 11 dialog with print preview where it's available, the classic one everywhere else), `modern` (the same, said explicitly), or `classic` (always the classic dialog). Only the classic dialog has a **Preferences** button, which opens the printer driver's own property sheet; the Windows 11 dialog has no way to show it, so set `classic` to reach a driver setting that its **More settings** pane doesn't offer. `modern` still falls back to the classic dialog when Windows can't show the modern one - before Windows 11, when running elevated, or when printing a selection (discussion #6202)
- Menu and command names say settings, not options: **Settings → Options...** is now **Settings...** and its dialog is titled **Settings** (was **SumatraPDF Options**); **Advanced Options...** is now **Advanced Settings...**. `CmdAdvancedOptions` is gone, the menu item runs `CmdAdvancedSettings`, the dialog; a shortcut definition naming `CmdAdvancedOptions` still works. **Settings → Open Advanced Settings File...** opens the settings file in the .txt editor (`CmdOpenSettingsFile`)
- The command palette can list a command under more than one name; **Navigate Files in Folder...** is also **Browse Files In Folder...**, and **Advanced Settings...** is also **Advanced Options...**
- **Toggle Free Pan** (`CmdToggleFreePan`, command palette): the view can go past the page edges by half a window, so any part of a page, a corner of a technical drawing included, can be brought to the center of the screen instead of being stuck at the window edge. Fit zooms and page placement are unchanged; it only adds scroll room. Remembered per document (discussions #6224, #6164)
- Starting a search adds a navigation point at the view it started from, once per search, so `Backspace` / `Alt + Left` returns there after find-as-you-type and Find Next moved through matches. The session-only `/` favorite marks the same view (fixes #6230)
- the Windows 11 print dialog's **More settings** pane has a **Page scaling** dropdown with the classic Advanced tab's choices: shrink to printable area, fit to printable area, stretch to fill paper, actual size. It starts at `PrinterDefaults.PrintScale`
- `ShowPageNumberInTabs` (off by default) shows the current page as `n/N` after the file name on tabs; the name ellipsizes first
- the home page shows reading progress (`12/62`, or `3:5/20` for chaptered ebooks) on list rows and as a badge on thumbnails, from the last place you were in that file. Turn it off with `ShowHomePageReadingProgress = false` (fixes #6199)
- PDF documents have an **Edit PDF** toggle at the end of the standard toolbar. It opens a second row of SVG annotation tools for highlight, underline, squiggly, strike out, text, free text, lines, shapes, ink, redaction, stamps, carets, and file attachments; text-markup tools are enabled only while text is selected. The annotation toolbar ends with **Find Annotation**, before the save buttons, which opens a floating **Annotations** window: a search box (`filter N annotations`) over the list of the document's annotations (arrows, Page Up/Down, Home/End). The list caret moves immediately; selecting the annotation on the page is debounced. Esc clears the search, or returns focus to the page if the box is already empty. A click in the list selects, a double-click selects and jumps to it. **Find Annotation** again, or the window's close button, hides it (fixes #6086). The window has **Delete Annotation**, **Discard changes**, **Save changes to** the current file, and **Save changes to a new PDF** at the bottom; save and discard stay disabled until there are unsaved changes, and delete stays disabled until an annotation is selected. Shift+click and Ctrl+click select multiple annotations; the delete button then reads **Delete N annotations**. Del deletes the selection. Choosing **Text**, **Free Text**, **Stamp**, **Caret**, **File Attachment**, **Line**, **Polyline**, **Square**, **Circle**, or **Ink** from this toolbar or the Command Palette lets you position the annotation on the page before placing it. A free text, stamp, caret, or file attachment follows the cursor as a preview until you click the page; free text previews as the text box it will create, sized to its text. Drag out a rectangle or ellipse, or click its two opposite corners; hold **Shift** for a square or circle. Ink commits each stroke when you release; the tool stays on for another. **Esc** or closing the hint leaves the tool. Finish a polyline with a double-click, right-click, **Space**, or **Enter**. Clicking an existing annotation in Edit PDF mode selects it and shows a compact property row under it (color swatch, opacity, border, font, icon, line endings, Contents, and **Delete Annotation** at the end). A file attachment's row starts with **Attach File**, and **Save Attachment** once a file is embedded. Icon, line-ending, and text-alignment menus show the glyph next to the name. Resizing a free text annotation drags only its outline; the annotation itself is rewritten once, when the drag ends, because re-laying out its text on every mouse move is slow. Outside Edit PDF mode a click does not select an annotation (including free text and stamps). `Ctrl + click` an annotation to enter Edit PDF mode (the annotation toolbar appears and the **Edit PDF** button is checked) and select it. The hover tip ("Highlight annotation. Ctrl+click to edit.") is no longer shown. `Ctrl + A` and `Ctrl + V` in a text box are that box's select-all and paste, not the page's - the annotation text editors, the page-number box, form fields (`Ctrl + C`, `Ctrl + X` and `Ctrl + Z` already were). A free text annotation's property row leads with the colour of its text, and its chips name what they change: **Text Color**, **Background Color**, **Border Width**, **Edit text**. Other annotation types get **Border Width** and **Edit Note** too. A free text annotation is edited where it sits on the page: double-click it, or press **Contents** on its property row, and an edit box opens over it in the annotation's font and size on a white background. Placing a new one opens the box straight away. The box grows with what you type and is sized the way MuPDF will lay the text out, so nothing wraps that the box showed whole. **Enter** makes a new line, and **Ctrl + Enter**, **Contents** again, clicking away or **Esc** goes back to the rendered annotation. Making a highlight, underline, squiggly or strike-out from a text selection now consumes the selection: the selection and its floating toolbar go away and the new annotation is selected instead, like every other annotation. Leaving Edit PDF mode leaves no annotation-editing UI behind: the selected annotation is deselected (its marker and resize handles go with it) and a half-finished placement is cancelled. The page context menu gathers everything annotation-related (create from selection, create under cursor, cut / copy / paste / delete, save, apply redactions) under one **Annotations** submenu, which ends with **Apply Redactions**, **Save changes**, **Save to new file** and **Discard changes**; each is disabled when there is nothing to act on. Copy and Paste Annotation show the `Ctrl + C` / `Ctrl + V` keys that reach them. Creating an annotation selects it. `CmdCreateAnnot*` turns Edit PDF mode on only with the `openedit` argument (`Shift + A` / `Shift + U`). Pasting an annotation still turns Edit PDF mode on. `openedit` still opens the Contents editor. The standalone Annotations editor window and the context-menu **Edit Annotations** command are gone. The command is `CmdToggleEditPDF` ("Toggle Edit PDF"); `CmdTogglePdfAnnotationsToolbar` still works in shortcuts and `ToolbarCustomLayout`
- Every Edit PDF toolbar button that creates a colored annotation (highlight, underline, squiggly, strike out, text, free text, line, polyline, square, circle, polygon, ink, stamp, caret, file attachment) and every color chip of a selected annotation share one color drop-down: the preset colors (`Annotations.PresetColors`) as swatches, plus a button that opens the color dialog on the whole set, where a color can be given an opacity. That dialog is owned by the main window, so it no longer opens behind it. A color carries the annotation's opacity (issue #6063), so an annotation with a color chip has no separate **Opacity** chip and its chips show the colors as they look on the page. Annotations with two colors, like a square or a circle, get a drop-down for each, and their interior can be left out with the drop-down's first swatch. Picking a color on a toolbar button is the color the next annotation of that type is made in, kept in a setting of its own (`Annotations.LineColor`, `SquareColor`, `InkColor` and so on; the text button uses `TextIconColor` and free text `FreeTextColor`). **Redact** has no such drop-down: its color is the box that covers the text. The **Ink** button's drop-down has more than colors: a preview of the stroke it will lay down and a **Thickness** slider under it, from Thin to Thick, which is `Annotations.InkBorderWidth` in points (6 by default). The preview follows the slider as you drag it, and so does the stroke you draw on the page. A selected ink annotation's color chip opens that same drop-down, where the slider is that stroke's own width, applied when you let go; it therefore has no **Border Width** chip. The default colors for underline, squiggly and strike out are now the nearest preset colors, and the first preset color is the yellow that highlights have always used
- A free text annotation's property row has **Bold**, **Italic** and **Underline** toggles next to **Font**. The **Font** menu lists Courier, Helvetica and Times Roman plus **Other Font (Embedded)...**, which picks any installed font with the Windows font dialog. Such a font is embedded in the PDF, so it looks the same everywhere; as that can add hundreds of kilobytes or more, picking one asks first. The font and style are written as the annotation's `/DS` default style, which Acrobat and other editors read too (fixes #6198)
- **Redact** marks selected text, or a dragged rectangle, for removal. The marks are red outlines and can still be moved or deleted. **Apply Redactions** permanently deletes the marked content from the file. You can undo it (`Ctrl + Z`) until you save; once the file is saved it cannot be undone
- The Edit PDF toolbar has a **Highlighter** next to **Highlight**: a marker pen you drag across the page, painting a wide translucent stroke over pictures and blank areas as well as text, with no text selection to make first. Release the mouse or pen to finish (`Enter` still works); **Esc** cancels. Closing the placement hint at the bottom of the window also finishes ink and polyline, so a touch device does not need a keyboard. The stroke keeps a constant on-screen width whatever the zoom and is saved as an ink annotation in `HighlightColor` at 40% opacity, so it can be moved, recolored or deleted like any other annotation
- **Extract Pages From PDF** has an **Only with annotations** option that filters the selected page range to pages containing annotations (fixes #6046)
- Polygon, polyline, and ink annotations can be moved by dragging them, like other shape annotations. Rich media and 3D annotations can be moved and resized too: the PDF spec and MuPDF both treat their `/Rect` as theirs to change
- SelectionHandlers `${selection}` in a `URL` percent-encodes reserved characters (`?`, `"`, `&`, `#`, …) so they stay part of the value instead of starting a new query or cutting the string (discussion #6029)
- SelectionHandlers `URL`, `Exe` and POST `Body` accept `${selectionPosition}`: the current selection's bounding box in screen pixels as `x,y,dx,dy`, so a helper can place itself next to the selection (discussion #6015)
- The floating selection toolbar uses SVG icons for every built-in action, sharing the PDF annotation toolbar’s icons for annotation actions and following `ToolbarSize`. Its built-in buttons can be chosen, reordered, and separated with `|` in `SelectionToolbarLayout`, the same idea as `ToolbarCustomLayout`. Custom handler SVG buttons use their `Name` as a tooltip (discussion #6015, fixes #6048)
- Picking an action on the floating selection toolbar hides it until the selection changes. Markup actions (highlight, underline, …) turn the selection into the annotation; **Copy to clipboard** keeps the selection and briefly shows "Copied to clipboard" in the bottom-left corner
- Text selection uses the font’s height for the highlight box and a 1-pixel outline, as in 3.6.1, instead of a tight glyph-ink box that left little padding above words such as “compass”
- **Ctrl+Delete** deletes the annotation under the cursor, even while a different annotation is selected in the list
- **Undo** (`Ctrl + Z`) and **Redo** (`Ctrl + Shift + Z`) for changes to a PDF, with buttons at the end of the Edit PDF toolbar that are greyed out when there is nothing to step to. Built on MuPDF's journal, so it covers annotations, form fields and applied redactions; one gesture is one step (creating, pasting or resizing an annotation comes back in a single undo), and undoing every change marks the document unmodified again
- The Edit PDF toolbar ends with two save buttons: one writes the changes back to the file you are reading (its tooltip names it), the other saves them into a new PDF. Both are greyed out while there is nothing to save
- In Edit PDF mode, **Ctrl + C** copies the selected annotation and **Ctrl + V** pastes a copy with its top-left at the mouse. **Ctrl + X** cuts: the original is deleted when the copy is pasted, so nothing is lost if the paste doesn't happen (fixes #5222). Also on the page context menu and in the command palette as **Cut Annotation** / **Copy Annotation** / **Paste Annotation**. Text markup (highlight, underline, squiggly, strike-out) can't be copied because it's anchored to the text it covers
- A SelectionHandlers entry can put a search / translate / helper button on the main toolbar with `ToolbarText` or `ToolbarSvgIcon`, the same as ExternalViewers (discussion #6015)
- The annotation list loads annotations from the pages currently on screen first; annotations from the rest of a large document load in the background without losing the current selection
- Update available notification shows the build date when the update-check file has a `BuiltOn` date, e.g. **Version 3.7.21539 available (built on 2026-08-21). Update**
- Advanced Settings shows **changed settings: n** in red, bold, centered on a yellow row when values have been edited in this session. Esc no longer closes the window while those edits are unsaved. The hints are a single line (**Enter or double-click to edit. Bold value: different from default**), and the window cannot be resized narrower than 480 pixels (fixes #6012)
- About window: **Copy program and machine info to clipboard** copies a multi-line dump (version, built-on date, OS, 32/64-bit, WebView2, memory, and other bug-report details). The right-hand date is labeled **built on** (fixes #6008)
- On the home page, hovering the **SumatraPDF** title shows the About box below it as a borderless dropdown (no second logo). Its links are clickable, and **Copy program and machine info to clipboard** is inside the box. Moving the mouse off the title hides it
- The home page has a command-palette button to the left of the **SumatraPDF** title and a **?** keyboard-shortcuts button to the right of it. The Keyboard Shortcuts window can be moved by dragging it
- Advanced Settings can edit compact values such as `FixedPageUI.PageSpacing` and `ComicBookUI.PageSpacing` (written as `4 4`). Changing them applies to open documents without restarting. Comics and image collections use `ComicBookUI.PageSpacing`, not `FixedPageUI.PageSpacing`
- The Read Aloud playback bar uses a compact speed slider (circle on a bar, with the rate next to it) instead of a click-to-cycle button. Speeds go from 0.5x to 3.5x in 0.25 steps from 2x up (2, 2.25, 2.5, 2.75, 3, 3.25, 3.5)
- The **Annotations** list (Find Annotation) opens beside the main window on the side with more room. When the window is maximized or fullscreen it sits on the right edge of the screen, vertically centered. Moving it is remembered until Sumatra is closed, not saved in settings
- **Help: Manual** (F1) opens next to the main window, in the upper half, on the side with more room, wide enough to show the table-of-contents sidebar. Its position and size are remembered across sessions and kept fully on-screen after a resolution or monitor change (fixes #6013)
- **Uniform Page Width** in the View menu keeps mixed-size pages at the same displayed width at percentage zoom levels, using page 1 as the reference. The chosen reading size stays unchanged when the window or fullscreen size changes, and the choice is remembered per document (fixes #5512)
- Document Properties for digitally signed PDFs shows the hash and signature algorithms, the document hash, the issuer and expiry, whether the signature is LTV-enabled, an RFC 3161 timestamp when one is present (device time vs secure TSA time), a PAdES level when the signature is CAdES, and whether the certificate is on the EU Trusted List. **View Certificate...** opens the Windows certificate dialog; **Update EU Trusted List** downloads the EU LOTL (fixes #5581)
- Kindle Print Replica (`.azw4`) files open as the embedded PDF instead of as a reflowable MOBI ebook (fixes #1315)
- keyboard shortcuts accept `AltGr` (also `RAlt` / `RightAlt`) as a modifier, the same as `Ctrl + Alt` on Windows, so bindings like `AltGr + Return` and `AltGr + Shift + Return` work (fixes #5973). Set Screenshot Hotkey can record Return and the arrow keys when a modifier (including AltGr) is held; unmodified Return / arrows are ignored so they are not registered as a global hotkey
- Command Palette: `Ctrl + A` selects the query; `Home` / `End` jump to the first / last match when the caret is already at the start / end of the query (`Ctrl + Home` / `Ctrl + End` always do); `Page Up` / `Page Down` move the list a page at a time (fixes #5972)
- Command Palette: type `%` for the table of contents of the current document (like `$` for favorites). `% TOC` appears in the mode row when the document has a TOC
- Command Palette: type `*` to search and jump to annotations in the current PDF (same rows and filter syntax as **Find Annotation**). `* Annotations` appears in the mode row after annotations have been collected and the document has at least one. Collection runs once in the background and is shared with **Find Annotation**, including when there are none
- comic book archives of 32 MB or less on a network drive are loaded into memory instead of being copied to the local `cbx-cache`
- PDFs opened from OneNote or Outlook (and other host-app cache folders) are copied first so the original file is not left locked; OneNote can sync the section instead of showing "We can't sync this section because we were denied access to the file" (fixes #4705)
- if a PDF has no outline, the Bookmarks sidebar is filled from numbered headings in the text (`I. Introduction`, `II.A. Nested`, `1.2 Title`) so you can still jump around papers and reports that never stored a TOC (fixes #5724)
- Command Palette mode switches at the top (`#` File History, `>` Commands, …) use the same smaller font as the hints at the bottom
- Explorer and Outlook preview pane: Ctrl+wheel zooms, drag pans when zoomed in, and the wheel pans then turns the page at the edge. Double-click returns to fit-page (fixes #859)
- **Transparency Grid** (`CmdToggleTransparencyGrid`, View menu) paints a checkerboard under the page so transparent PDFs (white elements on a hole) are visible, like Acrobat's Transparency Grid. Session-only; not saved in settings (fixes #1809)
- **Page Grid** (`CmdTogglePageGrid`, View menu) overlays graph paper on PDF, EPUB, and other paginated document pages, like PDF-XChange’s Show Grid (not comics). Showing the grid is session-only. **Configure Page Grid** (`CmdConfigurePageGrid`) sets units, spacing, subdivisions, origin, color and line style (dots, dotted lines, or solid); those values are saved in `FixedPageUI.PageGrid` (default 1 inch major / 4 subdivisions, color 128,128,255, dots), and can be restored with **Reset to defaults** (fixes #4398)
- Toggle Page Boxes (`CmdTogglePageBoxes`) outlines the PDF MediaBox, CropBox, BleedBox, TrimBox and ArtBox on each visible page — only boxes that page actually declares — and labels them `media`, `crop`, `trim`, and so on. For PDF development (print marks, trim vs crop). Palette and Debug menu; no default shortcut (fixes #814)
- Change Language is a modeless window like Change Theme (search box, language list, OK / Cancel) instead of a modal dialog
- Add Favorite is a modeless window like Change Theme instead of a modal dialog
- Change Scrollbar is a modeless window like Change Theme instead of a modal dialog
- Custom Zoom is a modeless window like Change Theme instead of a modal dialog
- Go to Page is a modeless window like Change Theme instead of a modal dialog (the toolbar page box is still used when the toolbar is visible)
- Enter password is a WindowBase dialog like Change Theme; it stays modal because opening an encrypted file has to wait for the password
- Set inverse search command line is a modeless window like Change Theme instead of a modal dialog
- Settings (Options) is a modeless window like Change Theme instead of a modal dialog
- Change Background Color and Change Tab Color share a modeless window like Change Theme instead of a modal dialog
- Navigate Files in Folder is a normal modeless window that stays open (no longer a popup that closes when it loses focus or after opening a file); Esc or the close button dismisses it, and Enter / double-click replaces the document in the current tab, while `Ctrl + Enter` / `Ctrl + double-click` switches to the tab already showing that file, or opens it in a new tab. `Alt + Up` goes to the parent directory (like Explorer), as does the `..` entry. `Del` moves the selected file to the recycle bin without asking (directories are not deleted); if that file is open in a tab, the tab closes first. The window uses the app icon and the regular UI font (fixes #5877). The listing re-reads the directory whenever the window is activated or the command is invoked again, so files renamed (`F2`), added or removed meanwhile show up; `F5` refreshes on demand (fixes #5878). It also works on the home page — there's a **Navigate Files in Folder** link next to **Open a document...** — starting in the folder of the most recently opened document
- Renamed the companion engine DLL from `libmupdf.dll` to `libsumatrapdf.dll` (through 3.6 the name was `libmupdf.dll`; 3.7 and later use `libsumatrapdf.dll`). Installer upgrades move the old name aside; see [Portable vs installer](SumatraPDF-portable.md) and [Failed to load libsumatrapdf.dll](Failed-to-load-libmupdf.md)
- Themes can set optional UI colors (`DisabledTextColor`, `DarkerTextColor`, `HotBackgroundColor`, `EdgeColor`, `HotEdgeColor`, `DisabledEdgeColor`, `ErrorBackgroundColor`, and notification highlight colors) so disabled and hover states are not derived only from `TextColor` / backgrounds; built-in themes (including Dracula) set them so tinted foregrounds no longer look muddy yellow (issue #4721)
- new built-in themes: **One Dark**, **Monokai**, **Nord**, **GitHub Dark**, **Catppuccin Mocha**, **Tokyo Night**, **Gruvbox**, **Night Owl**, **Ayu**, and **Palenight** (common palettes from VS Code and other editors)
- theme list cleanup: removed **Darker** (folded into **Charcoal**, the former “Dark background Bright text”); settings that still name `Darker` or the old long name keep working
- Screen readers (Narrator, NVDA, and other UI Automation clients) can access document text on the canvas for PDF, XPS, and DjVu; the experimental UIA provider is now enabled in release builds, not only debug, reading through the document character by character, word by word, line by line or page by page now advances instead of repeating the first line, and reading the text under the mouse pointer or finger works (Narrator mouse mode / touch exploration), including telling the screen reader where that text is on screen (issue #321)
- smoother mouse-wheel and arrow-key scrolling when `SmoothScroll` is enabled (default **true**): continuous exponential chase of the target, sub-pixel steps, 1 ms timer while animating; set `SmoothScroll = false` for instant steps
- add `ScrollLineAmount` advanced setting: distance scrolled by an arrow-key press or one mouse-wheel line; defaults to 16 screen pixels at 96 DPI (fixes #2447)
- `SaveMemory` (0–100, default 50) controls how aggressively unused page and image caches are freed: 0 keeps them until an allocation fails, 100 drops them as soon as a page is off-screen
- Favorites can open as a full-window tab so long paths and names use the whole window; the sidebar Favorites panel still works independently. The sidebar Favorites/ToC width can also be dragged past half the window (keeps ~200px for the document)
- Favorites list has a search box (like Bookmarks), in both the sidebar panel and the Favorites tab
- Favorites can be sorted alphabetically by name (or page label) within each file instead of by page number: `SortFavoritesByName = true`, or the **Sort By Name** checkbox in the Favorites tree context menu (fixes #2277)
- rename `CmdDiscardAnnotations` to `CmdDiscardChanges` ("Discard Changes"): reloads the current document from disk, dropping unsaved annotations and form changes; available from the tab context menu when there are unsaved changes and with `Ctrl + K`, `Discard Changes` command in [Command Palette](Command-Palette.md)
- PDF bookmark / link destinations now apply Adobe-style view modes (`/Fit`, `/FitH`, `/FitV`, `/FitB`, `/FitBH`, `/FitBV`, `/XYZ` zoom) instead of only jumping to the page (fixes #5828)
- add `IgnoreDestinationZoom` advanced setting: when true, clicking a bookmark or a link inside the document keeps the zoom you are reading at instead of switching to the zoom the destination asks for; it still goes to the page and the position on it. The same option Adobe Reader and Foxit call "forbid the change of the current Zoom factor during execution of 'Go to Destination' actions"; off by default (discussion #5938)
- following an internal link or bookmark can flash a highlight at the destination so you can see where you landed (a bibliography entry, figure, or named dest). Uses the same color and fade as LaTeX forward search, and stays solid for about two seconds before fading so it is still there after the page jump. Off by default; turn it on with `HighlightLinkDestination = true` (fixes #1085, #5945)
- empty fillable PDF form fields are highlighted in pale blue so they are visible without hovering. Toggle with View → Highlight Form Fields, the command palette (`CmdToggleHighlightFormFields`), or the `HighlightFormFields` advanced setting (default **true**) (fixes #5966)
- add `DisableLinks` advanced setting (default **false**): when true, document links are ignored so you can select and read without accidentally following them — useful for drawings and schematics with many links. Toggle it from the command palette. The existing **Toggle Show Links** only draws a blue outline around links; it does not disable them (fixes #5939)
- add `RememberViewOffsetOnPageTurn` advanced setting (default **false**): next/previous page keeps the same view position on the new page instead of jumping to the top, so zoomed-in pages of similar size stay lined up. It applies to explicit page turns (`N` / `P`, click-to-turn, the toolbar arrows); wheeling off the bottom of a page still opens the next page at its top, because there you are continuing to read rather than turning a page (fixes #5069)
- add `MouseWheelTurnsPage` advanced setting (default **false**): one wheel notch goes to the next / previous page instead of scrolling, even when the page is zoomed past the window. Together with `RememberViewOffsetOnPageTurn` the view stays parked on the part of the page you are reading and the pages move under it, which is how sheet music and scans with wide margins are read without touching the keyboard. `Alt + wheel` still scrolls, so the rest of the page stays reachable, and `Shift + wheel` (horizontal) and `Ctrl + wheel` (zoom) are unchanged. Bind it to a key or a toolbar button with `CmdToggleBoolSetting MouseWheelTurnsPage` (fixes #5069)
- `EBookUI` and `ComicBookUI` each have their own `DefaultDisplayMode` so ebooks and comics can open in a different layout than PDFs (empty keeps the global `DefaultDisplayMode`) (fixes #2588)
- `ComicBookUI.DefaultZoom` sets the first-open zoom for comic archives (`.cbz`, `.cbr`, …); empty uses Fit Page (the historical comic default), not the global `DefaultZoom`. Use `fit width` so new comics fill the window while PDFs stay at Fit Page (fixes #5946)
- Favorites remember how far you had scrolled on the page, so jumping to one returns you to that place, not just the top of the page
- in facing and book view, a landscape comic or image page (wider than it is tall) occupies the whole two-page row instead of pairing with the next page, so a double-page spread stored as one image displays as a centerfold. Off with `ComicBookUI.LandscapeAsSpread = false` (or `ImageUI.LandscapeAsSpread` for image folders); default is on (fixes #1324, #872)
- add `EBookUI.FontName` advanced setting: the font family for ebooks (EPUB, MOBI, FB2, …), e.g. `Segoe UI` or `Microsoft YaHei`. Empty (the default) keeps the engine serif. When set, it overrides the document's own `font-family` so you can read in a sans-serif or a CJK UI font without editing the file (fixes #3138)
- `EBookUI.FontName` (and `CustomCSS`) now win over the document even when it sets the font in an inline `style="font-family: ..."` or on a `<span>`, so you no longer need `IgnoreDocumentCSS = true` to read an ebook in the font you picked. A font name that can't be loaded is reported with a notification instead of silently doing nothing (fixes #4600)
- the ebook settings (font, size, line spacing, layout size, CSS) can be set for a single document, as an `EBookUI` block inside its entry in `FileStates`. Fields you leave out use the global `EBookUI` value, and nothing is written to the settings file for documents you haven't customized (fixes #4600)
- add `EBookUI.Margin`: the white space around the text of a reflowable document, in points, instead of the fixed 3 em / 2 em MuPDF uses. Written like a CSS margin - one number for all four sides, two for top/bottom and left/right, or four in top-right-bottom-left order. `0` gives the text the whole page. Also settable per document, and in the eBook Settings dialog (fixes #4600)
- new **Change eBook Settings** command (`CmdChangeEbookSettings`): a dialog with the font, size, margin and line spacing for a reflowable document, which shows the CSS it generates from them and lets you take over and write that CSS yourself. Applies to the open document only or to all ebooks (fixes #4600)
- add `ChmUI.FontName` advanced setting to choose the font in the CHM fixed-page view and override fonts specified by the document (fixes #2737)
- add `EBookUI.LineSpacing` advanced setting: set a line-height multiplier such as `1.5` for more space between lines in EPUB, MOBI, FB2 and other reflowable ebooks; 0 keeps the document or engine default (fixes #476)
- **Toggle Manga Mode** is available for PDF, XPS, DjVu, ebooks, images and other fixed-page documents, not only comic books. It puts facing and book-view pages in right-to-left order and remembers that choice per document (fixes #2258)
- `DefaultDisplayMode` accepts `page aspect`: on first open of a PDF, XPS, DjVu or PostScript file, pick the layout from page 1 — taller than wide uses continuous + fit width (papers), wider than tall uses single page + fit page (slides). A remembered view for that file still wins (fixes #4055)
- add `Fullscreen.DisplayMode` advanced setting: page layout to use in presentation (`Ctrl + L`) and windowed fullscreen (`Shift + Ctrl + L` / `F11`). Empty (the default) keeps the current behavior — presentation still goes to single page and fit-page, windowed fullscreen keeps whatever layout you had. Set it to `facing` or `book view` to switch to that layout on enter and restore the previous layout on exit (fixes #4753)
- add `SidebarOnRight` advanced setting: when true, the bookmarks / favorites sidebar is on the right of the window instead of the left. Right-to-left UI languages already put it on the right; this setting does the same in left-to-right languages (fixes #2165)
- add `ClickEdgeToTurnPage` advanced setting: when true, a click (not a drag) on the left fifth of the page area goes to the previous page and a click on the right fifth goes to the next page — useful for comics and for reading with a mouse or touchpad. In manga (right-to-left) mode the sides are reversed. Off by default so a click still selects text. Presentation mode (`Ctrl + L`) already turns pages on click and is unchanged (fixes #1203)
- the floating Find window (`Ctrl + F`, then pop out) can limit a search to a page range: **Limit to pages 1-N:** accepts lists such as `3,4-6,18-`, or a single span `10-25`, `10`, `10-`, `-25`. Empty (the default) still searches the whole document. The `n / m` counter and the results list follow the same range (fixes #5694)
- warning notifications ("File not found", "Errors in document", update messages) use an amber background in every theme instead of a color derived from the theme accent, which came out as a loud purple in Dracula and a bright blue in GitHub Dark, and was indistinguishable from a normal notification in most other dark themes. Links inside a warning use the warning text color so they stay readable (fixes #5876)
- while a search is still scanning, the Find status shows the page it is currently on next to the running match count (e.g. `520 61`), so a long search over a big document visibly progresses even across stretches with no matches
- the compact Find bar can be resized: drag its left edge to make the search field wider or narrower (the bar stays anchored to the right edge and keeps its height)
- select text with the keyboard, like a browser's caret browsing: `F7` (**Select Text With Keyboard**) puts a text caret in the page. The arrow keys move it, `Shift + arrows` extend the selection, `Home` / `End` go to the ends of the line and `Ctrl + Home` / `Ctrl + End` to the ends of the document, `Ctrl + Left` / `Ctrl + Right` move by word, and `PageUp` / `PageDown` by a screenful. `v` switches to visual mode, where the arrows extend the selection without holding Shift (like Vimium's caret / visual modes). `Ctrl + C` or `y` copies and leaves the mode, `Esc` or `F7` leaves it without copying (fixes #4684, #4116)
- extend a text selection from the keyboard by a character or a word, whichever way it was started (mouse drag, double-click, `Ctrl + A` or `F7`): the **Extend Selection One Character/Word Left/Right** commands. They have no default shortcut because `Ctrl + Shift + Left/Right` already navigate between files, so assign your own in the `Shortcuts` section of the advanced settings (discussion #5922)
- laser pointer for presentations: the **Toggle Laser Pointer** command turns the mouse cursor over the document into a glowing red laser dot, so you can point at what you're talking about. It has no default shortcut — assign one in the `Shortcuts` section of the advanced settings — and while it's on the cursor no longer auto-hides in presentation mode. Invoke it again to get the normal cursors back (fixes #5930)
- zoom to a selection: select an area with `Ctrl + drag` (or select text), then **Zoom / To Selection** (`Ctrl + 4`, also in the right-click menu) scales the view so the selection fills the window and centers it. The selection is kept, so you can still copy it, and `Alt + Left` (Navigate Back) returns to the view you zoomed from, zoom included (fixes #1699)
- follow links from the keyboard, like Vimium: `Shift + F` labels visible links with letters and highlights them; type a hint to follow the link (internal destination or URL). Prefix-free multi-letter hints are used when needed. `Shift + F` again or `Esc` leaves the mode. The labels follow the page while you scroll and are recalculated shortly after scrolling stops. Not offered for comic books, image folders and images, whose pages can't have links (fixes #2629)
- Bookmarks sidebar: **Collapse All** expands a single top-level root one level when that is all the outline has (typical Word-export TOC), and the context menu has **Expand to Level 1/2/3** for explicit depth control (fixes #5239)
- Bookmarks context menu **Collapse Same Level** collapses every outline entry that shares the parent of the selected/clicked item (siblings at that nesting level) (fixes #1895)
- FB2 document properties (`Ctrl+D`) now show the book annotation from `title-info` as Subject (fixes #2254)
- hovering a link that goes to a place inside the document shows the description the PDF gives it (the link annotation's `/Contents`), the way hovering an external link shows its URL; before, such links showed nothing (fixes #1724)
- Space in File Explorer (or on the desktop) previews the selected file in a popup, like macOS Quick Look. Esc or Space closes it; Left / Right open the previous / next file in the folder. Off with `ExplorerQuickLook = false` (fixes #2568)
- clicking a component on an Altium Designer schematic PDF shows a popup with the part's properties (comment, footprint, value, …). A line that contains a URL can be opened. Those hotspots used Acrobat JavaScript and previously did nothing (fixes #1198)
- bookmarks (PDF outline) entries are drawn with the color and the bold / italic style the document asks for
- zoom further than 6400%, for documents like large maps where the old limit hid detail that is in the file: the largest level in the `ZoomLevels` advanced setting is now the maximum zoom, so adding e.g. `12800 25600 51200` to it zooms that far. Values up to 1000000 are accepted; a given document is also limited by its own size, since all of its pages have to fit on one canvas. [Scrolling and zooming](Scrolling-and-zooming.md) documents the built-in levels as a `ZoomLevels` line to copy and edit (fixes #1195)
- add `ToolbarCustomLayout` advanced setting: the built-in toolbar buttons you want and the order you want them in, e.g. `ToolbarCustomLayout = CmdFindFirst | PageInfo CmdGoToPrevPage CmdGoToNextPage`. Leaving a button out hides it, `|` is a separator and `PageInfo` is the page number box; empty (the default) is the standard layout, which [Customize toolbar](Customize-toolbar.md) documents as a layout you can edit down (fixes #5095)
- new `Advanced Settings...` dialog (`Ctrl + K`, `Advanced Settings...` command in [Command Palette](Command-Palette.md)): a filterable list of the advanced settings where you can toggle booleans, pick enum values from a drop-down and edit strings, colors and numbers in-place, then `Save`. Replaces the per-setting toggle commands (`CmdToggleSmoothScroll`, `CmdToggleEscToExit`, `CmdToggleReuseInstance` etc.), which were removed
- can open and view Markdown documents (`.md`, `.markdown`): they render as formatted text (GitHub Flavored Markdown, including tables, task lists and strikethrough) via the rendering engine, and the installer registers the file association so they open from Explorer and drag&drop
- Markdown (WebView2 UI): fenced `mermaid` code blocks are rendered as diagrams (bundled Mermaid runtime, works offline). Fixed-page MuPDF markdown still shows the source code
- in Markdown and HTML documents, a relative link to a document rather than to another page — `[the manual](./manual.pdf)`, an `.epub`, a `.cbz` — opens that document in SumatraPDF (`Ctrl + click` opens it in a new window); files of a type we can't open are handed to the shell instead. Links to other pages, images and other web resources still follow inside the document view (discussion #5924)
- Markdown documents have a **Show Generated HTML** command (`Ctrl + K`, `Show Generated HTML` command in [Command Palette](Command-Palette.md)) that saves the rendered HTML to a temporary `.html` file and opens it in Notepad
- can open Windows icon files (`.ico`); a file with several sizes shows each size as a page
- HEIC / HEIF still images now decode with a built-in decoder (no Windows HEIC codec required for most phone photos); AVIF still uses dav1d. The system WIC path remains as a fallback if built-in decode fails
- With `SidebarWindowSize = grow` (default `keep` leaves the window alone, fixes #6205), showing the Bookmarks (or Favorites) sidebar grows the window when the work area has room, so the page keeps its size; hiding it shrinks the window again. Switching tabs does not change the window size. If the grown window would sit off-screen it is moved fully into view. If there is not enough room, the canvas shrinks as before (fixes #6080)
- Read Aloud underlines the sentence being spoken (blue) and the current word (amber), instead of a yellow background highlight
- Read Aloud **Voice** lists SAPI voices as well as WinRT OneCore voices, so adapters such as NaturalVoiceSAPIAdapter show up (fixes #6105)
- Read Aloud: adjustable playback speed — pick it in the new `Speed` submenu (next to `Voice` in the Read Aloud menu, toolbar dropdown and context menu) or with the speed slider on the playback bar; the speed persists across sessions via the `ReadAloudSpeed` advanced setting
- clicking an empty signature field in a PDF opens **Sign Document** with that field already selected, instead of doing nothing and leaving the command to be found in a menu (fixes #5964)
- **Sign Document** can use a certificate from the current user's Windows certificate store (the Personal / MY store), not only a `.pfx` / `.p12` file. The drop-down lists store certificates that have a private key; pick **Certificate file...** to keep the old file-and-password path (fixes #5965)
- adding a new signature (**New signature on page N**) now asks you to click or drag on the page to place it, instead of putting it in a fixed corner. A selection already on the page is still used (fixes #5967)
- **Sign Document** appearance: choose which lines the signature draws (labels such as "Digitally signed by", the name, the distinguished name, the date), and optionally a PNG or JPEG on the left instead of the large name (fixes #5963)
- EPUB, MOBI and HTML documents show WebP images instead of an IMAGE placeholder (fixes #3415). Standalone `.webp` files and comics already worked.
- updated the bundled MuPDF rendering engine to 1.28.5
- add [AI Chat with document](AI-Chat-with-document.md) sidebar (in View menu and `Ctrl + K` [Command Palette](Command-Palette.md)) for asking questions about the open PDF or image via [Claude Code](https://docs.anthropic.com/en/docs/claude-code); per-tab session state, model/effort selection, and session history from `~/.claude/projects/`
- add `ClaudeCode` advanced settings (`Model`, `Effort`, `SkipPermissions`, `BgColor`, `SidebarDx`) in `SumatraPDF-settings.txt`
- auto-link plain-text DOIs in PDF text (e.g. `10.1109/WICSA.2015.29` opens `https://doi.org/...`); uses the same auto-detect path as URLs and email addresses
- add `DisableAutoLinks` advanced setting to disable auto-linking of URLs, email addresses, and plain-text DOIs found in PDF text (fixes #5703)
- add `ShowDocumentFocusIndicator` advanced setting: when true, draws a focus ring around the document when it has keyboard focus (Tab to the page area); off by default (fixes #4644)
- add `ShowAnnotationNotification` advanced setting: when false, disables the tip shown when hovering an annotation (e.g. "Highlight annotation. Ctrl+click to edit."); on by default (fixes #4501)
- `ShowAnnotationAuthorInTooltip` optionally adds `Author: <author>` below an annotation tooltip's contents; off by default
- Bookmarks sidebar shows page numbers (labels) right-aligned on each entry; disable with `ShowTocPageNumbers = false` (fixes #3288)
- page-info tip shows extra detail for images: comics / image folders list the current image file name and size (both pages when two are visible in facing view); a single image file shows pixel resolution, size, and DPI when it is not the default 96 (fixes #4456)
- `-new-window` with several files opens each file in its own window. `-new-window-tabs` opens one new window and loads those files as tabs (issue #5044)
- Manga mode (R2L): Left/Right arrows and horizontal swipe reverse so Left advances and Right goes back, matching right-to-left reading (fixes #3964)
- starting a search (Ctrl+F) remembers the current page as favorite `/` so you can jump back via Favorites or the command palette `$` mode (fixes #5726)
- PDFs with a Catalog `/OpenAction` GoTo destination open at that page on first load (when there is no remembered view); URI/Launch/JavaScript open actions are ignored (fixes #1631)
- add `PaddingAfterLastPage` advanced setting: when true, continuous view has extra scroll room after the last page so you can bring the end of the document up (e.g. when the window is partly covered); off by default (fixes #411)
- document properties page size shows cm, mm, in (locale unit first) and points, e.g. `21.0x29.7 cm, 210x297 mm, 8.27x11.69 in, 595x842 pt` (fixes #2186, #5992)
- the `FixedPageUI.SelectionColor` advanced setting now honors an alpha channel: set an `#aarrggbb` value (e.g. `#40f5fc0c`) to make the text-selection overlay more transparent so selected text stays crisp instead of looking washed out; `#rrggbb` keeps the previous default opacity (fixes #3209)
- middle-click auto-scroll is now smooth: a high-frequency timer with fractional-pixel accumulation, so slow speeds stay even
- expand the table of contents tree down to the current page's entry and select it, like Explorer's "Expand to current folder" (in the Bookmarks sidebar right-click menu and the `Ctrl + K` Command Palette) (fixes #1998)
- Save As warns when a file can't be written (e.g. the destination path exceeds the Windows `MAX_PATH` limit)
- can convert an image to a PDF: right-click an image (or an open image document) and choose `Image / Convert to PDF`, or pick `PDF` in the format drop-down of the Save Image dialog. The new PDF gets `CreationDate`/`ModDate` metadata with the current time and time zone (fixes #949)
- **Image / Save** defaults to an exact copy: the dest file uses the original format (`.jpg` for a JPEG, …) and Save writes the original file bytes unless you crop, resize, or change the extension
- in the Favorites pane and menu, a favorite for a file with a long name now shows your favorite's name first, then the file name, so the name you gave it is no longer pushed out of view (fixes #829, #2236)
- case-insensitive search now treats German ß as equivalent to `ss`, so searching `Strasse` finds `Straße` and vice versa (fixes #933)
- hovering a thumbnail on the Frequently Read home page now shows a ✕ button in its top-right corner to remove that document from the list, without going through the right-click menu (fixes #283)
- home page document history: `Del` removes the keyboard-selected entry from history (shown as a shortcut on **Remove From History** in the right-click menu); the menu also has **Delete File** (recycle bin + drop from history) and **Show in folder** (Explorer, or Navigate Files in Folder when **File / Use SumatraPDF file picker** is on). The same **Show in folder** choice applies from File, the page context menu, and a tab's context menu
- Open File (`Ctrl + O`) can use either the standard Windows file picker or the in-app Navigate Files in Folder window (`FilePicker = os | sumatrapdf`, empty means Windows). Toggle with **File → Open → Use SumatraPDF File Picker**. **Open File With Windows File Picker** (`CmdOpenFileWithOSFilePicker`) always uses the system dialog. The home page no longer shows a separate Navigate Files in Folder link

- the home page document history can be shown as a list instead of thumbnails (toggle buttons next to the header, or the `HomePageViewMode = thumbnails | list` advanced setting). Each list row shows a small preview, the file name, the file's directory (right-aligned, muted), the file size, and remove/pin buttons (fixes #4909)
- new zoom mode `Fit by Orientation` (in the View / Zoom menu) that automatically fits width when the view is landscape and fits page when portrait, updating as you resize the window or rotate the screen (fixes #702)
- new zoom mode `Fit Height` (View / Zoom menu and command palette): scales the page so its height fills the window (width may require horizontal scrolling) — useful for landscape pages on portrait screens and for mixed page widths with a stable vertical size; also accepted as `-zoom fitheight` / advanced setting `fit height` and DDE zoom `-6` (fixes #1714)
- comics / images: advanced settings `ComicBookUI.LimitToWindowWidth` / `LimitToWindowHeight` and the same under `ImageUI` — when true, absolute zoom never makes a page wider (or taller) than the window; each page is capped independently so double-page spreads stay on screen while single pages can stay large (fixes #2197)
- comic book archives (`.cbz`, `.cbr`, …) whose images live in chapter folders now show those folders as nested Bookmarks (table of contents) entries. A directory shared by every file is still omitted so a single-folder comic stays a flat list. ComicInfo.xml bookmarks still win when present (fixes #5317)
- **Convert to PDF** (`CmdConvertToPDF`) for comic books (`.cbz`, `.cbr`, …), image folders, and single images: dialog suggests a unique `.pdf` path next to the source; original images are embedded when possible (fixes #4118, #5532). Docs: [Convert comics to PDF](Convert-comics-to-PDF.md)
- **Convert PDF to Images** (`CmdConvertPdfToImages`): dialog like Extract Text, with a destination path template (`<N>` is the page number), a PNG / JPEG / BMP format drop-down that updates the extension, and **Current** / **All** / **Custom** page radios (custom takes a range such as `1,3-5`). Writes one file per page at the chosen **Resolution (DPI)** (150 by default; pick from the list or type any value); PNGs are losslessly recompressed in the background (fixes #5991). Docs: [Convert PDF to Images](Convert-PDF-to-images.md)
- Explorer preview / thumbnails for FictionBook: plain `.fb2` and zip containers `.fb2z`, `.fbz`, `.zfb2`, and `.fb2.zip` (reinstall or re-enable the preview handler to pick up the extra extensions) (fixes #1677)
- add `sumatrapdf-tool.exe` command-line tools for PDF manipulation (see [Tools](Tools.md))
- [command palette](Command-Palette.md) has a new `%` mode that jumps to a table of contents entry of the current document (`Shift + F12`). Shows the fully expanded outline, indented by nesting level, with the entry closest to the current page pre-selected (fixes #5676)
- [command palette](Command-Palette.md) has a new `$` mode that jumps to a favorite, listing the current document's favorites first, then favorites of other documents
- [external viewer](Customize-external-viewers.md) command lines now support `%%` as a literal `%`, so e.g. `%%d` is passed to the program as `%d` (fixes #5583)
- with `ReuseInstance`, opening a file now reuses a window on the current virtual desktop (or opens a new window there) instead of switching to a window on another desktop (fixes #5630)
- add Back / Forward navigation buttons to the toolbar; navigation history now also records views you scrolled to and stayed on, not just table of contents / link jumps
- improved overlay scrollbar
- make thumbnails on home page scrollable
- add ability to register / unregister Windows preview handler and search filter from `Ctrl + K` Command Palette
- set a custom color for a document's tab from the tab right-click context menu
- compress, decompress, encrypt, decrypt, bake, delete pages from, and extract pages from PDF files (via `Ctrl + K` [Command Palette](Command-Palette.md))
- extract text from document pages to a .txt file (via `Ctrl + K` [Command Palette](Command-Palette.md))
- read text aloud using Windows text-to-speech: toolbar, main menu, and context menu **Read Aloud (TTS)** submenus with **Start Reading From Top** (viewport through end of document), **Start Reading Selection**, **Start Reading From Cursor Position** (context menu), pause / continue / stop, a playback bar on the canvas showing the document name, current page, and scope, word highlight while speaking, and a **Voice** submenu; chosen voice is remembered via the `ReadAloudVoiceId` advanced setting
- add `ToolbarText` and `ToolbarSvgIcon` parameters for `ExternalViewers` advanced setting to show external viewer as a toolbar button with text or an SVG icon (fixes #5741)
- move `Scrollbars` advanced setting from `FixedPageUI` to top-level
- toolbar has a new `overlay` mode: the toolbar floats over the page (sized to its natural width and centered) and is only revealed when the mouse moves near it. Set it with the new top-level `Toolbar = show | hide | overlay` advanced setting; `F8` (Toggle Toolbar) now cycles show → overlay → hide instead of just toggling show/hide
- the toolbar can be placed at the top or bottom of the window via the new `ToolbarPosition = top | bottom` advanced setting (works in both show and overlay modes)
- DjVu documents can be rendered with a new built-in plain-C decoder (`ext/djvudec`) instead of libdjvu
- add `EBookUI.BackgroundColor` advanced setting to override background color for ebook documents (epub, mobi etc.)
- add `ComicBookUI.BackgroundColor` advanced setting to override the default black background for comic book files
- add `ImageUI.BackgroundColor` advanced setting to override the default black background for image files
- background color settings (`FixedPageUI.BackgroundColor`, `EBookUI.BackgroundColor`, `ComicBookUI.BackgroundColor`, `ImageUI.BackgroundColor`) accept `checkered` value to show a checkerboard transparency pattern
- change document background color per-file or for all files of the same type (via `Ctrl + K` [Command Palette](Command-Palette.md))
- `Ctrl + click` on a PDF link opens it in a new tab (instead of navigating in the current tab)
- you can now drag&drop selected text to another application, like a text editor
- triple-click selects the whole line of text (double-click still selects a word) (fixes #694)
- add `stretch` page scaling (and a matching "Stretch pages to fill paper" option in the Advanced print dialog) that fills the paper in both dimensions, ignoring the aspect ratio (fixes #2220)
- add "Center page horizontally on the paper" option to the Advanced print dialog, to center a page smaller than the paper (fixes #348)
- add "Choose paper source by document page size" option to the Advanced print dialog, to let the printer pick the input tray whose paper matches the page (fixes #349)
- add "Print each page at its document page size" option to the Advanced print dialog, to correctly print documents with mixed page sizes (fixes #533)
- command-line printing now honors print defaults embedded in a PDF's `ViewerPreferences` (`PrintScaling`, `NumCopies`, `Duplex`, `PickTrayByPDFSize`); explicit `-print-settings` values override them, and `ignore-pdf-print-settings` disables them (fixes #534)
- command-line printing (`-print-to` / `-print-to-default`) now returns a distinct process exit code per failure category (file not loadable, printing not allowed, printer not found, driver failed, etc.) instead of a plain success/failure, so unattended callers can tell why a print failed (fixes #3478)
- can set a default for the print dialog's Collate checkbox via the new `PrinterDefaults.Collate` advanced setting (fixes #1558)
- add a "Rotate printout" option to the Advanced print dialog, to rotate the printout and fix a wrong orientation (e.g. upside-down output on virtual printers like XPS / Print to PDF) (fixes #1246)
- implement the `[GetFileState]` [DDE command](DDE-Commands.md) to query a document's path, zoom, view mode and version
- `[GetFileState]` also returns the current page and page count, and a new `[GetOpenFiles]` DDE request returns the paths of all open documents (fixes #5060)
- add `[GetMousePos]` DDE request returning the document position under the mouse cursor in PDF points (the `.smx` unit), for external annotation tools (fixes #1411)
- `[SetView]` DDE command now accepts a zoom of `0` to keep the current zoom
- toggle commands (`CmdToggleFullscreen`, `CmdTogglePresentationMode`, `CmdToggleToolbar`, `CmdToggleMenuBar`, `CmdToggleContinuousView`, `CmdToggleTableOfContents`/`CmdToggleBookmarks`) accept an optional `state` argument to force an on/off state instead of toggling, e.g. `[CmdToggleFullscreen on]` (fixes #5067)
- add `[GotoPageWord]` [DDE command](DDE-Commands.md) to go to a page and select a search term only if it's on that page (a page-constrained search, unlike `[Search]` which wraps); also documented the existing `[Search]` DDE command (fixes #3085)
- move `DefaultImageZoom` advanced setting to `ImageUI.DefaultZoom`, default to `shrink to fit`
- you can now transition between using tabs / not using tabs (`UseTabs` advanced setting) without restarting the app
- allow showing menu bar when using tabs (previously menu bar was only shown when not using tabs)
- capture screenshots of the desktop and all visible windows, saved as PNG files in `Screenshots` sub-directory of SumatraPDF data directory (global hotkey e.g. PrtSc requires a Shortcuts entry)
- you can drag&drop images from a browser onto SumatraPDF window. We'll download it to Downloads folder and open
- crop and resize images when viewing image files
- `Ctrl + V` pastes image from clipboard, saves as PNG in Downloads folder and opens it
- Can save images in different formats: PNG, JPEG, BMP, GIF, TIFF.
- add `Fullscreen` advanced setting with `Toolbar` (show / hide / overlay, like `Toolbar`) and `ShowMenubar` options for fullscreen mode. Use `F8` / `F9` to toggle toolbar / menubar while in fullscreen. Legacy `ShowToolbar` / `Fullscreen.ShowToolbar` remain for migration only
- add `Show Errors` in right-click context menu for PDF documents that have mupdf warnings/errors
- replace `HideScrollbars` and `UseOverlayScrollbar` settings with `Scrollbars` setting (values: `windows`, `smart`, `overlay`, `hidden`)
- save and restore groups of tabs; saved groups are persisted in `TabGroups` advanced setting
- add `Shrink To Fit` zoom mode: shows at 100% if page is smaller than view area, otherwise fits page
- add `TabsMru` advanced setting to change order of navigating tabs when using `Ctrl + Tab`
- add `CtrlTabSimple` advanced setting: when true, `Ctrl + Tab` / `Ctrl + Shift + Tab` switch to the next / previous tab immediately, in tab-strip order, without showing the tab switcher (the behavior before 3.6)
- the tab switcher (`Ctrl + Tab`) window is sized to the number of tabs instead of always being a tall, mostly empty window
- improve document properties for comic book files (CBZ, CBR, CB7, CBT). We now show list of image files and per-image EXIF metadata
- improve document properties for image files: size, dimensions, DPI, exif metadata
- support encrypted .cbz, .cbr files
- you can drag&drop images from PDF documents to other applications (web apps, image editors, file explorer etc.)
- pen/stylus input now works for text selection on Windows tablets
- use `GetFileAttributesEx` instead of opening files for change detection on network drives, avoiding Windows Defender re-scans
- add citation/reference hover preview: hovering an internal-document link (e.g. a `[1]` citation, figure reference, or footnote marker) now shows a small popup rendering the destination region, so you can see the bibliography entry / figure / footnote without leaving the current page. The `CitationHoverDelay` advanced setting sets the hover delay in ms (-1 disables the popup). With the cursor on the link, `Shift + wheel` (or a horizontal wheel) scrolls the popup and `Ctrl + wheel` zooms it; with the cursor on the popup, the wheel scrolls it and `Ctrl + wheel` zooms it. See [Citation hover preview](Citation-hover-preview.md) (fixes [#128](https://github.com/sumatrapdfreader/sumatrapdf/issues/128), [#4221](https://github.com/sumatrapdfreader/sumatrapdf/issues/4221))
- translate selected text with Grok Build, Claude Code, OpenAI Codex, or Antigravity when the corresponding CLI is installed (selection context menu); opens a dialog to edit the text, pick source and destination languages, and show the translation inline
- add a **Match whole word** toggle to the Find bar (next to **Match Case**) so a search only matches complete words, e.g. `cat` no longer matches `category` (fixes #4295)
- when searching, the **current** match is now highlighted with the customizable `FixedPageUI.SelectionColor` (the color users tune to be most noticeable) and all other matches use a secondary orange highlight, so the active match is easier to spot; previously it was the other way around (fixes #5740)
- find-as-you-type now waits briefly after you stop typing before searching (500 ms, or 1 s for 1–2 character terms) instead of searching on every keystroke; pressing Enter searches immediately (fixes #4626)
- add **Go to Next/Previous Favorite** commands (`Ctrl + K` Command Palette) that jump to the nearest favorite (bookmark) page after / before the current page (fixes #3744)
- can paste an image from the clipboard into a PDF as an image stamp annotation: right-click → **Create Annotation Under Cursor** → **Image From Clipboard** (or the `Ctrl + K` Command Palette). The stamp is created at the click point, sized to the image, and immediately selected so it can be moved/resized
- text in some PDFs that use embedded subset fonts naming glyphs like `G45` (with no `ToUnicode` map) is now extracted and searchable: previously such text came out as `�` and couldn't be found (e.g. searching "Emergency" failed). mupdf now recovers Unicode from those glyph names the way pdf.js does (fixes #3219)
- add `AllowExternalImages` advanced setting (off by default): when on, a PDF may display an image stored in a separate file referenced by name (an "external image stream"); the file must sit next to the PDF. Off by default for security, matching Acrobat (fixes #3731)
- add **Set Inverse Search Command Line** (`Ctrl + K`, `Set Inverse Search Command Line` command in [Command Palette](Command-Palette.md)): opens a standalone dialog to configure the SyncTeX inverse-search command (with detected TeX editors in a drop-down and a Help link to [LaTeX integration](LaTeX-integration.md)); OK saves `InverseSearchCmdLine` and enables TeX enhancements, Cancel leaves settings unchanged. Works from the home page without an open document
- one-click light/dark theme switching: **Toggle Light/Dark Theme** (`Ctrl + K`, `Toggle Light/Dark Theme` command in [Command Palette](Command-Palette.md)) flips between the last used light and dark themes (remembered in the new `LastLightTheme` / `LastDarkTheme` advanced settings). **Follow Windows** in the Change Theme dialog (or `Theme = System` in advanced settings) makes SumatraPDF follow the Windows light/dark app mode, switching automatically when the OS does (fixes #5995). Inspired by the [SumatraPDF Plus](https://github.com/dengxibo/sumatrapdf-plus) fork
- caption (title bar) minimize/maximize/restore/close buttons are drawn with Windows 11 style rounded glyphs (Segoe Fluent Icons outlines), DPI-scaled (from the [SumatraPDF Plus](https://github.com/dengxibo/sumatrapdf-plus) fork)
- new built-in **Light Warm** theme: a warm, paper-like "eye-care" chrome palette (from the [SumatraPDF Plus](https://github.com/dengxibo/sumatrapdf-plus) fork; their Dracula and pure-black dark palettes already exist here as the `Dracula` and `Dark` themes)
- smarter inverted (dark) page rendering for MuPDF documents (PDF, XPS, EPUB, MOBI, FB2, HTML, etc.): the `DocumentColorsFollowTheme` advanced setting (also via `Ctrl + K`, `Set Document Colors Follow Theme` command in [Command Palette](Command-Palette.md) and the **Change Theme** dialog) picks how page colors follow the UI theme: `off` (keep original page colors, the default), `smart` (recolor text and background but not images), or `legacy` (recolor text, background and images — pre-3.7 behavior). **Invert Colors** / `Shift + I` swaps the page colors for the session and is not saved. **Toggle Preserve PDF Image Colors in Dark Mode** switches image preservation for the session. Ported from the [SumatraPDF Plus](https://github.com/dengxibo/sumatrapdf-plus) fork
- reflowable MuPDF documents (EPUB, HTML, FB2, MOBI, TXT) apply those page colors as user CSS, so images stay as in the file even in `legacy` mode and when inverting with `Shift + I`
- a small floating toolbar pops up after selecting text, with the most common selection actions: **Copy**, **Read Aloud**, **Highlight**, **Underline**, **Squiggly**, **Strike Out** (annotation buttons only for documents that support annotations). It appears half a second after the selection settles, so it does not flash in and out while you are still selecting. Disable it with the new `SelectionToolbar` advanced setting. Ported from the [SumatraPDF Plus](https://github.com/dengxibo/sumatrapdf-plus) fork
- add `Annotations.FreeTextAlignment` advanced setting (`left`, `center`, `right`): how text is aligned in newly created free text annotations, so the **Text Alignment** you want no longer has to be set by hand on every annotation. Right-to-left scripts (Arabic, Hebrew, Persian) want `right`. `CmdCreateAnnotFreeText` and the other `CmdCreateAnnot*` commands take a matching `alignment` argument (issue #4799)
- clearer rendering of CAD / engineering-drawing PDFs: hairline strokes get a zoom-aware minimum width and typical CAD-export grays are darkened toward Acrobat-like contrast, so drawings stay readable when zoomed out. Off by default. Set `EngineeringDrawingEnhance` to `auto` to apply when a drawing is detected (PDF/E marker, CAD authoring tool in the metadata, or content heuristics; screenshot/raster and WPS-style hairline exports are handled too), or `on` for every PDF; per document, **Toggle Engineering Drawing Enhancement** (`Ctrl + K`, `Toggle Engineering Drawing Enhancement` command in [Command Palette](Command-Palette.md)). See [CAD / Engineering Drawings](CAD-Engineering-Drawings.md). Ported from the [SumatraPDF Plus](https://github.com/dengxibo/sumatrapdf-plus) fork
- **Fit Content** (`Ctrl + 3`) now works on print-ready PDFs. Those draw crop and registration marks in the bleed area outside the page, and the content detection used to count them, so it reported the whole page and zooming to content did nothing. Ink drawn outside the page is now ignored. Same for **Shrink** / **Fit to printable area** printing, which uses the same detection. Fit Content also crops the margins properly in the non-continuous **Single Page**, **Facing** and **Book View** modes (it used to show the top/left margin with the content cut off at the other end), and in the continuous modes the mouse wheel now scrolls the document instead of flipping a whole page per notch
- PDF documents can be digitally signed from the UI: **Sign Document...** (in the right-click **Document** submenu, for PDFs only) asks for a certificate (a `.pfx` / `.p12` file plus its password) and an optional reason and location, then fills in an empty signature field the document already has, or adds a new signature: you click or drag on the page to place it (or it uses the current selection if there is one) and saves to a file you pick. Previously signing was only possible with the bundled `sumatrapdf-tool sign` command line. The signature is written incrementally, so signatures already in the document stay valid, and Document Properties reports the signer and whether the document changed since signing (fixes #5962, #5967)
- The Annotations window can select many annotations with the usual Windows keys (`Shift` or `Ctrl` click, `Shift` + arrows, `Ctrl + A`) and `Del` deletes all of them (fixes #5976)
- **Bake PDF** includes annotations created in the current session
- Find remembers the last 10 search queries for the session (not saved to settings) and offers them from a drop-down on the find field (fixes #893)
- Re-opening Find (`Ctrl + F`) with the previous term still in the box highlights its matches on the visible pages without jumping to one; `Enter` restarts the search from the current page (fixes #6280)
- **Stop Reading** is always in the Read Aloud menu (main menu, context menu, toolbar dropdown), even when the playback bar is not visible, so a session can still be stopped from the top menu (fixes #6053). It is disabled when nothing is being read; the command palette lists it only while a session is active
- **Navigate Thumbnails** opens a page-thumbnail grid for the current fixed-page document; thumbnails appear as they are rendered in the background, and the grid supports arrow-key navigation, mouse selection, double-click or Enter to open a page, Escape to close, and a scrollbar for long documents. EPUB/MOBI thumbs show `chapter / page` on a rounded badge; each thumb is the chapter page it will open, not a shifted flat page number after another chapter laid out
- Multi-chapter ebooks (EPUB, MOBI) open showing only the first chapter and lay out the rest as you read them, instead of paginating the whole book up front — a 1000-chapter MOBI now opens in about 0.1s instead of roughly 40s. For those documents the toolbar shows **Chapter: [n] / N** next to **Page: [n] / M** (the page within the current chapter), the Go to Page dialog asks for a chapter and a page, and Next Page / Previous Page cross chapter boundaries. The remembered reading position is a chapter bookmark, so it survives font-size changes that reflow the book; old plain page numbers in settings still open at that flat page
- The document context menu groups copy / zoom / select under **Selection**, Google Lens under **Visual Search With Google Lens** (selection as image, this page, or the image under the cursor), and image actions under **Selected Image** (including Lens). **Copy As Image To Clipboard**, **Save As Image**, **Zoom To Selection**, and Lens from **Selection** appear only for a rectangular selection

**New commands:**

- `CmdMergePDF` : "Merge PDF..." — reorder, remove and add pages of a PDF by their thumbnails (fixes #6070)
- `CmdToggleThumbnails` : "Toggle Thumbnails" — shows or hides the sidebar's Thumbnails view (page thumbnails)
- `CmdOpenSettingsFile` : "Open Advanced Settings File..." — opens the settings file in the .txt editor (what Advanced Options did before it became a dialog)
- `CmdToggleFreePan` : "Toggle Free Pan" — scroll room past the page edges so a corner can be centered on screen; remembered per document (discussions #6224, #6164)
- `CmdGoToHomePage` : "Go To Home Page" — switch to the Home tab, adding it when `NoHomeTab` hid it (fixes #6228)
- `CmdZoomFitVisible` : "Zoom: Fit Visible" — content width fills the window (fixes #6241)
- `CmdAutoGenerateTOC` : "Generate Table Of Contents" — Bookmarks from numbered headings, on demand (fixes #6227)
- `CmdSignWithImage` : "Sign With Image" — stamps `Annotations.SignatureImage` without a file picker
- `CmdInsertTextSnippet` : "Insert Text Snippet" — base of the `TextSnippets` commands; not listed on its own
- `CmdApplyRedactions` : "Apply Redactions" — permanently removes content marked with the Redact tool
- `CmdToggleEditPDF` : "Toggle Edit PDF" — shows or hides Edit PDF mode
- `CmdUndo` : "Undo" — take back the last change to the PDF (`Ctrl + Z`)
- `CmdRedo` : "Redo" — re-apply the change Undo took back (`Ctrl + Shift + Z`)
- `CmdCutAnnotation` : "Cut Annotation" — copies the annotation and deletes it when the copy is pasted (`Ctrl + X`)
- `CmdCopyAnnotation` : "Copy Annotation" — copies the selected annotation in Edit PDF mode (`Ctrl + C`)
- `CmdPasteAnnotation` : "Paste Annotation" — pastes the copied annotation with its top-left at the mouse (`Ctrl + V` in Edit PDF mode)
- `CmdToggleUniformPageWidth` : "Toggle Uniform Page Width"
- `CmdAIChatWithClaudeCode` : "AI Chat"
- `CmdChangeBackgroundColor` : "Change Background Color"
- `CmdChangeTheme` : "Change Theme..." — dialog to pick a UI theme and document-color follow mode
- `CmdNavigateThumbnail` : "Navigate Thumbnails" — thumbnail grid for choosing a page
- `CmdChangeScrollbar` : "Change Scrollbar"
- `CmdCommandPalette %` : command palette table-of-contents mode (`CmdCommandPaletteTOC`, `Shift + F12`)
- `CmdCommandPalette $` : command palette favorites mode (`CmdCommandPaletteFavorites`)
- `CmdCommandPaletteFavorites` : "Command Palette: Favorites"
- `CmdContinueReadAloud` : "Continue Reading"
- `CmdDeleteFileAndOpenNext` : "Delete File And Open Next" — opens the next file in the folder, then moves the previous file to the Recycle Bin (discussion #5845)
- `CmdFavoriteShowInTab` : "Show Favorites in Tab" — full-window Favorites tab (sidebar Favorites still works)
- `CmdToggleFavoritesSort` : "Sort Favorites By Name" — Favorites tree context menu checkbox; toggles `SortFavoritesByName` (fixes #2277)
- `CmdZoomFitHeight` : "Zoom: Fit Height" — scale page height to the window (fixes #1714)
- `CmdSelectTextViaKeyboard` : "Select Text With Keyboard" (`F7`) — caret browsing: move a text caret with the arrows and select without the mouse (fixes #4684, #4116)
- `CmdExtendSelectionCharLeft`, `CmdExtendSelectionCharRight`, `CmdExtendSelectionWordLeft`, `CmdExtendSelectionWordRight` : "Extend Selection One Character/Word Left/Right" — no default shortcut, bind your own (discussion #5922)
- `CmdToggleLaserPointer` : "Toggle Laser Pointer" — laser dot cursor over the document, no default shortcut, bind your own (fixes #5930)
- `CmdToggleHoverPreview` : "Toggle Citation Hover Preview" — palette-only; enables/disables the citation/reference hover popup (`CitationHoverDelay`)
- `CmdToggleDisableLinks` : "Toggle Disable Links" — palette-only; toggles `DisableLinks` (fixes #5939)
- `CmdZoomToSelection` : "Zoom: To Selection" (`Ctrl + 4`) — zoom so the selection fills the window (fixes #1699)
- `CmdOpenFileNoHistory` : "Open File Without History..." — same picker as Open File; not added to File History or Windows Recent (fixes #6121)
- `CmdOpenFileWithOSFilePicker` : "Open File With Windows File Picker..." — always the system multi-select open dialog (when `FilePicker = sumatrapdf`, use this to force the Windows picker)
- `CmdToggleFilePicker` : "SumatraPDF File Picker" — the **Use SumatraPDF File Picker** check in **File → Open**; toggles `FilePicker` between Windows and SumatraPDF
- `CmdToggleBoolSetting` : "Toggle Boolean Setting" — custom shortcut/toolbar command with a setting name argument, e.g. `CmdToggleBoolSetting Fullscreen.ShowMenubar` (fixes #5912)
- `CmdFixDefaultApp` : "Fix Default App For Extension" — `CmdFixDefaultApp .pdf` opens the OS default-app UI for that extension; home page shows a bottom bar with fix links when registered extensions are no longer default
- `CmdToggleKeyboardLinkFollowing` : "Follow Link With Keyboard" (`Shift + F`) — labels visible links with Vimium-style letter hints; type a hint to follow its link (fixes #2629)
- `CmdFindToggleMatchWholeWord` : "Find: Toggle Match Whole Word" — Find bar toggle button
- `CmdGoToNextFavorite` : "Go to Next Favorite"
- `CmdNavigateFilesInFolder` : "Navigate Files in Folder" (`Ctrl + Shift + Up`) — directory browser for openable files (stays open; Enter/double-click replaces the current tab or enters a directory, `Ctrl + Enter`/`Ctrl + double-click` uses an existing or new tab, `..` goes up, `Del` deletes the selected file, `F5` refreshes, Esc closes)
- `CmdGoToPrevFavorite` : "Go to Previous Favorite"
- `CmdCreateAnnotImageFromClipboard` : "Create Image Annotation From Clipboard"
- `CmdAnnotationHighlightBrush` : "Highlighter" — mode that highlights every text selection until Esc or Enter
- `CmdFindAnnotation` : "Find Annotation" — opens the floating annotation list (fixes #6086)
- `CmdStopReadAloud` : "Stop Reading"
- `CmdReadAloudFromTopPage` : "Start Reading From Top"
- `CmdReadAloudSelection` : "Start Reading Selection"
- `CmdToggleGrayscale` : "Toggle Grayscale" — render document pages in grayscale; saved in `FixedPageUI.Grayscale` (#6207)
- `CmdReadAloudFromCursorPosition` : "Start Reading From Cursor Position" — no default shortcut, bind your own (discussion #6213)
- `CmdConvertImageToPdf` : "Convert Page To PDF" — image editor path for one page
- `CmdConvertToPDF` : "Convert To PDF..." — comic / image folder / image → multi-page PDF (fixes #4118, #5532)
- `CmdConvertPdfToImages` : "Convert PDF to Images..." — PDF pages → PNG / JPEG / BMP (fixes #5991)
- `CmdCropImage` : "Crop Image"
- `CmdDocumentExtractText` : "Extract Text From Document"
- `CmdDocumentShowOutline` : "Show Document Outline"
- `CmdExpandToCurrentPage` : "Expand TOC to Current Page"
- `CmdTocExpandToLevel1` : "Bookmarks: Expand to Level 1" — Bookmarks context menu
- `CmdTocExpandToLevel2` : "Bookmarks: Expand to Level 2" — Bookmarks context menu
- `CmdTocExpandToLevel3` : "Bookmarks: Expand to Level 3" — Bookmarks context menu
- `CmdTocCollapseSameLevel` : "Bookmarks: Collapse Same Level" — Bookmarks context menu
- `CmdListPrinters` : "List Printers"
- `CmdPauseReadAloud` : "Pause Reading"
- `CmdPdfBake` : "Bake PDF File"
- `CmdPdfCompress` : "Compress PDF"
- `CmdPdfDecrypt` : "Decrypt PDF"
- `CmdPdfDecompress` : "Decompress PDF"
- `CmdPdfDeletePages` : "Delete Pages From PDF"
- `CmdPdfEncrypt` : "Encrypt PDF"
- `CmdPdfExtractPages` : "Extract Pages From PDF"
- `CmdPdfShowInfo` : "Show PDF Info"
- `CmdToggleReadAloud` : "Toggle Read Aloud"
- `CmdRemoveDeletedFilesFromHistory` : "Remove Deleted Files From History"
- `CmdDeleteCachedFiles` : "Delete Cached Files" — deletes local network-drive comic book cache (`cbx-cache`)
- `CmdResizeImage` : "Resize Image"
- `CmdScreenshot` : "Take Screenshot"
- `CmdSetScreenshotHotkey` : "Set Screenshot Hotkey"
- `CmdSetInverseSearch` : "Set Inverse Search Command Line" — opens a dialog to configure the SyncTeX inverse-search command (`Ctrl + K`, `Set Inverse Search Command Line` command in [Command Palette](Command-Palette.md))
- `CmdShowGeneratedHTML` : "Show Generated HTML" — available for Markdown documents
- `CmdSetTabColor` : "Set Tab Color"
- `CmdStartAutoScroll` : "Start Auto-Scroll"
- `CmdToggleAutomaticallyScroll` : "Automatically Scroll" — hands-free continuous pan (`Ctrl + Shift + H`)
- `CmdAutomaticallyScrollFaster` : "Automatically Scroll Faster"
- `CmdAutomaticallyScrollSlower` : "Automatically Scroll Slower"
- `CmdToggleReadingBar` : "Reading Bar" — highlight or mask a horizontal band on the page
- `CmdToggleReadingBarInvert` : "Reading Bar Invert" — dim everything except the reading bar
- `CmdTabGroupRestore` : "Restore Tab Group"
- `CmdTabGroupSave` : "Save Tab Group"
- `CmdSetDocumentColorsFollowTheme` : "Set Document Colors Follow Theme"
- `CmdToggleEngineeringDrawingEnhance` : "Toggle Engineering Drawing Enhancement" — per-document override of the `EngineeringDrawingEnhance` advanced setting
- `CmdToggleLightDarkTheme` : "Toggle Light/Dark Theme"
- `CmdTogglePreservePdfImages` : "Toggle Preserve PDF Image Colors in Dark Mode" — session-only toggle
- `CmdToggleWindowsPreviewer` : "Toggle Windows Previewer"
- `CmdToggleWindowsSearchFilter` : "Toggle Windows Search Filter"
- `CmdTranslateSelection` : "Translate Selection..." — dialog to translate the current selection
- `CmdTranslateSelectionWithClaudeCode` : "Translate Selection with Claude Code"
- `CmdTranslateSelectionWithGrokBuild` : "Translate Selection with Grok Build"
- `CmdTranslateSelectionWithOpenAICodex` : "Translate Selection with OpenAI Codex"
- `CmdTranslateSelectionWithAntiGravity` : "Translate Selection with Antigravity"
- `CmdZoomFitByOrientation` : "Fit by Orientation"
- `CmdZoomShrinkToFit` : "Shrink To Fit"
- `CmdDebugShowFitContentArea` : "Debug: Show Fit Content Area" — Debug menu checkbox; outlines in red the area **Fit Content** zoom would fit to, without changing the zoom
- `CmdTogglePageBoxes` : "Toggle Page Boxes" — palette / Debug menu; outlines PDF Media/Crop/Bleed/Trim/Art boxes that the page actually has (fixes #814)
- `CmdSignDocument` : "Sign Document..." — sign a PDF with a Windows-store or `.pfx` / `.p12` certificate (fixes #5962)
- `CmdToggleTransparencyGrid` : "Toggle Transparency Grid" — View menu; session-only checkerboard under the page (fixes #1809)
- `CmdTogglePageGrid` : "Toggle Page Grid" — View menu; session-only graph paper on the page (fixes #4398)
- `CmdConfigurePageGrid` : "Configure Page Grid..." — View menu; dialog for grid spacing, origin, color and style
- `CmdCopySelectionAsImage` : "Copy Selection As Image" — clipboard image of a rectangular selection
- `CmdSaveSelectionAsImage` : "Save As Image..." — rectangular selection → PNG/JPEG/BMP at a chosen DPI (fixes #6127)
- `CmdSearchGoogleLensPage` : "Search Page with Google Lens"
- `CmdSearchGoogleLensImage` : "Search Image with Google Lens"
- `CmdToggleTrimEmptyMargins` : "Toggle Trim Empty Margins" — trims empty margins around page content from display on demand
- `CmdCopyLocationToClipboard` : "Copy Location To Clipboard" — palette-only; copies the current view (page, zoom, scroll position and file path) to the clipboard as cmd-line args that re-open it, e.g. `-page 33 -zoom "193%" -scroll 0,0 "Material.pdf"` (discussion #6163)

**New command-line arguments:**

- `-for-testing` : for ad-hoc testing; always starts a new instance, doesn't restore a session, doesn't save settings
- `-quicklook` : open a chrome-less always-on-top preview window (Explorer Space preview) (fixes #2568)
- `-quicklook-agent` : hidden File Explorer Space-bar helper (started when `ExplorerQuickLook` is true)
- `-dbg-control <named-pipe>` : drive automated tests over a named-pipe request/response protocol (`tests/control.ts`)
- `-dump-chm <file>` : headlessly list CHM contents, unpack entries to memory, and print TOC/index metadata
- `-pwd <password>` : open password-protected documents from the command line (fixes #906)
- `-new-window-tabs` : one new window, all files as tabs (issue #5044)
- `-log-to-file <file>` : log to a specific file (like `-log` but with a custom log file path)
- `-html-backend <ie|webview2>` : force the embedded browser used for CHM / markdown documents
- `-no-desktop-shortcut` : installer: don't create a desktop shortcut (discussion #6255)
- `/p` : Adobe Reader-compatible alias for `-print-dialog`
- `/t` : Adobe Reader-compatible silent print (alias for `-print-to`)
- `sumatrapdf-tool.exe <tool> <args>` : command-line tools (draw, convert, audit, bake, clean, create, extract, info, merge, pages, poster, recolor, show, trim, grep, trace)
- `-print-settings` tokens: `stretch`, `center`, `bin=auto`, `paper=auto`, `collate` / `nocollate`, `rotate=<90|180|270>`, `ignore-pdf-print-settings`

## 3.6.1 (2026-04-06)

- bugfixes

## 3.6 (2026-03-17)

- add `DisableAntiAlias` advanced setting
- temporarily hide / show annotations
- temporarily disable mouse click invoking TeX inverse search
- add `bgcolor`, `opacity`, `textsize`, `borderWidth` arguments to `CmdCreateAnnot*` commands
- add `Annotations.FreeTextBackgroundColor` and `Annotations.FreeTextOpacity` advanced settings
- sort thumbnails on home page by most recently used date. Set advanced setting `HomePageSortByFrequentlyRead = true` to revert to pre-3.6 behavior of sorting by frequency of use.
- support brotli compression in PDF files
- in Command Palette, if you start search with `:` we show everything (like in 3.5)
- in Command Palette, when viewing opened files history (`#`), you can press Delete to remove the entry from history
- improved zooming:
  - zooming with pinch touch screen gesture or with ctrl + scroll wheel now zooms around the mouse position and does continuous zoom levels. Used to zoom around top-left corner and progress fixed zoom levels shown in menu
- include manual (`F1` to launch browser with documentation)
- add `LazyLoading` advanced setting, defaults to true. When restoring a session lazy loading delays loading a file until its tab is selected. Makes SumatraPDF startup faster.
- move tabs left / right, like in Chrome (`Ctrl + Shift + PageUp` / `Ctrl + Shift + PageDown`)
- add ability to provide arguments to some commands when creating bindings in `Shortcuts`:
  - `CmdCreateAnnot*` commands take a color argument, `openedit` to automatically open edit annotations window when creating an annotation, `copytoclipboard` to copy selection to clipboard and `setcontent` to set contents of annotation to selection
  - `CmdScrollDown`, `CmdScrollUp` : integer argument, how many lines to scroll
  - `CmdGoToNextPage`, `CmdGoToPrevPage` : integer argument, how many pages to advance
  - `CmdNextTabSmart`, `CmdPrevTabSmart` (`Smart Tab Switch`), shortcut: `Ctrl + Tab`, `Ctrl + Shift + Tab`
- added `UIFontSize` advanced setting
- removed `TreeFontWeightOffset` advanced setting
- increase number of thumbnails on home page from 10 => 30
- add `ShowLinks` advanced setting
- default `ReuseInstance` setting to true
- added `Key` arg to `ExternalViewers` advanced setting (keyboard shortcut)
- added `Key` arg to `SelectionHandlers` advanced setting (keyboard shortcut)
- improved scrolling with mouse wheel and touch gestures
- theming improvements
- go back to opening settings file with default .txt editor (notepad most likely)
- don't exit fullscreen on double-click. must double-click in upper-right corner
- when opening via double-click, if `Ctrl` is pressed will always open in new tab (vs. activating existing tab)
- register for handling `.webp` files
- bug fix: Del should not delete an annotation if editing content
- bug fix: re-enable tree view full row select
- change: `CmdCreateAnnotHighlight` etc. no longer copies selection to clipboard by default. To get that behavior back, you can use `copytoclipboard` argument [instead](Commands.md#cmdcreateannothighlight-and-other-cmdcreateannot).
- change: `Ctrl + Tab` is now `CmdNextTabSmart`, was `CmdNextTab`. `Ctrl + Shift + Tab` is now `CmdPrevTabSmart`, was `CmdPrevTab`. To restore pre-3.6 immediate switching (no switcher popup), [rebind the keys](Customize-keyboard-shortcuts.md#restore-pre-36-ctrltab-no-smart-tab-switch-popup) or use `Ctrl + PageDown` / `Ctrl + PageUp` — see [Tabs and windows](Tabs-and-windows.md#restore-pre-36-ctrltab-no-switcher-popup)
- `CmdCommandPalette` takes optional `mode` argument: `@` for tab selection, `#` for selecting from file history and `>` for commands.
- command palette no longer shows combined tabs/file history/commands. `CmdCommandPalette` only shows commands. Because of that removed `CmdCommandPaletteNoFiles` because now `CmdCommandPalette` behaves like it
- removed `CmdCommandPaletteOnlyTabs`, replaced by `CmdCommandPaletteNoFiles @`
- `Ctrl + Shift + K` no longer active, use `Ctrl + K`. You can restore this shortcut by binding it to `CmdCommandPalette >` command.
- add `Name` field for shortcuts. If given, the command will show up in Command Palette (`Ctrl + K`)
- closing a current tab now behaves like in Chrome: selects next tab (to the right). We used to select previously active tab, but that's unpredictable and we prefer to align SumatraPDF behavior with other popular apps.
- swapped key bindings: `i` is now CmdTogglePageInfo, `I` is CmdInvertColors. Several people were confused by accidentally typing `i` to invert colors, is less likely to type it accidentally
- allow creating custom themes in advanced settings in `Themes` section. [See docs](https://www.sumatrapdfreader.org/docs/Customize-theme-colors).
- improve scrolling with middle click drag [#4529](https://github.com/sumatrapdfreader/sumatrapdf/issues/4529)
- make built-in keyboard shortcuts work on non-us keyboards (cyrillic , hebrew etc.)
- open current document in a new tab

**New commands:**

- `CmdCloseAllTabs` : "Close All Tabs"
- `CmdCloseTabsToTheLeft` : "Close Tabs To The Left"
- `CmdDeleteFile` : "Delete File"
- `CmdDuplicateInNewTab` : "Open Current Document In New Tab"
- `CmdHideAnnotations` : "Hide Annotations"
- `CmdInvokeInverseSearch` : "Invoke Inverse Search"
- `CmdMoveTabLeft` : "Move Tab Left" (`Ctrl + Shift + PageDown`)
- `CmdMoveTabRight` : "Move Tab Right" (`Ctrl + Shift + PageUp`)
- `CmdNextTabSmart` : "Smart Tab Switch" (`Ctrl + Tab`)
- `CmdPrevTabSmart` : "Smart Tab Switch" (`Ctrl + Shift + Tab`)
- `CmdShowAnnotations` : "Show Annotations"
- `CmdToggleTableOfContents` : "Toggle Table Of Contents"
- `CmdToggleAntiAlias` : "Toggle Anti-Alias"
- `CmdToggleFrequentlyRead` : "Toggle Frequently Read"
- `CmdToggleInverseSearch` : "Toggle Inverse Search"
- `CmdToggleLinks` : "Toggle Show Links"
- `CmdToggleShowAnnotations` : "Toggle Show Annotations"

## 3.5.2 (2023-10-25)

- fix not showing tab text
- make menus in dark themes look more like standard menus (bigger padding)
- fix Bookmarks for folder showing bad file names
- update translations

## 3.5.1 (2023-10-24)

- fix uninstaller crash
- disable lazy loading of files when restoring a session

## 3.5 (2023-10-23)

- Arm 64-bit builds
- dark mode (menu `Settings / Theme` or `Ctrl + K`, `Select next theme` command in [Command Palette](Command-Palette.md))
  you can use `i` (invert colors) to match the background / text color of rendered
  PDF document. Due to technical limitations, it doesn't work well with images
- `i` (invert colors) is remembered in settings
- select annotation under cursor and open annotation edit window
- rename `CmdShowCursorPosition` => `CmdToggleCursorPosition`
- add `Annotations [ FreeTextColor, FreeTextSize, FreeTextBorderWidth ]` settings
- ability to move annotations. `Ctrl + click` to select annotation and then move via drag & drop
- exit full screen / presentation modes via double click with left mouse button
- ability to drag out a tab to open it in new window
- support opening `.avif` images (including inside .cbz/,cbr files)
- respect image orientation `exif` metadata in .jpeg and .png images
- support Adobe Reader syntax for opening files (see command-line arguments below)
- add Next Tab / Prev Tab commands with `Ctrl + PageUp` / `Ctrl + PageDown` shortcuts
- keep Home tab open; add `NoHomeTab` advanced option to disable that
- add context menu to tabs
- bugfix: handle files we can't open in `next file in folder` / `prev file in folder` commands
- command palette: when search starts with `>`, only show commands, not files (like in Visual Studio Code)
- reopen last closed tab (`Ctrl + Shift + T`, like in web browsers)
- clear history from command palette
- can send commands via [DDE](https://www.sumatrapdfreader.org/docs/DDE-Commands)
- open file in Explorer, Directory Opus, Total Commander, or Double Commander from command palette
- close other tabs / close tabs to the right from command palette
- recognize `PgUp` / `PgDown` and a few more in keyboard shortcuts

**New commands:**

- `CmdClearHistory` : "Clear History"
- `CmdCloseOtherTabs` : "Close Other Tabs"
- `CmdCloseTabsToTheRight` : "Close Tabs To The Right"
- `CmdCommandPaletteOnlyTabs` : "Command Palette: Tabs Only" (`Alt + K`)
- `CmdEditAnnotations` : "Edit Annotations"
- `CmdNextTab` : "Next Tab" (`Ctrl + PageDown`)
- `CmdOpenWithDirectoryOpus` : "Open With Directory Opus"
- `CmdOpenWithDoubleCommander` : "Open With Double Commander"
- `CmdOpenWithExplorer` : "Open With Explorer"
- `CmdOpenWithTotalCommander` : "Open With Total Commander"
- `CmdPrevTab` : "Prev Tab" (`Ctrl + PageUp`)
- `CmdReopenLastClosedFile` : "Reopen Last Closed" (`Ctrl + Shift + T`)
- `CmdToggleCursorPosition` : "Toggle Cursor Position" (renamed from `CmdShowCursorPosition`)

**New command-line arguments:**

- `-dde` : enable DDE server
- `/A "page=<pageno>#nameddest=<dest>search=<string>"` : Adobe Reader-compatible open syntax
- `-print-settings disable-auto-rotation` : don't auto-rotate wide pages to fit paper

## 3.4.6 (2022-06-08)

- fix crashes
- fix hang in Fit Content mode and Bookmark links

## 3.4.5 (2022-06-05)

- fix crashes

## 3.4.4 (2022-06-02)

- restore `HOME` and `END` in find edit field
- fix crashes

## 3.4.3 (2022-05-29)

- re-enable `Backspace` in edit field
- fix installation for all users when using custom installation directory
- re-enable `Copy Image` context menu for comic book files
- fix display of some PDF images
- fix slow loading of some ePub files

## 3.4.2 (2022-05-27)

- make keyboard accelerators work when tree view has focus
- fix `-set-color-range` and `-bg-color` replacing `MainWindowBackground`
- fix crash with incorrectly defined selection handlers

## 3.4.1 (2022-05-25)

- fix downloading of symbols for better crash reports

## 3.4 (2022-05-24)

- [Command Palette](Command-Palette.md) (`Ctrl + K`)
- [customizable keyboard shortcuts](Customize-keyboard-shortcuts.md)
- better support for epub files using mupdf's epub engine. Adds text selection and search in ebook files. Better rendering fidelity. On the downside, might be slower.
- [search / translate selected text](Customize-search-translation-services.md) with web services
  - we have few built-in and you can [add your own](https://www.sumatrapdfreader.org/settings/settings3-4#SelectionHandlers)
- installer supports system-wide install via command line
- added `Annotations.TextIconColor` and `TextIconType` advanced settings
- added `Annotations.UnderlineColor` advanced setting
- added `Annotations.DefaultAuthor` advanced setting
- `i` keyboard shortcuts inverts document colors `Shift + i` does what `i` used to do i.e. show page number
- `u` and `Shift + u` keyboard shortcuts adds underline annotation for currently selected text
- `Delete` / `Backspace` keyboard shortcuts delete an annotation under mouse cursor
- support `.svg` files
- faster scrolling with mouse wheel when cursor over scrollbar
- search for text when opening a document from the command line; also `[Search("<file>", "<search-term>")]` DDE command
- a way to get list of used fonts in properties window
- support opening `.heic` image files (if Windows heic codec is installed)
- add experimental smooth scrolling (enabled with `SmoothScroll` advanced setting)

**New commands:**

- `CmdCommandPalette` : "Command Palette" (`Ctrl + K`)

**New command-line arguments:**

- `-all-users` : system-wide install (installer)
- `-search <term>` : search for text when opening a document

## 3.3.3 (2021-07-20)

- fix a crash in PdfFilter.dll

## 3.3.2 (2021-07-19)

- restore showing Table Of Contents for `.chm` files
- fix crashes

## 3.3.1 (2021-07-14)

- fix rotation in DjVu documents

## 3.3 (2021-07-06)

- added support for adding / removing / editing annotations in PDF files. Read [the tutorial](Editing-annotations.md)
- new toolbar
  - changed toolbar to scale with DPI by using new, vector icons
  - added rotate left / right to the toolbar
  - new toolbar:

  ![Toolbar](https://files.sumatrapdfreader.org/assets/sumatrapdf/docs/img/toolbar-b00c.png)

- added ability to hide scrollbar (more screen space for the document). Use right-click context menu.

Minor improvements and bug-fixes:

- advanced setting to change font size in bookmarks / favorites tree view e.g. `TreeFontSize = 12`
- support newer versions of ghostscript (≥ 9.54) for opening `.ps` files
- support jpeg-xr images in `.xps` files
- restore tooltips (regression in 3.2)
- update mupdf to latest version
- make silent installation always silent
- don't crash when attempting to zoom in on home page
- don't show "manga" view menu item for documents that are not comic books
- allow opening `fb2.zip` files ([#1657](https://github.com/sumatrapdfreader/sumatrapdf/issues/1657))
- restore ability to save embedded files (fixes [#1557](https://github.com/sumatrapdfreader/sumatrapdf/issues/1557))
- `Alt + Space` opens a sys menu

**New command-line arguments:**

- `-print-settings paperkind=${num}` : select paper by Windows paper kind constant ([checkin](https://github.com/sumatrapdfreader/sumatrapdf/pull/1815/commits/2104e6104ea759dc4f839c7e8be5973f5a4f0488))

## 3.2 (2020-03-15)

This release upgrades the core PDF parsing and rendering library mupdf to the latest version. This fixes PDF rendering bugs and improves performance.

Added support for multiple windows with tabs:

- added `File / New Window` (`Ctrl-n`) which opens a new window
- to compare the same file side-by-side, `Ctrl-Shift-n` shortcut opens current file in a new window. The same file is now opened in 2 windows that you can re-arrange as needed
- if you hold `SHIFT` when drag&dropping files from Explorer (and other apps), the file will be opened in a new window

Improved management of favorites:

- context menu (right mouse click) on the document area adds menu items for:
  - showing / hiding favorites view
  - adding current page to favorites (or removing if already is in favorites)
- context menu in bookmarks view adds menu item for adding selected page to favorites

This release no longer supports Windows XP. Latest version that support XP is 3.1.2 that you can download from

[https://www.sumatrapdfreader.org/download-prev.html](https://www.sumatrapdfreader.org/download-prev.html)

**New command-line arguments:**

- `-new-window` : open the document in a new window

## 3.1.2 (2016-08-14)

- fixed issue with icons being purple in latest Windows 10 update
- tell Windows 10 that SumatraPDF can open supported file types

## 3.1.1 (2015-11-02)

- (re)add support for old processors that don’t have SSE2
- support newer versions of unrar.dll
- allow keeping the browser plugin if it’s already installed
- crash fixes

## 3.1 (2015-10-24)

- 64bit builds
- all documents are restored at startup if a window with multiple tabs is closed (or if closing happened through File -> Exit); this can be disabled through the `RestoreSession` advanced setting
- printing happens (again) always as image which leads to more reliable results at the cost of requiring more printer memory; the "Print as Image" advanced printing option has been removed
- scrolling with touchpad (e.g. on Surface Pro) now works
- many crash and other bug fixes

## 3.0 (2014-10-18)

- Tabs! Enabled by default. Use Settings/Options... menu to go back to the old UI
- support table of contents and links in ebook UI
- add support for PalmDoc ebooks
- add support for displaying CB7 and CBT comic books (in addition to CBZ and CBR)
- add support for LZMA and PPMd compression in CBZ comic books
- allow saving Comic Book files as PDF
- swapped keybindings:
  - `F11` : Fullscreen mode (still also `Ctrl + Shift + L`)
  - `F5` : Presentation mode (also `Shift + F11`, still also `Ctrl + L`)
- added a document measurement UI. Press `m` to start. Keep pressing `m` to change measurement units
- new advanced settings: `FullPathInTitle`, `UseSysColors` (no longer exposed through the Options dialog), `UseTabs`
- replaced non-free UnRAR with a free RAR extraction library. If some CBR files fail to open for you, download unrar.dll from https://www.rarlab.com/rar_add.htm and place it alongside SumatraPDF.exe
- deprecated browser plugin. We keep it if it was installed in earlier version

## 2.5.2 (2014-05-13)

- use less memory for comic book files
- PDF rendering fixes

## 2.5.1 (2014-05-07)

- hopefully fix frequent ebook crashes

## 2.5 (2014-05-05)

- 2 page view for ebooks
- new keybindings:
  - `Ctrl + PgDn`, `Ctrl + Right` : go to next page
  - `Ctrl + PgUp`, `Ctrl + Left` : go to previous page
- 10x faster ebook layout
- support JP2 images
- new **[advanced settings](https://www.sumatrapdfreader.org/settings.html)**: `ShowMenuBar`, `ReloadModifiedDocuments`, `CustomScreenDPI`
- left/right clicking no longer changes pages in fullscreen mode (use Presentation mode if you rely on this feature)
- fixed multiple crashes and made multiple minor improvements

## 2.4 (2013-10-01)

- full-screen mode for ebooks (`Ctrl-L`)
- new key bindings:
  - `F9` - show/hide menu (not remembered after quitting)
  - `F8` - show/hide toolbar
- support WebP images (standalone and in comic books)
- support for RAR5 compressed comic books
- fixed multiple crashes

## 2.3.2 (2013-05-25)

- fix changing a language via Settings/Change Language

## 2.3.1 (2013-05-23)

- don't require SSE2 (to support old computers without SSE2 support)

## 2.3 (2013-05-22)

- greater configurability via **[advanced settings](https://www.sumatrapdfreader.org/settings.html)**
- "Go To Page" in ebook ui
- add View/Manga Mode menu item for Comic Book (CBZ/CBR) files
- new key bindings:
  - `Ctrl-Up` : page up
  - `Ctrl-Down` : page down
- add support for OpenXPS documents
- support Deflate64 in Comic Book (CBZ/CBR) files
- fixed missing paragraph indentation in EPUB documents
- printing with "Use original page sizes" no longer centers pages on paper
- reduced size. Installer is ~1MB smaller
- downside: this release no longer supports very old processors without **[SSE2 instructions](https://en.wikipedia.org/wiki/SSE2)**. Using SSE2 makes Sumatra faster. If you have an old computer without SSE2, you need to use 2.2.1.

## 2.2.1 (2013-01-12)

- fixed ebooks sometimes not remembering the viewing position
- fixed Sumatra not exiting when opening files from a network drive
- fixes for most frequent crashes and PDF parsing robustness fixes

## 2.2 (2012-12-24)

- add support for FictionBook ebook format
- add support for PDF documents encrypted with Acrobat X
- “Print as image” compatibility option in print dialog for documents that fail to print properly
- many robustness fixes and small improvements

**New command-line arguments:**

- `-manga-mode [1|true|0|false]` : proper display of manga comic books

## 2.1.1 (2012-05-07)

- fixes for a few crashes

## 2.1 (2012-05-03)

- support for EPUB ebook format
- added File/Rename menu item to rename currently viewed file (contributed by Vasily Fomin)
- support multi-page TIFF files
- support TGA images
- support for some comic book (CBZ) metadata
- support JPEG XR images (available on Windows Vista or later, for Windows XP the **[Windows Imaging Component](https://www.microsoft.com/en-us/download/details.aspx?id=32)** has to be installed)
- the installer is now signed

## 2.0.1 (2012-04-08)

- fix loading `.mobi` files from command line
- fix a crash loading multiple `.mobi` files at once
- fix a crash showing tooltips for table of contents tree entries

## 2.0 (2012-04-02)

- support for **[MOBI](https://blog.kowalczyk.info/articles/mobi-ebook-reader-viewer-for-windows.html)** eBook format
- support opening CHM documents from network drives
- a selection can be copied to a clipboard as an image by using right-click context menu
- using ucrt to reduce program size

## 1.9 (2011-11-23)

- support for **[CHM](https://blog.kowalczyk.info/articles/chm-reader-viewer-for-windows.html)** documents
- support touch gestures, available on Windows 7 or later. Contributed by Robert Prouse
- open linked audio and video files in an external media player
- improved support for PDF transparency groups

## 1.8 (2011-09-18)

- improved support for PDF form text fields
- various minor improvements and bug fixes
- speedup handling some types of djvu files

## 1.7 (2011-07-18)

- favorites
- improved support for right-to-left languages e.g. Arabic
- logical page numbers are displayed and used, if a document provides them (such as i, ii, iii, etc.)
- allow to restrict SumatraPDF's features with more granularity; see **[sumatrapdfrestrict.ini](https://github.com/sumatrapdfreader/sumatrapdf/blob/master/docs/sumatrapdfrestrict.ini)** for documentation
- `-named-dest` also matches strings in table of contents (improvement to existing option)
- improved support for EPS files (requires Ghostscript)
- more robust installer
- many minor improvements and bugfixes

## 1.6 (2011-05-30)

- add support for displaying DjVu documents
- display Frequently Read list when no document is open
- add support for displaying Postscript documents (requires recent Ghostscript version to be already installed)
- add support for displaying a folder containing images: drag the folder to SumatraPDF window
- support clickable links and a Table of Content for XPS documents
- display printing progress and allow to cancel it
- add Print toolbar button
- experimental: previewing of PDF documents in Windows Vista and 7. Creates thumbnails and displays documents in Explorer's Preview pane. Needs to be explicitly selected during install process. We've had reports that it doesn't work on Windows 7 x64.

## 1.5.1 (2011-04-26)

- fixes for rare crashes

## 1.5 (2011-04-23)

- add support for viewing XPS documents
- add support for viewing CBZ and CBR comic books
- add File/Save Shortcut menu item to create shortcuts to a specific place in a document
- add context menu for copying text, link addresses and comments. In browser plugin it also adds saving and printing commands
- add folder browsing (`Ctrl + Shift + Right` opens next PDF document in the current folder, `Ctrl + Shift + Left` opens previous document)

## 1.4 (2011-03-12)

- browser plugin for Firefox/Chrome/Opera (Internet Explorer is not supported). It's not installed by default so you have to check the appropriate checkbox in the installer
- IFilter that enables full-text search of PDF files in Windows Desktop Search (i.e. search from Windows Vista/7's Start Menu). Also not installed by default
- scrolling with right mouse button
- you can choose a custom installation directory in the installer
- menu items for re-opening current document in Foxit and PDF-XChange (if they're installed)
- we no longer compress the installer executable with mpress. It caused some anti-virus programs to falsely report Sumatra as a virus. The downside is that the binaries on disk are now bigger. Note: we still compress the portable .zip version
- removed `-title` cmd-line option
- support for AES-256 encrypted PDF documents
- fixed an integer overflow reported by Jeroen van der Gun and other small fixes and improvements to PDF handling

## 1.3 (2011-02-04)

- improved text selection and copying. We now mimic the way a browser or Adobe Reader works: just select text with mouse and use `Ctrl-C` to copy it to a clipboard
- `Shift + Left Mouse` now scrolls the document, `Ctrl + Left mouse` still creates a rectangular selection (for copying images)
- `c` shortcut toggles continuous mode
- `+` / `*` on the numeric keyboard now do zoom and rotation
- added toolbar icons for Fit Page and Fit Width and updated the look of toolbar icons
- add support for back/forward mouse buttons for back/forward navigation
- 1.2 introduces a new full screen mode and made it the default full screen mode. Old mode was still available but not easily discoverable. We've added View/Presentation menu item for new full screen mode and View/Fullscreen menu item for the old full screen mode, to make it more discoverable
- new, improved installer
- improved zoom performance (zooming to 6400% no longer crashes)
- text find uses less memory
- further printing improvements
- translation updates
- updated to latest mupdf for misc bugfixes and improvements
- use libjpeg-turbo library instead of libjpeg, for faster decoding of some PDFs
- updated openjpeg library to version 1.4 and freetype to version 2.4.4
- fixed 2 integer overflows reported by Stefan Cornelius from Secunia Research

## 1.2 (2010-11-26)

- improved printing: faster and uses less resources
- add `Ctrl-Y` as a shortcut for Custom Zoom
- add `Ctrl-A` as a shortcut for Select All Text
- improved full screen mode
- open embedded PDF documents
- allow saving PDF document attachments to disk
- latest fixes and improvements to PDF rendering from mupdf project

## 1.1 (2010-05-20)

- added book view (“View/Book View” menu item) option. It’s known as “Show Cover Page During Two-Up” in Adobe Reader
- added “File/Properties” menu item, showing basic information about PDF file
- added “File/Send by email” menu
- added export as text. When doing “File/Save As”, change “Save As types” from “ PDF documents” to “Text documents”. Don’t expect miracles, though. Conversion to text is not very good in most cases.
- auto-detect commonly used TeX editors for inverse-search command
- bug fixes to PDF handling (more PDFs are shown correctly)
- misc bug fixes and small improvements in UI
- add `Ctrl +` and `Ctrl –` as shortcuts for zooming (matches Adobe Reader)

## 1.0.1 (2009-11-27)

- many memory leaks fixed (Simon Bünzli)
- potential crash due to stack corruption (pointed out by Christophe Devine)
- making Sumatra default PDF reader no longer asks for admin privileges on Vista/Windows 7
- translation updates

## 1.0 (2009-11-17)

- lots of small bug fixes and improvements

## 0.9.4 (2009-07-19)

- improved PDF compatibility (more types of documents can be rendered)
- added settings dialog (contributed by Simon Bünzli)
- improvements in handling unicode
- changed default view from single page to continuous
- SyncTex improvements (contributed by William Blum)
- add option to not remember opened files
- a new icon for documents association (contributed by George Georgiou)
- lots of bugfixes and UI polish

## 0.9.3 (2008-10-07)

- fix an issue with opening non-ascii files
- updated Japanese and Brazilian translation

## 0.9.2 (2008-10-06)

- ability to disable auto-update check
- improved text rendering - should fix problems with overlapping text
- improved font substitution for fonts not present in PDF file
- can now open PDF files with non-ascii names
- improvements to DDE (contributed by Danilo Roascio)
- SyncTex improvements
- improve persistence of state (contributed by Robert Liu)
- fix crash when pressing `Cancel` when entering a password
- updated translations

## 0.9.1 (2008-08-22)

- improved rendering of some PDFs
- support for links inside PDF file
- enabled SyncTex support which mistakenly disabled in 0.9
- misc fixes and translation updates

**New command-line arguments:**

- `-restrict` : restrict features via `sumatrapdfrestrict.ini` (contributed by Matthew Wilcoxson)
- `-title <title>` : set window title (contributed by Matthew Wilcoxson)

## 0.9 (2008-08-10)

- add `Ctrl-P` as print shortcut
- add `F11` as full-screen shortcut
- password dialog no longer shows the password
- support for AES-encrypted PDF files
- updates to SyncTeX/PdfSync integration (contributed by William Blum)
- add DDE commands for jumping to named destination and opening PDF files (contributed by Alexander Klenin, William Blum)
- removed poppler rendering engine resulting in smaller program and updated to latest mupdf sources
- misc bugfixes and translation updates

**New command-line arguments:**

- `-nameddest <name>` : jump to named destination (contributed by Alexander Klenin)
- `-reuse-instance` : reuse an already running instance (contributed by William Blum)

## 0.8.1 (2008-05-27)

- automatic reloading of changed PDFs (contributed by William Blum)
- tex integration (contributed by William Blum)
- updated icon for case-sensitivity selection in find (contributed by Sonke Tesch)
- language change is now a separate dialog instead of a menu
- remember more settings (like default view)
- automatic checks for new versions
- ESC or single mouse click hides selection
- fix showing boxes in table of contents tree
- translation updates

**New command-line arguments:**

- `-lang <language-code>` : set UI language
- `-print-dialog` : show print dialog (contributed by Peter Astrand)

## 0.8 (2008-01-01)

- added search (contributed by MrChuoi)
- added table of contents (contributed by MrChuoi)
- added many translations
- new program icon
- fixed printing
- fixed some crashes
- rendering speedups
- fixed loading of some PDFs

**New command-line arguments:**

- `-esc-to-exit` : press Esc to exit
- `-bgcolor <color>` : set background color

## 0.7 (2007-07-28)

- added ability to select the text and copy to clipboard - contributed by Tomek Weksej
- made it multi-lingual (13 translations)
- added Save As option
- list of recently opened files is updated immediately
- fixed `.pdf` extension registration on Vista
- added ability to compile as DLL and C# sample application - contributed by Valery Possoz
- mingw compilation fixes and project files for CodeBlocks - contributed by MrChuoi
- fixed a few crashes
- moved the sources to Google Code project hosting

## 0.6 (2007-04-29)

- enable opening password-protected PDFs
- don't allow printing in PDFs that have printing forbidden
- don't automatically reopen files at startup
- fix opening PDFs from network shares
- new, better icon
- reload the document when changing rendering engine
- improve cursor shown when dragging
- fix toolbar appearance on XP and Vista with classic theme
- when MuPDF engine cannot load a file or render a page, we fallback to poppler engine to make rendering more robust
- fixed a few crashes

## 0.5 (2007-03-04)

- fixed rendering problems with some PDF files
- speedups - the application should feel snappy and there should be less waiting for rendering
- added `r` keybinding for reloading currently open PDF file
- added `Ctrl-Shift-+` and `Ctrl-Shift--` keybindings to rotate clockwise and counter-clockwise (just like Acrobat Reader)
- fixed a crash or two

## 0.4 (2007-02-18)

- printing
- ask before registering as a default handler for PDF files
- faster rendering thanks to alternative PDF rendering engine. Previous engine is available as well.
- scrolling with mouse wheel
- fix toolbar issues on win2k
- improve the way fonts directory is found
- improvements to portable mode
- uninstaller completely removes the program
- changed name of preferences files from `prefs.txt` to `sumatrapdfprefs.txt`

## 0.3 (2006-11-25)

- added toolbar for most frequently used operations
- should be more snappy because rendering is done in background and it caches one page ahead
- some things are faster

## 0.2 (2006-08-06)

- added facing, continuous and continuous facing viewing modes
- remember history of opened files
- session saving i.e. on exit remember which files are opened and restore the session when the program is started without any command-line parameters
- ability to open encrypted files
- "Go to page dialog"
- less invasive (less yellow) icon that doesn't jump at you on desktop
- fixed problem where sometimes text wouldn't show (better mapping for fonts; use a default font if can't find the font specified in PDF file)
- handle URI links inside PDF documents
- show "About" screen
- provide a download in a .zip file for those who can't run installation program
- switched to poppler code instead of xpdf

## 0.1 (2006-06-01)

- first version released


---

<!-- Uninstalling-SumatraPDF.md -->

# Uninstalling SumatraPDF

## Are you using an official SumatraPDF build?

Did you download SumatraPDF from the [official SumatraPDF website](https://www.sumatrapdfreader.org/download-free-pdf-viewer)?

If not, we can't help you because we didn't create the software you're using.

## Uninstalling Sumatra

There are two versions of SumatraPDF: an installer and a portable version (zipped executable).

## Uninstalling portable version

If you're using the zipped executable, you only need to delete `SumatraPDF.exe`.

## Uninstalling the installer version

If you installed SumatraPDF by running the official installer, uninstall it like any other application.

On Windows 10 / 11:

- start the Settings app ([instructions](https://www.digitalcitizen.life/introducing-windows-10-ways-open-settings))
- select `Apps`
- find `SumatraPDF` in the list, click it, and press the `Uninstall` button:

![Uninstall](https://files.sumatrapdfreader.org/assets/sumatrapdf/docs/img/uninstall-42bf.png)

## What if the above doesn't help?

What if you still have questions? You can use [Discussions](https://github.com/sumatrapdfreader/sumatrapdf/discussions) to ask for additional help.

However, in order for someone to help you, you need to provide the following information:

- Sumatra PDF version you're using
- your OS (Windows) version
- did you download an installer or a zipped executable?
- where did you download SumatraPDF from (the URL of the webpage you used)?
- is there a SumatraPDF directory in your Program Files directory (usually `C:\Program Files` or `C:\Program Files (x86)` on 64-bit systems)?
- what evidence is there that SumatraPDF is installed? Be precise and specific. Don't just say "there's a link to it"; tell us where that link is, what its name is, etc.

To emphasize: if you don't provide this information, we cannot help you.


---

<!-- Tabs-and-windows.md -->

# Tabs and windows

SumatraPDF opens documents in **tabs** inside one window, or in **separate windows**. Which you get depends on two independent settings, `UseTabs` and `ReuseInstance`, plus optional command-line flags.

**By default files open as tabs in the running SumatraPDF window.**

- **Tabs:** `UseTabs = true` opens new documents as tabs
- **Single instance:** `ReuseInstance = true` sends files from Explorer or the command line to the running process
- **Switch tabs:** `Ctrl + Tab` (Smart Tab Switch), `Ctrl + PageDown` / `Ctrl + PageUp`, `Alt + 1` … `Alt + 9`
- **New window:** `Ctrl + Shift + N`, or `-new-window` / `-new-window-tabs` on the command line
- **Session restore:** `RestoreSession = true` reopens last session's tabs

## Open documents in tabs

Set both in [advanced settings](Advanced-options-settings.md) (**Settings → Advanced Settings...**):

- `UseTabs = true` — new documents open as tabs in an existing window
- `ReuseInstance = true` — files opened from Explorer or the command line go to the running process

Both default to `true`. `UseTabs` needs a restart; `ReuseInstance` takes effect on the next file open.

## Fix: tabs enabled but new window every time

If `UseTabs = true` but `ReuseInstance = false`, each file is opened by a **new process**, so you always get a separate window — tabs only apply _within_ one process.

**Fix:** set `ReuseInstance = true` and restart SumatraPDF.

This is the most frequent tabs question on the [forum](https://github.com/sumatrapdfreader/sumatrapdf/discussions/5621).

## Open a document in a new window

- Shortcut: `Ctrl + Shift + N` opens the current document in a new window
- Command-line: `-new-window` opens each file in a new window even when `UseTabs = true` (**ver 3.2+**)
- Command-line: `-new-window-tabs` opens **one** new window with all files as tabs (**ver 3.7+**)

See the flags table under Reference.

## Switch tabs

See [Keyboard shortcuts](Keyboard-shortcuts.md):

- `Ctrl + Tab` / `Ctrl + Shift + Tab` — next / previous tab (**ver 3.6+**: opens the **Smart Tab Switch** list while you hold Ctrl; release to switch). Same idea as the browser tab switcher
- `Ctrl + PageDown` / `Ctrl + PageUp` — next / previous tab in **tab-strip order**, immediately, without the switcher popup (`CmdNextTab` / `CmdPrevTab`)
- `Alt + 1` … `Alt + 8`, `Alt + 9` (last tab) — jump to tab by number
- [Command Palette](Command-Palette.md): `Ctrl + K`, then type `@` to switch tabs by name

![Smart Tab Switch list, shown while Ctrl is held](https://files.sumatrapdfreader.org/assets/sumatrapdf/docs/img/tab-switcher-66da.png)

## Restore pre-3.6 Ctrl+Tab (no switcher popup)

In **3.5 and earlier**, `Ctrl + Tab` / `Ctrl + Shift + Tab` switched tabs immediately in tab-strip order (no overlay list). In **3.6+** those keys run **Smart Tab Switch** (`CmdNextTabSmart` / `CmdPrevTabSmart`), which shows a tab list while Ctrl is held.

To get the old behavior (useful when flicking quickly between two documents):

- Setting (**ver 3.7+**, simplest): set `CtrlTabSimple = true`. `Ctrl + Tab` / `Ctrl + Shift + Tab` then switch immediately in tab-strip order; set it back to `false` to get the switcher back.
- Shortcut: use `Ctrl + PageDown` / `Ctrl + PageUp` instead.
- Rebind: [rebind the keys](Customize-keyboard-shortcuts.md) in advanced settings so `Ctrl + Tab` runs plain next/prev tab:

```
Shortcuts [
    [
        Cmd = CmdNextTab
        Key = Ctrl + Tab
    ]
    [
        Cmd = CmdPrevTab
        Key = Ctrl + Shift + Tab
    ]
]
```

Note: `TabsMru` only changes the **order** of tabs inside the Smart Tab Switch list (most-recently-used vs strip order). It does **not** hide the switcher; use `CtrlTabSimple` or the rebind above.

## Close a tab

- Shortcut: `Ctrl + W` or `q`

## Show or hide the Home tab

When `UseTabs = true`, an empty window may show a **Home** tab.

- Setting: `NoHomeTab = true` skips it
- Close it when other tabs are open; reopen with `Ctrl + K`, then `Go To Home Page` in [Command Palette](Command-Palette.md)

## Reopen tabs on startup

With `RestoreSession = true`, SumatraPDF reopens tabs (and window positions) from the last session on startup. See [How we store settings](How-we-store-settings.md).

Note: `-for-testing` deliberately skips session restore and does not save settings.

## Tips

- If every file opens a new window despite `UseTabs = true`, set `ReuseInstance = true`.
- Use `Ctrl + PageDown` / `Ctrl + PageUp` to switch tabs without the switcher popup.
- Use `Ctrl + K`, `@` to find a tab by name when many are open.
- Use `-new-window-tabs` to open a batch of files together in their own window.

## Reference

### Settings

| Setting         | Default | What it does                                                                                      |
| --------------- | ------- | ------------------------------------------------------------------------------------------------- |
| `UseTabs`       | `true`  | New documents open as **tabs** in an existing window instead of always spawning a new window      |
| `ReuseInstance` | `true`  | Opening a file from Explorer or the command line **reuses** an already running SumatraPDF process |

| Setting         | Restart required?                       |
| --------------- | --------------------------------------- |
| `ReuseInstance` | No — takes effect on the next file open |
| `UseTabs`       | **Yes** — close and restart SumatraPDF  |

You can also change `ReuseInstance` and `UseTabs` at runtime (**ver 3.7+**) via `Ctrl + K`, `Advanced Settings...` in [Command Palette](Command-Palette.md) (`CmdAdvancedSettings`). Changing `UseTabs` affects **new** windows only; switching between tabbed and non-tabbed layout for an existing window may still need a restart.

### Command-line flags

| Flag               | Effect                                                                                                                                           |
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| `-new-window`      | Open each file in a **new window** even when `UseTabs = true` (**ver 3.2+**). Several files: one window per file                                 |
| `-new-window-tabs` | Open **one** new window and load all files as tabs in that window (**ver 3.7+**)                                                                 |
| `-reuse-instance`  | Send the file to an already running instance (mainly for [DDE](DDE-Commands.md) and scripts). For normal use, prefer the `ReuseInstance` setting |

`-reuse-instance` is **not** needed for everyday double-click opening when `ReuseInstance = true`.

### Multiple instances

If several SumatraPDF processes are already running (for example because `ReuseInstance = false`), behavior of `-reuse-instance` is undefined — the file may go to any instance.

To force a single instance, keep `ReuseInstance = true` and close extra windows.

## See also

- [FAQ](FAQ.md) — quick troubleshooting
- [Command-line arguments](Command-line-arguments.md) — `-new-window`, `-new-window-tabs`, `-reuse-instance`
- [How we store settings](How-we-store-settings.md) — `RestoreSession`, `SessionData`


---

<!-- Scrolling-and-zooming.md -->

# Scrolling, zooming and navigating

Move around a document with the keyboard, mouse or touchpad, change zoom and page layout, and jump back and forth between tabs, files and earlier positions. Page navigation is in the **Go To** menu, zoom in the **Zoom** menu, layout in the **View** menu.

**Scroll with the mouse wheel or arrow keys; zoom with `Ctrl` + wheel or `+` / `-`.**

- **Scroll:** arrow keys, `j` / `k`, mouse wheel, right-mouse drag
- **Turn pages:** `n` / `p`, `Space` / `Shift + Space`, `Home` / `End`
- **Go to page:** `g` or `Ctrl + g`
- **Zoom:** `+` / `-`, `Ctrl` + wheel, pinch
- **Fit:** `Ctrl + 0` (page), `Ctrl + 2` (width), `Ctrl + 3` (content)
- **Layout:** `Ctrl + 6` / `7` / `8` (single, facing, book), `c` (continuous)
- **Back / forward:** `Alt + Left` / `Alt + Right`
- **Free pan:** scroll any part of a page to the center

## Scroll with the keyboard

`Up`, `Down`, `Left`, and `Right` refer to the arrow keys. `Left` / `Right` change pages only when the page fits the window width; otherwise they scroll. In manga (right-to-left) mode they are swapped.

- `k`, `j`, `h`, `l` : scroll up / down / left / right
- `Up`, `Down` : scroll up / down
- `n`, `Right` : go to next page (aligns top of page with top of window)
- `p`, `Left` : go to previous page (aligns top of page with top of window)
- `Shift + Down`, `Shift + Up` : scroll forward / backward by a page
- `Space`, `Shift + Space` : scroll forward / backward by a page
- `Home`, `End` : go to first / last page
- `g`, `Ctrl + g` : go to page (text field in toolbar or dialog if toolbar not shown)

The **Go To** menu has **Next Page**, **Previous Page**, **First Page**, **Last Page** and **Page...**.

## Scroll with a mouse or touchpad

- click the scrollbar to scroll up or down by a page
- `Shift` + click the scrollbar : scroll to that position
- scroll up / down with the mouse wheel or a touchpad scrolling gesture
- press `Alt` while scrolling : scrolls faster (by half page instead of by line)
- mouse over scrollbar : scrolls faster (by half page instead of by line)
- hold the **right mouse button** and drag : pan the page (a click without dragging opens the context menu)

## Scroll a page corner to the center (free pan)

Scrolling normally stops when a page edge meets the window edge, so a detail in the corner of a page can only be viewed in the corner of the screen. **Toggle Free Pan** adds half a window of scroll room on every side, so any part of a page can be dragged or scrolled to the center.

- [Command Palette](Command-Palette.md): `Ctrl + K`, then `Toggle Free Pan` (`CmdToggleFreePan`; no default shortcut).

Fit Page / Fit Width and where a page lands when you navigate to it are unchanged. It is remembered per document.

## Turn pages with the mouse wheel

When a page is zoomed past the window you usually care about one band of it (music staves, text inside wide scan margins) and want the next page to open at that same place. Two advanced settings do that:

- `RememberViewOffsetOnPageTurn = true` : next / previous page keeps the view where it is instead of jumping to the top of the new page. It applies to page turns you ask for (`n` / `p`, click-to-turn, the toolbar arrows). Wheeling off the bottom of a page still opens the next page at its top, since that is reading on, not turning a page.
- `MouseWheelTurnsPage = true` : one wheel notch is a page turn rather than a scroll. `Alt + wheel` still scrolls, so you can always reach the rest of the page; `Shift + wheel` (horizontal) and `Ctrl + wheel` (zoom) are unchanged.

Turn on both and the wheel becomes a page turner while the view stays where you put it. To switch the mode on and off without editing the settings file, bind it to a key or a toolbar button with [`CmdToggleBoolSetting`](Commands.md#cmdtoggleboolsetting):

```
Shortcuts [
    [
        Cmd = CmdToggleBoolSetting MouseWheelTurnsPage
        Key = w
        Name = Wheel Turns Page
        ToolbarText = Wheel Turns Page
    ]
]
```

## Zoom with the keyboard

- `+`, `-` : zoom in / out
- `Ctrl + +`, `Ctrl + -` : zoom in / out
- `Ctrl + y` : dialog to set custom zoom level (between 8.3% and 6400%)
- `Ctrl + 0` : set zoom to fit whole page (or pages in multi-column view)
- `Ctrl + 1` : set 100% zoom
- `Ctrl + 2` : set zoom to fit width of page (or pages in multi-column view)
- `Ctrl + 3` : set zoom to fit content (like fit whole page but we auto-remove borders)
- Fit Height (View / Zoom menu, or `Ctrl + K`, `Zoom: Fit Height` command in [Command Palette](Command-Palette.md)): scale so the page fills the window height (may scroll horizontally)

## Zoom with the mouse

- `Ctrl` + mouse scroll wheel : zoom in / out
- hold the **right mouse button** + mouse scroll wheel : zoom in / out (same as Ctrl + wheel; the context menu does not open if you zoomed)
- `Ctrl` + touchpad scroll gesture : zoom in / out
- pinch-to-zoom gesture on a touchscreen
- with `ClickEdgeToTurnPage = true` (advanced setting): click the left fifth of the page area for the previous page, the right fifth for the next page (sides reverse in manga mode)

## Change page layout

- `c` : toggle continuous view (**View → Show Pages Continuously**)
- `Ctrl + 6` : single page view i.e. single column (**View → Single Page**)
- `Ctrl + 7` : facing view i.e. 2 columns (pages) (**View → Facing**)
- `Ctrl + 8` : 2 columns (pages) but offset by one page (**View → Book View**)

For comic books and manga (right-to-left reading, double-page spreads, `LimitToWindowWidth`), see [Comics and manga](Comics-and-manga.md).

## Go back to where you were

Certain actions add navigation points. Go back and forward through them like a browser's back button:

- `Alt + Left`, `Backspace` : go back in history (**Go To → Back**)
- `Alt + Right`, `Shift + Backspace` : go forward in history (**Go To → Forward**)

After following an internal hyperlink (footnote, TOC entry), use `Alt + Left` to go back. See [Hyperlinks](Hyperlinks.md).

Actions that add navigation points:

- explicitly going to a page (`g`, `Ctrl + g`)
- clicking on links within documents
- going to a page via Bookmarks tree view
- navigating via favorites (`Ctrl + b`)
- starting a search (`Ctrl + f`): the view the search started from, once per search, so `Backspace` returns there after find-as-you-type and Find Next moved through matches

## Switch tabs

- `Ctrl + Tab` / `Ctrl + Shift + Tab` : next / previous tab. **Ver 3.6+:** **Smart Tab Switch** (tab list while Ctrl is held). To get pre-3.6 immediate strip-order switching on those keys, [rebind](Customize-keyboard-shortcuts.md) them to `CmdNextTab` / `CmdPrevTab` — see [Tabs and windows](Tabs-and-windows.md#restore-pre-36-ctrltab-no-switcher-popup)
- `Ctrl + Page Down` : next tab (strip order, no popup)
- `Ctrl + Page Up` : previous tab (strip order, no popup)

## Move tabs

**v.3.6+**

- `Ctrl + Shift + Page Down` : move tab right
- `Ctrl + Shift + Page Up` : move tab left

## Open the next file in the folder

- `Shift + Control + Right` : go to next file in current folder
- `Shift + Control + Left` : go to previous file in current folder

## Tips

- Use `Alt` + wheel to scroll by half a page.
- Use `Ctrl + 3` on scans with wide margins; it fits content and removes borders.
- Press `Alt + Left` or `Backspace` to return to where you were before a search or a link.
- Combine `MouseWheelTurnsPage` and `RememberViewOffsetOnPageTurn` to read zoomed-in pages with the wheel only.
- Use free pan to center a detail that sits in a page corner.

## Zoom levels

Zooming in and out steps through a fixed list of zoom levels. This is the built-in list, and also the value of the `ZoomLevels` [advanced setting](Advanced-options-settings.md) that reproduces it:

```
ZoomLevels = 8.33 12.5 18 25 33.33 50 66.67 75 100 125 150 200 300 400 600 800 1000 1200 1600 2000 2400 3200 4800 6400
```

Setting `ZoomLevels` replaces the built-in list rather than adding to it: to change the steps, copy the line above and edit it. Fit Page, Fit Width and Fit Content are always available regardless of the list.

**Ver 3.7+:** the largest level in the list is also the highest zoom that can be set at all, in the Custom Zoom dialog (`Ctrl + y`) and everywhere else. To zoom further than 6400% (e.g. into a large map where the detail is in the file), add the levels you want on the end:

```
ZoomLevels = 8.33 12.5 18 25 33.33 50 66.67 75 100 125 150 200 300 400 600 800 1000 1200 1600 2000 2400 3200 4800 6400 12800 25600 51200 102400
```

Levels up to 1000000 (10000x) are accepted; anything larger is ignored. How far a document can be zoomed also depends on its size: all its pages are laid out on a single canvas measured in pixels, so a long document stops zooming in earlier than a short one.

## Related commands

You can [assign your own keyboard shortcuts](Customize-keyboard-shortcuts.md) to these commands.

Scrolling and navigation:

- `CmdScrollUp`, `CmdScrollDown`
- `CmdScrollLeft`, `CmdScrollRight`
- `CmdScrollUpHalfPage`, `CmdScrollDownHalfPage`
- `CmdScrollLeftPage`, `CmdScrollRightPage`
- `CmdScrollDownPage`, `CmdScrollUpPage`
- `CmdGoToNextPage`, `CmdGoToPrevPage`
- `CmdGoToFirstPage`, `CmdGoToLastPage`
- `CmdNavigateBack`, `CmdNavigateForward`
- `CmdOpenNextFileInFolder`, `CmdOpenPrevFileInFolder`

Tabs:

- `CmdNextTab`, `CmdPrevTab`, `CmdNextTabSmart`, `CmdPrevTabSmart`

Zoom and view:

- `CmdZoomIn`, `CmdZoomOut`
- `CmdZoomCustom`
- `CmdZoomFitPage`
- `CmdZoomActualSize`
- `CmdZoomFitWidth`
- `CmdZoomFitContent`

## See also

- [Comics and manga](Comics-and-manga.md) — right-to-left reading, double-page spreads
- [Tabs and windows](Tabs-and-windows.md) — tab switching and layout
- [Hyperlinks](Hyperlinks.md) — following and returning from links
- [Customize keyboard shortcuts](Customize-keyboard-shortcuts.md) — rebind any command above


---

<!-- Thumbnails-sidebar.md -->

# Thumbnails sidebar

The **Thumbnails** view of the sidebar shows every page as a thumbnail: click one to go there.

**Available in [pre-release 3.7](https://www.sumatrapdfreader.org/prerelease)**

**Open it with View → Show Thumbnails.** At a glance:

- **Show / hide:** **View → Show Thumbnails**, right-click → **Show Thumbnails**, or `Ctrl + K`, `Toggle Thumbnails`.
- **Switch views:** click the Bookmarks, Thumbnails or Favorites icon in a sidebar panel's header.
- **Go to a page:** click its thumbnail, or `Up` / `Down` while the thumbnails have the focus.
- **Move the focus:** `Tab` switches between the document and the thumbnails.
- **Reorder, remove or add pages:** the [Merge PDF window](Merge-PDF-window.md).

## Show the Thumbnails view

- **View → Show Thumbnails**, or right-click the document → **Show Thumbnails**.
- `Ctrl + K`, then `Toggle Thumbnails` in the [Command Palette](Command-Palette.md). The command is `CmdToggleThumbnails`, bind a shortcut to it as in [Customize keyboard shortcuts](Customize-keyboard-shortcuts.md).
- In a sidebar panel's header, click the Thumbnails icon (hover shows its name). The Bookmarks and Favorites icons switch back.

The Thumbnails view works for documents without bookmarks, too.

## Two sidebar panels

The sidebar has a top and a bottom panel. Each shows Bookmarks, Thumbnails or Favorites; the header icon of the view it shows is highlighted.

- **Show Thumbnails**, **Show Bookmarks** (`F12`) and **Show Favorites** open their view in the top panel if it's hidden, else in the bottom panel if that's hidden, else the top panel switches to it.
- If the view is already showing, the command hides its panel.
- Clicking the icon of a view the other panel shows swaps the two panels' views.
- The top panel, and what it shows, is remembered per document. The bottom panel is the same for all documents: `ShowFavorites` and `SidebarBottomView` in [advanced settings](Advanced-options-settings.md).

## Go to a page

Click a thumbnail. The page with the blue frame is the current one and follows you as you scroll the document.

Click a thumbnail or press `Tab` to give the thumbnails the keyboard focus; a dotted border shows they have it. Then `Up` / `Down` go to the previous / next page. Every other key works as in the document (`Page Down`, `Home`, shortcuts, ...). `Tab` moves the focus back to the document.

## Tips

- Use the Thumbnails view to find a page by how it looks: a figure, a table, a blank page.
- Tip: to reorder, remove or add pages by dragging thumbnails, use right-click → **Document** → **Merge PDF...** ([Merge PDF window](Merge-PDF-window.md)).
- Tip: `Ctrl + K`, then `&` shows a larger thumbnail grid in the [Command Palette](Command-Palette.md).

## See also

- [Merge PDF window](Merge-PDF-window.md) — reorder, remove and add pages
- [Reorder pages in a PDF](Reorder-PDF-pages.md) — with the command-line tool


---

<!-- Finding-text.md -->

# Finding text in documents

Find searches the current document for text. It works in PDF, EPUB, MOBI, and other formats that support text extraction, and opens from the **Find** toolbar button, `Ctrl + F` or **Go To → Find...**.

**Press `Ctrl + F`, type, and matches are found as you type.** A `n / m` counter shows the current match and the total number of matches.

- **Find:** open the find box — `Ctrl + F` or `/`
- **Find next / previous:** step through matches — `F3` / `Shift + F3`
- **Find selection:** use the selected text as the search term — `Ctrl + F3` / `Shift + Ctrl + F3`
- **Floating window:** a movable window with a list of all matches
- **Limit to pages:** search only a page range (floating window)
- **Command line:** open a document and start a search — `-search`

## Start a search

- Click the **Find** button in the toolbar, or use **Go To → Find...**.
- Press `Ctrl + F` or `/`.
- [Command Palette](Command-Palette.md): `Ctrl + K`, then `Find`.

A small find bar appears near the **Find** button. Type your text; matches are found as you type.

![The find bar with 7 matches; the current one is yellow](https://files.sumatrapdfreader.org/assets/sumatrapdf/docs/img/find-bar-8d4a.png)

## Go to the next or previous match

| Action                              | Shortcut            |
| ----------------------------------- | ------------------- |
| Find next                           | `F3`                |
| Find previous                       | `Shift + F3`        |
| Find next (selection as needle)     | `Ctrl + F3`         |
| Find previous (selection as needle) | `Shift + Ctrl + F3` |

Shortcuts depend on where keyboard focus is:

- **Focus in the document:** `F3` / `Shift + F3` jump to the next / previous match.
- **Focus in the find box:** `Enter` finds the next match, `Shift + Enter` the previous. In the **floating window** these (and the arrow keys) step through the results list with the cursor left in the box; with the **compact bar**, `F3` may not work until you click back in the document.

If `Ctrl + F` behaves oddly (for example replacing the search term with selected text), focus may be split between the find box and the page. Click the document pane, then press `F3`.

If `F3` changes volume instead of finding the next match (many laptops map `F1`–`F12` to volume and brightness unless you hold **Fn**), press **Fn + F3**, or rebind `CmdFindNext` in [custom keyboard shortcuts](Customize-keyboard-shortcuts.md).

All shortcuts are also listed in [Keyboard shortcuts](Keyboard-shortcuts.md) and [Commands](Commands.md).

## See all matches in a floating window

There are two find UIs:

- **Compact bar** (default): the small overlay near the toolbar.
- **Floating window:** a separate, movable and resizable window that also shows a **results list**. It floats over the document so it doesn't cover the page.

Switch between them with the diagonal-arrows button on the right of the find UI (hover it for a tooltip):

| Button                                         | Tooltip            | Action                                     |
| ---------------------------------------------- | ------------------ | ------------------------------------------ |
| arrows pointing **out**, on the compact bar    | _Open in a window_ | Pop the find UI out into a floating window |
| arrows pointing **in**, on the floating window | _Dock to toolbar_  | Dock it back to the compact bar            |

The choice is remembered across launches via the `SearchUIFloating` advanced setting (`true` = floating window). The floating window's position and size are remembered via `SearchUIWindowPos`. See [Advanced settings](Advanced-options-settings.md).

The results list shows every match below the search box, across the whole document, even on large files:

- Each row shows a **snippet** of the surrounding text with the match **highlighted**, plus the **page number** on the right.
- Click a result, or use **Up / Down** (and **Page Up / Page Down**) while the cursor stays in the search box, to jump to that match.
- **Find Next / Previous** (the buttons, `F3` / `Shift + F3`, or `Enter` / `Shift + Enter`) step through the list the same way.
- Typing selects and jumps to the first match automatically.

![The floating Find window with the list of matches](https://files.sumatrapdfreader.org/assets/sumatrapdf/docs/img/find-window-bba9.png)

## Search only some pages

In the floating window, below the search field, **Limit to pages 1-N:** restricts the search to a page range (N is the last page of the document). Leave the box empty to search every page.

- List several ranges: `3,4-6,18-` (page 3, pages 4–6, and page 18 through the end).
- Other forms: `10-25`, `10`, `10-`, `-25`.

The `n / m` counter and the results list follow the same range. The compact find bar always searches the whole document.

## Search from the command line

Open a document and start a search immediately:

```
SumatraPDF.exe -search "needle" document.pdf
```

The leading `-` is required. Adobe Reader-style `/A` also works:

```
SumatraPDF.exe /A "page=1;search=needle" document.pdf
```

See [Command-line arguments](Command-line-arguments.md) for the full `/A` parameter list.

For an already open document, use [DDE](DDE-Commands.md):

```
[Search("C:\path\file.pdf", "needle")]
```

To jump to a page and select a term only if it appears on that page:

```
[GotoPageWord("C:\path\file.pdf", 12, "needle")]
```

## Search across many PDFs

Use the `sumatrapdf-tool grep` command-line tool. See [Tool grep](Tool-grep.md) and [Search text in PDF from command line](Tool-x-search-pdf.md).

## Search the web or translate a selection

To send **selected** text to Google, Bing, DeepL, etc., see [Customize search / translation](Customize-search-translation-services.md). That is separate from in-document find.

## How search works

- Search is **case-insensitive** by default (German `ß` matches `ss` since 3.7).
- Matching continues onto following pages and **wraps** around to the start of the document.
- The **current** match is highlighted with `FixedPageUI.SelectionColor` (configurable in advanced settings); all other matches use a secondary orange highlight so the active match stands out.
- The find UI **closes when you switch tabs**; each tab gets its own fresh search.

## Tips

- Select a word and press `Ctrl + F3` to find its next occurrence without typing it.
- Use the floating window to see every match with its page number before jumping.
- Set a page range like `10-` to skip front matter.
- If `F3` does nothing, click the document first so it has focus.

## See also

- [FAQ](FAQ.md) — search shortcut troubleshooting
- [Keyboard shortcuts](Keyboard-shortcuts.md)
- [Command-line arguments](Command-line-arguments.md) — `-search`


---

<!-- Hyperlinks.md -->

# Hyperlinks in documents

SumatraPDF supports two kinds of links in PDF and other documents: **embedded hyperlinks** stored in the file, and **auto-detected links** it finds in plain text. They behave and are controlled differently.

**Click a link to follow it; press `Alt + Left` to come back.**

- **Embedded hyperlinks:** created by the document author; jump within the file, open another file, or open a URL
- **Auto-detected links:** plain-text URLs, email addresses and DOIs become clickable — disable with `DisableAutoLinks`
- **Navigate back / forward:** `Alt + Left` / `Alt + Right`
- **Preview a citation:** hover a `[1]`, footnote or figure reference to see its target in a popup — see [Citation hover preview](Citation-hover-preview.md)
- **Restrict links:** `LinkProtocols` in `sumatrapdfrestrict.ini`

## Follow a link

Click it. Embedded hyperlinks are **part of the PDF file** — created by the author in Word, LaTeX, Acrobat, etc. — and work in every standards-compliant viewer. They can:

- jump to another page or destination in the same file
- open another file
- open a URL in the default browser (`http://`, `https://`, `mailto:`, …)

SumatraPDF also turns **plain text** that _looks_ like a URL, email address, or DOI into a clickable link, even when the PDF contains no hyperlink annotation. For example, exporting `www.example.com` as plain text from a word processor creates a clickable link in SumatraPDF but not necessarily in every other viewer. A printed DOI such as `10.1109/WICSA.2015.29` opens as `https://doi.org/10.1109/WICSA.2015.29`.

This follows a long-standing PDF viewer convention (Adobe Reader does something similar).

## Go back after following a link

Internal links (footnotes, table of contents, cross-references) move you within the document. To return:

- `Alt + Left` or `Backspace` — go back in navigation history
- `Alt + Right` or `Shift + Backspace` — go forward

See [Scrolling and zooming](Scrolling-and-zooming.md).

## Preview a citation without leaving the page

Hover a `[12]` citation, footnote marker or figure reference to see its target in a popup, without jumping to it. Off by default; see [Citation hover preview](Citation-hover-preview.md) for turning it on and scrolling / zooming the popup.

## Disable auto-detected links

Users who treat unexpected links as a security concern often ask about this — see [discussion #5703](https://github.com/sumatrapdfreader/sumatrapdf/discussions/5703).

In [advanced settings](Advanced-options-settings.md) set:

```
DisableAutoLinks = true
```

Save the settings file. Embedded hyperlinks in the PDF file are **not** removed — only automatic detection of URL-like text, email addresses, and plain-text DOIs is disabled.

## Block following links (restricted mode)

In [restricted mode](Configure-for-restricted-use.md), `sumatrapdfrestrict.ini` controls which links open. `LinkProtocols` defaults to `http,https,mailto`.

Disable opening URLs from documents entirely:

```
[Policies]
DiskAccess = 0
```

or narrow allowed protocols:

```
LinkProtocols =
```

An empty `LinkProtocols` value blocks all protocol handlers. This is stricter than `DisableAutoLinks` — it affects embedded links too, not just auto-detection.

See [Configure for restricted use](Configure-for-restricted-use.md) and the [full restrict.ini reference](https://github.com/sumatrapdfreader/sumatrapdf/blob/master/docs/sumatrapdfrestrict.ini).

## Tips

- Use `Alt + Left` to return after jumping to a footnote or cross-reference.
- Use the citation hover preview to read a reference without jumping to it at all.
- Use `DisableAutoLinks = true` to stop plain text becoming clickable while keeping the author's links.
- Use an empty `LinkProtocols` in restricted mode to block all links, embedded ones included.

## Reference

### CHM and EPUB

- **CHM** files use HTML links; some `ms-its:` links open topics inside the help file.
- **EPUB** links are HTML anchors; external URLs open in the browser.

## See also

- [FAQ](FAQ.md)
- [Advanced settings](Advanced-options-settings.md) — `DisableAutoLinks`
- [Configure for restricted use](Configure-for-restricted-use.md) — `LinkProtocols`


---

<!-- Citation-hover-preview.md -->

# Citation hover preview

Hover a citation, footnote marker or figure reference and a popup shows what it points to: the bibliography entry, the footnote or the figure. You read it without leaving the page you're on.

**Available in version 3.7 or later.**

**Most often you hover a `[12]` citation to see the reference behind it.** At a glance:

- **Preview:** hover a link to another place in the document; the popup shows the target
- **Plain-text citations:** `[12]` references that aren't links are previewed too
- **Scroll the popup:** `Shift + wheel` with the cursor on the link, or the wheel with the cursor on the popup
- **Zoom the popup:** `Ctrl + wheel`, on the link or on the popup
- **Turn it on / off:** `Toggle Citation Hover Preview` in the [Command Palette](Command-Palette.md), or `CitationHoverDelay`

![Citation hover preview: hovering citation 2 shows its entry from the References page](https://files.sumatrapdfreader.org/assets/sumatrapdf/docs/img/citation-hover-preview-2d6d.png)

## Turn the preview on or off

The preview is off by default. To turn it on or off:

- [Command Palette](Command-Palette.md): `Ctrl + K`, then `Toggle Citation Hover Preview` (`CmdToggleHoverPreview`). On sets a 300 ms delay.
- [Advanced settings](Advanced-options-settings.md): `CitationHoverDelay` is how long, in milliseconds, you hover before the popup shows. `-1` turns the preview off.

```
CitationHoverDelay = 300
```

## Preview a citation

Hover the link and wait for the popup. It shows the region around the target: a whole bibliography entry, a footnote, an equation or a figure.

- Move the cursor away and the popup closes.
- Click the link to jump to the target as usual; `Alt + Left` comes back.
- Web links inside the popup can be clicked.

## Read more of the target with the mouse wheel

**With the cursor on the link:**

- `Shift + wheel` scrolls the popup. It continues onto the previous or next page.
- `Ctrl + wheel` zooms the popup.
- The plain wheel scrolls the document, as if the popup weren't there.

**With the cursor on the popup** (it stays open while you move onto it):

- The wheel scrolls the popup.
- `Ctrl + wheel` zooms it.

Note: some mouse software (Logitech Options+, Microsoft Mouse and Keyboard Center) sends `Shift + wheel` as horizontal scrolling. That scrolls the popup too.

## Tips

- Use `Shift + wheel` to read a long reference entry without moving the mouse.
- Move onto the popup when you want to read more of it: the plain wheel works there.
- Lower `CitationHoverDelay` (e.g. `150`) if the popup feels slow, raise it if it gets in the way.
- Use `Toggle Citation Hover Preview` to switch it off for a document with many links.

## See also

- [Hyperlinks](Hyperlinks.md) — following links and coming back
- [Scrolling, zooming, navigating](Scrolling-and-zooming.md) — the wheel in the document
- [Advanced settings](Advanced-options-settings.md) — `CitationHoverDelay`


---

<!-- Managing-favorites.md -->

# Managing favorites

Favorites save important places in documents so you can jump back to them later. You manage them from the **Favorites** menu, the favorites sidebar and the [Command Palette](Command-Palette.md).

**Press `Ctrl + B` to save the current place, then press `Ctrl + K` and type `$` to jump back.**

- **Add a favorite:** saves the current page and scroll position — `Ctrl + B`
- **Favorites sidebar:** lists favorites across documents — `Toggle Favorites`
- **Favorites in Command Palette:** searchable list — `Ctrl + K`, then `$`
- **Favorites button:** toolbar button for the same list — `CmdCommandPaletteFavorites`

## Add a favorite

The favorite stores the page **and** how far you had scrolled on it, so jumping back returns you to the same place on the page, not only the top.

- Menu: **Favorites → Add to favorites**
- Shortcut: `Ctrl + B`
- Command Palette: `Ctrl + K`, then `Add Favorite`

## Jump to a favorite from the Command Palette

Press `Ctrl + K`, then type `$`.

Favorites from the current document are listed first. Favorites from other documents follow and include the file name.

![Favorites in the Command Palette](https://files.sumatrapdfreader.org/assets/sumatrapdf/docs/img/command-palette-favorites-4873.png)

## Show or hide the favorites sidebar

The sidebar shows favorites saved across documents. Selecting one navigates to the saved place; if it's in another document, SumatraPDF opens that document.

![The favorites sidebar](https://files.sumatrapdfreader.org/assets/sumatrapdf/docs/img/favorites-sidebar-dc80.png)

- Menu: **Favorites → Show Favorites**
- Command Palette: `Ctrl + K`, then `Toggle Favorites`
- Shortcut: none by default; assign one to `CmdFavoriteToggle`
- Sidebar: the Favorites icon in a panel's header

Favorites share the sidebar with Bookmarks and Thumbnails; see [Two sidebar panels](Thumbnails-sidebar.md#two-sidebar-panels).

## Open favorites with a single key

Bind `CmdCommandPaletteFavorites` to a key in [advanced settings](Advanced-options-settings.md). Open **Settings → Open Advanced Settings File...**, find the `Shortcuts` section and add:

```
Shortcuts [
    [
        Cmd = CmdCommandPaletteFavorites
        Key = b
    ]
]
```

After saving, pressing `b` opens the Command Palette directly in favorites mode.

Note: `CmdCommandPalette` with a `$` mode argument also works, but in settings files a literal `$` must be escaped as `$$` (e.g. `Cmd = CmdCommandPalette $$`). Prefer `CmdCommandPaletteFavorites`.

## Add a favorites button to the toolbar

Add `ToolbarText` (or `ToolbarSvgIcon`) to the same shortcut entry. The button opens the same floating list as `Ctrl + K`, then `$`. See [Customize toolbar](Customize-toolbar.md).

```
Shortcuts [
    [
        Cmd = CmdCommandPaletteFavorites
        Name = Favorites
        ToolbarText = $
    ]
]
```

`Name` is the tooltip. The button is added after the built-in toolbar buttons.

## Tips

- Use `Ctrl + B` before scrolling away; the favorite keeps your scroll position, not just the page.
- Use `Ctrl + K`, `$` to reach favorites in other documents; they open the file for you.
- Bind `CmdCommandPaletteFavorites` instead of `CmdCommandPalette $$` to avoid escaping `$`.

## See also

- [Customize keyboard shortcuts](Customize-keyboard-shortcuts.md) — shortcut syntax details
- [Customize toolbar](Customize-toolbar.md) — toolbar buttons
- [Command Palette](Command-Palette.md) — `$` and other modes


---

<!-- Comics-and-manga.md -->

# Comics and manga

SumatraPDF opens comic-book archives and folders of images as multi-page documents. Use it to read comics page by page, as two-page spreads, or right-to-left for manga.

**Open a `.cbz` / `.cbr` file and press `Ctrl + 7` for two-page spreads.** At a glance:

- **Page layout:** single page `Ctrl + 6`, facing `Ctrl + 7`, book view `Ctrl + 8`, continuous `c`.
- **Manga mode:** right-to-left pages in facing and book views. **View → Manga Mode**
- **Zoom caps:** keep wide spreads inside the window while single pages stay at your zoom (ver 3.7+).
- **Landscape pages as spreads:** a wide page takes the whole two-page row (ver 3.7+).
- **Page info:** image file name and size. `i`
- **Convert to PDF:** turn a comic or image folder into a multi-page PDF.

## Open a comic or image folder

| Kind                | Extensions / how to open                                                                                             |
| ------------------- | -------------------------------------------------------------------------------------------------------------------- |
| Comic book archives | `.cbz`, `.cbr`, `.cbt`, `.cb7` (and `.ora`)                                                                          |
| Archives of images  | `.zip`, `.rar`, `.7z`, `.tar` that contain images                                                                    |
| Image folder        | open a directory of images (each file is a page)                                                                     |
| Single image        | PNG, JPEG, WebP, AVIF, HEIC, GIF (including animation), TIFF, and [other image types](Supported-document-formats.md) |

- Encrypted `.cbz` / `.cbr` files are supported (password prompt when needed).
- An **image folder** treats each image as a page, ordered by file name. The Bookmarks sidebar lists the files. The same `ImageUI` settings apply (`DefaultZoom`, `LimitToWindowWidth` / `Height`, `LandscapeAsSpread`, `WindowBgCol`).
- Archives opened from a **network drive** that are 32 MB or smaller are loaded into memory; larger ones may be copied into a local cache (`cbx-cache` under the [settings data directory](How-we-store-settings.md)) so page turns stay fast. Clear that cache with `Ctrl + K`, `Delete Cached Files` in [Command Palette](Command-Palette.md) (`CmdDeleteCachedFiles`).

## Navigate chapters

The Bookmarks sidebar lists pages in the archive.

- If the archive has a `ComicInfo.xml` with bookmarks, those names are used.
- Otherwise, if images live in **chapter folders**, the folders appear as nested outline entries (click a folder to jump to its first page). A directory shared by every file is omitted, so a comic whose files are all in one folder stays a flat list of file names.

## Choose a page layout

Use the same page layout commands as for PDF (**View** menu):

| Action                               | Shortcut / command               |
| ------------------------------------ | -------------------------------- |
| Single page                          | `Ctrl + 6` (`CmdSinglePageView`) |
| Facing (two pages)                   | `Ctrl + 7` (`CmdFacingView`)     |
| Book view (facing, first page alone) | `Ctrl + 8` (`CmdBookView`)       |
| Continuous scroll                    | `c` (`CmdToggleContinuousView`)  |

Facing or book view is useful for double-page spreads (see [Show landscape pages as spreads](#show-landscape-pages-as-spreads-ver-37)). Continuous mode is natural for long webtoon-style strips. See [Scrolling and zooming](Scrolling-and-zooming.md).

To turn the page by clicking the left or right edge of the window (like many comic readers), set `ClickEdgeToTurnPage = true` in [advanced settings](Advanced-options-settings.md). In manga mode the sides are reversed so a click on the left still advances.

## Read manga right-to-left

**Manga mode** displays pages right-to-left in facing and book views (typical for Japanese manga and right-to-left documents).

- **View → Manga Mode**
- `Ctrl + K`, `Toggle Manga Mode` in [Command Palette](Command-Palette.md) (`CmdToggleMangaMode`)
- Available for PDF, XPS, DjVu, ebooks, comic books, images and other fixed-page documents
- When manga mode is on, **Left** advances and **Right** goes back (and horizontal swipe matches that), so navigation follows right-to-left reading

### Make manga mode the default for new comics

In [advanced settings](Advanced-options-settings.md):

```
ComicBookUI [
    CbxMangaMode = true
]
```

That sets the **default** for comic books you have not opened before. Per-file state is stored as `DisplayR2L` under `FileStates` when [remembering state per document](How-we-store-settings.md).

Command-line `-manga-mode true|false` still works but is deprecated in favor of `ComicBookUI.CbxMangaMode`.

## Fit double-page spreads and single pages

Comics often mix **narrow single pages** with **wide double-page spreads**. If you zoom so singles look good, spreads may be wider than the window; if you fit the spread, singles look too small.

### Limit page size to the window (ver 3.7+)

Advanced settings under `ComicBookUI` (comics) and `ImageUI` (images / image folders):

```
ComicBookUI [
    LimitToWindowWidth = true
    LimitToWindowHeight = false
]
```

| Setting                      | Effect when using an **absolute** zoom (e.g. 150%)                                         |
| ---------------------------- | ------------------------------------------------------------------------------------------ |
| `LimitToWindowWidth = true`  | No page is drawn wider than the window; each page is capped at **Fit Width** for that page |
| `LimitToWindowHeight = true` | No page is drawn taller than the window; each page is capped at **Fit Height**             |

Enable **both** to cap at Fit Page. Caps apply **per page**, so:

1. Set zoom with `+` / `-`, `Ctrl + 1` (100%), or a custom level so **single** pages are the size you want.
2. Turn on `LimitToWindowWidth` (recommended for manga with double spreads).
3. Wide spreads shrink to the window width; smaller pages stay at your chosen zoom.

Virtual zoom modes (**Fit Width**, **Fit Page**, **Shrink to Fit**, etc.) already size relative to the window; the limit settings only affect **percentage** zooms.

### Show landscape pages as spreads (ver 3.7+)

In **facing** and **book view**, a page wider than it is tall is treated as a double-page spread: it takes the full row and is not paired with the next page. Comics that store a centerfold as one image show it that way. Book view still keeps the cover (page 1) alone.

```
ComicBookUI [
    LandscapeAsSpread = true
]

ImageUI [
    LandscapeAsSpread = true
]
```

Default is **true**. Set it to `false` (under `ComicBookUI`, or `ImageUI` for image folders) to keep the old pairing: every page occupies one slot of the two-page row, even if it is landscape (issue #872).

### Pick a zoom mode

| Mode                       | When it helps                                                                                                                                 |
| -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
| **Fit Width** (`Ctrl + 2`) | Every page fills the window width (spreads and singles both edge-to-edge; singles can become very large)                                      |
| **Fit Page** (`Ctrl + 0`)  | Whole page(s) visible                                                                                                                         |
| **Shrink to Fit**          | Never enlarge past 100%; only shrink pages that are larger than the window ([like IrfanView “fit only big images”](Scrolling-and-zooming.md)) |
| **Fit by Orientation**     | Fit width in landscape viewports, fit page in portrait                                                                                        |
| **Fit Height**             | Page height fills the window (handy for landscape pages)                                                                                      |

### Set the default zoom

- Single image files: `ImageUI.DefaultZoom` (default `shrink to fit`).
- Comic archives: `ComicBookUI.DefaultZoom` on first open (empty uses Fit Page, not the global `DefaultZoom`). A remembered zoom for that file still wins.

Set `ComicBookUI.DefaultZoom = fit width` to open new comics at Fit Width while PDFs stay at Fit Page.

## Change the background color

Comics and images use a **black** canvas by default (unlike PDF’s white). Override it:

```
ComicBookUI [
    WindowBgCol = #1a1a1a
]

ImageUI [
    WindowBgCol = #1a1a1a
]
```

- Values accept normal colors or `checkered` for a transparency checkerboard.
- Or `Ctrl + K`, `Change Background Color` in [Command Palette](Command-Palette.md) (`CmdChangeBackgroundColor`).

UI theme colors are separate — see [Customize theme colors](Customize-theme-colors.md).

## Adjust margins and page spacing

```
ComicBookUI [
    WindowMargin = 0 0 0 0
    PageSpacing = 4 4
]
```

- `WindowMargin` — top, right, bottom, left gap between the window and the document (default all zeros for comics)
- `PageSpacing` — horizontal and vertical gap between pages (between columns in facing / book view, between rows in continuous view)

Sizes are in pixels at 100% display scaling and are DPI-scaled.

## Show page info

Press `i` (`CmdTogglePageInfo`) for the page-info tip.

- Comics and image folders: the current image **file name** and size (both pages when two are visible in facing view).
- A single open image: pixel resolution, file size, and DPI when not the default 96.

Document properties (`Ctrl + D`) for comic archives list image files and, where present, EXIF and ComicInfo / ComicBookInfo metadata.

## Convert to PDF

Turn a comic, image folder, or single image into a multi-page PDF (`CmdConvertToPDF`):

- **File → Convert to PDF…**
- Right-click → **Document → Convert to PDF…**

**Convert page to PDF** on the image context menu (`CmdConvertImageToPdf`) saves only the **current page** via the image editor.

Full details, including the command line: [Convert comics to PDF](Convert-comics-to-PDF.md) and [Convert images to PDF](Convert-images-to-PDF.md).

## Copy a page image

Right-click a comic or image page and choose **Copy To Clipboard** (`CmdCopyImage`, `Copy Image` in [Command Palette](Command-Palette.md)) to copy the page image to the clipboard.

## Tips

- Turn on `LimitToWindowWidth` so spreads fit the window while single pages keep your zoom.
- Use book view (`Ctrl + 8`) to keep the cover alone and pair the following pages.
- Set `ClickEdgeToTurnPage = true` to turn pages by clicking the window edges.
- Use continuous view (`c`) for webtoon-style strips.
- Set `ComicBookUI.DefaultZoom = fit width` to open comics differently from PDFs.

## What is not available for comics / images

These PDF-oriented features do not apply to comic archives, image folders, or plain images:

- In-document text search and text selection (there is no extractable text)
- **Read Aloud** (menu, context menu, toolbar) — no text to speak
- Keyboard link following (`Shift + F`)
- [AI Chat with document](AI-Chat-with-document.md) (PDF only)

## Settings reference

### `ComicBookUI`

```
ComicBookUI [
    WindowMargin = 0 0 0 0
    PageSpacing = 4 4
    CbxMangaMode = false
    WindowBgCol =
    LimitToWindowWidth = false
    LimitToWindowHeight = false
    DefaultDisplayMode =
    DefaultZoom =
    LandscapeAsSpread = true
]
```

### `ImageUI`

```
ImageUI [
    WindowBgCol =
    DefaultZoom = shrink to fit
    LimitToWindowWidth = false
    LimitToWindowHeight = false
    LandscapeAsSpread = true
]
```

Full field comments: [Advanced settings](Advanced-options-settings.md).

### Related commands

| Command                                                     | Purpose                                                            |
| ----------------------------------------------------------- | ------------------------------------------------------------------ |
| `CmdToggleMangaMode`                                        | Toggle right-to-left facing/book layout                            |
| `CmdConvertToPDF`                                           | Convert comic / image folder / image to a multi-page PDF           |
| `CmdConvertImageToPdf`                                      | Convert the current page via the image editor                      |
| `CmdCopyImage`                                              | Copy current page image                                            |
| `CmdTogglePageInfo`                                         | Show / hide page info tip (`i`)                                    |
| `CmdDeleteCachedFiles`                                      | Clear local `cbx-cache` copies from network opens                  |
| `CmdChangeBackgroundColor`                                  | Pick canvas background                                             |
| `CmdZoomFitWidth` / `CmdZoomFitPage` / `CmdZoomShrinkToFit` | Zoom modes (see [Scrolling and zooming](Scrolling-and-zooming.md)) |

## See also

- [Convert comics to PDF](Convert-comics-to-PDF.md) — full conversion details
- [Supported document formats](Supported-document-formats.md) — every image and archive type
- [Scrolling and zooming](Scrolling-and-zooming.md) — zoom modes and layouts
- [Advanced settings](Advanced-options-settings.md) — all `ComicBookUI` / `ImageUI` fields
- [Commands](Commands.md) — command ids for rebinding
- [How we store settings](How-we-store-settings.md) — per-file state and data directory


---

<!-- CAD-Engineering-Drawings.md -->

# CAD / Engineering Drawings

SumatraPDF can thicken hairline strokes and darken mid-gray lines in CAD and engineering-drawing PDFs, so the drawing stays readable when you zoom out, closer to Acrobat.

**Available in version 3.7 or later.** PDF only.

**Set `EngineeringDrawingEnhance = auto` to enhance only PDFs that look like CAD drawings.** At a glance:

- **Zoom-aware minimum stroke width:** hairlines get thicker when zoomed out; no effect when zoomed in.
- **Darker grays:** typical CAD-export grays are darkened.
- **Global setting:** `EngineeringDrawingEnhance` = `off` / `auto` / `on`.
- **Per-file toggle:** `Toggle Engineering Drawing Enhancement` in [Command Palette](Command-Palette.md), current PDF only.

Text geometry is not changed. Off by default. The Explorer preview pane and the Windows Search filter never apply it.

## Enhance drawings in every PDF

Set `EngineeringDrawingEnhance` in [advanced settings](Advanced-options-settings.md):

```
EngineeringDrawingEnhance = off
```

| Value  | Effect                                             |
| ------ | -------------------------------------------------- |
| `off`  | Never enhance (default)                            |
| `auto` | Enhance only when the PDF looks like a CAD drawing |
| `on`   | Enhance every PDF                                  |

Change it in any of these ways:

- **Advanced Settings** dialog: **Settings → Advanced Settings...**, filter `EngineeringDrawingEnhance`, pick `off` / `auto` / `on`, Save. Or `Ctrl + K`, `Advanced Settings...` in [Command Palette](Command-Palette.md).
- **[Command Palette](Command-Palette.md) settings:** `Ctrl + K`, type `=EngineeringDrawingEnhance`, Enter, pick a value. Takes effect immediately, no restart.
- **Settings file:** **Settings → Open Advanced Settings File...**, edit `EngineeringDrawingEnhance = …`, save.

The setting is global: it applies to every PDF. If a file is already open, reopen it (or use the [per-file toggle](#toggle-enhancement-for-one-file)) so rendering picks up the new value.

## Toggle enhancement for one file

**Toggle Engineering Drawing Enhancement** (`CmdToggleEngineeringDrawingEnhance`) flips enhancement for the **current PDF only**.

- `Ctrl + K`, `Toggle Engineering Drawing Enhancement` in [Command Palette](Command-Palette.md)
- No default keyboard shortcut; bind one in [Customize keyboard shortcuts](Customize-keyboard-shortcuts.md)

The first use flips away from whatever is in effect (so with the default `off`, it turns enhancement on). After that it alternates on/off for that document.

This override is **session-only**. It is not saved in `FileStates`. Closing the file (or the tab) restores the global setting. It does not change `EngineeringDrawingEnhance` for other files.

## Tips

- Use `auto` to leave ordinary PDFs untouched.
- Use the per-file toggle to compare a drawing with and without enhancement.
- Use `=EngineeringDrawingEnhance` in the Command Palette to switch values without a restart.
- Bind a shortcut to `CmdToggleEngineeringDrawingEnhance` if you toggle often.

## How `auto` detects drawings

`auto` looks for a PDF/E marker, a CAD authoring tool in the document metadata, or content heuristics on the first pages (hairline vectors, raster screenshots of drawings, WPS-style hairline exports).

## Global vs per file

|       | Global `EngineeringDrawingEnhance` | Per-file toggle                        |
| ----- | ---------------------------------- | -------------------------------------- |
| Scope | All PDFs                           | Current document                       |
| Saved | Yes, in settings                   | No                                     |
| Wins  | Used unless the file has a toggle  | Beats the global setting for that file |

## See also

- [Advanced settings](Advanced-options-settings.md) — `EngineeringDrawingEnhance`
- [Commands](Commands.md) (`CmdToggleEngineeringDrawingEnhance`) — for rebinding
- [Command Palette](Command-Palette.md) — run the toggle and change settings


---

<!-- Accessibility.md -->

# Accessibility

SumatraPDF works with screen readers through Windows UI Automation, reads text aloud with built-in text-to-speech, and can be used from the keyboard alone.

**Most often you use a screen reader such as Narrator or NVDA to read document text.** At a glance:

- **Screen readers:** a [UI Automation](https://learn.microsoft.com/en-us/windows/win32/winauto/uiauto-uiautomationoverview) tree for Narrator, NVDA, JAWS and other UIA clients.
- **Read Aloud (TTS):** Windows text-to-speech with word highlight, playback bar, and pause / continue / stop — see [Read Aloud (TTS)](Read-Aloud.md).
- **Keyboard-only use:** [Keyboard shortcuts](Keyboard-shortcuts.md) and the [Command Palette](Command-Palette.md).

## Read a document with a screen reader

SumatraPDF exposes a UI Automation tree so screen readers (Microsoft Narrator, NVDA, and other UIA clients) can access document text.

### Microsoft Narrator

1. Start **Narrator** (Windows built-in, `Win+Ctrl+Enter`).
2. Open a document in SumatraPDF.
3. Move focus to the document canvas and navigate / select text — Narrator should be able to read document content.

**Ver 3.7+:** added reading through the document character by character, word by word, line by line and page by page. Before 3.7 the text range never advanced, so a screen reader would repeat the first line (or read nothing) even though the text was there. Reading the text under the mouse pointer or finger (Narrator's mouse mode, touch exploration) works too, and screen readers can now locate the text they read on screen — so Narrator can highlight it.

**Known issue:** Narrator sometimes stops reading until you switch focus to another window and back.

### Other screen readers (NVDA, JAWS, …)

Any client that uses Windows UI Automation should work, including NVDA and JAWS.

### Supported documents

UI Automation supports PDF, XPS, DjVu (documents that contain text we can extract).

Note: some PDF / DjVu documents are scanned pages, not text, so text reading will not work.

## Listen with Read Aloud

**Read Aloud (TTS)** reads text with Windows text-to-speech, with word highlight, playback bar, and pause / continue / stop. It is a separate, app-driven text-to-speech path, not a screen reader. Documented in [Read Aloud (TTS)](Read-Aloud.md).

## Use SumatraPDF without a mouse

Many actions are available without a mouse — see [Keyboard shortcuts](Keyboard-shortcuts.md), [Command Palette](Command-Palette.md), and [Finding text](Finding-text.md) (important for users who cannot use function keys without `Fn`).

## Tips

- If Narrator stops reading, switch focus to another window and back.
- Use [Read Aloud](Read-Aloud.md) to listen to a document without running a screen reader.
- Use `Ctrl + K` ([Command Palette](Command-Palette.md)) to run any command by name from the keyboard.

## Embedded (plugin) mode

UI Automation is **not** exposed when SumatraPDF runs in plugin mode, i.e. when it's started with the `-plugin <parent HWND>` command-line option and embedded as a frameless child window inside another application. The standalone SumatraPDF window is not affected.

## See also

- [Read Aloud (TTS)](Read-Aloud.md) — built-in text-to-speech
- [FAQ](FAQ.md)
- [Commands](Commands.md) — command ids for keyboard shortcuts


---

<!-- Editing-annotations.md -->

# Editing annotations

Add, change and save annotations (highlights, notes, stamps, images, ink) in PDF files, from the context menu, keyboard or the **Edit PDF** toolbar.

**Available in version 3.3 or later.**

**Most often you select text and press `a` to highlight it.** At a glance:

- **Highlight:** `a` highlights selected text; `u` underlines it. `Shift + A` / `Shift + U` also turn on Edit PDF mode.
- **Edit PDF mode:** toolbar toggle to add, select, and change annotations.
- **Highlighter:** free-hand marker stroke over anything on the page.
- **Copy / cut / paste:** `Ctrl + C`, `Ctrl + X`, `Ctrl + V`.
- **Undo / redo:** `Ctrl + Z`, `Ctrl + Shift + Z`.
- **Save:** `Ctrl + Shift + S` saves into the PDF.

## Highlight text

Select text and press `a`. This creates a yellow highlight annotation:

![A highlighted title and the unsaved changes dot on the tab](https://files.sumatrapdfreader.org/assets/sumatrapdf/docs/img/annot-unsaved-changes-3e3d.png)

Here the title was selected and highlighted with `a`. The red dot after the file name in the tab shows that the document has unsaved changes.

Other annotations you can create from a selection (right-click → **Annotations → Create From Selection**):

- highlight
- underline
- strike out
- squiggly underline
- redact

![Context Menu Annotation From Selection](https://files.sumatrapdfreader.org/assets/sumatrapdf/docs/img/context-menu-annot-from-sel-b208.png)

The selected text is also copied to the clipboard, so you can, for example, `Ctrl + V` it into the annotation's `Contents` property.

## Turn on Edit PDF mode

- **Toolbar:** **Edit PDF** button in the main toolbar.
- **Keyboard:** `Shift + A` / `Shift + U` create a highlight / underline (like `a` / `u`) and turn on Edit PDF mode.
- **Command Palette:** `Ctrl + K`, then `Toggle Edit PDF` (`CmdToggleEditPDF`).

The annotation tools show in a second toolbar row:

![The Edit PDF toolbar](https://files.sumatrapdfreader.org/assets/sumatrapdf/docs/img/edit-pdf-toolbar-6565.png)

## Find an annotation

**Find Annotation**, near the end of the Edit PDF toolbar (before the Save button), opens a floating **Annotations** window: a search box (`filter N annotations`) over the list of the document's annotations. Press it again, or close the window, to hide it. Also `Ctrl + K`, then `Find Annotation` (`CmdFindAnnotation`).

![The Annotations window](https://files.sumatrapdfreader.org/assets/sumatrapdf/docs/img/find-annotation-window-7197.png)

## Add an annotation at the mouse

Right-click → **Annotations → Create Under Cursor** creates an annotation at the mouse location:

- text
- free text
- highlighter
- stamp
- image from the clipboard
- image from a file (`Image From File...`)
- caret
- line, square, circle

![Context Menu Annotation Under Cursor](https://files.sumatrapdfreader.org/assets/sumatrapdf/docs/img/context-menu-annot-under-cursor-e639.png)

## Add a signature image

To put a picture of your signature (or any other image) on a PDF page:

- right-click the page → **Document → Insert Image...**, or
- right-click the page → **Annotations → Create Under Cursor → Image From File...**

Pick a PNG (or JPEG, etc.). The image is stamped on the page and you can drag or resize it. Save with `Ctrl + Shift + S` or the Save button of the Edit PDF toolbar (see [Save annotations to the PDF](#save-annotations-to-the-pdf)). See also [Add an image to a PDF](Add-an-image-to-a-PDF.md).

**Ver 3.7+:** to skip picking the file every time, set your signature image in [advanced settings](Advanced-options-settings.md):

```
Annotations [
	SignatureImage = C:\Users\me\signature.png
]
```

Then right-click → **Annotations → Create Under Cursor → Sign With Image** (or **Document → Sign With Image**, or `Sign With Image` in the [Command Palette](Command-Palette.md), `CmdSignWithImage`) stamps it at once. A transparent PNG looks best.

## Insert predefined text

**Ver 3.7+:** text you type often (an approval line, your name and date, a standard remark) can be a text snippet. Add them in [advanced settings](Advanced-options-settings.md):

```
TextSnippets [
	[
		Name = Approved
		Text = Approved\nJ. Doe
		Key = Ctrl+Shift+1
	]
]
```

- `Name`: shown in the menu and the [Command Palette](Command-Palette.md)
- `Text`: the text; `\n` starts a new line
- `Key`: optional keyboard shortcut

Right-click the page → **Annotations → Create Under Cursor** lists the snippets after **Free Text** (several go in an **Insert Text** submenu). The snippet becomes a free text annotation at the mouse, which you can move and edit like any other.

Note: this is an electronic signature image, not a cryptographic digital signature (right-click → **Document → Sign Document...**, see [Sign a PDF](Sign-a-PDF.md); it uses a certificate from the Windows store or a `.pfx` / `.p12` file). **Sign Document** can also draw a PNG or JPEG inside the digital signature itself, and you can turn off the "Digitally signed by" labels and the other lines.

## Paint with the Highlighter

The **Highlighter** is a marker pen: drag on the page and it paints a wide translucent stroke wherever the mouse goes, over pictures and blank areas as well as text. The selection-based **Highlight** (`a`) still needs text to attach to.

Start it with:

- **Toolbar:** **Annotations** toolbar.
- **Context menu:** right-click → **Annotations → Create Under Cursor → Highlighter**.
- **Command Palette:** `Ctrl + K`, then `Highlighter` (`CmdAnnotationHighlightBrush`).

Drag to paint, release the mouse or pen to finish, `Esc` to cancel. Closing the hint at the bottom of the window also finishes polyline. The stroke keeps a constant on-screen width while you draw, whatever the zoom.

**Ink** is the same on a tablet: release commits that stroke and the tool stays selected so you can draw another. `Esc` or closing the hint leaves the tool.

The stroke is saved as an ink annotation in the `HighlightColor` from Advanced Settings (yellow by default) at 40% opacity, so you can move, recolor, or delete it like any other annotation.

## Change an annotation

Click an annotation in Edit PDF mode to select it. A compact property row appears under it (color, opacity, border, font, icon, line endings, Contents). A file attachment's row starts with **Attach File**, and **Save Attachment** once a file is embedded. Icon, line-ending, and text-alignment menus show the glyph next to the name. The filter list and floating list also select an annotation when you click a row.

![A selected free text annotation with its property row](https://files.sumatrapdfreader.org/assets/sumatrapdf/docs/img/annot-property-row-6f18.png)

Outside Edit PDF mode, click a file attachment whose file Sumatra can open (a PDF, for example) to open it in a new tab. Use **Save Attachment** on the page context menu to write it to disk.

## Move an annotation

In Edit PDF mode, left-click an annotation and drag it. This works for a selected shape annotation too (including polygon, polyline, and ink).

To place it precisely, select it and press the arrow keys: each press moves it by a pixel, `Shift + arrow` by 10 pixels (ver 3.7+).

## Delete an annotation

Select it and press `Delete` (or press `Delete` with the mouse over it), or use **Delete Annotation** in the floating list.

## Copy, cut and paste annotations

- `Ctrl + C` copies the selected annotation.
- `Ctrl + V` pastes a copy with its top-left corner at the mouse. You can paste on another page, or into another PDF.
- `Ctrl + X` cuts: it copies the annotation under the cursor (or the selected one, like `Delete` does) and the original is deleted when you paste, so nothing is lost if the paste doesn't happen. Only the first paste moves the annotation; pasting again makes copies.
- Copy and Paste are also on the page context menu and in the command palette.

Note: only annotations that can be moved can be copied. Text markup (highlight, underline, squiggly, strike-out) is anchored to the text it covers, so it can't be copied and pasted elsewhere. Neither can file attachments, whose embedded file isn't copied.

## Undo and redo

`Ctrl + Z` takes back the last change to the PDF, `Ctrl + Shift + Z` re-applies it. The Undo and Redo buttons on the Edit PDF toolbar do the same and are greyed out when there is nothing to step to.

One gesture is one step: creating an annotation also sets its color, size and contents, and a resize drag rewrites it as the mouse moves, but a single `Ctrl + Z` takes all of it back. The history covers everything that changes the document, not just annotations, and goes back to the state the file was opened (or last saved) in — undoing every change makes the document count as unmodified again.

## Save annotations to the PDF

With unsaved changes, the document's tab shows a red dot after the file name.

| Action                   | Shortcut / command                                                                                                                                                         |
| ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Save annotations to file | `Ctrl + Shift + S` (`CmdSaveAnnotations`), the Save button at the end of the Edit PDF toolbar, or right-click → **Annotations → Save changes**                             |
| Save to a new PDF        | `CmdSaveAnnotationsNewFile` (the Save button's drop-down, tab context menu, right-click → **Annotations → Save to new file**, or command palette)                          |
| Discard unsaved changes  | `CmdDiscardChanges` (tab context menu **Discard changes**, or `Ctrl + K`, `Discard Changes` command in [Command Palette](Command-Palette.md)) — reloads the file from disk |
| Save when closing        | Prompt dialog — choose existing file, new file, or discard                                                                                                                 |

Hover over the Save button on the Edit PDF toolbar for a drop-down with **Save changes to** followed by the file name, **Save changes to a new PDF** and **Discard changes**. They are greyed out while there is nothing to save.

When you close the document (or exit the app) with unsaved annotations, SumatraPDF asks if you want to save them:

![Unsaved changes dialog](https://files.sumatrapdfreader.org/assets/sumatrapdf/docs/img/unsaved-annotations-dialog-6c31.png)

- `Save to existing PDF` overwrites the PDF with the newly added annotations.
- `Save to new PDF` saves as a new file.
- `Discard changes` loses the annotations.
- `Cancel`, or closing the dialog, keeps the document open.

## Tips

- Save with `Ctrl + Shift + S` before closing to skip the save prompt.
- Use **Discard Changes** (`CmdDiscardChanges`) to drop unsaved work without closing the tab.
- Use `Shift + A` to highlight and enter Edit PDF mode in one step.
- Use `Ctrl + X` then `Ctrl + V` to move an annotation to another page or PDF.
- Set `HighlightColor` to `#80ffff00` for half-transparent highlights.

## Set default colors, size, and opacity

Open **Settings → Advanced Settings...** and edit the `Annotations.*` settings (or the `Annotations` block in the settings file, via **Open Advanced Settings File...**):

| Setting                                     | Used for                                       |
| ------------------------------------------- | ---------------------------------------------- |
| `HighlightColor`                            | New highlights (`a`) — default `#ffff00`       |
| `UnderlineColor`                            | Underline annotations                          |
| `SquigglyColor`                             | Squiggly underline                             |
| `StrikeOutColor`                            | Strike-out                                     |
| `FreeTextColor` / `FreeTextBackgroundColor` | Free text annotations                          |
| `FreeTextSize`                              | Default font size for free text (default `12`) |
| `FreeTextBorderWidth`                       | Border width for free text                     |
| `FreeTextOpacity`                           | `0`–`100` percent opacity for free text        |
| `TextIconColor` / `TextIconType`            | Sticky-note style icons                        |
| `DefaultAuthor`                             | Author name written into new annotations       |

Highlight, underline, squiggly and strike-out colors accept `#aarrggbb` so you can set a default opacity: `#80ffff00` is a half-transparent yellow highlight. `#rrggbb` (6 digits) is fully opaque. You can still change one annotation's opacity from the compact property row.

Free-text opacity is the separate `FreeTextOpacity` percent (0–100).

See [Advanced settings](Advanced-options-settings.md) for the full list.

### Keyboard shortcuts with custom colors

**Ver 3.6+:** `CmdCreateAnnotHighlight` accepts a color argument. You can bind e.g. green highlights to a key — see [Customize keyboard shortcuts](Customize-keyboard-shortcuts.md).

### Toolbar buttons

Add annotation commands to the toolbar via the `Shortcuts` array — see [Customize toolbar](Customize-toolbar.md). Example commands: `CmdCreateAnnotHighlight`, `CmdCreateAnnotUnderline`, `CmdSaveAnnotations`.

## Annotations from other programs

SumatraPDF can display most standard PDF annotations created in Acrobat, Foxit, etc. Some proprietary annotation types may show only an icon. Free-text presets and appearance vary between editors.

## See also

- [Customize keyboard shortcuts](Customize-keyboard-shortcuts.md) — bind annotation commands, e.g. colored highlights
- [Customize toolbar](Customize-toolbar.md) — add annotation buttons
- [Advanced settings](Advanced-options-settings.md) — `Annotations` defaults
- [Keyboard shortcuts](Keyboard-shortcuts.md) — all annotation keys


---

<!-- Fill-PDF-forms.md -->

# Fill a PDF form

Type into text fields, tick checkboxes and radio buttons, and pick values from lists in a fillable PDF form, then save the filled form as a PDF.

**Available in [pre-release 3.7](https://www.sumatrapdfreader.org/prerelease)**

**Click a field and type.** At a glance:

- **Text field:** click it, type, press `Tab` for the next field.
- **Checkbox / radio button:** click it.
- **Combo box / list box:** click it, then click a value in the list.
- **Find empty fields:** **View → Highlight Form Fields** (on by default).
- **Save:** `Ctrl + Shift + S` saves into the PDF; `Ctrl + S` saves to a new PDF.
- **Undo:** `Ctrl + Z`.

You don't need [Edit PDF mode](Editing-annotations.md#turn-on-edit-pdf-mode) to fill a form: fields work with it on or off. In Edit PDF mode with an annotation selected, the first click only deselects the annotation.

## Fill in fields

Hover over a field: the cursor shows whether you can type into it or click it. Read-only fields can't be changed.

**Text fields:**

1. Click the field. An edit box opens over it with the current text selected.
2. Type.
3. Finish with any of:
   - `Enter` (in a multi-line field `Enter` starts a new line)
   - `Tab` / `Shift + Tab` — keep the text and go to the next / previous text or list field on the same page (checkboxes and radio buttons are skipped)
   - click somewhere else
4. `Esc` closes the box without keeping what you typed.

Password fields hide what you type. Fields with a maximum length stop accepting text at that length.

**Checkboxes:** click to check, click again to uncheck.

**Radio buttons:** click one to select it; the others in the group are cleared. Clicking the selected one clears it, unless the form doesn't allow that.

**Combo boxes and list boxes:** click the field. A list of values drops down (below the field, or above it near the bottom of the window). Click a value, or use the arrow keys and `Enter`. `Esc` or clicking away closes the list without changing the value.

If the form has calculations (for example a total that adds up other fields), they run when you change a field. To turn off JavaScript in PDFs, set `DisableJavaScript = true` in [Advanced settings](Advanced-options-settings.md); calculations then don't run.

Hovering over a field shows its tooltip, if the form's author gave it one.

## Highlight empty fields

Empty fields are tinted pale blue, so you can see what's left to fill in. Filled-in fields, read-only fields and signed signature fields are not tinted. The tint is only on screen; it's not part of the file.

Turn it on or off:

- **View → Highlight Form Fields**
- `Ctrl + K`, then `Toggle Highlight Form Fields` (`CmdToggleHighlightFormFields`) in [Command Palette](Command-Palette.md)
- `HighlightFormFields` in [Advanced settings](Advanced-options-settings.md) (default `true`)

## Sign a signature field

Click an empty signature field to open **Sign Document** with that field selected. See [Sign a PDF](Sign-a-PDF.md).

## Save the filled form

After you change a field, the document's tab shows a red dot: it has unsaved changes. Save them into the PDF:

| To                     | Do                                                                                                                                                                                     |
| ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Overwrite the PDF      | `Ctrl + Shift + S`, `Ctrl + K` then `Save Annotations to existing PDF` (`CmdSaveAnnotations`), tab context menu **Save changes to existing PDF**, or right-click the page → **Annotations → Save changes** |
| Save to a new PDF      | `Ctrl + S`, `Ctrl + K` then `Save Annotations to a new PDF` (`CmdSaveAnnotationsNewFile`), tab context menu **Save changes to new PDF**, or right-click the page → **Annotations → Save to new file** |
| Throw the changes away | `Ctrl + K` then `Discard Changes` (`CmdDiscardChanges`), tab context menu **Discard changes**, or right-click the page → **Annotations → Discard changes** — reloads the file from disk |

In Edit PDF mode the **Save** button at the end of the Edit PDF toolbar does the same; hover over it for the other two choices.

Saving to a new PDF suggests `<name> Copy.pdf` next to the original. After saving, SumatraPDF reloads the saved file.

If you close the document (or SumatraPDF) with unsaved changes, the **Unsaved changes** dialog asks what to do:

- **Save to existing PDF** overwrites the PDF.
- **Save to new PDF** asks for a file name.
- **Discard changes** loses what you filled in.
- **Cancel** keeps the document open.

## Make the filled form final

A saved form can still be edited in SumatraPDF and other PDF programs. To turn the filled-in values into ordinary page content, bake the PDF: see [Flatten PDF forms and annotations](Flatten-PDF-forms-and-annotations.md).

## Tips

- Use `Tab` to go through the text fields of a page without the mouse.
- Use **Save to new PDF** to keep the blank form for next time.
- Use `Ctrl + Z` to take back a change; `Ctrl + Shift + Z` redoes it. Inside an open text box, `Ctrl + Z` undoes typing in that box.
- Bake the form before you send it if the recipient shouldn't change the answers.

## See also

- [Sign a PDF](Sign-a-PDF.md) — sign a signature field with a certificate
- [Flatten PDF forms and annotations](Flatten-PDF-forms-and-annotations.md) — make the answers permanent
- [Add an image to a PDF](Add-an-image-to-a-PDF.md) — put a picture of your signature on the form
- [Editing annotations](Editing-annotations.md) — add notes, highlights and text boxes


---

<!-- Sign-a-PDF.md -->

# Sign a PDF

Digitally sign a PDF with a certificate, from your Windows certificate store or a `.pfx` / `.p12` file, with **Sign Document...**. To put a picture of your handwritten signature on a page instead, see [Add an image to a PDF](Add-an-image-to-a-PDF.md).

**Available in [pre-release 3.7](https://www.sumatrapdfreader.org/prerelease)**

**Right-click the page → Document → Sign Document..., pick a certificate, click Sign, then save.** At a glance:

- **Sign Document...** (`CmdSignDocument`) — adds a cryptographic signature (PKCS#7) made with your certificate's private key.
- **Certificate:** one from your Windows certificate store, or a `.pfx` / `.p12` file and its password.
- **Where:** an empty signature field in the PDF, or a new signature box you draw on the page.
- **Appearance:** choose the lines shown in the signature box, and add a PNG or JPEG image.
- **Command line:** `sumatrapdf-tool sign` signs the PDF's signature fields with a `.pfx` file.

A digital signature shows who signed and whether the PDF changed after signing. To sign you need a certificate with a private key: one issued to you (by your employer, a government ID card, a certificate authority) or one you made yourself. Other PDF readers trust the signature only if they trust the certificate.

## Sign a PDF

1. Open the PDF.
2. Start **Sign Document...** in any of these ways:
   - Right-click the page → **Document → Sign Document...**
   - `Ctrl + K`, then `Sign Document` in [Command Palette](Command-Palette.md)
   - Click an empty signature field in the PDF. The dialog opens with that field selected.
3. In the **Sign Document** dialog, pick the **Certificate:** (see [Choose a certificate](#choose-a-certificate)).
4. Optionally fill in **Reason (optional):** and **Location (optional):**. They are shown in the signature box.
5. Pick **Where to sign:**
   - **Empty signature field: name (page N)** — a signature field the PDF already has. These come first in the list.
   - **New signature on page N** — a new signature on the current page.
6. Optionally change the **Appearance:** (see [Change how the signature looks](#change-how-the-signature-looks)).
7. Click **Sign**.
   - For a new signature, the dialog hides and asks you to *Click or drag on the page to place the signature*. Drag a box, or click to place a box of the default size (2 × 0.75 inches) centered where you clicked. `Esc` brings the dialog back.
   - If you selected something on the page before opening the dialog, the new signature fills the selection's rectangle instead.
8. A save dialog opens. The signature is computed when the file is written, so you save right away. It suggests `<name> Copy.pdf`; pick the original file name to sign it in place.

The signed PDF opens in SumatraPDF. Signatures already in the document stay valid: the new one is appended to the file.

**Cancel** or `Esc` closes the dialog without signing.

## Choose a certificate

The **Certificate:** drop-down lists the certificates in your Windows Personal certificate store that have a private key, are valid today and may be used for signing, as *name (expires yyyy-mm-dd)*. If there are any, the first one is selected.

To sign with a certificate file:

1. Pick **Certificate file...**, the last item in the drop-down.
2. Type the path, or click **Browse...** and pick a `.pfx` or `.p12` file.
3. Type its **Password:**.

If the password is wrong, you get *Wrong password for the certificate file.*

## Change how the signature looks

Under **Appearance:**, check what the signature box shows. All are on by default:

- **Show labels** — "Digitally signed by", "DN:", "Date:" and similar labels
- **Show name** — the signer's name
- **Show DN** — the certificate's distinguished name
- **Show date** — the signing date and time
- **Show name as graphic** — the name in large letters on the left

**Image (optional):** click **Choose...** and pick a PNG or JPEG, for example a scan of your handwritten signature. It is drawn on the left instead of the large name.

SumatraPDF remembers these choices until you close it. If you turn off the name, DN and date and leave reason and location empty, the name is shown anyway so the box isn't blank.

## Check a signature

Open **Properties** (`Ctrl + D`) of a signed PDF: it lists each signature with the signer, whether the certificate is trusted and whether the document changed since signing.

## Sign from the command line

`sumatrapdf-tool sign` works with signature fields the PDF already has and a `.pfx` certificate file. It can't add a new signature field.

List the signature fields and their object numbers:

```
sumatrapdf-tool sign form.pdf
```

```
   12: Signature is not signed.
```

Sign field `12`:

```
sumatrapdf-tool sign -s me.pfx -P password -o signed.pdf form.pdf 12
```

Verify the signatures:

```
sumatrapdf-tool sign -v signed.pdf
```

```
Verifying signature 12:
	Distinguished name: cn=Jamie Rivera, o=Example, ou=, email=, c=
	Certificate error: Self-signed certificate.
	The document is unchanged since signing.
	The fields signed by this signature are unchanged.
```

Without `-o` the signed PDF is written to `out.pdf`. All options: [sumatrapdf-tool sign](Tool-sign.md).

## Tips

- Fill in the form and [flatten it](Flatten-PDF-forms-and-annotations.md) before you sign. Baking a signed PDF removes the signature.
- Sign into a new file (the suggested `<name> Copy.pdf`) to keep the unsigned original.
- Use a PNG of your handwritten signature as the **Image** to get a signature that looks signed and is also verifiable.
- A self-signed certificate works, but readers show it as not trusted.

## See also

- [Add an image to a PDF](Add-an-image-to-a-PDF.md) — a picture of your signature, without a certificate
- [Fill a PDF form](Fill-PDF-forms.md) — fill in the form before signing
- [Flatten PDF forms and annotations](Flatten-PDF-forms-and-annotations.md)
- [All cmd-line tools](Tools.md)


---

<!-- Printing.md -->

# Printing

Print a document, a page range or a rectangular part of a page, from the print dialog or the command line.

**Press `Ctrl + P` to print the current document.** At a glance:

- **Print dialog:** printer, copies, page range. `Ctrl + P`
- **Print Selection:** print a rectangular fragment of a page.
- **Advanced options:** odd/even pages, page scaling, centering, paper source.
- **Command-line printing:** unattended printing with every option, on every Windows version.
- **Actual size (1:1):** print at exact size, including scans with a wrong or missing DPI.

If a printout looks wrong (banding, wrong colors, stalls), see [Reporting printing bugs](Reporting-printing-bugs.md) first — most such problems come from the printer driver, not SumatraPDF.

## Print a document

Open the system print dialog, then pick the printer, number of copies and page range:

- **File → Print...**, or the toolbar button
- `Ctrl + P`
- `Ctrl + K`, then `Print Document...` in [Command Palette](Command-Palette.md) (`CmdPrint`)

## Print part of a page

To print only a fragment of a page (a detail of a drawing, one table):

1. Select the area as a rectangle: hold `Ctrl` and drag with the left mouse button.
2. Right-click the selection and choose **Print Selection...**, or press `Ctrl + P` and pick **Selection** under _Page Range_ in the print dialog.
3. To print the fragment at its real size choose **Actual size (1:1)** under _Advanced_; **Shrink** / **Fit** scale it to the paper instead.

The selection prints on one sheet, at the top-left (or centered with **Center page horizontally**).

Note: only rectangular selections can be printed; a text selection is not offered.

Note: the Windows 11 print dialog can't print a selection, so SumatraPDF uses the classic dialog for it.

## Choose advanced print options

The system print dialog has an **Advanced** tab (a second tab next to _General_) with SumatraPDF's own options.

**Print range**

- **All selected pages** – print the chosen range as-is
- **Odd pages only** / **Even pages only** – print only odd/even pages of the range (useful for manual two-sided printing)

**Page scaling**

- **Shrink pages to printable area** – default; only scales down pages that are too big for the paper, leaves smaller pages at original size
- **Fit pages to printable area** – scale every page up or down so it fills the printable area, keeping the aspect ratio
- **Stretch pages to fill paper** – fill the paper in both dimensions, _not_ keeping the aspect ratio (the page is distorted to fit)
- **Actual size (1:1)** – print at 100%, no scaling (best for forms, labels, technical drawings and anything that must print at an exact size). For images the size comes from the resolution recorded in the file; see [Printing at actual size](#printing-at-actual-size-11)

**Other**

- **Center page horizontally on the paper** – center a page that is smaller than the paper; otherwise such a page is aligned to the top-left corner. Useful for envelopes or smaller stock fed through a tray that centers the paper
- **Choose paper source by document page size** – let the printer pick the input tray whose paper matches the page size (the same idea as Adobe's "Choose paper source by PDF page size")
- **Print each page at its document page size (mixed sizes)** – for documents whose pages have different sizes, set the paper size per page so each page goes to the right paper/tray instead of all pages using the first page's size
- **Rotate printout** – rotate the printout by extra degrees to fix a wrong orientation (same as `rotate=` in `-print-settings`)

## Get the Advanced options on Windows 11

On Windows 11 (22H2 and later) Windows replaced the classic print dialog with a new "modern" one that does **not** show application-provided tabs. SumatraPDF puts the most used **Advanced** options in its **More settings** pane instead: **Page scaling** (the same four choices as above), **Center page horizontally** and **Rotate printout**. The paper-source options are not available there.

For the rest you have two options:

1. **Use [command-line printing](#print-from-the-command-line)** — it doesn't depend on the dialog and exposes every Advanced option.
2. **Restore the legacy print dialog** for your user account. This affects all apps, not just SumatraPDF:

   ```
   reg add "HKCU\Software\Microsoft\Print\UnifiedPrintDialog" /v PreferLegacyPrintDialog /t REG_DWORD /d 1 /f
   ```

   Then sign out and back in. To undo, delete that value.

## Print from the command line

Command-line printing never shows a dialog (unless you ask for one) and exposes every option, so it works the same on every Windows version. After printing, SumatraPDF exits; check the process [exit code](#exit-codes) for success/failure.

- `-print-to-default` — print to the system default printer
- `-print-to "<printer-name>"` — print to a named printer, e.g. `-print-to "Microsoft Print to PDF"`
- `-print-settings "<list>"` — tweak printing without the dialog (see [`-print-settings` options](#-print-settings-options))
- `-silent` — suppress error message boxes (for unattended/background printing)
- `-print-dialog` — show the print dialog instead of printing silently
- `/p` — Adobe Reader alias for `-print-dialog`
- `/t <file> <printer>` — Adobe Reader silent print (`/t <printer>` if the file is already on the command line); optional driver/port args are ignored
- `-exit-when-done` — used with `-print-dialog` (and `-stress-test`); exit after the dialog is dismissed and the document printed

You can print several files in one command; the settings apply to all of them:

```
SumatraPDF.exe -print-to "HP LaserJet" -print-settings "fit" a.pdf b.pdf c.pdf
```

Use `SumatraPDF.exe -list-printers` to list installed printers, paper names, `paperkind=` IDs and tray names.

## Printing at actual size (1:1)

"Actual size" needs two things: no scaling (**Actual size (1:1)** in the dialog, `noscale` on the command line) and a correct idea of how big the document is.

- **PDF, XPS, DjVu, EPUB...** have real page sizes, so no scaling is all it takes.
- **Images** (TIFF, PNG, JPEG, BMP, scans) are only pixels; their physical size is pixels divided by the resolution stored in the file (TIFF resolution tags, PNG `pHYs`, JPEG JFIF density, EXIF). SumatraPDF uses that, and assumes 96 dpi when the file has none. A 300 dpi A3 scan therefore prints as A3 only if the scanner wrote 300 dpi into the file; a file with no resolution prints about 3x too large, and a file that claims 72 dpi comes out bigger still. The resolution SumatraPDF read is shown in Document Properties (`Ctrl + D`) as _DPI_.
- **Image folders and comic books** (CBZ, CBR, a directory of images) are always treated as 96 dpi, whatever the images say, so their pages fit a screen.

When the file's resolution is missing or wrong, tell SumatraPDF what it is:

- from the window: set `PrinterDefaults.PrintDpi` (**Settings → Advanced Settings...**), e.g. `PrintDpi = 300`, then print with **Actual size (1:1)**
- from the command line: `-print-settings "noscale,dpi=300"`

The override only sets the size; the pixels are still sent at full resolution.

Printing a rectangular selection (see [Print part of a page](#print-part-of-a-page)) at actual size works the same way: choose **Actual size (1:1)**.

## Change print dialog defaults

Change some defaults used by the print dialog with the `PrinterDefaults` advanced setting (**Settings → Advanced Settings...**):

```
PrinterDefaults [
	PrintScale = none
	Collate = collate
	PrintDpi = 0
]
```

- `PrintScale` — default page scaling. Values: `shrink` (default), `fit`, `stretch`, `none`.
- `Collate` — default for the print dialog's Collate checkbox. Values: `default` (leave the printer/driver default), `collate`, `nocollate`. You can still change it per print in the dialog. For command-line printing, use the `collate` / `nocollate` `-print-settings` tokens instead.
- `PrintDpi` — resolution to assume for the document when printing at original size; `0` (default) uses what the file says. The same as `dpi=<n>` in `-print-settings`, for printing from the window. See [Printing at actual size](#printing-at-actual-size-11).

## Recipes for common tasks

**Print a PDF to the default printer, unattended**

```
SumatraPDF.exe -print-to-default -silent document.pdf
```

**Print at exact size (no scaling) — forms, labels, pre-printed stationery**

```
SumatraPDF.exe -print-to "Label Printer" -print-settings "noscale" label.pdf
```

**Print a scan at its real size when the file lacks (or lies about) its DPI**

```
SumatraPDF.exe -print-to "Plotter" -print-settings "noscale,dpi=300" drawing.tif
```

**Print a small page centered on larger paper (e.g. an envelope)**

```
SumatraPDF.exe -print-to "HP LaserJet" -print-settings "noscale,center" envelope.pdf
```

**Fit every page to the paper, in grayscale, 2 copies**

```
SumatraPDF.exe -print-to "Office Printer" -print-settings "fit,monochrome,2x" report.pdf
```

**Two-sided, long-edge binding, fit to page**

```
SumatraPDF.exe -print-to "Office Printer" -print-settings "fit,duplexlong" report.pdf
```

**Manual two-sided on a one-sided printer** (print odd pages, flip the stack, then print even pages)

```
SumatraPDF.exe -print-to "Office Printer" -print-settings "odd,fit" report.pdf
SumatraPDF.exe -print-to "Office Printer" -print-settings "even,fit" report.pdf
```

**Print only the last 3 pages**

```
SumatraPDF.exe -print-to-default -print-settings "-3--1" document.pdf
```

**Print a specific paper size from a specific tray**

```
SumatraPDF.exe -print-to "Office Printer" -print-settings "paper=A5,bin=2,fit" booklet.pdf
```

**Print a document with mixed page sizes to matching paper/trays**

```
SumatraPDF.exe -print-to "Multi-tray Printer" -print-settings "paper=auto,bin=auto" mixed.pdf
```

**Print a wide (landscape) page in its original orientation (no 90° rotation)**

```
SumatraPDF.exe -print-to "Receipt Printer" -print-settings "disable-auto-rotation" wide.pdf
```

**Fix an upside-down printout (e.g. when printing to XPS / Print to PDF)**

```
SumatraPDF.exe -print-to "Microsoft Print to PDF" -print-settings "rotate=180" doc.pdf
```

**"Print" to a PDF file**

```
SumatraPDF.exe -print-to "Microsoft Print to PDF" -print-settings "output=C:\out\result.pdf" input.pdf
```

## Tips

- Use **Odd pages only**, then **Even pages only** (or `odd` / `even`) for manual two-sided printing.
- Use **Actual size (1:1)** / `noscale` for forms, labels and technical drawings.
- Use `-print-to "Microsoft Print to PDF"` to tell a driver problem from a SumatraPDF one.
- Run a command without `-silent` first; error dialogs explain failures.
- Use `-print-to-default` to avoid printer-name mismatches.

## Troubleshooting

### Paper size or tray ignored

Drivers often report paper sizes under non-obvious names. If `paper=A4` has no effect:

1. Print once from the Windows dialog and note the exact paper name in the driver, or list names with `-list-printers`.
2. Use that string: `-print-settings "paper=A3 297 x 420 mm"`.
3. Or use `paperkind=<num>` with the Windows `DMPAPER_*` id.
4. For mixed page sizes: `paper=auto,bin=auto`.

Combine with `ignore-pdf-print-settings` if the PDF embeds conflicting `ViewerPreferences`.

### Wrong orientation or margins

- Wide pages auto-rotate 90° to fit — add `disable-auto-rotation` to keep original orientation.
- Upside-down virtual printer output — try `rotate=180`.
- Content too small — use `fit` or `shrink` (default); exact size — `noscale`.

### Job prints to wrong printer

`-print-to` requires the **exact** printer name from Windows Settings → Printers. `-print-to-default` avoids name mismatches.

### Silent script reports failure

Check the [exit code](#exit-codes). Common results:

| Code | Check                                                                             |
| ---- | --------------------------------------------------------------------------------- |
| `4`  | Printer name typo or no default printer                                           |
| `5`  | Driver error — update driver, try printing to "Microsoft Print to PDF" to isolate |
| `6`  | `sumatrapdfrestrict.ini` has `PrinterAccess = 0`                                  |

Add `-silent` only after confirming the command works interactively (without `-silent`, error dialogs explain failures).

### Lines or barcodes missing

SumatraPDF renders each page to a bitmap before printing (see [How SumatraPDF prints](#how-sumatrapdf-prints)). Very fine lines, hairline barcodes, or light gray rules may disappear at printer resolution. Try `noscale` with a higher-DPI driver, or print from a vector-aware tool. See [Reporting printing bugs](Reporting-printing-bugs.md) — often driver/resolution, not SumatraPDF logic.

### Windows 11: no Advanced tab in print dialog

Use [command-line printing](#print-from-the-command-line) or enable the [legacy print dialog](#get-the-advanced-options-on-windows-11) — CLI exposes every Advanced option on all Windows versions.

## How SumatraPDF prints

SumatraPDF renders each page to an image and sends that image to the printer. This is reliable across document types (PDF, XPS, CBZ, etc.) but means:

- the print spool can be large and printing can be slower than text-based printers
- print quality follows the printer resolution, not a vector path
- screen-only settings (anti-aliasing, color range, background color) do **not** change the printout

## Exit codes

For unattended/silent printing, the process exit code tells you _why_ a print failed:

| Exit code | Meaning                                                  |
| --------- | -------------------------------------------------------- |
| `0`       | success                                                  |
| `2`       | couldn't open the file (not found or unsupported format) |
| `3`       | the document doesn't allow printing                      |
| `4`       | the printer (named, or default) doesn't exist            |
| `5`       | the printer driver / device failed                       |
| `6`       | printing is disabled by restriction policy               |

With several files, the code is `0` only if all printed, otherwise the category of the first failure. Anything that goes wrong inside the spooler/driver _after_ the job is submitted (out of paper, printer offline, jam) can't be reported — SumatraPDF only knows whether the job was handed off.

## `-print-settings` options

The list is comma-separated, e.g. `-print-settings "1-5,odd,fit,monochrome"`. Order doesn't matter. Available tokens:

**Which pages**

| Option         | Meaning                                                      |
| -------------- | ------------------------------------------------------------ |
| `5`            | a single page                                                |
| `2-6`          | a page range                                                 |
| `10-8`         | a reversed range (prints 10, 9, 8)                           |
| `last`         | the last page                                                |
| `-1`, `-2`     | count from the end (`-1` = last page, `-2` = second-to-last) |
| `-3--1`        | a range using negatives (here, the last 3 pages)             |
| `even` / `odd` | only even / only odd pages of the selected range             |

**Scaling and placement**

| Option    | Meaning                                                                                                                                               |
| --------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
| `noscale` | print at 100% (no scaling), i.e. actual size / 1:1                                                                                                    |
| `dpi=<n>` | resolution to assume for the document, e.g. `dpi=300` for a 300 dpi scan whose file says otherwise (or nothing); decides the size `noscale` prints at |
| `shrink`  | scale down only pages too big for the paper (default)                                                                                                 |
| `fit`     | scale every page to fill the printable area, keeping aspect ratio                                                                                     |
| `stretch` | fill the paper in both dimensions, ignoring aspect ratio                                                                                              |
| `center`  | center the page horizontally on the paper                                                                                                             |

**Orientation**

| Option                                    | Meaning                                                                                                                                                                                                        |
| ----------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `portrait` / `landscape`                  | rotate the _content_ 90° (this is content rotation, **not** the paper orientation, which is set by the printer/driver)                                                                                         |
| `disable-auto-rotation`                   | don't auto-rotate a wide page 90° to fit the paper; print it in its original orientation                                                                                                                       |
| `rotate=90` / `rotate=180` / `rotate=270` | rotate the printout by extra degrees, to fix a wrong orientation (e.g. `rotate=180` for upside-down output on virtual printers). In the window, use the **Rotate printout** dropdown on the Advanced print tab |

**Paper and tray**

| Option               | Meaning                                                                                                                                        |
| -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| `paper=A4`           | standard size: `A2`, `A3`, `A4`, `A5`, `A6`, `letter`, `legal`, `tabloid`, `statement`, or a name the printer reports (e.g. `A3 297 x 420 mm`) |
| `paper=76mm x 130mm` | a custom paper size                                                                                                                            |
| `paper=auto`         | set the paper size from each page's own size (for mixed page sizes)                                                                            |
| `paperkind=<num>`    | paper size by Windows `DMPAPER_*` id; use when `paper=A3` doesn't match the driver's paper name                                                |
| `bin=<num or name>`  | select the input tray (by number or name)                                                                                                      |
| `bin=auto`           | let the printer pick the tray whose paper matches the page size                                                                                |

Note: if `paper=A4` doesn't take effect, the driver may report the size under a different name. List the exact names your printer accepts (`-list-printers`) and use one of them, or fall back to `paperkind=<num>`.

**Copies, sides and color**

| Option                  | Meaning                                                     |
| ----------------------- | ----------------------------------------------------------- |
| `3x`                    | number of copies (here, 3)                                  |
| `collate` / `nocollate` | collate copies (`1,2,3 / 1,2,3`) or not (`1,1 / 2,2 / 3,3`) |
| `simplex`               | one-sided                                                   |
| `duplex` / `duplexlong` | two-sided, flip on long edge                                |
| `duplexshort`           | two-sided, flip on short edge                               |
| `color`                 | force color                                                 |
| `monochrome`            | force grayscale/black-and-white                             |

**Output (advanced)**

| Option                      | Meaning                                                                                        |
| --------------------------- | ---------------------------------------------------------------------------------------------- |
| `output=<file>`             | write to a file (for "print to file" style printers)                                           |
| `docname=<name>`            | set the print job name shown in the print queue                                                |
| `ignore-pdf-print-settings` | ignore the print defaults embedded in the PDF (see [below](#print-defaults-embedded-in-a-pdf)) |

## Print defaults embedded in a PDF

A PDF can carry print hints in its `ViewerPreferences` dictionary. When you print a **PDF** from the command line, SumatraPDF reads them and uses them as defaults:

| ViewerPreferences key | Effect                                                                                |
| --------------------- | ------------------------------------------------------------------------------------- |
| `PrintScaling`        | `/None` prints at original size (no scaling); `/AppDefault` uses SumatraPDF's default |
| `NumCopies`           | number of copies                                                                      |
| `Duplex`              | `Simplex`, `DuplexFlipShortEdge` or `DuplexFlipLongEdge`                              |
| `PickTrayByPDFSize`   | when true, pick the input tray by page size (same as `bin=auto`)                      |

These are **defaults only**. Anything you pass in `-print-settings` overrides the PDF's value — e.g. `-print-settings "2x"` prints 2 copies even if the PDF asks for 3. To ignore the PDF's embedded values completely, add `ignore-pdf-print-settings`:

```
SumatraPDF.exe -print-to-default -print-settings "ignore-pdf-print-settings" document.pdf
```

This applies to command-line printing only; when you print from the window, the print dialog's own values are used.

## See also

- [FAQ](FAQ.md) — printing quick answers
- [Command-line arguments](Command-line-arguments.md) — all command-line options
- [Reporting printing bugs](Reporting-printing-bugs.md) — what to include when a printout is wrong


---

<!-- Read-Aloud.md -->

# Read Aloud (TTS)

Read Aloud reads document text with Windows text-to-speech. Start it from the toolbar, the main or context menu, or the [Command Palette](Command-Palette.md).

**Available in pre-release 3.7+.**

**Most often you click the toolbar Read Aloud button to listen from the current position.** At a glance:

- **Read Aloud:** reads the selection if there is one, otherwise from the first visible text to the end of the document.
- **Start scopes:** from top of the viewport, from the right-click position, or the selection only.
- **Follow-along:** the spoken sentence and word are underlined; the view scrolls to keep them visible.
- **Playback bar:** document name, page, scope, **Pause** / **Resume** and **Stop**.
- **Voice:** pick any installed Windows voice.

## Start reading

Open a document with selectable text (PDF, EPUB, etc.), then use one of:

- **Toolbar:** Read Aloud button. Click to start / pause / continue. The icon shows a speaker when idle or paused, a pause symbol while speaking. The dropdown arrow has the explicit start scopes and **Voice**.
- **Main menu:** **Read Aloud** (after Selection).
- **Context menu:** **Read Aloud** (after Document).
- **Command Palette:** `Ctrl + K`, then `Read Aloud` (`CmdToggleReadAloud`). Also **Start Reading From Top**, **Start Reading Selection**.

### Choose where to start

| Command                                | Behavior                                                                                                       |
| -------------------------------------- | -------------------------------------------------------------------------------------------------------------- |
| **Read Aloud** (toolbar / palette)     | Selection if present, otherwise first visible text in the viewport; continues through the rest of the document |
| **Start Reading From Top**             | First visible text in the viewport → end of document                                                           |
| **Start Reading From Cursor Position** | Context menu only — right-click position → end of document (disabled when there is no text at the cursor)      |
| **Start Reading Selection**            | Selected text only; does not continue past the selection                                                       |

Scope labels on the playback bar: **Smart start**, **From top**, **From cursor**, or **Selection**.

## Follow along

While a session is active (speaking or paused), a **playback bar** at the bottom of the canvas shows the document name, **page X of Y**, start scope, and **Pause** / **Resume** and **Stop** buttons on the left.

- **Follow-along:** the spoken sentence is underlined in blue, the current word in amber.
- **Auto-scroll:** the viewport scrolls to keep the spoken word in view. If you scroll the highlight fully off-screen, auto-scroll stops for that session so manual navigation is respected.

![Read Aloud: the spoken sentence and word are underlined, the playback bar is at the bottom](https://files.sumatrapdfreader.org/assets/sumatrapdf/docs/img/read-aloud-playback-bar-fa54.png)

## Pause, continue or stop

- **Pause** stops speech and remembers your position so you can **Continue Reading** later.
- **Stop** ends the session and clears the resume position.
- **Playback bar:** **Pause** / **Resume** and **Stop** buttons.
- **Menus:** **Stop Reading** is always in the Read Aloud menus (main menu, context menu, toolbar dropdown), even if the playback bar is not visible; it is disabled when nothing is being read.
- **Command Palette:** **Pause Reading**, **Continue Reading**, and **Stop Reading** appear when they apply.

Switching to another tab stops reading and clears the resume position on the tab you left.

## Change the voice

Open **Voice** in any Read Aloud menu and pick **System default** or an installed Windows voice (WinRT OneCore voices and SAPI voices, including those from [NaturalVoiceSAPIAdapter](https://github.com/gexgd0419/NaturalVoiceSAPIAdapter)).

The choice is saved in `ReadAloudVoiceId` in [Advanced settings](Advanced-options-settings.md) (`SumatraPDF-settings.txt`). Leave it empty for the system default.

## Tips

- Select a paragraph, then use **Start Reading Selection** to hear only that part.
- Right-click a spot and use **Start Reading From Cursor Position** to start mid-page.
- Scroll the highlight off-screen to stop auto-scroll and browse while listening.
- Install [NaturalVoiceSAPIAdapter](https://github.com/gexgd0419/NaturalVoiceSAPIAdapter) for more voices.

## Limitations

- Uses Windows speech voices installed on your system (WinRT Speech Synthesis, plus SAPI voices such as NaturalVoiceSAPIAdapter).
- EPUB/complex layouts may read in an order that does not match visual layout.
- Copy-restricted documents cannot be read aloud (no message is shown).
- Pages with no extractable text show a short _“No text available to read aloud”_ notification.
- Does not replace a full screen-reader experience for blind users — see [Accessibility](Accessibility.md) for UI Automation / Narrator.

## See also

- [Commands](Commands.md) — Read Aloud commands
- [Advanced settings](Advanced-options-settings.md) — `ReadAloudVoiceId`
- [Version history](Version-history.md) — 3.7 Read Aloud entry
- [Accessibility](Accessibility.md) — screen readers and other accessibility features


---

<!-- AI-Chat-with-document.md -->

# AI Chat with document

AI Chat is a sidebar where you ask questions about the PDF you are reading. Answers come from an AI agent CLI running on your computer — SumatraPDF does not send your files to its own servers.

**Available in pre-release 3.7+ on Windows 10 or later.**

**Most often you open View → Claude chat (or another backend) and type a question.** At a glance:

- **Four backends:** [Claude Code](#claude-code), [Grok Build](#grok-build), [OpenAI Codex](#openai-codex), and [Antigravity](#antigravity).
- **Per-tab sessions:** each document tab has its own conversation.
- **Resume:** pick a previous session from the session dropdown.
- **Options:** model, effort level or sandbox mode, per backend.
- **Stop:** cancel a reply in progress.

**Nothing happens unless you explicitly invoke it.** SumatraPDF never starts an AI agent or sends document content to an AI service on its own. An agent CLI runs only when you open a chat panel, send a message, or use an AI translate-selection command. To decide whether to show AI commands in menus, SumatraPDF only checks if the CLI executable exists on disk.

## Open a chat

Open a PDF (see [Supported documents](#supported-documents)), then:

- **Menu:** **View → Claude chat** (`CmdAIChatWithClaudeCode`), **View → Grok chat** (`CmdAIChatWithGrokBuild`), **View → Codex chat** (`CmdAIChatWithOpenAICodex`), or **View → Antigravity chat** (`CmdAIChatWithAntiGravity`).
- **Context menu:** **AI chat with document using** → **Grok Build**, **OpenAI Codex**, **Claude Code**, or **Antigravity**.
- **Command Palette:** `Ctrl + K`, then `Claude chat...`, `Codex chat...`, `Grok chat...` or `Antigravity chat...`.
- **Keyboard:** no default key binding; assign your own — see [Customize keyboard shortcuts](Customize-keyboard-shortcuts.md).

Drag the splitter between the document and the chat panel to resize the sidebar.

## Ask a question

Type a question in the input box at the bottom of the sidebar and press `Enter`. While the agent is working on a reply, use **Stop** to cancel the current request.

Each document tab has its own chat session. Switching tabs switches the sidebar to that tab's conversation history.

## Resume a previous session

Pick a previous session from the session dropdown. SumatraPDF lists and resumes sessions for the current document's folder. Each CLI stores history in its own location:

- Claude Code: `~/.claude/projects/` (encoded by project directory)
- Grok Build: `~/.grok/sessions/`
- OpenAI Codex: `~/.codex/sessions/` (with descriptions from `~/.codex/history.jsonl`)
- Antigravity: `~/.gemini/antigravity/projects/`, `~/.gemini/antigravity-cli/projects/`, or `~/.gemini/projects/` (encoded by project directory)

## Choose model and options

Backend-specific controls in the sidebar:

- **Claude Code:** model, effort level, and optionally **Skip Permissions** (passes `--dangerously-skip-permissions` — use only if you understand the security implications).
- **Grok Build:** model, effort level, and optionally **Always Approve** (passes `--always-approve`).
- **OpenAI Codex:** model, sandbox mode, and optionally **Skip Sandbox**.
- **Antigravity:** model, effort level, and **Auto Approve** (on by default).

Defaults are saved in [advanced settings](Advanced-options-settings.md) (see [Settings](#settings)).

## Tips

- Assign a shortcut to your preferred chat command; there is none by default.
- Leave **Skip Permissions** / **Skip Sandbox** off unless you understand the security implications.
- Keep **Auto Approve** on for Antigravity; without it the agent can't read the document.
- If a CLI isn't found, put it on `PATH` or in one of the folders listed for that backend below.

## Supported documents

AI Chat is available only for **PDF** (`.pdf`) files.

It is **not** available for single images, comic archives (`.cbr`, `.cbz`, etc.), folders of images, DjVu, ebooks (EPUB, MOBI, …), CHM, XPS, PostScript, plain text, and other formats. On those tabs the **AI chat with document** commands and context-menu submenu are hidden.

## Set up a backend

### Claude Code

This feature requires **[Claude Code](https://docs.anthropic.com/en/docs/claude-code)** to be installed and available on your system. SumatraPDF launches the `claude` command-line tool when you send a message.

If Claude Code is missing, the chat panel shows an error such as _Cannot find claude. Is Claude Code installed?_

Install and set up Claude Code using Anthropic's official guide:

- [Set up Claude Code](https://code.claude.com/docs/en/setup)

After installation, make sure `claude` (or `claude.exe`) is on your `PATH`. SumatraPDF also looks in `%USERPROFILE%\.local\bin\`, `%USERPROFILE%\AppData\Local\Programs\claude-code\`, and `%USERPROFILE%\AppData\Roaming\npm\`.

The model picker includes Claude Code's documented aliases: `default`, `best`, `sonnet`, `opus`, `haiku`, `sonnet[1m]`, `opus[1m]`, and `opusplan`. Claude Code resolves these aliases according to the user's account and configured provider.

### Grok Build

This feature can also use **[Grok Build](https://x.ai/news/grok-build-cli)** (the `grok` command-line tool).

If Grok Build is missing, the chat panel shows an error such as _Cannot find grok. Is Grok Build installed?_

Install Grok Build and sign in using xAI's instructions. SumatraPDF looks for `grok.exe` on `PATH`, in `%USERPROFILE%\.grok\bin\`, and in `%USERPROFILE%\.local\bin\`.

Open the panel with **View → Grok chat** (`CmdAIChatWithGrokBuild`), or `Ctrl + K`, `Grok chat...` command in [Command Palette](Command-Palette.md).

Grok Build settings are in the `GrokBuild` section of [advanced settings](Advanced-options-settings.md). The **Always Approve** checkbox passes `--always-approve` to Grok Build.

The first time you open the Grok chat panel in an app session, SumatraPDF runs `grok models` and uses the models available to the signed-in Grok CLI in the model picker. If that query fails, the picker falls back to `grok-4.5`.

### OpenAI Codex

This feature can also use **[OpenAI Codex](https://developers.openai.com/codex/cli)** (the `codex` command-line tool).

If OpenAI Codex is missing, the chat panel shows an error such as _Cannot find codex. Is OpenAI Codex installed?_

Install and sign in using OpenAI's official guides:

- [Codex CLI](https://developers.openai.com/codex/cli)
- [Codex quickstart](https://developers.openai.com/codex/quickstart)
- [Codex on Windows](https://developers.openai.com/codex/windows)

After installation, make sure `codex` (or `codex.exe`) is on your `PATH`, or in `%USERPROFILE%\.codex\bin\` or `%USERPROFILE%\.local\bin\`.

Open the panel with **View → Codex chat** (`CmdAIChatWithOpenAICodex`), or `Ctrl + K`, `Codex chat...` command in [Command Palette](Command-Palette.md).

Codex settings are in the `CodexBuild` section of [advanced settings](Advanced-options-settings.md). The **Skip Sandbox** checkbox passes `--dangerously-bypass-approvals-and-sandbox` to Codex — use only if you understand the security implications.

The first time you open the Codex chat panel in an app session, SumatraPDF asks the signed-in Codex CLI which models are available and uses them in the model picker. If that query fails, the picker falls back to `gpt-5.5`, `gpt-5.4`, and `o3`. You can also pick a sandbox mode: **Read-only**, **Workspace write**, or **Full access**.

### Antigravity

This feature can also use Google's **[Antigravity](https://antigravity.google/)** CLI (the `antigravity` or `agy` command-line tool).

If Antigravity is missing, the chat panel shows an error such as _Cannot find antigravity. Is Antigravity installed?_

Install Antigravity and sign in using Google's instructions. SumatraPDF looks for `antigravity.exe` or `agy.exe` on `PATH`, in `%USERPROFILE%\.local\bin\`, `%USERPROFILE%\.gemini\antigravity-cli\bin\`, `%USERPROFILE%\AppData\Local\agy\bin\`, `%USERPROFILE%\AppData\Roaming\Antigravity\bin\`, `%USERPROFILE%\AppData\Local\Programs\`, and `%USERPROFILE%\AppData\Roaming\npm\`.

Open the panel with **View → Antigravity chat** (`CmdAIChatWithAntiGravity`), or `Ctrl + K`, `Antigravity chat...` command in [Command Palette](Command-Palette.md).

Antigravity settings are in the `AntiGravity` section of [advanced settings](Advanced-options-settings.md). The **Auto Approve** checkbox passes `--dangerously-skip-permissions` to Antigravity. It is **on by default**: the CLI can't ask for permissions when run non-interactively, so without it the agent can't read the document. It also lets the agent use other tools without asking.

The first time you open the Antigravity chat panel in an app session, SumatraPDF runs `agy models` and uses the models available to the signed-in CLI in the model picker. If that query fails, the picker falls back to a built-in list of Gemini 3.8 / 3.7 / 3.6 Flash, Gemini 3.1 Pro, Claude Sonnet / Opus 4.6, and GPT-OSS 120B models. The default is `gemini-3.8-flash-medium`. Add more model IDs, comma-separated, with the `Models` setting.

## Settings

Sidebar width is shared by all backends via the `AIChatSidebarDx` advanced setting.

Backend-specific options are in [advanced settings](Advanced-options-settings.md) (`SumatraPDF-settings.txt`):

- `ClaudeCode` — default model, effort level, **Skip Permissions**, background color
- `GrokBuild` — default model, effort level, **Always Approve**, background color
- `CodexBuild` — default model, extra models, sandbox mode, **Skip Sandbox**, background color
- `AntiGravity` — default model, extra models, effort level, **Auto Approve**, background color

## Requirements and limitations

- **Windows 10+** only (uses WebView2 for the chat UI).
- Requires a working installation of at least one supported agent CLI and network access as required by that CLI.
- Each agent runs as a separate process; behavior, models, and billing follow that provider's terms and your account.

## See also

- [Commands](Commands.md) — `CmdAIChatWithClaudeCode`, `CmdAIChatWithGrokBuild`, `CmdAIChatWithOpenAICodex`, `CmdAIChatWithAntiGravity`
- [Command Palette](Command-Palette.md)
- [Advanced settings](Advanced-options-settings.md) — `ClaudeCode`, `GrokBuild`, `CodexBuild`, and `AntiGravity` sections
- [Version history](Version-history.md) — 3.7 AI Chat entry
- [Claude Code documentation](https://docs.anthropic.com/en/docs/claude-code) (Anthropic)
- [Grok Build](https://x.ai/news/grok-build-cli) (xAI)
- [OpenAI Codex CLI](https://developers.openai.com/codex/cli) (OpenAI)
- [Antigravity](https://antigravity.google/) (Google)


---

<!-- Keyboard-shortcuts.md -->

# Keyboard shortcuts

You can [customize keyboard shortcuts](Customize-keyboard-shortcuts.md). Also see [standard Windows keyboard shortcuts](https://support.microsoft.com/en-us/windows/keyboard-shortcuts-in-windows-dcc61a57-8ff0-cffe-9796-cb9706c75eec) for controls like tree view or edit fields.

:columns

### File menu

- `Ctrl + N` Open a new window
- `Ctrl + O` Open a file
- `Ctrl + W` Close current file
- `Ctrl + S` Save current file as
- `F2` Rename current file
- `Ctrl + P` Print
- `Ctrl + D` Properties
- `Ctrl + Q`, `Alt-F4` Quit app

### Go To menu

- `Right Arrow` / `Left Arrow` — Next / Previous Page
  scrolls left / right if page width > window width
- `Home` First Page
- `End` Last Page
- `Ctrl + G` Go To Page...
- `Alt + Left Arrow` Back
- `Alt + Right Arrow` Forward
- `Ctrl + F` Find... (see [Finding text](Finding-text.md))

### Favorites menu

- `Ctrl + B` Add current page to favorites

### View menu

- `Ctrl + 6` Single Page
- `Ctrl + 7` Facing
- `Ctrl + 8` Book View
- `Ctrl + Shift + -`, `[` — Rotate Left (counterclockwise)
- `Ctrl + Shift + +`, `]` — Rotate Right (clockwise)
- `F5` Enter / Exit Presentation
- `F11` Enter / Exit Full Screen
- `F12` Show / Hide Bookmarks
- `F8` Show / Hide Toolbar
- `Ctrl + A` Select All
- `Ctrl + C` Copy Selection
- `F7` Select text with the keyboard (**ver 3.7+**): puts a caret in the page text; arrows move it, `Shift + arrows` select, `v` toggles visual mode (arrows select without Shift), `Ctrl + C` or `y` copies, `Esc` or `F7` leaves

### Zoom menu

- `Ctrl + 0` Fit Page
- `Ctrl + 1` Actual Size
- `Ctrl + 2` Fit Width
- `Ctrl + 3` Fit Content
- `Ctrl + Y` Custom Zoom...

### Navigation

- `j` / `k` Scroll up / down by line
- `h` / `l` Scroll left / right
- `Up` / `Down` Scroll up/down by line
- `Shift + Left` / `Shift + Right` — Scroll left / right faster
- `space` Scroll by screen
- `Shift + space` Scroll back by screen
- `n` / `p` Next / previous page
- `Page Down` / `Page Up` Next / previous page
- `Ctrl + Down` / `Ctrl + Up` Next / previous page
- `Alt + Left` Go back
- `Alt + Right` Go forward
- `Ctrl + G` Go to page
- `g` Go to page
- `Home` Go to first page
- `End` Go to last page
- `b` Flip a page in book mode
- `Ctrl + Shift + Right` Open next document in the directory
- `Ctrl + Shift + Left` Open previous document in the directory

### Viewing state

- `+` / `-` zoom in/out
- `Ctrl + scroll wheel` zoom in/out
- `Right Mouse + scroll wheel` zoom in/out (hold the button; a click without moving still opens the context menu)
- `z` cycle zoom: Fit Page → Fit Width → Fit Height → Fit Content → Fit Visible → Shrink To Fit → Fit Page
- `c` toggle between continuous/non-continuous mode
- `Ctrl + Shift + -` rotate left
- `/` on numeric keypad rotate left
- `Ctrl + Shift + +` rotate right
- `*` on numeric keypad rotate right
- `F12` show/hide bookmarks (table of contents)
- `F6` switch focus between bookmarks window and main window
- `Ctrl + L`, `F5`, `Shift + F11` — Enter / exit presentation mode (minimal full screen mode)
- `F11`, `Ctrl + Shift + L`, `f` Enter / Exit full screen mode
- `ESC` exit full screen or presentation mode
- mouse double-click in the top-right corner (not over text) exits full screen or presentation mode
- `i` toggle showing page info (**ver 3.6+** )
- `i` invert colors in the document (**ver 3.5.2 or earlier**)
- `Shift + i` invert colors in the document (**ver 3.6+**)
- `Shift + i` toggle showing page info (**ver 3.5.2 or earlier**)
- `m` show cursor position in document coordinates
- `F8` show/hide toolbar
- `F9` show/hide menu
- `w` in presentation mode, make whole screen white
- `.` in presentation mode, make whole screen black

### Actions

- `Ctrl + K` Command palette
- `Ctrl + O` Open a new document
- `Ctrl + W` Close current document
- `Ctrl + F4` Also close current document
- `Ctrl + S` Save current document as...
- `Ctrl + Shift + S` Save annotations to the PDF
- `Ctrl + P` Print
- `F2` Rename file and reopen with new name
- `Ctrl + Shift + N` Open current document in new window
- `r` Reload document
- `Ctrl + F` Find text
- `/` Find text
- `F3` Find next
- `Shift + F3` Find previous
- `Alt + F4` Close window (and all documents in it). Quit app if last window.
- `q` Close current document (tab). Close window if last tab. Quit app if last window.
- `Ctrl + Q` Quit app (close all windows and opened documents)
- `Ctrl + Left Mouse` Select area (can then use with copy, print or +/- zoom)
- `Ctrl + B` Add current page to favorites
- `Right Mouse` drag to pan the page in any direction
- `Alt + Scroll Wheel` Increase vertical scroll wheel steps (faster)
- `Shift + Scroll Wheel` Pan horizontally with scroll wheel
- `Ctrl + Y` Show dropdown zoom control
- `F1` Show documentation / manual

### Tabs

- `Ctrl + Tab` / `Ctrl + Shift + Tab` — next / previous tab. **Ver 3.6+:** these open **Smart Tab Switch** (a tab list while Ctrl is held). For immediate tab-strip order without the list, use `Ctrl + PageDown` / `Ctrl + PageUp`, or [rebind](Customize-keyboard-shortcuts.md) `Ctrl + Tab` to `CmdNextTab` / `CmdPrevTab` (see [Tabs and windows](Tabs-and-windows.md#restore-pre-36-ctrltab-no-switcher-popup))
- `Ctrl + PageDown` go to next tab (strip order, no popup)
- `Ctrl + PageUp` go to previous tab (strip order, no popup)
- `Alt + 1` go to tab 1. Use `Alt + 2`, etc. up to `Alt + 8`
- `Alt + 9` go to last tab

### Annotations

**Ver 3.3+**, some in **ver 3.4+**:

- `a` create highlight annotation from selected text
- `A` like `a` plus turns on Edit PDF mode
- `u` create underline annotation from selected text
- `U` like `u` plus turns on Edit PDF mode
- `Delete` delete annotation under mouse cursor
- `Ctrl + C` copy the selected annotation, `Ctrl + X` cut the one under the mouse cursor, `Ctrl + V` paste it with its top-left at the mouse. A cut annotation is deleted when the copy is pasted (**ver 3.7+**)
- `Ctrl + Z` undo the last change to the PDF, `Ctrl + Shift + Z` redo it (**ver 3.7+**)
- `Ctrl-Shift-S` save annotations to current PDF file

:columns


---

<!-- Customize-keyboard-shortcuts.md -->

# Customize keyboard shortcuts

Add new keyboard shortcuts, reassign existing ones to a different [command](Commands.md), or disable them, using the `Shortcuts` [advanced setting](Advanced-options-settings.md).

**Available in version 3.4 or later.**

**Most people use it to rebind a key to a different command.** At a glance:

- **Rebind a key:** `Cmd` + `Key` in the `Shortcuts` array.
- **Disable a built-in shortcut:** bind the key to `CmdNone`.
- **Command with an argument (ver 3.6+):** e.g. `CmdCreateAnnotHighlight #00ff00`.
- **Command Palette entry (ver 3.6+):** add `Name`.
- **Global shortcut (ver 3.7+):** prefix `Key` with `Global ` to work when SumatraPDF isn't focused.
- **Toolbar button:** add `ToolbarText`, see [Customize toolbar](Customize-toolbar.md).

## Add or change a shortcut

1. Open the settings file:
   - Menu: **Settings → Open Advanced Settings File...**
   - [Command Palette](Command-Palette.md): `Ctrl + K`, then `Open Advanced Settings File...`
2. It opens in your default text editor. Find the `Shortcuts` array and add definitions.
3. Save. Changes apply immediately, no restart needed.

Example:

```
Shortcuts [
    [
        Cmd = CmdOpenFile
        Key = Alt + o
    ]
    [
        Cmd = CmdNone
        Key = q
    ]
    [
        Name = Create green highlight
        Cmd = CmdCreateAnnotHighlight #00ff00
        Key = a
    ]
    [
        Cmd = CmdNextTab
        ToolbarText = Next Tab
    ]
]
```

- by default, `Ctrl + O` runs `CmdOpenFile` (open a file). This changes it to `Alt + O`
- by default, `q` closes the document. Binding it to `CmdNone` disables that built-in shortcut
- **ver 3.6+:** `CmdCreateAnnotHighlight` takes a color argument (`#00ff00` is green). This reassigns `a` to create a green highlight annotation (instead of the default yellow)
- **ver 3.6+:** `Name` is optional. If provided, the command appears in the command palette (`Ctrl + K`)

## Add a global shortcut

**Ver 3.7+:** prefix `Key` with `Global ` to register a system-wide shortcut that works even when SumatraPDF does not have focus:

```
Shortcuts [
    [
        Cmd = CmdGoToNextPage
        Key = Global PageDown
    ]
    [
        Cmd = CmdScreenshot
        Key = Global Alt+PrtSc
    ]
]
```

- To avoid hotkey conflicts, global shortcuts are only registered by the first running SumatraPDF instance.
- Commands that need a window or document go to the most recently activated open window. If it's closed, the previously active open window is used. The shortcut does not steal focus or bring background windows to the foreground.
- If registering fails (e.g. another program already registered it), a warning notification is shown.

## Restore pre-3.6 Ctrl+Tab (no Smart Tab Switch popup)

**Ver 3.6+** binds `Ctrl + Tab` / `Ctrl + Shift + Tab` to **Smart Tab Switch** (`CmdNextTabSmart` / `CmdPrevTabSmart`), which shows a tab list while Ctrl is held. In 3.5 those keys switched tabs immediately in strip order (`CmdNextTab` / `CmdPrevTab`).

**Ver 3.7+:** simplest is `CtrlTabSimple = true` in advanced settings. Or rebind the keys:

```
Shortcuts [
    [
        Cmd = CmdNextTab
        Key = Ctrl + Tab
    ]
    [
        Cmd = CmdPrevTab
        Key = Ctrl + Shift + Tab
    ]
]
```

`Ctrl + PageDown` / `Ctrl + PageUp` already run next/prev tab without the popup. More detail: [Tabs and windows](Tabs-and-windows.md#restore-pre-36-ctrltab-no-switcher-popup).

## Tips

- Test changes without restarting: they apply as soon as you save the settings file.
- If a shortcut doesn't work, check the command name and arguments; parse failures are logged, so [check the logs](Debugging-Sumatra.md#getting-logs).
- Use `CmdNone` to free a key before reusing it elsewhere.
- Bind `CmdCommandPaletteFavorites` / `CmdCommandPaletteTOC`, not `CmdCommandPalette $` / `CmdCommandPalette %` (see escaping below).

## Format of the `Key` value

- just a key (such as `a`, `Z`, or `5`), i.e. the letters `a` to `z` and `A` to `Z`, and the numbers `0` to `9`
- modifiers + key. Modifiers are `Shift`, `Alt`, `Ctrl`, and `AltGr` (also `RAlt` / `RightAlt`), e.g. `Alt + F1`, `Ctrl + Shift + Y`, or `AltGr + Return`. On Windows, `AltGr` is the same as `Ctrl + Alt`
- special keys (e.g. `Alt + F3`):
  - `F1` - `F24`
  - `numpad0` - `numpad9` : `0` to `9` on a numerical keyboard
  - `Delete`, `Backspace`, `Insert`, `Home`, `End`, `Escape`
  - `Left`, `Right`, `Up`, `Down` for arrow keys
  - full list of [special keys](https://github.com/sumatrapdfreader/sumatrapdf/blob/master/src/Accelerators.cpp#L14)
- without modifiers, case matters, i.e. `a` and `A` are different
- with modifiers, use `Shift` to select uppercase, i.e. `Alt + a` is the same as `Alt + A`; use `Alt + Shift + A` for uppercase `A`

## Escaping in settings values

String values in the advanced settings file use `$` as an escape character. Write a literal `$` as `$$`. A lone `$` at the end of a value is a trailing-whitespace marker, not a dollar sign.

This matters for `CmdCommandPalette` mode arguments: use `CmdCommandPaletteFavorites` (or `CmdCommandPaletteTOC` for table of contents) instead of `CmdCommandPalette $` / `CmdCommandPalette %` when binding shortcuts.

## Commands

See the [full list of commands](Commands.md) ([or in the source code](https://github.com/sumatrapdfreader/sumatrapdf/blob/master/src/Commands.h#L9)).

## See also

- [Commands](Commands.md) — command ids to bind
- [Customize toolbar](Customize-toolbar.md) — buttons via `ToolbarText` / `ToolbarSvgIcon`
- [Command Palette](Command-Palette.md) — where `Name`d shortcuts show up
- [Tabs and windows](Tabs-and-windows.md) — tab switching keys
- [Advanced settings](Advanced-options-settings.md) — all settings


---

<!-- Commands.md -->

# Commands

You can control SumatraPDF with commands:

- use [command palette](Command-Palette.md) (`Ctrl + K`) to invoke a command by its description
- [customize a keyboard shortcut](Customize-keyboard-shortcuts.md) to invoke a command by its id
- **ver 3.5+:** [send a command via DDE](DDE-Commands.md) e.g. `[CmdClose]` to invoke `Close Document` command
- **ver 3.6+:** some commands [accept arguments](Commands.md#commands-with-arguments)

:search:

## File

```commands
Command IDs,Keyboard shortcuts,Command Palette,Notes
CmdClose,"Ctrl + W, Ctrl + F4",Close Document,
CmdCloseCurrentDocument,q,Close Current Document,
CmdCommandPalette,Ctrl + K,Command Palette,
CmdCommandPaletteTOC,Shift + F12,Command Palette: Table Of Contents,"Jump to a table of contents entry of the current document, ver 3.7+"
CmdCommandPaletteFavorites,,Command Palette: Favorites,"Jump to a favorite, ver 3.7+"
CmdDuplicateInNewWindow,Shift + Ctrl + N,Open Current Document In New Window,
CmdDuplicateInNewTab,,Open Current Document In New Tab,ver 3.6+
CmdExit,Ctrl + Q,Exit Application,
CmdMoveFrameFocus,F6,Move Frame Focus,
CmdNewWindow,Ctrl + N,Open New SumatraPDF Window,
CmdOpenFile,Ctrl + O,Open File...,"uses the Windows file picker or Navigate Files in Folder according to the `FilePicker` advanced setting (empty/os = Windows, sumatrapdf = in-app), ver 3.7+"
CmdOpenFileNoHistory,,Open File Without History...,"same picker as Open File, but the document is not added to File History or Windows Recent Documents (fixes #6121), ver 3.7+"
CmdOpenFileWithOSFilePicker,,Open File With Windows File Picker...,"always the standard Windows multi-select file open dialog, ver 3.7+"
CmdOpenFileWithSumatraFilePicker,,Open File With SumatraPDF File Picker...,"always the in-app Navigate Files in Folder window, ver 3.7+"
CmdToggleFilePicker,,SumatraPDF File Picker,"checkbox under File / Open; toggles `FilePicker` empty/os ↔ sumatrapdf, ver 3.7+"
CmdToggleBoolSetting,,Toggle Boolean Setting,"in the Command Palette, lists boolean advanced settings; Enter or a click toggles one and closes. Custom shortcuts: `CmdToggleBoolSetting <SettingName>` (case-insensitive leaf or dotted path), e.g. `Fullscreen.ShowMenubar` (fixes #5912), ver 3.7+"
CmdFixDefaultApp,,Fix Default App For Extension,"`CmdFixDefaultApp .pdf` opens the OS dialog to set the default app for that extension; used by the home-page bottom bar when Sumatra is no longer the default, ver 3.7+"
CmdFileHistory,,Open Recent File,"`CmdFileHistory <path>` opens that file; used for the recent files listed in the File menu, each of which carries its own path, ver 3.7+"
CmdFavorite,,Go to Favorite,"`CmdFavorite <path> page=<page>` goes to that favorite; used for the favorites listed in the Favorites menu, each of which carries its own file path and page, ver 3.7+"
CmdOpenNextFileInFolder,Shift + Ctrl + Right,Open Next File In Folder,
CmdNavigateFilesInFolder,Shift + Ctrl + Up,Navigate Files in Folder,"directory browser for openable files in the current file's folder (stays open; Enter/double-click replaces the current tab, Ctrl+Enter/Ctrl+double-click switches to the tab already showing the file or opens a new tab, Alt+Up or Backspace goes to the parent directory (from a drive root: to Home), Alt+Left and Alt+Right go back and forward through the folders visited, Home lists drives and Explorer's Quick access, the search field (Ctrl+F, or just start typing) filters the list the way the command palette matches, clicking the folder path edits it in place (Enter goes to that directory or to a file's directory with the file selected, Esc or an invalid path restores it), Del moves the selected file to the recycle bin, F5 re-reads the directory); also used when `FilePicker = sumatrapdf`; also listed in the command palette as `Browse Files In Folder...`, ver 3.7+"
CmdOpenPrevFileInFolder,Shift + Ctrl + Left,Open Previous File In Folder,
CmdOpenSelectedDocument,,Open Selected Document,
CmdPinSelectedDocument,,Pin Selected Document,
CmdPrint,Ctrl + P,Print Document...,
CmdProperties,Ctrl + D,Document Properties...,
CmdReloadDocument,r,Reload Document,
CmdRenameFile,F2,Rename File...,
CmdReopenLastClosedFile,Shift + Ctrl + T,Reopen Last Closed,
CmdSaveAs,Ctrl + S,Save File As...,
CmdToggleCursorPosition,m,Toggle Cursor Position,
CmdShowInFolder,,Show File In Folder...,"Explorer (selects the file), or Navigate Files in Folder when FilePicker = sumatrapdf, ver 3.7+"
CmdToggleBookmarks,F12,Toggle Bookmarks,
CmdToggleThumbnails,,Toggle Thumbnails,"shows or hides the sidebar's Thumbnails view, ver 3.7+"
CmdToggleTableOfContents,,Toggle Table Of Contents,ver 3.6+
CmdCollapseAll,,Collapse All,"Bookmarks: collapse the outline; if there is only one top-level entry with children, expand it one level (Word-style TOC), ver 3.7+"
CmdExpandAll,,Expand All,
CmdExpandToCurrentPage,,Expand TOC to Current Page,"In the Bookmarks (table of contents) sidebar, expand the tree down to the entry for the current page and select it, ver 3.7+"
CmdAutoGenerateTOC,,Generate Table Of Contents,"For a PDF without an outline, build Bookmarks from numbered headings in the text and show them; the AutoGenerateTOC setting does this on open, ver 3.7+"
CmdTocExpandToLevel1,,Bookmarks: Expand to Level 1,"Collapse the Bookmarks tree so only top-level entries are visible (context menu), ver 3.7+"
CmdTocExpandToLevel2,,Bookmarks: Expand to Level 2,"Expand top-level Bookmarks once (context menu), ver 3.7+"
CmdTocExpandToLevel3,,Bookmarks: Expand to Level 3,"Expand Bookmarks two levels deep (context menu), ver 3.7+"
CmdTocCollapseSameLevel,,Bookmarks: Collapse Same Level,"Collapse all Bookmarks siblings of the selected/clicked entry (same nesting level), ver 3.7+"
CmdOpenEmbeddedPDF,,Open Embedded PDF,
CmdSaveEmbeddedFile,,Save Embedded File...,
CmdCreateShortcutToFile,,Create .lnk Shortcut,
CmdSelectAll,Ctrl + A,Select All,
CmdSelectCurrentPage,,Select Current Page,"selects the text of the current page only; Selection menu and selection context menu, ver 3.7+"
CmdExtendSelectionCharLeft,,Extend Selection One Character Left,"ver 3.7+, no default shortcut; grows or shrinks the existing text selection (see below)"
CmdExtendSelectionCharRight,,Extend Selection One Character Right,"ver 3.7+, no default shortcut; grows or shrinks the existing text selection (see below)"
CmdExtendSelectionWordLeft,,Extend Selection One Word Left,"ver 3.7+, no default shortcut; grows or shrinks the existing text selection (see below)"
CmdExtendSelectionWordRight,,Extend Selection One Word Right,"ver 3.7+, no default shortcut; grows or shrinks the existing text selection (see below)"
CmdCopyComment,,Copy Comment,
CmdShowAnnotationText,,Show Comment,"opens a read-only card with the annotation's whole text; also on a left click on the annotation, ver 3.7+"
CmdCopyImage,,Copy Image,
CmdCopyLinkTarget,,Copy Link Target,
CmdCopySelection,"Ctrl + C, Ctrl + Insert",Copy Selection,"in Edit PDF mode with an annotation selected, copies that annotation instead of text"
CmdCopySelectionAsImage,,Copy Selection As Image,"copy a rectangular selection as an image, ver 3.7+"
CmdSaveSelectionAsImage,,Save As Image...,"save a rectangular (Ctrl+drag) selection as PNG, JPEG or BMP at a chosen DPI, independent of the current zoom, ver 3.7+ (fixes #6127)"
CmdPrintSelection,,Print Selection...,"open the print dialog with Selection pre-selected to print only the rectangular (Ctrl+drag) selection; also in the selection context menu, ver 3.7+ (fixes #6222)"
CmdSearchGoogleLens,,Search with Google Lens,"opens the selection, image under the cursor, or current page in Google Lens, ver 3.7+"
CmdSearchGoogleLensPage,,Search Page with Google Lens,"current page (or the page under the cursor from the context menu), ver 3.7+"
CmdSearchGoogleLensImage,,Search Image with Google Lens,"image under the cursor, ver 3.7+"
CmdCopyFilePath,,Copy File Path,ver 3.5+
CmdCopyLocationToClipboard,,Copy Location To Clipboard,"copies the current view (page, zoom, scroll position and file path) to the clipboard as command-line arguments, ver 3.7+"
CmdDeleteFile,,Delete Currently Opened File, ver 3.6+
CmdDeleteFileAndOpenNext,,Delete File And Open Next,"moves the current file to the Recycle Bin after the next file opens successfully, ver 3.7+"
CmdShowGeneratedHTML,,Show Generated HTML,"available for Markdown files; saves the generated HTML to a temporary .html file and opens it in Notepad, ver 3.7+"
```

## Search

```commands
Command IDs,Keyboard shortcuts,Command Palette,Notes
CmdFindFirst,Ctrl + F,Find,
CmdFindToggleMatchCase,,Find: Toggle Match Case,
CmdFindToggleMatchWholeWord,,Find: Toggle Match Whole Word,
CmdFindNext,F3,Find Next,
CmdFindNextSel,Ctrl + F3,Find Next Selection,
CmdFindPrev,Shift + F3,Find Previous,
CmdFindPrevSel,Shift + Ctrl + F3,Find Previous Selection,
```

## Viewing

```commands
Command IDs,Keyboard shortcuts,Command Palette,Notes
CmdBookView,"Ctrl + 8, Ctrl + Numpad 8",Book View,
CmdFacingView,"Ctrl + 7, Ctrl + Numpad 7",Facing View,
CmdInvertColors,Shift + I,Invert Colors,was `i` before 3.6
CmdToggleGrayscale,,Toggle Grayscale,"ver 3.7+, render document pages in grayscale; saved in `FixedPageUI.Grayscale`"
CmdRotateLeft,"[, Shift + Ctrl + Subtract",Rotate Left,
CmdRotateRight,"], Shift + Ctrl + Add",Rotate Right,
CmdSinglePageView,"Ctrl + 6, Ctrl + Numpad 6",Single Page View,
CmdToggleContinuousView,c,Toggle Continuous View,
CmdSelectTextViaKeyboard,F7,Select Text With Keyboard,"ver 3.7+, caret browsing: puts a text caret in the page which the arrow keys move; Shift + arrows extend the selection, v toggles visual mode (arrows select without Shift), Home/End go to the line ends, Ctrl + Home/End to the document ends, Ctrl + arrows move by word, Ctrl + C or y copies, Esc or F7 leaves the mode. Not available for documents with no extractable text (fixes #4684, #4116)"
CmdToggleKeyboardLinkFollowing,Shift + F,Follow Link With Keyboard,"ver 3.7+, labels visible links with Vimium-style letter hints; type a hint to follow its link, Esc or Shift + F again leaves the mode. Multi-letter hints are used when needed. Not available for comic books, image folders and images (fixes #2629)"
CmdToggleFullscreen,"f, Shift + Ctrl + L, F11",Toggle Fullscreen,
CmdToggleMangaMode,,Toggle Manga Mode,"Right-to-left facing/book layout for fixed-page documents; before 3.7 this was limited to comic books"
CmdToggleUniformPageWidth,,Toggle Uniform Page Width,"At percentage zoom levels, scales every page to the width page 1 has at that zoom; remembered per document (fixes #5512)"
CmdToggleTrimEmptyMargins,,Toggle Trim Empty Margins,"Trims empty margins around page content from display on demand, ver 3.7+"
CmdToggleFreePan,,Toggle Free Pan,"Lets the view go past the page edges by half a window, so any part of a page (a corner of a drawing) can be brought to the center of the screen; remembered per document, ver 3.7+"
CmdToggleMenuBar,F9,Toggle Menu Bar,
CmdTogglePageInfo,i,Show / Hide Current Page Number,was Shift + i before 3.6
CmdTogglePageBoxes,,Toggle Page Boxes,"ver 3.7+, outlines the PDF MediaBox, CropBox, BleedBox, TrimBox and ArtBox on each page (only boxes that page actually has) and labels them. Palette and Debug menu. No default shortcut (fixes #814)"
CmdChangeScrollbar,,Change Scrollbar,"Opens dialog to choose scrollbar mode (windows/smart/overlay/hidden)"
CmdChangeBackgroundColor,,Change Background Color,"Opens color picker to change document background color"
CmdChangeEbookSettings,,Change eBook Settings,"ver 3.7+, opens a dialog for the font, size, line spacing and CSS of a reflowable document (EPUB, MOBI, FB2, ...), for that document only or for all ebooks. Not shown for fixed-page documents. See Customize-eBook-UI.md"
CmdToggleToolbar,F8,Toggle Toolbar,
CmdAIChatWithClaudeCode,,AI Chat with document using Claude Code,"Toggle Claude Code chat sidebar, ver 3.7+. See AI-Chat-with-document.md"
CmdAIChatWithGrokBuild,,AI Chat with document using Grok Build,"Toggle Grok Build chat sidebar, ver 3.7+. See AI-Chat-with-document.md#grok-build"
CmdAIChatWithOpenAICodex,,AI Chat with document using OpenAI Codex,"Toggle OpenAI Codex chat sidebar, ver 3.7+. See AI-Chat-with-document.md#openai-codex"
CmdAIChatWithAntiGravity,,AI Chat with document using Antigravity,"Toggle Antigravity chat sidebar, ver 3.7+. See AI-Chat-with-document.md#antigravity"
CmdTranslateSelectionWithAntiGravity,,Translate Selection with Antigravity,"Translate selected text with Antigravity CLI, ver 3.7+"
CmdChangeTheme,,Change Theme...,"ver 3.7+, opens a dialog to pick a UI theme (including **Follow Windows**, which automatically tracks Windows light/dark app mode) and optionally how document colors follow the theme (`DocumentColorsFollowTheme`)"
CmdNavigateThumbnail,,Navigate Thumbnails,"opens a thumbnail grid for the current document; arrow keys and the mouse select a page, Enter or double-click opens it, and Esc closes the grid"
CmdToggleLightDarkTheme,,Toggle Light/Dark Theme,"ver 3.7+, switches between the last used light and dark themes (see `LastLightTheme` / `LastDarkTheme` advanced settings)"
CmdToggleEngineeringDrawingEnhance,,Toggle Engineering Drawing Enhancement,"ver 3.7+, toggles CAD/engineering-drawing line enhancement for the current PDF (see [CAD / Engineering Drawings](CAD-Engineering-Drawings.md))"
CmdSetDocumentColorsFollowTheme,,Set Document Colors Follow Theme,"ver 3.7+, opens a dialog to pick how MuPDF-rendered documents follow the UI theme (`DocumentColorsFollowTheme`: off, smart, legacy)"
CmdTogglePreservePdfImages,,Toggle Preserve PDF Image Colors in Dark Mode,"ver 3.7+, session-only toggle of image preservation on inverted pages"
CmdToggleLinks,,Toggle Show Links,"Toggle drawing blue rectangle around links, ver 3.6+"
CmdToggleHighlightFormFields,,Toggle Highlight Form Fields,"ver 3.7+, toggles pale-blue highlight of empty fillable PDF form fields (`HighlightFormFields`; default on) (fixes #5966)"
CmdToggleTransparencyGrid,,Toggle Transparency Grid,"ver 3.7+, checkerboard under the page so transparent PDFs (white art on a hole) are visible, like Acrobat's Transparency Grid. Session-only, not saved (fixes #1809)"
CmdTogglePageGrid,,Toggle Page Grid,"ver 3.7+, dotted major/minor graph paper on PDF, EPUB, and other paginated document pages; not comics. Session-only visibility; spacing, origin, color and style are `FixedPageUI.PageGrid` (fixes #4398)"
CmdConfigurePageGrid,,Configure Page Grid...,"ver 3.7+, dialog to set page-grid units, spacing, subdivisions, origin, color and line style (dots / dotted / solid), like PDF-XChange Measurement. Reset to defaults restores the shipped appearance settings; Show Grid is the session toggle"
CmdToggleDisableLinks,,Toggle Disable Links,"ver 3.7+, palette-only; toggles `DisableLinks` so clicks, hover and keyboard following ignore document links (fixes #5939)"
CmdToggleHoverPreview,,Toggle Citation Hover Preview,"ver 3.7+, palette-only; toggles the citation/reference hover popup (`CitationHoverDelay`: 300 ms when on, -1 when off)"
```

## Tabs

```commands
Command IDs,Keyboard shortcuts,Command Palette,Notes
CmdCloseAllTabs,,Close All Tabs,ver 3.6+
CmdCloseTabsToTheLeft,,Close Tabs To The Left,ver 3.6+
CmdCloseTabsToTheRight,,Close Tabs To The Right,ver 3.6+
CmdGoToHomePage,,Go To Home Page,"switches to the Home tab; adds it as the first tab when `NoHomeTab` removed it (fixes #6228), ver 3.7+"
CmdCloseOtherTabs,,Close Other Tabs,ver 3.6+
CmdNextTab,Ctrl + PageUp,Next Tab,
CmdPrevTab,Ctrl + PageDown,Previous Tab,
CmdMoveTabRight,Ctrl + Shift + PageUp,Move Tab Right,ver 3.6+
CmdMoveTabLeft,Ctrl + Shift + PageDown,Move Tab Left,ver 3.6+
CmdNextTabSmart,Ctrl + Tab,Smart tab Switch,ver 3.6+
CmdPrevTabSmart,Ctrl + Shift + Tab,Smart tab Switch,ver 3.6+
CmdTabGroupSave,,Save Tab Group,ver 3.7+
CmdTabGroupRestore,,Restore Tab Group,ver 3.7+
```

## Navigation

```commands
Command IDs,Keyboard shortcuts,Command Palette,Notes
CmdScrollUp,"k, Up",Scroll Up,
CmdScrollDown,"j, Down",Scroll Down,
CmdScrollLeft,"h, Left",Scroll Left,
CmdScrollRight,"l, Right",Scroll Right,
CmdScrollUpHalfPage,Shift + Up,Scroll Up By Half Page,
CmdScrollDownHalfPage,Shift + Down,Scroll Down By Half Page,
CmdStartAutoScroll,,Start Auto-Scroll,"Start (or stop) middle-click-style auto-scroll anchored at the cursor, without needing a middle mouse button; move the cursor away from the anchor to scroll. Invoke again (or middle-click) to stop, ver 3.7+"
CmdToggleAutomaticallyScroll,Ctrl + Shift + H,Automatically Scroll,"Hands-free continuous pan (Acrobat-style). A bar at the bottom shows speed and Pause / Stop / Reverse. While it is on: Up/Down change speed, 0-9 set it, minus reverses, Left/Right turn the page, Space pauses, Esc stops. Distinct from CmdStartAutoScroll, ver 3.7+"
CmdAutomaticallyScrollFaster,,Automatically Scroll Faster,"Increase Automatically Scroll speed (no default shortcut; Up/Down while scrolling also change speed), ver 3.7+"
CmdAutomaticallyScrollSlower,,Automatically Scroll Slower,"Decrease Automatically Scroll speed, ver 3.7+"
CmdToggleReadingBar,,Reading Bar,"Toggle a horizontal reading bar on the page (highlight band, or invert to dim the rest). Drag to move, drag the top/bottom edge to resize, hover for a close button. Ctrl+Up/Down move it, Ctrl+Shift+Up/Down change height, Esc hides it. Settings in ReadingBar. Also Focus on the Automatically Scroll bar. ver 3.7+"
CmdToggleReadingBarInvert,,Reading Bar Invert,"Toggle invert (screen mask) for the reading bar; remembered in ReadingBar.Invert. ver 3.7+"
CmdScrollUpPage,"Ctrl + Up, PageUp, Shift + Return, Shift + Space",Scroll Up By Page,
CmdScrollDownPage,"Ctrl + Down, PageDown, Return, Space",Scroll Down By Page,
CmdScrollLeftPage,Shift + Left,Scroll Left By Page,
CmdScrollRightPage,Shift + Right,Scroll Right By Page,
CmdGoToFirstPage,"Ctrl + Home, Home",First Page,
CmdGoToLastPage,"Ctrl + End, End",Last Page,
CmdGoToPrevPage,"p",Previous Page,
CmdGoToNextPage,"n",Next Page,
CmdGoToPage,"g, Ctrl + G",Go to Page...,
CmdNavigateBack,"Alt + Left, Backspace",Navigate Back,
CmdNavigateForward,"Alt + Right, Shift + Backspace",Navigate Forward,
```

## Favorites

```commands
Command IDs,Keyboard shortcuts,Command Palette,Notes
CmdFavoriteAdd,Ctrl + B,Add Favorite,
CmdFavoriteDel,,Delete Favorite,
CmdFavoriteToggle,,Toggle Favorites,
CmdFavoriteShowInTab,,Show Favorites in Tab,"Full-window Favorites tab (independent of sidebar), ver 3.7+"
CmdToggleFavoritesSort,,Sort Favorites By Name,"Toggle alphabetical order within each file (also Favorites tree context menu checkbox); maps to `SortFavoritesByName`, ver 3.7+"
CmdGoToNextFavorite,,Go to Next Favorite,
CmdGoToPrevFavorite,,Go to Previous Favorite,
```

## Presentation

```commands
Command IDs,Keyboard shortcuts,Command Palette,Notes
CmdTogglePresentationMode,"Ctrl + L, Shift + F11, F5",View: Presentation Mode,
CmdPresentationBlackBackground,.,Presentation Black Background,
CmdPresentationWhiteBackground,w,Presentation White Background,
CmdToggleLaserPointer,,Toggle Laser Pointer,"ver 3.7+, replaces the mouse cursor over the document with a glowing red laser dot for pointing things out. No default shortcut, assign your own. Stays visible in presentation mode (the cursor doesn't auto-hide while it's on)"
```

## Annotations

```commands
Command IDs,Keyboard shortcuts,Command Palette,Notes
CmdInsertImage,,Insert Image...,"Pick an image and stamp it onto the current page as a stamp annotation - a signature, say (fixes #1744), ver 3.7+"
CmdSignWithImage,,Sign With Image,"ver 3.7+, stamps the Annotations.SignatureImage image on the page without asking; asks for an image if it isn't set"
CmdInsertTextSnippet,,Insert Text Snippet,"ver 3.7+, inserts a TextSnippets entry as a free text annotation. Each snippet is its own command, named after it; the bare command does nothing"
CmdCreateAnnotCaret,,Create Caret Annotation,
CmdCreateAnnotCircle,,Create Circle Annotation,
CmdFindAnnotation,,Find Annotation,"opens the floating annotation list, where you can filter the document's annotations and jump to one, ver 3.7+"
CmdCreateAnnotFileAttachment,,Create File Attachment Annotation,"click to place, like Stamp/Caret; Esc cancels, ver 3.7+"
CmdCreateAnnotFreeText,,Create Free Text Annotation,
CmdCreateAnnotHighlight,"a, A",Create Highlight Annotation,"`A` (`Shift + A`) is `CmdCreateAnnotHighlight openedit`: also turns on Edit PDF mode"
CmdAnnotationHighlightBrush,,Highlighter,"a mode: every text selection is highlighted, until Esc or Enter. Text already selected is highlighted right away, ver 3.7+"
CmdCreateAnnotInk,,Create Ink Annotation,"drag to paint; release commits the stroke and leaves the tool on. Esc or closing the hint leaves the tool, ver 3.7+"
CmdCreateAnnotLine,,Create Line Annotation,
CmdCreateAnnotLink,,Create Link Annotation,
CmdCreateAnnotPolygon,,Create Polygon Annotation,
CmdCreateAnnotPolyLine,,Create Poly Line Annotation,
CmdCreateAnnotPopup,,Create Popup Annotation,
CmdCreateAnnotRedact,,Create Redact Annotation,"marks selected text, or a dragged rectangle, for removal; content is not deleted until Apply Redactions, ver 3.7+"
CmdApplyRedactions,,Apply Redactions,"permanently deletes content marked with the Redact tool, after a confirmation; save a copy afterwards, ver 3.7+"
CmdCreateAnnotSquare,,Create Square Annotation,
CmdCreateAnnotSquiggly,,Create Squiggly Annotation,
CmdCreateAnnotStamp,,Create Stamp Annotation,
CmdCreateAnnotImageFromClipboard,,Create Image Annotation From Clipboard,
CmdCreateAnnotStrikeOut,,Create Strike Out Annotation,
CmdCreateAnnotText,,Create Text Annotation,
CmdCreateAnnotUnderline,"u, U",Create Underline Annotation,"`U` (`Shift + U`) is `CmdCreateAnnotUnderline openedit`: also turns on Edit PDF mode"
CmdUndo,Ctrl + Z,Undo,"ver 3.7+, takes back the last change to the PDF (annotations, form fields, applied redactions). One gesture is one step: creating, pasting or resizing an annotation comes back in a single Undo. Disabled when there is nothing to undo; in a text box Ctrl + Z is the text box's undo"
CmdRedo,Shift + Ctrl + Z,Redo,"ver 3.7+, re-applies the change Undo took back. Disabled when there is nothing to redo"
CmdCutAnnotation,Ctrl + X,Cut Annotation,"ver 3.7+, copies the annotation under the cursor (or the selected one) and deletes it when the copy is pasted; in a text box Ctrl + X is the text box's cut"
CmdCopyAnnotation,Ctrl + C,Copy Annotation,"ver 3.7+, copies the selected annotation in Edit PDF mode; Ctrl + C is CmdCopySelection and copies the annotation when one is selected. Only annotations that can be moved can be copied, so text markup (highlight, underline, squiggly, strike-out) and file attachments are excluded"
CmdPasteAnnotation,Ctrl + V,Paste Annotation,"ver 3.7+, pastes the copied annotation with its top-left at the mouse and deletes the original if it was cut; Ctrl + V is CmdPasteClipboardImage and pastes the annotation when Edit PDF is on and one has been copied"
CmdDeleteAnnotation,Delete,Delete Annotation,
CmdSaveAnnotations,Shift + Ctrl + S,Save Annotations to existing PDF,
CmdSaveAnnotationsNewFile,,Save Annotations to new PDF,ver 3.6+
CmdSignDocument,,Sign Document...,"digitally sign a PDF with a certificate from the Windows store or a .pfx / .p12 file; choose which name/date/labels to draw and optionally a PNG/JPEG; a new signature is placed by clicking or dragging on the page, ver 3.7+"
CmdDiscardChanges,,Discard Changes,"reloads the document from disk, discarding unsaved annotations and form changes; also on the tab context menu when there are unsaved changes, ver 3.7+ (renamed from `CmdDiscardAnnotations`)"
CmdShowAnnotations,,Show Annotations,"ver 3.6+, for current document"
CmdHideAnnotations,,Hide Annotations,"ver 3.6+, for current document"
CmdToggleShowAnnotations,,Toggle Showing Annotations,"ver 3.6+, for current document"
CmdToggleEditPDF,,Toggle Edit PDF,"shows or hides Edit PDF mode (the annotation-tools row), ver 3.7+ (renamed from `CmdTogglePdfAnnotationsToolbar`)"
```

## Zoom

```commands
Command IDs,Keyboard shortcuts,Command Palette,Notes
CmdToggleZoom,z,Toggle Zoom,
CmdZoomActualSize,"Ctrl + 1, Ctrl + Numpad 1",Zoom: Actual Size,
CmdZoomCustom,Ctrl + Y,Zoom: Custom...,
CmdZoomFitContent,"Ctrl + 3, Ctrl + Numpad 3",Zoom: Fit Content,
CmdZoomFitVisible,,Zoom: Fit Visible,"ver 3.7+, fits the width of the page content (blank margins cropped, 2pt of them kept) to the window and scrolls vertically, like Fit Width without the margins; Foxit calls it Fit Visible (fixes #6241)"
CmdZoomToSelection,"Ctrl + 4, Ctrl + Numpad 4",Zoom: To Selection,"ver 3.7+, zooms so the current selection (Ctrl + drag rectangle or selected text) fills the window and centers it; the selection is kept so it can still be copied, and Navigate Back (Alt + Left) returns to the view it was zoomed from. Also in the Zoom menu and the right-click menu (fixes #1699)"
CmdZoomShrinkToFit,,Zoom: Shrink To Fit,"Shows at 100% if page is smaller than view area, otherwise fits page"
CmdZoomFitPage,"Ctrl + 0, Ctrl + Numpad 0",Zoom: Fit Page,
CmdZoomFitPageAndSinglePage,,Zoom: Fit Page and Single Page,
CmdZoomFitWidth,"Ctrl + 2, Ctrl + Numpad 2",Zoom: Fit Width,
CmdZoomFitHeight,,Zoom: Fit Height,"Scale so the page fills the window height (may scroll horizontally); useful for landscape pages on portrait screens (fixes #1714), ver 3.7+"
CmdZoomFitByOrientation,,Zoom: Fit Page or Width by Orientation,"Fit width when the view is wider than tall (landscape), fit page otherwise (portrait); re-evaluated as the window/screen is resized or rotated"
CmdZoomFitWidthAndContinuous,,Zoom: Fit Width And Continuous,
CmdZoomIn,Ctrl + Add,Zoom In,
CmdZoomOut,Ctrl + Subtract,Zoom Out,
CmdZoom100,,Zoom: 100%,
CmdZoom12_5,,Zoom: 12.5%,
CmdZoom125,,Zoom: 125%,
CmdZoom150,,Zoom: 150%,
CmdZoom1600,,Zoom: 1600%,
CmdZoom200,,Zoom: 200%,
CmdZoom25,,Zoom: 25%,
CmdZoom3200,,Zoom: 3200%,
CmdZoom400,,Zoom: 400%,
CmdZoom50,,Zoom: 50%,
CmdZoom6400,,Zoom: 6400%,
CmdZoom8_33,,Zoom: 8.33%,
CmdZoom800,,Zoom: 800%,
```

## File information / conversion

```commands
Command IDs,Keyboard shortcuts,Command Palette,Notes
CmdPdfShowInfo,,Show PDF Info,shows information about currently opened PDF file
CmdDocumentShowOutline,,Show Document Outline,shows the outline (table of contents) of currently opened document
CmdPdfBake,,Bake PDF File,bakes interactive form and annotation content into static graphics; saves to a new PDF file and opens it
CmdDocumentExtractText,,Extract Text From Document,"extract text from document pages to a .txt file, with configurable page ranges, ver 3.7+"
```

## External app

```commands
Command IDs,Keyboard shortcuts,Command Palette,Notes
CmdOpenWithExplorer,,Open Directory In Explorer,ver 3.5+
CmdOpenWithDirectoryOpus,,Open Directory In Directory Opus,ver 3.5+
CmdOpenWithTotalCommander,,Open Directory In Total Commander,ver 3.5+
CmdOpenWithDoubleCommander,,Open Directory In Double Commander,ver 3.5+
CmdOpenWithAcrobat,,Open in Adobe Acrobat,
CmdOpenWithFoxit,,Open in Foxit Reader,
CmdOpenWithFoxitPhantom,,Open in Foxit Phantom,
CmdOpenWithHtmlHelp,,Open in Microsoft HTML Help,
CmdOpenWithPdfDjvuBookmarker,,Open in Pdf&Djvu Bookmarker,
CmdOpenWithPdfXchange,,Open in PDF-XChange,
CmdOpenWithXpsViewer,,Open in Microsoft Xps Viewer,
CmdTranslateSelection,,Translate Selection...,"ver 3.7+, opens a dialog to translate the selected text (edit text, pick languages and engine); used from the selection context menu and command palette"
CmdTranslateSelectionWithDeepL,,Translate Selection with DeepL,
CmdTranslateSelectionWithGoogle,,Translate Selection with Google,
CmdTranslateSelectionWithGrokBuild,,Translate Selection with Grok Build,"ver 3.7+, requires the Grok Build CLI"
CmdTranslateSelectionWithClaudeCode,,Translate Selection with Claude Code,"ver 3.7+, requires the Claude Code CLI"
CmdTranslateSelectionWithOpenAICodex,,Translate Selection with OpenAI Codex,"ver 3.7+, requires the OpenAI Codex CLI"
CmdSearchSelectionWithBing,,Search Selection with Bing,
CmdSearchSelectionWithGoogle,,Search Selection with Google,
CmdSearchSelectionWithWikipedia,,Search Selection with Wikipedia,ver 3.6+
CmdSearchSelectionWithGoogleScholar,,Search Selection with Google Scholar,ver 3.6+
CmdSendByEmail,,Send Document By Email...,
CmdInvokeInverseSearch,,Invoke Inverse Search,ver 3.6+

```

## System

```commands
Command IDs,Keyboard shortcuts,Command Palette,Notes
CmdOpenSettingsFile,,Open Advanced Settings File...,"Opens the settings file in the text editor associated with .txt files; menu `Settings` / `Open Advanced Settings File...`, ver 3.7+"
CmdAdvancedSettings,,Advanced Settings...,"ver 3.7+, opens a dialog for viewing and editing the advanced settings: filter by name, click a setting to toggle / pick / edit its value, then Save; `CmdAdvancedOptions` in a shortcut definition still means this command; also listed in the command palette as `Advanced Options...`"
CmdChangeLanguage,,Change Language...,
CmdCheckUpdate,,Check For Updates,
CmdClearHistory,,Clear History,Clears history of opened files (for recently opened list in home page)
CmdRemoveDeletedFilesFromHistory,,Remove Deleted Files From History,"ver 3.7+, removes from history entries for files that no longer exist on disk"
CmdDeleteCachedFiles,,Delete Cached Files,"ver 3.7+, deletes local copies of comic book archives cached under cbx-cache when opened from a network drive"
CmdContributeTranslation,,Contribute Translation,
CmdForgetSelectedDocument,,Remove Selected Document From History,
CmdListPrinters,,List Printers,ver 3.7+
CmdOptions,,Settings...,
CmdSetInverseSearch,,Set Inverse Search Command Line,"ver 3.7+, opens a dialog to set the SyncTeX inverse-search command and enables TeX enhancements"
CmdScreenshot,,Take Screenshot,"ver 3.7+, can be registered as a global hotkey via Shortcuts entry (e.g. Key = Global PrtSc) or with the Set Screenshot Hotkey command"
CmdCropImage,,Crop Image,ver 3.7+
CmdResizeImage,,Resize Image,ver 3.7+
CmdSaveImage,,Save Image,"Save image from context menu, ver 3.7+"
CmdConvertImageToPdf,,Convert Page To PDF,"Save the image under the cursor (or the current image document page) as a new PDF via the image editor, ver 3.7+"
CmdConvertToPDF,,Convert To PDF,"Convert a comic book, image folder, or single image to a multi-page PDF (dialog picks a unique .pdf path), ver 3.7+ (fixes #4118, #5532). Docs: Convert-comics-to-PDF.md, Convert-images-to-PDF.md"
CmdConvertPdfToImages,,Convert PDF to Images...,"Render PDF pages to PNG, JPEG or BMP (format drop-down updates the extension). Destination path is a template: <N> is replaced by the page number. Pages: current, all, or a custom range. PNGs are optimized in the background, ver 3.7+ (fixes #5991). Docs: Convert-PDF-to-images.md"
CmdPasteClipboardImage,Ctrl + V,Paste Image From Clipboard,"Paste image from clipboard and open it, ver 3.7+. In Edit PDF mode, pastes a copied annotation at the mouse instead"
CmdShowErrors,,Show Errors,"Show mupdf warnings/errors in right-click context menu, ver 3.7+"
CmdShowLog,,Show Logs,
```

## Help

```commands
Command IDs,Keyboard shortcuts,Command Palette,Notes
CmdHelpOpenManual,F1,Help: Manual,
CmdHelpOpenKeyboardShortcuts,,Help: Keyboard Shortcuts,
CmdToggleKeyboardHelp,?,Show Keyboard Shortcuts,"Overlay listing the most useful commands by section, each row showing the key it is currently bound to. Press again (or Esc) to close it, ver 3.7+"
CmdHelpAbout,,Help: About SumatraPDF,
CmdHelpOpenManualOnWebsite,,Help: Manual On Website,
CmdHelpVisitWebsite,,Help: SumatraPDF Website,
```

## Misc

```commands
Command IDs,Keyboard shortcuts,Command Palette,Notes
CmdToggleInverseSearch,,Toggle Inverse Search,"temporarily disable TeX inverse search on left mouse click, ver 3.6+"
CmdToggleWindowsPreviewer,,Register / Un-register Windows Previewer,"Only available when SumatraPDF is installed. Registers or un-registers the PDF preview handler for Windows Explorer preview pane, ver 3.7+"
CmdToggleWindowsSearchFilter,,Register / Un-register Windows Search Filter,"Only available when SumatraPDF is installed. Registers or un-registers the PDF search filter for Windows Search indexing, ver 3.7+"
CmdSetTabColor,,Set Tab Color,"Set a custom color for the tab of the current document, available from tab context menu, ver 3.7+"
CmdPdfCompress,,Compress PDF,"Compress a PDF file using aggressive garbage collection and optimization, ver 3.7+"
CmdPdfDecompress,,Decompress PDF,"Decompress a PDF file for easier inspection, ver 3.7+"
CmdPdfDeletePages,,Delete Pages From PDF,"Delete pages from a PDF file using page ranges like 1,3-8,13-N where N is the last page, ver 3.7+"
CmdMergePDF,,Merge PDF...,"Opens the Merge PDF window: add pages of other PDFs, reorder and remove pages by their thumbnails, save over the PDF or as a new one, ver 3.7+"
CmdPdfExtractPages,,Extract Pages From PDF,"Extract pages from a PDF file using page ranges like 1,3-8,13-N where N is the last page, ver 3.7+"
CmdPdfEncrypt,,Encrypt PDF,"Encrypt a PDF file with a password using AES-256 encryption, ver 3.7+"
CmdPdfDecrypt,,Decrypt PDF,"Decrypt an encrypted PDF file, removing password protection, ver 3.7+"
CmdSetScreenshotHotkey,,Set Screenshot Hotkey,"Open dialog to set or remove a global hotkey for taking screenshots, ver 3.7+"
CmdToggleReadAloud,,Toggle Read Aloud,"Read aloud using Windows text-to-speech. Reads the selection if there is one, otherwise from the first visible text through the end of the document. Invoking again pauses reading; invoking when paused continues. Voice is chosen in the Read Aloud Voice submenu and remembered in ReadAloudVoiceId, ver 3.7+"
CmdPauseReadAloud,,Pause Reading,"Pause reading text aloud; resume with CmdContinueReadAloud, ver 3.7+"
CmdContinueReadAloud,,Continue Reading,"Continue reading text aloud from where it was paused, ver 3.7+"
CmdStopReadAloud,,Stop Reading,"Stop reading text aloud and clear the resume position. Always in the Read Aloud menu (disabled when nothing is being read) and in the command palette while a session is active, even when the playback bar is not visible, ver 3.7+"
CmdReadAloudFromTopPage,,Start Reading From Top,"Read from the first visible text in the viewport through the end of the document, ver 3.7+"
CmdReadAloudSelection,,Start Reading Selection,"Read the current text selection aloud, ver 3.7+"
CmdReadAloudFromCursorPosition,,Start Reading From Cursor Position,"Read from the text under the mouse cursor through the end of the document. From the command palette, uses the mouse position from before the palette was opened, ver 3.7+"
CmdToggleToolbarShowReadAloud,,Read Aloud: Show In Toolbar,"Show or hide the Read Aloud buttons in the toolbar; remembered in the `ToolbarShowReadAloud` setting, ver 3.7+"
```

## Debug

```commands
Command IDs,Keyboard shortcuts,Command Palette,Notes
CmdDebugCrashMe,,Debug: Crash Me,
CmdDebugShowNotif,,Debug: Show Notification,
CmdDebugStartStressTest,,Debug: Start Stress Test,
CmdDebugTogglePredictiveRender,,Debug: Toggle Predictive Rendering,
CmdDebugToggleRenderInfo,,Debug: Toggle Render Queue Info,
CmdDebugToggleCacheInfo,,Debug: Toggle Cache Info,
CmdDebugToggleRtl,,Debug: Toggle RTL,
CmdToggleImages,,Toggle Show Images,"Outline the images on the page, like the link outlines. A debug aid: it lasts for the session and is not saved in the settings, ver 3.7+"
CmdDebugShowFitContentArea,,Debug: Show Fit Content Area,"outlines in red the area Fit Content zoom would fit to (whole page if no content box was detected), without changing the zoom, ver 3.7+"
CmdNone,,Do nothing,
```

## Deprecated or internal

```commands
Command IDs,Keyboard shortcuts,Command Palette,Notes
CmdInstallPrereleaseUpdate,,internal,"used by the pre-release update notification link (Update); not for user shortcuts or DDE"
CmdTogglePdfPreviewLogging,,internal,"toggles PDF shell-preview logging for debugging the Windows preview handler; not for normal use"
CmdDebugCorruptMemory,,don't use,
CmdSelectionHandler,,use SelectionHandlers advanced setting instead,
CmdSetTheme,,don't use,
CmdViewWithExternalViewer,,don't use,
CmdSaveAttachment,,don't use,
CmdOpenAttachment,,don't use,
CmdExec,,internal,"runs an external program with optional filter; used internally (e.g. selection handlers), not for normal shortcuts or DDE"
CmdDebugToggleDpiOverride,,internal,"debug builds only: cycles a pretend DPI (125, 150, 75, off) to check how the UI reacts to a DPI change; does nothing in a release build"
```

`CmdFindMatch` is an old name for `CmdFindToggleMatchCase`. It is not a generated command ID, but SumatraPDF still accepts it in old shortcut settings for compatibility.

`CmdTogglePdfAnnotationsToolbar` is an old name for `CmdToggleEditPDF`. SumatraPDF still accepts it in old shortcut and `ToolbarCustomLayout` settings.

# Commands with arguments

**Ver 3.6+:** some commands accept arguments that provide more options when creating [custom keyboard shortcuts](Customize-keyboard-shortcuts.md).

For example:

```
Shortcuts [
    [
        Cmd = CmdCreateAnnotHighlight #00ff00
        Key = a
    ]
]
```

By default, `a` invokes `CmdCreateAnnotHighlight` with the default yellow color.

You can override the `a` shortcut to create a green (`#00ff00`) highlight annotation.

You can create multiple keyboard shortcuts for multiple colors.

Arguments can be strings, numbers, Booleans, or colors (`#rrggbb` or `#aarrggbb` format).

Arguments have names. For example, `CmdCreateAnnotHighlight` has a `color` argument of type color and an optional `copytoclipboard` Boolean argument.

The format for providing arguments is `CmdCreateAnnotHighlight color: #fafafa copytoclipboard: true`.

For Boolean arguments, using the name alone is the same as setting the value to `true`, i.e. `copytoclipboard` is the same as `copytoclipboard: true`.

For default arguments, you can skip the name. For example, `color` is the default `CmdCreateAnnotHighlight` argument, so `CmdCreateAnnotHighlight #fafafa` is the same as `CmdCreateAnnotHighlight color: #fafafa`.

You can combine those rules: `CmdCreateAnnotHighlight #fafafa copytoclipboard` is the same as `CmdCreateAnnotHighlight color: #fafafa copytoclipboard: true`.

## `CmdExtendSelectionCharLeft` and other `CmdExtendSelection*`

**Ver 3.7+**

`CmdExtendSelectionCharLeft`, `CmdExtendSelectionCharRight`, `CmdExtendSelectionWordLeft`, and `CmdExtendSelectionWordRight` move the free end of the current text selection by one character or one word, the way `Shift + Left/Right` and `Ctrl + Shift + Left/Right` do in a text editor. Moving toward the selection's anchor shrinks it, moving away grows it, and the selection continues across page boundaries.

They have no default shortcut because the obvious keys are already taken (`Ctrl + Shift + Left/Right` navigate between files), so assign your own:

```
Shortcuts [
    [
        Cmd = CmdExtendSelectionWordRight
        Key = Ctrl + Shift + Right
    ]
    [
        Cmd = CmdExtendSelectionWordLeft
        Key = Ctrl + Shift + Left
    ]
]
```

The selection can come from anywhere: dragging with the mouse, double-clicking a word, pressing `Ctrl + A`, or using keyboard selection (`F7`). While `F7` keyboard selection is active, these commands move the caret, so it stays at the end of the selection. Without a selection, they do nothing, and they're not available for documents with no extractable text.

## `CmdScrollUp`, `CmdScrollDown`

**Ver 3.6+**

Arguments:

- `n` : default, integer, how many lines to scroll up or down (default: 1)

Use case: if you want to speed up scrolling with the `j` and `k` keys, you can reassign them:

```
Shortcuts [
    [
        Cmd = CmdScrollDown 5
        Key = j
    ]
    [
        Cmd = CmdScrollUp n: 5
        Key = k
    ]
]
```

## `CmdGoToNextPage`, `CmdGoToPrevPage`

**Ver 3.6+**

Arguments:

- `n` : default, integer, how many pages to advance by (default: 1)

Use case: if you want to go forward or back by more than one page.

## `CmdCreateAnnotHighlight` and other `CmdCreateAnnot*`

Arguments:

- `color` : default, color
- `openedit` : Boolean, `false` if not given. Turns on Edit PDF mode and opens the Contents editor on the property row after creating the annotation. Built-in `Shift + A` / `Shift + U` use this.
- `copytoclipboard` : Boolean, `false` if not given. For highlight/underline/squiggly/strikeout annotations, copies the selection (the annotation's text) to the clipboard. This used to be the default behavior for built-in keyboard shortcuts such as `a`, but now it has to be chosen explicitly.
- `setcontent` : Boolean, `false` if not given. For highlight/underline/squiggly/strikeout annotations, sets the annotation's content to the selection (the annotation's text)

Use cases:

- change default color for annotations
- create multiple shortcuts for different colors

Example: change `a` to create a green highlight annotation:

```
Shortcuts [
    [
        Cmd = CmdCreateAnnotHighlight #00ff00
        Key = a
    ]
]
```

## Other CmdCreateAnnot\* arguments

**Ver 3.6+**

Arguments for `CmdCreateAnnotHighlight` plus:

- `color` : default, color of text and border, black if not given
- `bgcolor` : background color of annotation, fully transparent if not given
- `textsize` : size of annotation text, 12 if not given
- `borderwidth` : border width of free text, ink, line, polyline, polygon, square and circle annotations, 1 if not given
- `alignment` : **ver 3.7+**, how free text is aligned in its box: `left`, `center`, or `right`. Left if not given
- `opacity` : opacity of annotation, 0 = fully transparent (i.e. invisible), 100 = fully opaque (default if not given)
- `interiorcolor` : interior color for circle, square, etc. annotations, fully transparent if not given

## `CmdToggleBoolSetting`

**Ver 3.7+**

Arguments:

- `name` : default, string — name of a boolean advanced setting (case-insensitive leaf name or dotted path, e.g. `Fullscreen.ShowMenubar`)

Toggles that setting between `true` and `false`. Useful for custom shortcuts or toolbar buttons. Unknown setting names show a warning when the shortcut is defined and when the command runs.

Without a `name` argument, the Command Palette lists every non-internal boolean setting (`=` prefix). Enter or a click toggles the selected setting and closes the palette.

Example: toggle fullscreen menubar with `t`:

```
Shortcuts [
	[
		Cmd = CmdToggleBoolSetting Fullscreen.ShowMenubar
		Key = t
		Name = Toggle Fullscreen Menubar
	]
]
```

Add `ToolbarText` to the same entry to also get a toolbar button for it. Example: turn the reading mode of [`MouseWheelTurnsPage`](Advanced-options-settings.md) on and off with `w` or from the toolbar:

```
Shortcuts [
	[
		Cmd = CmdToggleBoolSetting MouseWheelTurnsPage
		Key = w
		Name = Wheel Turns Page
		ToolbarText = Wheel Turns Page
	]
]
```

The same works for any other boolean advanced setting, e.g. `CmdToggleBoolSetting RememberViewOffsetOnPageTurn` or `CmdToggleBoolSetting ClickEdgeToTurnPage`.

## `CmdZoomCustom`

**Ver 3.6+**

Arguments:

- `level` : default, string or integer, zoom level

`level` can be:

- a number describing the zoom level as a percentage, e.g.:
  - `50` or `50%` means 50% zoom
  - `125` means 125% zoom
- a virtual zoom level:
  - `actual size` (100% zoom level)
  - `fit page`
  - `fit width`
  - `fit content`
  - `fit visible`

Example:

```
Shortcuts [
    [
        Cmd = CmdZoomCustom 50%
        Key = z
    ]
]
```

## `CmdCommandPalette`

**Ver 3.6+**

Argument:

- `mode` : default, optional string. Values:
  - `@` for open files (tabs)
  - `#` for history of files
  - `>` for commands
  - `&` for page thumbnails
  - `%` for table of contents (`CmdCommandPaletteTOC`, `Shift + F12`)
  - `$` for favorites (`CmdCommandPaletteFavorites`)
  - `*` for annotations in the current PDF
  - `=` for boolean advanced settings (`CmdToggleBoolSetting`)

Without an argument it defaults to `>`.

To bind a keyboard shortcut to a palette mode, prefer the dedicated commands
(`CmdCommandPaletteTOC`, `CmdCommandPaletteFavorites`) over `CmdCommandPalette`
with a `mode` argument. A literal `$` in settings must be written as `$$` (see
[customize keyboard shortcuts](Customize-keyboard-shortcuts.md#escaping-in-settings-values)).

Example:

```
Shortcuts [
    [
        Cmd = CmdCommandPalette #
        Key = Ctrl + h
    ]
    [
        Cmd = CmdCommandPaletteFavorites
        Key = b
    ]
]
```

## Toggle commands (force an on/off state)

**Ver 3.7+**

These toggle commands accept an optional `state` boolean argument that forces an explicit state instead of flipping the current one. This is useful for automation (e.g. via [DDE](DDE-Commands.md)) where you want to set a known state rather than toggle blindly:

- `CmdToggleFullscreen`
- `CmdTogglePresentationMode`
- `CmdToggleToolbar`
- `CmdToggleMenuBar`
- `CmdToggleContinuousView`
- `CmdToggleTableOfContents`, `CmdToggleBookmarks`
- `CmdToggleThumbnails`
- `CmdToggleDisableLinks`

Arguments:

- `state` : default, boolean. `on`/`true`/`1`/`yes` forces the feature on, `off`/`false`/`0`/`no` forces it off. If the document is already in the requested state, nothing happens. If omitted, the command toggles (the original behavior).

Examples (DDE):

```
[CmdToggleFullscreen on]
[CmdToggleToolbar off]
[CmdToggleContinuousView state: on]
```

# Debugging

If a custom shortcut defined in `Shortcuts` doesn't work, it could be caused by an invalid command name or invalid command arguments.

We log information about unsuccessful shortcut parsing, so [check the logs](Debugging-Sumatra.md#getting-logs) if things don't work as expected.


---

<!-- Customize-toolbar.md -->

# Customize toolbar

Choose which buttons the toolbar shows, how it is displayed, and add your own buttons for any [command](Commands.md) or external viewer. Everything is set in the [advanced settings](Advanced-options-settings.md) file.

**Available in version 3.6 or later.**

**Most people use `ToolbarCustomLayout` to trim the toolbar to the buttons they use.** At a glance:

- **Button layout (ver 3.7+):** `ToolbarCustomLayout` picks the built-in buttons and their order.
- **Display mode (ver 3.7+):** `Toolbar = show / overlay / hide`; `F8` cycles through them.
- **Custom buttons:** `ToolbarText` or `ToolbarSvgIcon` in the `Shortcuts` setting adds a button for any command.
- **External viewer buttons:** `ToolbarText` / `ToolbarSvgIcon` in `ExternalViewers`.

## Open the settings file

- Menu: **Settings → Open Advanced Settings File...**
- [Command Palette](Command-Palette.md): `Ctrl + K`, then `Open Advanced Settings File...`

It opens in your default text editor.

## Choose which buttons are on the toolbar, and in what order

**Ver 3.7+:** `ToolbarCustomLayout` lists the built-in buttons you want, in the order you want them:

```
ToolbarCustomLayout = CmdFindFirst | PageInfo CmdGoToPrevPage CmdGoToNextPage | CmdZoomOut CmdZoomIn
```

- entries are [command ids](Commands.md), separated by spaces (commas and semicolons work too)
- `|` (or `Separator`) inserts a separator
- `PageInfo` is the page number box (`Page: 3 / 120`); leave it out and it isn't shown at all
- **leaving a button out is how you hide it** — keep the toolbar and fill it with the buttons you actually use
- an empty value (the default) means the standard layout
- names that aren't built-in toolbar buttons are ignored (see the log with `-log`)

The standard toolbar written out, a starting point to edit down:

```
ToolbarCustomLayout = CmdOpenFile CmdPrint | PageInfo CmdGoToPrevPage CmdGoToNextPage | CmdNavigateBack CmdNavigateForward | CmdToggleReadAloud | CmdZoomFitWidthAndContinuous CmdZoomFitPageAndSinglePage CmdRotateLeft CmdRotateRight CmdZoomOut CmdZoomIn | CmdFindFirst | CmdToggleEditPDF
```

Note: some buttons only show when they apply, so a listed button may stay hidden: Read Aloud needs `ToolbarShowReadAloud`, Find needs a searchable document, rotate needs a rotatable document, Edit PDF needs an editable PDF.

**Edit PDF** toggles a second row of annotation tools. Highlight, underline, squiggly and strike out are enabled only while text is selected.

Some buttons have a drop-down: Zoom In / Zoom Out list the zoom levels, Save in Edit PDF lists the ways to end the session, Read Aloud has voice and speed. Rest the mouse on the button to open it after a short delay; right-click opens it at once if it is not already shown.

## Show, hide or overlay the toolbar

**Ver 3.7+:** the `Toolbar` advanced setting controls how the toolbar is shown:

- `show` : pinned at the top of the window (the default)
- `hide` : no toolbar
- `overlay` : floats over the page, sized to its natural width and horizontally centered. Hidden until the mouse moves near the top of the page

```
Toolbar = overlay
```

To cycle show → overlay → hide:

- Keyboard: `F8`
- Menu: **View → Show Toolbar**
- [Command Palette](Command-Palette.md): `Ctrl + K`, then `Toggle Toolbar` (`CmdToggleToolbar`)

## Add a button for a command

In the `Shortcuts` array, add a definition with `ToolbarText` (a text label):

```
Shortcuts [
    [
        Cmd = CmdPrevTab
        ToolbarText = Prev Tab
    ]
    [
        Cmd = CmdNextTab
        ToolbarText = Next Tab
    ]
    [
        Name = Send By Mail
        Cmd = CmdSendByEmail
        Key = Shift + M
        ToolbarText = ✉
    ]
    [
        Cmd = CmdNavigateBack
        ToolbarText = ←
    ]
    [
        Cmd = CmdNavigateForward
        ToolbarText = →
    ]
]
```

- `CmdNextTab` is one of the [commands](Commands.md)
- `Next Tab` is shown in the toolbar
- if you provide `Name`, it is available in the [Command Palette](Command-Palette.md)

The toolbar with these buttons (after the built-in Find and Edit PDF buttons):

![Toolbar with Prev Tab, Next Tab, send by mail, back and forward buttons](https://files.sumatrapdfreader.org/assets/sumatrapdf/docs/img/toolbar-custom-buttons-4757.png)

Buttons you add (`ToolbarText` / `ToolbarSvgIcon`) always come after the built-in ones. See [customize shortcuts](Customize-keyboard-shortcuts.md) for full docs on the `Shortcuts` setting.

## Command palette on the toolbar

`Ctrl + K` then `$` opens the [command palette](Command-Palette.md) in favorites mode (a floating list that closes when it loses focus). For a toolbar button, add a shortcut with `ToolbarText` or `ToolbarSvgIcon`:

```
Shortcuts [
    [
        Cmd = CmdCommandPaletteFavorites
        Name = Favorites
        ToolbarText = $
    ]
]
```

The table of contents (document bookmarks) is `Ctrl + K` then `%`, or `Shift + F12`. For a toolbar button use `CmdCommandPaletteTOC` the same way.

## Add a button for an external viewer

See [customize external viewers](Customize-external-viewers.md).

## Using SVG icons

**Ver 3.7+:** set `ToolbarSvgIcon` to an SVG icon. It is rendered like built-in toolbar icons (theme text/background colors are applied automatically). If both `ToolbarSvgIcon` and `ToolbarText` are set, the icon is used.

Use [Tabler Icons](https://tabler.io/icons) SVGs (24×24, `stroke="currentColor"`, `fill="none"`) — the built-in toolbar icons use the same format.

```
Shortcuts [
    [
        Cmd = CmdNavigateBack
        Name = Back
        ToolbarSvgIcon = <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" stroke-width="1" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><rect x="0" y="0" width="24" height="24" stroke="none"></rect><path d="M9 14l-4 -4l4 -4" /><path d="M5 10h11a4 4 0 1 1 0 8h-1" /></svg>
    ]
    [
        Cmd = CmdNavigateForward
        Name = Forward
        ToolbarSvgIcon = <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" stroke-width="1" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><rect x="0" y="0" width="24" height="24" stroke="none"></rect><path d="M15 14l4 -4l-4 -4" /><path d="M19 10h-11a4 4 0 1 0 0 8h1" /></svg>
    ]
]
```

`Name` is the button's tooltip. If omitted, the command's default name is used.

## Using Unicode symbols

As an alternative to SVG, use Unicode symbols in `ToolbarText` — they are drawn as button labels using the UI font.

Symbols supported by Windows' Segoe UI font: http://zuga.net/articles/unicode-all-characters-supported-by-the-font-segoe-ui/

To find one, search for a term such as `arrow`, then copy and paste the symbol (e.g. `→`) into the settings file.

## Tips

- Start from the standard `ToolbarCustomLayout` above and delete what you don't use.
- Hiding a button doesn't disable the command: it's still in the menu, the [command palette](Command-Palette.md) and on its keyboard shortcut.
- Use `Toolbar = overlay` to get the vertical space back and still reach the toolbar from the top of the page.
- Set `Name` on a custom button to get a readable tooltip and a Command Palette entry.
- If a `ToolbarCustomLayout` entry has no effect, run with `-log`: unknown names are logged.

## See also

- [Customize keyboard shortcuts](Customize-keyboard-shortcuts.md) — the `Shortcuts` setting in full
- [Customize external viewers](Customize-external-viewers.md) — toolbar buttons for other programs
- [Commands](Commands.md) — command ids to use in buttons
- [Advanced settings](Advanced-options-settings.md) — all settings


---

<!-- Customize-theme-colors.md -->

# Customize theme (colors)

Change the colors of the SumatraPDF UI (menus, tabs, toolbars) by defining your own theme with the [`Themes` advanced setting](Advanced-options-settings.md), and optionally make document pages follow it.

**Available in version 3.6 or later.**

**Most people copy a built-in theme, rename it and change a few colors.** At a glance:

- **Pick a theme:** **Settings → Theme**, `Ctrl + K` then `Set theme '<name>'`, or `Theme = <name>`.
- **Create a theme:** add an entry to the `Themes` array.
- **Customize a built-in theme:** copy its definition (below), give it a new `Name`.
- **Recolor document pages:** `DocumentColorsFollowTheme = off / smart / legacy`.
- **Invert page colors for this session:** `Shift + I` (`CmdInvertColors`).

## Create a theme

1. Open the settings file:
   - Menu: **Settings → Open Advanced Settings File...**
   - [Command Palette](Command-Palette.md): `Ctrl + K`, then `Open Advanced Settings File...`
2. `SumatraPDF-settings.txt` opens in your default text editor. Scroll to the bottom, find the `Themes` array and add theme definitions.

```
Themes [
    [
        Name = My Dark Theme
        TextColor = #bac9d0
        BackgroundColor = #263238
        ControlBackgroundColor = #263238
        ActiveTabBackgroundColor = #263238
        InactiveTabBackgroundColor = #4d3a56
        LinkColor = #8aa3b0
        DisabledTextColor = #6b7c85
        DarkerTextColor = #8aa3b0
        HotBackgroundColor = #324047
        EdgeColor = #37474f
        HotEdgeColor = #546e7a
        DisabledEdgeColor = #1e272c
        ErrorBackgroundColor = #5c2b2b
        NotificationBackgroundColor = #2e3c43
        NotificationHighlightColor = #455a64
        NotificationHighlightTextColor = #eceff1
        ColorizeControls = true
    ]
]
```

This creates a theme named `My Dark Theme`. Built-in themes already ship with these colors filled in; their definitions are [listed below](#built-in-themes).

## Customize a built-in theme

Copy its definition from [Built-in themes](#built-in-themes) (or `src/Theme.cpp`) into your `Themes` setting, give it a new `Name`, and change the colors you want.

For example, copy `Dracula`, rename it `My Dracula`, and set `ActiveTabBackgroundColor` and `InactiveTabBackgroundColor` to your preferred tab colors. Select `My Dracula` in **Settings → Theme** after saving.

## Choose a theme

After you save the settings file:

- Menu: **Settings → Theme**, then choose a theme
- [Command Palette](Command-Palette.md): `Ctrl + K`, then `Set theme '<name>'`
- Settings file: change `Theme = ` in `SumatraPDF-settings.txt` (e.g. `Theme = Solarized Dark`)

## Make document pages follow the theme

UI themes only recolor chrome (menus, tabs, toolbars). Separately, **document pages** (PDF, XPS, DjVu, EPUB, MOBI, FB2, comics, images, and other MuPDF-rendered formats) can follow the theme via **`DocumentColorsFollowTheme`**:

| Value               | Effect                                                                                                                                                                                                                                                                                                                                             |
| ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`off`** (default) | Keep the document’s own page colors.                                                                                                                                                                                                                                                                                                               |
| **`smart`**         | Recolor text and page background using `FixedPageUI.TextColor` / `FixedPageUI.BackgroundColor` when set, otherwise the current theme’s text/background. **Photos and other images stay as in the file** — preferred for dark reading. Reflowable MuPDF formats (EPUB, HTML, FB2, MOBI) do this with CSS rather than by recoloring the page bitmap. |
| **`legacy`**        | Also recolor images on PDF, XPS, and DjVu (older invert / colorize behavior). Reflowable MuPDF formats still use CSS, so images stay original.                                                                                                                                                                                                     |

To change it:

- Menu: **Settings → Theme…** or **Settings → Make Document Colors Follow Theme**
- [Command Palette](Command-Palette.md): `Ctrl + K`, then `Set Document Colors Follow Theme` (`CmdSetDocumentColorsFollowTheme`) for a drop-down including **`legacy`**
- Advanced settings: `DocumentColorsFollowTheme = off` / `smart` / `legacy`

This is independent of `Theme = ...`: use a dark UI theme with `DocumentColorsFollowTheme = off` (original white PDF pages), or a light UI with `smart` page recoloring.

The `Dark` theme with `DocumentColorsFollowTheme = off` (left) and `smart` (right):

![Dark theme with document colors off and smart](https://files.sumatrapdfreader.org/assets/sumatrapdf/docs/img/theme-document-colors-cda7.png)

## Invert page colors temporarily

Press `Shift + I` (`CmdInvertColors`). It swaps the page colors for the rest of the session, whatever `DocumentColorsFollowTheme` and `FixedPageUI` are set to, and is not saved to the settings file.

## Tips

- Start from a built-in theme close to what you want instead of writing all colors.
- Keep `ColorizeControls = true`; with `false` much of the UI ignores the theme.
- Set the optional colors when a tinted `TextColor` makes derived disabled / hover colors look wrong.
- Use `DocumentColorsFollowTheme = smart` for dark reading that keeps photos intact.
- Use `Shift + I` for a one-off inversion that isn't saved.

## Theme color reference

**Required / base colors**

- `TextColor` and `BackgroundColor` set the main window's text and background colors.
- `ControlBackgroundColor` sets the background of Windows controls (buttons, window frame, menus, list controls, etc.).
- `ActiveTabBackgroundColor` and `InactiveTabBackgroundColor` set the backgrounds of active and inactive tabs. If empty, they use the control background and its derived inactive shade.
- `LinkColor` sets the color of links. It is typically blue.
- `ColorizeControls` should be `true`. If it is `false`, we won't try to change the colors of standard Windows controls (menus, toolbars, buttons, etc.), so much of the UI will not respect the theme colors.

**Optional UI colors** (leave empty to derive from the base colors; set them when a warm or tinted `TextColor` would make derived disabled/hover colors look wrong — e.g. Dracula’s near-white foreground)

- `DisabledTextColor` — grayed / disabled labels and buttons
- `DarkerTextColor` — secondary / muted text
- `HotBackgroundColor` — hovered control background
- `EdgeColor` / `HotEdgeColor` / `DisabledEdgeColor` — control borders
- `ErrorBackgroundColor` — error surfaces
- `NotificationBackgroundColor` / `NotificationHighlightColor` / `NotificationHighlightTextColor` — in-app notification tips
- `ActiveTabBackgroundColor` / `InactiveTabBackgroundColor` — active and inactive tab backgrounds

## Built-in Themes

These are the built-in theme definitions. Copy one into your Themes setting and give it a new Name to create a customized theme.

```text
Themes [
    [
        Name = Light
        TextColor = #000000
        BackgroundColor = #f2f2f2
        ControlBackgroundColor = #ffffff
        ActiveTabBackgroundColor = #ffffff
        InactiveTabBackgroundColor = #e6e6e6
        LinkColor = #0020a0
        DisabledTextColor = #808080
        DarkerTextColor = #404040
        HotBackgroundColor = #e8e8e8
        EdgeColor = #c0c0c0
        HotEdgeColor = #808080
        DisabledEdgeColor = #d0d0d0
        ErrorBackgroundColor = #ffe0e0
        NotificationBackgroundColor = #fafafa
        NotificationHighlightColor = #ffee70
        NotificationHighlightTextColor = #8d0801
        ColorizeControls = false
    ]
    [
        Name = Dark
        TextColor = #F9FAFB
        BackgroundColor = #000000
        ControlBackgroundColor = #000000
        ActiveTabBackgroundColor = #000000
        InactiveTabBackgroundColor = #191919
        LinkColor = #6B7280
        DisabledTextColor = #6B7280
        DarkerTextColor = #9CA3AF
        HotBackgroundColor = #1F2937
        EdgeColor = #374151
        HotEdgeColor = #6B7280
        DisabledEdgeColor = #1F2937
        ErrorBackgroundColor = #7F1D1D
        NotificationBackgroundColor = #111827
        NotificationHighlightColor = #422006
        NotificationHighlightTextColor = #fde68a
        ColorizeControls = true
    ]
    [
        Name = Light Warm
        TextColor = #333333
        BackgroundColor = #ebe6da
        ControlBackgroundColor = #f5f1e8
        ActiveTabBackgroundColor = #f5f1e8
        InactiveTabBackgroundColor = #e6dcc5
        LinkColor = #0020a0
        DisabledTextColor = #8a8578
        DarkerTextColor = #5c574c
        HotBackgroundColor = #e8e2d4
        EdgeColor = #c9c2b0
        HotEdgeColor = #8a8578
        DisabledEdgeColor = #ddd6c6
        ErrorBackgroundColor = #f5d6d0
        NotificationBackgroundColor = #f8f4ea
        NotificationHighlightColor = #e8d48b
        NotificationHighlightTextColor = #5c3a0a
        ColorizeControls = true
    ]
    [
        Name = Dark from 3.5
        TextColor = #bac9d0
        BackgroundColor = #263238
        ControlBackgroundColor = #263238
        ActiveTabBackgroundColor = #263238
        InactiveTabBackgroundColor = #4d3a56
        LinkColor = #8aa3b0
        DisabledTextColor = #6b7c85
        DarkerTextColor = #8aa3b0
        HotBackgroundColor = #324047
        EdgeColor = #37474f
        HotEdgeColor = #546e7a
        DisabledEdgeColor = #1e272c
        ErrorBackgroundColor = #5c2b2b
        NotificationBackgroundColor = #2e3c43
        NotificationHighlightColor = #4a3a12
        NotificationHighlightTextColor = #ffdf9e
        ColorizeControls = true
    ]
    [
        Name = Charcoal
        TextColor = #ffffff
        BackgroundColor = #2d2d30
        ControlBackgroundColor = #2d2d30
        ActiveTabBackgroundColor = #2d2d30
        InactiveTabBackgroundColor = #45454a
        LinkColor = #9999a0
        DisabledTextColor = #808088
        DarkerTextColor = #b0b0b8
        HotBackgroundColor = #3e3e42
        EdgeColor = #505058
        HotEdgeColor = #808088
        DisabledEdgeColor = #252528
        ErrorBackgroundColor = #5a1d1d
        NotificationBackgroundColor = #38383c
        NotificationHighlightColor = #4a3c16
        NotificationHighlightTextColor = #ffe2a0
        ColorizeControls = true
    ]
    [
        Name = Solarized Light
        TextColor = #212323
        BackgroundColor = #fdf6e3
        ControlBackgroundColor = #eee8d5
        ActiveTabBackgroundColor = #eee8d5
        InactiveTabBackgroundColor = #e0d5b1
        LinkColor = #268bd2
        DisabledTextColor = #93a1a1
        DarkerTextColor = #586e75
        HotBackgroundColor = #e6dfc8
        EdgeColor = #93a1a1
        HotEdgeColor = #657b83
        DisabledEdgeColor = #eee8d5
        ErrorBackgroundColor = #f8d0c8
        NotificationBackgroundColor = #f5efdc
        NotificationHighlightColor = #f3e2b3
        NotificationHighlightTextColor = #5c4405
        ColorizeControls = true
    ]
    [
        Name = Solarized Dark
        TextColor = #839496
        BackgroundColor = #002b36
        ControlBackgroundColor = #073642
        ActiveTabBackgroundColor = #073642
        InactiveTabBackgroundColor = #5b0c6f
        LinkColor = #268bd2
        DisabledTextColor = #586e75
        DarkerTextColor = #657b83
        HotBackgroundColor = #0a4a58
        EdgeColor = #586e75
        HotEdgeColor = #839496
        DisabledEdgeColor = #002b36
        ErrorBackgroundColor = #5c1a1a
        NotificationBackgroundColor = #003543
        NotificationHighlightColor = #3d3208
        NotificationHighlightTextColor = #eec97a
        ColorizeControls = true
    ]
    [
        Name = Dracula
        TextColor = #f8f8f2
        BackgroundColor = #282a36
        ControlBackgroundColor = #44475a
        ActiveTabBackgroundColor = #44475a
        InactiveTabBackgroundColor = #5d5a76
        LinkColor = #8be9fd
        DisabledTextColor = #6272a4
        DarkerTextColor = #6272a4
        HotBackgroundColor = #565a73
        EdgeColor = #6272a4
        HotEdgeColor = #bd93f9
        DisabledEdgeColor = #343746
        ErrorBackgroundColor = #ff5555
        NotificationBackgroundColor = #343746
        NotificationHighlightColor = #4a3c14
        NotificationHighlightTextColor = #f1fa8c
        ColorizeControls = true
    ]
    [
        Name = Nebula
        TextColor = #CBE3E7
        BackgroundColor = #100E23
        ControlBackgroundColor = #1E1C31
        ActiveTabBackgroundColor = #1E1C31
        InactiveTabBackgroundColor = #312e51
        LinkColor = #91DDFF
        DisabledTextColor = #6b6b8a
        DarkerTextColor = #a0a0c0
        HotBackgroundColor = #2a2745
        EdgeColor = #3e3a5c
        HotEdgeColor = #91DDFF
        DisabledEdgeColor = #15132a
        ErrorBackgroundColor = #5c1a2e
        NotificationBackgroundColor = #1a1830
        NotificationHighlightColor = #3d2f12
        NotificationHighlightTextColor = #f0d9a0
        ColorizeControls = true
    ]
    [
        Name = Greeny
        TextColor = #FDD085
        BackgroundColor = #4F6232
        ControlBackgroundColor = #1E3304
        ActiveTabBackgroundColor = #1E3304
        InactiveTabBackgroundColor = #086139
        LinkColor = #A2E53B
        DisabledTextColor = #8a9a60
        DarkerTextColor = #c0c878
        HotBackgroundColor = #2a4210
        EdgeColor = #6a7a40
        HotEdgeColor = #A2E53B
        DisabledEdgeColor = #152808
        ErrorBackgroundColor = #5c2810
        NotificationBackgroundColor = #3a4a28
        NotificationHighlightColor = #5c4a18
        NotificationHighlightTextColor = #fde7b0
        ColorizeControls = true
    ]
    [
        Name = Choco
        TextColor = #D7AD62
        BackgroundColor = #2A1104
        ControlBackgroundColor = #172736
        ActiveTabBackgroundColor = #172736
        InactiveTabBackgroundColor = #402659
        LinkColor = #E8CD12
        DisabledTextColor = #8a7040
        DarkerTextColor = #b09050
        HotBackgroundColor = #243848
        EdgeColor = #3a4a58
        HotEdgeColor = #E8CD12
        DisabledEdgeColor = #0e1820
        ErrorBackgroundColor = #5c2010
        NotificationBackgroundColor = #1e2e3c
        NotificationHighlightColor = #4a3208
        NotificationHighlightTextColor = #f5d89b
        ColorizeControls = true
    ]
    [
        Name = Purpy
        TextColor = #E2C3C3
        BackgroundColor = #20222A
        ControlBackgroundColor = #1E0126
        ActiveTabBackgroundColor = #1E0126
        InactiveTabBackgroundColor = #440257
        LinkColor = #EFF0B8
        DisabledTextColor = #8a7088
        DarkerTextColor = #b0a0b0
        HotBackgroundColor = #2e1838
        EdgeColor = #4a3060
        HotEdgeColor = #EFF0B8
        DisabledEdgeColor = #140018
        ErrorBackgroundColor = #5c1a2a
        NotificationBackgroundColor = #28203a
        NotificationHighlightColor = #46360f
        NotificationHighlightTextColor = #f0d9a8
        ColorizeControls = true
    ]
    [
        Name = One Dark
        TextColor = #abb2bf
        BackgroundColor = #282c34
        ControlBackgroundColor = #21252b
        ActiveTabBackgroundColor = #21252b
        InactiveTabBackgroundColor = #3d3747
        LinkColor = #61afef
        DisabledTextColor = #5c6370
        DarkerTextColor = #7f848e
        HotBackgroundColor = #2c313c
        EdgeColor = #181a1f
        HotEdgeColor = #528bff
        DisabledEdgeColor = #1b1d23
        ErrorBackgroundColor = #be5046
        NotificationBackgroundColor = #2c313a
        NotificationHighlightColor = #40351a
        NotificationHighlightTextColor = #e5c07b
        ColorizeControls = true
    ]
    [
        Name = Monokai
        TextColor = #f8f8f2
        BackgroundColor = #272822
        ControlBackgroundColor = #3e3d32
        ActiveTabBackgroundColor = #3e3d32
        InactiveTabBackgroundColor = #5a5848
        LinkColor = #66d9ef
        DisabledTextColor = #75715e
        DarkerTextColor = #a6a68a
        HotBackgroundColor = #49483e
        EdgeColor = #75715e
        HotEdgeColor = #a6e22e
        DisabledEdgeColor = #1e1f1c
        ErrorBackgroundColor = #f92672
        NotificationBackgroundColor = #34352f
        NotificationHighlightColor = #46411c
        NotificationHighlightTextColor = #e6db74
        ColorizeControls = true
    ]
    [
        Name = Nord
        TextColor = #d8dee9
        BackgroundColor = #2e3440
        ControlBackgroundColor = #3b4252
        ActiveTabBackgroundColor = #3b4252
        InactiveTabBackgroundColor = #59506f
        LinkColor = #88c0d0
        DisabledTextColor = #4c566a
        DarkerTextColor = #81a1c1
        HotBackgroundColor = #434c5e
        EdgeColor = #4c566a
        HotEdgeColor = #88c0d0
        DisabledEdgeColor = #2e3440
        ErrorBackgroundColor = #bf616a
        NotificationBackgroundColor = #3b4252
        NotificationHighlightColor = #4a3f26
        NotificationHighlightTextColor = #ebcb8b
        ColorizeControls = true
    ]
    [
        Name = GitHub Dark
        TextColor = #e6edf3
        BackgroundColor = #0d1117
        ControlBackgroundColor = #161b22
        ActiveTabBackgroundColor = #161b22
        InactiveTabBackgroundColor = #332a40
        LinkColor = #2f81f7
        DisabledTextColor = #6e7681
        DarkerTextColor = #8b949e
        HotBackgroundColor = #21262d
        EdgeColor = #30363d
        HotEdgeColor = #58a6ff
        DisabledEdgeColor = #21262d
        ErrorBackgroundColor = #da3633
        NotificationBackgroundColor = #161b22
        NotificationHighlightColor = #3d2a04
        NotificationHighlightTextColor = #e3b341
        ColorizeControls = true
    ]
    [
        Name = Catppuccin Mocha
        TextColor = #cdd6f4
        BackgroundColor = #1e1e2e
        ControlBackgroundColor = #181825
        ActiveTabBackgroundColor = #181825
        InactiveTabBackgroundColor = #2c2c43
        LinkColor = #89b4fa
        DisabledTextColor = #6c7086
        DarkerTextColor = #a6adc8
        HotBackgroundColor = #313244
        EdgeColor = #45475a
        HotEdgeColor = #cba6f7
        DisabledEdgeColor = #11111b
        ErrorBackgroundColor = #f38ba8
        NotificationBackgroundColor = #181825
        NotificationHighlightColor = #45391f
        NotificationHighlightTextColor = #f9e2af
        ColorizeControls = true
    ]
    [
        Name = Tokyo Night
        TextColor = #c0caf5
        BackgroundColor = #1a1b26
        ControlBackgroundColor = #16161e
        ActiveTabBackgroundColor = #16161e
        InactiveTabBackgroundColor = #2b2b3b
        LinkColor = #7aa2f7
        DisabledTextColor = #565f89
        DarkerTextColor = #a9b1d6
        HotBackgroundColor = #292e42
        EdgeColor = #3b4261
        HotEdgeColor = #7dcfff
        DisabledEdgeColor = #0f0f14
        ErrorBackgroundColor = #f7768e
        NotificationBackgroundColor = #16161e
        NotificationHighlightColor = #3d3117
        NotificationHighlightTextColor = #e0af68
        ColorizeControls = true
    ]
    [
        Name = Gruvbox
        TextColor = #ebdbb2
        BackgroundColor = #282828
        ControlBackgroundColor = #3c3836
        ActiveTabBackgroundColor = #3c3836
        InactiveTabBackgroundColor = #56514e
        LinkColor = #83a598
        DisabledTextColor = #928374
        DarkerTextColor = #a89984
        HotBackgroundColor = #504945
        EdgeColor = #665c54
        HotEdgeColor = #fabd2f
        DisabledEdgeColor = #1d2021
        ErrorBackgroundColor = #fb4934
        NotificationBackgroundColor = #3c3836
        NotificationHighlightColor = #4a3a1a
        NotificationHighlightTextColor = #fabd2f
        ColorizeControls = true
    ]
    [
        Name = Night Owl
        TextColor = #d6deeb
        BackgroundColor = #011627
        ControlBackgroundColor = #0b2942
        ActiveTabBackgroundColor = #0b2942
        InactiveTabBackgroundColor = #44126d
        LinkColor = #82aaff
        DisabledTextColor = #5f7e97
        DarkerTextColor = #7fdbca
        HotBackgroundColor = #1d3b53
        EdgeColor = #122d42
        HotEdgeColor = #c792ea
        DisabledEdgeColor = #01111d
        ErrorBackgroundColor = #ef5350
        NotificationBackgroundColor = #0b2942
        NotificationHighlightColor = #3a2d16
        NotificationHighlightTextColor = #ecc48d
        ColorizeControls = true
    ]
    [
        Name = Ayu
        TextColor = #bfbdb6
        BackgroundColor = #0b0e14
        ControlBackgroundColor = #0d1017
        ActiveTabBackgroundColor = #0d1017
        InactiveTabBackgroundColor = #261f37
        LinkColor = #59c2ff
        DisabledTextColor = #565b66
        DarkerTextColor = #acb6bf
        HotBackgroundColor = #1b2733
        EdgeColor = #1b2733
        HotEdgeColor = #e6b450
        DisabledEdgeColor = #06070a
        ErrorBackgroundColor = #f07178
        NotificationBackgroundColor = #0d1017
        NotificationHighlightColor = #362a12
        NotificationHighlightTextColor = #e6b450
        ColorizeControls = true
    ]
    [
        Name = Palenight
        TextColor = #a6accd
        BackgroundColor = #292d3e
        ControlBackgroundColor = #1b1e2b
        ActiveTabBackgroundColor = #1b1e2b
        InactiveTabBackgroundColor = #332e4a
        LinkColor = #82aaff
        DisabledTextColor = #676e95
        DarkerTextColor = #8796b0
        HotBackgroundColor = #32374d
        EdgeColor = #3c435e
        HotEdgeColor = #c792ea
        DisabledEdgeColor = #151820
        ErrorBackgroundColor = #ff5370
        NotificationBackgroundColor = #1b1e2b
        NotificationHighlightColor = #3f3520
        NotificationHighlightTextColor = #ffcb6b
        ColorizeControls = true
    ]
]
```

## See also

- [Advanced settings](Advanced-options-settings.md) — `Themes`, `Theme`, `DocumentColorsFollowTheme`, `FixedPageUI`
- [Command Palette](Command-Palette.md) — switch themes by name


---

<!-- Customize-eBook-UI.md -->

# Customize eBook UI

EPUB, MOBI, FB2, and similar formats use SumatraPDF's **eBook UI** (HTML-based layout). Since **version 3.4** the engine is MuPDF-based: text selection, in-document search, and bookmarks work much like PDF.

## The eBook Settings dialog (**ver 3.7+**)

With an ebook open, use `Ctrl + K`, `Change eBook Settings` command in
[Command Palette](Command-Palette.md) (`CmdChangeEbookSettings`). It has the font, size,
margin and line spacing, and shows the CSS those values produce in a read-only
box, so you can see exactly what is applied. **Margin** is a single field, but it
takes the same one, two or four values as the setting. Tick **Custom CSS** and the box becomes
editable: what you type there is then used instead of the generated rules (it
starts out holding them, so nothing is lost by taking over).

At the bottom, **This file** stores the settings for the open document only and
**For all ebooks** stores them globally, the same way **Change Background Color**
works. In per-document mode only the values that differ from the global ones are
stored, so everything else keeps following the global setting. The document is
reloaded when you press OK.

**Reset to defaults** undoes the customization at whichever of the two is
selected: for one document that means inheriting everything from the global
section again, for all ebooks it means the values SumatraPDF ships with. `Tab`
moves between the controls; `Esc` does _not_ close the dialog, so a long piece
of CSS can't be lost by a stray keypress — use **Cancel**.

The command is only offered for reflowable documents — for a PDF or an image
there is no font or CSS to change.

## What you can customize

The same settings, and a few more, are in **Settings → Advanced Settings...**,
in the `EBookUI` section:

```
EBookUI [
    FontName =
    FontSize = 0
    Margin =
    LineSpacing = 0
    LayoutDx = 0
    LayoutDy = 0
    IgnoreDocumentCSS = false
    CustomCSS =
    WindowBgCol =
]
```

| Setting                 | Meaning                                                                                                                                                                                                                                                                                                                 |
| ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `FontName`              | Default font family, e.g. `Segoe UI` or `Microsoft YaHei` (empty = engine default, usually a serif). Overrides the document's `font-family`, including inline `style="font-family: ..."`. A font that can't be loaded is reported with a notification (**ver 3.7+**)                                                    |
| `FontSize`              | Base font size (default `8.0`; `0` = built-in default)                                                                                                                                                                                                                                                                  |
| `Margin`                | White space around the text, in points, written like a CSS margin: one number for all four sides, two for top/bottom and left/right, or four in top-right-bottom-left order. Empty keeps the default (3 em above and below, 2 em to the sides, so it follows the font size); `0` leaves no margin at all (**ver 3.7+**) |
| `LineSpacing`           | Line-height multiplier, e.g. `1.5` for expanded spacing (`0` = document or engine default; **ver 3.7+**)                                                                                                                                                                                                                |
| `LayoutDx` / `LayoutDy` | Virtual page width / height for reflow (defaults `420` / `595`)                                                                                                                                                                                                                                                         |
| `IgnoreDocumentCSS`     | Ignore stylesheet from the EPUB (`true` = your `CustomCSS` wins)                                                                                                                                                                                                                                                        |
| `CustomCSS`             | Extra CSS rules. A declaration marked `!important` beats the document's own CSS and its inline styles, so `IgnoreDocumentCSS` is rarely needed                                                                                                                                                                          |
| `WindowBgCol`           | Canvas background around the reflowed text (**ver 3.7+**)                                                                                                                                                                                                                                                               |

Full field reference: [Advanced settings](Advanced-options-settings.md).

## Settings for a single document (**ver 3.7+**)

The same options can be set for one document only, as an `EBookUI` block inside
that file's entry in `FileStates`:

```
FileStates [
    [
        FilePath = C:\books\war-and-peace.epub
        EBookUI [
            FontName = Microsoft YaHei
            LineSpacing = 1.4
        ]
    ]
]
```

A field you leave out (empty, or `0` for the numbers) uses the value from the
global `EBookUI` section, so the block above changes only the font and the line
spacing for that one book. `Margin` is empty when unset, since `0` means no
margin at all. `IgnoreDocumentCSS` is `true` / `false` here, and
empty means "use the global setting" — so a single document can keep the
publisher's CSS even when the global setting ignores it.

The block is written to the settings file only for documents that have one, and
it survives `RememberOpenedFiles = false` (it's a setting you typed, not reading
history). The document has to be reopened for a change to take effect.

`WindowBgCol` and `DefaultDisplayMode` have no per-document version here: the
`BgCol` and `DisplayMode` fields of the file entry already do that job.

## Themes and document page colors

UI themes (`Theme = ...`) only change window chrome. Ebooks that go through MuPDF (EPUB, HTML, FB2, MOBI, and similar reflowable formats) use the same **`DocumentColorsFollowTheme`** setting as PDF, applied as user CSS (page background and text color). **Images stay as in the file** — they are not inverted by bitmap recoloring.

| Value        | Effect                                                                           |
| ------------ | -------------------------------------------------------------------------------- |
| **`off`**    | Original page colors.                                                            |
| **`smart`**  | Dark (or custom) text and background; **images stay intact**.                    |
| **`legacy`** | Same as **`smart`** for these formats (bitmap invert of images is PDF/XPS/DjVu). |

- **`Shift + I`** swaps the page colors for the session (not saved). Images still stay as in the file.
- For **`legacy`**, use Settings → Theme… / Make Document Colors Follow Theme, or set `DocumentColorsFollowTheme = legacy` in advanced settings. On reflowable MuPDF documents that still only changes text and background.

For dark reading of reflowed EPUBs without recoloring the whole page, you can also use `EBookUI.CustomCSS` + `IgnoreDocumentCSS = true` and `WindowBgCol`. See [Customize theme colors](Customize-theme-colors.md).

## Continuous vs paged view

Use the same view commands as PDF: `c` toggles continuous mode; `Ctrl + 6` / `7` / `8` change column layout. See [Scrolling and zooming](Scrolling-and-zooming.md).

## Search and navigation

- In-document find: `Ctrl + F`, `F3` — see [Finding text](Finding-text.md)
- Table of contents: `F12` or command palette `*` prefix
- Internal links: click to follow; `Alt + Left` to go back

## Known limitations

Report issues in [discussions](https://github.com/sumatrapdfreader/sumatrapdf/discussions) or the [issue tracker](https://github.com/sumatrapdfreader/sumatrapdf/issues).

- **Vertical writing** (some Asian EPUBs): may not detect top-to-bottom / right-to-left layout correctly.
- **CSS features**: not every EPUB3 layout feature is supported; complex fixed-layout EPUBs may look wrong.
- **`ReloadModifiedDocuments`**: auto-reload when the file changes on disk does not apply to eBook UI documents.
- **Thumbnails in Explorer** for `.epub`: limited compared to PDF — see installer `-with-preview` in [Installation](Installation.md).

## CHM files

CHM uses a separate `ChmUI` section. Set `ChmUI.UseFixedPageUI = true` to render CHM with the PDF-style fixed-page engine instead of the interactive browser view. In that mode, set `ChmUI.FontName` to override the document font; when empty it falls back to `EBookUI.FontName` and then the engine default.

## See also

- [Supported document formats](Supported-document-formats.md)
- [FAQ](FAQ.md) — dark mode / invert questions
- [Advanced settings](Advanced-options-settings.md)


---

<!-- Customize-external-viewers.md -->

# Customize external viewers

Open the current document in a different program from the `File` menu. SumatraPDF auto-detects some popular apps (Adobe, Foxit, PDF-XChange, etc.) and you can add your own with the `ExternalViewers` [advanced setting](https://www.sumatrapdfreader.org/settings/settings.html).

**Most people use it to open the PDF they're viewing in another reader, e.g. Adobe Reader.** At a glance:

- **Open in another program:** pick it in the `File` menu.
- **Add a viewer:** an entry in `ExternalViewers` with `CommandLine`, `Name`, `Filter`.
- **Keyboard shortcut (ver 3.6+):** `Key`.
- **Toolbar button (ver 3.7+):** `ToolbarText` or `ToolbarSvgIcon`.

## Open the document in another program

Use the `File` menu and pick the viewer. Viewers you add appear there under their `Name`.

## Add a custom viewer

1. Menu: **Settings → Open Advanced Settings File...** to open the configuration file.
2. Modify the `ExternalViewers` section.

Available fields:

```
ExternalViewers [
  [
    CommandLine =
    Name =
    Filter =

    // ver 3.6+:
    Key =

    // ver 3.7+:
    ToolbarText =
    ToolbarSvgIcon =
  ]
]
```

Example:

```
ExternalViewers [
  [
    CommandLine = "C:\Program Files\FoxitReader\FoxitReader.exe" /A page=%p "%1"
    Name = Foxit &Reader
    Filter = *.pdf
    Key = Ctrl + m
    ToolbarText = Foxit
  ]
]
```

## Add a shortcut or toolbar button

- `Key` (ver 3.6+) is an optional keyboard shortcut that invokes the viewer.
- `ToolbarText` (ver 3.7+) is optional and adds a toolbar button for the viewer.
- `ToolbarSvgIcon` (ver 3.7+) is optional and sets an SVG icon for that button. If both are set, the SVG icon is used. See [Customize toolbar](Customize-toolbar.md#using-svg-icons) for the icon format.

## Tips

- Always quote file / directory values (`"%1"`, `"%d"`) so paths with spaces work.
- Use `Filter = *` and `"%d"` to open the document's folder in a file manager.
- Use `%p` to open the viewer at the current page, if it supports page numbers.
- Use `%%` to pass a literal `%`, e.g. `sumatrapdf-tool draw -o page-%%d.png`.

## Reference

### `CommandLine`

Full path of the executable used to open a file, followed by its arguments. Arguments can use special values:

- `"%1"` : the full path of the current document
- `%p` : the current page number. Not all viewers support page numbers
- `"%d"` : the directory of the current document. Useful for launching file managers. Available in version **3.5** and later
- `%%` : a literal `%`. Use this to pass a `%` to the external program; for example, `%%d` reaches it as `%d` (handy for tools like `sumatrapdf-tool draw -o page-%d.png`). Available in version **3.7** and later

Use quotes around file / directory special values (i.e. `"%1"` and `"%d"`) to avoid issues with paths that have spaces in them.

### `Name`

Displayed in the `File` menu.

### `Filter`

Restricts which files the viewer can open:

- only PDF files: `*.pdf`
- PNG and JPEG files: `*.png;*.jpg;*.jpeg`
- all files: `*` (useful for file managers)

## See also

- [Customize toolbar](Customize-toolbar.md) — toolbar buttons and SVG icons
- [Customize keyboard shortcuts](Customize-keyboard-shortcuts.md) — key names and modifiers
- [Advanced settings](https://www.sumatrapdfreader.org/settings/settings.html) — all settings


---

<!-- Customize-search-translation-services.md -->

# Customize search / translation

Send selected text to a web search engine, a translation service, an API or a local program. Built-in services are in the selection context menu; add your own with the `SelectionHandlers` [advanced setting](https://www.sumatrapdfreader.org/settings/settings.html).

**Available in version 3.4 or later.**

**Most people use it to search or translate a selected word or phrase.** At a glance:

- **Search / translate:** right-click selection → `Selection` → `Search with` / `Translate with` (Google, Bing, DeepL, ...).
- **Command Palette:** `Ctrl + K`, then e.g. `deepl`.
- **Add a service:** an entry in `SelectionHandlers` with `URL`, `Name`, optional `Key` (ver 3.6+).
- **Selection toolbar button (ver 3.7+):** `SelectToolbarNameOrSvg`.
- **Main toolbar button (ver 3.7+):** `ToolbarText` / `ToolbarSvgIcon`.
- **Long text, APIs (ver 3.7+):** `Method = POST` / `POST-VIA-BROWSER`.
- **Run a program:** `Exe` instead of `URL`.

## Search or translate the selection

You can send selected text to the Google or Bing search engine, or to the Google or DeepL translation service.

With the mouse:

- select text
- right-click to open the context menu

![Context Menu Selection](https://files.sumatrapdfreader.org/assets/sumatrapdf/docs/img/context-menu-selection-0a3b.png)

- use the `Selection` submenu, then `Translate with` or `Search with`, and select the web service:

![Context Menu Translate](https://files.sumatrapdfreader.org/assets/sumatrapdf/docs/img/context-menu-translate-3650.png)

With the [Command Palette](Command-Palette.md):

- select text
- `Ctrl + K`, `Translate Selection with DeepL` command (type `deepl` to find it)

![Using Command Palette](https://files.sumatrapdfreader.org/assets/sumatrapdf/docs/img/cmd-palette-translate-dd89.png)

- press `Enter` (or double-click with the mouse) to execute the action

## Add a service

1. Menu: **Settings → Open Advanced Settings File...** to open the configuration file.
2. Modify the `SelectionHandlers` section.

This adds the [DuckDuckGo](https://duckduckgo.com/) search engine:

```
SelectionHandlers [
  [
    URL = https://duckduckgo.com/?ia=web&q=${selection}
    Name = &DuckDuckGo
    Key = Ctrl + t
  ]
]
```

- `URL` is the website that will be launched. `${selection}` is replaced with the current selection, URL-encoded as a query value (spaces become `%20`, and reserved characters such as `?`, `"`, `&` and `#` become `%XX` so they are not parsed as more URL syntax).
- `Name` is what appears in the menu. Use an `&` character to add a Windows hotkey for keyboard-only invocation.
- **Ver 3.6+:** `Key` is a keyboard shortcut in the same format as in the [`Shortcuts`](Customize-keyboard-shortcuts.md) advanced setting.

## Add a button to the selection toolbar (ver 3.7+)

Selecting text pops up a small toolbar over the selection (turn it off with `SelectionToolbar` in advanced settings). `SelectToolbarNameOrSvg` puts the handler on it, so sending the selection to a service is one click instead of a trip through the context menu:

```
SelectionHandlers [
  [
    URL = https://duckduckgo.com/?q=${selection}
    Name = &DuckDuckGo
    SelectToolbarNameOrSvg = Search
  ]
]
```

![Selection toolbar with a handler button](https://files.sumatrapdfreader.org/assets/sumatrapdf/docs/img/selection-toolbar-handler-0308.png)

The value is the button's text. Keep it short — the toolbar sits over what you are reading, and every handler you add makes it wider. Unlike `Name`, it is shown as you typed it: no `&` hotkey handling, and no translation.

If the value starts with `<svg`, it is an SVG icon drawn instead of the text, in the same format as `ToolbarSvgIcon` in [Customize toolbar](Customize-toolbar.md#using-svg-icons): 24x24, `stroke="currentColor"` and `fill="none"` so the icon picks up the theme's text color, and a full-size `<rect>` so its background comes out transparent. The icon is rendered at `ToolbarSize`, matching main-toolbar icons, and the handler's `Name` is its tooltip. [Tabler Icons](https://tabler.io/icons) are already in that shape:

```
SelectionHandlers [
  [
    URL = https://duckduckgo.com/?q=${selection}
    Name = &DuckDuckGo
    SelectToolbarNameOrSvg = <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><rect x="0" y="0" width="24" height="24" stroke="none"></rect><circle cx="11" cy="11" r="7"></circle><path d="M21 21l-4.35-4.35"></path></svg>
  ]
]
```

Handlers without `SelectToolbarNameOrSvg` are unaffected: they stay in the context menu and the command palette.

## Add a button to the main toolbar (ver 3.7+)

Set `ToolbarText` (a short label) or `ToolbarSvgIcon` (same SVG format as [Customize toolbar](Customize-toolbar.md#using-svg-icons)). If both are set, the icon is used:

```
SelectionHandlers [
  [
    URL = https://duckduckgo.com/?q=${selection}
    Name = &DuckDuckGo
    ToolbarText = DDG
  ]
]
```

## Choose which buttons are on the selection toolbar (Ver 3.7+)

`SelectionToolbarLayout` lists the built-in buttons you want, in the order you want them — the same idea as `ToolbarCustomLayout` for the main toolbar:

```
SelectionToolbarLayout = CmdCopySelection | CmdCreateAnnotHighlight CmdCreateAnnotUnderline
```

- entries are [command ids](Commands.md), separated by spaces (commas and semicolons work too)
- `|` (or `Separator`) inserts a separator
- **leaving a button out is how you hide it**
- an empty value (the default) is the standard set
- names that aren't selection-toolbar buttons are ignored (see the log with `-log`)
- handler buttons from `SelectToolbarNameOrSvg` still come last

The standard selection toolbar written out:

```
SelectionToolbarLayout = CmdCopySelection CmdTranslateSelection CmdReadAloudSelection CmdCreateAnnotHighlight CmdCreateAnnotUnderline CmdCreateAnnotSquiggly CmdCreateAnnotStrikeOut CmdCreateAnnotText
```

## Send long text (ver 3.7+)

A URL can only hold so much text. If you select several paragraphs and send them
to a service with the default settings, the text is shortened to fit and you get
a notification saying so.

`Method` controls how the selection is sent:

| Method             | Length limit | Sees your browser session | Custom headers | Shows result      |
| ------------------ | ------------ | ------------------------- | -------------- | ----------------- |
| `GET` (default)    | ~8000 chars  | yes                       | no             | in a browser tab  |
| `POST`             | none         | no                        | yes            | in a notification |
| `POST-VIA-BROWSER` | none         | yes                       | no             | in a browser tab  |

If `Method` is missing or is `GET`, a handler behaves exactly as it did before
3.7, so existing settings keep working unchanged.

### Why the GET limit exists

With `GET` the selection has to fit in the URL, and URL-encoding makes text
bigger — sometimes much bigger:

- an ASCII letter stays 1 character
- a space becomes `%20`, a newline becomes `%0A` — 3 characters each
- a Chinese, Japanese or Korean character is 3 bytes of UTF-8, so it becomes
  `%XX%XX%XX` — **9 characters**

So the same budget is roughly 8000 Latin characters but only about 900 CJK
characters. When the text doesn't fit, SumatraPDF shortens it at a character
boundary (never in the middle of a character) and tells you it did.

Use `POST` or `POST-VIA-BROWSER` when you need to send more.

### `Method = POST`

SumatraPDF makes the HTTP request itself and puts the selection in the request
body, so there is no length limit. This is the option for API services:

```
SelectionHandlers [
  [
    Name = Send to my API
    URL = https://example.com/api/summarize
    Method = POST
    Headers = Authorization: Bearer my-secret-key
  ]
]
```

- `Body` is the request body. If you leave it out, the body is the raw selection
  and nothing else.
- `ContentType` sets the `Content-Type` header. Default is
  `text/plain; charset=utf-8`, which matches the default raw-selection body.
- `Headers` are extra headers, one per line. A settings value is a single line,
  so separate them by typing `\n`:
  `Headers = Authorization: Bearer key\nX-Client: sumatrapdf`

The request is made by SumatraPDF, **not** by your browser. The service does not
see your cookies or logins — whatever you put in `Headers` is the only
credential it gets. That is usually what you want for an API key, and it means
`POST` will _not_ work with a site that expects you to be signed in; use
`POST-VIA-BROWSER` for those.

The response is not rendered. You get a notification with the HTTP status code
and the beginning of the response body, which is enough to see whether it worked
and what the error was.

### `Method = POST-VIA-BROWSER`

SumatraPDF writes a small temporary HTML page containing a form that submits
itself, and opens it in your default browser. Also unlimited in length, and
because your browser sends it, the service sees your normal session — cookies,
logins and all. That is what you want for a site you're already signed in to.

```
SelectionHandlers [
  [
    Name = Send to my web app
    URL = https://example.com/analyze
    Method = POST-VIA-BROWSER
    Body = text=${selection}&lang=${userlang}
  ]
]
```

`Body` is a form-encoded template: `name=value` pairs separated by `&`. Each
value becomes a hidden form field. If you leave `Body` out, a single field named
`text` is sent.

The template is split into fields **before** substitution, so a selection
containing `&` or `=` can't accidentally create extra fields.

`ContentType` and `Headers` are ignored here — a form submission always posts
`application/x-www-form-urlencoded` and cannot set custom headers. If you need
an `Authorization` header, use `Method = POST`.

Some sites reject a form submitted from a local file (CSRF protection). If that
happens, `POST` with an API key, or `${selectionfile}` with a helper program, is
the way around it.

## Run a program instead of a web service

`${selectionPosition}` is for a helper that wants to sit next to the selection
(a dictionary popup, Anki helper, …). The four integers are the bounding box
of the visible selection in screen pixels, the same space as a Win32
`SetWindowPos`. It is empty if there is no visible selection.

Use `Exe` instead of `URL` to hand the selection to a program. Combined with
`${selectionfile}` there is no length limit at all and no encoding to worry
about, because the text goes through a file rather than the command line:

```
SelectionHandlers [
  [
    Name = Summarize locally
    Exe = "C:\tools\summarize.exe" --pos ${selectionPosition} "${selectionfile}"
  ]
]
```

The temporary file is UTF-8 and lives in your temp directory. It is reused (and
overwritten) the next time a handler runs.

## Tips

- Use `POST` or `POST-VIA-BROWSER` to send more than ~8000 Latin (about 900 CJK) characters.
- Inside a JSON `Body` always use `${selectionjson}`, not `${selection}`.
- Use `Exe` with `${selectionfile}` for no length limit and no encoding to worry about.
- Try a local LLM via Ollama first: no API key, nothing leaves your computer.
- Keep `SelectToolbarNameOrSvg` labels short; every one widens the selection toolbar.
- Remove API keys from `Headers` before sharing your settings file.

## Placeholders

These can be used in `URL`, `Exe`, and `Body`:

| Placeholder            | Replaced with                                                       |
| ---------------------- | ------------------------------------------------------------------- |
| `${selection}`         | the selected text. URL-encoded in `URL`, raw in `Body` / `Exe`      |
| `${selectionjson}`     | the selected text escaped for a JSON string (no surrounding quotes) |
| `${selectionfile}`     | path to a temporary UTF-8 file holding the selection                |
| `${selectionPosition}` | the selection's bounding box in screen pixels, `x,y,dx,dy`          |
| `${userlang}`          | language code of the current UI language, e.g. `de` for German      |

`${selectionjson}` matters more than it looks. Selected text routinely contains
quotes and newlines, and dropping those into a JSON body raw produces invalid
JSON that the service rejects. Inside a JSON body always use `${selectionjson}`,
never `${selection}`:

```
Body = {"text": "${selectionjson}", "target": "de"}
```

## Examples for real services

These are starting points. Check the service's own documentation for the current
endpoint and parameter names rather than assuming these still match.

### DeepL API

DeepL takes form-encoded parameters and an API key in a header. Free accounts
use `api-free.deepl.com`, paid ones use `api.deepl.com`:

```
SelectionHandlers [
  [
    Name = DeepL to German
    URL = https://api-free.deepl.com/v2/translate
    Method = POST
    ContentType = application/x-www-form-urlencoded
    Body = text=${selection}&target_lang=DE
    Headers = Authorization: DeepL-Auth-Key your-key-here
  ]
]
```

This puts the raw selection into a form-encoded body. If your text can contain
`&` or `=`, prefer DeepL's JSON API with `${selectionjson}` instead.

### A local LLM via Ollama

Ollama runs on your own machine and needs no API key, so nothing leaves your
computer — a good thing to try first:

```
SelectionHandlers [
  [
    Name = Summarize with Ollama
    URL = http://localhost:11434/api/generate
    Method = POST
    ContentType = application/json
    Body = {"model": "llama3", "prompt": "Summarize this:\n\n${selectionjson}", "stream": false}
  ]
]
```

### An OpenAI-compatible chat API

Anything speaking the OpenAI chat-completions protocol (OpenAI itself, or a
local server such as LM Studio) works the same way:

```
SelectionHandlers [
  [
    Name = Explain this
    URL = https://api.openai.com/v1/chat/completions
    Method = POST
    ContentType = application/json
    Body = {"model": "gpt-4o-mini", "messages": [{"role": "user", "content": "Explain:\n\n${selectionjson}"}]}
    Headers = Authorization: Bearer sk-your-key-here
  ]
]
```

The reply arrives as raw JSON in a notification. For reading a long answer, a
helper program using `Exe` and `${selectionfile}` is more comfortable.

## A warning about API keys

Anything in `Headers` is stored **in plain text** in your settings file, which is
not encrypted. Don't put a key there that you would mind someone reading if they
got hold of the file, and remove keys before sharing your settings. Prefer keys
that are scoped and revocable.

`POST` also sends your selected text to whichever server you configured. That is
the point of the feature, but it's worth being deliberate about which documents
you use it on.

## See also

- [Customize toolbar](Customize-toolbar.md) — `ToolbarCustomLayout`, SVG icon format
- [Customize keyboard shortcuts](Customize-keyboard-shortcuts.md) — `Key` format
- [Command Palette](Command-Palette.md) — run handlers by name
- [Commands](Commands.md) — ids for `SelectionToolbarLayout`


---

<!-- Advanced-options-settings.md -->

# Advanced settings

You can cusotmize SumatraPDF using [advanced settings](https://www.sumatrapdfreader.org/settings/settings), stored in `SumatraPDF-settings.txt` file.

To edit advanced settings:

- menu `Settings` / `Advanced Settings...` opens setting editor
- or `Ctrl + K` `Advanced Settings...` command in [Command Palette](Command-Palette.md)
- or directly in `Ctrl + K` Command Palette: type `=` for settings editor

Some settings, like keyboard shortcuts, can only be set by editing settings file:
-  menu `Settings` / `Open Advanced Settings File...`
-  or with Command Palette: `Ctrl + K`, type `open settings`, press `Enter`
- or the **Open Settings File** button in the Advanced Settings dialog

This opens `SumatraPDF-settings.txt` file in default .txt editor.  Make changes and save the file.

To reset to default settings, delete settings file. SumatraPDF will re-create it with default values.

Documentation for all settings is at [https://www.sumatrapdfreader.org/settings/settings](https://www.sumatrapdfreader.org/settings/settings)

Here are some things you can customize:

- [keyboard shortcuts](Customize-keyboard-shortcuts.md)
- width of tab with `Tab Width`
- window background color with `FixedPageUI.BackgroundColor`
- color used to highlight text with `FixedPageUI.SelectionColor`
- control scrollbar mode with `FixedPageUI.Scrollbars` (values: `windows`, `smart`, `overlay`, `hidden`)
- CAD / engineering-drawing line rendering enhancements `EngineeringDrawingEnhance` — [CAD / Engineering Drawings](CAD-Engineering-Drawings.md)

Advanced settings file also stores the history and state of opened files so that we can e.g. re-open on the page

## Settings

Below is an explanation of what the different settings mean and what their default values are.

If you add or remove lines with square brackets, **make sure to always add/remove square brackets in pairs**! Else you risk losing all the data following them.

```
; default layout of pages. valid values: automatic, single page, facing, book
; view, continuous, continuous facing, continuous book view, page aspect. page
; aspect (3.7+): first open of a PDF, XPS, DjVu or PostScript file uses page 1 —
; taller than wide is continuous + fit width, wider than tall is single page +
; fit page; a remembered FileState still wins
DefaultDisplayMode = automatic

; default zoom. valid values: fit page, fit width, fit height, fit content, fit
; visible or percent like 100%
DefaultZoom = fit page

; if true, JavaScript in PDF documents is disabled (e.g. form-field calculations
; won't run) (introduced in version 3.7)
DisableJavaScript = false

; if true, a PDF may load an image stored in a separate file referenced by name
; (an external image stream); the file must sit next to the PDF. Off by default
; for security (matches Acrobat) (introduced in version 3.7)
AllowExternalImages = false

; if true, show the SyncTeX inverse search command line in Settings -> Options,
; so a double-click in the document can jump to the matching line in a LaTeX
; editor
EnableTeXEnhancements = false

; if true, Esc key closes SumatraPDF. In presentation or fullscreen mode, Esc
; leaves that mode first
EscToExit = false

; if true, show the full path to the document in the title bar (introduced in
; version 3.0)
FullPathInTitle = false

; pattern used to launch the LaTeX editor when doing inverse search
InverseSearchCmdLine =

; if true, restoring a session delays loading each document until its tab is
; selected (introduced in version 3.6)
LazyLoading = false

; background color of the area around the document, traditionally yellow. Only
; applies to the Light theme; the default #80fff200 is a marker meaning "use the
; theme's color", so setting any other value also colorizes the toolbar and
; sidebars
MainWindowBackground = #80fff200

; if true, doesn't open Home tab
NoHomeTab = false

; if true, the home page lists documents by how often they've been opened (the
; pre-3.6 behavior); if false, the most recently opened come first
HomePageSortByFrequentlyRead = false

; valid values: thumbnails, list (introduced in version 3.7)
HomePageViewMode = thumbnails

; valid values: (empty), os, sumatrapdf (introduced in version 3.7)
FilePicker = 

; valid values: (empty), auto, modern, classic (introduced in version 3.7)
PrinterUI = 

; if true, a document will be reloaded automatically whenever it's changed
; (currently doesn't work for documents shown in the ebook UI) (introduced in
; version 2.5)
ReloadModifiedDocuments = true

; if true, keep a history of opened documents and their display settings
; (FileStates); closing a document doesn't remove it from the history. Also
; required for saving SessionData
RememberOpenedFiles = true

; if true, store display settings for each document separately (i.e. everything
; after UseDefaultState in FileStates)
RememberStatePerDocument = true

; if true, documents that were still open when the last window was closed
; (SessionData) are reopened at startup
RestoreSession = true

; if true, open documents in the already running SumatraPDF instead of starting
; a new one
ReuseInstance = true

; if true, show the menu bar (F9 toggles it; the choice is remembered across
; sessions) (introduced in version 2.5)
ShowMenubar = true

; if true, show the menu bar when using tabs (useTabs = true) (introduced in
; version 3.7)
ShowMenubarWithTabs = false

; if true, show the current page as n/N after the file name on tabs (introduced
; in version 3.7)
ShowPageNumberInTabs = false

; if true, show reading progress (n/N, or chapter:page for ebooks) on home page
; thumbnails and list rows (introduced in version 3.7)
ShowHomePageReadingProgress = true

; if true, a document with chapters (EPUB, MOBI) shows the current place as a
; chapter and a page within that chapter, in the toolbar, Go to Page and the
; page-info tip. if false, those show one page number for the whole document.
; the saved position stays a chapter bookmark either way, and next / previous
; page still cross chapters (introduced in version 3.7)
ShowChaptersInEbooks = false

; if true, show tips on the home page (introduced in version 3.7)
ShowTips = true

; up to 13 custom colors for the background color picker, separated by space
; (e.g. '#ff0000 #00ff00 #0000ff') (introduced in version 3.7)
CustomColors =

; legacy bool for toolbar; if Toolbar is empty, derived as show/hide (internal;
; use Toolbar instead)
ShowToolbar = true

; toolbar mode: show (pinned), hide (no toolbar), overlay (toolbar floats over
; the page, sized to its natural width and centered, only shown when the mouse
; is near it). if empty, derived from ShowToolbar (introduced in version 3.7)
Toolbar = show

; where the toolbar is placed: top or bottom (applies to both show and overlay
; modes) (introduced in version 3.7)
ToolbarPosition = top

; if true, the find UI is a floating, movable window with a results list instead
; of the compact toolbar overlay (introduced in version 3.7)
SearchUIFloating = false

; if true, show the sidebar's bottom panel: Favorites, unless SidebarBottomView
; says otherwise
ShowFavorites = false

; what the sidebar's bottom panel shows: favorites (the default), bookmarks or
; thumbnails (introduced in version 3.7)
SidebarBottomView =

; if true, favorites within each file are sorted alphabetically by name (or page
; label); if false (the default), they are sorted by page number (introduced in
; version 3.7)
SortFavoritesByName = false

; if true, show the table of contents (Bookmarks) sidebar when the document has
; one
ShowToc = true

; if true, every document with bookmarks opens with the Bookmarks sidebar, even
; one that was closed with it hidden (introduced in version 3.7)
AlwaysShowSidebar = false

; if true, put the bookmarks / favorites sidebar on the right of the window
; (left is the default; right-to-left UI languages already put it on the right)
; (introduced in version 3.7)
SidebarOnRight = false

; valid values: (empty), keep, grow (introduced in version 3.7)
SidebarWindowSize = 

; if true, draw a blue border around links in the document (introduced in
; version 3.6)
ShowLinks = false

; if true, highlight empty fillable PDF form fields in pale blue so they are
; easy to find (introduced in version 3.7)
HighlightFormFields = true

; if true, a click (not a drag) on the left fifth of the page area goes to the
; previous page and a click on the right fifth goes to the next page (reversed
; in manga / right-to-left mode). Links, annotations and presentation-mode
; clicks are unchanged (introduced in version 3.7)
ClickEdgeToTurnPage = false

; if true, document links are ignored so you can select and read (useful for
; drawings with many links); if false, clicking a link follows it (introduced in
; version 3.7)
DisableLinks = false

; if true, Space in File Explorer (or on the desktop) previews the selected file
; in a popup window, like macOS Quick Look. Esc or Space closes it; Left / Right
; open the previous / next file in the folder. Starts a small background helper
; at logon so it works even when SumatraPDF is not open (introduced in version
; 3.7)
ExplorerQuickLook = false

; if true, next/previous page keeps the same view position on the page instead
; of jumping to the top (useful when zoomed in on similarly sized pages)
; (introduced in version 3.7)
RememberViewOffsetOnPageTurn = false

; if true, one mouse-wheel notch goes to the next / previous page instead of
; scrolling; combine with RememberViewOffsetOnPageTurn to read zoomed-in pages
; without touching the keyboard. Alt + wheel still scrolls, Shift + wheel
; scrolls horizontally and Ctrl + wheel zooms (introduced in version 3.7)
MouseWheelTurnsPage = false

; if true, in single page / facing / book view, scrolling past the top or bottom
; of a zoomed-in page goes to the previous / next page; if false, scrolling
; stops at the edge and the page is changed only by the keyboard, toolbar or
; scrollbar. A page that fits the window has nothing to scroll, so a wheel notch
; turns it either way (introduced in version 3.7)
ScrollEdgeTurnsPage = true

; if true, draw a focus ring around the document when it has keyboard focus (Tab
; to the page area) (introduced in version 3.7)
ShowDocumentFocusIndicator = false

; if true, show a tip when hovering an annotation (e.g. "Highlight annotation.
; Ctrl+click to edit.") (introduced in version 3.7)
ShowAnnotationNotification = true

; if true, at the end of a document show a hint to open the next file in the
; folder. Closing the hint sets it to false (introduced in version 3.7)
ShowFileNavigateHint = true

; if true, show the author at the bottom of an annotation tooltip as "Author:
; <author>" (introduced in version 3.7)
ShowAnnotationAuthorInTooltip = false

; if true, show page numbers (labels) right-aligned on bookmark /
; table-of-contents entries (introduced in version 3.7)
ShowTocPageNumbers = true

; if true, a PDF without an outline gets a table of contents built from numbered
; headings in its text (Generate Table Of Contents command does it on demand)
; (introduced in version 3.7)
AutoGenerateTOC = false

; if true, show a list of frequently read documents when no document is loaded
ShowStartPage = true

; width of the favorites / bookmarks sidebar in screen pixels, as last resized
; (0 means the default)
SidebarDx = 0

; scrollbar mode: windows (standard Windows scrollbar), smart (overlay scrollbar
; with auto-hide), overlay (always visible overlay scrollbar), hidden (no
; scrollbars) (introduced in version 3.7)
Scrollbars = windows

; if true, show a scrollbar in single page mode as well (introduced in version
; 3.6)
ScrollbarInSinglePage = false

; if true, smooth mouse-wheel and arrow-key scrolling (exponential chase of the
; target; continuous input stays fluid) (introduced in version 3.6)
SmoothScroll = true

; distance, in screen pixels at 96 DPI, scrolled by an arrow-key press or one
; mouse-wheel line; values below 1 use 16 (introduced in version 3.7)
ScrollLineAmount = 16

; how hard to free unused page and image caches to save RAM (0 to 100). 0 keeps
; them until an allocation fails; 100 drops them as soon as a page is off-screen
; (introduced in version 3.7)
SaveMemory = 50

; if true, continuous view has extra scroll room after the last page so you can
; scroll the end of the document to the top of the window (introduced in version
; 3.7)
PaddingAfterLastPage = false

; if true, going to a destination (clicking a bookmark or a link inside the
; document) keeps the current zoom instead of applying the zoom the destination
; asks for; it still goes to the page and the position. Same as Adobe Reader's
; 'forbid the change of the current zoom factor during execution of Go to
; Destination actions' (introduced in version 3.7)
IgnoreDestinationZoom = false

; if true, following an internal link or bookmark flashes a highlight at the
; destination so you can see where you landed (a bibliography entry, figure, or
; named destination). The color and fade match ForwardSearch. Off when the
; destination is only a page with no position (introduced in version 3.7)
HighlightLinkDestination = false

; how long an internal-document link has to be hovered, in milliseconds, before
; a popup rendering the destination region (citation entry, figure, footnote)
; appears. -1 (the default) disables the popup; set a positive value like 300 to
; enable it (introduced in version 3.7)
CitationHoverDelay = -1

; voice id for Read Aloud text-to-speech; empty or unset means system default.
; Voice ids match those used internally by the Read Aloud Voice menu (WinRT
; voice id or SAPI token id) (introduced in version 3.7)
ReadAloudVoiceId =

; playback speed multiplier for Read Aloud text-to-speech (0.5 .. 3.0), 1 is
; normal speed; can also be changed from the Read Aloud playback bar (introduced
; in version 3.7)
ReadAloudSpeed = 1

; pixels per second for Automatically Scroll (View menu / Ctrl+Shift+H). 8 to
; 320; also changed from the auto-scroll bar and the arrow keys while scrolling
; (introduced in version 3.7)
ReadingAutoScrollSpeed = 40

; reading bar (View menu): a horizontal band on the page to keep your place.
; Highlight fills the band; Invert dims everything else (introduced in version
; 3.7)
ReadingBar [
    ; fill of the reading bar in highlight mode. #aarrggbb sets opacity (00 =
    ; transparent, FF = opaque); #rrggbb is fully opaque (introduced in version
    ; 3.7)
    Background = #66ffe082

    ; if true, dim the page except the reading bar (screen mask); if false, draw
    ; a colored highlight band (introduced in version 3.7)
    Invert = false

    ; height of the reading bar in pixels at 96 DPI; 0 uses a default of about
    ; three lines. dragging the top or bottom edge of the bar also changes this
    ; (introduced in version 3.7)
    Height = 0
]

; if true, mouse wheel scrolling is faster when mouse is over a scrollbar
; (introduced in version 3.6)
FastScrollOverScrollbar = false

; if true, prevents the screen from turning off when in fullscreen or
; presentation mode
PreventSleepInFullscreen = true

; maximum width of a single tab, in pixels at 100% display scaling (at least 60)
TabWidth = 300

; valid themes: Light, Dark, Light Warm, Dark from 3.5, Charcoal, Solarized
; Light, Solarized Dark, Dracula, Nebula, Greeny, Choco, Purpy, One Dark,
; Monokai, Nord, GitHub Dark, Catppuccin Mocha, Tokyo Night, Gruvbox, Night Owl,
; Ayu, Palenight, System (introduced in version 3.5)
Theme = Light

; color theme of the in-app manual (F1): app (follow the app's theme), light or
; dark. The switch in the manual's top-right corner changes it (introduced in
; version 3.7)
HelpTheme = app

; the light theme the light/dark toggle and the System theme switch to
; (introduced in version 3.7)
LastLightTheme = 

; the dark theme the light/dark toggle and the System theme switch to
; (introduced in version 3.7)
LastDarkTheme = 

; how MuPDF-rendered documents (PDF, XPS, DjVu, EPUB, MOBI, FB2, CBZ, images,
; etc.) use UI / FixedPageUI colors for the page. Values: off (document's own
; colors; default); smart (recolor text and page background, keep photos/images
; as-is — best for dark reading); legacy (also recolor images; pre-3.7
; invert-style). Does not change menus/toolbars — use Theme for UI chrome.
; Settings / Theme and the CmdSetDocumentColorsFollowTheme command set all three
; values. Shift+I (Invert Colors) is separate: it swaps the page colors for the
; session whatever this is set to (introduced in version 3.7)
DocumentColorsFollowTheme = off

; if both the favorites and the bookmarks part of the sidebar are visible, this
; is the height of the bookmarks (table of contents) part, in screen pixels
TocDy = 0

; the toolbar's built-in buttons, in the order you want them, e.g. CmdOpenFile
; CmdPrint PageInfo | CmdFindFirst. Leave a button out to hide it. | is a
; separator and PageInfo is the page number box. Empty (the default) means the
; standard layout. Buttons you added yourself (see Shortcuts) still come last
; (introduced in version 3.7)
ToolbarCustomLayout = 

; if true, the toolbar has a Read Aloud button (with a drop-down for voice,
; speed and what to read). Read Aloud is still reachable from the Read Aloud
; menu when this is false (introduced in version 3.7)
ToolbarShowReadAloud = false

; size of the toolbar icons in pixels at 100% display scaling (8-64); the
; toolbar itself is a few pixels taller (introduced in version 3.4)
ToolbarSize = 18

; font name for bookmarks and favorites tree views. automatic means Windows
; default
TreeFontName = automatic

; font size for bookmarks and favorites tree views, in pixels; 0 means the
; Windows default. Not scaled by the display scaling (introduced in version 3.3)
TreeFontSize = 0

; overrides the font size used for menus, toolbar and dialogs, in pixels; 0
; means the Windows default. Not scaled by the display scaling (introduced in
; version 3.6)
UIFontSize = 0

; if true, render MuPDF-based documents (PDF, XPS, DjVu, EPUB etc.) without
; anti-aliasing, giving sharper but jagged edges (introduced in version 3.6)
DisableAntiAlias = false

; CAD/engineering PDF line rendering: off, auto (enhance if a CAD drawing is
; detected) or on (introduced in version 3.7)
EngineeringDrawingEnhance = off

; if true, disables auto-linking of URLs and email addresses found in PDF text
; (introduced in version 3.7)
DisableAutoLinks = false

; if true, use the Windows system colors for the document background and text.
; Overrides other color settings
UseSysColors = false

; if true, documents are opened in tabs instead of new windows (introduced in
; version 3.0)
UseTabs = true

; if true, a small floating toolbar with selection actions (copy, read aloud,
; highlight etc.) pops up after selecting text. Set to false to disable it
; (introduced in version 3.7)
SelectionToolbar = true

; which built-in buttons the selection toolbar has and in what order, e.g.
; CmdCopySelection | CmdCreateAnnotHighlight. | or Separator inserts a
; separator. Leave a button out to hide it. Empty (the default) is the standard
; set. SelectionHandlers with SelectToolbarNameOrSvg still come last (introduced
; in version 3.7)
SelectionToolbarLayout = 

; if true, Ctrl+Tab and Ctrl+Shift+Tab show the tab switcher in most recently
; used order instead of tab-strip order (introduced in version 3.7)
TabsMru = false

; if true, Ctrl+Tab and Ctrl+Shift+Tab immediately switch to the next / previous
; tab in tab-strip order (the behavior before version 3.6) instead of showing
; the tab switcher (introduced in version 3.7)
CtrlTabSimple = false

; sequence of zoom levels when zooming in/out; values must lie between 8.33 and
; 1000000 (the largest one becomes the maximum zoom, which is 6400 by default)
ZoomLevels = 

; how much a single zoom in / zoom out step changes the zoom, as a percentage of
; the current zoom level. If 0 or negative, zooming steps through ZoomLevels
; instead
ZoomIncrement = 0

; customization options for PDF, XPS, DjVu and PostScript UI
FixedPageUI [
    ; if true, render document pages in grayscale. Toggle with
    ; CmdToggleGrayscale (introduced in version 3.7)
    Grayscale = false

    ; color used instead of black for the document's text
    TextColor = #000000

    ; color used instead of white for the document's page background
    BackgroundColor = #ffffff

    ; color value for the text selection rectangle (also used to highlight found
    ; text). Use an #aarrggbb value to control opacity: a smaller alpha (e.g.
    ; #40ffff00) makes the selection more transparent so the selected text stays
    ; crisp; #rrggbb uses the default opacity (introduced in version 2.4)
    SelectionColor = #ffff00

    ; top, right, bottom and left margin (in that order) between window and
    ; document
    WindowMargin = 2 4 2 4

    ; horizontal and vertical gap between pages (between columns in facing/book
    ; view, between rows in continuous view)
    PageSpacing = 4 4

    ; experimental: instead of a single background color, fade through these
    ; colors from the top of the document to the bottom (stops are spread
    ; evenly, at most 3 colors). The shifting background is meant to give a
    ; subconscious sense of reading progress. Suggested values: #2828aa #28aa28
    ; #aa2828
    GradientColors =

    ; if given, sets the canvas background color for PDF files (introduced in
    ; version 3.7)
    WindowBgCol = 

    ; measurement grid overlay (View > Page Grid). Spacing and style are saved;
    ; showing the grid is session-only (introduced in version 3.7)
    PageGrid [
        ; distance between major vertical grid lines, in PDF points (1/72 inch)
        ; (introduced in version 3.7)
        Width = 72

        ; distance between major horizontal grid lines, in PDF points
        ; (introduced in version 3.7)
        Height = 72

        ; minor lines per major cell (introduced in version 3.7)
        Subdivisions = 4

        ; horizontal origin offset from the left of the page, in PDF points
        ; (introduced in version 3.7)
        OffsetX = 0

        ; vertical origin offset from the bottom of the page, in PDF points
        ; (introduced in version 3.7)
        OffsetY = 0

        ; color of the page grid overlay (introduced in version 3.7)
        Color = #8080ff

        ; grid overlay style: dots (marks at intersections), dotted (dotted
        ; lines), or solid (introduced in version 3.7)
        Style = dots

        ; units shown in the Configure Page Grid dialog: pt, in, mm, or cm
        ; (introduced in version 3.7)
        Units = in
    ]
]

; customization options for the ebook UI (EPUB, MOBI, FB2, PDB and plain text)
EBookUI [
    ; default font family for ebooks (e.g. Segoe UI, Georgia, Microsoft YaHei).
    ; empty uses the engine default (typically a serif). applied as user CSS
    ; with !important, which beats the document's own font-family even when it
    ; comes from an inline style attribute; leave empty to keep the publisher's
    ; fonts. wrapping quotes are stripped. a name that can't be loaded is
    ; reported with a notification when the document opens (introduced in
    ; version 3.7)
    FontName = 

    ; font size in points; 0 means the default (8.0)
    FontSize = 0

    ; white space around the text, in points (not screen pixels), like LayoutDx.
    ; one number sets all four sides, two are top/bottom and left/right, four
    ; are top, right, bottom, left - the same order as in CSS. empty keeps the
    ; default (3 em above and below, 2 em left and right, so it follows the font
    ; size); 0 leaves no margin at all. each value can be up to 200 (introduced
    ; in version 3.7)
    Margin =

    ; line-height multiplier for ebook text (e.g. 1.5); 0 keeps the document or
    ; engine default. values from 0.5 to 5 are accepted (introduced in version
    ; 3.7)
    LineSpacing = 0

    ; width of the page the ebook is laid out into, in points (not screen
    ; pixels); 0 means the default (420)
    LayoutDx = 0

    ; height of the page the ebook is laid out into, in points (not screen
    ; pixels); 0 derives it from the window's shape when the document is opened,
    ; so Fit Width shows a whole page
    LayoutDy = 0

    ; if true, the CSS in the ebook is ignored and only CustomCSS applies
    IgnoreDocumentCSS = false

    ; additional CSS applied to ebooks; set IgnoreDocumentCSS = true if the
    ; document's own CSS overrides it
    CustomCSS =

    ; if given, sets the canvas background color for ebook documents (epub, mobi
    ; etc.) (introduced in version 3.7)
    WindowBgCol = 

    ; default page layout for ebooks; empty uses the global DefaultDisplayMode.
    ; valid values: automatic, single page, facing, book view, continuous,
    ; continuous facing, continuous book view (introduced in version 3.7)
    DefaultDisplayMode = 
]

; customization options for Comic Book UI
ComicBookUI [
    ; top, right, bottom and left margin (in that order) between window and
    ; document
    WindowMargin = 0 0 0 0

    ; horizontal and vertical gap between pages (between columns in facing/book
    ; view, between rows in continuous view)
    PageSpacing = 4 4

    ; if true, documents that don't state their own reading direction default to
    ; manga mode, i.e. right to left. A document that states a direction (PDF
    ; ViewerPreferences/Direction, or an EPUB with page-progression-direction)
    ; is shown the way it asks for
    CbxMangaMode = false

    ; if given, sets the canvas background color for comic book files
    ; (introduced in version 3.7)
    WindowBgCol = 

    ; if true, absolute zoom never makes a page wider than the window (each page
    ; is capped at Fit Width). Useful for comics/manga with double-page spreads
    ; that are much wider than regular pages (issue #2197) (introduced in
    ; version 3.7)
    LimitToWindowWidth = false

    ; if true, absolute zoom never makes a page taller than the window (each
    ; page is capped at Fit Height) (introduced in version 3.7)
    LimitToWindowHeight = false

    ; default page layout for comic books; empty uses the global
    ; DefaultDisplayMode. valid values: automatic, single page, facing, book
    ; view, continuous, continuous facing, continuous book view (introduced in
    ; version 3.7)
    DefaultDisplayMode = 

    ; default zoom for comic books; empty uses fit page. valid values: fit page,
    ; fit width, fit height, fit content, fit visible, shrink to fit or percent
    ; like 100% (introduced in version 3.7)
    DefaultZoom = 

    ; if true, in facing and book view a landscape page (wider than tall)
    ; occupies the whole two-page row instead of pairing with the next page. For
    ; comics that store double-page spreads as one image (issues #1324, #872)
    ; (introduced in version 3.7)
    LandscapeAsSpread = true
]

; customization options for image files UI
ImageUI [
    ; if given, sets the canvas background color for image files (introduced in
    ; version 3.7)
    WindowBgCol = 

    ; default zoom for image files. valid values: fit page, fit width, fit
    ; height, fit content, fit visible, shrink to fit or percent like 100%
    ; (introduced in version 3.7)
    DefaultZoom = shrink to fit

    ; if true, absolute zoom never makes a page wider than the window (each page
    ; is capped at Fit Width). Useful for image folders with mixed aspect ratios
    ; (issue #2197) (introduced in version 3.7)
    LimitToWindowWidth = false

    ; if true, absolute zoom never makes a page taller than the window (each
    ; page is capped at Fit Height) (introduced in version 3.7)
    LimitToWindowHeight = false

    ; if true, in facing and book view a landscape page (wider than tall)
    ; occupies the whole two-page row instead of pairing with the next page
    ; (issues #1324, #872) (introduced in version 3.7)
    LandscapeAsSpread = true
]

; customization options for CHM UI. UseFixedPageUI switches to the PDF-style
; view; FontName applies to that view
ChmUI [
    ; if true, the UI used for PDF documents will be used for CHM documents as
    ; well
    UseFixedPageUI = false

    ; font family for the CHM fixed-page view (e.g. Segoe UI, Georgia, Microsoft
    ; YaHei). empty uses EBookUI.FontName or the engine default. overrides fonts
    ; specified by the document; wrapping quotes are stripped (introduced in
    ; version 3.7)
    FontName =
]

; customization options for Markdown UI. If UseFixedPageUI is true, MuPDF is
; used; otherwise WebView2 browser view is used when available
MarkdownUI [
    ; if true, use MuPDF (cmark-gfm) to render markdown; if false, use WebView2
    ; browser view when available
    UseFixedPageUI = false
]

; customization options for HTML UI. If UseFixedPageUI is true, MuPDF is used;
; otherwise WebView2 browser view is used when available (introduced in version
; 3.7)
HtmlUI [
    ; if true, use MuPDF to render HTML; if false, use WebView2 browser view
    ; when available
    UseFixedPageUI = false
]

; settings for the Claude Code chat sidebar (introduced in version 3.7)
ClaudeCode [
    ; Claude model alias for --model (e.g. sonnet, opus, haiku); uses opus if
    ; not in the model list
    Model = sonnet

    ; extra Claude model aliases for the dropdown, comma-separated; documented
    ; Claude Code aliases are always included
    Models = 

    ; Claude effort level: 0=Low, 1=Medium, 2=High, 3=Max
    Effort = 1

    ; if true, pass --dangerously-skip-permissions to Claude Code
    SkipPermissions = false

    ; background color of the Claude Code chat panel
    BgColor = #ffffff
]

; settings for the Grok Build chat sidebar (introduced in version 3.7)
GrokBuild [
    ; Grok model ID for --model (e.g. grok-4.5)
    Model = grok-4.5

    ; extra Grok model IDs for the dropdown, comma-separated; used in addition
    ; to models reported by Grok
    Models = 

    ; Grok effort level: 0=Low, 1=Medium, 2=High, 3=XHigh, 4=Max
    Effort = 1

    ; if true, pass --always-approve to Grok Build (auto-approve tool
    ; executions)
    AlwaysApprove = false

    ; background color of the Grok Build chat panel
    BgColor = #ffffff
]

; settings for the OpenAI Codex chat sidebar (introduced in version 3.7)
CodexBuild [
    ; Codex model ID for -m (e.g. gpt-5.5, gpt-5.4, o3)
    Model = gpt-5.5

    ; extra Codex model IDs for the dropdown, comma-separated; used in addition
    ; to models reported by Codex
    Models = 

    ; Codex sandbox mode: 0=read-only, 1=workspace-write, 2=danger-full-access
    Sandbox = 1

    ; if true, pass --dangerously-bypass-approvals-and-sandbox to Codex
    SkipSandbox = false

    ; background color of the OpenAI Codex chat panel
    BgColor = #ffffff
]

; settings for the Antigravity chat sidebar (introduced in version 3.7)
AntiGravity [
    ; Antigravity model ID for --model (e.g. gemini-3.8-flash-medium)
    Model = gemini-3.8-flash-medium

    ; extra Antigravity model IDs for the dropdown, comma-separated
    Models = 

    ; Antigravity effort level: 0=Low, 1=Medium, 2=High, 3=Max
    Effort = 1

    ; if true, pass --dangerously-skip-permissions to Antigravity CLI so it can
    ; read the current file etc. in headless print mode (agy cannot prompt for
    ; permissions with -p)
    AutoApprove = true

    ; background color of the Antigravity chat panel
    BgColor = #ffffff
]

; width of the AI chat sidebar (0 = use default); shared by Claude Code, Grok
; Build, and OpenAI Codex (internal) (introduced in version 3.7)
AIChatSidebarDx = 0

; remembered destination language for selection translation; empty uses OS UI
; language (introduced in version 3.7)
TranslateToLang = 

; remembered source language for selection translation; empty means Auto
; (introduced in version 3.7)
TranslateFromLang = 

; remembered engine for Translate Selection: Google, DeepL, Grok Build, Claude
; Code, OpenAI Codex or Antigravity (introduced in version 3.7)
TranslateEngine = 

; default values for annotations in PDF documents (introduced in version 3.3)
Annotations [
    ; color of newly created highlight annotations. Use an #aarrggbb value to
    ; set default opacity (00 = transparent, FF = opaque); #rrggbb is fully
    ; opaque
    HighlightColor = #ffff00

    ; color of newly created underline annotations. #aarrggbb sets default
    ; opacity the same way as HighlightColor
    UnderlineColor = #8bf05d

    ; color of newly created squiggly underline annotations. #aarrggbb sets
    ; default opacity the same way as HighlightColor (introduced in version 3.5)
    SquigglyColor = #f199d2

    ; color of newly created strike out annotations. #aarrggbb sets default
    ; opacity the same way as HighlightColor (introduced in version 3.5)
    StrikeOutColor = #e24745

    ; text color of newly created free text annotations (introduced in version
    ; 3.5)
    FreeTextColor = 

    ; background color of newly created free text annotations (introduced in
    ; version 3.6)
    FreeTextBackgroundColor = 

    ; opacity of free text annotation in percent (0-100); 0 - fully transparent
    ; (invisible), 50 - half transparent, 100 - fully opaque (introduced in
    ; version 3.6)
    FreeTextOpacity = 100

    ; font size of free text annotations, in points (introduced in version 3.5)
    FreeTextSize = 12

    ; border width of free text annotations, in points (introduced in version
    ; 3.5)
    FreeTextBorderWidth = 1

    ; how text is aligned in newly created free text annotations (Text Alignment
    ; in the compact property row): left, center or right. Right-to-left scripts
    ; (Arabic, Hebrew, Persian) want right (introduced in version 3.7)
    FreeTextAlignment = left

    ; colors offered by the drop-down on the annotation toolbar's buttons,
    ; separated by space. Picking one sets the color of new annotations of that
    ; type. The color a button currently makes annotations in is added when it
    ; is missing (introduced in version 3.7)
    PresetColors = #ffff00 #8bf05d #99defa #f199d2 #e24745 #ff0000 #0000ff #000000

    ; color of newly created text (sticky note) annotations
    TextIconColor = 

    ; color of newly created line annotations. If not set, the PDF engine's
    ; default (red) is used (introduced in version 3.7)
    LineColor = 

    ; color of newly created polyline annotations. If not set, the PDF engine's
    ; default (red) is used (introduced in version 3.7)
    PolyLineColor = 

    ; color of newly created square annotations. If not set, the PDF engine's
    ; default (red) is used (introduced in version 3.7)
    SquareColor = 

    ; color of newly created circle annotations. If not set, the PDF engine's
    ; default (red) is used (introduced in version 3.7)
    CircleColor = 

    ; color of newly created polygon annotations. If not set, the PDF engine's
    ; default (red) is used (introduced in version 3.7)
    PolygonColor = 

    ; color of newly created ink annotations, as #aarrggbb: the alpha is how
    ; translucent the stroke is (00 = transparent, FF = opaque), so the color is
    ; exactly what ends up on the page (introduced in version 3.7)
    InkColor = #66ffff00

    ; colors offered by the ink button's drop-down, separated by space. Use
    ; #aarrggbb values: the alpha is the stroke's opacity. The color ink
    ; currently draws in is added when it is missing (introduced in version 3.7)
    InkColors = #66ffff00 #668bf05d #6699defa #66f199d2 #66e24745

    ; width of the stroke of new ink annotations, in points (introduced in
    ; version 3.7)
    InkBorderWidth = 16

    ; color of newly created stamp annotations. If not set, the PDF engine's
    ; default (red) is used (introduced in version 3.7)
    StampColor = 

    ; color of newly created caret annotations. If not set, the PDF engine's
    ; default (red) is used (introduced in version 3.7)
    CaretColor = 

    ; color of newly created file attachment annotations. If not set, the PDF
    ; engine's default (red) is used (introduced in version 3.7)
    FileAttachmentColor = 

    ; icon shown for text (sticky note) annotations: comment, help, insert, key,
    ; new paragraph, note or paragraph. If not set, note is used
    TextIconType = 

    ; author recorded on newly created annotations. If not set, the Windows user
    ; name is used; set it to (none) to leave the author out entirely
    ; (introduced in version 3.4)
    DefaultAuthor = 

    ; image (e.g. a transparent .png of your signature) that Sign With Image
    ; stamps on the page. If not set, or the file is missing, Sign With Image
    ; asks for an image (introduced in version 3.7)
    SignatureImage =
]

; list of additional external viewers for various file types. See docs for more information (https://www.sumatrapdfreader.org/docs/Customize-external-viewers)
ExternalViewers [
  [
    ; command line with which to call the external viewer, may contain %p for
    ; page number and "%1" for the file name (add quotation marks around paths
    ; containing spaces)
    CommandLine =

    ; name of the external viewer to be shown in the menu (implied by
    ; CommandLine if missing)
    Name =

    ; optional filter for which file types the menu item is to be shown;
    ; separate multiple entries using ';' and don't include any spaces (e.g.
    ; *.pdf;*.xps for all PDF and XPS documents)
    Filter =

    ; optional: keyboard shortcut e.g. Alt + 7 (introduced in version 3.6)
    Key =

    ; if given, shows in toolbar (introduced in version 3.7)
    ToolbarText =

    ; optional SVG icon for toolbar button; if both ToolbarSvgIcon and
    ; ToolbarText are set, the icon is used (introduced in version 3.7)
    ToolbarSvgIcon =
  ]
]

; customization options for how forward search results are shown (used from
; LaTeX editors)
ForwardSearch [
    ; if greater than 0, the forward search result is marked with a bar down the
    ; left side of the page instead of highlighting the matched text. The value
    ; is how far the bar sits from the left edge of the page, in document units
    HighlightOffset = 0

    ; width of that bar in document units (only used when HighlightOffset is
    ; greater than 0)
    HighlightWidth = 15

    ; color used for the forward search highlight
    HighlightColor = #6581ff

    ; if true, the highlight stays visible until the next mouse click instead of
    ; fading away after a few seconds
    HighlightPermanent = false
]

; these override the default settings in the Print dialog
PrinterDefaults [
    ; default value for scaling (shrink, fit, none)
    PrintScale = shrink

    ; default value for collate in the print dialog (default, collate,
    ; nocollate) (introduced in version 3.7)
    Collate = default

    ; resolution to assume for the document when printing at original size (e.g.
    ; 300 for a 300 dpi scan whose file doesn't say); 0 uses the resolution
    ; recorded in the file (introduced in version 3.7)
    PrintDpi = 0
]

; options for fullscreen mode (introduced in version 3.7)
Fullscreen [
    ; legacy bool for fullscreen toolbar; if Fullscreen.Toolbar is empty,
    ; derived as show/hide (internal; use Fullscreen.Toolbar instead)
    ShowToolbar = false

    ; toolbar mode in fullscreen: show (pinned), hide (no toolbar), overlay
    ; (toolbar floats over the page, only shown when the mouse is near it). if
    ; empty, derived from Fullscreen.ShowToolbar (introduced in version 3.7)
    Toolbar = hide

    ; if true, show the menu bar in fullscreen mode
    ShowMenubar = false

    ; page layout in presentation (Ctrl+L) and windowed fullscreen (Shift+Ctrl+L
    ; / F11). empty keeps the current behavior: presentation uses single page,
    ; windowed fullscreen keeps the existing layout. valid values: automatic,
    ; single page, facing, book view, continuous, continuous facing, continuous
    ; book view (introduced in version 3.7)
    DisplayMode = 
]

; list of handlers for selected text, shown in context menu when text selection
; is active. See docs for more information (https://www.sumatrapdfreader.org/docs/Customize-search-translation-services)
SelectionHandlers [
  [
    ; url to invoke for the selection. ${selection} is the selected text,
    ; ${userlang} the UI language (e.g. 'de'), ${selectionPosition} the
    ; selection's screen rect as x,y,dx,dy
    URL =

    ; name shown in context menu
    Name =

    ; keyboard shortcut (introduced in version 3.6)
    Key =

    ; command line of a program to run instead of opening a URL. Use
    ; ${selectionfile} to pass the selection as a temporary utf-8 file, which
    ; has no length limit, and ${selectionPosition} for the selection's screen
    ; rect (x,y,dx,dy). If set, URL is ignored (introduced in version 3.7)
    Exe =

    ; how to send the selection. GET (default) puts it in the URL, which limits
    ; how much text fits. POST sends it in the request body with no length limit
    ; and shows the response. POST-VIA-BROWSER submits a form from your browser
    ; instead, so the service sees your normal browser session (cookies, logins)
    ; (introduced in version 3.7)
    Method = GET

    ; request body for POST / POST-VIA-BROWSER; the same ${selection},
    ; ${selectionjson}, ${userlang} and ${selectionPosition} substitutions
    ; apply. If unset, the body is the raw selection (introduced in version 3.7)
    Body =

    ; value of the Content-Type header for POST. Defaults to 'text/plain;
    ; charset=utf-8', which matches the default raw-selection body. Use
    ; 'application/json' or 'application/x-www-form-urlencoded' when Body is in
    ; that format. Ignored by POST-VIA-BROWSER, which always submits a form
    ; (introduced in version 3.7)
    ContentType =

    ; extra HTTP headers for POST, one per line as 'Name: value' (use \n to
    ; separate them in this file). Needed for services that authenticate with an
    ; api key, e.g. 'Authorization: Bearer sk-...'. Ignored by POST-VIA-BROWSER.
    ; Note that anything you put here is stored in plain text in this settings
    ; file (introduced in version 3.7)
    Headers =

    ; if set, the handler also gets a button on the floating selection toolbar.
    ; The value is the button's text, or, if it starts with '<svg', an icon to
    ; draw instead. SVG buttons use Name as their tooltip and ToolbarSize as
    ; their icon size (introduced in version 3.7)
    SelectToolbarNameOrSvg =

    ; if set, the handler also gets a button on the main toolbar with this label
    ; (introduced in version 3.7)
    ToolbarText =

    ; optional SVG icon for that main-toolbar button; if both ToolbarSvgIcon and
    ; ToolbarText are set, the icon is used (introduced in version 3.7)
    ToolbarSvgIcon =
  ]
]

; predefined text inserted as a free text annotation from the context menu or
; the command palette (introduced in version 3.7)
TextSnippets [
  [
    ; name shown in the context menu and the command palette
    Name =

    ; text of the free text annotation it inserts; \n starts a new line
    Text =

    ; keyboard shortcut
    Key =
  ]
]

; custom keyboard shortcuts
Shortcuts [
  [
    ; command to run, e.g. CmdOpenFile. See the list of commands (https://www.sumatrapdfreader.org/docs/Commands)
    Cmd = 

    ; keyboard shortcut (e.g. Ctrl-Alt-F)
    Key = 

    ; name shown in command palette (introduced in version 3.6)
    Name =

    ; if given, shows in toolbar (introduced in version 3.6)
    ToolbarText =

    ; optional SVG icon for toolbar button; if both ToolbarSvgIcon and
    ; ToolbarText are set, the icon is used (introduced in version 3.7)
    ToolbarSvgIcon =
  ]
]

; color themes (introduced in version 3.6)
Themes [
  [
    ; name of the theme, as shown in the Settings / Theme menu
    Name = 

    ; color of text in menus, toolbar, tabs and sidebars
    TextColor = 

    ; background color of the window around the document
    BackgroundColor = 

    ; background color of toolbar, tabs, sidebars and dialogs
    ControlBackgroundColor = 

    ; background color of the active tab; if empty, uses ControlBackgroundColor
    ; (introduced in version 3.7)
    ActiveTabBackgroundColor = 

    ; background color of inactive tabs; if empty, derived from
    ; ControlBackgroundColor (introduced in version 3.7)
    InactiveTabBackgroundColor = 

    ; color of clickable links in the UI
    LinkColor = 

    ; color of disabled (grayed out) text; if empty, derived from the colors
    ; above (introduced in version 3.7)
    DisabledTextColor = 

    ; color of secondary / muted text like the page label; if empty, derived
    ; from the colors above (introduced in version 3.7)
    DarkerTextColor = 

    ; background color of a control the mouse is over; if empty, derived from
    ; the colors above (introduced in version 3.7)
    HotBackgroundColor = 

    ; color of control borders and separators; if empty, derived from the colors
    ; above (introduced in version 3.7)
    EdgeColor = 

    ; border color of a control the mouse is over; if empty, derived from the
    ; colors above (introduced in version 3.7)
    HotEdgeColor = 

    ; border color of a disabled control; if empty, derived from the colors
    ; above (introduced in version 3.7)
    DisabledEdgeColor = 

    ; background color of error messages; if empty, derived from the colors
    ; above (introduced in version 3.7)
    ErrorBackgroundColor = 

    ; background color of notification tips; if empty, derived from the colors
    ; above (introduced in version 3.7)
    NotificationBackgroundColor = 

    ; background color of a highlighted notification tip; if empty, derived from
    ; the colors above (introduced in version 3.7)
    NotificationHighlightColor = 

    ; text color of a highlighted notification tip; if empty, derived from the
    ; colors above (introduced in version 3.7)
    NotificationHighlightTextColor = 

    ; if true, apply the theme colors to Windows controls and window areas too
    ColorizeControls = false
  ]
]

; saved groups of tabs (introduced in version 3.7)
TabGroups [
  [
    ; name of the tab group, as shown when restoring it
    Name = 

    ; documents that belong to this tab group
    TabFiles [
      [
        ; path of the document
        Path = 
      ]
    ]
  ]
]

; actual resolution of the main screen in DPI, used to show documents at their
; physical size; if 0 or negative, the resolution reported by Windows is used
; (introduced in version 2.5)
CustomScreenDPI = 0

; a whitespace separated list of passwords to try when opening a password
; protected document (passwords containing spaces must be quoted) (introduced in
; version 2.4)
DefaultPasswords =

; ISO code (langs.html) of the current UI language
UiLanguage =

; SumatraPDF won't offer to update to this version again
VersionToSkip =

; default state of the window. 1 is normal, 2 is maximized, 3 is fullscreen, 4
; is minimized
WindowState = 1

; default position (x, y) and size (width, height) of the window
WindowPos = 0 0 0 0

; position/size of the floating find window (see SearchUIFloating)
SearchUIWindowPos = 0 0 0 0

; position/size of the in-app Help: Manual window (introduced in version 3.7)
HelpWindowPos = 0 0 0 0

; history of opened files, most recently used first. A closed file stays here
; until it drops off the list or the history is cleared
FileStates [
  [
    ; pages of this document bookmarked in the Favorites menu
    Favorites [
      [
        ; name of this favorite as shown in the menu
        Name =

        ; number of the bookmarked page, or `bm:<bookmark>` for documents with
        ; chapters (see PagePosition.cpp)
        PageNo = 1

        ; label for this page (only present if logical and physical page numbers
        ; are not the same)
        PageLabel =

        ; position on the page when the favorite was added (document units; -1
        ; if not stored) (introduced in version 3.7)
        ScrollPos = -1 -1

        ; session-only favorite; omitted when serializing array elements
        ; (introduced in version 3.7)
        IsTemporary = false
      ]
    ]

    ; reflowable (ebook) settings for just this document. The block is absent
    ; until you add it; a field left empty or 0 uses the global EBookUI value.
    ; The global section's WindowBgCol and DefaultDisplayMode are already
    ; per-document as BgCol and DisplayMode below (introduced in version 3.7)
    EBookUI [
        ; font family for this document (e.g. Segoe UI, Microsoft YaHei); empty
        ; uses EBookUI.FontName (introduced in version 3.7)
        FontName = 

        ; font size in points for this document; 0 uses EBookUI.FontSize
        ; (introduced in version 3.7)
        FontSize = 0

        ; white space around the text for this document, in points; one, two or
        ; four values like EBookUI.Margin. empty uses EBookUI.Margin (introduced
        ; in version 3.7)
        Margin =

        ; line-height multiplier for this document (e.g. 1.5); 0 uses
        ; EBookUI.LineSpacing (introduced in version 3.7)
        LineSpacing = 0

        ; width of the page this document is laid out into, in points; 0 uses
        ; EBookUI.LayoutDx (introduced in version 3.7)
        LayoutDx = 0

        ; height of the page this document is laid out into, in points; 0 uses
        ; EBookUI.LayoutDy (introduced in version 3.7)
        LayoutDy = 0

        ; whether the CSS in this document is ignored: true or false; empty uses
        ; EBookUI.IgnoreDocumentCSS (introduced in version 3.7)
        IgnoreDocumentCSS = 

        ; additional CSS applied to this document; empty uses EBookUI.CustomCSS
        ; (introduced in version 3.7)
        CustomCSS = 
    ]

    ; data required to determine which parts of the table of contents have been
    ; expanded
    TocState =

    ; path of the document
    FilePath =

    ; data required to open a password protected document without having to ask
    ; for the password again
    DecryptionKey =

    ; what the sidebar's top panel shows: bookmarks (the default), thumbnails or
    ; favorites (introduced in version 3.7)
    SidebarView =

    ; layout of pages. valid values: automatic, single page, facing, book view,
    ; continuous, continuous facing, continuous book view
    DisplayMode = automatic

    ; zoom (in %) or one of those values: fit page, fit width, fit height, fit
    ; content, fit visible
    Zoom = fit page

    ; if given, overrides the background color for this document (introduced in
    ; version 3.7)
    BgCol = 

    ; if given, overrides the tab color for this document (introduced in version
    ; 3.7)
    TabCol = 

    ; number of times this document has been opened recently
    OpenCount = 0

    ; number of the last read page, or `bm:<bookmark>` for documents with
    ; chapters (folds in ReparseIdx; see PagePosition.cpp)
    PageNo = 1

    ; number of pages in the document when it was last open; 0 if unknown. Used
    ; to show reading progress on the home page (introduced in version 3.7)
    PageCount = 0

    ; how far pages have been rotated as a multiple of 90 degrees
    Rotation = 0

    ; state of the window. 1 is normal, 2 is maximized, 3 is fullscreen, 4 is
    ; minimized
    WindowState = 0

    ; width of the bookmarks / favorites sidebar in screen pixels, as last
    ; resized
    SidebarDx = 0

    ; how far this document has been scrolled (in x and y direction)
    ScrollPos = 0 0

    ; default position (can be on any monitor)
    WindowPos = 0 0 0 0

    ; if true, the document is "pinned" to the Frequently Read list, so that
    ; recently opened documents don't displace it
    IsPinned = false

    ; if true, the file is considered missing and won't be shown in any list
    IsMissing = false

    ; if true, this document opens with the global defaults instead of the
    ; values below
    UseDefaultState = false

    ; if true, show the table of contents (Bookmarks) sidebar when the document
    ; has one
    ShowToc = true

    ; if true, the document is displayed right-to-left in facing and book view
    ; modes
    DisplayR2L = false

    ; if true, percentage zoom scales every page to the width page 1 has at that
    ; zoom level (introduced in version 3.7)
    UniformPageWidth = false

    ; if true, empty margins around page content are trimmed from display
    ; (introduced in version 3.7)
    TrimEmptyMargins = false

    ; if true, the view can be panned past the page edges, so any part of a page
    ; can be brought to the center of the window (introduced in version 3.7)
    FreePan = false
  ]
]

; windows and tabs still open when SumatraPDF was last closed; reopened at
; startup if RestoreSession is true (introduced in version 3.1)
SessionData [
  [
    ; data required for restoring the view state of a single tab
    TabStates [
      [
        ; path of the document
        FilePath =

        ; layout of pages in this tab. valid values: automatic, single page,
        ; facing, book view, continuous, continuous facing, continuous book view
        DisplayMode = automatic

        ; number of the last read page, or `bm:<bookmark>` for documents with
        ; chapters (see PagePosition.cpp)
        PageNo = 1

        ; zoom (in %) or one of those values: fit page, fit width, fit height,
        ; fit content, fit visible
        Zoom = fit page

        ; how far pages have been rotated as a multiple of 90 degrees
        Rotation = 0

        ; how far this document has been scrolled (in x and y direction)
        ScrollPos = 0 0

        ; if true, the table of contents was shown when the document was closed
        ShowToc = true

        ; what the sidebar's top panel showed: bookmarks, thumbnails or
        ; favorites (introduced in version 3.7)
        SidebarView =

        ; which table of contents items were expanded (see FileStates ->
        ; TocState)
        TocState =
      ]
    ]

    ; index of the currently selected tab (1-based)
    TabIndex = 1

    ; state of the window. 1 is normal, 2 is maximized, 3 is fullscreen, 4 is
    ; minimized
    WindowState = 0

    ; position of the window (can be on any monitor)
    WindowPos = 0 0 0 0

    ; width of the favorites / bookmarks sidebar in screen pixels (0 if it
    ; wasn't shown)
    SidebarDx = 0
  ]
]

; data required for reloading documents after an auto-update (introduced in
; version 3.0)
ReopenOnce =

; data required to determine when SumatraPDF last checked for updates
TimeOfLastUpdateCheck = 0 0

; value required to determine recency for the OpenCount value in FileStates
OpenCountWeek = 0

; position of the document properties window
PropWinPos = 0 0

; if true, check once a day whether an update is available
CheckForUpdates = true
```

## Syntax for color values

The syntax for colors is: `#rrggbb` or `#aarrggbb`.

The components are hex values (ranging from 00 to FF) and stand for:
- `aa` : alpha (opacity). `00` is fully transparent, `FF` is fully opaque, and `7F` is about 50% opaque
- `rr` : red component
- `gg` : green component
- `bb` : blue component

For example `#ff0000` is opaque red. `#7fff0000` is half-transparent red. `#rrggbb` (6 digits) is the same as `#FFrrggbb`. You can use [Sphere](https://colorsphere.app/) to pick a color. This applies to annotation colors too (`Annotations.HighlightColor`, underline, squiggly, strike-out).



---

<!-- How-we-store-settings.md -->

# How we store settings

## Where we store settings

Persisted data is stored in the `SumatraPDF-settings.txt` file.

In the portable version, the file is stored in the same directory as the SumatraPDF executable. In the installed version, it's in the `%LOCALAPPDATA%\SumatraPDF` directory.

Starting with version 1.6, we also persist thumbnails for the "Frequently read" list. They are stored as `.png` files in the `sumatrapdfcache` subdirectory.

Override the directory with `-appdata <path>` on the command line — see [Installation](Installation.md).

See [https://www.sumatrapdfreader.org/settings/settings](https://www.sumatrapdfreader.org/settings/settings) for information about all the settings.

## How settings apply

Not every setting works the same way. Understanding the three layers avoids "I changed it but nothing happened" confusion.

### 1. Global defaults (first open)

Settings like `DefaultDisplayMode` and `DefaultZoom` in [advanced settings](Advanced-options-settings.md) apply when you open a document **for the first time** — when there is no saved state for that file yet.

The **Settings → Options** dialog ("remember these settings for each document") writes global defaults into the same settings file. They do **not** retroactively change files you have already opened.

### 2. Per-document state (reopen)

When `RememberStatePerDocument = true` (default), SumatraPDF saves display settings per file in the `FileStates` section: zoom, scroll position, view mode, sidebar width, tab color, etc.

The next time you open that file, **saved state wins** over global defaults. This is why changing "default two-page view" does not affect a PDF you have opened before — see [FAQ](FAQ.md).

To reset one file: delete its `[[FileStates]]` block from the settings file, or delete the entire settings file to reset everything.

### 3. Restart-required settings

Some settings apply only after restarting SumatraPDF:

- `UseTabs` — tabbed vs separate windows for **new** windows
- Others noted in [advanced settings](Advanced-options-settings.md) (e.g. some UI layout options)

`ReuseInstance` and most color/theme changes take effect immediately or on the next file open.

### Session restore

| Setting                      | Effect                                                                                                               |
| ---------------------------- | -------------------------------------------------------------------------------------------------------------------- |
| `RestoreSession = true`      | On startup, reopen the tabs and windows still open at last close (`SessionData`)                                     |
| `RememberOpenedFiles = true` | Keep a history of opened files (`FileStates`) for Home / `#` command palette; also required for saving `SessionData` |
| `LazyLoading = true`         | When restoring session, load tab content only when the tab is selected                                               |

`FileStates` and `SessionData` answer different questions. `FileStates` is the history: a file stays there after
you close it, until it drops off the list or you clear the history (File > Clear History). `SessionData` only lists
what was still open when the last window closed. Close a tab before closing the window and it is gone from
`SessionData` but remains in `FileStates`.

`-for-testing` skips restore and does not save settings.

### What is not in the settings file

- **Unsaved annotations** — kept in memory until you save or discard; see [Editing annotations](Editing-annotations.md)
- **Installer / restrict policy** — `sumatrapdfrestrict.ini` beside the executable; see [Configure for restricted use](Configure-for-restricted-use.md)

## Reset to defaults

Delete `SumatraPDF-settings.txt`. SumatraPDF recreates it on next launch with factory defaults.

## See also

- [FAQ](FAQ.md)
- [Tabs and windows](Tabs-and-windows.md) — `UseTabs`, `ReuseInstance`, `RestoreSession`
- [Advanced settings](Advanced-options-settings.md)


---

<!-- Command-line-arguments.md -->

# Command-line arguments

For command-line arguments for the installer see [this page](Installer-cmd-line-arguments.md).

You can launch Sumatra with additional command-line options: `SumatraPDF [argument ...] [filepath ...]`.

Most arguments start with a dash (`-`). Some Adobe Reader slash forms are also accepted (`/p`, `/t`, `/A`). Some arguments are followed by additional parameters.

Anything that is not recognized as a known option is interpreted as a file path, so it's possible to mix file paths and command-line arguments.

## List of command line options

- `-presentation` : start in presentation view
- `-fullscreen` : start in full screen view
- `-new-window` : open each file in its own new window rather than in a tab of an existing window (**ver 3.2+**). With several file arguments, it opens one window per file
- `-new-window-tabs` : open **one** new window and load all files as tabs in that window (**ver 3.7+**, issue #5044)
- `-appdata <directory>` : set a custom directory in which to store the `SumatraPDF-settings.txt` file and thumbnail cache
- `-restrict` : runs in restricted mode, where you can disable features that require access to the file system, registry, and internet. Useful for kiosk-like usage. See [Configure for restricted use](Configure-for-restricted-use.md).
- `-for-testing` : for ad-hoc testing by humans or agents. Always starts a new instance, doesn't restore a session (only loads files given on the command line) and doesn't save settings (**ver 3.7+**)
- `-quicklook` : open the file in a chrome-less always-on-top preview window (Explorer Space preview). Esc or Space closes it (**ver 3.7+**, fixes #2568)
- `-quicklook-agent` : run the hidden File Explorer Space-bar helper with no UI. Started automatically when `ExplorerQuickLook` is true (**ver 3.7+**)
- `-dbg-control <named-pipe>` : starts a test control server on a named pipe. Used by automated tests through `tests/control.ts`; combine with `-for-testing`. (**ver 3.7+**). In a profile build, the control commands `StartPerfLog` / `StopPerfLog` enable function-timing logs around a region of code. `WaitSessionRestored` waits until startup session restore (tabs, selected document, first layout) has finished; needed because `-for-testing` skips restore
- `-start-perf-log` : in a profile build (`bun cmd/build.ts -profile`), start writing function enter/exit timings immediately. Off by default. The log is saved to `sumperf.txt` next to the exe on exit, or to `-log-perf-file <path>`
- `-log-perf-file <path>` : write the profile function-timing log to this path instead of `sumperf.txt` (**ver 3.7+**)
- `-dump-chm <file>` : headlessly opens a CHM file, lists contained files with sizes, unpacks each file to memory to validate retrieval, and prints TOC/index metadata to stdout. Exits with a non-zero code if the CHM can't be opened, enumerated, or unpacked.
- `-pwd <password>` : use the given password to open password-protected documents. If the password is wrong, SumatraPDF falls back to default passwords and then asks interactively.

## Navigation options

- `-named-dest <destination-name>` : searches the first indicated file for a destination, table-of-contents entry, or (starting with version 3.1) page label matching `<destination-name>`, and scrolls the document to it. If the document is already open, it goes to the running SumatraPDF (the `ReuseInstance` setting, on by default; otherwise add `-reuse-instance`).
- `-page <pageNo>` : scrolls the first indicated file to the indicated page. If the document is already open, it goes to the running SumatraPDF (the `ReuseInstance` setting, on by default; otherwise add `-reuse-instance`).
- `-view <view-mode>` : sets the view mode for the first indicated file. Available view modes:
  - `"single page"`
  - `"continuous single page"`
  - `facing`
  - `"continuous facing"`
  - `"book view"`
  - `"continuous book view"`

  Options containing spaces must be enclosed in double quotes.

  If the document is already open, it goes to the running SumatraPDF (the `ReuseInstance` setting, on by default; otherwise add `-reuse-instance`).

- `-zoom <zoom-level>` : sets the zoom level for the first indicated file. Alternatives are `"fit page"`, `"fit width"`, `"fit height"`, `"fit content"`, `"fit visible"`, or any percentage value. If the document is already open, it goes to the running SumatraPDF (the `ReuseInstance` setting, on by default; otherwise add `-reuse-instance`).
- `-scroll <x,y>` : scrolls to the given coordinates for the first indicated file. If the document is already open, it goes to the running SumatraPDF (the `ReuseInstance` setting, on by default; otherwise add `-reuse-instance`).
- `-search <term>` : start a search for a given term when opening a document, e.g. `SumatraPDF -search "foo" bar.pdf`. **Ver 3.4+**. The leading `-` is required.
- `/A "<params>"` : Adobe Reader-compatible open parameters for the first file (**ver 3.5+**). `params` is a list of `name=value` pairs separated by `;`, `#`, or `&`. Recognized names:
  - `page=<n>` : go to page n (1-based)
  - `nameddest=<name>` : jump to a named destination
  - `search=<term>` : start a search (same as `-search`)

  e.g. `SumatraPDF /A "page=1;search=mr Fox" file.pdf`. The same `name=value` list can be appended to a file path after `?`, e.g. `file.pdf?page=4;search=foo`.

## Send DDE commands

- `-dde cmd` : sends [DDE commands](DDE-Commands.md) to the currently running instance, e.g. `-dde '[Open("C:\Users\kjk\foo.pdf")]'`. Make sure to quote arguments properly. File paths must be absolute. **Ver 3.5+**.

## Printing options

For a detailed printing guide with examples for common tasks, see [Printing](Printing.md).

- `-print-to-default` : prints all files indicated on this command line to the system default printer. After printing, SumatraPDF exits immediately (check the error code for failure).
- `-print-to <printer-name>` : prints all files indicated on this command line to the named printer. After printing, SumatraPDF exits immediately (check the error code for failure). E.g. `-print-to "Microsoft XPS Document Writer"` prints all indicated files to the XPS virtual printer.
- `-print-settings <settings-list>`
  - used in combination with `-print-to` and `-print-to-default`. Lets you adjust printing-related settings without using the Print dialog. The settings list is a comma-separated list of page ranges and advanced options such as
    - page ranges: a single page (e.g. `5`), a range (e.g. `2-6`, or reversed `10-8`), `last` for the last page, or a negative number counting from the end (`-1` is the last page, `-2` the second-to-last; ranges may use negatives too, e.g. `-3--1` for the last 3 pages)
    - `even` or `odd`.
    - `portrait` or `landscape` : can provide a 90-degree rotation of the contents (NOT the rotation of the paper, which must be preset in the printer defaults)
    - `disable-auto-rotation` : by default a page wider than it is tall is rotated 90 degrees to fit the paper; this prints the content in its original orientation instead (available since 3.5)
    - `rotate=<degrees>` : rotate the printout by an extra `90`, `180` or `270` degrees (on top of the automatic rotation). Useful to fix a wrong orientation, e.g. upside-down (`rotate=180`) output on virtual printers
    - `noscale`, `shrink`, `fit` and `stretch` (`stretch` fills the paper in both dimensions, ignoring the aspect ratio)
    - `dpi=<n>` : the resolution to assume for the document, e.g. `dpi=300` for a 300 dpi scan whose file doesn't record it. Decides how big `noscale` prints an image; ignored for documents with real page sizes like PDF (available since 3.7, [details](Printing.md#printing-at-actual-size-11))
    - `center` : horizontally center the page on the paper. Useful with `noscale` when the page is smaller than the paper (e.g. envelopes or A5 stock fed through a tray that centers the paper)
    - `color` or `monochrome`
    - `collate` or `nocollate` : when printing multiple copies, collate (1,2,3,1,2,3) or don't (1,1,2,2,3,3)
    - `duplex`, `duplexshort`, `duplexlong` and `simplex`
    - `bin=<num or name>` : select tray to print to. Use `bin=auto` to let the printer pick the input tray whose paper matches the document page size (like Adobe's "Choose paper source by PDF page size")
    - `paper=<page size>` : page size is `A2`, `A3`, `A4`, `A5`, `A6`, `letter`, `legal`, `tabloid`, `statement`, or a name reported by the printer (e.g. `A3 297 x 420 mm`). Custom dimensions: `paper=76mm x 130mm`. Use `paper=auto` to set the paper size from each page's own size, for documents with mixed page sizes (combine with `bin=auto` to also pick the matching tray)
    - `paperkind=<num>` : paper size by Windows `DMPAPER_*` id (from `SumatraPDF.exe -list-printers`); use when `paper=A3` does not match the driver's paper name
    - `ignore-pdf-print-settings` : don't apply the print defaults embedded in a PDF's `ViewerPreferences` (see below)
  - e.g. `-print-settings "1-3,5,10-8,odd,fit,bin=2"` prints pages 1, 3, 5, 9 (i.e. the odd pages from the ranges 1-3, 5-5 and 10-8) and scales them so that they fit into the printable area of the paper.
  - `-print-settings "3x"` : prints the document 3 times
  - For PDF files, print defaults embedded in the document's `ViewerPreferences` are applied automatically: `PrintScaling` (`/None` means no scaling), `NumCopies`, `Duplex` (`Simplex` / `DuplexFlipShortEdge` / `DuplexFlipLongEdge`) and `PickTrayByPDFSize` (pick the tray by page size). Any explicit value in `-print-settings` overrides the PDF's default; add `ignore-pdf-print-settings` to ignore the PDF's values entirely.
- `-silent` : used in combination with `-print-to` and `-print-to-default`. Silences any error messages related to command line printing.
- `-print-dialog` : displays the Print dialog for all the files indicated on this command line.
- `/p` : Adobe Reader compatibility alias for `-print-dialog`.
- `/t <file> <printer>` : Adobe Reader compatibility for silent printing (same as `-print-to <printer> <file>`). Optional driver and port arguments are accepted and ignored. If the file is already on the command line, `/t <printer>` is enough.
- `-exit-when-done` : used in combination with `-print-dialog` (and `-stress-test`). Exits SumatraPDF after the Print dialog has been dismissed and the document printed.

Adobe Reader flags that are **not** supported because they conflict with SumatraPDF options: `/h` (help, not hidden mode), `/n` (stress-test parallelism, not new instance), `/s` (silent printing errors, not suppress splash).

When printing with `-print-to` / `-print-to-default`, the process exit code tells you why printing failed (useful for unattended/silent printing):

| Exit code | Meaning                                                  |
| --------- | -------------------------------------------------------- |
| `0`       | success                                                  |
| `2`       | couldn't open the file (not found or unsupported format) |
| `3`       | the document doesn't allow printing                      |
| `4`       | the printer (named, or default) doesn't exist            |
| `5`       | the printer driver / device failed                       |
| `6`       | printing is disabled by restriction policy               |

With multiple files, the exit code is `0` only if all printed; otherwise it's the category of the first failure. Note: failures that happen inside the print spooler/driver _after_ the job is submitted (out of paper, offline, etc.) can't be reported this way.

## Options related to forward/inverse search (for LaTeX editors)

- `-forward-search "<sourcepath>" <line> "<pdfpath>"`: performs a forward search from a LaTeX source file to a loaded PDF document (using PdfSync or SyncTeX). This is an alternative to the ForwardSearch DDE command. E.g. `-forward-search "/path/to/main.tex" 123 "/path/to/main.pdf"` highlights all text related to line 123 in main.tex.
- `-reuse-instance` : tells an already open SumatraPDF to load the indicated files. If there are several running instances, behavior is undefined. Only needed when communicating with SumatraPDF through DDE (use the ReuseInstance setting instead otherwise).
- `-inverse-search <command-line>` : sets the command line to be used for performing an inverse search from a PDF document (usually back to a LaTeX source file). The inverse search command line can also be set with `Ctrl + K`, `Set Inverse Search Command Line` command in [Command Palette](Command-Palette.md), from `Settings` / `Settings...` when `EnableTeXEnhancements` is enabled, or via the `InverseSearchCmdLine` advanced setting. Use the variable %f for the current filename and %l for the current line.
- `-fwdsearch-offset <offset> -fwdsearch-width <width> -fwdsearch-color <hexcolor> -fwdsearch-permanent <flag>` : lets you customize the forward-search highlight. Set the offset to a positive number to change the highlight style to a rectangle at the left of the page (instead of rectangles over all the text). The flag for `-fwdsearch-permanent` can be 0 (make the highlight fade away, the default) or 1.
  [Deprecated]: Use the corresponding advanced settings instead.

## Developer options

- `-console` : Opens a console window alongside SumatraPDF for accessing (MuPDF) debug output.
- `-list-printers` : prints installed printers, default settings, paper sizes and input trays, then exits. This is useful when choosing `-print-to`, `paper=`, `paperkind=` or `bin=` values for command-line printing. With `-console` or `-silent`, output goes only to the console (no dialog window).
- `-stress-test <path> [file-filter] [range] [cycle-count]`
  : Renders all pages of the indicated file/directory for stability and performance testing. E.g.:

  ```
  -stress-test file1.pdf 25x
  -stress-test file2.pdf 1-3
  -stress-test dir *.pdf;*.xps 15- 3x
  ```

  renders file1.pdf 25 times, renders pages 1 to 3 of file2.pdf and renders all but the first 14 PDF and XPS files from dir 3 times.

- `-html-backend <ie|webview2>` : forces the embedded browser that shows CHM and markdown documents. By default WebView2 is used when it's installed and the IE control otherwise; this makes a test cover both. (**ver 3.7+**)

- `-bench <filepath> [page-range]` : Renders all pages (or just the indicated ones) for the given file and then outputs the required rendering times for performance testing and comparisons. Often used together with `-console`.

## Deprecated options

The following options just set values in the settings file and may be removed in any future version:

- `-bg-color <hexcolor>` : changes the yellow background to a different color. See, for example, [html-color-codes.info](https://html-color-codes.info/) for a way to generate a color's hex code. `-bg-color #999999` changes the color to gray. Deprecated: use the `MainWindowBackground` setting instead.
- `-esc-to-exit` : enables the Escape key to quit SumatraPDF. Deprecated: use the `EscToExit` setting instead.
- `-set-color-range <text-hexcolor> <background-hexcolor>` : uses the given two colors for foreground and background and maps all other colors used in a document in between these two. E.g. `-set-color-range #dddddd #333333` displays soft white text on a dark gray background. Deprecated: use the `FixedPageUI.TextColor` and `FixedPageUI.BackgroundColor` settings instead.
- `-lang <language-code>` : sets the UI language. See [Translation languages](https://github.com/sumatrapdfreader/sumatrapdf/blob/master/src/TranslationLangs.cpp) for the list of available language codes. E.g. `-lang de`. Deprecated: use the `UiLanguage` setting instead.
- `-manga-mode <mode>` : enables or disables "Manga mode" for reading (mainly Japanese) comic books from right to left. Mode must be "true" or 1 for enabling and "false" or 0 for disabling this feature. Deprecated: use the `ComicBookUI.CbxMangaMode` setting instead.
- `-invert-colors` : temporarily swaps fixed-page document text and background colors for the current run. The older alias `-invertcolors` is also accepted.


---

<!-- DDE-Commands.md -->

# DDE Commands

You can control SumatraPDF with [DDE commands](https://docs.microsoft.com/en-us/windows/win32/dataxchg/dynamic-data-exchange).

They are primarily used to integrate SumatraPDF as a [preview tool for applications such as LaTeX editors](LaTeX-integration.md) that generate PDF files.

## Format of DDE commands

Single DDE command: `[Command(parameter1, parameter2, ..., )]`

Multiple DDE commands: `[Command1(parameter1, parameter2, ..., )][Command2(...)][...]`

## Sending DDE commands

You can use the Windows API to send DDE commands to the `SUMATRA` server and `control` topic. See the `DDEExecute()` function in [src/base/Win.cpp](https://github.com/sumatrapdfreader/sumatrapdf/blob/master/src/base/Win.cpp) for an example.

Alternatively, you can use the `-dde` command-line argument to `SumatraPDF.exe`, e.g. `SumatraPDF.exe -dde "[SetView(\"c:\\file.pdf\",\"continuous\",-3)]"`.

Notice that `"` and `\` in the DDE command string are escaped with `\`.

## List of DDE commands:

### Named commands

**Ver 3.5+**: you can send all [named commands](Commands.md) as DDE:

- format `[<command_id>]` e.g. `[CmdClose]`

### Open file

- format: `[Open("<filePath>"[,<newWindow>,<focus>,<forceRefresh>])]`
- arguments:
  - if `newWindow` is 1 then a new window is created even if the file is already open
  - if `focus` is 1 then the focus is set to the window
  - if `forceRefresh` is 1 the command forces a refresh of the file window if it is already open (useful for files opened over a network that don't get file-change notifications)
- example: `[Open("c:\file.pdf",1,1,0)]`

### Forward-search

- format: `[ForwardSearch(["<pdffilepath>",]"<sourcefilepath>",<line>,<column>[,<newwindow>,<setfocus>])]`
- arguments:
  - `pdffilepath` : path to the PDF document (if this path is omitted and the document isn't already open, SumatraPDF won't open it for you)
  - `column` : this parameter is for future use (just always pass 0)
  - `newwindow` : 1 to open the document in a new window (even if the file is already open)
  - `focus` : 1 to set focus to SumatraPDF's window
- examples
  - `[ForwardSearch("c:\file.pdf","c:\folder\source.tex",298,0)]`
  - `[ForwardSearch("c:\folder\source.tex",298,0,0,1)]`

### Jump to named destination command

- format: `[GotoNamedDest("<pdffilepath>","<destination name>")]`
- example: `[GotoNamedDest("c:\file.pdf", "chapter.1")]`
- note: the PDF file must already be open

### Go to page

- format: `[GotoPage("<pdffilepath>",<page number>)]`
- example: `[GotoPage("c:\file.pdf", 37)]`
- note: the PDF file must already be open

### Search

Search the document for a term and select/scroll to the first match. Like the Find box, the search continues onto following pages and wraps around to the start.

- format: `[Search("<pdffilepath>","<search-term>")]`
- example: `[Search("c:\file.pdf", "needle")]`
- note: the PDF file must already be open

### Go to page and word

**Ver 3.7+**

Go to a specific page and select the search term **only if it is found on that page** (unlike `Search`, which keeps searching following pages and wraps around). If the term is not on that page, it stays on the page and selects nothing. Useful for making a shortcut to a precise location.

- format: `[GotoPageWord("<pdffilepath>",<page number>,"<search-term>")]`
- example: `[GotoPageWord("c:\file.pdf", 12, "green")]`
- note: the PDF file must already be open

### Set view settings

- format: `[SetView("<pdffilepath>","<view mode>",<zoom level>[,<scrollX>,<scrollY>])]`
- arguments:
  - `view mode`:
    - `"single page"`
    - `"facing"`
    - `"book view"`
    - `"continuous"`
    - `"continuous facing"`
    - `"continuous book view"`
  - `zoom level` : either a zoom factor between 8 and 6400 (in percent) or one of -1 (Fit Page), -2 (Fit Width), -3 (Fit Content) or -6 (Fit Height). Use `0` to keep the current zoom unchanged — useful when scrolling with the scroll arguments, since re-applying a Fit zoom on every call re-fits the page and would reset the scroll position
  - `scrollX, scrollY` : PDF document (user) coordinates of the point that should be visible in the top-left of the window
- example: `[SetView("c:\file.pdf","continuous",-3)]`
- note: the PDF file must already be open

### Presentation and fullscreen

**Ver 3.7+**

Show the document in presentation or fullscreen mode, like the `-presentation` / `-fullscreen` [command-line arguments](Command-line-arguments.md). A second SumatraPDF started with one of them sends it to the running instance.

- format: `[Presentation("<pdffilepath>")]` or `[FullScreen("<pdffilepath>")]`
- example: `[Presentation("c:\file.pdf")]`
- note: the PDF file must already be open

### Get file state

Unlike the commands above (which are sent as DDE _execute_ requests), this is a DDE _request_ transaction: it returns information about a document.

- format: `[GetFileState("<pdffilepath>")]` or `[GetFileState()]` for the currently active document
- returns multiple `key: value` lines (split the response by `\n`, then each line by the first `:`):

  ```
  path: c:\file.pdf
  page: 1
  pageCount: 6
  zoom: 120
  view: continuous
  sumver: 3.7
  ```

  - `page` : the current page number; `pageCount` : the total number of pages
  - `zoom` : a zoom factor in percent, or -1 (Fit Page), -2 (Fit Width), -3 (Fit Content), -6 (Fit Height) — the same convention as `SetView`
  - on error (no such open file) it returns `error: <message>`

- example: `[GetFileState()]`

### Get open files

Also a DDE _request_ transaction: returns the full path of every open document (across all windows and tabs), one per line.

- format: `[GetOpenFiles()]`
- returns one file path per line (split the response by `\n`); empty if nothing is open
- example: `[GetOpenFiles()]`

### Get mouse position

**Ver 3.7+**

Also a DDE _request_ transaction: returns the document position currently under the mouse cursor, in PDF points (the same unit used by `.smx` files and the `m` cursor-position notification). Useful for external tools that interact with annotations at the cursor.

- format: `[GetMousePos()]`
- returns:

  ```
  page: 1
  x: 305.04
  y: 395.58
  ypdf: 396.42
  ```

  - `page` : the page under the cursor, or `0` if the cursor isn't over a page
  - `x`, `y` : the position on that page, in PDF points, MuPDF convention (origin top-left, `y` increases downward — same as the `m` notification and `.smx`)
  - `ypdf` : the same point's `y` in PDF/Adobe convention (origin bottom-left, `y` increases upward); only present when over a page. `x` is the same in both conventions.

- example: `[GetMousePos()]`


---

<!-- LaTeX-integration.md -->

# LaTeX integration

SumatraPDF is a common PDF previewer for LaTeX on Windows: it opens quickly, reloads when the PDF is rebuilt, and supports **SyncTeX** so you can jump between source and PDF. [Typst](https://typst.app/) users on Windows use it the same way for live PDF reload (see [Typst](#typst)); Typst does not emit SyncTeX.

For LaTeX edited/compiled **inside WSL**, see [LaTeX integration with WSL](LaTeX-integration-wsl.md). Editors can also drive Sumatra with [DDE commands](DDE-Commands.md); prefer command-line `-forward-search` when possible (simpler and Unicode-friendly).

## SyncTeX: forward and inverse search

Compile with SyncTeX enabled (most tools use `-synctex=1` or an equivalent). That produces a `.synctex` / `.synctex.gz` next to the PDF.

| Direction          | Who starts it    | What happens                                                                                     |
| ------------------ | ---------------- | ------------------------------------------------------------------------------------------------ |
| **Forward search** | Editor → Sumatra | Jump from a `.tex` line to the matching place in the PDF (highlight).                            |
| **Inverse search** | Sumatra → editor | Double-click (or inverse-search click) in the PDF opens the matching source line in your editor. |

Forward search is usually configured **in the editor** (viewer command / external PDF viewer). Inverse search is configured **in Sumatra** via the inverse-search command line (below).

Recommended Sumatra settings (Advanced Settings or once via the inverse-search dialog):

```
EnableTeXEnhancements = true
ReuseInstance = true
ReloadModifiedDocuments = true
```

- **EnableTeXEnhancements** — shows TeX-related UI (including inverse-search options) and enables inverse search on click when configured.
- **ReuseInstance** — one Sumatra process reuses the open window when the editor launches the viewer again (avoids many windows).
- **ReloadModifiedDocuments** — reloads the PDF after LaTeX rebuilds it.

## Inverse search command line (`InverseSearchCmdLine`)

**Purpose:** when you inverse-search in the PDF, Sumatra builds a process command line from this pattern and launches your editor at the matching source file and line.

**Where to set it (any one of these):**

1. `Ctrl + K`, `Set Inverse Search Command Line` command in [Command Palette](Command-Palette.md) (detects common editors; enables TeX enhancements on OK)
2. **Settings → Options** (when TeX enhancements are on) → inverse-search field
3. Advanced setting `InverseSearchCmdLine` in `SumatraPDF-settings.txt`
4. One-shot via command line: `-inverse-search "<command-line>"` (writes the same setting)

**Placeholders** (replaced by Sumatra when launching the editor):

| Token | Meaning                             |
| ----- | ----------------------------------- |
| `%f`  | Full path of the source `.tex` file |
| `%l`  | Line number (1-based)               |
| `%c`  | Column (when available; often 0)    |

Use quotes around paths that may contain spaces. Adjust executable paths to match your install (Program Files vs Program Files (x86), user installs, portable layouts).

**Example (Notepad++):**

```
"C:\Program Files\Notepad++\notepad++.exe" -n%l "%f"
```

---

## Setup by editor / environment

In each section: (1) configure Sumatra inverse search, (2) configure the editor to open Sumatra and run forward search, (3) compile with SyncTeX.

Paths below use common 64-bit install locations; change them if yours differ.

### TeXstudio

**1. Inverse search (in Sumatra)**

```
"C:\Program Files\TeXstudio\texstudio.exe" "%f" -line %l
```

**2. Viewer / forward search (in TeXstudio)**

- **Options → Configure TeXstudio → Commands** (or **Build**)
- Set **External PDF viewer** / PDF viewer command to something like:

```
"C:/Program Files/SumatraPDF/SumatraPDF.exe" -reuse-instance -forward-search "?c:am.tex" @ "?am.pdf"
```

TeXstudio’s `?c:am.tex`, `@` (line), and `?am.pdf` expand to the current root source, line, and PDF. Older docs used `-inverse-search` on this same command line; setting `InverseSearchCmdLine` once in Sumatra is enough and easier to maintain.

**3. Use it**

- Build with SyncTeX (default in TeXstudio PDF workflows).
- Forward: TeXstudio’s “Go to PDF” / jump to PDF action.
- Inverse: double-click in Sumatra.

### Visual Studio Code / Cursor (LaTeX Workshop)

Install the [LaTeX Workshop](https://marketplace.visualstudio.com/items?itemName=James-Yu.latex-workshop) extension. External-viewer SyncTeX is not officially supported by LaTeX Workshop; this is the setup that works with Sumatra.

**1. Inverse search (in Sumatra)**

Set this once (`Ctrl + K`, `Set Inverse Search Command Line` command in [Command Palette](Command-Palette.md), or Advanced Settings). Overwrite `InverseSearchCmdLine` in place; do not paste it under the “Settings below are not recognized” footer, or Sumatra ignores it.

Prefer the `code` / `cursor` CLI on `PATH`, or a full path to the `.cmd` launcher:

```
"C:\Users\<you>\AppData\Local\Programs\Microsoft VS Code\bin\code.cmd" -r -g "%f:%l"
```

`-r` reuses the existing VS Code window. `-g "%f:%l"` opens file `%f` at line `%l` (lowercase L). Using `.cmd` (not only `Code.exe`) avoids some inverse-search failures on Windows. For Cursor, use the analogous `cursor.cmd` path.

If that still fails, launch via Electron’s CLI:

```
"C:\Users\<you>\AppData\Local\Programs\Microsoft VS Code\Code.exe" "C:\Users\<you>\AppData\Local\Programs\Microsoft VS Code\resources\app\out\cli.js" --ms-enable-electron-run-as-node -r -g "%f:%l"
```

Also set `EnableTeXEnhancements = true` (the inverse-search dialog does this on OK).

**2. External viewer (in VS Code `settings.json`)**

`Ctrl + Shift + P` → **Preferences: Open User Settings (JSON)**. Point `viewer.command` / `synctex.command` at your Sumatra (installer under `C:/Program Files/SumatraPDF/`, or portable under `%LOCALAPPDATA%/SumatraPDF/`).

```json
{
  "latex-workshop.view.pdf.viewer": "external",
  "latex-workshop.view.pdf.external.viewer.command": "C:/Program Files/SumatraPDF/SumatraPDF.exe",
  "latex-workshop.view.pdf.external.viewer.args": ["-reuse-instance", "%PDF%"],
  "latex-workshop.view.pdf.external.synctex.command": "C:/Program Files/SumatraPDF/SumatraPDF.exe",
  "latex-workshop.view.pdf.external.synctex.args": ["-reuse-instance", "-forward-search", "%TEX%", "%LINE%", "%PDF%"]
}
```

`%TEX%`, `%LINE%`, and `%PDF%` are LaTeX Workshop placeholders. Do not add `-inverse-search "..."` here once Sumatra already has `InverseSearchCmdLine`; sending it on every jump can cause issues.

**3. Use it**

- Build so SyncTeX is produced (LaTeX Workshop recipes usually pass `-synctex=1`).
- View PDF: LaTeX Workshop **View LaTeX PDF file in external viewer**.
- Forward: **SyncTeX from cursor** (`Ctrl + Alt + J`).
- Inverse: double-click in Sumatra → VS Code focuses `%f` at line `%l`.

For LaTeX inside WSL Remote, see [LaTeX integration with WSL](LaTeX-integration-wsl.md) (TexLab, not LaTeX Workshop).

### TeXworks

**1. Inverse search (in Sumatra)**

```
"C:\Program Files\MiKTeX\miktex\bin\x64\texworks.exe" -p=%l "%f"
```

(or your TeX Live / standalone TeXworks path)

**2. Viewer (in TeXworks)**

- **Edit → Preferences → Typesetting** (or **Preview**)
- PDF viewer: SumatraPDF, or a custom command:

```
"C:\Program Files\SumatraPDF\SumatraPDF.exe" -reuse-instance "$fullname.pdf"
```

Enable SyncTeX in the typesetting tool arguments (`-synctex=1` on pdfLaTeX/XeLaTeX/LuaLaTeX). TeXworks’ “jump to PDF” uses SyncTeX when the viewer supports it; with Sumatra, forward search is often:

```
"C:\Program Files\SumatraPDF\SumatraPDF.exe" -reuse-instance -forward-search "$fullname.tex" $line "$fullname.pdf"
```

(exact placeholders depend on TeXworks version; use its help for `$fullname` / line variables).

### WinEdt

WinEdt has built-in SumatraPDF integration.

**1. PDF viewer (in WinEdt)**

- **Options → Execution Modes → PDF Viewer**
- Uncheck Auto-detect if needed, choose **SumatraPDF**, or browse to `SumatraPDF.exe`.

WinEdt’s macros typically call Sumatra with `-forward-search` (preferred over older DDE).

**2. Inverse search (in Sumatra)**

```
"C:\Program Files\WinEdt Team\WinEdt\WinEdt.exe" "[Open(|%f|);SelPar(%l,8)]"
```

**3. Use it**

- Compile with SyncTeX enabled in the execution mode.
- Forward: WinEdt’s PDF preview / search commands.
- Inverse: double-click in Sumatra.

### TeXnicCenter

**1. Inverse search (in Sumatra)**

```
"C:\Program Files\TeXnicCenter\TeXnicCenter.exe" /nosplash /ddecmd "[goto('%f', '%l')]"
```

**2. Output profile viewer (in TeXnicCenter)**

- **Build → Define Output Profiles** (`Alt + F7`) → PDF profile → **Viewer**
- **Executable path:** `C:\Program Files\SumatraPDF\SumatraPDF.exe` (path only)
- **View project’s output:** command-line argument `"%bm.pdf"`
- **Forward search:**

```
-reuse-instance -forward-search "%Wc" %l "%bm.pdf"
```

**3. Sumatra**

- `ReuseInstance = true`, `ReloadModifiedDocuments = true`, `EnableTeXEnhancements = true`
- Build and view once, then inverse-search with double-click.

### Texmaker

**1. Inverse search (in Sumatra)**

```
"C:\Program Files\Texmaker\texmaker.exe" "%f" -line %l
```

**2. Viewer (in Texmaker)**

- **Options → Configure Texmaker → Commands**
- **External viewer:**

```
"C:/Program Files/SumatraPDF/SumatraPDF.exe" -reuse-instance %.pdf
```

For SyncTeX forward search (if your Texmaker version supports a dedicated “built-in + external” / jump option), use:

```
"C:/Program Files/SumatraPDF/SumatraPDF.exe" -reuse-instance -forward-search %.tex @ %.pdf
```

(`%.tex` / `%.pdf` / `@` are Texmaker placeholders for root name and line.)

Ensure **PdfLaTeX** (etc.) includes `-synctex=1`.

### Notepad++

Notepad++ is not a full LaTeX IDE; pair it with a build tool (e.g. NppExec + `latexmk`, or an external Makefile).

**1. Inverse search (in Sumatra)**

```
"C:\Program Files\Notepad++\notepad++.exe" -n%l "%f"
```

**2. Open / forward search**

Run Sumatra with something like (NppExec / Run dialog; expand paths to match your macros):

```
"C:\Program Files\SumatraPDF\SumatraPDF.exe" -reuse-instance -forward-search "$(FULL_CURRENT_PATH)" $(CURRENT_LINE) "$(CURRENT_DIRECTORY)\$(NAME_PART).pdf"
```

### Sublime Text (LaTeXTools or similar)

**1. Inverse search (in Sumatra)**

```
"C:\Program Files\Sublime Text\sublime_text.exe" "%f:%l:%c"
```

**2. LaTeXTools**

In LaTeXTools settings, set the Windows viewer to SumatraPDF (or the package’s Sumatra preset). LaTeXTools documents the forward-search invocation; it generally calls Sumatra with `-forward-search` and `-reuse-instance`.

### Vim / gVim

**1. Inverse search (in Sumatra)**

Simple open at line:

```
"C:\Program Files\Vim\vim91\gvim.exe" --remote-silent +%l "%f"
```

Or, with a custom callback (see below), a `--remote-send` form.

**2. Forward search** (example, Vim9 script in `ftplugin/tex.vim`):

```vim
def ForwardSearch()
  var root = expand('%:p:r')
  system($'SumatraPDF.exe -reuse-instance -forward-search {root}.tex {line(".")} {root}.pdf')
enddef
nnoremap <buffer> <F5> <ScriptCmd>ForwardSearch()<CR>
```

Use the full path to `SumatraPDF.exe` if it is not on `PATH`.

**3. Optional callback inverse search**

Define a global function the inverse-search line can call, then set:

```
gvim --servername GVIM --remote-send ":call BackwardSearch(%l, '%f')<CR>"
```

(with a matching `BackwardSearch` implementation in your config).

### Emacs (AUCTeX)

See [EmacsWiki AUCTeX – SumatraPDF](https://www.emacswiki.org/emacs/AUCTeX#toc25) for the maintained recipe.

Typical pieces:

- **Inverse search (Sumatra):**  
  `"C:\...\emacsclientw.exe" -n +%l "%f"`  
  (start an Emacs server first)
- **Forward search:** AUCTeX viewer entry calling  
  `SumatraPDF.exe -reuse-instance -forward-search %b.tex %n %o`  
  (exact expandos depend on your AUCTeX viewer config)

### LyX

On Windows, set the PDF viewer to SumatraPDF under **Tools → Preferences → File Handling → File Formats** (PDF).

For SyncTeX-style jumps, use a PDF viewer converter / view command that launches:

```
SumatraPDF.exe -reuse-instance "$o"
```

and set inverse search in Sumatra to your LyX executable with the arguments LyX documents for SyncTeX inverse search (version-specific). See [LyX + Sumatra forward/inverse search notes](http://joonro.github.io/blog/posts/inverse-and-forward-search-lyx-windows/) for a full walkthrough.

### Typst

[Typst](https://typst.app/) is a markup typesetter (not LaTeX). The Typst project [recommends SumatraPDF on Windows](https://typst.app/open-source/) because Sumatra reloads the PDF while `typst watch` rewrites it and does not lock the file.

The Typst CLI does **not** write SyncTeX (`.synctex` / `.synctex.gz`). Sumatra’s forward search (`-forward-search`) and inverse search (double-click to source) need that file, so they do not work for `.typ` the way they do for LaTeX. For click-to-source, use [Tinymist](https://github.com/Myriad-Dreamin/tinymist)’s built-in preview, not Sumatra.

**1. Sumatra**

```
ReuseInstance = true
ReloadModifiedDocuments = true
```

**2. CLI**

In the project directory:

```
typst watch main.typ
```

Open `main.pdf` in Sumatra (or run `typst compile --open main.typ` once if Sumatra is the default PDF viewer). Each save rebuilds the PDF; Sumatra reloads it.

**3. VS Code / Cursor (Tinymist)**

Install [Tinymist Typst](https://marketplace.visualstudio.com/items?itemName=myriad-dreamin.tinymist). To keep a PDF next to the source for Sumatra:

```json
{
  "tinymist.exportPdf": "onSave"
}
```

Use `"onType"` to rewrite the PDF on every keystroke (heavier). Open that PDF in Sumatra. Inverse-search command line is the same as for [LaTeX Workshop](#visual-studio-code--cursor-latex-workshop) (`code.cmd -r -g "%f:%l"`), but without SyncTeX it will not jump to a line.

**4. Use it**

- Edit `.typ` → compiler or Tinymist writes PDF → Sumatra reloads.
- Source ↔ preview jumps: Tinymist preview, not Sumatra.

---

## Tips and troubleshooting

1. **Always compile with SyncTeX** (`-synctex=1`). Without `.synctex`/`.synctex.gz`, jumps cannot map lines. Typst does not emit SyncTeX; see [Typst](#typst).
2. **Set inverse search once in Sumatra** rather than stuffing a long `-inverse-search "..."` into every editor viewer command.
3. **Paths with spaces** must be quoted; placeholders `%f` / `%l` stay outside or inside quotes as in the examples.
4. **PDF does not reload after build** — set `ReloadModifiedDocuments = true`; avoid locking the PDF (Sumatra does not lock like some readers).
5. **Many Sumatra windows** — set `ReuseInstance = true` and pass `-reuse-instance` from the editor when opening/forward-searching.
6. **Wrong or missing inverse editor** — use **Set Inverse Search Command Line** and pick a detected editor, or paste a command that works from a `cmd` prompt with a sample file and line.
7. **Accented / non-ASCII paths** — use a Unicode-capable editor launch line; prefer UTF-8 locale / editor settings (see also historical notes on inverse search and encoding).
8. **WSL sources** — use [LaTeX integration with WSL](LaTeX-integration-wsl.md).
9. **DDE** — still works for some editors (e.g. TeXnicCenter `goto`); for new setups prefer `-forward-search` and a normal process command for inverse search. See [DDE Commands](DDE-Commands.md).

## Related

- [Command-line arguments](Command-line-arguments.md) (`-forward-search`, `-inverse-search`, forward-search highlight flags)
- [DDE Commands](DDE-Commands.md)
- [LaTeX integration with WSL](LaTeX-integration-wsl.md)
- [Typst](https://typst.app/), [Tinymist](https://github.com/Myriad-Dreamin/tinymist)
- Advanced settings: `InverseSearchCmdLine`, `EnableTeXEnhancements`, `ForwardSearch` highlight options


---

<!-- Configure-for-restricted-use.md -->

# Configure for restricted use

SumatraPDF can be configured for restricted use.

Restricted mode is useful if you want to use SumatraPDF as a bundled viewer for your program's documentation or in kiosk mode.

In restricted mode, some actions that are not appropriate in such contexts are disabled:

- opening new files
- launching URLs from within PDF documents
- text and image selection
- printing
- changing default settings
- saving to disk
- automatic and manual update checks
- a history of recently opened files
- TeX preview support
- registering as a default PDF viewer
- opening with Adobe Acrobat
- emailing PDFs

To restrict SumatraPDF, put the `sumatrapdfrestrict.ini` file in the same directory as `SumatraPDF.exe`.

Here is the [full documentation for the available options](https://github.com/sumatrapdfreader/sumatrapdf/blob/master/docs/sumatrapdfrestrict.ini).

To disable only auto-detected URL, email, and plain-text DOI links in PDF text (not embedded hyperlinks), use `DisableAutoLinks` in normal [advanced settings](Advanced-options-settings.md) instead — see [Hyperlinks](Hyperlinks.md).


---

<!-- Installer-cmd-line-arguments.md -->

# Installer cmd-line arguments

To get a list of options, run the installer with `-help`.

Available options:

- `-install` : triggers installation
- `-s`, `-silent` : performs a silent installation without showing the UI
- `-d <directory>` e.g. `Sumatra-install.exe -install -d "c:\Sumatra PDF"`
  sets the directory where the program is installed. The default is `%LOCALAPPDATA%\SumatraPDF`, or `%PROGRAMFILES%\SumatraPDF` with `-all-users`
- `-x` : don't install, extract the files
  extracts files to the current directory, or to `-d <directory>` if specified. When the destination is this executable's own directory, `SumatraPDF.exe` is left in place and only the payload (`libsumatrapdf.dll` and the other installation files) is unpacked. Errors are printed to the console if one is already attached.
- `-with-filter` : install search filter
- `-with-preview` : install shell preview for PDF files
- `-uninstall` : uninstalls SumatraPDF

**Ver 3.2+**

- `-log`
  writes the installation log to `%LOCALAPPDATA%\sumatra-install-log.txt`. At the end of the installation, it opens the log file in Notepad.

**Ver 3.4+**

- `-all-users` : installs system-wide, for all users
  installs to `%PROGRAMFILES%\SumatraPDF` and writes to the `HKLM` registry

**Ver 3.6+**

- `-fast-install` : internal for auto-update, automatically starts installation with default options, starts the app when installation is finished

**Ver 3.7+**

- `-no-desktop-shortcut` : don't create a desktop shortcut (the **Install desktop shortcut** option). An upgrade keeps the choice of the previous installation


---

<!-- Tools.md -->

# SumatraPDF command-line tools

**Available in [pre-release 3.7](https://www.sumatrapdfreader.org/prerelease)**

You can run `sumatrapdf-tool.exe <tool>` or [SumatraPDF.exe <tool>](Tools.md) to perform operations on PDF and other files. Both work with the portable EXE; no install required.

## `sumatrapdf-tool.exe` vs. `SumatraPDF.exe`

When you install SumatraPDF, we also install `sumatrapdf-tool.exe` and add it to PATH.

`sumatrapdf-tool.exe` is a console program that provides command-line access to many of SumatraPDF's features.

It's meant for use from the command line or from scripts.

The same commands work with the portable EXE as `SumatraPDF.exe <tool>` — no install and no extra extract. You can also extract `sumatrapdf-tool.exe` with `-x` if you want the console binary.

The difference is that `SumatraPDF.exe` is a GUI application, so it won't work as well when, for example, redirecting output to a file or running from scripts.

## I want to…

| Goal                                           | Tool / doc                                                                                                       |
| ---------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- |
| Delete specific pages                          | `clean` — [Delete pages from PDF](Tool-x-delete-pages-from-pdf.md)                                               |
| Delete the last page without knowing the count | `clean input.pdf out.pdf 1--2` (`-2` = second-to-last page)                                                      |
| Extract pages into a new PDF                   | `clean` — [Extract pages from PDF](Tool-x-extract-pages-from-pdf.md)                                             |
| Merge PDFs                                     | `merge` — [Merge PDFs](Merge-PDFs.md)                                                                            |
| Split a PDF                                    | `merge` / `clean` — [Split a PDF](Split-a-PDF.md)                                                                |
| Reorder pages                                  | `clean` — [Reorder pages in a PDF](Reorder-PDF-pages.md)                                                         |
| Rotate pages permanently                       | `run` — [Rotate PDF pages](Rotate-PDF-pages.md)                                                                  |
| Crop page margins                              | `run` — [Crop PDF page margins](Crop-PDF-margins.md)                                                             |
| Print a large page as a poster                 | `run` — [Print a large page as a poster](Print-PDF-as-poster.md)                                                 |
| Add page numbers / a watermark                 | `run` — [Page numbers](Add-page-numbers-to-PDF.md), [Watermark](Add-a-watermark-to-PDF.md)                       |
| Add bookmarks (table of contents)              | `run` — [Add a table of contents](Add-table-of-contents-to-PDF.md)                                               |
| Search text in one or many PDFs                | `grep` — [Tool grep](Tool-grep.md)                                                                               |
| Extract plain text                             | `draw -tt` or `grep` — [Extract text from PDF](Tool-x-extract-text-from-pdf.md)                                  |
| Extract embedded images                        | `extract` — [Extract images from PDF](Tool-x-extract-images-from-pdf.md)                                         |
| Extract fonts                                  | `info`, `extract` — [Extract fonts from a PDF](Extract-fonts-from-PDF.md)                                        |
| Save attached files                            | `extract`, `run` — [Save files attached to a PDF](Save-PDF-attachments.md)                                       |
| Compress / rewrite PDF                         | `clean` — [Compress a PDF](Tool-x-compress-pdf.md)                                                               |
| Remove compression streams                     | `clean` — [Decompress a PDF](Tool-x-decompress-pdf.md)                                                           |
| Password-protect a PDF                         | `clean` — [Encrypt a PDF](Tool-x-encrypt-pdf-with-password.md)                                                   |
| Remove password                                | `clean` — [Decrypt a PDF](Tool-x-decrypt-pdf.md)                                                                 |
| Repair a damaged PDF                           | `clean` — [Repair a damaged PDF](Repair-a-damaged-PDF.md)                                                        |
| Convert to grayscale                           | `recolor` — [Convert a PDF to grayscale](Convert-PDF-to-grayscale.md)                                            |
| Flatten forms and annotations                  | `bake` — [Flatten PDF forms and annotations](Flatten-PDF-forms-and-annotations.md)                               |
| Sign a PDF                                     | `sign` — [Sign a PDF](Sign-a-PDF.md), [Tool sign](Tool-sign.md)                                                  |
| Convert images / other formats to PDF          | `convert` / `draw` — [Tool convert](Tool-convert.md); how-tos: [images](Convert-images-to-PDF.md), [comics](Convert-comics-to-PDF.md), [EPUB](Convert-EPUB-to-PDF.md) |
| Inspect PDF structure                          | `info`, `show`, `pages` — [See PDF info](Show-PDF-info.md), [Tool info](Tool-info.md)                            |
| Run a tool on many files                       | [Process many PDFs at once](Batch-process-PDFs.md)                                                               |
| Run JavaScript on PDFs                         | `run` — [Tool run](Tool-run.md)                                                                                  |

The same page-delete operations are also available in the app: `Ctrl + K`, `Delete Pages From PDF` command in [Command Palette](Command-Palette.md), or context menu **Document → Delete Pages From PDF**.

```
sumatrapdf-tool.exe <command> [options]
  draw    -- convert document
  convert -- convert document (with simpler options)
  audit   -- produce usage stats from PDF files
  bake    -- bake PDF form into static content
  clean   -- rewrite PDF file
  create  -- create PDF document
  extract -- extract font and image resources
  info    -- show information about PDF resources
  merge   -- merge pages from multiple PDF sources into a new PDF
  pages   -- show information about PDF pages
  poster  -- split large PDF page into many tiles
  recolor -- change colorspace of PDF document
  show    -- show internal PDF objects
  sign    -- manipulate PDF digital signatures
  trim    -- trim PDF page contents
  grep    -- search for text
  trace   -- trace device calls
  run     -- run a MuPDF JavaScript program
```

Tools:

- [draw](Tool-draw.md)
- [convert](Tool-convert.md)
- [audit](Tool-audit.md)
- [bake](Tool-bake.md)
- [clean](Tool-clean.md)
- [extract](Tool-extract.md)
- [info](Tool-info.md)
- [merge](Tool-merge.md)
- [pages](Tool-pages.md)
- [poster](Tool-poster.md)
- [recolor](Tool-recolor.md)
- [show](Tool-show.md)
- [sign](Tool-sign.md)
- [trim](Tool-trim.md)
- [grep](Tool-grep.md)
- [trace](Tool-trace.md)
- [run](Tool-run.md)
- [run JavaScript examples](Tool-run-javascript-examples.md)


---

<!-- Tool-draw.md -->

# sumatrapdf-tool draw

or [SumatraPDF.exe draw](Tools.md)

**Available in [pre-release 3.7](https://www.sumatrapdfreader.org/prerelease)**

**Usage:** `sumatrapdf-tool draw [options] file [pages]`

See [all-options](#all-options) below.

You can use `draw` to:

- convert PDF to other formats (image, HTML, SVG)
- extract, delete pages
- extract text

## Example usage

Let's assume you have `foo.pdf` with 8 pages.

### Extract the second page as a PNG image

`sumatrapdf-tool draw -o foo-page-2.png -F png foo.pdf 2`

### Rotate pages

Use the `-R 90|180|270` option to rotate pages.

### Extract each page as PNG image

`sumatrapdf-tool draw -o "foo-%d.png" foo.pdf`

### Convert PDF to PNG

`sumatrapdf-tool draw -o "foo-%d.png" foo.pdf`

### Change output image size

Each page in a PDF has a given width / height.

When converting to an image (like PNG), you can change the size of the output image:

`sumatrapdf-tool draw -o "foo-%d.png" -w 400 -h 800 foo.pdf`

### Render at a specific resolution (DPI)

Instead of a pixel size, you can render at a resolution with `-r` (the default is 72 DPI). This is handy for print-quality images:

`sumatrapdf-tool draw -o "foo-%d.png" -r 300 foo.pdf`

### Convert PNG to PDF

`sumatrapdf-tool draw  -o foo.pdf foo.png`

### Convert PDF to self-contained HTML file

`sumatrapdf-tool draw -o foo.html foo.pdf`

### Convert PDF to self-contained SVG file

`sumatrapdf-tool draw -o foo.svg foo.pdf`

### Extract all text from PDF

`sumatrapdf-tool draw -o foo.txt foo.pdf`

### Structured text

In a PDF, text consists of characters positioned on a page.

If you want detailed information about text in a PDF, especially for further programmatic processing, you can extract structured text: font, glyph (character), and position.

### Extract structured text from PDF in XML format

`sumatrapdf-tool draw -o foo.stext foo.pdf`

In XML format it might look like:

```xml
<font name="CharisSIL" size="7.9701">
<char quad="187.4652 295.9985 191.96033 295.9985 187.4652 301.9683 191.96033 301.9683" x="187.4652" y="301.871" bidi="0" color="#000000" alpha="#ff" flags="16" c="d"/>
```

This shows that the letter `d` in the `CharisSIL` font is at a given x/y position on the page.

### Extract structured text from PDF in JSON format

`sumatrapdf-tool draw -o foo.stext.json -F stext.json foo.pdf`

It's the same information but in JSON format.

## All options

```
usage: SumatraPDF draw [options] file [pages]
  -p -    password

  -o -    output file name (%d for page number)
  -F -    output format (default inferred from output file name)
          raster: png, pnm, pam, pbm, pkm, pwg, pcl, ps, pdf, j2k
          vector: svg, pdf, trace, ocr.trace
          text: txt, html, xhtml, stext, stext.json
          ocr'd text: ocr.txt, ocr.html, ocr.xhtml, ocr.stext, ocr.stext.json (disabled)
          bitmap-wrapped-as-pdf: pclm, ocr.pdf

  -q      be quiet (don't print progress messages)
  -s -    show extra information:
          m - show memory use
          t - show timings
          f - show page features
          5 - show md5 checksum of rendered image

  -R -    rotate clockwise (default: 0 degrees)
  -r -    resolution in dpi (default: 72)
  -w -    width (in pixels) (maximum width if -r is specified)
  -h -    height (in pixels) (maximum height if -r is specified)
  -f      fit width and/or height exactly; ignore original aspect ratio
  -b -    use named page box (MediaBox, CropBox, BleedBox, TrimBox, or ArtBox)
  -B -    maximum band_height (pXm, pcl, pclm, ocr.pdf, ps, psd and png output only)
  -T -    maximum number of rendering threads (banded mode only, limited to number of bands per page)

  -W -    page width for EPUB layout
  -H -    page height for EPUB layout
  -S -    font size for EPUB layout
  -U -    file name of user stylesheet for EPUB layout
  -X      disable document styles for EPUB layout
  -a      disable usage of accelerator file

  -c -    colorspace (mono, gray, grayalpha, rgb, rgba, cmyk, cmykalpha, filename of ICC profile)
  -e -    proof icc profile (filename of ICC profile)
  -G -    apply gamma correction
  -I      invert colors

  -A -    number of bits of antialiasing (0 to 8)
  -A -/-  number of bits of antialiasing (0 to 8) (graphics, text)
  -l -    minimum stroked line width (in pixels)
  -K      do not draw text
  -KK     only draw text
  -D      disable use of display list
  -i      ignore errors
  -m -    limit memory usage in bytes
  -L      low memory mode (avoid caching, clear objects after each page)
  -P      parallel interpretation/rendering
  -N      disable ICC workflow ("N"o color management)
  -O -    Control spot/overprint rendering
            0 = No spot rendering
            1 = Overprint simulation (default)
            2 = Full spot rendering
  -t -    Specify language/script for OCR (default: eng) (disabled)
  -d -    Specify path for OCR files (default: rely on TESSDATA_PREFIX environment variable) (disabled)
  -k -{,-}        Skew correction options. auto or angle {0=increase size, 1=maintain size, 2=decrease size} (disabled)

  -y l    List the layer configs to stderr
  -y -    Select layer config (by number)
  -y -{,-}*       Select layer config (by number), and toggle the listed entries

  -Y      List individual layers to stderr
  -z -    Hide individual layer
  -Z -    Show individual layer

  pages   comma separated list of page numbers and ranges
```


---

<!-- Tool-convert.md -->

# sumatrapdf-tool convert

or [SumatraPDF.exe convert](Tools.md)

**Available in [pre-release 3.7](https://www.sumatrapdfreader.org/prerelease)**

**Usage:** `sumatrapdf-tool convert [options] file [pages]`

`convert` converts a document into another format: raster images (`png`, `pnm`, `cbz` ...), print formats (`pcl`, `ps`, `pwg` ...), vector formats (`pdf`, `svg`) or text (`html`, `xhtml`, `text`, `stext`). The output format is inferred from the output file's extension, or set explicitly with `-F`.

The output file name is given with `-o`. For per-page formats, embed `%d` in the name to substitute the page number (printf modifiers like `%03d` work too). If you don't pass `-o`, output goes to stdout.

Convert each page of a PDF to a PNG image:

`sumatrapdf-tool convert -o page%d.png input.pdf`

Convert a PDF to plain text:

`sumatrapdf-tool convert -o out.txt input.pdf`

Convert only pages 1-5 to a single CBZ:

`sumatrapdf-tool convert -o out.cbz input.pdf 1-5`

Fine-tune the output with `-O` (for example the render resolution for raster output):

`sumatrapdf-tool convert -o page%d.png -O resolution=300 input.pdf`

## All options

```
Usage: SumatraPDF convert [options] file [pages]
  -p -    password

  -b -    use named page box (MediaBox, CropBox, BleedBox, TrimBox, or ArtBox)
  -A -    number of bits of antialiasing (0 to 8)
  -W -    page width for EPUB layout
  -H -    page height for EPUB layout
  -S -    font size for EPUB layout
  -U -    file name of user stylesheet for EPUB layout
  -X      disable document styles for EPUB layout

  -o -    output file name (%d for page number)
  -F -    output format (default inferred from output file name)
                  raster: cbz, png, pnm, pgm, ppm, pam, pbm, pkm.
                  print-raster: pcl, pclm, ps, pwg.
                  vector: pdf, svg.
                  text: html, xhtml, text, stext.
  -O -    comma separated list of options for output format

  pages   comma separated list of page ranges (N=last page)

Raster output options:
  rotate=N: rotate rendered pages N degrees counterclockwise
  resolution=N: set both X and Y resolution in pixels per inch
  x-resolution=N: X resolution of rendered pages in pixels per inch
  y-resolution=N: Y resolution of rendered pages in pixels per inch
  width=N: render pages to fit N pixels wide (ignore resolution option)
  height=N: render pages to fit N pixels tall (ignore resolution option)
  colorspace=(gray|rgb|cmyk): render using specified colorspace
  alpha: render pages with alpha channel and transparent background
  graphics=(aaN|cop|app): set the rasterizer to use
  text=(aaN|cop|app): set the rasterizer to use for text
          aaN=antialias with N bits (0 to 8)
          cop=center of pixel
          app=any part of pixel

PCL output options:
  colorspace=mono: render 1-bit black and white page
  colorspace=rgb: render full color page
  preset=generic|ljet4|dj500|fs600|lj|lj2|lj3|lj3d|lj4|lj4pl|lj4d|lp2563b|oce9050
  spacing=0: No vertical spacing capability
  spacing=1: PCL 3 spacing (<ESC>*p+<n>Y)
  spacing=2: PCL 4 spacing (<ESC>*b<n>Y)
  spacing=3: PCL 5 spacing (<ESC>*b<n>Y and clear seed row)
  mode2: Enable mode 2 graphics compression
  mode3: Enable mode 3 graphics compression
  eog_reset: End of graphics (<ESC>*rB) resets all parameters
  has_duplex: Duplex supported (<ESC>&l<duplex>S)
  has_papersize: Papersize setting supported (<ESC>&l<sizecode>A)
  has_copies: Number of copies supported (<ESC>&l<copies>X)
  is_ljet4pjl: Disable/Enable HP 4PJL model-specific output
  is_oce9050: Disable/Enable Oce 9050 model-specific output

PCLm output options:
  compression=none: No compression (default)
  compression=flate: Flate compression
  strip-height=N: Strip height (default 16)

PWG output options:
  media_class=<string>: set the media_class field
  media_color=<string>: set the media_color field
  media_type=<string>: set the media_type field
  output_type=<string>: set the output_type field
  rendering_intent=<string>: set the rendering_intent field
  page_size_name=<string>: set the page_size_name field
  advance_distance=<int>: set the advance_distance field
  advance_media=<int>: set the advance_media field
  collate=<int>: set the collate field
  cut_media=<int>: set the cut_media field
  duplex=<int>: set the duplex field
  insert_sheet=<int>: set the insert_sheet field
  jog=<int>: set the jog field
  leading_edge=<int>: set the leading_edge field
  manual_feed=<int>: set the manual_feed field
  media_position=<int>: set the media_position field
  media_weight=<int>: set the media_weight field
  mirror_print=<int>: set the mirror_print field
  negative_print=<int>: set the negative_print field
  num_copies=<int>: set the num_copies field
  orientation=<int>: set the orientation field
  output_face_up=<int>: set the output_face_up field
  page_size_x=<int>: set the page_size_x field
  page_size_y=<int>: set the page_size_y field
  separations=<int>: set the separations field
  tray_switch=<int>: set the tray_switch field
  tumble=<int>: set the tumble field
  media_type_num=<int>: set the media_type_num field
  compression=<int>: set the compression field
  row_count=<int>: set the row_count field
  row_feed=<int>: set the row_feed field
  row_step=<int>: set the row_step field

Structured text options:
  preserve-images: keep images in output
  preserve-ligatures: do not expand ligatures into constituent characters
  preserve-spans: do not merge spans on the same line
  preserve-whitespace: do not convert all whitespace into space characters
  inhibit-spaces: don't add spaces between gaps in the text
  paragraph-break: break blocks at paragraph boundaries
  dehyphenate: attempt to join up hyphenated words
  ignore-actualtext: do not apply ActualText replacements
  use-cid-for-unknown-unicode: use character code if unicode mapping fails
  use-gid-for-unknown-unicode: use glyph index if unicode mapping fails
  accurate-bboxes: calculate char bboxes from the outlines
  accurate-ascenders: calculate ascender/descender from font glyphs
  accurate-side-bearings: expand char bboxes to completely include width of glyphs
  collect-styles: attempt to detect text features (fake bold, strikeout, underlined etc)
  clip: do not include text that is completely clipped
  clip-rect=x0:y0:x1:y1 specify clipping rectangle within which to collect content
  structured: collect structure markup
  vectors: include vector bboxes in output
  segment: attempt to segment the page
  table-hunt: hunt for tables within a (segmented) page
  resolution: resolution to render at

PDF output options:
  decompress: decompress all streams (except compress-fonts/images)
  compress=yes|flate|brotli: compress all streams, yes defaults to flate
  compress-fonts: compress embedded fonts
  compress-images: compress images
  compress-effort=0|percentage: effort spent compressing, 0 is default, 100 is max effort
  ascii: ASCII hex encode binary streams
  pretty: pretty-print objects with indentation
  labels: print object labels
  clean: pretty-print graphics commands in content streams
  sanitize: sanitize graphics commands in content streams
  garbage: garbage collect unused objects
  or garbage=compact: ... and compact cross reference table
  or garbage=deduplicate: ... and remove duplicate objects
  incremental: write changes as incremental update
  objstms: use object streams and cross reference streams
  appearance=yes|all: synthesize just missing, or all, annotation/widget appearance streams
  continue-on-error: continue saving the document even if there is an error
  decrypt: write unencrypted document
  encrypt=rc4-40|rc4-128|aes-128|aes-256: write encrypted document
  permissions=NUMBER: document permissions to grant when encrypting
  user-password=PASSWORD: password required to read document
  owner-password=PASSWORD: password required to edit document
  regenerate-id: (default yes) regenerate document id

SVG output options:
  text=text: Emit text as <text> elements (inaccurate fonts).
  text=path: Emit text as <path> elements (accurate fonts).
  no-reuse-images: Do not reuse images using <symbol> definitions.
  resolution: Resolution to use when rasterizing elements.
```


---

<!-- Tool-audit.md -->

# sumatrapdf-tool audit

or [SumatraPDF.exe audit](Tools.md)

**Available in [pre-release 3.7](https://www.sumatrapdfreader.org/prerelease)**

**Usage:** `sumatrapdf-tool audit [options] input.pdf [input2.pdf ...]`

See [all-options](#all-options) below.

Audit is an advanced option for inspecting the PDF file format.

It generates an HTML report of operator and space usage in a PDF file. The report has three parts:

- how much of the file is actual object data vs. the overhead of storing those objects (inside and outside of object streams)
- a breakdown of how space is used by the different kinds of objects
- how frequently each graphical operator is used in the content streams

The figures are indicative rather than 100% accurate, and the report assumes some familiarity with the PDF format.

## Generate HTML report about PDF file

`sumatrapdf-tool audit -o report.html .\foo.pdf`

You can then open `report.html` in a browser.

## All options

```
Usage: SumatraPDF audit [options] input.pdf [input2.pdf ...]
  -o -    output file
```


---

<!-- Tool-bake.md -->

# sumatrapdf-tool bake

or [SumatraPDF.exe bake](Tools.md)

**Available in [pre-release 3.7](https://www.sumatrapdfreader.org/prerelease)**

**Usage:** `sumatrapdf-tool bake [options] input.pdf [output.pdf]`

The PDF format has annotations and widgets (used in forms) as special kinds of objects.

`bake` is an advanced tool that converts annotations and widgets into regular, static PDF content.

By default it bakes both annotations and form fields into the page content. Use `-A` to keep annotations as annotations (don't bake them) and `-F` to keep form fields interactive.

If you don't specify an output file, it writes to `out.pdf`.

## All options

```
Usage: SumatraPDF bake [options] input.pdf [output.pdf]
  -A      keep annotations
  -F      keep forms
  -O -    comma separated list of output options
```


---

<!-- Tool-clean.md -->

# sumatrapdf-tool clean

or [SumatraPDF.exe clean](Tools.md)

**Available in [pre-release 3.7](https://www.sumatrapdfreader.org/prerelease)**

**Usage:** `sumatrapdf-tool clean [options] input.pdf [output.pdf] [pages]`

See [all-options](#all-options) below.

`clean` rewrites the syntax of a PDF file. You can:

- compress a PDF
- decompress a PDF
- encrypt / decrypt a PDF
- extract / remove pages
- repair a broken PDF (rewriting it often fixes structural problems)

If you don't specify an output file, it writes to `out.pdf`.

## Compress a PDF

`sumatrapdf-tool clean -gggg -e 100 -f -i -t -Z foo.pdf foo-compressed.pdf`

## Decompress a PDF

`sumatrapdf-tool clean -d foo.pdf foo-decompressed.pdf`

## Encrypt a PDF

`sumatrapdf-tool clean -E aes-256 -U pwd foo.pdf foo-encrypted.pdf`

To open `foo-encrypted.pdf`, the user will now have to provide the password `pwd`.

## Decrypt a PDF

`sumatrapdf-tool clean -D -p pwd foo-encrypted.pdf foo-decrypted.pdf`

## Extract pages from PDF as PDF

`sumatrapdf-tool clean input.pdf output.pdf 1,3-5`

This creates `output.pdf` with pages 1, 3, 4, and 5 from `input.pdf`.

## Delete a page from PDF

Suppose you have an eight-page `input.pdf`. To delete page 4:

`sumatrapdf-tool clean input.pdf output.pdf 1-3,5-N`

`N` represents the last page.

### Extract the second page

`sumatrapdf-tool draw -o foo-page-2.pdf foo.pdf 2`

### Extract pages 1, 2, 7, and 8 into separate files

`sumatrapdf-tool draw -o "foo-page-%d.pdf" foo.pdf 1-2,7,8`

### Delete the third page

`sumatrapdf-tool draw -o foo-3rd-page-deleted.pdf foo.pdf 1-2,4-8`

## All options

```
Usage: SumatraPDF clean [options] input.pdf [output.pdf] [pages]
  -p -    password
  -g      garbage collect unused objects
  -gg     in addition to -g compact xref table
  -ggg    in addition to -gg merge duplicate objects
  -gggg   in addition to -ggg check streams for duplication
  -D      save file without encryption
  -E -    save file with new encryption (rc4-40, rc4-128, aes-128, or aes-256)
  -O -    owner password (only if encrypting)
  -U -    user password (only if encrypting)
  -P -    permission flags (only if encrypting)
  -a      ascii hex encode binary streams
  -d      decompress streams
  -z      deflate uncompressed streams
  -e -    compression "effort" (0 = default, 1 = min, 100 = max)
  -f      compress font streams
  -i      compress image streams
  -c      clean content streams
  -s      sanitize content streams
  -t      compact object syntax
  -tt     indented object syntax
  -L      write object labels
  -v      vectorize text
  -A      create appearance streams for annotations
  -AA     recreate appearance streams for annotations
  -m      preserve metadata
  -S      subset fonts if possible [EXPERIMENTAL!]
  -Z      use objstms if possible for extra compression
  --{color,gray,bitonal}-{,lossy-,lossless-}image-subsample-method -
          average, bicubic
  --{color,gray,bitonal}-{,lossy-,lossless-}image-subsample-dpi -[,-]
          DPI at which to subsample [+ target dpi]
  --{color,gray,bitonal}-{,lossy-,lossless-}image-recompress-method -[:quality]
          never, same, lossless, jpeg, j2k, fax, jbig2
  --recompress-images-when -
          smaller (default), always
  --structure=keep|drop   Keep or drop the structure tree
  pages   comma separated list of page numbers and ranges
```


---

<!-- Tool-extract.md -->

# sumatrapdf-tool extract

or [SumatraPDF.exe extract](Tools.md)

**Available in [pre-release 3.7](https://www.sumatrapdfreader.org/prerelease)**

**Usage:** `sumatrapdf-tool extract [options] file.pdf [object numbers]`

`extract` saves embedded images and font files from a PDF to disk. The files are written to the current folder, named `image-<object number>.<ext>` and `font-<object number>.<ext>` with the number padded to 4 digits (e.g. `image-0003.jpg`). Files attached to the PDF are saved too. To extract fonts, see [Extract fonts from a PDF](Extract-fonts-from-PDF.md).

You can use [`sumatrapdf-tool info`](Tool-info.md) to get a list of the image, font, and other objects in a PDF file.

You can then use `sumatrapdf-tool extract` to save image objects to files.

For example, `sumatrapdf-tool info -I` might return:

```
Images (73):
        1       (8 0 R):        [ DCT ] 1280x1781 8bpc ICC (3 0 R)
```

`(8 0 R)` is the object number of the page with the image.

`(3 0 R)` is the object number of the image.

`sumatrapdf-tool extract file.pdf 3` will save the image with object number 3 as `image-0003.jpg`.

If you don't give any object numbers, it extracts all images and fonts from the file.

## All options

```
Usage: SumatraPDF extract [options] file.pdf [object numbers]
  -p      password
  -r      convert images to rgb
  -a      embed SMasks as alpha channel
  -N      do not use ICC color conversions
```


---

<!-- Tool-info.md -->

# sumatrapdf-tool info

or [SumatraPDF.exe info](Tools.md)

**Available in [pre-release 3.7](https://www.sumatrapdfreader.org/prerelease)**

**Usage:** `sumatrapdf-tool info [options] file.pdf [pages]`

A PDF file can contain embedded fonts, images, patterns, etc. Each object has an object number.

`sumatrapdf-tool info foo.pdf` shows a list of objects in the PDF file.

By default it shows all supported types of objects.

Objects are reported per page: the page's object number followed by the matching objects used on it. If you don't supply a `pages` list, all pages are inspected.

You can narrow down what it prints with options:

- `-F` list fonts
- `-I` list images

## All options

```
Usage: SumatraPDF info [options] file.pdf [pages]
  -p -    password for decryption
  -F      list fonts
  -I      list images
  -M      list dimensions
  -P      list patterns
  -S      list shadings
  -X      list form and postscript xobjects
  -Z      list ZUGFeRD info
  pages   comma separated list of page numbers and ranges
```


---

<!-- Tool-merge.md -->

# sumatrapdf-tool merge

or [SumatraPDF.exe merge](Tools.md)

**Available in [pre-release 3.7](https://www.sumatrapdfreader.org/prerelease)**

**Usage:** `sumatrapdf-tool merge [-o output.pdf] [-O options] input.pdf [pages] [input2.pdf] [pages2] ...`

`merge` picks pages from two or more files and combines them into a single output PDF.

Each input file can be followed by a comma-separated list of page numbers and ranges to take from it (the first page is `1`, the last is `N`). If you omit the page list for a file, all of its pages are used.

To take pages 1-3 from `a.pdf` and page 5 from `b.pdf` into `merged.pdf`:

`sumatrapdf-tool merge -o merged.pdf a.pdf 1-3 b.pdf 5`

If you don't specify `-o`, the output is written to `out.pdf`. See `-O` below for the available output options.

## All options

```
Usage: SumatraPDF merge [-o output.pdf] [-O options] input.pdf [pages] [input2.pdf] [pages2] ...
  -o -    name of PDF file to create
  -O -    comma separated list of output options
  input.pdf       name of input file from which to copy pages
  pages   comma separated list of page numbers and ranges

PDF output options:
  decompress: decompress all streams (except compress-fonts/images)
  compress=yes|flate|brotli: compress all streams, yes defaults to flate
  compress-fonts: compress embedded fonts
  compress-images: compress images
  compress-effort=0|percentage: effort spent compressing, 0 is default, 100 is max effort
  ascii: ASCII hex encode binary streams
  pretty: pretty-print objects with indentation
  labels: print object labels
  clean: pretty-print graphics commands in content streams
  sanitize: sanitize graphics commands in content streams
  garbage: garbage collect unused objects
  or garbage=compact: ... and compact cross reference table
  or garbage=deduplicate: ... and remove duplicate objects
  incremental: write changes as incremental update
  objstms: use object streams and cross reference streams
  appearance=yes|all: synthesize just missing, or all, annotation/widget appearance streams
  continue-on-error: continue saving the document even if there is an error
  decrypt: write unencrypted document
  encrypt=rc4-40|rc4-128|aes-128|aes-256: write encrypted document
  permissions=NUMBER: document permissions to grant when encrypting
  user-password=PASSWORD: password required to read document
  owner-password=PASSWORD: password required to edit document
  regenerate-id: (default yes) regenerate document id
```


---

<!-- Tool-pages.md -->

# sumatrapdf-tool pages

or [SumatraPDF.exe pages](Tools.md)

**Available in [pre-release 3.7](https://www.sumatrapdfreader.org/prerelease)**

`Usage: sumatrapdf-tool pages [options] file.pdf [pages]`

`pages` lists the box dimensions (MediaBox, CropBox, TrimBox, etc.), rotation, and UserUnit for each page in XML format. The output looks like:

```xml
<page pagenum="1">
<MediaBox l="0" b="0" r="595.28" t="841.89" />
<CropBox l="85.0394" b="109.134" r="510.241" t="732.756" />
<TrimBox l="113.386" b="137.48" r="481.894" t="704.41" />
<Rotate v="0" />
</page>
```

If you don't supply a `pages` list, all pages are shown.

## All options

```
Usage: SumatraPDF pages [options] file.pdf [pages]
  -p -    password for decryption
  pages   comma separated list of page numbers and ranges
```


---

<!-- Tool-poster.md -->

# sumatrapdf-tool poster

or [SumatraPDF.exe poster](Tools.md)

**Available in [pre-release 3.7](https://www.sumatrapdfreader.org/prerelease)**

**Usage:** `sumatrapdf-tool poster [options] input.pdf [output.pdf]`

`poster` splits large PDF pages into many tiles.

Note: in the current pre-release `poster` fails with `format error: malformed page tree`. Until it's fixed, use the script in [Print a large page as a poster](Print-PDF-as-poster.md).

Suppose you want to print a PDF page at a larger size. `poster` creates a PDF in which each page is enlarged and split into multiple pages that you can print separately and then stitch together.

To print a page that is twice as big in both x and y dimensions:

`sumatrapdf-tool poster -x 2 -y 2 input.pdf output.pdf`

`-x` and `-y` are the number of pieces into which each page is divided horizontally and vertically, so `-x 2 -y 2` turns every PDF page into four pages that you can print separately and assemble into a larger print.

Use `-m` to add an overlap (in points or as a percentage) between adjacent tiles, which makes it easier to align and glue them together. If you don't specify an output file, it writes to `out.pdf`.

## All options

```
Usage: SumatraPDF poster [options] input.pdf [output.pdf]
  -p -    password
  -m -    margin (overlap) between pages (pts, or %)
  -x      x decimation factor
  -y      y decimation factor
  -r      split right-to-left
```


---

<!-- Tool-recolor.md -->

# sumatrapdf-tool recolor

or [SumatraPDF.exe recolor](Tools.md)

**Available in [pre-release 3.7](https://www.sumatrapdfreader.org/prerelease)**

**Usage:** `sumatrapdf-tool recolor [options] <input filename>`

A PDF can use several color spaces. You can use `recolor` to change the color space.

To convert a PDF to gray: `sumatrapdf-tool recolor -o output.pdf -c gray input.pdf`

The output color space (`-c`) can be `gray` (the default), `rgb`, or `cmyk`. Use `-r` to also remove any [output intents](https://en.wikipedia.org/wiki/PDF/X) (embedded color profiles) from the file.

## All options

```
Usage: SumatraPDF recolor [options] <input filename>
  -c -    Output colorspace (gray(default), rgb, cmyk)
  -r      Remove OutputIntent(s)
  -o -    Output file
```


---

<!-- Tool-show.md -->

# sumatrapdf-tool show

or [SumatraPDF.exe show](Tools.md)

**Available in [pre-release 3.7](https://www.sumatrapdfreader.org/prerelease)**

**Usage:** `sumatrapdf-tool show [options] file.pdf ( trailer | xref | pages | grep | outline | js | form | <path> ) *`

`show` is an advanced tool for inspecting the internal structure of a PDF file. It prints the requested objects and streams to standard output (streams are decoded, and non-printable bytes are shown as a period by default).

You tell it what to show with one or more keywords, or a path to an object:

- `trailer` - the trailer dictionary
- `xref` - the cross reference table
- `pages` - the object number for every page
- `grep` - all objects in a compact one-line format, suitable for piping to `grep`
- `outline` - the document outline (table of contents / bookmarks)
- `js` - document-level JavaScript
- `form` - form objects
- `<path>` - a path to a specific object (see [Object paths](#object-paths) below)

## trailer

```
<<
  /ID [ <FD33BEA90DDE04BE16E7189D77594BCA> <614CE953883E263E0CE7B36E3DAD0D99> ]
  /Root 145 0 R
  /Info 144 0 R
  /Type /XRef
  /Size 161
  /W [ 1 4 2 ]
  /DecodeParms <<
    /Columns 7
    /Predictor 12
  >>
  /Filter /FlateDecode
  /Length 288
>>
```

**trailer.Root**

```
145 0 obj
<<
  /PageLayout /TwoPageRight
  /Type /Catalog
  /PageLabels <<
    /Kids [ 131 0 R 132 0 R 133 0 R 134 0 R 135 0 R 136 0 R 137 0 R
        138 0 R 139 0 R 140 0 R 141 0 R 142 0 R 143 0 R ]
  >>
  /ViewerPreferences <<
    /Direction /L2R
  >>
  /Pages 43 0 R
  /Version /1.6
  /AcroForm 148 0 R
  /Outlines 149 0 R
  /Metadata 160 0 R
>>
endobj
```

**trailer.Root.Outlines.First**

```
PS C:\Users\kjk\Downloads> 150 0 obj
<<
  /Parent 149 0 R
  /Title (de DAME.)
  /Dest 151 0 R
  /C [ 0 0 0 ]
  /Next 152 0 R
>>
endobj
```

## xref

```
00000: 0000000000 65535 f
00001: 0000000017 00000 n
00002: 0000610334 00000 n
00003: 0000000147 00000 o
```

## pages

```
page 1 = 3 0 R
page 2 = 8 0 R
page 3 = 13 0 R
```

## outline

```
|    "de DAME."      #page=1&zoom=75,0,0
|       "DATHIS."       #page=3&zoom=75,0,0
|       "DAVID D'ANGERS."       #page=5&zoom=75,0,0
```

## Object paths

Instead of a keyword, you can pass a path to drill down to a specific object. A path starts with an object number or the keyword `trailer` or `pages`, and walks into the object with `.` or `/` separators. Use `pages/N` to select the Nth page (the first page is `1`), and `*` to iterate over all array indices or dictionary properties.

Find the number of pages in a document:

`sumatrapdf-tool show input.pdf trailer/Root/Pages/Count`

Print the content stream of the first page (`-b` prints raw stream bytes):

`sumatrapdf-tool show -b input.pdf pages/1/Contents`

Print the base font name of every font used on every page:

`sumatrapdf-tool show input.pdf pages/*/Resources/Font/*/BaseFont`

List all JPEG-compressed streams (using `grep` to filter the one-line output):

`sumatrapdf-tool show input.pdf grep | grep "/Filter/DCTDecode"`

## All options

```
Usage: SumatraPDF show [options] file.pdf ( trailer | xref | pages | grep | outline | js | form | <path> ) *
  -p -    password
  -o -    output file
  -e      leave stream contents in their original form
  -b      print only stream contents, as raw binary data
  -g      print only object, one line per object, suitable for grep
  -r      force repair before showing any objects
  -L      show object labels
  path: path to an object, starting with either an object number,
          'pages', 'trailer', or a property in the trailer;
          path elements separated by '.' or '/'. Path elements must be
          array index numbers, dictionary property names, or '*'.
```


---

<!-- Tool-sign.md -->

# sumatrapdf-tool sign

or [SumatraPDF.exe sign](Tools.md)

**Available in [pre-release 3.7](https://www.sumatrapdfreader.org/prerelease)**

**Usage:** `sumatrapdf-tool sign [options] input.pdf [signature object numbers]`

`sign` lists, signs and verifies the digital signatures in a PDF. It works with the signature fields the PDF already has and a certificate file (`.pfx` / `.p12`); it can't add a new signature field. To sign in SumatraPDF, including adding a new signature box, see [Sign a PDF](Sign-a-PDF.md).

List the signature fields and their object numbers:

```
sumatrapdf-tool sign form.pdf
```

```
   12: Signature is not signed.
```

Sign field `12` with a certificate file:

```
sumatrapdf-tool sign -s me.pfx -P password -o signed.pdf form.pdf 12
```

Without `-o` the signed PDF is written to `out.pdf`. Without object numbers, all signature fields are processed.

Verify the signatures:

```
sumatrapdf-tool sign -v signed.pdf
```

```
Verifying signature 12:
	Distinguished name: cn=Jamie Rivera, o=Example, ou=, email=, c=
	Certificate error: Self-signed certificate.
	The document is unchanged since signing.
	The fields signed by this signature are unchanged.
```

`-c` clears signatures. A signature marked read-only can't be cleared: `sign` prints `read only signature cannot be cleared` and writes no file.

## All options

```
Usage: SumatraPDF sign [options] input.pdf [signature object numbers]
	-p -	password
	-v 	verify signature
	-c 	clear signatures
	-s -	sign signatures using certificate file
	-P -	certificate password
	-o -	output file name
```

`-p` is the password of an encrypted PDF; `-P` is the password of the certificate file.


---

<!-- Tool-trim.md -->

# sumatrapdf-tool trim

or [SumatraPDF.exe trim](Tools.md)

**Available in [pre-release 3.7](https://www.sumatrapdfreader.org/prerelease)**

**Usage:** `sumatrapdf-tool trim [options] <input filename>`

A PDF page has fixed dimensions. It can also have MediaBox, CropBox, BleedBox, TrimBox, and ArtBox values that define rectangular areas within the page.

You can see what kind of boxes a PDF page has using [sumatrapdf-tool pages](Tool-pages.md).

Using `trim`, you can trim the area outside a given box, i.e. remove any content outside the box.

With `-e`, it does the opposite, i.e. removes the content inside the box.

`trim` doesn't change the page size: it only removes content. To make pages smaller, see [Crop PDF page margins](Crop-PDF-margins.md).

Without `-b`, `trim` uses the CropBox (the usage text below says MediaBox, but it's the CropBox). Most PDFs have no CropBox: then `trim` prints `No box found for page 0` for each page and changes nothing. Use `-b mediabox`, or `-f` to fall back to the MediaBox.

The `-m` margin can be given as a single value applied to all sides, two values `<V>,<H>` (vertical, horizontal), or four values `<T>,<R>,<B>,<L>` (top, right, bottom, left). Positive values move inward; negative values move outward.

## Examples

Trim to the MediaBox with a 200 point margin inwards:

`sumatrapdf-tool trim -b mediabox -m 200 -o out.pdf in.pdf`

Trim with 20 points off the top & bottom and 30 points off the left & right:

`sumatrapdf-tool trim -b mediabox -m 20,30 -o out.pdf in.pdf`

Trim with separate margins for each side (top, right, bottom, left):

`sumatrapdf-tool trim -b mediabox -m 10,10,50,20 -o out.pdf in.pdf`

Remove the contents of the ArtBox instead of keeping them:

`sumatrapdf-tool trim -b artbox -e -o out.pdf in.pdf`

## All options

```
Usage: SumatraPDF trim [options] <input filename>
  -b -    Which box to trim to (MediaBox(default), CropBox, BleedBox, TrimBox, ArtBox)
  -m -    Add margins to box (+ve for inwards, -ve outwards).
                  <All> or <V>,<H> or <T>,<R>,<B>,<L>
  -e      Exclude contents of box, rather than include them
  -f      Fallback to mediabox if specified box not available
  -o -    Output file
```


---

<!-- Tool-grep.md -->

# sumatrapdf-tool grep

or [SumatraPDF.exe grep](Tools.md)

**Available in [pre-release 3.7](https://www.sumatrapdfreader.org/prerelease)**

To search for text in `file.pdf`:

`sumatrapdf-tool grep -i foo file.pdf`

`-i` ignores case, i.e. performs a case-insensitive search, which is probably a good default.

Other options:

- `-a` ignore accents (diacritics)

## Search with a regular expression

`sumatrapdf-tool grep -i -G x.* file.pdf`

- `-G` specifies that the search pattern is a regular expression
- `-i` combines it with the case-insensitive flag
- `x.*` is a regular expression that matches every string that starts with `x`

## Show where matches are

By default only the matching text is printed. Add:

- `-n` to print the page number for each match
- `-H` to print the file name for each match (useful when searching several files at once)
- `-[` and `-]` to wrap each match with a start / end marker, so you can spot it within the line

`sumatrapdf-tool grep -i -n -H foo file.pdf file2.pdf`

You can also search more than one file by listing them after the pattern.

## All options

```
usage: SumatraPDF grep [options] pattern input.pdf [ input2.pdf ... ]
  -p -    password for encrypted PDF files
  -G      pattern is a regexp
  -a      ignore accents (diacritics)
  -i      ignore case
  -H      print filename for each match
  -n      print page number for each match
advanced options:
  -S      comma-separated list of search options
  -O      comma-separated list of stext options
  -b      search pages in backwards order
  -[ -    start marker
  -] -    end marker
  -v      verbose
  -q      quiet (don't print warnings and errors)

Search options:
  exact: match exact, case sensitive pattern
  ignore-case: case insensitive search
  ignore-diacritics: ignore character diacritics
  regexp: interpret search pattern as regular expression
  keep-lines: preserve line breaks so pattern can match them
  keep-paragraphs: preserve paragraph breaks so pattern can match them
  keep-hyphens: preserve hyphens, avoiding joining lines

Structured text options:
  preserve-images: keep images in output
  preserve-ligatures: do not expand ligatures into constituent characters
  preserve-spans: do not merge spans on the same line
  preserve-whitespace: do not convert all whitespace into space characters
  inhibit-spaces: don't add spaces between gaps in the text
  paragraph-break: break blocks at paragraph boundaries
  dehyphenate: attempt to join up hyphenated words
  ignore-actualtext: do not apply ActualText replacements
  use-cid-for-unknown-unicode: use character code if unicode mapping fails
  use-gid-for-unknown-unicode: use glyph index if unicode mapping fails
  accurate-bboxes: calculate char bboxes from the outlines
  accurate-ascenders: calculate ascender/descender from font glyphs
  accurate-side-bearings: expand char bboxes to completely include width of glyphs
  collect-styles: attempt to detect text features (fake bold, strikeout, underlined etc)
  clip: do not include text that is completely clipped
  clip-rect=x0:y0:x1:y1 specify clipping rectangle within which to collect content
  structured: collect structure markup
  vectors: include vector bboxes in output
  segment: attempt to segment the page
  table-hunt: hunt for tables within a (segmented) page
  resolution: resolution to render at
```


---

<!-- Tool-trace.md -->

# sumatrapdf-tool trace

or [SumatraPDF.exe trace](Tools.md)

**Available in [pre-release 3.7](https://www.sumatrapdfreader.org/prerelease)**

**Usage:** `sumatrapdf-tool trace [options] file [pages]`

Trace is an advanced tool for inspecting how a page is rendered.

It prints an XML trace of all the device calls used to draw a page. The root element is the document, with a child element for each page, and within each page one element per device call (path fills and strokes, text spans, images, clips, etc.).

The output is very large and can look like:

```xml
<?xml version="1.0"?>
<document filename=".\bug-5476-discussion-Andre.Leroy.Dictionnaire.de.pomologie.pdf">
<page number="1" mediabox="0 0 409 684">
<set_default_colorspaces gray="DeviceGray" rgb="DeviceRGB" cmyk="DeviceCMYK" oi="None"/>
<group bbox="0 0 409 684" isolated="1" knockout="0" blendmode="Normal" alpha="1">
    <ignore_text transform=".17986 0 0 -.17986 0 684">
        <span font="Courier" wmode="0" bidi="0" trm="231.11 0 0 231.11">
            <g unicode="P" glyph="P" x="688" y="3173" adv=".6"/>
            <g unicode="O" glyph="O" x="826.666" y="3173" adv=".6"/>
            <g unicode="I" glyph="I" x="965.33206" y="3173" adv=".6"/>
            <g unicode="R" glyph="R" x="1103.998" y="3173" adv=".6"/>
            <g unicode="E" glyph="E" x="1242.6641" y="3173" adv=".6"/>
            <g unicode="S" glyph="S" x="1381.3301" y="3173" adv=".6"/>
        </span>
    </ignore_text>
...
```

## All options

```
Usage: SumatraPDF trace [options] file [pages]
  -p -    password

  -b -    use named page box (MediaBox, CropBox, BleedBox, TrimBox, or ArtBox)

  -W -    page width for EPUB layout
  -H -    page height for EPUB layout
  -S -    font size for EPUB layout
  -U -    file name of user stylesheet for EPUB layout
  -X      disable document styles for EPUB layout

  -d      use display list

  pages   comma separated list of page numbers and ranges
```


---

<!-- Tool-run.md -->

# sumatrapdf-tool run

or [SumatraPDF.exe run](Tools.md)

**Available in [pre-release 3.7](https://www.sumatrapdfreader.org/prerelease)**

**Usage:** `sumatrapdf-tool run script.js [arguments...]`

`run` executes a [sumatrapdf-tool](Tool-run-javascript-examples.md) JavaScript program. It's
the same scripting engine as `mutool run` and gives you programmatic access to
PDF (and other) documents: read and edit pages, annotations, and metadata; render
images; extract text; and more.

## Run a script

`sumatrapdf-tool run script.js` runs the program in `script.js`.

A minimal `hello.js`:

```js
print("hello from sumatrapdf-tool run");
```

```
sumatrapdf-tool run hello.js
```

## Open a document

The MuPDF API is available to scripts. For example, `pages.js` prints the number
of pages of a document:

```js
var doc = Document.openDocument(scriptArgs[0]);
print(doc.countPages() + " pages");
```

```
sumatrapdf-tool run pages.js file.pdf
```

## Script arguments

When you run `sumatrapdf-tool run script.js a b c`, the script can read the arguments
that follow the script name:

- `scriptPath` - path of the script (`script.js`)
- `scriptArgs` - array of the arguments after the script (`["a", "b", "c"]`)
- `process.argv` - Node-compatible array of all arguments, including the program
  name and script path

## Interactive mode (REPL)

Run `sumatrapdf-tool run` with no script to start an interactive read-eval-print loop.
It prints a `> ` prompt, evaluates each line you type, and prints the result:

```
sumatrapdf-tool run
> 1 + 2
3
> var doc = Document.openDocument("file.pdf")
> doc.countPages()
21
```

Press `Ctrl + Z` then `Enter` (end of input) to quit, or call `quit()`.

## Reading from stdin

`readline()` reads a line from standard input, so scripts can be driven by
piped or typed input (added in 3.7, [issue #5665](https://github.com/sumatrapdfreader/sumatrapdf/issues/5665)).

`echo.js`:

```js
var line = readline();
print("you typed: " + line);
```

```
echo hello | sumatrapdf-tool run echo.js
```

The interactive REPL also reads from stdin, so you can pipe a whole program into
it:

```
echo "print(6*7)" | sumatrapdf-tool run
```

## Built-in functions

In addition to the MuPDF API, these global functions are available:

- `print(...)` - print arguments followed by a newline
- `write(...)` - print arguments without a trailing newline
- `read(filename)` - read a file and return its contents as a string
- `readline()` - read one line from standard input
- `repr(value)` - return a string representation of a value
- `load(filename)` - load and execute another script file
- `gc()` - run the garbage collector
- `quit(code)` - exit the program

## MuPDF JavaScript API

The objects used above (`Document`, `Page`, `Pixmap`, `PDFDocument`, `Buffer`
etc.) are the MuPDF scripting API. `sumatrapdf-tool run` is the same as `mutool run`.
See the upstream documentation:

- [`mutool run`](https://mupdf.readthedocs.io/en/1.27.2/tools/mutool-run.html) - the equivalent MuPDF command-line tool
- [JavaScript examples](Tool-run-javascript-examples.md) - example-driven recipes
- [JavaScript API reference](Tool-run-javascript-reference.md) - full list of classes and methods


---

<!-- Tool-run-javascript-examples.md -->

# JavaScript examples for sumatrapdf-tool run

or [SumatraPDF.exe run](Tools.md)

**Available in [pre-release 3.7](https://www.sumatrapdfreader.org/prerelease)**

Example-driven recipes for [sumatrapdf-tool run](Tool-run.md). The scripting engine is the
same as [`mutool run`](https://mupdf.readthedocs.io/en/latest/tools/mutool-run.html);
these examples are adapted from the [MuPDF JavaScript cookbook](https://mupdf.readthedocs.io/en/latest/cookbook/javascript/index.html).

Save a script to a `.js` file and run it:

```
sumatrapdf-tool run script.js [arguments...]
```

For the full list of classes and methods, see the [JavaScript API reference](Tool-run-javascript-reference.md).

## Contents

### Basics

- [Load a PDF](#load-a-pdf)
- [Create a PDF](#create-a-pdf)
- [Add an annotation](#add-an-annotation)
- [Convert PDF to plain text](#convert-pdf-to-plain-text)
- [Convert PDF to images](#convert-pdf-to-images)

### Advanced

- [Create PDF](#create-pdf)
- [Create PDF (low level)](#create-pdf-low-level)
- [Merge PDFs](#merge-pdfs)
- [Create PDF with thumbnails](#create-pdf-with-thumbnails)
- [Draw graphics with Device](#draw-graphics-with-device)
- [Trace device](#trace-device)

## Basics

### Load a PDF

The following example demonstrates how to load a document and then print out the page
count. Ensure you have a PDF file named `test.pdf` alongside this example before
running it.

```js
import * as mupdf from "mupdf"

var doc = mupdf.Document.openDocument("test.pdf")
console.log(doc.countPages())
```

### Create a PDF

How to create a new PDF file with a single blank page:

```js
import * as mupdf from "mupdf"

var doc = new mupdf.PDFDocument()
doc.insertPage(-1, doc.addPage([0, 0, 595, 842], 0, null, ""))
doc.save("blank.pdf")
```

### Add an annotation

How to add a simple annotation to a PDF file:

```js
import * as mupdf from "mupdf"

var doc = mupdf.Document.openDocument("blank.pdf")

var page = doc.loadPage(0)

var annot = page.createAnnotation("FreeText")
annot.setRect([10, 10, 200, 100])
annot.setContents("Hello, world!")

page.update()

doc.save("annotation.pdf")
```

### Convert PDF to plain text

```js
import * as mupdf from "mupdf"

var doc = mupdf.Document.openDocument("test.pdf")
for (var i = 0; i < doc.countPages(); ++i) {
	var page = doc.loadPage(i)
	var text = page.toStructuredText().asText()
	console.log(text)
}
```

### Convert PDF to images

```js
import * as fs from "fs"
import * as mupdf from "mupdf"

var doc = mupdf.Document.openDocument("test.pdf")
for (var i = 0; i < doc.countPages(); ++i) {
	var page = doc.loadPage(i)
	var pixmap = page.toPixmap(
		mupdf.Matrix.scale(96 / 72, 96 / 72),
		mupdf.ColorSpace.DeviceRGB
	)
	var buffer = pixmap.asPNG()
	fs.writeFileSync("page" + (i+1) + ".png", buffer)
}
```

## Advanced

### Create PDF

Create a new PDF from scratch using helper functions to create resources and page
objects. This assumes a basic working knowledge of the PDF file format.

```js
import * as mupdf from "mupdf"

// Create a PDF from scratch using helper functions.

// This example creates a new PDF file from scratch, using helper
// functions to create resources and page objects.
// This assumes a basic working knowledge of the PDF file format.

import mupdf from "mupdf"

// Create a new empty document with no pages.
var pdf = new mupdf.PDFDocument()

// Load built-in font and create WinAnsi encoded simple font resource.
var font = pdf.addSimpleFont(new mupdf.Font("Times-Roman"))

// Load PNG file and create image resource.
var image = pdf.addImage(new mupdf.Image("example.jpg"))

// Create resource dictionary.
var resources = pdf.addObject({
	Font: { Tm: font },
	XObject: { Im0: image },
})

// Create content stream data.
var contents =
	"10 10 280 330 re s\n" +
	"q 200 0 0 200 50 100 cm /Im0 Do Q\n" +
	"BT /Tm 16 Tf 50 50 TD (Hello, world!) Tj ET\n"

// Create a new page object.
var page = pdf.addPage([0,0,300,350], 0, resources, contents)

// Insert page object at the end of the document.
pdf.insertPage(-1, page)

// Save the document to file.
pdf.save("out.pdf", "pretty,ascii,compress-images,compress-fonts")
```

### Create PDF (low level)

Create a new PDF from scratch using only the low-level APIs.

```js
import * as mupdf from "mupdf"

// Create a PDF from scratch.

// This example creates a new PDF file from scratch, using only the low level APIs.
// This assumes a basic working knowledge of the PDF file format.

// Create a new empty document with no pages.
var pdf = new mupdf.PDFDocument()

// Create and add a font resource.
var font = pdf.addObject({
	Type: "Font",
	Subtype: "Type1",
	Encoding: "WinAnsiEncoding",
	BaseFont: "Times-Roman",
})

// Create and add an image resource:
var image = pdf.addRawStream(
	// The raw stream contents, hex encoded to match the Filter entry:
	"004488CCEEBB7733>",
	// The image object dictionary:
	{
		Type: "XObject",
		Subtype: "Image",
		Width: 4,
		Height: 2,
		BitsPerComponent: 8,
		ColorSpace: "DeviceGray",
		Filter: "ASCIIHexDecode",
	}
);

// Create resource dictionary.
var resources = pdf.addObject({
	Font: { Tm: font },
	XObject: { Im0: image },
})

// Create content stream.
var buffer = new Buffer()
buffer.writeLine("10 10 280 330 re s")
buffer.writeLine("q 200 0 0 200 50 100 cm /Im0 Do Q")
buffer.writeLine("BT /Tm 16 Tf 50 50 TD (Hello, world!) Tj ET")
var contents = pdf.addStream(buffer)

// Create page object.
var page = pdf.addObject({
	Type: "Page",
	MediaBox: [0,0,300,350],
	Contents: contents,
	Resources: resources,
})

// Insert page object into page tree.
var pagetree = pdf.getTrailer().Root.Pages
pagetree.Count = 1
pagetree.Kids = [ page ]
page.Parent = pagetree

// Save the document.
pdf.save("out.pdf")
```

### Merge PDFs

A re-implementation of `sumatrapdf-tool merge` in JavaScript.

```
sumatrapdf-tool run pdf-merge.js output.pdf input1.pdf input2.pdf ...
```

```js
// A re-implementation of "sumatrapdf-tool merge" in JavaScript.

import * as mupdf from "mupdf"

function copyPage(dstDoc, srcDoc, pageNumber, dstFromSrc) {
	var srcPage, dstPage
	srcPage = srcDoc.findPage(pageNumber)
	dstPage = dstDoc.newDictionary()
	dstPage.Type = dstDoc.newName("Page")
	if (srcPage.MediaBox) dstPage.MediaBox = dstFromSrc.graftObject(srcPage.MediaBox)
	if (srcPage.Rotate) dstPage.Rotate = dstFromSrc.graftObject(srcPage.Rotate)
	if (srcPage.Resources) dstPage.Resources = dstFromSrc.graftObject(srcPage.Resources)
	if (srcPage.Contents) dstPage.Contents = dstFromSrc.graftObject(srcPage.Contents)
	dstDoc.insertPage(-1, dstDoc.addObject(dstPage))
}

function copyAllPages(dstDoc, srcDoc) {
	var dstFromSrc = dstDoc.newGraftMap()
	var k, n = srcDoc.countPages()
	for (k = 0; k < n; ++k)
		copyPage(dstDoc, srcDoc, k, dstFromSrc)
}

function pdfmerge() {
	var srcDoc, dstDoc, i

	dstDoc = new mupdf.PDFDocument()
	for (i = 3; i < process.argv.length; ++i) {
		srcDoc = mupdf.Document.openDocument(process.argv[i])
		copyAllPages(dstDoc, srcDoc)
	}
	dstDoc.save(process.argv[2], "compress")
}

if (process.argv.length < 4)
	print("usage: sumatrapdf-tool run pdf-merge.js output.pdf input1.pdf input2.pdf ...")
else
	pdfmerge()
```

### Create PDF with thumbnails

Create a PDF containing thumbnails of pages rendered from another PDF.

```js
// Create a PDF containing thumbnails of pages rendered from another PDF.

import * as mupdf from "mupdf"

var pdf = new mupdf.PDFDocument()

var subdoc = mupdf.Document.openDocument("pdfref17.pdf")

var resources = { XObject: {} }

var contents = new mupdf.Buffer()
for (var i=0; i < 5; ++i) {
	var pixmap = subdoc.loadPage(1140+i).toPixmap([0.2,0,0,0.2,0,0], mupdf.ColorSpace.DeviceRGB, true)
	resources.XObject["Im" + i] = pdf.addImage(new Image(pixmap))
	contents.writeLine("q 100 0 0 150 " + (50+100*i) + " 50 cm /Im" + i + " Do Q")
}

var page = pdf.addPage([0,0,100+i*100,250], 0, resources, contents)
pdf.insertPage(-1, page)

pdf.save("out.pdf")
```

### Draw graphics with Device

Use the device interface to draw graphics and save as a PNG.

```js
// Use device interface to draw some graphics and save as a PNG.

import * as mupdf from "mupdf"

var font = new mupdf.Font("Times-Roman")
var image = new mupdf.Image("huntingofthesnark.png")
var path, text

var pixmap = new mupdf.Pixmap(mupdf.ColorSpace.DeviceRGB, [ 0, 0, 500, 600 ], false)
pixmap.clear(255)
var device = new mupdf.DrawDevice(mupdf.Matrix.identity, pixmap)
var transform = [ 2, 0, 0, 2, 0, 0 ]
{
	text = new mupdf.Text()
	{
		text.showString(font, [ 16, 0, 0, -16, 100, 30 ], "Hello, world!")
		text.showString(font, [ 0, 16, 16, 0, 15, 100 ], "Hello, world!")
	}
	device.fillText(text, transform, mupdf.ColorSpace.DeviceGray, [ 0 ], 1)

	path = new mupdf.Path()
	{
		path.moveTo(10, 10)
		path.lineTo(90, 10)
		path.lineTo(90, 90)
		path.lineTo(10, 90)
		path.closePath()
	}
	device.fillPath(path, false, transform, mupdf.ColorSpace.DeviceRGB, [ 1, 0, 0 ], 1)
	device.strokePath(
		path,
		{ dashes: [ 5, 10 ], lineWidth: 3, lineCap: "Round" },
		transform,
		mupdf.ColorSpace.DeviceRGB,
		[ 0, 0, 0 ],
		1
	)

	path = new mupdf.Path()
	{
		path.moveTo(100, 100)
		path.curveTo(150, 100, 200, 150, 200, 200)
		path.curveTo(200, 300, 0, 300, 100, 100)
		path.closePath()
	}
	device.clipPath(path, true, transform)
	{
		device.fillImage(image, Matrix.concat(transform, [ 300, 0, 0, 300, 0, 0 ]), 1)
	}
	device.popClip()
}
device.close()

pixmap.saveAsPNG("out.png")
```

### Trace device

Trace device calls while rendering a page.

```
sumatrapdf-tool run trace-device.js document.pdf pageNumber
```

```js
import * as mupdf from "mupdf"

var Q = JSON.stringify

var pathPrinter = {
	moveTo: function (x,y) { print("moveTo", x, y) },
	lineTo: function (x,y) { print("lineTo", x, y) },
	curveTo: function (x1,y1,x2,y2,x3,y3) { print("curveTo", x1, y1, x2, y2, x3, y3) },
	closePath: function () { print("closePath") },
}

var textPrinter = {
	beginSpan: function (f,m,wmode, bidi, dir, lang) {
		print("beginSpan",f,m,wmode,bidi,dir,repr(lang));
	},
	showGlyph: function (f,m,g,u,v,b) { print("glyph",f,m,g,u,v,b) },
	endSpan: function () { print("endSpan"); }
}

var traceDevice = {
	fillPath: function (path, evenOdd, ctm, colorSpace, color, alpha) {
		print("fillPath", evenOdd, ctm, colorSpace, color, alpha)
		path.walk(pathPrinter)
	},
	clipPath: function (path, evenOdd, ctm) {
		print("clipPath", evenOdd, ctm)
		path.walk(pathPrinter)
	},
	strokePath: function (path, stroke, ctm, colorSpace, color, alpha) {
		print("strokePath", Q(stroke), ctm, colorSpace, color, alpha)
		path.walk(pathPrinter)
	},
	clipStrokePath: function (path, stroke, ctm) {
		print("clipStrokePath", Q(stroke), ctm)
		path.walk(pathPrinter)
	},

	fillText: function (text, ctm, colorSpace, color, alpha) {
		print("fillText", ctm, colorSpace, color, alpha)
		text.walk(textPrinter)
	},
	clipText: function (text, ctm) {
		print("clipText", ctm)
		text.walk(textPrinter)
	},
	strokeText: function (text, stroke, ctm, colorSpace, color, alpha) {
		print("strokeText", Q(stroke), ctm, colorSpace, color, alpha)
		text.walk(textPrinter)
	},
	clipStrokeText: function (text, stroke, ctm) {
		print("clipStrokeText", Q(stroke), ctm)
		text.walk(textPrinter)
	},
	ignoreText: function (text, ctm) {
		print("ignoreText", ctm)
		text.walk(textPrinter)
	},

	fillShade: function (shade, ctm, alpha) {
		print("fillShade", shade, ctm, alpha)
	},
	fillImage: function (image, ctm, alpha) {
		print("fillImage", image, ctm, alpha)
	},
	fillImageMask: function (image, ctm, colorSpace, color, alpha) {
		print("fillImageMask", image, ctm, colorSpace, color, alpha)
	},
	clipImageMask: function (image, ctm) {
		print("clipImageMask", image, ctm)
	},

	beginMask: function (area, luminosity, colorspace, color) {
		print("beginMask", area, luminosity, colorspace, color)
	},
	endMask: function () {
		print("endMask")
	},

	popClip: function () {
		print("popClip")
	},

	beginGroup: function (area, isolated, knockout, blendmode, alpha) {
		print("beginGroup", area, isolated, knockout, blendmode, alpha)
	},
	endGroup: function () {
		print("endGroup")
	},
	beginTile: function (area, view, xstep, ystep, ctm, id) {
		print("beginTile", area, view, xstep, ystep, ctm, id)
		return 0
	},
	endTile: function () {
		print("endTile")
	},
	beginLayer: function (name) {
		print("beginLayer", name)
	},
	endLayer: function () {
		print("endLayer")
	},
	beginStructure: function (structure, raw, uid) {
		print("beginStructure", structure, raw, uiw)
	},
	endStructure: function () {
		print("endStructure")
	},
	beginMetatext: function (meta, metatext) {
		print("beginMetatext", meta, metatext)
	},
	endMetatext: function () {
		print("endMetatext")
	},

	renderFlags: function (set, clear) {
		print("renderFlags", set, clear)
	},
	setDefaultColorSpaces: function (colorSpaces) {
		print("setDefaultColorSpaces", colorSpaces.getDefaultGray(),
		colorSpaces.getDefaultRGB(), colorSpaces.getDefaultCMYK(),
		colorSpaces.getOutputIntent())
	},

	close: function () {
		print("close")
	},
}

if (scriptArgs.length != 2)
	print("usage: sumatrapdf-tool run trace-device.js document.pdf pageNumber")
else {
	var doc = mupdf.Document.openDocument(scriptArgs[0]);
	var page = doc.loadPage(parseInt(scriptArgs[1])-1);
	page.run(traceDevice, mupdf.Matrix.identity);
}
```


---

<!-- Tool-run-javascript-reference.md -->

# JavaScript API reference for sumatrapdf-tool run

or [SumatraPDF.exe run](Tools.md)

**Available in [pre-release 3.7](https://www.sumatrapdfreader.org/prerelease)**

API reference for [sumatrapdf-tool run](Tool-run.md). The scripting engine is the same as [`mutool run`](https://mupdf.readthedocs.io/en/latest/tools/mutool-run.html); this page is adapted from the [MuPDF JavaScript reference](https://mupdf.readthedocs.io/en/latest/reference/javascript/index.html).

See also [JavaScript examples](Tool-run-javascript-examples.md).

## Contents

- [Introduction](#introduction)
- [Functions](#functions)
- [Types](#types)
  - [Archive](#archive)
  - [Buffer](#buffer)
  - [Color](#color)
  - [ColorSpace](#colorspace)
  - [DOM](#dom)
  - [DefaultColorSpaces](#defaultcolorspaces)
  - [Device](#device)
  - [DisplayList](#displaylist)
  - [DisplayListDevice](#displaylistdevice)
  - [Document](#document)
  - [DocumentWriter](#documentwriter)
  - [DrawDevice](#drawdevice)
  - [Font](#font)
  - [Image](#image)
  - [Link](#link)
  - [LinkDestination](#linkdestination)
  - [Matrix](#matrix)
  - [MultiArchive](#multiarchive)
  - [OutlineItem](#outlineitem)
  - [OutlineIterator](#outlineiterator)
  - [Page](#page)
  - [Path](#path)
  - [PathWalker](#pathwalker)
  - [Pixmap](#pixmap)
  - [Point](#point)
  - [Quad](#quad)
  - [Rect](#rect)
  - [Shade](#shade)
  - [Story](#story)
  - [StrokeState](#strokestate)
  - [StructuredText](#structuredtext)
  - [StructuredTextWalker](#structuredtextwalker)
  - [Text](#text)
  - [TextWalker](#textwalker)
  - [TreeArchive](#treearchive)
  - [PDFAnnotation](#pdfannotation)
  - [PDFDocument](#pdfdocument)
  - [PDFFilespecParams](#pdffilespecparams)
  - [PDFGraftMap](#pdfgraftmap)
  - [PDFObject](#pdfobject)
  - [PDFPage](#pdfpage)
  - [PDFProcessor](#pdfprocessor)
  - [PDFWidget](#pdfwidget)

## Introduction

This is the JavaScript API available through `sumatrapdf-tool run`. The
scripting engine is the same as `mutool run`.

## Functions

Most functionality is provided by member functions of class objects.
There are just a couple of top level configuration functions listed
here.

#### mupdf.installLoadFontFunction(callback)

Install a handler to load system (or missing) fonts.

The callback function will be called with four arguments:

```
callback(fontName, scriptName, isBold, isItalic)
```

The callback should return either a `Font` object for the requested
font, or `null` if an exact match cannot be found (so that the font
loading machinery can keep looking through the chain of fallback
fonts).

#### mupdf.enableICC()

Enable ICC-profiles based operation.

#### mupdf.disableICC()

Disable ICC-profiles based operation.

#### mupdf.emptyStore()

Empty all cached entries from the store.

#### mupdf.shrinkStore(percent)

Remove cached entries from the store until it holds less
data than the specified threshold.

If the store was initialized with a limit, the threshold is a
percentage of the limit. If the store is unlimited in size, the
threshold is a percentage of what the store currently holds.

Returns a boolean indicating whether or not the store was able to be
shrunk to below the threshold.

- **number percent**: 
- **Returns:** boolean

#### mupdf.setUserCSS(stylesheet, useDocumentStyles)

Set a style sheet to apply to all reflowable documents.

- **string stylesheet**: The CSS text to use.
- **boolean useDocumentStyles**: 
Whether to respect the document's own style sheet.

## Types

### Common

### Archive

#### Constructors

#### Archive(path)

Create a new archive based either on a tar- or zip-file or the contents of a directory.

- **string path**: Path string to the archive file or directory.

```
var archive1 = new mupdf.Archive("example1.zip")
var archive2 = new mupdf.Archive("example2.tar")
var archive3 = new mupdf.Archive("images/")
```

#### Archive(buffer)

Create a new archive based either on a tar- or zip-file contained in a buffer.

- **Buffer | ArrayBuffer | Uint8Array | string buffer**: Buffer containing a archive.

```
var archive1 = new mupdf.Archive(fs.readFileSync("example1.zip"))
var archive2 = new mupdf.Archive(fs.readFileSync("example1.tar"))
```

#### Instance methods

#### Archive.prototype.getFormat()

Returns a string describing the archive format.

- **Returns:** string

```
var archive = new mupdf.Archive("example1.zip")
print(archive.getFormat())
```

#### Archive.prototype.countEntries()

Returns the number of entries in the archive.

- **Returns:** number

```
var archive = new mupdf.Archive("example1.zip")
var numEntries = archive.countEntries()
```

#### Archive.prototype.listEntry(idx)

Returns the name of entry number idx in the archive, or null if idx is
out of range.

- **number idx**: Entry index.

- **Returns:** string | null

```
var archive = new mupdf.Archive("example1.zip")
var entry = archive.listEntry(0)
```

#### Archive.prototype.hasEntry(name)

Returns true if an entry of the given name exists in the archive.

- **string name**: Entry name to look for.

- **Returns:** boolean

```
var archive = new mupdf.Archive("example1.zip")
var hasEntry = archive.hasEntry("file1.txt")
```

#### Archive.prototype.readEntry(name)

Returns the contents of the entry of the given name.

- **string name**: Name of entry to look for.

- **Returns:** `Buffer`

```
var archive = new mupdf.Archive("example1.zip")
var contents = archive.readEntry("file1.txt")
```

#### Examples

```
		var archive = new mupdf.Archive("example1.zip")
		var n = archive.countEntries()
		for (var i = 0; i < n; ++i) {
			var entry = archive.listEntry(i)
			var contents = archive.readEntry(entry)
			console.log("entry", entry, contents.length)
		}
```

### Buffer

Buffer objects are used for working with binary data, e.g. returned from
`asJPEG`. They can be used much like arrays, but are much more
efficient since they only store bytes.

#### Constructors

#### Buffer(data)

Creates a new Buffer initialized with contents from data.

- **Buffer | ArrayBuffer | Uint8Array | string | null data**: Contents used to populate buffer, or leave it empty if `null`.

```
var buffer = new mupdf.Buffer("hello world")
```

#### Instance properties

#### Buffer.prototype.length

The number of bytes in this buffer (read-only).

- **Throws:** TypeError on attempted writes.

- **Returns:** number

#### Buffer.prototype.[n]

Get or set the byte at index `n`.

- **Throws:** RangeError on out of bounds accesses.

```
var byte = buffer[0]
```

#### Instance methods

#### Buffer.prototype.asString()

Returns the contents of this buffer as a string.

- **Returns:** string

```
var str = buffer.asString()
```

#### Buffer.prototype.getLength()

Returns the number of bytes in this buffer.

- **Returns:** number

```
var length = buffer.getLength()
```

#### Buffer.prototype.readByte(at)

Returns the byte at the specified index `at` if within `0 <= at < getLength()`. Otherwise returns `undefined`.

- **number at**: Index to read byte at.

- **Returns:** number

```
buffer.readByte(0)
```

#### Buffer.prototype.slice(start, end)

Create a new buffer containing a (subset of) the data in this buffer.
Start and end are offsets from the beginning of this buffer, and if negative from the end of this buffer.
If `start` points to the end of this buffer, or if `end` point to at or before `start`, then an empty buffer will be returned.

- **number start**: Start index.
- **number end**: End index (optional).

- **Returns:** `Buffer`

```
var buffer = new mupdf.Buffer()
buffer.write("hello world") // buffer contains "hello world"
var newBuffer = buffer.slice(1, -1) // newBuffer contains "ello worl"
```

#### Buffer.prototype.write(str)

Append the string as UTF-8 to the end of this buffer.

- **string str**: String to append.

```
buffer.write("hello world")
```

#### Buffer.prototype.writeBuffer(data)

Append the contents of the `data` buffer to the end of this buffer.

- **Buffer | ArrayBuffer | Uint8Array | string data**: Data buffer to append.

```
buffer.writeBuffer(anotherBuffer)
```

#### Buffer.prototype.writeByte(byte)

Append a single byte to the end of this buffer.
Only the least significant 8 bits of the value are appended.

- **number byte**: The byte value to append.

```
buffer.writeByte(0x2a)
```

#### Buffer.prototype.writeLine(str)

Append string to the end of this buffer ending with a newline.

- **string str**: String to append.

```
buffer.writeLine("a line")
```

#### Buffer.prototype.writeRune(c)

Encode a unicode character as UTF-8 and append to the end of
the buffer.

- **number c**: The character unicode codepoint.

```js
buffer.writeRune(0x4f60) // To append U+4f60, 你
buffer.writeRune(0x597d) // To append U+597d, 好
buffer.writeRune(0xff01) // To append U+ff01, ！
```

#### Buffer.prototype.save(filename)

Write the contents of the buffer to a file.

- **string filename**: Filename to save to.

```js
buffer.save("buffer.dat")
```

### Color

Colors are specified as arrays with the appropriate number of components for
the associated `ColorSpace`. Each component value is stored as floating
point value between 0 and 1, where 0 means no colorant and 1
means maximum colorant.

For example:

- In the `ColorSpace.DeviceCMYK` color space the components are [Cyan, Magenta, Yellow, Black]. A full intensity magenta color would therefore be [0, 1, 0, 0].
- In the `ColorSpace.DeviceRGB` color space the components are [Red, Green, Blue]. A full intensity green color would therefore be [0, 1, 0].
- In the `ColorSpace.DeviceGray` color space the components are [Black]. A full intensity black color would therefore be [0].

In TypeScript this is defined as follows:

```
	type Color = [number] | [number, number, number] | [number, number, number, number]
```

### ColorSpace

Defines what color system is used for an object, and which colorants exist.

For a `Pixmap` the interface `Pixmap.prototype.getColorSpace()` returns its colorspace,
which defines what colorants make up the pixel colors in the Pixmap and
how those colorants are stored. If that colorspace is e.g.,
`ColorSpace.DeviceRGB`, then the colorants **red**, **green** and
**blue** are combined to make up the color of each pixel.

#### Constructors

#### ColorSpace(from, name)

Create a new ColorSpace from an ICC profile.

- **Buffer | ArrayBuffer | Uint8Array | string from**: A buffer containing an ICC profile.
- **string name**: A user descriptive name for the new colorspace.

```
var icc_colorspace = new mupdf.ColorSpace(fs.readFileSync("SWOP.icc"), "SWOP")
```

#### Static properties

#### ColorSpace.DeviceGray

The default Grayscale colorspace

#### ColorSpace.DeviceRGB

The default RGB colorspace

#### ColorSpace.DeviceBGR

The default RGB colorspace, but with components in reverse order

#### ColorSpace.DeviceCMYK

The default CMYK colorspace

#### ColorSpace.Lab

The default Lab colorspace

#### Instance methods

#### ColorSpace.prototype.getName()

Return the name of this colorspace.

#### ColorSpace.prototype.getNumberOfComponents()

A Grayscale colorspace has one component, RGB has 3, CMYK has 4, and DeviceN may have any number of components.

- **Returns:** number of components

```
var cs = mupdf.ColorSpace.DeviceRGB
var num = cs.getNumberOfComponents() // 3
```

#### ColorSpace.prototype.getType()

Returns a string indicating the type of this colorspace, one of:

- **Returns:** `"None" | "Gray" | "RGB" | "BGR" | "CMYK" | "Lab" | "Indexed" | "Separation"`

#### ColorSpace.prototype.isCMYK()

Returns `true` if the object is a CMYK color space.

- **Returns:** boolean

```
var bool = colorSpace.isCMYK()
```

#### ColorSpace.prototype.isDeviceN()

Returns `true` if the object is a Device N color space.

- **Returns:** boolean

```
var bool = colorSpace.isDeviceN()
```

#### ColorSpace.prototype.isGray()

Returns `true` if the object is a gray color space.

- **Returns:** boolean

```
var bool = colorSpace.isGray()
```

#### ColorSpace.prototype.isIndexed()

Returns `true` if the object is an Indexed color space.

- **Returns:** boolean

```
var bool = colorSpace.isIndexed()
```

#### ColorSpace.prototype.isLab()

Returns `true` if the object is a Lab color space.

- **Returns:** boolean

```
var bool = colorSpace.isLab()
```

#### ColorSpace.prototype.isRGB()

Returns `true` if the object is an RGB color space.

- **Returns:** boolean

```
var bool = colorSpace.isRGB()
```

#### ColorSpace.prototype.isSubtractive()

Returns `true` if the object is a subtractive color space.

- **Returns:** boolean

```
var bool = colorSpace.isSubtractive()
```

#### ColorSpace.prototype.toString()

Return name of this colorspace.

- **Returns:** string

```
var cs = mupdf.ColorSpace.DeviceRGB
var name = cs.toString() // "[ColorSpace DeviceRGB]"
```

### DOM

This represents an HTML or an DOM node. It is a helper class intended to
access the DOM (Document Object Model) content of a `Story`
object.

#### Constructors

#### DOM

*(not constructible with `new`)*

Instances of this class are returned by `Story.prototype.document()`.

#### Instance methods

#### DOM.prototype.body()

Return a DOM for the body element.

- **Returns:** `DOM`

```
var result = xml.body()
```

#### DOM.prototype.documentElement()

Return a DOM for the top level element.

- **Returns:** `DOM`

```
var result = xml.documentElement()
```

#### DOM.prototype.createElement(tag)

Create an element with the given tag type, but do not link it into
the `DOM` yet.

- **string tag**: Tag name to use for element.

- **Returns:** `DOM`

```
var result = xml.createElement("div")
```

#### DOM.prototype.createTextNode(text)

Create a text node with the given text contents, but do not link
it into the `DOM` yet.

- **string text**: Text contents to put into element.

- **Returns:** `DOM`

```
var result = xml.createElement("Hello world!")
```

#### DOM.prototype.find(tag, attribute, value)

Find the first element matching the tag, attribute and value. Set
either of those to `null` to match anything.

- **string tag**: The tag of the element to look for.
- **string attribute**: The attribute of the element to look for.
- **string value**: The value of the attribute of the element to look for.

- **Returns:** `DOM` | null

```
var result = xml.find("tag", "attribute", "value")
```

#### DOM.prototype.findNext(tag, attribute, value)

Find the next element matching the tag, attribute and value. Set either
of those to `null` to match anything.

- **string tag**: The tag of the element to look for.
- **string attribute**: The attribute of the element to look for.
- **string value**: The value of the attribute of the element to look for.

- **Returns:** `DOM` | null

```
var result = xml.findNext("tag", "attribute", "value")
```

#### DOM.prototype.appendChild(dom, childDom)

Insert an element as the last child of a parent, unlinking the child
from its current position if required.

- **DOM dom**: The DOM that will be parent.
- **DOM childDom**: The DOM that will be a child.

```
xml.appendChild(dom, childDom)
```

#### DOM.prototype.insertBefore(dom, elementDom)

Insert an element before this element, unlinking the new element
from its current position if required.

- **DOM dom**: The reference DOM.
- **DOM elementDom**: The DOM that will be inserted before.

```
xml.insertBefore(dom, elementDom)
```

#### DOM.prototype.insertAfter(dom, elementDom)

Insert an element after this element, unlinking the new element
from its current position if required.

- **DOM dom**: The reference DOM.
- **DOM elementDom**: The DOM that will be inserted after.

```
xml.insertAfter(dom, elementDom)
```

#### DOM.prototype.remove()

Remove this element from the `DOM`. The element can be
added back elsewhere if required.

```
var result = xml.remove()
```

#### DOM.prototype.clone()

Clone this element (and its children). The clone is not yet linked
into the `DOM`.

- **Returns:** `DOM`

```
var result = xml.clone()
```

#### DOM.prototype.firstChild()

Return the first child of the element as a `DOM`, or
`null` if no child exist.

- **Returns:** `DOM` | null

```
var result = xml.firstChild()
```

#### DOM.prototype.parent()

Return the parent of the element as a `DOM`, or `null`
if no parent exists.

- **Returns:** `DOM` | null

```
var result = xml.parent()
```

#### DOM.prototype.next()

Return the next element as a `DOM`, or null if no such
element exists.

- **Returns:** `DOM` | null

```
var result = xml.next()
```

#### DOM.prototype.previous()

Return the previous element as a `DOM`, or null if no such
element exists.

- **Returns:** `DOM` | null

```
var result = xml.previous()
```

#### DOM.prototype.addAttribute(attribute, value)

Add attribute with the given value, returns the updated element as
a DOM.

- **string attribute**: Desired attribute name.
- **string value**: Desired attribute value.

- **Returns:** `DOM`

```
var result = xml.addAttribute("attribute", "value")
```

#### DOM.prototype.removeAttribute(attribute)

Remove the specified attribute from the element, returns the
updated element as a DOM.

- **string attribute**: The name of the attribute to remove.

- **Returns:** `DOM`

```
xml.removeAttribute("attribute")
```

#### DOM.prototype.getAttribute(attribute)

Return the element's attribute value as a string, or null if no
such attribute exists.

- **string attribute**: The name of the attribute to look up.

- **Returns:** string | null

```
var result = xml.attribute("attribute")
```

#### DOM.prototype.getAttributes()

Returns a dictionary object with properties and their values
corresponding to the element's attributes and their values.

- **Returns:** Object

```
var dict = xml.getAttributes()
```

#### DOM.prototype.getText()

Returns the text contents of the node.

- **Returns:** string | null

```
var text = xml.getText()
```

#### DOM.prototype.getTag()

Returns the tag name for the node.

- **Returns:** string | null

```
var text = xml.getTag()
```

### DefaultColorSpaces

An object given to a `Device` with the `Device.prototype.setDefaultColorSpaces()` call so it
can obtain the current default `ColorSpace` objects.

#### Constructors

#### DefaultColorSpaces()

#### Instance methods

#### DefaultColorSpaces.prototype.getDefaultGray()

Get the default gray colorspace.

- **Returns:** `ColorSpace`

#### DefaultColorSpaces.prototype.getDefaultRGB()

Get the default RGB colorspace.

- **Returns:** `ColorSpace`

#### DefaultColorSpaces.prototype.getDefaultCMYK()

Get the default CMYK colorspace.

- **Returns:** `ColorSpace`

#### DefaultColorSpaces.prototype.getOutputIntent()

Get the output intent.

- **Returns:** `ColorSpace`

#### DefaultColorSpaces.prototype.setDefaultGray(colorspace)

- **ColorSpace colorspace**: The new default gray colorspace.

#### DefaultColorSpaces.prototype.setDefaultRGB(colorspace)

- **ColorSpace colorspace**: The new default RGB  colorspace.

#### DefaultColorSpaces.prototype.setDefaultCMYK(colorspace)

- **ColorSpace colorspace**: The new default CMYK colorspace.

#### DefaultColorSpaces.prototype.setOutputIntent(colorspace)

- **ColorSpace colorspace**: The new default output intent.

### Device

All built-in devices have the methods listed below. Any function that
accepts a device will also accept a Javascript object with the same
methods. Any missing methods are simply ignored, so you only need to
create methods for the device calls you care about.

Many of the methods take graphics objects as arguments: `Path`,
`Text`, `Image` and `Shade`.

Colors are specified as arrays with the appropriate number of components
for the color space.

The methods that clip graphics, e.g. `Device.prototype.clipPath()`,
`Device.prototype.clipStrokePath()`, `Device.prototype.clipText()`, etc., must be balanced with
a corresponding `Device.prototype.popClip()`.

#### Constructors

#### Device(callbacks)

Create a Device which calls back to Javascript.

The callback object may provide functions matching the methods
on the Device class. Any device calls that don't have a corresponding
function will simply be ignored.

- **callbacks**: object containing callback functions

You can create other devices with `DrawDevice` and `DisplayListDevice`.

#### Constants

:term:`Blend mode` constants for use with `Device.prototype.beginGroup`:

#### Device.BLEND_NORMAL

#### Device.BLEND_MULTIPLY

#### Device.BLEND_SCREEN

#### Device.BLEND_OVERLAY

#### Device.BLEND_DARKEN

#### Device.BLEND_LIGHTEN

#### Device.BLEND_COLOR_DODGE

#### Device.BLEND_COLOR_BURN

#### Device.BLEND_HARD_LIGHT

#### Device.BLEND_SOFT_LIGHT

#### Device.BLEND_DIFFERENCE

#### Device.BLEND_EXCLUSION

#### Device.BLEND_HUE

#### Device.BLEND_SATURATION

#### Device.BLEND_COLOR

#### Device.BLEND_LUMINOSITY

#### Instance methods

#### Device.prototype.close()

Tell this device that we are done, and flush any pending output.

Before closing, ensure that there have been as many calls to
`popClip()` as there have been to the clipping functions:
`clipPath()`, `clipStrokePath()`, `clipText()`, etc.

```
device.close()
```

Line art
^^^^^^^^

#### Device.prototype.fillPath(path, evenOdd, ctm, colorspace, color, alpha)

Fill a path.

- **Path path**: Path object.
- **boolean evenOdd: Use :term:`even-odd rule` or :term**: `non-zero winding number rule` to fill the path.
- **Matrix ctm**: The transform to apply.
- **ColorSpace colorspace**: The colorspace of the color to fill with.
- **Color color**: The color to fill the path with.
- **number alpha: The :term**: `opacity`.

```
device.fillPath(path, false, mupdf.Matrix.identity, mupdf.ColorSpace.DeviceRGB, [1, 0, 0], true)
```

#### Device.prototype.strokePath(path, stroke, ctm, colorspace, color, alpha)

Stroke a path.

- **Path path**: Path object.
- **StrokeState stroke**: Stroke state.
- **Matrix ctm**: The transform to apply.
- **ColorSpace colorspace**: Colorspace.
- **Color color**: The color to stroke the path with.
- **number alpha: The :term**: `opacity`.

```
device.strokePath(path,
{dashes: [5, 10], lineWidth: 3, lineCap: 'Round' },
mupdf.Matrix.identity,
mupdf.ColorSpace.DeviceRGB,
[0, 1, 0],
0.5
)
```

#### Device.prototype.clipPath(path, evenOdd, ctm)

Clip a path.

- **Path path**: Path object.
- **boolean evenOdd: Use :term:`even-odd rule` or :term**: `non-zero winding number rule` to fill the path.
- **Matrix ctm**: The transform to apply.

```
device.clipPath(path, true, mupdf.Matrix.identity)
```

#### Device.prototype.clipStrokePath(path, stroke, ctm)

Clip & stroke a path.

- **Path path**: Path object.
- **StrokeState stroke**: Stroke state.
- **Matrix ctm**: The transform to apply.

```
device.clipStrokePath(path, true, mupdf.Matrix.identity)
```

Text
^^^^

#### Device.prototype.fillText(text, ctm, colorspace, color, alpha)

Fill a text object.

- **Text text**: Text object.
- **Matrix ctm**: The transform to apply.
- **ColorSpace colorspace**: Colorspace
- **Color color**: The color used to fill the text.
- **number alpha: The :term**: `opacity`.

```
device.fillText(text, mupdf.Matrix.identity, mupdf.ColorSpace.DeviceRGB, [1, 0, 0], 1)
```

#### Device.prototype.strokeText(text, stroke, ctm, colorspace, color, alpha)

Stroke a text object.

- **Text text**: Text object.
- **StrokeState stroke**: Stroke state.
- **Matrix ctm**: The transform to apply.
- **ColorSpace colorspace**: Colorspace
- **Color color**: The color used to stroke the text.
- **number alpha: The :term**: `opacity`.

```
device.strokeText(text,
{ dashes: [5, 10], lineWidth: 3, lineCap: 'Round' },
mupdf.Matrix.identity,
mupdf.ColorSpace.DeviceRGB,
[1, 0, 0],
1
)
```

#### Device.prototype.clipText(text, ctm)

Clip a text object.

- **Text text**: Text object.
- **Matrix ctm**: The transform to apply.

```
device.clipText(text, mupdf.Matrix.identity)
```

#### Device.prototype.clipStrokeText(text, stroke, ctm)

Clip & stroke a text object.

- **Text text**: Text object.
- **StrokeState stroke**: stroke state.
- **Matrix ctm**: The transform to apply.

```
device.clipStrokeText(text,
{ dashes: [5, 10], lineWidth: 3, lineCap: 'Round' },
mupdf.Matrix.identity
)
```

#### Device.prototype.ignoreText(text, ctm)

Invisible text that can be searched but should not be visible, such as for overlaying a scanned OCR image.

- **Text text**: Text object.
- **Matrix ctm**: The transform to apply.

```
device.ignoreText(text, mupdf.Matrix.identity)
```

Shadings
^^^^^^^^

#### Device.prototype.fillShade(shade, ctm, alpha)

Fill a shading, also known as a gradient.

- **Shade shade**: The gradient.
- **Matrix ctm**: The transform to apply.
- **number alpha: The :term**: `opacity`.

```
device.fillShade(shade, mupdf.Matrix.identity, true, { overPrinting: true })
```

Images
^^^^^^

#### Device.prototype.fillImage(image, ctm, alpha)

Draw an image. An image always fills a unit rectangle [0, 0, 1, 1], so must be transformed to be placed and drawn at the appropriate size.

- **Image image**: Image object.
- **Matrix ctm**: The transform to apply.
- **number alpha: The :term**: `opacity`.

```
device.fillImage(image, mupdf.Matrix.identity, false, { overPrinting: true })
```

#### Device.prototype.fillImageMask(image, ctm, colorspace, color, alpha)

An image mask is an image without color. Fill with the color where the image is opaque.

- **Image image**: Image object.
- **Matrix ctm**: The transform to apply.
- **ColorSpace colorspace**: Colorspace
- **Color color**: The color to be used.
- **number alpha: The :term**: `opacity`.

```
device.fillImageMask(image, mupdf.Matrix.identity, mupdf.ColorSpace.DeviceRGB, [0, 1, 0], true)
```

#### Device.prototype.clipImageMask(image, ctm)

Clip graphics using the image to mask the areas to be drawn.

- **Image image**: Image object.
- **Matrix ctm**: The transform to apply.

```
device.clipImageMask(image, mupdf.Matrix.identity)
```

Clipping and masking
^^^^^^^^^^^^^^^^^^^^

#### Device.prototype.popClip()

Pop the clip mask installed by the last clipping operation.

```
device.popClip()
```

#### Device.prototype.beginMask(area, luminosity, colorspace, color)

Create a soft mask. Any drawing commands between `beginMask` and `endMask` are grouped and used as a clip mask.

- **Rect area**: Mask area.
- **boolean luminosity**: If luminosity is `true`, the mask is derived from the luminosity (grayscale value) of the graphics drawn; otherwise the color is ignored completely and the mask is derived from the alpha of the group.
- **ColorSpace colorspace**: Colorspace
- **Color color**: The color to be used.

```
device.beginMask([0, 0, 100, 100], true, mupdf.ColorSpace.DeviceRGB, [1, 0, 1])
```

#### Device.prototype.endMask()

Ends the mask.

```
device.endMask()
```

Groups and transparency
^^^^^^^^^^^^^^^^^^^^^^^

#### Device.prototype.beginGroup(area, colorspace, isolated, knockout, blendmode, alpha)

Begin a transparency blending group. See :term:`knockout and isolation`
and :term:`blend mode` in the glossary for a cursory overview of the
concepts.

- **Rect area**: The blend area.
- **ColorSpace colorspace**: Colorspace
- **boolean isolated**: Whether the group is isolated.
- **boolean knockout**: Whether the group is knockout.
- **string blendmode**: The blend mode used when compositing this group with its backdrop.
- **number alpha: The :term**: `opacity`.

The blendmode is one of these string values or the corresponding enum constants:
Normal, Multiply, Screen, Overlay, Darken, Lighten, ColorDodge, ColorBurn, HardLight, SoftLight, Difference, Exclusion, Hue, Saturation, Color, Luminosity.

You can also use the `Device.BLEND_NORMAL` constant:

```
device.beginGroup(
[0, 0, 100, 100],
mupdf.ColorSpace.DeviceRGB,
true,
true,
"Multiply",
0.5
)
```

#### Device.prototype.endGroup()

Ends the blending group.

```
device.endGroup()
```

Tiling
^^^^^^

#### Device.prototype.beginTile(area, view, xstep, ystep, ctm, id, doc_id)

Draw a tiling pattern. Any drawing commands between `beginTile` and `endTile` are grouped and then repeated across the whole page. Apply a clip mask to restrict the pattern to the desired shape.

- **Rect area**: Area
- **Rect view**: View
- **number xstep**: x step.
- **number ystep**: y step.
- **Matrix ctm**: The transform to apply.
- **number id**: 
- **number doc_id**: 
The purpose of id/doc_id is to allow for efficient caching of
rendered tiles. If id is 0, then no caching is performed. If
it is non-zero, then id/doc_id are assumed to uniquely
identify this tile.

```
device.beginTile([0, 0, 100, 100], [100, 100, 200, 200], 10, 10, mupdf.Matrix.identity, 0)
```

#### Device.prototype.endTile()

Ends the tiling pattern.

```
device.endTile()
```

Render flags
^^^^^^^^^^^^

#### Device.prototype.renderFlags(set, clear)

The specified rendering flags are set, and some others are cleared.

Both set and clear are arrays where each element one of these flag names:

- "mask"
- "color"
- "uncacheable"
- "fillcolor-undefined"
- "strokecolor-undefined"
- "startcap-undefined"
- "dashcap-undefined"
- "endcap-undefined"
- "linejoin-undefined"
- "miterlimit-undefined"
- "linewidth-undefined"
- "bbox-defined"
- "gridfit-as-tiled"

- **Array of string set**: Rendering flags to set.
- **Array of string clear**: Rendering flags to clear.

```
device.renderFlags(["mask", "startcap-undefined"], [])
```

Device colorspaces
^^^^^^^^^^^^^^^^^^

#### Device.prototype.setDefaultColorSpaces(defaultCS)

Change the set of default device colorspaces to one given.

- **DefaultColorSpaces defaultCS**: The new set of default colorspaces.

```
var defaultCS = new DefaultColorSpaces()
defaultCS.setDefaultRGB(defaultCS.getDefaultGray())
device.setDefaultColorSpaces(new DefaultColorSpaces())
```

Layers
^^^^^^

#### Device.prototype.beginLayer(name)

Begin a marked-content layer with the given name.

- **string name**: Name of this marked-content layer.

```
device.beginLayer("my tag")
```

#### Device.prototype.endLayer()

End a marked-content layer.

```
device.endLayer()
```

Structures
^^^^^^^^^^

#### Device.prototype.beginStructure(structure, raw, index)

Begin a :term:`standard structure type` with the raw tag name and a unique identifier.

- **string structure**: One of the pre-defined structure types in PDF.
- **string raw**: The tag name.
- **number index**: A unique identifier.

```
device.beginStructure("Document", "my_tag_name", 123)
```

#### Device.prototype.endStructure()

End a standard structure element.

```
device.endStructure()
```

Metatext
^^^^^^^^

#### Device.prototype.beginMetatext(meta, text)

Begin meta text where meta is either of:

- "ActualText"
- "Alt"
- "Abbreviation"
- "Title"

- **string meta**: The meta text type
- **string text**: The text value.

```
device.beginMetatext("Title", "My title")
```

#### Device.prototype.endMetatext()

End meta text information.

```
device.endMetatext()
```

### DisplayList

A display list is a sequence of device calls that can be replayed multiple
times. This is useful e.g. when you need to render a page at multiple
resolutions, or when you want to both render a page and later search for
text in it. Using a display list to do this, improves performance because
it avoids repeatedly reinterpreting the document from file

To populate a display list use the `DisplayListDevice`.

```
	var list = new mupdf.DisplayList([0, 0, 595, 842])
	var listDevice = new mupdf.DisplayListDevice(list)
	page.run(listDevice, mupdf.Matrix.identity)
```

	var pixmap = new mupdf.Pixmap(mupdf.ColorSpace.DeviceRGB, [0, 0, 595, 842], false)
	var drawDevice = new mupdf.DrawDevice(mupdf.Matrix.identity, pixmap)
	list.run(drawDevice, mupdf.Matrix.identity)

	var searchHits = list.search("hello world")

#### Constructors

#### DisplayList(mediabox)

Create an empty display list. The mediabox rectangle should be the
bounds of the page.

- **Rect mediabox**: The size of the page.

```
var displayList = new mupdf.DisplayList([0, 0, 595, 842])
```

#### Instance methods

#### DisplayList.prototype.run(device, matrix)

Play back this display lists sequence of device calls to the given device.

- **Device device**: The device to replay the device calls to.
- **Matrix matrix**: Transformation matrix to apply to coordinates in all device calls.

```
displayList.run(device, mupdf.Matrix.identity)
```

#### DisplayList.prototype.getBounds()

Return a bounding rectangle that encompasses all the contents of the display list.

- **Returns:** `Rect`

```
var bounds = displayList.getBounds()
```

#### DisplayList.prototype.toPixmap(matrix, colorspace, alpha)

Render a display list to a `Pixmap`.

- **Matrix matrix**: Transformation matrix.
- **ColorSpace colorspace**: The desired colorspace of the returned pixmap.
- **boolean alpha**: Whether the returned pixmap has transparency or not. If the pixmap handles transparency, it starts out transparent (otherwise it is filled white), before the contents of the display list are rendered onto the pixmap.

- **Returns:** `Pixmap`

```
var pixmap = displayList.toPixmap(mupdf.Matrix.identity, mupdf.ColorSpace.DeviceRGB, false)
```

#### DisplayList.prototype.toStructuredText(options)

Extract the text on the page into a `StructuredText` object.

- **string options**: 
See :doc:`/reference/common/stext-options`.

- **Returns:** `StructuredText`

```
var sText = displayList.toStructuredText("preserve-whitespace")
```

#### DisplayList.prototype.search(needle, max_hits)

Search the display list text for all instances of the text value
`needle`, and return an array of search hits. Each search hit is an
array of `Quad`, each corresponding to a single character in the search
hit.

- **string needle**: The text to search for.
- **number options**: Optional options for the search. A logical or of options such as `StructuredText.SEARCH_EXACT`.

- **Returns:** Array of Array of `Quad`

```
var results = displayList.search("my search phrase")
```

#### DisplayList.protoype.decodeBarcode(subarea, rotate)

Decodes a barcode detected in the display list, and returns an
object with properties for barcode type and contents.

- **Rect subarea**: Only detect barcode within subarea. Defaults to the entire area returned by `DisplayList.prototype.getBounds()`.
- **number rotate**: Degrees of rotation to rotate display list before detecting barcode. Defaults to 0.

- **Returns:** Object with barcode information.

```js
var barcodeInfo = displayList.decodeBarcode([0, 0, 100, 100 ], 0)
```

### DisplayListDevice

#### Constructors

#### DisplayListDevice(displayList)

Create a device for recording onto a display list.

- **DisplayList displayList**: the display list to populate.

```
var myDisplayList = new mupdf.DisplayList([0, 0, 100, 100])
var displayListDevice = new mupdf.DisplayListDevice(myDisplayList)
```

### Document

MuPDF can open many document types such as PDF, XPS, CBZ, EPUB, FictionBook 2
and a handful of image formats.

#### Document

*(not constructible with `new`)*

#### Constants

Permission flags for `Document.prototype.hasPermission`:

#### Document.PERMISSION_PRINT

`"print"` -- Print the document.

#### Document.PERMISSION_EDIT

`"edit"` -- Modify the contents of the document by operations other than those controlled by the other flags: (annotate, form, assemble).

#### Document.PERMISSION_COPY

`"edit"` -- Copy or otherwise extract text from the document.

#### Document.PERMISSION_ANNOTATE

`"annotate"` -- Add or modify annotations.

#### Document.PERMISSION_FORM

`"form"` -- Fill in existing form fields.

#### Document.PERMISSION_ACCESSIBILITY

`"accessibility"` --
Copy or otherwise extract text from the document in support of accessibility.

#### Document.PERMISSION_ASSEMBLE

`"assemble"` -- Insert, rotate, or delete pages and create bookmarks.

#### Document.PERMISSION_PRINT_HQ

`"print-hq"` -- Print the document to a representation from which a faithful digital
copy of the PDF content could be generated.

#### Static methods

#### 

Document.openDocument(filename)
Document.openDocument(filename, dir)
Document.openDocument(filename, accelerator, dir)
Document.openDocument(buffer, magic)
Document.openDocument(buffer, magic, acceleratorbuffer)
Document.openDocument(buffer, magic, acceleratorbuffer, dir)

Open the named or given document.

- **string filename**: File name to open.
- **Buffer | ArrayBuffer | Uint8Array | string buffer**: Buffer containing a document file.
- **string magic: An optional :term**: `MIME-type` or file extension. Defaults to "application/pdf".
- **string accelerator**: File name of accelerator file.
- **Buffer | ArrayBuffer | Uint8Array | string acceleratorbuffer**: Buffer containing an accelerator file.
- **Archive dir**: An archive from which to load resources for rendering.

- **Returns:** Document

```
var document1 = mupdf.Document.openDocument("my_pdf.pdf", "application/pdf")
var document2 = mupdf.Document.openDocument("my_pdf.pdf", dir)
var document3 = mupdf.Document.openDocument("my_pdf.pdf", acceleratorfile, dir)
var document4 = mupdf.Document.openDocument(fs.readFileSync("my_pdf.pdf"), "application/pdf")
var document5 = mupdf.Document.openDocument(fs.readFileSync("my_pdf.pdf"), acceleratorbuffer, "application/pdf")
var document6 = mupdf.Document.openDocument(fs.readFileSync("my_pdf.pdf"), acceleratorbuffer, dir, "application/pdf")
```

#### 

Document.recognize(magic)
Document.recognizeContent(filename)
Document.recognizeContent(buffer, magic)
Document.recognizeContent(buffer, dir, magic)

Check if MuPDF can open a document with the provided magic, or with the contents in the given file/buffer.

- **string magic: An optional :term**: `MIME-type` or file extension. Defaults to "application/pdf".
- **string filename**: File name to check contents of.
- **Buffer | ArrayBuffer | Uint8Array | string buffer**: Buffer containing a PDF file.
- **Archive dir**: An archive from which to load resources for rendering.

- **Returns:** boolean

```
var recognized1 = mupdf.Document.recognize("application/pdf")
var recognized2 = mupdf.Document.recognizeContent("my_pdf.pdf")
var recognized3 = mupdf.Document.recognizeContent(buffer, "application/pdf")
var recognized4 = mupdf.Document.recognizeContent(buffer, dir, "application/pdf")
```

#### Instance methods

#### Document.prototype.needsPassword()

Returns `true` if a password is required to open a password protected PDF.

- **Returns:** boolean

```
var needsPassword = document.needsPassword()
```

#### Document.prototype.authenticatePassword(password)

Returns a bitfield value against the password authentication result.

- **string password**: The password to attempt authentication with.

- **Returns:** number

| **Bitfield value** | **Description** |
| --- | --- |
| 0 | Failed |
| 1 | No password needed |
| 2 | Is User password and is okay |
| 4 | Is Owner password and is okay |
| 6 | Is both User & Owner password and is okay |

```
var auth = document.authenticatePassword("abracadabra")
```

#### Document.prototype.hasPermission(permission)

Check if a user is allowed permission to perform certain operations on the document.

- **"print" | "edit" | "copy" | "annotate" | "form" | "accessibility" | "assemble" | "print-hq" permission**: 

See `Document.PERMISSION_PRINT`, etc.

- **Returns:** boolean

```
var canEdit1 = document.hasPermission("edit")
var canEdit2 = document.hasPermission(Document.PERMISSION_EDIT)
```

#### Document.prototype.getMetaData(key)

Return various meta data information. The common keys are: format, encryption, info:ModDate, and info:Title. Returns `undefined` if the meta data does not exist.

- **string key**: What metadata type to return.

- **Returns:** string | null

```
var format = document.getMetaData("format")
var modificationDate = doc.getMetaData("info:ModDate")
var author = doc.getMetaData("info:Author")
```

#### Document.prototype.setMetaData(key, value)

Set document meta data information field to a new value.

- **string key**: Metadata key to set.
- **string value**: New value to set for the given key.

```
document.setMetaData("info:Author", "My Name")
```

#### Document.prototype.isReflowable()

Returns true if the document is reflowable, such as EPUB, FB2 or XHTML.

- **Returns:** boolean

```
var isReflowable = document.isReflowable()
```

#### Document.prototype.layout(pageWidth, pageHeight, fontSize)

Layout a reflowable document (EPUB, FictionBook2, HTML or XHTML) to fit
the specified page and font sizes.

- **number pageWidth**: Desired page width.
- **number pageHeight**: Desired page height.
- **number fontSize**: Desire font size.

```
document.layout(300, 300, 16)
```

#### Document.prototype.countPages()

Count the number of pages in the document. This may change if you call
the layout function with different parameters.

- **Returns:** number

```
var numPages = document.countPages()
```

#### Document.prototype.loadPage(number)

Returns a `Page` object for the given page number.

For documents where `Document.prototype.isPDF()` returns true,
the returned `Page` is of the subclass `PDFPage`.

- **number number**: Number of page to load, 0 means the first page in the document.

- **Returns:** `Page` | `PDFPage`.

```
var page = document.loadPage(0) // loads the 1st page of the document
```

#### Document.prototype.loadOutline()

Returns an array with the outline (also known as table of contents or
bookmarks). In the array is an object for each heading with the
property 'title', and a property 'page' containing the page number. If
the object has a 'down' property, it contains an array with all the
sub-headings for that entry.

- **Returns:** Array of `OutlineItem` (nested).

```
var outline = document.loadOutline()
```

#### Document.prototype.outlineIterator()

Returns an `OutlineIterator` for the document outline.

- **Returns:** `OutlineIterator`

```
var obj = document.outlineIterator()
```

#### Document.prototype.resolveLink(link)

Resolve a document internal link URI to a page index.

- **Link | string link**: A link or a link URI string to resolve.

- **Returns:** number

```
var pageNumber = document.resolveLink(my_link)
```

#### Document.prototype.resolveLinkDestination(link)

Resolve a document internal link URI to a link destination.

- **Link | string link**: A link or a link URI string to resolve.

- **Returns:** `LinkDestination`

```
var linkDestination = document.resolveLinkDestination(linkuri)
```

#### Document.prototype.isPDF()

Returns `true` if the document is a `PDFDocument`.

- **Returns:** boolean

```
var isPDF = document.isPDF()
```

#### Document.prototype.asPDF()

Returns a PDF version of the document (if possible).
PDF documents return themselves.
Documents that have an underlying PDF representation return that.
Other document types return null.

- **Returns:** `PDFDocument` | null

```
var doc = mupdf.Document.openDocument(filename)
var pdf = doc.asPDF()
if (pdf) {
// the document has a native PDF representation
} else {
// it does not have a native PDF representation
}
```

#### Document.prototype.formatLinkURI(linkDestination)

Format a document internal link destination object to a URI string suitable for `Page.prototype.createLink()`.

- **LinkDestination linkDestination**: The link destination object to format.

- **Returns:** string

```
var uri = document.formatLinkURI({
chapter: 0,
page: 42,
type: "FitV",
x: 0,
y: 0,
width: 100,
height: 50,
zoom: 1
})
page.createLink([0, 0, 100, 100], uri)
```

### DocumentWriter

DocumentWriter objects are used to create new documents in several formats.

#### Constructors

#### 

DocumentWriter(buffer, format, options)
DocumentWriter(filename, format, options)

Create a new document writer to create a document with the specified format and output options. If `format` is `null` it is inferred from the filename. The `options` argument is a comma separated list of flags and key-value pairs.

For supported output `format` values and `options` see
:doc:`/reference/common/document-writer-options`.

- **Buffer buffer**: The buffer to output to.
- **Buffer filename**: The file name to output to.
- **string format**: The file format.
- **string options**: The options as key-value pairs.

```
var writer = new mupdf.DocumentWriter(buffer, "PDF", "")
```

#### Instance methods

#### DocumentWriter.prototype.beginPage(mediabox)

Begin rendering a new page. Returns a `Device` that can be used to render the page graphics.

- **Rect mediaBox**: The page size.

- **Returns:** `Device`

```
var device = writer.beginPage([0, 0, 100, 100])
```

#### DocumentWriter.prototype.endPage()

Finish the page rendering.

```
writer.endPage()
```

#### DocumentWriter.prototype.close()

Finish the document and flush any pending output. It is a
requirement to make this call to ensure that the output file is
complete.

```
writer.close()
```

### DrawDevice

The DrawDevice can be used to render to a `Pixmap`; either by running a Page
using `Page.prototype.run()` with it or by calling the device methods directly.

#### Constructors

#### DrawDevice(matrix, pixmap)

Create a device for drawing into a `Pixmap`. The `Pixmap` bounds used should match the transformed page bounds, or you can adjust them to only draw a part of the page.

- **Matrix matrix**: The matrix to apply.
- **Pixmap pixmap**: The pixmap that will be drawn to.

```
var drawDevice = new mupdf.DrawDevice(mupdf.Matrix.identity, pixmap)
```

### Font

Font objects can be created from TrueType, OpenType,
Type1 or CFF fonts. In PDF there are also special
Type3 fonts.

#### Constructors

#### 

Font(name, data, index)
Font(name, filename, index)

Create a new font. Either from a buffer, a file name, or a
built-in font name.

The built-in standard PDF fonts are:

- `"Times-Roman"`
- `"Times-Italic"`
- `"Times-Bold"`
- `"Times-BoldItalic"`
- `"Helvetica"`
- `"Helvetica-Oblique"`
- `"Helvetica-Bold"`
- `"Helvetica-BoldOblique"`
- `"Courier"`
- `"Courier-Oblique"`
- `"Courier-Bold"`
- `"Courier-BoldOblique"`
- `"Symbol"`
- `"ZapfDingbats"`

The built-in CJK fonts are referenced by language code:
`"zh-Hant"`, `"zh-Hans"`, `"ja"`, `"ko"`.

- **string name**: Font name.
- **Buffer | ArrayBuffer | Uint8Array data**: The font data if loaded from a buffer.
- **string filename**: The name of the font file to load.
- **number index**: Subfont index (only used for TTC fonts).

```
var font1 = new mupdf.Font("Times-Roman")
var font2 = new mupdf.Font("ko")
```

                var font3 = new mupdf.Font("Comic Sans", "/usr/share/fonts/truetype/msttcorefonts/Comic_Sans_MS.ttf")
                var font4 = new mupdf.Font("Comic Sans", "/usr/share/fonts/truetype/msttcorefonts/Comic_Sans_MS.ttf", 1)
		var font5 = new mupdf.Font("Freight Sans", fs.readFileSync("DroidSansFallbackFull.ttf"))

#### Constants

Encoding constants for `PDFDocument.prototype.addSimpleFont`:

#### Font.SIMPLE_ENCODING_LATIN

WinAnsiEncoding (a.k.a. CP-1252)

#### Font.SIMPLE_ENCODING_GREEK

ISO-8859-7

#### Font.SIMPLE_ENCODING_CYRILLIC

KOI8-U

#### Instance methods

#### Font.prototype.getName()

Get the font name.

- **Returns:** string

```
var name = font.getName()
```

#### Font.prototype.encodeCharacter(unicode)

Get the glyph index for a unicode character. Glyph `0` is returned if the font does not have a glyph for the character.

- **number | string unicode**: The unicode character, or the first unicode character of a string.

- **Returns:** number.

```
var index = font.encodeCharacter(0x42)
```

#### Font.prototype.advanceGlyph(glyph , wmode)

Return advance width for a glyph in either horizontal or vertical writing mode.

- **number glyph**: The glyph as unicode character.
- **number wmode**: `0` for horizontal writing, and `1` for vertical writing, defaults to horizontal.

- **Returns:** number

```
var width = font.advanceGlyph(0x42)
```

#### Font.prototype.isBold()

Returns `true` if font is bold.

- **Returns:** boolean

```
var isBold = font.isBold()
```

#### Font.prototype.isItalic()

Returns `true` if font is italic.

- **Returns:** boolean

```
var isItalic = font.isItalic()
```

#### Font.prototype.isMono()

Returns `true` if font is monospaced.

- **Returns:** boolean

```
var isMono = font.isMono()
```

#### Font.prototype.isSerif()

Returns `true` if font is serif.

- **Returns:** boolean

```
var isSerif = font.isSerif()
```

### Image

#### Constructors

#### 

Image(pixmap, mask)
Image(data, mask)
Image(filename, mask)

Create an Image and populate it with image data decoded either from a pixmap,
a data buffer, or a file.

- **Pixmap pixmap**: A pixmap with the image data.
- **Buffer | ArrayBuffer | Uint8Array data**: Image data.
- **string filename**: Image file to load.
- **Image mask**: An optional image mask.

```
var image1 = new mupdf.Image(pixmap, imagemask)
var image2 = new mupdf.Image(buffer, imagemask)
var image3 = new mupdf.Image("logo.png", imagemask)
```

#### Instance methods

#### Image.prototype.getWidth()

Get the image width in pixels.

- **Returns:** number

```
var width = image.getWidth()
```

#### Image.prototype.getHeight()

Get the image height in pixels.

- **Returns:** number

```
var height = image.getHeight()
```

#### Image.prototype.getXResolution()

Returns the x resolution for the `Image` in dots per inch.

- **Returns:** number

```
var xRes = image.getXResolution()
```

#### Image.prototype.getYResolution()

Returns the y resolution for the `Image` in dots per inch.

- **Returns:** number

```
var yRes = image.getYResolution()
```

#### Image.prototype.getColorSpace()

Returns the `ColorSpace` for the `Image`. Returns null if the image has
no colors (for example if it is an opacity mask with only an alpha
channel).

- **Returns:** `ColorSpace` | null

```
var cs = image.getColorSpace()
```

#### Image.prototype.getNumberOfComponents()

Number of colors; plus one if an alpha channel is present.

- **Returns:** number

```
var num = image.getNumberOfComponents()
```

#### Image.prototype.getBitsPerComponent()

Returns the number of bits per component.

- **Returns:** number

```
var bits = image.getBitsPerComponent()
```

#### Image.prototype.getImageMask()

Returns `true` if this image is an image mask.

- **Returns:** boolean

```
var hasMask = image.getImageMask()
```

#### Image.prototype.getMask()

Get another `Image` used as a mask for this one.

- **Returns:** `Image` | null

```
var mask = image.getMask()
```

#### Image.prototype.getInterpolate()

Returns whether interpolation was used during decoding.

- **Returns:** boolean

```js
var interpolate = image.getInterpolate()
```

#### Image.prototype.getColorKey()

Returns an array with `2 * getNumberOfComponents()` integers
for an image with color key masking, or `null` if masking is
not used. Each pair of integers define an interval, and
component values within those intervals are not painted.

- **Returns:** Array of number | null

```js
var result = image.getColorKey()
```

#### Image.prototype.getDecode()

Returns an array with `2 * getNumberOfComponents()` numbers
for an image with color mapping, or `null` if mapping is not
used. Each pair of numbers define the lower and upper values to
which the component values are mapped linearly.

- **Returns:** Array of number | null

```js
var arr = image.getDecode()
```

#### Image.prototype.getOrientation()

Returns the orientation of the image.

- **Returns:** number

```js
var orientation = image.getOrientation()
```

#### Image.prototype.setOrientation(orientation)

Set the image orientation to the given orientation.

- **number orientation**: 
Orientation value described in this table:

======= ===========
Value	Description
======= ===========
0	Undefined
1	0 degree ccw rotation. (Exif = 1)
2	90 degree ccw rotation. (Exit = 8)
3	180 degree ccw rotation. (Exif = 3)
4	270 degree ccw rotation. (Exif = 6)
5	flip on X. (Exif = 2)
6	flip on X, then rotate ccw by 90 degrees. (Exif = 5)
7	flip on X, then rotate ccw by 180 degrees. (Exif = 4)
4	flip on X, then rotate ccw by 270 degrees. (Exif = 7)
======= ===========

#### Image.prototype.toPixmap(scaledWidth, scaledHeight)

Create a `Pixmap` from this image. The `scaledWidth` and
`scaledHeight` arguments are optional, but may be used to decode a
down-scaled `Pixmap`.

- **number scaledWidth**: 
- **number scaledHeight**: 

- **Returns:** `Pixmap`

```js
var pixmap = image.toPixmap()
var scaledPixmap = image.toPixmap(100, 100)
```

### Link

Link objects contain information about page links, such as their bounding
box and their destination URI.

To determine whether a link is document-internal or an external link to a web page, see `Link.prototype.isExternal()`.
Finally, to resolve a document-internal link see `Document.prototype.resolveLinkDestination()`.

#### Constructors

#### Link

*(not constructible with `new`)*

To obtain the links on a page see `Page.prototype.getLinks()`.

To create a new link on a page see `Page.prototype.createLink()`.

#### Instance methods

#### Link.prototype.getBounds()

Returns a rectangle describing the link's location on the page.

- **Returns:** `Rect`

```
var rect = link.getBounds()
```

#### Link.prototype.setBounds(rect)

Sets the bounds for the link's location on the page.

- **Rect rect**: Desired bounds for link.

```js
link.setBounds([0, 0, 100, 100])
```

#### Link.prototype.getURI()

Returns a string URI describing the link's destination. If
`isExternal()` returns `true`, this is a URI suitable for a
browser, if it returns `false` pass it to `Document.prototype.resolveLink` to access
to the destination page in the document.

- **Returns:** string

```
var uri = link.getURI()
```

#### Link.prototype.setURI(uri)

Sets this link's destination to the given URI. To create links to other
pages within the document, see `Document.prototype.formatLinkURI()`.

- **string uri**: An URI describing the desired link destination.

#### Link.prototype.isExternal()

Returns a boolean indicating if the link is external or not. URIs whose
link URI has a valid scheme followed by colon, e.g.
`https://example.com` and `mailto:test@example.com`, are defined to
be external.

- **Returns:** boolean

```
var isExternal = link.isExternal()
```

### LinkDestination

A link destination points to a location within a document and how a document viewer should show that destination.

#### LinkDestination(chapter, page, type, x, y, width, height)

- **number chapter**: 
- **number page**: 
- **"Fit" | "FitB" | "FitH" | "FitBH" | "FitV" | "FitBV" | "FitR" | "XYZ" type**: 

#### Constants

The possible type values:

#### LinkDestination.FIT

Display the page with contents zoomed to make the entire page visible.

#### LinkDestination.FIT_H

Scroll to the top coordinate and zoom to make the page width visible.

#### LinkDestination.FIT_V

Scroll to the left coordinate and zoom to make the page height visible.

#### LinkDestination.FIT_B

Zoom to fit the page bounding box.

#### LinkDestination.FIT_BH

Zoom to fit the page bounding box width.

#### LinkDestination.FIT_BV

Zoom to fit the page bounding box height.

#### LinkDestination.FIT_R

Scroll and zoom to make the specified rectangle visible.

#### LinkDestination.XYZ

Display with coordinates at the top left zoomed in to the specified magnification factor.

#### Instance properties

#### LinkDestination.prototype.chapter

    The chapter within the document.

#### LinkDestination.prototype.page

    The page within the document.

#### LinkDestination.prototype.type

    Either "Fit", "FitB", "FitH", "FitBH", "FitV", "FitBV", "FitR" or "XYZ".

    The type controls which of the x, y, width, height, and zoom values are used.

#### LinkDestination.prototype.x

    The left coordinate. Used for "FitV", "FitBV", "FitR", and "XYZ".

#### LinkDestination.prototype.y

    The top coordinate. Used for "FitH", "FitBH", "FitR", and "XYZ".

#### LinkDestination.prototype.width

    The width of the zoomed in region. Used for "FitR".

#### LinkDestination.prototype.height

    The height of the zoomed in region. Used for "FitR".

#### LinkDestination.prototype.zoom

    The zoom factor. Used for "XYZ".

### Matrix

A Matrix is used to compute transformations of points and graphics
objects.

3-by-3 matrices of this form can perform 2-dimensional transformations
such as translations, rotations, scaling, and skewing:

```
	/ a b 0 \
	| c d 0 |
	\ e f 1 /
```

Because of the fixes values in the right-most column, such a matrix is
represented in Javascript as an array of six numbers:

```
	[a, b, c, d, e, f]
```

In TypeScript the Matrix type is defined as follows:

```
	type Matrix = [number, number, number, number, number, number]
```

#### Constructors

#### Matrix

*(interface type)*

Matrices are not represented by a class; they are just plain arrays of six numbers.

#### Static properties

#### Matrix.identity

The identity matrix, short hand for `[1, 0, 0, 1, 0, 0]`.

```
var m = mupdf.Matrix.identity
```

#### Static methods

#### Matrix.scale(sx, sy)

Returns a scaling matrix, short hand for `[sx, 0, 0, sy, 0, 0]`.

- **number sx**: X scale as a floating point number.
- **number sy**: Y scale as a floating point number.

- **Returns:** `Matrix`

```
var m = mupdf.Matrix.scale(2, 2)
```

#### Matrix.translate(tx, ty)

Return a translation matrix, short hand for `[1, 0, 0, 1, tx, ty]`.

- **number tx**: X translation as a floating point number.
- **number ty**: Y translation as a floating point number.

- **Returns:** `Matrix`

```
var m = mupdf.Matrix.translate(2, 2)
```

#### Matrix.rotate(theta)

Return a rotation matrix, short hand for
`[cos(theta), sin(theta), -sin(theta), cos(theta), 0, 0]`.

- **number theta**: Rotation in degrees, positive for CW and negative for CCW.

- **Returns:** `Matrix`

```
var m = mupdf.Matrix.rotate(90)
```

#### Matrix.concat(a, b)

Concatenate matrices `a` and `b`. Bear in mind that matrix
multiplication is not commutative.

- **Matrix a**: Left side matrix.
- **Matrix b**: Right side matrix.

- **Returns:** `Matrix`

```
var m = mupdf.Matrix.concat([1, 1, 1, 1, 1, 1], [2, 2, 2, 2, 2, 2])
// expected result [4, 4, 4, 4, 6, 6]
```

#### Matrix.invert(matrix)

Inverts the supplied matrix and returns the result.

- **Matrix matrix**: Matrix to invert.

- **Returns:** `Matrix`

```
var m = mupdf.Matrix.invert([1, 0.5, 1, 1, 1, 1])
```

### MultiArchive

#### Constructors

#### MultiArchive()

Create a new empty multi archive.

```
var multiArchive = new mupdf.MultiArchive()
```

#### Instance methods

#### MultiArchive.prototype.mountArchive(subArchive, path)

Add an archive to the set of archives handled by a multi archive.
If `path` is `null`, the `subArchive` contents appear at the
top-level, otherwise they will appear prefixed by the string
`path`.

- **Archive subArchive**: An archive that will be a child archive of this one.
- **string path**: The path at which the archive will be inserted.

In the following example `example1.zip` contains `file1.txt` and
`example2.zip` contains `file2.txt`. The MultiArchive now lets you
access both `file1.txt` and `subpath/file2.txt`:

```
var archive = new mupdf.MultiArchive()
archive.mountArchive(new mupdf.Archive("example1.zip"), null)
archive.mountArchive(new mupdf.Archive("example2.zip"), "subpath")
console.log(archive.hasEntry("file1.txt"))
console.log(archive.hasEntry("subpath/file2.txt"))
```

### OutlineItem

Outline items are returned from the `Document.prototype.loadOutline` method and
represent a table of contents entry.

They are also used with the `OutlineIterator` interface.

#### Constructors

#### OutlineItem

*(interface type)*

Outline items are passed around as plain objects.

```js
	interface OutlineItem {
		title: string | undefined,
		uri: string | undefined,
		open: boolean,
		down?: OutlineItem[],
		page?: number,
	}
```

### OutlineIterator

An outline iterator can be used to walk over all the items in an Outline and
query their properties. To be able to insert items at the end of a list of
sibling items, it can also walk one item past the end of the list. To get an
instance of `OutlineIterator` use `Document.prototype.outlineIterator()`.

In the context of a PDF file, the document's Outline is also known as Table of
Contents or Bookmarks.

#### Constructors

#### OutlineIterator

*(not constructible with `new`)*

OutlineIterator instances are returned by `Document.prototype.outlineIterator()`.

#### Constants

Navigation return codes:

#### OutlineIterator.ITERATOR_DID_NOT_MOVE

Movement was not possible.

#### OutlineIterator.ITERATOR_AT_ITEM

New position has a valid item.

#### OutlineIterator.ITERATOR_AT_EMPTY

New position has no item, but one can be inserted here.

Style bit flags:

#### OutlineIterator.FLAG_BOLD

Bit is set outline item style is bold.

#### OutlineIterator.FLAG_ITALIC

Bit is set if outline item style is italic.

#### Instance methods

#### OutlineIterator.prototype.item()

Return a `OutlineItem` or `null` if out of range.

- **Returns:** `OutlineItem` | null

```
var obj = outlineIterator.item()
```

#### OutlineIterator.prototype.next()

Move the iterator position to "next". The return value is negative if
this movement is not possible, `0` if the new position has a valid
item, or `1` if the new position has no item but one can be inserted
here.

- **Returns:** number

```
var result = outlineIterator.next()
```

#### OutlineIterator.prototype.prev()

Move the iterator position to "previous". The return value is negative
if this movement is not possible, `0` if the new position has a valid
item, or `1` if the new position has no item but one can be inserted
here.

- **Returns:** number

```
var result = outlineIterator.prev()
```

#### OutlineIterator.prototype.up()

Move the iterator position "up". The result value is negative if this
movement is not possible, `0` if the new position has a valid item,
or `1` if the new position has no item but one can be inserted here.

- **Returns:** number

```
var result = outlineIterator.up()
```

#### OutlineIterator.prototype.down()

Move the iterator position "down". The return value is negative if this
movement is not possible, `0` if the new position has a valid item,
or `1` if the new position has no item but one can be inserted here.

- **Returns:** number

```
var result = outlineIterator.down()
```

#### OutlineIterator.prototype.insert(item)

Insert item before the current item. The position does not change. The
return value is `0` if the current position has a valid item, or
`1` if the position has no valid item.

- **OutlineItem item**: the item to insert

- **Returns:** number

```
var result = outlineIterator.insert(item)
```

#### OutlineIterator.prototype.delete()

Delete the current item. This implicitly moves to the next item. The
return value is `0` if the new position has a valid item, or `1` if
the position contains no valid item, but one may be inserted at this
position.

- **Returns:** number

```
outlineIterator.delete()
```

#### OutlineIterator.prototype.update(item)

Updates the current item properties with values from the supplied item's properties.

- **OutlineItem item**: An item populated with the properties that should be stored.

```
outlineIterator.update(item)
```

### Page

A Page object is a page that has been loaded from a `Document`.

Page objects that belong to a `PDFDocument`, also provide
the interface described in `PDFPage`.

#### Constructors

#### Page

*(not constructible with `new`)*

Page instances are returned by `Document.prototype.loadPage()`.

#### Constants

The :term:`page box` types:

#### Page.MEDIA_BOX

#### Page.CROP_BOX

#### Page.BLEED_BOX

#### Page.TRIM_BOX

#### Page.ART_BOX

#### Instance methods

#### Page.prototype.getBounds(box)

Returns a rectangle describing the page dimensions.

- **string box: Which :term**: `page box` to query.

- **Returns:** `Rect`

```
var rect = page.getBounds()
```

#### Page.prototype.run(device, transform)

Calls device functions for all the contents on the page, using the
specified transform.

The device can be one of the built-in devices (`DrawDevice` and `DisplayListDevice`)
or a Javascript `Device`.

The matrix transforms coordinates from user space to device space.

- **Device device**: The device object.
- **Matrix matrix**: The transformation matrix.

```
page.run(dev, mupdf.Matrix.identity)
```

#### Page.prototype.runPageContents(device, transform)

This is the same as the `Page.prototype.run()` method above but it only
runs the page itself and omits annotations and widgets.

- **Device device**: The device object.
- **Matrix matrix**: The transformation matrix.

```
page.runPageContents(dev, mupdf.Matrix.identity)
```

#### Page.prototype.runPageAnnots(device, transform)

This is the same as the `Page.prototype.run()` method above but it only
runs the page annotations.

- **Device device**: The device object.
- **Matrix matrix**: The transformation matrix.

```
page.runPageAnnots(dev, mupdf.Matrix.identity)
```

#### Page.prototype.runPageWidgets(device, transform)

This is the same as the `Page.prototype.run()` method above but it only
runs the page widgets.

- **Device device**: The device object.
- **Matrix matrix**: The transformation matrix.

```
page.runPageWidgets(dev, mupdf.Matrix.identity)
```

#### Page.prototype.toPixmap(matrix, colorspace, alpha, showExtras)

Render the page into a `Pixmap` using the specified transform
matrix and colorspace. If `alpha` is `true`, the page will be drawn
on a transparent background, otherwise white. If `showExtras` is
`true` then the operation will include any page annotations and/or
widgets.

- **Matrix matrix**: The transformation matrix.
- **ColorSpace colorspace**: The desired colorspace of the returned pixmap.
- **boolean alpha**: Whether the resulting pixmap should have an alpha component. Defaults to `true`.
- **boolean showExtras**: Whether to render annotations and widgets. Defaults to `true`.

- **Returns:** `Pixmap`

```
var pixmap = page.toPixmap(mupdf.Matrix.identity, mupdf.ColorSpace.DeviceRGB, true, true)
```

#### Page.prototype.toDisplayList(showExtras)

Record the contents on the page into a `DisplayList`. If
`showExtras` is `true` then the operation will include all
annotations and/or widgets on the page.

- **boolean showExtras**: Whether to render annotations and widgets. Defaults to `true`.

- **Returns:** `DisplayList`

```
var displayList = page.toDisplayList(true)
```

#### Page.prototype.toStructuredText(options)

Extract the text on the page into a `StructuredText` object.

- **string options**: 
See :doc:`/reference/common/stext-options`.

- **Returns:** `StructuredText`

```
var sText = page.toStructuredText("preserve-whitespace")
```

#### Page.prototype.search(needle, maxHits)

Search the page text for all instances of the `needle` value,
and return an array of search hits.

Each search hit is an array of `Quad`, each corresponding
to a character in the search hit.

- **string needle**: The text to search for.
- **number options**: Optional options for the search. A logical or of options such as `StructuredText.SEARCH_EXACT`.

- **Returns:** Array of Array of `Quad`

```
var results = page.search("my search phrase")
```

#### Page.prototype.getLinks()

Return an array of all the links on the page. If there are no
links then an empty array is returned.

Each link is an object with a 'bounds' property, and either a
'page' or 'uri' property, depending on whether it's an internal or
external link.

- **Returns:** Array of `Link`

```
var links = page.getLinks()
var link = links[0]
var linkDestination = doc.resolveLink(link)
```

#### Page.prototype.createLink(rect, uri)

Create a new link with the supplied metrics for the page, linking to the destination URI string.

To create links to other pages within the document see the `Document.prototype.formatLinkURI` method.

- **Rect rect**: Rectangle specifying the active area on the page the link should cover.
- **string destinationUri**: A URI string describing the desired link destination.

- **Returns:** `Link`.

```
// create a link to an external URL
var link = page.createLink([0, 0, 100, 50], "https://example.com")
```

// create a link to another page in the document
var link = page.createLink([0, 100, 100, 150], "#page=1&view=FitV,0")

#### Page.prototype.deleteLink(link)

Delete the link from the page.

- **Link link**: The link to remove.

```
page.deleteLink(link_obj)
```

#### Page.prototype.getLabel()

Returns the page number as a string using the numbering scheme of the document.

- **Returns:** string

```
var label = page.getLabel()
```

#### Page.prototype.isPDF()

Returns `true` if the page is from a PDF document.

- **Returns:** boolean

```
var isPDF = page.isPDF()
```

#### Page.prototype.decodeBarcode(subarea, rotate)

Decodes a barcode detected on the page, and returns an object with
properties for barcode type and contents.

- **Rect subarea**: Only detect barcode within subarea. Defaults to the entire page.
- **number rotate**: Degrees of rotation to rotate page before detecting barcode. Defaults to 0.

- **Returns:** Object with barcode information.

```js
var info = page.decodeBarcode(page.getBounds(), 0)
```

### Path

A path object represents vector graphics, as if drawn by a pen. They can
be used for stroking, filling or as a clip mask. The Path only determines
the shape, not properties such as color, line width or line joins, etc.

A path contains a sequence of zero or more subpaths, each subpath consists
of a sequence of zero or more basic operations which begins by a move to
point and ends with a close:

* move to point, append by calling `Path.prototype.moveTo()`
* close subpath, append by calling `Path.prototype.closePath()`
* draw a straight line, append by calling `Path.prototype.lineTo()`
* draw a cubic Bézier curve, append by calling either of `Path.prototype.curveTo()`,
  `Path.prototype.curveToV()`, or `Path.prototype.curveToY()`
* draw a rectangle, append by calling `Path.prototype.rect()`, this is a subpath on
  its own and is equivalent to a move to a position, followed by drawing three
  lines and closing the subpath.

After a subpath is closed, the only operation that may be appended is a
move to point, in order to start a new subpath. This is a requirement to
ensure that an unclosed path always has a current point from which to
start basic drawing operations.

Once all desired operations have been appended to a Path, its bounds can
be determined, and it can be transformed. Finally, it's possible to
iterate over the basic path operations via `Path.prototype.walk()`.

#### Constructors

#### Path()

Create a new empty path.

```
var path = new mupdf.Path()
```

#### Instance methods

#### Path.prototype.closePath()

Append operation closing the current subpath by drawing a straight
line to the point given in the last `moveTo()`. This also invalidates
the current point, but a new one may be set by calling `moveTo()`.

```
path.closePath()
```

#### Path.prototype.curveTo(x1, y1, x2, y2, x3, y3)

Append operation drawing a cubic Bézier curve from the current point
to (x3, y3) using (x1, y1) and (x2, y2) as control points.

- **number x1**: X1 coordinate.
- **number y1**: Y1 coordinate.
- **number x2**: X2 coordinate.
- **number y2**: Y2 coordinate.
- **number x3**: X3 coordinate.
- **number y3**: Y3 coordinate.

```
path.curveTo(0, 0, 10, 10, 100, 100)
```

#### Path.prototype.curveToV(cx, cy, ex, ey)

Append operation drawing a cubic Bézier curve from the current point
to (ex, ey) using the current point and (cx, cy) as control points.
Will be converted to `Path.prototype.curveTo()` when appended to this Path.

- **number cx**: CX coordinate.
- **number cy**: CY coordinate.
- **number ex**: EX coordinate.
- **number ey**: EY coordinate.

```
path.curveToV(0, 0, 100, 100)
```

#### Path.prototype.curveToY(cx, cy, ex, ey)

Append operation drawing a cubic Bézier curve from the current point
to (ex, ey) using the (cx, cy) and (ex, ey) as control points. Will be
converted to `Path.prototype.curveTo()` when appended to this Path.

- **number cx**: CX coordinate.
- **number cy**: CY coordinate.
- **number ex**: EX coordinate.
- **number ey**: EY coordinate.

```
path.curveToY(0, 0, 100, 100)
```

#### Path.prototype.getBounds(strokeState, transform)

Return a bounding rectangle for the path.

Since the path does not describe properties such as line width, line
joins, etc., the caller must provide a `strokeState`, containing
those properties, to determine the bounds of path if it is stroked.

If no `strokeState` is provided, this call determines the bounds of
the path if it is filled.

`transform` is applied to the points in the path while computing the
bounds, but it is not applied to the points as stored in path, i.e.
the Path is not altered.

- **StrokeState | null stroke**: The stroking properties to use.
- **Matrix transform**: A transform matrix applied to all points in path.

- **Returns:** `Rect`

```
var rect = path.getBounds(strokeState, mupdf.Matrix.identity)
```

#### Path.prototype.lineTo(x, y)

Append operation drawing a straight line from the current point to the
given point.

- **number x**: X coordinate.
- **number y**: Y coordinate.

```
path.lineTo(20, 20)
```

#### Path.prototype.moveTo(x, y)

Append operation of lifting and moving the pen to the given point.
This begins a new subpath and sets the current point.

- **number x**: X coordinate.
- **number y**: Y coordinate.

```
path.moveTo(10, 10)
```

#### Path.prototype.rect(x1, y1, x2, y2)

Shorthand for sequence:

```
moveTo(x1, y1)
lineTo(x2, y1)
lineTo(x2, y2)
lineto(x1, y2)
closePath()
```

- **number x1**: X1 coordinate.
- **number y1**: Y1 coordinate.
- **number x2**: X2 coordinate.
- **number y2**: Y2 coordinate.

```
path.rect(0, 0, 100, 100)
```

#### Path.prototype.transform(matrix)

Transform the path by applying the given transformation matrix.

This is done by transforming each point in all of the paths' basic
drawing operations.

- **Matrix matrix**: Transformation matrix to apply.

```
path.transform(mupdf.Matrix.scale(2, 2))
```

#### Path.prototype.walk(walker)

Iterate over all the basic drawing operations in this Path, calling
a corresponding callback in the walker object passing the coordinates
stored with the drawing operation.

- **PathWalker walker**: Object with callback functions.

```
function print(...args) {
console.log(args.join(" "))
}
```

var pathPrinter = {
moveTo: function (x, y) { print("moveTo", x, y) },
lineTo: function (x, y) { print("lineTo", x, y) },
curveTo: function (x1, y1, x2, y2, x3, y3) { print("curveTo", x1, y1, x2, y2, x3, y3) },
closePath: function () { print("closePath") },
}

var traceDevice = {
fillPath: function (path, evenOdd, ctm, colorSpace, color, alpha) {
print("fillPath", evenOdd, ctm, colorSpace, color, alpha)
path.walk(pathPrinter)
},
clipPath: function (path, evenOdd, ctm) {
print("clipPath", evenOdd, ctm)
path.walk(pathPrinter)
},
strokePath: function (path, stroke, ctm, colorSpace, color, alpha) {
print("strokePath", JSON.stringify(stroke), ctm, colorSpace, color, alpha)
path.walk(pathPrinter)
},
clipStrokePath: function (path, stroke, ctm) {
print("clipStrokePath", JSON.stringify(stroke), ctm)
path.walk(pathPrinter)
}
}

var doc = mupdf.Document.openDocument(fs.readFileSync("test.pdf"), "application/pdf")
var page = doc.loadPage(0)
var device = new mupdf.Device(traceDevice)
page.run(device, mupdf.Matrix.identity)

### PathWalker

#### Constructors

#### PathWalker

*(interface type)*

An object implementing this interface of optional callback functions
can be used to get calls whenever `Path.prototype.walk()` iterates over a
basic drawing operation corresponding to that of the function name.

#### closePath()

Called when `Path.prototype.walk()` encounters a close subpath operation.

#### curveTo(x1, y1, x2, y2, x3, y3)

Called when `Path.prototype.walk()` encounters an operation drawing a Bézier
curve from the current point to (x3, y3) using (x1, y1) and (x2, y2)
as control points.

- **number x1**: X1 coordinate.
- **number y1**: Y1 coordinate.
- **number x2**: X2 coordinate.
- **number y2**: Y2 coordinate.
- **number x3**: X3 coordinate.
- **number y3**: Y3 coordinate.

#### lineTo(x, y)

Called when `Path.prototype.walk()` encounters an operation drawing a straight
line from the current point to the given point.

- **number x**: X coordinate.
- **number y**: Y coordinate.

#### moveTo(x, y)

Called when `Path.prototype.walk()` encounters an operation moving the pen to
the given point, beginning a new subpath and sets the current point.

- **number x**: X coordinate.
- **number y**: Y coordinate.

### Pixmap

A Pixmap object contains a color raster image (short for pixel map).
The components in a pixel in the Pixmap are all byte values,
with the transparency as the last component.

A Pixmap also has a location (x, y) in addition to its size;
so that they can easily be used to represent tiles of a page.

#### Constructors

#### 

Pixmap(colorspace, bbox, alpha)
Pixmap(pixmap, mask)

Create a new empty Pixmap whose pixel data is **not**
initialized. Alternatively create a new Pixmap based on an
existing Pixmap without alpha and combine it with a single
component soft mask of the same dimensions.

- **ColorSpace | null colorspace**: The desired colorspace for the new pixmap. `null` implies a single component alpha pixmap.
- **Rect bbox**: The desired dimensions of the new pixmap.
- **boolean alpha**: Whether the new pixmap should have an alpha component.
- **Pixmap pixmap**: The original pixmap without alpha.
- **Pixmap mask**: Soft mask used as alpha in the combined pixmap.

```
var pixmap1 = new mupdf.Pixmap(mupdf.ColorSpace.DeviceRGB, [0, 0, 100, 100], true)
var pixmap2 = new mupdf.Pixmap(
new mupdf.Image("photo.png").toPixmap(),
new mupdf.Image("softmask.png").toPixmap()
)
```

#### Instance methods

#### Pixmap.prototype.clear(value)

Clear the pixels to the specified value. Pass 255 for white, 0 for black, or omit for transparent.

- **number value**: The value to use for clearing.

```
pixmap.clear(255)
```

#### Pixmap.prototype.getBounds()

Return the pixmap bounds.

- **Returns:** `Rect`

```
var rect = pixmap.getBounds()
```

#### Pixmap.prototype.getWidth()

Get the width of the pixmap.

- **Returns:** number

```
var w = pixmap.getWidth()
```

#### Pixmap.prototype.getHeight()

Get the height of the pixmap.

- **Returns:** number

```
var h = pixmap.getHeight()
```

#### Pixmap.prototype.getNumberOfComponents()

Number of colors; plus one if an alpha channel is present.

- **Returns:** number

```
var num = pixmap.getNumberOfComponents()
```

#### Pixmap.prototype.getAlpha()

Returns whether an alpha channel is present.

- **Returns:** boolean

```
var alpha = pixmap.getAlpha()
```

#### Pixmap.prototype.getStride()

Number of bytes per row.

- **Returns:** number

```
var stride = pixmap.getStride()
```

#### Pixmap.prototype.getColorSpace()

Returns the colorspace of this pixmap. Returns null if the pixmap has
no colors (for example if it is an opacity mask with only an alpha
channel).

- **Returns:** `ColorSpace` | null

```
var cs = pixmap.getColorSpace()
```

#### Pixmap.prototype.setResolution(x, y)

Set horizontal and vertical resolution.

- **number x**: Horizontal resolution in dots per inch.
- **number y**: Vertical resolution in dots per inch.

```
pixmap.setResolution(300, 300)
```

#### Pixmap.prototype.getX()

Returns the x coordinate of the pixmap.

```js
var x = pixmap.getX()
```

#### Pixmap.prototype.getY()

Returns the y coordinate of the pixmap.

- **Returns:** number

```js
var y = pixmap.getY()
```

#### Pixmap.prototype.getXResolution()

Returns the horizontal resolution in dots per inch for this pixmap.

- **Returns:** number

```
var xRes = pixmap.getXResolution()
```

#### Pixmap.prototype.getYResolution()

Returns the vertical resolution in dots per inch for this pixmap.

- **Returns:** number

```
var yRes = pixmap.getYResolution()
```

#### Pixmap.prototype.invert()

Invert all pixels. All components are processed, except alpha which is unchanged.

```
pixmap.invert()
```

#### Pixmap.prototype.invertLuminance()

Transform all pixels so that luminance of each pixel is inverted,
and the chrominance remains as unchanged as possible.
All components are processed, except alpha which is unchanged.

```
pixmap.invertLuminance()
```

#### Pixmap.prototype.gamma(p)

Apply gamma correction to this pixmap. All components are processed,
except alpha which is unchanged.

Values `>= 0.1 & < 1` darkens the pixmap, `> 1 & < 10` lightens the pixmap.

- **number p**: Desired gamma level.

```
pixmap.gamma(3.5)
```

#### Pixmap.prototype.tint(black, white)

Tint all pixels in RGB, BGR or Gray pixmaps.
Map black and white respectively to the given hex RGB values.

- **Color | number black**: Map black to this color.
- **Color | number white**: Map white to this color.

```
pixmap.tint(0xffff00, 0xffff00)
```

#### Pixmap.prototype.warp(points, width, height)

Return a warped subsection of this pixmap, where the corner of
the input quadrilateral will be "warped" to become the four corner
points of the returned pixmap defined by the requested dimensions.

- **Quad points**: The corners of a convex quadrilateral within the `Pixmap` to be warped.
- **number width**: Width of resulting pixmap.
- **number height**: Height of resulting pixmap.

- **Returns:** `Pixmap`

```
var warpedPixmap = pixmap.warp([[0, 0], [100, 100], [130, 170], [150, 200]], 200, 200)
```

#### Pixmap.prototype.autowarp(points)

Same as `Pixmap.prototype.warp()` except that width and height
are automatically determined.

- **Quad points**: The corners of a convex quadrilateral within the `Pixmap` to be warped.

- **Returns:** `Pixmap`

```js
var warpedPixmap = pixmap.autowarp([0,0,100,0,0,100,100,100])
```

#### Pixmap.prototype.convertToColorSpace(colorspace, proof, defaultColorSpaces, colorParams, keepAlpha)

Convert pixmap into a new pixmap of a desired colorspace.
A proofing colorspace, a set of default colorspaces and color
parameters used during conversion may be specified.
Finally a boolean indicates if alpha should be preserved
(default is to not preserve alpha).

- **ColorSpace colorspace**: The desired colorspace.
- **ColorSpace proof**: Optional proofing colorspace; pass `null` to skip.
- **DefaultColorSpaces defaultColorSpaces**: Optional; pass `null` to skip.
- **Object colorParams**: Optional color parameters; pass `null` to skip.
- **boolean keepAlpha**: Whether to keep the alpha component.

Note: `keepAlpha` is the fifth argument: `pix.convertToColorSpace(ColorSpace.DeviceGray, null, null, null, true)`. A pixmap with alpha can't be converted with `keepAlpha` false ("cannot drop alpha when converting pixmap").

- **Returns:** `Pixmap`

#### Pixmap.prototype.getPixels()

Returns an array of pixels for this pixmap.

- **Returns:** Array of number

```
var pixels = pixmap.getPixels()
```

#### Pixmap.prototype.asPNG()

Returns a buffer of this pixmap as a PNG.

- **Returns:** `Buffer`

```
var buffer = pixmap.asPNG()
```

#### Pixmap.prototype.asPSD()

Returns a buffer of this pixmap as a PSD.

- **Returns:** `Buffer`

```
var buffer = pixmap.asPSD()
```

#### Pixmap.prototype.asPAM()

Returns a buffer of this pixmap as a PAM.

- **Returns:** `Buffer`

```
var buffer = pixmap.asPAM()
```

#### Pixmap.prototype.asJPEG(quality, invert_cmyk)

Returns a buffer of this pixmap as a JPEG.
Note, if this pixmap has an alpha channel then an exception will be thrown.

- **number quality**: Desired compression quality, between `0` and `100`.
- **boolean invert_cmyk: How to handle polarity in :term**: `CMYK JPEG` images.

- **Returns:** `Buffer`

```
var buffer = pixmap.asJPEG(80, false)
```

#### Pixmap.prototype.decodeBarcode(rotate)

Decodes a barcode detected in the pixmap, and returns an object with
properties for barcode type and contents.

- **number rotate**: Degrees of rotation to rotate pixmap before detecting barcode. Defaults to 0.

- **Returns:** Object with barcode information.

```js
var barcodeInfo = displayList.decodeBarcode([0, 0, 100, 100 ], 0)
```

#### Pixmap.prototype.encodeBarcode(barcodeType, contents, size, errorCorrectionLevel, quietZones, humanReadableText)

Encodes a barcode into a pixmap. The supported types of barcode is either one of:

| Matrix | Linear Product | Linear Industrial |  |  |  |
| --- | --- | --- | --- | --- | --- |
| String | Name | String | Name | String | Name |
| `qrcode` | QR Code | `upca` | UPC-A | `code39` | Code 39 |
| `microqrcode` | Micro QR Code | `upce` | UPC-E | `code93` | Code 93 |
| `rmqrcode` | rMQR Code | `ean8` | EAN-8 | `code128` | Code 128 |
| `aztec` | Aztec | `ean13` | EAN-13 | `codabar` | Codabar |
| `datamatrix` | DataMatrix | `databar` | DataBar | `databarexpanded` | DataBar Expanded |
| `pdf417` | PDF417 | `databarlimited` | DataBar Limited | `dxfilmedge` | DX Film Edge |
| `maxicode` | MaxiCode | \ | `itf` | ITF |  |

- **string barcodeType**: The desired barcode type.
- **string contents**: The textual content to encode into the barcode.
- **number size**: The size of the barcode in pixels.
- **number errorCorrectionLevel**: The error correction level (0-8).
- **boolean quietZones**: Whether to add an empty margin around the barcode.
- **boolean humanReadableText**: Whether to add human-readable text. Some barcodes, e.g. EAN-13, can have the barcode contents printed in human-readable text next to the barcode.

- **Returns:** `Pixmap`

```js
var pix = Pixmap.encodeBarcode("qrcode", "Hello world!", 100, 2, true, false)
```

#### Pixmap.prototype.getSample(x, y, index)

Get the value of component `index` at position x, y (relative to
the image origin: 0, 0 is the top left pixel).

- **number x**: X coordinate.
- **number y**: Y coordinate.
- **number index**: Component index. i.e. For CMYK ColorSpaces 0 = Cyan, 3 = Black, for RGB 0 = Red, 2 == Blue etc.

- **Throws:** RangeError if x, y, or index are out of range.

- **Returns:** number

```js
// Get green component of pixel at 10, 10
var sample = rgbpixmap.getSample(10, 10, 1)
```

#### Pixmap.prototype.saveAsPNG(filename)

Save this Pixmap as a PNG. Only works for gray and RGB images.

- **string filename**: Desired name of image file.

```js
pixmap.saveAsPNG("filename.png")
```

#### Pixmap.prototype.saveAsJPEG(filename, quality)

Save this Pixmap as a JPEG file. Only works for gray, RGB and CMYK images.

- **string filename**: Desired name of image file.
- **number quality**: Desired quality between 0 and 100. Defaults to 90.

```js
pixmap.saveAsJPEG("filename.jpg", 80)
```

#### Pixmap.prototype.saveAsPAM(filename)

Save this Pixmap as a PAM file.

- **string filename**: Desired name of image file.

```js
pixmap.saveAsPAM("filename.pam")
```

#### Pixmap.prototype.saveAsPNM(filename)

Save this Pixmap as a PNM file. Only works for gray and RGB images without alpha.

- **string filename**: Desired name of image file.

```js
pixmap.saveAsPNM("filename.pnm")
```

#### Pixmap.prototype.saveAsPBM(filename)

Save this Pixmap as a PBM file. Only works for alpha only, gray and CMYK images without alpha.

- **string filename**: Desired name of image file.

```js
pixmap.saveAsPBM("filename.pbm")
```

#### Pixmap.prototype.saveAsPKM(filename)

Save this Pixmap as a PKM file. Only works for alpha only, gray and CMYK images without alpha.

- **string filename**: Desired name of image file.

```js
pixmap.saveAsPKM("filename.pkm")
```

#### Pixmap.prototype.saveAsJPX(filename, quality)

Save this Pixmap as a JPX file.

- **string filename**: Desired name of image file.
- **number quality**: Desired quality between 0 and 100. Defaults to 90.

```js
pixmap.saveAsJPX("filename.jpx", 90)
```

#### Pixmap.prototype.detectDocument(points)

Detect a "document" in a `Pixmap`. Only a grayscale `Pixmap`
without alpha is supported, anything else will cause an exception
to be thrown.

Returns null if no document was detected.

- **Returns:** `Quad` | null

```js
var documentLocation = pixmap.detectDocument([0,0,100,0,100,100,0,100])
```

#### Pixmap.prototype.detectSkew()

Returns the angle of skew detected from `Pixmap`.
Note, if the `Pixmap` is not Greyscale with no alpha then an exception will be thrown.

- **Returns:** number

```js
var angle = pixmap.detectSkew()
```

#### Pixmap.prototype.deskew(angle, border)

Returns a new `Pixmap` being the deskewed version of the supplied `Pixmap`.
Note, if a `Pixmap` is supplied that is not RGB or Greyscale, or has alpha then an exception will be thrown.

- **number angle**: The angle to deskew.
- **string border**: "increase" increases the size of the pixmap so no pixels are lost. "maintain" maintains the size of the pixmap. "decrease" decreases the size of the page so no new pixels are shown.
- **Returns:** `Pixmap`

```js
var deskewed = pixmap.deskew(angle, 0)
```

#### Pixmap.prototype.computeMD5()

Returns the MD5 digest of the pixmap pixel data.
The digest is returned as a string of 16 hex digits.

- **Returns:** string

```js
var md5 = pixmap.computeMD5()
```

### Point

A Point describes a point in space. It is represented by an array with two coordinates.

#### Constructors

#### Point

*(interface type)*

Points are not represented by a class; they are just plain arrays of two numbers.

#### Static methods

#### Point.transform(point, matrix)

Transforms the supplied point by the given transformation matrix.

- **Point point**: Point to transform.
- **Matrix matrix**: Matrix describing transformation to perform.

- **Returns:** `Point`

```
var m = mupdf.Point.transform([100, 100], [1, 0.5, 1, 1, 1, 1])
```

### Quad

An object representing a quadrilateral or :term:`QuadPoint`.

In TypeScript the Quad type is defined as follows:

```
	type Quad = [ number, number, number, number number, number, number, number ]
```

#### Constructors

#### Quad

*(interface type)*

Quads are not represented by a class; they are just plain arrays of eight numbers.

#### Static properties

#### Quad.empty

A quad whose coordinates are such that it is categorized as empty.

#### Quad.invalid

A quad whose coordinates are such that it is categorized as invalid.

#### Quad.infinite

A quad whose coordinates are such that it is categorized as infinite.

#### Static methods

#### Quad.isEmpty(quad)

Returns a boolean indicating if the quad is empty or not.

- **Quad quad**: Rectangle to evaluate.

- **Returns:** boolean

```
var isEmpty = mupdf.Quad.isEmpty([0, 0, 0, 0]) // true
var isEmpty = mupdf.Quad.isEmpty([0, 0, 100, 100]) // false
```

#### Quad.isValid(quad)

Returns a boolean indicating if the quad is valid or not.

- **Quad quad**: Rectangle to evaluate.

- **Returns:** boolean

```
var isValid = mupdf.Quad.isValid([0, 0, 100, 100]) // true
var isValid = mupdf.Quad.isValid([0, 0, -100, 100]) // false
```

#### Quad.isInfinite(quad)

Returns a boolean indicating if the quad is infinite or not.

- **Quad quad**: Rectangle to evaluate.

- **Returns:** boolean

```
var isInfinite = mupdf.Quad.isInfinite([0x80000000, 0x80000000, 0x7fffff80, 0x7fffff80]) //true
var isInfinite = mupdf.Quad.isInfinite([0, 0, 100, 100]) // false
```

#### Quad.transform(quad, matrix)

Transforms the supplied quad by the given transformation matrix.

Transforming an invalid, empty or infinite quad results in the
supplied quad being returned without change.

- **Quad quad**: Quad to transform.
- **Matrix matrix**: Matrix describing transformation to perform.

- **Returns:** `Quad`

```
var m = mupdf.Quad.transform([0, 0, 100, 100], [1, 0.5, 1, 1, 1, 1])
```

#### Quad.isPointInside(quad, point)

Return whether the point is inside the quad.

:returns boolean

```
var inside = mupdf.Rect.isPointInside([0, 0, 100, 100], [50, 50])
```

#### Quad.quadFromRect(rect)

Create a Quad that maps exactly to the coordinate of rectangle.

- **Rect rect**: 

- **Returns:** `Quad`

### Rect

A Rect describes an axis-aligned rectangle by specifying the coordinates
of its upper left and lower right corners. In Javascript they are
represented by a 4-element array: `[minX, minY, maxX, maxY]`

The relationship between the `minX`, `minY`, `maxX` and `maxY`
values can be set so that a rectangle is categorized as invalid, empty or
infinite. This matters when passing such rectangles to
`Rect.transform()`. There are convenience functions to obtain such
rectangles: `Rect.empty`, `Rect.invalid` and
`Rect.infinite`.

In TypeScript the Rect type is defined as follows:

```
	type Rect = [number, number, number, number]
```

#### Constructors

#### Rect

*(interface type)*

Rects are not represented by a class; they are just plain arrays of four numbers.

#### Static properties

#### Rect.empty

A rectangle whose coordinates are such that it is categorized as empty.

#### Rect.invalid

A rectangle whose coordinates are such that it is categorized as invalid.

#### Rect.infinite

A rectangle whose coordinates are such that it is categorized as infinite.

#### Static methods

#### Rect.isEmpty(rect)

Returns whether the rectangle is empty or not.

- **Rect rect**: Rectangle to evaluate.

- **Returns:** boolean

```
var isEmpty = mupdf.Rect.isEmpty([0, 0, 0, 0]) // true
var isEmpty = mupdf.Rect.isEmpty([0, 0, 100, 100]) // false
```

#### Rect.isValid(rect)

Returns whether the rectangle is valid or not.

- **Rect rect**: Rectangle to evaluate.

- **Returns:** boolean

```
var isValid = mupdf.Rect.isValid([0, 0, 100, 100]) // true
var isValid = mupdf.Rect.isValid([0, 0, -100, 100]) // false
```

#### Rect.isInfinite(rect)

Returns whether the rectangle is infinite or not.

- **Rect rect**: Rectangle to evaluate.

- **Returns:** boolean

```
var isInfinite = mupdf.Rect.isInfinite([0x80000000, 0x80000000, 0x7fffff80, 0x7fffff80]) //true
var isInfinite = mupdf.Rect.isInfinite([0, 0, 100, 100]) // false
```

#### Rect.transform(rect, matrix)

Transforms the supplied rectangle by the given transformation matrix.

Transforming an invalid, empty or infinite rectangle results in the
supplied rectangle being returned without change.

- **Rect rect**: Rectangle to transform.
- **Matrix matrix**: Matrix describing transformation to perform.

- **Returns:** `Rect`

```
var m = mupdf.Rect.transform([0, 0, 100, 100], [1, 0.5, 1, 1, 1, 1])
```

#### Rect.isPointInside(rect, point)

Return whether the point is inside the rectangle.

:returns boolean

```
var inside = mupdf.Rect.isPointInside([0, 0, 100, 100], [50, 50])
```

#### Rect.rectFromQuad(quad)

Create a Rect that encompasses the entire quad.

- **Quad quad**: 

- **Returns:** `Rect`

### Shade

A Shade object is used to define shadings.

#### Shade

*(not constructible with `new`)*

#### Instance methods

#### Shade.prototype.getBounds()

Returns a rectangle containing the dimensions of the shading
contents.

- **Returns:** `Rect`

```
var bounds = shade.getBounds()
```

### Story

#### Constructors

#### Story(contents, userCSS, em, archive)

Create a new story with the given contents, formatted according to the
provided user-defined CSS and em size, and an archive to lookup images,
etc.

- **string contents**: HTML source code. If omitted, a basic minimum is generated.
- **string userCSS**: CSS source code. Defaults to the empty string.
- **number em**: The default text font size. Default to 12.
- **Archive archive**: An archive from which to load resources for rendering. Currently supported resource types are images and text fonts. If omitted, the Story will not try to look up any such data and may thus produce incomplete output. Defaults to null.

```
var story = new mupdf.Story(<contents>, <css>, <em>, <archive>)
```

#### Instance methods

#### Story.prototype.document()

Return an `DOM` for an unplaced story. This allows adding content before placing the `Story`.

- **Returns:** `DOM`

```
var xml = story.document()
```

#### Story.prototype.place(rect, flags)

Place (or continue placing) this Story into the supplied rectangle.
Call `draw()` to draw the placed content before calling `place()` again
to continue placing remaining content.

`more` in the returned object can take either of these values:

* 0 means that all the text was placed successfully.

* 1 means that some text was not placed due not fitting within the height of the rectangle.

* 2 means that some text was not placed due not fitting within the width of the rectangle. For this to be detected `flags` must be set to 1.

- **Rect rect**: Rectangle to place the story within.
- **number flags**: When set to 1, will detect when a word does not fit in the rectangle, instead `more` set to 2.

- **Returns:** `{ filled: Rect, more: number }`

```
do {
var result = story.place([0, 0, 100, 100])
// TODO: create device for this bit of story
story.draw(device, mupdf.Matrix.identity)
// TODO: close device
} while (result.more)
```

#### Story.prototype.draw(device, transform)

Draw the placed Story to the given `Device` with the given transform.

- **Device device**: The device
- **Matrix transform**: The transform matrix.

```
story.draw(device, mupdf.Matrix.identity)
```

### StrokeState

A StrokeState controls the properties of how stroking operations are performed.
Besides controlling the line width, it is also possible to control
:term:`line cap style`, :term:`line join style`, and the :term:`miter limit`.

#### Constructors

#### StrokeState(template)

Create a new empty stroke state object.

The Javascript object used as template allows for setting
the following attributes:

* "lineCap": string: The :term:`line cap style` to be used. One of `"Butt" | "Round" | "Square"`
* "lineJoin": string: The :term:`line join style` to be used. One of `"Miter" | "Round" | "Bevel"`
* "lineWidth": number: The line width to be used.
* "miterLimit": number: The :term:`miter limit` to be used.
* "dashPhase": number: The dash phase to be used.
* "dashPattern": Array of number: The sequence of dash lengths to be used.

- **Object template**: An object with the parameters to set.

```
var strokeState = new mupdf.StrokeState({
lineCap: "Square",
lineJoin: "Bevel",
lineWidth: 2.0,
miterLimit: 1.414,
dashPhase: 11,
dashPattern: [ 2, 3 ]
})
```

#### Instance methods

#### StrokeState.prototype.getLineCap()

Get the :term:`line cap style`.

- **Returns:** `"Butt" | "Round" | "Square"`

```
var lineCap = strokeState.getLineCap()
```

#### StrokeState.prototype.getLineJoin()

Get the :term:`line join style`.

- **Returns:** `"Miter" | "Round" | "Bevel"`

```
var lineJoin = strokeState.getLineJoin()
```

#### StrokeState.prototype.getLineWidth()

Get the line line width.

- **Returns:** number

```
var width = strokeState.getLineWidth()
```

#### StrokeState.prototype.getMiterLimit()

Get the :term:`miter limit`.

- **Returns:** number

```
var limit = strokeState.getMiterLimit()
```

#### StrokeState.prototype.getDashPhase()

Get the dash pattern phase (where in the dash pattern stroking starts).

- **Returns:** number

```js
var limit = strokeState.getDashPhase()
```

#### StrokeState.prototype.getDashPattern()

Get the dash pattern as an array of numbers specifying alternating
lengths of dashes and gaps, or null if none set.

- **Returns:** Array of number | null

```js
var dashPattern = strokeState.getDashPattern()
```

### StructuredText

StructuredText objects hold text from a page that has been analyzed and grouped
into blocks, lines and spans.

#### Constructors

#### StructuredText

*(not constructible with `new`)*

To obtain a StructuredText instance use `Page.prototype.toStructuredText()`.

#### Static properties

#### StructuredText.SEARCH_EXACT

used to search untransformed text

#### StructuredText.SEARCH_IGNORE_CASE

used to search text ignoring case differences

#### StructuredText.SEARCH_IGNORE_DIACRITICS

used to search text ignoring diacritics

#### StructuredText.SEARCH_REGEXP

used to search text with the needle being a regexp

#### StructuredText.SEARCH_KEEP_LINES

used to search text preserving line breaks.

#### StructuredText.SEARCH_KEEP_PARAGRAPHS

used to search text preserving paragraph breaks.

#### StructuredText.SEARCH_KEEP_HYPHENS

used to search text preserving hyphens and not joining lines.

#### Instance methods

#### StructuredText.prototype.search(needle, maxHits)

Search the text for all instances of needle, and return an array with all matches found on the page.

Each match in the result is an array containing one or more Quads that cover the matching text.

- **string needle**: The text to search for.
- **number options**: Optional options for the search. A logical or of options such as `StructuredText.SEARCH_EXACT`.

- **Returns:** Array of Array of `Quad`

```
var result = sText.search("Hello World!")
```

#### StructuredText.prototype.highlight(p, q, maxHits)

Return an array of `Quad` used to highlight a selection defined by the start and end points.

- **Point p**: Start point.
- **Point q**: End point.
- **number maxHits**: The maximum number of hits to return. Default 500.

- **Returns:** Array of `Quad`

```
var result = sText.highlight([100, 100], [200, 100])
```

#### StructuredText.prototype.copy(p, q)

Return the text from the selection defined by the start and end points.

- **Point p**: Start point.
- **Point q**: End point.

- **Returns:** string

```
var result = sText.copy([100, 100], [200, 100])
```

#### StructuredText.prototype.walk(walker)

- **StructuredTextWalker walker**: Callback object.

Walk through the blocks (images or text blocks) of the structured text.
For each text block walk over its lines of text, and for each line each
of its characters. For each block, line or character the walker will
have a method called.

```
var sText = page.toStructuredText()
sText.walk({
beginLine: function (bbox, wmode, direction) {
console.log("beginLine", bbox, wmode, direction)
},
endLine: function () {
console.log("endLine")
},
beginTextBlock: function (bbox) {
console.log("beginTextBlock", bbox)
},
endTextBlock: function () {
console.log("endTextBlock")
},
beginStruct: function (standard, raw, index) {
console.log("beginStruct", standard, raw, index)
},
endStruct: function () {
console.log("endStruct")
},
onChar: function (utf, origin, font, size, quad, argb, flags) {
console.log("onChar", utf, origin, font, size, quad, argb, flags)
},
onImageBlock: function (bbox, transform, image) {
console.log("onImageBlock", bbox, transform, image)
},
onVector: function (bbox, flags, argb) {
console.log("onVector", bbox, flags, argb)
},
})
```

#### StructuredText.prototype.asText()

Returns a plain text representation.

- **Returns:** string

#### StructuredText.prototype.asHTML(id)

Returns a string containing an HTML rendering of the text.

- **number id**: 
Used to number the "id" on the top div tag (as `"page" + id`).

- **Returns:** string

#### StructuredText.prototype.asJSON(scale)

Returns a JSON string representing the structured text data.

This is a simplified serialization of the information that
`StructuredText.prototype.walk()` provides.

Note: You must extract the structured text with "preserve-spans"!
If you forget to set this option, any font changes in the middle of the
line will not be present in the JSON output.

- **number scale**: Scaling factor to multiply all the coordinates by. Pass `1` for coordinates in points: without it, every coordinate and font size comes out as `-2147483648`.

- **Returns:** string containing JSON of the following schema:

```typescript
type StructuredTextPage = {
blocks: StructuredTextBlock[]
}
type StructuredTextBlock = {
type: "image" | "text",
bbox: {
x: number,
y: number,
w: number,
h: number
},
lines: StructuredTextLine[],
}
type StructuredTextLine = {
wmode: 0 | 1,	// 0=horizontal, 1=vertical
bbox: {
x: number,
y: number,
w: number,
h: number
},
font: {
name: string,
family: "serif" | "sans-serif" | "monospace",
weight: "normal" | "bold",
style: "normal" | "italic",
size: number
},
// text origin point for first character in line
x: number,
y: number,
text: string
}
```

```
var data = JSON.parse(page.toStructuredText("preserve-spans").asJSON(1))
```

### StructuredTextWalker

A structured text walker is an object with (optional) callback methods
used to iterate over the contents of a `StructuredText`.

#### Constructors

#### StructuredTextWalker

*(interface type)*

On beginLine the direction parameter is a vector (e.g. [0, 1]) and
can you can calculate the rotation as an angle with some trigonometry on the vector.

#### beginTextBlock(bbox)

Called before every text block in the `StructuredText`.

- **Rect bbox**: 

#### endTextBlock()

Called after every text block.

#### beginLine(bbox, wmode, direction)

Called before every line of text in a block.

- **Rect bbox**: 
- **number wmode**: 
- **Point direction**: 

#### endLine()

Called after every line of text.

#### beginStruct(standard, raw, index)

Called to indicate that a new structure element begins. May not
be neatly nested within blocks or lines.

- **string standard**: 
- **string raw**: 
- **number index**: 

#### endStruct()

Called after every structure element.

#### onChar(c, origin, font, size, quad, color, flags)

Called for every character in a line of text.

- **string c**: 
- **Point origin**: 
- **Font font**: 
- **number size**: 
- **Quad quad**: 
- **Color color**: 
- **number flags**: 

#### onImageBlock(bbox, transform, image)

Called for every image in a `StructuredText` if its options were
set to preserve images.

- **Rect bbox**: 
- **Matrix transform**: 
- **Image image**: 

#### onVector(bbox, flags, rgb)

Called for every vector in a `StructuredText` if its options
were set to collect vectors.

- **Rect bbox**: 
- **Object flags**: 
- **Array of number rgb**: 

The flags object is of the form `{ isStroked: boolean, isRectangle: boolean }`.

### Text

A Text object contains text. See the `Device.prototype.fillText`.

#### Constructors

#### Text()

Create a new empty text object.

```
var text = new mupdf.Text()
```

#### Instance methods

#### Text.prototype.getBounds(strokeState, transform)

Get the bounds of the instance.

- **StrokeState strokeState**: The stroking state.
- **Matrix transform**: The transformation matrix.

#### Text.prototype.showGlyph(font, trm, gid, uni, wmode)

Add a glyph to the text object.

Transform is the text matrix, specifying font size and glyph location.
For example: `[size, 0, 0, -size, x, y]`.

Glyph and unicode may be `-1` for n-to-m cluster mappings. For
example, the "fi" ligature would be added in two steps: first the glyph
for the 'fi' ligature and the unicode value for 'f'; then glyph `-1`
and the unicode value for 'i'.

- **Font font**: Font object.
- **Matrix trm**: Transformation matrix.
- **number gid**: Glyph id.
- **number uni**: Unicode codepoint.
- **number wmode**: `0` (default) for horizontal writing, and `1` for vertical writing.

```
text.showGlyph(new mupdf.Font("Times-Roman"), mupdf.Matrix.identity, 21, 0x66, 0)
text.showGlyph(new mupdf.Font("Times-Roman"), mupdf.Matrix.identity, -1, 0x69, 0)
```

#### Text.prototype.showString(font, trm, str, wmode)

Add a simple string to this Text object. Will do font substitution if the font does not have all the unicode characters required.

- **Font font**: Font object.
- **Matrix trm**: Transformation matrix.
- **string str**: Content for Text object.
- **number wmode**: `0` (default) for horizontal writing, and `1` for vertical writing.

```
text.showString(new mupdf.Font("Times-Roman"), mupdf.Matrix.identity, "Hello World")
```

#### Text.prototype.walk(walker)

- **TextWalker walker**: Function with protocol methods, see example below for details.

```
function print(...args) {
console.log(args.join(" "))
}
```

var textPrinter = {
beginSpan: function (f, m, wmode, bidi, dir, lang) {
print("beginSpan", f, m, wmode, bidi, dir, Q(lang))
},
showGlyph: function (f, m, g, u, v, b) { print("glyph", f, m, g, String.fromCodePoint(u), v, b) },
endSpan: function () { print("endSpan") }
}

var traceDevice = {
fillText: function (text, ctm, colorSpace, color, alpha) {
print("fillText", ctm, colorSpace, color, alpha)
text.walk(textPrinter)
},
clipText: function (text, ctm) {
print("clipText", ctm)
text.walk(textPrinter)
},
strokeText: function (text, stroke, ctm, colorSpace, color, alpha) {
print("strokeText", Q(stroke), ctm, colorSpace, color, alpha)
text.walk(textPrinter)
},
clipStrokeText: function (text, stroke, ctm) {
print("clipStrokeText", Q(stroke), ctm)
text.walk(textPrinter)
},
ignoreText: function (text, ctm) {
print("ignoreText", ctm)
text.walk(textPrinter)
}
}

var doc = mupdf.PDFDocument.openDocument(fs.readFileSync("test.pdf"), "application/pdf")
var page = doc.loadPage(0)
var device = new mupdf.Device(traceDevice)
page.run(device, mupdf.Matrix.identity)

### TextWalker

#### TextWalker

An object implementing this interface of optional callback functions
can be used to get calls whenever `Text.prototype.walk()` iterates over a text object.

#### beginSpan(font, trm, wmode, bidiLevel, markupDirection, language)

Called before every text span in the `Text` being walked.

- **Font font**: 
- **Matrix trm**: 
- **number wmode**: 
- **int bidiLevel**: 
- **int markupDirection**: 
- **string language**: 

#### endSpan()

Called at the end of every span in the text.

#### showGlyph(font, trm, gid, ucs, wmode, bidiLevel)

Called once per character for in a text span.

- **Font font**: 
- **Matrix trm**: 
- **number gid**: 
- **number ucs**: 
- **number wmode**: 
- **number bidiLevel**: 

### TreeArchive

#### Constructors

#### TreeArchive()

Create a new empty tree archive.

```
var treeArchive = new mupdf.TreeArchive()
```

#### Instance methods

#### TreeArchive.prototype.add(name, buffer)

Add a named buffer to a tree archive.

- **string name**: Name of archive entry to add.
- **Buffer | ArrayBuffer | Uint8Array | string buffer**: Buffer of data to store with the entry.

```
var buf = new mupdf.Buffer()
buf.writeLine("hello world!")
var archive = new mupdf.TreeArchive()
archive.add("file2.txt", buf)
print(archive.hasEntry("file2.txt"))
```

### PDF

### PDFAnnotation

PDF Annotations belong to a specific `PDFPage` and may be
created/changed/removed. Because annotation appearances may change (for several
reasons) it is possible to scan through the annotations on a page and query
them to see whether a re-render is necessary.

Additionally redaction annotations can be applied to a `PDFPage`,
destructively removing content from the page.

### Annotation Types

These are the annotation types, and which attributes they have.

Text
	An icon with a popup of text.

	Set the appearance with the Icon attribute.

	Attributes: `Rect`, `color-attribute`, `icon-attribute`.

FreeText
	Text in a rectangle on the page.

	The text font and color is defined by DefaultAppearance.

	Attributes: `border-attribute`, `rect-attribute`, `default-appearance-attribute`.

Line
	A line with optional arrow heads.

	The line width is determined by the border attribute.

	The end points are defined by the Line attribute.

	Attributes: `border-attribute`, `color-attribute`, `line-attribute`, `line-ending-styles-attribute`.

Square
	A rectangle.

	Attributes: `rect-attribute`, `rect-attribute`, `color-attribute`, `interior-color-attribute`.

Circle
	An ellipse.

	Attributes: `rect-attribute`, `border-attribute`, `color-attribute`, `interior-color-attribute`.

Polygon, PolyLine
	A polygon shape (closed and open).

	The shape is defined by the Vertices attribute.

	The line width is defined by the Border attribute.

	Attributes: `vertices-attribute`, `border-attribute`, `color-attribute`, `interior-color-attribute`, LineEndingStyles.

Highlight, Underline, Squiggly, StrikeOut
	Text markups.

	The shape is defined by the `quadpoints-attribute`.

Stamp
	A rubber stamp.

	The appearance is either a stock name, or a `custom image <stamp-image-attribute>`.

Ink
	A free-hand line.

	The shape is defined by the `inklist-attribute` attribute.

FileAttachment
	A file attachment.

	The appearance is an icon on the page.

	Set the attached file contents with the `filespec-attribute` attribute,
	and the appearance with the `icon-attribute` attribute.

Redaction
	A black box.

	Redaction annotations are used to mark areas of the page that
	can be redacted. They do NOT redact any content by themselves,
	you MUST apply them using `PDFAnnotation.prototype.applyRedaction` or
	`PDFPage.prototype.applyRedactions`.

These annotation types are special and handled with other APIs:

- `Link`
- Popup -- see `PDFAnnotation.prototype.setPopup()`
- Widget -- see `PDFWidget`

### Constructors

#### PDFAnnotation

*(not constructible with `new`)*

To get the annotations on a page use `PDFPage.prototype.getAnnotations()`.

To create a new annotation call `PDFPage.prototype.createAnnotation()`.

### Instance methods

#### PDFAnnotation.prototype.getBounds()

Returns a rectangle containing the location and dimension of the annotation.

- **Returns:** `Rect`

```
var bounds = annotation.getBounds()
```

#### PDFAnnotation.prototype.run(device, matrix)

Calls the device functions to draw the annotation.

- **Device device**: The device to make device calls to while rendering the annotation.
- **Matrix matrix**: The transformation matrix.

```
annotation.run(device, mupdf.Matrix.identity)
```

#### PDFAnnotation.prototype.toPixmap(matrix, colorspace, alpha)

Render the annotation into a `Pixmap`, using the
`transform`, `colorspace` and `alpha` parameters.

- **Matrix matrix**: Transformation matrix.
- **ColorSpace colorspace**: The desired colorspace of the returned pixmap.
- **boolean alpha**: Whether the returned pixmap has transparency or not. If the pixmap handles transparency, it starts out transparent (otherwise it is filled white), before the contents of the display list are rendered onto the pixmap.

- **Returns:** `Pixmap`

```
var pixmap = annotation.toPixmap(mupdf.Matrix.identity, mupdf.ColorSpace.DeviceRGB, true)
```

#### PDFAnnotation.prototype.toDisplayList()

Record the contents of the annotation into a `DisplayList`.

- **Returns:** `DisplayList`

```
var displayList = annotation.toDisplayList()
```

#### PDFAnnotation.prototype.getObject()

Get the underlying `PDFObject` for an annotation.

- **Returns:** `PDFObject`

```
var obj = annotation.getObject()
```

#### PDFAnnotation.prototype.setAppearance(appearance, state, transform, bbox, resources, contents)

Set the annotation appearance stream for the given appearance. The
desired appearance is given as a transform along with a bounding box, a
PDF dictionary of resources and a content stream.

- **string | null appearance**: Appearance stream ("N" for normal, "R" for roll-over or "D" for down). Defaults to "N".
- **string | null state**: The annotation state to set the appearance for or null for the current state. Only widget annotations of pushbutton, check box, or radio button type have states, which are "Off" or "Yes". For other types of annotations pass null.
- **Matrix transform**: The transformation matrix.
- **Rect bbox**: The bounding box.,
- **PDFObject resources**: Resources object.
- **Buffer | ArrayBuffer | Uint8Array | string contents**: Contents string.

```
annotation.setAppearance(
"N",
null,
mupdf.Matrix.identity,
[0, 0, 100, 100],
resources,
contents
)
```

#### PDFAnnotation.prototype.update()

Update the appearance stream to account for changes in the annotation.

Returns true if the annotation appearance changed during the call.

- **Returns:** boolean

```
annotation.update()
```

#### PDFAnnotation.prototype.setAppearanceFromDisplayList(appearance, state, transform, list)

Set the annotation appearance stream for the given appearance. The
desired appearance is given as a transform along with a display list.

- **string appearance**: Appearance stream ("N", "R" or "D").
- **string state**: The annotation state to set the appearance for or null for the current state. Only widget annotations of pushbutton, check box, or radio button type have states, which are "Off" or "Yes". For other types of annotations pass null.
- **Matrix transform**: The transformation matrix.
- **DisplayList list**: The display list.

```
annotation.setAppearanceFromDisplayList(
"N",
null,
mupdf.Matrix.identity,
displayList
)
```

#### PDFAnnotation.prototype.getHiddenForEditing()

Get a special annotation hidden flag for editing. This flag prevents the annotation from being rendered.

- **Returns:** boolean

```
var hidden = annotation.getHiddenForEditing()
```

#### PDFAnnotation.prototype.setHiddenForEditing(hidden)

Set a special annotation hidden flag for editing. This flag prevents the annotation from being rendered.

- **boolean hidden**: 

```
annotation.setHiddenForEditing(true)
```

#### PDFAnnotation.prototype.getHot()

Check if the annotation is hot, i.e. that the pointing device's cursor
is hovering over the annotation.

- **Returns:** boolean

```
annotation.getHot()
```

#### PDFAnnotation.prototype.setHot(hot)

Set the annotation as being hot, i.e. that the pointing device's cursor
is hovering over the annotation.

- **boolean hot**: 

```
annotation.setHot(true)
```

#### PDFAnnotation.prototype.requestSynthesis()

Request that if an annotation does not have an appearance stream, flag
the annotation to have one generated. The appearance stream
will be created during future calls to
`PDFAnnotation.prototype.update()` on or
`PDFPage.prototype.update()`.

```
annotation.requestSynthesis()
```

#### PDFAnnotation.prototype.requestResynthesis()

Request that an appearance stream shall be re-generated for an
annotation next time update() is called on
`PDFAnnotation.prototype.update()` or
`PDFPage.prototype.update()`.

This is a side-effect of setting annotation attributes through
the PDFAnnotation interface, so normally this call does not
need to be done explicitly.

```
annotation.requestResynthesis()
```

#### PDFAnnotation.prototype.process(processor)

Run through the annotation appearance stream and call methods
on the supplied `PDFProcessor`.

- **PDFProcessor processor**: User defined function.

```
annotation.process(processor)
```

#### PDFAnnotation.prototype.applyRedaction(blackBoxes, imageMethod, lineArtMethod, textMethod)

Applies a single Redaction annotation.

See `PDFPage.prototype.applyRedactions` for details.

### Annotation attributes

PDF Annotations have many attributes. Some of these are common to all
annotations, and some only exist on specific annotation types.

#### Common

#### PDFAnnotation.prototype.getType()

Return the :term:`annotation type` for this annotation.

- **Returns:** string

```
var type = annotation.getType()
```

#### PDFAnnotation.prototype.getFlags()

Get the annotation flags.

See `PDFAnnotation.prototype.setFlags`.

- **Returns:** number

```
var flags = annotation.getFlags()
```

#### PDFAnnotation.prototype.setFlags(flags)

Set the annotation flags.

- **number flags**: A bit mask with the flags (see below).

| Bit | Name |
| --- | --- |
| 1 | Invisible |
| 2 | Hidden |
| 3 | Print |
| 4 | NoZoom |
| 5 | NoRotate |
| 6 | NoView |
| 7 | ReadOnly |
| 8 | Locked |
| 9 | ToggleNoView |
| 10 | LockedContents |

```
annotation.setFlags(4) // Clears all other flags and sets "NoZoom".
```

#### PDFAnnotation.prototype.getContents()

Get the annotation contents.

- **Returns:** string

```
var contents = annotation.getContents()
```

#### PDFAnnotation.prototype.setContents(text)

Set the annotation contents.

- **string text**: 

```
annotation.setContents("Hello World")
```

#### PDFAnnotation.prototype.getCreationDate()

Get the annotation creation date as a Date object.

- **Returns:** Date

```
var date = annotation.getCreationDate()
```

#### PDFAnnotation.prototype.setCreationDate(date)

Set the creation date.

- **Date date**: A Date object.

```
annotation.setCreationDate(new Date())
```

#### PDFAnnotation.prototype.getModificationDate()

Get the annotation modification date as a Date object.

- **Returns:** Date

```
var date = annotation.getModificationDate()
```

#### PDFAnnotation.prototype.setModificationDate(date)

Set the modification date.

- **Date date**: 

```
annotation.setModificationDate(new Date())
```

#### PDFAnnotation.prototype.getLanguage()

Get the annotation :term:`language code` (or get the one
inherited from the document).

- **Returns:** string | null

```
var language = annotation.getLanguage()
```

#### PDFAnnotation.prototype.setLanguage(language)

Set the annotation :term:`language code`.

- **string language**: The desired language code.

```
annotation.setLanguage("en")
```

#### Rect

For annotations that can be resized by setting its bounding box rectangle
(e.g. Square and FreeText), `PDFAnnotation.prototype.hasRect()` returns `true`.

Other annotation types, (e.g. Line, Polygon, and InkList)
change size by adding/removing vertices.
Yet other annotations (e.g. Highlight and StrikeOut)
change size by adding/removing QuadPoints.

The underlying Rect attribute on the PDF object is automatically updated as needed
for these other annotation types.

#### PDFAnnotation.prototype.hasRect()

Checks whether the annotation can be resized by setting its
bounding box.

- **Returns:** boolean

```
var hasRect = annotation.hasRect()
```

#### PDFAnnotation.prototype.getRect()

Get the annotation bounding box.

- **Returns:** `Rect`

```
var rect = annotation.getRect()
```

#### PDFAnnotation.prototype.setRect(rect)

Set the annotation bounding box.

- **Rect rect**: The new desired bounding box.

```
annotation.setRect([0, 0, 100, 100])
```

#### Rich contents

#### PDFAnnotation.prototype.hasRichContents()

Returns whether the annotation is capable of supporting rich text
contents.

- **Returns:** boolean

```
var hasRichContents = annotation.hasRichContents()
```

#### PDFAnnotation.prototype.getRichContents()

Obtain the annotation's rich-text contents, as opposed to the plain
text contents obtained by `getContents()`.

- **Returns:** string

```
var richContents = annotation.getRichContents()
```

#### PDFAnnotation.prototype.setRichContents(plainText, richText)

Set the annotation's rich-text contents, as opposed to the plain
text contents set by `setContents()`.

- **string plainText**: 
- **string richText**: 

```
annotation.setRichContents("plain text", "<b><i>Rich-Text</i></b>")
```

#### PDFAnnotation.prototype.getRichDefaults()

Get the default style used for the annotation's rich-text contents.

- **Returns:** string

```
var richDefaults = annotation.getRichDefaults()
```

#### PDFAnnotation.prototype.setRichDefaults(style)

Set the default style used for the annotation's rich-text contents.

- **string style**: 

```
annotation.setRichDefaults("font-size: 16pt")
```

#### Color

The meaning of the color attribute depends on the annotation type. For some it is the color
of the border.

#### PDFAnnotation.prototype.getColor()

Get the annotation color, represented as an array of 0, 1, 3, or 4 component values.

- **Returns:** `Color`

```
var color = annotation.getColor()
```

#### PDFAnnotation.prototype.setColor(color)

Set the annotation color, represented as an array of 0, 1, 3, or 4 component values.

- **Color color**: The new color.

- **Throws:** TypeError if number of components is not 0, 1, 3, or 4.

```
annotation.setColor([0, 1, 0])
```

#### Opacity

#### PDFAnnotation.prototype.getOpacity()

Get the annotation :term:`opacity`.

- **Returns:** number

```
var opacity = annotation.getOpacity()
```

#### PDFAnnotation.prototype.setOpacity(opacity)

Set the annotation :term:`opacity`.

- **number opacity**: The desired opacity.

```
annotation.setOpacity(0.5)
```

#### Quadding

#### PDFAnnotation.prototype.hasQuadding()

Returns whether the annotation is capable of supporting
quadding (justification).

- **Returns:** boolean

```
var hasQuadding = annotation.hasQuadding()
```

#### PDFAnnotation.prototype.getQuadding()

Get the annotation quadding (justification). Quadding value, 0
for left-justified, 1 for centered, 2 for right-justified

- **Returns:** number

```
var quadding = annotation.getQuadding()
```

#### PDFAnnotation.prototype.setQuadding(value)

Set the annotation quadding (justification). Quadding value, 0
for left-justified, 1 for centered, 2 for right-justified.

- **number value**: The desired quadding.

```
annotation.setQuadding(1)
```

#### Author

#### PDFAnnotation.prototype.hasAuthor()

Returns whether the annotation is capable of supporting an author.

- **Returns:** boolean

```
var hasAuthor = annotation.hasAuthor()
```

#### PDFAnnotation.prototype.getAuthor()

Gets the annotation author.

- **Returns:** string

```
var author = annotation.getAuthor()
```

#### PDFAnnotation.prototype.setAuthor(author)

Sets the annotation author.

- **string author**: 

```
annotation.setAuthor("Jane Doe")
```

#### Border

#### PDFAnnotation.prototype.hasBorder()

Returns whether the annotation is capable of supporting a border.

- **Returns:** boolean

```
var hasBorder = annotation.hasBorder()
```

#### PDFAnnotation.prototype.getBorderStyle()

Get the annotation :term:`border style`.

- **Returns:** string

```
var borderStyle = annotation.getBorderStyle()
```

#### PDFAnnotation.prototype.setBorderStyle(style)

Set the annotation :term:`border style`.

- **string style**: The annotation style.

```
annotation.setBorderStyle("Dashed")
```

#### PDFAnnotation.prototype.getBorderWidth()

Get the border width in points.

- **Returns:** number

```
var w = annotation.getBorderWidth()
```

#### PDFAnnotation.prototype.setBorderWidth(width)

Set the border width in points. Retains any existing border effects.

- **number width**: 

```
annotation.setBorderWidth(1.5)
```

#### PDFAnnotation.prototype.getBorderDashCount()

Returns the number of items in the border dash pattern.

- **Returns:** number

```
var dashCount = annotation.getBorderDashCount()
```

#### PDFAnnotation.prototype.getBorderDashItem(idx)

Returns the length of dash pattern item idx.

- **number idx**: 

- **Returns:** number

```
var length = annotation.getBorderDashItem(0)
```

#### PDFAnnotation.prototype.setBorderDashPattern(list)

Set the annotation border dash pattern to the given array of dash item lengths. The supplied array represents the respective line stroke and gap lengths, e.g. [1, 1] sets a small dash and small gap, [2, 1, 4, 1] would set a medium dash, a small gap, a longer dash and then another small gap.

- **Array of number dashPattern**: 

```
annotation.setBorderDashPattern([2.0, 1.0, 4.0, 1.0])
```

#### PDFAnnotation.prototype.clearBorderDash()

Clear the entire border dash pattern for an annotation.

```
annotation.clearBorderDash()
```

#### PDFAnnotation.prototype.addBorderDashItem(length)

Append an item (of the given length) to the end of the border dash pattern.

- **number length**: 

```
annotation.addBorderDashItem(10.0)
```

#### PDFAnnotation.prototype.hasBorderEffect()

Returns whether the annotation is capable of supporting a border
effect.

- **Returns:** boolean

```
var hasEffect = annotation.hasBorderEffect()
```

#### PDFAnnotation.prototype.getBorderEffect()

Get the :term:`border effect`.

- **Returns:** string

```
var effect = annotation.getBorderEffect()
```

#### PDFAnnotation.prototype.setBorderEffect(effect)

Set the :term:`border effect`.

- **string effect**: The border effect.

```
annotation.setBorderEffect("None")
```

#### PDFAnnotation.prototype.getBorderEffectIntensity()

Get the annotation border effect intensity.

- **Returns:** number

```
var intensity = annotation.getBorderEffectIntensity()
```

#### PDFAnnotation.prototype.setBorderEffectIntensity(intensity)

Set the annotation border effect intensity. Recommended values are between 0 and 2 inclusive.

- **number intensity**: Border effect intensity.

```
annotation.setBorderEffectIntensity(1.5)
```

#### Callout

Callouts are used with FreeText annotations and
allow for a graphical line to point to an area on a page.

#### PDFAnnotation.prototype.hasCallout()

Returns whether the annotation is capable of supporting a callout.

- **Returns:** boolean

#### PDFAnnotation.prototype.setCalloutLine(line)

Takes an array of 2 or 3 `points <Point>`. Supply an empty array to
remove the callout line.

- **Array of Point points**: 

#### PDFAnnotation.prototype.getCalloutLine()

Returns the array of points.

- **Returns:** Array of `Point` | null

#### PDFAnnotation.prototype.setCalloutPoint(p)

Takes a point where the callout should point to.

- **Point p**: 

#### PDFAnnotation.prototype.getCalloutPoint()

Returns the callout point.

- **Returns:** `Point`

#### PDFAnnotation.prototype.setCalloutStyle(style)

Sets the :term:`line ending style` of the callout line.

- **string style**: 

#### PDFAnnotation.prototype.getCalloutStyle()

Returns the callout style.

- **Returns:** string

#### Default Appearance

#### PDFAnnotation.prototype.hasDefaultAppearance()

Returns whether the annotation is capable of supporting a default
appearance.

- **Returns:** boolean

```
var hasRect = annotation.hasDefaultAppearance()
```

#### PDFAnnotation.prototype.getDefaultAppearance()

Get the default text appearance used for free text annotations
as an object containing the font, size, and color.

- **Returns:** `{ font: string, size: number, color: Color }`

```
var appearance = annotation.getDefaultAppearance()
console.log("DA font:", appearance.font, appearance.size)
console.log("DA color:", appearance.color)
```

#### PDFAnnotation.prototype.setDefaultAppearance(font, size, color)

Set the default text appearance used for free text annotations.

- **string font: The desired default font**: `"Helv" | "TiRo" | "Cour"` for Helvetica, Times Roman, and Courier respectively.
- **number size**: The desired default font size.
- **Color color**: The desired default font color.

```
annotation.setDefaultAppearance("Helv", 16, [0, 0, 0])
```

#### Filespec

#### PDFAnnotation.prototype.hasFilespec()

Returns whether the annotation is capable of supporting a
:term:`file specification`.

- **Returns:** boolean

```
var hasFilespec = annotation.hasFilespec()
```

#### PDFAnnotation.prototype.getFilespec()

Get the :term:`file specification` PDF object for the file attachment, or null if none set.

- **Returns:** `PDFObject` | null

```
var fs = annotation.getFilespec()
```

#### PDFAnnotation.prototype.setFilespec(fs)

Set the :term:`file specification` PDF object for the file attachment.

- **`PDFObject` fs**: 

```
annotation.setFilespec(fs)
```

#### Icon

#### PDFAnnotation.prototype.hasIcon()

Returns whether the annotation is capable of supporting an icon.

- **Returns:** boolean

```
var hasIcon = annotation.hasIcon()
```

#### PDFAnnotation.prototype.getIcon()

Get the annotation :term:`icon name`, either a standard or custom name.

- **Returns:** string

```
var icon = annotation.getIcon()
```

#### PDFAnnotation.prototype.setIcon(name)

Set the annotation :term:`icon name`.

Note that standard icon names can be used to resynthesize the annotation appearance, but custom names cannot.

- **string name: An :term**: `icon name`.

```
annotation.setIcon("Note")
```

#### Ink List

Ink annotations consist of a number of strokes, each consisting of a sequence of vertices between which a smooth line will be drawn.

#### PDFAnnotation.prototype.hasInkList()

Returns whether the annotation is capable of supporting an ink list.

- **Returns:** boolean

```
var hasInkList = annotation.hasInkList()
```

#### PDFAnnotation.prototype.getInkList()

Get the annotation ink list, represented as an array of strokes.
Each stroke consists of an array of points.

- **Returns:** Array of Array of `Point`

```
var inkList = annotation.getInkList()
```

#### PDFAnnotation.prototype.setInkList(inkList)

Set the annotation ink list, represented as an array of strokes.
Each stroke consists of an array of points.

- **Array of Array of Point inkList**: 

```
// this draws a box with a cross in three strokes:
annotation.setInkList([
[
[0, 0], [10, 0], [10, 10], [0, 10], [0, 0]
],
[
[10, 0], [0, 10]
],
[
[0, 0], [10, 10]
]
])
```

#### PDFAnnotation.prototype.clearInkList()

Clear the list of ink strokes for the annotation.

```
annotation.clearInkList()
```

#### PDFAnnotation.prototype.addInkListStroke()

Add a new empty stroke to the ink annotation.

```
annotation.addInkListStroke()
```

#### PDFAnnotation.prototype.addInkListStrokeVertex(v)

Append a vertex to end of the last stroke in the ink annotation.

- **Point v**: 

```
annotation.addInkListStrokeVertex([0, 0])
```

#### Interior Color

#### PDFAnnotation.prototype.hasInteriorColor()

Returns whether the annotation is capable of supporting an interior
color.

- **Returns:** boolean

```
var hasInteriorColor = annotation.hasInteriorColor()
```

#### PDFAnnotation.prototype.getInteriorColor()

Get the annotation interior color, represented as an array of 0, 1, 3, or 4 component values.

- **Returns:** `Color`

```
var interiorColor = annotation.getInteriorColor()
```

#### PDFAnnotation.prototype.setInteriorColor(color)

Sets the annotation interior color.

- **Color color**: The new desired interior color.

- **Throws:** TypeError if number of components is not 0, 1, 3, or 4.

```
annotation.setInteriorColor([0, 1, 1])
```

#### Line

#### PDFAnnotation.prototype.hasLine()

Returns whether the annotation is capable of supporting a line.

- **Returns:** boolean

```
var hasLine = annotation.hasLine()
```

#### PDFAnnotation.prototype.getLine()

Get line end points, represented by an array of two points, each represented as an [x, y] array.

- **Returns:** Array of `Point`

```
var line = annotation.getLine()
```

#### PDFAnnotation.prototype.setLine(a, b)

Set the two line end points, each represented as an [x, y] array.

- **Point a**: The new point a.
- **Point b**: The new point b.

```
annotation.setLine([100, 100], [150, 175])
```

#### Line Ending Styles

#### PDFAnnotation.prototype.hasLineEndingStyles()

Returns whether the annotation is capable of supporting
:term:`line ending style`.

- **Returns:** boolean

```
var hasLineEndingStyles = annotation.hasLineEndingStyles()
```

#### PDFAnnotation.prototype.getLineEndingStyles()

Get the start and end :term:`line ending style` values for each end of the line annotation.

- **Returns:** `{ start: string, end: string }` Returns an object with the key/value pairs

```
var lineEndingStyles = annotation.getLineEndingStyles()
```

#### PDFAnnotation.prototype.setLineEndingStyles(start, end)

Sets the :term:`line ending style` values for each end of the line annotation.

- **string start**: 
- **string end**: 

```
annotation.setLineEndingStyles("Square", "OpenArrow")
```

#### Line Leaders

In a PDF line leaders refer to two lines at the ends of the line annotation,
oriented perpendicular to the line itself. These are common in technical
drawings when illustrating distances.

#### PDFAnnotation.prototype.setLineLeader(v)

Sets the line leader length.

- **number v**: 
The length of leader lines that extend from each endpoint of
the line perpendicular to the line itself. A positive value
means that the leader lines appear in the direction that is
clockwise when traversing the line from its starting point to
its ending point a negative value indicates the opposite
direction.

Setting a value of 0 effectively removes the line leader.

#### PDFAnnotation.prototype.getLineLeader()

Gets the line leader length.

- **Returns:** number

#### PDFAnnotation.prototype.setLineLeaderExtension(v)

Sets the line leader extension.

- **number v**: 
A non-negative number representing the length of leader line
extensions that extend from the line proper 180 degrees from
the leader lines.

Setting a value of 0 effectively removes the line leader extension.

#### PDFAnnotation.prototype.getLineLeaderExtension()

Gets the line leader extension.

- **Returns:** number

#### PDFAnnotation.prototype.setLineLeaderOffset(v)

Sets the line leader offset.

- **number v**: 
A non-negative number representing the length of the leader
line offset, which is the amount of empty space between the
endpoints of the annotation and the beginning of the leader
lines.

Setting a value of 0 effectively removes the line leader offset.

#### PDFAnnotation.prototype.getLineLeaderOffset()

Gets the line leader offset.

- **Returns:** number

#### PDFAnnotation.prototype.setLineCaption(on)

Sets whether line caption is enabled or not.

When line captions are enabled then calling the
`PDFAnnotation.prototype.setContents` on the line annotation will
render the contents onto the line as the caption text.

- **boolean on**: 

#### PDFAnnotation.prototype.getLineCaption()

Returns whether the line caption is enabled or not.

- **Returns:** boolean

#### PDFAnnotation.prototype.setLineCaptionOffset(point)

Sets the line caption offset.

The x value of the offset point is the horizontal offset along the
annotation line from its midpoint, with a positive value indicating
offset to the right and a negative value indicating offset to the
left. The y value of the offset point is the vertical offset
perpendicular to the annotation line, with a positive value
indicating a shift up and a negative value indicating a shift down.

Setting a point of [0, 0] removes the caption offset.

- **Point point**: A point specifying the offset of the caption text from its normal position.

#### PDFAnnotation.prototype.getLineCaptionOffset()

Returns the line caption offset as a point, [x, y].

- **Returns:** `Point`

#### Open

Open refers to whether the annotation is display in an open state when the
page is loaded. A Text Note annotation is considered open if the user has
clicked on it to view its contents.

#### PDFAnnotation.prototype.hasOpen()

Returns whether the annotation is capable of supporting annotation
open state.

- **Returns:** boolean

```
var hasOpen = annotation.hasOpen()
```

#### PDFAnnotation.prototype.getIsOpen()

Get annotation open state.

- **Returns:** boolean

```
var isOpen = annotation.getIsOpen()
```

#### PDFAnnotation.prototype.setIsOpen(state)

Set annotation open state.

- **boolean state**: 

```
annotation.setIsOpen(true)
```

#### Popup

#### PDFAnnotation.prototype.hasPopup()

Returns whether the annotation is capable of supporting a popup.

- **Returns:** boolean

```
var hasPopup = annotation.hasPopup()
```

#### PDFAnnotation.prototype.getPopup()

Get annotation popup rectangle.

- **Returns:** `Rect`

```
var popupRect = annotation.getPopup()
```

#### PDFAnnotation.prototype.setPopup(rect)

Set annotation popup rectangle.

- **Rect rect**: The desired area where the popup should appear.

```
annotation.setPopup([0, 0, 100, 100])
```

#### QuadPoints

Text markup and redaction annotations consist of a set of
quadadrilaterals, or :term:`QuadPoints <QuadPoint>`.
These are used in e.g. Highlight
annotations to mark up several disjoint spans of text.

In Javascript QuadPoints are represented with `Quad` objects.

#### PDFAnnotation.prototype.hasQuadPoints()

Returns whether the annotation is capable of supporting quadpoints.

- **Returns:** boolean

```
var hasQuadPoints = annotation.hasQuadPoints()
```

#### PDFAnnotation.prototype.getQuadPoints()

Get the annotation's quadpoints, describing the areas affected by
text markup annotations and link annotations.

- **Returns:** Array of `Quad`

```
var quadPoints = annotation.getQuadPoints()
```

#### PDFAnnotation.prototype.setQuadPoints(quadList)

Set the annotation quadpoints describing the areas affected by
text markup annotations and link annotations.

- **Array of Quad quadList**: The quadpoints to set.

```
// two quads, the first one wider than the second one
annotation.setQuadPoints([
[ 100, 100, 200, 100, 200, 150, 100, 150 ],
[ 125, 150, 175, 150, 175, 200, 125, 200 ]
])
```

#### PDFAnnotation.prototype.clearQuadPoints()

Clear the list of quadpoints for the annotation.

```
annotation.clearQuadPoints()
```

#### PDFAnnotation.prototype.addQuadPoint(quad)

Append a single quadpoint to the annotation.

- **Quad quad**: The quadpoint to add.

```
annotation.addQuadPoint([1, 2, 3, 4, 5, 6, 7, 8])
```

#### Vertices

Polygon and polyline annotations consist of a sequence of vertices with a straight line between them. Those can be controlled by:

#### PDFAnnotation.prototype.hasVertices()

Returns whether the annotation is capable of supporting vertices.

- **Returns:** boolean

```
var hasVertices = annotation.hasVertices()
```

#### PDFAnnotation.prototype.getVertices()

Get the annotation vertices, represented as an array of points.

- **Returns:** Array of `Point`

```
var vertices = annotation.getVertices()
```

#### PDFAnnotation.prototype.setVertices(vertices)

Set the annotation vertices, represented as an array of points.

- **Array of Point vertices**: 

```
annotation.setVertices([
[0, 0],
[10, 10],
[20, 20]
])
```

#### PDFAnnotation.prototype.clearVertices()

Clear the list of vertices for the annotation.

```
annotation.clearVertices()
```

#### PDFAnnotation.prototype.addVertex(vertex)

Append a single vertex point to the annotation.

- **Point vertex**: 

```
annotation.addVertex([0, 0])
```

#### Stamp image

#### PDFAnnotation.prototype.getStampImageObject()

If the annotation is a stamp annotation and it consists of an
image, return the `PDFObject` representing that image.

- **Returns:** `PDFObject` | null

```
var pdfobj = annotation.getStampImageObject()
```

#### PDFAnnotation.prototype.setStampImageObject(imgobj)

Create an appearance stream containing the image passed as
argument and set that as the normal appearance of the
annotation.

- **PDFObject imgobj**: PDFObject corresponding to the desired image.

```
annotation.setStampImageObject(imgobj)
```

#### PDFAnnotation.prototype.setStampImage(img)

Add the image passed as argument to the document as a PDF
object, and pass a reference to that object to when setting the
normal appearance of the stamp annotation.

- **Image img**: The image to become the stamp annotations appearance.

```
annotation.setStampImage(img)
```

#### Intent

#### PDFAnnotation.prototype.hasIntent()

Returns whether the annotation is capable of supporting an intent.

- **Returns:** boolean

```
var hasIntent = annotation.hasIntent()
```

#### PDFAnnotation.prototype.getIntent()

Get the annotation intent, one of the values below:

* "FreeTextCallout"
* "FreeTextTypeWriter"
* "LineArrow"
* "LineDimension"
* "PolyLineDimension"
* "PolygonCloud"
* "PolygonDimension"
* "StampImage"
* "StampSnapshot"

- **Returns:** string

```
var intent = annotation.getIntent()
```

#### PDFAnnotation.prototype.setIntent(intent)

Set the annotation intent.

- **string intent**: Intent value, see `getIntent()` for permissible values.

```
annotation.setIntent("LineArrow")
```

#### Events

PDF annotations can have different appearances depending on whether
the pointing device's cursor is hovering over an annotation, or if the
pointing device's button is pressed.

PDF widgets, which is a type of annotation, may also have associated
Javascript functions that are executed when certain events occur.

Therefore it is important to tell an PDFAnnotation when the pointing
device's cursor enters/exits an annotation, when it's button is
clicked, or when an annotation gains/loses input focus.

#### PDFAnnotation.prototype.eventEnter()

Trigger appearance changes and event handlers for
when the pointing device's cursor enters an
annotation's active area.

```
annot.eventEnter()
```

#### PDFAnnotation.prototype.eventExit()

Trigger appearance changes and event handlers for
when the pointing device's cursor exits an
annotation's active area.

```
annot.eventExit()
```

#### PDFAnnotation.prototype.eventDown()

Trigger appearance changes and event handlers for
when the pointing device's button is depressed within
an annotation's active area.

```
widget.eventDown()
```

#### PDFAnnotation.prototype.eventUp()

Trigger appearance changes and event handlers for
when the pointing device's button is released within
an annotation's active area.

```
widget.eventUp()
```

#### PDFAnnotation.prototype.eventFocus()

Trigger event handlers for when an annotation gains
input focus.

```
widget.eventFocus()
```

#### PDFAnnotation.prototype.eventBlur()

Trigger event handlers for when an annotation loses
input focus.

```
widget.eventBlur()
```

### PDFDocument

The PDFDocument is a specialized subclass of `Document` which has
additional methods that are only available for PDF files.

#### PDF Objects

A PDF document contains objects: dictionaries, arrays, names, strings, numbers,
booleans, and indirect references.
Some dictionaries also have attached data. These are called streams,
and may be compressed.

At the root of the PDF document is the trailer object; which contains pointers to the meta
data dictionary and the catalog object, which in turn contains references to the pages and
forms and everything else.

Pointers in PDF are called indirect references, and are of the form
32 0 R (where 32 is the object number, 0 is the generation, and R is
magic syntax). All functions in MuPDF dereference indirect
references automatically.

	PDFObjects are always bound to the document that created them. Do
	**NOT** mix and match objects from one document with another
	document!

#### Constructors

#### PDFDocument()

Create a brand new PDF document instance that begins empty with no pages.

To open an existing PDF document, use `Document.openDocument()`.

#### Static methods

#### PDFDocument.formatURIFromPathAndDest(path, destination)

Format a link URI given a
`system independent path <https://opensource.adobe.com/dc-acrobat-sdk-docs/pdfstandards/pdfreference1.7old.pdf#G8.1640868>`
to a remote document and a destination object or a destination
string suitable for `Page.prototype.createLink()`.

- **string path**: An absolute or relative path to a remote document file.
- **Link | string destination**: Link or string referring to a destination using either a destination object or a destination name in the remote document.

#### PDFDocument.appendDestToURI(uri, destination)

Append a fragment representing a document destination to a an
existing URI that points to a remote document. The resulting
string is suitable for `Page.prototype.createLink()`.

- **string uri**: An URI to a remote document file.
- **Link | string | number destination**: A Link or string referring to a destination using either a destination object or a destination name in the remote document, or a page number.

#### Instance methods

#### PDFDocument.prototype.needsPassword()

Returns true if a password is required to open a password protected PDF.

- **Returns:** boolean

```
var needsPassword = document.needsPassword()
```

#### PDFDocument.prototype.authenticatePassword(password)

Returns a bitfield value against the password authentication result.

The values returned by this interface are interpreted like this:

| Bit | Description |
| --- | --- |
| 0 | Failed |
| 1 | No password needed |
| 2 | User password is okay |
| 4 | Owner password is okay |

- **string password**: The password to attempt authentication with.

- **Returns:** number

```
var auth = document.authenticatePassword("abracadabra")
```

#### PDFDocument.prototype.hasPermission(permission)

Returns true if the document has permission for the supplied permission parameter.

These are the recognized permission strings:

| String | The Document may... |
| --- | --- |
| print | ... be printed. |
| edit | ... be edited. |
| copy | ... be copied. |
| annotate | ... have annotations added/removed. |
| form | ... have form field contents edited. |
| accessibility | ... be copied for accessibility. |
| assemble | ... have its pages rearranged. |
| print-hq | ... be printed in high quality be printed in high quality. |

- **string permission**: The permission to seek for, e.g. "edit".

- **Returns:** boolean

```
var canEdit = document.hasPermission("edit")
```

#### PDFDocument.prototype.getVersion()

Returns the PDF document version as an integer multiplied by
10, so e.g. a PDF-1.4 document would return 14.

- **Returns:** number

```
var version = pdfDocument.getVersion()
```

#### PDFDocument.prototype.setLanguage(lang)

Set the document's :term:`language code`.

- **string lang**: 

```
pdfDocument.setLanguage("en")
```

#### PDFDocument.prototype.getLanguage()

Get the document's :term:`language code`.

- **Returns:** string | null

```
var lang = pdfDocument.getLanguage()
```

#### PDFDocument.prototype.wasPureXFA()

Returns whether the document was an XFA form without AcroForm
fields.

- **Returns:** boolean

```
var wasPureXFA = pdfDocument.wasPureXFA()
```

#### PDFDocument.prototype.wasRepaired()

Returns whether the document was repaired when opened.

- **Returns:** boolean

```
var wasRepaired = pdfDocument.wasRepaired()
```

#### PDFDocument.prototype.loadNameTree(treeName)

Return an object whose properties and their values come from
corresponding names/values from the given name tree.

- **Returns:** Object

```
var dests = pdfDocument.loadNameTree("Dests")
for (var p in dests) {
console.log("Destination: " + p)
}
```

#### Objects

#### PDFDocument.prototype.newNull()

Create a new null object.

- **Returns:** `PDFObject`

```
var obj = doc.newNull()
```

#### PDFDocument.prototype.newBoolean(v)

Create a new boolean object.

- **boolean v**: 

- **Returns:** `PDFObject`

```
var obj = doc.newBoolean(true)
```

#### PDFDocument.prototype.newInteger(v)

Create a new integer object.

- **number v**: 

- **Returns:** `PDFObject`

```
var obj = doc.newInteger(1)
```

#### PDFDocument.prototype.newReal(v)

Create a new real number object.

- **number v**: 

- **Returns:** `PDFObject`

```
var obj = doc.newReal(7.3)
```

#### PDFDocument.prototype.newString(v)

Create a new string object.

- **string v**: 

- **Returns:** `PDFObject`

```
var obj = doc.newString("hello")
```

#### PDFDocument.prototype.newByteString(v)

Create a new byte string object.

- **Uint8Array | Array of number v**: 

- **Returns:** `PDFObject`

```
var obj = doc.newByteString([21, 31])
```

#### PDFDocument.prototype.newName(v)

Create a new name object.

- **string v**: 

- **Returns:** `PDFObject`

```
var obj = doc.newName("hello")
```

#### PDFDocument.prototype.newIndirect(objectNumber, generation)

Create a new indirect object.

- **number objectNumber**: 
- **number generation**: 

- **Returns:** `PDFObject`

```
var obj = doc.newIndirect(42, 0)
```

#### PDFDocument.prototype.newArray()

Create a new array object.

- **Returns:** `PDFObject`

```
var obj = doc.newArray()
```

#### PDFDocument.prototype.newDictionary()

Create a new dictionary object.

- **Returns:** `PDFObject`

```
var obj = doc.newDictionary()
```

#### Indirect objects

#### PDFDocument.prototype.getTrailer()

The trailer dictionary. This contains indirect references to the "Root"
and "Info" dictionaries.

- **Returns:** `PDFObject`

```
var dict = doc.getTrailer()
```

#### PDFDocument.prototype.countObjects()

Return the number of objects in the PDF.

- **Returns:** number

```
var num = doc.countObjects()
```

#### PDFDocument.prototype.createObject()

Allocate a new numbered object in the PDF, and return an indirect
reference to it. The object itself is uninitialized.

- **Returns:** `PDFObject`

```
var obj = doc.createObject()
```

#### PDFDocument.prototype.deleteObject(num)

Delete the object referred to by an indirect reference or its object number.

- **PDFObject | number num**: Delete the referenced object number.

```
doc.deleteObject(obj)
```

#### PDFDocument.prototype.addObject(obj)

Add obj to the PDF as a numbered object, and return an indirect reference to it.

- **PDFObject obj**: Object to add.

- **Returns:** `PDFObject`

```
var ref = doc.addObject(obj)
```

#### PDFDocument.prototype.addStream(buf, obj)

Create a stream object with the contents of buffer, add it to the PDF, and return an indirect reference to it. If object is defined, it will be used as the stream object dictionary.

- **Buffer | ArrayBuffer | Uint8Array | string buf**: Buffer whose data to put into stream.
- **PDFObject obj**: The object to add the stream to.

- **Returns:** `PDFObject`

```
var stream = doc.addStream(buffer, object)
```

#### PDFDocument.prototype.addRawStream(buf, obj)

Create a stream object with the contents of buffer, add it to the PDF, and return an indirect reference to it. If object is defined, it will be used as the stream object dictionary. The buffer must contain already compressed data that matches "Filter" and "DecodeParms" set in the stream object dictionary.

- **Buffer | ArrayBuffer | Uint8Array | string buf**: Buffer whose data to put into stream.
- **PDFObject obj**: The object to add the stream to.

- **Returns:** `PDFObject`

```
var stream = doc.addRawStream(buffer, object)
```

#### Page Tree

#### PDFDocument.prototype.setPageTreeCache(enabled)

Enable or disable the page tree cache that is used to speed up page object lookups.
The page tree cache is used unless explicitly disabled with this function.

Disabling the page tree cache reduces the number objects that we need to read from the file when loading a single page.
However it will make page lookups slower overall!

- **boolean enabled**: 

#### PDFDocument.protoype.findPage(number)

Return the `PDFObject` for a page number.

- **number number**: The page number, the first page is number zero.

- **Throws:** Error on out of range page numbers.

- **Returns:** `PDFObject`

```
var obj = pdfDocument.findPage(0)
```

#### PDFDocument.prototype.findPageNumber(page)

Find a given `PDFPage` and return its page number.
If the page can not be found, returns -1.

- **PDFPage page**: 

- **Returns:** number

```
var pageNumber = pdfDocument.findPageNumber(page)
```

#### PDFDocument.prototype.lookupDest(obj)

Find the destination corresponding to a specific named
destination given as a name or byte string in the form of a
`PDFObject`.

Returns null if the named destination does not exist.

- **PDFObject obj**: 

- **Returns:** `PDFObject` | null

```
var destination = pdfDocument.lookupDest(nameobj)
```

#### PDFDocument.prototype.rearrangePages(pages)

Rearrange (re-order and/or delete) pages in the PDFDocument.

The pages in the document will be rearranged according to the
input list. Any pages not listed will be removed, and pages may
be duplicated by listing them multiple times.

The PDF objects describing removed pages will remain in the
file and take up space (and can be recovered by forensic tools)
unless you save with the "garbage" option set, see `PDFDocument.prototype.save()`.

- **Array of number pages**: An array of page numbers, each page number is 0-based.

```
var document = new Document.openDocument("my_pdf.pdf")
pdfDocument.rearrangePages([3,2])
pdfDocument.save("fewer_pages.pdf", "garbage")
```

#### PDFDocument.prototype.insertPage(at, page)

Insert the page's `PDFObject` into the page tree at the page
number specified by `at` (numbered from 0). If `at` is -1,
the page is inserted at the end of the document.

- **number at**: The index to insert at.
- **PDFObject page**: The PDFObject representing the page to insert.

```
pdfDocument.insertPage(-1, page)
```

#### PDFDocument.prototype.deletePage(index)

Delete the page at the given index.

- **number index**: The page number, the first page is number zero.

```
pdfDocument.deletePage(0)
```

#### PDFDocument.prototype.addPage(mediabox, rotate, resources, contents)

Create a new `PDFPage` object. Note: this function does NOT add
it to the page tree, use `PDFDocument.prototype.insertPage()`
to do that.

Creation of page contents is described in detail in the PDF
specification's section on `Content Streams
<https://opensource.adobe.com/dc-acrobat-sdk-docs/pdfstandards/pdfreference1.7old.pdf#G8.1913072>`_.

- **Rect mediabox**: Describes the dimensions of the page.
- **number rotate**: Rotation value.
- **PDFObject resources**: Resources dictionary object.
- **Buffer | ArrayBuffer | Uint8Array | string contents**: Contents string. This represents the page content stream.

- **Returns:** `PDFObject`

```
var helvetica = pdfDocument.addSimpleFont(new mupdf.Font("Helvetica"), "Latin")
var fonts = pdfDocument.newDictionary()
fonts.put("F1", helvetica)
var resources = pdfDocument.addObject(pdfDocument.newDictionary())
resources.put("Font", fonts)
var pageObject = pdfDocument.addPage(
[0,0,300,350],
0,
resources,
"BT /F1 12 Tf 100 100 Td (Hello, world!) Tj ET"
)
pdfDocument.insertPage(-1, pageObject)
```

#### Resources

#### PDFDocument.prototype.addSimpleFont(font, encoding)

Create a `PDFObject` from the `Font` object as a simple font.

- **Font font**: 
- **"Latin" | "Greek" | "Cyrillic" encoding**: Which 8-bit encoding to use. Defaults to "Latin".

See `Font.SIMPLE_ENCODING_LATIN`, etc.

- **Returns:** `PDFObject`

```
var obj = pdfDocument.addSimpleFont(new mupdf.Font("Times-Roman"), "Latin")
```

#### PDFDocument.prototype.addCJKFont(font, language, wmode, style)

Create a `PDFObject` from the `Font` object as a UTF-16 encoded
CID font for the given language ("zh-Hant", "zh-Hans", "ko", or
"ja"), writing mode ("H" or "V"), and style ("serif" or
"sans-serif").

- **Font font**: 
- **string language**: 
- **number wmode**: `0` for horizontal writing, and `1` for vertical writing.
- **string style**: 

- **Returns:** `PDFObject`

```
var obj = pdfDocument.addCJKFont(new mupdf.Font("ja"), "ja", 0, "serif")
```

#### PDFDocument.prototype.addFont(font)

Create a `PDFObject` from the `Font` object as an Identity-H
encoded CID font.

- **Font font**: 

- **Returns:** `PDFObject`

```
var obj = pdfDocument.addFont(new mupdf.Font("Times-Roman"))
```

#### PDFDocument.prototype.addImage(image)

Create a `PDFObject` from the `Image` object.

- **Image image**: 

- **Returns:** `PDFObject`

```
var obj = pdfDocument.addImage(new mupdf.Image(pixmap))
```

#### PDFDocument.prototype.loadImage(obj)

Load an `Image` from a `PDFObject` (typically an indirect
reference to an image resource).

- **PDFObject obj**: 

- **Returns:** `Image`

```
var image = pdfDocument.loadImage(obj)
```

#### Embedded/Associated files

#### PDFDocument.protoype.addEmbeddedFile(filename, mimetype, contents, creationDate, modificationDate, addChecksum)

Embedded a file into the document. If a checksum is added then
the file contents can be verified later. An indirect reference
to a :term:`file specification` object is returned.

The returned :term:`file specification` object can later be e.g.
connected to an annotation using
`PDFAnnotation.prototype.setFilespec()`.

- **string filename**: 
- **string mimetype: The :term**: `MIME-type`.
- **Buffer | ArrayBuffer | Uint8Array | string contents**: 
- **Date creationDate**: 
- **Date modificationDate**: 
- **boolean addChecksum**: Defaults to false.

- **Returns:** `PDFObject`

```
var fileSpecObject = pdfDocument.addEmbeddedFile(
"my_file.jpg",
 "image/jpeg",
 buffer,
 new Date(),
 new Date(),
 false
)
```

#### PDFDocument.prototype.getEmbeddedFiles()

Returns a record of any embedded files on the this PDFDocument.

- **Returns:** Record<string, PDFObject>

#### PDFDocument.prototype.deleteEmbeddedFile(filename)

Delete an embedded file by filename.

- **string filename**: Name of embedded file to delete.

```
doc.deleteEmbeddedFile("test.txt")
```

#### PDFDocument.prototype.insertEmbeddedFile(filename, fileSpecObject)

Insert the given file specification as an embedded file using
the given filename.

- **string filename**: Name of the file to insert.
- **PDFObject fileSpecObject: :term**: `File specification`.

```
pdfDocument.insertEmbeddedFile("test.txt", fileSpecObject)
pdfDocument.deleteEmbeddedFile("test.txt")
```

#### PDFDocument.prototype.getFilespecParams(fileSpecObject)

Get the file specification parameters from the :term:`file specification`.

- **PDFObject fileSpecObject: :term**: `file specification` object.

- **Returns:** `PDFFilespecParams`

```
var obj = pdfDocument.getFilespecParams(fileSpecObject)
```

#### PDFDocument.prototype.getEmbeddedFileContents(fileSpecObject)

Returns a `Buffer` with the contents of the embedded file
referenced by `fileSpecObject`.

- **Object fileSpecObject: :term**: `file specification`

- **Returns:** `Buffer` | null

```
var buffer = pdfDocument.getEmbeddedFileContents(fileSpecObject)
```

#### PDFDocument.prototype.verifyEmbeddedFileChecksum(fileSpecObject)

Verify the MD5 checksum of the embedded file contents.

- **Object fileSpecObject: :term**: `file specification`.

- **Returns:** boolean

```
var fileChecksumValid = pdfDocument.verifyEmbeddedFileChecksum(fileSpecObject)
```

#### PDFDocument.prototype.isFilespec(object)

Check if the given `object` is a :term:`file specification`.

- **PDFObject object**: 

- **Returns:** boolean

```
var isFilespec = pdfDocument.isFilespec(obj)
```

#### PDFDocument.prototype.isEmbeddedFile(object)

Check if the given `object` is a :term:`file specification` representing a file
embedded into the PDF document.

- **PDFObject object**: 

- **Returns:** boolean

```
var isFilespecObject = pdfDocument.isEmbeddedFile(obj)
```

#### PDFDocument.prototype.countAssociatedFiles()

Return the number of :term:`associated files <associated file>`
associated with this document. Note that this is the number of
files associated at the document level, not necessarily the
total number of files associated with elements throughout the
entire document.

- **Returns:** number

```
var count = pdfDocument.countAssociatedFiles()
```

#### PDFDocument.prototype.associatedFile(n)

Return the :term:`file specification` object that represents the nth
:term:`associated file` for this document.

`n` should be in the range `0 <= n < countAssociatedFiles()`.

Returns null if no associated file exists or index is out of range.

- **Returns:** `PDFObject` | null

```
var obj = pdfDocument.associatedFile(0)
```

#### Grafting

#### PDFDocument.prototype.newGraftMap()

Create a graft map on the destination document, so that objects that have already been copied can be found again. Each graft map should only be used with one source document. Make sure to create a new graft map for each source document used.

- **Returns:** `PDFGraftMap`

```
var graftMap = doc.newGraftMap()
```

#### PDFDocument.prototype.graftObject(obj)

Deep copy an object into the destination document. This function will
not remember previously copied objects. If you are copying several
objects from the same source document using multiple calls, you
should use a graft map instead, see
`PDFDocument.prototype.newGraftMap()`.

- **PDFObject obj**: The object to graft.

- **Returns:** `PDFObject`

```
var copiedObj = doc.graftObject(obj)
```

#### PDFDocument.prototype.graftPage(to, srcDoc, srcPage)

Graft a page and its resources at the given page number from the source document to the requested page number in the document.

- **number to**: The page number to insert the page before. Page numbers start at 0 and -1 means at the end of the document.
- **PDFDocument srcDoc**: Source document.
- **number srcPage**: Source page number.

This would copy the first page of the source document (0) to the last page (-1) of the current PDF document.

```
doc.graftPage(-1, srcDoc, 0)
```

#### Journalling

#### PDFDocument.prototype.enableJournal()

Activate journalling for the document.

```
pdfDocument.enableJournal()
```

#### PDFDocument.prototype.getJournal()

Returns a Javascript object with a property indicating the
current position, and the names of each entry in the
undo/redo journal history:

`{ position: number, steps: Array of string }`

- **Returns:** Object

```
var journal = pdfDocument.getJournal()
```

#### PDFDocument.prototype.beginOperation(op)

Begin a journal operation. Each call to begin an operation
should be paired with a call to either
`PDFDocument.prototype.endOperation()` if the operation was
successful, or to `PDFDocument.prototype.abandonOperation()` if
it failed.

- **string op**: The name of the operation.

```
pdfDocument.beginOperation("Change annotation color")
// Change the annotation
pdfDocument.endOperation()
```

#### PDFDocument.prototype.beginImplicitOperation()

Begin an implicit journal operation. Implicit operations are
operations that happen due to other operations, and that should
not be subdivided into separate undo steps. E.g. editing several
attributes of a `PDFAnnotation` might be desirable to do in a
single undo step. See `PDFDocument.prototype.beginOperation()`
for the requirements about paired calls.

```
pdfDocument.beginOperation("Complex operation")
pdfDocument.beginImplicitOperation()
pdfDocument.endOperation()
pdfDocument.beginImplicitOperation()
pdfDocument.endOperation()
pdfDocument.endOperation()
```

#### PDFDocument.prototype.endOperation()

End a previously started normal or implicit operation. After
this it can be `undone <PDFDocument.prototype.undo()>` and
`redone <PDFDocument.prototype.redo()>`.

```
pdfDocument.endOperation()
```

#### PDFDocument.prototype.abandonOperation()

Abandon a normal or implicit operation. Reverts to the state
before that operation began. This is normally called if an
operation failed for some reason.

```
pdfDocument.abandonOperation()
```

#### PDFDocument.prototype.canUndo()

Returns whether undo is possible in this state.

- **Returns:** boolean

```
var canUndo = pdfDocument.canUndo()
```

#### PDFDocument.prototype.canRedo()

Returns whether redo is possible in this state.

- **Returns:** boolean

```
var canRedo = pdfDocument.canRedo()
```

#### PDFDocument.prototype.undo()

Move backwards in the undo history. Changes to the document
after this call will throw away all subsequent undo history.

```
pdfDocument.undo()
```

#### PDFDocument.prototype.redo()

Move forwards in the undo history.

```
pdfDocument.redo()
```

#### PDFDocument.prototype.saveJournal(filename)

Save the undo/redo journal to a file.

- **string filename**: File to save the journal to.

```
pdfDocument.saveJournal("test.journal")
```

#### Layers

#### PDFDocument.prototype.countLayerConfigs()

Return the number of optional content layer configurations in this document.

- **Returns:** number

```
var configs = pdfDocument.countLayerConfigs()
```

#### PDFDocument.prototype.getLayerConfigName(n)

Return the name of configuration number `n`, where `n` is
`0 <= n < countLayerConfigs()`.

- **Returns:** string

```
var name = pdfDocument.getLayerConfigName(0)
```

#### PDFDocument.prototype.getLayerConfigInfo(n)

Return the creator of configuration number `n`, where `n` is
`0 <= n < countLayerConfigs()`.

- **Returns:** string

```
var creator = pdfDocument.getLayerConfigCreator(0)
```

#### PDFDocument.prototype.selectLayerConfig(n)

Select layer configuration number `n`, where `n` is
`0 <= n < countLayerConfigs()`.

```
var info = pdfDocument.selectLayerConfig(1)
```

#### PDFDocument.prototype.countLayerConfigUIs()

Return the number of optional content layer UI elements in this document
given the selected optional content layer configuration.

- **Returns:** number

#### PDFDocument.prototype.getLayerConfigUIInfo(n)

Return the information about optional content layer UI element number `n`,
where `n` is `0 <= n < countLayerConfigUIs()`.

- **Returns:** `{ type: number, depth: number, selected: boolean, locked: boolean, text: string }`

#### PDFDocument.prototype.countLayers()

Return the number of optional content layers in this document.

- **Returns:** number

```
var layers = pdfDocument.countLayers()
```

#### PDFDocument.prototype.isLayerVisible(n)

Return whether layer `n` is visible, where `n` should be in
the interval `0 <= n < countLayers()`.

- **number n**: What layer to check visibility of.

- **Returns:** boolean

```
var visible = pdfDocument.isLayerVisible(1)
```

#### PDFDocument.prototype.setLayerVisible(n, visible)

Set layer `n` to be visible or invisible, where `n` is
in the interval `0 <= n < countLayers()`.

Pages affected by a visibility change, need to be processed
again for the layers to be visible/invisible.

- **number n**: What layer to change visibility for.
- **boolean visible**: Whether the layer should be visible.

- **Returns:** number

```
pdfDocument.setLayerVisible(1, true)
```

#### getLayerName(n)

Return the name of layer number `n`, where `n` is
`0 <= n < countLayers()`.

- **Returns:** string

```
var name = pdfDocument.getLayerName(0)
```

#### Page Labels

#### PDFDocument.prototype.setPageLabels(index, style, prefix, start)

Sets the page label numbering for the page and all pages following it, until the next page with an attached label.

- **number index**: The start page index to start labeling from.
- **string style: Can be one of the following strings**: "" (none), "D" (decimal), "R" (roman numerals upper-case), "r" (roman numerals lower-case), "A" (alpha upper-case), or "a" (alpha lower-case).
- **string prefix**: Define a prefix for the labels.
- **number start**: The ordinal with which to start numbering.

```
doc.setPageLabels(0, "D", "Prefix", 1)
```

#### PDFDocument.prototype.deletePageLabels(index)

Removes any associated page label from the page.

- **number index**: 

```
doc.deletePageLabels(0)
```

#### Saving

#### PDFDocument.prototype.check()

Check the file for syntax errors, and run a repair pass if any are
found. This is a costly operation, but may be necessary to prevent any
changes to a document from being potentially lost.

If a syntax error is discovered after a file has been edited, those
edits may be lost during the file repair pass.
In practice this rarely happens because syntax errors that trigger a
repair usually happen either when first opening the document or when
loading a page; but you can never be certain!

#### PDFDocument.prototype.canBeSavedIncrementally()

Returns whether the document can be saved incrementally, e.g.
repaired documents or applying redactions prevents incremental
saves.

- **Returns:** boolean

```
var canBeSavedIncrementally = pdfDocument.canBeSavedIncrementally()
```

#### PDFDocument.prototype.saveToBuffer(options)

Saves the document to a Buffer.

- **string options: See :doc**: `/reference/common/pdf-write-options`.

- **Returns:** `Buffer`

```
var buffer = doc.saveToBuffer("garbage=2,compress=yes")
```

#### PDFDocument.prototype.save(filename, options)

Saves the document to a file.

- **string filename**: 
- **string options: See :doc**: `/reference/common/pdf-write-options`

```
doc.save("out.pdf", "incremental")
```

#### PDFDocument.prototype.countVersions()

Returns the number of versions of the document in a PDF file,
typically 1 + the number of updates.

- **Returns:** number

```
var versionNum = pdfDocument.countVersions()
```

#### PDFDocument.prototype.hasUnsavedChanges()

Returns true if the document has been changed since it was last
opened or saved.

- **Returns:** boolean

```
var hasUnsavedChanges = pdfDocument.hasUnsavedChanges()
```

#### PDFDocument.prototype.countUnsavedVersions()

Returns the number of unsaved updates to the document.

- **Returns:** number

```
var unsavedVersionNum = pdfDocument.countUnsavedVersions()
```

#### PDFDocument.prototype.validateChangeHistory()

Check the history of the document, and determine the last
version that checks out OK. Returns `0` if the entire history
is OK, `1` if the next to last version is OK, but the last
version has issues, etc.

- **Returns:** number

```
var changeHistory = pdfDocument.validateChangeHistory()
```

#### Processing

#### PDFDocument.prototype.subsetFonts()

Scan the document and establish which glyphs are used from each
font, next rewrite the font files such that they only contain
the used glyphs. By removing unused glyphs the size of the font
files inside the PDF will be reduced.

```
pdfDocument.subsetFonts()
```

#### PDFDocument.prototype.bake(bakeAnnots, bakeWidgets)

*Baking* a document changes all the annotations and/or form fields (otherwise known as widgets) in the document into static content. It "bakes" the appearance of the annotations and fields onto the page, before removing the interactive objects so they can no longer be changed.

Effectively this removes the "annotation or "widget" type of these objects, but keeps the appearance of the objects.

- **boolean bakeAnnots**: Whether to bake annotations or not. Defaults to true.
- **boolean bakeWidgets**: Whether to bake widgets or not. Defaults to true.

#### AcroForm Javascript

#### PDFDocument.prototype.enableJS()

Enable interpretation of document Javascript actions.

```
pdfDocument.enableJS()
```

#### PDFDocument.prototype.disableJS()

Disable interpretation of document Javascript actions.

```
pdfDocument.disableJS()
```

#### PDFDocument.prototype.isJSSupported()

Returns whether interpretation of document Javascript actions
is supported. Interpretation of Javascript may be disabled at
build time.

- **Returns:** boolean

```
var jsIsSupported = pdfDocument.isJSSupported()
```

#### PDFDocument.prototype.setJSEventListener(listener)

Calls the listener whenever a document Javascript action
triggers an event.

At present the only callback the listener will be used for
is an alert event.

- **Object listener**: The Javascript listener function.

```
pdfDocument.setJSEventListener({
onAlert: function(message) {
print(message)
}
})
```

#### ZUGFeRD

#### PDFDocument.prototype.zugferdProfile()

Determine if the current PDF is a ZUGFeRD PDF, and, if so,
return the profile type in use. Possible return values include:
"NOT ZUGFERD", "COMFORT", "BASIC", "EXTENDED", "BASIC WL",
"MINIMUM", "XRECHNUNG", and "UNKNOWN".

- **Returns:** string

```
var profile = pdfDocument.zugferdProfile()
```

#### PDFDocument.prototype.zugferdVersion()

Determine if the current PDF is a ZUGFeRD PDF, and, if so,
return the version of the spec it claims to conform to.
Returns 0 for non-zugferd PDFs.

- **Returns:** number

```
var version = pdfDocument.zugferdVersion()
```

#### PDFDocument.prototype.zugferdXML()

Return a buffer containing the embedded ZUGFeRD XML data from
this ZUGFeRD PDF.

- **Returns:** `Buffer` | null

```
var buf = pdfDocument.zugferdXML()
```

### PDFFilespecParams

This object represents the information found in a :term:`file specification`.
Such files may be both external files and files embedded inside the PDF document.

This Object has the properties below. If not present in the file
specification they are set to `undefined`.

`filename`
    The name of the file.

`mimetype`
    The MIME type for an embedded file.

`size`
    The size in bytes of the embedded file contents.

`creationDate`
    The creation date of the embedded file.

`modificationDate`
    The modification date of the embedded file.

### PDFGraftMap

The graft map is a structure used to copy objects between different PDF documents,
and track which objects have already been copied so that they can be re-used.

#### Constructors

#### PDFGraftMap

*(not constructible with `new`)*

Call `PDFDocument.prototype.newGraftMap` to create a graft map.

#### Instance methods

#### PDFGraftMap.prototype.graftObject(obj)

Return a deep copy of the given object suitable for use within
the graft map's target document.

- **PDFObject object**: The object to graft.

- **Returns:** `PDFObject`

```
var map = document.newGraftMap()
map.graftObject(obj)
```

#### PDFGraftMap.prototype.graftPage(to, srcDoc, srcPage)

Graft a page and its resources at the given page number from
the source document to the requested page number in the
destination document connected to the map.

Page numbers start at 0 and -1 means at the end of the
document.

- **number to**: The page number to insert the page before.
- **PDFDocument srcDoc**: Source document.
- **number srcPage**: Source page number.

```
var map = dstdoc.newGraftMap()
map.graftObject(-1, srcdoc, 0)
```

### PDFObject

All functions that take a `PDFObject` apply an automatic translation between
Javascript objects and `PDFObject` using a few basic rules:

-
	`null`, `true`, `false`, and numbers are translated directly.

-
	Strings are translated to PDF names, unless they are surrounded by
	parentheses: `"Foo"` becomes the `/Foo` and `"(Foo)"` becomes
	`(Foo)`.

-
	Arrays and dictionaries are recursively translated to PDF arrays and dictionaries.
	Be aware of cycles though! The translation does NOT cope with cyclic references!

This automatic translation goes both ways -- entries of PDF dictionaries and
arrays can be accessed like Javascript objects and arrays.

#### Constructors

#### PDFObject

*(not constructible with `new`)*

Use the methods on a `PDFDocument` instance to create new objects.

#### Instance properties

#### PDFObject.prototype.length

Number of entries in array PDFObjects. Zero for all other object types.

#### PDFObject.prototype.[n]

Get or set the element at index `n` in an array (0-indexed).

- **Throws:** Error on out of bounds accesses.

```
var pdfObject = pdfDocument.newArray()
pdfObject[0] = "hello"
pdfObject[1] = "world"
```

#### PDFObject.prototype.[name]

Access a key named `name` in a dictionary. It is both possible to
get and set its value, but also delete the key entirely.

```
var pages = doc.getTrailer().Root.Pages
pages.Hello = "world"
pages["Xyzzy"] = 42
delete pages["Hello"]
delete pages.Xyzzy
```

#### Instance methods

#### PDFObject.prototype.get(...path)

Access dictionaries and arrays in the `PDFObject`.

Returns null if the dictionary key does not exist, or if
the array index is out of range.

- **Array<number | string | PDFObject> ...path**: The path.

- **Returns:** `PDFObject` | null

```
var dict = pdfDocument.newDictionary()
var value = dict.get("my_key")
var arr = pdfDocument.newArray()
var value = arr.get(1)
var page7 = pdfDocument.getTrailer().get("Root", "Pages", "Kids", 7)
```

#### PDFObject.prototype.getInheritable(key)

For a dictionary, if the requested key does not exist,
getInheritable() will walk Parent references to parent
dictionaries and lookup the same key there.

If no key can be found in any parent or grand-parent or
grand-grand-parent, all the way up, `null` is returned.

- **PDFObject | string key**: 

- **Returns:** `PDFObject` | null

```js
var page = pdfDocument.loadPage(0)
var pageObj = page.getObject()
var rotate = pageObj.getInheritable("Rotate")
```

#### PDFObject.prototype.put(key, value)

Set values in `PDFObject` dictionaries or arrays.

- **PDFObject | string | number key**: Interpreted as an index for arrays or a key string for dictionaries.
- **PDFObject | Array | string | number | boolean | null value**: The value to set at the array index or for dictionary key.

```
var dict = pdfDocument.newDictionary()
dict.put("my_key", "my_value")
var arr = pdfDocument.newArray()
arr.put(0, 42)
```

#### PDFObject.prototype.delete(key)

Delete a reference from a `PDFObject`.

- **number | string | PDFObject key**: 

```
var dict = pdfDocument.newDictionary()
dict.put("my_key", "my_value")
dict.delete("my_key")
var arr = pdfDocument.newArray()
arr.put(1, 42)
arr.delete(1)
```

#### PDFObject.prototype.resolve()

If the object is an indirect reference, return the object it points to; otherwise return the object itself.

- **Returns:** `PDFObject`

```
var resolvedObj = obj.resolve()
```

#### PDFObject.prototype.isArray()

- **Returns:** boolean

```
var result = obj.isArray()
```

#### PDFObject.prototype.isDictionary()

- **Returns:** boolean

```
var result = obj.isDictionary()
```

#### PDFObject.prototype.forEach(callback)

Iterate over all the entries in a dictionary or array and call a function for each value-key pair.

- **callback: ``(val: PDFObject, key: number | string, self**: PDFObject) => void``

```
obj.forEach(function (value, key) {
console.log("value="+value+",key="+key)
})
```

#### PDFObject.prototype.push(item)

Append item to the end of the object.

- **PDFObject item**: 

```
obj.push("item")
```

#### PDFObject.prototype.toString(tight, ascii)

Returns the object as a pretty-printed string.

- **boolean tight**: Whether to print the object as tightly as possible, or as human-readably as possible.
- **boolean ascii**: Whether to print binary data as ascii or as binary data.

- **Returns:** string

```
var str = obj.toString()
```

#### PDFObject.prototype.valueOf()

Try to convert a PDF object into a corresponding primitive Javascript value.

Indirect references are converted to the string "obj 0 R" where obj
is the PDF object's object number.

Names are converted to strings.

Arrays and dictionaries are not converted.

- **Returns:** A Javascript value or this.

```
var val = obj.valueOf()
```

#### PDFObject.prototype.compare(other_obj)

Compare the object to another one. Returns 0 on match, non-zero
on mismatch.

- **PDFObject other**: 

- **Returns:** number

```js
var match = pdfObj.compare(other_obj)
```

#### Streams

The only way to access a stream is via an indirect object, since all streams are numbered objects.

#### PDFObject.prototype.isStream()

Returns whether the object is an indirect reference pointing to a stream.

- **Returns:** boolean

```
var val = obj.isStream()
```

#### PDFObject.prototype.readStream()

Read the contents of the stream object into a `Buffer`.

- **Returns:** `Buffer`

```
var buffer = obj.readStream()
```

#### PDFObject.prototype.readRawStream()

Read the raw, uncompressed, contents of the stream object into a
`Buffer`.

- **Returns:** `Buffer`

```
var buffer = obj.readRawStream()
```

#### PDFObject.prototype.writeObject(obj)

Update the object the indirect reference points to.

- **PDFObject obj**: 

```
obj.writeObject(obj)
```

#### PDFObject.prototype.writeStream(buf)

Update the contents of the stream the indirect reference points to.
This will update the "Length", "Filter" and "DecodeParms" automatically.

- **Buffer | ArrayBuffer | Uint8Array buf**: 

```
obj.writeStream(buffer)
```

#### PDFObject.prototype.writeRawStream(buf)

Update the contents of the stream the indirect reference points to.
The buffer must contain already compressed data that matches
the "Filter" and "DecodeParms". This will update the "Length"
automatically, but leave the "Filter" and "DecodeParms" untouched.

- **Buffer | ArrayBuffer | Uint8Array buf**: 

```
obj.writeRawStream(buffer)
```

#### Primitive Objects

Primitive PDF objects such as booleans, names, and numbers can usually be
treated like Javascript values (thanks to valueOf). When that is not sufficient
use these functions:

#### PDFObject.prototype.isNull()

Returns true if the object is null.

- **Returns:** boolean

```
var val = obj.isNull()
```

#### PDFObject.prototype.isBoolean()

Returns whether the object is a boolean.

- **Returns:** boolean

```
var val = obj.isBoolean()
```

#### PDFObject.prototype.asBoolean()

Get the boolean primitive value.

- **Returns:** boolean

```
var val = obj.asBoolean()
```

#### PDFObject.prototype.isInteger()

Returns whether the object is an integer.

- **Returns:** boolean

```
var val = obj.isInteger()
```

#### PDFObject.prototype.isReal()

Returns whether the object is a PDF real number.

- **Returns:** boolean

```js
var val = pdfObj.isReal()
```

#### PDFObject.prototype.isNumber()

Returns whether the object is a number (an integer or a real).

- **Returns:** boolean

```
var val = obj.isNumber()
```

#### PDFObject.prototype.asNumber()

Get the number primitive value.

- **Returns:** number

```
var val = obj.asNumber()
```

#### PDFObject.prototype.isName()

Returns whether the object is a name.

- **Returns:** boolean

```
var val = obj.isName()
```

#### PDFObject.prototype.asName()

Get the name as a string.

- **Returns:** string

```
var val = obj.asName()
```

#### PDFObject.prototype.isString()

Returns whether the object is a string.

- **Returns:** boolean

```
var val = obj.isString()
```

#### PDFObject.prototype.asString()

Convert a "text string" to a Javascript unicode string.

- **Returns:** string

```
var val = obj.asString()
```

#### PDFObject.prototype.asByteString()

Convert a string to an array of byte values.

- **Returns:** Uint8Array | Array of number

```
var val = obj.asByteString()
```

#### PDFObject.prototype.isIndirect()

Is the object an indirect reference.

- **Returns:** boolean

```
var val = obj.isIndirect()
```

#### PDFObject.prototype.asIndirect()

Return the object number the indirect reference points to.

- **Returns:** number

```
var val = obj.asIndirect()
```

### PDFPage

A PDFPage inherits `Page`, so its interface is also available for
PDFPage objects.

#### Constructors

#### PDFPage

*(not constructible with `new`)*

Instances of this class are returned by :js`~Document.prototype.loadPage` called on a `PDFDocument`.

#### Instance methods

#### PDFPage.prototype.getObject()

Get the underlying `PDFObject` for a `PDFPage`.

- **Returns:** `PDFObject`

```
var obj = page.getObject()
```

#### PDFPage.prototype.getAnnotations()

Returns an array of all annotations on the page.

- **Returns:** Array of `PDFAnnotation`

```
var annots = page.getAnnotations()
```

#### PDFPage.prototype.getWidgets()

Returns an array of all widgets on the page.

- **Returns:** Array of `PDFWidget`

```
var widgets = page.getWidgets()
```

#### PDFPage.prototype.setPageBox(box, rect)

Sets the type of box required for the page.

- **string box: The :term**: `page box` type to change.
- **Rect rect**: The new desired dimensions.

```
page.setPageBox("ArtBox", [10, 10, 585, 832])
```

#### PDFPage.prototype.createAnnotation(type)

Create a new blank annotation of a given annotation type.

- **string type: The :term**: `annotation type` to create.

- **Returns:** `PDFAnnotation`.

```
var annot = page.createAnnotation("Text")
```

#### PDFPage.prototype.deleteAnnotation(annot)

Delete a `PDFAnnotation` from the page.

- **PDFAnnotation annot**: 

```
var annots = getAnnotations()
page.delete(annots[0])
```

#### PDFPage.prototype.update()

Loop through all annotations of the page and update them.

Returns true if re-rendering is needed because at least one
annotation was changed (due to either events or Javascript
actions or annotation editing).

- **Returns:** boolean

```
// edit an annotation
var updated = page.update()
```

#### PDFPage.prototype.toPixmap(matrix, colorspace, alpha, showExtras, usage, box)

Render the page into a `Pixmap` with the PDF "usage" and :term:`page box`.

- **Matrix matrix**: The transformation matrix.
- **ColorSpace colorspace**: The desired colorspace.
- **boolean alpha**: Whether or not the returned pixmap will use alpha.
- **boolean renderExtra**: Whether annotations and widgets should be rendered. Defaults to true.
- **string usage**: If the output is destined for viewing or printing. Defaults to "View".
- **string box**: Default is "CropBox".

- **Returns:** `Pixmap`

```
var pixmap = page.toPixmap(
mupdf.Matrix.identity,
mupdf.ColorSpace.DeviceRGB,
true,
false,
"View",
"CropBox"
)
```

#### PDFPage.prototype.applyRedactions(blackBoxes, imageMethod, lineArtMethod, textMethod)

Applies all the Redaction annotations on the page.

Redactions are a special type of annotation used to permanently remove (or
"redact") content from a PDF.

- **boolean blackBoxes**: Whether to use black boxes at each redaction or not.
- **number imageMethod**: Default is `PDFPage.REDACT_IMAGE_PIXELS`.
- **number lineArtMethod**: Default is `PDFPage.REDACT_LINE_ART_REMOVE_IF_COVERED`.
- **number textMethod**: Default is `PDFPage.REDACT_TEXT_REMOVE`.

Once redactions are added to a page you can *apply* them, which is an
irreversible action, thus it is a two step process as follows:

```
var annot1 = page.createAnnotation("Redaction")
annot1.setRect([0, 0, 500, 100])
var annot2 = page.createAnnotation("Redaction")
annot2.setRect([0, 600, 500, 700])
page.applyRedactions(true, mupdf.PDFPage.REDACT_IMAGE_NONE)
```

#### PDFPage.prototype.process(processor)

Run through the page contents stream and call methods on the
supplied `PDFProcessor`.

- **PDFProcessor processor**: User defined function callback object.

```js
pdfPage.process(processor)
```

#### PDFPage.prototype.getTransform()

Return the transform from PDF user space (arbitrary page origin, y
ascending, UserUnit dpi) to MuPDF page space (upper left page origin,
y descending, 72 dpi). It includes the page's `/Rotate` and CropBox
offset. Use `Matrix.invert(pdfPage.getTransform())` to go from page
space (e.g. `page.getBounds()`, search results) to user space, the
coordinates of the page's content stream.

- **Returns:** `Matrix`

```js
var transform = pdfPage.getTransform()
```

#### PDFPage.prototype.createSignature(name)

Create a new signature widget with the given name as field
label.

- **string name**: The desired field label.

- **Returns:** `PDFWidget`

```js
var signatureWidget = pdfPage.createSignature("test")
```

#### PDFPage.prototype.countAssociatedFiles()

Return the number of :term:`associated files <associated file>`
associated with this page. Note that this is the number of
files associated with this page, not necessarily the
total number of files associated with elements throughout the
entire document.

- **Returns:** number

```js
var count = pdfPage.countAssociatedFiles()
```

#### PDFPage.prototype.associatedFile(n)

Return the :term:`file specification` object that represents the nth
Associated File on this page.

`n` should be in the range `0 <= n < countAssociatedFiles()`.

Returns null if no associated file exists or index is out of range.

- **Returns:** `PDFObject` | null

```js
var obj = pdfPage.associatedFile(0)
```

#### PDFPage.prototype.clip(rect)

Clip the page to the given rectangle.

- **Rect rect**: The new desired dimensions.

```js
pdfPage.clip([0, 0, 200, 300])
```

### PDFProcessor

A PDF processor object provides callbacks that will be called for each
PDF operator when it is passed to `PDFAnnotation.prototype.process` and
`PDFPage.prototype.process`. The callbacks correspond to the equivalent
PDF operator. Refer to the PDF specification's section on `graphic
operators
<https://opensource.adobe.com/dc-acrobat-sdk-docs/pdfstandards/pdfreference1.7old.pdf#G9.3859555>`_
for what these do and what the callback arguments are.

#### Constructors

#### PDFProcessor(callbacks)

*(interface type)*

#### Special resource tracking

These are not operators per se, but are called when the
current resource dictionary used changes such as when
executing XObject forms.

- push_resources(resources)
- pop_resources()

#### General graphics state callbacks

- op_w(lineWidth: number)
- op_j(lineJoin: number)
- op_J(lineCap: number)
- op_M(miterLimit: number)
- op_d(dashPattern: Array of number, phase: number)
- op_ri(intent: string)
- op_i(flatness: number)
- op_gs(name: string, extGState: `PDFObject`)

#### Special graphics state

- op_q()
- op_Q()
- op_cm(a: number, b: number, c: number, d: number, e: number, f: number)

#### Path construction

- op_m(x: number, y: number)
- op_l(x: number, y: number)
- op_c(x1: number, y1: number, x2: number, y2: number, x3: number, y3: number)
- op_v(x2: number, y2: number, x3: number, y3: number)
- op_y(x1: number, y1: number, x3: number, y3: number)
- op_h()
- op_re(x: number, y: number, w: number, h: number)

#### Path painting

- op_S()
- op_s()
- op_F()
- op_f()
- op_fstar()
- op_B()
- op_Bstar()
- op_b()
- op_bstar()
- op_n()

#### Clipping paths

- op_W()
- op_Wstar()

#### Text objects

- op_BT()
- op_ET()

#### Text state

- op_Tc(charSpace: number)
- op_Tw(wordSpace: number)
- op_Tz(scale: number)
- op_TL(leading: number)
- op_Tf(name: string, size: number)
- op_Tr(render: number)
- op_Ts(rise: number)

#### Text positioning

- op_Td(tx: number, ty: number)
- op_TD(tx: number, ty: number)
- op_Tm(a: number, b: number, c: number, d: number, e: number, f: number)
- op_Tstar()

#### Text showing

- op_TJ(textArray: Array of (string | number))
- op_Tj(stringOrByteArray: string | Array of number)
- op_squote(stringOrByteArray: string | Array of number)
- op_dquote(wordSpace: number, charSpace: number, stringOrByteArray: string | Array of number)

#### Type 3 fonts

- op_d0(wx: number, wy: number)
- op_d1(wx: number, wy: number, llx: number, lly: number, urx: number, ury: number)

#### Color

- op_CS(name: string, colorspace: `ColorSpace`)
- op_cs(name: string, colorspace: `ColorSpace`)
- op_SC_color(color: Array of number)
- op_sc_color(color: Array of number)

- op_SC_pattern(name: string, patternID: number, color: Array of number)
- op_sc_pattern(name: string, patternID: number, color: Array of number)
- op_SC_shade(name: string, shade: `Shade`)
- op_sc_shade(name: string, shade: `Shade`)

- op_G(gray: number)
- op_g(gray: number)
- op_RG(r: number, g: number, b: number)
- op_rg(r: number, g: number, b: number)
- op_K(c: number, m: number, y: number, k: number)
- op_k(c: number, m: number, y: number, k: number)

#### Shadings

- op_sh(name: string, shade: Shade)

#### Inline images

- op_BI(image: `Image`, colorspace: `ColorSpace`)

#### XObjects (Images and Forms)

- op_Do_image(name: string, image: `Image`)
- op_Do_form(name: string, xobject: `PDFObject`, resources: `PDFObject`)

#### Marked content

- op_MP(tag: string)
- op_DP(tag: string, raw: string)
- op_BMC(tag: string)
- op_BDC(tag: string, raw: string)
- op_EMC()

#### Compatibility

- op_BX()
- op_EX()

### PDFWidget

:term:`Widgets <Widget Type>` are annotations that represent form
components such as buttons, text inputs and signature fields.

Because PDFWidget inherits `PDFAnnotation`, they also provide the
same interface as other annotation types.

Many widgets, e.g. text inputs or checkboxes, are the visual representation of
an associated form field. As the widget changes state, so does its
corresponding field value; for example when the text is edited in a text input
or a checkbox is checked. Note that widgets may be changed by Javascript event
handlers triggered by edits on other widgets.

The PDF specification has sections on `Widget annotations
<https://opensource.adobe.com/dc-acrobat-sdk-docs/pdfstandards/pdfreference1.7old.pdf#G13.1951506>`_
and
`Interactive forms
<https://opensource.adobe.com/dc-acrobat-sdk-docs/pdfstandards/pdfreference1.7old.pdf#G13.1951635>`_
with further details.

#### Constructors

#### PDFWidget

*(not constructible with `new`)*

To get the widgets on a page, see `PDFPage.prototype.getWidgets()`.

#### Instance methods

#### PDFWidget.prototype.getFieldType()

Return the widget type, one of the following:

`"button" | "checkbox" | "combobox" | "listbox" | "radiobutton" | "signature" | "text"`

- **Returns:** string

```
var type = widget.getFieldType()
```

#### PDFWidget.prototype.getFieldFlags()

Return the field flags which indicate attributes for the
field. There are convenience functions to check some of these:
:js`~PDFWidget.prototype.isReadOnly()`,
:js`~PDFWidget.prototype.isMultiline()`,
:js`~PDFWidget.prototype.isPassword()`,
:js`~PDFWidget.prototype.isComb()`,
:js`~PDFWidget.prototype.isButton()`,
:js`~PDFWidget.prototype.isPushButton()`,
:js`~PDFWidget.prototype.isCheckbox()`,
:js`~PDFWidget.prototype.isRadioButton()`,
:js`~PDFWidget.prototype.isText()`,
:js`~PDFWidget.prototype.isChoice()`,
:js`~PDFWidget.prototype.isListBox()`,
and
:js`~PDFWidget.prototype.isComboBox()`.

For details refer to the PDF specification's sections
on flags
`common to all field types
<https://opensource.adobe.com/dc-acrobat-sdk-docs/pdfstandards/pdfreference1.7old.pdf#G13.1697681>`_,
`for button fields
<https://opensource.adobe.com/dc-acrobat-sdk-docs/pdfstandards/pdfreference1.7old.pdf#G13.1697832>`_,
`for text fields
<https://opensource.adobe.com/dc-acrobat-sdk-docs/pdfstandards/pdfreference1.7old.pdf#G13.1967484>`_,
and
`for choice fields
<https://opensource.adobe.com/dc-acrobat-sdk-docs/pdfstandards/pdfreference1.7old.pdf#G13.1873701>`_.

- **Returns:** number

```
var flags = widget.getFieldFlags()
```

#### PDFWidget.prototype.getName()

Retrieve the name of the field.

- **Returns:** string

```
var fieldName = widget.getName()
```

#### PDFWidget.prototype.getMaxLen()

Get maximum allowed length of the string value.

- **Returns:** number

```
var length = widget.getMaxLen()
```

#### PDFWidget.prototype.getOptions()

Returns an array of strings which represent the value for each corresponding radio button or checkbox field.

- **Returns:** Array of string

```
var options = widget.getOptions()
```

#### PDFWidget.prototype.getLabel()

Get the field name as a string.

- **Returns:** string

```
var label = widget.getLabel()
```

#### Editing

#### PDFWidget.prototype.getValue()

Get the widget value.

- **Returns:** string

```
var value = widget.getValue()
```

#### PDFWidget.prototype.setTextValue(value)

Set the widget string value.

- **string value**: New text value.

```
widget.setTextValue("Hello World!")
```

#### PDFWidget.prototype.setChoiceValue(value)

Sets the choice value against the widget.

- **string value**: New choice value.

```
widget.setChoiceValue("Yes")
```

#### PDFWidget.prototype.toggle()

Toggle the state of the widget, returns true if the state changed.

- **Returns:** boolean

```
var state = widget.toggle()
```

#### PDFWidget.prototype.getEditingState()

Get whether the widget is in editing state.

- **Returns:** boolean

```
var state = widget.getEditingState()
```

#### PDFWidget.prototype.setEditingState(state)

Set whether the widget is in editing state.

When in editing state any changes to the widget value will not
cause any side-effects such as changing other widgets or
running Javascript event handlers. This is intended for, e.g.
when a text widget is interactively having characters typed
into it. Once editing is finished the state should reverted
back, before updating the widget value again.

- **boolean state**: 

```
widget.getEditingState(false)
```

#### PDFWidget.prototype.layoutTextWidget()

Layout the value of a text widget. Returns a text layout object.

- **Returns:** Object

```
var layout = widget.layoutTextWidget()
```

#### Flags

#### PDFWidget.prototype.isReadOnly()

If the value is read only and the widget cannot be interacted with.

- **Returns:** boolean

```
var isReadOnly = widget.isReadOnly()
```

#### PDFWidget.prototype.isRadioButton()

Return whether the widget is of "radiobutton" type.

- **Returns:** boolean

#### Signatures

#### PDFWidget.prototype.isSigned()

Returns true if the signature is signed.

- **Returns:** boolean

```
var isSigned = widget.isSigned()
```

#### PDFWidget.prototype.validateSignature()

Returns number of updates ago when signature became invalid.
Returns 0 is signature is still valid, 1 if it became
invalid during the last save, etc.

- **Returns:** number

```
var validNum = widget.validateSignature()
```

#### PDFWidget.prototype.checkCertificate()

Returns "OK" if signature checked out OK, otherwise a text
string containing an error message, e.g. "Self-signed
certificate." or "Signature invalidated by change to
document.", etc.

- **Returns:** string

```
var result = widget.checkCertificate()
```

#### PDFWidget.prototype.checkDigest()

Returns "OK" if digest checked out OK, otherwise a text string
containing an error message.

- **Returns:** string

```
var result = widget.checkDigest()
```

#### PDFWidget.prototype.getSignatory()

Returns a text string with the distinguished name from a signed
signature, or a text string with an error message.

The returned string follows the format:

``"cn=Name, o=Organization, ou=Organizational Unit,
email=jane.doe@example.com, c=US"``

- **Returns:** string

```
var signatory = widget.getSignatory()
```

#### PDFWidget.prototype.previewSignature(signer, signatureConfig, image, reason, location)

Return a `Pixmap` preview of what the signature would look like
if signed with the given configuration. Reason and location may
be `undefined`, in which case they are not shown.

- **PDFPKCS7Signer signer**: 
- **Object signatureConfig**: 
- **Image image**: 
- **string reason**: 
- **string location**: 

- **Returns:** Pixmap

```
var pixmap = widget.previewSignature(
signer,
{
showLabels: true,
showDate: true
},
image,
"",
""
)
```

#### PDFWidget.prototype.sign(signer, signatureConfig, image, reason, location)

Sign the signature with the given configuration. Reason and
location may be `undefined`, in which case they are not shown.

- **PDFPKCS7Signer signer**: 
- **Object signatureConfig**: 
- **Image image**: 
- **string reason**: 
- **string location**: 

```
widget.sign(
signer,
{
showLabels: true,
showDate: true
},
image,
"",
""
)
```

#### PDFWidget.prototype.clearSignature()

Clear a signed signature, making it unsigned again.

```
widget.clearSignature()
```

#### PDFWidget.prototype.incrementalChangesSinceSigning()

Returns true if there have been incremental changes since the
signature widget was signed.

- **Returns:** boolean

```
var changed = widget.incrementalChangesSinceSigning()
```


---

<!-- Merge-PDFs.md -->

# Merge PDFs

Combine several PDF files, or pages picked from each of them, into one PDF with the `merge` command-line tool.

**Available in [pre-release 3.7](https://www.sumatrapdfreader.org/prerelease)**

**Run `sumatrapdf-tool merge -o all.pdf a.pdf b.pdf`.** At a glance:

- **Whole files:** `sumatrapdf-tool merge -o all.pdf a.pdf b.pdf c.pdf`
- **Some pages of each file:** `sumatrapdf-tool merge -o out.pdf a.pdf 1-3 b.pdf 5`
- **Insert a file in the middle of another:** `sumatrapdf-tool merge -o out.pdf a.pdf 1-3 b.pdf a.pdf 4-N`
- **Every PDF in a folder:** a PowerShell one-liner, see below.

`sumatrapdf-tool` is installed with SumatraPDF and added to PATH. [SumatraPDF.exe merge](Tools.md) takes the same arguments. To merge by dragging thumbnails, use the [Merge PDF window](Merge-PDF-window.md).

## Merge whole files

```
sumatrapdf-tool merge -o all.pdf a.pdf b.pdf c.pdf
```

- Files are added in the order you list them.
- Put file names with spaces in quotes: `"01 intro.pdf"`.
- `-o` is the file to create. Without `-o` the result goes to `out.pdf`.

## Pick pages from each file

Put a page list after a file name to take only those pages. A file without a page list is added whole.

```
sumatrapdf-tool merge -o out.pdf a.pdf 1-3 b.pdf 5 c.pdf
```

This takes pages 1, 2 and 3 of `a.pdf`, page 5 of `b.pdf` and all of `c.pdf`.

The page list is comma-separated, with no spaces:

| Page list | Pages                                                     |
| --------- | --------------------------------------------------------- |
| `5`       | page 5                                                    |
| `1-3,7`   | pages 1, 2, 3 and 7                                       |
| `8-N`     | page 8 to the last page (`N` is the last page)            |
| `-1`      | the last page; `-2` is the second-to-last                 |
| `1--2`    | every page except the last                                |
| `N-1`     | all pages in reverse order                                |

Pages are taken in the order you list them, so the same syntax reorders and repeats pages: see [Reorder pages in a PDF](Reorder-PDF-pages.md). Note: `1-N-1` is not "all but the last page"; it repeats the last page. Use `1--2`.

You can list the same file more than once. To insert all of `b.pdf` after page 3 of `a.pdf`:

```
sumatrapdf-tool merge -o out.pdf a.pdf 1-3 b.pdf a.pdf 4-N
```

## Merge every PDF in a folder

In PowerShell, in the folder with the PDFs:

```
$files = (Get-ChildItem *.pdf | Sort-Object Name).FullName
sumatrapdf-tool merge -o ..\all.pdf $files
```

Files are merged in name order. The result is written to the parent folder so running the command again doesn't merge the previous result too.

## Merge images or other documents

`merge` reads only PDF files. For anything else it prints `Cannot merge document 'photo.png'.` and leaves that file out. Convert it to PDF first, then merge:

```
sumatrapdf-tool convert -O compress -o photo.pdf photo.png
sumatrapdf-tool merge -o out.pdf report.pdf photo.pdf
```

See [Convert images to PDF](Convert-images-to-PDF.md), [Convert EPUB to PDF](Convert-EPUB-to-PDF.md) and [Convert comics to PDF](Convert-comics-to-PDF.md).

## What the merged PDF keeps

- Bookmarks (table of contents) of each file are copied and point to the new page numbers. Bookmarks to pages you didn't take are dropped.
- Note: with a range written backwards (`N-1`, `6-4`) bookmarks keep their old page numbers. To reorder one file, use `clean` ([Reorder pages in a PDF](Reorder-PDF-pages.md)).
- `-O` sets output options, e.g. `-O compress,garbage`. See [sumatrapdf-tool merge](Tool-merge.md) for the list.

## Tips

- Check the messages after merging: if a file is missing or isn't a PDF, `merge` skips it with `Cannot merge document '...'` and still writes the output (and still exits with code 0).
- Name files `01 ...`, `02 ...` so a folder merges in the right order.
- Write the output to a new file, not over one of the inputs.
- Use [Compress a PDF](Tool-x-compress-pdf.md) if the merged file is large.

## See also

- [Split a PDF](Split-a-PDF.md) — the reverse: one PDF into several
- [Reorder pages in a PDF](Reorder-PDF-pages.md) — reverse, move and repeat pages
- [Delete pages from PDF](Tool-x-delete-pages-from-pdf.md)
- [Batch process PDFs](Batch-process-PDFs.md) — run tools over many files
- [sumatrapdf-tool merge](Tool-merge.md) — all options
- [All cmd-line tools](Tools.md)


---

<!-- Merge-PDF-window.md -->

# Merge PDF window

The **Merge PDF** window shows the pages of a PDF as thumbnails: add pages of other PDFs, drag pages into a new order, remove pages, then save the result.

**Available in [pre-release 3.7](https://www.sumatrapdfreader.org/prerelease)**

**Open it with right-click → Document → Merge PDF....** At a glance:

- **Open:** right-click → **Document** → **Merge PDF...**, or `Ctrl + K`, `Merge PDF`.
- **Add pages of another PDF:** **Add PDF...**, or drop PDF files from Explorer between two thumbnails.
- **Move pages:** drag them. A blue bar shows where they go.
- **Remove a page:** the ✕ in its top-right corner, `Delete`, **Remove**, or right-click → **Remove**.
- **Restore a removed page:** the ↻ in its corner, `Delete`, **Restore**, or right-click → **Restore**.
- **Select pages:** click, `Ctrl` + click, `Shift` + click, drag a box around them, `Ctrl + A`.
- **Save:** **Save** writes over the document, **Save As...** creates a new PDF and opens it.

## Open the Merge PDF window

- Right-click the document → **Document** → **Merge PDF...**.
- `Ctrl + K`, then `Merge PDF` in the [Command Palette](Command-Palette.md). The command is `CmdMergePDF`; bind a shortcut to it as in [Customize keyboard shortcuts](Customize-keyboard-shortcuts.md).

It works for PDF documents. The window shows the document's pages, with the current page selected.

## Add pages from other PDFs

- Click **Add PDF...** and pick one or more PDF files, then choose where their pages go: **At the end**, **At the beginning** or **After page** N. N starts as the last selected page; typing a number picks **After page**.
- Or drag PDF files from Explorer onto the thumbnails. A blue bar shows where their pages go.

With pages from more than one file, each page has a colored strip on top; the colors and file names are listed at the bottom, after the page count. Hover a page to see its file and page number.

If a PDF has a password, you're asked for it.

## Reorder pages

1. Select the pages to move.
2. Drag them. A blue bar shows where they go.
3. Release. The pages move together, in their current order, and stay selected.

Near the top or bottom edge the list scrolls while you drag. `Esc` cancels the drag.

## Remove pages

Removed pages stay in the list, dimmed, so you can change your mind. They are left out when you save.

- Hover a page and click the ✕ in its top-right corner.
- Select pages and press `Delete`, click **Remove**, or right-click → **Remove**.

To bring a page back, click the ↻ in its corner, or select it and press `Delete`, click **Restore**, or right-click → **Restore**. `Delete` removes the selected pages, or restores them when they are all removed.

## Select pages

- Click a page to select it; `Ctrl` + click adds or removes one; `Shift` + click selects a range.
- Drag a box from the space between pages; `Ctrl` + drag adds to the selection.
- Arrow keys, `Page Up` / `Page Down`, `Home` / `End` move the selection; with `Shift` they extend it.
- `Ctrl + A` selects all pages.

## Save the result

- **Save** writes the pages over the document and reloads it.
- **Save As...** writes them to a new PDF and opens it in a new tab. The document is not changed.

The document's bookmarks, links, annotations and form fields are kept and follow their pages. Unsaved annotations are included.

Note: annotations and form fields of added PDFs become part of their pages: they show as before but can't be edited. The added files aren't changed.

## Tips

- Use **Save As...** first if you're not sure: the original stays as it is.
- Use Merge PDF to delete pages by how they look; [Delete pages from PDF](Tool-x-delete-pages-from-pdf.md) takes page numbers.
- Tip: to merge many files or script it, use `sumatrapdf-tool merge` ([Merge PDFs](Merge-PDFs.md)).

## See also

- [Merge PDFs](Merge-PDFs.md) — with the command-line tool
- [Reorder pages in a PDF](Reorder-PDF-pages.md) — with the command-line tool
- [Thumbnails sidebar](Thumbnails-sidebar.md) — go to a page by its thumbnail


---

<!-- Split-a-PDF.md -->

# Split a PDF

Cut one PDF into several smaller PDFs: by page ranges, into parts of a fixed number of pages, or one file per page.

**Available in [pre-release 3.7](https://www.sumatrapdfreader.org/prerelease)**

**Take each part with `sumatrapdf-tool merge -o part1.pdf book.pdf 1-10`.** At a glance:

- **One part, in SumatraPDF:** **Extract Pages From PDF** (`CmdPdfExtractPages`).
- **Parts by page range:** one `merge` command per part.
- **One file per page:** a `for` loop in cmd.exe or PowerShell, or `draw -o page-%d.pdf`.
- **Parts of N pages:** a PowerShell loop.

`sumatrapdf-tool` is installed with SumatraPDF and added to PATH. [SumatraPDF.exe <tool>](Tools.md) takes the same arguments.

## Extract one part in SumatraPDF

1. Open the PDF.
2. Start **Extract Pages From PDF** in either of these ways:
   - Right-click the document → **Document → Extract Pages From PDF**
   - `Ctrl + K`, `Extract Pages From PDF` in [Command Palette](Command-Palette.md)
3. Check the destination path, and type the pages in **Pages To Extract:**, e.g. `11-20` or `2,5-7,13-` (`13-` means page 13 to the end).
4. Click **Extract Pages**. The new PDF opens in SumatraPDF.

Repeat for each part. More in [Extract pages from PDF](Tool-x-extract-pages-from-pdf.md).

## Split into parts by page ranges

Run one command per part:

```
sumatrapdf-tool merge -o part1.pdf book.pdf 1-10
sumatrapdf-tool merge -o part2.pdf book.pdf 11-20
sumatrapdf-tool merge -o part3.pdf book.pdf 21-N
```

`N` is the last page. For the page list syntax see [Merge PDFs](Merge-PDFs.md#pick-pages-from-each-file).

`clean` does the same; note the output file comes before the pages and there is no `-o`:

```
sumatrapdf-tool clean book.pdf part1.pdf 1-10
```

## Get the page count

The loops below need the number of pages. `info` prints it:

```
sumatrapdf-tool info book.pdf 1
```

Look for the `Pages: 120` line. The `1` at the end limits the rest of the report to page 1.

## Split into one file per page

In a cmd.exe window (replace `120` with the page count):

```
for /L %i in (1,1,120) do @sumatrapdf-tool merge -o page-%i.pdf book.pdf %i
```

In a `.bat` file, double the `%` signs. This one also reads the page count:

```
@echo off
for /f "tokens=2" %%n in ('sumatrapdf-tool info book.pdf 1 ^| findstr /b "Pages:"') do set N=%%n
for /L %%i in (1,1,%N%) do sumatrapdf-tool merge -o page-%%i.pdf book.pdf %%i
```

In PowerShell:

```
$n = [int]((sumatrapdf-tool info book.pdf 1 | Select-String '^Pages: (\d+)').Matches[0].Groups[1].Value)
1..$n | ForEach-Object { sumatrapdf-tool merge -o ("page-{0:D3}.pdf" -f $_) book.pdf $_ }
```

This names the files `page-001.pdf`, `page-002.pdf`, ... so they sort in page order.

### One command with `draw`

```
sumatrapdf-tool draw -o page-%d.pdf book.pdf
```

`%d` is replaced by the page number (`%03d` gives `page-001.pdf`). Add a page list to write only some pages: `draw -o page-%d.pdf book.pdf 1-2,7`. In a `.bat` file write `%%d`.

Note: `draw` redraws each page into a new PDF instead of copying it, so the files are bigger (in a test, 38 kB per page instead of 1 kB). Use the `merge` loop to keep pages exactly as they are.

## Split into parts of N pages

In PowerShell, parts of 10 pages named `book-1-10.pdf`, `book-11-20.pdf`, ...:

```
$n = [int]((sumatrapdf-tool info book.pdf 1 | Select-String '^Pages: (\d+)').Matches[0].Groups[1].Value)
$size = 10
for ($i = 1; $i -le $n; $i += $size) {
    $last = [Math]::Min($i + $size - 1, $n)
    sumatrapdf-tool merge -o "book-$i-$last.pdf" book.pdf "$i-$last"
}
```

## Tips

- Use `merge` rather than `draw` to split: pages, fonts and bookmarks are copied as they are.
- Bookmarks that point into a part are kept in that part.
- Run the loops in an empty folder, or put the output in a subfolder (`-o parts\page-%i.pdf`, after `mkdir parts`).
- To remove pages instead of splitting, see [Delete pages from PDF](Tool-x-delete-pages-from-pdf.md).

## See also

- [Merge PDFs](Merge-PDFs.md) — the reverse: several PDFs into one
- [Reorder pages in a PDF](Reorder-PDF-pages.md)
- [Batch process PDFs](Batch-process-PDFs.md) — run a tool over many files
- [Extract pages from PDF](Tool-x-extract-pages-from-pdf.md)
- [sumatrapdf-tool merge](Tool-merge.md), [clean](Tool-clean.md), [draw](Tool-draw.md), [info](Tool-info.md)
- [All cmd-line tools](Tools.md)


---

<!-- Reorder-PDF-pages.md -->

# Reorder pages in a PDF

Put the pages of a PDF in a new order: move, swap, reverse or repeat pages, or interleave two scans, by listing the pages in the order you want.

**Available in [pre-release 3.7](https://www.sumatrapdfreader.org/prerelease)**

**List the pages in the new order: `sumatrapdf-tool clean in.pdf out.pdf 3,1,2,4-N`.** At a glance:

- **Any order:** `3,1,2,4-N` — page 3 first, then 1, 2, and 4 to the end.
- **Reverse:** `N-1` — last page first.
- **Move the last page to the front:** `N,1--2`
- **Move the first page to the end:** `2-N,1`
- **Repeat a page:** `1,1-N` — page 1 twice.
- **Pages from several files:** `merge`, see below.
- **Interleave front and back scans:** a PowerShell loop, see below.

`sumatrapdf-tool` is installed with SumatraPDF and added to PATH. [SumatraPDF.exe <tool>](Tools.md) takes the same arguments. The tool writes a new PDF and leaves the original unchanged. To reorder pages by dragging them, use the [Merge PDF window](Merge-PDF-window.md).

## Put pages in a new order

```
sumatrapdf-tool clean in.pdf out.pdf 3,1,2,4-N
```

`out.pdf` gets the pages of `in.pdf` in the order listed. Pages you don't list are left out. Bookmarks are kept and point to the pages' new positions.

`merge` takes the same page list, with `-o` for the output:

```
sumatrapdf-tool merge -o out.pdf in.pdf 3,1,2,4-N
```

Note: with a range written backwards (`N-1`, `6-4`) `merge` puts the pages in the right order but leaves bookmarks at their old page numbers. Use `clean` to reorder a single file.

## Page list syntax

Comma-separated, no spaces. Pages are copied in the order written.

| Page list   | Result on a 6-page PDF                                    |
| ----------- | --------------------------------------------------------- |
| `3,1,2,4-N` | 3, 1, 2, 4, 5, 6 (`N` is the last page)                   |
| `1,3,2,4-N` | 1, 3, 2, 4, 5, 6 (swap pages 2 and 3)                     |
| `N-1`       | 6, 5, 4, 3, 2, 1 (reverse)                                |
| `6-4`       | 6, 5, 4 (a range written backwards runs backwards)        |
| `N,1--2`    | 6, 1, 2, 3, 4, 5 (`-2` is the second-to-last page)        |
| `2-N,1`     | 2, 3, 4, 5, 6, 1                                          |
| `1,1-N`     | 1, 1, 2, 3, 4, 5, 6 (a page listed twice is copied twice) |
| `-3--1`     | 4, 5, 6 (the last three pages)                            |

Note: `1-N-1` does not mean "all but the last page": it reads as `1-N` followed by `-1`, and repeats the last page. Use `1--2`.

Page numbers past the end are cut to the last page: `4-9` on a 6-page PDF gives 4, 5, 6.

## Reverse the page order

```
sumatrapdf-tool clean in.pdf reversed.pdf N-1
```

## Move pages between documents

`merge` takes pages from several files in one go, so you can insert pages from another PDF at any position. To put page 2 of `cover.pdf` first and all of `appendix.pdf` after page 10:

```
sumatrapdf-tool merge -o out.pdf cover.pdf 2 in.pdf 1-10 appendix.pdf in.pdf 11-N
```

See [Merge PDFs](Merge-PDFs.md).

## Interleave front and back scans

A document scanned one side at a time gives two PDFs: `fronts.pdf` (pages 1, 3, 5, ...) and `backs.pdf` (pages ..., 6, 4, 2: reversed, because the stack was turned over). To combine them in reading order, in PowerShell:

```
$n = [int]((sumatrapdf-tool info fronts.pdf 1 | Select-String '^Pages: (\d+)').Matches[0].Groups[1].Value)
$parts = foreach ($i in 1..$n) { "fronts.pdf"; "$i"; "backs.pdf"; "$($n - $i + 1)" }
sumatrapdf-tool merge -o book.pdf @parts
```

For 3 sheets this runs `merge -o book.pdf fronts.pdf 1 backs.pdf 3 fronts.pdf 2 backs.pdf 2 fronts.pdf 3 backs.pdf 1`. If `backs.pdf` is already in page order, use `"$i"` instead of `"$($n - $i + 1)"`.

## Tips

- Open the result in SumatraPDF and check the order before you delete the original.
- Use `Ctrl + K`, `Delete Pages From PDF` in SumatraPDF to drop pages without reordering ([Delete pages from PDF](Tool-x-delete-pages-from-pdf.md)).
- Use [Rotate PDF pages](Rotate-PDF-pages.md) for pages that are upside down or sideways.

## See also

- [Merge PDFs](Merge-PDFs.md) — combine pages from several PDFs
- [Split a PDF](Split-a-PDF.md) — one PDF into several
- [Delete pages from PDF](Tool-x-delete-pages-from-pdf.md)
- [sumatrapdf-tool clean](Tool-clean.md), [merge](Tool-merge.md)
- [All cmd-line tools](Tools.md)


---

<!-- Tool-x-delete-pages-from-pdf.md -->

# Delete pages from PDF

> Use `sumatrapdf-tool.exe` or [SumatraPDF.exe](Tools.md) with the same arguments.

**Available in [pre-release 3.7](https://www.sumatrapdfreader.org/prerelease)**

## In the application

To delete pages from a PDF in SumatraPDF:

- open a PDF document
- `Ctrl + K`, `Delete Pages From PDF` command in [Command Palette](Command-Palette.md)

Or:

- open a PDF document
- right-click to open the context menu
- select `Document` > `Delete Pages From PDF`

## From the command line

To delete a page from a PDF using SumatraPDF:

`sumatrapdf-tool clean input.pdf output.pdf 1-3,5-N`

This deletes page 4 from `input.pdf` and creates `output.pdf`.

You can delete any number of pages by providing the range of pages to retain.

`N` is a special character meaning "last page".

For all options, see [sumatrapdf-tool clean](Tool-clean.md).


---

<!-- Tool-x-extract-pages-from-pdf.md -->

# Extract pages from PDF

> Use `sumatrapdf-tool.exe` or [SumatraPDF.exe](Tools.md) with the same arguments.

**Available in [pre-release 3.7](https://www.sumatrapdfreader.org/prerelease)**

## In the application

To extract pages from a PDF in SumatraPDF:

- open a PDF document
- `Ctrl + K`, `Extract Pages From PDF` command in [Command Palette](Command-Palette.md)

Or:

- open a PDF document
- right-click to open the context menu
- select `Document` > `Extract Pages From PDF`

Enter the page range to consider. Select **Only with annotations** to extract
only annotated pages within that range; use `1-N` to consider the whole PDF.

## From the command line

To extract pages from a PDF using SumatraPDF on a command line:

`sumatrapdf-tool clean input.pdf output.pdf 1,2-5,8-N`

This extracts pages 1, 2, 3, 4, 5, and 8 through the last page from `input.pdf`, and saves them as `output.pdf`.

`N` is a special character meaning "last page".

## Delete page or pages from PDF

To delete a page, extract all pages except the one you want to delete. See [delete pages from PDF](Tool-x-delete-pages-from-pdf.md).


---

<!-- Rotate-PDF-pages.md -->

# Rotate PDF pages permanently

**Rotate Left** and **Rotate Right** in SumatraPDF turn the pages on screen only. To save rotated pages in the PDF file, so every viewer shows them turned, run a short script with `sumatrapdf-tool run`.

**Available in [pre-release 3.7](https://www.sumatrapdfreader.org/prerelease)**

**To fix sideways pages for good, run `rotate-pages.js` (below) on the PDF.** At a glance:

- **Rotate the view:** `[` / `]`, **View → Rotate Left / Rotate Right**. The file is not changed.
- **Rotate all pages in the file:** `sumatrapdf-tool run rotate-pages.js in.pdf out.pdf 90`
- **Rotate some pages:** `sumatrapdf-tool run rotate-pages.js in.pdf out.pdf -90 2,5-7`
- **Turn upside-down back sides of a scan:** `sumatrapdf-tool run rotate-pages.js in.pdf out.pdf 180 even`

## Rotate the view in SumatraPDF

Use any of these:

- **View → Rotate Left** or **View → Rotate Right**
- the **Rotate Left** / **Rotate Right** toolbar buttons
- `[` rotates left (counterclockwise), `]` rotates right (clockwise); `Ctrl + Shift + -` and `Ctrl + Shift + +` do the same, and so do `/` and `*` on the numeric keypad
- `Ctrl + K`, `Rotate Left` or `Rotate Right` in [Command Palette](Command-Palette.md) (`CmdRotateLeft`, `CmdRotateRight`)

Each press turns all pages of the document by 90 degrees. This only changes how SumatraPDF shows the document:

- The PDF file is not changed. Other PDF viewers, and other people you send the file to, see the original orientation.
- SumatraPDF remembers the rotation for that file and uses it next time you open it. It is saved as `Rotation` in `FileStates` in the [settings](Advanced-options-settings.md), when `RememberStatePerDocument` is `true` (the default).
- Printing pages doesn't use it. To turn the printout, use **Rotate printout** in the print dialog, see [Printing](Printing.md).

## Rotate pages in the PDF file

1. Save the script below as `rotate-pages.js`.
2. Run it with the angle and the pages to rotate:

```
sumatrapdf-tool run rotate-pages.js in.pdf out.pdf 90
```

`out.pdf` is a copy of `in.pdf` with the pages turned. [SumatraPDF.exe run](Tools.md) with the same arguments works the same.

```js
// Rotate pages of a PDF permanently.
// Usage: sumatrapdf-tool run rotate-pages.js in.pdf out.pdf [angle] [pages]
// e.g.   sumatrapdf-tool run rotate-pages.js in.pdf out.pdf 90 1,3-5,N

// ---- Settings (used when not given on the command line) ----
var ANGLE = 90      // clockwise: 90, 180 or 270; -90 turns left
var PAGES = "1-N"   // e.g. "2", "1,3-5", "4-N" (N is the last page), "odd", "even"
// ------------------

if (scriptArgs.length < 2) {
	print("usage: sumatrapdf-tool run rotate-pages.js in.pdf out.pdf [angle] [pages]")
	quit(1)
}
if (scriptArgs.length > 2) ANGLE = parseInt(scriptArgs[2])
if (scriptArgs.length > 3) PAGES = scriptArgs[3]

var doc = Document.openDocument(scriptArgs[0])
var n = doc.countPages()

// turn "1,3-5,N" into [1, 3, 4, 5, n]
function parsePages(spec) {
	var pages = []
	spec.split(",").forEach(function (part) {
		if (part == "odd" || part == "even") {
			for (var p = part == "odd" ? 1 : 2; p <= n; p += 2) pages.push(p)
			return
		}
		var r = part.replace(/N/g, n).split("-")
		for (var p = parseInt(r[0]); p <= parseInt(r[r.length - 1]); p++) pages.push(p)
	})
	return pages
}

parsePages(PAGES).forEach(function (p) {
	if (p < 1 || p > n) return
	var pageObj = doc.loadPage(p - 1).getObject()
	var old = pageObj.getInheritable("Rotate")
	var rotate = (old ? old.valueOf() : 0) + ANGLE
	pageObj.put("Rotate", ((rotate % 360) + 360) % 360)
})

doc.save(scriptArgs[1], "garbage,compress")
```

The arguments after `out.pdf` are optional:

- **angle:** `90` turns clockwise (right), `-90` or `270` counterclockwise (left), `180` upside down. Use a multiple of 90; PDF doesn't allow other angles.
- **pages:** page numbers and ranges, separated by commas, with no spaces: `3`, `1,4-6`, `10-N` (`N` is the last page), `odd` or `even`. Leave it out to rotate every page.

Without arguments, the script uses `ANGLE` and `PAGES` from the top of the script.

Examples:

| You want                                  | Command                                                         |
| ----------------------------------------- | --------------------------------------------------------------- |
| Every page to the right                   | `sumatrapdf-tool run rotate-pages.js in.pdf out.pdf 90`         |
| Page 3 to the left                        | `sumatrapdf-tool run rotate-pages.js in.pdf out.pdf -90 3`      |
| Pages 2, 5 to 8 and the last page         | `sumatrapdf-tool run rotate-pages.js in.pdf out.pdf 90 2,5-8,N` |
| Upside-down back sides of a two-sided scan | `sumatrapdf-tool run rotate-pages.js in.pdf out.pdf 180 even`   |

The script sets the rotation (`/Rotate`) of each page, adding to the rotation the page already has. The page content is not touched: text, links, bookmarks, annotations and form fields stay as they are, and the file size stays about the same.

## Rotate with sumatrapdf-tool draw

`sumatrapdf-tool draw` can also rotate, without a script:

```
sumatrapdf-tool draw -R 90 -o out.pdf in.pdf
```

It draws the pages again into a new PDF and rotates every page it writes; with a page list (`... in.pdf 2-4`) it writes only those pages. Bookmarks and links are lost, and the file can get much bigger. Use `rotate-pages.js` instead when you can. See [sumatrapdf-tool draw](Tool-draw.md).

Note: `merge` and `clean` have no rotate option.

## Tips

- Write to a new file. Saving over the input file fails with `cannot remove file`.
- Rotating pages changes the file, so it breaks existing digital signatures. Rotate before you sign.
- To rotate many files, run the script in a loop: see [Batch process PDFs](Batch-process-PDFs.md).

## See also

- [Reorder PDF pages](Reorder-PDF-pages.md) — change the order of pages
- [Crop PDF margins](Crop-PDF-margins.md) — another page-level fix for scans
- [Keyboard shortcuts](Keyboard-shortcuts.md)
- [sumatrapdf-tool run](Tool-run.md) — how scripts run
- [All cmd-line tools](Tools.md)


---

<!-- Crop-PDF-margins.md -->

# Crop PDF page margins

Make PDF pages smaller by cutting off white margins, and remove headers, footers or other content printed in the margins, from the command line. **Toggle Page Boxes** in SumatraPDF shows the boxes that set a page's size.

**Available in [pre-release 3.7](https://www.sumatrapdfreader.org/prerelease)**

**Crop every page by 36 points (half an inch) on each side: `sumatrapdf-tool run crop.js in.pdf out.pdf 36 36 36 36`.** At a glance:

- **See the page boxes:** `Ctrl + K`, `Toggle Page Boxes` (`CmdTogglePageBoxes`) in SumatraPDF, or `sumatrapdf-tool pages in.pdf`.
- **Crop the page (hide the margins):** the `crop.js` script below, run with `sumatrapdf-tool run`.
- **Remove content in the margins:** `sumatrapdf-tool trim -b mediabox -m 40 -o out.pdf in.pdf`

`sumatrapdf-tool` is installed with SumatraPDF and added to PATH. [SumatraPDF.exe <tool>](Tools.md) takes the same arguments.

## How page boxes work

- **MediaBox** is the whole sheet.
- **CropBox** is the part of the sheet that viewers, SumatraPDF included, show and print. Without a CropBox the whole MediaBox is shown.
- **BleedBox**, **TrimBox** and **ArtBox** are for print production; many PDFs don't have them.

Cropping sets the CropBox: the margins are hidden, but what's in them stays in the file. `trim` does the opposite: it deletes content outside a box but keeps the page size.

## See the page boxes

In SumatraPDF, open the PDF and press `Ctrl + K`, then `Toggle Page Boxes` in [Command Palette](Command-Palette.md). Each box the page has is outlined and labeled with its name. Run it again to hide them. In pre-release builds it is also **Debug → Show page boxes**. The command is only offered for PDF files.

From the command line:

```
sumatrapdf-tool pages in.pdf 1
```

```xml
<page pagenum="1">
<MediaBox l="0" b="0" r="595" t="842" />
<CropBox l="36" b="36" r="559" t="806" />
<Rotate v="0" />
</page>
```

Values are in points (1/72 inch), measured from the bottom-left corner. Leave out the page number to list every page. `pages` lists only the boxes set on the page itself; a MediaBox set once for the whole document isn't shown. See [sumatrapdf-tool pages](Tool-pages.md).

## Crop the margins

Save this as `crop.js`:

```js
// sumatrapdf-tool run crop.js in.pdf out.pdf top right bottom left
var doc = Document.openDocument(scriptArgs[0]);
var top = Number(scriptArgs[2]), right = Number(scriptArgs[3]);
var bottom = Number(scriptArgs[4]), left = Number(scriptArgs[5]);
for (var i = 0; i < doc.countPages(); i++) {
	var page = doc.loadPage(i);
	var r = page.getBounds("MediaBox"); // [x0, y0, x1, y1], y0 is the top
	page.setPageBox("CropBox", [r[0] + left, r[1] + top, r[2] - right, r[3] - bottom]);
}
doc.save(scriptArgs[1]);
```

Then run it with the margins to cut, in points, in the order top, right, bottom, left:

```
sumatrapdf-tool run crop.js in.pdf out.pdf 36 36 36 36
```

- 72 points = 1 inch, 28.35 points = 1 cm.
- Every page is cropped by the same amounts.
- Top and left mean as the page is shown, also on rotated pages.
- Margins are measured from the sheet (MediaBox), so cropping an already cropped file replaces the old crop instead of adding to it. To undo a crop, run it with `0 0 0 0`.

Open `out.pdf` in SumatraPDF, or check the new CropBox with `sumatrapdf-tool pages out.pdf 1`. More on scripts: [sumatrapdf-tool run](Tool-run.md).

## Remove content in the margins

`trim` deletes text, images and drawings that lie completely outside a box. To remove everything within 40 points of the page edges, e.g. running headers, footers and page numbers:

```
sumatrapdf-tool trim -b mediabox -m 40 -o out.pdf in.pdf
```

- `-b` is the box to start from: `mediabox`, `cropbox`, `bleedbox`, `trimbox` or `artbox`.
- `-m` moves the box inward (negative values move it outward): one value for all sides, `20,30` for top and bottom, left and right, or `10,20,30,40` for top, right, bottom, left.
- `-e` does the reverse: removes the content inside the box and keeps the margins.
- `-o` is required; without it `trim` stops with `argument error: no output to write to`.
- Anything that is partly inside the box is kept whole.
- The page size doesn't change. To also make the page smaller, run `crop.js` on the result.

Note: pass `-b`. Without it `trim` uses the CropBox, and on a page without one it prints `No box found for page 0` and changes nothing. `-f` falls back to the MediaBox, but then ignores `-m`.

If `trim -b mediabox` also prints `No box found for page ...`, the pages share one MediaBox set for the whole document (`sumatrapdf-tool pages` then lists no MediaBox). Give every page its own CropBox first, then trim to it:

```
sumatrapdf-tool run crop.js in.pdf tmp.pdf 0 0 0 0
sumatrapdf-tool trim -b cropbox -m 40 -o out.pdf tmp.pdf
```

More in [sumatrapdf-tool trim](Tool-trim.md).

## Tips

- Use `Toggle Page Boxes` or `pages` first to see how big the margins are.
- Use `trim` when the content must really be gone; cropping only hides it. To remove sensitive content, see [Redact a PDF](Redact-a-PDF.md).
- Write to a new file and compare it with the original in SumatraPDF before replacing it.

## See also

- [Print a large page as a poster](Print-PDF-as-poster.md) — split a page into tiles
- [Printing](Printing.md) — print a rectangular part of a page with **Print Selection**
- [sumatrapdf-tool trim](Tool-trim.md), [pages](Tool-pages.md), [run](Tool-run.md)
- [All cmd-line tools](Tools.md)


---

<!-- Print-PDF-as-poster.md -->

# Print a large page as a poster

Print a page (a map, a plan, a chart) bigger than your paper, on several sheets that you tape together. Split the page into tiles with a small script for `sumatrapdf-tool run`, then print the tiles from SumatraPDF, scaled to fill the paper.

**Available in [pre-release 3.7](https://www.sumatrapdfreader.org/prerelease)**

**Split with `sumatrapdf-tool run poster.js plan.pdf tiles.pdf 2 2`, then print `tiles.pdf` with Fit pages to printable area.** At a glance:

- **Split into tiles:** `poster.js` with the number of columns and rows.
- **Overlap for gluing:** an optional fifth argument, in points.
- **Print:** `Ctrl + P`, **Advanced** tab, **Fit pages to printable area**; or `SumatraPDF.exe -print-to-default -print-settings "fit" tiles.pdf`.

`sumatrapdf-tool` is installed with SumatraPDF and added to PATH. [SumatraPDF.exe <tool>](Tools.md) takes the same arguments.

Note: the [poster](Tool-poster.md) tool is meant for this, but in the current pre-release it stops with `format error: malformed page tree`. The script below does the same job.

## Split the page into tiles

Save this as `poster.js`:

```js
// sumatrapdf-tool run poster.js in.pdf out.pdf columns rows [overlap]
var src = Document.openDocument(scriptArgs[0]);
var out = new PDFDocument();
var cols = Number(scriptArgs[2]), rows = Number(scriptArgs[3]);
var overlap = Number(scriptArgs[4] || 0); // in points (1/72 inch)
for (var i = 0; i < src.countPages(); i++) {
	for (var y = 0; y < rows; y++) {
		for (var x = 0; x < cols; x++) {
			out.graftPage(-1, src, i);
			var page = out.loadPage(out.countPages() - 1);
			var b = page.getBounds(); // visible page: [0, 0, width, height]
			var w = b[2] / cols, h = b[3] / rows;
			page.setPageBox("CropBox", [
				Math.max(0, x * w - overlap), Math.max(0, y * h - overlap),
				Math.min(b[2], (x + 1) * w + overlap), Math.min(b[3], (y + 1) * h + overlap)]);
		}
	}
}
out.save(scriptArgs[1]);
```

Split every page of `plan.pdf` into 2 columns and 2 rows:

```
sumatrapdf-tool run poster.js plan.pdf tiles.pdf 2 2
```

- Each page becomes `columns × rows` pages, starting at the top-left tile and going row by row, left to right.
- Tiles are cut from the visible page, so a [cropped](Crop-PDF-margins.md) page is split without its margins.
- Every page of the PDF is split. For just one page, take it out first: `sumatrapdf-tool merge -o page.pdf plan.pdf 3`.

To add an overlap, give it in points (72 points = 1 inch, 28.35 points = 1 cm):

```
sumatrapdf-tool run poster.js plan.pdf tiles.pdf 2 2 20
```

Each tile then reaches 20 points past every cut, so neighboring tiles share a 40-point strip that you can glue over.

## How big the poster gets

Each tile is printed to fill a sheet, so the poster is `columns` sheets wide and `rows` sheets tall:

- An A4 page split 2 × 2 and printed on A4 paper comes out about A2 size, on 4 sheets.
- 3 × 3 gives 9 sheets, three times the width and height.

Tiles of an A4 or Letter page split 2 × 2 have the same shape as the page, so they fill the paper. SumatraPDF turns a wide tile sideways to fit the paper.

## Print the tiles

1. Open `tiles.pdf` in SumatraPDF.
2. Press `Ctrl + P`.
3. On the **Advanced** tab, under **Page scaling**, choose **Fit pages to printable area**. In the Windows 11 print dialog this is under **More settings** → **Page scaling**.
4. Print.

From the command line:

```
SumatraPDF.exe -print-to-default -print-settings "fit" tiles.pdf
```

Use `-print-to "<printer name>"` for another printer. See [Printing](Printing.md) for all options.

## Tips

- Print one tile first (e.g. **Pages** `1` in the print dialog) to check the size before printing them all.
- Printers can't print to the edge of the paper: cut the white border off one side of each sheet, or use an overlap and glue the sheets over each other.
- Write the tile number on the back of each sheet as it comes out; tiles go row by row from the top-left.
- Use `sumatrapdf-tool pages tiles.pdf` to see the area each tile covers (its CropBox).

## See also

- [Printing](Printing.md) — print dialog, page scaling, command-line printing
- [Crop PDF page margins](Crop-PDF-margins.md) — cut off white margins before splitting
- [Split a PDF](Split-a-PDF.md) — split into files, not tiles
- [sumatrapdf-tool run](Tool-run.md), [poster](Tool-poster.md)
- [All cmd-line tools](Tools.md)


---

<!-- Convert-images-to-PDF.md -->

# Convert images to PDF

Turn one image, several images, or a folder of images into a PDF with one page per image, from SumatraPDF or from the command line.

**Available in [pre-release 3.7](https://www.sumatrapdfreader.org/prerelease)**

**Open the image (or folder) and use File → Convert to PDF…** At a glance:

- **In SumatraPDF:** **Convert to PDF…** (`CmdConvertToPDF`) — the image, or every image in the folder, to one PDF.
- **Current page only:** **Convert page to PDF** (`CmdConvertImageToPdf`), via the image editor.
- **Command line:** `sumatrapdf-tool convert -O compress -o out.pdf a.png b.jpg`

To convert a comic book archive (`.cbz`, `.cbr`, ...), see [Convert comics to PDF](Convert-comics-to-PDF.md).

## Convert in SumatraPDF

1. Open an image, or a folder of images (see [Comics and manga](Comics-and-manga.md#open-a-comic-or-image-folder)).
2. Start **Convert to PDF…** in any of these ways:
   - **File → Convert to PDF…**
   - Right-click the document → **Document → Convert to PDF…**
   - Right-click an image → **Convert to PDF...**
   - `Ctrl + K`, `Convert To PDF` in [Command Palette](Command-Palette.md)
3. A dialog shows the source path and a suggested destination:
   - Default path is the same location and base name with a `.pdf` extension.
   - If that file already exists, the name is made unique (e.g. `photo.1.pdf`).
   - Edit the path in the text field, or use **…** to browse.
4. Click **Convert to PDF**. On success the new PDF is written and opened in SumatraPDF. On failure you get a short error dialog.

Press **Esc** or **Cancel** to close the dialog without converting.

Works for PNG, JPEG, WebP, JPEG XL, HEIC, AVIF, TIFF, GIF, and [other image types](Supported-document-formats.md). Animated GIFs, multi-page TIFFs and ICO files get one page per frame.

### Convert only the current page

**Convert page to PDF** (`CmdConvertImageToPdf`, on the image context menu) converts only the current page, through the image editor and a save dialog. For a single image **Convert to PDF…** gives the same one-page PDF without opening the image editor.

### How images are stored in the PDF

SumatraPDF embeds the original image bytes when PDF can use them directly:

| Format                                          | Behavior                                                                        |
| ----------------------------------------------- | ------------------------------------------------------------------------------- |
| **JPEG**, **PNG**                               | Embedded as-is (usually the most compact)                                       |
| **Animated GIF, multi-page TIFF, ICO**          | Each frame is rendered as its own page                                          |
| **WebP, JPEG XL, HEIC, AVIF, TGA**, and similar | Decoded, encoded as PNG, then losslessly recompressed (zopfli) before embedding |
| If encode/embed fails                           | Page is **rendered** into the PDF as a last resort                              |
| If every path fails for a page                  | That page is **skipped** (conversion continues with the rest)                   |

There is no quality / DPI setting: JPEG and PNG keep their original data, other formats go through a lossless PNG path. The PDF's producer metadata is set to the current SumatraPDF version (e.g. `SumatraPDF 3.7`).

## Convert from the command line

Use `sumatrapdf-tool.exe convert`, or [SumatraPDF.exe convert](Tools.md) with the same arguments.

One image:

```
sumatrapdf-tool convert -O compress -o photo.pdf photo.png
```

Several images, one page each, in the order given:

```
sumatrapdf-tool convert -O compress -o album.pdf 01.png 02.jpg 03.png
```

Every image in a folder, in file name order:

```
sumatrapdf-tool convert -O compress -o album.pdf C:\Photos\Trip
```

- `-O compress` compresses the image data. Without it PNG and other non-JPEG images are stored uncompressed: a 20 kB PNG screenshot becomes a 790 kB PDF instead of 25 kB. JPEG images are always embedded as-is.
- Reads PNG, JPEG, WebP, BMP, GIF and TIFF. For HEIC, AVIF and JPEG XL, use **Convert to PDF…** in SumatraPDF.

More options: [sumatrapdf-tool convert](Tool-convert.md).

## Tips

- Use JPEG or PNG sources for the smallest PDF; they are embedded without re-encoding.
- Name files `01.png`, `02.png`, ... so a folder converts in the right order.
- Use [Compress a PDF](Tool-x-compress-pdf.md) for documents that are already PDF.

## See also

- [Convert comics to PDF](Convert-comics-to-PDF.md)
- [Convert PDF to images](Convert-PDF-to-images.md) — the reverse direction
- [sumatrapdf-tool convert](Tool-convert.md)
- [Supported document formats](Supported-document-formats.md)
- [All cmd-line tools](Tools.md)


---

<!-- Convert-comics-to-PDF.md -->

# Convert comics to PDF

Turn a comic book archive (`.cbz`, `.cbr`, `.cb7`, `.cbt`) or an archive of images into a PDF with one page per image, from SumatraPDF or from the command line.

**Available in [pre-release 3.7](https://www.sumatrapdfreader.org/prerelease)**

**Open the `.cbz` and use File → Convert to PDF… to get one PDF with every page.** At a glance:

- **In SumatraPDF:** **Convert to PDF…** (`CmdConvertToPDF`) — all pages to one PDF.
- **Command line:** `sumatrapdf-tool convert -O compress -o book.pdf comic.cbz`

This restores the pre–3.5 comic → PDF workflow (issues [#4118](https://github.com/sumatrapdfreader/sumatrapdf/issues/4118), [#5532](https://github.com/sumatrapdfreader/sumatrapdf/issues/5532)).

## Convert in SumatraPDF

1. Open the comic (see [Comics and manga](Comics-and-manga.md#open-a-comic-or-image-folder)).
2. Start **Convert to PDF…** in any of these ways:
   - **File → Convert to PDF…**
   - Right-click the document → **Document → Convert to PDF…**
   - `Ctrl + K`, `Convert To PDF` in [Command Palette](Command-Palette.md)
3. A dialog shows the source path and a suggested destination:
   - Default path is the same location and base name with a `.pdf` extension.
   - If that file already exists, the name is made unique (e.g. `book.1.pdf`).
   - Edit the path in the text field, or use **…** to browse.
4. Click **Convert to PDF**. On success the new PDF is written and opened in SumatraPDF. On failure you get a short error dialog.

Press **Esc** or **Cancel** to close the dialog without converting.

What can be converted:

| Source              | Examples                                            |
| ------------------- | --------------------------------------------------- |
| Comic book archives | `.cbz`, `.cbr`, `.cbt`, `.cb7`, `.ora`              |
| Archives of images  | `.zip`, `.rar`, `.7z`, `.tar` that contain images   |

JPEG and PNG pages are embedded as-is, other image formats are losslessly re-encoded; see [how images are stored in the PDF](Convert-images-to-PDF.md#how-images-are-stored-in-the-pdf).

## Convert from the command line

Use `sumatrapdf-tool.exe convert`, or [SumatraPDF.exe convert](Tools.md) with the same arguments:

```
sumatrapdf-tool convert -O compress -o book.pdf comic.cbz
```

- Works for `.cbz`, `.cb7` and `.cbt`.
- `-O compress` compresses the image data. Without it PNG pages are stored uncompressed and the PDF gets much bigger. JPEG pages are always embedded as-is.
- Add a page range to convert only part of the comic: `sumatrapdf-tool convert -O compress -o chapter1.pdf comic.cbz 1-24`

More options: [sumatrapdf-tool convert](Tool-convert.md).

## See also

- [Comics and manga](Comics-and-manga.md) — opening and reading comics
- [Convert images to PDF](Convert-images-to-PDF.md)
- [Convert PDF to images](Convert-PDF-to-images.md) — the reverse direction
- [sumatrapdf-tool convert](Tool-convert.md)
- [All cmd-line tools](Tools.md)


---

<!-- Convert-EPUB-to-PDF.md -->

# Convert EPUB to PDF

Turn an EPUB ebook into a PDF from the command line with `sumatrapdf-tool convert`, or from SumatraPDF by printing to **Microsoft Print to PDF**.

**Use `sumatrapdf-tool convert -o book.pdf book.epub`: the PDF keeps selectable, searchable text.** At a glance:

- **Command line:** `sumatrapdf-tool convert -o book.pdf book.epub` — text stays text, small files, page size and font size are adjustable. **Available in [pre-release 3.7](https://www.sumatrapdfreader.org/prerelease)**
- **In SumatraPDF:** **File → Print** to the **Microsoft Print to PDF** printer — pages become images: no text selection or search, much bigger files.

**Convert to PDF…** in SumatraPDF is only for [images](Convert-images-to-PDF.md) and [comics](Convert-comics-to-PDF.md); it's not shown for EPUB.

## Convert from the command line

Use `sumatrapdf-tool.exe convert`, or [SumatraPDF.exe convert](Tools.md) with the same arguments:

```
sumatrapdf-tool convert -o book.pdf book.epub
```

The book is laid out into pages of 420 x 595 points (about A5) by default. Change the layout with:

| Option     | Meaning                                                  |
| ---------- | -------------------------------------------------------- |
| `-W <n>`   | page width in points (72 points = 1 inch)                |
| `-H <n>`   | page height in points                                    |
| `-S <n>`   | font size in points                                      |
| `-U <css>` | file name of a user stylesheet applied to the book       |
| `-X`       | ignore the book's own styles                             |

A4 pages with 12 pt text:

```
sumatrapdf-tool convert -W 595 -H 842 -S 12 -o book.pdf book.epub
```

US Letter is `-W 612 -H 792`.

Add a page range after the file name to convert only part of the book: `sumatrapdf-tool convert -o start.pdf book.epub 1-20`.

More options: [sumatrapdf-tool convert](Tool-convert.md).

## Convert in SumatraPDF (print to PDF)

1. Open the EPUB.
2. **File → Print...** (`Ctrl + P`).
3. Pick the **Microsoft Print to PDF** printer and click **Print**.
4. Choose where to save the PDF.

The same from the command line, without dialogs:

```
SumatraPDF.exe -print-to "Microsoft Print to PDF" -print-settings "output=C:\out\book.pdf" book.epub
```

SumatraPDF prints each page as an image (see [Printing](Printing.md)), so the PDF has no text layer: you can't select, copy or search text in it, and it is many times bigger than one made with `sumatrapdf-tool convert` (7 MB instead of 160 kB for a short test book).

## See also

- [sumatrapdf-tool convert](Tool-convert.md)
- [Printing](Printing.md) — `-print-to` and `-print-settings`
- [Customize eBook UI](Customize-eBook-UI.md) — how SumatraPDF shows EPUB
- [Convert images to PDF](Convert-images-to-PDF.md)
- [Convert comics to PDF](Convert-comics-to-PDF.md)
- [All cmd-line tools](Tools.md)


---

<!-- Tool-x-convert-text-to-pdf.md -->

# Convert text file to a PDF

> Use `sumatrapdf-tool.exe` or [SumatraPDF.exe](Tools.md) with the same arguments.

To use SumatraPDF to convert a text file to a PDF from the command line:

`sumatrapdf-tool convert -o output.pdf input.txt`

More info:

- [sumatrapdf-tool convert](Tool-convert.md)


---

<!-- Convert-PDF-to-images.md -->

# Convert PDF to Images

**Available in [pre-release 3.7](https://www.sumatrapdfreader.org/prerelease)**

**Convert PDF to Images** renders each chosen page of the open PDF to an image file (issue [#5991](https://github.com/sumatrapdfreader/sumatrapdf/issues/5991)).

Command id: `CmdConvertPdfToImages` (see [Commands](Commands.md)).

## When it is available

The command appears only when the open document is a **PDF**. It is hidden for comics, images, EPUB, DjVu, CHM, and other non-PDF files. For the reverse direction see [Convert images to PDF](Convert-images-to-PDF.md) and [Convert comics to PDF](Convert-comics-to-PDF.md).

## In the application

1. Open a PDF.
2. Start **Convert PDF to Images…** in any of these ways:
   - Right-click the document → **Document → Convert PDF to Images…**
   - `Ctrl + K`, `Convert PDF to Images...` command in [Command Palette](Command-Palette.md)
3. A dialog shows the source path and a destination **template**:
   - Default is the same folder and base name as the PDF, with `-<N>.png` (for `book.pdf`, `book-<N>.png`).
   - `<N>` is replaced by the 1-based page number (`book-1.png`, `book-2.png`, …).
   - A **format** drop-down (PNG, JPEG, BMP) next to the path works like Save Image: picking a format updates the file extension.
   - Edit the path, or use **…** to browse. If the chosen name has no `<N>`, `-<N>` is inserted before the extension.
4. Choose which pages to convert:
   - **Current** — the page you are viewing
   - **All** — every page (the default)
   - **Custom** — a range in the edit box, same syntax as Extract Pages: `1,3-5,8-` (`N` is the last page)
5. Click **Convert**. On success, Explorer opens on the first written file. On failure you get a short error dialog.

Press **Esc** or **Cancel** to close the dialog without converting.

Pages are rendered at the **Resolution (DPI)** you pick: 72, 96, **150** (default), 300, 600 or 1200, or type any other value. It is independent of your current zoom level. A page that would exceed 16384 pixels per side is refused with "Too large for this DPI". PNG files are losslessly recompressed in the background (the same Zopfli pass as Save Image).

## From the command line

`sumatrapdf-tool convert` can also write images. Use `%d` in the output name for the page number:

```
sumatrapdf-tool convert -o book-%d.png book.pdf
sumatrapdf-tool convert -o book-%d.png book.pdf 1-3,8
```

## See also

- [Convert images to PDF](Convert-images-to-PDF.md), [Convert comics to PDF](Convert-comics-to-PDF.md) — the reverse direction
- [Extract text from PDF](Tool-x-extract-text-from-pdf.md)
- [Extract pages from PDF](Tool-x-extract-pages-from-pdf.md)
- **Save Selection As Image** (`CmdSaveSelectionAsImage`) — a rectangular selection, at a chosen DPI, not a whole page


---

<!-- Convert-PDF-to-grayscale.md -->

# Convert a PDF to grayscale

Make a gray copy of a PDF file with `sumatrapdf-tool recolor`, or only view pages in gray in SumatraPDF with **Toggle Grayscale**.

**Available in [pre-release 3.7](https://www.sumatrapdfreader.org/prerelease)**

**To make a gray PDF file, run `sumatrapdf-tool recolor -c gray -o gray.pdf color.pdf`.** At a glance:

- **Gray PDF file:** `sumatrapdf-tool recolor` rewrites the colors of text, graphics and images as shades of gray.
- **View in gray:** **Toggle Grayscale** (`CmdToggleGrayscale`) shows pages in gray on screen. The file doesn't change.
- **Print in gray:** `monochrome` in `-print-settings`, or print the gray PDF made by `recolor`.

## Make a grayscale PDF file

Use `sumatrapdf-tool recolor`, or [SumatraPDF.exe recolor](Tools.md) with the same arguments:

```
sumatrapdf-tool recolor -c gray -o report-gray.pdf report.pdf
```

- Every page is converted: text, vector graphics and images.
- `-c gray` is the default, so `sumatrapdf-tool recolor -o report-gray.pdf report.pdf` does the same.
- Without `-o` the result is written to `out.pdf` in the current folder.
- Add `-r` to also remove output intents (color profiles for print production).
- The command prints nothing when it succeeds.

Open the new file in SumatraPDF to check it, or render a page to an image: `sumatrapdf-tool draw -o check.png report-gray.pdf 1`.

`recolor` can also convert to other color spaces: `-c rgb` or `-c cmyk`.

Note: colors of similar brightness become similar grays. In a test, red text, a blue box and green text came out as 47%, 35% and 52% gray, so a chart that relies on color alone can become hard to read.

## View pages in grayscale in SumatraPDF

`Ctrl + K`, then `Toggle Grayscale` in [Command Palette](Command-Palette.md). Run it again to go back to color.

- It isn't in any menu. To give it a shortcut, [customize a keyboard shortcut](Customize-keyboard-shortcuts.md) for `CmdToggleGrayscale`.
- It changes only how pages look on screen. The file isn't modified and printing isn't affected.
- It applies to all documents and is remembered after restart: it's saved as `Grayscale` in `FixedPageUI` in [advanced settings](Advanced-options-settings.md). You can also set it there:

```
FixedPageUI [
    Grayscale = true
]
```

- Only the page image is gray. Text selection, search highlights and other things drawn on top of the page keep their colors.

## Print in grayscale

**Toggle Grayscale** doesn't change the printout. Instead:

- From the command line, add `monochrome` to `-print-settings`. It asks the printer driver to print in black and white:

```
SumatraPDF.exe -print-to "Office Printer" -print-settings "monochrome" report.pdf
```

- In the print dialog (`Ctrl + P`), choose grayscale or black and white in the printer's own options. The option's name depends on the printer driver.
- Or print the gray PDF made with `recolor`. That works with every printer.

See [Printing](Printing.md) for all print options.

## Tips

- Use `recolor` before sending a document to a black-and-white printer or copier, to see how it will look.
- Use **Toggle Grayscale** to read a colorful document with less distraction, without making a copy.
- To make gray images of pages instead of a PDF, use `sumatrapdf-tool convert -o page%d.png -O colorspace=gray report.pdf` (see [Convert PDF to images](Convert-PDF-to-images.md)).
- To convert a whole folder, see [Process many PDFs at once](Batch-process-PDFs.md).

## See also

- [sumatrapdf-tool recolor](Tool-recolor.md) — all options
- [Printing](Printing.md) — `-print-settings` and the print dialog
- [Command Palette](Command-Palette.md) — run **Toggle Grayscale**
- [All cmd-line tools](Tools.md)


---

<!-- Redact-a-PDF.md -->

# Redact a PDF

Permanently remove confidential text, images and graphics from a PDF: mark what to remove with **Redact**, then **Apply Redactions** to delete it and cover the spot with a black box.

**Available in [pre-release 3.7](https://www.sumatrapdfreader.org/prerelease)**

**Select the text, right-click → Annotations → Create From Selection → Redact, then Annotations → Apply Redactions, then save to a new PDF.** At a glance:

- **Mark:** **Redact** (`CmdCreateAnnotRedact`) marks selected text, or an area you drag out. Marks are red outlines.
- **Apply:** **Apply Redactions** (`CmdApplyRedactions`) removes everything under every mark and draws black boxes.
- **Undo:** `Ctrl + Z` brings the content back until you save.
- **Save:** `Ctrl + S` saves to a new PDF.

A mark on its own removes nothing: the text is still in the file until you apply the redactions and save.

## Mark text for redaction

1. Select the text.
2. Mark it in any of these ways:
   - Right-click → **Annotations → Create From Selection → Redact**
   - **Redact** button on the [Edit PDF](Editing-annotations.md#turn-on-edit-pdf-mode) toolbar
   - `Ctrl + K`, then `Create Redact Annotation` in [Command Palette](Command-Palette.md)

The selected text gets a red outline. Repeat for everything you want to remove.

## Mark an area for redaction

Use this for images, signatures, or anything that isn't text.

1. With no text selected, click the **Redact** button on the Edit PDF toolbar (or `Ctrl + K`, `Create Redact Annotation`).
2. *Mark content for redaction. Drag or click twice.* Drag a rectangle over the area, or click two opposite corners. `Esc` cancels.

## Change or remove a mark

Marks are annotations. In Edit PDF mode, click a mark to select it, drag it to [move it](Editing-annotations.md#move-an-annotation), or press `Delete` to [delete it](Editing-annotations.md#delete-an-annotation).

## Apply the redactions

Apply every mark in the document in any of these ways:

- Right-click → **Annotations → Apply Redactions**
- **Apply Redactions** button on the Edit PDF toolbar, next to **Redact**. It shows up once you've marked something.
- `Ctrl + K`, then `Apply Redactions` in [Command Palette](Command-Palette.md)

The command is available only while the document has redaction marks. It also applies marks that came with the PDF.

What applying does, under each mark:

- **Text** is deleted from the page. It can no longer be selected, searched or copied.
- **Images:** the covered pixels are blanked; the rest of the image stays.
- **Vector graphics** (lines, shapes, table borders) that touch the mark are removed, even the parts outside it.
- A **black box** is drawn over the area.

The marks disappear and *Redactions applied.* is shown. `Ctrl + Z` ([Undo](Editing-annotations.md#undo-and-redo)) restores the content until you save.

## Save the redacted PDF

Save to a new file so you keep the original:

- `Ctrl + S`, or `Ctrl + K`, then `Save Annotations to a new PDF` (`CmdSaveAnnotationsNewFile`)
- Right-click → **Annotations → Save to new file**, or the tab's context menu → **Save changes to new PDF**

`Ctrl + Shift + S` (**Save changes**) overwrites the original.

After redacting, SumatraPDF writes the whole file anew rather than appending the change, so the removed content is not left in an older revision inside the file. Once saved, the redaction can't be undone.

## Check the result

Open the saved PDF and make sure the content is gone:

- Search for the redacted text with `Ctrl + F`.
- Try to select text where the black boxes are.
- From the command line, search the file: `sumatrapdf-tool grep "123-45-6789" redacted.pdf` prints nothing when the text is gone. See [sumatrapdf-tool grep](Tool-grep.md).

Note: only content under the marks is removed. The same text elsewhere — on other pages, in bookmarks, in document properties, in attachments — stays.

## Tips

- Mark everything first, then apply once.
- Use an area mark over images and scanned pages: scanned text is a picture, and text search won't find it.
- Leave a margin around graphics you don't want removed; any line that touches a mark goes.
- Search the whole document (`Ctrl + F`) for every occurrence before you apply.

## See also

- [Editing annotations](Editing-annotations.md) — Edit PDF mode, selecting and deleting marks, undo
- [Flatten PDF forms and annotations](Flatten-PDF-forms-and-annotations.md) — make other annotations part of the page
- [sumatrapdf-tool grep](Tool-grep.md) — search PDFs from the command line


---

<!-- Add-an-image-to-a-PDF.md -->

# Add an image to a PDF

Put a picture on a PDF page — a scanned signature, a logo, a "PAID" stamp — from an image file or the clipboard, then move and resize it and save.

**Available in [pre-release 3.7](https://www.sumatrapdfreader.org/prerelease)**

**Right-click where the image should go → Annotations → Create Under Cursor → Image From File..., pick the image, drag it into place, and save.** At a glance:

- **From a file:** **Insert Image...** (`CmdInsertImage`).
- **From the clipboard:** **Image From Clipboard** (`CmdCreateAnnotImageFromClipboard`).
- **Move / resize:** drag the image, or its corner handles, in [Edit PDF](Editing-annotations.md#turn-on-edit-pdf-mode) mode.
- **Save:** `Ctrl + Shift + S` saves into the PDF; `Ctrl + S` saves to a new PDF.

The image is added as an image stamp annotation. It prints and shows in other PDF readers, and can still be moved or deleted until you [flatten the PDF](Flatten-PDF-forms-and-annotations.md).

Note: this is a picture of a signature, not a digital signature. To sign with a certificate, see [Sign a PDF](Sign-a-PDF.md).

## Insert an image from a file

1. Start **Insert Image...** in any of these ways:
   - Right-click the page where the image should go → **Annotations → Create Under Cursor → Image From File...**
   - Right-click the page → **Document → Insert Image...**
   - `Ctrl + K`, then `Insert Image` in [Command Palette](Command-Palette.md)
2. Pick an image: PNG, JPEG, BMP, GIF, TIFF, WebP, HEIC or ICO.
3. The image is placed with its top-left corner where you right-clicked (from the Command Palette: at the mouse pointer). It keeps its natural size (96 DPI unless the file says otherwise).

SumatraPDF turns on Edit PDF mode and selects the image, so you can move it right away.

## Insert an image from the clipboard

1. Copy an image in another program (for example **Copy image** in a web browser, or a screenshot).
2. Right-click the page where the image should go → **Annotations → Create Under Cursor → Image From Clipboard**, or `Ctrl + K`, then `Create Image Annotation From Clipboard` (placed at the mouse pointer).

When the clipboard has no image, the menu item is greyed out and the command is not in the Command Palette.

Note: `Ctrl + V` (**Paste Image From Clipboard**, `CmdPasteClipboardImage`) does not put the image on the page. It saves the clipboard image as `clipboard.png` in the SumatraPDF data folder and opens it in a new tab. In Edit PDF mode, `Ctrl + V` pastes a copied annotation instead.

## Move and resize the image

In Edit PDF mode:

- **Move:** drag the image.
- **Resize:** click the image to select it, then drag a resize handle. The image keeps its proportions.
- **Delete:** select it and press `Delete`.
- **Copy to another page or PDF:** `Ctrl + C`, then `Ctrl + V` at the new spot. See [Copy, cut and paste annotations](Editing-annotations.md#copy-cut-and-paste-annotations).
- **Undo:** `Ctrl + Z`.

## Save the PDF

- `Ctrl + Shift + S` saves into the PDF (`CmdSaveAnnotations`).
- `Ctrl + S` saves to a new PDF (`CmdSaveAnnotationsNewFile`); it suggests `<name> Copy.pdf`.
- The **Save** button at the end of the Edit PDF toolbar; hover over it for **Save changes to a new PDF** and **Discard changes**.

More ways, and the prompt you get when closing with unsaved changes: [Save annotations to the PDF](Editing-annotations.md#save-annotations-to-the-pdf).

## Add an image from the command line

`sumatrapdf-tool run` with a short [JavaScript](Tool-run.md) program adds an image stamp. `stamp-image.js`:

```js
// usage: sumatrapdf-tool run stamp-image.js in.pdf image.png out.pdf
var doc = mupdf.Document.openDocument(scriptArgs[0]);
var page = doc.loadPage(0);
var img = new mupdf.Image(scriptArgs[1]);
var annot = page.createAnnotation("Stamp");
// [left, top, right, bottom] in points (1/72 inch) from the top-left corner of the page
annot.setRect([400, 40, 400 + img.getWidth() / 2, 40 + img.getHeight() / 2]);
annot.setStampImage(img);
annot.update();
doc.save(scriptArgs[2]);
```

```
sumatrapdf-tool run stamp-image.js invoice.pdf logo.png out.pdf
```

`loadPage(0)` is the first page.

## Tips

- Use a PNG with a transparent background for a signature, so only the ink covers the page.
- Scan or photograph your signature at a high resolution and scale it down on the page: it stays sharp when printed.
- Put the image on the clipboard once and use **Image From Clipboard** on every page that needs it.
- [Flatten the PDF](Flatten-PDF-forms-and-annotations.md) before sending it if the image shouldn't be moved or removed.

## See also

- [Sign a PDF](Sign-a-PDF.md) — a digital signature, which can also show your signature image
- [Fill a PDF form](Fill-PDF-forms.md)
- [Editing annotations](Editing-annotations.md) — other annotations, Edit PDF mode, saving
- [Flatten PDF forms and annotations](Flatten-PDF-forms-and-annotations.md)


---

<!-- Add-page-numbers-to-PDF.md -->

# Add page numbers to a PDF

Stamp "Page 3 of 10" (or just "3") on every page of a PDF with a short script you run with `sumatrapdf-tool run`.

**Available in [pre-release 3.7](https://www.sumatrapdfreader.org/prerelease)**

**Save the script below as `add-page-numbers.js` and run it on your PDF.** At a glance:

- **Run:** `sumatrapdf-tool run add-page-numbers.js in.pdf out.pdf`
- **Text:** `FORMAT` is `Page {n} of {total}`, `{n}`, `- {n} -`, ...
- **Position:** `POSITION` puts the number at the bottom or top, left, center or right; `MARGIN` sets the distance from the edge.
- **Look:** `FONT`, `FONT_SIZE`, `COLOR`.
- **Cover page:** `SKIP_PAGES` leaves the first pages without a number; `FIRST_NUMBER` sets where counting starts.

## Add page numbers

1. Save the script as `add-page-numbers.js`.
2. Change the settings at the top of the script, if you want.
3. Run it:

```
sumatrapdf-tool run add-page-numbers.js in.pdf out.pdf
```

`out.pdf` is a copy of `in.pdf` with a page number on every page. [SumatraPDF.exe run](Tools.md) with the same arguments works the same.

```js
// Add page numbers to every page of a PDF.
// Usage: sumatrapdf-tool run add-page-numbers.js in.pdf out.pdf

// ---- Settings ----
var FORMAT = "Page {n} of {total}" // "{n}" for just the number
var POSITION = "bottom-center"     // bottom-left, bottom-center, bottom-right,
                                   // top-left, top-center, top-right
var MARGIN = 24                    // distance from the page edge, in points (72 = 1 inch)
var FONT = "Helvetica"             // Helvetica, Times-Roman, Courier, Helvetica-Bold, ...
var FONT_SIZE = 10                 // in points
var COLOR = [0, 0, 0]              // red, green, blue from 0 to 1
var SKIP_PAGES = 0                 // leave the first N pages (e.g. a cover) without a number
var FIRST_NUMBER = 1               // number shown on the first numbered page
// ------------------

if (scriptArgs.length != 2) {
	print("usage: sumatrapdf-tool run add-page-numbers.js in.pdf out.pdf")
	quit(1)
}

var doc = Document.openDocument(scriptArgs[0])
var font = new Font(FONT)
var fontRef = doc.addSimpleFont(font)
var total = FIRST_NUMBER + doc.countPages() - SKIP_PAGES - 1

// open "q" before the page's own content, close it with "Q" after,
// so changes the page makes to the graphics state don't affect our text
var saveState = doc.addStream("q\n")

function textWidth(s) {
	var w = 0
	for (var i = 0; i < s.length; i++)
		w += font.advanceGlyph(font.encodeCharacter(s.charCodeAt(i)), 0)
	return w * FONT_SIZE
}

function num(v) {
	return Math.round(v * 100) / 100
}

function pdfString(s) {
	return "(" + s.replace(/[\\()]/g, "\\$&") + ")"
}

for (var i = SKIP_PAGES; i < doc.countPages(); i++) {
	var page = doc.loadPage(i)
	var pageObj = page.getObject()

	// add the font to the page resources
	var res = pageObj.getInheritable("Resources")
	if (!res) {
		res = doc.newDictionary()
		pageObj.put("Resources", res)
	}
	if (!res.get("Font"))
		res.put("Font", doc.newDictionary())
	res.get("Font").put("PageNumFont", fontRef)

	// page size as you see it (crop box, after rotation)
	var b = page.getBounds()
	var w = b[2] - b[0], h = b[3] - b[1]

	var text = FORMAT.replace("{n}", FIRST_NUMBER + i - SKIP_PAGES).replace("{total}", total)
	var tw = textWidth(text)
	var x = MARGIN, y = MARGIN
	if (POSITION.indexOf("center") >= 0) x = (w - tw) / 2
	if (POSITION.indexOf("right") >= 0) x = w - MARGIN - tw
	if (POSITION.indexOf("top") >= 0) y = h - MARGIN - FONT_SIZE

	// map "bottom-left corner as you see it, y up" to the page's own coordinates;
	// handles /Rotate and crop boxes that don't start at 0,0
	var m = Matrix.concat([1, 0, 0, -1, b[0], b[3]], Matrix.invert(page.getTransform()))

	var stamp = "\nQ q " + m.map(num).join(" ") + " cm " +
		"BT /PageNumFont " + FONT_SIZE + " Tf " + COLOR.join(" ") + " rg " +
		num(x) + " " + num(y) + " Td " + pdfString(text) + " Tj ET Q\n"

	// new page content: q, the old content, Q, page number
	var contents = doc.newArray()
	contents.push(saveState)
	var old = pageObj.get("Contents")
	if (old && old.isArray())
		old.forEach(function (c) { contents.push(c) })
	else if (old)
		contents.push(old)
	contents.push(doc.addStream(stamp))
	pageObj.put("Contents", contents)
}

doc.save(scriptArgs[1], "garbage,compress")
```

The numbers are part of the page, so they show in every PDF viewer and print. They are real text: you can search for them and select them.

The number is placed on the page as you see it: landscape pages, pages with a rotation (`/Rotate`) and cropped pages get it at the bottom of the visible page, reading left to right.

## Change the text and position

Edit the settings at the top of the script:

| You want                                   | Setting                                          |
| ------------------------------------------ | ------------------------------------------------ |
| Just the number: `7`                       | `FORMAT = "{n}"`                                 |
| `- 7 -`                                    | `FORMAT = "- {n} -"`                             |
| Number in the bottom right corner          | `POSITION = "bottom-right"`                      |
| Number at the top                          | `POSITION = "top-center"`                        |
| Closer to the edge                         | `MARGIN = 12`                                    |
| Bigger, bold, gray                         | `FONT_SIZE = 14`, `FONT = "Helvetica-Bold"`, `COLOR = [0.5, 0.5, 0.5]` |
| No number on the cover, page 2 shows `1`   | `SKIP_PAGES = 1`                                 |
| No number on the cover, page 2 shows `2`   | `SKIP_PAGES = 1`, `FIRST_NUMBER = 2`             |
| Continue from a previous file, start at 41 | `FIRST_NUMBER = 41`                              |

`{total}` is the last number printed, so `Page {n} of {total}` stays right when you skip pages or start at another number.

`FONT` is a standard PDF font: `Helvetica`, `Times-Roman` or `Courier`, or a bold or italic variant such as `Helvetica-Bold`, `Times-Italic`, `Courier-Oblique`, `Helvetica-BoldOblique`. Standard fonts are not embedded, so the file stays small. Use only Latin characters in `FORMAT`.

## Number many PDFs

Run the script in a loop. In `cmd.exe`, to write numbered copies of every PDF in the current folder to a `numbered` folder:

```
mkdir numbered
for %f in (*.pdf) do sumatrapdf-tool run add-page-numbers.js "%f" "numbered\%f"
```

More: [Batch process PDFs](Batch-process-PDFs.md).

## Tips

- Write to a new file. Saving over the input file fails with `cannot remove file`.
- Keep the original: running the script twice stamps the numbers twice.
- Open `out.pdf` in SumatraPDF to check the position before you number many files.
- Adding numbers changes the pages, so it breaks existing digital signatures. Number the PDF before you sign it.
- To number only part of a document, [split it](Split-a-PDF.md), number the part, and [merge](Merge-PDFs.md) it back.

## See also

- [Add a watermark to a PDF](Add-a-watermark-to-PDF.md) — "DRAFT" across every page, same approach
- [Batch process PDFs](Batch-process-PDFs.md) — run the script on many files
- [sumatrapdf-tool run](Tool-run.md) — how scripts run
- [JavaScript API reference](Tool-run-javascript-reference.md) — the objects the script uses
- [All cmd-line tools](Tools.md)


---

<!-- Add-a-watermark-to-PDF.md -->

# Add a watermark to a PDF

Put a large, semi-transparent "DRAFT" or "CONFIDENTIAL" across every page of a PDF, or a logo image, with a short script you run with `sumatrapdf-tool run`.

**Available in [pre-release 3.7](https://www.sumatrapdfreader.org/prerelease)**

**Save the script below as `add-watermark.js` and run it on your PDF.** At a glance:

- **Run:** `sumatrapdf-tool run add-watermark.js in.pdf out.pdf`
- **Text:** `TEXT`, `FONT`, `COLOR`; `FONT_SIZE = 0` sizes it to fit the page.
- **Angle:** `ANGLE = -1` follows the page diagonal; `0` is horizontal.
- **Transparency:** `OPACITY` from `0` (invisible) to `1` (solid).
- **Over or under:** `UNDER = true` draws it behind the page content.
- **Logo:** `IMAGE` adds a PNG or JPEG at the center of every page.

## Add a text watermark

1. Save the script as `add-watermark.js`.
2. Change `TEXT` and the other settings at the top of the script, if you want.
3. Run it:

```
sumatrapdf-tool run add-watermark.js in.pdf out.pdf
```

`out.pdf` is a copy of `in.pdf` with the watermark on every page. [SumatraPDF.exe run](Tools.md) with the same arguments works the same.

```js
// Add a semi-transparent text or image watermark to every page of a PDF.
// Usage: sumatrapdf-tool run add-watermark.js in.pdf out.pdf

// ---- Settings ----
var TEXT = "DRAFT"          // "" for no text
var FONT = "Helvetica-Bold" // Helvetica, Times-Roman, Courier, Times-Bold, ...
var FONT_SIZE = 0           // in points; 0 fits the text across the page
var COLOR = [1, 0, 0]       // red, green, blue from 0 to 1
var ANGLE = -1              // degrees counter-clockwise; -1 follows the page diagonal
var IMAGE = ""              // path of a PNG or JPEG logo, drawn at the center; "" for none
var IMAGE_WIDTH = 0.4       // image width as a fraction of the page width
var OPACITY = 0.3           // 0 is invisible, 1 is solid
var UNDER = false           // true puts the watermark under the page content
// ------------------

if (scriptArgs.length != 2) {
	print("usage: sumatrapdf-tool run add-watermark.js in.pdf out.pdf")
	quit(1)
}

var doc = Document.openDocument(scriptArgs[0])
var font = new Font(FONT)
var fontRef = doc.addSimpleFont(font)
var gsRef = doc.addObject({ Type: "ExtGState", ca: OPACITY, CA: OPACITY })
var image = IMAGE ? new Image(IMAGE) : null
var imageRef = image ? doc.addImage(image) : null
var saveState = doc.addStream("q\n")

function num(v) {
	return Math.round(v * 1000) / 1000
}

function pdfString(s) {
	return "(" + s.replace(/[\\()]/g, "\\$&") + ")"
}

function textWidth(s, size) {
	var w = 0
	for (var i = 0; i < s.length; i++)
		w += font.advanceGlyph(font.encodeCharacter(s.charCodeAt(i)), 0)
	return w * size
}

// add a resource to the page, e.g. addResource(pageObj, "Font", "WmFont", fontRef)
function addResource(pageObj, type, name, ref) {
	var res = pageObj.getInheritable("Resources")
	if (!res) {
		res = doc.newDictionary()
		pageObj.put("Resources", res)
	}
	if (!res.get(type))
		res.put(type, doc.newDictionary())
	res.get(type).put(name, ref)
}

for (var i = 0; i < doc.countPages(); i++) {
	var page = doc.loadPage(i)
	var pageObj = page.getObject()
	addResource(pageObj, "ExtGState", "WmGS", gsRef)

	// page size as you see it (crop box, after rotation)
	var b = page.getBounds()
	var w = b[2] - b[0], h = b[3] - b[1]

	// map "center of the page as you see it, y up" to the page's own coordinates;
	// handles /Rotate and crop boxes that don't start at 0,0
	var center = Matrix.concat([1, 0, 0, -1, b[0] + w / 2, b[1] + h / 2],
		Matrix.invert(page.getTransform()))

	var s = "q /WmGS gs\n"
	if (TEXT) {
		addResource(pageObj, "Font", "WmFont", fontRef)
		var angle = ANGLE == -1 ? Math.atan2(h, w) * 180 / Math.PI : ANGLE
		var size = FONT_SIZE
		if (!size) {
			// the biggest size at which the rotated text fits in 80% of the page
			var c = Math.abs(Math.cos(angle * Math.PI / 180))
			var sn = Math.abs(Math.sin(angle * Math.PI / 180))
			var tw = textWidth(TEXT, 1), th = 0.7 // text height (capitals), at size 1
			size = 0.8 * Math.min(w / (tw * c + th * sn), h / (tw * sn + th * c))
		}
		var m = Matrix.concat(Matrix.rotate(angle), center)
		s += "q " + m.map(num).join(" ") + " cm BT /WmFont " + num(size) + " Tf " +
			COLOR.join(" ") + " rg " + num(-textWidth(TEXT, size) / 2) + " " +
			num(-0.35 * size) + " Td " + pdfString(TEXT) + " Tj ET Q\n"
	}
	if (image) {
		addResource(pageObj, "XObject", "WmImage", imageRef)
		var iw = IMAGE_WIDTH * w
		var ih = iw * image.getHeight() / image.getWidth()
		var m = Matrix.concat([iw, 0, 0, ih, -iw / 2, -ih / 2], center)
		s += "q " + m.map(num).join(" ") + " cm /WmImage Do Q\n"
	}
	s += "Q\n"

	// new page content: watermark, then the old content, or
	// q, the old content, Q, then watermark
	var contents = doc.newArray()
	if (UNDER)
		contents.push(doc.addStream(s))
	else
		contents.push(saveState)
	var old = pageObj.get("Contents")
	if (old && old.isArray())
		old.forEach(function (c) { contents.push(c) })
	else if (old)
		contents.push(old)
	if (!UNDER)
		contents.push(doc.addStream("\nQ " + s))
	pageObj.put("Contents", contents)
}

doc.save(scriptArgs[1], "garbage,compress")
```

The watermark is centered on the page as you see it, including landscape pages, pages with a rotation (`/Rotate`) and cropped pages. With `FONT_SIZE = 0` the text is as big as fits in 80% of each page, so it scales with the page size.

## Change the look

Edit the settings at the top of the script:

| You want                          | Setting                                      |
| --------------------------------- | -------------------------------------------- |
| Different text                    | `TEXT = "CONFIDENTIAL"`                      |
| Gray instead of red               | `COLOR = [0.5, 0.5, 0.5]`                    |
| Lighter                           | `OPACITY = 0.15`                             |
| Horizontal                        | `ANGLE = 0`                                  |
| Always 45 degrees                 | `ANGLE = 45`                                 |
| Fixed size, e.g. 72 points        | `FONT_SIZE = 72`                             |
| Serif font                        | `FONT = "Times-Bold"`                        |

`FONT` is a standard PDF font: `Helvetica`, `Times-Roman` or `Courier`, or a bold or italic variant such as `Helvetica-Bold`, `Times-Italic`, `Courier-Oblique`. Standard fonts are not embedded, so the file stays small. Use only Latin characters in `TEXT`.

## Put the watermark under the content

Set `UNDER = true`. The page's text and pictures are drawn on top of the watermark, so it never covers anything.

Note: Anything opaque on the page hides the watermark under it: images, colored backgrounds, and the whole page of a scanned document. For scans, keep `UNDER = false`.

## Add a logo or image watermark

Set `IMAGE` to the path of a PNG or JPEG file:

```js
var TEXT = ""               // "" for no text
var IMAGE = "C:\\Pictures\\logo.png"
var IMAGE_WIDTH = 0.4       // image width as a fraction of the page width
```

- The image is centered, `IMAGE_WIDTH` of the page width, with `OPACITY` applied.
- Keep `TEXT` to get both the text and the image.
- Transparent areas of a PNG stay transparent.
- Write `\\` for each `\` in the path, or use `/`: `"C:/Pictures/logo.png"`.

## Tips

- Write to a new file. Saving over the input file fails with `cannot remove file`.
- Keep the original: the watermark becomes part of the page content and there is no easy way to take it out.
- The watermark text is real text: it shows up when you search or copy text from the page.
- Adding a watermark changes the pages, so it breaks existing digital signatures. Add it before you sign.
- To watermark many files, run the script in a loop: see [Batch process PDFs](Batch-process-PDFs.md).

## See also

- [Add page numbers to a PDF](Add-page-numbers-to-PDF.md) — same approach, a number on every page
- [Add an image to a PDF](Add-an-image-to-a-PDF.md) — one image on one page
- [Batch process PDFs](Batch-process-PDFs.md) — run the script on many files
- [sumatrapdf-tool run](Tool-run.md) — how scripts run
- [JavaScript API reference](Tool-run-javascript-reference.md) — the objects the script uses


---

<!-- Add-table-of-contents-to-PDF.md -->

# Add a table of contents to a PDF

Get a clickable table of contents (bookmarks) for a PDF that has none: let SumatraPDF build one from the numbered headings for reading, or save real bookmarks into the PDF with a short script.

**Available in [pre-release 3.7](https://www.sumatrapdfreader.org/prerelease)**

**Press `Ctrl + K` and run `Generate Table Of Contents` to get bookmarks for a paper or report without an outline.** At a glance:

- **Generate Table Of Contents** (`CmdAutoGenerateTOC`): builds bookmarks from numbered headings and shows them in the sidebar. Not saved into the file.
- **`AutoGenerateTOC` setting:** does the same every time you open a PDF without an outline.
- **Save bookmarks into the PDF:** `sumatrapdf-tool run add-toc.js in.pdf out.pdf`, a script that writes the outline you list.
- **Show / hide Bookmarks:** `F12`

## Generate a table of contents from headings

1. Open the PDF.
2. Press `Ctrl + K` and run `Generate Table Of Contents` in [Command Palette](Command-Palette.md). The command is only in the Command Palette, and only for PDF-like documents.
3. The **Bookmarks** sidebar opens once the headings are found. On a long document this takes a moment; you can keep reading meanwhile.

If the PDF already has a table of contents, the command just shows it.

SumatraPDF looks for lines that start with a section number and a period, followed by a word that doesn't start with a lowercase letter:

- `1. Introduction`, `2.3. Results`, `1.2 Scope`
- Roman numerals: `IV. Discussion`, `II.A. Setup`

Numbering decides nesting: `2.3.` goes under `2.`, `II.A.` goes under `II.`. Headings without a number (`Chapter One`, `Abstract`) are not found, and a scanned PDF without a text layer gives no headings.

Note: the generated table of contents exists only while the document is open. It is not written into the PDF, so other PDF readers don't see it. To keep bookmarks in the file, see [Save bookmarks into the PDF](#save-bookmarks-into-the-pdf).

### Generate it automatically

To build the table of contents every time you open a PDF that has none, set `AutoGenerateTOC = true` in [advanced settings](Advanced-options-settings.md) (**Settings → Advanced Settings...**). It is off by default because badly scanned (OCRed) text makes the scan slow and the result useless.

## Save bookmarks into the PDF

SumatraPDF can't edit bookmarks in the window. Use the [`run`](Tool-run.md) command-line tool with a script that writes the outline and saves a new PDF.

1. Save this as `add-toc.js` and edit the list: `title` is the bookmark text, `page` the page number (1 is the first page), `children` the nested bookmarks.

   ```js
   // usage: sumatrapdf-tool run add-toc.js in.pdf out.pdf
   var toc = [
       { title: "Chapter 1", page: 1 },
       { title: "Chapter 2", page: 2, children: [
           { title: "Section 2.1", page: 3 },
       ]},
       { title: "Chapter 3", page: 4 },
   ];

   function addItems(it, items) {
       for (var i = 0; i < items.length; i++) {
           var t = items[i];
           it.insert({ title: t.title, uri: "#page=" + t.page, open: true });
           if (t.children) {
               it.prev(); // move to the item just inserted
               it.down(); // its (empty) list of children
               addItems(it, t.children);
               it.up();
               it.next();
           }
       }
   }

   var doc = Document.openDocument(scriptArgs[0]);
   var it = doc.outlineIterator();
   while (it.item()) {
       it.delete(); // remove the existing outline, if any
   }
   addItems(it, toc);
   doc.save(scriptArgs[1], "garbage,compress");
   ```

2. Run it:

   ```
   sumatrapdf-tool run add-toc.js report.pdf report-toc.pdf
   ```

3. Check the result without opening the file:

   ```
   sumatrapdf-tool show report-toc.pdf outline
   ```

   ```
   |	"Chapter 1"	#page=1
   +	"Chapter 2"	#page=2
   |		"Section 2.1"	#page=3
   |	"Chapter 3"	#page=4
   ```

The script replaces any existing outline. To add to it instead, remove the `while` loop: new bookmarks are then inserted before the first existing one.

Use `SumatraPDF.exe run` instead of `sumatrapdf-tool run` if you only have SumatraPDF installed (see [Tools](Tools.md)).

### Make bookmarks from large text

If the headings are set in a bigger font than the body text, this script adds a bookmark for every line at least a given size (18 points by default):

```js
// usage: sumatrapdf-tool run toc-from-headings.js in.pdf out.pdf [min-font-size]
var minSize = scriptArgs.length > 2 ? parseFloat(scriptArgs[2]) : 18;
var doc = Document.openDocument(scriptArgs[0]);
var it = doc.outlineIterator();
while (it.item()) {
    it.delete();
}
var n = doc.countPages();
for (var i = 0; i < n; i++) {
    var text = JSON.parse(doc.loadPage(i).toStructuredText().asJSON(1));
    text.blocks.forEach(function (block) {
        (block.lines || []).forEach(function (line) {
            var title = line.text.trim();
            if (line.font.size >= minSize && title.length > 0) {
                it.insert({ title: title, uri: "#page=" + (i + 1), open: true });
            }
        });
    });
}
doc.save(scriptArgs[1], "garbage,compress");
```

```
sumatrapdf-tool run toc-from-headings.js report.pdf report-toc.pdf 20
```

It makes a flat list. Run `sumatrapdf-tool show report-toc.pdf outline` to see what it picked up, and adjust the size.

## Tips

- Use `Shift + F12` (**Command Palette: Table Of Contents**) to jump to a bookmark by typing part of its title.
- Write the output to a new file. Saving over the PDF you opened fails with `Permission denied`.
- Use `Generate Table Of Contents` first to see which headings a document has, then copy them into `add-toc.js`.
- Open a bookmark from the command line with `-named-dest "Chapter 2"` (see [Open a PDF at a page or search term](Open-PDF-at-page-from-command-line.md)).

## See also

- [sumatrapdf-tool run](Tool-run.md) and the [JavaScript reference](Tool-run-javascript-reference.md) (`OutlineIterator`)
- [sumatrapdf-tool show](Tool-show.md): inspect the outline of a PDF
- [Advanced settings](Advanced-options-settings.md): `AutoGenerateTOC`
- [Command Palette](Command-Palette.md)


---

<!-- Flatten-PDF-forms-and-annotations.md -->

# Flatten PDF forms and annotations

Make filled-in form fields and annotations (highlights, notes, text boxes, stamps, images) part of the page, so they can't be edited any more and look the same in every PDF reader and printer. SumatraPDF calls this *baking*.

**Available in [pre-release 3.7](https://www.sumatrapdfreader.org/prerelease)**

**Right-click the page → Document → Bake PDF, and click Bake PDF.** At a glance:

- **In SumatraPDF:** **Bake PDF File...** (`CmdPdfBake`) — bakes forms and annotations into a new PDF and opens it.
- **Command line:** `sumatrapdf-tool bake form.pdf flat.pdf`
- **Keep one kind interactive:** `bake -A` keeps annotations, `bake -F` keeps form fields.

After baking:

- Form fields are gone: the values you typed, ticked or picked are printed on the page. The PDF is no longer a fillable form.
- Annotations are gone as annotations: they are drawn on the page and can't be selected, moved or deleted.
- Text from form fields and text boxes can still be selected and searched.

## Bake a PDF in SumatraPDF

1. Open the PDF. Fill in the form or add annotations first; see [Fill a PDF form](Fill-PDF-forms.md) and [Editing annotations](Editing-annotations.md).
2. Start **Bake PDF** in any of these ways:
   - Right-click the page → **Document → Bake PDF**
   - `Ctrl + K`, then `Bake PDF File` in [Command Palette](Command-Palette.md)
3. The **Bake PDF** dialog shows the source path and a destination:
   - The default is the same folder and name, made unique: `form.pdf` becomes `form.1.pdf`.
   - Edit the path, or click **...** to browse.
4. Click **Bake PDF**. The baked PDF is written and opened in SumatraPDF. The original is not changed.

Unsaved changes (form values, annotations) are included: you don't have to save before baking. `Esc` or **Cancel** closes the dialog.

The app always bakes both form fields and annotations. To keep one of them interactive, use the command line.

## Bake from the command line

Use `sumatrapdf-tool.exe bake`, or [SumatraPDF.exe bake](Tools.md) with the same arguments.

Bake form fields and annotations:

```
sumatrapdf-tool bake form.pdf flat.pdf
```

Without an output file name, the result is written to `out.pdf`.

Bake only the form fields; annotations stay editable:

```
sumatrapdf-tool bake -A form.pdf flat.pdf
```

Bake only the annotations; form fields stay fillable:

```
sumatrapdf-tool bake -F form.pdf flat.pdf
```

More: [sumatrapdf-tool bake](Tool-bake.md).

## Bake before you sign

Baking rewrites the PDF. Baking a digitally signed PDF removes the signature (with `-F` the signature field stays, but the signature is no longer valid). Fill in and bake first, then [sign](Sign-a-PDF.md) the baked copy.

## Tips

- Bake a filled form before you email it, so the recipient sees your answers in any viewer and can't change them.
- Keep the unbaked PDF if you may need to change the answers later; baking can't be undone.
- Bake after [adding a signature image](Add-an-image-to-a-PDF.md) so it can't be moved or deleted.
- Use `bake -F` to fix annotations in place but leave a form fillable.
- To remove confidential content, use [Redact a PDF](Redact-a-PDF.md), not baking: baking draws annotations on top of the page but removes nothing under them.

## See also

- [Fill a PDF form](Fill-PDF-forms.md)
- [Editing annotations](Editing-annotations.md)
- [Sign a PDF](Sign-a-PDF.md)
- [sumatrapdf-tool bake](Tool-bake.md)
- [All cmd-line tools](Tools.md)


---

<!-- Tool-x-extract-text-from-pdf.md -->

# Extract text from PDF using SumatraPDF

> Use `sumatrapdf-tool.exe` or [SumatraPDF.exe](Tools.md) with the same arguments.

**Available in [pre-release 3.7](https://www.sumatrapdfreader.org/prerelease)**

## In the application

To extract text from a PDF in SumatraPDF:

- open a PDF document
- `Ctrl + K`, `Extract Text From Document` command in [Command Palette](Command-Palette.md)

Or:

- open a PDF document
- right-click to open the context menu
- select `Document` > `Extract Text From Document`

![Extract text from PDF in SumatraPDF](https://files.sumatrapdfreader.org/assets/sumatrapdf/docs/img/extract-text-dialog-2814.png)

This extracts text from the document and saves it as a text file.

You can extract text from all pages or select a subset of pages.

## From the command line

You can use the SumatraPDF command line to extract text from a PDF file.

### Extract all text from PDF

`sumatrapdf-tool convert -o output.txt input.pdf`

### Extract text from selected pages of a PDF

`sumatrapdf-tool convert -o output.txt input.pdf 1-3,4,8-9`

This extracts text from pages 1, 2, 3, 4, 8, and 9.

# Structured text

PDF files don't really contain text. Text is made of glyphs (characters) in a given font, positioned at `(x,y)` coordinates on a page.

Text extraction is based on heuristics, i.e. the program tries to identify words and lines based on the positions of characters.

Structured text is detailed information about every character on the page:

- font
- glyph
- `(x,y)` position on the page
- bounding box (area) of the glyph

For example, in XML format it looks like:

```xml
<font name="CharisSIL" size="7.9701">
<char quad="187.4652 295.9985 191.96033 295.9985 187.4652 301.9683 191.96033 301.9683" x="187.4652" y="301.871" bidi="0" color="#000000" alpha="#ff" flags="16" c="d"/>
```

This shows that the letter `d` in the `CharisSIL` font is at a given x/y position on the page.

You can use this output in your custom processing program.

### Extract structured text from PDF in XML format

`sumatrapdf-tool draw -o foo.stext foo.pdf`

### Extract structured text from PDF in JSON format

`sumatrapdf-tool draw -o foo.stext.json -F stext.json foo.pdf`

It's the same information but in JSON format.


---

<!-- Tool-x-extract-images-from-pdf.md -->

# Extract images from a PDF

> Use `sumatrapdf-tool.exe` or [SumatraPDF.exe](Tools.md) with the same arguments.

**Available in [pre-release 3.7](https://www.sumatrapdfreader.org/prerelease)**

You can use SumatraPDF from the command line to extract images embedded in a PDF file.

To extract all images: `sumatrapdf-tool extract input.pdf`

It will save each image in a file named `image-<object number>.<ext>` in the current folder, with the number padded to 4 digits (e.g. `image-0003.png`).

The image extension depends on the file type; for example, JPEG images will be saved as `.jpg` files.

## To extract specific images

You can extract only specific images. In a PDF file, each image has an object number.

First, you need to find the object numbers of the embedded images: `sumatrapdf-tool info -I input.pdf`

The output looks like:

```
Images (9):
        1       (1189 0 R):     [ Flate ] 400x300 8bpc DevRGB (3 0 R)
        1       (1189 0 R):     [ Flate ] 400x300 8bpc DevRGB (6 0 R)
        1       (1189 0 R):     [ Flate ] 602x250 8bpc DevRGB (10 0 R)
        1       (1189 0 R):     [ Flate ] 278x288 8bpc DevRGB (15 0 R)
```

`3`, `6`, `10`, and `15` are object numbers.

To extract images 3 and 15: `sumatrapdf-tool extract input.pdf 3 15`

Reference:

- [sumatrapdf-tool extract](Tool-extract.md)
- [sumatrapdf-tool info](Tool-info.md)


---

<!-- Extract-fonts-from-PDF.md -->

# Extract fonts from a PDF

List the fonts a PDF uses with `sumatrapdf-tool info -F`, and save the embedded font files with `sumatrapdf-tool extract`.

**Available in [pre-release 3.7](https://www.sumatrapdfreader.org/prerelease)**

**Run `sumatrapdf-tool extract file.pdf` to save every embedded font (and image).** At a glance:

- **List fonts:** `sumatrapdf-tool info -F file.pdf`
- **Which fonts are embedded:** **Document Properties** in SumatraPDF (`Ctrl + D`)
- **Save all fonts and images:** `sumatrapdf-tool extract file.pdf`
- **Save one font:** `sumatrapdf-tool extract file.pdf <font descriptor number>`

Use `sumatrapdf-tool.exe`, or [SumatraPDF.exe <tool>](Tools.md) with the same arguments.

## List the fonts in a PDF

```
sumatrapdf-tool info -F fonts.pdf
```

```
fonts.pdf:

PDF-1.7

Pages: 1

Retrieving info from pages 1-1...
Fonts (3):
	1	(12 0 R):	TrueType "Georgia" WinAnsiEncoding (3 0 R)
	1	(12 0 R):	TrueType "Consolas" WinAnsiEncoding (6 0 R)
	1	(12 0 R):	Type1 "Helvetica" WinAnsiEncoding (9 0 R)
```

Each line is: page number, the page's object, font type, font name, encoding and the font's object number.

- A name like `EASOZS+Times-Roman` (6 letters and `+`) is a subset: only the characters used in the document are embedded.
- `info` doesn't say whether a font is embedded. In SumatraPDF, open the PDF and press `Ctrl + D` (**File → Properties**). The **Fonts:** list at the bottom marks embedded fonts, e.g. `Georgia (TrueType; Ansi; embedded)`.

Add a page list to see the fonts of some pages only: `sumatrapdf-tool info -F file.pdf 2-3`.

## Save all embedded fonts

```
sumatrapdf-tool extract fonts.pdf
```

```
extracting font-0005.ttf
extracting font-0008.ttf
```

- Files are written to the current folder, not the folder of the PDF.
- `extract` also saves all images (`image-0003.png`, ...). See [Extract images from a PDF](Tool-x-extract-images-from-pdf.md).
- Fonts that aren't embedded (like `Helvetica` above) are skipped: there is no font file in the PDF.
- Existing files with the same name are overwritten.

The file name is `font-<number>.<ext>`. The number is the object number of the font's descriptor, padded to 4 digits. The extension is the font format:

| Extension | Font format                        |
| --------- | ---------------------------------- |
| `.ttf`    | TrueType                           |
| `.cff`    | Type 1 font in CFF (compact) form  |
| `.cid`    | CID font in CFF form               |
| `.otf`    | OpenType                           |
| `.pfa`    | Type 1                             |

For example, a PDF made by groff has its Type 1 fonts stored as CFF:

```
extracting font-0008.cff
extracting font-0010.cff
extracting font-0012.cff
extracting font-0014.cff
extracting font-0016.cff
```

## Save one font

`extract` takes the object number of the font's descriptor, which is not the number `info -F` shows. To find it, show the font object from `info -F` (here `3`) with [`sumatrapdf-tool show`](Tool-show.md):

```
sumatrapdf-tool show fonts.pdf 3
```

The output contains a line like `/FontDescriptor 5 0 R`. Extract object `5`:

```
sumatrapdf-tool extract fonts.pdf 5
```

```
extracting font-0005.ttf
```

Note: `sumatrapdf-tool extract fonts.pdf 3` (the number from `info -F`) saves nothing and reports no error.

## When extract finds no fonts

Some PDFs (for example, one made with **Microsoft Print to PDF**) keep the font descriptor inside the font object instead of as a separate object. `extract` doesn't see those fonts and saves nothing. Save the font data with `show` instead:

1. Show the font object from `info -F`:

   ```
   sumatrapdf-tool show lorem.pdf 11
   ```

2. Find the font file in the output, e.g. `/FontFile2 8 0 R` (`FontFile2` is TrueType, `FontFile3` is CFF or OpenType, `FontFile` is Type 1).
3. Save that object's data:

   ```
   sumatrapdf-tool show -b -o font.ttf lorem.pdf 8
   ```

`-b` writes the decompressed stream data only, which is the font file.

## Tips

- Subset fonts contain only the characters used in the document; they are not complete fonts.
- A `.cff` or `.cid` file is bare font data; Windows can't install it without converting it first.
- Check the font's license before you reuse it; embedding a font in a PDF doesn't make it free to use.
- To extract fonts from many PDFs, see [Process many PDFs at once](Batch-process-PDFs.md).

## See also

- [sumatrapdf-tool extract](Tool-extract.md)
- [sumatrapdf-tool info](Tool-info.md)
- [sumatrapdf-tool show](Tool-show.md)
- [See PDF info: pages, page size, fonts, security](Show-PDF-info.md)
- [All cmd-line tools](Tools.md)


---

<!-- Save-page-region-as-image.md -->

# Save part of a page as an image

Copy or save a rectangular part of a page (a chart, a table, a formula) as an image, save a picture embedded in a document, or take a screenshot of a window.

**Available in [pre-release 3.7](https://www.sumatrapdfreader.org/prerelease)**

**Hold `Ctrl`, drag a rectangle over the page, then right-click it and choose Selection → Save As Image...** At a glance:

- **Copy As Image To Clipboard** (`CmdCopySelectionAsImage`): the selected area, at the current zoom.
- **Save As Image...** (`CmdSaveSelectionAsImage`): the selected area as PNG, JPEG or BMP, at a chosen DPI.
- **Selected Image** menu: copy, save, crop or resize a picture embedded in the page, at its own resolution.
- **Take Screenshot...** (`CmdScreenshot`): capture the desktop or a window, then crop and save it.

To turn whole pages into images, see [Convert PDF to images](Convert-PDF-to-images.md).

## Select an area

Hold `Ctrl` and drag with the left mouse button. A rectangle is drawn over the page.

- Drag an edge or a corner of the rectangle to resize it, or drag inside it to move it.
- Press `Esc`, or click an empty part of the page, to remove it.

Note: a plain drag over text selects text, and a right-button drag pans the page. The image commands need a rectangle.

## Copy the area to the clipboard

With a rectangle selected, use any of:

- Right-click → **Selection → Copy As Image To Clipboard**
- `Ctrl + K`, then `Copy Selection As Image` in [Command Palette](Command-Palette.md)
- `Ctrl + C`: copies the text inside the rectangle and the image, so a word processor pastes text and an image editor pastes the picture

The image is rendered at the current zoom: zoom in before copying for more pixels. Rotation is kept.

## Save the area as an image file

1. Select a rectangle.
2. Start **Save As Image...**:
   - Right-click → **Selection → Save As Image...**
   - `Ctrl + K`, then `Save As Image...` in [Command Palette](Command-Palette.md)
3. In the **Save Selection As Image** dialog:
   - The path defaults to the document's folder and name with `-sel.png`, e.g. `report-sel.png` (made unique if it exists). Edit it, or use **...** to browse.
   - Pick the format: **PNG**, **JPEG** or **BMP**. The extension follows.
   - Pick the **Resolution (DPI)**: 72, 96, 150, **300** (default), 600 or 1200, or type any other value. The resulting size in pixels is shown next to it. The DPI doesn't depend on your zoom.
4. Click **Save**. The image is written and opened in a new tab.

If the size shows "Too large for this DPI", pick a lower DPI or a smaller area (the limit is 16384 pixels per side).

## Save a picture from the page

To get a photo or figure that is embedded in the document as an image, right-click it and open **Selected Image**:

- **Copy To Clipboard** (`CmdCopyImage`)
- **Save** (`CmdSaveImage`)
- **Crop** (`CmdCropImage`)
- **Resize** (`CmdResizeImage`)
- **Convert to PDF...** (see [Convert images to PDF](Convert-images-to-PDF.md))

You get the image at its own resolution, not at the zoom you view it at. The menu appears only when the mouse is over an image; for text, vector drawings, or a part of an image, use a rectangle and **Save As Image...** instead.

**Save**, **Crop** and **Resize** open the image editing window:

- The path defaults to the document's folder: `<document>_page_<N>` with the image's own extension, e.g. `report_page_3.jpg`.
- Formats: PNG, JPEG, BMP, GIF, TIFF, WebP (when Windows has the WebP encoder) and PDF.
- If you don't change the image and keep its format, the original bytes are saved, with no re-compression.
- **Crop:** drag over the image to draw the crop area, then **Apply Crop**. Arrow keys move an edge by one pixel.
- **Resize:** drag a corner, or use the arrow keys to change width and height by one pixel, then **Apply Resize**.
- **Copy** puts the current (cropped or resized) image on the clipboard.

For an image file open in SumatraPDF (PNG, JPEG, ...), the same commands are in [Command Palette](Command-Palette.md): `Save Image...`, `Crop Image...`, `Resize Image...`.

## Take a screenshot

**Take Screenshot...** (`CmdScreenshot`) captures the desktop and every visible window, including other programs.

1. Press `Ctrl + K` and run `Take Screenshot...`.
2. Thumbnails of the captures appear. Use the arrow keys or the mouse to pick one:
   - `Enter` or a click: open it in the **Crop Image** window, to crop, resize, pick a format and save.
   - `Ctrl + C`: copy it to the clipboard.
   - `Esc`: cancel.

Screenshots are saved by default in the `Screenshots` folder of the SumatraPDF data folder, named after the program (e.g. `SumatraPDF.png`).

### Set a screenshot hotkey

To take a screenshot with a key, even when SumatraPDF isn't in front:

1. Press `Ctrl + K` and run `Set Screenshot Hotkey...` (`CmdSetScreenshotHotkey`).
2. Press the key combination, e.g. `Alt + PrtSc`, and click **Set**. **Remove** clears it.

This saves a `Shortcuts` entry for `CmdScreenshot` with a `Global` key; you can also write it yourself (see [Customize keyboard shortcuts](Customize-keyboard-shortcuts.md)). There is no hotkey by default.

## Tips

- Use **Save As Image...** at 300 DPI or more for print; **Copy As Image To Clipboard** is fine for a chat or an e-mail.
- Use `Ctrl + 4` (**Zoom To Selection**) to fill the window with the rectangle before copying it at a higher resolution.
- Use the image context menu's **Save** for photos: you get the original file, not a re-rendered copy.
- Use [sumatrapdf-tool extract](Tool-x-extract-images-from-pdf.md) to save every image of a PDF at once.

## See also

- [Convert PDF to images](Convert-PDF-to-images.md): whole pages as image files
- [Extract images from PDF](Tool-x-extract-images-from-pdf.md): from the command line
- [Printing](Printing.md#print-part-of-a-page): print the selected area
- [Keyboard shortcuts](Keyboard-shortcuts.md)


---

<!-- Save-PDF-attachments.md -->

# Save files attached to a PDF

A PDF can carry other files: attached to the whole document (listed in the Bookmarks sidebar) or to a spot on a page (a paperclip or pushpin icon). Open or save them from SumatraPDF, or save them all from the command line.

**Right-click the attachment and choose Save Attachment.** At a glance:

- **Files attached to the document:** listed at the end of the **Bookmarks** sidebar (`F12`); right-click → **Save Attachment...** or **Open Attachment**.
- **File attachment on a page:** click the icon to open the file; right-click → **Save Attachment**.
- **Command line:** `sumatrapdf-tool extract file.pdf` saves every attached file (plus images and fonts).
- **Command line, original names:** a short `run` script, see [below](#save-attachments-with-their-names).

## Save a file attached to the document

1. Open the PDF and show the sidebar: `F12`, or **View → Show Bookmarks**. Attached files are listed after the table of contents, by file name. Hover one to see `Attachment: ...`.
2. Right-click the file name and choose:
   - **Save Attachment...** (`CmdSaveAttachment`): a save dialog opens with the attachment's name in the PDF's folder.
   - **Open Attachment** (`CmdOpenAttachment`): opens it in a new tab. Shown only for `.pdf` attachments.

Clicking an attachment in the sidebar does nothing; use the right-click menu.

Note: the sidebar menu can also show **Save Embedded File...** (`CmdSaveEmbeddedFile`) and **Open Embedded PDF** (`CmdOpenEmbeddedPDF`), for bookmark entries that link to an embedded file. They work the same way.

## Save a file attached to a page

A file attachment annotation shows as an icon on the page, for example a paperclip or a pushpin.

- **Open it:** click the icon. A file SumatraPDF can open (a PDF, an image, ...) opens in a new tab (ver 3.7+). For other files, save them.
- **Save it:** right-click the icon → **Save Attachment**, then pick where to save. The name defaults to the attachment's name in the PDF's folder.
- **In Edit PDF mode:** click the annotation; its property row has **Save Attachment** (see [Editing annotations](Editing-annotations.md)).

To attach a file yourself, use the **File Attachment** annotation (see [Editing annotations](Editing-annotations.md)).

None of these commands are in the [Command Palette](Command-Palette.md): they act on the attachment you right-click.

## Save attachments from the command line

**Available in [pre-release 3.7](https://www.sumatrapdfreader.org/prerelease)**

### Save everything

```
sumatrapdf-tool extract report.pdf
```

```
extracting file-0017.csv (data.csv)
extracting file-0019.txt (notes.txt)
```

- Files attached to the document and to pages are both saved, as `file-<object number>.<extension>`. The original name is printed in parentheses.
- Files go to the current folder, not the PDF's folder.
- `extract` also saves every image and font in the PDF. To save only one file, give its object number: `sumatrapdf-tool extract report.pdf 17`.

To find the object numbers of document attachments without extracting anything:

```
sumatrapdf-tool show report.pdf trailer/Root/Names/EmbeddedFiles/Names
```

```
[ (data.csv) 17 0 R ]
```

More options: [sumatrapdf-tool extract](Tool-extract.md).

### Save attachments with their names

This script saves document attachments and page attachments to the current folder, under their own names. Save it as `save-attachments.js`:

```js
// usage: sumatrapdf-tool run save-attachments.js file.pdf
var doc = Document.openDocument(scriptArgs[0]);
function save(name, fs) {
    var buf = doc.getEmbeddedFileContents(fs);
    if (buf) {
        buf.save(name);
        print("saved " + name);
    }
}
var files = doc.getEmbeddedFiles();
for (var name in files) {
    save(name, files[name]);
}
for (var i = 0; i < doc.countPages(); i++) {
    doc.loadPage(i).getAnnotations().forEach(function (a) {
        if (a.getType() == "FileAttachment" && a.hasFilespec()) {
            var fs = a.getFilespec();
            save(doc.getFilespecParams(fs).filename, fs);
        }
    });
}
```

```
sumatrapdf-tool run save-attachments.js report.pdf
```

```
saved data.csv
saved notes.txt
```

A file with the same name is overwritten. Use `SumatraPDF.exe` instead of `sumatrapdf-tool` if you only have SumatraPDF installed (see [Tools](Tools.md)).

## Tips

- Use `sumatrapdf-tool extract` in an empty folder: it can write many image and font files.
- Use [Batch process PDFs](Batch-process-PDFs.md) to run the script over a folder of PDFs.
- If nothing is listed, the PDF has no attached files; a link to an outside file is not an attachment.

## See also

- [Editing annotations](Editing-annotations.md): add a file attachment
- [sumatrapdf-tool extract](Tool-extract.md) and [sumatrapdf-tool run](Tool-run.md)
- [JavaScript reference](Tool-run-javascript-reference.md): `getEmbeddedFiles`, `getEmbeddedFileContents`
- [Show PDF info](Show-PDF-info.md)


---

<!-- Tool-x-search-pdf.md -->

# Search text in PDF from command line

> Use `sumatrapdf-tool.exe` or [SumatraPDF.exe](Tools.md) with the same arguments.

To search text in `file.pdf`:

`sumatrapdf-tool grep -i foo file.pdf`

`-i` ignores case, i.e. performs a case-insensitive search, which is probably a good default.

Other options:

- `-a` ignore accents (diacritics)

## Search with a regular expression

`sumatrapdf-tool grep -i -G x.* file.pdf`

- `-G` specifies that the search pattern is a regular expression
- `-i` combines it with the case-insensitive flag
- `x.*` is a regular expression that matches every string that starts with `x`

For all options, see [sumatrapdf-tool grep](Tool-grep.md).


---

<!-- Tool-x-compress-pdf.md -->

# Compress a PDF

> Use `sumatrapdf-tool.exe` or [SumatraPDF.exe](Tools.md) with the same arguments.

**Available in [pre-release 3.7](https://www.sumatrapdfreader.org/prerelease)**

## In the application

To compress a PDF in SumatraPDF:

- open a PDF document
- `Ctrl + K`, `Compress PDF` command in [Command Palette](Command-Palette.md)

Or:

- open a PDF document
- right-click to open the context menu
- select `Document` > `Compress PDF`

## From the command line

To compress a PDF using SumatraPDF from the command line:

`sumatrapdf-tool clean -gggg -e 100 -f -i -t -Z foo.pdf foo-compressed.pdf`

This uses the most aggressive compression flags.

For an explanation of all flags, see [sumatrapdf-tool clean](Tool-clean.md).

If a PDF file is uncompressed, the compressed version should be smaller.

If a PDF is already compressed, this will have little effect.

You can also [decompress a PDF](Tool-x-decompress-pdf.md).


---

<!-- Tool-x-decompress-pdf.md -->

# Decompress a PDF

> Use `sumatrapdf-tool.exe` or [SumatraPDF.exe](Tools.md) with the same arguments.

**Available in [pre-release 3.7](https://www.sumatrapdfreader.org/prerelease)**

## In the application

To decompress a PDF in SumatraPDF:

- open a PDF document
- `Ctrl + K`, `Decompress PDF` command in [Command Palette](Command-Palette.md)

Or:

- open a PDF document
- right-click to open the context menu
- select `Document` > `Decompress PDF`

## From the command line

To decompress a PDF using SumatraPDF from the command line:

`sumatrapdf-tool clean -d foo.pdf foo-decompressed.pdf`

For an explanation of all flags, see [sumatrapdf-tool clean](Tool-clean.md).

You might want to decompress a PDF to inspect its structure more easily.

If a PDF file is compressed, the decompressed version should be bigger.

If a PDF is already decompressed, this will have little effect.

You can also [compress a PDF](Tool-x-compress-pdf.md).


---

<!-- Tool-x-encrypt-pdf-with-password.md -->

# Encrypt a PDF with password

> Use `sumatrapdf-tool.exe` or [SumatraPDF.exe](Tools.md) with the same arguments.

**Available in [pre-release 3.7](https://www.sumatrapdfreader.org/prerelease)**

## In the application

To encrypt a PDF in SumatraPDF:

- open an unencrypted PDF document
- `Ctrl + K`, `Encrypt PDF` command in [Command Palette](Command-Palette.md)

Or:

- open an unencrypted PDF document
- right-click to open the context menu
- select `Document` > `Encrypt PDF`

## From the command line

To encrypt a PDF with a password using SumatraPDF from the command line:

`sumatrapdf-tool clean -E aes-256 -U pwd foo.pdf foo-encrypted.pdf`

Flags:

- `-E` : encryption algorithm
- `-U <pwd>` : password required to open PDF file

You can see [all flags](Tool-clean.md).

You can also [decrypt a PDF](Tool-x-decrypt-pdf.md).


---

<!-- Tool-x-decrypt-pdf.md -->

# Decrypt a PDF

> Use `sumatrapdf-tool.exe` or [SumatraPDF.exe](Tools.md) with the same arguments.

**Available in [pre-release 3.7](https://www.sumatrapdfreader.org/prerelease)**

## In the application

To decrypt a PDF in SumatraPDF:

- open an encrypted PDF document
- `Ctrl + K`, `Decrypt PDF` command in [Command Palette](Command-Palette.md)

Or:

- open an encrypted PDF document
- right-click to open the context menu
- select `Document` > `Decrypt PDF`

## From the command line

To decrypt a PDF using SumatraPDF from the command line:

`sumatrapdf-tool clean -D -p pwd foo-encrypted.pdf foo-decrypted.pdf`

Flags:

- `-D` : decrypt
- `-p <pwd>` : provide password

You can see [all flags](Tool-clean.md).

You can also [encrypt a PDF](Tool-x-encrypt-pdf-with-password.md).


---

<!-- Repair-a-damaged-PDF.md -->

# Repair a damaged PDF

Fix a PDF that other apps refuse to open or open with errors, for example after an interrupted download, by rewriting it with `sumatrapdf-tool clean`.

**Available in [pre-release 3.7](https://www.sumatrapdfreader.org/prerelease)**

**Run `sumatrapdf-tool clean damaged.pdf repaired.pdf`.** At a glance:

- **Repair:** `clean` rebuilds a broken cross-reference table (the index of objects in the file) and writes a new, well-formed PDF.
- **Check:** run `pages`, `info` or `draw -F txt` on the result.
- **Save what's left:** keep only the pages that survived with a page list.

Use `sumatrapdf-tool.exe`, or [SumatraPDF.exe clean](Tools.md) with the same arguments.

## Repair a PDF

```
sumatrapdf-tool clean damaged.pdf repaired.pdf
```

For a damaged file it prints messages like these:

```
format error: cannot find startxref
warning: trying to repair broken xref
warning: repairing PDF document
```

They mean the file's index was missing or wrong, so it was rebuilt by scanning the whole file. The command still succeeds (exit code `0`) and writes `repaired.pdf`. For an undamaged file `clean` prints nothing.

- Without an output file name, the result is written to `out.pdf`.
- For a password-protected PDF, add `-p <password>`.

Note: SumatraPDF uses the same repair code when it opens a PDF, so a damaged file may open in SumatraPDF but not in other apps. The repaired file opens in other apps too.

## Check the result

List the pages and their sizes:

```
sumatrapdf-tool pages repaired.pdf
```

Print the text of every page:

```
sumatrapdf-tool draw -F txt repaired.pdf
```

If these commands print no `error` or `warning` lines, the repair worked. `draw` prints a `page repaired.pdf 1` line for each page; those are progress messages, not errors.

## Save the pages that survived

If part of the file is gone, `clean` still writes a file, but pages whose data was lost come out blank, and tools warn when they read it:

```
format error: non-page object in page tree
warning: Page tree load failed. Falling back to slow lookup
```

`pages` shows a lost page with no size:

```
<page pagenum="3">
</page>
```

Keep only the good pages:

```
sumatrapdf-tool clean damaged.pdf good.pdf 1-2
```

`good.pdf` has pages 1 and 2 and opens without warnings. The page list works as in [Extract pages from PDF](Tool-x-extract-pages-from-pdf.md): `1-5,7,9-N`, where `N` is the last page.

## Garbage collection (`-g`)

`-g`, `-gg`, `-ggg` and `-gggg` remove unused objects and make the file smaller (see [sumatrapdf-tool clean](Tool-clean.md)).

Repair without `-g` first. In a test with a lost page, plain `clean` made a blank page 3, but `clean -g` made a file that failed on page 3 with `format error: cycle in page tree`. Once you have a good file, compress it:

```
sumatrapdf-tool clean -gggg -e 100 -f -i -t -Z good.pdf good-small.pdf
```

## What can't be fixed

- `clean` can't recover data that isn't in the file. Text, images and pages that were cut off are lost; get the file again if you can.
- Some damage stops the repair. `clean` then prints an error such as `syntax error: invalid key in dict`, exits with code `1` and writes no file.

## Tips

- Keep the damaged original. Write the repaired file under a new name.
- If a download was interrupted, download it again before you try to repair it.
- Use `sumatrapdf-tool info repaired.pdf` to see the page count, fonts and images of the result (see [See PDF info](Show-PDF-info.md)).
- To repair a whole folder, see [Process many PDFs at once](Batch-process-PDFs.md).

## See also

- [sumatrapdf-tool clean](Tool-clean.md) — all options
- [Compress a PDF](Tool-x-compress-pdf.md)
- [sumatrapdf-tool pages](Tool-pages.md) and [sumatrapdf-tool info](Tool-info.md) — check the result
- [All cmd-line tools](Tools.md)


---

<!-- Show-PDF-info.md -->

# See PDF info: pages, page size, fonts, security

See a PDF's title, author, page count, page size, fonts, encryption and permissions in SumatraPDF with **Document Properties** and **Show PDF Info**, or from the command line with `sumatrapdf-tool info` and `pages`.

**Show PDF Info and the command-line tools are available in [pre-release 3.7](https://www.sumatrapdfreader.org/prerelease)**

**Press `Ctrl + D` for Document Properties.** At a glance:

- **Document Properties:** `Ctrl + D`. Metadata, PDF version, page count, size of the current page, permissions, encryption, signatures and fonts, in plain words.
- **Show PDF Info:** the same report as `sumatrapdf-tool info`: metadata, encryption, page sizes, fonts and images, with PDF object numbers.
- **`sumatrapdf-tool info`:** that report in a terminal, with options to show only fonts, images or page sizes.
- **`sumatrapdf-tool pages`:** the size boxes and rotation of every page.

## See Document Properties

Open it in any of these ways:

- **File → Properties**
- `Ctrl + D`
- Right-click the document → **Document → Properties**
- Right-click the tab → **Properties...**
- `Ctrl + K`, then `Document Properties...` in [Command Palette](Command-Palette.md) (`CmdProperties`)

For a PDF it shows, when the file has them:

- **File**, **File Size**, **File Type**
- **Title**, **Subject**, **Author**, **Copyright**, **Keywords**
- **Created**, **Modified**
- **Application** (the program that made the document) and **PDF Producer** (the program that made the PDF)
- **PDF Version**
- **Denied Permissions:** `printing document`, `copying text`
- **Encryption**, e.g. `Standard V5 R6 256-bit AES`
- **Signatures:** digital signatures and whether they are valid (see [Sign a PDF](Sign-a-PDF.md))
- **Fast Web View** and **PDF Optimizations** (Tagged PDF, PDF/A, PDF/X, PDF/E)
- **Number of Pages**
- **Current Page (N) Size:** in cm, mm, inches and points, with the paper name, e.g. `(A4)` or `(Letter)`. Your locale's unit comes first.
- **Fonts:** every font, with its type, encoding and whether it is embedded, e.g. `Georgia (TrueType; Ansi; embedded)`. The list appears a moment after the window opens.

Click **Copy To Clipboard** to copy all of it as text. Press `Esc` to close the window.

Document Properties also works for other formats (EPUB, comics, images...), with the fields that format has. For images it shows the size, DPI and camera (EXIF) details.

## See Show PDF Info

Open it in any of these ways:

- Right-click the document → **Document → Show PDF Info**
- `Ctrl + K`, then `Show PDF Info...` in [Command Palette](Command-Palette.md) (`CmdPdfShowInfo`)

It's only shown for PDF files. It opens a **PDF Info** window with the same text that `sumatrapdf-tool info file.pdf` prints (see below). Use it when you need object numbers, for example to [extract a font](Extract-fonts-from-PDF.md) or an image.

## See PDF info from the command line

Use `sumatrapdf-tool.exe`, or [SumatraPDF.exe <tool>](Tools.md) with the same arguments.

```
sumatrapdf-tool info report.pdf
```

```
report.pdf:

PDF-1.7
Info object (13 0 R):
<</Title(Annual Report 2026)/Author(Jane Doe)>>
Pages: 3

Not a ZUGFeRD file.
Retrieving info from pages 1-3...
Mediaboxes (1):
	1	(6 0 R):	[ 0 0 595 842 ]

Fonts (1):
	1	(6 0 R):	Type1 "Helvetica" WinAnsiEncoding (3 0 R)
```

- `PDF-1.7` is the PDF version.
- `Info object` has the metadata: title, author, creator, producer and dates (`D:20260217025405-08'00'` is 2026-02-17 02:54:05, UTC-8).
- `Pages:` is the page count.
- `Mediaboxes` lists each different page size once, in points (1/72 inch): `[ 0 0 595 842 ]` is 595 x 842 pt, which is A4 (210 x 297 mm). `612 x 792` is US Letter.
- `Fonts` and `Images` list the resources used on each page. The number in brackets at the end is the object number.
- `Not a ZUGFeRD file.` means the PDF has no embedded electronic invoice.

Show only some of it:

- `-F` fonts, `-I` images, `-M` page sizes (media boxes)
- `-P` patterns, `-S` shadings, `-X` form XObjects
- a page list at the end, e.g. `sumatrapdf-tool info -F report.pdf 2-3`

See [sumatrapdf-tool info](Tool-info.md) for all options.

### See if a PDF is encrypted

An encrypted PDF has an `Encryption object` in the `info` output:

```
Encryption object (0 0 R):
<</Filter/Standard/R 6/V 5/Length 256/P -3904/EncryptMetadata true/StmF/StdCF/StrF/StdCF/CF<</StdCF<</AuthEvent/DocOpen/CFM/AESV3/Length 32>>>>/O<...>/U<...>/OE<...>/UE<...>/Perms<...>>>
```

- `/Length 256` with `AESV3` is 256-bit AES; `AESV2` is AES-128.
- `/P` holds the permission flags; **Denied Permissions** in Document Properties shows the ones that matter for reading (printing, copying text).

If the PDF needs a password to open, `info` fails with `argument error: cannot authenticate password`. Add the password with `-p`:

```
sumatrapdf-tool info -p secret locked.pdf
```

To remove the password, see [Decrypt a PDF](Tool-x-decrypt-pdf.md).

## See the size of every page

`info` lists each page size once. To see every page, with rotation and all size boxes, use `pages`:

```
sumatrapdf-tool pages mixed.pdf
```

```
mixed.pdf:
<page pagenum="1">
<MediaBox l="0" b="0" r="595" t="842" />
<Rotate v="0" />
</page>
<page pagenum="2">
<MediaBox l="0" b="0" r="612" t="792" />
<Rotate v="90" />
</page>
```

- Sizes are in points (1/72 inch): width is `r - l`, height is `t - b`.
- `Rotate v="90"` means the page is shown turned 90 degrees, so this Letter page is displayed in landscape.
- A page with a **CropBox** (visible area), **TrimBox**, **BleedBox** or **ArtBox** lists those too. See [sumatrapdf-tool pages](Tool-pages.md).
- Add a page list to see some pages only: `sumatrapdf-tool pages mixed.pdf 2`.

## Tips

- Use **Copy To Clipboard** in Document Properties to paste the details into a bug report or an email.
- Use `sumatrapdf-tool pages` to find pages of a different size before printing (see [Printing](Printing.md)).
- To check many PDFs at once, see [Process many PDFs at once](Batch-process-PDFs.md).
- Use `sumatrapdf-tool info` on a file that won't open elsewhere; warnings about a broken xref mean it needs [repair](Repair-a-damaged-PDF.md).

## See also

- [Extract fonts from a PDF](Extract-fonts-from-PDF.md)
- [sumatrapdf-tool info](Tool-info.md) and [sumatrapdf-tool pages](Tool-pages.md)
- [Encrypt a PDF](Tool-x-encrypt-pdf-with-password.md) and [Decrypt a PDF](Tool-x-decrypt-pdf.md)
- [All cmd-line tools](Tools.md)


---

<!-- Batch-process-PDFs.md -->

# Process many PDFs at once

Run a `sumatrapdf-tool` command on every PDF in a folder with a `for` loop in the Command Prompt (`cmd.exe`) or in PowerShell.

**Available in [pre-release 3.7](https://www.sumatrapdfreader.org/prerelease)**

**Open a terminal in the folder with the PDFs and run a loop.** At a glance:

- **Command Prompt:** `for %f in (*.pdf) do sumatrapdf-tool ... "%f"`
- **.bat file:** the same, with `%%f` instead of `%f`.
- **PowerShell:** `Get-ChildItem *.pdf | ForEach-Object { sumatrapdf-tool ... $_.FullName }`
- **Search:** `grep` takes many files in one command.

The examples use `sumatrapdf-tool`, which the installer adds to `PATH`. [SumatraPDF.exe <tool>](Tools.md) takes the same arguments.

## Write a loop in the Command Prompt

```
for %f in (*.pdf) do @sumatrapdf-tool clean "%f" "fixed\%~nf.pdf"
```

- `%f` is the full file name, e.g. `annual report.pdf`.
- `%~nf` is the name without the extension, e.g. `annual report`. Use it to build output names.
- Put quotes around `"%f"` and around output names so names with spaces work.
- `@` stops cmd from printing each command before it runs it.
- `for /r %f in (*.pdf) do ...` also goes into subfolders; `%f` is then the full path.

Write the results to a separate folder (create it first with `mkdir fixed`). That keeps them apart from the originals, and running the loop again won't process them.

## Write a loop in a .bat file

In a `.bat` file, double every `%`: `%%f`, `%%~nf`, and `%%d` for the page number in image names.

```
@echo off
mkdir text
for %%f in (*.pdf) do sumatrapdf-tool convert -o "text\%%~nf.txt" "%%f"
```

Note: a single `%d` in a `.bat` file is eaten by cmd. `convert` then gets broken arguments and prints its usage text.

## Write a loop in PowerShell

```
mkdir fixed
Get-ChildItem *.pdf | ForEach-Object { sumatrapdf-tool clean $_.FullName "fixed\$($_.BaseName).pdf" }
```

- `$_.FullName` is the full path of the file; `$_.BaseName` is the name without the extension.
- Use `$(...)` to put `$_.BaseName` inside a string.
- Names with spaces work without extra quotes.
- Use `Get-ChildItem -Recurse *.pdf` to include subfolders.

This works the same in PowerShell 7 (`pwsh`) and in Windows PowerShell 5.1.

## Compress all PDFs

Command Prompt:

```
mkdir small
for %f in (*.pdf) do @sumatrapdf-tool clean -gggg -e 100 -f -i -t -Z "%f" "small\%~nf.pdf"
```

PowerShell:

```
mkdir small
Get-ChildItem *.pdf | ForEach-Object { sumatrapdf-tool clean -gggg -e 100 -f -i -t -Z $_.FullName "small\$($_.BaseName).pdf" }
```

A file that is already compressed may not get smaller, and a very small one can even grow a little. See [Compress a PDF](Tool-x-compress-pdf.md).

## Extract the text of all PDFs

Each PDF becomes a `.txt` file with the same name.

Command Prompt:

```
mkdir text
for %f in (*.pdf) do @sumatrapdf-tool convert -o "text\%~nf.txt" "%f"
```

PowerShell:

```
mkdir text
Get-ChildItem *.pdf | ForEach-Object { sumatrapdf-tool convert -o "text\$($_.BaseName).txt" $_.FullName }
```

See [Extract text from PDF](Tool-x-extract-text-from-pdf.md).

## Convert all PDFs to PNG images

One image per page, named `<file>-<page>.png`, e.g. `annual report-1.png`, `annual report-2.png`. `resolution=150` sets the image resolution in dots per inch.

Command Prompt:

```
mkdir png
for %f in (*.pdf) do @sumatrapdf-tool convert -o "png\%~nf-%d.png" -O resolution=150 "%f"
```

In a `.bat` file:

```
mkdir png
for %%f in (*.pdf) do sumatrapdf-tool convert -o "png\%%~nf-%%d.png" -O resolution=150 "%%f"
```

PowerShell:

```
mkdir png
Get-ChildItem *.pdf | ForEach-Object { sumatrapdf-tool convert -o "png\$($_.BaseName)-%d.png" -O resolution=150 $_.FullName }
```

See [Convert PDF to images](Convert-PDF-to-images.md).

## Search all PDFs

`grep` takes many files, so you don't always need a loop. `-i` ignores case, `-H` prints the file name and `-n` the page number:

```
sumatrapdf-tool grep -i -H -n "green" "annual report.pdf" invoice.pdf
```

Each match is one line: file name, page number and the line of text, separated by tabs:

```
annual report.pdf	1	Green text on page 1
annual report.pdf	2	Green text on page 2
annual report.pdf	3	Green text on page 3
invoice.pdf	1	Green text on page 1
invoice.pdf	2	Green text on page 2
invoice.pdf	3	Green text on page 3
```

`grep` doesn't expand `*.pdf` itself: `sumatrapdf-tool grep -i foo *.pdf` fails with `cannot open *.pdf`. Let the shell list the files instead.

PowerShell, all PDFs in one command:

```
sumatrapdf-tool grep -i -H -n "green" (Get-ChildItem *.pdf).Name
```

PowerShell, including subfolders:

```
sumatrapdf-tool grep -i -H -n "green" (Get-ChildItem -Recurse *.pdf).FullName
```

Command Prompt, one file at a time (`for /r` to include subfolders):

```
for %f in (*.pdf) do @sumatrapdf-tool grep -i -H -n "green" "%f"
```

See [sumatrapdf-tool grep](Tool-grep.md) for regular expressions and other options.

## Tips

- Try the command on one file first, then put it in a loop.
- Use `-H` with `grep` so you know which file each match comes from.
- Use a `.bat` file for a job you repeat; remember to double the `%`.
- Other tools work the same way: [grayscale](Convert-PDF-to-grayscale.md), [repair](Repair-a-damaged-PDF.md), [PDF info](Show-PDF-info.md).

## See also

- [All cmd-line tools](Tools.md)
- [sumatrapdf-tool clean](Tool-clean.md), [convert](Tool-convert.md), [grep](Tool-grep.md)
- [Merge PDFs](Merge-PDFs.md) — combine many PDFs into one file


---

<!-- Print-selected-pages.md -->

# Print only some pages

Print a page range, the current page, odd or even pages, or just a rectangular part of a page, from the print dialog or the command line.

**Press `Ctrl + P` and type the pages under Page Range, e.g. `1-3, 8`.** At a glance:

- **Page range:** in the print dialog, `Ctrl + P`.
- **Current page:** in the print dialog.
- **Odd / even pages:** the dialog's **Advanced** tab, or `odd` / `even` on the command line.
- **Part of a page:** **Print Selection...** (`CmdPrintSelection`) after `Ctrl` + drag.
- **Command line:** `SumatraPDF.exe -print-to-default -print-settings "1-3,8" file.pdf`

For all print options (scaling, paper, trays, duplex) see [Printing](Printing.md).

## Print a page range

1. Open the print dialog: `Ctrl + P`, **File → Print...**, the toolbar's print button, or `Ctrl + K`, then `Print Document...` in [Command Palette](Command-Palette.md).
2. Under **Page Range** choose **Pages** and type the pages: single pages and ranges separated by commas, e.g. `1-3, 8, 10-12`. You can give up to 10 ranges.
3. Click **Print**.

Page numbers are physical pages: 1 is the first page of the file, whatever number is printed on it.

On Windows 11 the new print dialog has the same choice under **Pages** (custom range).

## Print the current page

Press `Ctrl + P` and choose **Current Page** under _Page Range_. The page you are looking at is printed.

In the Windows 11 dialog, choose the current page under **Pages**, or type its number as a custom range.

## Print odd or even pages

In the print dialog's **Advanced** tab (next to _General_), choose **Odd pages only** or **Even pages only**. It applies to the page range you picked, so you can print the odd pages of `1-20` only.

Use it for manual two-sided printing: print the odd pages, turn the stack over, put it back, print the even pages.

The Windows 11 dialog doesn't have these options. Use the [command line](#print-pages-from-the-command-line) or [restore the classic dialog](Printing.md#get-the-advanced-options-on-windows-11).

## Print part of a page

1. Hold `Ctrl` and drag with the left mouse button to select a rectangle on the page.
2. Start **Print Selection...** (`CmdPrintSelection`):
   - Right-click → **Selection → Print Selection...**
   - `Ctrl + K`, then `Print Selection...` in [Command Palette](Command-Palette.md)
   - or press `Ctrl + P` and choose **Selection** under _Page Range_
3. The print dialog opens with **Selection** already chosen. Click **Print**.

**Print Selection...** is new in [pre-release 3.7](https://www.sumatrapdfreader.org/prerelease); choosing **Selection** in the dialog works in older versions too. To print the area at its real size instead of fitting the paper, see [Print part of a page](Printing.md#print-part-of-a-page).

Note: a text selection can't be printed on its own; only a rectangle.

## Print pages from the command line

Put the pages in `-print-settings`, with `-print-to "<printer>"` or `-print-to-default`. Nothing is shown and SumatraPDF exits when done.

Pages 1 to 3 and 8:

```
SumatraPDF.exe -print-to-default -print-settings "1-3,8" report.pdf
```

Only page 5, to a named printer:

```
SumatraPDF.exe -print-to "Office Printer" -print-settings "5" report.pdf
```

The last page, or the last 3 pages:

```
SumatraPDF.exe -print-to-default -print-settings "last" report.pdf
SumatraPDF.exe -print-to-default -print-settings "-3--1" report.pdf
```

Odd pages of pages 1 to 20, then the even ones:

```
SumatraPDF.exe -print-to-default -print-settings "1-20,odd" report.pdf
SumatraPDF.exe -print-to-default -print-settings "1-20,even" report.pdf
```

Pages 10 to 8 in reverse order, fitted to the paper:

```
SumatraPDF.exe -print-to-default -print-settings "10-8,fit" report.pdf
```

Page tokens mix freely with the other options (`fit`, `2x`, `duplex`, ...). The full list is in [`-print-settings` options](Printing.md#-print-settings-options).

To pick the pages in the dialog instead, use `-print-dialog`:

```
SumatraPDF.exe -print-dialog report.pdf
```

## Tips

- Use [Split a PDF](Split-a-PDF.md) or **Extract Pages From PDF** (right-click → **Document**) when you need the pages as a file rather than on paper.
- Use `-print-settings` in a script or a shortcut for a range you print often.
- Use **Current Page** with `Ctrl + G` (Go to Page) to print one page of a long document quickly.

## See also

- [Printing](Printing.md): every print option, Windows 11 dialog, troubleshooting
- [Command-line arguments](Command-line-arguments.md#printing-options)
- [Print a PDF as a poster](Print-PDF-as-poster.md)
- [Save part of a page as an image](Save-page-region-as-image.md)


---

<!-- Present-a-PDF.md -->

# Present a PDF as slides

Show a PDF (slides exported from PowerPoint, Keynote, LaTeX Beamer, ...) full screen, one page at a time, and move through it with the keyboard, the mouse or a presenter remote.

**Press `F5` to start presenting and `Esc` to stop.** At a glance:

- **Presentation:** full screen, one page at a time, fit to the screen. `F5`, `Ctrl + L`, `Shift + F11`
- **Next / previous slide:** `Right` / `Left`, `Page Down` / `Page Up`, `Space`, a click
- **Black / white screen:** `.` (or `b`) / `w`
- **Laser pointer:** **Toggle Laser Pointer** (`CmdToggleLaserPointer`), ver 3.7+
- **Command line:** `SumatraPDF.exe -presentation slides.pdf`

## Start presenting

Open the PDF, then:

- press `F5`, `Ctrl + L` or `Shift + F11`
- **View → Presentation**
- `Ctrl + K`, then `View: Presentation Mode` in [Command Palette](Command-Palette.md) (`CmdTogglePresentationMode`)

SumatraPDF fills the screen with the current page:

- one page at a time, zoomed to fit the screen, with no margins
- no menu, toolbar, tabs or sidebar
- the mouse cursor hides after 3 seconds without moving
- the screen doesn't turn off or go to sleep (`PreventSleepInFullscreen` setting)

Presentation works for PDF and other page-based documents; it is not available for CHM help files.

To present two pages side by side, set `Fullscreen.DisplayMode = facing` (or `book view`) in [advanced settings](Advanced-options-settings.md) (ver 3.7+).

## Move between slides

| Go to              | Keys                                    | Mouse                             |
| ------------------ | --------------------------------------- | --------------------------------- |
| Next slide         | `Right`, `Page Down`, `Space`, `n`      | left click, `Shift` + right click |
| Previous slide     | `Left`, `Page Up`, `Shift + Space`, `p` | right click, `Shift` + left click |
| First / last slide | `Home` / `End`                          |                                   |
| A slide by number  | `Ctrl + G` or `g`, type the number      |                                   |

Most presenter remotes send `Page Down` / `Page Up`, so they work without setup.

To open the context menu while presenting, hold `Ctrl` and right-click.

## Blank the screen

Turn the screen black or white to take the audience's attention off the slides:

- `.` (period): black screen (`CmdPresentationBlackBackground`). Press `.` again to return.
- `w`: white screen (`CmdPresentationWhiteBackground`). Press `w` again to return.
- `b`: black screen (in the default one-page layout).

Any other key, or a click, also brings the slide back. The "blank screen" button of a Logitech-style presenter sends `.`, so it works too.

## Point with a laser pointer

**Available in [pre-release 3.7](https://www.sumatrapdfreader.org/prerelease)**

**Toggle Laser Pointer** (`CmdToggleLaserPointer`) turns the mouse cursor over the page into a glowing red dot. While it's on, the cursor doesn't hide in presentation mode. Links and text still work under it. Run the command again to get the normal cursor back.

- `Ctrl + K`, then `Toggle Laser Pointer` in [Command Palette](Command-Palette.md)

It has no default key. To toggle it with a key, add a shortcut in [advanced settings](Advanced-options-settings.md) (see [Customize keyboard shortcuts](Customize-keyboard-shortcuts.md)):

```
Shortcuts [
    [
        Cmd = CmdToggleLaserPointer
        Key = Ctrl + Shift + P
    ]
]
```

## Stop presenting

- `Esc`
- `F5`, `Ctrl + L` or `Shift + F11` again
- double-click the top-right corner of the screen

The window comes back with the layout and zoom it had before.

## Presentation or full screen

|               | Presentation (`F5`)     | Full screen (`F11`)                                                 |
| ------------- | ----------------------- | ------------------------------------------------------------------- |
| Layout        | one page, fit to screen | your current layout and zoom                                        |
| Toolbar, menu | hidden                  | hidden by default (`Fullscreen.Toolbar`, `Fullscreen.ShowMenubar`) |
| Mouse click   | next / previous page    | selects text, follows links                                         |
| Cursor        | hides after 3 seconds   | stays                                                               |

Full screen is for reading: `F11`, `Ctrl + Shift + L` or `f`, **View → Fullscreen**, `-fullscreen` on the command line.

## Start a presentation from the command line

```
SumatraPDF.exe -presentation slides.pdf
```

Start on a given slide:

```
SumatraPDF.exe -presentation -page 5 slides.pdf
```

Note: `-presentation` applies when this command starts SumatraPDF. If SumatraPDF is already running (and `ReuseInstance` is on, the default), the file opens in the running window in normal view; press `F5`.

See [Command-line arguments](Command-line-arguments.md) and [Open a PDF at a page or search term](Open-PDF-at-page-from-command-line.md).

## Tips

- Use `-page` in a desktop shortcut to start a talk on its first slide every time.
- Use `.` on a presenter remote to blank the screen during questions.
- Use `Ctrl + K` while presenting to run any command without leaving presentation mode.
- Use `F12` while presenting to show the Bookmarks sidebar and jump to a section.

## See also

- [Keyboard shortcuts](Keyboard-shortcuts.md)
- [Customize keyboard shortcuts](Customize-keyboard-shortcuts.md)
- [Advanced settings](Advanced-options-settings.md): `Fullscreen`, `PreventSleepInFullscreen`
- [Command-line arguments](Command-line-arguments.md)


---

<!-- Open-PDF-at-page-from-command-line.md -->

# Open a PDF at a page or search term

Open a document at a given page, chapter or search result, with the zoom and layout you want, from a script, a desktop shortcut or another program.

**Run `SumatraPDF.exe -page 42 book.pdf` to open `book.pdf` at page 42.** At a glance:

- **Page:** `-page <n>`
- **Chapter, bookmark or page label:** `-named-dest "<name>"`
- **Search:** `-search "<text>"` (ver 3.4+)
- **Layout, zoom, scroll position:** `-view`, `-zoom`, `-scroll`
- **Where you are now:** **Copy Location To Clipboard** (`CmdCopyLocationToClipboard`, ver 3.7+) copies these arguments for you.
- **Document already open:** the same arguments move the open document; or send [DDE commands](DDE-Commands.md).

Put options before or after the file name; the full list is in [Command-line arguments](Command-line-arguments.md#navigation-options).

## Open at a page

```
SumatraPDF.exe -page 42 "C:\Books\manual.pdf"
```

`-page` counts physical pages: `1` is the first page of the file, whatever number is printed on it. To go to a printed page number such as `xii` or `A-3`, use `-named-dest`.

## Open at a chapter or page label

`-named-dest` looks for, in this order:

1. a named destination stored in the PDF (e.g. `chapter.3` in LaTeX output)
2. a table of contents entry whose title matches (case and extra spaces don't matter), then one whose title contains the text, starting at a word
3. a page label (the page number printed in the book)

```
SumatraPDF.exe -named-dest "Installation" manual.pdf
SumatraPDF.exe -named-dest xii manual.pdf
```

If both `-named-dest` and `-page` are given, `-named-dest` wins.

## Open and search for text

**Available in version 3.4 or later.**

```
SumatraPDF.exe -search "invoice total" report.pdf
```

SumatraPDF opens the document, shows the find bar with the text and goes to the first match. Press `F3` for the next match, `Shift + F3` for the previous one.

## Open with a layout and zoom

```
SumatraPDF.exe -page 10 -view "continuous" -zoom "fit width" report.pdf
SumatraPDF.exe -page 3 -view facing -zoom 150 report.pdf
```

- `-view`: `"single page"`, `"continuous single page"` (or `continuous`), `facing`, `"continuous facing"`, `"book view"`, `"continuous book view"`
- `-zoom`: `"fit page"`, `"fit width"`, `"fit height"`, `"fit content"`, `"fit visible"`, or a percentage such as `150` or `"150%"`
- `-scroll x,y`: the position on the page, in document units; the easiest way to get it is **Copy Location To Clipboard**

Values with spaces need quotes.

## Reopen exactly where you are

**Available in [pre-release 3.7](https://www.sumatrapdfreader.org/prerelease)**

1. In SumatraPDF, press `Ctrl + K` and run `Copy Location To Clipboard` in [Command Palette](Command-Palette.md) (`CmdCopyLocationToClipboard`).
2. The clipboard now holds the page, zoom, scroll position and file, e.g.:

   ```
   -page 33 -zoom "193%" -scroll 0,0 "C:\Books\Material.pdf"
   ```

3. Paste it after `SumatraPDF.exe` in a script, a note, or the **Target** of a desktop shortcut.

## Jump in a document that is already open

When SumatraPDF is already running, the file opens in that window, and if it is already open there the same options move it to the page, destination, or search. This uses the `ReuseInstance` setting, which is on by default. If you turned it off, add `-reuse-instance`:

```
SumatraPDF.exe -reuse-instance -page 37 "C:\Books\manual.pdf"
```

Programs that talk DDE (editors, scripts, [LaTeX tools](LaTeX-integration.md)) can send commands to the `SUMATRA` server, `control` topic, for a file that is already open:

- `[GotoPage("C:\Books\manual.pdf", 37)]` — go to page 37
- `[GotoNamedDest("C:\Books\manual.pdf", "Installation")]` — go to a destination or bookmark
- `[Search("C:\Books\manual.pdf", "firewall")]` — find the first match
- `[GotoPageWord("C:\Books\manual.pdf", 12, "firewall")]` — go to page 12 and select the word if it is on that page (ver 3.7+)
- `[SetView("C:\Books\manual.pdf", "continuous", -2)]` — continuous layout, fit width

From the command line, send them with `-dde` (ver 3.5+). Inside the command, `"` and `\` are escaped with `\`; see [DDE commands](DDE-Commands.md) for the format and all commands.

## Make a desktop shortcut to a page

1. Right-click the desktop → **New → Shortcut**.
2. For the location, enter the program, the options and the file, e.g.:

   ```
   "C:\Program Files\SumatraPDF\SumatraPDF.exe" -page 120 -zoom "fit width" "C:\Books\manual.pdf"
   ```

3. Name it and click **Finish**.

Use the path of your `SumatraPDF.exe`; the portable version can be anywhere.

## Adobe Reader style options

**Available in version 3.5 or later.**

Programs written for Adobe Reader can use `/A`:

```
SumatraPDF.exe /A "page=5" report.pdf
SumatraPDF.exe /A "nameddest=Installation;search=firewall" report.pdf
```

`page=`, `nameddest=` and `search=` are supported; other Adobe open parameters are ignored. See [Command-line arguments](Command-line-arguments.md#navigation-options).

## Tips

- Use `-named-dest` with a bookmark title in scripts: it keeps working when pages are added before the chapter.
- Use `-new-window` to open the document in its own window instead of a tab.
- Add `-presentation` to start a talk at a slide (see [Present a PDF as slides](Present-a-PDF.md)).
- Use `-search` with a unique phrase to open a long log or report at the right spot.

## See also

- [Command-line arguments](Command-line-arguments.md): all options
- [DDE commands](DDE-Commands.md): control a running SumatraPDF
- [LaTeX integration](LaTeX-integration.md): forward and inverse search
- [Tabs and windows](Tabs-and-windows.md)


---

<!-- Contribute-translation.md -->

# Contribute translation

Sumatra is translated into many languages but we rely on you to help us keep translations for your language up to date.

To help us translate Sumatra:

- go to [https://www.apptranslator.org/app/SumatraPDF](https://www.apptranslator.org/app/SumatraPDF)
- log in with your GitHub account
- pick a language you know
- add new translations or improve existing translations

To get notified about new strings that need translation, subscribe to your language's RSS feed in the reader of your choice. For example, [this feed](https://www.apptranslator.org/rss?app=SumatraPDF&lang=de) lists changes for German.

## The meaning of & in translations

`&` means that the following character is the hotkey. For example, `&File` means that the `F` key is a hotkey for that menu item. Hotkeys are underlined in menu items, although the underline can be disabled system-wide.

You don't have to add hotkeys in translations; they are provided for convenience and easier keyboard use.

In translated text, a different character can be used as the accelerator.

See [https://github.com/sumatrapdfreader/sumatrapdf/discussions/2919](https://github.com/sumatrapdfreader/sumatrapdf/discussions/2919) for more information.


---

<!-- How-to-submit-bug-reports.md -->

# How to submit bug reports

Did you encounter a bug in SumatraPDF?

## Check the latest pre-release build

First, see if it still happens in the latest [pre-release version](https://www.sumatrapdfreader.org/prerelease). The bug may already have been fixed there.

## Create an issue

If the problem is present in the latest [pre-release build](https://www.sumatrapdfreader.org/prerelease), please create a bug report in our [issue tracker](https://github.com/sumatrapdfreader/sumatrapdf/issues).

## Provide a test file

Does it involve a specific PDF (or CHM or XPS) file?

Please attach it to the issue (try dragging and dropping it onto the issue field). Without a test document, we can rarely make progress on fixing the issue.

If the file (or other information) is confidential, you can e-mail it directly to [kkowalczyk@gmail.com](mailto:kkowalczyk@gmail.com) ([Krzysztof Kowalczyk](https://blog.kowalczyk.info/), SumatraPDF's main developer).

## Provide reproduction steps

Often the bug only happens in a specific scenario.

If possible, please provide step-by-step instructions for reproducing the issue.

## Reporting crashes

[Submit crash report](Submit-crash-report.md)


---

<!-- Submit-crash-report.md -->

# Submit crash report

Please help us fix SumatraPDF crashes.

If you have a reproducible crash:

- download symbols:
  - menu: `Debug` / `Download Symbols`
  - `Ctrl + K`, `Debug: Download Symbols` command in [Command Palette](Command-Palette.md)
- trigger the crash
- when you see the crash dialog, press `Cancel` to open the crash report in the default text editor
- post the crash log as a gist at [https://gist.github.com/](https://gist.github.com/). For example, press `Ctrl + A` to select all text, `Ctrl + C` to copy it to the clipboard, and then `Ctrl + V` to paste it into the gist
- create a bug report at [https://github.com/sumatrapdfreader/sumatrapdf/issues](https://github.com/sumatrapdfreader/sumatrapdf/issues)
- post a link to the gist in the bug report
- **include the file that caused the crash**
  - attach it to the GitHub issue (put it in a `.zip` file if the file type is not accepted)
  - or, if the file is private, email it to kkowalczyk@gmail.com (and reference the bug number)
  - I can’t stress it enough: if I can’t reproduce a crash myself, I might not be able to fix it
- provide additional information like:
  - what you were doing when the crash happened
  - when the crash happened: when opening a file, changing the view, etc.
  - how you opened the file: drag and drop onto the SumatraPDF window, double-click in the file manager, from the command line, etc.
  - the best information is a set of steps I can do to reproduce the crash


---

<!-- Reporting-printing-bugs.md -->

# Reporting printing bugs

Printing bugs are hard to diagnose because each printer has a different driver, so the same file may print correctly on one printer but not on another.

When reporting printing bugs in the [issue tracker](https://github.com/sumatrapdfreader/sumatrapdf/issues), please include the following information:

- version of Sumatra
- version of the OS (e.g. Windows Vista or Windows 10)
- name of the printer
- can you open and see the file in Sumatra?
- what exactly happens, and are there any error messages?
- if it happens only for some files but not the others
  - is there anything different about the files that don't print that jumps out?
  - please attach the file that doesn't print to the bug report. If the file is confidential, you can email it to [kkowalczyk@gmail.com](mailto:kkowalczyk@gmail.com) ([Krzysztof Kowalczyk](https://blog.kowalczyk.info/), SumatraPDF's main developer).


---

<!-- Update-check-doesnt-work.md -->

# Update check doesn't work?

A new version of SumatraPDF has been released, but the `Help → Check for Updates` menu didn't notify you. Is this a bug?

Most likely not.

We wait at least a week before activating the update check. That way, if there is a major problem with a new release that we didn't catch in testing, fewer people will have to download another update containing the fix.


---

<!-- Failed-to-load-libmupdf.md -->

# Failed to load libsumatrapdf.dll

When installed, SumatraPDF consists of two files:

- `SumatraPDF.exe`
- `libsumatrapdf.dll`

**Name change:** through version **3.6** this library was named **`libmupdf.dll`**. From version **3.7** it is named **`libsumatrapdf.dll`**. The role is the same (MuPDF and the other document codecs used by the app). Older docs, antivirus logs, and this page’s URL still use the historical `libmupdf` name.

You're reading this page because `libsumatrapdf.dll` failed to load and SumatraPDF can't proceed.

**How can that happen?**

There are many possible reasons. The error code and message come from Windows.

## Antivirus / security software (most common for portable / pre-release)

Portable and single-file builds extract `libsumatrapdf.dll` next to the executable or under `%LocalAppData%\SumatraPDF-data\` the first time they run.

Some antivirus products:

- block `LoadLibrary` on a just-written DLL
- quarantine or delete the DLL immediately after it is extracted
- return unusual error codes (for example **87** / “Invalid parameter”, **5** / access denied, **32** / sharing violation)

This is especially common with real-time protection and “behavior” or “ransomware” shields.

**What to try:**

1. **Add exclusions** for:
   - the folder that contains `SumatraPDF.exe` (portable install)
   - `%LocalAppData%\SumatraPDF-data\` (extracted build-specific files)
2. Temporarily **disable real-time scanning**, start SumatraPDF once so `libsumatrapdf.dll` can load, then re-enable scanning (keep the exclusions).
3. Check the antivirus quarantine for `libsumatrapdf.dll` (or, on older installs, `libmupdf.dll`) and restore it if found.
4. Prefer the **official installer** from [sumatrapdfreader.org](https://www.sumatrapdfreader.org/download-free-pdf-viewer) if portable keeps failing.
5. Re-download SumatraPDF (ensure the download is complete and not modified).

If the dialog shows a Windows error code, note it when asking for help.

## Other causes

- Incomplete copy of a multi-file install (`libsumatrapdf.dll` missing next to the `.exe`)
- Wrong / leftover `libsumatrapdf.dll` from another version (size mismatch)
- Corrupted download or disk errors
- Security policies blocking unsigned or newly written modules

**How to investigate a specific error code:**

- Search: `LoadLibrary <error-code>`
- Ask an AI: `when calling LoadLibrary() Win32 API I got error <code>. What does it mean?`
- Ask in [SumatraPDF discussions](https://github.com/sumatrapdfreader/sumatrapdf/discussions)

See also [Corrupted installation](Corrupted-installation.md) and [Installation](Installation.md).


---

<!-- Corrupted-installation.md -->

# Corrupted installation

See also [Installation](Installation.md) for an overview of the portable and installer versions.

If you're reading this, you might have been told by SumatraPDF that you have a corrupted installation.

**How can that happen?**

SumatraPDF comes in two flavors: a portable version and an installer.

A portable version is a self-contained executable and cannot be corrupted.

An installer needs to be run to be properly installed. Part of it is extracting the engine library (`libsumatrapdf.dll` from **3.7**; through **3.6** it was named `libmupdf.dll`).

There are two possible problems:

- `libsumatrapdf.dll` is missing
- `libsumatrapdf.dll` is there but its version doesn't match the version of `SumatraPDF.exe`

**How to solve the problem?**

If you want to place SumatraPDF in any location, under any name, use the self-contained portable flavor.

If you want to use the installable version, install it. The installer will run if the `.exe` filename contains `-install` (as it will if you download an [official build](https://www.sumatrapdfreader.org/download-free-pdf-viewer)).

If you rename the `.exe`, you can force it to run as the installer with the `-install` option.

Alternatively, you can extract `libsumatrapdf.dll` and all other files with the `-x` option.


---

<!-- Why-only-Windows.md -->

# Why only Windows?

People sometimes suggest that SumatraPDF should be available for other operating systems, such as Linux, macOS, and Android.

This won't happen.

The first reason is that the current developers don't know how to write software for those other platforms.

The second reason is that it would mean writing the whole program from scratch for a new platform.

SumatraPDF is tightly integrated with and optimized for Windows. Making a version for another operating system would not be a matter of making a few changes here and there; it would require writing all the UI code from scratch, i.e. redoing years of development that went into SumatraPDF.

SumatraPDF is an open-source project, so anyone is free to use our source code to create an equivalent application for another operating system, but we're unlikely to do it ourselves.


---

<!-- Privacy-policy.md -->

# Privacy policy

What SumatraPDF and www.sumatrapdfreader.org collect, why, and how long it is kept.

Last updated: September 24, 2026.

**In short:** your documents never leave your computer. SumatraPDF contacts our server to check for updates and to send a report when it crashes. The website has no ads, no analytics and no cookies. We don't sell or share data for marketing.

## Your documents

SumatraPDF opens, displays, edits and prints documents on your computer. It doesn't upload documents, their names, or the list of files you have read. The list of recently opened files is kept only in the settings file on your computer (see [How we store settings](How-we-store-settings.md)).

## Update checks

When `CheckForUpdates` is on (the default), SumatraPDF asks www.sumatrapdfreader.org whether a newer version exists: at most once a day in a release build, and on every start in a pre-release build. The request includes:

- the SumatraPDF version
- the Windows version, whether SumatraPDF is 32 or 64-bit and whether it's an ARM build
- the language of the user interface
- the version of Microsoft Edge WebView2, if installed, and whether SumatraPDF was installed from the Microsoft Store
- which CPU instruction sets (SIMD) are available

Our server stores each request with your IP address. We use it to count how many people use each version and to decide how fast to roll out new versions.

To turn update checks off, set `CheckForUpdates = false` in [Advanced settings](Advanced-options-settings.md).

## Crash reports

When SumatraPDF crashes, official builds send a crash report to www.sumatrapdfreader.org. A report contains:

- a minidump: a snapshot of the program's state at the moment of the crash (the call stacks of its threads and the memory they point to), which can include fragments of the document that was open
- your SumatraPDF settings, without the list of recently opened files
- the version and system information listed under update checks
- your IP address

We use crash reports only to find and fix bugs. They are deleted after 31 days.

## Features that use other services

These features send data to another service only when you use them:

- **[AI Chat with document](AI-Chat-with-document.md)** sends your questions and text from the document to the AI provider you choose, with your own account or API key. That provider's privacy policy applies.
- **Search and translate** a selection ([Customize search / translation](Customize-search-translation-services.md)) opens the service in your web browser with the selected text.
- **Ask AI** in the documentation's search box opens the AI site you pick with your question.

[Read Aloud](Read-Aloud.md) uses the voices installed in Windows. SumatraPDF doesn't send the text anywhere.

## The website

www.sumatrapdfreader.org doesn't use cookies, analytics, ads or tracking scripts. Like most web servers, ours logs each request: the time, the address of the page, the page you came from, your browser's user agent and your IP address. We use the logs to run and fix the website.

The website remembers your choice of color theme and whether the documentation sidebar is hidden in your browser's local storage. It stays in your browser.

Some documentation pages embed YouTube videos from youtube-nocookie.com. YouTube doesn't set cookies until you play a video; when you do, [Google's privacy policy](https://policies.google.com/privacy) applies.

## Service providers

We don't sell data or share it for advertising. The data above is processed by the companies that run our infrastructure:

- Hetzner (the web server)
- Cloudflare (network delivery of the website and file downloads, files.sumatrapdfreader.org)
- S3-compatible cloud storage (crash reports and update-check statistics)
- Upstash (update-check counts)

## YouTube uploads

"SumatraPDF video uploader" is a tool with which the SumatraPDF developers upload videos to the SumatraPDF YouTube channel, using the YouTube API. It accesses only that channel and doesn't access data of other YouTube users.

## Contact

Questions about this policy: ask in the [forum](https://github.com/sumatrapdfreader/sumatrapdf/discussions) or open an [issue](https://github.com/sumatrapdfreader/sumatrapdf/issues).
