@@ -456,66 +456,77 @@ public static void removeLanguageListener (long hwnd) {
456456public static void removeLanguageListener (Control control ) {
457457 removeLanguageListener (control .handle );
458458}
459+
459460/**
460461 * Determine the base direction for the given text. The direction is derived
461- * from that of the first strong bidirectional character. In case the text
462- * doesn't contain any strong characters, the base direction is to be
463- * derived from a higher-level protocol (e.g. the widget orientation).
462+ * from the first strong bidirectional RIGHT_TO_LEFT character. Or if that does
463+ * not exist from the first strong LEFT_TO_RIGHT character
464464 * <p>
465465 *
466- * @param text
467- * Text base direction should be resolved for.
466+ * @param text Text base direction should be resolved for.
468467 * @return SWT#LEFT_RIGHT or SWT#RIGHT_TO_LEFT if the text contains strong
469468 * characters and thus the direction can be resolved, SWT#NONE
470469 * otherwise.
471470 * @since 3.105
472471 */
473- public static int resolveTextDirection (String text ) {
474- if (text == null ) return SWT .NONE ;
475- int length = text .length ();
476- if (length == 0 ) return SWT .NONE ;
477- char [] rtlProbe = {' ' , ' ' , '1' };
478- char [] ltrProbe = {'\u202b' , 'a' , ' ' };
479- char [] numberProbe = {'\u05d0' , ' ' , ' ' };
480- GCP_RESULTS result = new GCP_RESULTS ();
481- result .lStructSize = GCP_RESULTS .sizeof ;
482- int nGlyphs = result .nGlyphs = ltrProbe .length ;
483- long hHeap = OS .GetProcessHeap ();
484- long lpOrder = result .lpOrder = OS .HeapAlloc (hHeap , OS .HEAP_ZERO_MEMORY , nGlyphs * 4 );
485- long hdc = OS .GetDC (0 );
486- int [] order = new int [1 ];
472+ public static int resolveTextDirection (String text ) {
473+ if (text == null )
474+ return SWT .NONE ;
487475 int textDirection = SWT .NONE ;
488- for (int i = 0 ; i < length ; i ++) {
489- char ch = text .charAt (i );
490- rtlProbe [0 ] = ch ;
491- OS .GetCharacterPlacement (hdc , rtlProbe , rtlProbe .length , 0 , result , OS .GCP_REORDER );
492- OS .MoveMemory (order , result .lpOrder , 4 );
493- if (order [0 ] == 2 ) {
494- textDirection = SWT .RIGHT_TO_LEFT ;
495- break ;
496- }
497- if (textDirection == SWT .LEFT_TO_RIGHT ) {
498- // If textDirection is already LTR, skip probing for LTR again.
499- continue ;
476+ for (int i = 0 ; i < text .length (); i ++) {
477+ char c = text .charAt (i );
478+ byte directionality = Character .getDirectionality (c );
479+ int strongDirection = getStrongDirection (directionality );
480+ if (strongDirection != SWT .NONE ) {
481+ textDirection = strongDirection ;
500482 }
501- ltrProbe [2 ] = ch ;
502- OS .GetCharacterPlacement (hdc , ltrProbe , ltrProbe .length , 0 , result , OS .GCP_REORDER );
503- OS .MoveMemory (order , result .lpOrder + 4 , 4 );
504- if (order [0 ] == 1 ) {
505- numberProbe [2 ] = ch ;
506- OS .GetCharacterPlacement (hdc , numberProbe , numberProbe .length , 0 , result , OS .GCP_REORDER );
507- OS .MoveMemory (order , result .lpOrder , 4 );
508- if (order [0 ] == 0 ) {
509- textDirection = SWT .LEFT_TO_RIGHT ;
510- // Do-not break here, instead scan the complete text for any RTL possibility
511- }
483+ if (textDirection == SWT .RIGHT_TO_LEFT ) {
484+ break ;
512485 }
513486 }
514- OS .ReleaseDC (0 , hdc );
515- OS .HeapFree (hHeap , 0 , lpOrder );
516487 return textDirection ;
488+ }
489+
490+ static int getStrongDirection (byte directionality ) {
491+ switch (directionality ) {
492+ // Strong bidirectional character types in the Unicode specification:
493+ case Character .DIRECTIONALITY_LEFT_TO_RIGHT :
494+ return SWT .LEFT_TO_RIGHT ;
495+ case Character .DIRECTIONALITY_RIGHT_TO_LEFT :
496+ case Character .DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC :
497+ return SWT .RIGHT_TO_LEFT ;
498+
499+ // Weak:
500+ // case Character.DIRECTIONALITY_EUROPEAN_NUMBER: return SWT.NONE;
501+ // case Character.DIRECTIONALITY_EUROPEAN_NUMBER_SEPARATOR: return SWT.NONE;
502+ // case Character.DIRECTIONALITY_EUROPEAN_NUMBER_TERMINATOR: return SWT.NONE;
503+ // XXX Arabic Number is not a strong direction, however former windows algorithm
504+ // would detect some as LEFT_TO_RIGHT and some as RIGHT_TO_LEFT:
505+ // case Character.DIRECTIONALITY_ARABIC_NUMBER: return SWT.RIGHT_TO_LEFT;
506+ // case Character.DIRECTIONALITY_COMMON_NUMBER_SEPARATOR: return SWT.NONE;
507+ // case Character.DIRECTIONALITY_NONSPACING_MARK: return SWT.LEFT_TO_RIGHT;
508+ // case Character.DIRECTIONALITY_BOUNDARY_NEUTRAL: return SWT.NONE;
517509
510+ // Neutral:
511+ // case Character.DIRECTIONALITY_PARAGRAPH_SEPARATOR: return SWT.LEFT_TO_RIGHT;
512+ // case Character.DIRECTIONALITY_SEGMENT_SEPARATOR: return SWT.LEFT_TO_RIGHT;
513+ // case Character.DIRECTIONALITY_WHITESPACE: return SWT.NONE;
514+ // case Character.DIRECTIONALITY_OTHER_NEUTRALS: return SWT.NONE;
515+
516+ // Explicit Formatting:
517+ // case Character.DIRECTIONALITY_LEFT_TO_RIGHT_EMBEDDING: return SWT.LEFT_TO_RIGHT;
518+ // case Character.DIRECTIONALITY_LEFT_TO_RIGHT_OVERRIDE: return SWT.LEFT_TO_RIGHT;
519+ // case Character.DIRECTIONALITY_RIGHT_TO_LEFT_EMBEDDING: return SWT.LEFT_TO_RIGHT;
520+ // case Character.DIRECTIONALITY_RIGHT_TO_LEFT_OVERRIDE: return SWT.LEFT_TO_RIGHT;
521+ // case Character.DIRECTIONALITY_POP_DIRECTIONAL_FORMAT: return SWT.LEFT_TO_RIGHT;
522+ // case Character.DIRECTIONALITY_LEFT_TO_RIGHT_ISOLATE: return SWT.LEFT_TO_RIGHT;
523+ // case Character.DIRECTIONALITY_RIGHT_TO_LEFT_ISOLATE: return SWT.LEFT_TO_RIGHT;
524+ // case Character.DIRECTIONALITY_FIRST_STRONG_ISOLATE: return SWT.LEFT_TO_RIGHT;
525+ // case Character.DIRECTIONALITY_POP_DIRECTIONAL_ISOLATE: return SWT.LEFT_TO_RIGHT;
526+ }
527+ return SWT .NONE ;
518528}
529+
519530/**
520531 * Switch the keyboard language to the specified language type. We do
521532 * not distinguish between multiple bidi or multiple non-bidi languages, so
0 commit comments