Skip to content

Commit 5ef0da1

Browse files
committed
Support variable fonts in textToPoints
1 parent ebd77b6 commit 5ef0da1

File tree

1 file changed

+41
-9
lines changed

1 file changed

+41
-9
lines changed

src/type/p5.Font.js

Lines changed: 41 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -669,14 +669,42 @@ class Font {
669669
// convert lines to paths
670670
let uPE = this.data?.head?.unitsPerEm || 1000;
671671
let scale = renderer.states.textSize / uPE;
672-
let pathsForLine = lines.map(l => this._lineToGlyphs(l, scale));
672+
673+
const axs = this._currentAxes(renderer);
674+
let pathsForLine = lines.map(l => this._lineToGlyphs(l, { scale, axs }));
673675

674676
// restore the baseline
675677
renderer.drawingContext.textBaseline = setBaseline;
676678

677679
return pathsForLine;
678680
}
679681

682+
_currentAxes(renderer) {
683+
let axs;
684+
if ((this.data?.fvar?.length ?? 0) > 0) {
685+
const fontAxes = this.data.fvar[0];
686+
axs = fontAxes.map(([tag, minVal, maxVal, defaultVal, flags, name]) => {
687+
if (!renderer) return defaultVal;
688+
if (tag === 'wght') {
689+
return renderer.states.fontWeight;
690+
} else if (tag === 'wdth') {
691+
return renderer.states.fontStretch
692+
} else if (renderer.canvas.style.fontVariationSettings) {
693+
const match = new RegExp(`\\b${tag}\s+(\d+)`)
694+
.exec(renderer.canvas.style.fontVariationSettings);
695+
if (match) {
696+
return parseInt(match[1]);
697+
} else {
698+
return defaultVal;
699+
}
700+
} else {
701+
return defaultVal;
702+
}
703+
});
704+
}
705+
return axs;
706+
}
707+
680708
_textToPathPoints(str, x, y, width, height, options) {
681709

682710
({ width, height, options } = this._parseArgs(width, height, options));
@@ -760,21 +788,24 @@ class Font {
760788
return lines.map(coordify);
761789
}
762790

763-
_lineToGlyphs(line, scale = 1) {
791+
_lineToGlyphs(line, { scale = 1, axs } = {}) {
764792

765793
if (!this.data) {
766794
throw Error('No font data available for "' + this.name
767795
+ '"\nTry downloading a local copy of the font file');
768796
}
769-
let glyphShapes = Typr.U.shape(this.data, line.text);
797+
let glyphShapes = Typr.U.shape(this.data, line.text, { axs });
770798
line.glyphShapes = glyphShapes;
771-
line.glyphs = this._shapeToPaths(glyphShapes, line, scale);
799+
800+
line.glyphs = this._shapeToPaths(glyphShapes, line, { scale, axs });
772801

773802
return line;
774803
}
775804

776-
_positionGlyphs(text) {
777-
const glyphShapes = Typr.U.shape(this.data, text);
805+
_positionGlyphs(text, options) {
806+
let renderer = options?.graphics?._renderer || this._pInst._renderer;
807+
const axs = this._currentAxes(renderer);
808+
const glyphShapes = Typr.U.shape(this.data, text, { axs });
778809
const positionedGlyphs = [];
779810
let x = 0;
780811
for (const glyph of glyphShapes) {
@@ -784,11 +815,11 @@ class Font {
784815
return positionedGlyphs;
785816
}
786817

787-
_singleShapeToPath(shape, { scale = 1, x = 0, y = 0, lineX = 0, lineY = 0 } = {}) {
818+
_singleShapeToPath(shape, { scale = 1, x = 0, y = 0, lineX = 0, lineY = 0, axs } = {}) {
788819
let font = this.data;
789820
let crdIdx = 0;
790821
let { g, ax, ay, dx, dy } = shape;
791-
let { crds, cmds } = Typr.U.glyphToPath(font, g);
822+
let { crds, cmds } = Typr.U.glyphToPath(font, g, true, axs);
792823

793824
// can get simple points for each glyph here, but we don't need them ?
794825
let glyph = { /*g: line.text[i], points: [],*/ path: { commands: [] } };
@@ -816,7 +847,7 @@ class Font {
816847
return { glyph, ax, ay };
817848
}
818849

819-
_shapeToPaths(glyphs, line, scale = 1) {
850+
_shapeToPaths(glyphs, line, { scale = 1, axs } = {}) {
820851
let x = 0, y = 0, paths = [];
821852

822853
if (glyphs.length !== line.text.length) {
@@ -832,6 +863,7 @@ class Font {
832863
y,
833864
lineX: line.x,
834865
lineY: line.y,
866+
axs,
835867
});
836868

837869
paths.push(glyph);

0 commit comments

Comments
 (0)