Hello Neil,
I have added a function “FillR2LPositions” to calculate the real positions of R2L characters, and the virtual positions which we see on screen.
It’s tested only with characters
inside “”, supposing there is only 1 segment of quotes “”, and only one line.
The positions are calculated fine, but when I try it
in FindText , supposing the search is done for complete word :
long Document::FindText(int minPos, int maxPos, const char *search,
int flags, int *length)
, although the position is returned correctly the selection is not, the selection is always shifted right.
So if I type:
Hi “السلام عليكم و رحمة الله و بركاته”
And then search for “عليكم”, I get the selection like this:
Hi “السلام عليكم و رحمة الله و بركاته”
Sorry I have disabled most of the events handles in WndProc , just to be able to handle the essential events .
The initialization is done in Initialize(HWND parentHwnd, const wchar_t* text) function , which is called after LoadD2D() , under SCI_SETTECHNOLOGY event.
Also I disabled WndPaint(uptr_t wParam) , and used OnDraw , instead of adding modifications inside Paint.
The main players here are :
The code mainly dependable on text_ , and the layout is rendered with the whole text each time of Draw .
I think handling R2L text with wstring as one block is easier and more accurate than going though all the characters one by one , specially in R2L , the loops will increase if we check the whole paragraph each time a new character is added .
Unfortunately, I still don't understand the lexers and the styling process , so I couldn't add the styles , I just used vs.styles[STYLE_DEFAULT] in text format. Would you please explain the styling process , I may can try it , if you accept the new approach.
Using wstring will need changes to be done in GUI , so the messages sent to Scintilla will be in the same type. For example , for find and replace , the event lParam finding a string should be in wstring too.
Thanks
Raghda
This code is working better on simple cases - its cool seeing the forward arrow moving to the left in right-to-left text.
> Now these functions are returning objects and using Font in inputs :
> • int PositionFromPoint(Point pt, const char *s, int len, int width, Font & font_);
> • Point XYFromPosition(const char *s, int len, int width , int caretPosition , int offset, Font & font_);
> • PRectangle CaretRectangle(const char *s, int len, int width, int caretPosition, int offset , int caretWidth, Font & font_);
These are using a caret position in wchar_t and so UTF16Length must be called first. Since not all platforms are UTF-16, the ‘caretPosition’ argument should be in bytes for each method with UTF16Length called inside the SurfaceD2D platform-layer code.
The CaretRectangle method doesn’t seem to be doing anything more than XYFromPosition: it sets the height but we already know the line height to use for the caret height. Unless you have a plan to report more information from CaretRectangle then it isn’t needed. Avoiding code is a goodness.
> The fonts used are taken from the style of a specific position in the needed line , until now this seems working fine , even with styled text , but I don't know how will it behave if we have at the same line some very big characters with other small ones.
Having different fonts, sizes and weights are important features of Scintilla. The BreakFinder::Next changes try to avoid breaking right-to-left text and then depending on the Surface methods to make it work together but I think that is not going to work for different text styles as only one Font is passed to each Surface call. It may be better to treat each direction switch as a break.
The current code works with simple text with few changes in direction or styles but it behaves less well as the text becomes more complex. I’ve been using this “Arabic.cxx" file to try with normal SciTE C++ styles where operators are bold and a different font is used for identifiers/numbers and strings. I don’t know which type of text Uniface are interested in - maybe its for documentation or only for a single text style but if its for source code with multiple styles (like bold for operators), its examples like the following that should be made to work well.
XYFromPosition and PositionFromPoint are calling a newly added function to fill the textLayout styles for each char :
void SurfaceD2D::FillTextLayoutFormats(const char ** styleFontsNames, int * styleSizes, int * styleWeight, IDWriteTextLayout * textLayout, wchar_t *buffer , int tLen)
But it's still not accurate, because the text size is not correct.
At FillTextLayoutFormats , textLayout->SetFontSize(styleSizes[stylesInLine] / 71, textRange);
styleSizes[stylesInLine] which is taking the value of vstyle.styles[ll->styles[stylesInLine]].size is too big , and when dividing it by 75-70 the behavior improves , but the value to divide by is not the same for all the styles .
So where can I find the correct size ? or the correct ratio to divide by?
Thanks
Raghda
Thanks
Raghda
Here are the new files , after fixing the bugs mentioned above :
https://drive.google.com/drive/folders/0B1_ta5eAkhnIYmdiR3dJQU1zR3c?usp=sharing
For calculating the tab width in Scintilla I used the position of the tab in line , positions_[positionsInLine + 1] - positions_[positionsInLine];
Also a new method is added , to calculate tab width in textLayout :
XYPOSITION SurfaceD2D::WCharWidth(FontID fontID_, wchar_t wch)
It's almost the same as XYPOSITION SurfaceD2D::WidthChar(Font &font_, char ch) , but using FonID instead of Font and returning textMetrics.width instead of textMetrics.widthIncludingTrailingWhitespace
What else do you think is missing or needs to be added ?
https://drive.google.com/drive/folders/0B1_ta5eAkhnISHBTTkMzZTNyeVU?usp=sharing
For the tab positioning , DirectWrite has a method SetIncrementalTabStop , I used it with vsDraw.tabWidth to give the textLayout tab the same size :
textLayout->SetIncrementalTabStop(tabWidth);
And for the control chars , some new methods are added to give the text layout the same representation of each control char :• void ReplaceRepresentation(std::wstring &buffer);• int GetPositionInLayout(const char *s, int len, int position);• const char * IsRepresentation(unsigned int character);But there is something I don't know why it happens , when I try control chars with the original SciTE, the representative chars are displayed with dark gray background , while in my version they are displayed with light gray !
And regarding the right to left chars selection highlight , because the right and the left positions are swapped , and the selection range intersection sees only from left to right ,
I added these lines to : static void DrawTranslucentSelection(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll,
if (charPosition){pos = isTrailingHit ? hitTestMetrics.textPosition : caretMetrics.textPosition;}else{pos = isTrailingHit ? hitTestMetrics.textPosition + hitTestMetrics.length : caretMetrics.textPosition;}
bool CellBuffer::IsWeakChar(unsigned int character){if ((character >= 0x0 && character <= 0x40) || (character >= 0x5B && character <= 0x60) ||(character >= 0x7B && character <= 0xBF) || (character >= 0x2B9 && character <= 0x362) ||(character >= 0x1DC0 && character <= 0x1DC9) || (character >= 0x2010 && character <= 0x20F0) ||(character >= 0x2190 && character <= 0x23FA) || (character >= 0x2422 && character <= 0x2426) ||(character >= 0x2440 && character <= 0x2473) || (character >= 0x24EA && character <= 0x2B59) ||(character >= 0x2E00 && character <= 0x2E3B) || (character >= 0x2FF0 && character <= 0x301F) ||(character >= 0x3251 && character <= 0x325F) || (character >= 0x32B1 && character <= 0x32BF) ||(character >= 0xFE10 && character <= 0xFF6B) || (character >= 0xFF01 && character <= 0xFF20) ||(character >= 0xFF3B && character <= 0xFF40) || (character >= 0xFF5B && character <= 0xFF64) ||(character >= 0x1D7E2 && character <= 0x1D7FF) || (character >= 0x1F030 && character <= 0x1F0F5) ||(character >= 0x1F300 && character <= 0x1F6FF))return true;return false;}
while (rects<stringLength)
- Update Scintilla to v3.5.5 (Christian Walther, Heyoupeng, ARATA Mizuki). - Improve RTL support in wxStyledTextCtrl (Zane U. Ji).
- Add wxStyledTextCtrl copy/paste text events (Christian Walther).
okay ^_^
--
You received this message because you are subscribed to a topic in the Google Groups "scintilla-interest" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/scintilla-interest/6u5YFzkRzRE/unsubscribe.
To unsubscribe from this group and all its topics, send an email to scintilla-inter...@googlegroups.com.
To post to this group, send email to scintilla...@googlegroups.com.
Visit this group at https://groups.google.com/group/scintilla-interest.
For more options, visit https://groups.google.com/d/optout.
> To unsubscribe from this group and all its topics, send an email to scintilla-interest+unsub...@googlegroups.com.
//PrintText العَرَبِيَّة
You will see the same behavior
You can try using arrows , you you will get the same behavior , because the letter after t is <space> and after space is the Arabic letter"ا" not "ة" , so it's normal when we click the close to the end of the space , the correct position is the position of the next char which is "ا" , and because the textLayout reading direction is still Left to Right , the position of the caret is considered at the left(before) of the char , and here with the Arabic char the position before (left) of the chars is actually right of the char.
So when you close to the end of the <space> you get the caret at the right of letter "ا" , and when you click close to the start of the <space> you get the caret before the <space> with is the left of the letter"t" .
And if you click the on letter "ة" you get the end of line!
You can see it more crazy if you try to add an English letter after :D
I can add and conditional statements to adjust it , but I think if you are going to give the user an option to select R2L or L2R , then I can change textLayout to something like :
textLayout->SetFlowDirection(DWRITE_FLOW_DIRECTION_RIGHT_TO_LEFT);
textLayout->SetReadingDirection(DWRITE_READING_DIRECTION_RIGHT_TO_LEFT);
--
You received this message because you are subscribed to a topic in the Google Groups "scintilla-interest" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/scintilla-interest/6u5YFzkRzRE/unsubscribe.
To unsubscribe from this group and all its topics, send an email to scintilla-inter...@googlegroups.com.
1) Decide whether to use Win32 extended window styles or a Scintilla API to control base text direction.
2) Implement the SCI_SETBIDIRECTIONAL API to allow a runtime choice of bidirectional behaviour.
3) Implement a preprocessor symbol to enable R2L code. Could call this “ENABLE_BIDIRECTIONAL”.4) Add initial implementation of R2L code, enabled only when both compiled with ENABLE_BIDIRECTIONAL and the runtime setting.5) Implement base text direction control.
One issue not addressed by the patch is using EditModel::bidirectional to determine the argument to SetReadingDirection which I’d like you to work on and check the resulting behaviour.
I’ve been making further small simplifications in an effort to clarify just what is needed, particularly in FindLostSpace and other code that iterates the whole string. This code has the potential to impact performance when used on long lines and where most lines will have no representations and only have tabs at the beginning. If possible, I’d like to change whole string iteration to checking just the positions of interest where there is a representation or tab, using an array of tab/representation positions instead of an element per text byte. This could also minimize the storage cost. The reason I want to address this now is that it will be part of the interface to the ScreenLine class so may require changes to multiple platform layers if done later.
Neil
--You received this message because you are subscribed to a topic in the Google Groups "scintilla-interest" group.To unsubscribe from this topic, visit https://groups.google.com/d/topic/scintilla-interest/6u5YFzkRzRE/unsubscribe.
To unsubscribe from this group and all its topics, send an email to scintilla-interest+unsub...@googlegroups.com.To post to this group, send email to scintilla-interest@googlegroups.com.
{if (model.bidirectional == EditModel::Bidirectional::bidiR2L)
if (screenLine->widthReprs[charStart] > 0.0f) {blobs.push_back(BlobInline(screenLine->widthReprs[charStart]));textLayout->SetInlineObject(&blobs.back(), textRange);}
--
You received this message because you are subscribed to a topic in the Google Groups "scintilla-interest" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/scintilla-interest/6u5YFzkRzRE/unsubscribe.
To unsubscribe from this group and all its topics, send an email to scintilla-inter...@googlegroups.com.
To post to this group, send email to scintilla...@googlegroups.com.
if (BidiR2L)