vJASS & Zinc Documentation
For the latest documentation about how it works vJASS and Zinc language layers for Warcraft III, please follow these links:
Jasshelper documentation - Zinc documentation - WC3 Optimizer documentation

[System] WordWrap

Purgeandfire · 13347

0 Members and 1 Guest are viewing this topic.

[System] WordWrap
on: August 17, 2012, 01:02:38 AM
Category: String handling
Language: vJASS

Related Topics or Resources



by

http://en.wikipedia.org/wiki/Word_wrapping

This is not as featured/precise as text editor word wrapping, but it does the job pretty well.

The description is in the documentation.

Code: jass
  1. library WordWrap /* v2.1.0.0
  2. *********************************************************************
  3. *
  4. *  Simulates word wrapping for multiboards and texttags.
  5. *  Word wrapping is where, if a text is too long, it will
  6. *  cut to the next line rather than cutting off the text.
  7. *
  8. *  How it works:
  9. *
  10. *      - Specify a source string and a size margin. The margin
  11. *        determines what the size of the line can be before it
  12. *        splits the string into fragments. The value is more or
  13. *        less arbritrary, so just experiment with values.
  14. *      - Explodes the string by spaces into words.
  15. *      - Checks the size of each word.
  16. *      - Once the size margin is reached, it will cut the string.
  17. *      - The first line is stored in the array under the index 0.
  18. *      - Rinse and repeat until it fragments the entire string.
  19. *      - You can retrieve the count to know the max index reached.
  20. *
  21. *********************************************************************
  22. *
  23. *   */uses/*
  24. *  
  25. *       */ StringSize /*  http://wc3jass.com/5014/snippet-stringsize/
  26. *
  27. *    This library does not require Ascii, but StringSize requires
  28. *    the Ascii library:
  29. *
  30. *
  31. *********************************************************************
  32. *
  33. *  function WordWrapString takes string source, real sizeMargin, boolean preserveColors returns nothing
  34. *
  35. *      - Breaks the string into several fragments.
  36. *      - Size margin determines the size the string can reach
  37. *        before it fragments the string and breaks to the next
  38. *        line.
  39. *      - Preserve colors is a boolean to check if a color
  40. *        code is being broken during the word wrap. If you
  41. *        are not using color codes (ex: |cffffcc00text|r)
  42. *        then you should set this to false to save performance.
  43. *
  44. *  function GetWrappedStringFragment takes integer index returns string
  45. *
  46. *      - Retrieves the fragmented strings. The indices start at 0
  47. *        and will go up to the "count" index - 1. (see below) The last
  48. *        line will be:
  49. *
  50. *          GetWrappedStringFragment(GetWrappedStringCount() - 1)
  51. *
  52. *  function GetWrappedStringCount takes nothing returns integer
  53. *
  54. *      - Returns the total number of fragments. Indices start at 0,
  55. *        and the final line will be this number minus 1.
  56. *
  57. *********************************************************************
  58. *
  59. *  struct WordWrap
  60. *
  61. *      static method getLine takes integer index returns string
  62. *
  63. *      static method getCount takes nothing returns integer
  64. *
  65. *      static method create takes string source, real sizeMargin, boolean preserveColors returns thistype
  66. *
  67. *********************************************************************
  68. *
  69. *  Credits
  70. *
  71. *      - cleeezzz & tooltiperror for the idea.
  72. *
  73. *  Bugs
  74. *
  75. *      - If there is a single word that is longer than the
  76. *        "sizeMargin" input, then this system will fail.
  77. *        It requires extra checks. I may update this later
  78. *        to fix that problem, but for now this should be fine.
  79. *        PM or message me if you have any problems.
  80. *
  81. *********************************************************************/
  82.  
  83.     struct WordWrap extends array
  84.         private static string array line
  85.         private static integer count = 0
  86.  
  87.         static method getLine takes integer index returns string
  88.             return line[index]
  89.         endmethod
  90.        
  91.         static method getCount takes nothing returns integer
  92.             return count
  93.         endmethod
  94.        
  95.         private static method preserveColor takes nothing returns nothing
  96.             local integer i = 0
  97.             local integer k = 0
  98.             local integer l = 0
  99.             local string temp = ""
  100.             local string hex = ""
  101.             local boolean carryOn = false
  102.             loop
  103.                 exitwhen i == count
  104.                 set carryOn = false
  105.                 set hex = ""
  106.                 set k = 0
  107.                 set l = StringLength(line[i])
  108.                 loop
  109.                     exitwhen k == l
  110.                     set temp = SubString(line[i], k, k+1)
  111.                     if temp == "|" then
  112.                         set temp = SubString(line[i], k+1, k+2)
  113.                         if temp == "c" then
  114.                             set hex = SubString(line[i], k, k+10)
  115.                             set carryOn = true
  116.                         elseif temp == "r" then
  117.                             set carryOn = false
  118.                         endif
  119.                     endif
  120.                     set k = k + 1
  121.                 endloop
  122.                 set i = i + 1
  123.                 if carryOn then
  124.                     set line[i] = hex + line[i]
  125.                 endif
  126.             endloop
  127.         endmethod
  128.        
  129.         static method create takes string source, real size, boolean preserveColors returns thistype
  130.             local integer l = StringLength(source)
  131.             local integer i = 0
  132.             local integer k = 0
  133.             local string s
  134.            
  135.             local string word
  136.             local real result = 0
  137.             local real ssize = 0
  138.            
  139.             loop
  140.                 exitwhen count == 0
  141.                 set count = count - 1
  142.                 set line[count] = ""
  143.             endloop
  144.             loop
  145.                 exitwhen i == l
  146.                 set s = SubString(source, i, i+1)
  147.                 if s == " " or i == (l-1) then
  148.                     set word = SubString(source, k, i) + s
  149.                     set ssize = MeasureString(word)
  150.                     set result = result + ssize
  151.                     if result <= size then
  152.                         set line[count] = line[count] + word
  153.                     else
  154.                         set count = count + 1
  155.                         set line[count] = word
  156.                         set result = ssize
  157.                     endif
  158.                     set k = i + 1
  159.                 endif
  160.                 set i = i + 1
  161.             endloop
  162.             set count = count + 1
  163.             if preserveColors then
  164.                 call ForForce(bj_FORCE_PLAYER[0], function thistype.preserveColor)
  165.             endif
  166.             return 0
  167.         endmethod
  168.     endstruct
  169.  
  170.     function WordWrapString takes string source, real sizeMargin, boolean preserveColors returns nothing
  171.         call WordWrap.create(source, sizeMargin, preserveColors)
  172.     endfunction
  173.  
  174.     function GetWrappedStringFragment takes integer i returns string
  175.         return WordWrap.getLine(i)
  176.     endfunction
  177.  
  178.     function GetWrappedStringCount takes nothing returns integer
  179.         return WordWrap.getCount()
  180.     endfunction
  181.  
  182. endlibrary
  183.  

Here is more information and pictures. First, take a look at this sample code:
Code: jass
  1. scope Testing initializer Init
  2.    
  3.     private function esc takes nothing returns nothing
  4.         local string text = "Hello, my name is Joe. I work in a button factory. One day, my boss said to me, \"Hiya Joe! Are you busy?\" "+/*
  5.         */" I said, \"No\"."    //our original text
  6.         local integer i = 0
  7.         call WordWrapString(text, 450, true) //We will break it into lines, 450 maximum pixels per line
  8.         loop
  9.             exitwhen i == GetWrappedStringCount()    //loop through each line up to the max line count.
  10.             call BJDebugMsg(GetWrappedStringFragment(i))  //This is how you read a line
  11.             set i = i + 1
  12.         endloop
  13.     endfunction
  14.    
  15.     private function Init takes nothing returns nothing
  16.         local trigger t = CreateTrigger()
  17.         call TriggerRegisterPlayerEvent(t, Player(0), EVENT_PLAYER_END_CINEMATIC)
  18.         call TriggerAddAction(t, function esc)
  19.     endfunction
  20. endscope

This is that sample above, with a width of 150:

This is that sample above, but with a width of 450:


For color preservation, it is basically an option to preserve color codes when skipping to the next line. If it is set to "false", then it will not preserve the colors, boosting performance, but ruining how it looks. If you have something like this:
|cff00FF00Hello World! It is a
beautiful day!|r

It should color the entire text. However, without color preservation, it will only color the top line. It should be fine to disable this if you are only color coding individual words, or if you aren't using color codes, but otherwise it should be enabled.

Here is an example with color preservation:


Without it, it would look like this:


Enjoy, all feedback is welcome.
« Last Edit: December 19, 2017, 12:40:45 PM by moyack »



Re: [System] WordWrap
Reply #1 on: August 17, 2012, 01:06:00 AM

This is great! Really need a good system for making text on my SRPG, thanks for this one purge! Gonna try it when I got home.

Chronicles of Darkness
by: SonofJay

A BlizzMod Hosted Project

They can hate, let them hate, make them hate.


Re: [System] WordWrap
Reply #2 on: August 18, 2012, 01:15:22 AM

Thanks.

I might end up making a multiboard/text tag system for this. It seems a bit much to have a system for everything, but it is really frustrating to deal with. If I made something to auto-extend multiboards or w/e or to create new text tags for new lines, then that thing would no longer be a problem. :)

If only there was a way to get resolution. I'm still looking to see if there is any hope of retrieving that.



Re: [System] WordWrap
Reply #3 on: August 18, 2012, 02:59:49 AM

I think the best way is to ask the user to say which resolution he is using through a dialog box or whatever else.
And because we don't always know which one we are using you could chek for each resolution what is the lowest texttag size available, and then display all these sizes with the text equal to the resolution, then the user just have to choice the biggest one he can see, but meh maybe it's already too much for the average battle.net player :p

vJass is already a jass preprocessor, no need to (ab)use vJass features in order to make some inferior vJass preprocessor coded "by hand".


Re: [System] WordWrap
Reply #4 on: September 01, 2012, 09:07:57 PM

Updated with optimizations and fixed a bug that came with my 2.0 update.



Re: [System] WordWrap
Reply #5 on: September 02, 2012, 09:22:07 AM

Definitely a very nice piece of code, and it does the job pretty well. Approved of course!!


 

Power of Corruption - A Warcraft III altered melee map   Chaos Realm - The world of Game modders and wc3 addicts     WC3JASS.com - The JASS Vault   Jetcraft - A Starcraft II mod