From c31cbe646de017d930d6f344fa025d0f955cf043 Mon Sep 17 00:00:00 2001 From: Marcel Mraz Date: Wed, 7 Feb 2024 21:44:48 +0100 Subject: [PATCH] deprecate baseline --- .../excalidraw/actions/actionBoundText.tsx | 3 +- .../data/__snapshots__/transform.test.ts.snap | 19 ------ packages/excalidraw/data/restore.ts | 9 +-- packages/excalidraw/element/newElement.ts | 13 ++-- packages/excalidraw/element/resizeElements.ts | 33 ++-------- packages/excalidraw/element/textElement.ts | 60 +------------------ packages/excalidraw/element/types.ts | 1 - packages/excalidraw/renderer/renderElement.ts | 2 +- .../data/__snapshots__/restore.test.ts.snap | 2 - 9 files changed, 14 insertions(+), 128 deletions(-) diff --git a/packages/excalidraw/actions/actionBoundText.tsx b/packages/excalidraw/actions/actionBoundText.tsx index 722ad5111..32c315137 100644 --- a/packages/excalidraw/actions/actionBoundText.tsx +++ b/packages/excalidraw/actions/actionBoundText.tsx @@ -49,7 +49,7 @@ export const actionUnbindText = register({ selectedElements.forEach((element) => { const boundTextElement = getBoundTextElement(element, elementsMap); if (boundTextElement) { - const { width, height, baseline } = measureText( + const { width, height } = measureText( boundTextElement.originalText, getFontString(boundTextElement), boundTextElement.lineHeight, @@ -63,7 +63,6 @@ export const actionUnbindText = register({ containerId: null, width, height, - baseline, text: boundTextElement.originalText, x, y, diff --git a/packages/excalidraw/data/__snapshots__/transform.test.ts.snap b/packages/excalidraw/data/__snapshots__/transform.test.ts.snap index dcd48f8b5..903be9315 100644 --- a/packages/excalidraw/data/__snapshots__/transform.test.ts.snap +++ b/packages/excalidraw/data/__snapshots__/transform.test.ts.snap @@ -219,7 +219,6 @@ exports[`Test Transform > Test arrow bindings > should bind arrows to existing t { "angle": 0, "backgroundColor": "transparent", - "baseline": 0, "boundElements": [ { "id": "id48", @@ -263,7 +262,6 @@ exports[`Test Transform > Test arrow bindings > should bind arrows to existing t { "angle": 0, "backgroundColor": "transparent", - "baseline": 0, "boundElements": [ { "id": "id48", @@ -365,7 +363,6 @@ exports[`Test Transform > Test arrow bindings > should bind arrows to existing t { "angle": 0, "backgroundColor": "transparent", - "baseline": 0, "boundElements": null, "containerId": "id48", "fillStyle": "solid", @@ -462,7 +459,6 @@ exports[`Test Transform > Test arrow bindings > should bind arrows to shapes whe { "angle": 0, "backgroundColor": "transparent", - "baseline": 0, "boundElements": null, "containerId": "id37", "fillStyle": "solid", @@ -629,7 +625,6 @@ exports[`Test Transform > Test arrow bindings > should bind arrows to text when { "angle": 0, "backgroundColor": "transparent", - "baseline": 0, "boundElements": null, "containerId": "id41", "fillStyle": "solid", @@ -668,7 +663,6 @@ exports[`Test Transform > Test arrow bindings > should bind arrows to text when { "angle": 0, "backgroundColor": "transparent", - "baseline": 0, "boundElements": [ { "id": "id41", @@ -712,7 +706,6 @@ exports[`Test Transform > Test arrow bindings > should bind arrows to text when { "angle": 0, "backgroundColor": "transparent", - "baseline": 0, "boundElements": [ { "id": "id41", @@ -1146,7 +1139,6 @@ exports[`Test Transform > should transform text element 1`] = ` { "angle": 0, "backgroundColor": "transparent", - "baseline": 0, "boundElements": null, "containerId": null, "fillStyle": "solid", @@ -1185,7 +1177,6 @@ exports[`Test Transform > should transform text element 2`] = ` { "angle": 0, "backgroundColor": "transparent", - "baseline": 0, "boundElements": null, "containerId": null, "fillStyle": "solid", @@ -1424,7 +1415,6 @@ exports[`Test Transform > should transform to labelled arrows when label provide { "angle": 0, "backgroundColor": "transparent", - "baseline": 0, "boundElements": null, "containerId": "id25", "fillStyle": "solid", @@ -1463,7 +1453,6 @@ exports[`Test Transform > should transform to labelled arrows when label provide { "angle": 0, "backgroundColor": "transparent", - "baseline": 0, "boundElements": null, "containerId": "id26", "fillStyle": "solid", @@ -1502,7 +1491,6 @@ exports[`Test Transform > should transform to labelled arrows when label provide { "angle": 0, "backgroundColor": "transparent", - "baseline": 0, "boundElements": null, "containerId": "id27", "fillStyle": "solid", @@ -1542,7 +1530,6 @@ exports[`Test Transform > should transform to labelled arrows when label provide { "angle": 0, "backgroundColor": "transparent", - "baseline": 0, "boundElements": null, "containerId": "id28", "fillStyle": "solid", @@ -1792,7 +1779,6 @@ exports[`Test Transform > should transform to text containers when label provide { "angle": 0, "backgroundColor": "transparent", - "baseline": 0, "boundElements": null, "containerId": "id13", "fillStyle": "solid", @@ -1831,7 +1817,6 @@ exports[`Test Transform > should transform to text containers when label provide { "angle": 0, "backgroundColor": "transparent", - "baseline": 0, "boundElements": null, "containerId": "id14", "fillStyle": "solid", @@ -1871,7 +1856,6 @@ exports[`Test Transform > should transform to text containers when label provide { "angle": 0, "backgroundColor": "transparent", - "baseline": 0, "boundElements": null, "containerId": "id15", "fillStyle": "solid", @@ -1913,7 +1897,6 @@ exports[`Test Transform > should transform to text containers when label provide { "angle": 0, "backgroundColor": "transparent", - "baseline": 0, "boundElements": null, "containerId": "id16", "fillStyle": "solid", @@ -1953,7 +1936,6 @@ exports[`Test Transform > should transform to text containers when label provide { "angle": 0, "backgroundColor": "transparent", - "baseline": 0, "boundElements": null, "containerId": "id17", "fillStyle": "solid", @@ -1994,7 +1976,6 @@ exports[`Test Transform > should transform to text containers when label provide { "angle": 0, "backgroundColor": "transparent", - "baseline": 0, "boundElements": null, "containerId": "id18", "fillStyle": "solid", diff --git a/packages/excalidraw/data/restore.ts b/packages/excalidraw/data/restore.ts index 12e7f1af1..46ae89601 100644 --- a/packages/excalidraw/data/restore.ts +++ b/packages/excalidraw/data/restore.ts @@ -35,14 +35,13 @@ import { import { getDefaultAppState } from "../appState"; import { LinearElementEditor } from "../element/linearElementEditor"; import { bumpVersion } from "../element/mutateElement"; -import { getFontString, getUpdatedTimestamp, updateActiveTool } from "../utils"; +import { getUpdatedTimestamp, updateActiveTool } from "../utils"; import { arrayToMap } from "../utils"; import { MarkOptional, Mutable } from "../utility-types"; import { detectLineHeight, getContainerElement, getDefaultLineHeight, - measureBaseline, } from "../element/textElement"; import { normalizeLink } from "./url"; @@ -207,11 +206,6 @@ const restoreElement = ( : // no element height likely means programmatic use, so default // to a fixed line height getDefaultLineHeight(element.fontFamily)); - const baseline = measureBaseline( - element.text, - getFontString(element), - lineHeight, - ); element = restoreElementWithProperties(element, { fontSize, fontFamily, @@ -222,7 +216,6 @@ const restoreElement = ( originalText: element.originalText || text, lineHeight, - baseline, }); // if empty text, mark as deleted. We keep in array diff --git a/packages/excalidraw/element/newElement.ts b/packages/excalidraw/element/newElement.ts index 447a07993..d270e2fd6 100644 --- a/packages/excalidraw/element/newElement.ts +++ b/packages/excalidraw/element/newElement.ts @@ -246,7 +246,6 @@ export const newTextElement = ( y: opts.y - offsets.y, width: metrics.width, height: metrics.height, - baseline: metrics.baseline, containerId: opts.containerId || null, originalText: text, lineHeight, @@ -264,13 +263,12 @@ const getAdjustedDimensions = ( y: number; width: number; height: number; - baseline: number; } => { - const { - width: nextWidth, - height: nextHeight, - baseline: nextBaseline, - } = measureText(nextText, getFontString(element), element.lineHeight); + const { width: nextWidth, height: nextHeight } = measureText( + nextText, + getFontString(element), + element.lineHeight, + ); const { textAlign, verticalAlign } = element; let x: number; let y: number; @@ -324,7 +322,6 @@ const getAdjustedDimensions = ( return { width: nextWidth, height: nextHeight, - baseline: nextBaseline, x: Number.isFinite(x) ? x : element.x, y: Number.isFinite(y) ? y : element.y, }; diff --git a/packages/excalidraw/element/resizeElements.ts b/packages/excalidraw/element/resizeElements.ts index deb5fead3..55351c5a7 100644 --- a/packages/excalidraw/element/resizeElements.ts +++ b/packages/excalidraw/element/resizeElements.ts @@ -211,8 +211,7 @@ const measureFontSizeFromWidth = ( element: NonDeleted, elementsMap: ElementsMap, nextWidth: number, - nextHeight: number, -): { size: number; baseline: number } | null => { +): { size: number } | null => { // We only use width to scale font on resize let width = element.width; @@ -227,14 +226,9 @@ const measureFontSizeFromWidth = ( if (nextFontSize < MIN_FONT_SIZE) { return null; } - const metrics = measureText( - element.text, - getFontString({ fontSize: nextFontSize, fontFamily: element.fontFamily }), - element.lineHeight, - ); + return { size: nextFontSize, - baseline: metrics.baseline + (nextHeight - metrics.height), }; }; @@ -307,12 +301,7 @@ const resizeSingleTextElement = ( if (scale > 0) { const nextWidth = element.width * scale; const nextHeight = element.height * scale; - const metrics = measureFontSizeFromWidth( - element, - elementsMap, - nextWidth, - nextHeight, - ); + const metrics = measureFontSizeFromWidth(element, elementsMap, nextWidth); if (metrics === null) { return; } @@ -340,7 +329,6 @@ const resizeSingleTextElement = ( fontSize: metrics.size, width: nextWidth, height: nextHeight, - baseline: metrics.baseline, x: nextElementX, y: nextElementY, }); @@ -394,7 +382,7 @@ export const resizeSingleElement = ( let scaleX = atStartBoundsWidth / boundsCurrentWidth; let scaleY = atStartBoundsHeight / boundsCurrentHeight; - let boundTextFont: { fontSize?: number; baseline?: number } = {}; + let boundTextFont: { fontSize?: number } = {}; const boundTextElement = getBoundTextElement(element, elementsMap); if (transformHandleDirection.includes("e")) { @@ -446,7 +434,6 @@ export const resizeSingleElement = ( if (stateOfBoundTextElementAtResize) { boundTextFont = { fontSize: stateOfBoundTextElementAtResize.fontSize, - baseline: stateOfBoundTextElementAtResize.baseline, }; } if (shouldMaintainAspectRatio) { @@ -460,14 +447,12 @@ export const resizeSingleElement = ( boundTextElement, elementsMap, getBoundTextMaxWidth(updatedElement, boundTextElement), - getBoundTextMaxHeight(updatedElement, boundTextElement), ); if (nextFont === null) { return; } boundTextFont = { fontSize: nextFont.size, - baseline: nextFont.baseline, }; } else { const minWidth = getApproxMinLineWidth( @@ -636,7 +621,6 @@ export const resizeSingleElement = ( if (boundTextElement && boundTextFont != null) { mutateElement(boundTextElement, { fontSize: boundTextFont.fontSize, - baseline: boundTextFont.baseline, }); } handleBindTextResize( @@ -763,7 +747,6 @@ export const resizeMultipleElements = ( > & { points?: ExcalidrawLinearElement["points"]; fontSize?: ExcalidrawTextElement["fontSize"]; - baseline?: ExcalidrawTextElement["baseline"]; scale?: ExcalidrawImageElement["scale"]; boundTextFontSize?: ExcalidrawTextElement["fontSize"]; }; @@ -838,17 +821,11 @@ export const resizeMultipleElements = ( } if (isTextElement(orig)) { - const metrics = measureFontSizeFromWidth( - orig, - elementsMap, - width, - height, - ); + const metrics = measureFontSizeFromWidth(orig, elementsMap, width); if (!metrics) { return; } update.fontSize = metrics.size; - update.baseline = metrics.baseline; } const boundTextElement = originalElements.get( diff --git a/packages/excalidraw/element/textElement.ts b/packages/excalidraw/element/textElement.ts index fc4c15f2d..e3bd26ac8 100644 --- a/packages/excalidraw/element/textElement.ts +++ b/packages/excalidraw/element/textElement.ts @@ -18,7 +18,6 @@ import { DEFAULT_FONT_FAMILY, DEFAULT_FONT_SIZE, FONT_FAMILY, - isSafari, TEXT_ALIGN, VERTICAL_ALIGN, } from "../constants"; @@ -61,7 +60,6 @@ export const redrawTextBoundingBox = ( text: textElement.text, width: textElement.width, height: textElement.height, - baseline: textElement.baseline, }; boundTextUpdates.text = textElement.text; @@ -82,7 +80,6 @@ export const redrawTextBoundingBox = ( boundTextUpdates.width = metrics.width; boundTextUpdates.height = metrics.height; - boundTextUpdates.baseline = metrics.baseline; if (container) { const maxContainerHeight = getBoundTextMaxHeight( @@ -183,7 +180,6 @@ export const handleBindTextResize = ( const maxWidth = getBoundTextMaxWidth(container, textElement); const maxHeight = getBoundTextMaxHeight(container, textElement); let containerHeight = container.height; - let nextBaseLine = textElement.baseline; if ( shouldMaintainAspectRatio || (transformHandleType !== "n" && transformHandleType !== "s") @@ -202,7 +198,6 @@ export const handleBindTextResize = ( ); nextHeight = metrics.height; nextWidth = metrics.width; - nextBaseLine = metrics.baseline; } // increase height in case text element height exceeds if (nextHeight > maxHeight) { @@ -230,7 +225,6 @@ export const handleBindTextResize = ( text, width: nextWidth, height: nextHeight, - baseline: nextBaseLine, }); if (!isArrowElement(container)) { @@ -294,59 +288,7 @@ export const measureText = ( const fontSize = parseFloat(font); const height = getTextHeight(text, fontSize, lineHeight); const width = getTextWidth(text, font); - const baseline = measureBaseline(text, font, lineHeight); - return { width, height, baseline }; -}; - -export const measureBaseline = ( - text: string, - font: FontString, - lineHeight: ExcalidrawTextElement["lineHeight"], - wrapInContainer?: boolean, -) => { - const container = document.createElement("div"); - container.style.position = "absolute"; - container.style.whiteSpace = "pre"; - container.style.font = font; - container.style.minHeight = "1em"; - if (wrapInContainer) { - container.style.overflow = "hidden"; - container.style.wordBreak = "break-word"; - container.style.whiteSpace = "pre-wrap"; - } - - container.style.lineHeight = String(lineHeight); - - container.innerText = text; - - // Baseline is important for positioning text on canvas - document.body.appendChild(container); - - const span = document.createElement("span"); - span.style.display = "inline-block"; - span.style.overflow = "hidden"; - span.style.width = "1px"; - span.style.height = "1px"; - container.appendChild(span); - let baseline = span.offsetTop + span.offsetHeight; - const height = container.offsetHeight; - - if (isSafari) { - const canvasHeight = getTextHeight(text, parseFloat(font), lineHeight); - const fontSize = parseFloat(font); - // In Safari the font size gets rounded off when rendering hence calculating the safari height and shifting the baseline if it differs - // from the actual canvas height - const domHeight = getTextHeight(text, Math.round(fontSize), lineHeight); - if (canvasHeight > height) { - baseline += canvasHeight - domHeight; - } - - if (height > canvasHeight) { - baseline -= domHeight - canvasHeight; - } - } - document.body.removeChild(container); - return baseline; + return { width, height }; }; /** diff --git a/packages/excalidraw/element/types.ts b/packages/excalidraw/element/types.ts index aae0a8a30..85f42adcf 100644 --- a/packages/excalidraw/element/types.ts +++ b/packages/excalidraw/element/types.ts @@ -176,7 +176,6 @@ export type ExcalidrawTextElement = _ExcalidrawElementBase & fontSize: number; fontFamily: FontFamilyValues; text: string; - baseline: number; textAlign: TextAlign; verticalAlign: VerticalAlign; containerId: ExcalidrawGenericElement["id"] | null; diff --git a/packages/excalidraw/renderer/renderElement.ts b/packages/excalidraw/renderer/renderElement.ts index de4bcfe53..e6f7df731 100644 --- a/packages/excalidraw/renderer/renderElement.ts +++ b/packages/excalidraw/renderer/renderElement.ts @@ -395,7 +395,7 @@ const drawElementOnCanvas = ( element.fontSize, element.lineHeight, ); - const verticalOffset = element.height - element.baseline; + const verticalOffset = 0; //TODO_DOMLESS; for (let index = 0; index < lines.length; index++) { context.fillText( lines[index], diff --git a/packages/excalidraw/tests/data/__snapshots__/restore.test.ts.snap b/packages/excalidraw/tests/data/__snapshots__/restore.test.ts.snap index 0c06b65f1..63bc3ca5c 100644 --- a/packages/excalidraw/tests/data/__snapshots__/restore.test.ts.snap +++ b/packages/excalidraw/tests/data/__snapshots__/restore.test.ts.snap @@ -289,7 +289,6 @@ exports[`restoreElements > should restore text element correctly passing value f { "angle": 0, "backgroundColor": "transparent", - "baseline": 0, "boundElements": [], "containerId": null, "fillStyle": "solid", @@ -330,7 +329,6 @@ exports[`restoreElements > should restore text element correctly with unknown fo { "angle": 0, "backgroundColor": "transparent", - "baseline": 0, "boundElements": [], "containerId": null, "fillStyle": "solid",