Posted 10 years ago by Matt Gerrans
Version: 14.2.0610
Avatar

When I set the FlowDirection of an ordinary TextBox to RightToLeft, the text stays the same, but becomes right-aligned.    When I do this with the SyntaxEditor, it right-aligns, but also draws the text backward (mirrored).    Is there another property I need to set to get the right-to-left to work without that mirroring effect?

[Modified 10 years ago]

Comments (36)

Posted 9 years ago by Matt Gerrans
Avatar

Just pinging on this one again for Monday morning.

Posted 9 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hi Matt,

I don't believe that SyntaxEditor should allow RTL.  We have it set to not inherit down the FlowDirection setting from parent elements and always do LeftToRight.  This is because it's a code editor and things wouldn't format correctly with indenting, etc. if RTL was used.  Perhaps you are setting FlowDirection directly on the SyntaxEditor control here?  If so, you shouldn't do that.  I believe when we've looked at Visual Studio in a RTL system, it also kept the code editor portion LeftToRight.


Actipro Software Support

Posted 9 years ago by Matt Gerrans
Avatar

Ah, okay, I guess that make sense.   Since our implemtation only shows a single line of code (in a grid) at a time, I kind of forgot about the whole idea of a code editor with formatting including indentation.

Posted 9 years ago by Matt Gerrans
Avatar

Even with the without changing flow direction it seems like the cursor should go to the left of the last character typed, when entering arabic text, but instead it goes to the right.    The text appears in the correct location (at the left) when typing, but it is a bit disconcerting that the cursor is not where the next character will appear as you type.   Is there some way to control this?

Also, I get strange behavior when typing parentheses (and other braces/brackets) depending on whether I'm at the end of a line (of Arabic text) or in the middle of some Arabic text.   Within the text, it works as expected, but on the edges, it behaves strangely.   I'll try adding the invisble RTL Unicode marker to see if I can fix that, but I wanted to also ask you if there is some special case code in the SyntaxEditor that's causing this inconsistency, because Word does not behave the same way.   I suspect this is related to the cursor behavior, because Word will snap the cursor to where the ")" character appeared (at the left of the existing text), whereas SyntaxEditor will instead enter a "(" at the right of the existing text (even though it was the ")" key that was hit).

Posted 9 years ago by Matt Gerrans
Avatar

Additional observation:


It seems like the editor treats the end of the line scenario as if there is an imaginary left-oriented chacter there (maybe there really is, if it is looking at the newline character and considers it LTR).   If you position the cursor in the middle of some RTL text and start typing, it does correctly move to the left as you type.

Interestingly, it looks like Word's behavior is not quite right, either.   When you are at the right of the text (ie. in position to insert the next character you type as the first letter of the line) and you type a character, word sends you (moves the caret) to the left (the end of the line) and puts the character there.   It seems like it should put that character where the caret was (ie. insert before the first word).

The SyntaxEditor has similar bevior, in that starting from the same position, it will put character you type (or its mate if it is a parentheses/brace/bracket), at the left (being the end of the text instead of the beginning), but it differs in that the caret will remain at the right of the text.   Ideally it would not swap delimiter pairs in this case, at least.

Posted 9 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hi Matt,

For questions with bi-directional editing behavior, it would be helpful if you could give specific examples describing what you are typing where and what the expected result is.  We have a "Globallization" QuickStart that has Arabic text in it so that would be a good place to base any scenarios on.  Such as starting with that sample, and typing a '(' paren character at a certain ln/ch (as seen in the statusbar), and what you would expect to see.  Thanks.


Actipro Software Support

Posted 9 years ago by Matt Gerrans
Avatar

Okay, finally got back to this.    Here is a specific scenario (I can attach a demo project, but it doesn't take anything special, just any form with the Syntax Editor on it; it also can be done in the Globalization QuickStart):

In the SyntaxEditor, type in foo and leaving the caret where it is, switch the input to Arabic (AR), then type some more letters.   What's expected is that the cursor remains to the right of the text foo while Arabic characters appear to the right of the caret.

What actually happens is that the cursor moves (or stays) to the right of the Arabic characters that appear.

If you click somewhere in the existing Arabic text and type there, it will work as expected; the caret moves to the left of the new character that's been typed.

For comparision, try the same thing in Word: start a new document, with EN input, type foo and then switch to AR input and type some more; the caret will stay just to the right of the second "o" between the Enlish and Arabic text as you type, which is what we'd exepect.

By the way, the reason this is even more unmistakeable with parentheses and braces as discussed above is because they take on the LTR/RTL characteristics the text they are near.   It seems like maybe the SyntaxEditor is looking at the \r at the end of the line and maybe assuming LTR behavior because of it or something like that.   So, you'll notice, if you are in AR mode and in the middle of some Arabic text when you type ) and then some text and then (, the Arabic text you typed will be in between the parentheses, which is what we'd like.   However, if the caret is at the end of the line (of Arabic text) and you do *exactly* the same thing, you get different results: When you type the ), a ( will appear at the end (far left of the line, while the caret is still at the far right), then your text, then when you type the ( you get another ( at the right of the text you just typed.   Kind of confusing to follow, but if you try this out in both the SyntaxEditor and Word, doing exactly the same things, you'll see the problem.

Thanks!

[Modified 9 years ago]

Posted 9 years ago by Matt Gerrans
Avatar

Here is another simple experiment to do in both the SyntaxEditor and in Word (and/or WordPad):

Type in two English words, separated by two spaces, with the caret between those spaces, then do the Right-Alt-Shift keystroke to change to Arabic and type in the right parentheses some Arabic letters and then the left parentheses.    Compare how it works (and results) in Word to the SyntaxEditor.

Posted 9 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hi Matt,

We did a lot of work on this today and were able to improve things.  Basically we keep the logic mostly as-is for caret location determination since it's already mostly right.  However if the caret is between two characters that are of differing flow directions, that's where the need for improvement was.

In this scenario, instead of rendering the caret over the bounds of the next character, we use the bounds of the previous character but flip the flow direction on it for caret location-determining purposes.  It's a bit complex but the net result is that it works pretty much like caret movement in VS does now.  This update will be in the next maintenance release.


Actipro Software Support

Posted 9 years ago by Matt Gerrans
Avatar

Awesome!   Thank you!

Yes, I know it is complex; I've been fooling around with trying to make a work from the outside; tracing all the text/typing/key events and looking at where the caret is to try and iron it out.   There are legitimate gray areas where the caret is between text with different orientations (even worse when one of the characters is of an "ambiguous" nature that takes on the orientation of its neighbor, as is the case for most delimiters) which makes it kind of mind bending.

When would the next maintenance release be?    Is there any way I could get an advance beta test of it, to try it out in our bidirectional scenario?    Since we have people working with the real bidirectional scenario (Arabic for most text + English for our DSL elements), you would get very real-world feedback.

Thanks,

- Matt

Posted 9 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hi Matt,

The maintenance release should be in the next several weeks but if you would like a preview build to test with, please write our support address and we'll hook you up.


Actipro Software Support

Posted 9 years ago by Matt Gerrans
Avatar

Great, will do.  Thanks!

Posted 9 years ago by Matt Gerrans
Avatar

Thanks for the preview; it looks like bidirectional editing is working better now.

Here is one case you may want to look at: When you have a completely empty control and you type in an Arabic character, it looks like it doesn't quite work right on that first character, but does for subsequent characters.   After typing the first character, the caret is to the right of the character that appears.    Now, the second chracter typed will appear to the right (instead of the left, where it should be) of that first chracter; After typing the second character, it begins to work correctly (the caret will be tween them and so the third will come out correct, to the left of the second, with the caret to the left of the third character).

Posted 9 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hi Matt,

Odd, I just tried typing Arabic in a blank document and didn't see that happening.  The caret properly stayed to the left of the first character typed.  I'm pretty sure the preview build we gave you had the latest code.  Which specific character on the English keyboard are you typing into a blank document while an Arabic keyboard is active to see this happen?  I'm testing in our SDI Editor.


Actipro Software Support

Posted 9 years ago by Matt Gerrans
Avatar

Ah ha, sorry about that; I should have tried it in the sample app first.    Turns out I had a remnant of my attempted work-arounds in there still.   After removing that, it to works as expected.

The only thing that is slightly strange is that as you are typing in Arabic, the caret will jump to the right of the Arabic text after typing a space, if you continue to type in Arabic, the caret will jump back to the left and the words will appear correctly.    This is a little bit odd, but doesn't affect the output.   You can see this if you type an Arabic word into the empty control, then hit space.  I tried this on the sample app as well.

Posted 9 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar

From that I can tell, VS behaves the same way if the space is near the end of a document or by other non-RTL text.  If you are instead in the middle of a run of RTL text (like in a string token), pressing space keeps it where it is since that's a neutral character.


Actipro Software Support

Posted 9 years ago by Matt Gerrans
Avatar

I'm not sure VS is the best reference here, since it is pretty quirky and doesn't seem to support bidirectional text all that well.   In VS, if you type three Arabic words in a row, they will come out in the wrong order.   The Actirpro SyntaxEditor is already doing better in this case, since the words will come out in the right order.

VS apparently assumes English/LTR programming with the occasional RTL string in quotes and maybe some RTL in comments.  What I'm struggling with now is that we want to have mostly Arabic text with some English keywords inserted, so as you are typing right-to-left, the result of an autocomplete should put the keyword to the left of the text you are typing and likewise the caret should go to the left of that.

For example, the text "شسيب {Restaurant} شسيب (بي) ه" could all be typed right-to-left.  After typing the ه when you hit the } you should get an auto-complete dropdown, where you choose {Restaurant} and it should insert to the left and put your caret to the left, so when you continue typing شسيب it comes out at the left (that being the last word of the phrase).

Right now, what's happening is that when the {Restaurant} is inserted by the auto complete session, it goes to the right of the text instead and the caret goes to the right of it, so the next Arabic word you type comes out on the right also and things are all mixed up.   I will try to fix this case myself, but if you have any suggestions on the best approach for this, let me know.

Similarly DelimiterAutoCompleter is not working quite right.    When the CurrentInputLanguage is RTL and I type a ")" at the end of the line, it does correctly do the auto-completion and "()" appears (eg. in an empty control type "ش" (the a-key when in Arabic input mode) then type ")").   However, it appears to the right of the existing text.    Since it is correctly identifying the ")" as the opening delimiter, it seems to know that we're doing RTL, so ideally, it would put the "()" to the left and the caret between.

Additionally, it seems like DelimiterAutoCompleter stops working when the caret is inside Arabic text (instead of at the end of the line).   Eg. Type in "شلا" ("a" key, then "b" key with Arabic input), then the left arrow, to move the cursor betwen them, then type the ")" and you won't get the autocompletion at all.   This occurs inside Arabic text or in the spaces between words.

Posted 9 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hi Matt,

The way a lot of our logic works for IntelliPrompt and other features is that it's scanning the logical order of characters in the core text stream, and most of the time doesn't know whether text is LTR or RTL.  The visual layout (which comes from core WPF text rendering classes) and caret/selection movement code are really the only areas that are aware of the flow direction since we rely on the info from the visual layout for the latter.

For your first scenario with Restaurant, and knowing how the WPF text rendering engine works related to logical character order, I can understand why it's behaving as you describe.  Unfortunately I'm not sure how to get it to behave differently.

For the "ش()" scenario, that is out of our control since the core WPF text rendering engine is moving the parens to the right.

For the last scenario, that is just the logic of how the delimiter auto completion works.  The same thing happens in English text too.


Actipro Software Support

Posted 9 years ago by Matt Gerrans
Avatar

Hi again, I have been continuing to work on this and have managed to resolve most of the thorny issues by coding around them.    One thing that I'm not able to fix, however, is the way delimiters behave at the end of a run of RTL text.   With delimiter auto completion on, if you type an Arabic charaacter, then the delimiter, you'll get the pair of delimiters on the right, instead of the left.   Note, that the auto-completion is triggered on the correct delimiter (ie. the one that is opening for RTL, but would be closing for LTR).   Really what we would expect (and what I've implemented with my own handling of auto-completion for some other things) is for the pair of parentheses (or whatever delimiters) to appear to the right, with the caret between them.   So whats happening is that the parentheses are behaving like LTR text, even though they are next to RTL text.    If you type an RTL character inside them, they flip out.   If you type an RTL character to the right of them, they begin to behave correctly.    See this picture, where the same text from the Syntax Editor is also displayed in the ordinary TextBox below it and the indvidual characters are displayed above (let me know if you can't see this image).

https://onedrive.live.com/redir?resid=6C454525A71229A4!17708&authkey=!ALgcZh6wIOS9vmI&v=3&ithint=photo%2cpng

I tried to fix this by using the Unicode right-to-left marker to remove any ambiguity and indicate the orientation of the delimiters, but the Syntax Editor doesn't seem to pick up those propery:

https://onedrive.live.com/redir?resid=6C454525A71229A4!17707&authkey=!ALft7rHbkQ07DQI&v=3&ithint=photo%2cjpg

Note that adding the RTL markers for the ordinary TextBox does cause it to display the text correctly.   I think the RTL marker should have the same effect as having an ordinary RTL character.

Posted 9 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hi Matt,

I tried typing "a(a)" with the Arabic keyboard on and see it working better in Notepad.  That being said, I then tried doing the same in VS and it didn't seem to render the same there.  It looked more like SyntaxEditor did.  Then I tried making a WPF FormattedText object with the same text and it rendered as it does in VS.  Unfortunately we're at the mercy of however the Microsoft .NET text rendering procedures work here.  I would suggest you try using FormattedText and render it in a control's OnRender override to see what results you get.  That should match whatever you see in SyntaxEditor.  Let us know if you see it rendering correctly with that.  SyntaxEditor doesn't use FormattedText but rather uses the more advanced WPF text formatting API (in the System.Windows.Media.TextFormatting namespace).  That being said, I believe FormattedText ends up using the same core logic for handling bi-di.


Actipro Software Support

Posted 9 years ago by Matt Gerrans
Avatar

Hi again,

I probably wasn't explicit enough in the previous message, but one important thing to note in the two different pictures in that message is that in the second one, where I have added the Unicode RightToLeft markers (0x8207 codepoint) around the delimiters, they show up correctly in the ordinary TextBox control (exact same sequence of characters), but not in the SyntaxEditor (until you add a non-invisible RTL character, of course).    They both behave the same when there are no RTL markers added (as in the first picture, upper right).

It is also worth noting that Visual Studio's behavior is different in comments than it is in code.   In the comments, the same text (with the markers) will behave as it does in the TextBox and display correctly.    In the code (which has the stronger tendency to left-to-right orientation) it seems to assume that the parentheses are explicitly left-to-right tokens, which makes sense, since they are C# (in the case I tried) syntax elements.

I'm wondering if the SyntaxEditor is doing something similar?   I think since the default behavior of a TextBox with the markers there is to behave as if they are RTL characters, I'm wondering if the SyntaxEditor has special case code that's looking at them but not recognizing them as RTL and therefore assuming they are LTR.   If it were just honoring these hidden characters, that would solve this particular problem.

I don't have the "blueprint" package, but I am motivated to have the SyntaxEditor work nicely with bidirectional text (even if it that means better than VS does), so I would be willing to make the necessary improvements and submit them to you for review and use, if you like.

Posted 9 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hi Matt,

I'm not sure but per our last reply, you should make a custom control and override its OnRender method and see if you can draw a FormattedText with the text string the way you want.  We use the more advanced System.Windows.Media.TextFormatting namespace classes to render text, but I think FormattedText ends up using the same core logic.  Since we rely on all that to be done properly and it's a black box to us, we'd need to get a working example there first before anything else could be done.

I don't believe we do anything special with bi-di when calling the text rendering.  We just pass a stream of text into the text renderer and it tells us how it should be laid out.


Actipro Software Support

Posted 9 years ago by Matt Gerrans
Avatar

Hi again,

So I looked at overriding OnRender(), but that is a draconian approach; it would mean losing all the features that we're getting from the SyntaxEditor and doing them "manually," which kind of defeats the purpose of using the SyntaxEditor.   It also looks like it would lead to a lot of other problems, by trying to hack it from the outside.

Now, what I was pointing out in the posts above is that the Unicode Right-to-left marker character is intended specifically to solve a problem like this.    When placing that character around the parentheses, a TextBox will display it correctly, Notepad will display it correctly and so will the Visual Studio editor.    The SyntaxEditor won't however.   I suspect this is because the SyntaxEditor is ignoring the RTL marker, or maybe assuming it is itself a LeftToRight character because it is not specifically a character in the Right-to-left set of characters (instead of being a special character).

I think if the SyntaxEditor could just honor this character, it would solve this problem for me and anyone else doing real bidirectional support.    It would make it work the same way that other editors do when the RTL marker is present.   That's why I was suggesting fixing the SyntaxEditor code, rather than trying to override its rendering behavior.    Based on the fact that the default for these other editors is to work correctly when the RTL marker is there, I'm guessing it might be a trivial fix in the SyntaxEditor code.

Posted 9 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hi Matt,

Sorry, I think you misunderstood our previous reply.  We are utilizing the core WPF text rendering procedures (written by Microsoft, not us) to handle display of bi-di text.  We don't really do anything special for the display of it.  We were suggesting the OnRender test so that you can see if you can get it to display your bi-di scenario correctly in a custom control.  This is not intended to be a workaround or fix for the problem.  We're just seeing if you can help narrow down why it's not working in core WPF text rendering procedures in general, as that info may help eventually solve the problem.


Actipro Software Support

Posted 9 years ago by Matt Gerrans
Avatar

Ah ha.   The screenshots I sent you actually already have a display of the exact same text in another control.  The SyntaxEditor is above and the same text is being echoed in the control below it.   As I said, if the RTL markers are not present, then both the SyntaxEditor and the other control display text the same way.   However, if the RTL characters are added, the SyntaxEditor continues to display the same way, but the other control displays the text as intended.    That's why I'm thinking that the SyntaxEditor may be doing something slightly different (eg. perhaps stripping out the non-display characters before rendering, or something like that).

Posted 9 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar
Hi Matt,

If you did the custom control rendering per what we described in a previous post and that is what you are displaying in your screenshot, then please show us the source code of the OnRender method you used for that custom control. Again, we need to see a custom WPF Control that does the text rendering in OnRender so that we can compare. Thanks!


Actipro Software Support

Posted 9 years ago by Matt Gerrans
Avatar

Okay, I'm experimenting with the FormattedText, but that is a pretty non-trivial task.   The MSDN fwlink to their full sample is broken, so I'm kind of flying blind with some of their incomplete snippets from individual class and method docs.   Let me know if you have any other good pointers to documentation and/or samples of it.

From what I can see of how GetTextRun() is handled, I'm guessing that maybe the SyntaxEditor's handling isn't noticing the RTL character and returning TextCharacters of the right kind for it.   In other words if the current character is 0x8207, it should return the same kind of TextCharacter object it returns if the character is Arabic (or other real RTL character).

Please point me to whatever documentation sources you all may have used to develop your implementation.    If I could have a look at your custom TextSource and whatever custom TextRunProperties and custome TextParagraphProperties it is returning from GetTextRun() that would help too.

Thanks,

[Modified 9 years ago]

Posted 9 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hi Matt,

In WPF, there are two ways to custom render text using Microsoft's API.

1) The easiest way is to use FormattedText, which you can do simply by making a custom blank control and have something like this:

protected override void OnRender(DrawingContext drawingContext) {
	drawingContext.DrawRectangle(Brushes.White, null, new Rect(0, 0, this.ActualWidth, this.ActualHeight));
	var ft = new FormattedText("Abc", System.Globalization.CultureInfo.CurrentCulture, System.Windows.FlowDirection.LeftToRight,
		new Typeface(this.FontFamily.Source), 14, Brushes.Black);
	drawingContext.DrawText(ft, new Point(10, 10));
}

I'd be interested in seeing if you can get the scenario rendering correctly with just code like above.

2) The second way, and far more complicated, is to use their text formatting namespace and all of its classes (TextSource, etc.).  That requires extensive setup and configuration, which we did years ago, so I'm not sure what documentation is out there on it at this time.  That being said, I believe that FormattedText (way #1 above) ends up calling a lot of the same stuff that appears in this second way but it wraps it all up for you.  So either way should theoretically produce similar results.


Actipro Software Support

Posted 9 years ago by Matt Gerrans
Avatar

Okay, with some simple code like the above, it does render correctly when the Unicode Right-to-Left markers are in the text.

This is exactly what my code looks like (in a simple class that overrides TextBox):

protected override void OnRender(DrawingContext drawingContext)
{
    const string text = "ش‏(ب)‏";
    var characters = text.ToCharArray(); // For debugging inspection.
    var typeface = new Typeface(FontFamily.Source);
    var culture = System.Globalization.CultureInfo.CurrentCulture;
    const FlowDirection direction = System.Windows.FlowDirection.LeftToRight;
    var ft = new FormattedText(text, culture, direction, typeface, FontSize, Brushes.Blue);
    drawingContext.DrawText(ft, new Point(5, 5));
}

 Note that the array characters has six characters in it:

- characters	{char[6]}	char[]
		[0]	1588 'ش'	char
		[1]	8207 '‏'	char
		[2]	40 '('	char
		[3]	1576 'ب'	char
		[4]	41 ')'	char
		[5]	8207 '‏'	char

 The string even looks correct in Visual Studio, but this same string in the SyntaxEditor) shows the first Arabic character, then a close-paren, then the second Arabic character and another close-paren.

By the way, I just discovered something very interesting that may contribute to the solution to this problem: When typing in this text, it doesn't display correctly, but when it is copy/pasted in it does display correctly.    I am adding the Right-to-Left marker character in the Text property override (in its setter).    Perhaps the problem is that there is some sequence problem, so that the text is actually rendered before the RTL markers are added.

Posted 9 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hi Matt,

To confirm, if you copy/paste the text you have above into a SyntaxEditor instance or if you set that string in code-behind to the SyntaxEditor as its document text, it will render correctly as you expect.

But if you try typing in the same character sequence while editing in a SyntaxEditor, something doesn't take correctly (possibly due to characters being out of order) and the result is that you get two close parens.

Is that an accurate summary of the problem?  What exact key sequence do I type on an English keyboard to properly enter that character sequence?  I'd like to try it in VS and compare to what is happening in SE.


Actipro Software Support

Posted 9 years ago by Matt Gerrans
Avatar

Yea, that's correct.    It doesn't work in VS, because VS will not be inserting those RTL markers.    I'm guessing I can get it to work correctly in the SyntaxEditor if I can just get the order of operations right; that is, SE is working correctly when the text is pasted, so it might be that it has done the rendering before I've added in the RTL marker during typing (and therefore has not seen the RTL marker there at the time of rendering).   I'll experiment with invalidating and whatnot to see if that will help.

Posted 9 years ago by Matt Gerrans
Avatar

Maybe I am adding the bidirectional marker characters in the wrong place/way.    What is the recommended way to add to incoming characters?    In other words, when the user has typed in some Arabic text and then some delimiter like a parenthesis, I want to also add in the Right-to-Left marker character.    What would be the recommended way of doing this?    Should I do this with a custom auto-completer?

Posted 9 years ago by Matt Gerrans
Avatar

Just an update: I just tried ActiveView.InsertSurroundingText() in the OnDocumentTextChanged() when the conditions are right (we're in RTL scenario and a parenthesis is the TypedText) and that seems to be working pretty well.   While this works, let me know if this is something better done with an auto-completer or a custom edit action.

Posted 9 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hi Matt,

Could you give some more detailed information on the scenario you are trying to programmatically achieve?  Such as describe the exact keystrokes the user would be doing in this scenario and what you want to happen behind the scenes.  Thanks!


Actipro Software Support

Posted 9 years ago by Matt Gerrans
Avatar

Hi,

Here is what I'm trying achieve:

As you know, some characters are RTL and some are LTR, but some are "weak" and take on the directionality of their neighbors.   This includes delimiters and punctuation among other things.   When the user is typing (only in an RTL language, like Arabic, of course) and any of the set of characters that have "weak" directionality are typed, I want to put a Unicode marker characters (either LTR 0x8206 or RTL 0x8206) either before or after that character to give it a strong orientation.

Since we really have bidirectional text, we want some "weak" characters to behave as RTL and others to behave as LTR.    For example we have keywords inside curly braces that will always be English, while the rest of the text, including text inside parentheses or square brackets will all be Arabic.   So to keep things displaying propery (especially at the end-of-line scenario), I want to put RTL markers near the parenthesis and square brackets and put LTR markers near the curly braces.    An example might look like this:

ش (ب|غ) شىي {restaurant} سي

In this case, we'd want the RTL marker before the "(" and after the ")" and the LTR marker before the "{" and after the "}".    We could also have those keywods inside the parentheses by the way, as one of the choices separated by the pipe.

These "weak" characters really behave badly when they have some Arabic text on one side and English text on the other, so it is necessary to tell them what their allegiance is.   Given our language scheme, we know which weak characters should behave as RTL and which should behave as LTR and the markers provide that buffer from the nearby text that is oriented differently.

I think this could be achieved while the user types, but probably also needs to be re-done on the current state of the text to deal proprly with deletes/replacements/pastes, etc.   Given that, perhaps it is better not to do it on the fly, but instead fix up the text after changes?    If so, what would be the best place and/or recommended method to do that?

Additionally, I need to properly handle left-right arrow navigation, so that we don't have to hit the key twice to get past the invisible marker character.   Adjusting the Caret location in OnKeyUp for Key.Right and Key.Left may be sufficient to handle this.

FYI, the English keywords mentioned above are already implmented with an auto-completer, so that when you type the initial curly, you get the dropdown and choose one to use.   So you really don't need to switch the keyboard back to EN in order to get mixed bidirectional text.   However, when this auto-completion occurs, ideally what I'd get inserted into the text would be surrounded by the LTR markers, so instead of "{navigate}" it would be "\x8206{navigate}\x8206".

Posted 9 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hi Matt,

Thank you for the explanation.  We've looked into this some more but the results aren't good for what you are trying to do.

The problem with inserting these markers in the midst of user edits is that any programmatic document text updates you make will become their own undo transaction.  This means that any time the user does Ctrl+Z after one of these, they will see nothing change since the invisible markers would only have been altered.  They would have to undo a second time to get to the undo transaction they really wanted.  There isn't a way for you to insert/remove markers that would work around that issue since all programmatic text updates enter the undo/redo history to maintain proper text change continuity.

Also, handling left/right and delete/backspace navigation is actually a fairly complex thing in certain scenarios and isn't something that you can really properly do on your own.  That's pretty low-level and there isn't a way to customize that either.

The items you show in your completion list can certainly insert text other than what is displayed in the completion list itself (via the pre- and post-text properties on the completion item).  That piece of what you wanted to do would be ok.

But for the auto-marker updates on user editing, I'm not thinking that will be possible.  Perhaps you could make ti easier for the user to inject the markers themselves by providing toolbar buttons or hotkeys or some other method of accessing them?


Actipro Software Support

The latest build of this product (v24.1.1) was released 2 months ago, which was after the last post in this thread.

Add Comment

Please log in to a validated account to post comments.