GLFont - blitStringSpecial(...) blit text with color code and carriage return!

Started by nmare, August 10, 2013, 05:59:46 PM

Previous topic - Next topic

nmare

Hi devs,

Im using jpct-ae since at least 1 year now and i want to contribute to the community. So i offer you guys this little addon to the GLFont lib.  This is a way to say thank to Egon Olsen for his nice  support.

I needed for my GUI to display text in multi line with color codes. So I worked on my Label object to add this features. It gave an horrible code with terrible performances and
I quickly realized that I had to work directly in the GLFont class to get there.

The following code is not perfect. it work with a sacrifice of 20 FPS, so it is especially useful for text displays in the online help, credit pages or things like that. DO NOT USE IN A HUD.
If you need to keep fps high, you have to use the usual method.

I really worked hard to improve it, but the use of regex (even compiled) slowed everything.  It look like nothing, but i worked 3 evening on that thing...

Dont be shy to make change and you can easily add colors by adding the colors in the SwitchColor function and modifying the patternReplace pattern. Tell me if you see a way to optimize it.


How it work 

Carriage return: You add a '|' in your string every time you want to do a carriage return.  This function will also force a carriage return when you go past the bounds (with word wrap).

Color: You add a color code in your string to switch colors.  Color codes are /#0 to /#9. 


Text sample:

<string name="txtcredit">Game design by /#2Stephane Boivin/#9 (devgeek studio/www.puzzker.com)
||Programming (Web, 2d, 3d, android, database) by /#2Stephane Boivin/#9 (devgeek studio/www.puzzker.com)
||Opengl engine (jpct ae) was developed by /#2Egon Olsen/#9 (www.jpct.net)
||Illustrations by /#2Alexandre C./#9 (alex@alexbd.com, www.alexbd.com)
|||/#4(C) 2013 All right reserved to devgeek studio (www.devgeek.ca) </string>

Screen shot:



How to add it to your lib:

First you need to add this line of code in the properties of the GLFont Class. (Yeah, you can make it private also, but i needed it somewhere else)


public Paint PaintObject; // Make the paint object public for later use


And at the beginning of the GLFont(...) function, you add :    


PaintObject = paint;


Then you add this piece of code at the end of the GLFont class just before the "}". 


// Color Switch
// return true if color changed.
private boolean SwitchColor(String str) {
if( str.startsWith("/#") ) {
if( str.equals("/#0") ) color = RGBColor.BLACK;
if( str.equals("/#1") ) color = RGBColor.BLUE;
if( str.equals("/#2") ) color = RGBColor.GREEN;
if( str.equals("/#3") ) color = RGBColor.RED;
if( str.equals("/#4") ) color = new RGBColor(255,255,0); // yellow
if( str.equals("/#5") ) color = new RGBColor(15,5,120); // purple
if( str.equals("/#6") ) color = new RGBColor(235,65,235); // pink
if( str.equals("/#7") ) color = new RGBColor(215,155,35); // orange
if( str.equals("/#8") ) color = new RGBColor(128,128,128); // gray
if( str.equals("/#9") ) color = RGBColor.WHITE;
return true;
}
return false;
}

/* Made by Stephane Boivin from DevGeek Studio ( devgeek.ca / puzzker.com ) 2013
* Same of blitString but add special color codes, carriage return and a text width.
* @param buffer
*            buffer to blit into
* @param s
*            string to blit
* @param x
*            leftmost point
* @param transparency
*            transparency value, make sure >= 0
* @param width
*            text size (limit on x)
* @param y
*            baseline
* Codes:
* Color code: /#0 to /#9
* Carriage return: |
*/
public RGBColor color = RGBColor.WHITE; // Default color.
public void blitStringSpecial(FrameBuffer buffer, String s, int x, int y, int width, int transparency) {
char c;
int xPos = x; // char position
Point size;
boolean skip = false;
String chunk = "";
int charSpace = 0; // Chars count before next space
Pattern patternSplit = Pattern.compile("[ \\|]");
Pattern patternReplace = Pattern.compile("/#[0-9]"); // use "/#[0-9][A-Z]" to add more color code (/#A)
y -= baseline;

for (int i = 0; i < s.length(); i++) {
c = s.charAt(i);

// Carriage return if the next chunk of string go past the bounds
charSpace--;
if( charSpace <= 0 ) {
chunk = patternSplit.split(s.substring(i),0)[0]; // get next chunk
charSpace = chunk.length()-1;
chunk = patternReplace.matcher(chunk).replaceAll(""); // remove color codes

// Carriage return
if( xPos + (int)PaintObject.measureText(chunk) > x + width) { 
xPos = x;
y += this.fontHeight; 
}
}

// Check Color code
if( i+3 < s.length()) skip = SwitchColor(s.substring(i,i+3));

if( !skip ) {
int index = alphabet.indexOf(c);
if (index == -1)
index = alphabet.indexOf('?');
if (index != -1) {

if( c == '|' ) { // carriage return
xPos = x;
y += this.fontHeight; 
} else { // blit
size = pack.blit(buffer, index, xPos, y, transparency, false, color);
xPos += size.x;
}

}
} else i += 2; // skip the color code
}
}




Sample use:   

Font.color = RGBColor.WHITE;  // this line is optional as the default color is white anyway
Font.blitStringSpecial(fb, Text, TxtPosY, TxtPosX, Width - (Margin*2), 15);


Hope this help you.  I made this for my actual project (puzzker.com) an android puzzle game that will be released in the next month. I will add it this week end in the Project section of this forum.

P.S  Sorry for the grammar, english is my 2nd language.
DevGeek studio
Indie Developer (android, opengl, databases)

EgonOlsen

Looks nice! It might be possible to speed it up by replacing the regex by some custom code, but for the context it's used in, i guess it's fine the way it is.

nmare


Found a bug and probably few ways to boost it...  I will post some change soon.   I think i will communicate with the original author to see if i can publish a new version of his tool (with the original credits of course).
DevGeek studio
Indie Developer (android, opengl, databases)

raft

looks very useful, good work:) I've added link to this thread in GLFont's thread