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

User avatar
Emmeran
Quite a regular
Quite a regular
Posts: 46
Joined: Wed Jan 12, 2005 12:06
Location: Germany, near Nuremberg
Contact:

Different colours in one string

Postby Emmeran » Sun Dec 26, 2004 23:47

I made yet some changes to make this possible:
In class Font:

Code: Select all

void Font::drawTextLine(const String; text, const Vector3;

position, const Rect; clip_rect, const ColourRect; colours) const
{
   Vector3   cur_pos(position);

   uint char_count = text.length();
   CodepointMap::const_iterator   pos, end = d_cp_map.end();

   /** FORMATING **/
   size_t pos1 = String::npos, pos2 = String::npos;
   ColourRect aCol = colours;
   String r,g,b;

   pos1 = text.find("###");
   pos2 = text.find("#-#");

   for (uint c = 0; c < char_count; ++c)
   {
      if (c > pos1 + 9) pos1 = text.find("###", c);
      if (c > pos2 + 3) pos2 = text.find("#-#", c);
      //        >< pos1          >< pos2
      //           >< + 3           >< + 3
      //                 >< + 9 
      // texttext###012345texttext#-#texttexttext
      if ((char_count < pos1 + 10 || c < pos1 || c >=

pos1 + 9) ;;
         (char_count < pos2 + 4  || c < pos2 || c

>= pos2 + 3))
      {
         pos = d_cp_map.find(text[c]);

         if (pos != end)
         {
            pos->second.d_image->draw(cur_pos,

clip_rect, aCol);
            cur_pos.d_x +=

pos->second.d_horz_advance;
         }
      }
      else if (pos1 == c)
      {
         r = text.substr(pos1 + 3, 2);
         g = text.substr(pos1 + 5, 2);
         b = text.substr(pos1 + 7, 2);

         aCol.setColours(colour(
            (float)(TextUtils::hex2dec(r) / 255.0f),
            (float)(TextUtils::hex2dec(g) / 255.0f),
            (float)(TextUtils::hex2dec(b) / 255.0f)));
      }
      else if (pos2 == c)
      {
         aCol = colours;
      }
   }
}


Code: Select all

float Font::getTextExtent(const String; text) const
{
   uint cur_extent = 0;

   uint char_count = text.length();
   CodepointMap::const_iterator   pos, end = d_cp_map.end();

   size_t pos1 = String::npos, pos2 = String::npos;

   pos1 = text.find("###");
   pos2 = text.find("#-#");

   for (uint c = 0; c < char_count; ++c)
   {
      if (c > pos1 + 9) pos1 = text.find("###", c);
      if (c > pos2 + 3) pos2 = text.find("#-#", c);

      if ((char_count < pos1 + 10 || c < pos1 || c >=

pos1 + 9) ;;
         (char_count < pos2 + 4  || c < pos2 || c

>= pos2 + 3))
      {
         pos = d_cp_map.find(text[c]);

         if (pos != end)
         {
            cur_extent +=

pos->second.d_horz_advance;
         }
      }
   }

   return (float)cur_extent;
}



and in class TextUtils: I added the function hex2dec:
in CEGUITextUtils.cpp:

Code: Select all

unsigned char TextUtils::hex2dec(String twoLetters)
{
   char values[256] = "\0";
   values['0'] =  0;
   values['1'] =  1;
   values['2'] =  2;
   values['3'] =  3;
   values['4'] =  4;
   values['5'] =  5;
   values['6'] =  6;
   values['7'] =  7;
   values['8'] =  8;
   values['9'] =  9;
   values['A'] = 10;
   values['B'] = 11;
   values['C'] = 12;
   values['D'] = 13;
   values['E'] = 14;
   values['F'] = 15;
   values['a'] = 10;
   values['b'] = 11;
   values['c'] = 12;
   values['d'] = 13;
   values['e'] = 14;
   values['f'] = 15;

   return values[twoLetters.at(0)] * 16 + values[twoLetters.at(1)];
}


and, of course, in CEGUITextUtils.h:

Code: Select all

   static unsigned char hex2dec(String twoLetters);


have phun,
Emmeran


PS:
by the way: you can format your text with this changes this way:

text text text ###ff0000red text red text###00ff00green text green text and so on#-#text in orginial colour ... ###0000ffand now comes blue text ...

you can use every colour specified by an 6-char hexcode

EDIT Improved readability by converting the HMTL tags into real characters: &quote; into "

User avatar
CrazyEddie
CEGUI Project Lead
Posts: 6760
Joined: Wed Jan 12, 2005 12:06
Location: England
Contact:

Different colours in one string

Postby CrazyEddie » Wed Dec 29, 2004 10:27

This is definately similar to things I have planned for the near to mid future, though I'd not be happy implementing them in the Font itself.

My own approach will consist of a new 'static' widget which will support some minimal markup; for things like font name, colours, images, etc. This widget will build a "draw list" which is calculated only when the static widgets string is changed (as opposed to re-calculating everything, each draw).

Thanks for sharing the code though, I imagine there will be a few people hacking this, or similar code, into their systems ;)

CE.

User avatar
Emmeran
Quite a regular
Quite a regular
Posts: 46
Joined: Wed Jan 12, 2005 12:06
Location: Germany, near Nuremberg
Contact:

Different colours in one string

Postby Emmeran » Wed Dec 29, 2004 13:09

I'm looking forward to this widget :-D

User avatar
gcarlton
Just can't stay away
Just can't stay away
Posts: 149
Joined: Wed Jan 12, 2005 12:06

Re: Different colours in one string

Postby gcarlton » Sun Jan 16, 2005 01:44

One advantage of having colour (+image) markup in the font is that it can be applied to any widget. We wouldn't want to have to make up a new MarkupListbox, MarkupCombobox, etc.

Also, the code can be made efficient enough (particularly in the non-markup case) that calling it every draw would not be an issue.

User avatar
CrazyEddie
CEGUI Project Lead
Posts: 6760
Joined: Wed Jan 12, 2005 12:06
Location: England
Contact:

Re: Different colours in one string

Postby CrazyEddie » Sun Jan 16, 2005 07:28

Hmmm.

I'll think about this some more :)

CE.

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

*bump*

Postby ldb » Fri May 04, 2007 15:46

i dont know about anyone else, but i personally think this would be an incredible feature to have!

this is pretty much exactly how world of warcraft handles different colors within a single string.

any thoughts, suggestions etc...?
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 » Fri May 04, 2007 19:02

Warcraft 3 already did this too (maybe aso 2 and 1 ?).
My thought was to implement this, but let the user (game programmer) choose the trigger string using a function, and maybe also choose between rgb and hex representation.
maybe something like

Code: Select all

pFont->setColorTrigger( "C|*" );
pFont->setColorFormat( Font::Hexadecimal | Font::BGRA );

would result in the following color string to represent a opaque blue color:

Code: Select all

C|*FF0000FF

and

Code: Select all

pFont->setColorFormat( Font::Decimal | Font::RGB );

would result in the following (opaque blue again):

Code: Select all

C|*(255,0,0)


I'm seriously thinking about implementing this, but there should be an ability to disable color parsing in some way, for some fonts (widgets) only, say disable it in tooltips but enable it in chat windows.

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 05, 2007 09:53

Pompei2 wrote:My thought was to implement this, but let the user (game programmer) choose the trigger string using a function, and maybe also choose between rgb and hex representation.
maybe something like

Code: Select all

pFont->setColorTrigger( "C|*" );
pFont->setColorFormat( Font::Hexadecimal | Font::BGRA );


would result in the following color string to represent a opaque blue color:

Code: Select all

C|*FF0000FF

and

Code: Select all

pFont->setColorFormat( Font::Decimal | Font::RGB );

would result in the following (opaque blue again):

Code: Select all

C|*(255,0,0)



awesome idea. this will make the system very flexible.

I'm seriously thinking about implementing this, but there should be an ability to disable color parsing in some way, for some fonts (widgets) only, say disable it in tooltips but enable it in chat windows.


i had thought of the same thing. turning it off by default could also eliminate cases in existing client code that just happens to use the color format strings (which would probably be extremely rare, but possible.)

this is assuming there is a "default" color format string (which would be nice). i guess requiring explicitly setting the color format/trigger string would avoid this, but its always nice to have a default option.

if you do implement it, let me know. i had considered implementing it as well (but i hadnt thought of your real cool approach)
No matter where you go, there you are.

Rackle
CEGUI Team (Retired)
Posts: 534
Joined: Mon Jan 16, 2006 11:59
Location: Montréal

Postby Rackle » Sat May 05, 2007 11:05

There has been talk of changing the way lists (combobox, listbox, multicolumn list) are designed, by allowing us to use CEGUI::Window instead of a specific list type. When that happens we'll be able to design a complex list item; a base window containing a hierarchy of objects. For example such an item could contain static images, static text, checkboxes, etc.

Let's take this a step further.

Let's make every text displayed based on the static text widget.

Then we extend the static text widget to support markup, both with text colors (or colours), multiple font support for name (arial, Times New Roman), size, and styles (such as normal, bold, italic, and underlined). I'm abitious so all of these would be settable within a text string. The exact markup needs to be defined but this is using the phpBB markup:

Code: Select all

[color=red]This[/color] [b]is[/b] [i]a[/i] [u]test[/u] [size=7]string[/size].

To generate this string within Cegui: This is a test string.

This is just an idea, while still waking up...

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 05, 2007 18:56

Rackle wrote:

Code: Select all

[color=red]This[/color] [b]is[/b] [i]a[/i] [u]test[/u] [size=7]string[/size].

To generate this string within Cegui: This is a test string.

This is just an idea, while still waking up...


im not sure how useful it would be to specify font styles. i think just specifying which font to draw (within the text string) with would handle all those cases.

the reason is that as far as i know, the fonts are just rasterized at run-time and cegui has no concept of font styles. if i were to use bold, italic, or whatever fonts, i would load it from a font definition (for that style) and just set it as the font used to draw that particular style.

with your approach it would require someone to load a font, specfiy its style and then tell cegui what style it is (im not sure of any other way to accomplish what youre suggesting).

all this can be simplified by just specifying the font within the text string. another thing, is that when i use fonts of different sizes, i create entirely new font definitions for them so they look better -- for instance i have a 10 point font, and a 12 point font.

another issue is that from a clients point of view, they may get the impression cegui is able to draw fonts in a particular style, which would be next to impossible to accomplish given the way it currently generates and renders fonts (i think, i could be wrong). so then the user is sitting there scratching their head as to why <b>my string</b> is not actually rendering a bold font. this could be very frustrating.

good idea, i think it just overcomplicates things and the complexity can be reduced by simply specifying which font to use, in the text string, when drawing the text.
Last edited by ldb on Sun May 06, 2007 13:57, edited 1 time in total.
No matter where you go, there you are.

Rackle
CEGUI Team (Retired)
Posts: 534
Joined: Mon Jan 16, 2006 11:59
Location: Montréal

Re: Different colours in one string

Postby Rackle » Sat May 05, 2007 21:51

Each .font file describes a single font, in a single style (let's call it normal). In order to obtain a bold version there needs to be a second .font file, and a third font file for italic, and maybe a fourth for underline (although I suspect we can query the font for the ?baseline? position and draw a line a few pixels below).

A simple markup could be [use font file abc.font]text 1[use font file def.font]text 2[use font file ghi.font]text 3.

My more complex markup would require either modifying the .font files to contains the styles (bold, italic, bold-italic) or to expand the font manager along these lines:

Code: Select all

CEGUI::FontManager::getSingleton().createFont("Commonwealth-10.font", 10, "Commonwealth-10B.font", "Commonwealth-10I.font", "Commonwealth-10BI.font");


The imaginary parameters are 1) the "normal" font file, the font size, the bold font file, the italic font file, the bold-italic font file.

Yes it's more complex.

However I prefer to make the text strings more generic. That way an application can create all of its text for a particular font, specifying a generic size and style markup. Should it be decided that a different font is to be used within the application then all of these text files do not have to be modified.

Or what if the user can select the font to be displayed? This can be an even more difficult situation to deal with.

Anyway, these are just musings. I'm not ready to start coding anything just yet. Please everyone, provide lots and lots of ideas, as well as possible problems with any suggested approaches.

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

Postby Pompei2 » Sun May 06, 2007 12:08

This is a hard choice ... I think rackle's approach is an overkill, but it would be nice to have it :) But I'm not ready to implement such a complex thing. (That I don't need it yet is one reason).

Maybe we should create something like two different text-renderers. One with just the color codes, the other one with all the markup code. then by default every widget would use the (less memory consuming) first one (only colors).

But it would be possible to set a widget to use the more advanced one, like enable it for tooltips and some statictexts, but leaving it disabled for all buttons/listboxes/...

Also a function that says "let all tooltips use the advanced text renderer" would be nice.

As most people only want monocolored text in their widgets, maybe creating a very simple text renderer (the current one) and using this one as default would be even better.

Ah and last but not least, how should editboxes handle all this ??

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

Postby ldb » Sun May 06, 2007 12:28

Pompei2 wrote:This is a hard choice ... I think rackle's approach is an overkill, but it would be nice to have it :) But I'm not ready to implement such a complex thing. (That I don't need it yet is one reason).


yup, its essentially a rich text widget. im definitly not up for that challenge, and i dont really need such a widget.

im going to just go ahead and start hacking away at CEGUIFont to add some color markup, using Pompei2's suggestion of:

Code: Select all

pFont->setColorTrigger( "C|*" );
pFont->setColorFormat( Font::Hexadecimal | Font::BGRA );


thats pretty much perfect for my needs at the moment.

im not really one for planning things out too far ahead (my way of doing things is pretty much hack first, ask questions later -- i know that sounds bad, but it works surprisingly well for me), so im just gonna hack until it works pretty well. if i think it might be useful, ill post a patch. perhaps we can merge some code together if things overlap.
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 » Sun May 06, 2007 12:55

Ok, nice, I'll sit here, drink a coffee and wait for your patch :D

do you plan to integrate the ability to activate and de-activate it ?

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

Postby ldb » Sun May 06, 2007 12:59

Pompei2 wrote:do you plan to integrate the ability to activate and de-activate it ?


sure. i had planned on having it de-activated by default.

and be forewarned! the first patch will be messy!
No matter where you go, there you are.


Return to “Bug Reports, Suggestions, Feature Requests”

Who is online

Users browsing this forum: No registered users and 19 guests