Fixed DirectX RTL text issue where it'd be over other text / offscreen (#1873)

This is a partial fix of #538 . This does *not* change the Console RTL behavior, it does however fix an issue in the rendering. Basically, DirectX expects the origin to be on the right if it is going to draw RTL text. This PR is a simple fix for that. Rather than draw with the left point and then move the origin rightwards, we check if it's RTL, if so, we move the origin rightwards immediately, and then draw. LTR rendering is unchanged.
This doesn't fix underlying questions of RTL handling in the console. It's just a render bugfix. However, this render bugfix should still be a big help and solve the low-hanging issues.

## Validation Steps Performed
Behavior was tested. No changes were made to underlying console.
Three sample cases:
1. RTL text input
Before:
![image](https://user-images.githubusercontent.com/16987694/60816422-6737e100-a1a2-11e9-9e14-c62323fd5b02.png)
After:
![image](https://user-images.githubusercontent.com/16987694/60816395-5ab38880-a1a2-11e9-9f0a-17b03f8268ce.png)
2. Hebrew Output
Before (the Hebrew text is all being drawn to the left of the screen, hence the phantom text):
![image](https://user-images.githubusercontent.com/16987694/60816527-93ebf880-a1a2-11e9-9ba3-d3ebb46cc404.png)
After:
![image](https://user-images.githubusercontent.com/16987694/60816456-77e85700-a1a2-11e9-9783-9e69849f026d.png)
3. Mixed Output
So, this is where this is partial. Due to inherent stuff with RTL behavior, it doesn't look perfect. But the rendering itself is no longer at fault.
Before:
![image](https://user-images.githubusercontent.com/16987694/60816593-b5e57b00-a1a2-11e9-82be-0fcabb80f7d4.png)
After:
![image](https://user-images.githubusercontent.com/16987694/60816607-bb42c580-a1a2-11e9-849a-12846ec4d5c0.png)
This commit is contained in:
Moshe Schorr 2019-07-10 21:27:36 +03:00 committed by Dustin L. Howett (MSFT)
parent 0e6f290806
commit b970356600

View file

@ -498,6 +498,20 @@ CustomTextLayout::CustomTextLayout(IDWriteFactory2* const factory,
glyphRunDescription.stringLength = run.textLength;
glyphRunDescription.textPosition = run.textStart;
// Calculate the origin for the next run based on the amount of space
// that would be consumed. We are doing this calculation now, not after,
// because if the text is RTL then we need to advance immediately, before the
// write call since DirectX expects the origin to the RIGHT of the text for RTL.
const auto postOriginX = std::accumulate(_glyphAdvances.begin() + run.glyphStart,
_glyphAdvances.begin() + run.glyphStart + run.glyphCount,
mutableOrigin.x);
// Check for RTL, if it is, apply space adjustment.
if (WI_IsFlagSet(glyphRun.bidiLevel, 1))
{
mutableOrigin.x = postOriginX;
}
// Try to draw it
RETURN_IF_FAILED(renderer->DrawGlyphRun(clientDrawingContext,
mutableOrigin.x,
@ -507,10 +521,9 @@ CustomTextLayout::CustomTextLayout(IDWriteFactory2* const factory,
&glyphRunDescription,
nullptr));
// Shift origin to the right for the next run based on the amount of space consumed.
mutableOrigin.x = std::accumulate(_glyphAdvances.begin() + run.glyphStart,
_glyphAdvances.begin() + run.glyphStart + run.glyphCount,
mutableOrigin.x);
// Either way, we should be at this point by the end of writing this sequence,
// whether it was LTR or RTL.
mutableOrigin.x = postOriginX;
}
}
CATCH_RETURN();