[Editor] Add the possibility to change the thickness of a free highlight (bug 1876096)
This commit is contained in:
		
							parent
							
								
									f81f9bb7d3
								
							
						
					
					
						commit
						2b8ecf5688
					
				@ -349,6 +349,8 @@ pdfjs-editor-ink-opacity-input = Opacity
 | 
				
			|||||||
pdfjs-editor-stamp-add-image-button =
 | 
					pdfjs-editor-stamp-add-image-button =
 | 
				
			||||||
    .title = Add image
 | 
					    .title = Add image
 | 
				
			||||||
pdfjs-editor-stamp-add-image-button-label = Add image
 | 
					pdfjs-editor-stamp-add-image-button-label = Add image
 | 
				
			||||||
 | 
					# This refers to the thickness of the line used for free highlighting (not bound to text)
 | 
				
			||||||
 | 
					pdfjs-editor-free-highlight-thickness-input = Thickness
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pdfjs-free-text =
 | 
					pdfjs-free-text =
 | 
				
			||||||
    .aria-label = Text Editor
 | 
					    .aria-label = Text Editor
 | 
				
			||||||
 | 
				
			|||||||
@ -155,6 +155,14 @@ class DrawLayer {
 | 
				
			|||||||
    path.setAttribute("d", line.toSVGPath());
 | 
					    path.setAttribute("d", line.toSVGPath());
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  updateLine(id, line) {
 | 
				
			||||||
 | 
					    const root = this.#mapping.get(id);
 | 
				
			||||||
 | 
					    const defs = root.firstChild;
 | 
				
			||||||
 | 
					    const path = defs.firstChild;
 | 
				
			||||||
 | 
					    this.updateBox(id, line.box);
 | 
				
			||||||
 | 
					    path.setAttribute("d", line.toSVGPath());
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  removeFreeHighlight(id) {
 | 
					  removeFreeHighlight(id) {
 | 
				
			||||||
    this.remove(id);
 | 
					    this.remove(id);
 | 
				
			||||||
    this.#toUpdate.delete(id);
 | 
					    this.#toUpdate.delete(id);
 | 
				
			||||||
 | 
				
			|||||||
@ -359,7 +359,11 @@ class AnnotationEditorLayer {
 | 
				
			|||||||
        // Do nothing on right click.
 | 
					        // Do nothing on right click.
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      HighlightEditor.startHighlighting(this, event);
 | 
					      HighlightEditor.startHighlighting(
 | 
				
			||||||
 | 
					        this,
 | 
				
			||||||
 | 
					        this.#uiManager.direction === "ltr",
 | 
				
			||||||
 | 
					        event
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
      event.preventDefault();
 | 
					      event.preventDefault();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
				
			|||||||
@ -472,7 +472,7 @@ class AnnotationEditor {
 | 
				
			|||||||
    // the position: it'll be done when the user will release the mouse button.
 | 
					    // the position: it'll be done when the user will release the mouse button.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let { x, y } = this;
 | 
					    let { x, y } = this;
 | 
				
			||||||
    const [bx, by] = this.#getBaseTranslation();
 | 
					    const [bx, by] = this.getBaseTranslation();
 | 
				
			||||||
    x += bx;
 | 
					    x += bx;
 | 
				
			||||||
    y += by;
 | 
					    y += by;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -481,7 +481,14 @@ class AnnotationEditor {
 | 
				
			|||||||
    this.div.scrollIntoView({ block: "nearest" });
 | 
					    this.div.scrollIntoView({ block: "nearest" });
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  #getBaseTranslation() {
 | 
					  /**
 | 
				
			||||||
 | 
					   * Get the translation to take into account the editor border.
 | 
				
			||||||
 | 
					   * The CSS engine positions the element by taking the border into account so
 | 
				
			||||||
 | 
					   * we must apply the opposite translation to have the editor in the right
 | 
				
			||||||
 | 
					   * position.
 | 
				
			||||||
 | 
					   * @returns {Array<number>}
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					  getBaseTranslation() {
 | 
				
			||||||
    const [parentWidth, parentHeight] = this.parentDimensions;
 | 
					    const [parentWidth, parentHeight] = this.parentDimensions;
 | 
				
			||||||
    const { _borderLineWidth } = AnnotationEditor;
 | 
					    const { _borderLineWidth } = AnnotationEditor;
 | 
				
			||||||
    const x = _borderLineWidth / parentWidth;
 | 
					    const x = _borderLineWidth / parentWidth;
 | 
				
			||||||
@ -532,7 +539,7 @@ class AnnotationEditor {
 | 
				
			|||||||
    this.x = x /= pageWidth;
 | 
					    this.x = x /= pageWidth;
 | 
				
			||||||
    this.y = y /= pageHeight;
 | 
					    this.y = y /= pageHeight;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const [bx, by] = this.#getBaseTranslation();
 | 
					    const [bx, by] = this.getBaseTranslation();
 | 
				
			||||||
    x += bx;
 | 
					    x += bx;
 | 
				
			||||||
    y += by;
 | 
					    y += by;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -50,11 +50,13 @@ class HighlightEditor extends AnnotationEditor {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  #outlineId = null;
 | 
					  #outlineId = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  #thickness;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  static _defaultColor = null;
 | 
					  static _defaultColor = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  static _defaultOpacity = 1;
 | 
					  static _defaultOpacity = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  static _defaultThickness = 10;
 | 
					  static _defaultThickness = 12;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  static _l10nPromise;
 | 
					  static _l10nPromise;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -71,6 +73,7 @@ class HighlightEditor extends AnnotationEditor {
 | 
				
			|||||||
  constructor(params) {
 | 
					  constructor(params) {
 | 
				
			||||||
    super({ ...params, name: "highlightEditor" });
 | 
					    super({ ...params, name: "highlightEditor" });
 | 
				
			||||||
    this.color = params.color || HighlightEditor._defaultColor;
 | 
					    this.color = params.color || HighlightEditor._defaultColor;
 | 
				
			||||||
 | 
					    this.#thickness = params.thickness || HighlightEditor._defaultThickness;
 | 
				
			||||||
    this.#opacity = params.opacity || HighlightEditor._defaultOpacity;
 | 
					    this.#opacity = params.opacity || HighlightEditor._defaultOpacity;
 | 
				
			||||||
    this.#boxes = params.boxes || null;
 | 
					    this.#boxes = params.boxes || null;
 | 
				
			||||||
    this._isDraggable = false;
 | 
					    this._isDraggable = false;
 | 
				
			||||||
@ -112,17 +115,31 @@ class HighlightEditor extends AnnotationEditor {
 | 
				
			|||||||
    ];
 | 
					    ];
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  #createFreeOutlines({ highlight, highlightId, clipPathId }) {
 | 
					  #createFreeOutlines({ highlightOutlines, highlightId, clipPathId }) {
 | 
				
			||||||
    this.#highlightOutlines = highlight.getOutlines(
 | 
					    this.#highlightOutlines = highlightOutlines;
 | 
				
			||||||
      this._uiManager.direction === "ltr"
 | 
					    const extraThickness = 1.5;
 | 
				
			||||||
 | 
					    this.#focusOutlines = highlightOutlines.getNewOutline(
 | 
				
			||||||
 | 
					      /* Slightly bigger than the highlight in order to have a little
 | 
				
			||||||
 | 
					         space between the highlight and the outline. */
 | 
				
			||||||
 | 
					      this.#thickness / 2 + extraThickness,
 | 
				
			||||||
 | 
					      /* innerMargin = */ 0.0025
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
    this.#id = highlightId;
 | 
					 | 
				
			||||||
    this.#clipPathId = clipPathId;
 | 
					 | 
				
			||||||
    const { x, y, width, height, lastPoint } = this.#highlightOutlines.box;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // We need to redraw the highlight because we change the coordinates to be
 | 
					    if (highlightId >= 0) {
 | 
				
			||||||
    // in the box coordinate system.
 | 
					      this.#id = highlightId;
 | 
				
			||||||
    this.parent.drawLayer.finalizeLine(this.#id, this.#highlightOutlines);
 | 
					      this.#clipPathId = clipPathId;
 | 
				
			||||||
 | 
					      // We need to redraw the highlight because we change the coordinates to be
 | 
				
			||||||
 | 
					      // in the box coordinate system.
 | 
				
			||||||
 | 
					      this.parent.drawLayer.finalizeLine(highlightId, highlightOutlines);
 | 
				
			||||||
 | 
					      this.#outlineId = this.parent.drawLayer.highlightOutline(
 | 
				
			||||||
 | 
					        this.#focusOutlines
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					    } else if (this.parent) {
 | 
				
			||||||
 | 
					      this.parent.drawLayer.updateLine(this.#id, highlightOutlines);
 | 
				
			||||||
 | 
					      this.parent.drawLayer.updateLine(this.#outlineId, this.#focusOutlines);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    const { x, y, width, height, lastPoint } = highlightOutlines.box;
 | 
				
			||||||
 | 
					    this.#lastPoint = lastPoint;
 | 
				
			||||||
    switch (this.rotation) {
 | 
					    switch (this.rotation) {
 | 
				
			||||||
      case 0:
 | 
					      case 0:
 | 
				
			||||||
        this.x = x;
 | 
					        this.x = x;
 | 
				
			||||||
@ -153,30 +170,24 @@ class HighlightEditor extends AnnotationEditor {
 | 
				
			|||||||
        break;
 | 
					        break;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					 | 
				
			||||||
    const innerMargin = 1.5;
 | 
					 | 
				
			||||||
    this.#focusOutlines = highlight.getFocusOutline(
 | 
					 | 
				
			||||||
      /* Slightly bigger than the highlight in order to have a little
 | 
					 | 
				
			||||||
         space between the highlight and the outline. */
 | 
					 | 
				
			||||||
      HighlightEditor._defaultThickness + innerMargin
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
    this.#outlineId = this.parent.drawLayer.highlightOutline(
 | 
					 | 
				
			||||||
      this.#focusOutlines
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
    this.#lastPoint = lastPoint;
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /** @inheritdoc */
 | 
				
			||||||
  static initialize(l10n, uiManager) {
 | 
					  static initialize(l10n, uiManager) {
 | 
				
			||||||
    AnnotationEditor.initialize(l10n, uiManager);
 | 
					    AnnotationEditor.initialize(l10n, uiManager);
 | 
				
			||||||
    HighlightEditor._defaultColor ||=
 | 
					    HighlightEditor._defaultColor ||=
 | 
				
			||||||
      uiManager.highlightColors?.values().next().value || "#fff066";
 | 
					      uiManager.highlightColors?.values().next().value || "#fff066";
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /** @inheritdoc */
 | 
				
			||||||
  static updateDefaultParams(type, value) {
 | 
					  static updateDefaultParams(type, value) {
 | 
				
			||||||
    switch (type) {
 | 
					    switch (type) {
 | 
				
			||||||
      case AnnotationEditorParamsType.HIGHLIGHT_DEFAULT_COLOR:
 | 
					      case AnnotationEditorParamsType.HIGHLIGHT_DEFAULT_COLOR:
 | 
				
			||||||
        HighlightEditor._defaultColor = value;
 | 
					        HighlightEditor._defaultColor = value;
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
 | 
					      case AnnotationEditorParamsType.HIGHLIGHT_THICKNESS:
 | 
				
			||||||
 | 
					        HighlightEditor._defaultThickness = value;
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -194,6 +205,9 @@ class HighlightEditor extends AnnotationEditor {
 | 
				
			|||||||
      case AnnotationEditorParamsType.HIGHLIGHT_COLOR:
 | 
					      case AnnotationEditorParamsType.HIGHLIGHT_COLOR:
 | 
				
			||||||
        this.#updateColor(value);
 | 
					        this.#updateColor(value);
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
 | 
					      case AnnotationEditorParamsType.HIGHLIGHT_THICKNESS:
 | 
				
			||||||
 | 
					        this.#updateThickness(value);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -203,6 +217,10 @@ class HighlightEditor extends AnnotationEditor {
 | 
				
			|||||||
        AnnotationEditorParamsType.HIGHLIGHT_DEFAULT_COLOR,
 | 
					        AnnotationEditorParamsType.HIGHLIGHT_DEFAULT_COLOR,
 | 
				
			||||||
        HighlightEditor._defaultColor,
 | 
					        HighlightEditor._defaultColor,
 | 
				
			||||||
      ],
 | 
					      ],
 | 
				
			||||||
 | 
					      [
 | 
				
			||||||
 | 
					        AnnotationEditorParamsType.HIGHLIGHT_THICKNESS,
 | 
				
			||||||
 | 
					        HighlightEditor._defaultThickness,
 | 
				
			||||||
 | 
					      ],
 | 
				
			||||||
    ];
 | 
					    ];
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -213,6 +231,10 @@ class HighlightEditor extends AnnotationEditor {
 | 
				
			|||||||
        AnnotationEditorParamsType.HIGHLIGHT_COLOR,
 | 
					        AnnotationEditorParamsType.HIGHLIGHT_COLOR,
 | 
				
			||||||
        this.color || HighlightEditor._defaultColor,
 | 
					        this.color || HighlightEditor._defaultColor,
 | 
				
			||||||
      ],
 | 
					      ],
 | 
				
			||||||
 | 
					      [
 | 
				
			||||||
 | 
					        AnnotationEditorParamsType.HIGHLIGHT_THICKNESS,
 | 
				
			||||||
 | 
					        this.#thickness || HighlightEditor._defaultThickness,
 | 
				
			||||||
 | 
					      ],
 | 
				
			||||||
    ];
 | 
					    ];
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -238,6 +260,27 @@ class HighlightEditor extends AnnotationEditor {
 | 
				
			|||||||
    });
 | 
					    });
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /**
 | 
				
			||||||
 | 
					   * Update the thickness and make this action undoable.
 | 
				
			||||||
 | 
					   * @param {number} thickness
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					  #updateThickness(thickness) {
 | 
				
			||||||
 | 
					    const savedThickness = this.#thickness;
 | 
				
			||||||
 | 
					    const setThickness = th => {
 | 
				
			||||||
 | 
					      this.#thickness = th;
 | 
				
			||||||
 | 
					      this.#changeThickness(th);
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    this.addCommands({
 | 
				
			||||||
 | 
					      cmd: setThickness.bind(this, thickness),
 | 
				
			||||||
 | 
					      undo: setThickness.bind(this, savedThickness),
 | 
				
			||||||
 | 
					      post: this._uiManager.updateUI.bind(this._uiManager, this),
 | 
				
			||||||
 | 
					      mustExec: true,
 | 
				
			||||||
 | 
					      type: AnnotationEditorParamsType.INK_THICKNESS,
 | 
				
			||||||
 | 
					      overwriteIfSameType: true,
 | 
				
			||||||
 | 
					      keepUndo: true,
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /** @inheritdoc */
 | 
					  /** @inheritdoc */
 | 
				
			||||||
  async addEditToolbar() {
 | 
					  async addEditToolbar() {
 | 
				
			||||||
    const toolbar = await super.addEditToolbar();
 | 
					    const toolbar = await super.addEditToolbar();
 | 
				
			||||||
@ -268,6 +311,13 @@ class HighlightEditor extends AnnotationEditor {
 | 
				
			|||||||
    return super.fixAndSetPosition(this.#getRotation());
 | 
					    return super.fixAndSetPosition(this.#getRotation());
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /** @inheritdoc */
 | 
				
			||||||
 | 
					  getBaseTranslation() {
 | 
				
			||||||
 | 
					    // The editor itself doesn't have any CSS border (we're drawing one
 | 
				
			||||||
 | 
					    // ourselves in using SVG).
 | 
				
			||||||
 | 
					    return [0, 0];
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /** @inheritdoc */
 | 
					  /** @inheritdoc */
 | 
				
			||||||
  getRect(tx, ty) {
 | 
					  getRect(tx, ty) {
 | 
				
			||||||
    return super.getRect(tx, ty, this.#getRotation());
 | 
					    return super.getRect(tx, ty, this.#getRotation());
 | 
				
			||||||
@ -322,6 +372,18 @@ class HighlightEditor extends AnnotationEditor {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  #changeThickness(thickness) {
 | 
				
			||||||
 | 
					    if (!this.#isFreeHighlight) {
 | 
				
			||||||
 | 
					      return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    this.#createFreeOutlines({
 | 
				
			||||||
 | 
					      highlightOutlines: this.#highlightOutlines.getNewOutline(thickness / 2),
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    this.fixAndSetPosition();
 | 
				
			||||||
 | 
					    const [parentWidth, parentHeight] = this.parentDimensions;
 | 
				
			||||||
 | 
					    this.setDims(this.width * parentWidth, this.height * parentHeight);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  #cleanDrawLayer() {
 | 
					  #cleanDrawLayer() {
 | 
				
			||||||
    if (this.#id === null || !this.parent) {
 | 
					    if (this.#id === null || !this.parent) {
 | 
				
			||||||
      return;
 | 
					      return;
 | 
				
			||||||
@ -480,7 +542,7 @@ class HighlightEditor extends AnnotationEditor {
 | 
				
			|||||||
    return this.#highlightOutlines.serialize(rect, this.#getRotation());
 | 
					    return this.#highlightOutlines.serialize(rect, this.#getRotation());
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  static startHighlighting(parent, { target: textLayer, x, y }) {
 | 
					  static startHighlighting(parent, isLTR, { target: textLayer, x, y }) {
 | 
				
			||||||
    const {
 | 
					    const {
 | 
				
			||||||
      x: layerX,
 | 
					      x: layerX,
 | 
				
			||||||
      y: layerY,
 | 
					      y: layerY,
 | 
				
			||||||
@ -518,7 +580,8 @@ class HighlightEditor extends AnnotationEditor {
 | 
				
			|||||||
      { x, y },
 | 
					      { x, y },
 | 
				
			||||||
      [layerX, layerY, parentWidth, parentHeight],
 | 
					      [layerX, layerY, parentWidth, parentHeight],
 | 
				
			||||||
      parent.scale,
 | 
					      parent.scale,
 | 
				
			||||||
      this._defaultThickness,
 | 
					      this._defaultThickness / 2,
 | 
				
			||||||
 | 
					      isLTR,
 | 
				
			||||||
      /* innerMargin = */ 0.001
 | 
					      /* innerMargin = */ 0.001
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
    ({ id: this._freeHighlightId, clipPathId: this._freeHighlightClipId } =
 | 
					    ({ id: this._freeHighlightId, clipPathId: this._freeHighlightClipId } =
 | 
				
			||||||
@ -541,7 +604,7 @@ class HighlightEditor extends AnnotationEditor {
 | 
				
			|||||||
    if (!this._freeHighlight.isEmpty()) {
 | 
					    if (!this._freeHighlight.isEmpty()) {
 | 
				
			||||||
      parent.createAndAddNewEditor(event, false, {
 | 
					      parent.createAndAddNewEditor(event, false, {
 | 
				
			||||||
        highlightId: this._freeHighlightId,
 | 
					        highlightId: this._freeHighlightId,
 | 
				
			||||||
        highlight: this._freeHighlight,
 | 
					        highlightOutlines: this._freeHighlight.getOutlines(),
 | 
				
			||||||
        clipPathId: this._freeHighlightClipId,
 | 
					        clipPathId: this._freeHighlightClipId,
 | 
				
			||||||
      });
 | 
					      });
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
@ -595,7 +658,7 @@ class HighlightEditor extends AnnotationEditor {
 | 
				
			|||||||
      annotationType: AnnotationEditorType.HIGHLIGHT,
 | 
					      annotationType: AnnotationEditorType.HIGHLIGHT,
 | 
				
			||||||
      color,
 | 
					      color,
 | 
				
			||||||
      opacity: this.#opacity,
 | 
					      opacity: this.#opacity,
 | 
				
			||||||
      thickness: 2 * HighlightEditor._defaultThickness,
 | 
					      thickness: this.#thickness,
 | 
				
			||||||
      quadPoints: this.#serializeBoxes(rect),
 | 
					      quadPoints: this.#serializeBoxes(rect),
 | 
				
			||||||
      outlines: this.#serializeOutlines(rect),
 | 
					      outlines: this.#serializeOutlines(rect),
 | 
				
			||||||
      pageIndex: this.pageIndex,
 | 
					      pageIndex: this.pageIndex,
 | 
				
			||||||
 | 
				
			|||||||
@ -350,6 +350,8 @@ class FreeOutliner {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  #innerMargin;
 | 
					  #innerMargin;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  #isLTR;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  #top = [];
 | 
					  #top = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // The first 6 elements are the last 3 points of the top part of the outline.
 | 
					  // The first 6 elements are the last 3 points of the top part of the outline.
 | 
				
			||||||
@ -377,9 +379,10 @@ class FreeOutliner {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  static #MIN = FreeOutliner.#MIN_DIST + FreeOutliner.#MIN_DIFF;
 | 
					  static #MIN = FreeOutliner.#MIN_DIST + FreeOutliner.#MIN_DIFF;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  constructor({ x, y }, box, scaleFactor, thickness, innerMargin = 0) {
 | 
					  constructor({ x, y }, box, scaleFactor, thickness, isLTR, innerMargin = 0) {
 | 
				
			||||||
    this.#box = box;
 | 
					    this.#box = box;
 | 
				
			||||||
    this.#thickness = thickness * scaleFactor;
 | 
					    this.#thickness = thickness * scaleFactor;
 | 
				
			||||||
 | 
					    this.#isLTR = isLTR;
 | 
				
			||||||
    this.#last.set([NaN, NaN, NaN, NaN, x, y], 6);
 | 
					    this.#last.set([NaN, NaN, NaN, NaN, x, y], 6);
 | 
				
			||||||
    this.#innerMargin = innerMargin;
 | 
					    this.#innerMargin = innerMargin;
 | 
				
			||||||
    this.#min_dist = FreeOutliner.#MIN_DIST * scaleFactor;
 | 
					    this.#min_dist = FreeOutliner.#MIN_DIST * scaleFactor;
 | 
				
			||||||
@ -571,24 +574,7 @@ class FreeOutliner {
 | 
				
			|||||||
    return buffer.join(" ");
 | 
					    return buffer.join(" ");
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  getFocusOutline(thickness) {
 | 
					  getOutlines() {
 | 
				
			||||||
    // Build the outline of the highlight to use as the focus outline.
 | 
					 | 
				
			||||||
    const [x, y] = this.#points;
 | 
					 | 
				
			||||||
    const outliner = new FreeOutliner(
 | 
					 | 
				
			||||||
      { x, y },
 | 
					 | 
				
			||||||
      this.#box,
 | 
					 | 
				
			||||||
      this.#scaleFactor,
 | 
					 | 
				
			||||||
      thickness,
 | 
					 | 
				
			||||||
      /* innerMargin = */ 0.0025
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
    outliner.#points = null;
 | 
					 | 
				
			||||||
    for (let i = 2; i < this.#points.length; i += 2) {
 | 
					 | 
				
			||||||
      outliner.add({ x: this.#points[i], y: this.#points[i + 1] });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return outliner.getOutlines();
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  getOutlines(isLTR) {
 | 
					 | 
				
			||||||
    const top = this.#top;
 | 
					    const top = this.#top;
 | 
				
			||||||
    const bottom = this.#bottom;
 | 
					    const bottom = this.#bottom;
 | 
				
			||||||
    const last = this.#last;
 | 
					    const last = this.#last;
 | 
				
			||||||
@ -637,8 +623,10 @@ class FreeOutliner {
 | 
				
			|||||||
      return new FreeHighlightOutline(
 | 
					      return new FreeHighlightOutline(
 | 
				
			||||||
        outline,
 | 
					        outline,
 | 
				
			||||||
        points,
 | 
					        points,
 | 
				
			||||||
 | 
					        this.#box,
 | 
				
			||||||
 | 
					        this.#scaleFactor,
 | 
				
			||||||
        this.#innerMargin,
 | 
					        this.#innerMargin,
 | 
				
			||||||
        isLTR
 | 
					        this.#isLTR
 | 
				
			||||||
      );
 | 
					      );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -686,24 +674,40 @@ class FreeOutliner {
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    outline.set([NaN, NaN, NaN, NaN, bottom[4], bottom[5]], N);
 | 
					    outline.set([NaN, NaN, NaN, NaN, bottom[4], bottom[5]], N);
 | 
				
			||||||
    return new FreeHighlightOutline(outline, points, this.#innerMargin, isLTR);
 | 
					    return new FreeHighlightOutline(
 | 
				
			||||||
 | 
					      outline,
 | 
				
			||||||
 | 
					      points,
 | 
				
			||||||
 | 
					      this.#box,
 | 
				
			||||||
 | 
					      this.#scaleFactor,
 | 
				
			||||||
 | 
					      this.#innerMargin,
 | 
				
			||||||
 | 
					      this.#isLTR
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class FreeHighlightOutline extends Outline {
 | 
					class FreeHighlightOutline extends Outline {
 | 
				
			||||||
 | 
					  #box;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  #bbox = null;
 | 
					  #bbox = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  #innerMargin;
 | 
					  #innerMargin;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  #isLTR;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  #points;
 | 
					  #points;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  #scaleFactor;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  #outline;
 | 
					  #outline;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  constructor(outline, points, innerMargin, isLTR) {
 | 
					  constructor(outline, points, box, scaleFactor, innerMargin, isLTR) {
 | 
				
			||||||
    super();
 | 
					    super();
 | 
				
			||||||
    this.#outline = outline;
 | 
					    this.#outline = outline;
 | 
				
			||||||
    this.#points = points;
 | 
					    this.#points = points;
 | 
				
			||||||
 | 
					    this.#box = box;
 | 
				
			||||||
 | 
					    this.#scaleFactor = scaleFactor;
 | 
				
			||||||
    this.#innerMargin = innerMargin;
 | 
					    this.#innerMargin = innerMargin;
 | 
				
			||||||
 | 
					    this.#isLTR = isLTR;
 | 
				
			||||||
    this.#computeMinMax(isLTR);
 | 
					    this.#computeMinMax(isLTR);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const { x, y, width, height } = this.#bbox;
 | 
					    const { x, y, width, height } = this.#bbox;
 | 
				
			||||||
@ -841,6 +845,34 @@ class FreeHighlightOutline extends Outline {
 | 
				
			|||||||
  get box() {
 | 
					  get box() {
 | 
				
			||||||
    return this.#bbox;
 | 
					    return this.#bbox;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  getNewOutline(thickness, innerMargin) {
 | 
				
			||||||
 | 
					    // Build the outline of the highlight to use as the focus outline.
 | 
				
			||||||
 | 
					    const { x, y, width, height } = this.#bbox;
 | 
				
			||||||
 | 
					    const [layerX, layerY, layerWidth, layerHeight] = this.#box;
 | 
				
			||||||
 | 
					    const sx = width * layerWidth;
 | 
				
			||||||
 | 
					    const sy = height * layerHeight;
 | 
				
			||||||
 | 
					    const tx = x * layerWidth + layerX;
 | 
				
			||||||
 | 
					    const ty = y * layerHeight + layerY;
 | 
				
			||||||
 | 
					    const outliner = new FreeOutliner(
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        x: this.#points[0] * sx + tx,
 | 
				
			||||||
 | 
					        y: this.#points[1] * sy + ty,
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      this.#box,
 | 
				
			||||||
 | 
					      this.#scaleFactor,
 | 
				
			||||||
 | 
					      thickness,
 | 
				
			||||||
 | 
					      this.#isLTR,
 | 
				
			||||||
 | 
					      innerMargin ?? this.#innerMargin
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					    for (let i = 2; i < this.#points.length; i += 2) {
 | 
				
			||||||
 | 
					      outliner.add({
 | 
				
			||||||
 | 
					        x: this.#points[i] * sx + tx,
 | 
				
			||||||
 | 
					        y: this.#points[i + 1] * sy + ty,
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return outliner.getOutlines();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export { FreeOutliner, Outliner };
 | 
					export { FreeOutliner, Outliner };
 | 
				
			||||||
 | 
				
			|||||||
@ -88,6 +88,7 @@ const AnnotationEditorParamsType = {
 | 
				
			|||||||
  INK_OPACITY: 23,
 | 
					  INK_OPACITY: 23,
 | 
				
			||||||
  HIGHLIGHT_COLOR: 31,
 | 
					  HIGHLIGHT_COLOR: 31,
 | 
				
			||||||
  HIGHLIGHT_DEFAULT_COLOR: 32,
 | 
					  HIGHLIGHT_DEFAULT_COLOR: 32,
 | 
				
			||||||
 | 
					  HIGHLIGHT_THICKNESS: 33,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Permission flags from Table 22, Section 7.6.3.2 of the PDF specification.
 | 
					// Permission flags from Table 22, Section 7.6.3.2 of the PDF specification.
 | 
				
			||||||
 | 
				
			|||||||
@ -14,7 +14,9 @@
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
 | 
					  awaitPromise,
 | 
				
			||||||
  closePages,
 | 
					  closePages,
 | 
				
			||||||
 | 
					  createPromise,
 | 
				
			||||||
  getEditorSelector,
 | 
					  getEditorSelector,
 | 
				
			||||||
  getSerialized,
 | 
					  getSerialized,
 | 
				
			||||||
  kbBigMoveLeft,
 | 
					  kbBigMoveLeft,
 | 
				
			||||||
@ -32,6 +34,11 @@ const selectAll = async page => {
 | 
				
			|||||||
  );
 | 
					  );
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const waitForPointerUp = page =>
 | 
				
			||||||
 | 
					  createPromise(page, resolve => {
 | 
				
			||||||
 | 
					    window.addEventListener("pointerup", resolve, { once: true });
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const getXY = (page, selector) =>
 | 
					const getXY = (page, selector) =>
 | 
				
			||||||
  page.evaluate(sel => {
 | 
					  page.evaluate(sel => {
 | 
				
			||||||
    const bbox = document.querySelector(sel).getBoundingClientRect();
 | 
					    const bbox = document.querySelector(sel).getBoundingClientRect();
 | 
				
			||||||
@ -586,4 +593,92 @@ describe("Highlight Editor", () => {
 | 
				
			|||||||
      );
 | 
					      );
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  describe("Free highlight thickness can be changed", () => {
 | 
				
			||||||
 | 
					    let pages;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    beforeAll(async () => {
 | 
				
			||||||
 | 
					      pages = await loadAndWait(
 | 
				
			||||||
 | 
					        "empty.pdf",
 | 
				
			||||||
 | 
					        ".annotationEditorLayer",
 | 
				
			||||||
 | 
					        null,
 | 
				
			||||||
 | 
					        null,
 | 
				
			||||||
 | 
					        { highlightEditorColors: "yellow=#000000" }
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    afterAll(async () => {
 | 
				
			||||||
 | 
					      await closePages(pages);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    it("must check that the thickness is correctly updated", async () => {
 | 
				
			||||||
 | 
					      await Promise.all(
 | 
				
			||||||
 | 
					        pages.map(async ([browserName, page]) => {
 | 
				
			||||||
 | 
					          await page.click("#editorHighlight");
 | 
				
			||||||
 | 
					          await page.waitForSelector(".annotationEditorLayer.highlightEditing");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          const rect = await page.$eval(".annotationEditorLayer", el => {
 | 
				
			||||||
 | 
					            // With Chrome something is wrong when serializing a DomRect,
 | 
				
			||||||
 | 
					            // hence we extract the values and just return them.
 | 
				
			||||||
 | 
					            const { x, y } = el.getBoundingClientRect();
 | 
				
			||||||
 | 
					            return { x, y };
 | 
				
			||||||
 | 
					          });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          for (let i = 0; i < 3; i++) {
 | 
				
			||||||
 | 
					            const x = rect.x + 120 + i * 120;
 | 
				
			||||||
 | 
					            const y = rect.y + 120 + i * 120;
 | 
				
			||||||
 | 
					            const clickHandle = await waitForPointerUp(page);
 | 
				
			||||||
 | 
					            await page.mouse.move(x, y);
 | 
				
			||||||
 | 
					            await page.mouse.down();
 | 
				
			||||||
 | 
					            await page.mouse.move(x + 100, y + 100);
 | 
				
			||||||
 | 
					            await page.mouse.up();
 | 
				
			||||||
 | 
					            await awaitPromise(clickHandle);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            await page.waitForSelector(getEditorSelector(i));
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          let value = 12;
 | 
				
			||||||
 | 
					          await waitForSerialized(page, 3);
 | 
				
			||||||
 | 
					          let serialized = await getSerialized(page);
 | 
				
			||||||
 | 
					          expect(serialized.map(x => x.thickness))
 | 
				
			||||||
 | 
					            .withContext(`In ${browserName}`)
 | 
				
			||||||
 | 
					            .toEqual([value, value, value]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          await selectAll(page);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          const prevWidth = await page.evaluate(
 | 
				
			||||||
 | 
					            sel => document.querySelector(sel).getBoundingClientRect().width,
 | 
				
			||||||
 | 
					            getEditorSelector(0)
 | 
				
			||||||
 | 
					          );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          value = 24;
 | 
				
			||||||
 | 
					          page.evaluate(val => {
 | 
				
			||||||
 | 
					            window.PDFViewerApplication.eventBus.dispatch(
 | 
				
			||||||
 | 
					              "switchannotationeditorparams",
 | 
				
			||||||
 | 
					              {
 | 
				
			||||||
 | 
					                source: null,
 | 
				
			||||||
 | 
					                type: window.pdfjsLib.AnnotationEditorParamsType
 | 
				
			||||||
 | 
					                  .HIGHLIGHT_THICKNESS,
 | 
				
			||||||
 | 
					                value: val,
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					          }, value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          await page.waitForFunction(
 | 
				
			||||||
 | 
					            (w, sel) =>
 | 
				
			||||||
 | 
					              document.querySelector(sel).getBoundingClientRect().width !== w,
 | 
				
			||||||
 | 
					            {},
 | 
				
			||||||
 | 
					            prevWidth,
 | 
				
			||||||
 | 
					            getEditorSelector(0)
 | 
				
			||||||
 | 
					          );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          await waitForSerialized(page, 3);
 | 
				
			||||||
 | 
					          serialized = await getSerialized(page);
 | 
				
			||||||
 | 
					          expect(serialized.map(x => x.thickness))
 | 
				
			||||||
 | 
					            .withContext(`In ${browserName}`)
 | 
				
			||||||
 | 
					            .toEqual([value, value, value]);
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
				
			|||||||
@ -1094,20 +1094,21 @@
 | 
				
			|||||||
  height: auto;
 | 
					  height: auto;
 | 
				
			||||||
  padding-inline: 10px;
 | 
					  padding-inline: 10px;
 | 
				
			||||||
  padding-block: 10px 16px;
 | 
					  padding-block: 10px 16px;
 | 
				
			||||||
 | 
					  gap: 16px;
 | 
				
			||||||
  display: flex;
 | 
					  display: flex;
 | 
				
			||||||
  flex-direction: column;
 | 
					  flex-direction: column;
 | 
				
			||||||
  box-sizing: border-box;
 | 
					  box-sizing: border-box;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  .editorParamsLabel {
 | 
				
			||||||
 | 
					    width: fit-content;
 | 
				
			||||||
 | 
					    inset-inline-start: 0;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  .colorPicker {
 | 
					  .colorPicker {
 | 
				
			||||||
    display: flex;
 | 
					    display: flex;
 | 
				
			||||||
    flex-direction: column;
 | 
					    flex-direction: column;
 | 
				
			||||||
    gap: 8px;
 | 
					    gap: 8px;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #highlightColorPickerLabel {
 | 
					 | 
				
			||||||
      width: fit-content;
 | 
					 | 
				
			||||||
      inset-inline-start: 0;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .dropdown {
 | 
					    .dropdown {
 | 
				
			||||||
      display: flex;
 | 
					      display: flex;
 | 
				
			||||||
      justify-content: space-between;
 | 
					      justify-content: space-between;
 | 
				
			||||||
@ -1145,4 +1146,58 @@
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  #editorHighlightThickness {
 | 
				
			||||||
 | 
					    display: flex;
 | 
				
			||||||
 | 
					    flex-direction: column;
 | 
				
			||||||
 | 
					    align-items: center;
 | 
				
			||||||
 | 
					    gap: 4px;
 | 
				
			||||||
 | 
					    align-self: stretch;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .editorParamsLabel {
 | 
				
			||||||
 | 
					      width: 100%;
 | 
				
			||||||
 | 
					      height: auto;
 | 
				
			||||||
 | 
					      align-self: stretch;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .thicknessPicker {
 | 
				
			||||||
 | 
					      display: flex;
 | 
				
			||||||
 | 
					      justify-content: space-between;
 | 
				
			||||||
 | 
					      align-items: center;
 | 
				
			||||||
 | 
					      align-self: stretch;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      --example-color: #bfbfc9;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      @media (prefers-color-scheme: dark) {
 | 
				
			||||||
 | 
					        --example-color: #80808e;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      @media screen and (forced-colors: active) {
 | 
				
			||||||
 | 
					        --example-color: HighlightText;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      &::before {
 | 
				
			||||||
 | 
					        content: "";
 | 
				
			||||||
 | 
					        width: 8px;
 | 
				
			||||||
 | 
					        aspect-ratio: 1;
 | 
				
			||||||
 | 
					        display: block;
 | 
				
			||||||
 | 
					        border-radius: 100%;
 | 
				
			||||||
 | 
					        background-color: var(--example-color);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      .editorParamsSlider {
 | 
				
			||||||
 | 
					        width: unset;
 | 
				
			||||||
 | 
					        height: 14px;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      &::after {
 | 
				
			||||||
 | 
					        content: "";
 | 
				
			||||||
 | 
					        width: 24px;
 | 
				
			||||||
 | 
					        aspect-ratio: 1;
 | 
				
			||||||
 | 
					        display: block;
 | 
				
			||||||
 | 
					        border-radius: 100%;
 | 
				
			||||||
 | 
					        background-color: var(--example-color);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -32,6 +32,7 @@ class AnnotationEditorParams {
 | 
				
			|||||||
    editorInkThickness,
 | 
					    editorInkThickness,
 | 
				
			||||||
    editorInkOpacity,
 | 
					    editorInkOpacity,
 | 
				
			||||||
    editorStampAddImage,
 | 
					    editorStampAddImage,
 | 
				
			||||||
 | 
					    editorFreeHighlightThickness,
 | 
				
			||||||
  }) {
 | 
					  }) {
 | 
				
			||||||
    const dispatchEvent = (typeStr, value) => {
 | 
					    const dispatchEvent = (typeStr, value) => {
 | 
				
			||||||
      this.eventBus.dispatch("switchannotationeditorparams", {
 | 
					      this.eventBus.dispatch("switchannotationeditorparams", {
 | 
				
			||||||
@ -58,6 +59,9 @@ class AnnotationEditorParams {
 | 
				
			|||||||
    editorStampAddImage.addEventListener("click", () => {
 | 
					    editorStampAddImage.addEventListener("click", () => {
 | 
				
			||||||
      dispatchEvent("CREATE");
 | 
					      dispatchEvent("CREATE");
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					    editorFreeHighlightThickness.addEventListener("input", function () {
 | 
				
			||||||
 | 
					      dispatchEvent("HIGHLIGHT_THICKNESS", this.valueAsNumber);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    this.eventBus._on("annotationeditorparamschanged", evt => {
 | 
					    this.eventBus._on("annotationeditorparamschanged", evt => {
 | 
				
			||||||
      for (const [type, value] of evt.details) {
 | 
					      for (const [type, value] of evt.details) {
 | 
				
			||||||
@ -77,6 +81,9 @@ class AnnotationEditorParams {
 | 
				
			|||||||
          case AnnotationEditorParamsType.INK_OPACITY:
 | 
					          case AnnotationEditorParamsType.INK_OPACITY:
 | 
				
			||||||
            editorInkOpacity.value = value;
 | 
					            editorInkOpacity.value = value;
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
 | 
					          case AnnotationEditorParamsType.HIGHLIGHT_THICKNESS:
 | 
				
			||||||
 | 
					            editorFreeHighlightThickness.value = value;
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
				
			|||||||
@ -176,6 +176,12 @@ See https://github.com/adobe-type-tools/cmap-resources
 | 
				
			|||||||
            <div id="editorHighlightColorPicker" class="colorPicker">
 | 
					            <div id="editorHighlightColorPicker" class="colorPicker">
 | 
				
			||||||
              <span id="highlightColorPickerLabel" class="editorParamsLabel" data-l10n-id="pdfjs-editor-highlight-colorpicker-label">Highlight color</span>
 | 
					              <span id="highlightColorPickerLabel" class="editorParamsLabel" data-l10n-id="pdfjs-editor-highlight-colorpicker-label">Highlight color</span>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
 | 
					            <div id="editorHighlightThickness">
 | 
				
			||||||
 | 
					              <label for="editorFreeHighlightThickness" class="editorParamsLabel" data-l10n-id="pdfjs-editor-free-highlight-thickness-input">Thickness</label>
 | 
				
			||||||
 | 
					              <div class="thicknessPicker">
 | 
				
			||||||
 | 
					                <input type="range" id="editorFreeHighlightThickness" class="editorParamsSlider" value="12" min="8" max="24" step="1" tabindex="101">
 | 
				
			||||||
 | 
					              </div>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
          </div>
 | 
					          </div>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -172,6 +172,9 @@ function getViewerConfiguration() {
 | 
				
			|||||||
      editorInkThickness: document.getElementById("editorInkThickness"),
 | 
					      editorInkThickness: document.getElementById("editorInkThickness"),
 | 
				
			||||||
      editorInkOpacity: document.getElementById("editorInkOpacity"),
 | 
					      editorInkOpacity: document.getElementById("editorInkOpacity"),
 | 
				
			||||||
      editorStampAddImage: document.getElementById("editorStampAddImage"),
 | 
					      editorStampAddImage: document.getElementById("editorStampAddImage"),
 | 
				
			||||||
 | 
					      editorFreeHighlightThickness: document.getElementById(
 | 
				
			||||||
 | 
					        "editorFreeHighlightThickness"
 | 
				
			||||||
 | 
					      ),
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    printContainer: document.getElementById("printContainer"),
 | 
					    printContainer: document.getElementById("printContainer"),
 | 
				
			||||||
    openFileInput:
 | 
					    openFileInput:
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user