From 374b062d9b68267639bafcc57681a3360a9bfda8 Mon Sep 17 00:00:00 2001 From: rithik56 Date: Thu, 1 Feb 2024 11:56:29 +0530 Subject: [PATCH 01/13] add fallback character when a character is missing from custom font --- src/render/glyph_manager.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/render/glyph_manager.js b/src/render/glyph_manager.js index 940f9130d30..7ed334dac71 100644 --- a/src/render/glyph_manager.js +++ b/src/render/glyph_manager.js @@ -114,7 +114,7 @@ class GlyphManager { return; } - glyph = this._tinySDF(entry, stack, id); + glyph = this._tinySDF(entry, stack, id, false); if (glyph) { entry.glyphs[id] = glyph; fnCallback(null, {stack, id, glyph}); @@ -158,7 +158,7 @@ class GlyphManager { if (err) { fnCallback(err); } else if (result) { - fnCallback(null, {stack, id, glyph: result.glyphs[id] || null}); + fnCallback(null, {stack, id, glyph: result.glyphs[id] || this._tinySDF(entry, stack, id, true) || this._tinySDF(entry, stack, 63, true) || null}); } }); }, (err, glyphs: ?Array<{stack: string, id: number, glyph: ?StyleGlyph}>) => { @@ -206,9 +206,9 @@ class GlyphManager { } } - _tinySDF(entry: Entry, stack: string, id: number): ?StyleGlyph { + _tinySDF(entry: Entry, stack: string, id: number, isFallback: boolean): ?StyleGlyph { const fontFamily = this.localFontFamily; - if (!fontFamily || !this._doesCharSupportLocalGlyph(id)) return; + if (!isFallback && (!fontFamily || !this._doesCharSupportLocalGlyph(id))) return; let tinySDF = entry.tinySDF; if (!tinySDF) { From bdfa142f6a96fff98055def84d451a7243c9e9bc Mon Sep 17 00:00:00 2001 From: rithik56 Date: Thu, 1 Feb 2024 16:19:16 +0530 Subject: [PATCH 02/13] added feature to show the fallback character if a character is not present in custom font --- src/render/glyph_manager.js | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/src/render/glyph_manager.js b/src/render/glyph_manager.js index 7ed334dac71..45ac283f6f6 100644 --- a/src/render/glyph_manager.js +++ b/src/render/glyph_manager.js @@ -59,6 +59,7 @@ class GlyphManager { // Multiple fontstacks may share the same local glyphs, so keep an index // into the glyphs based soley on font weight localGlyphs: {[_: string]: {glyphs: {[id: number]: StyleGlyph | null}, ascender: ?number, descender: ?number}}; + fallbackGlyphs: {[stack: string] : StyleGlyph | null}; urls: {[scope: string]: ?string}; // exposed as statics to enable stubbing in unit tests @@ -78,6 +79,7 @@ class GlyphManager { '500': {}, '900': {} }; + this.fallbackGlyphs = {}; } setURL(url: ?string, scope: string) { @@ -114,7 +116,7 @@ class GlyphManager { return; } - glyph = this._tinySDF(entry, stack, id, false); + glyph = this._tinySDF(entry, stack, id); if (glyph) { entry.glyphs[id] = glyph; fnCallback(null, {stack, id, glyph}); @@ -158,7 +160,25 @@ class GlyphManager { if (err) { fnCallback(err); } else if (result) { - fnCallback(null, {stack, id, glyph: result.glyphs[id] || this._tinySDF(entry, stack, id, true) || this._tinySDF(entry, stack, 63, true) || null}); + let glyph = result.glyphs[id]; + if (!glyph && !this.fallbackGlyphs[stack]) { + this.getGlyphs({[stack]: [63]}, '', (err, results) => { + if (!err) { + this.fallbackGlyphs[stack] = glyph = results[stack].glyphs[63]; + } + fnCallback(null, { + stack, + id, + glyph + }); + }); + } else { + fnCallback(null, { + stack, + id, + glyph: glyph || this.fallbackGlyphs[stack] + }); + } } }); }, (err, glyphs: ?Array<{stack: string, id: number, glyph: ?StyleGlyph}>) => { From 25571cefa8acafb47f89e8fad228f41fa03120aa Mon Sep 17 00:00:00 2001 From: rithik56 Date: Thu, 1 Feb 2024 22:41:26 +0530 Subject: [PATCH 03/13] bug fix --- src/render/glyph_manager.js | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/src/render/glyph_manager.js b/src/render/glyph_manager.js index 45ac283f6f6..9f4c76165cc 100644 --- a/src/render/glyph_manager.js +++ b/src/render/glyph_manager.js @@ -59,7 +59,6 @@ class GlyphManager { // Multiple fontstacks may share the same local glyphs, so keep an index // into the glyphs based soley on font weight localGlyphs: {[_: string]: {glyphs: {[id: number]: StyleGlyph | null}, ascender: ?number, descender: ?number}}; - fallbackGlyphs: {[stack: string] : StyleGlyph | null}; urls: {[scope: string]: ?string}; // exposed as statics to enable stubbing in unit tests @@ -79,7 +78,6 @@ class GlyphManager { '500': {}, '900': {} }; - this.fallbackGlyphs = {}; } setURL(url: ?string, scope: string) { @@ -156,27 +154,30 @@ class GlyphManager { }); } - requests.push((err, result: ?{glyphs: {[_: number]: StyleGlyph | null}, ascender?: number, descender?: number}) => { + requests.push((err, result) => { if (err) { fnCallback(err); } else if (result) { - let glyph = result.glyphs[id]; - if (!glyph && !this.fallbackGlyphs[stack]) { - this.getGlyphs({[stack]: [63]}, '', (err, results) => { - if (!err) { - this.fallbackGlyphs[stack] = glyph = results[stack].glyphs[63]; + + const glyph = result.glyphs[id] || entry.glyphs[63]; + + if (!glyph) { + this.getGlyphs({[stack]:[63]}, '', (err, res) => { + if (err) { + fnCallback(err); + } else { + fnCallback(null, { + stack, + id, + glyph: res[stack].glyphs[63] || null + }); } - fnCallback(null, { - stack, - id, - glyph - }); }); } else { fnCallback(null, { stack, id, - glyph: glyph || this.fallbackGlyphs[stack] + glyph }); } } From f30bf37fd3216c0f059224269ae4265a65797d1a Mon Sep 17 00:00:00 2001 From: rithik56 Date: Thu, 1 Feb 2024 22:47:46 +0530 Subject: [PATCH 04/13] bug fixes --- src/render/glyph_manager.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/render/glyph_manager.js b/src/render/glyph_manager.js index 9f4c76165cc..8b2ceea44e0 100644 --- a/src/render/glyph_manager.js +++ b/src/render/glyph_manager.js @@ -154,7 +154,7 @@ class GlyphManager { }); } - requests.push((err, result) => { + requests.push((err, result: ?{glyphs: {[_: number]: StyleGlyph | null}, ascender?: number, descender?: number}) => { if (err) { fnCallback(err); } else if (result) { @@ -227,9 +227,9 @@ class GlyphManager { } } - _tinySDF(entry: Entry, stack: string, id: number, isFallback: boolean): ?StyleGlyph { + _tinySDF(entry: Entry, stack: string, id: number): ?StyleGlyph { const fontFamily = this.localFontFamily; - if (!isFallback && (!fontFamily || !this._doesCharSupportLocalGlyph(id))) return; + if (!fontFamily || !this._doesCharSupportLocalGlyph(id)) return; let tinySDF = entry.tinySDF; if (!tinySDF) { From 2c43d42107de963ca4b051968c92d49b66eb1ac9 Mon Sep 17 00:00:00 2001 From: rithik56 Date: Fri, 2 Feb 2024 00:28:56 +0530 Subject: [PATCH 05/13] replaced null instance of glyph with fallback glyph --- src/render/glyph_manager.js | 40 +++++++++++++++---------------------- 1 file changed, 16 insertions(+), 24 deletions(-) diff --git a/src/render/glyph_manager.js b/src/render/glyph_manager.js index 8b2ceea44e0..b0be6b6c06c 100644 --- a/src/render/glyph_manager.js +++ b/src/render/glyph_manager.js @@ -91,8 +91,13 @@ class GlyphManager { const url = this.urls[scope] || config.GLYPHS_URL; for (const stack in glyphs) { + let isFound = false; for (const id of glyphs[stack]) { all.push({stack, id}); + if (!isFound && Math.floor(id / 256) === 0) isFound = true; + } + if (!isFound) { + all.push({stack, id: 63}); } } @@ -158,28 +163,11 @@ class GlyphManager { if (err) { fnCallback(err); } else if (result) { - - const glyph = result.glyphs[id] || entry.glyphs[63]; - - if (!glyph) { - this.getGlyphs({[stack]:[63]}, '', (err, res) => { - if (err) { - fnCallback(err); - } else { - fnCallback(null, { - stack, - id, - glyph: res[stack].glyphs[63] || null - }); - } - }); - } else { - fnCallback(null, { - stack, - id, - glyph - }); - } + fnCallback(null, { + stack, + id, + glyph: result.glyphs[id] || null + }); } }); }, (err, glyphs: ?Array<{stack: string, id: number, glyph: ?StyleGlyph}>) => { @@ -192,10 +180,14 @@ class GlyphManager { // Clone the glyph so that our own copy of its ArrayBuffer doesn't get transferred. if (result[stack] === undefined) result[stack] = {}; if (result[stack].glyphs === undefined) result[stack].glyphs = {}; - result[stack].glyphs[id] = glyph && { + result[stack].glyphs[id] = glyph ? { id: glyph.id, bitmap: glyph.bitmap.clone(), - metrics: glyph.metrics + metrics: glyph.metrics, + } : { + id, + bitmap: this.entries[stack].glyphs[63].bitmap.clone(), + metrics: this.entries[stack].glyphs[63].metrics, }; result[stack].ascender = this.entries[stack].ascender; result[stack].descender = this.entries[stack].descender; From 73bf79beb0467b9d05c2317b38cacb6ceda4d81d Mon Sep 17 00:00:00 2001 From: rithik56 <70520896+rithik56@users.noreply.github.com> Date: Fri, 2 Feb 2024 00:32:13 +0530 Subject: [PATCH 06/13] formatting and variable name changes --- src/render/glyph_manager.js | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/render/glyph_manager.js b/src/render/glyph_manager.js index b0be6b6c06c..f88ff0d0b5c 100644 --- a/src/render/glyph_manager.js +++ b/src/render/glyph_manager.js @@ -91,12 +91,12 @@ class GlyphManager { const url = this.urls[scope] || config.GLYPHS_URL; for (const stack in glyphs) { - let isFound = false; + let isFoundFallbackRange = false; for (const id of glyphs[stack]) { all.push({stack, id}); - if (!isFound && Math.floor(id / 256) === 0) isFound = true; + if (!isFoundFallbackRange && Math.floor(id / 256) === 0) isFoundFallbackRange = true; } - if (!isFound) { + if (!isFoundFallbackRange) { all.push({stack, id: 63}); } } @@ -163,11 +163,7 @@ class GlyphManager { if (err) { fnCallback(err); } else if (result) { - fnCallback(null, { - stack, - id, - glyph: result.glyphs[id] || null - }); + fnCallback(null, {stack, id, glyph: result.glyphs[id] || null}); } }); }, (err, glyphs: ?Array<{stack: string, id: number, glyph: ?StyleGlyph}>) => { From b06e83ff445a98f92be01643b571134bdf8551f1 Mon Sep 17 00:00:00 2001 From: rithik56 Date: Fri, 2 Feb 2024 23:53:47 +0530 Subject: [PATCH 07/13] add enableFallbackGlyph option in glyph manager class --- src/render/glyph_manager.js | 12 +++++++----- src/style/style.js | 3 ++- test/unit/render/glyph_manager.test.js | 2 +- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/render/glyph_manager.js b/src/render/glyph_manager.js index f88ff0d0b5c..a0f9667a1b8 100644 --- a/src/render/glyph_manager.js +++ b/src/render/glyph_manager.js @@ -59,13 +59,14 @@ class GlyphManager { // Multiple fontstacks may share the same local glyphs, so keep an index // into the glyphs based soley on font weight localGlyphs: {[_: string]: {glyphs: {[id: number]: StyleGlyph | null}, ascender: ?number, descender: ?number}}; + enableFallbackGlyph: ?boolean urls: {[scope: string]: ?string}; // exposed as statics to enable stubbing in unit tests static loadGlyphRange: typeof loadGlyphRange; static TinySDF: Class; - constructor(requestManager: RequestManager, localGlyphMode: number, localFontFamily: ?string) { + constructor(requestManager: RequestManager, localGlyphMode: number, localFontFamily: ?string, enableFallbackGlyph: ?boolean) { this.requestManager = requestManager; this.localGlyphMode = localGlyphMode; this.localFontFamily = localFontFamily; @@ -78,6 +79,7 @@ class GlyphManager { '500': {}, '900': {} }; + this.enableFallbackGlyph = enableFallbackGlyph; } setURL(url: ?string, scope: string) { @@ -91,12 +93,12 @@ class GlyphManager { const url = this.urls[scope] || config.GLYPHS_URL; for (const stack in glyphs) { - let isFoundFallbackRange = false; + let doesCharSupportFallbackGlyphRange = false; for (const id of glyphs[stack]) { all.push({stack, id}); - if (!isFoundFallbackRange && Math.floor(id / 256) === 0) isFoundFallbackRange = true; + if (!!this.enableFallbackGlyph && id >= 0 && id <= 255) doesCharSupportFallbackGlyphRange = true; } - if (!isFoundFallbackRange) { + if (!!this.enableFallbackGlyph && !doesCharSupportFallbackGlyphRange) { all.push({stack, id: 63}); } } @@ -180,7 +182,7 @@ class GlyphManager { id: glyph.id, bitmap: glyph.bitmap.clone(), metrics: glyph.metrics, - } : { + } : !!this.enableFallbackGlyph && this.entries[stack].glyphs[63] && { id, bitmap: this.entries[stack].glyphs[63].bitmap.clone(), metrics: this.entries[stack].glyphs[63].metrics, diff --git a/src/style/style.js b/src/style/style.js index bd9f6050904..14268684306 100644 --- a/src/style/style.js +++ b/src/style/style.js @@ -148,6 +148,7 @@ export type StyleOptions = { validate?: boolean, localFontFamily?: ?string, localIdeographFontFamily?: string, + enableFallbackGlyph?: Boolean, dispatcher?: Dispatcher, imageManager?: ImageManager, @@ -306,7 +307,7 @@ class Style extends Evented { options.localFontFamily ? LocalGlyphMode.all : (options.localIdeographFontFamily ? LocalGlyphMode.ideographs : LocalGlyphMode.none), - options.localFontFamily || options.localIdeographFontFamily); + options.localFontFamily || options.localIdeographFontFamily, options.enableFallbackGlyph); } if (options.modelManager) { diff --git a/test/unit/render/glyph_manager.test.js b/test/unit/render/glyph_manager.test.js index e6bdc127527..dcfd52f2a99 100644 --- a/test/unit/render/glyph_manager.test.js +++ b/test/unit/render/glyph_manager.test.js @@ -44,7 +44,7 @@ const createLoadGlyphRangeStub = (t) => { const createGlyphManager = (font, allGlyphs) => { const manager = new GlyphManager(identityTransform, font ? (allGlyphs ? LocalGlyphMode.all : LocalGlyphMode.ideographs) : LocalGlyphMode.none, - font); + font, false); manager.setURL('https://localhost/fonts/v1/{fontstack}/{range}.pbf'); return manager; }; From 373d12957d6f7d594433e5bda86b59d2460a2940 Mon Sep 17 00:00:00 2001 From: rithik56 Date: Sat, 3 Feb 2024 00:09:54 +0530 Subject: [PATCH 08/13] test flow fixes --- src/style/style.js | 2 +- test/unit/render/glyph_manager.test.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/style/style.js b/src/style/style.js index 14268684306..908f96d5daf 100644 --- a/src/style/style.js +++ b/src/style/style.js @@ -148,7 +148,7 @@ export type StyleOptions = { validate?: boolean, localFontFamily?: ?string, localIdeographFontFamily?: string, - enableFallbackGlyph?: Boolean, + enableFallbackGlyph?: boolean, dispatcher?: Dispatcher, imageManager?: ImageManager, diff --git a/test/unit/render/glyph_manager.test.js b/test/unit/render/glyph_manager.test.js index dcfd52f2a99..d792af03c9c 100644 --- a/test/unit/render/glyph_manager.test.js +++ b/test/unit/render/glyph_manager.test.js @@ -41,10 +41,10 @@ const createLoadGlyphRangeStub = (t) => { }); }; -const createGlyphManager = (font, allGlyphs) => { +const createGlyphManager = (font, allGlyphs, enableFallbackGlyph) => { const manager = new GlyphManager(identityTransform, font ? (allGlyphs ? LocalGlyphMode.all : LocalGlyphMode.ideographs) : LocalGlyphMode.none, - font, false); + font, !!enableFallbackGlyph); manager.setURL('https://localhost/fonts/v1/{fontstack}/{range}.pbf'); return manager; }; From 85bcefadec37b4ff2512f355ab158153fef2ba5b Mon Sep 17 00:00:00 2001 From: rithik56 Date: Sat, 3 Feb 2024 00:36:37 +0530 Subject: [PATCH 09/13] unit test fixes --- src/render/glyph_manager.js | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/src/render/glyph_manager.js b/src/render/glyph_manager.js index a0f9667a1b8..c81a8dd88d7 100644 --- a/src/render/glyph_manager.js +++ b/src/render/glyph_manager.js @@ -178,19 +178,25 @@ class GlyphManager { // Clone the glyph so that our own copy of its ArrayBuffer doesn't get transferred. if (result[stack] === undefined) result[stack] = {}; if (result[stack].glyphs === undefined) result[stack].glyphs = {}; - result[stack].glyphs[id] = glyph ? { - id: glyph.id, - bitmap: glyph.bitmap.clone(), - metrics: glyph.metrics, - } : !!this.enableFallbackGlyph && this.entries[stack].glyphs[63] && { - id, - bitmap: this.entries[stack].glyphs[63].bitmap.clone(), - metrics: this.entries[stack].glyphs[63].metrics, - }; + if (glyph) { + result[stack].glyphs[id] = { + id: glyph.id, + bitmap: glyph.bitmap.clone(), + metrics: glyph.metrics, + }; + } else if (this.enableFallbackGlyph) { + const fallbackGlyph = this.entries[stack].glyphs[63]; + if (fallbackGlyph) { + result[stack].glyphs[id] = { + id, + bitmap: fallbackGlyph.bitmap.clone(), + metrics: fallbackGlyph.metrics, + }; + } + } result[stack].ascender = this.entries[stack].ascender; result[stack].descender = this.entries[stack].descender; } - callback(null, result); } }); From 656290cc65da7eda852f3cf2917d3a4b85acaa8c Mon Sep 17 00:00:00 2001 From: rithik56 Date: Sat, 3 Feb 2024 00:45:09 +0530 Subject: [PATCH 10/13] unit test fix --- src/render/glyph_manager.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/render/glyph_manager.js b/src/render/glyph_manager.js index c81a8dd88d7..e10efb43a57 100644 --- a/src/render/glyph_manager.js +++ b/src/render/glyph_manager.js @@ -192,7 +192,11 @@ class GlyphManager { bitmap: fallbackGlyph.bitmap.clone(), metrics: fallbackGlyph.metrics, }; + } else { + result[stack].glyphs[id] = null; } + } else { + result[stack].glyphs[id] = null; } result[stack].ascender = this.entries[stack].ascender; result[stack].descender = this.entries[stack].descender; From 645e3e9fdcc606f1459f0f8d8c09b82a51230817 Mon Sep 17 00:00:00 2001 From: rithik56 Date: Sat, 3 Feb 2024 12:27:37 +0530 Subject: [PATCH 11/13] added unit tests for testing the enable fallback glyph feature and added option in map constructor to enable fallback glyph --- src/ui/map.js | 11 +++++++--- test/unit/render/glyph_manager.test.js | 28 ++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/src/ui/map.js b/src/ui/map.js index 79609ff5d14..1637fe100d4 100755 --- a/src/ui/map.js +++ b/src/ui/map.js @@ -195,6 +195,7 @@ const defaultOptions = { maxTileCacheSize: null, localIdeographFontFamily: 'sans-serif', localFontFamily: null, + enableFallbackGlyph: false, transformRequest: null, accessToken: null, fadeDuration: 300, @@ -301,6 +302,7 @@ const defaultOptions = { * @param {string} [options.localFontFamily=null] Defines a CSS * font-family for locally overriding generation of all glyphs. Font settings from the map's style will be ignored, except for font-weight keywords (light/regular/medium/bold). * If set, this option overrides the setting in localIdeographFontFamily. + * @param {boolean} [options.enableFallbackGlyph=false] IF true, will show the fallback character ? in place of characters which are missing from custom fonts * @param {RequestTransformFunction} [options.transformRequest=null] A callback run before the Map makes a request for an external URL. The callback can be used to modify the url, set headers, or set the credentials property for cross-origin requests. * Expected to return a {@link RequestParameters} object with a `url` property and optionally `headers` and `credentials` properties. * @param {boolean} [options.collectResourceTiming=false] If `true`, Resource Timing API information will be collected for requests made by GeoJSON and Vector Tile web workers (this information is normally inaccessible from the main Javascript thread). Information will be returned in a `resourceTiming` property of relevant `data` events. @@ -400,6 +402,7 @@ class Map extends Camera { _mapId: number; _localIdeographFontFamily: string; _localFontFamily: ?string; + _enableFallbackGlyph: ?boolean; _requestManager: RequestManager; _locale: Object; _removed: boolean; @@ -611,10 +614,11 @@ class Map extends Camera { this._localFontFamily = options.localFontFamily; this._localIdeographFontFamily = options.localIdeographFontFamily; + this._enableFallbackGlyph = options.enableFallbackGlyph; if (options.style || !options.testMode) { const style = options.style || config.DEFAULT_STYLE; - this.setStyle(style, {localFontFamily: this._localFontFamily, localIdeographFontFamily: this._localIdeographFontFamily}); + this.setStyle(style, {localFontFamily: this._localFontFamily, localIdeographFontFamily: this._localIdeographFontFamily, enableFallbackGlyph: this._enableFallbackGlyph}); } if (options.projection) { @@ -1940,16 +1944,17 @@ class Map extends Camera { * @see [Example: Change a map's style](https://www.mapbox.com/mapbox-gl-js/example/setstyle/) */ setStyle(style: StyleSpecification | string | null, options?: {diff?: boolean} & StyleOptions): this { - options = extend({}, {localIdeographFontFamily: this._localIdeographFontFamily, localFontFamily: this._localFontFamily}, options); + options = extend({}, {localIdeographFontFamily: this._localIdeographFontFamily, localFontFamily: this._localFontFamily, enableFallbackGlyph: this._enableFallbackGlyph}, options); if ((options.diff !== false && options.localIdeographFontFamily === this._localIdeographFontFamily && - options.localFontFamily === this._localFontFamily) && this.style && style) { + options.localFontFamily === this._localFontFamily && options.enableFallbackGlyph === this._enableFallbackGlyph) && this.style && style) { this._diffStyle(style, options); return this; } else { this._localIdeographFontFamily = options.localIdeographFontFamily; this._localFontFamily = options.localFontFamily; + this._enableFallbackGlyph = options.enableFallbackGlyph; return this._updateStyle(style, options); } } diff --git a/test/unit/render/glyph_manager.test.js b/test/unit/render/glyph_manager.test.js index d792af03c9c..8d36a228ac2 100644 --- a/test/unit/render/glyph_manager.test.js +++ b/test/unit/render/glyph_manager.test.js @@ -227,3 +227,31 @@ test('GlyphManager locally generates latin glyphs', (t) => { t.end(); }); }); + +test('GlyphManager replaces missing glyphs from custom font with ? character glyph of the corresponding font', (t) => { + t.stub(GlyphManager, 'TinySDF').value(TinySDF); + // enableFallbackGlyph option is set to true + const manager = createGlyphManager('sans-serif', true, true); + + manager.getGlyphs({'Arial Unicode MS': [0x2253]}, undefined, (err, result) => { + t.ifError(err); + const glyphs = result['Arial Unicode MS'].glyphs; + t.equal(glyphs[0x2253].metrics.advance, 10); + t.equal(glyphs[0x2253].metrics.width, 11); + t.equal(glyphs[0x2253].metrics.height, 19); + t.end(); + }); +}); + +test('GlyphManager do not replace missing glyph from custom font with ? character glyph', (t) => { + t.stub(GlyphManager, 'TinySDF').value(TinySDF); + // enableFallbackGlyph option is set to false + const manager = createGlyphManager('sans-serif', true, false); + + manager.getGlyphs({'Arial Unicode MS': [0x2253]}, undefined, (err, result) => { + t.ifError(err); + const glyphs = result['Arial Unicode MS'].glyphs; + t.equal(glyphs[0x2253], null); + t.end(); + }); +}); From 2ad34c94177737305f25ff940f61f692b97d54c1 Mon Sep 17 00:00:00 2001 From: rithik56 Date: Tue, 6 Feb 2024 22:25:25 +0530 Subject: [PATCH 12/13] minor changes --- src/render/glyph_manager.js | 4 ++-- src/ui/map.js | 2 +- test/unit/render/glyph_manager.test.js | 28 -------------------------- 3 files changed, 3 insertions(+), 31 deletions(-) diff --git a/src/render/glyph_manager.js b/src/render/glyph_manager.js index e10efb43a57..2b743f1b791 100644 --- a/src/render/glyph_manager.js +++ b/src/render/glyph_manager.js @@ -96,9 +96,9 @@ class GlyphManager { let doesCharSupportFallbackGlyphRange = false; for (const id of glyphs[stack]) { all.push({stack, id}); - if (!!this.enableFallbackGlyph && id >= 0 && id <= 255) doesCharSupportFallbackGlyphRange = true; + if (this.localGlyphMode !== LocalGlyphMode.all && !!this.enableFallbackGlyph && id >= 0 && id <= 255) doesCharSupportFallbackGlyphRange = true; } - if (!!this.enableFallbackGlyph && !doesCharSupportFallbackGlyphRange) { + if (this.localGlyphMode !== LocalGlyphMode.all && !!this.enableFallbackGlyph && !doesCharSupportFallbackGlyphRange) { all.push({stack, id: 63}); } } diff --git a/src/ui/map.js b/src/ui/map.js index 1637fe100d4..e8f2ccc8526 100755 --- a/src/ui/map.js +++ b/src/ui/map.js @@ -302,7 +302,7 @@ const defaultOptions = { * @param {string} [options.localFontFamily=null] Defines a CSS * font-family for locally overriding generation of all glyphs. Font settings from the map's style will be ignored, except for font-weight keywords (light/regular/medium/bold). * If set, this option overrides the setting in localIdeographFontFamily. - * @param {boolean} [options.enableFallbackGlyph=false] IF true, will show the fallback character ? in place of characters which are missing from custom fonts + * @param {boolean} [options.enableFallbackGlyph=false] If `true`, will show the fallback character ? In place of characters which are missing from custom fonts. * @param {RequestTransformFunction} [options.transformRequest=null] A callback run before the Map makes a request for an external URL. The callback can be used to modify the url, set headers, or set the credentials property for cross-origin requests. * Expected to return a {@link RequestParameters} object with a `url` property and optionally `headers` and `credentials` properties. * @param {boolean} [options.collectResourceTiming=false] If `true`, Resource Timing API information will be collected for requests made by GeoJSON and Vector Tile web workers (this information is normally inaccessible from the main Javascript thread). Information will be returned in a `resourceTiming` property of relevant `data` events. diff --git a/test/unit/render/glyph_manager.test.js b/test/unit/render/glyph_manager.test.js index 8d36a228ac2..d792af03c9c 100644 --- a/test/unit/render/glyph_manager.test.js +++ b/test/unit/render/glyph_manager.test.js @@ -227,31 +227,3 @@ test('GlyphManager locally generates latin glyphs', (t) => { t.end(); }); }); - -test('GlyphManager replaces missing glyphs from custom font with ? character glyph of the corresponding font', (t) => { - t.stub(GlyphManager, 'TinySDF').value(TinySDF); - // enableFallbackGlyph option is set to true - const manager = createGlyphManager('sans-serif', true, true); - - manager.getGlyphs({'Arial Unicode MS': [0x2253]}, undefined, (err, result) => { - t.ifError(err); - const glyphs = result['Arial Unicode MS'].glyphs; - t.equal(glyphs[0x2253].metrics.advance, 10); - t.equal(glyphs[0x2253].metrics.width, 11); - t.equal(glyphs[0x2253].metrics.height, 19); - t.end(); - }); -}); - -test('GlyphManager do not replace missing glyph from custom font with ? character glyph', (t) => { - t.stub(GlyphManager, 'TinySDF').value(TinySDF); - // enableFallbackGlyph option is set to false - const manager = createGlyphManager('sans-serif', true, false); - - manager.getGlyphs({'Arial Unicode MS': [0x2253]}, undefined, (err, result) => { - t.ifError(err); - const glyphs = result['Arial Unicode MS'].glyphs; - t.equal(glyphs[0x2253], null); - t.end(); - }); -}); From 23762ab68ae024a3e75c22e5d6db615b8e0d01c0 Mon Sep 17 00:00:00 2001 From: rithik56 <70520896+rithik56@users.noreply.github.com> Date: Tue, 6 Feb 2024 22:29:10 +0530 Subject: [PATCH 13/13] Update glyph_manager.test.js --- test/unit/render/glyph_manager.test.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/unit/render/glyph_manager.test.js b/test/unit/render/glyph_manager.test.js index d792af03c9c..e6bdc127527 100644 --- a/test/unit/render/glyph_manager.test.js +++ b/test/unit/render/glyph_manager.test.js @@ -41,10 +41,10 @@ const createLoadGlyphRangeStub = (t) => { }); }; -const createGlyphManager = (font, allGlyphs, enableFallbackGlyph) => { +const createGlyphManager = (font, allGlyphs) => { const manager = new GlyphManager(identityTransform, font ? (allGlyphs ? LocalGlyphMode.all : LocalGlyphMode.ideographs) : LocalGlyphMode.none, - font, !!enableFallbackGlyph); + font); manager.setURL('https://localhost/fonts/v1/{fontstack}/{range}.pbf'); return manager; };