cocos2d-x 文本 优化

  不得不说,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显示

 

 

你可能感兴趣的:(cocos2d-x)