Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 42892 - BIDI: Images are misaligned in RTL menu items
Summary: BIDI: Images are misaligned in RTL menu items
Status: RESOLVED WONTFIX
Alias: None
Product: Platform
Classification: Eclipse Project
Component: SWT (show other bugs)
Version: 2.1.1   Edit
Hardware: PC Windows 2000
: P1 normal (vote)
Target Milestone: 2.1.2   Edit
Assignee: Felipe Heidrich CLA
QA Contact:
URL:
Whiteboard:
Keywords:
: 87760 (view as bug list)
Depends on:
Blocks: 42426
  Show dependency tree
 
Reported: 2003-09-10 14:56 EDT by Matthew Hatem CLA
Modified: 2007-07-21 11:20 EDT (History)
4 users (show)

See Also:


Attachments
detailed description (45.97 KB, application/x-zip-compressed)
2003-09-10 14:57 EDT, Matthew Hatem CLA
no flags Details
Example (2.07 KB, text/plain)
2003-09-11 17:26 EDT, Felipe Heidrich CLA
no flags Details
Menu and MenuItem with proposed changes. (16.50 KB, application/octet-stream)
2003-09-15 09:31 EDT, Semion Chichelnitsky CLA
no flags Details
New versions of Menu and MenuItem (15.90 KB, application/octet-stream)
2003-09-18 11:18 EDT, Semion Chichelnitsky CLA
no flags Details
One more version of MenuItem.java (36.63 KB, text/plain)
2003-09-18 12:45 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 Matthew Hatem CLA 2003-09-10 14:56:51 EDT
BiDi bugs in CoolBar/ToolBar.  Please see attachment for details.
Comment 1 Matthew Hatem CLA 2003-09-10 14:57:33 EDT
Created attachment 6071 [details]
detailed description
Comment 2 Felipe Heidrich CLA 2003-09-11 15:57:24 EDT
This bug report actually contains 5 individual bug.  Normally, we would require 
5 independent reports because some we will fix and some will not.  This means, 
strictly speaking that we can never mark this problem report fixed because 
there will be unfixed portions.  Fortunately, there is only one real problem 
here.  If you do not agree, please open PR's for the other 4 "bugs".

Bug 1, Bug 2, - WONTFIX
The example code is wrong.  FH to fix the example code.

Bug 3 - ASSIGNED
RTL MenuItem does not draw the image in the wrong position.

Bug 4, Bug 5, - WONTFIX
The example code is wrong.  FH to fix the example code.

Since Bug 3 is the only thing we should fix, I am renaming the title.

Comment 3 Felipe Heidrich CLA 2003-09-11 17:14:45 EDT
Semion, could help with this ?

You can start of looking at MenuItem.wmDrawChild, in this method windows pass 
in a DRAWITEMSTRUCT structure which has the rect for receiver to draw within.
This rect is not in the correct location when RTL flag is used.
Comment 4 Felipe Heidrich CLA 2003-09-11 17:26:22 EDT
Created attachment 6086 [details]
Example

Note that I avoid the helper APIs 'new Menu (Menu)', 'new Menu (MenuItem)' and
'new Menu (Control)' cause they don't take style bit. When any of these APIs is
used the Menu inherit the orientation of the Shell what is not very instinctive
and prone to problems.
Comment 5 Semion Chichelnitsky CLA 2003-09-15 09:31:27 EDT
Created attachment 6098 [details]
Menu and MenuItem with proposed changes.

I think, we can do something, as minimum, for Win98/ME/2000/XP. 
Zip contains your demo with some additional changes, Menu.java and
MenuItem.java. Note, that your example demonstraits one more problem (isn't
bidi-specific): MenuItem with SWT.CASCADE style can't be displayed with both
text and image. This problem is solved with proposed changes too.
Comment 6 Felipe Heidrich CLA 2003-09-15 13:27:28 EDT
Semion, could you please help me to understand your code:

- Replace the old style MIIM_TYPE  by the new ones MIIM_STRING, MIIM_BITMAP, 
MIIM_FTYPE.
Why do you need this ? Is it for fixing images with cascade items or for fixing 
images on RTL items ?

- Set MIIM_BITMAP in createItem.
Again, you need that for fixing images with cascade items or for fixing images 
on RTL items ?

- Not using MFT_RIGHTJUSTIFY | MFT_RIGHTORDER, but mirroring the GC in 
wmDrawChild instead.
I believe this is the real fix for the problem with images on RTL items. Is it 
safe doing this ?

- In MenuItem.setText you set info.hbmpItem with HBMMENU_CALLBACK, but mask 
doesn't have the MIIM_BITMAP flag, it seems wrong.

- Always increase MEASUREITEMSTRUCT during wmMeasureChild.
The trim added in this method goes around the image, so why do you need this 
space when there is no image ?

It would be better if you had just fix one bug (don't bother with images on 
Cascade items) and if you had used the code base from HEAD. 
Comment 7 Felipe Heidrich CLA 2003-09-15 14:48:49 EDT
Semion, FYI: Windows CE does not support the new style flag.

I found a bug in the code, Run the code setting opposite orientation for the 
Shell and the Menu bar, see what happens.
Comment 8 Semion Chichelnitsky CLA 2003-09-18 11:18:25 EDT
Created attachment 6144 [details]
New versions of Menu and MenuItem

This attachment contains new versions of Menu.java and MenuItem.java with
proposed changes. In addition two new definitions should be added to OS.java:
       public static final int MIIM_STRING = 0x40;
       public static final int MIIM_FTYPE = 0x100;
Yes, proposed fix is mirroring the GC in wmDrawChild(). Because we should
mirror GC of all items, including such of them, which doesn't have image, we
should define all items with MIIM_BITMAP in the fMask and with HBMENU_CALLBACK
in the hbmpItem field of MENUITEMINFO. Mirroring shouldn't be done for items of
MenuBar, therefore for these items we, as usually, should use MFT_RIGHTJUSTIFY
bit ( but not MFT_RIGHTORDER bit, which change direction of all cascade items
in the tree of menus).
When rtl cascade item belongs to drop-down menu, which is connected with item
from menu bar, and when it has text only and this text has the longest length
in it's drop-down menu, this item doesn't have space between arrow and text.
Using wmMeasureChild() we can increase this distance.
Comment 9 Semion Chichelnitsky CLA 2003-09-18 12:45:03 EDT
Created attachment 6151 [details]
One more version of MenuItem.java

We have one more problem with items from MenuBar. Change of MenuBar's
orientation doesn't cause corresponding change of text order of it's items. We
can solve this problem in wmDrawChild() using SetTextAlign() and TA_RTLREADING
flag (TA_RTLREADING = 256).
Comment 10 Felipe Heidrich CLA 2003-09-18 14:34:29 EDT
The code relies on mirroring the GC before drawing and it assumes that the OS 
will draw after it. It fails cause the OS can draw with the GC before we 
changed the orientation, or the OS can draw with another GC. There is no 
guaranties.
Using LTR Shell and RTL MenuBar and RTL DropDown Menu, try this scenarios:
The first MenuItem in the DropDown Menu is SWT.CHECK or SWT.RADIO, select it, 
and pop-up the menu again.
-> The check mark and the radio mark are drawn  before the GC is mirrored and 
therefore are in the wrong position.
->The second MenuItem in the DropDown Menu is SWT.CHECK or SWT.RADIO, select 
it, and pop-up the menu again. When the menu first shows up the check mark (or 
the radio mark) are in the right place, hover the MenuItems with mouse, once 
you hover the second item it draws again (with selection background), the check 
mark (or the radio mark) are move to the wrong place.
-> The shadows and the positioning of the DropDown Menu are wrong.
Comment 11 Semion Chichelnitsky CLA 2003-09-22 08:46:56 EDT
I agree. Currently I don't see solution for this problem. We can try to use 
MFT_OWNERDRAW to receive full control for drawing the menu, but it is quite 
another principle of work. What do you think about this?    
Comment 12 Felipe Heidrich CLA 2003-09-23 15:09:46 EDT
Owner draw will cause too many problems... drawing mnemonics and accelerators 
are very hard.

Two ideas, before calling GC.win32_new() in wmDrawChild (), we can:
Add `data.layout = -1;` which will conserve the gc orientation which is good by 
default (it has the same orientation as the Shell).
In case where the Menu bar orientation and the Shell orientation are not the 
same we will need to change the gc orientation, for that we could add the line:
`data.style = parent.style & (SWT.RIGHT_TO_LEFT | SWT.LEFT_TO_RIGHT);` instead 
of `data.layout = -1;`.
Still won't work cause the check marks, radio marks, arrow and text alignment 
can be wrong. That is because we are changing the same gc that the OS will use 
to draw. The code should save the GC state,  change it, draw, and restore the 
GC state before returning it to the OS.
The latest version of my hack looks like:

LRESULT wmDrawChild (int wParam, int lParam) {
	DRAWITEMSTRUCT struct = new DRAWITEMSTRUCT ();
	OS.MoveMemory (struct, lParam, DRAWITEMSTRUCT.sizeof);
	if (image != null) {
		GCData data = new GCData();
		data.device = display;
		//data.style = parent.style & (SWT.RIGHT_TO_LEFT | 
SWT.LEFT_TO_RIGHT);
		data.layout = -1;
		GC gc = GC.win32_new (struct.hDC, data);
		int layout = -1;
		if ((parent.style & SWT.RIGHT_TO_LEFT) != 0) {
			layout = OS.GetLayout (gc.handle);
			OS.SetLayout (gc.handle, OS.LAYOUT_RTL);
		}
		gc.drawImage (image, struct.left, struct.top + 2);
		if (layout != -1) {
			OS.SetLayout (gc.handle, layout);
		}
		gc.dispose ();
	}
	return null;
}

Still, I'm having some problems with mesaurments and I didn't test pop-up menus.

Comment 13 Semion Chichelnitsky CLA 2003-09-24 04:41:27 EDT
Probably I missed something. I already tried the similar code in wmDrawChild()
and refused from it, because check and radio marks are displayed in this case 
in the same place, as our images, therefore we don't see them. Do you have this 
problem too? 
I don't understand, what you wrote about orientation of MenuBar and how it 
connected with orientation of drop-down menu. As far as I understand, our 
problem appears, when orientation of current menu is differ from orientation of 
Shell...
Comment 14 Felipe Heidrich CLA 2003-09-24 17:10:26 EDT
I've release code in HEAD to initialize GCData.layout with -1.
Whitout this the code on HEAD would always align menu item images on the wrong 
edge. Still, the scenario Menu (with Images) and Shell with different 
orientation.
I'm afraid we can not fix this problem. It looks like OS limitation/bug that we 
can't work around.

Note: In 2.1.2 since the wmDrawChild code doesn't use GC (it uses BitBlit 
instead) we actually don't need to change any code.

Comment 15 Steve Northover CLA 2004-03-05 15:19:59 EST
We won't be working around the Windows limitation.
Comment 16 Felipe Heidrich CLA 2005-03-11 13:11:22 EST
*** Bug 87760 has been marked as a duplicate of this bug. ***
Comment 17 Mohsen Saboorian CLA 2007-07-21 11:20:08 EDT
Just to add a comment on this bug, this behavior is also buggy in Vista. I don't know if Vista has also problems on rendering icons for RTL menu items bug its menu items have a place for icons (like office 2003 e.g), which is not used by SWT. SWT reners icons in another place.