Skip to content

Commit

Permalink
Improve line breaking algorithm
Browse files Browse the repository at this point in the history
  • Loading branch information
tevelee committed Jun 27, 2024
1 parent 7b9d20d commit 901c468
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 11 deletions.
20 changes: 10 additions & 10 deletions Sources/Flow/Internal/Layout.swift
Original file line number Diff line number Diff line change
Expand Up @@ -162,28 +162,28 @@ struct FlowLayout {

costs[0] = 0

for end in 0 ..< count {
for end in 1 ... count {
var totalBreadth: CGFloat = 0
for start in stride(from: end, through: 0, by: -1) {
for start in (0 ..< end).reversed() {
let size = sizes[start].breadth
let spacing = start > 0 && start < end ? spacings[start] : 0
let spacing = (end - start) == 1 ? 0 : spacings[start + 1]
totalBreadth += size + spacing
if totalBreadth > proposedBreadth {
break
}
let remainingSpace = proposedBreadth - totalBreadth
let penalty = abs(totalBreadth - (proposedBreadth / CGFloat(end - start + 1))) * 2
let cost = costs[start] + remainingSpace * remainingSpace + penalty
if cost < costs[end + 1] {
costs[end + 1] = cost
breaks[end + 1] = start
let bias = CGFloat(count - end) * 0.5 // Introduce a small bias to prefer breaks that fill earlier lines more
let cost = costs[start] + remainingSpace * remainingSpace + bias
if cost < costs[end] {
costs[end] = cost
breaks[end] = start
}
}
}

var breakpoints: [Int] = []
var i = count
while let breakPoint = breaks[i], breakPoint >= 0 {
while let breakPoint = breaks[i] {
breakpoints.insert(i, at: 0)
i = breakPoint
}
Expand All @@ -192,7 +192,7 @@ struct FlowLayout {
var newLines: Lines = []
for (start, end) in breakpoints.adjacentPairs() {
var line: ItemWithSpacing<Line> = .init(item: [], size: .zero)
for index in start..<end {
for index in start ..< end {
let subview = subviews[index]
let size = sizes[index]
let spacing = index == start ? 0 : spacings[index] // Reset spacing for the first item in each line
Expand Down
5 changes: 4 additions & 1 deletion Tests/FlowTests/Utils/TestSubview.swift
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,10 @@ extension FlowLayout {
)
placeSubviews(
in: CGRect(origin: .zero, size: bounds),
proposal: ProposedViewSize(width: size.width, height: size.height),
proposal: ProposedViewSize(
width: min(size.width, bounds.width),
height: min(size.height, bounds.height)
),
subviews: subviews,
cache: &cache
)
Expand Down

0 comments on commit 901c468

Please sign in to comment.