Passing exact bounding rectangle from GdipMeasureString() to GdipDrawString() may currently result in nothing being rendered because gdip_format_string decides the string does not fit in the rectangle. The effectively considered width is a result of truncation of float rect->Width. Even without any transform or scaling in play, the float math performed on margin and width in GdipDrawString() is enough to introduce rounding error so that the truncation rounds to smaller integer while float value is very close to the next one.
As tests shows, Windows seems to do some rounding on the value. I bisected the epsilon value more precisely locally and it looks like it is very close to 0.005. The result is a bit biased with the current font size in test (probably due to some extra math and rounding on the way) but doubling font size yields 0.005 almost exactly.
Fixes text rendering in a game which randomly skips characters (in fact, most of them).
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/4416
A length of -1 has no special meaning for the mbsn*coll functions, and
since it is > INT_MAX, it will eventually trigger _invalid_parameter in
_strnicmp_l in newer versions of msvcrt.
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/4415
Current copy-prop of swizzle instructions can result in infinite loops,
as with the included test before this commit.
Consider the following sequence of instructions where a load is stored
in the same variable it loads:
1 : A
2 : A = @1
3 : @1.x
In this case @3 would call copy_propagation_get_value() on A.x and
would get @1, without detecting that that is indeed the same node
it is already using as swizzle->value. So it would return true,
keeping copy-prop spinning.
To avoid this, it is check that the replacement instruction is not the
same as the swizzle->load instruction.
---
This was discovered when trying to compile shaders from [Bug 19499](https://www.codeweavers.com/support/bugs/browse?cmd=bug_edit;bug_id=….
--
https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/482