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.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
spec.require_paths = %w[lib assets] spec.require_paths = %w[lib assets]
spec.add_dependency "clipboard", "~> 1.3.5" spec.add_dependency "clipboard", "~> 1.3"
spec.add_dependency "excon", "~> 0.78.0" spec.add_dependency "excon", "~> 0.88"
spec.add_dependency "gosu", "~> 1.1" spec.add_dependency "gosu", "~> 1.1"
spec.add_dependency "gosu_more_drawables", "~> 0.3" spec.add_dependency "gosu_more_drawables", "~> 0.3"
# spec.add_dependency "ffi", :platforms => [:mswin, :mingw] # Required by Clipboard on Windows # 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 wrap_behavior = style.text_wrap
copy = @raw_text.to_s.dup copy = @raw_text.to_s.dup
if line_width(copy[0]) <= max_width && line_width(copy) > max_width && wrap_behavior != :none # Only perform text wrapping: if it is enabled, is possible to wrap, and text is too long to fit on one line
breaks = [] 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_start = 0
line_end = copy.length line_end = copy.length
while line_start != copy.length # find length of lines
if line_width(copy[line_start...line_end]) > max_width while line_width(copy[line_start..line_end]) > max_width
line_end = ((line_end - line_start) / 2.0) search_start = line_start
line_end = 1.0 if line_end <= 1 search_end = line_end
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
else # FOUND IT! # Perform a binary search to find length of line
entering_line_end = line_end.floor while search_start < search_end
max_reach = line_end.floor - line_start < 63 ? line_end.floor - line_start : 63 midpoint = ((search_start.to_f + search_end) / 2.0).floor
reach = 0
if wrap_behavior == :word_wrap if line_width(copy[line_start..midpoint]) > max_width
max_reach.times do |i| search_end = midpoint
reach = i else
break if copy[line_end.floor - i].to_s.match(/[[:punct:]]| /) 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 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 end
breaks << line_end.floor line_start = failed ? search_end : word_search_end + 1 # walk in front of punctuation
line_start = line_end.floor else
line_end = copy.length line_start = search_end
break if entering_line_end == copy.length || reach == max_reach
end end
breaks << line_start
end end
breaks.each_with_index do |pos, index| breaks.each_with_index do |pos, index|