Skip to content

Commit

Permalink
Avoid calling theme function in RichText too often as it is costly.
Browse files Browse the repository at this point in the history
This reduce the time spend in lock from 6% to 4% which is not
negligeable. From the trace, it seems that we are taking the RichText
propertyLock to often and that cause another 2 points. Another PR should
review those and reduce the amount of time calling the locking
mechanism.
  • Loading branch information
Cedric BAIL committed Apr 13, 2023
1 parent 3d70ce5 commit 48fc8e4
Showing 1 changed file with 21 additions and 9 deletions.
30 changes: 21 additions & 9 deletions widget/richtext.go
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,8 @@ func (t *RichText) rows() int {
func (t *RichText) updateRowBounds() {
t.propertyLock.RLock()
var bounds []rowBoundary
maxWidth := t.size.Width - 2*theme.InnerPadding() + 2*t.inset.Width
innerPadding := theme.InnerPadding()
maxWidth := t.size.Width - 2*innerPadding + 2*t.inset.Width
wrapWidth := maxWidth

var iterateSegments func(segList []RichTextSegment)
Expand Down Expand Up @@ -384,7 +385,7 @@ func (t *RichText) updateRowBounds() {

leftPad := float32(0)
if textSeg.Style == RichTextStyleBlockquote {
leftPad = theme.InnerPadding() * 2
leftPad = innerPadding * 2
}
retBounds := lineBounds(textSeg, t.Wrapping, wrapWidth-leftPad, maxWidth, func(text []rune) float32 {
return fyne.MeasureText(string(text), textSize, textStyle).Width
Expand Down Expand Up @@ -459,8 +460,12 @@ func (r *textRenderer) Layout(size fyne.Size) {
}
r.obj.propertyLock.RUnlock()

left := theme.InnerPadding() - r.obj.inset.Width
yPos := theme.InnerPadding() - r.obj.inset.Height
// Accessing theme here is slow, so we cache the value
innerPadding := theme.InnerPadding()
lineSpacing := theme.LineSpacing()

left := innerPadding - r.obj.inset.Width
yPos := innerPadding - r.obj.inset.Height
lineWidth := size.Width - left*2
var rowItems []fyne.CanvasObject
rowAlign := fyne.TextAlignLeading
Expand All @@ -483,7 +488,7 @@ func (r *textRenderer) Layout(size fyne.Size) {

obj.Move(fyne.NewPos(left, yPos))
obj.Resize(fyne.NewSize(lineWidth, height))
yPos += height + theme.LineSpacing()
yPos += height + lineSpacing
continue
}
rowItems = append(rowItems, obj)
Expand All @@ -495,7 +500,7 @@ func (r *textRenderer) Layout(size fyne.Size) {
if text, ok := bound.segments[0].(*TextSegment); ok {
rowAlign = text.Style.Alignment
if text.Style == RichTextStyleBlockquote {
leftPad = theme.LineSpacing() * 4
leftPad = lineSpacing * 4
}
} else if link, ok := bound.segments[0].(*HyperlinkSegment); ok {
rowAlign = link.Alignment
Expand All @@ -507,7 +512,7 @@ func (r *textRenderer) Layout(size fyne.Size) {

lastSeg := bound.segments[len(bound.segments)-1]
if !lastSeg.Inline() && row < len(bounds)-1 && bounds[row+1].segments[0] != lastSeg { // ignore wrapped lines etc
yPos += theme.LineSpacing()
yPos += lineSpacing
}
}
}
Expand All @@ -530,6 +535,9 @@ func (r *textRenderer) MinSize() fyne.Size {
rowHeight := float32(0)
rowWidth := float32(0)

// Accessing the theme here is slow, so we cache the value
lineSpacing := theme.LineSpacing()

i := 0
for row, bound := range bounds {
for range bound.segments {
Expand Down Expand Up @@ -559,7 +567,7 @@ func (r *textRenderer) MinSize() fyne.Size {

lastSeg := bound.segments[len(bound.segments)-1]
if !lastSeg.Inline() && row < len(bounds)-1 && bounds[row+1].segments[0] != lastSeg { // ignore wrapped lines etc
height += theme.LineSpacing()
height += lineSpacing
}
}

Expand Down Expand Up @@ -670,6 +678,10 @@ func (r *textRenderer) layoutRow(texts []fyne.CanvasObject, align fyne.TextAlign
tallestBaseline := float32(0)
realign := false
baselines := make([]float32, len(texts))

// Access to theme is slow, so we cache the text size
textSize := theme.TextSize()

for i, text := range texts {
var size fyne.Size
if txt, ok := text.(*canvas.Text); ok {
Expand All @@ -685,7 +697,7 @@ func (r *textRenderer) layoutRow(texts []fyne.CanvasObject, align fyne.TextAlign
} else if c, ok := text.(*fyne.Container); ok {
wid := c.Objects[0]
if link, ok := wid.(*Hyperlink); ok {
s, base := fyne.CurrentApp().Driver().RenderedTextSize(link.Text, theme.TextSize(), link.TextStyle)
s, base := fyne.CurrentApp().Driver().RenderedTextSize(link.Text, textSize, link.TextStyle)
if base > tallestBaseline {
if tallestBaseline > 0 {
realign = true
Expand Down

0 comments on commit 48fc8e4

Please sign in to comment.