Word Wrap - Simple Version #1
BlitzMax Forums/BlitzMax Programming/Word Wrap - Simple Version #1
| ||
Since I haven't seen any code on the forums for this type of routine that actually works, here is a good word wrap routine that works, and works well. Version #1 can easily be adapted to most any type of application. This code is released into Public Domain. If anyone finds any bugs or gotch-ya's! please let me know either here, or by email. Have fun, Shortwind SuperStrict Local a:String="This string is very long and we (x+y=34*sqr(z)/cos(r)*pi+(x*y)/87) will test various length texts."+.. " To test these functions for proper goodness is the stuff of dreams. And "+.. "the dreams are (x+y=34*sqr(z)/cos(r)*pi+(x*y)/87) here and not there. But what if the dreams and here"+.. " and not there? Well, if the first and second part are not in the third part then the third part is "+.. "not the circle of the square. But sometimes things are not as they seem. Even though the seem is there,"+.. "it may not be there when we look into the seemingly endlessness of space and time... Oh, but there is"+.. "no time like the present even though there is no present in the time of the timeness that is time." Local boxwidth:Int=20 DoMyWrap(a,boxwidth) End '------------------Start of Function ---------------------------- Function DoMyWrap(a:String, width:Int) Local s:Int, e:Int s=1 e=width While s<Len(a) If Len(a)<e Then Print a Exit ElseIf s+e>=Len(a) Then Print Mid(a,s) Exit End If While Mid(a,s+e,1)<>" " And e>0 e=e-1 Wend If e=0 Then Print Mid(a,s,width) s=s+width e=width Else Print Mid(a,s,e) s=s+e+1 e=width End If Wend End Function |
| ||
They have a place for folks like you... it's called the Code Archives. Muhahaha! Here is the Algorithm section, just click on the "Add to..." link at the top. http://www.blitzbasic.com/codearcs/codearcs.php?cat=6 |
| ||
It'd be more practical to return a word wrapped string. Then everyone can decide whether to print to the console (which I only use for debugging) or to do something else with it (draw into a canvas?).. |
| ||
This one peels the lines out of the original text and passes the lines back as wrapped strings.Local a:String="This string is very long and we (x+y=34*sqr(z)/cos(r)*pi+(x*y)/87) will test various length texts."+.. " To test these functions for proper goodness is the stuff of dreams. And "+.. "the dreams are (x+y=34*sqr(z)/cos(r)*pi+(x*y)/87) here and not there. But what if the dreams and here"+.. " and not there? Well, if the first and second part are not in the third part then the third part is "+.. "not the circle of the square. But sometimes things are not as they seem. Even though the seem is there,"+.. "it may not be there when we look into the seemingly endlessness of space and time... Oh, but there is"+.. "no time like the present even though there is no present in the time of the timeness that is time." Local display:String=a Repeat Local txt:String=Wrapper(display,30) Print txt Until txt="" Function Wrapper:String(text:String Var,width:Int) Local result:String If Len(text)>width Local spotcheck:Int=width Local char:String Repeat spotcheck:-1 char=Mid(text,spotcheck,1) Until char=" " Or spotcheck=0 If spotcheck=0 ' no breaks result=Left(text,width) text=Right(text,Len(text)-width) Else result=Left(text,spotcheck-1) text=Right(text,Len(text)-spotcheck) End If Else result=text text="" End If Return result End Function |
| ||
@CS_TBL, I did say: Version #1 can easily be adapted... (LOL) @_Skully, Impressive, but I actually found a design flaw in your code, and my own. (Plus, in the current configuration of your code, mine and yours don't print the same. Yours seems to be breaking on a space early or something.... Run them side by side and you'll see what I mean.) Anyway... It's a matter of astectics I suppose, but in the very beginning of the example string, when it reaches the long word that will not fit on the line, it should not make a new line, but print what it can on the current line, and then continue. Currently both our code doesn't do this. An example: (Here is how it works now....) This string is very long and we (x+y=34*sqr(z)/cos(r)*pi+(x*y) /87) will test various length ... But it probably should be like this... This string is very long and we (x+y=34*sqr(z)/cos(r)*pi+(x *y)/87) will test various length ... This isn't really a big deal, it just looks funny when it is displayed. I suppose there should be a look-ahead to see if the non-spaced-word is longer then the current window size. Or maybe there is an easier way. :O :) |
| ||
LOL. OH! MY! GOD! LOL Now my brain hurts trying to get this thing fixed. ha hah aha ha... |
| ||
Version #1 can easily be adapted... (LOL) Yes, that's why I launched the string-return suggestion, so that someone could implement it! :P |
| ||
Just written text-wrapping code myself. Its heavily integrated into my bitmap font class so I can't really post any of it right now. Basically I have a function which chops a long line of text up into lines of no more than X pixels wide. It first cuts the text into individual words, and measures the pixel width of each. Then, it starts to build lines of text by adding words. If it can add the next word without the total width of the current line exceeding X pixels, it does so. If not, it puts the current line into a TList and starts a new one. It continues doing this until no words are left to add. Finally, I convert the TList to an array (I need it this way for what I'm doing - you wouldn't *have* to), and return the array to the main program. I can then draw the text any time I want without having to recalculate it all every time. The only time I would need to recalculate it from the original text, is if I wanted to change the font size, or the font itself. But I never need to do this anyway. |
| ||
{edit} oops.. posted messed code lol |
| ||
I know this thread is a few years out of date, but I ran across it while trying to find a simple word wrap, but I don't use BlitzMax so rewrote this to run in simple .bb format. It does have one glaring problem, however. If any 1 "word" is larger than the width value then it crashes to error. Thanks for the original code! It really helped me for what I'm working on. a$ = "This string is very long and we (x+y=34*sqr(z)/cos(r)*pi+(x*y)/87) will test various length texts." a = a + " To test these functions for proper goodness is the stuff of dreams. And " a = a + "the dreams are (x+y=34*sqr(z)/cos(r)*pi+(x*y)/87) here and not there. But what if the dreams and here" a = a + " and not there? Well, if the first and second part are not in the third part then the third part is " a = a + "not the circle of the square. But sometimes things are not as they seem. Even though the seem is there," a = a + "it may not be there when we look into the seemingly endlessness of space and time... Oh, but there is" a = a + "no time like the present even though there is no present in the time of the timeness that is time." ;BEGIN Wrapper(a,40) WaitKey() End ;END PROGRAM Function Wrapper$(Var$,width) While Var <> "" result$ = "" ;if length of string is greater than our width If Len(Var) > width spotcheck = width char$ = "" ;Look for the last space in our next 'width chunk' of the MasterText Repeat spotcheck = spotcheck - 1 char = Mid(Var,spotcheck,1) Until char = " " Or spotcheck = 0 ;didn't find a space If spotcheck = 0 result = Left(Var,width) Var = Right(Var,Len(Var) - width) ;found a space Else result = Left(Var,spotcheck - 1) Var = Right(Var,Len(Var) - spotcheck) EndIf ;length of string is less than return width so send it all back Else result=Var Var="" EndIf Print result Wend End Function |
| ||
LoL. Originally found this with a simple "word wrap" search of the site and didn't even bother to look what forum category it fell under :P Explains why it was in BlitzMax. But just in case some other .bb guy stumbles along my same path to here I'll leave it unless someone objects. |