# Loooong wordwrap

**URL:** <https://www.ruby-forum.com/t/loooong-wordwrap/174651>\
**Category:** Ruby\
**Created:** [August 31, 2009, 4:37am UTC](https://www.ruby-forum.com/t/loooong-wordwrap/174651 "2009-08-31T04:37:17Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![artrat](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/b2d939/32.png) [@artrat](https://www.ruby-forum.com/u/artrat)\
**Post date:** [August 31, 2009, 4:37am UTC](https://www.ruby-forum.com/t/loooong-wordwrap/174651/1 "2009-08-31T04:37:17Z")

</div>

Hi all,

I’m certainly finding this a fun challenge but wanted to know if anyonw  
can help

I’m trying to wrap long words that have no spaces, but only the  
application is a game and I need to wrap a word based on its true pixel  
font width and place this into an array of lines, only that I pass to  
method the width in pixels that I need to wrap against.

for a game I;m trying to build (Gosu lib)

font.text\_width is the true pixel length of the string  
width is in pixels  
text is a string

i.e.

def wordwrap(text,width,font)  
words = text.split(’ ')  
lines = [words.shift]  
words.each do |word|  
if font.text\_width("#{lines[-1]} #{word}") \< width  
lines[-1] \<\< ’ ’ \<\< word  
else

```
    lines.push(word)
  end
end

```

####I have loooooooooong word that needs wrapping  
if (text.index(’ ').nil? and font.text\_width(text) \> width)

```
        ## I need to chop the string into parts so I have an array

```

of lines all measuring the “width” pixel width

```
end

```

end

Could somebody help, I really have tried many ways and coming from PHP  
I’m not too sure of how to do this in Ruby

Thanks!!  
Art

---

<div class="post-metadata">

**Author:** ![artrat](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/b2d939/32.png) [@artrat](https://www.ruby-forum.com/u/artrat)\
**Post date:** [August 31, 2009, 7:37am UTC](https://www.ruby-forum.com/t/loooong-wordwrap/174651/2 "2009-08-31T07:37:32Z")

</div>

On Sunday 30 August 2009 09:51:57 pm Arthur R. wrote:

> Also this method wordwrap is called everysingle keystroke and 60 times a  
> second (60 FPS)

I’m not sure how that makes sense. Ok, yes, after every keystroke, but  
if the  
method is too much, couldn’t you cache the resultant image, or  
triangles, or  
scene, or even just text, until the user presses another key?

---

<div class="post-metadata">

**Author:** ![artrat](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/b2d939/32.png) [@artrat](https://www.ruby-forum.com/u/artrat)\
**Post date:** [August 31, 2009, 4:51am UTC](https://www.ruby-forum.com/t/loooong-wordwrap/174651/3 "2009-08-31T04:51:55Z")

</div>

Also this method wordwrap is called everysingle keystroke and 60 times a  
second (60 FPS) not like a web app where you would call the method after  
the user has finised entering the text. so its a little tricky!!

---

<div class="post-metadata">

**Author:** ![artrat](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/b2d939/32.png) [@artrat](https://www.ruby-forum.com/u/artrat)\
**Post date:** [August 31, 2009, 2:04pm UTC](https://www.ruby-forum.com/t/loooong-wordwrap/174651/4 "2009-08-31T14:04:33Z")

</div>

def wordwrap(textinput,width,font)  
lines=[]  
if (textinput.text.index(’ ').nil? and  
font.text\_width(textinput.text) \> width)  
no\_lines=font.text\_width(textinput.text)/width  
b = no\_lines.ceil  
no\_chars=textinput.caret\_pos  
no\_each\_line=(textinput.caret\_pos / b).ceil  
for i in 1…b do  
if i \< b  
lines.push(textinput.text.slice((i-1)\*no\_each\_line.to\_i,no\_each\_line))  
else  
lines.push(textinput.text.slice((i-1)\*no\_each\_line.to\_i,no\_each\_line+b))  
end  
end  
else

```
    words = textinput.text.split(' ')
    lines = [words.shift]
    words.each do |word|
      if font.text_width("#{lines[-1]} #{word}") < width
        lines[-1] << ' ' << word
      else
        lines.push(word)
      end
    end
end
return lines

```

end

something like this - is what I need to do but I am chopping the text in  
to equal parts to make it fit into lines within the box,
