feat: add line height attribute to text element (#6360)

* feat: add line height attribute to text element

* lint

* update line height when redrawing text bounding box

* fix tests

* retain line height when pasting styles

* fix test

* create a util for calculating ling height using old algo

* update line height when resizing multiple text elements

* make line height backward compatible

* udpate line height for older element when font size updated

* remove logs

* Add specs

* lint

* review fixes

* simplify by changing `lineHeight` from px to unitless

* make param non-optional

* update comment

* fix: jumping text due to font size being calculated incorrectly

* update line height when font family is updated

* lint

* Add spec

* more specs

* rename to getDefaultLineHeight

* fix getting lineHeight for potentially undefined fontFamily

* reduce duplication

* fix fallback

* refactor and comment tweaks

* fix

---------

Co-authored-by: dwelle <luzar.david@gmail.com>
This commit is contained in:
Aakansha Doshi 2023-03-22 11:32:38 +05:30 committed by GitHub
parent ac4c8b3ca7
commit 83383977f5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
18 changed files with 326 additions and 143 deletions

View file

@ -3,8 +3,10 @@ import { render, waitFor, GlobalTestState } from "./test-utils";
import { Pointer, Keyboard } from "./helpers/ui";
import ExcalidrawApp from "../excalidraw-app";
import { KEYS } from "../keys";
import { getApproxLineHeight } from "../element/textElement";
import { getFontString } from "../utils";
import {
getDefaultLineHeight,
getLineHeightInPx,
} from "../element/textElement";
import { getElementBounds } from "../element";
import { NormalizedZoomValue } from "../types";
@ -118,12 +120,10 @@ describe("paste text as single lines", () => {
it("should space items correctly", async () => {
const text = "hkhkjhki\njgkjhffjh\njgkjhffjh";
const lineHeight =
getApproxLineHeight(
getFontString({
fontSize: h.app.state.currentItemFontSize,
fontFamily: h.app.state.currentItemFontFamily,
}),
const lineHeightPx =
getLineHeightInPx(
h.app.state.currentItemFontSize,
getDefaultLineHeight(h.state.currentItemFontFamily),
) +
10 / h.app.state.zoom.value;
mouse.moveTo(100, 100);
@ -135,19 +135,17 @@ describe("paste text as single lines", () => {
for (let i = 1; i < h.elements.length; i++) {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const [fx, elY] = getElementBounds(h.elements[i]);
expect(elY).toEqual(firstElY + lineHeight * i);
expect(elY).toEqual(firstElY + lineHeightPx * i);
}
});
});
it("should leave a space for blank new lines", async () => {
const text = "hkhkjhki\n\njgkjhffjh";
const lineHeight =
getApproxLineHeight(
getFontString({
fontSize: h.app.state.currentItemFontSize,
fontFamily: h.app.state.currentItemFontFamily,
}),
const lineHeightPx =
getLineHeightInPx(
h.app.state.currentItemFontSize,
getDefaultLineHeight(h.state.currentItemFontFamily),
) +
10 / h.app.state.zoom.value;
mouse.moveTo(100, 100);
@ -158,7 +156,7 @@ describe("paste text as single lines", () => {
const [fx, firstElY] = getElementBounds(h.elements[0]);
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const [lx, lastElY] = getElementBounds(h.elements[1]);
expect(lastElY).toEqual(firstElY + lineHeight * 2);
expect(lastElY).toEqual(firstElY + lineHeightPx * 2);
});
});
});
@ -224,7 +222,7 @@ describe("Paste bound text container", () => {
await sleep(1);
expect(h.elements.length).toEqual(2);
const container = h.elements[0];
expect(container.height).toBe(354);
expect(container.height).toBe(368);
expect(container.width).toBe(166);
});
});
@ -247,7 +245,7 @@ describe("Paste bound text container", () => {
await sleep(1);
expect(h.elements.length).toEqual(2);
const container = h.elements[0];
expect(container.height).toBe(740);
expect(container.height).toBe(770);
expect(container.width).toBe(166);
});
});