feat: improve text measurements in bound containers (#6187)

* feat: move to canvas measureText

* calcualte height with better heuristic

* improve heuristic more

* remove vertical offset as its not needed

* lint

* calculate width of individual char and ceil to calculate width and remove adjustment factor

* push the word if equal to max width

* update height when text overflows for vertical alignment top/bottom

* remove the hack of updating height when line mismatch as its not needed

* remove scroll height and calculate the height instead

* remove unused code

* fix

* remove

* use math.ceil for whole width instead of individual chars

* fix tests

* fix

* fix

* redraw text bounding box instead when font loaded to fix alignment as well

* fix

* fix

* fix

* Add a 0.05px extra only for firefox

* Add spec

* stop taking ceil and increase firefox editor width by 0.05px

* Ad 0.05px in safari too

* lint

* lint

* remove baseline from measureFontSizeFromWH

* don't redraw on font load

* lint

* refactor name and signature
This commit is contained in:
Aakansha Doshi 2023-02-23 16:33:10 +05:30 committed by GitHub
parent 39b96cb011
commit 9659254fd6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 142 additions and 349 deletions

View file

@ -36,13 +36,11 @@ import {
MAX_DECIMALS_FOR_SVG_EXPORT,
MIME_TYPES,
SVG_NS,
VERTICAL_ALIGN,
} from "../constants";
import { getStroke, StrokeOptions } from "perfect-freehand";
import {
getApproxLineHeight,
getBoundTextElement,
getBoundTextElementOffset,
getContainerElement,
} from "../element/textElement";
import { LinearElementEditor } from "../element/linearElementEditor";
@ -280,22 +278,19 @@ const drawElementOnCanvas = (
const lineHeight = element.containerId
? getApproxLineHeight(getFontString(element))
: element.height / lines.length;
let verticalOffset = element.height - element.baseline;
if (element.verticalAlign === VERTICAL_ALIGN.BOTTOM) {
verticalOffset = getBoundTextElementOffset(element);
}
const horizontalOffset =
element.textAlign === "center"
? element.width / 2
: element.textAlign === "right"
? element.width
: 0;
context.textBaseline = "bottom";
for (let index = 0; index < lines.length; index++) {
context.fillText(
lines[index],
horizontalOffset,
(index + 1) * lineHeight - verticalOffset,
(index + 1) * lineHeight,
);
}
context.restore();
@ -1300,7 +1295,7 @@ export const renderElementToSvg = (
);
const lines = element.text.replace(/\r\n?/g, "\n").split("\n");
const lineHeight = element.height / lines.length;
const verticalOffset = element.height - element.baseline;
const verticalOffset = element.height;
const horizontalOffset =
element.textAlign === "center"
? element.width / 2