-
Notifications
You must be signed in to change notification settings - Fork 3.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Rtl labels support #5771
Rtl labels support #5771
Changes from 13 commits
60da6aa
fc812bc
8762607
64fd8d2
e3c601f
db98c03
5826c7e
775e637
f09b883
70c3ab6
8d18aa3
52dc64f
8350668
a0f0c1a
41cea83
84354e4
c22adcf
f91e96d
281d4d3
c1adde1
6d65918
5f304a8
304e774
f7dfcaa
10b05d2
8878a7b
12fe81d
15a3c9c
9ab1704
04538ba
eb9e155
97c5c36
7245d72
4a69abf
cfb6419
ea5ceeb
c098454
d3df024
7068841
bdb582e
99010f2
ab9ac19
84e5d95
eec1e4d
b3971a9
69a49e8
bcc762c
7a0c0e3
3432f03
df1ddea
80b370b
0020337
abc7b9e
fac9512
11b485e
32c5657
118abe4
e109e98
c2aa9cc
6bca30d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,7 +2,7 @@ Change Log | |
========== | ||
|
||
### 1.37 - 2017-09-01 | ||
|
||
* Added suppport for RTL labels | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Make this a little more descriptive, maybe |
||
* Fixed `replaceState` bug that was causing the `CesiumViewer` demo application to crash in Safari and iOS | ||
* Fixed issue where `Model` and `BillboardCollection` would throw an error if the globe is undefined [#5638](https://github.com/AnalyticalGraphicsInc/cesium/issues/5638) | ||
* Fixed issue where the `Model` glTF cache loses reference to the model's buffer data. [#5720](https://github.com/AnalyticalGraphicsInc/cesium/issues/5720) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -86,6 +86,9 @@ See [CONTRIBUTING.md](CONTRIBUTING.md) for details on how to contribute to Cesiu | |
* [Jason Crow](https://github.com/jason-crow) | ||
* [Flightradar24 AB](https://www.flightradar24.com) | ||
* [Aleksei Kalmykov](https://github.com/kalmykov) | ||
* [webiks](https://www.webiks.com) | ||
* [Hod Bauer](https://github.com/hodbauer) | ||
* [Yonatan Kra](https://github.com/yonatankra) | ||
|
||
## [Individual CLA](Documentation/Contributors/CLAs/individual-cla-agi-v1.0.txt) | ||
* [Victor Berchet](https://github.com/vicb) | ||
|
@@ -152,4 +155,5 @@ See [CONTRIBUTING.md](CONTRIBUTING.md) for details on how to contribute to Cesiu | |
* [Rishabh Shah](https://github.com/rms13) | ||
* [Rudraksha Shah](https://github.com/Rudraksha20) | ||
* [Cody Guldner](https://github.com/burn123) | ||
* [Yonatan Kra](https://github.com/yonatankra) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Did you mean to add yourself to this section as well as the webiks section above? |
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,6 +8,7 @@ define([ | |
'../Core/defineProperties', | ||
'../Core/DeveloperError', | ||
'../Core/DistanceDisplayCondition', | ||
'../Core/freezeObject', | ||
'../Core/NearFarScalar', | ||
'./Billboard', | ||
'./HeightReference', | ||
|
@@ -24,6 +25,7 @@ define([ | |
defineProperties, | ||
DeveloperError, | ||
DistanceDisplayCondition, | ||
freezeObject, | ||
NearFarScalar, | ||
Billboard, | ||
HeightReference, | ||
|
@@ -147,6 +149,9 @@ define([ | |
|
||
this._clusterShow = true; | ||
|
||
this._rtl = defaultValue(options.rtl, false); | ||
this.text = defaultValue(options.text, ''); | ||
|
||
this._updateClamping(); | ||
} | ||
|
||
|
@@ -279,6 +284,15 @@ define([ | |
} | ||
//>>includeEnd('debug'); | ||
|
||
if (this.rtl) { | ||
if (this._originalValue === value) { | ||
value = this._text; | ||
return; | ||
} | ||
this._originalValue = value; | ||
value = this.reverseRtl(value); | ||
} | ||
|
||
if (this._text !== value) { | ||
this._text = value; | ||
rebindAllGlyphs(this); | ||
|
@@ -1030,6 +1044,42 @@ define([ | |
} | ||
} | ||
} | ||
}, | ||
|
||
/** | ||
* Determines whether or not run the reverseRtl algorithm on the text of the label | ||
* @memberof Label.prototype | ||
* @type {Boolean} | ||
* @default false | ||
* | ||
* @example | ||
* // Example 1. | ||
* // Set a label's rtl during init | ||
* var myLabelEntity = viewer.entities.add({ | ||
* id: 'my label', | ||
* text: 'זה טקסט בעברית \n ועכשיו יורדים שורה', | ||
* rtl: true | ||
* }); | ||
* | ||
* @example | ||
* // Example 2. | ||
* var myLabelEntity = viewer.entities.add({ | ||
* id: 'my label', | ||
* text: 'English text' | ||
* }); | ||
* // Set a label's rtl after init | ||
* myLabelEntity.rtl = true; | ||
* myLabelEntity.text = 'טקסט חדש' | ||
*/ | ||
rtl : { | ||
get : function() { | ||
return this._rtl; | ||
}, | ||
set : function(value) { | ||
if (this._rtl !== value) { | ||
this._rtl = value; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think you should call There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thank you @ggetz for your comments. I will fix them after the weekend. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks @hodbauer! If I understand correctly, if
That may be confusing to people using this feature. |
||
} | ||
} | ||
} | ||
}); | ||
|
||
|
@@ -1196,5 +1246,171 @@ define([ | |
return false; | ||
}; | ||
|
||
function declareTypes() { | ||
var TextTypes = { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would just declare this at the top of the file instead of creating it every time. Then just use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @mramato If I understand you, you want me to change the code to something like: var TextTypes = freezeObject({
LTR : 0,
RTL : 1,
WEAK : 2,
BRACKETS : 3
});
return TextTypes; and put it inside the define near to the glyph functions as is (without a function scope)? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, though you won't need the |
||
LTR : 0, | ||
RTL : 1, | ||
WEAK : 2, | ||
BRACKETS : 3 | ||
}; | ||
return freezeObject(TextTypes); | ||
} | ||
|
||
function convertTextToTypes(text, rtlDir, rtlChars) { | ||
var ltrChars = /[a-zA-Z0-9]/; | ||
var bracketsChars = /[()[\]{}<>]/; | ||
var parsedText = []; | ||
var word = ''; | ||
var types = declareTypes(); | ||
var lastType = rtlDir ? types.RTL : types.LTR; | ||
var currentType = ''; | ||
var textLength = text.length; | ||
for (var textIndex = 0; textIndex < textLength; ++textIndex) { | ||
var character = text.charAt(textIndex); | ||
if (rtlChars.test(character)) { | ||
currentType = types.RTL; | ||
} | ||
else if (ltrChars.test(character)) { | ||
currentType = types.LTR; | ||
} | ||
else if (bracketsChars.test(character)) { | ||
currentType = types.BRACKETS; | ||
} | ||
else { | ||
currentType = types.WEAK; | ||
} | ||
|
||
if (lastType === currentType && currentType !== types.BRACKETS) { | ||
word += character; | ||
} | ||
else { | ||
parsedText.push({Type : lastType, Word : word}); | ||
lastType = currentType; | ||
word = character; | ||
} | ||
} | ||
parsedText.push({Type : currentType, Word : word}); | ||
return parsedText; | ||
} | ||
|
||
function reverseWord(word) { | ||
return word.split('').reverse().join(''); | ||
} | ||
|
||
function spliceWord(result, pointer, word) { | ||
return result.slice(0, pointer) + word + result.slice(pointer); | ||
} | ||
|
||
function reverseBrackets(bracket) { | ||
switch(bracket) { | ||
case '(': | ||
return ')'; | ||
case ')': | ||
return '('; | ||
case '[': | ||
return ']'; | ||
case ']': | ||
return '['; | ||
case '{': | ||
return '}'; | ||
case '}': | ||
return '{'; | ||
case '<': | ||
return '>'; | ||
case '>': | ||
return '<'; | ||
} | ||
} | ||
|
||
/** | ||
* | ||
* @param {String} text the text to parse and reorder | ||
* @returns {String} the text as rtl direction | ||
*/ | ||
Label.prototype.reverseRtl = function(value) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This function should be private, I don't think anyone should be calling this directly. |
||
var rtlChars = /[א-ת]/; | ||
var texts = value.split('\n'); | ||
var result = ''; | ||
for (var i = 0; i < texts.length; i++) { | ||
var text = texts[i]; | ||
var rtlDir = rtlChars.test(text.charAt(0)); | ||
var parsedText = convertTextToTypes(text, rtlDir, rtlChars); | ||
|
||
var types = declareTypes(); | ||
|
||
var splicePointer = 0; | ||
for(var wordIndex = 0; wordIndex < parsedText.length; ++wordIndex) { | ||
var subText = parsedText[wordIndex]; | ||
var reverse = subText.Type === types.BRACKETS ? reverseBrackets(subText.Word) : subText.Word; | ||
if(rtlDir) { | ||
if (subText.Type === types.RTL) { | ||
result = reverseWord(subText.Word) + result; | ||
splicePointer = 0; | ||
} | ||
else if (subText.Type === types.LTR) { | ||
result = spliceWord(result,splicePointer, subText.Word); | ||
splicePointer += subText.Word.length; | ||
} | ||
else if (subText.Type === types.WEAK || subText.Type ===types.BRACKETS) { | ||
if (parsedText[wordIndex -1].Type === types.RTL) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add a space after the operator here and throughout. |
||
result = reverse + result; | ||
splicePointer = 0; | ||
} | ||
else if (parsedText.length > wordIndex +1) { | ||
if (parsedText[wordIndex +1].Type === types.RTL) { | ||
result = reverse + result; | ||
splicePointer = 0; | ||
} | ||
else { | ||
result = spliceWord(result,splicePointer, subText.Word); | ||
splicePointer += subText.Word.length; | ||
} | ||
} | ||
else { | ||
result = spliceWord(result,splicePointer, subText.Word); | ||
} | ||
} | ||
} | ||
else if (subText.Type === types.RTL) { | ||
result = spliceWord(result, splicePointer, reverseWord(subText.Word)); | ||
} | ||
else if (subText.Type === types.LTR) { | ||
result += subText.Word; | ||
splicePointer = result.length; | ||
} | ||
else if (subText.Type === types.WEAK || subText.Type ===types.BRACKETS) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. spacing after There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. and on line 1354 |
||
if (wordIndex > 0) { | ||
if (parsedText[wordIndex -1].Type === types.RTL) { | ||
if (parsedText.length > wordIndex +1) { | ||
if (parsedText[wordIndex +1].Type === types.LTR) { | ||
result += subText.Word; | ||
splicePointer = result.length; | ||
} | ||
else if (parsedText[wordIndex +1].Type === types.RTL) { | ||
result = spliceWord(result, splicePointer, reverse); | ||
} | ||
} | ||
else { | ||
result += subText.Word; | ||
} | ||
} | ||
else { | ||
result += subText.Word; | ||
splicePointer = result.length; | ||
} | ||
} | ||
else { | ||
result += subText.Word; | ||
splicePointer = result.length; | ||
} | ||
} | ||
} | ||
if (i < texts.length - 1) { | ||
result += '\n'; | ||
} | ||
} | ||
return result; | ||
}; | ||
|
||
return Label; | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you be more descriptive for the button label? Maybe
Set label with right-to-left language