Need fast font library

Discuss the development of new homebrew software, tools and libraries.

Moderators: cheriff, TyRaNiD

Post Reply
ne0h
Posts: 386
Joined: Thu Feb 21, 2008 2:15 am

Need fast font library

Post by ne0h »

Hi,
I'm working on a text editor, I've tried to use intraFont to blit text, but it's very slow, so I need a fastest font library?
What library can I use?
Better if with ttf support!
Thanks!
J.F.
Posts: 2906
Joined: Sun Feb 22, 2004 11:41 am

Post by J.F. »

There's four ways of doing text: TTF (standard lib), PGFonts (custom font thingy used in the olden days), intraFont, and do-it-yourself. I haven't seen a case where intraFont was slow before. Might be something about how you're trying to use it rather than the lib itself. In general, if you think intraFont is too slow, you're going to have to do it yourself by hand for any better speed.
ne0h
Posts: 386
Joined: Thu Feb 21, 2008 2:15 am

Post by ne0h »

Thanks, I'll try...
User avatar
Torch
Posts: 825
Joined: Wed May 28, 2008 2:50 am

Post by Torch »

Since its a text editor, a small console type font should suffice, I assume.
In that case, you can simply take the blit.c sample and modify it to use the GU instead of writing pixels to VRAM.
ne0h
Posts: 386
Joined: Thu Feb 21, 2008 2:15 am

Post by ne0h »

Torch, if is possible I'll write the text editor with a good font, not a simple console text...
Anyway I'm trying to improve it for a best speed...
ne0h
Posts: 386
Joined: Thu Feb 21, 2008 2:15 am

Post by ne0h »

What I can do to speed up the blitting function of intraFont?
The text editor without text writted works at 100 fps, if I've a half of page with text it slows down to 10fps!
So, intraFont is slow to blit text!
I've already tried to speed it up doing what Benhur has sayd ( INTRAFONT_CACHE_ALL ) but it was still too much slow!
Is the ttf library more efficent?
Sorry for my english...

ne0h
Pirata Nervo
Posts: 409
Joined: Tue Oct 09, 2007 4:22 am

Post by Pirata Nervo »

Why not just blit when something changes?
There's no need on keep blitting the whole text every loop when nothing is changed.
Blit it one time, if the user presses any button blit again
Image
Upgrade your PSP
J.F.
Posts: 2906
Joined: Sun Feb 22, 2004 11:41 am

Post by J.F. »

TrueType is HORRIBLY slow. If you think intraFont is slow, you don't even want to try TTF. :D

Have you tried playing with the alignment and scaling? Are you doing multiple characters at once or one at a time? You really don't give enough info here to help any.
Insert_witty_name
Posts: 376
Joined: Wed May 10, 2006 11:31 pm

Post by Insert_witty_name »

You could look at pgeFont, which uses TrueType fonts and is fast http://www.psp-programming.com/forums/i ... 458.0.html

intraFont is base on the code of pgeFont.

I'm unsure why you're getting such a slowdown with intraFont, unless you're doing something fundamentally wrong.
PosX100
Posts: 98
Joined: Wed Aug 15, 2007 1:02 am

Post by PosX100 »

A texture mapped font library should be enough.

Just cull out unwanted data from the screen , and render only
what's inside screen bounds.

If you want even more speed , just create a multi-layered tile array ,
& render only what's inside screen.

This is extremely fast method , since you're not looping through each tile/layer ,
but only to those that you're actually need.

Here's how to render only needed elements:

Code: Select all

//where "view"  = some "camera" vector
unsigned int head_x = abs(app->view.x / font->glyph->w);
unsigned int head_y = abs(app->view.y / font->glyph->h);

unsigned int max_elems_x = ( app->window.w / font->glyph->w );
unsigned int max_elems_y = ( app->window.h / font->glyph->h );

unsigned int end_x  = ((head_x+1) +  max_elems_x)%tilelayer[active_layer]->w;
unsigned int end_y  = ((head_y+1) +  max_elems_y)%tilelayer[active_layer]->h;

//looping through active tiles 

for &#40; register unsigned int y = head_y; y< end_y; y ++; &#41;
&#123;
	for &#40; register unsigned int x = head_x; x< end_x; x ++; &#41;
		&#123;
			TTEntry* e = &tileLayer&#91;active_layer&#93;->map&#91;y&#93;&#91;x&#93;;
                        handle&#40;e&#41;;
			//lala
		&#125;
&#125;
ne0h
Posts: 386
Joined: Thu Feb 21, 2008 2:15 am

Post by ne0h »

Ok, this is a a part of the main loop:

Code: Select all

while&#40;1&#41;
    &#123;
        sceCtrlReadBufferPositive&#40;&pad, 1&#41;;
        ne0h_CtrlReadLatch&#40;&latch&#41;;

        WindowsMgr.Window&#40;0, 0, 480, 272, "%s %s", language->globals.xplora , language->text_editor.text_editor&#41;;

        TextEditorBlitText&#40;&#41;;
        
        TextEditorBlitCursorIfNeeded&#40;&#41;;
        
        intraFontPrintf&#40;20, 20, "%d", cycle++&#41;;

        if&#40;danzeff&#41; danzeff_render&#40;&#41;;

        XgeScreenReplaceRefresh&#40;&#41;;

        &#91;... Othres checks for buttons ...&#93;
&#125;
If I try to comment out "TextEditorBlitText();" I've something like 100fps, otherwise 10fps...
The same if I comment out "real_x = intraFontPrintf(real_x, real_y, "%c", c);"

This is the code of TextEditorBlitText:

Code: Select all

void TextEditorBlitTextr&#40;&#41;
&#123;
    int line_from = Text->first_visible_line;
    int line_to = line_from + INTRAFONT_SCREEN_HEIGHT_LINES;
    if&#40;line_to > Text->lines&#41; line_to = Text->num_lines;

    int real_y_min = 30;
    int real_x_min = 0;

    int y = 0;
    int real_y = real_y_min;

    int line = line_from;
    for&#40;; line < line_to; line++&#41;
    &#123;
        TextLine* line1 = Text->lines&#91;line&#93;;
        if&#40;line1 && line1->text&#41;
        &#123;
            int col_to = line1->col_max;
            int x = 0;
            int real_x = real_x_min;
            
            int col = col_from;
            for&#40;; col_id < col_to; col_id++&#41;
            &#123;
                u8 c = a_line->text&#91;col_id&#93;;

                real_x = intraFontPrintf&#40;real_x, real_y, "%c", c&#41;;

                if&#40;line_id == Text->curr_line&#41;
                &#123;
                    cursor_pos&#91;line_id&#93;&#91;col_id&#93; = real_x;
                &#125;

                x++;
                if&#40;real_x > 470&#41;
                      break;
            &#125;
        &#125;
        y++;
        real_y += psp_font_height;
        if&#40;y > INTRAFONT_SCREEN_HEIGHT_LINES&#41;
               break;
    &#125;
&#125;
This blit on char at time for getting the right cursor position.
Anyway I've tried to blit the entire line at time, but it's still slow.
If the text blitted is 2 lines I've 60 fps and no-one problem,
if I've all the page filled by text it slow down to 5 - 6 fps!!
Anyway thanks!

Insert_witty_name, I'll try pgeFont,
thanks!

EDIT:
Insert_witty_name, have you a link for download it?
The one posted doesn't work!
PosX100
Posts: 98
Joined: Wed Aug 15, 2007 1:02 am

Post by PosX100 »

First of all , you're on the wrong track of implementing an
editor.

You shoud go a bit low level , and handle the "code" buffer
where the text is stored , but oh , well...

Here's how to optimize a bit the code(assuming you're culling out
unwanted text to be rendered) (, but i will have to repeat myself : you're on the wrong track) :

Code: Select all

void TextEditorBlitTextr&#40;&#41;
&#123;
	unsigned int	line_from = Text->first_visible_line ,
		//if this constant is what it sounds like , then 
		//you have to subtract it with current line index
               line_to = &#40;INTRAFONT_SCREEN_HEIGHT_LINES - line_from&#41;%Text->num_lines,
		y = 30 x = 0 , line = line_from;

    for&#40;; line < line_to; line++&#41;
    &#123;
        TextLine* line = Text->lines&#91;line&#93;;
		
	//assuming line structure has text structure which hold the text  
		intraFontPrintf&#40;x, y, "%s", &#40;char*&#41;line->text&#41;;
		
		y += psp_font_height + 1;

        if&#40;line_id == Text->curr_line&#41;
        &#123;
			cursor->x = &#40;xscroll*character_width&#41; % &#40;Text->lines&#91;line&#93;->char_count *character_width&#41;;
			curror->y = &#40;yscroll*character_height&#41; % &#40;INTRAFONT_SCREEN_HEIGHT_LINES * line height&#41;;
        &#125;
	&#125;

&#125;
ne0h
Posts: 386
Joined: Thu Feb 21, 2008 2:15 am

Post by ne0h »

I haven't understand!
What optimize your this code?
If I blit a entire line the speed is a bit different but not enough, maybe I can speed up to 7fps form 6, something like nothing...
Next I doesn't have a monospaced font, intraFont has not a constant width, so...
PosX100 wrote:handle the "code" buffer where the text is stored
I haven't understand, sorry.
What I've to check?
J.F.
Posts: 2906
Joined: Sun Feb 22, 2004 11:41 am

Post by J.F. »

I don't believe you're only getting 6-7 fps. It's not possible. I've worked on GUIs using intraFont, and they can easily get 60 FPS (not sure how much faster they can go as the gui always limits itself to no faster than the vertical blank rate). You've got something else slowing things down that are unrelated to intraFont.
PosX100
Posts: 98
Joined: Wed Aug 15, 2007 1:02 am

Post by PosX100 »

ne0h wrote:I haven't understand!
What optimize your this code?
If I blit a entire line the speed is a bit different but not enough, maybe I can speed up to 7fps form 6, something like nothing...
Next I doesn't have a monospaced font, intraFont has not a constant width, so...
PosX100 wrote:handle the "code" buffer where the text is stored
I haven't understand, sorry.
What I've to check?
If you can't understand , then i can't help .

Anyway , if you're getting 6-7 fps :

1)
There's some (more)bad code behind this(judging by your code,its possible)

2)
You're counting fps the WRONG way...
ne0h
Posts: 386
Joined: Thu Feb 21, 2008 2:15 am

Post by ne0h »

Ok, probably the code have some bugs, but why when I didn't print anything I've 100 "cycle" for second, and when I blit the text I've 10, or less "cycle" for second?
Can I improve the code for getting at least 30 "cycle" for second?
The code has maybe a lot of uneeded thinks, I can try to improve it, but I think that the font blit "section" is slower than the others...
The code that I've posted blit only the needed part of the text, nothing else...
J.F., I use intraFont in the main programm and it doesn't slows down, it's very fast, I don't know why in the text editor is very slow!
I'll try to improve the code, maybe intraFont is not really the main thing that slow down.
Anyway thanks!
J.F.
Posts: 2906
Joined: Sun Feb 22, 2004 11:41 am

Post by J.F. »

Like PosX100 said, maybe your FPS calculation is off... maybe the values you're getting are REALLY 1000 and 100, not 100 and 10. I can't see how a main loop with nothing going on (since you commented out the main thing) can ONLY get 100 FPS. I can get better than that on Doom with everything going. So either your calculation is off or your code is seriously farged somewhere. One way you can tell for certain is to change your while loop so that instead of running constantly, it instead does X loops and stops - say 600 loops. Time how long the app runs from when it enters the loop until it leaves and divide by 600. If it were really only 10 FPS, it would stay in the loop a minute.
PosX100
Posts: 98
Joined: Wed Aug 15, 2007 1:02 am

Post by PosX100 »

Calculating fps :

#1

Code: Select all

float timePrev = 0.0f;
int   fps      = 0;

&#123;
	const float timeNow  = getTimeInMs&#40;&#41; *.0001;

	//to get the delta for frame IDP games/apps&#58;
	//float delta = &#40;timeNow - timePrev&#41;;
 
	++fps;

	if&#40; timeNow - timePrev > 1.0f &#41;
	&#123;

		timePrev = timeNow;
		fps = 0;
	&#125;
&#125;
Or , per samples:

#2

Code: Select all


static const int FPS_SAMPLES = 48;
static float fpsSamplesBuf&#91;FPS_SAMPLES&#93;;
static int   currentSample = 0;
static float fps           = 0.0f;

void handleFpsSamples&#40;const float delta&#41;
&#123;
	fpsSamplesBuf&#91;currentSample % FPS_SAMPLES&#93; = &#40;float&#41;&#40;1.0f / delta&#41;;
	
	if&#40;currentSample >= FPS_SAMPLES-1&#41;
	&#123;
		currentSample = 0;
		
		fps = 0.0f;

		for&#40;int i = 0; i<FPS_SAMPLES; i++&#41;
			fps += fpsSamplesBuf&#91;i&#93;;

		if&#40;&#40;int&#41;fps&#41;
			fps /= FPS_SAMPLES;
	&#125;

	currentSample++;

&#125;

#3 or per per samples with accurate timing:

Code: Select all


static const int FPS_SAMPLES = 48;
static float fpsSamplesBuf&#91;FPS_SAMPLES&#93;;
static int   currentSample = 0;
static float timePrev      = 0.0f;
static float timeNow       = 0.0f;
static float delta   	   = 0.0f;
static float fps           = 0.0f;
static int   updateTimer   = 0;

void handleFpsSamples&#40;&#41;
&#123;
	timeNow  = getTimeInMs&#40;&#41; *.0001;

	delta = &#40;timeNow - timePrev&#41;;

	timePrev = timeNow;

	updateTimer += &#40;int&#41;&#40;delta&#41;;

	fpsSamplesBuf&#91;currentSample % FPS_SAMPLES&#93; = &#40;float&#41;&#40;1.0f / delta&#41;;
	
	if&#40;currentSample >= FPS_SAMPLES-1&#41;
	&#123;
		currentSample = 0;
		
		fps = 0.0f;

		for&#40;int i = 0; i<FPS_SAMPLES; i++&#41;
			fps += fpsSamplesBuf&#91;i&#93;;

		if&#40;&#40;int&#41;fps&#41;
			fps /= FPS_SAMPLES;
	&#125;

	if&#40; updateTimer >= 10&#41;
	&#123;
		updateTimer = 0;
		currentSample++;
	&#125;
&#125;

ne0h
Posts: 386
Joined: Thu Feb 21, 2008 2:15 am

Post by ne0h »

-.-, I don't need how to calculate fps
I've only write a estimated value
Anyway wait one minute, I'm trying to do something...
PosX100
Posts: 98
Joined: Wed Aug 15, 2007 1:02 am

Post by PosX100 »

ne0h wrote:-.-, I don't need how to calculate fps
I've only write a estimated value
lol...
ne0h wrote: intraFontPrintf(20, 20, "%d", cycle++);
WUT?
ne0h
Posts: 386
Joined: Thu Feb 21, 2008 2:15 am

Post by ne0h »

Ok, this code works around at 2000 fps

Code: Select all

while&#40;1&#41;
&#123;
        XgeClearScreen&#40;WHITE&#41;;
        
        intraFontPrintf&#40;40, 40, "%d", cycle++&#41;;
        
        XgeScreenReplaceRefresh&#40;&#41;;
&#125;
And this around at 200! -.-

Code: Select all

while&#40;1&#41;
&#123;
        XgeFillScreenRect&#40;WHITE, 0, 0, 480, 272&#41;;
        
        intraFontPrintf&#40;40, 40, "%d", cycle++&#41;;
        
        XgeScreenReplaceRefresh&#40;&#41;;
&#125;
The problem is FillScreenRect
( I'm using this function in the windowsmgr ), this is very slow!
This is the code:

Code: Select all

int skipX = PSP_LINE_SIZE - width;
    int x, y;
    XgeColor* data = XgeGetVramDrawBuffer&#40;&#41; + x0 + y0 * PSP_LINE_SIZE;
    for&#40;y = 0; y < height; y++, data += skipX&#41;
    &#123;
        for&#40;x = 0; x < width; x++, data++&#41;
            *data = Color;
    &#125;
What I can do to improve it?
I've also used "sceCtrlPeekBufferPositive", "sceCtrlReadBufferPositive" is more slow, why?
What's the difference between these two functions?
I've also tryied to blit the text with printf, so I can remove flipScreen and Window etc, and I've something like 10000 fps!!!
Anyway now the text editor with all the GUI elements blitted (but no text)
run around 1000 fps...
With text is around 100 fps, so very good!
This what I've done:

Code: Select all

while&#40;1&#41;
&#123;
        sceCtrlPeekBufferPositive&#40;&pad, 1&#41;;
        ne0h_CtrlReadLatch&#40;&latch&#41;;
        
        XgeClearScreen&#40;WHITE&#41;;
        
        TextEditorBlitTextEx&#40;&#41;;
        
        intraFontPrintf&#40;40, 40, "%d", cycle++&#41;;
        
        TextEditorBlitTextCursor&#40;&#41;;
        
        if&#40;danzeff&#41; danzeff_render&#40;&#41;;
        
        XgeScreenReplaceRefresh&#40;&#41;;
&#125;
TextEditorBlitTextEx:

Code: Select all

void TextEditorBlitTextEx&#40;&#41;
&#123;
    int line_from = Text->first_visible_line;
    int line_to = line_from + EDITOR_SCREEN_HEIGHT;
    if&#40;line_to > Text->num_lines&#41; line_to = Text->num_lines;

    int y = 0;
    int real_y = 30;
    
    int line_num;
    for&#40;line_num = line_from; line_num < line_to; line_num++&#41;
    &#123;
        TextLine* line = Text->lines&#91;line_num&#93;;
        if&#40;line && line->text&#41;
        &#123;
            if&#40;line->text&#91;0&#93; > ' '&#41;
                     intraFontPrintf&#40;0, real_y, line->text&#41;;
        &#125;
        y++;
        real_y += TextEditorFontHeight;
        if&#40;y > INTRAFONT_SCREEN_HEIGHT_LINES&#41; break;
    &#125;
&#125;
I've still a lot of things to improve, but the speed now is great!
THE ONLY one problem now I've is how to get the right position
of the cursor!!!
Anyway if I print the entire line is obviously faster that blit each character, sorry!
Thanks very much!
Last edited by ne0h on Sun Dec 14, 2008 1:44 am, edited 1 time in total.
ne0h
Posts: 386
Joined: Thu Feb 21, 2008 2:15 am

Post by ne0h »

PosX100 wrote:
ne0h wrote:intraFontPrintf(20, 20, "%d", cycle++);
WUT?
oh, yes, this is to estimate the fps...
PosX100
Posts: 98
Joined: Wed Aug 15, 2007 1:02 am

Post by PosX100 »

ne0h wrote:
PosX100 wrote:
ne0h wrote:intraFontPrintf(20, 20, "%d", cycle++);
WUT?
oh, yes, this is to estimate the fps...
Lol...
  • 10.000 fps
    2.000 fps
    1.000 fps
    200 fps
    100 fps
    10 fps
    7 fps
    6 fps
    2 fps
...lmao , i feel like i've been Rick roll'd
(http://www.youtube.com/watch?v=oHg5SJYRHA0).


You have no idea what you're saying ... don't you?.
If you wan't to calculate frames per second correctly , read my previous post.

If you don't wanna learn , i don't really care :-) , but just stop saying that you're calculating FPS...
ne0h
Posts: 386
Joined: Thu Feb 21, 2008 2:15 am

Post by ne0h »

PosX100 wrote:You have no idea what you're saying ... don't you?.
If you wan't to calculate frames per second correctly , read my previous post.
If you don't wanna learn , i don't really care :-) , but just stop saying that you're calculating FPS...
Ok,
I'm calculating how many cycle does the main loop,
it's only estimated by watching the value that is printed on the screen, with that i can see that in one second go from 120 to 130, so I've writed that I've 10fps, if is 11 or 9 is not a problem,
I don't need the exactly measure!
Are different if I've 10fps or 12?? 9 or 8? 1000 or 1021 ?
The main problem is not how many (exactly) fps does the main cycle...
I have others problems to resolve...
BenHur
Posts: 28
Joined: Sat Oct 20, 2007 5:26 pm

Post by BenHur »

ne0h wrote:Next I doesn't have a monospaced font, intraFont has not a constant width, so...
Yes, it does (but it's ugly). Study the sample provided with intraFont.
The 4th parameter of intraFontSetStyle lets you set the monospace-width, e.g. to 12 pixels:

Code: Select all

intraFontSetStyle&#40;ltn&#91;8&#93;, 1.0f,WHITE,BLACK,INTRAFONT_WIDTH_FIX | 12&#41;;
ne0h wrote:THE ONLY one problem now I've is how to get the right position of the cursor!!!
Easy, just use intraFontMeasureText to measure the length of the sub-string from the beginning of the line to the current cursor position.

Cheers, BenHur
ne0h
Posts: 386
Joined: Thu Feb 21, 2008 2:15 am

Post by ne0h »

Yes, I've seen this function, ( intraFontMeasure* ) but if I try to measure a string that contains special characters ( like 'è' or 'à' ) I've the lenght of he string form the first char to the firs special char!
I've also tryied intraFontMeasureTextUCS2, but this doesn't measure the "special" char, so I've the lenght of the string without special characters
Anyway I've tryied with fixed with of text on the results if not very good, it's ugly...
So if is possible I'll try to use the standard variable width!
Anyway thanks for intraFont BenHur, it's amazing!
BenHur
Posts: 28
Joined: Sat Oct 20, 2007 5:26 pm

Post by BenHur »

ne0h wrote:Yes, I've seen this function, ( intraFontMeasure* ) but if I try to measure a string that contains special characters ( like 'è' or 'à' ) I've the lenght of he string form the first char to the firs special char!
'è' and 'à' are not part of the standard ascii table (0x8A and 0x85), but part of the extended ascii table (which is not supported in intraFont). The corresponding unicode UCS2 values are 0x00E0 and 0x00E8. See:

Code: Select all

http&#58;//www.psp-programming.com/benhur/pgf_char_table_ltn0.htm
The 0x8A and 0x85 chars do not exist in ltn0.pgf, thus a zero length is measured and nothing is displayed, correct?
Since I encountered this issue before, I should add support for the extended ascii table. I'll do it as soon as I find the time...
In the mean-time you can either use text files with a correct UCS2 encoding or do the extended ascii to UCS2 conversion yourself.

Cheers, BenHur

Update:
I released intraFont 0.23, it supports UTF-8 encoded input and a few codepages (currently only 437, 850 and win-1252; let me know if you need others, they're easy to add).
With these features displaying special characters (e.g. Umlaute, accents, ...) should no longer be a problem - if the codepage is set to match the input or UTF-8 encoded input is used.

Cheers, BenHur
Post Reply