enakomeren prelom vrstic
This commit is contained in:
67
projector.py
67
projector.py
@@ -239,30 +239,81 @@ class SongProjector:
|
|||||||
"""
|
"""
|
||||||
Vrne seznam pod-vrstic, ki skupaj tvorijo `line`,
|
Vrne seznam pod-vrstic, ki skupaj tvorijo `line`,
|
||||||
pri čemer so dolge največ `self.color_width` pikslov.
|
pri čemer so dolge največ `self.color_width` pikslov.
|
||||||
|
Namesto preprostega 'greedy' preloma izračuna število delov
|
||||||
|
in poskuša narediti vrstice podobnih dolžin.
|
||||||
"""
|
"""
|
||||||
words = line.split()
|
words = line.split()
|
||||||
if not words:
|
if not words:
|
||||||
return [""]
|
return [""]
|
||||||
|
|
||||||
sub_lines = []
|
total_width = self.custom_font.measure(line)
|
||||||
current_words = []
|
if total_width <= self.color_width:
|
||||||
|
return [line]
|
||||||
|
|
||||||
|
# Izračunamo, na koliko delov moramo prelomiti vrstico
|
||||||
|
num_parts = (total_width // self.color_width) + 1
|
||||||
|
|
||||||
|
# Če je num_parts še vedno premalo (zaradi presledkov), preverimo z greedy
|
||||||
|
temp_sub_lines = []
|
||||||
|
current_words = []
|
||||||
for word in words:
|
for word in words:
|
||||||
test_line = " ".join(current_words + [word])
|
test_line = " ".join(current_words + [word])
|
||||||
# Izmerimo širino v pikslih
|
|
||||||
if self.custom_font.measure(test_line) <= self.color_width:
|
if self.custom_font.measure(test_line) <= self.color_width:
|
||||||
current_words.append(word)
|
current_words.append(word)
|
||||||
else:
|
else:
|
||||||
if current_words:
|
if current_words:
|
||||||
sub_lines.append(" ".join(current_words))
|
temp_sub_lines.append(" ".join(current_words))
|
||||||
current_words = [word]
|
current_words = [word]
|
||||||
else:
|
else:
|
||||||
# Beseda je sama po sebi predolga (zelo redko)
|
temp_sub_lines.append(word)
|
||||||
sub_lines.append(word)
|
|
||||||
current_words = []
|
current_words = []
|
||||||
|
|
||||||
if current_words:
|
if current_words:
|
||||||
sub_lines.append(" ".join(current_words))
|
temp_sub_lines.append(" ".join(current_words))
|
||||||
|
|
||||||
|
num_parts = max(num_parts, len(temp_sub_lines))
|
||||||
|
if num_parts <= 1:
|
||||||
|
return [line]
|
||||||
|
|
||||||
|
# Ciljna dolžina vsakega dela
|
||||||
|
target_width = total_width / num_parts
|
||||||
|
|
||||||
|
sub_lines = []
|
||||||
|
remaining_words = words
|
||||||
|
|
||||||
|
# Porazdelimo besede tako, da so vrstice čim bolj enakomerne
|
||||||
|
for i in range(num_parts - 1):
|
||||||
|
best_split_idx = 1
|
||||||
|
min_diff = float('inf')
|
||||||
|
|
||||||
|
for j in range(1, len(remaining_words)):
|
||||||
|
test_line = " ".join(remaining_words[:j])
|
||||||
|
width = self.custom_font.measure(test_line)
|
||||||
|
|
||||||
|
if width > self.color_width:
|
||||||
|
break
|
||||||
|
|
||||||
|
diff = abs(width - target_width)
|
||||||
|
if diff < min_diff:
|
||||||
|
min_diff = diff
|
||||||
|
best_split_idx = j
|
||||||
|
else:
|
||||||
|
# Ker širina narašča, ko se enkrat začne diff povečevati,
|
||||||
|
# smo našli lokalni minimum za to vrstico
|
||||||
|
break
|
||||||
|
|
||||||
|
sub_lines.append(" ".join(remaining_words[:best_split_idx]))
|
||||||
|
remaining_words = remaining_words[best_split_idx:]
|
||||||
|
if not remaining_words:
|
||||||
|
break
|
||||||
|
|
||||||
|
if remaining_words:
|
||||||
|
# Zadnji del (lahko je še vedno predolg, če so bile prejšnje vrstice prekratke)
|
||||||
|
last_line = " ".join(remaining_words)
|
||||||
|
if self.custom_font.measure(last_line) <= self.color_width:
|
||||||
|
sub_lines.append(last_line)
|
||||||
|
else:
|
||||||
|
# Če je zadnji del še vedno predolg, ga rekurzivno razbijemo (varnostni mehanizem)
|
||||||
|
sub_lines.extend(self.split_long_line(last_line))
|
||||||
|
|
||||||
return sub_lines
|
return sub_lines
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user