November 28, 2020, 02:26:10 PM

Author Topic: [bmx] Word wrap by Pineapple [ 1+ years ago ]  (Read 761 times)

Offline BlitzBot

  • Jr. Member
  • **
  • Posts: 1
[bmx] Word wrap by Pineapple [ 1+ years ago ]
« on: June 29, 2017, 12:28:43 AM »
Title : Word wrap
Author : Pineapple
Posted : 1+ years ago

Description : Function takes a string and a width in pixels as arguments, returns a list of word-wrapped lines.

Code :
Code: BlitzMax
  1. '       --+-----------------------------------------------------------------------------------------+--
  2. '         |   This code was originally written by Sophie Kirschner (sophiek@pineapplemachine.com)   |  
  3. '         | It is released as public domain. Please don't interpret that as liberty to claim credit |  
  4. '         |   that isn't yours, or to sell this code when it could otherwise be obtained for free   |  
  5. '         |                because that would be a really shitty thing of you to do.                |
  6. '       --+-----------------------------------------------------------------------------------------+--
  7.  
  8. SuperStrict
  9.  
  10. Import brl.linkedlist
  11. Import brl.max2d
  12.  
  13. ' How different characters are treated can be modified with these.
  14.  
  15. Global _wrap_space%[]=[32] ' Spaces: good for ending a line on
  16. Global _wrap_hyphen%[]=[45] ' Hyphen: only good for ending a line on if surrounded by non-special characters (i.e. letters, like a normal hyphen rather than a dash.)
  17. Global _wrap_newline%[]=[10,255] ' Newline: newlines
  18. Global _wrap_roughcut%=_wrap_hyphen[0] ' Which character to use to show that a word has been interrupted.
  19.  
  20. ' Returns a list of strings that are single, sequential, word-wrapped lines of the passed string.
  21. ' str           -       the string to be word-wrapped
  22. ' maxwidth      -       the maximum number of pixels that a line is allowed to be wide
  23. ' charwidth     -       a function that takes an integer ascii value and returns a character width.
  24. '                       the default thing should be sufficient if you're using regular old blitzmax
  25. '                       drawtext, but if you're using bitmap fonts or anything else funny, you might
  26. '                       want write a different one.
  27. ' maxcutoff     -       this is the maximum number of characters to scan backward to find a space
  28. '                       or hyphen to cleanly end a line on before settling with a mid-word hyphenation.
  29. '                       for convenience, set to -1 to default to the global value that can be
  30. '                       modified whenever.
  31.  
  32. Function _wrap_charwidth%(char%) ' See above (charwidth argument)
  33.         Return TextWidth(Chr(char))
  34. End Function
  35.  
  36. Global _wrap_maxcutoff%=9 ' Also see above (maxcutoff argument)
  37.  
  38. Function WrapString:TList(str$ Var,maxwidth%,charwidth%(char%)=_wrap_charwidth,maxcutoff%=-1)
  39.         If maxcutoff=-1 Then maxcutoff=_wrap_maxcutoff
  40.         Local pos%=0,linew%=0
  41.         Local basepos%=0
  42.         Local list:TList=CreateList()
  43.         Repeat
  44.                 If pos<str.length Then linew:+charwidth(str[pos])
  45.                 If _numinarray(str[pos],_wrap_newline)
  46.                         Local line$=""
  47.                         For Local i%=basepos Until pos
  48.                                 line:+Chr(str[i])
  49.                         Next
  50.                         list.addlast line
  51.                         basepos=pos+1
  52.                         pos=basepos
  53.                         linew=0
  54.                 ElseIf linew>maxwidth Then
  55.                         Local cutoff%=pos-1
  56.                         Local goodcut%=False,skipaspace%=False
  57.                         While cutoff>basepos And pos-cutoff<maxcutoff
  58.                                 If _numinarray(str,_wrap_space) Or _wrappablehyphen(str,cutoff) Then
  59.                                         goodcut=True
  60.                                         Exit
  61.                                 EndIf
  62.                                 cutoff:-1                              
  63.                         Wend
  64.                         If Not goodcut Then
  65.                                 Local budget%=charwidth(_wrap_roughcut)
  66.                                 Local subbed%=0,subcount%=0
  67.                                 cutoff=pos-1
  68.                                 While subbed<budget
  69.                                         subbed:+charwidth(str)
  70.                                         subcount:+1
  71.                                         cutoff:-1
  72.                                 Wend
  73.                                 If subcount<=1 And cutoff<str.length-1-subcount And _numinarray(str[cutoff+1+subcount],_wrap_space) Then
  74.                                         goodcut=True
  75.                                         skipaspace=True
  76.                                         cutoff:+subcount
  77.                                 EndIf
  78.                         EndIf
  79.                         Local line$=""
  80.                         For Local i%=basepos To cutoff
  81.                                 line:+Chr(str[i])
  82.                         Next
  83.                         If Not goodcut Then
  84.                                 line:+Chr(_wrap_roughcut)
  85.                         EndIf
  86.                         list.addlast line
  87.                         basepos=cutoff+1+skipaspace
  88.                         pos=basepos
  89.                         linew=0
  90.                 Else
  91.                         pos:+1
  92.                         If pos>=str.length Then
  93.                                 Local line$=""
  94.                                 For Local i%=basepos Until str.length
  95.                                         line:+Chr(str[i])
  96.                                 Next
  97.                                 list.addlast line
  98.                                 Exit
  99.                         EndIf
  100.                 EndIf
  101.         Forever
  102.         Return list
  103. End Function
  104. ' used by WrapString. checks if an int is in an int array.
  105. Function _numinarray%(i%,a%[])
  106.         For Local c%=EachIn a
  107.                 If i=c Return True
  108.         Next
  109.         Return False
  110. End Function
  111. ' used by WrapString. checks if a hyphen is surrounded by not-special characters, presumably letters.
  112. Function _wrappablehyphen%(str$ Var,pos%)
  113.         If pos<=0 Or pos>=str.length-1 Then Return False
  114.         If Not _numinarray(str[pos],_wrap_hyphen) Then Return False
  115.         Local disqbefore%=_numinarray(str[pos-1],_wrap_hyphen) Or _numinarray(str[pos-1],_wrap_space) Or _numinarray(str[pos-1],_wrap_newline)
  116.         Local disqafter%=_numinarray(str[pos+1],_wrap_hyphen) Or _numinarray(str[pos+1],_wrap_space) Or _numinarray(str[pos+1],_wrap_newline)
  117.         Return Not(disqbefore Or disqafter)
  118. End Function
  119.  
  120.  
  121.  
  122. ' Example code
  123.  
  124. Rem
  125.  
  126. Graphics 320,320
  127. Local str$="Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. " ..
  128.         + "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. " ..
  129.         + "Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. " ..
  130.         + "Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
  131.        
  132. Local list:TList=wrapstring(str,300)
  133.  
  134. Repeat
  135.         Cls
  136.        
  137.         Local y%=10
  138.         For Local s$=EachIn list
  139.                 DrawText s,10,y
  140.                 y:+20
  141.         Next
  142.        
  143.         Flip
  144.         Delay 20
  145. Until KeyDown(27) Or AppTerminate()
  146.  
  147. EndRem


Comments : none...

 

SimplePortal 2.3.6 © 2008-2014, SimplePortal