Updated required gems, reimplemented text wrapping to use a proper binary search and correct inserting newlines in the wrong spot for certain text lengths

This commit is contained in:
2021-11-16 23:35:49 -06:00
parent 0aa9b59316
commit a915a25699
2 changed files with 35 additions and 29 deletions

View File

@@ -27,8 +27,8 @@ Gem::Specification.new do |spec|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
spec.require_paths = %w[lib assets]
spec.add_dependency "clipboard", "~> 1.3.5"
spec.add_dependency "excon", "~> 0.78.0"
spec.add_dependency "clipboard", "~> 1.3"
spec.add_dependency "excon", "~> 0.88"
spec.add_dependency "gosu", "~> 1.1"
spec.add_dependency "gosu_more_drawables", "~> 0.3"
# spec.add_dependency "ffi", :platforms => [:mswin, :mingw] # Required by Clipboard on Windows

View File

@@ -66,41 +66,47 @@ module CyberarmEngine
wrap_behavior = style.text_wrap
copy = @raw_text.to_s.dup
if line_width(copy[0]) <= max_width && line_width(copy) > max_width && wrap_behavior != :none
breaks = []
# Only perform text wrapping: if it is enabled, is possible to wrap, and text is too long to fit on one line
if wrap_behavior != :none && line_width(copy[0]) <= max_width && line_width(copy) > max_width
breaks = [] # list of indexes to insert a line break
line_start = 0
line_end = copy.length
line_end = copy.length
while line_start != copy.length
if line_width(copy[line_start...line_end]) > max_width
line_end = ((line_end - line_start) / 2.0)
line_end = 1.0 if line_end <= 1
elsif line_end < copy.length && line_width(copy[line_start...line_end + 1]) < max_width
# To small, grow!
# TODO: find a more efficient way
line_end += 1
# find length of lines
while line_width(copy[line_start..line_end]) > max_width
search_start = line_start
search_end = line_end
else # FOUND IT!
entering_line_end = line_end.floor
max_reach = line_end.floor - line_start < 63 ? line_end.floor - line_start : 63
reach = 0
# Perform a binary search to find length of line
while search_start < search_end
midpoint = ((search_start.to_f + search_end) / 2.0).floor
if wrap_behavior == :word_wrap
max_reach.times do |i|
reach = i
break if copy[line_end.floor - i].to_s.match(/[[:punct:]]| /)
if line_width(copy[line_start..midpoint]) > max_width
search_end = midpoint
else
search_start = midpoint + 1
end
end
if wrap_behavior == :word_wrap
word_search_end = search_end
failed = false
until(copy[word_search_end].to_s.match(/[[:punct:]]| /))
word_search_end -= 1
if word_search_end <= 1 || word_search_end < line_start
failed = true
break
end
# puts "Max width: #{max_width}/#{line_width(@raw_text)} Reach: {#{reach}/#{max_reach}} Line Start: #{line_start}/#{line_end.floor} (#{copy.length}|#{@raw_text.length}) [#{entering_line_end}] '#{copy}' {#{copy[line_start...line_end]}}"
line_end = line_end.floor - reach + 1 if reach != max_reach # Add +1 to walk in front of punctuation
end
breaks << line_end.floor
line_start = line_end.floor
line_end = copy.length
break if entering_line_end == copy.length || reach == max_reach
line_start = failed ? search_end : word_search_end + 1 # walk in front of punctuation
else
line_start = search_end
end
breaks << line_start
end
breaks.each_with_index do |pos, index|