From caf3462911dfc1740555959fd41a3903bdbeb2da Mon Sep 17 00:00:00 2001
From: Calixte Denizet <calixte.denizet@gmail.com>
Date: Wed, 5 Jul 2023 18:09:53 +0200
Subject: [PATCH] [Editor] Move the 'keep aspect ratio' stuff to the
 AnnotationEditor level

It'll help to avoid code duplication between the different editors having
this feature.
---
 src/display/editor/editor.js | 45 ++++++++++++++++++++++++++++++++++++
 src/display/editor/ink.js    | 42 ++++++++-------------------------
 2 files changed, 54 insertions(+), 33 deletions(-)

diff --git a/src/display/editor/editor.js b/src/display/editor/editor.js
index 3751d8244..a974a88e4 100644
--- a/src/display/editor/editor.js
+++ b/src/display/editor/editor.js
@@ -21,6 +21,11 @@
 import { bindEvents, ColorManager } from "./tools.js";
 import { FeatureTest, shadow, unreachable } from "../../shared/util.js";
 
+// The dimensions of the resizer is 15x15:
+// https://searchfox.org/mozilla-central/rev/1ce190047b9556c3c10ab4de70a0e61d893e2954/toolkit/content/minimal-xul.css#136-137
+// so each dimension must be greater than RESIZER_SIZE.
+const RESIZER_SIZE = 16;
+
 /**
  * @typedef {Object} AnnotationEditorParameters
  * @property {AnnotationEditorUIManager} uiManager - the global manager
@@ -34,6 +39,8 @@ import { FeatureTest, shadow, unreachable } from "../../shared/util.js";
  * Base class for editors.
  */
 class AnnotationEditor {
+  #aspectRatio = 0;
+
   #boundFocusin = this.focusin.bind(this);
 
   #boundFocusout = this.focusout.bind(this);
@@ -614,6 +621,44 @@ class AnnotationEditor {
       this.parent.setActiveEditor(null);
     }
   }
+
+  /**
+   * Set the minimum dimensions of the editor.
+   */
+  setMinDims() {
+    const { style } = this.div;
+    if (this.#aspectRatio >= 1) {
+      style.minHeight = `${RESIZER_SIZE}px`;
+      style.minWidth = `${Math.round(this.#aspectRatio * RESIZER_SIZE)}px`;
+    } else {
+      style.minWidth = `${RESIZER_SIZE}px`;
+      style.minHeight = `${Math.round(RESIZER_SIZE / this.#aspectRatio)}px`;
+    }
+  }
+
+  /**
+   * Set the aspect ratio to use when resizing.
+   * @param {number} width
+   * @param {number} height
+   */
+  setAspectRatio(width, height) {
+    this.#aspectRatio = width / height;
+  }
+
+  getHeight(width, height) {
+    if (
+      this.#aspectRatio &&
+      Math.abs(this.#aspectRatio - width / height) > 1e-2
+    ) {
+      height = Math.ceil(width / this.#aspectRatio);
+      this.setDims(width, height);
+    }
+    return height;
+  }
+
+  static get MIN_SIZE() {
+    return RESIZER_SIZE;
+  }
 }
 
 // This class is used to fake an editor which has been deleted.
diff --git a/src/display/editor/ink.js b/src/display/editor/ink.js
index 5ec0fdb1b..599e2b314 100644
--- a/src/display/editor/ink.js
+++ b/src/display/editor/ink.js
@@ -22,17 +22,10 @@ import { AnnotationEditor } from "./editor.js";
 import { InkAnnotationElement } from "../annotation_layer.js";
 import { opacityToHex } from "./tools.js";
 
-// The dimensions of the resizer is 15x15:
-// https://searchfox.org/mozilla-central/rev/1ce190047b9556c3c10ab4de70a0e61d893e2954/toolkit/content/minimal-xul.css#136-137
-// so each dimension must be greater than RESIZER_SIZE.
-const RESIZER_SIZE = 16;
-
 /**
  * Basic draw editor in order to generate an Ink annotation.
  */
 class InkEditor extends AnnotationEditor {
-  #aspectRatio = 0;
-
   #baseHeight = 0;
 
   #baseWidth = 0;
@@ -795,7 +788,7 @@ class InkEditor extends AnnotationEditor {
       this.#setCanvasDims();
       this.setDims(this.width * parentWidth, this.height * parentHeight);
       this.#redraw();
-      this.#setMinDims();
+      this.setMinDims();
       this.div.classList.add("disabled");
     } else {
       this.div.classList.add("editing");
@@ -839,13 +832,7 @@ class InkEditor extends AnnotationEditor {
 
     this.canvas.style.visibility = "hidden";
 
-    if (
-      this.#aspectRatio &&
-      Math.abs(this.#aspectRatio - width / height) > 1e-2
-    ) {
-      height = Math.ceil(width / this.#aspectRatio);
-      this.setDims(width, height);
-    }
+    height = this.getHeight(width, height);
 
     const [parentWidth, parentHeight] = this.parentDimensions;
     this.width = width / parentWidth;
@@ -1086,8 +1073,8 @@ class InkEditor extends AnnotationEditor {
 
     const bbox = this.#getBbox();
     const padding = this.#getPadding();
-    this.#baseWidth = Math.max(RESIZER_SIZE, bbox[2] - bbox[0]);
-    this.#baseHeight = Math.max(RESIZER_SIZE, bbox[3] - bbox[1]);
+    this.#baseWidth = Math.max(AnnotationEditor.MIN_SIZE, bbox[2] - bbox[0]);
+    this.#baseHeight = Math.max(AnnotationEditor.MIN_SIZE, bbox[3] - bbox[1]);
 
     const width = Math.ceil(padding + this.#baseWidth * this.scaleFactor);
     const height = Math.ceil(padding + this.#baseHeight * this.scaleFactor);
@@ -1096,8 +1083,8 @@ class InkEditor extends AnnotationEditor {
     this.width = width / parentWidth;
     this.height = height / parentHeight;
 
-    this.#aspectRatio = width / height;
-    this.#setMinDims();
+    this.setAspectRatio(width, height);
+    this.setMinDims();
 
     const prevTranslationX = this.translationX;
     const prevTranslationY = this.translationY;
@@ -1118,17 +1105,6 @@ class InkEditor extends AnnotationEditor {
     );
   }
 
-  #setMinDims() {
-    const { style } = this.div;
-    if (this.#aspectRatio >= 1) {
-      style.minHeight = `${RESIZER_SIZE}px`;
-      style.minWidth = `${Math.round(this.#aspectRatio * RESIZER_SIZE)}px`;
-    } else {
-      style.minWidth = `${RESIZER_SIZE}px`;
-      style.minHeight = `${Math.round(RESIZER_SIZE / this.#aspectRatio)}px`;
-    }
-  }
-
   /** @inheritdoc */
   static deserialize(data, parent, uiManager) {
     if (data instanceof InkAnnotationElement) {
@@ -1146,7 +1122,7 @@ class InkEditor extends AnnotationEditor {
     const scaleFactor = editor.parentScale;
     const padding = data.thickness / 2;
 
-    editor.#aspectRatio = width / height;
+    editor.setAspectRatio(width, height);
     editor.#disableEditing = true;
     editor.#realWidth = Math.round(width);
     editor.#realHeight = Math.round(height);
@@ -1180,8 +1156,8 @@ class InkEditor extends AnnotationEditor {
     }
 
     const bbox = editor.#getBbox();
-    editor.#baseWidth = Math.max(RESIZER_SIZE, bbox[2] - bbox[0]);
-    editor.#baseHeight = Math.max(RESIZER_SIZE, bbox[3] - bbox[1]);
+    editor.#baseWidth = Math.max(AnnotationEditor.MIN_SIZE, bbox[2] - bbox[0]);
+    editor.#baseHeight = Math.max(AnnotationEditor.MIN_SIZE, bbox[3] - bbox[1]);
     editor.#setScaleFactor(width, height);
 
     return editor;