feat: text measurements based on font metrics (#7693)

* Introduced vertical offset based on harcoded font metrics 

* Unified usage of alphabetic baseline for both canvas & svg export

* Removed baseline property

* Removed font-size rounding on Safari

* Removed artificial width offset
This commit is contained in:
Marcel Mraz 2024-03-05 19:33:27 +00:00 committed by GitHub
parent 160440b860
commit 7e471b55eb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 83 additions and 154 deletions

View file

@ -50,6 +50,7 @@ import {
getLineHeightInPx,
getBoundTextMaxHeight,
getBoundTextMaxWidth,
getVerticalOffset,
} from "../element/textElement";
import { LinearElementEditor } from "../element/linearElementEditor";
@ -383,16 +384,23 @@ const drawElementOnCanvas = (
: element.textAlign === "right"
? element.width
: 0;
const lineHeightPx = getLineHeightInPx(
element.fontSize,
element.lineHeight,
);
const verticalOffset = element.height - element.baseline;
const verticalOffset = getVerticalOffset(
element.fontFamily,
element.fontSize,
lineHeightPx,
);
for (let index = 0; index < lines.length; index++) {
context.fillText(
lines[index],
horizontalOffset,
(index + 1) * lineHeightPx - verticalOffset,
index * lineHeightPx + verticalOffset,
);
}
context.restore();

View file

@ -17,6 +17,7 @@ import {
getBoundTextElement,
getContainerElement,
getLineHeightInPx,
getVerticalOffset,
} from "../element/textElement";
import {
isArrowElement,
@ -556,6 +557,11 @@ const renderElementToSvg = (
: element.textAlign === "right"
? element.width
: 0;
const verticalOffset = getVerticalOffset(
element.fontFamily,
element.fontSize,
lineHeightPx,
);
const direction = isRTL(element.text) ? "rtl" : "ltr";
const textAnchor =
element.textAlign === "center"
@ -567,14 +573,14 @@ const renderElementToSvg = (
const text = svgRoot.ownerDocument!.createElementNS(SVG_NS, "text");
text.textContent = lines[i];
text.setAttribute("x", `${horizontalOffset}`);
text.setAttribute("y", `${i * lineHeightPx}`);
text.setAttribute("y", `${i * lineHeightPx + verticalOffset}`);
text.setAttribute("font-family", getFontFamilyString(element));
text.setAttribute("font-size", `${element.fontSize}px`);
text.setAttribute("fill", element.strokeColor);
text.setAttribute("text-anchor", textAnchor);
text.setAttribute("style", "white-space: pre;");
text.setAttribute("direction", direction);
text.setAttribute("dominant-baseline", "text-before-edge");
text.setAttribute("dominant-baseline", "alphabetic");
node.appendChild(text);
}