-
Notifications
You must be signed in to change notification settings - Fork 689
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
TextFormatter
bugs
#3418
Comments
I understand your doubt. Maybe you can improve the documentation for this method. In fact, in this case it should return 1, because this method is used for the vertical direction of the text, to obtain the maximum size that a column will occupy in a set of characters. If in a line there is a glyph that occupies two columns then it will return 2. Therefore, it does not return the sum of the column sizes but only the maximum size occupied by a character. |
Yeah, I think I see it now. On it... |
This helped me fix issues here: /// <summary>
/// Returns the number of columns required to render <paramref name="lines"/> oriented vertically.
/// </summary>
/// <remarks>
/// This API will return incorrect results if the text includes glyphs who's width is dependent on surrounding
/// glyphs (e.g. Arabic).
/// </remarks>
/// <param name="lines">The lines.</param>
/// <param name="startLine">The line in the list to start with (any lines before will be ignored).</param>
/// <param name="linesCount">The number of lines to process (if less than <c>lines.Count</c>, any lines after will be ignored).</param>
/// <param name="tabWidth">The number of columns used for a tab.</param>
/// <returns>The width required.</returns>
public static int GetColumnsRequiredForVerticalText (
List<string> lines,
int startLine = -1,
int linesCount = -1,
int tabWidth = 0
) This was my bad. I renamed this method way back without really understanding what it did. |
Glad this helped fix the error. What matters is that now you know its purpose and it will certainly be well documented. |
Is it just me or is vertical text with multiple lines, except when centered horiz, completely broken? Note, to test this, you have to use this PR which fixes a crash in the scenario and updates the API per above: |
While we're at it, perhaps you could help me understand why this test isn't working right [SetupFakeDriver]
[Theory]
[InlineData ("A", 0, "")]
[InlineData ("A", 1, "A")]
[InlineData ("A", 2, "A")]
[InlineData ("A B", 3, "A B")]
[InlineData ("A B", 1, "A")]
[InlineData ("A B", 2, "A")]
[InlineData ("A B", 3, "A B")]
[InlineData ("A B", 4, "A B")] // BUGBUG: This should be "A B"
[InlineData ("A B", 5, "A B")]// BUGBUG: This should be "A B"
[InlineData ("A B", 6, "A B")]// BUGBUG: This should be "A B"
[InlineData ("A B", 10, "A B")]// BUGBUG: This should be "A B"
[InlineData ("ABC ABC", 10, "ABC ABC")] // BUGBUG: this is wrong
[InlineData ("ABC ABC", 12, "ABC ABC")] // BUGBUG: this is wrong
public void Draw_Horizontal_Justified (string text, int width, string expectedText)
{
TextFormatter tf = new ()
{
Text = text,
Alignment = TextAlignment.Justified,
};
tf.Draw (new Rectangle (0, 0, width, 1), Attribute.Default, Attribute.Default);
TestHelpers.AssertDriverContentsWithFrameAre (expectedText, _output);
} |
Only the ones in the middle vertically are correct. The ones on the sides are incorrect. |
I was not setting tf.Size. Nevermind. |
Now, I really did find a bug in [SetupFakeDriver]
[Theory]
[InlineData ("A", 0, false, "")]
[InlineData ("A", 1, false, "A")]
[InlineData ("A", 2, false, " A")]
[InlineData ("AB", 1, false, "A")]
[InlineData ("AB", 2, false, "AB")]
[InlineData ("ABC", 3, false, "ABC")]
[InlineData ("ABC", 4, false, " ABC")]
[InlineData ("ABC", 6, false, " ABC")]
[InlineData ("A", 0, true, "")]
[InlineData ("A", 1, true, "A")]
[InlineData ("A", 2, true, " A")]
[InlineData ("AB", 1, true, "")] // BUGBUG: This is wrong, it should be "A"
[InlineData ("AB", 2, true, "AB")]
[InlineData ("ABC", 3, true, "ABC")]
[InlineData ("ABC", 4, true, " ABC")]
[InlineData ("ABC", 6, true, " ABC")]
public void Draw_Horizontal_Right (string text, int width, bool autoSize, string expectedText)
{
TextFormatter tf = new ()
{
Text = text,
Alignment = TextAlignment.Right,
AutoSize = autoSize,
};
if (!autoSize)
{
tf.Size = new Size (width, 1);
}
tf.Draw (new Rectangle (Point.Empty, new (width, 1)), Attribute.Default, Attribute.Default);
TestHelpers.AssertDriverContentsWithFrameAre (expectedText, _output);
} |
I've also seen that Button doesn't draw the right brackets in justified alignment in some situations. Have you ever noticed this? |
(This is my bug. nevermind again... I can't repro it on v2_develop). |
Nevermind again and now mind... It IS a bug in v2_develop. I just had the test disabled. This fails:
This works
|
@BDisp since you wrote the TextFormatter.Draw code (?), could you look at this and see if you can see how to fix it? |
If you don't mind, I'll look at it tomorrow. Thanks. |
A lot of this has already been fixed in code and documentation fixes I currently have outstanding. I'd suggest not dealing with it right now, until that's done. |
There were a few test cases that were very clearly explicitly defined incorrectly to ignore what were probably deemed minor issues when it was done. Some even had comments explicitly saying that. Those now are defined correctly and pass correctly in what I've got in progress. |
My laptop is broken and only on Tuesday the SSD will be ready. Sorry. |
Bummer! |
Luckily it was ready early. Both are not correct. In horizontal alignment to the right, it is always the last letter of a word that is always placed to the right, in the case of left-to-right direction. In this case it will be "B". The following change works: In the case of the vertical direction of the text, it still seems like you are confusing the function that returns the maximum width of a rune, whose value should be 1, 2 or the tab width and not the sum of all runes. Remember that the Draw method already separates new lines and therefore these functions do not have to deal with them. |
I'm not following you here. Can you elaborate with a unit test? Or a visual? |
Nevermind. I see now. |
Likewise, in the vertical alignment at the bottom, it is always the last letter of a word that is always placed at the bottom, in the case of the direction from top to bottom and it will also be “B”. |
This PR fixes the vertical issue to some extent. However, wide runes are very broken and the way the current code is written will make it very challenging to fix. Making the change suggested for the horizontal bug fixes that, but breaks other unit tests. I don't want to chase those down given how fragile TextFormatter.Draw is. For I had the idea I could write a I finished the I think the right fix for THIS PR is a) Wait for @dodexahedron to get us the changes he made to |
Yeah it is much more robust in its unicode handling. I started trying to separate that out into a separate branch, but the changes I've had to make are extensive enough that it is a mess to do that. I got ambitious and tackled various problems that went deep/spidered out to other classes and/or that made it difficult to change it. It actually is what started me on the whole source generator thing, because I found myself repeating some bits of code more than I liked and kept running into subtly different implementations of certain things. The change set touches dozens of files and goes clear down to some of the lower level stuff like the console drivers and Key. And all that needs to be rebased on changes that happened over the past month as well, so I've got a fair chunk of work to do on all that. |
The problem with this is not with the |
Yes. The entire way all of that is handled has been redone. |
And I want to do more to it, but even when I was in the middle of working on it before I realized it would need to be a multi-stage process because it's just too much to dump all at once. |
But I think the method it works now is not the most correct. In the horizontal direction of the text it is the |
@dodexahedron would it be possible for you to share your WIP TextFormatter improvements? I am sorta blocked on several PRs, including |
@tig initially I tried to fix the bugs using your branch, but you had already made a lot of changes, especially in the vertical direction of the text, which was confusing me and didn't help me fix them. As these bugs already existed in the v2_develop branch, I decided to fix them, as well as improve the centered and right alignment in the horizontal direction of the text and the middle and bottom alignment in the vertical direction of the text. I think these corrections and improvements can help you with your PR. |
I brought #3429 down locally and it's much better. Nice! However, it's still broken for some vertical text scenarios with wide chars: I will incorporate these changes into my Now, I ask you to not work on this anymore, for now.. I do not think it is worth continuing to hack away at the old TextFormatter code to try to fix these vertical-text use cases. TextFormatter needs to be COMPLETELY RE-WRITTEN to not be so fragile. Let's see what @dodexahedron has come up with and how we can combine that with my new Closing this issue. |
I totally missed the last few comments here. I'll have to dig through my various stashes, though I do think at least some of it is already in one or more of the branches I had before. But I agree pretty strongly with:
And I got to writing more for this reply, but I need to go to bed and come back to it fresh. I'll revise and finish up that clearly sleepy comment that it ultimately became tomorrow (Well...today, technicaly, in my time zone). |
I wanna be clear on my view:
Rewriting TF is not a near term priority. We can ship v2 without rewriting it. This is because it DOES work great for almost all horizontal use cases and a lot of typical vertical cases. Short term, any effort put into TextFormatter should be put into more unit tests. If they expose bugs, the tests should be annotated. Unless the bug is an obvious main-line use case we should not bother to fix it, but should ensure the eventual rewrite does. When we DO rewrite it, I want us to start with a clear, complete, and concise design spec. Not code. |
One last point: BDisp did an amazing job making TF support vertical text originally. He put a LOT of innovative work into it. I, however, did a shitty job with the original implementation and as a result we have the fragility described above, which makes the work BDisp did even more impressive! |
All sounds great to me. My experience while approaching it largely mirrored a lot of that, especially with regards to certain fixes exposing bugs that tests would have (and in some cases already did but were sidestepped) exposed. It's an important piece of the puzzle because, after all, this is a text mode library. :) |
This API is described as:
Based on this, this unit test should pass. It doesn't. The actual width returned is
1
.I'm massively confused. Perhaps the API docs are completely wrong?
@BDisp can you advise?
The text was updated successfully, but these errors were encountered: