📄 gu_font.c
字号:
//if (linesize>0) x = (maxwidth-gu_font_line_width_get( s )); }
int maxlines = (MAX_CACHE_LINES*16)/FONTHEIGHT; while (*c!='\0' && i<MAX_CACHE_STRING && numlines<=maxlines) { if (*c==' ')
{ x += CHARWIDTH('t');
c++;
} else if (*c=='\n')
{ numlines++;
c++; x = 0; if (IsSet(flags,FLAG_ALIGN_CENTER))
{ //linesize = strpos( c, '\n' ); x = ((maxwidth-gu_font_line_width_get( c))/2);
} else if (IsSet(flags,FLAG_ALIGN_RIGHT)) { //linesize = strpos( c, '\n' ); x = (maxwidth-gu_font_line_width_get( c)); } y += FONTHEIGHT; }
else if ((unsigned char)*c>=32)
{ gu_font_cache_glyph( x, y, *c, cache ); x += CHARWIDTH(*c);
c++; }
if (IsSet(flags,FLAG_CLIP_WRAP)) if (x>=472)
{ numlines++; x = 0; y += FONTHEIGHT; }
i++; }
}
void gu_font_safe_constructor(struct gu_font_struct *f)
{
if (f==0) return;
f->name[0] = '\0';
f->id = -1;
f->data = 0;
f->d_width = 0;
f->d_height = 0;
memset( f->chars, 0, 256*sizeof(struct gu_char_struct) );
}
void gu_font_safe_destructor(struct gu_font_struct *f)
{
if (f==0) return;
if (f->data!=0) free(f->data);
f->data = 0;
}
void gu_font_list_safe_constructor(struct gu_font_list_struct *f)
{
if (f==0) return;
f->font = 0;
f->next = 0;
}
void gu_font_list_safe_destructor(struct gu_font_list_struct *f)
{
if (f==0) return;
gu_font_safe_destructor(f->font);
f->next = 0;
}
char* gu_font_init()
{
if (gu_font_initialized==1) return(0);
char* result = gu_glyph_cache_init();
if (result!=0)
return(result);
// Create a white color CLUT usable by GU gu_font_color_set( 0xFFFFFF ); gu_font_border_color_set( 0x000000 ); // Black border
gu_font_initialized = 1;
return(0);
}
void gu_font_close()
{
if (gu_font_initialized==0) return;
gu_glyph_cache_free();
gu_font_free_all();
gu_font_initialized=0;
}
struct gu_font_struct* gu_font_find( char* name )
{
struct gu_font_list_struct *f = gu_font_manager.list;
while (f!=0)
{
if (f->font!=0)
{
if (strcmp( f->font->name, name)==0)
return(f->font);
}
f = f->next;
}
return(0);
}
struct gu_font_list_struct* gu_font_list_remove( char* name )
{
struct gu_font_list_struct *f = gu_font_manager.list;
if (f==0) return(0);
if (f->font!=0)
if (strcmp( f->font->name, name)==0)
{
gu_font_manager.list = f->next;
gu_font_manager.num_fonts--;
return(f);
}
while (f->next!=0)
{
if (f->next->font!=0)
{
if (strcmp( f->next->font->name, name)==0)
{
f->next = f->next->next;
gu_font_manager.num_fonts--;
return(f->next);
}
}
f = f->next;
}
return(0);
}
char* gu_font_load( char* name )
{
struct gu_font_struct* f = gu_font_find( name );
if (f!=0)
{
gu_cur_font = f;
return(0);
}
SceUID fd; if (!(fd = sceIoOpen( name, PSP_O_RDONLY, 0777)))
return("gu_font_load: Could not open file");
f = malloc(sizeof(struct gu_font_struct));
if (f==0)
{
sceIoClose(fd);
return("gu_font_load: malloc failed on f");
}
gu_font_safe_constructor( f );
strncpy(f->name,name,MAX_NAME_SIZE-1);
f->id = gu_font_manager.id_counter++;
f->d_width = 128;
f->d_height = 256;
struct gu_font_list_struct* new_list = malloc(sizeof(struct gu_font_list_struct));
if (new_list==0)
{
free(f);
sceIoClose(fd);
return("gu_font_load: malloc failed on new_list");
}
gu_font_list_safe_constructor(new_list);
new_list->font = f;
new_list->next = gu_font_manager.list;
f->data = memalign( 16, 256*128 ); if (f->data==0)
{
free(f);
free(new_list);
sceIoClose(fd);
return("gu_font_load: memalign failed on f->data");
}
struct gu_font_header_struct header; sceIoRead( fd,&header,sizeof(struct gu_font_header_struct) ); /*if (header.ID != FOURCC('G','U','F','1'))
{
free(f->data);
free(f);
free(new_list);
sceIoClose(fd);
return("gu_font_load: wrong filetype");
}
*/ sceIoRead( fd,f->chars,sizeof(struct gu_char_struct)*256 ); sceIoRead( fd,f->data,128*256 ); sceIoClose( fd ); sceKernelDcacheWritebackAll(); gu_font_manager.num_fonts++;
gu_font_manager.list = new_list;
gu_cur_font = f; return(0);
}
void gu_font_free( char* name )
{
struct gu_font_list_struct* f = gu_font_list_remove( name );
gu_font_list_safe_destructor( f );
}
void gu_font_free_all()
{
struct gu_font_list_struct* f = gu_font_manager.list;
struct gu_font_list_struct* t = 0;
while (f!=0)
{
t = f->next;
gu_font_list_safe_destructor(f);
f = t;
}
gu_font_manager.list = 0;
gu_font_manager.num_fonts = 0;
gu_font_manager.id_counter = 0;
}
void gu_font_set( char* name )
{
struct gu_font_struct* f = gu_font_find( name );
if (f!=0)
gu_cur_font = f;
}
void* gu_font_texture_get( char* name )
{
struct gu_font_struct* f = gu_font_find( name );
if (f==0) return(0);
return(f->data);
}
void gu_font_border_enable( int enable )
{
if (gu_font_border==enable) return; gu_font_border = enable; if (enable)
{ gu_font_border_color_set( gu_font_border_color ); gu_font_color_set( gu_font_color ); }
else
{ unsigned short* clut = (unsigned short*)(((unsigned int)gu_font_clut)|0x40000000); int i; for (i=0;i<8;i++) *(clut++) = 0x0; for (i=8;i<16;i++) *(clut++) = (i << 12) | BGR444(gu_font_color); }
}
void gu_font_border_color_set( int color )
{
gu_font_border_color = color; if (gu_font_border==0) return; unsigned short* clut = (unsigned short*)(((unsigned int)gu_font_clut)|0x40000000); int i; *(clut++) = 0x0; // Transparent parts always black for (i=1;i<8;i++) *(clut++) = (((i << 1)+1) << 12) | BGR444(color);
}
void gu_font_color_set( int color )
{
gu_font_color = color; unsigned short* clut = (unsigned short*)(((unsigned int)gu_font_clut)|0x40000000); int i; clut+=8; if (gu_font_border==0)
{ for (i=8;i<16;i++) *(clut++) = (i << 12) | BGR444(color); }
else
{ for (i=8;i<16;i++) *(clut++) = (15 << 12) | BGR444_blend(color,i); }
}
int gu_font_line_width_get( char* s )
{
if (s==0 || gu_cur_font==0) return 0; char* c = s; int x = 0; while (*c!='\0' && *c!='\n')
{ if (*c==' ')
{ x += CHARWIDTH('t'); }
else if ((unsigned char)*c>32)
{ x += CHARWIDTH(*c); } c++; } return (x);
}
int gu_font_width_get( char* s, int flag )
{
if (s==0 || gu_cur_font==0) return 0; char* c = s; int x = 0; int width = 0; if (flag == 0) flag--;
while (*c!='\0' && flag!=0)
{ if (*c==' ')
{ flag--; x += CHARWIDTH('t'); }
else if (*c=='\n')
{ if (x>width) width=x; x = 0; }
else if ((unsigned char)*c>32)
{ flag--; x += CHARWIDTH(*c); } c++; } return (x>width?x:width);
}
int gu_font_height_get( char* s )
{
if (s == 0 || gu_cur_font==0) return 0; char* c = s; int height = FONTHEIGHT;
while (*c!='\0')
{ if (*c=='\n')
{ height += FONTHEIGHT; } c++; } return (height);
}
inline int gu_font_height()
{
return FONTHEIGHT;
}
inline int gu_char_width_get( char c )
{
return CHARWIDTH(c);
}
inline int gu_char_height_get( char c )
{
return CHARHEIGHT(c);
}
void gu_font_printf( int x, int y, int flags, char* fmt, ... ) {
if (gu_cur_font==0) return;
va_list ap; char p[512]; va_start( ap,fmt ); vsnprintf( p,512,fmt,ap ); va_end( ap );
if (p[0]=='\0') return;
int width = gu_font_width_get( p, 0 );
int height = gu_font_height_get( p );
struct gu_glyph_cache_struct* gu_drawbuffer = gu_glyph_cache_manager_get( p, width, height, flags, gu_cur_font->id );
if (gu_drawbuffer==0) return;
if (gu_drawbuffer->cacheptr==0) return;
if (gu_drawbuffer->dirty==1)
{
gu_font_cache_string( p, width, flags, gu_drawbuffer->cacheptr );
}
// string is now in cache, so just draw sceGuClutMode(GU_PSM_4444,0,0xff,0); // 16-bit palette sceGuClutLoad((16/8),gu_font_clut); // upload 2*8 entries (16) sceGuTexMode(GU_PSM_T4,0,0,0); // 4-bit image, but unswizzled sceGuTexImage(0,512,MAX_CACHE_LINES*16,512,gu_drawbuffer->cacheptr); sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0);
sceGuTexFilter(GU_NEAREST,GU_NEAREST); sceGuEnable( GU_BLEND ); if (IsSet(flags,FLAG_SHADOW))
{ sceGuTexFunc(GU_TFX_MODULATE,GU_TCC_RGBA); blit_fast( 0, 0, width, height, x+2, y+2 ); } sceGuTexFunc(GU_TFX_REPLACE,GU_TCC_RGBA); blit_fast( 0, 0, width, height, x, y );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -