Skip to content

Conversation

@benoitkugler
Copy link
Contributor

@benoitkugler benoitkugler commented Dec 12, 2025

This PR is a first step towards support for tabs (for #174).

The only API added is the Line.AlignTabs method which aligns all tabs of a given line.

This seems enough if you only wrap text one line at a time (typically using shaping.NewSliceIterator and Wrapper.WrapNextLine), which is my use case.

Supporting tabs when wrapping a whole paragraph seems harder, since we have to align tabs again at the start of every line. The non exported Output.applyTabs should probably be used every time we "consume" a new shaped run.

@andydotxyz
Copy link
Contributor

Supporting tabs when wrapping a whole paragraph seems harder, since we have to align tabs again at the start of every line.

An interesting point. Do we? In the work I have done elsewhere the tab alignment is referring to the first line (where the actual tab character was) and the others have a 0 offset.

However it is a little dependent on use-case and may not always follow. However a more complete solution is how many taps the first and "all others" indent as two options I think?

There is the complication also of where the run does not start at the beginning of the paragraph so the initial indent is less due to previous content rather than because of the tab characters...

@benoitkugler
Copy link
Contributor Author

An interesting point. Do we? In the work I have done elsewhere the tab alignment is referring to the first line (where the actual tab character was) and the others have a 0 offset.

Even if we keep the tab alignement defined by the first line, I think we would have to adjust tabs (that is mutate tab glyphs advances) since the wrapping might have change the relative position between runs (in the next line) and tabs grid. For instance if we cut a line in the middle of a "tab column".

@benoitkugler
Copy link
Contributor Author

There is the complication also of where the run does not start at the beginning of the paragraph so the initial indent is less due to previous content rather than because of the tab characters...

Good point. So perhaps we should add a parameter indicating the start of the first column tab, which typically defaults to 0 ?

@andydotxyz
Copy link
Contributor

An interesting point. Do we? In the work I have done elsewhere the tab alignment is referring to the first line (where the actual tab character was) and the others have a 0 offset.

Even if we keep the tab alignement defined by the first line, I think we would have to adjust tabs (that is mutate tab glyphs advances) since the wrapping might have change the relative position between runs (in the next line) and tabs grid. For instance if we cut a line in the middle of a "tab column".

I guess the challenge of the mutating advance approach is that the advance is only correct in the context of the initial offset - i.e. depending how much the first line is offset (or the paragraph) will change how the tab advance will be applied...

@andydotxyz
Copy link
Contributor

There is the complication also of where the run does not start at the beginning of the paragraph so the initial indent is less due to previous content rather than because of the tab characters...

Good point. So perhaps we should add a parameter indicating the start of the first column tab, which typically defaults to 0 ?

Yes that sounds good. Perhaps the first line is a parameter and the other lines is a second, which might cover the previous point too?

whereswaldon and others added 4 commits December 23, 2025 13:54
* [shaping] expose the space we trim when wrapping with TrimWhiteSpace enabled

* minor typos

* Replace setup-go-faster action with setup-go

* Replace setup-go-faster action with setup-go

* [shaping] expose the space we trim when wrapping with TrimWhiteSpace enabled

* minor typos

* remove debug fmt.Println
@benoitkugler
Copy link
Contributor Author

So, we now have func (l Line) AlignTabs(text []rune, columnWidth, lineOffset fixed.Int26_6).
This method is intended for simple one by one line wrapping; supporting whole paragraph layout is a future work.

Copy link
Contributor

@andydotxyz andydotxyz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me, and the tests appear correct.
I have not had a chance to test it in any real usage, but hope to in a while to see if we can move off the Fyne-specific wrapping.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants