@@ -159,9 +159,20 @@ void WindowsTextLayoutManager::GetTextLayout(
159159 winrt::check_hresult (spTextFormat->SetTextAlignment (alignment));
160160
161161 // Set reading direction based on baseWritingDirection
162- if (outerFragment.textAttributes .baseWritingDirection &&
163- *outerFragment.textAttributes .baseWritingDirection == facebook::react::WritingDirection::RightToLeft) {
164- winrt::check_hresult (spTextFormat->SetReadingDirection (DWRITE_READING_DIRECTION_RIGHT_TO_LEFT));
162+ if (outerFragment.textAttributes .baseWritingDirection ) {
163+ DWRITE_READING_DIRECTION readingDirection = DWRITE_READING_DIRECTION_LEFT_TO_RIGHT;
164+
165+ // Handle explicit RightToLeft
166+ if (*outerFragment.textAttributes .baseWritingDirection == facebook::react::WritingDirection::RightToLeft) {
167+ readingDirection = DWRITE_READING_DIRECTION_RIGHT_TO_LEFT;
168+ }
169+ // For all other cases (including Natural), use context-aware detection
170+ else {
171+ // For Natural direction, detect from text content
172+ readingDirection = GetNaturalReadingDirection (attributedStringBox);
173+ }
174+
175+ winrt::check_hresult (spTextFormat->SetReadingDirection (readingDirection));
165176 }
166177
167178 // Get text with Object Replacement Characters for attachments
@@ -553,4 +564,43 @@ winrt::hstring WindowsTextLayoutManager::GetTransformedText(const AttributedStri
553564 return result;
554565}
555566
567+ DWRITE_READING_DIRECTION WindowsTextLayoutManager::GetNaturalReadingDirection (const AttributedStringBox &attributedStringBox) noexcept {
568+ const auto &attributedString = attributedStringBox.getValue ();
569+
570+ // Analyze the text content to determine the natural reading direction
571+ // Look for the first strong directional character
572+ for (const auto &fragment : attributedString.getFragments ()) {
573+ if (!fragment.isAttachment ()) {
574+ auto fragmentText = Microsoft::Common::Unicode::Utf8ToUtf16 (fragment.string );
575+
576+ for (wchar_t ch : fragmentText) {
577+ // Check for strong RTL characters (Arabic, Hebrew ranges)
578+ if ((ch >= 0x0590 && ch <= 0x05FF ) || // Hebrew
579+ (ch >= 0x0600 && ch <= 0x06FF ) || // Arabic
580+ (ch >= 0x0750 && ch <= 0x077F ) || // Arabic Supplement
581+ (ch >= 0x08A0 && ch <= 0x08FF ) || // Arabic Extended-A
582+ (ch >= 0xFB1D && ch <= 0xFB4F ) || // Hebrew Presentation Forms
583+ (ch >= 0xFB50 && ch <= 0xFDFF ) || // Arabic Presentation Forms-A
584+ (ch >= 0xFE70 && ch <= 0xFEFF )) { // Arabic Presentation Forms-B
585+ return DWRITE_READING_DIRECTION_RIGHT_TO_LEFT;
586+ }
587+ // Check for strong LTR characters (Latin, Cyrillic, etc.)
588+ else if ((ch >= 0x0041 && ch <= 0x005A ) || // Latin uppercase
589+ (ch >= 0x0061 && ch <= 0x007A ) || // Latin lowercase
590+ (ch >= 0x00C0 && ch <= 0x00D6 ) || // Latin extended
591+ (ch >= 0x00D8 && ch <= 0x00F6 ) || // Latin extended
592+ (ch >= 0x00F8 && ch <= 0x00FF ) || // Latin extended
593+ (ch >= 0x0100 && ch <= 0x017F ) || // Latin Extended-A
594+ (ch >= 0x0180 && ch <= 0x024F ) || // Latin Extended-B
595+ (ch >= 0x0400 && ch <= 0x04FF )) { // Cyrillic
596+ return DWRITE_READING_DIRECTION_LEFT_TO_RIGHT;
597+ }
598+ }
599+ }
600+ }
601+
602+ // If no strong directional characters found, use system default (LTR)
603+ return DWRITE_READING_DIRECTION_LEFT_TO_RIGHT;
604+ }
605+
556606} // namespace facebook::react
0 commit comments