Bug 40006 - BIDI: rtl-oriented StyledText has overlapping segments problem
Summary: BIDI: rtl-oriented StyledText has overlapping segments problem
Status: RESOLVED FIXED
Alias: None
Product: Platform
Classification: Eclipse Project
Component: SWT (show other bugs)
Version: 3.0   Edit
Hardware: PC Windows 2000
: P3 normal (vote)
Target Milestone: 2.1.2   Edit
Assignee: Knut Radloff CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2003-07-14 05:37 EDT by Semion Chichelnitsky CLA
Modified: 2003-09-10 14:04 EDT (History)
3 users (show)

See Also:


Attachments
BiDiUtil.java from build N20030710 with proposed changes (21.43 KB, text/plain)
2003-07-14 05:45 EDT, Semion Chichelnitsky CLA
no flags Details
Screen shot of test scenario (41.33 KB, image/jpeg)
2003-09-03 17:09 EDT, Knut Radloff CLA
no flags Details
Screen shot of test scenario (41.87 KB, image/jpeg)
2003-09-03 17:13 EDT, Knut Radloff CLA
no flags Details
"Aa" problem (7.12 KB, image/jpeg)
2003-09-08 06:22 EDT, Semion Chichelnitsky CLA
no flags Details
"AA" problem (6.13 KB, image/jpeg)
2003-09-08 07:10 EDT, Semion Chichelnitsky CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Semion Chichelnitsky CLA 2003-07-14 05:37:21 EDT
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.
Comment 1 Semion Chichelnitsky CLA 2003-07-14 05:45:17 EDT
Created attachment 5440 [details]
BiDiUtil.java from build N20030710 with proposed changes

Changes have b40006 tag.
Comment 2 Semion Chichelnitsky CLA 2003-07-14 12:35:44 EDT
Excuse me, it is my mistake in the previous comment: decrementing the last dx 
value is in the method drawGlyphs().
Comment 3 Knut Radloff CLA 2003-07-24 12:28:01 EDT
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".
Comment 4 Semion Chichelnitsky CLA 2003-07-29 05:28:54 EDT
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.
Comment 5 Knut Radloff CLA 2003-09-03 17:09:15 EDT
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.
Comment 6 Knut Radloff CLA 2003-09-03 17:13:02 EDT
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.
Comment 7 Knut Radloff CLA 2003-09-03 17:15:32 EDT
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.
Comment 8 Semion Chichelnitsky CLA 2003-09-08 06:22:26 EDT
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.
Comment 9 Semion Chichelnitsky CLA 2003-09-08 07:10:17 EDT
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.
Comment 10 Knut Radloff CLA 2003-09-08 12:20:11 EDT
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.
Comment 11 Knut Radloff CLA 2003-09-09 11:01:36 EDT
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).
Comment 12 Felipe Heidrich CLA 2003-09-09 17:08:12 EDT
fixed 2.1.2