Skip to content

Commit 50e83c3

Browse files
Add new option to CanvasFont "getCharScale" which returns scale factor 0-1 for a code point (playcanvas#1307)
Default CanvasFont scale works for most characters, for particular fonts or characters a custom scale may be required Provide your own function that returns a scale 0-1 for a code point to customize
1 parent 3dda432 commit 50e83c3

2 files changed

Lines changed: 27 additions & 9 deletions

File tree

examples/canvas-font/index.html

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,15 @@
4141
fontName: "Arial",
4242
fontSize: size,
4343
width: 128,
44-
height: 128
44+
height: 128,
45+
getCharScale: function (code) {
46+
// finger pointing up is a particular long character, use more scaling
47+
if (code === 0x261D) {
48+
return 0.8;
49+
} else {
50+
return -1; // use default scaler
51+
}
52+
}
4553
});
4654

4755
var asset = new pc.Asset("CanvasFont", "font", {});
@@ -87,7 +95,7 @@
8795

8896
// some sample text
8997
var firstline = "ÉÅAå 東京 🐇🔥🂡 font";
90-
var secondline = "😀😀😀🤢🤥🤝😻👍👨‍🎤😡💪🏿😍🤔💽🦀🍑👻😗😏😒👽👾🎃😺💩😈🤒💑👢🐭🦁🐸🐍🦐🐙";
98+
var secondline = "😀😀😀🤢🤥🤝😻👍👨‍🎤😡💪🏿😍🤔💽🦀🍑👻😗😏😒👽👾🎃😺💩😈🤒💑👢🐭🦁🐸🐍🦐🐙";
9199
var thirdline = "Testing MSDF font";
92100

93101
cf.createTextures(firstline);

src/framework/components/text/canvas-font.js

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ Object.assign(pc, function () {
3030
* @param {pc.Color} [options.color] The color the font will be rendered into the texture atlas as, defaults to white
3131
* @param {Number} [options.width] The width of each texture atlas, defaults to 2048
3232
* @param {Number} [options.height] The height of each texture atlas, defaults to 2048
33+
* @param {Number} [options.getCharScale] A custom function which takes a codepoint and return scale value 0-1 to scale char down before rendering into atlas. Return -1 to use default scale value.
3334
*/
3435
var CanvasFont = function (app, options) {
3536
this.type = "bitmap";
@@ -45,6 +46,8 @@ Object.assign(pc, function () {
4546
this.fontName = options.fontName || 'Arial';
4647
this.color = options.color || new pc.Color(1, 1, 1);
4748

49+
this._customGetCharScale = options.getCharScale || null;
50+
4851
var w = options.width > MAX_TEXTURE_SIZE ? MAX_TEXTURE_SIZE : (options.width || DEFAULT_TEXTURE_SIZE);
4952
var h = options.height > MAX_TEXTURE_SIZE ? MAX_TEXTURE_SIZE : (options.height || DEFAULT_TEXTURE_SIZE);
5053

@@ -190,7 +193,7 @@ Object.assign(pc, function () {
190193
var ch = symbols[i];
191194
var code = pc.string.getCodePoint(symbols[i]);
192195

193-
var fs = this.getCharScale(code) * this.fontSize;
196+
var fs = this._getCharScale(code) * this.fontSize;
194197
ctx.font = this.fontWeight + ' ' + fs.toString() + 'px "' + this.fontName + '"';
195198
ctx.textAlign = TEXT_ALIGN;
196199
ctx.textBaseline = TEXT_BASELINE;
@@ -289,26 +292,33 @@ Object.assign(pc, function () {
289292
//
290293
// If we required we can allow a user-custom function here that users can
291294
// supply special cases for their character set
292-
CanvasFont.prototype.getCharScale = function (code) {
293-
var scale = 1.0;
295+
CanvasFont.prototype._getCharScale = function (code) {
296+
// if a custom scale function is available use it
297+
// custom scale function can ignore chars by return -1
298+
if (this._customGetCharScale) {
299+
var scale = this._customGetCharScale(code);
300+
if (scale >= 0) {
301+
return scale;
302+
}
303+
}
294304

295305
if (code >= 0x00C0 && code <= 0x00DD) {
296306
// capital letters with accents
297-
scale = (this.fontSize - (this.fontSize / 8)) / this.fontSize;
307+
return 0.875;
298308
} else if (code >= 0x1f000 && code <= 0x1F9FF) {
299309
// "emoji" misc. images and emoticon range of unicode
300-
scale = (this.fontSize - (this.fontSize / 8)) / this.fontSize;
310+
return 0.875;
301311
}
302312

303-
return scale;
313+
return 1.0;
304314
};
305315

306316
CanvasFont.prototype._addChar = function (json, char, charCode, x, y, w, h, xoffset, yoffset, xadvance, mapNum, mapW, mapH) {
307317
if (json.info.maps.length < mapNum + 1) {
308318
json.info.maps.push({ "width": mapW, "height": mapH });
309319
}
310320

311-
var scale = this.getCharScale(charCode) * this.fontSize / 32;
321+
var scale = this._getCharScale(charCode) * this.fontSize / 32;
312322

313323
json.chars[charCode] = {
314324
"id": charCode,

0 commit comments

Comments
 (0)