Community
Participate
Working Groups
This problem was reported in the bug 30434. We suggested to solve it by decrementing the last dx value in the method getRenderInfo(). It determines char positions correctly, and for this purpose dx can be used as is. Problem appears when ExtTextOut() is used with mirrored DC. For some reason it increases width of typed text by one pixel. Because segments of text in this case are displayed visually from right to left and ExtTextOut() types text from left to right, each next segment of text damages previous one. Lynne Kues in the comment #27 to bug 30434 wrote, that "...decrementing the last dx value solves the overlapping segment problem... However, we're not sure this is really necessary. Until [Bug 37293] is fixed, it's not worth investigating this further." Bug 37293 was fixed in 08/05/2003, but "overlapping segment problem" remains. Therefore we again suggest to use decrementing of last dx value to solve it.
Created attachment 5440 [details] BiDiUtil.java from build N20030710 with proposed changes Changes have b40006 tag.
Excuse me, it is my mistake in the previous comment: decrementing the last dx value is in the method drawGlyphs().
Can you provide an example that demonstrates the problem and the fix? We tried: "arabicENGLISHmore" rendered as eromENGLISHcibara Even with the dx adjustment the 'm' in "erom" still overlapped the 'E' in "ENGLISH".
Unfortunately, I can't recreate problem from your example, probably, because I don't know what font/font size were used. Here is another example: set Arabic Transparent font, size 48, switch keyboard to English, type A capital, switch to Arabic, press the same button. You are right, english letter is overlapped by arabic letter, but as far as I understand, this problem has another reason. GetCharacterPlacement() returns for corresponding glyph lesser width, than actually needed, but ExtTextOut() types it without clipping. You can check this by typing of this arabic character as first character on empty line. Note, that glyph is partially placed on XINSET area. It is causes the cheese in the end of ltr line (or in the start of rtl line), that you wrote about in the comment #2 to bug 40019. Problem, which is reported in this bug, is about one additional pixel, that is appended to each segment of text, which is typed with mirrored DC. Set, for example, font Tahoma, size 48, type capital A, switch keyboard to Hebrew or Arabic language and press the same button. As you can see, english segment is overlapped by bidi segment, and in this case problem is caused by additional pixel in the end of bidi segment, which is typed after the english letter. Unlike problem, which is described in your comment, this problem can be solved by decrementing of last dx value. It can be solved also,for example, by typing of segments of the text in the reverse sequence (this can be done in the drawBidiText() method). Note, that in case of problem from your comment, overlapping remains and difference is only one: another segment is overlapped. "Your" problem,probably, can be solved by another way. drawGlyphs() should type segment of text twice: once - without clipping and with transparent background, and after that - with clipping and with real background. Method itself can seam in this case like this: .................. .................. static final int ETO_CLIPPED = 0x4; .................. .................. public static void drawGlyphs(GC gc, char[] renderBuffer, int[] renderDx, int x, int y) { // RECT rect = null; int length = renderDx.length; //b40006 boolean isRightOriented = OS.GetLayout(gc.handle) != 0; if (OS.GetLayout (gc.handle) != 0) { reverse(renderDx); renderDx[length-1]--; //b40006 reverse(renderBuffer); } int clen = 0; for (int i=0; i<length; i++) clen += renderDx[i]; rect = new RECT(); rect.left = x; rect.right = x + clen +1; rect.top = y; rect.bottom = y + gc.getClipping().height; OS.SetBkMode(gc.handle,OS.TRANSPARENT); OS.ExtTextOutW(gc.handle, x, y, ETO_GLYPH_INDEX , null, renderBuffer, renderBuffer.length, renderDx); OS.SetBkMode(gc.handle,OS.OPAQUE); OS.ExtTextOutW(gc.handle, x, y, ETO_GLYPH_INDEX | ETO_CLIPPED, rect, renderBuffer, renderBuffer.length, renderDx); } You can see difference with following example, which can be done before and after changes: using rtl StyledText, font Times New Roman, size 48, switch to Hebrew, press button 'f', switch keyboard to English and press the same button. Now change style of english letter. Note, that it works, when segment , which is overlapped, is placed after segment with "incorrect" width. In opposite case the second segment will be clipped (with our changes or without them). Probably, we can avoid this problem by changing of sequence of drowned segments: 1) draw segments not in logical, but in visual order; 2) in case of ltr StyledText, draw segments in reverse order. I would like to note, that this problem is not something bidi specific - try, for example, to type something with font Times New Roman using letters 'f' and 'j' and different styles of line's segments.
Created attachment 5966 [details] Screen shot of test scenario I've attached a screenshot of the result of typing 'A' in English and 'A' in Arabic mode. This looks wrong even with the dx-- fix applied.
Created attachment 5967 [details] Screen shot of test scenario This is a screenshot after typing "Aa". Not sure if you are saying the problem occurs when typing a valid lowercase arabic character (as in "Aa") or an uppercase character ("AA", the first one being English). The output is the same regardless of whether I include the dx-- fix. I guess I still don't see which problem this bug is addressing.
Needless to say the screenshot in attachment #5967 [details] looks fine. There is no overlap. My system locale is set to Arabic, Saudi Arabia. User locale is English, US.
Created attachment 6012 [details] "Aa" problem Let us start from problem with typing "Aa" ( because exactly this problem I had in mind). Your attachment doesn't look fine, as you wrote: arabic "a" steal one pixel from english "A". See attachment "Aa" and compare, how this looks with fix and without fix.
Created attachment 6013 [details] "AA" problem Now about problem with typing "AA" (Shift is pressed or CapsLock is switched on; first "A" is pressed on english keyborad, second - after switching to arabic). As far as I understand, when we press Shift+A in Arabic keyboard, we receive something, that is called "Arabic Kasrah", is used to change the previous letter and is displayed inside of matrix of the previous letter. It means, that it is the right point to use version of method drawGlyphs(), which was written about in the comment #4. See attachment "AA" to compare, how this looks with current and with suggested version of method drawGlyphs(). Note, I don't want to say, that using new version of this method can solve all possible problems. This case need some additional investigation.
I do see the problem now in attachment #5967 [details]. I didn't look closely enough before. When I use Arabic transparent font size 11 or smaller the A is still cut off, in the Aa example. This is even with the dx-- fix applied. I was unable to recreate the problem I mention in comment #3 though. This clipping is resolved with the transparent rendering you suggest.
Released the dx-- fix and a modified version of the transparent rendering patch Semion supplied. With the transparent rendering and bug 40019 fixed the workaround for bug 4776 is no longer necessary (this is in StyledText.redraw).
fixed 2.1.2