📄 gu_font.c.svn-base
字号:
/*PMP ModCopyright (C) 2006 RaphaelE-mail: raphael@fx-world.orgThis program is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2 of the License, or(at your option) any later version.This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.*//*font rendering system*/// TODO: Clean up again// TODO: fix temporary cache for multi-use#include <pspkernel.h>#include <pspiofilemgr.h>#include <pspgu.h>#include <stdarg.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <malloc.h>#include <math.h>#include "common/mem64.h"#include "gu_font.h"#include "common/texture_subdivision.h"static FT_Library library = 0;static FT_Open_Args open_args;static FT_StreamRec font_stream;static char font_filename[1024];static FT_Face face = 0;static FT_Stroker stroker = 0;static unsigned long gufont_font_stream_io( FT_Stream stream, unsigned long offset, unsigned char* buffer, unsigned long count ) { sceIoLseek32(stream->descriptor.value, offset, PSP_SEEK_SET); if ( count == 0 ) return 0; return sceIoRead(stream->descriptor.value, buffer, count);}static void gufont_font_stream_close(FT_Stream stream) { sceIoClose( stream->descriptor.value );}int gufont_haveflags = GU_FONT_HAS_UNICODE_CHARMAP;int gufont_hasitalic = 0;int gufont_hasbold = 0;static unsigned int gufont_color = 0xffffff;static unsigned int gufont_border_color = 0x000000;static unsigned int gufont_border_enable = 0;static float gufont_border_size = 1.0;static unsigned int gufont_pixel_size = 16;static unsigned int gufont_char_width = 16;static unsigned int gufont_char_height = 16;static float gufont_asc_scale = 2.0;static float gufont_multcode_scale = 1.0;static unsigned int gufont_embolden_enable = 0;static unsigned int gufont_align = 1;static unsigned int gufont_distance = 16;static int gu_font_initialized = 0;#define DIVWIDTH 3#define CHARSCALEWIDTH( fixed_width, scale ) ((int)(1.0*fixed_width/scale))#define CHARWIDTH(c) (((c > 255)?CHARSCALEWIDTH(gufont_char_width,gufont_multcode_scale) : CHARSCALEWIDTH(gufont_char_width,gufont_asc_scale)))#define CHARWIDTH2(c,style) (((c > 255)?CHARSCALEWIDTH(gufont_char_width,gufont_multcode_scale):CHARSCALEWIDTH(gufont_char_width,gufont_asc_scale)))#define SBIT_HASH_SIZE (997)typedef struct Cache_Bitmap_{ int width; int height; int left; int top; char format; short max_grays; int pitch; unsigned char* buffer;} Cache_Bitmap;typedef struct SBit_HashItem_ { unsigned long ucs_code; int glyph_index; int size; int embolden; int xadvance; int yadvance; Cache_Bitmap bitmap; Cache_Bitmap border_bitmap;} SBit_HashItem;static SBit_HashItem sbit_hash_root[SBIT_HASH_SIZE];#define IsSet(val,flag) (val&flag)==flagtypedef u32 Color;#define A(color) ((u8)(color >> 24 & 0x000000FF))#define B(color) ((u8)(color >> 16 & 0x000000FF))#define G(color) ((u8)(color >> 8 & 0x000000FF))#define R(color) ((u8)(color & 0x000000FF))#define DRAW_BUFFER_SIZE 262144#define SUB_SCREEN_WIDTH 480#define SUB_SCREEN_HEIGHT 128#define SUB_SCREEN_TEXTURE_WIDTH 512static int gufont_output_width = 480;static int gufont_output_height = 272;static int gufont_output_sub_width = SUB_SCREEN_WIDTH;static int gufont_output_sub_height = SUB_SCREEN_HEIGHT;static int gufont_output_x = 0;static int gufont_output_y = 0;static unsigned char __attribute__((aligned(64))) sub_8888[DRAW_BUFFER_SIZE];static unsigned char __attribute__((aligned(64))) border_sub_8888[DRAW_BUFFER_SIZE]; static char cache_string[2048];struct vertex_struct { short texture_x; short texture_y; float vertex_x; float vertex_y; float vertex_z; };void putPixelScreenBuffer(void* buffer, Color color, int x, int y){ *((Color*)buffer+y*SUB_SCREEN_TEXTURE_WIDTH+x) = color;}void draw_cachedbitmap(void *buffer, Cache_Bitmap* sbt, FT_Int x, FT_Int y, int width, int height, Color color){ FT_Int i, j; Color pixel, grey; int a, r, g, b; if( !sbt->buffer ) return; if(sbt->format ==FT_PIXEL_MODE_MONO){ for(j = 0; j< sbt->height; j++) for(i = 0; i< sbt->width ; i++) { if( i+x < 0 || i+x >= width || j+y < 0 || j+y >= height) continue; if ( sbt->buffer[j*sbt->pitch+i/8] & (0x80>>(i%8)) ) pixel = color; else pixel = 0; if (pixel) putPixelScreenBuffer(buffer, pixel, i+x, j+y); } } else if(sbt->format ==FT_PIXEL_MODE_GRAY){ for(j = 0; j< sbt->height; j++) for(i = 0; i< sbt->width ; i++) { if( i+x < 0 || i+x >= width || j+y < 0 || j+y >= height) continue; grey = sbt->buffer[j*sbt->pitch+i]; if ( grey ) { { //a = (grey * A(color)) / 255; r = (grey * R(color)) / 255; g = (grey * G(color)) / 255; b = (grey * B(color)) / 255; } pixel = (0xff000000) | (b << 16) | (g << 8) | r; } else pixel = 0; if (pixel) putPixelScreenBuffer(buffer, pixel, i+x, j+y); } }}void draw_bitmap(void *buffer, FT_Bitmap *bitmap, FT_Int x, FT_Int y, int width, int height, Color color){ FT_Int i, j; Color pixel, grey; int a, r, g, b; if( !bitmap->buffer ) return; if(bitmap->pixel_mode ==FT_PIXEL_MODE_MONO){ for(j = 0; j< bitmap->rows; j++) for(i = 0; i< bitmap->width ; i++) { if( i+x < 0 || i+x >= width || j+y < 0 || j+y >= height) continue; if ( bitmap->buffer[j*bitmap->pitch+i/8] & (0x80>>(i%8)) ) pixel = color; else pixel = 0; if (pixel) putPixelScreenBuffer(buffer, pixel, i+x, j+y); } } else if(bitmap->pixel_mode ==FT_PIXEL_MODE_GRAY){ for(j = 0; j< bitmap->rows; j++) for(i = 0; i< bitmap->width ; i++) { if( i+x < 0 || i+x >= width || j+y < 0 || j+y >= height) continue; grey = bitmap->buffer[j*bitmap->pitch+i]; if ( grey ) { { //a = (grey * A(color)) / 255; r = (grey * R(color)) / 255; g = (grey * G(color)) / 255; b = (grey * B(color)) / 255; } pixel = (0xff000000) | (b << 16) | (g << 8) | r; } else pixel = 0; if (pixel) putPixelScreenBuffer(buffer, pixel, i+x, j+y); } }}// NOTE: the following function only handles triple byte utf8 encodings maximumstatic unsigned short get_next_utf8( char** utf8 ) { if ((*utf8)==0) return 0; // skip follow-bytes at start of stream while ((*(*utf8)&0xC0)==0x80) (*utf8)++; unsigned char u1 = *(*utf8); if ((u1&0x80)==0) return ((unsigned short)u1); // ASCII else if ((u1&0xE0)==0xC0) { (*utf8)++; unsigned char u2 = *(*utf8); // return (((unsigned short)(u1&0x1F) << 6) | (unsigned short)(u2&0x3F)); } else if ((u1&0xF0)==0xE0) { (*utf8)++; unsigned char u2 = *(*utf8)++; unsigned char u3 = *(*utf8); return (((unsigned short)(u1&0xF) << 12) | ((unsigned short)(u2&0x3F)<<6) | (unsigned short)(u3&0x3F)); } else return (unsigned short)u1; }static unsigned short get_next_utf16le( short** utf16 ) { if ((*utf16)==0) return 0; return (unsigned short)(*(*utf16)); }static unsigned short get_next_utf16be( short** utf16 ) { if ((*utf16)==0) return 0; unsigned short u1 =*(*utf16); return (unsigned short)(((u1&0xFF)<<8)|(u1>>8)); }#define SWAPBYTES(c) ((((c)&0xFF)<<8)|((c)>>8))static short* utf16be2le( short* utf16 ) { if (utf16==0) return 0; short* utf16le = utf16; while (*utf16le!=0) { *utf16le++ = SWAPBYTES(*utf16le); } return(utf16); }static int gu_font_parse_bbcode( char** c, int* style ) { if (c==0 || *c==0) return(0); register char c0 = (*c)[0], c1 = (*c)[1], c2 = (*c)[2], c3 = (*c)[3]; if (c0=='[') { // parse bbcode formatting if (c1=='/' && c3==']') { if (c2=='i' || c2=='I') { *style &= ~GU_FONT_ITALIC; (*c)+=3; } else if (c2=='b' || c2=='B') { *style &= ~GU_FONT_BOLD; (*c)+=3; } else return(0); } else if (c2==']') { if (c1=='i' || c1=='I') { *style |= GU_FONT_ITALIC; (*c)+=2; } else if (c1=='b' || c1=='B') { *style |= GU_FONT_BOLD; (*c)+=2; } else return(0); } else return(0); } else return(0); return(1); } static int gu_font_utf16le_parse_bbcode( short** c, int* style ) { if (c==0 || *c==0) return(0); register short c0 = (*c)[0], c1 = (*c)[1], c2 = (*c)[2], c3 = (*c)[3]; if (c0=='[') { // parse bbcode formatting if (c1=='/' && c3==']') { if (c2=='i' || c2=='I') { *style &= ~GU_FONT_ITALIC; (*c)+=3; } else if (c2=='b' || c2=='B') { *style &= ~GU_FONT_BOLD; (*c)+=3; } else return(0); } else if (c2==']') { if (c1=='i' || c1=='I') { *style |= GU_FONT_ITALIC; (*c)+=2; } else if (c1=='b' || c1=='B') { *style |= GU_FONT_BOLD; (*c)+=2; } else return(0); } else return(0); } else return(0); return(1); }static int gu_font_utf16be_parse_bbcode( short** c, int* style ) { if (c==0 || *c==0) return(0); if (SWAPBYTES((*c)[0])=='[') { // parse bbcode formatting if (SWAPBYTES((*c)[1])=='/' && SWAPBYTES((*c)[3])==']') { if (SWAPBYTES((*c)[2])=='i' || SWAPBYTES((*c)[2])=='I') { *style &= ~GU_FONT_ITALIC; (*c)+=3; } else if (SWAPBYTES((*c)[2])=='b' || SWAPBYTES((*c)[2])=='B') { *style &= ~GU_FONT_BOLD; (*c)+=3; } else return(0); } else if (SWAPBYTES((*c)[2])==']') { if (SWAPBYTES((*c)[1])=='i' || SWAPBYTES((*c)[1])=='I') { *style |= GU_FONT_ITALIC; (*c)+=2; } else if (SWAPBYTES((*c)[1])=='b' || SWAPBYTES((*c)[1])=='B') { *style |= GU_FONT_BOLD; (*c)+=2; } else return(0); } else return(0); } else return(0); return(1); }void sbit_cache_init(void){ int i; for (i = 0; i < SBIT_HASH_SIZE; ++i) { memset(&sbit_hash_root[i], 0, sizeof(SBit_HashItem)); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -