Skip to content

feat(text): Shape complex single line UI text - #3231

Open
OmarAglan wants to merge 1 commit into
TheSuperHackers:mainfrom
OmarAglan:feature/arabic-ui-text-shaping
Open

feat(text): Shape complex single line UI text#3231
OmarAglan wants to merge 1 commit into
TheSuperHackers:mainfrom
OmarAglan:feature/arabic-ui-text-shaping

Conversation

@OmarAglan

@OmarAglan OmarAglan commented Aug 28, 2026

Copy link
Copy Markdown

Adds contextual shaping and bidirectional ordering for complex single-line UI text in Render2DSentenceClass.

The existing sentence renderer processes text one WCHAR at a time, which prevents Arabic letters from using their contextual forms and breaks the visual order of mixed Arabic and Latin text. Eligible strings are now itemized as one paragraph, divided into visually ordered font runs only at character-cluster boundaries, and rasterized once before being copied across the existing A4R4G4B4 sentence textures.

Plain Latin strings continue to use the existing per-character renderer. Multiline text, text requiring wrapping, text with an active hot-key marker, monospaced text, and editable text entries remain on the legacy path.

The required Uniscribe entry points are loaded at runtime through #3241. If Uniscribe is unavailable, rendering falls back to the legacy path.

Before

Arabic text before shaping

After

Arabic text after shaping

The change was validated with:

  • Visual Studio 2022 x86 Release builds of Generals and Zero Hour
  • The repository’s portable VC6 toolchain for Generals and Zero Hour
  • Runtime testing of normally authored Arabic menu strings in Zero Hour
  • git diff --check

The implementation was developed with AI assistance, then manually reviewed and simplified against the nearby renderer and runtime-loader code.

@OmarAglan
OmarAglan marked this pull request as ready for review August 28, 2026 10:21
@qodo-free-for-open-source-projects

qodo-free-for-open-source-projects Bot commented Aug 28, 2026

Copy link
Copy Markdown

PR Summary by Qodo

Shape complex single-line UI text with Uniscribe

✨ Enhancement 🐞 Bug fix 🕐 40+ Minutes

Grey Divider

AI Description

• Shape complex single-line UI text with contextual glyphs and bidirectional ordering.
• Measure and rasterize eligible runs through dynamically loaded Windows Uniscribe.
• Preserve legacy rendering for Latin, multiline, hotkey, monospaced, and editable text.
Diagram

graph TD
  A["Display String"] --> B["Sentence Renderer"] --> C{"Complex eligible?"}
  C -- Yes --> D["Windows Uniscribe"] --> E["GDI Raster"] --> F["Sentence Textures"]
  C -- No --> G["Legacy Glyph Path"] --> F
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Adopt DirectWrite rendering
  • ➕ Provides a modern shaping and text-layout stack
  • ➕ Could support multiline layout and caret metrics in one backend
  • ➖ Requires a broader renderer redesign beyond existing GDI HFONT integration
  • ➖ Raises migration, compatibility, and review risk substantially
2. Link usp10 statically
  • ➕ Removes function-pointer wrappers and lazy-load branching
  • ➕ Makes missing APIs fail at build or process load time
  • ➖ Introduces a hard Windows import dependency
  • ➖ Loses graceful fallback to legacy rendering when Uniscribe is unavailable

Recommendation: Keep the runtime-loaded Uniscribe approach for this scoped change. It reuses the existing GDI font pipeline, preserves legacy behavior when shaping is unavailable or unsupported, and avoids a disproportionate DirectWrite migration; editable and multiline shaping can be added once caret and layout metrics are designed.

Files changed (12) +600 / -5

Enhancement (7) +406 / -5
DisplayString.hExpose per-string complex text control +1/-0

Expose per-string complex text control

• Adds an abstract switch allowing display-string implementations and UI controls to enable or disable complex shaping.

Core/GameEngine/Include/GameClient/DisplayString.h

render2dsentence.cppShape and rasterize eligible complex text runs +355/-3

Shape and rasterize eligible complex text runs

• Detects complex single-line text, measures and renders it as one Uniscribe run, and copies bounded raster chunks into existing sentence textures. It preserves the legacy path for excluded modes, unsupported dimensions, non-Windows builds, or shaping failures.

Core/Libraries/Source/WWVegas/WW3D2/render2dsentence.cpp

render2dsentence.hDeclare complex shaping renderer APIs +18/-2

Declare complex shaping renderer APIs

• Adds font-level complexity, measurement, and rasterization methods plus renderer eligibility, sizing, texture-building, and enablement state.

Core/Libraries/Source/WWVegas/WW3D2/render2dsentence.h

W3DDisplayString.hExpose complex shaping in Generals display strings +1/-0

Expose complex shaping in Generals display strings

• Adds the W3D display-string override for controlling complex text shaping.

Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DDisplayString.h

W3DDisplayString.cppUse shaped widths and propagate shaping state +15/-0

Use shaped widths and propagate shaping state

• Returns whole-run Uniscribe width when applicable and applies shaping enablement to normal and hotkey renderers. State changes invalidate cached text geometry.

Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplayString.cpp

W3DDisplayString.hExpose complex shaping in Zero Hour display strings +1/-0

Expose complex shaping in Zero Hour display strings

• Adds the W3D display-string override for controlling complex text shaping.

GeneralsMD/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DDisplayString.h

W3DDisplayString.cppUse shaped widths and propagate shaping state +15/-0

Use shaped widths and propagate shaping state

• Returns whole-run Uniscribe width when applicable and applies shaping enablement to normal and hotkey renderers. State changes invalidate cached text geometry.

GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplayString.cpp

Bug fix (2) +10 / -0
GameWindowManager.cppKeep Generals text entries on legacy rendering +5/-0

Keep Generals text entries on legacy rendering

• Disables complex shaping for editable, selected, and composition display strings because caret and partial-character metrics remain per-character.

Generals/Code/GameEngine/Source/GameClient/GUI/GameWindowManager.cpp

GameWindowManager.cppKeep Zero Hour text entries on legacy rendering +5/-0

Keep Zero Hour text entries on legacy rendering

• Disables complex shaping for editable, selected, and composition display strings until shaped caret positioning is supported.

GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GameWindowManager.cpp

Other (3) +184 / -0
CMakeLists.txtBuild the Uniscribe loader on Windows +2/-0

Build the Uniscribe loader on Windows

• Registers the new runtime loader sources in the Windows-only WWLib source list.

Core/Libraries/Source/WWVegas/WWLib/CMakeLists.txt

Usp10Loader.cppLoad Uniscribe APIs safely at runtime +111/-0

Load Uniscribe APIs safely at runtime

• Implements one-time, lock-protected loading of the system usp10.dll and resolves the shaping APIs used by the renderer. Wrappers return failures when the library or required exports are unavailable.

Core/Libraries/Source/WWVegas/WWLib/Usp10Loader.cpp

Usp10Loader.hDefine the runtime Uniscribe interface +71/-0

Define the runtime Uniscribe interface

• Declares the required Uniscribe flags, opaque analysis types, API wrappers, and resolved function-pointer storage without adding a static import dependency.

Core/Libraries/Source/WWVegas/WWLib/Usp10Loader.h

@qodo-free-for-open-source-projects

qodo-free-for-open-source-projects Bot commented Aug 28, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (1) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)

Grey Divider


Action required

1. Mixed text uses fallback font ✓ Resolved 🐞 Bug ≡ Correctness
Description
The complex path selects AlternateUnicodeFont for the entire string, so Latin characters in mixed
Arabic/Latin UI text no longer use the requested primary font. Existing font behavior delegates only
non-ASCII characters to the configured Unicode fallback, so this changes Latin styling and metrics
whenever the two fonts differ.
Code

Core/Libraries/Source/WWVegas/WW3D2/render2dsentence.cpp[R1418-1419]

+	FontCharsClass *render_font = AlternateUnicodeFont && this != AlternateUnicodeFont ?
+		AlternateUnicodeFont : this;
Evidence
The normal font lookup keeps characters below 256 in the primary font and delegates only non-ASCII
characters to the alternate font. The new code instead analyzes and outputs the whole string using
the alternate font's DC/HFONT, while game font loading identifies that font specifically as the
Unicode fallback.

Core/Libraries/Source/WWVegas/WW3D2/render2dsentence.cpp[1312-1319]
Core/Libraries/Source/WWVegas/WW3D2/render2dsentence.cpp[1418-1427]
Core/Libraries/Source/WWVegas/WW3D2/render2dsentence.cpp[1492-1539]
Core/GameEngineDevice/Source/W3DDevice/GameClient/GUI/W3DGameFont.cpp[80-99]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Complex mixed-script strings are measured and rendered entirely with `AlternateUnicodeFont`, replacing the requested primary font for Latin runs.
## Issue Context
The existing character path uses the primary font for ASCII and delegates only non-ASCII characters to `AlternateUnicodeFont`. Preserve that division while shaping the complete bidi string, using run-level font selection/fallback consistently for both measurement and rendering.
## Fix Focus Areas
- Core/Libraries/Source/WWVegas/WW3D2/render2dsentence.cpp[1418-1427]
- Core/Libraries/Source/WWVegas/WW3D2/render2dsentence.cpp[1492-1539]
- Core/Libraries/Source/WWVegas/WW3D2/render2dsentence.cpp[1312-1319]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

2. Unsupported runs rasterize twice 🐞 Bug ➹ Performance
Description
Build_Complex_Sentence creates the complete GDI bitmap and A4R4G4B4 raster before checking whether
its width exceeds WrapWidth. Every single-line complex string requiring wrapping therefore pays
for a full-run shape, bitmap allocation, pixel conversion, and discard before Build_Sentence
renders it again through the legacy wrapped path, with particularly high cost for long text.
Code

Core/Libraries/Source/WWVegas/WW3D2/render2dsentence.cpp[R687-688]

+	if (!Font->Rasterize_Complex_Text(text, &raster, &text_width, &text_height) ||
+		!Is_Complex_Text_Size_Supported(text_width, text_height))
Evidence
The complex predicate does not exclude wrapped renderers, while the support check rejects runs whose
measured width reaches WrapWidth. Build_Complex_Sentence invokes the allocating rasterizer
before that support check; after it returns false, Build_Sentence immediately continues into the
existing centered/non-centered renderer, proving the discarded first rendering is repeated work.

Core/Libraries/Source/WWVegas/WW3D2/render2dsentence.cpp[621-632]
Core/Libraries/Source/WWVegas/WW3D2/render2dsentence.cpp[642-645]
Core/Libraries/Source/WWVegas/WW3D2/render2dsentence.cpp[680-692]
Core/Libraries/Source/WWVegas/WW3D2/render2dsentence.cpp[1292-1302]
Core/Libraries/Source/WWVegas/WW3D2/render2dsentence.cpp[1632-1645]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Complex text is fully rasterized before checking whether its dimensions qualify for the complex single-line path. If its width reaches the configured wrapping width, that raster is discarded and the legacy path renders the text again.
## Issue Context
Use the lightweight Uniscribe extent query and `Is_Complex_Text_Size_Supported` before allocating/rasterizing the full run. Retain a post-rasterization dimension check for defensive consistency if needed.
## Fix Focus Areas
- Core/Libraries/Source/WWVegas/WW3D2/render2dsentence.cpp[680-692]
- Core/Libraries/Source/WWVegas/WW3D2/render2dsentence.cpp[642-645]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. Run rerasterized per chunk ✓ Resolved 🐞 Bug ➹ Performance
Description
Every texture-width chunk calls Blit_Complex_Text, which remeasures, reshapes, allocates a
full-run bitmap, and rasterizes the entire string before copying one slice. Because chunks are
capped by the texture width, rendering cost and allocated pixel work grow quadratically with long
single-line strings and repeat even for ordinary runs wider than one texture.
Code

Core/Libraries/Source/WWVegas/WW3D2/render2dsentence.cpp[R679-680]

+		if (!Font->Blit_Complex_Text(text, LockedPtr, LockedStride, TextureOffset.I,
+			TextureOffset.J, source_x, chunk_width))
Evidence
The outer loop advances source_x by at most the available texture width, but each iteration
invokes a helper that recomputes full extents, allocates a text_width-wide bitmap, reruns
Uniscribe analysis, and outputs the complete string. Thus a run split into N chunks performs N
full-run rasterizations rather than one rasterization plus N slice copies.

Core/Libraries/Source/WWVegas/WW3D2/render2dsentence.cpp[664-690]
Core/Libraries/Source/WWVegas/WW3D2/render2dsentence.cpp[1494-1539]
Core/Libraries/Source/WWVegas/WW3D2/render2dsentence.cpp[1542-1552]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The complex string is fully analyzed and rasterized once for every texture chunk, making long-run construction scale quadratically.
## Issue Context
`Build_Complex_Sentence` iterates over texture-sized slices, while `Blit_Complex_Text` recreates a full-width DIB and repeats `ScriptStringAnalyse`/`ScriptStringOut` on every call. Produce the full raster once, then copy each slice into its destination surface.
## Fix Focus Areas
- Core/Libraries/Source/WWVegas/WW3D2/render2dsentence.cpp[664-690]
- Core/Libraries/Source/WWVegas/WW3D2/render2dsentence.cpp[1494-1552]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Tip of the day
💡 Did you know, you can route each action level your way: inline, summary, both, or drop

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Comment thread Core/Libraries/Source/WWVegas/WW3D2/render2dsentence.cpp Outdated
Comment thread Core/Libraries/Source/WWVegas/WW3D2/render2dsentence.cpp Outdated
@greptile-apps

greptile-apps Bot commented Aug 28, 2026

Copy link
Copy Markdown

Greptile Summary

The PR adds contextual shaping and bidirectional ordering for eligible complex single-line UI text while retaining the legacy path for wrapping, hotkeys, editable text, monospaced text, and unavailable Uniscribe.

  • Adds Uniscribe-based complex-text measurement, visual run ordering, rasterization, and texture chunking.
  • Keeps the shared display-string contract synchronized across Generals and Zero Hour.
  • Resolves shaped-to-legacy fallback before layout dimensions are consumed.
  • Rejects unsupported shaped dimensions before entering texture chunk processing.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains.

Important Files Changed

Filename Overview
Core/Libraries/Source/WWVegas/WW3D2/render2dsentence.cpp Implements complex-text eligibility, Uniscribe layout and rasterization, bounded surface allocation, texture chunking, and legacy fallback; the previously reported oversized-text failures are no longer reachable.
Core/Libraries/Source/WWVegas/WW3D2/render2dsentence.h Extends the sentence renderer and font interfaces with complex-text measurement, rasterization, enablement, and fallback-result reporting.
Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplayString.cpp Resolves sentence construction before returning shaped dimensions and replaces cached extents when rendering falls back to the legacy path.
GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplayString.cpp Mirrors the Generals display-string fallback and layout-ordering fixes.
Core/GameEngine/Source/GameClient/GUI/GameWindowManager.cpp Explicitly keeps editable and IME-related display strings on the legacy renderer until shaped caret metrics are supported.
Core/Libraries/Source/WWVegas/WW3D2/ww3d.cpp Unloads the runtime Uniscribe entry points during WW3D shutdown.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Display string text changes] --> B{Eligible complex single line?}
    B -- No --> C[Legacy per-character measurement and rendering]
    B -- Yes --> D[Measure shaped paragraph]
    D --> E{Dimensions supported?}
    E -- No --> C
    E -- Yes --> F[Rasterize shaped visual runs]
    F --> G{Rasterization succeeded?}
    G -- No --> C
    G -- Yes --> H[Split raster across sentence textures]
    H --> I[Draw shaped sentence]
    C --> J[Publish legacy extents]
    I --> K[Publish shaped extents]
Loading

Reviews (14): Last reviewed commit: "feat(text): Shape complex single-line UI..." | Re-trigger Greptile

Comment thread Core/Libraries/Source/WWVegas/WW3D2/render2dsentence.cpp
@tintinhamans

Copy link
Copy Markdown

@codex

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a852d41fbb

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread Core/Libraries/Source/WWVegas/WW3D2/render2dsentence.cpp Outdated
Comment thread Core/Libraries/Source/WWVegas/WW3D2/render2dsentence.cpp Outdated
@stephanmeesters

Copy link
Copy Markdown

I can't tell from the text and images what the problems were and how this fixes it.

The main-menu test confirms correct contextual shaping, bidirectional ordering, digit ordering, centering, and clipping.

Can you give before and afters of each of these individually?

@OmarAglan

Copy link
Copy Markdown
Author

I can't tell from the text and images what the problems were and how this fixes it.

The main-menu test confirms correct contextual shaping, bidirectional ordering, digit ordering, centering, and clipping.

Can you give before and afters of each of these individually?

will provide examples of it as soon as possible

@OmarAglan

OmarAglan commented Aug 28, 2026

Copy link
Copy Markdown
Author

I can't tell from the text and images what the problems were and how this fixes it.

The main-menu test confirms correct contextual shaping, bidirectional ordering, digit ordering, centering, and clipping.

Can you give before and afters of each of these individually?

will provide examples of it as soon as possible

the Arabic text as for now!

before

sshot001

after

sshot_20260828_215246_250

@OmarAglan
OmarAglan force-pushed the feature/arabic-ui-text-shaping branch from f88c715 to d25f054 Compare August 28, 2026 19:08
Comment thread Core/Libraries/Source/WWVegas/WW3D2/render2dsentence.cpp Outdated
@OmarAglan
OmarAglan force-pushed the feature/arabic-ui-text-shaping branch from d25f054 to eff4156 Compare August 28, 2026 19:33
@OmarAglan
OmarAglan marked this pull request as draft August 30, 2026 20:13
@OmarAglan

Copy link
Copy Markdown
Author

draft to fix the vc6 issue

Comment thread Core/Libraries/Source/WWVegas/WW3D2/render2dsentence.cpp Outdated
Comment thread Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplayString.cpp Outdated
@bobtista

Copy link
Copy Markdown

We can handle VC6 in a small prerequisite PR by runtime-loading usp10.dll, using DbgHelpLoader as an example. Then this PR can drop the usp10 link and guard the Uniscribe code with _WIN32.

@OmarAglan
OmarAglan force-pushed the feature/arabic-ui-text-shaping branch from eff4156 to 74c1e27 Compare August 31, 2026 20:08
@OmarAglan
OmarAglan marked this pull request as ready for review August 31, 2026 20:10
Comment thread Core/Libraries/Source/WWVegas/WW3D2/render2dsentence.cpp Outdated
@qodo-free-for-open-source-projects

Copy link
Copy Markdown

Code review by qodo was updated up to the latest commit 74c1e27

@OmarAglan

OmarAglan commented Aug 31, 2026

Copy link
Copy Markdown
Author

We can handle VC6 in a small prerequisite PR by runtime-loading usp10.dll, using DbgHelpLoader as an example. Then this PR can drop the usp10 link and guard the Uniscribe code with _WIN32.

yes im working on it!

@xezon

xezon commented Sep 1, 2026

Copy link
Copy Markdown

In what shape is the arabic text you tested with? As far as I am aware the old translations had the words reversed to accomodate the game implementation. Can arabic text now be supplied normally?

@OmarAglan

Copy link
Copy Markdown
Author

In what shape is the arabic text you tested with? As far as I am aware the old translations had the words reversed to accomodate the game implementation. Can arabic text now be supplied normally?

i used noraml text arabic, i didnt reverse the text, this fixes the hack that is to reverse the arabic text!
still i need to extand upon this on adding maybe support for arabic text in chat and multi line, this can be addressed in follow up pr.

@OmarAglan

Copy link
Copy Markdown
Author

needs rebase and conflict fix, working on it.

@OmarAglan
OmarAglan force-pushed the feature/arabic-ui-text-shaping branch 2 times, most recently from a845dfe to 80cebad Compare September 2, 2026 18:24
@OmarAglan

Copy link
Copy Markdown
Author

Rebased and fixed and addressed all the changes required

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 80cebad841

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread Core/Libraries/Source/WWVegas/WW3D2/render2dsentence.cpp Outdated
Comment thread Core/Libraries/Source/WWVegas/WW3D2/render2dsentence.cpp
Comment thread GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplayString.cpp Outdated
@OmarAglan
OmarAglan force-pushed the feature/arabic-ui-text-shaping branch from 80cebad to 60951d4 Compare September 3, 2026 18:47

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 60951d4c23

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread Core/Libraries/Source/WWVegas/WW3D2/render2dsentence.cpp Outdated
Comment thread Core/Libraries/Source/WWVegas/WW3D2/render2dsentence.cpp Outdated
@OmarAglan
OmarAglan force-pushed the feature/arabic-ui-text-shaping branch 2 times, most recently from a5a59b9 to 42b2337 Compare September 4, 2026 01:37
@OmarAglan
OmarAglan force-pushed the feature/arabic-ui-text-shaping branch from 42b2337 to 2220c79 Compare September 4, 2026 10:02
Comment thread Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplayString.cpp Outdated
@OmarAglan
OmarAglan force-pushed the feature/arabic-ui-text-shaping branch 2 times, most recently from 4985fdf to c986ded Compare September 4, 2026 11:10
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

@OmarAglan

Copy link
Copy Markdown
Author

Rebased!

@OmarAglan

Copy link
Copy Markdown
Author

@codex

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c986dedf67

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

hotkey.translate(TheHotKeyManager->searchHotKey(getText()));
}

const Bool hasHotkey = !hotkey.isEmpty();

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Validate the accelerator before enabling hotkey parsing

When a hotkey-enabled complex label contains a literal ampersand followed by whitespace (for example, Arabic text containing &), this still sets hasHotkey: the current HotKeyManager::searchHotKey() returns the character after any & without validating it (Core/GameEngine/Source/GameClient/MessageStream/HotKey.cpp:211-218), while the sentence renderer consumes the marker only when the following character is greater than L' ' (render2dsentence.cpp:1150). ParseHotKey therefore remains true and Is_Single_Line_Complex_Text() rejects the whole label, leaving its Arabic text unshaped. This predicate mismatch is fresh evidence beyond the resolved no-marker case; derive hasHotkey using the renderer's accelerator-validity rules.

Useful? React with 👍 / 👎.

@OmarAglan
OmarAglan force-pushed the feature/arabic-ui-text-shaping branch from c986ded to f881a12 Compare September 4, 2026 18:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants