From 756cefd6891c8d3874a777b1ff43a701b71f4fc3 Mon Sep 17 00:00:00 2001 From: hodbauer Date: Sun, 27 Jan 2019 12:31:59 +0200 Subject: [PATCH 1/2] fixed reversing non alphabetic characters on RTL labels --- CHANGES.md | 1 + Source/Scene/Label.js | 21 +++++++++++++++++---- Specs/Scene/LabelCollectionSpec.js | 11 +++++++++++ 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 514dda84cfae..a5f35fb7c00a 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -23,6 +23,7 @@ Change Log * Improved the performance of `QuantizedMeshTerrainData.interpolateHeight`. [#7508](https://github.com/AnalyticalGraphicsInc/cesium/pull/7508) ##### Fixes :wrench: +* Fixed an issue where RTL labels not reversing correctly non alphabetic characters [#7501](https://github.com/AnalyticalGraphicsInc/cesium/pull/7501) * Fixed 3D Tiles performance regression. [#7482](https://github.com/AnalyticalGraphicsInc/cesium/pull/7482) * Fixed an issue where classification primitives with the `CESIUM_3D_TILE` classification type would render on terrain. [#7422](https://github.com/AnalyticalGraphicsInc/cesium/pull/7422) * Fixed an issue where 3D Tiles would show through the globe. [#7422](https://github.com/AnalyticalGraphicsInc/cesium/pull/7422) diff --git a/Source/Scene/Label.js b/Source/Scene/Label.js index b2fa4c8a4b69..278e7fcdbecd 100644 --- a/Source/Scene/Label.js +++ b/Source/Scene/Label.js @@ -1340,6 +1340,7 @@ define([ var result = ''; for (var i = 0; i < texts.length; i++) { var text = texts[i]; + // first character of the line is a RTL character, so need to manage different cases var rtlDir = rtlChars.test(text.charAt(0)); var parsedText = convertTextToTypes(text, rtlChars); @@ -1347,10 +1348,10 @@ define([ var line = ''; for (var wordIndex = 0; wordIndex < parsedText.length; ++wordIndex) { var subText = parsedText[wordIndex]; - var reverse = subText.Type === textTypes.BRACKETS ? reverseBrackets(subText.Word) : subText.Word; + var reverse = subText.Type === textTypes.BRACKETS ? reverseBrackets(subText.Word) : reverseWord(subText.Word); if (rtlDir) { if (subText.Type === textTypes.RTL) { - line = reverseWord(subText.Word) + line; + line = reverse + line; splicePointer = 0; } else if (subText.Type === textTypes.LTR) { @@ -1358,14 +1359,18 @@ define([ splicePointer += subText.Word.length; } else if (subText.Type === textTypes.WEAK || subText.Type === textTypes.BRACKETS) { + // current word is weak, last one was bracket if (subText.Type === textTypes.WEAK && parsedText[wordIndex - 1].Type === textTypes.BRACKETS) { - line = reverseWord(subText.Word) + line; + line = reverse + line; } + // current word is weak or bracket, last one was rtl else if (parsedText[wordIndex - 1].Type === textTypes.RTL) { line = reverse + line; splicePointer = 0; } + // current word is weak or bracket, there is at least one more word else if (parsedText.length > wordIndex + 1) { + // next word is rtl if (parsedText[wordIndex + 1].Type === textTypes.RTL) { line = reverse + line; splicePointer = 0; @@ -1375,22 +1380,30 @@ define([ splicePointer += subText.Word.length; } } + // current word is weak or bracket, and it the last in this line else { line = spliceWord(line, 0, reverse); } } } + // ltr line, rtl word else if (subText.Type === textTypes.RTL) { - line = spliceWord(line, splicePointer, reverseWord(subText.Word)); + line = spliceWord(line, splicePointer, reverse); } + // ltr line, ltr word else if (subText.Type === textTypes.LTR) { line += subText.Word; splicePointer = line.length; } + // ltr line, weak or bracket word else if (subText.Type === textTypes.WEAK || subText.Type === textTypes.BRACKETS) { + // not first word in line if (wordIndex > 0) { + // last word was rtl if (parsedText[wordIndex - 1].Type === textTypes.RTL) { + // there is at least one more word if (parsedText.length > wordIndex + 1) { + // next word is rtl if (parsedText[wordIndex + 1].Type === textTypes.RTL) { line = spliceWord(line, splicePointer, reverse); } diff --git a/Specs/Scene/LabelCollectionSpec.js b/Specs/Scene/LabelCollectionSpec.js index 9c0df743e2f9..ee6f35e5c726 100644 --- a/Specs/Scene/LabelCollectionSpec.js +++ b/Specs/Scene/LabelCollectionSpec.js @@ -1983,6 +1983,17 @@ defineSuite([ expect(label.text).toEqual(text); expect(label._renderedText).toEqual(expectedText); }); + + it('should reversing correctly non alphabetic characters', function() { + var text = 'A אב: ג\nאב: ג'; + var expectedText = 'A ג :בא\nג :בא'; + var label = labels.add({ + text : text + }); + + expect(label.text).toEqual(text); + expect(label._renderedText).toEqual(expectedText); + }); }); it('computes bounding sphere in 3D', function() { From 737c95e8aab136178263b99fbbf2ee2b2abd78f3 Mon Sep 17 00:00:00 2001 From: hodbauer Date: Thu, 7 Feb 2019 23:37:26 +0200 Subject: [PATCH 2/2] fixed reversing non alphabetic characters on RTL labels updating CHANGES.md --- CHANGES.md | 1 + Source/Scene/Label.js | 21 +++++++++++++++++---- Specs/Scene/LabelCollectionSpec.js | 11 +++++++++++ 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index e68ca412ffce..a6c7746569d7 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -11,6 +11,7 @@ Change Log ##### Fixes :wrench: * Fixed an issue where models would cause a crash on load if some primitives were Draco encoded and others were not. [#7383](https://github.com/AnalyticalGraphicsInc/cesium/issues/7383) +* Fixed an issue where RTL labels not reversing correctly non alphabetic characters [#7501](https://github.com/AnalyticalGraphicsInc/cesium/pull/7501) * Fixed Node.js support for the `Resource` class and any functionality using it internally. * Fixed an issue where some ground polygons crossing the Prime Meridian would have incorrect bounding rectangles. [#7533](https://github.com/AnalyticalGraphicsInc/cesium/pull/7533) * Fixed an issue where polygons on terrain using rhumb lines where being rendered incorrectly. [#7538](https://github.com/AnalyticalGraphicsInc/cesium/pulls/7538) diff --git a/Source/Scene/Label.js b/Source/Scene/Label.js index b2fa4c8a4b69..278e7fcdbecd 100644 --- a/Source/Scene/Label.js +++ b/Source/Scene/Label.js @@ -1340,6 +1340,7 @@ define([ var result = ''; for (var i = 0; i < texts.length; i++) { var text = texts[i]; + // first character of the line is a RTL character, so need to manage different cases var rtlDir = rtlChars.test(text.charAt(0)); var parsedText = convertTextToTypes(text, rtlChars); @@ -1347,10 +1348,10 @@ define([ var line = ''; for (var wordIndex = 0; wordIndex < parsedText.length; ++wordIndex) { var subText = parsedText[wordIndex]; - var reverse = subText.Type === textTypes.BRACKETS ? reverseBrackets(subText.Word) : subText.Word; + var reverse = subText.Type === textTypes.BRACKETS ? reverseBrackets(subText.Word) : reverseWord(subText.Word); if (rtlDir) { if (subText.Type === textTypes.RTL) { - line = reverseWord(subText.Word) + line; + line = reverse + line; splicePointer = 0; } else if (subText.Type === textTypes.LTR) { @@ -1358,14 +1359,18 @@ define([ splicePointer += subText.Word.length; } else if (subText.Type === textTypes.WEAK || subText.Type === textTypes.BRACKETS) { + // current word is weak, last one was bracket if (subText.Type === textTypes.WEAK && parsedText[wordIndex - 1].Type === textTypes.BRACKETS) { - line = reverseWord(subText.Word) + line; + line = reverse + line; } + // current word is weak or bracket, last one was rtl else if (parsedText[wordIndex - 1].Type === textTypes.RTL) { line = reverse + line; splicePointer = 0; } + // current word is weak or bracket, there is at least one more word else if (parsedText.length > wordIndex + 1) { + // next word is rtl if (parsedText[wordIndex + 1].Type === textTypes.RTL) { line = reverse + line; splicePointer = 0; @@ -1375,22 +1380,30 @@ define([ splicePointer += subText.Word.length; } } + // current word is weak or bracket, and it the last in this line else { line = spliceWord(line, 0, reverse); } } } + // ltr line, rtl word else if (subText.Type === textTypes.RTL) { - line = spliceWord(line, splicePointer, reverseWord(subText.Word)); + line = spliceWord(line, splicePointer, reverse); } + // ltr line, ltr word else if (subText.Type === textTypes.LTR) { line += subText.Word; splicePointer = line.length; } + // ltr line, weak or bracket word else if (subText.Type === textTypes.WEAK || subText.Type === textTypes.BRACKETS) { + // not first word in line if (wordIndex > 0) { + // last word was rtl if (parsedText[wordIndex - 1].Type === textTypes.RTL) { + // there is at least one more word if (parsedText.length > wordIndex + 1) { + // next word is rtl if (parsedText[wordIndex + 1].Type === textTypes.RTL) { line = spliceWord(line, splicePointer, reverse); } diff --git a/Specs/Scene/LabelCollectionSpec.js b/Specs/Scene/LabelCollectionSpec.js index 9c0df743e2f9..ee6f35e5c726 100644 --- a/Specs/Scene/LabelCollectionSpec.js +++ b/Specs/Scene/LabelCollectionSpec.js @@ -1983,6 +1983,17 @@ defineSuite([ expect(label.text).toEqual(text); expect(label._renderedText).toEqual(expectedText); }); + + it('should reversing correctly non alphabetic characters', function() { + var text = 'A אב: ג\nאב: ג'; + var expectedText = 'A ג :בא\nג :בא'; + var label = labels.add({ + text : text + }); + + expect(label.text).toEqual(text); + expect(label._renderedText).toEqual(expectedText); + }); }); it('computes bounding sphere in 3D', function() {