Join GitHub today
GitHub is home to over 50 million developers working together to host and review code, manage projects, and build software together.
Sign upOverhaul Text Arrangement and Trimming #1556
Conversation
MaxSize support is probably pretty slow, and will be caught out by strings with combining characters (need to do some research on that), but gives pretty reasonable results. It could be performed more quickly by render contexts with access to glyph information (e.g. SkiaSharp), where cropping the line would be logarithmic (i.e. irrelevant) rather that log-linear. WPF (the bottom-most line is drawn clipped) Skia on WPF (the bottom-most line is skipped completely) |
@Jonarw would you mind taking a gander at the changes in Skia, and let me know if this looks too abhorrent to you to be an acceptable change? Having done the provisional implementation of |
Generally I think the I am a bit sceptical if clipping on character level is really the way to go for implementing I am more concerned that we might be trying to do something very complex that we don't actually really need (see also my comment in #1559) - after all, I haven't missed this feature on SkiaSharp so far. |
I am also not too sure how about I feel about guessing the font metrics (ascent, descent, leading) by doing multiple text measurements. At the current state, the exact algorithm for text height measurement should be an implementation detail of the render context, which we shouldn't rely on. If we effectively move the responsibility for vertical text arrangement out of the render context and into the
|
@Jonarw yeah, it's pretty horrendous, and I think what you describe is actually close to how OxyPlot was designed: To that end, I would suggest keeping the current API as it is (i.e. |
You are right of course, from the perspective of I haven't completely wrapped my mind around this, I need to think about it some more... |
Thanks for the comments on what must look a complete mess at the moment. I'll probably next implement your suggestions about abstracting out the 'basic' measurement stuff (so we don't have to infer metrics), and put the whole thing in its own class. Rough plan:
The additional interface will duly provide the information the managed only |
Recent changes:
Next tasks:
Any feedback (esspecially negative) welcome as always. |
Refitting done, so Also refitted the TextTrimmer so it supports Unicode and adding additional tests. This of course has made it slower... but I don't think that should be a concern: it is rarely used, and would be providing a capability that is presently unavailable almost everywhere. I doubt it is perfect (i.e. there will be strings that it gives nonsense results on), but it should be fairly easy to extend by making the central regexes more complicated. Annoyingly we can't compile the regexes because we started .NET Standard 1.0; however, the architecture means that if someone really cared they can swap out the text trimmer for their own; whether this is a good architecture is another issue. WinForms is still broken: either I'm having difficultly extracting the font metrics (i.e. |
Fixed WinForms. I think that means everything is working as I understand it should. I've not StyleCop'd this, but I'm going to open for review because there is nothing else I'm intending to do at the moment. |
8a10280
to
1927d3d
Looks very promising! Just for my understanding: This adapts ImageSharp, SkiaSharp, WinForms and Pdf, at the moment, right? So WPF would still have to be adjusted for this (but could also be its own issue and PR). Also we should then add more sophisticated |
@Jonarw thanks. I'll eagerly await your feedback, and perhaps put my efforts into #1516 It also adapts the built-in SVG renderer, which now depends on an I've not refitted WPF yet because frankly I'm frightened of it, but I can do that work for this PR or it can be done later if @objorke approves. For the purposes of consistent vertical alignment it is probably a good idea, but it may still be that we leave the trimming to it (though as I've discussed elsewhere, trimming by character seems a much better strategy to me) which could complicate matters with multi-line text Regards advanced trimmers: yep, that was pretty much what I had in mind. The performance so far is perfectly good in my opinion, but there is plenty of scope for improvement. I won't claim the current trimmer behaviour is perfect, but it should be fairly easy to adapt if we find difficulties, and the architecture means it should be easy to support users without regular releases. |
255f460
to
44867b0
To me this looks very good now! |
(Rebased) I don't believe that there was anything more I intended to do with this. Considerations for the future, perhaps:
|
I just stumbled over this PR again and I still think it would be very nice to merge this! I think after all this time we can only assume that there would be no objections from objorke's side. @VisualMelon Would you rebase this to the current develop, so we could verify this with the latest changes? |
@Jonarw my main reservation is that it changes the text trimming (this could be moved to separate PR). I've not really solicited @objorke's feedback since this came to be in some sort of a stable state, so I've been keen to wait a little longer now that I've actually pinged him here. I'll get on with rebasing and retesting anyhow, |
Sorry, I am not able to follow all the conversations here at the moment. But I am very happy to see all the improvements you are implementing on the library, it is way more thorough than the original design. I agree text trimming could be a separate PR, but wouldn't object if both are merged in this one! Keep going! |
@objorke thanks for the comment. The only performance implications should be when there are large numbers of text annotations/labels/etc. with a max size that actually constrains them, otherwise it's just a big refactoring that makes everything a little more consistent. The trimming algorithm is |
Added two performance examples with ~100 items of text: trimmed in one case, not trimmed in the other. With WinForms and the WPF/Skia renderer, the trimming example is observably slower, but not significantly so. With WPF, it is significantly slower, which is a regressions as previously the trimming was just as fast. However, I can't observe any degradation in responsiveness if The cost is a function of the speed at which text is measured by the platform, and the |
I think the performance should be good enough for now. We can tweak this in the future for render contexts where we have individual glyph information and the situation with WPF should already be much better once we can go through #1609. |
Just came across some small nitpick-stuff |
@Jonarw thanks. I'd better let StyleCop have another go at it soon. |
/// <summary> | ||
/// Gets or sets a value indicating whether to squash the bounds of trimmed text to the size the text. | ||
/// </summary> | ||
public bool SquashTrimmedTextBounds { get; set; } |
This comment has been minimized.
This comment has been minimized.
Jonarw
Aug 24, 2020
Member
I can't quite figure out what exactly this property does - could this be explained a bit more clearly?
This comment has been minimized.
This comment has been minimized.
VisualMelon
Aug 29, 2020
•
Author
Contributor
I'm struggling to explain this clearly... maybe a picture will help for your benefit (obviously the documentation needs text).
This is SquashTrimmedTextBounds = true
:
This is SquashTrimmedTextBounds = false
:
Note how the text is squashed toward it's alignment dot with true
.
When true
, if text is trimmed horizontally, then the bounds are squashed to the bounds of trimmed value; otherwise they are 'clamped' to the max size. This only changes the way that the text is arranged, and looking at those two figures now, I think it should be true
. We could remove it and just treat it as true
... that would solve all my problems
This comment has been minimized.
This comment has been minimized.
VisualMelon
Aug 29, 2020
Author
Contributor
Just realised this only applies vertically... the horizontal is already bounded... I think I'll make it 'hard coded' true
instead, to reduce confusion.
(Need to fix the tests after #1645) |
Thinking about #391, do we need to be able to measure the size of trimmed text? E.g. if something asks for 3 lines of text, but only has space for 2.5 lines, we may not want it allocating the space for 2.5 lines when it could allocate space for just 2. |
This may make sense. But to be consistent, this should then also apply in the horizontal direction, i.e. it should return the actual width (including ellipsis character) and not the |
VisualMelon commentedMay 10, 2020
•
edited
Fixes #1531, #1559, and #1554
Checklist
Changes proposed in this pull request:
ITextMeasurer
interface, and implementations for all RenderContexts that can support itITextTrimmer
interface, andSimpleTextTrimmer
implementation which uses 'character ellipsis' trimming mode as its defaultTextArranger
class, which arranges multiline text as per #1554 and #1551TextArranger
for text arrangement (thereby resolving #1531 and #1559 )OxyPlot.ImageSharp
with additional testsUseVerticalAlignmentWorkaround
property fromOxyPlot.Svg
as it is redundant and will only get in the wayBig Issues
ITextTrimmer
is weak: the render context determines the type of trimming that is done, which may not be ideal@oxyplot/admins