openpilot is an open source driver assistance system. openpilot performs the functions of Automated Lane Centering and Adaptive Cruise Control for over 200 supported car makes and models.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

103 lines
2.7 KiB

import pyray as rl
from openpilot.system.ui.lib.text_measure import measure_text_cached
def _break_long_word(font: rl.Font, word: str, font_size: int, max_width: int) -> list[str]:
if not word:
return []
parts = []
remaining = word
while remaining:
if measure_text_cached(font, remaining, font_size).x <= max_width:
parts.append(remaining)
break
# Binary search for the longest substring that fits
left, right = 1, len(remaining)
best_fit = 1
while left <= right:
mid = (left + right) // 2
substring = remaining[:mid]
width = measure_text_cached(font, substring, font_size).x
if width <= max_width:
best_fit = mid
left = mid + 1
else:
right = mid - 1
# Add the part that fits
parts.append(remaining[:best_fit])
remaining = remaining[best_fit:]
return parts
def wrap_text(font: rl.Font, text: str, font_size: int, max_width: int) -> list[str]:
if not text or max_width <= 0:
return []
# Split text by newlines first to preserve explicit line breaks
paragraphs = text.split('\n')
all_lines: list[str] = []
for paragraph in paragraphs:
# Handle empty paragraphs (preserve empty lines)
if not paragraph.strip():
all_lines.append("")
continue
# Process each paragraph separately
words = paragraph.split()
if not words:
all_lines.append("")
continue
lines: list[str] = []
current_line: list[str] = []
current_width = 0
space_width = int(measure_text_cached(font, " ", font_size).x)
for word in words:
word_width = int(measure_text_cached(font, word, font_size).x)
# Check if word alone exceeds max width (need to break the word)
if word_width > max_width:
# Finish current line if it has content
if current_line:
lines.append(" ".join(current_line))
current_line = []
current_width = 0
# Break the long word into parts
lines.extend(_break_long_word(font, word, font_size, max_width))
continue
# Calculate width if we add this word
needed_width = current_width
if current_line: # Need space before word
needed_width += space_width
needed_width += word_width
# Check if word fits on current line
if needed_width <= max_width:
current_line.append(word)
current_width = needed_width
else:
# Start new line with this word
if current_line:
lines.append(" ".join(current_line))
current_line = [word]
current_width = word_width
# Add remaining words
if current_line:
lines.append(" ".join(current_line))
# Add all lines from this paragraph
all_lines.extend(lines)
return all_lines