• cocos2dx 文本 优化


      不得不说,CCLabelTTF是一个很鸡肋的组件,在2dx for ios库里面,它的底层使用了UIKit包来实现文本显示,但其显示特性较弱,几乎不可扩展。比如实现文字阴影,描边还有另一个更2的问题,当我们采用2dx的多分辨解决方案时,如

    CCDirector::sharedDirector()->setContentScaleFactor(2.0); 这时的所有的文字都模糊不清,惨不忍睹。很多人此时会考虑抛弃ios默认字体,该自定义字体库,但几千个字符(包括诸如日文,韩文等)全部整合起来还是很麻烦的

        首先,我们追根溯源,查看2dx源代码,发现CCLabelTTF底层是由CCImage来渲染的,核心代码 

    《CCImage.mm》

    static bool _initWithString(const char * pText, cocos2d::CCImage::ETextAlign eAlign, const char * pFontName, int nSize, tImageInfo* pInfo)

    关于代码细节此处不再详解,大致是用NSString 的draw方法来绘制文字,这里我们仿造来写一个

    1.在《CCImage.h》中加入这些方法

    //UIImage转CCImage
    
        bool initWithUIImage(void* uimg);
    
     /**
    
    获取文字显示大小,注意,只是获取文字的显示区域大小,这个大小是 依据文字fontsize,是否换行等属性来确定,也就是说,调用该方法,文字并未渲染!*/
    
        static CCSize getImageStringSize(const char *pText,float fontSize, ccColor3B fillColor,ccColor4B shadowColor,bool isShadow,CCSize dimensions,CCTextAlignment hAlignment ,CCVerticalTextAlignment vAlignment);
    
    //渲染文字
    
        void initWithShadowLabel( const char * pText,float fontSize,ccColor3B fillColor,ccColor4B shadowColor,bool isShadow = true,CCSize dimensions = CCSizeZero,CCTextAlignment h = kCCTextAlignmentLeft,CCVerticalTextAlignment v = kCCVerticalTextAlignmentTop);

     2. 

      1 // UIImage转CCImage
      2 
      3 bool CCImage::initWithUIImage(void* uimg)
      4 
      5 {
      6 
      7     CGImageRef CGImage = [(UIImage *)uimg CGImage];
      8 
      9     tImageInfo info = {0};
     10 
     11     bool bRet = _initWithImage(CGImage, &info);
     12 
     13     if (bRet)
     14 
     15     {
     16 
     17         m_nHeight = (short)info.height;
     18 
     19         m_nWidth = (short)info.width;
     20 
     21         m_nBitsPerComponent = info.bitsPerComponent;
     22 
     23         m_bHasAlpha = info.hasAlpha;
     24 
     25         m_bPreMulti = info.isPremultipliedAlpha;
     26 
     27         m_pData = info.data;
     28 
     29     }
     30 
     31     return bRet;
     32 
     33 }
     34 
     35 CCSize CCImage::getImageStringSize(const char *pText,float fontSize, ccColor3B fillColor,ccColor4B shadowColor,bool isShadow,CCSize dimensions,CCTextAlignment hAlignment ,CCVerticalTextAlignment vAlignment)
     36 
     37 {
     38 
     39     ETextAlign align;
     40 
     41     //获取文本对齐方式
     42 
     43     if (kCCVerticalTextAlignmentTop == vAlignment)
     44 
     45     {
     46 
     47         align = (kCCTextAlignmentCenter == hAlignment) ? CCImage::kAlignTop
     48 
     49         : (kCCTextAlignmentLeft == hAlignment) ? CCImage::kAlignTopLeft : CCImage::kAlignTopRight;
     50 
     51     }
     52 
     53     elseif (kCCVerticalTextAlignmentCenter == vAlignment)
     54 
     55     {
     56 
     57         align = (kCCTextAlignmentCenter == hAlignment) ? CCImage::kAlignCenter
     58 
     59         : (kCCTextAlignmentLeft == hAlignment) ? CCImage::kAlignLeft : CCImage::kAlignRight;
     60 
     61     }
     62 
     63     elseif (kCCVerticalTextAlignmentBottom == vAlignment)
     64 
     65     {
     66 
     67         align = (kCCTextAlignmentCenter == hAlignment) ? CCImage::kAlignBottom
     68 
     69         : (kCCTextAlignmentLeft == hAlignment) ? CCImage::kAlignBottomLeft : CCImage::kAlignBottomRight;
     70 
     71     }
     72 
     73     else
     74 
     75     {
     76 
     77         CCAssert(false, "Not supported alignment format!");
     78 
     79     }
     80 
     81 //此处可以自己修改成其他字体样式,经过比较,我们选择使用系统加粗字体
     82 
     83     UIFont *font = [UIFont boldSystemFontOfSize:fontSize];
     84 
     85     NSString *str = [NSString stringWithUTF8String:pText];
     86 
     87     CGSize dim, constrainSize;
     88 
     89     constrainSize.width = dimensions.width;
     90 
     91     constrainSize.height = dimensions.height;
     92 
     93     // create the font ,这块代码 从引擎拷贝过来
     94 
     95     if (font)
     96 
     97     {
     98 
     99         dim = _calculateStringSize(str, font, &constrainSize);
    100 
    101     }
    102 
    103     // compute start point
    104 
    105     int startH = 0;
    106 
    107     if (constrainSize.height > dim.height)
    108 
    109     {
    110 
    111         // vertical alignment
    112 
    113         unsigned int vAlignment = (align >> 4) & 0x0F;
    114 
    115         if (vAlignment == ALIGN_TOP)
    116 
    117         {
    118 
    119             startH = 0;
    120 
    121         }
    122 
    123         else if (vAlignment == ALIGN_CENTER)
    124 
    125         {
    126 
    127             startH = (constrainSize.height - dim.height) / 2;
    128 
    129         }
    130 
    131         else
    132 
    133         {
    134 
    135             startH = constrainSize.height - dim.height;
    136 
    137         }
    138 
    139     }
    140 
    141     return CCSizeMake(dim.width, dim.height - startH);
    142 
    143 }
    144 
    145  
    146 
    147 void CCImage::initWithShadowLabel(const char *pText,float fontSize, ccColor3B fillColor,ccColor4B shadowColor,bool isShadow,CCSize dimensions,CCTextAlignment hAlignment ,CCVerticalTextAlignment vAlignment)
    148 
    149 {
    150 
    151     do {    
    152 
    153         CGFloat scaleFactor = CCDirector::sharedDirector()->getContentScaleFactor();
    154 
    155         //获取文本对齐方式
    156 
    157         ETextAlign align;
    158 
    159         if (kCCVerticalTextAlignmentTop == vAlignment)
    160 
    161         {
    162 
    163             align = (kCCTextAlignmentCenter == hAlignment) ? CCImage::kAlignTop
    164 
    165             : (kCCTextAlignmentLeft == hAlignment) ? CCImage::kAlignTopLeft : CCImage::kAlignTopRight;
    166 
    167         }
    168 
    169         elseif (kCCVerticalTextAlignmentCenter == vAlignment)
    170 
    171         {
    172 
    173             align = (kCCTextAlignmentCenter == hAlignment) ? CCImage::kAlignCenter
    174 
    175             : (kCCTextAlignmentLeft == hAlignment) ? CCImage::kAlignLeft : CCImage::kAlignRight;
    176 
    177         }
    178 
    179         elseif (kCCVerticalTextAlignmentBottom == vAlignment)
    180 
    181         {
    182 
    183             align = (kCCTextAlignmentCenter == hAlignment) ? CCImage::kAlignBottom
    184 
    185             : (kCCTextAlignmentLeft == hAlignment) ? CCImage::kAlignBottomLeft : CCImage::kAlignBottomRight;
    186 
    187         }
    188 
    189         else
    190 
    191         {
    192 
    193             break;
    194 
    195         }
    196 
    197         UIFont *font = [UIFont boldSystemFontOfSize:fontSize];
    198 
    199         NSString *str = [NSString stringWithUTF8String:pText];
    200 
    201         CC_BREAK_IF(!font);
    202 
    203         CGSize dim, constrainSize;
    204 
    205         constrainSize.width = dimensions.width;
    206 
    207         constrainSize.height = dimensions.height;
    208 
    209         
    210 
    211         // create the font
    212 
    213  
    214 
    215         dim = _calculateStringSize(str, font, &constrainSize);
    216 
    217         
    218 
    219         // compute start point
    220 
    221         int startH = 0;
    222 
    223         if (constrainSize.height > dim.height)
    224 
    225         {
    226 
    227             // vertical alignment
    228 
    229             unsigned int vAlignment = (align >> 4) & 0x0F;
    230 
    231             if (vAlignment == ALIGN_TOP)
    232 
    233             {
    234 
    235                 startH = 0;
    236 
    237             }
    238 
    239             else if (vAlignment == ALIGN_CENTER)
    240 
    241             {
    242 
    243                 startH = (constrainSize.height - dim.height) / 2;
    244 
    245             }
    246 
    247             else
    248 
    249             {
    250 
    251                 startH = constrainSize.height - dim.height;
    252 
    253             }
    254 
    255         }
    256 
    257         // adjust text rect
    258 
    259         if (constrainSize.width > 0 && constrainSize.width > dim.width)
    260 
    261         {
    262 
    263             dim.width = constrainSize.width;
    264 
    265         }
    266 
    267         if (constrainSize.height > 0 && constrainSize.height > dim.height)
    268 
    269         {
    270 
    271             dim.height = constrainSize.height;
    272 
    273         }
    274 
    275         
    276 
    277         CGSize size;
    278 
    279         size.width = dim.width * scaleFactor;
    280 
    281         size.height = dim.height * scaleFactor;
    282 
    283         
    284 
    285         UIGraphicsBeginImageContextWithOptions(size,false,scaleFactor);
    286 
    287         
    288 
    289         CGContextRef context = UIGraphicsGetCurrentContext();
    290 
    291         CC_BREAK_IF(!context);
    292 
    293  
    294 
    295         //    CGContextSetLineWidth(context, 2);
    296 
    297         ccColor4F fillColor4f = ccc4FFromccc3B(fillColor);
    298 
    299    //设置文本颜色
    300 
    301         CGContextSetRGBFillColor(context, fillColor4f.r, fillColor4f.g, fillColor4f.b, fillColor4f.a);
    302 
    303         // 这个地方 绘制文本阴影
    304 
    305         ccColor4F sColor4F =ccc4FFromccc4B(shadowColor);
    306 
    307         float sColor[4] = {sColor4F.r, sColor4F.g, sColor4F.b, sColor4F.a};
    308 
    309         CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    310 
    311         CGColorRef color = CGColorCreate(colorSpace,sColor);
    312 
             313 CGColorSpaceRelease(colorSpace); 314 315 if (isShadow) 316 317 { 318 319     //设置文字阴影 320 321 CGContextSetShadowWithColor(context, CGSizeMake(1.0, 1.0), 0.0, color); 322 323 } 324 325 // draw in context 326 327 CGContextScaleCTM(context, scaleFactor, scaleFactor);
    328     CGColorRelease(color);
    329    //绘制换行文本
    330 
    331         [str drawInRect:CGRectMake(0, startH, dim.width, dim.height) withFont:font lineBreakMode:(UILineBreakMode)UILineBreakModeWordWrapalignment:align];
    332 
    333         //    [str drawAtPoint:CGPointMake(0.0, 0.0) withFont:font]; // 画单行文本
    334 
    335         UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    336 
    337         UIGraphicsEndImageContext();
    338 
    339         this->initWithUIImage(image);        
    340 
    341     }
    342 
    343     while (0);
    344 
    345 }

    剩下的就是把CCImage转成CCtexture2D,然后交给CCSprite显示

     

  • 相关阅读:
    454 Authentication failed, please open smtp flag first!
    zabbix 调用的发邮件脚本
    Apache Shiro 标签方式授权
    Realm [realm.ShiroDbRealm@15408475] does not support authentication token
    简单的zabbix agent自动安装脚本
    创建IPC端口失败:拒绝访问
    如何对报表的参数控件赋值
    如何对报表的参数控件赋值
    Socket 通信原理(Android客户端和服务器以TCP&&UDP方式互通)
    mysql 执行计划走分区
  • 原文地址:https://www.cnblogs.com/howeho/p/3010106.html
Copyright © 2020-2023  润新知