Jump to content

Pseudo Rich Text modification for gdisp.c


king2

Recommended Posts

Edit: This is 'work in progress'. Make sure you read the entire thread to get the latest version of this feature

I wanted to get strikethrough effect for some part of my label's text, so I made modification to gdisp.c (added approximately 200 lines of code) and want to share this with other people. As this code inserted into GDISP, this feature can be used in any text found in different widgets, like buttons, checkboxes, lists and so on.

You can see results below on screenshot attached, different styles in one text in one label. Sorry for bad photo, I cannot make screenshot from my hardware :).

rich_text.thumb.png.f8380e61cf968b2e75ff

This styling was made by inserting special control characters into text (0xf000..0xf0ff, this is Unicode Private User Area, so we do not breaking anything). Each control character changes current style of all following characters. 0xf000 means default style, and others, means corresponding styles from 1 to 255.

Each of style can set:

  • change color of text or not and to which color
  • fill text background or not and with which color
  • underline or not, and with which color
  • strikethrough or not and with which color

To turn on this feature you should define GDISP_RICH_TEXT in your gfxconf.h.

How it looks from developer side (copied directly from firmware shown above (assuming that UTF-8 sequence 0xEF 0x80 0x81 is Unicode character 0xF001):

rich_text_style_t rich_text_styles[] = {
    { Red, White, Green, 0, RICH_TEXT_CHANGECOLOR | RICH_TEXT_UNDERLINED | RICH_TEXT_FILLBACKGROUND },
    { Blue, Yellow, 0, Red, RICH_TEXT_CHANGECOLOR | RICH_TEXT_STRIKETHROUGH | RICH_TEXT_FILLBACKGROUND }
};
rich_text_transition_t style_buffer[16];

gdispRichTextSetStyles((rich_text_style_t *) &rich_text_styles, sizeof(rich_text_styles), style_buffer, sizeof(style_buffer));

sprintf(datetime_str, "%02d.\xEF\x80\x81%02d.%04d\xEF\x80\x80 %02d:\xEF\x80\x82%02d\xEF\x80\x80:%02d", timp.tm_mday, timp.tm_mon+1, timp.tm_year+1900, timp.tm_hour, timp.tm_min, timp.tm_sec);

We should declare styles array, space for transitions, and initialize the 'engine'. It will scan each text for control characters and will build special list of transitions, removing control characters from text string (one function declared, used in gdispGDrawString()gdispGFillString()gdispGDrawStringBox() and gdispGFillStringBox() + another one to just strip characters, used in gdispGetStringWidthCount()). Transitions list contains array of structs with style start position and number of style that will be applied from this position, for each transition that will be found in text flow.

Next, in drawcharglyph() and fillcharglyph() callbacks one more function called, and applies these styles to characters painted on screen.

Number of transitions is limited by amount of memory given by uGFX user, line length can be up to 65535 characters. Developer can define and use to 255 styles.

I have attached patch files for gdisp.c and gdisp.h as well as modified files itself. It has extreme level of commenting inside, so I think it will be not so hard to understand what's going on under the hood. If you will find this patch useful enough, I will not resist too much from including this into uGFX core. :$

What are you thinking about this? Will it be useful?

rich_text.zip

Link to comment
Share on other sites

I have changed something, so see new file attached.

  • added possibility to use custom or default color for underline and strikethrough (added 2 new flags)
  • changed flags names (see gdisp.h)
  • fixed bug where background was not saved properly

Now we can change widget style, and underline/strikethrough color will be changed accordingly with that style. Sure, we still can override that colors with our own custom ones.

rich_text.zip

Link to comment
Share on other sites

  • 3 weeks later...

Sorry, but previous patch was a piece of junk. I was wrong modifying string 'in place', because it skips all rich text in all redraws except first one (I tested this on clock text, so everything looked ok). As this patch will be not included into main uGFX source code, I made another one, much simpler but still powerful, but it changes mcufont file.

How it works: 

  • I use left-to-right rendering always, even with right justify
  • it initializes default style at each rendering start
  • it applies styles without transitions buffer and modifying source string, so it much simpler

When initializing, you should use all as previous, but supplying transition buffer is not necessary, only styles description should be passed:

rich_text_style_t rich_text_styles[] = {
    { Gray, 0, 0, 0, RT_CHANGE_TEXT_COLOR },
    { Red, 0, 0, 0, RT_CHANGE_TEXT_COLOR },
    { Gray, 0, 0, 0, RT_CHANGE_TEXT_COLOR|RT_STRIKETHROUGH },
    { Blue, Yellow, 0, Red, RT_STRIKETHROUGH | RT_CHANGE_BG_COLOR }
};
gdispRichTextSetStyles((rich_text_style_t *) &rich_text_styles, sizeof((rich_text_style_t *) rich_text_styles));

Patch file included.

Feel free to ask questions, if you will have problems with it.

rich_text_patch2.zip

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...