Different colours in one string

If you found a bug in our library or on our website, please report it in this section. In this forum you can also make concrete suggestions or feature requests.

Moderators: CEGUI MVP, CEGUI Team

Pompei2
Home away from home
Home away from home
Posts: 489
Joined: Tue May 23, 2006 16:31

Postby Pompei2 » Fri May 11, 2007 12:59

Of course, I'm following this thread :) I will test your changes this weekend. thank you for working on this, so I don't need to do it :P

User avatar
Ludi
Quite a regular
Quite a regular
Posts: 59
Joined: Sun Aug 13, 2006 12:33

Postby Ludi » Sat May 12, 2007 01:27

What about adding a starting trigger, which indicates to use font coloring or not for the current string? This trigger could be set like the color trigger.

_This is a ^00ff00ff colored text.

This is a not a colored text.

User avatar
ldb
Quite a regular
Quite a regular
Posts: 54
Joined: Sat Mar 24, 2007 13:39
Location: Bloomington, IL
Contact:

Postby ldb » Sat May 12, 2007 03:46

Ludi wrote:What about adding a starting trigger, which indicates to use font coloring or not for the current string? This trigger could be set like the color trigger.

_This is a ^00ff00ff colored text.

This is a not a colored text.


my feeling on this is that ive already introduced a lot of (well, not a lot, but enough) extra logic in the draw text methods and i tried to keep it to a minimum. as long as the trigger string is carefully chosen, you shouldnt have to worry about getting a false positive in the trigger string detection.
No matter where you go, there you are.

User avatar
Ludi
Quite a regular
Quite a regular
Posts: 59
Joined: Sun Aug 13, 2006 12:33

Postby Ludi » Sat May 12, 2007 09:21

This was more a sort of "opimization". Currently, as I understand your changes, you parse every string, when you enable coloring, even if it doesn't contain color information.

Could you post your changes here or the font.cpp/.h directly here, instead of the diff. I don't have cegui in a repository and I'm to lazy to apply all the changes by hand ;)

User avatar
ldb
Quite a regular
Quite a regular
Posts: 54
Joined: Sat Mar 24, 2007 13:39
Location: Bloomington, IL
Contact:

Postby ldb » Sat May 12, 2007 15:52

Ludi wrote:This was more a sort of "opimization". Currently, as I understand your changes, you parse every string, when you enable coloring, even if it doesn't contain color information.

Could you post your changes here or the font.cpp/.h directly here, instead of the diff. I don't have cegui in a repository and I'm to lazy to apply all the changes by hand ;)


ok, that makes sense. i thought about it a little bit and decided an extra "trigger" is not really necessary. what do you think of this? before looping through every character of the string, it first checks if a colour trigger was found, then inside the for loop, just does a check against a bool (foundColourTrigger).

Code: Select all

...

   bool foundColourTrigger = false;
   
    if (d_colourFormatEnabled)
        // find first occurance of colour trigger string.
        if (text.find_first_of(d_colourFormatTrigger) != String::npos)
            foundColourTrigger = true;

    for (size_t c = 0; c < textlen; ++c)
    {
        // parse color information if enabled and we found a colour trigger.
        if (foundColourTrigger)
        {
            // only try to parse colour information when enough chars exist.
            if (c + triglen + 8 <= textlen)
            {
                // look for colour trigger at position c.
                if (strncmp(&str[c], trigstr, triglen) == 0)
                {
                    // found colour trigger, skip past trigger string
                    c += triglen;
                   
                    // copy colour string into buffer
                    memcpy(buf, &str[c], 8);
                   
                    // convert colour string into hex format (AARRGGBB)
                    sscanf(buf, "%x", &argb);
                    curColour.setColours(argb);

                    // skip past colour string.
                    c += 8;
                }
            }
        }
...



when a colour format trigger is found, it still does a strncmp() at every character of the string to check for the trigger, but i think this definitely speeds things up when colour formatting is enabled, but no colour trigger was found.

http://www.puresimplicity.net/~ldb/CEGUIFont.h
http://www.puresimplicity.net/~ldb/CEGUIFont.cpp
No matter where you go, there you are.

User avatar
ldb
Quite a regular
Quite a regular
Posts: 54
Joined: Sat Mar 24, 2007 13:39
Location: Bloomington, IL
Contact:

Postby ldb » Mon May 14, 2007 12:45

heres a pretty cool example of the colour stuff in action:

http://www.puresimplicity.net/~ldb/test.png

this is how its being done in code:

Code: Select all

// this is the font i use for drawing the text in those little windows
Font* font = FontManager::getSingleton().getFont("dc146-9");
font->setColourTrigger("|c");
font->setColourTriggerEnabled(true);


Code: Select all

// the heading line of the player window
char buf[128];
sprintf(buf, "|cFFFFFFFFHeading: |cFF00FF00%.2f %.2f %.2f", mHeading.x, mHeading.y, mHeading.z);
mPlayerStateWindow->mPlayerHeading->setText(buf);


i dont think it would be possible to use a single static text widget for both colours with the way the system currently works. you would need two separate widgets (a "label", such as "Heading:" and the "value", such as the "x y z"), and set each ones color before setting the text. im pretty sure this avoids the need to do that (by just setting the colours in a single line of text, in a single StaticText widget).

im liking it so far...but there are some caveats:

when setting the text colours in this way, the text alpha is not inherited from the widget. for example, when i fade these windows out, the text is not faded along with the widget. im trying to think of a way to fix this. whats juggling around in my head right now is to just grab the widget alpha when i call setText() and use that in my colour format.

don't attempt to use it in anything other than a StaticText widget. you will get strange results.

it does not work with languages other than english.

these are all things i plan on fixing.
No matter where you go, there you are.

User avatar
Ludi
Quite a regular
Quite a regular
Posts: 59
Joined: Sun Aug 13, 2006 12:33

Postby Ludi » Mon May 14, 2007 23:28

Hi ldb (is it an akronym?),

sorry for the late response. First of all, thanks for the files. During the time I was waiting, I made my own modification (actually, it's really easy, easier than I though).

Here's my code:

Code: Select all

   bool coloring = false;
   ColourRect color = colours;
   size_t charPos = 0;
   char colorBuffer[8];
   argb_t argb;


   if (length > 1)
   {
      if (text[0] == '_')
      {
         // The String begins with _Text, so we color the string
         // If it begins with __Text, we skip one underscore
         ++charPos;
         if (text[1] != '_')
         {
            coloring = true;
         }
      }
   }
    for (; charPos < length; ++charPos)
    {
      if (coloring && text[charPos] == '^' && (charPos + 8) < length)
      {
         ++charPos;
         if (text[charPos] != '^')
         {
            memcpy(colorBuffer, text.c_str() + charPos, 8);
            sscanf(colorBuffer, "%x", &argb);

            color.setColours(argb);
            charPos += 8;
         }
      }
    ...


Basically, it's the same as yours, except that I'm using a fixed color trigger (the ^ like Quake3) and I'm using the _ to indicate, wheather the string should be colored.

After thinking about it, we might should setup a testbed, where we can test the performance of different approaches.

About the alpha problem: Why not using the original alpha (this should contain the correct alpha value, right?). This way, you will just be able to set the color in the string.

And one more thing is to use instead a doule hex value per color only one (so, instead FF only F for red). So, we will only need three characters for a complete color value (and without alpha). The reason for this is that, in my case, I'm using a big string table for localization. And with the current method, everything is full with hex codes and therefore you'll lose the overview fast.

"^F00This is a red text" instead of "^FFFF0000This is a read text." With only three characters for the color, there's still the possibility to have 4096 different colors (16^3), which should be enough.

Why does it only work with english text? German is working too ;)

User avatar
ldb
Quite a regular
Quite a regular
Posts: 54
Joined: Sat Mar 24, 2007 13:39
Location: Bloomington, IL
Contact:

Postby ldb » Tue May 15, 2007 14:50

Ludi wrote:Hi ldb (is it an akronym?),

Basically, it's the same as yours, except that I'm using a fixed color trigger (the ^ like Quake3) and I'm using the _ to indicate, wheather the string should be colored.


ldb are my initials.

im assuming this is just for your testing purposes. i would prefer allowing the user to set the colour trigger to whatever they want. using a fixed colour trigger would cost a lot in terms of flexibility. i do not think an extra trigger to tell the font whether or not there is colour information is needed. the reason is that you can easily parse the string and find a match for a colour format trigger.

About the alpha problem: Why not using the original alpha (this should contain the correct alpha value, right?). This way, you will just be able to set the color in the string.


its easier, and more flexible, to let the user choose the alpha value by setting it in the format string. see my next point for why i think this is the case.

And one more thing is to use instead a doule hex value per color only one (so, instead FF only F for red). So, we will only need three characters for a complete color value (and without alpha). The reason for this is that, in my case, I'm using a big string table for localization. And with the current method, everything is full with hex codes and therefore you'll lose the overview fast.

"^F00This is a red text" instead of "^FFFF0000This is a read text." With only three characters for the color, there's still the possibility to have 4096 different colors (16^3), which should be enough.


id rather not limit the amount of colours based on what i think "should be enough". i want to give the user full control over all the colours available in a 32-bit value.

Why does it only work with english text? German is working too ;)


sorry, i should have been more specific. it currently only works with the ASCII character set. i believe this is due to the fact utf8 is a variable length encoding format (a single char can be 1 to 4 bytes, depending on the unicode symbol). im not entirely sure, but doesnt the german language fit within the ASCII character set? something such as cyrillic or chinese alphabet will fail.
No matter where you go, there you are.

User avatar
Ludi
Quite a regular
Quite a regular
Posts: 59
Joined: Sun Aug 13, 2006 12:33

Postby Ludi » Tue May 15, 2007 20:15

Well, after thinking more about it, I'm going with a third solution.

First, I'll remove the _ from the beginning. Next is, that I'm going to use the Quake style to use ^0 ... ^9, but with the possibility to set the specific color for the values 0 ... 9.

This will be the best solution for our project.

Pompei2
Home away from home
Home away from home
Posts: 489
Joined: Tue May 23, 2006 16:31

Postby Pompei2 » Thu May 17, 2007 13:24

I can't wait till it's completely done ldb :D
looks very promiscing.

I had a tought about the enable it on per-widget or per-font basis. For the user, it's nearly the same:
in a per-widget basis, the user would need to activate it on every widget he wants (one line per widget)
in a per-font basis, the user would need to choose the font on every widget he wants (also one line per widget)
But in a per-font basis he can set it globally too, so it's better. You chose the right one ;)

One question tough: why does it only work with static text ??If your two patch files are still the actual ones, then I see no reference to static text in them ?

User avatar
ldb
Quite a regular
Quite a regular
Posts: 54
Joined: Sat Mar 24, 2007 13:39
Location: Bloomington, IL
Contact:

Postby ldb » Thu May 17, 2007 14:57

Pompei2 wrote:But in a per-font basis he can set it globally too, so it's better. You chose the right one


well, it wasnt really a matter of choice -- i was pretty much forced into that decision. im just glad its worked out. :wink:

but yeah, this way the user can define a font, which has colour triggering enabled, and share that font between many widgets, so it essentially can be global on a per "set of widgets" basis.

Pompei2 wrote:One question tough: why does it only work with static text ??If your two patch files are still the actual ones, then I see no reference to static text in them ?


when i was testing the non ASCII characters (using the FontDemo sample), i noticed when using the colour stuff in a multi line edit box, it actually worked, but the behavior was very unexpected. basically what happened was the lines were correctly coloured, and the format strings were not visible, but when i clicked on a line of text, the colour format string became visible, and when i deselected the string, the colour format would disapear. one cool side effect of this was that i could edit the colour string in the text box, deselect the text, the colour format would disappear and the colours would stay. so, i could essentially alter the color of any string in the edit box, much like a word processor. but, like i said, it was very unexpected behavior and needs refined.

i guess what i meant to say was: dont expect correct behavior in anything other than a static text widget. i need to test more widgets.

and thank you for the kind words. its nice to know someone likes what youre doing! your idea of a colour trigger, etc was brilliant!
No matter where you go, there you are.

Pompei2
Home away from home
Home away from home
Posts: 489
Joined: Tue May 23, 2006 16:31

Postby Pompei2 » Thu May 17, 2007 17:12

ldb wrote:and thank you for the kind words. its nice to know someone likes what youre doing! your idea of a colour trigger, etc was brilliant!

I AM brillant ! :D no seriously, thank you ;)

Your strange behavior has probably something to do with calculation of wich part of text is selected ect. can't really express what i mean :) But now I definitely go take a look at it (and maybe i see the problem) !

zarroba
Not too shy to talk
Not too shy to talk
Posts: 22
Joined: Tue Jul 11, 2006 12:54

Postby zarroba » Mon Jun 18, 2007 08:51

ldb, thanks for your work. I was about to start doing some kind of a RichText Multiline Editbox when I saw this thread and your solution for rendering different colours in a line of text. I think its a very good way to start. I was thinking of implementing some triggers for the font style (bold, italic, etc), so I'll read carefully Rackle's posts. I have just tried your code and it really works funny in an editbox or multiline editbox. For my project I would rather prefer if the colour code wouldn't be shown. Have you research further into this behaviour so I can correct it if you haven't already?

thanks

User avatar
ldb
Quite a regular
Quite a regular
Posts: 54
Joined: Sat Mar 24, 2007 13:39
Location: Bloomington, IL
Contact:

Postby ldb » Mon Jun 18, 2007 20:48

zarroba wrote:ldb, thanks for your work. I was about to start doing some kind of a RichText Multiline Editbox when I saw this thread and your solution for rendering different colours in a line of text. I think its a very good way to start. I was thinking of implementing some triggers for the font style (bold, italic, etc), so I'll read carefully Rackle's posts. I have just tried your code and it really works funny in an editbox or multiline editbox. For my project I would rather prefer if the colour code wouldn't be shown. Have you research further into this behaviour so I can correct it if you haven't already?

thanks


thanks for the kind words.

yes, as i said in a previous post, multiline edit boxes have some pretty bizarre behavior. currently, there is no way for the colour formatting to know what type of widget is currently rendering the text, since the code is contained in the font itself, which has no knowledge of which widget it is being rendered in.

i have pretty much left the code as is (i havent really touched it in a while, since ive postponed my project temporarily.) but, since you are interested, its motivated me to take another crack at it.

at this point, all i can recommend (which is not the best way, obviously) would be to create a second font, turn off colour triggering, and use that for your multiline edit box. obviously you then lose the colour triggering for that font.

i have also thought a little about coming up with a rich text kind of widget which does exactly as you suggest, but im not sure my current colour trigger stuff is appropriate for that kind of functionality. my patch is pretty much a simple hack.

i think ill take another gander at the code and see what things i can come up with. i am very open to any suggestions.

what i would like to see is actual xml tags for specifying font attributes, like <size=12><color="#FFFFFFFF"><b>this is bold white 12 point text</b></color></size>.

also, with mechanisms like this in place, i think it could be a great start for a very simple browser like widget. think of something similar to the in-game browser of EVE-Online (see this link), which works surprisingly well. EVE-Online also has a very nice rich text style widget (see this link). im guessing their browser and rich text widgets are tightly coupled, so implementing one would get you the other for "free".

im toying around right now with embedding Navi (a llmozlib based library, which is very nice), into a CEGUI window(see this screen shot). it's pretty cool, but it might be a little too much for what im wanting (yet, it still opens up a LOT of possiblities). im just not too keen on another dependency added into CEGUI.

i think a native browser widget would be the best solution at the moment (but not the most simple thing to implement). a start would be parsing/rendering a document containing html tags, from there it could be extended to something representing an actual browser.

the thing is, is that this has all been discussed in various forum posts, so we can talk about it until we are blue in the face =) its just a matter of buckling down and trying to get some stuff written. the problem is that im way oversimplifiying the problem. its not going to be easy at all, and would probably take some pretty serious changes to the text rendering code. perhaps the best bet here is to write a completely new text renderer which handles xml tags, since modifying the existing text renderer would break all the existing widgets.

again, thanks for the kind words.
No matter where you go, there you are.

zarroba
Not too shy to talk
Not too shy to talk
Posts: 22
Joined: Tue Jul 11, 2006 12:54

Postby zarroba » Tue Jun 19, 2007 09:15

Thanks for the reply ldb.
My first idea to implement this Richtext Widget was to use Gecko or something similar. But for now the use we are going to make of such widget is to implement a script editor, so we just need colouring and styles.
I'll try the suggestion of Rackle and associate to a font its bold, italic and bold/italic styles and when the trigger is find I'll render with it. I'll keep you posted on the results..



Return to “Bug Reports, Suggestions, Feature Requests”

Who is online

Users browsing this forum: No registered users and 6 guests