Skip to content

Commit

Permalink
feat(display): Support high-resolution displays
Browse files Browse the repository at this point in the history
  • Loading branch information
personalizedrefrigerator committed Oct 28, 2023
1 parent 5b07797 commit 676beb9
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 5 deletions.
41 changes: 36 additions & 5 deletions packages/js-draw/src/rendering/Display.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export default class Display {
private textRenderer: TextOnlyRenderer;
private textRerenderOutput: HTMLElement|null = null;
private cache: RenderingCache;
private devicePixelRatio: number = window.devicePixelRatio ?? 1;
private resizeSurfacesCallback?: ()=> void;
private flattenCallback?: ()=> void;

Expand Down Expand Up @@ -136,17 +137,32 @@ export default class Display {
}

this.resizeSurfacesCallback = () => {
const expectedWidth = (canvas: HTMLCanvasElement): number => {
return Math.ceil(canvas.clientWidth * this.devicePixelRatio);
};
const expectedHeight = (canvas: HTMLCanvasElement): number => {
return Math.ceil(canvas.clientHeight * this.devicePixelRatio);
};

const hasSizeMismatch = (canvas: HTMLCanvasElement): boolean => {
return canvas.clientHeight !== canvas.height || canvas.clientWidth !== canvas.width;
return expectedHeight(canvas) !== canvas.height || expectedWidth(canvas) !== canvas.width;
};

// Ensure that the drawing surfaces sizes match the
// canvas' sizes to prevent stretching.
if (hasSizeMismatch(dryInkCanvas) || hasSizeMismatch(wetInkCanvas)) {
dryInkCanvas.width = dryInkCanvas.clientWidth;
dryInkCanvas.height = dryInkCanvas.clientHeight;
wetInkCanvas.width = wetInkCanvas.clientWidth;
wetInkCanvas.height = wetInkCanvas.clientHeight;
dryInkCanvas.width = expectedWidth(dryInkCanvas);
dryInkCanvas.height = expectedHeight(dryInkCanvas);
wetInkCanvas.width = expectedWidth(wetInkCanvas);
wetInkCanvas.height = expectedHeight(wetInkCanvas);

// Ensure correct drawing operations on high-resolution screens.
// See
// https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Optimizing_canvas#scaling_for_high_resolution_displays
wetInkCtx.resetTransform();
dryInkCtx.resetTransform();
dryInkCtx.scale(this.devicePixelRatio, this.devicePixelRatio);
wetInkCtx.scale(this.devicePixelRatio, this.devicePixelRatio);

this.editor.notifier.dispatch(EditorEventType.DisplayResized, {
kind: EditorEventType.DisplayResized,
Expand All @@ -160,7 +176,10 @@ export default class Display {
this.resizeSurfacesCallback();

this.flattenCallback = () => {
dryInkCtx.save();
dryInkCtx.resetTransform();
dryInkCtx.drawImage(wetInkCanvas, 0, 0);
dryInkCtx.restore();
};

this.getColorAt = (screenPos: Point2) => {
Expand Down Expand Up @@ -194,6 +213,18 @@ export default class Display {
this.editor.createHTMLOverlay(textRendererOutputContainer);
}

/**
* Sets the device-pixel-ratio.
*
* Intended for debugging. Users do not need to call this manually.
*
* @internal
*/
public setDevicePixelRatio(dpr: number) {
this.devicePixelRatio = dpr;
this.resizeSurfacesCallback?.();
}

/**
* Rerenders the text-based display.
* The text-based display is intended for screen readers and can be navigated to by pressing `tab`.
Expand Down
3 changes: 3 additions & 0 deletions packages/js-draw/src/rendering/renderers/CanvasRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,10 @@ export default class CanvasRenderer extends AbstractRenderer {
}

public clear() {
this.ctx.save();
this.ctx.resetTransform();
this.ctx.clearRect(0, 0, this.ctx.canvas.width, this.ctx.canvas.height);
this.ctx.restore();
}

protected beginPath(startPoint: Point2) {
Expand Down

0 comments on commit 676beb9

Please sign in to comment.