Skip to content

Commit e3b92d3

Browse files
committed
Get variable font rendering working in WebGL
1 parent 5ef0da1 commit e3b92d3

File tree

12 files changed

+326
-199
lines changed

12 files changed

+326
-199
lines changed

src/type/p5.Font.js

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@ const invalidFontError = 'Sorry, only TTF, OTF and WOFF files are supported.'; /
5151
const fontFaceVariations = ['weight', 'stretch', 'style'];
5252

5353

54-
55-
class Font {
54+
let nextId = 0;
55+
export class Font {
5656
constructor(p, fontFace, name, path, data) {
5757
if (!(fontFace instanceof FontFace)) {
5858
throw Error('FontFace is required');
@@ -62,6 +62,7 @@ class Font {
6262
this.path = path;
6363
this.data = data;
6464
this.face = fontFace;
65+
this.id = nextId++;
6566
}
6667

6768
/**
@@ -688,10 +689,12 @@ class Font {
688689
if (tag === 'wght') {
689690
return renderer.states.fontWeight;
690691
} else if (tag === 'wdth') {
691-
return renderer.states.fontStretch
692-
} else if (renderer.canvas.style.fontVariationSettings) {
692+
// TODO: map from keywords (normal, ultra-condensed, etc) to values
693+
// return renderer.states.fontStretch
694+
return defaultVal;
695+
} else if (renderer.textCanvas().style.fontVariationSettings) {
693696
const match = new RegExp(`\\b${tag}\s+(\d+)`)
694-
.exec(renderer.canvas.style.fontVariationSettings);
697+
.exec(renderer.textCanvas().style.fontVariationSettings);
695698
if (match) {
696699
return parseInt(match[1]);
697700
} else {

src/type/textCore.js

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1749,7 +1749,7 @@ function textCore(p5, fn) {
17491749
modified = true;
17501750
}
17511751
// does it exist in the canvas.style ?
1752-
else if (prop in this.canvas.style) {
1752+
else if (prop in this.textCanvas().style) {
17531753
this._setCanvasStyleProperty(prop, value, debug);
17541754
modified = true;
17551755
}
@@ -1913,16 +1913,16 @@ function textCore(p5, fn) {
19131913
}
19141914

19151915
// lets try to set it on the canvas style
1916-
this.canvas.style[opt] = value;
1916+
this.textCanvas().style[opt] = value;
19171917

19181918
// check if the value was set successfully
1919-
if (this.canvas.style[opt] !== value) {
1919+
if (this.textCanvas().style[opt] !== value) {
19201920

19211921
// fails on precision for floating points, also quotes and spaces
19221922

19231923
if (0) console.warn(`Unable to set '${opt}' property` // FES?
19241924
+ ' on canvas.style. It may not be supported. Expected "'
1925-
+ value + '" but got: "' + this.canvas.style[opt] + "'");
1925+
+ value + '" but got: "' + this.textCanvas().style[opt] + "'");
19261926
}
19271927
};
19281928

@@ -2075,7 +2075,7 @@ function textCore(p5, fn) {
20752075
Object.entries(props).forEach(([prop, val]) => {
20762076
ele.style[prop] = val;
20772077
});
2078-
this.canvas.appendChild(ele);
2078+
this.textCanvas().appendChild(ele);
20792079
cachedDiv = ele;
20802080
}
20812081
return cachedDiv;
@@ -2435,7 +2435,9 @@ function textCore(p5, fn) {
24352435
};
24362436

24372437
if (p5.Renderer2D) {
2438-
2438+
p5.Renderer2D.prototype.textCanvas = function () {
2439+
return this.canvas;
2440+
};
24392441
p5.Renderer2D.prototype.textDrawingContext = function () {
24402442
return this.drawingContext;
24412443
};
@@ -2535,15 +2537,31 @@ function textCore(p5, fn) {
25352537
}
25362538

25372539
if (p5.RendererGL) {
2538-
p5.RendererGL.prototype.textDrawingContext = function () {
2539-
if (!this._textDrawingContext) {
2540+
p5.RendererGL.prototype.textCanvas = function() {
2541+
if (!this._textCanvas) {
25402542
this._textCanvas = document.createElement('canvas');
25412543
this._textCanvas.width = 1;
25422544
this._textCanvas.height = 1;
2543-
this._textDrawingContext = this._textCanvas.getContext('2d');
2545+
this._textCanvas.style.display = 'none';
2546+
// Has to be added to the DOM for measureText to work properly!
2547+
this.canvas.parentElement.insertBefore(this._textCanvas, this.canvas);
2548+
}
2549+
return this._textCanvas;
2550+
};
2551+
p5.RendererGL.prototype.textDrawingContext = function() {
2552+
if (!this._textDrawingContext) {
2553+
const textCanvas = this.textCanvas();
2554+
this._textDrawingContext = textCanvas.getContext('2d');
25442555
}
25452556
return this._textDrawingContext;
25462557
};
2558+
const oldRemove = p5.RendererGL.prototype.remove;
2559+
p5.RendererGL.prototype.remove = function() {
2560+
if (this._textCanvas) {
2561+
this._textCanvas.parentElement.removeChild(this._textCanvas);
2562+
}
2563+
oldRemove.call(this);
2564+
};
25472565

25482566
p5.RendererGL.prototype._positionLines = function (x, y, width, height, lines) {
25492567

src/webgl/p5.RendererGL.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -457,6 +457,13 @@ class RendererGL extends Renderer {
457457
};
458458
}
459459

460+
remove() {
461+
this.wrappedElt.remove();
462+
this.wrappedElt = null;
463+
this.canvas = null;
464+
this.elt = null;
465+
}
466+
460467
//////////////////////////////////////////////
461468
// Geometry Building
462469
//////////////////////////////////////////////

src/webgl/p5.Texture.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,14 @@ class Texture {
8686
return this;
8787
}
8888

89+
remove() {
90+
if (this.glTex) {
91+
const gl = this._renderer.GL;
92+
gl.deleteTexture(this.glTex);
93+
this.glTex = undefined;
94+
}
95+
}
96+
8997
_getTextureDataFromSource () {
9098
let textureData;
9199
if (this.isFramebufferTexture) {

0 commit comments

Comments
 (0)