一般来说尽量不要频繁地穿越C/Lua边界,效率会掉很多。
这个功能其实最好在c源码中实现,似乎也不是特别麻烦。
- // 写竖立字符串
- // x,y 坐标
- // str 字符串
- // color 颜色
- // size 字体大小,字形为宋体。
- // fontname 字体名
- // charset 字符集 0 GBK 1 big5
- // OScharset 0 简体显示 1 繁体显示
- int JY_DrawVerticalStr(int x, int y, const char *str,int color,int size,const char *fontname,
- int charset, int OScharset)
- {
- SDL_Color c,c2;
- SDL_Surface *fontSurface=NULL;
- int w,h;
- SDL_Rect rect1,rect2,rect_dest;
- SDL_Rect rect;
- char tmp1[256],tmp2[256];
- Uint16 tmp3[2];
- TTF_Font *myfont;
- SDL_Surface *tempSurface;
- SDL_Surface *OriSurface = NULL;
- int i ;
- if(strlen(str)>127){
- JY_Error("JY_DrawStr: string length more than 127: %s",str);
- return 0;
- }
- myfont=GetFont(fontname,size);
- if(myfont==NULL)
- return 1;
- c.r=(Uint8) ((color & 0xff0000) >>16);
- c.g=(Uint8) ((color & 0xff00)>>8);
- c.b=(Uint8) ((color & 0xff));
- c2.r=c.r>>1; //阴影色
- c2.b=c.b>>1;
- c2.g=c.g>>1;
- if(charset==0 && OScharset==0){//GBK -->unicode简体
- JY_CharSet(str,tmp2,3);
- }
- else if(charset==0 && OScharset==1){//GBK -->unicode繁体
- JY_CharSet(str,tmp1,1);
- JY_CharSet(tmp1,tmp2,2);
- }
- else if(charset==1 && OScharset==0){ //big5-->unicode简体
- JY_CharSet(str,tmp1,0);
- JY_CharSet(tmp1,tmp2,3);
- }
- else if(charset==1 && OScharset==1){ ////big5-->unicode繁体
- JY_CharSet(str,tmp2,2);
- }
- else{
- strcpy(tmp2,str);
- }
- //增加\n
- tmp3[1] = 0;
- for(i=0;i<256;i+=2){
- *tmp3 = *(Uint16 *)(tmp2 + i);
- if(tmp3[0] == 0)break;
- if(g_Rotate==0){
- rect=g_Surface->clip_rect;
- }
- else{
- rect=RotateReverseRect(&g_Surface->clip_rect);
- }
- TTF_SizeUNICODE(myfont, (Uint16 *)tmp3, &w, &h);
- if( (x>=rect.x+rect.w) || (x+w+1) <=rect.x ||
- (y>=rect.y+rect.h) || (y+h+1) <=rect.y){ // 超出裁剪范围则不显示
- return 1;
- }
- fontSurface=TTF_RenderUNICODE_Blended(myfont,(Uint16 *)tmp3, c); //生成表面
- if(fontSurface==NULL)
- return 1;
-
- rect1.x=(Sint16)x;
- rect1.y=(Sint16)(y + (i / 2) * fontSurface->h);
- rect1.w=(Uint16)fontSurface->w;
- rect1.h=(Uint16)fontSurface->h;
- //JY_ShowSurface(0);
- if(g_Rotate==0){
- rect2=rect1;
- //rect_dest.x=rect2.x+1;
- //rect_dest.y=rect2.y+1;
- //SDL_SetColors(fontSurface,&c2,1,1);
- //SDL_BlitSurface(fontSurface, NULL, g_Surface, &rect_dest); //表面写到游戏表面--阴影色
- rect_dest.x=rect2.x;
- rect_dest.y=rect2.y;
- SDL_SetColors(fontSurface,&c,1,1);
- //SDL_BlitSurface(fontSurface, NULL, OriSurface, &rect_dest); //表面写到ori表面
- SDL_BlitSurface(fontSurface, NULL, g_Surface, &rect_dest); //表面写到ori表面
- }
- else if(g_Rotate==1){
- tempSurface=RotateSurface(fontSurface);
- SDL_FreeSurface(fontSurface);
- fontSurface=tempSurface;
- rect2=RotateRect(&rect1);
- //rect_dest.x=rect2.x-1;
- //rect_dest.y=rect2.y+1;
- //SDL_SetColors(fontSurface,&c2,1,1);
- //SDL_BlitSurface(fontSurface, NULL, g_Surface, &rect_dest); //表面写到游戏表面 --阴影色
- rect_dest.x=rect2.x;
- rect_dest.y=rect2.y;
- SDL_SetColors(fontSurface,&c,1,1);
- //SDL_BlitSurface(fontSurface, NULL, OriSurface, &rect_dest); //表面写到ori表面
- SDL_BlitSurface(fontSurface, NULL, g_Surface, &rect_dest); //表面写到ori表面
-
- }
- SDL_FreeSurface(fontSurface); //释放表面
- SDL_FreeSurface(OriSurface); //释放表面
- }
- //free(tmp3);
- return 0;
- }
复制代码 随后在边界函数处改成这样,给drawstr增加一个隐藏参数Vertical,倘若被赋值则执行竖排绘制字符串
- int HAPI_DrawStr(lua_State *pL)
- {
- int x=(int)lua_tonumber(pL,1);
- int y=(int)lua_tonumber(pL,2);
- const char *str=lua_tostring(pL,3);
- int color=(int)lua_tonumber(pL,4);
- int size=(int)lua_tonumber(pL,5);
- const char *fontname=lua_tostring(pL,6);
- int charset=(int)lua_tonumber(pL,7);
- int OScharset=(int)lua_tonumber(pL,8);
- if(lua_isnoneornil(pL,9)==0 ){
- JY_DrawVerticalStr(x, y, str,color,size,fontname,charset,OScharset);
- }
- else
- {
- JY_DrawStr(x, y, str,color,size,fontname,charset,OScharset);
- }
复制代码 lua的边界接口函数也只需稍微处理一下即可
- function DrawString(x,y,str,color,size,vert) --显示阴影字符串,增加竖排绘制
- -- local r,g,b=GetRGB(color);
- -- lib.DrawStr(x+1,y+1,str,RGB(math.modf(r/2),math.modf(g/2),math.modf(b/2)),size,CC.FontName,CC.SrcCharSet,CC.OSCharSet);
- lib.DrawStr(x,y,str,color,size,CC.FontName,CC.SrcCharSet,CC.OSCharSet,vert);
- end
复制代码 PS:我这里将阴影字符串注释掉了,如果有人想移植的话需要更改部分内容。
基本上改好,整个代码只穿过一次边界,效率应该比每次都要穿越一次边界的lua法来的高些。 |