From 3169d800b30ed3b236d9769f1846ca8d3ef019e9 Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Fri, 1 Nov 2024 19:32:36 +0200 Subject: [PATCH 1/3] CONTRIBUTORS.md --- CONTRIBUTORS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 5bd6a8a5cdaf..b2dc5773acd4 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -414,4 +414,5 @@ See [CONTRIBUTING.md](CONTRIBUTING.md) for details on how to contribute to Cesiu - [Adam Wirth](https://github.com/adamwirth) - [Javier Sanchez](https://github.com/jvrjsanchez) - [Jérôme Fayot](https://github.com/jfayot) +- [Michael Nusair](https://github.com/mnpcmw6444) - [Kirn Kim](https://github.com/squrki) From 4b50d48b1103465f2b1321c4987498e6a04101b5 Mon Sep 17 00:00:00 2001 From: "mnpcmw6444@gmail.com" Date: Wed, 20 Nov 2024 16:39:17 +0200 Subject: [PATCH 2/3] better fix --- packages/engine/Source/Scene/Label.js | 16 ++++ .../engine/Specs/Scene/LabelCollectionSpec.js | 78 +++++++++++++++++++ 2 files changed, 94 insertions(+) diff --git a/packages/engine/Source/Scene/Label.js b/packages/engine/Source/Scene/Label.js index 7196877768a9..18059255dfb0 100644 --- a/packages/engine/Source/Scene/Label.js +++ b/packages/engine/Source/Scene/Label.js @@ -391,6 +391,7 @@ Object.defineProperties(Label.prototype, { return this._text; }, set: function (value) { + value = Label.filterUnsupportedCharacters(value); //>>includeStart('debug', pragmas.debug); if (!defined(value)) { throw new DeveloperError("value is required."); @@ -1346,6 +1347,21 @@ Label.getScreenSpaceBoundingBox = function ( return result; }; +/** + * Removes control characters, which will cause an error when rendering a glyph. + * @private + * @param {string} text The original label text + * @returns {string} The renderable filtered text + */ +Label.filterUnsupportedCharacters = function (text) { + const problematicCharactersRegex = new RegExp( + // eslint-disable-next-line no-control-regex + /[\u0000-\u001F\u202a-\u206f\u200b-\u200f]/, + "g", + ); + return text.replace(problematicCharactersRegex, ""); +}; + /** * Determines if this label equals another label. Labels are equal if all their properties * are equal. Labels in different collections can be equal. diff --git a/packages/engine/Specs/Scene/LabelCollectionSpec.js b/packages/engine/Specs/Scene/LabelCollectionSpec.js index 3f163690e81e..e4488420cba2 100644 --- a/packages/engine/Specs/Scene/LabelCollectionSpec.js +++ b/packages/engine/Specs/Scene/LabelCollectionSpec.js @@ -2560,6 +2560,84 @@ describe( }); }); + it("filterUnsupportedCharacters removes unicode characters from text only if they cause render issues", function () { + const text = "a😀b"; + const expectedText = "a😀b"; + expect(Label.filterUnsupportedCharacters(text)).toEqual(expectedText); + }); + + it("filterUnsupportedCharacters removes unicode characters from text only if they cause render issues", function () { + const text = "awe2!$34f❤️b"; + const expectedText = "awe2!$34f❤️b"; + expect(Label.filterUnsupportedCharacters(text)).toEqual(expectedText); + }); + + it("filterUnsupportedCharacters removes unicode characters from text only if they cause render issues", function () { + const text = "lakneklf\u200fsldknfklf"; + const expectedText = "lakneklfsldknfklf"; + expect(Label.filterUnsupportedCharacters(text)).toEqual(expectedText); + }); + + it("filterUnsupportedCharacters removes unicode characters from text only if they cause render issues", function () { + const text = "test \u200f - with Right-to-Left Mark (RLM)"; + const expectedText = "test - with Right-to-Left Mark (RLM)"; + expect(Label.filterUnsupportedCharacters(text)).toEqual(expectedText); + }); + + it("filterUnsupportedCharacters removes unicode characters from text only if they cause render issues", function () { + const text = "test \u200b - with Zero-Width Space"; + const expectedText = "test - with Zero-Width Space"; + expect(Label.filterUnsupportedCharacters(text)).toEqual(expectedText); + }); + + it("filterUnsupportedCharacters removes unicode characters from text only if they cause render issues", function () { + const text = "test \u202a - with Left-to-Right Embedding"; + const expectedText = "test - with Left-to-Right Embedding"; + expect(Label.filterUnsupportedCharacters(text)).toEqual(expectedText); + }); + + it("filterUnsupportedCharacters removes unicode characters from text only if they cause render issues", function () { + const text = "test 😀 - Emoji"; + const expectedText = "test 😀 - Emoji"; + expect(Label.filterUnsupportedCharacters(text)).toEqual(expectedText); + }); + + it("filterUnsupportedCharacters removes unicode characters from text only if they cause render issues", function () { + const text = "test ❤️ - Emoji"; + const expectedText = "test ❤️ - Emoji"; + expect(Label.filterUnsupportedCharacters(text)).toEqual(expectedText); + }); + + it("filterUnsupportedCharacters removes unicode characters from text only if they cause render issues", function () { + const text = "test 🌍 - Emoji"; + const expectedText = "test 🌍 - Emoji"; + expect(Label.filterUnsupportedCharacters(text)).toEqual(expectedText); + }); + + it("filterUnsupportedCharacters removes unicode characters from text only if they cause render issues", function () { + const text = "test \u2060 - with Word Joiner"; + const expectedText = "test - with Word Joiner"; + expect(Label.filterUnsupportedCharacters(text)).toEqual(expectedText); + }); + + it("filterUnsupportedCharacters removes unicode characters from text only if they cause render issues", function () { + const text = "test \u0000 - with Null Character"; + const expectedText = "test - with Null Character"; + expect(Label.filterUnsupportedCharacters(text)).toEqual(expectedText); + }); + + it("filterUnsupportedCharacters removes unicode characters from text only if they cause render issues", function () { + const text = "test \u000A - with Line Feed (LF)"; + const expectedText = "test - with Line Feed (LF)"; + expect(Label.filterUnsupportedCharacters(text)).toEqual(expectedText); + }); + + it("filterUnsupportedCharacters removes unicode characters from text only if they cause render issues", function () { + const text = "test \u001F - with Unit Separator (US)"; + const expectedText = "test - with Unit Separator (US)"; + expect(Label.filterUnsupportedCharacters(text)).toEqual(expectedText); + }); + describe("height referenced labels", function () { beforeEach(function () { scene.globe = new Globe(); From e7b7ea2929c37c5f8628daf27ccfcbd858d30403 Mon Sep 17 00:00:00 2001 From: ggetz Date: Wed, 20 Nov 2024 13:32:49 -0500 Subject: [PATCH 3/3] Adjust setter, ensure line breaks and tabs still work --- packages/engine/Source/Scene/Label.js | 10 ++++------ packages/engine/Specs/Scene/LabelCollectionSpec.js | 4 ++-- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/packages/engine/Source/Scene/Label.js b/packages/engine/Source/Scene/Label.js index 18059255dfb0..61168a5ff2c0 100644 --- a/packages/engine/Source/Scene/Label.js +++ b/packages/engine/Source/Scene/Label.js @@ -391,7 +391,6 @@ Object.defineProperties(Label.prototype, { return this._text; }, set: function (value) { - value = Label.filterUnsupportedCharacters(value); //>>includeStart('debug', pragmas.debug); if (!defined(value)) { throw new DeveloperError("value is required."); @@ -401,8 +400,7 @@ Object.defineProperties(Label.prototype, { if (this._text !== value) { this._text = value; - // Strip soft-hyphen (auto-wrap) characters from input string - const renderedValue = value.replace(/\u00ad/g, ""); + const renderedValue = Label.filterUnsupportedCharacters(value); this._renderedText = Label.enableRightToLeftDetection ? reverseRtl(renderedValue) : renderedValue; @@ -1348,7 +1346,7 @@ Label.getScreenSpaceBoundingBox = function ( }; /** - * Removes control characters, which will cause an error when rendering a glyph. + * Removes control characters and soft hyphon (auto-wrap) characters, which will cause an error when rendering a glyph. This does not remove tabs, carriage returns, or newlines. * @private * @param {string} text The original label text * @returns {string} The renderable filtered text @@ -1356,7 +1354,7 @@ Label.getScreenSpaceBoundingBox = function ( Label.filterUnsupportedCharacters = function (text) { const problematicCharactersRegex = new RegExp( // eslint-disable-next-line no-control-regex - /[\u0000-\u001F\u202a-\u206f\u200b-\u200f]/, + /[\u0000-\u0008\u000E-\u001F\u00ad\u202a-\u206f\u200b-\u200f]/, "g", ); return text.replace(problematicCharactersRegex, ""); @@ -1518,7 +1516,7 @@ function reverseBrackets(bracket) { } } -//To add another language, simply add its Unicode block range(s) to the below regex. +// To add another language, add its Unicode block range(s) to the below regex. const hebrew = "\u05D0-\u05EA"; const arabic = "\u0600-\u06FF\u0750-\u077F\u08A0-\u08FF"; const rtlChars = new RegExp(`[${hebrew}${arabic}]`); diff --git a/packages/engine/Specs/Scene/LabelCollectionSpec.js b/packages/engine/Specs/Scene/LabelCollectionSpec.js index e4488420cba2..68c7d7dbf6dd 100644 --- a/packages/engine/Specs/Scene/LabelCollectionSpec.js +++ b/packages/engine/Specs/Scene/LabelCollectionSpec.js @@ -2627,8 +2627,8 @@ describe( }); it("filterUnsupportedCharacters removes unicode characters from text only if they cause render issues", function () { - const text = "test \u000A - with Line Feed (LF)"; - const expectedText = "test - with Line Feed (LF)"; + const text = "test \u000E - with Shift Out (SO)"; + const expectedText = "test - with Shift Out (SO)"; expect(Label.filterUnsupportedCharacters(text)).toEqual(expectedText); });