• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[Snippet] GradientText

Kazeon

Hosted Project: EC
Level 33
Joined
Oct 12, 2011
Messages
3,449
Description
A simple library used to add degradated color effect to any inputted message.​
Requirements
- HexString by Spinnaker
- JNGP​
Code
JASS:
library GradientText /* v3.2 */ requires HexString
    /********************************************************************************************
    *                                                                                           *
    *                                      'Gradient Text'                                      *
    *                                               *****                                       *
    *                                            by Dalvengyr                                   *
    *                                                                                           *
    * Description:                                                                              *
    *   This library is used to convert inputted string into the degradated one based on given  *
    *   or specified color code.                                                                *
    *                                                                                           *
    *               !! ADD_PREFIX at HexString library must be "false" !!                       *
    *                                                                                           *
    * Requirement:                                                                              *
    *   - HexString by Bannar aka Spinnaker                                                     *
    *       hiveworkshop.com/forums/jass-resources-412/snippet-hexstring-248993/                *
    *   - JNGP                                                                                  *
    *                                                                                           *
    * APIs                                                                                      *
    *                                                                                           *
    *   1. Create gradations for inputed string                                                 *
    *                                                                                           *
    *   function GradientText takes string s returns string                                     *
    *                                                                                           *
    *   2. Create gradations for inputed string with specific color code and size. Size is in   *
    *   percentage                                                                              *
    *                                                                                           *
    *   function GradientTextEx takes string s, string code1, string code2, integer size returns string
    *                                                                                           *
    ********************************************************************************************/
    
    globals
                            // Configuration //
    
        // For identifying a color code. Don't use "|c" !!
        
        public      constant        string          IDENTIFIER           = "#"
        
        // You are recommended to keep this as true. Will delete any character '|'
        
        private     constant        boolean         DELETE               = true
        
        // Furthermore, edit them by your own risk
        
        private constant integer LENGTH = StringLength(IDENTIFIER)
        private string array String
        private integer array Integer
        
    endglobals
    
    private function addGradation takes string s, string code1, string code2, integer len returns string
    
        local boolean b
        
        if len > 1 and code1 != code2 then
            set String[0] = ""
            set Integer[0] = 1
            
            // Convert hex code to integer
            set Integer[1] = HS2I(SubString(code1, 0, 2))
            set Integer[2] = HS2I(SubString(code1, 2, 4))
            set Integer[3] = HS2I(SubString(code1, 4, 6))
            
            // Set the color interval from code1 to code2 devided by length of string
            set Integer[4] = (HS2I(SubString(code2, 0, 2)) - Integer[1]) / (len + 1)
            set Integer[5] = (HS2I(SubString(code2, 2, 4)) - Integer[2]) / (len + 1)
            set Integer[6] = (HS2I(SubString(code2, 4, 6)) - Integer[3]) / (len + 1)
            
            loop
                exitwhen Integer[0] > len
                set String[4] = SubString(s, Integer[0] - 1, Integer[0])
                if String[4] != " " then
                    set b = true
                    static if DELETE then
                        if String[4] == "|" then
                            set b = false
                        endif
                    endif
                    
                    if b then
                        // Convert integer to hex code
                        set String[1] = I2HS(Integer[1] + Integer[4] * Integer[0], false)
                        set String[2] = I2HS(Integer[2] + Integer[5] * Integer[0], false)
                        set String[3] = I2HS(Integer[3] + Integer[6] * Integer[0], false)
                        
                        // Attach '0' if hex code only contains one letter
                        set Integer[8] = 1
                        loop
                            exitwhen Integer[8] > 3
                            if StringLength(String[Integer[8]]) == 1 then
                                set String[Integer[8]] = "0" + String[Integer[8]]
                            endif
                            set Integer[8] = Integer[8] + 1
                        endloop
                        
                        set String[0] = String[0] + "|cff" + String[1] + String[2] + String[3] + String[4]
                    endif
                else
                    set String[0] = String[0] + " "
                endif
                set Integer[0] = Integer[0] + 1
            endloop
        else
            static if DELETE then
                // Search for symbol '|' first
                set Integer[0] = 0
                loop
                    exitwhen Integer[0] > len
                    if SubString(s, Integer[0], Integer[0] + 1) == "|" then
                        set s = SubString(s, 0, Integer[0]) + SubString(s, Integer[0] + 1, len)
                        set len = len - 1
                    endif
                    set Integer[0] = Integer[0] + 1
                endloop
            endif
            
            set String[0] = "|cff" + code1 + s
        endif
        
        return String[0]
    endfunction
    
    function GradientText takes string s returns string
    
        local string code1 = ""
        local string code2 = ""
        local string grad
        local integer i = 0
        local integer t = 0
        local integer dex1
        local integer dex2
        local integer len = StringLength(s)
        
        // t is used to save last search point in the loop
        // dex1(2) is used to save found hex code's position
        loop
            exitwhen i > len
            if SubString(s, i, i + LENGTH) == IDENTIFIER then
                // If first code is still empty then save found code to it
                if code1 == "" then
                    set t = i
                    set dex1 = i
                    set code1 = SubString(s, i + LENGTH, i + LENGTH + 6)
                    // Remove found code from string
                    set s = SubString(s, 0, i) + SubString(s, i + LENGTH + 6, len)
                    set len = len - (LENGTH + 6)
                else
                    set dex2 = i
                    set code2 = SubString(s, i + LENGTH, i + LENGTH + 6)
                    set s = SubString(s, 0, i) + SubString(s, i + LENGTH + 6, len)
                    set len = len - (LENGTH + 6)
                    
                    if HS2I(code1) >= 0 and HS2I(code2) >= 0 then
                        set grad = addGradation(SubString(s, dex1, dex2), code1, code2, dex2 - dex1)
                    else
                        set grad = SubString(s, dex1, dex2)
                        debug call BJDebugMsg("Invalid color code: " + code1 + " - " + code2)
                    endif
                    // Insert the result into string s
                    set s = SubString(s, 0, dex1) + grad + SubString(s, dex2, len)
                    
                    // Preparation to search for another hex code
                    set code1 = code2
                    set t = t + StringLength(grad)
                    set i = t
                    set len = len - (dex2 - dex1) + t
                    set dex1 = t
                endif 
            endif
            set i = i + 1
        endloop
        
        if code1 != "" then
            if code2 == "" then
                // If there is only one found hex code
                if HS2I(code1) >= 0 then
                    // Use function addGradation to remove symbol '|' before inserting hex code
                    set s = SubString(s, 0, dex1) + addGradation(SubString(s, dex1, len), code1, code1, len - dex1) + "|r"
                debug else
                    debug call BJDebugMsg("Invalid color code: " + code1 + " - " + code2)
                endif
            else
                set s = s + "|r"
            endif
        endif
        
        return s
    endfunction

    function GradientTextEx takes string s, string code1, string code2, integer size returns string
    
        local boolean b = true
        local integer len = StringLength(s)
        local integer sz = R2I(len * (size * .01))
        local integer i = 0
        local integer mod
        local string res = ""
        
        // If specified code is invalid then skip the rest
        if HS2I(code1) < 0 or HS2I(code2) < 0 or StringLength(code1) != 6  or StringLength(code2) != 6 then
            debug call BJDebugMsg("Invalid color code: " + code1 + " - " + code2)
            return s
        endif
        
        // Avoid critical error
        if sz < 1 then
            set sz = 1
        endif
        
        // Loop to insert hex code into string based on given size
        loop
            set mod = i - (i/sz) * sz
            if mod == 0 then
                if b then
                    set res = res + IDENTIFIER + code1
                else
                    set res = res + IDENTIFIER + code2
                endif
                set b = not b
            endif
            
            if i <= len then
                set res = res + SubString(s, i, i + 1)
            endif
            
            exitwhen i >= len and mod == 0
            set i = i + 1
        endloop
        
        return GradientText(res)
    endfunction
    
endlibrary

Demo
JASS:
// Use this function to unparse any color code
// So you can check whether the degradation color is true or not
// Example: call BJDebugMsg(UnparseColorCode(GradientText(s)))
function UnparseColorCode takes string s returns string

    local integer len = StringLength(s)
    local integer i = 0
    local string sub
    
    loop
        exitwhen i > len
        set sub = SubString(s, i, i + 2)
        if sub == "|c" or sub == "|C" then
            set s = SubString(s, 0, i) + GradientText_IDENTIFIER + SubString(s, i + 4, len)
        endif
        set i = i + 1
    endloop
    
    return s
endfunction
    
function Trig_Test_1_Actions takes nothing returns nothing
    // Use GradientText function to degradate chat string and display the result
    call DisplayTimedTextToPlayer(Player(0), 0.0, 0.0, 0.0, GradientText(GetEventPlayerChatString()))
endfunction

function InitTrig_Test takes nothing returns nothing

    local string s = GradientTextEx("1234567890", "FF0000", "00FF00", 50) + " => GradientTextEx test."
    
    set gg_trg_Test = CreateTrigger()
    call TriggerRegisterPlayerChatEvent(gg_trg_Test, Player(0), "", false)
    call TriggerAddAction(gg_trg_Test, function Trig_Test_1_Actions)
    call DisplayTimedTextToPlayer(Player(0), 0, 0, 0, s)
    call DisplayTimedTextToPlayer(Player(0), 0, 0, 0, "You may enter any message with color code such as " + GradientText_IDENTIFIER + "ff0000Hello " + GradientText_IDENTIFIER + "ffff00There" + GradientText_IDENTIFIER + "00ff00")
endfunction
 

Attachments

  • GradientText.w3x
    23.2 KB · Views: 167
Last edited:
  • In HD2I, hex is useless. Just doreturn S2I(s)
  • Your debugging globals should be inside a static if.

    JASS:
        globals
            private constant string     identifier      = "0x"
        endglobals
        
        static if (DEBUG_MODE) then
            globals
                private constant string     debugMsg1       = "Invalid color code!"
                private constant string     debugMsg2       = "Input oversized!"
            endglobals
        endif

    This should work but I think I remember it not, so let me know. If not, you can just not use the globals altogether.

  • Maybe the library name (as well as the api) could be GradientText?
  • You could just use one "|r" at the end of the result, to reduce string size. Basically |r isn't need for each color code, only at the end IIRC.
  • Have you considered utilizing something like HexString
 
In case you don't want to use static ifs and since the debugging variables are constant, you could do this:

JASS:
globals
    private constant string identifier                   = "0x"
        
    // This message will be shown when user inputs invalid color code
    debug constant string GradationGenerator___debugMsg1 = "Invalid color code!"
        
    // This message will be shown when user inputs too many chars
    debug constant string GradationGenerator___debugMsg2 = "Input oversized!"
endglobals
You also still haven't removedlocal integer hexin HD2I and replaced the return statement withreturn S2I(s)

JASS:
if code1 != "" then
    if code2 == "" then
        if X2I(code1) >= 0 then
Could be shortened to

if code1 != "" and code2 == "" and X2I(code1) >= 0 thenand all the other ones like it.

And what are you thoughts on "GradientText" as the library name?
 
Review:
  • UnparseCode and GetIdentifier are too general names. They may collide with other systems/code. You should consider renaming them to something more specific, or incorporating the library name in there somehow.
  • Color codes don't necessarily start off with |cff (if I recall correctly). They can also start with |c00, |c01, etc. That portion is generally assumed to have been the alpha part of the text color, but it doesn't function. That is why most of them are just left as |cff. So just check if they start with |c in UnparseCode.

I still have to look at the rest. But those are things to keep you busy until I review more. xD
 
Placing globals inside a static if does not work correctly. Do what I suggested before:

JASS:
    globals
        constant string GRADIENT_IDENTIFIER = "0x"

        private constant string REPLACER = ""
        private constant boolean SHOW_ALPHA = false

        debug constant string GradientText_ERROR_1 = "Invalid color code!"
        debug constant string GradientText_ERROR_2 = "Input oversized!"
    endglobals
You should really be using HexString for performance and to reduce code size. There's no good reason to have pseudo-code in this script.

Your constant variables should be in ALL_CAPS like shown above.

Also, insidegrad(or wherever logical) use anarrayto reduce the amount of local variables used.

Now for the API I think this fits more:

JASS:
    /* APIs                                                                                  */
    /* - function GradientText takes string s returns string                                     */
    /*                                                                                       */
    /* - function GradientTextEx takes string s, string code1, string code2 returns string        */
    /*                                                                                       */
    /* - function RemoveGradientText takes string s returns string
I suggest removing GetGTIndentifier and make identifier (GRADIENT_IDENTIFIER) public.

UnparseColorCode may also be redundant because the user should have a copy of the unparsed string elsewhere, but for sake of completeness maybe that function should stay.

That's it for now, get those things fixed and I'll have more.
 

Bannar

Code Reviewer
Level 26
Joined
Mar 19, 2008
Messages
3,140
JASS:
        debug else
            debug if DEBUG_MSG != null then
                debug call BJDebugMsg(DEBUG_MSG)
            debug endif

// ->>>
    debug call BJDebugMsg(DEBUG_MSG)
If string is null, debugmsg call wont show you anything anyways.

if SHOW_ALPHA then -> static if SHOW_ALPHA then

Shorten description. Trust me, none reads block of text. Do it like this: 1 sentence describing what is resource made for and add up to 2 sentences if you think there are important notes worth mentioning. Result: we end with 3 lines with an enter between -> success.

Add a line mentioning requirements possibly including link to such script.
 
Dalvengyr said:
afaik, it's better to declare some variables if we only use a few..

7 local integers isn't just a few.

Dalvengyr said:
about function name change, damage has been done, I can't undo :p

I don't see any reason it's not change-able. How is it too late? You submitted this less than a week ago.

The API is unexplanatory, awkward, and doesn't really fit.

It may be just me so we'll see what the other moderators think but "Gradient" is just too simple and "Gradient2" is just.. bad.

You also need to changeDEBUG_MSGto something else because it can easily conflict with other libraries. MaybeGradientText_ERROR
 
Last edited:
Dalvengyr said:
DEBUG_MSG == GradientText_DEBUG_MSG so what's wrong with that name?

Umm what?DEBUG_MSG != GradientText_DEBUG_MSGHow are they equal?

There's a bug where you can't put private/public keywords in front of debug globals, so you need to do it manually.

Dalvengyr said:
if I change the API, then I need to change the whole FC at demo map (and at my UCS too) which is really hurt.. D:

CNTRL + F with Find & Replace tool? How is that going to "hurt"?
 

Bannar

Code Reviewer
Level 26
Joined
Mar 19, 2008
Messages
3,140
@Almia: dont deny his work.
Ok, there is color lib by Nes, and what? Its not even here.

TriggerHappy uploaded UnitDex even though Nes UI gotten popular after those several years. Is that wrong? Hell, no.
I've also written color lib, however, it mimics wxColour and an extension wxColourDatabase, and who knows, meaby this will get submited too.

Many, including Nes, share opinion that writing something for the first time (or whatever) doesnt automatically means you have copyrights to that idea.
 
Ok, there is color lib by Nes, and what? Its not even here.

And I don't even thing it has the same functionality. Could StringColor provide gradients?

I suppose it could have been useful being integrated in this script, but in reality most Nestharus' resources are basically dead for public use.

I wouldn't have made UnitDex if nestharus didn't ragequit.
 

Kazeon

Hosted Project: EC
Level 33
Joined
Oct 12, 2011
Messages
3,449
guys, this is what will happens if you are trying to use one of nestharus's resource..
attachment.php


at first I was trying to use TextTag library, but they are requiring each other, it was what happening after I was trying to complete the requirements (note that I haven't completed all the requirements)
 

Attachments

  • a.jpg
    a.jpg
    616.7 KB · Views: 523

Bannar

Code Reviewer
Level 26
Joined
Mar 19, 2008
Messages
3,140
Although there is much that could be improved in Nes' resources in case of portability, we can not however, call it crap. There are multiple libs of his, that are quite usefull and still prevail (why shouldnt they, if job well done?).
Problem is (was) that Nes wanted to convert evething to his will, or better, just rewrite everything >.>

And he has forgotten about optional keyword, sadly.
 

Kazeon

Hosted Project: EC
Level 33
Joined
Oct 12, 2011
Messages
3,449
And he has forgotten about optional keyword, sadly.
lol that's the problem..

Which is exactly why we dont use Nestharus crap :>
I think Nesth's resources are good, but banana is right, we don't need all his resources at once, he need to make some of them optional so we don't have to import everything >.>
 
Level 19
Joined
Mar 18, 2012
Messages
1,716
An issue I also mentioned a few months ago. I recommend you don't use "TextTag" for your system unless you want that noone uses it in the end.

Too many not optional requirements with too much code noone needs in 99% of all cases.
ItemPosition, GetItemOwner, StaticUniqueList, AllocQ, ... just for creating a TextTag.
Nestharus made some excellent resources, but TextTag is just a bad joke.
 
It seems like your adding new functions just.. because. Try to stick to the core idea of the script and not bloat it with extra things like RepeatLastGradation.
  • UnparseColorCode->RemoveGradientText
  • SizedGradientText->GradientTextSized - Btw, what does this do.
  • RepeatLastGradation - I really don't see the point of this function
  • RainbowText - Probably shouldn't be included in the library. Also shouldn't this create a text with all the colors in the rainbow (probably in order), not just random colors? Unless I read the code wrong.
 
Dalvengyr said:
it's GradientTextEx but you can input the size..

Size being?...

Dalvengyr said:
so, I need to delete the two functions?

Unless you can explain why they should be there

Dalvengyr said:
I think RainbowText is still somehow useful, and yes it's random color, so what's better name?

Except your function doesn't really create a rainbow text, it creates a random gradient.
 

Kazeon

Hosted Project: EC
Level 33
Joined
Oct 12, 2011
Messages
3,449
Size being?...
wut? yes it has size, which it's in percentage, just like photoshop which you can scale up/down the gradient scale :grin:
Unless you can explain why they should be there
uhm.. I think I will remove RepeatLastGradation, I can't explain the functionality :grin:

but, for RainbowText, it can generate random color, yes, it's random, not rainbow color, so please share a suitable name if you don't mind :) thnks
 

Bannar

Code Reviewer
Level 26
Joined
Mar 19, 2008
Messages
3,140
JASS:
   /* APIs                                                                                      *
    *                                                                                           *
    *   1. Create gradations for inputed string with speculation color codes have been included *
    *   inside the string                                                                       *
    *   function GradientText takes string s returns string                                     *
    *   Ex: call GradientText("0xffff001230x00ff00")    */
VS:
JASS:
   /*
    *   function GradientText takes string s returns string
    *      gradate string s; s must include its color speculation    */

Shorten description a bit. Examples should not be included in libs view, demo code is here for a reason. If you want to be more fancy, you could write // call GradientText("0xffff001230x00ff00") at the top of given function like Bribe did in his Table.
 

Kazeon

Hosted Project: EC
Level 33
Joined
Oct 12, 2011
Messages
3,449
Here it is, an update, a very good one I guess
- All examples removed. thnks to bannana >.>
- UnparseColorCode is eliminated from library since I realized it has no relation with Gradient Text thingy
- Repeatitive actions on addGradation is now replaced with loop so it's neater :>
- better coding style I guess, easier to read.

So is there anything I can fix/ improve? special thanks for two gays (TH and Bannana) who helped me a lot so far!!

updated
- I have checked photoshop again and found that original inputed color code should not included in the result, so now the gradation is 99% accurate, I can make it 100% if only I know how to convert hex to real instead of integer, or maybe there is another solution? still thinking of it..
- array variables are now declared as globals
- GradientTextSized renamed to GradientTextEx
- fixed bug where GradientTextEx adds some extra spaces at the result
 
Last edited:

Kazeon

Hosted Project: EC
Level 33
Joined
Oct 12, 2011
Messages
3,449
Well, is this going to be approved or not? You have promised to approve this likely more than 4 months ago :/ Am I need to change name to Bribe or Nestharus first to be approved here? Seriously, if you want me to wait another 4 months just for 0.000001 milisecond optimization, better you just GY this. I'm not joking.
 
Last edited:

Kazeon

Hosted Project: EC
Level 33
Joined
Oct 12, 2011
Messages
3,449
>.>

Okay, I was quite heaten up. Remembering TH has promised more 4 months ago.

And this is requred for my ucs to get approved. I've been waiting for sooo long to get any review for it but none :(

My nick is not Bribe nor Nestharus and there are few resources approved out there. PnF, TH, Maggy.. (the list goes on).
But you are Bannar, you are one of them. #Suddenly got runny nose after saying this >.>
 
Last edited:
I tested it a few days before your post and it wasn't even functional and now you're mad at me for not instantly approving it?

lol I would also like to see this 'promise' I made.

I suggest you re-read all my posts in this thread.

EDIT #2: Sorry my mistake. You should probably add// !! ADD_PREFIX at HexString library must be "false" !! to the post though.

Approved.
 
Last edited:
Top