Skip to content

Commit e6ae60c

Browse files
authored
fix(PrintControl): make DPI scale the export in fit mode (#93)
In the default 'fit' page mode the export canvas was always the on-screen map canvas size, so changing the DPI had no effect on the output — the exported image (and its file size) was identical regardless of the chosen DPI, even though the DPI control stayed enabled. Treat DPI as a resolution multiplier relative to the 96 DPI baseline in fit mode (pageW = baseW * dpi / 96), matching how paper presets already scale, and report the chosen density in the PNG/JPEG/PDF/SVG metadata via _effectiveDpi(). The physical size stays the base size at 96 DPI, so only the pixel count — and therefore the file size — grows with DPI. Bumps version to 0.20.1.
1 parent 91dd304 commit e6ae60c

3 files changed

Lines changed: 20 additions & 13 deletions

File tree

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "maplibre-gl-components",
3-
"version": "0.20.0",
3+
"version": "0.20.1",
44
"description": "Legend, colorbar, and HTML control components for MapLibre GL JS maps",
55
"type": "module",
66
"main": "./dist/index.cjs",

src/lib/core/PrintControl.ts

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -953,13 +953,12 @@ export class PrintControl implements IControl {
953953

954954
/**
955955
* Resolve the DPI used for physical sizing (PDF points, SVG inches, raster
956-
* metadata). `dpi` is ignored in the legacy `'fit'` page mode, so a fixed
957-
* 96 DPI is used there to keep that output deterministic.
956+
* metadata). Applies to every page mode — including `'fit'`, where the DPI
957+
* scales the export resolution — so viewers report the chosen density.
958958
*
959959
* @returns The effective dots-per-inch.
960960
*/
961961
private _effectiveDpi(): number {
962-
if (this._state.pageSize === "fit") return 96;
963962
return this._state.dpi > 0 ? this._state.dpi : 96;
964963
}
965964

@@ -1637,21 +1636,28 @@ export class PrintControl implements IControl {
16371636
const mapW = mapCanvas.width;
16381637
const mapH = mapCanvas.height;
16391638

1640-
// Legacy 'fit' mode: page is the current canvas (or Custom width/height),
1641-
// and the map is stretched to fill it, preserving historical behavior.
1639+
// 'fit' mode: the page is the current canvas (or Custom width/height), with
1640+
// the map stretched to fill it. `dpi` acts as a resolution multiplier
1641+
// relative to the 96 DPI baseline, so a higher DPI yields a larger,
1642+
// higher-resolution export (the map is scaled up from the canvas, matching
1643+
// the paper-preset behavior). The physical size stays the base size at
1644+
// 96 DPI, so only the pixel count — and therefore the file size — grows.
16421645
if (this._state.pageSize === "fit") {
1643-
const pageW = this._state.width || mapW;
1644-
const pageH = this._state.height || mapH;
1646+
const baseW = this._state.width || mapW;
1647+
const baseH = this._state.height || mapH;
1648+
const dpi = this._state.dpi > 0 ? this._state.dpi : 96;
1649+
const dpiScale = dpi / 96;
1650+
const pageW = Math.max(1, Math.round(baseW * dpiScale));
1651+
const pageH = Math.max(1, Math.round(baseH * dpiScale));
16451652
return {
16461653
pageW,
16471654
pageH,
16481655
content: { x: 0, y: 0, w: pageW, h: pageH },
16491656
mapDest: { x: 0, y: 0, w: pageW, h: pageH },
16501657
scaleX: mapW > 0 ? pageW / mapW : 1,
16511658
clip: false,
1652-
// dpi is ignored in 'fit' mode, so physical sizing uses a fixed 96 DPI.
1653-
pageWidthIn: pageW / 96,
1654-
pageHeightIn: pageH / 96,
1659+
pageWidthIn: baseW / 96,
1660+
pageHeightIn: baseH / 96,
16551661
};
16561662
}
16571663

src/lib/core/types.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3212,8 +3212,9 @@ export interface PrintControlOptions {
32123212
orientation?: PrintOrientation;
32133213
/**
32143214
* Output resolution in dots per inch. Combined with a paper `pageSize` it
3215-
* determines the export pixel dimensions (pixels = inches x dpi). Ignored
3216-
* when `pageSize` is `'fit'`. Default: 96.
3215+
* determines the export pixel dimensions (pixels = inches x dpi). In `'fit'`
3216+
* mode it scales the export resolution relative to the 96 DPI baseline (a
3217+
* higher DPI produces a larger, higher-resolution image). Default: 96.
32173218
*/
32183219
dpi?: number;
32193220
/** Page margin in points (1/72 inch) around the map. Ignored for `'fit'`. Default: 0. */

0 commit comments

Comments
 (0)