Don't split surrogate pairs when breaking runs for scaling. Affects emoji rendering. #4704 (#4731)

## Summary of the Pull Request
- Surrogate pairs are being split in half with the run splitting check.

## References
- Related to #4708 but not going to fix it.

## PR Checklist
* [x] Closes #4704
* [x] I work here.
* [x] I am a core contributor.

## Detailed Description of the Pull Request / Additional comments
- The adjustment of the run heights in the correction function reports back a text index and a scaling factor. However, I didn't remember at the time that the text is being stored as UTF-16. So the index given can be pointing to the high surrogate of a pair. Thus adding 1 to split "after" the text character, then backing up by 1 isn't valid in if the index given was for a high surrogate.

The quick fix is to advance by two if it's a high surrogate and one otherwise.

## Validation Steps Performed
- Used the sample code from #4704 to print the house emoji in various situations into the buffer.
This commit is contained in:
Michael Niksa 2020-02-26 13:55:22 -08:00 committed by GitHub
parent 61e5917fe8
commit d7ea526c3c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -361,13 +361,16 @@ CustomTextLayout::CustomTextLayout(gsl::not_null<IDWriteFactory1*> const factory
// If scale corrections were needed, we need to split the run.
for (auto [index, scale] : _glyphScaleCorrections)
{
// Don't split in the middle of a surrogate pair.
const auto after = IS_HIGH_SURROGATE(_text.at(index)) ? 2 : 1;
// Split after the adjustment first so it
// takes a copy of all the run properties before we modify them.
// GH 4665: This is the other half of the potential future perf item.
// If glyphs needing the same scale are coalesced, we could
// break fewer times and have fewer runs.
_SetCurrentRun(index + 1);
_SplitCurrentRun(index + 1);
_SetCurrentRun(index + after);
_SplitCurrentRun(index + after);
// Now split just this glyph off.
_SetCurrentRun(index);