CCLabelTTF.js 41 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101
  1. /****************************************************************************
  2. Copyright (c) 2010-2012 cocos2d-x.org
  3. Copyright (c) 2008-2010 Ricardo Quesada
  4. Copyright (c) 2011 Zynga Inc.
  5. http://www.cocos2d-x.org
  6. Permission is hereby granted, free of charge, to any person obtaining a copy
  7. of this software and associated documentation files (the "Software"), to deal
  8. in the Software without restriction, including without limitation the rights
  9. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10. copies of the Software, and to permit persons to whom the Software is
  11. furnished to do so, subject to the following conditions:
  12. The above copyright notice and this permission notice shall be included in
  13. all copies or substantial portions of the Software.
  14. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  20. THE SOFTWARE.
  21. ****************************************************************************/
  22. /**
  23. * cc.LabelTTF is a subclass of cc.TextureNode that knows how to render text labels<br/>
  24. * All features from cc.TextureNode are valid in cc.LabelTTF<br/>
  25. * cc.LabelTTF objects are slow for js-binding on mobile devices.Consider using cc.LabelAtlas or cc.LabelBMFont instead. <br/>
  26. * Consider using cc.LabelAtlas or cc.LabelBMFont instead.<br/>
  27. * @class
  28. * @extends cc.Sprite
  29. */
  30. cc.LabelTTF = cc.Sprite.extend(/** @lends cc.LabelTTF# */{
  31. _dimensions:null,
  32. _hAlignment:cc.TEXT_ALIGNMENT_CENTER,
  33. _vAlignment:cc.VERTICAL_TEXT_ALIGNMENT_TOP,
  34. _fontName: null,
  35. _fontSize:0.0,
  36. _string:"",
  37. _originalText: null,
  38. _isMultiLine:false,
  39. _fontStyleStr:null,
  40. // font shadow
  41. _shadowEnabled:false,
  42. _shadowOffset:null,
  43. _shadowOpacity:0,
  44. _shadowBlur:0,
  45. _shadowColorStr:null,
  46. // font stroke
  47. _strokeEnabled:false,
  48. _strokeColor:null,
  49. _strokeSize:0,
  50. _strokeColorStr:null,
  51. // font tint
  52. _textFillColor:null,
  53. _fillColorStr:null,
  54. _strokeShadowOffsetX:0,
  55. _strokeShadowOffsetY:0,
  56. _needUpdateTexture:false,
  57. _labelCanvas:null,
  58. _labelContext:null,
  59. _lineWidths:null,
  60. /**
  61. * Constructor
  62. */
  63. ctor:function () {
  64. cc.Sprite.prototype.ctor.call(this);
  65. this._dimensions = cc.SizeZero();
  66. this._hAlignment = cc.TEXT_ALIGNMENT_LEFT;
  67. this._vAlignment = cc.VERTICAL_TEXT_ALIGNMENT_TOP;
  68. this._opacityModifyRGB = false;
  69. this._fontStyleStr = "";
  70. this._fontName = "Arial";
  71. this._isMultiLine = false;
  72. this._shadowEnabled = false;
  73. this._shadowOffset = cc.SizeZero();
  74. this._shadowOpacity = 0;
  75. this._shadowBlur = 0;
  76. this._shadowColorStr = "rgba(128, 128, 128, 0.5)";
  77. this._strokeEnabled = false;
  78. this._strokeColor = cc.white();
  79. this._strokeSize = 0;
  80. this._strokeColorStr = "";
  81. this._textFillColor = cc.white();
  82. this._fillColorStr = "rgba(255,255,255,1)";
  83. this._strokeShadowOffsetX = 0;
  84. this._strokeShadowOffsetY = 0;
  85. this._needUpdateTexture = false;
  86. this._lineWidths = [];
  87. this._setColorsString();
  88. },
  89. init:function () {
  90. return this.initWithString(" ", this._fontName, this._fontSize);
  91. },
  92. _measureConfig: function() {
  93. this._getLabelContext().font = this._fontStyleStr;
  94. },
  95. _measure: function(text) {
  96. return this._getLabelContext().measureText(text).width;
  97. },
  98. _checkNextline: function( text, width){
  99. var tWidth = this._measure(text);
  100. // Estimated word number per line
  101. var baseNb = Math.floor( text.length * width / tWidth );
  102. // Next line is a line with line break
  103. var nextlinebreak = text.indexOf('\n');
  104. if(baseNb*0.8 >= nextlinebreak && nextlinebreak > 0) return nextlinebreak+1;
  105. // Text width smaller than requested width
  106. if(tWidth < width) return text.length;
  107. var found = false, l = width + 1, idfound = -1, index = baseNb, result,
  108. re = cc.LabelTTF._checkRegEx,
  109. reversre = cc.LabelTTF._reverseCheckRegEx,
  110. enre = cc.LabelTTF._checkEnRegEx,
  111. substr = text.substr(baseNb);
  112. // Forward check
  113. // Find next special caracter or chinese caracters
  114. while (result = re.exec(substr)) {
  115. index += result[0].length;
  116. var tem = text.substr(0, index);
  117. l = this._measure(tem);
  118. if(result[2] == '\n' && l < width) {
  119. found = true;
  120. idfound = index;
  121. break;
  122. }
  123. if(l > width) {
  124. if(idfound != -1)
  125. found = true;
  126. break;
  127. }
  128. idfound = index;
  129. substr = text.substr(index);
  130. }
  131. if(found) return idfound;
  132. // Backward check when forward check failed
  133. substr = text.substr(0, baseNb);
  134. idfound = baseNb;
  135. while (result = reversre.exec(substr)) {
  136. // BUG: Not secured if check with result[0]
  137. idfound = result[1].length;
  138. substr = result[1];
  139. l = this._measure(substr);
  140. if(l < width) {
  141. if(enre.test(result[2]))
  142. idfound++;
  143. break;
  144. }
  145. }
  146. // Avoid when idfound == 0, the process may enter in a infinite loop
  147. return idfound || 1;
  148. },
  149. /**
  150. * Prints out a description of this class
  151. * @return {String}
  152. */
  153. description:function () {
  154. return "<cc.LabelTTF | FontName =" + this._fontName + " FontSize = " + this._fontSize.toFixed(1) + ">";
  155. },
  156. setColor: null,
  157. _setColorForCanvas: function (color3) {
  158. cc.NodeRGBA.prototype.setColor.call(this, color3);
  159. this._setColorsStringForCanvas();
  160. },
  161. _setColorsString: null,
  162. _setColorsStringForCanvas: function () {
  163. this._needUpdateTexture = true;
  164. var locDisplayColor = this._displayedColor, locDisplayedOpacity = this._displayedOpacity;
  165. var locStrokeColor = this._strokeColor, locFontFillColor = this._textFillColor;
  166. this._shadowColorStr = "rgba(" + (0 | (locDisplayColor.r * 0.5)) + "," + (0 | (locDisplayColor.g * 0.5)) + "," + (0 | (locDisplayColor.b * 0.5)) + "," + this._shadowOpacity + ")";
  167. this._fillColorStr = "rgba(" + (0 | (locDisplayColor.r /255 * locFontFillColor.r)) + "," + (0 | (locDisplayColor.g / 255 * locFontFillColor.g)) + ","
  168. + (0 | (locDisplayColor.b / 255 * locFontFillColor.b)) + ", " + locDisplayedOpacity / 255 + ")";
  169. this._strokeColorStr = "rgba(" + (0 | (locDisplayColor.r / 255 * locStrokeColor.r)) + "," + (0 | (locDisplayColor.g / 255 * locStrokeColor.g)) + ","
  170. + (0 | (locDisplayColor.b / 255 * locStrokeColor.b)) + ", " + locDisplayedOpacity / 255 + ")";
  171. },
  172. _setColorsStringForWebGL:function(){
  173. this._needUpdateTexture = true;
  174. var locStrokeColor = this._strokeColor, locFontFillColor = this._textFillColor;
  175. this._shadowColorStr = "rgba(128,128,128," + this._shadowOpacity + ")";
  176. this._fillColorStr = "rgba(" + (0 | locFontFillColor.r) + "," + (0 | locFontFillColor.g) + "," + (0 | locFontFillColor.b) + ", 1)";
  177. this._strokeColorStr = "rgba(" + (0 | locStrokeColor.r) + "," + (0 | locStrokeColor.g) + "," + (0 | locStrokeColor.b) + ", 1)";
  178. },
  179. updateDisplayedColor:null,
  180. _updateDisplayedColorForCanvas:function(parentColor){
  181. cc.NodeRGBA.prototype.updateDisplayedColor.call(this,parentColor);
  182. this._setColorsString();
  183. },
  184. setOpacity: null,
  185. _setOpacityForCanvas: function (opacity) {
  186. if (this._opacity === opacity)
  187. return;
  188. cc.Sprite.prototype.setOpacity.call(this, opacity);
  189. this._setColorsString();
  190. this._needUpdateTexture = true;
  191. },
  192. updateDisplayedOpacity: null,
  193. updateDisplayedOpacityForCanvas: function(parentOpacity){
  194. cc.NodeRGBA.prototype.updateDisplayedOpacity.call(this, parentOpacity);
  195. this._setColorsString();
  196. },
  197. /**
  198. * returns the text of the label
  199. * @return {String}
  200. */
  201. getString:function () {
  202. return this._string;
  203. },
  204. /**
  205. * return Horizontal Alignment of cc.LabelTTF
  206. * @return {cc.TEXT_ALIGNMENT_LEFT|cc.TEXT_ALIGNMENT_CENTER|cc.TEXT_ALIGNMENT_RIGHT}
  207. */
  208. getHorizontalAlignment:function () {
  209. return this._hAlignment;
  210. },
  211. /**
  212. * return Vertical Alignment of cc.LabelTTF
  213. * @return {cc.VERTICAL_TEXT_ALIGNMENT_TOP|cc.VERTICAL_TEXT_ALIGNMENT_CENTER|cc.VERTICAL_TEXT_ALIGNMENT_BOTTOM}
  214. */
  215. getVerticalAlignment:function () {
  216. return this._vAlignment;
  217. },
  218. /**
  219. * return Dimensions of cc.LabelTTF
  220. * @return {cc.Size}
  221. */
  222. getDimensions:function () {
  223. return cc.size(this._dimensions.width, this._dimensions.height);
  224. },
  225. /**
  226. * return font size of cc.LabelTTF
  227. * @return {Number}
  228. */
  229. getFontSize:function () {
  230. return this._fontSize;
  231. },
  232. /**
  233. * return font name of cc.LabelTTF
  234. * @return {String}
  235. */
  236. getFontName:function () {
  237. return this._fontName;
  238. },
  239. /**
  240. * initializes the cc.LabelTTF with a font name, alignment, dimension and font size
  241. * @param {String} label string
  242. * @param {String} fontName
  243. * @param {Number} fontSize
  244. * @param {cc.Size} [dimensions=]
  245. * @param {Number} [hAlignment=]
  246. * @param {Number} [vAlignment=]
  247. * @return {Boolean} return false on error
  248. */
  249. initWithString:function (label, fontName, fontSize, dimensions, hAlignment, vAlignment) {
  250. var strInfo;
  251. if(label)
  252. strInfo = label + "";
  253. else
  254. strInfo = "";
  255. fontSize = fontSize || 16;
  256. dimensions = dimensions || cc.size(0, fontSize);
  257. hAlignment = hAlignment || cc.TEXT_ALIGNMENT_LEFT;
  258. vAlignment = vAlignment || cc.VERTICAL_TEXT_ALIGNMENT_TOP;
  259. if (cc.Sprite.prototype.init.call(this)) {
  260. this._opacityModifyRGB = false;
  261. this._dimensions = cc.size(dimensions.width, dimensions.height);
  262. this._fontName = fontName || "Arial";
  263. this._hAlignment = hAlignment;
  264. this._vAlignment = vAlignment;
  265. //this._fontSize = (cc.renderContextType === cc.CANVAS) ? fontSize : fontSize * cc.CONTENT_SCALE_FACTOR();
  266. this._fontSize = fontSize;
  267. this._fontStyleStr = this._fontSize + "px '" + fontName + "'";
  268. this._fontClientHeight = cc.LabelTTF.__getFontHeightByDiv(fontName,this._fontSize);
  269. this.setString(strInfo);
  270. this._setColorsString();
  271. this._updateTexture();
  272. this._needUpdateTexture = false;
  273. return true;
  274. }
  275. return false;
  276. },
  277. /**
  278. * initializes the CCLabelTTF with a font name, alignment, dimension and font size
  279. * @param {String} text
  280. * @param {cc.FontDefinition} textDefinition
  281. * @return {Boolean}
  282. */
  283. initWithStringAndTextDefinition:null,
  284. _initWithStringAndTextDefinitionForCanvas:function(text, textDefinition){
  285. if(!cc.Sprite.prototype.init.call(this))
  286. return false;
  287. // prepare everything needed to render the label
  288. this._updateWithTextDefinition(textDefinition, false);
  289. // set the string
  290. this.setString(text);
  291. return true;
  292. },
  293. _initWithStringAndTextDefinitionForWebGL:function(text, textDefinition){
  294. if(!cc.Sprite.prototype.init.call(this))
  295. return false;
  296. // shader program
  297. this.setShaderProgram(cc.ShaderCache.getInstance().programForKey(cc.LabelTTF._SHADER_PROGRAM));
  298. // prepare everything needed to render the label
  299. this._updateWithTextDefinition(textDefinition, false);
  300. // set the string
  301. this.setString(text);
  302. return true;
  303. },
  304. /**
  305. * set the text definition used by this label
  306. * @param {cc.FontDefinition} theDefinition
  307. */
  308. setTextDefinition:function(theDefinition){
  309. if (theDefinition)
  310. this._updateWithTextDefinition(theDefinition, true);
  311. },
  312. /**
  313. * get the text definition used by this label
  314. * @return {cc.FontDefinition}
  315. */
  316. getTextDefinition:function(){
  317. return this._prepareTextDefinition(false);
  318. },
  319. /**
  320. * enable or disable shadow for the label
  321. * @param {cc.Size} shadowOffset
  322. * @param {Number} shadowOpacity (0 to 1)
  323. * @param {Number} shadowBlur
  324. * @param {Boolean} [mustUpdateTexture=false] This parameter is not used. It's kept for cocos2d-x JSB compatibility
  325. */
  326. enableShadow:function(shadowOffset, shadowOpacity, shadowBlur, mustUpdateTexture){
  327. shadowOpacity = shadowOpacity || 0.5;
  328. if (false === this._shadowEnabled)
  329. this._shadowEnabled = true;
  330. var locShadowOffset = this._shadowOffset;
  331. if (locShadowOffset && (locShadowOffset.width != shadowOffset.width) || (locShadowOffset.height != shadowOffset.height)) {
  332. locShadowOffset.width = shadowOffset.width;
  333. locShadowOffset.height = shadowOffset.height;
  334. }
  335. if (this._shadowOpacity != shadowOpacity ){
  336. this._shadowOpacity = shadowOpacity;
  337. }
  338. this._setColorsString();
  339. if (this._shadowBlur != shadowBlur)
  340. this._shadowBlur = shadowBlur;
  341. this._needUpdateTexture = true;
  342. },
  343. /**
  344. * disable shadow rendering
  345. * @param {Boolean} [mustUpdateTexture=false] This parameter is not used. It's kept for cocos2d-x JSB compatibility
  346. */
  347. disableShadow:function(mustUpdateTexture){
  348. if (this._shadowEnabled) {
  349. this._shadowEnabled = false;
  350. this._needUpdateTexture = true;
  351. }
  352. },
  353. /**
  354. * enable or disable stroke
  355. * @param {cc.Color3B} strokeColor
  356. * @param {Number} strokeSize
  357. * @param {Boolean} [mustUpdateTexture=false] This parameter is not used. It's kept for cocos2d-x JSB compatibility
  358. */
  359. enableStroke:function(strokeColor, strokeSize, mustUpdateTexture){
  360. if(this._strokeEnabled === false)
  361. this._strokeEnabled = true;
  362. var locStrokeColor = this._strokeColor;
  363. if ( (locStrokeColor.r !== strokeColor.r) || (locStrokeColor.g !== strokeColor.g) || (locStrokeColor.b !== strokeColor.b) ) {
  364. locStrokeColor.r = strokeColor.r;
  365. locStrokeColor.g = strokeColor.g;
  366. locStrokeColor.b = strokeColor.b;
  367. this._setColorsString();
  368. }
  369. if (this._strokeSize!== strokeSize)
  370. this._strokeSize = strokeSize || 0;
  371. this._needUpdateTexture = true;
  372. },
  373. /**
  374. * disable stroke
  375. * @param {Boolean} [mustUpdateTexture=false] This parameter is not used. It's kept for cocos2d-x JSB compatibility
  376. */
  377. disableStroke:function(mustUpdateTexture){
  378. if (this._strokeEnabled){
  379. this._strokeEnabled = false;
  380. this._needUpdateTexture = true;
  381. }
  382. },
  383. /**
  384. * set text tinting
  385. * @param {cc.Color3B} tintColor
  386. * @param {Boolean} [mustUpdateTexture=false] This parameter is not used. It's kept for cocos2d-x JSB compatibility
  387. */
  388. setFontFillColor:null,
  389. _setFontFillColorForCanvas: function (tintColor, mustUpdateTexture) {
  390. //mustUpdateTexture = (mustUpdateTexture == null) ? true : mustUpdateTexture;
  391. var locTextFillColor = this._textFillColor;
  392. if (locTextFillColor.r != tintColor.r || locTextFillColor.g != tintColor.g || locTextFillColor.b != tintColor.b) {
  393. locTextFillColor.r = tintColor.r;
  394. locTextFillColor.g = tintColor.g;
  395. locTextFillColor.b = tintColor.b;
  396. this._setColorsString();
  397. this._needUpdateTexture = true;
  398. }
  399. },
  400. _setFontFillColorForWebGL: function (tintColor, mustUpdateTexture) {
  401. var locTextFillColor = this._textFillColor;
  402. if (locTextFillColor.r != tintColor.r || locTextFillColor.g != tintColor.g || locTextFillColor.b != tintColor.b) {
  403. locTextFillColor.r = tintColor.r;
  404. locTextFillColor.g = tintColor.g;
  405. locTextFillColor.b = tintColor.b;
  406. this._setColorsString();
  407. this._needUpdateTexture = true;
  408. }
  409. },
  410. //set the text definition for this label
  411. _updateWithTextDefinition:function(textDefinition, mustUpdateTexture){
  412. if(textDefinition.fontDimensions){
  413. this._dimensions.width = textDefinition.fontDimensions.width;
  414. this._dimensions.height = textDefinition.fontDimensions.height;
  415. } else {
  416. this._dimensions.width = 0;
  417. this._dimensions.height = 0;
  418. }
  419. this._hAlignment = textDefinition.fontAlignmentH;
  420. this._vAlignment = textDefinition.fontAlignmentV;
  421. this._fontName = textDefinition.fontName;
  422. this._fontSize = textDefinition.fontSize||12;
  423. this._fontStyleStr = this._fontSize + "px '" + this._fontName + "'";
  424. this._fontClientHeight = cc.LabelTTF.__getFontHeightByDiv(this._fontName,this._fontSize);
  425. // shadow
  426. if ( textDefinition.shadowEnabled)
  427. this.enableShadow(textDefinition.shadowOffset, textDefinition.shadowOpacity, textDefinition.shadowBlur, false);
  428. // stroke
  429. if ( textDefinition.strokeEnabled )
  430. this.enableStroke(textDefinition.strokeColor, textDefinition.strokeSize, false);
  431. // fill color
  432. this.setFontFillColor(textDefinition.fontFillColor, false);
  433. if (mustUpdateTexture)
  434. this._updateTexture();
  435. },
  436. _prepareTextDefinition:function(adjustForResolution){
  437. var texDef = new cc.FontDefinition();
  438. if (adjustForResolution){
  439. //texDef.fontSize = (cc.renderContextType === cc.CANVAS) ? this._fontSize : this._fontSize * cc.CONTENT_SCALE_FACTOR();
  440. texDef.fontSize = this._fontSize;
  441. texDef.fontDimensions = cc.SIZE_POINTS_TO_PIXELS(this._dimensions);
  442. } else {
  443. texDef.fontSize = this._fontSize;
  444. texDef.fontDimensions = cc.size(this._dimensions.width, this._dimensions.height);
  445. }
  446. texDef.fontName = this._fontName;
  447. texDef.fontAlignmentH = this._hAlignment;
  448. texDef.fontAlignmentV = this._vAlignment;
  449. // stroke
  450. if ( this._strokeEnabled ){
  451. texDef.strokeEnabled = true;
  452. var locStrokeColor = this._strokeColor;
  453. texDef.strokeColor = new cc.Color3B(locStrokeColor.r, locStrokeColor.g, locStrokeColor.b);
  454. texDef.strokeSize = this._strokeSize;
  455. }else
  456. texDef.strokeEnabled = false;
  457. // shadow
  458. if ( this._shadowEnabled ){
  459. texDef.shadowEnabled = true;
  460. texDef.shadowBlur = this._shadowBlur;
  461. texDef.shadowOpacity = this._shadowOpacity;
  462. texDef.shadowOffset = adjustForResolution ? cc.SIZE_POINTS_TO_PIXELS(this._shadowOffset)
  463. : cc.size(this._shadowOffset.width,this._shadowOffset.height);
  464. }else
  465. texDef._shadowEnabled = false;
  466. // text tint
  467. var locTextFillColor = this._textFillColor;
  468. texDef.fontFillColor = new cc.Color3B(locTextFillColor.r, locTextFillColor.g, locTextFillColor.b);
  469. return texDef;
  470. },
  471. _fontClientHeight:18,
  472. /**
  473. * changes the string to render
  474. * @warning Changing the string is as expensive as creating a new cc.LabelTTF. To obtain better performance use cc.LabelAtlas
  475. * @param {String} text text for the label
  476. */
  477. setString:function (text) {
  478. text = String(text);
  479. if (this._originalText != text) {
  480. this._originalText = text + "";
  481. this._updateString();
  482. // Force update
  483. this._needUpdateTexture = true;
  484. }
  485. },
  486. _updateString: function() {
  487. this._string = this._originalText;
  488. },
  489. /**
  490. * set Horizontal Alignment of cc.LabelTTF
  491. * @param {cc.TEXT_ALIGNMENT_LEFT|cc.TEXT_ALIGNMENT_CENTER|cc.TEXT_ALIGNMENT_RIGHT} alignment Horizontal Alignment
  492. */
  493. setHorizontalAlignment:function (alignment) {
  494. if (alignment !== this._hAlignment) {
  495. this._hAlignment = alignment;
  496. // Force update
  497. this._needUpdateTexture = true;
  498. }
  499. },
  500. /**
  501. * set Vertical Alignment of cc.LabelTTF
  502. * @param {cc.VERTICAL_TEXT_ALIGNMENT_TOP|cc.VERTICAL_TEXT_ALIGNMENT_CENTER|cc.VERTICAL_TEXT_ALIGNMENT_BOTTOM} verticalAlignment
  503. */
  504. setVerticalAlignment:function (verticalAlignment) {
  505. if (verticalAlignment != this._vAlignment) {
  506. this._vAlignment = verticalAlignment;
  507. // Force update
  508. this._needUpdateTexture = true;
  509. }
  510. },
  511. /**
  512. * set Dimensions of cc.LabelTTF
  513. * @param {cc.Size} dim
  514. */
  515. setDimensions:function (dim) {
  516. if (dim.width != this._dimensions.width || dim.height != this._dimensions.height) {
  517. this._dimensions = dim;
  518. this._updateString();
  519. // Force udpate
  520. this._needUpdateTexture = true;
  521. }
  522. },
  523. /**
  524. * set font size of cc.LabelTTF
  525. * @param {Number} fontSize
  526. */
  527. setFontSize:function (fontSize) {
  528. if (this._fontSize !== fontSize) {
  529. this._fontSize = fontSize;
  530. this._fontStyleStr = fontSize + "px '" + this._fontName + "'";
  531. this._fontClientHeight = cc.LabelTTF.__getFontHeightByDiv(this._fontName,fontSize);
  532. // Force update
  533. this._needUpdateTexture = true;
  534. }
  535. },
  536. /**
  537. * set font name of cc.LabelTTF
  538. * @param {String} fontName
  539. */
  540. setFontName:function (fontName) {
  541. if (this._fontName && this._fontName != fontName ) {
  542. this._fontName = fontName;
  543. this._fontStyleStr = this._fontSize + "px '" + fontName + "'";
  544. this._fontClientHeight = cc.LabelTTF.__getFontHeightByDiv(fontName,this._fontSize);
  545. // Force update
  546. this._needUpdateTexture = true;
  547. }
  548. },
  549. _drawTTFInCanvas: function (context) {
  550. if (!context)
  551. return;
  552. var locStrokeShadowOffsetX = this._strokeShadowOffsetX, locStrokeShadowOffsetY = this._strokeShadowOffsetY;
  553. var locContentSizeHeight = this._contentSize.height - locStrokeShadowOffsetY, locVAlignment = this._vAlignment, locHAlignment = this._hAlignment,
  554. locFontHeight = this._fontClientHeight, locStrokeSize = this._strokeSize;
  555. context.setTransform(1, 0, 0, 1, 0 + locStrokeShadowOffsetX * 0.5 , locContentSizeHeight + locStrokeShadowOffsetY * 0.5);
  556. //this is fillText for canvas
  557. if (context.font != this._fontStyleStr)
  558. context.font = this._fontStyleStr;
  559. context.fillStyle = this._fillColorStr;
  560. var xOffset = 0, yOffset = 0;
  561. //stroke style setup
  562. var locStrokeEnabled = this._strokeEnabled;
  563. if (locStrokeEnabled) {
  564. context.lineWidth = locStrokeSize * 2;
  565. context.strokeStyle = this._strokeColorStr;
  566. }
  567. //shadow style setup
  568. if (this._shadowEnabled) {
  569. var locShadowOffset = this._shadowOffset;
  570. context.shadowColor = this._shadowColorStr;
  571. context.shadowOffsetX = locShadowOffset.width;
  572. context.shadowOffsetY = -locShadowOffset.height;
  573. context.shadowBlur = this._shadowBlur;
  574. }
  575. context.textBaseline = cc.LabelTTF._textBaseline[locVAlignment];
  576. context.textAlign = cc.LabelTTF._textAlign[locHAlignment];
  577. var locContentWidth = this._contentSize.width - locStrokeShadowOffsetX;
  578. if (locHAlignment === cc.TEXT_ALIGNMENT_RIGHT)
  579. xOffset += locContentWidth;
  580. else if (locHAlignment === cc.TEXT_ALIGNMENT_CENTER)
  581. xOffset += locContentWidth / 2;
  582. else
  583. xOffset += 0;
  584. if (this._isMultiLine) {
  585. var locStrLen = this._strings.length;
  586. if (locVAlignment === cc.VERTICAL_TEXT_ALIGNMENT_BOTTOM)
  587. yOffset = locFontHeight + locContentSizeHeight - locFontHeight * locStrLen;
  588. else if (locVAlignment === cc.VERTICAL_TEXT_ALIGNMENT_CENTER)
  589. yOffset = locFontHeight / 2 + (locContentSizeHeight - locFontHeight * locStrLen) / 2;
  590. for (var i = 0; i < locStrLen; i++) {
  591. var line = this._strings[i];
  592. var tmpOffsetY = -locContentSizeHeight + (locFontHeight * i) + yOffset;
  593. if (locStrokeEnabled)
  594. context.strokeText(line, xOffset, tmpOffsetY);
  595. context.fillText(line, xOffset, tmpOffsetY);
  596. }
  597. } else {
  598. if (locVAlignment === cc.VERTICAL_TEXT_ALIGNMENT_BOTTOM) {
  599. if (locStrokeEnabled)
  600. context.strokeText(this._string, xOffset, yOffset);
  601. context.fillText(this._string, xOffset, yOffset);
  602. } else if (locVAlignment === cc.VERTICAL_TEXT_ALIGNMENT_TOP) {
  603. yOffset -= locContentSizeHeight ;
  604. if (locStrokeEnabled)
  605. context.strokeText(this._string, xOffset, yOffset);
  606. context.fillText(this._string, xOffset, yOffset);
  607. } else {
  608. yOffset -= locContentSizeHeight * 0.5;
  609. if (locStrokeEnabled)
  610. context.strokeText(this._string, xOffset, yOffset);
  611. context.fillText(this._string, xOffset, yOffset);
  612. }
  613. }
  614. },
  615. _getLabelContext:function () {
  616. if (this._labelContext)
  617. return this._labelContext;
  618. if (!this._labelCanvas) {
  619. var locCanvas = document.createElement("canvas");
  620. var labelTexture = new cc.Texture2D();
  621. labelTexture.initWithElement(locCanvas);
  622. this.setTexture(labelTexture);
  623. this._labelCanvas = locCanvas;
  624. }
  625. this._labelContext = this._labelCanvas.getContext("2d");
  626. return this._labelContext;
  627. },
  628. _updateTTF: function () {
  629. var locDimensionsWidth = this._dimensions.width, i, strLength;
  630. var locLineWidth = this._lineWidths;
  631. locLineWidth.length = 0;
  632. this._isMultiLine = false ;
  633. this._measureConfig();
  634. if (locDimensionsWidth !== 0) {
  635. // Content processing
  636. var text = this._string;
  637. this._strings = [];
  638. for (i = 0, strLength = this._string.length; i < strLength;) {
  639. // Find the index of next line
  640. var next = this._checkNextline(text.substr(i), locDimensionsWidth);
  641. var append = text.substr(i, next);
  642. this._strings.push(append);
  643. i += next;
  644. }
  645. } else {
  646. this._strings = this._string.split('\n');
  647. for (i = 0, strLength = this._strings.length; i < strLength; i++) {
  648. locLineWidth.push(this._measure(this._strings[i]));
  649. }
  650. }
  651. if (this._strings.length > 0)
  652. this._isMultiLine = true;
  653. var locSize, locStrokeShadowOffsetX = 0, locStrokeShadowOffsetY = 0;
  654. if (this._strokeEnabled)
  655. locStrokeShadowOffsetX = locStrokeShadowOffsetY = this._strokeSize * 2;
  656. if (this._shadowEnabled) {
  657. var locOffsetSize = this._shadowOffset;
  658. locStrokeShadowOffsetX += Math.abs(locOffsetSize.width) * 2;
  659. locStrokeShadowOffsetY += Math.abs(locOffsetSize.height) * 2;
  660. }
  661. //get offset for stroke and shadow
  662. if (locDimensionsWidth === 0) {
  663. if (this._isMultiLine)
  664. locSize = cc.size(0 | (Math.max.apply(Math, locLineWidth) + locStrokeShadowOffsetX),
  665. 0 | ((this._fontClientHeight * this._strings.length) + locStrokeShadowOffsetY));
  666. else
  667. locSize = cc.size(0 | (this._measure(this._string) + locStrokeShadowOffsetX), 0 | (this._fontClientHeight + locStrokeShadowOffsetY));
  668. } else {
  669. if (this._dimensions.height === 0) {
  670. if (this._isMultiLine)
  671. locSize = cc.size(0 | (locDimensionsWidth + locStrokeShadowOffsetX), 0 | ((this._fontClientHeight * this._strings.length) + locStrokeShadowOffsetY));
  672. else
  673. locSize = cc.size(0 | (locDimensionsWidth + locStrokeShadowOffsetX), 0 | (this._fontClientHeight + locStrokeShadowOffsetY));
  674. } else {
  675. //dimension is already set, contentSize must be same as dimension
  676. locSize = cc.size(0 | (locDimensionsWidth + locStrokeShadowOffsetX), 0 | (this._dimensions.height + locStrokeShadowOffsetY));
  677. }
  678. }
  679. this.setContentSize(locSize);
  680. this._strokeShadowOffsetX = locStrokeShadowOffsetX;
  681. this._strokeShadowOffsetY = locStrokeShadowOffsetY;
  682. // need computing _anchorPointInPoints
  683. var locAP = this._anchorPoint;
  684. this._anchorPointInPoints.x = (locStrokeShadowOffsetX * 0.5) + ((locSize.width - locStrokeShadowOffsetX) * locAP.x);
  685. this._anchorPointInPoints.y = (locStrokeShadowOffsetY * 0.5) + ((locSize.height - locStrokeShadowOffsetY) * locAP.y);
  686. },
  687. getContentSize:function(){
  688. if(this._needUpdateTexture)
  689. this._updateTTF();
  690. return cc.Sprite.prototype.getContentSize.call(this);
  691. },
  692. _updateTexture:function () {
  693. var locContext = this._getLabelContext(), locLabelCanvas = this._labelCanvas;
  694. var locContentSize = this._contentSize;
  695. if(this._string.length === 0){
  696. locLabelCanvas.width = 1;
  697. locLabelCanvas.height = locContentSize.height;
  698. this.setTextureRect(cc.rect(0, 0, 1, locContentSize.height));
  699. return true;
  700. }
  701. //set size for labelCanvas
  702. locContext.font = this._fontStyleStr;
  703. this._updateTTF();
  704. var width = locContentSize.width, height = locContentSize.height;
  705. var flag = locLabelCanvas.width == width && locLabelCanvas.height == height;
  706. locLabelCanvas.width = width;
  707. locLabelCanvas.height = height;
  708. if(flag) locContext.clearRect(0, 0, width, height);
  709. //draw text to labelCanvas
  710. this._drawTTFInCanvas(locContext);
  711. this._texture.handleLoadedTexture();
  712. this.setTextureRect(cc.rect(0, 0, width, height));
  713. return true;
  714. },
  715. visit:function(ctx){
  716. if(!this._string || this._string == "")
  717. return;
  718. if(this._needUpdateTexture ){
  719. this._needUpdateTexture = false;
  720. this._updateTexture();
  721. }
  722. var context = ctx || cc.renderContext;
  723. cc.Sprite.prototype.visit.call(this,context);
  724. },
  725. draw: null,
  726. /**
  727. * draw sprite to canvas
  728. * @param {WebGLRenderingContext} ctx 3d context of canvas
  729. */
  730. _drawForWebGL: function (ctx) {
  731. if (!this._string || this._string == "")
  732. return;
  733. var gl = ctx || cc.renderContext, locTexture = this._texture;
  734. if (locTexture && locTexture._isLoaded) {
  735. this._shaderProgram.use();
  736. this._shaderProgram.setUniformForModelViewAndProjectionMatrixWithMat4();
  737. cc.glBlendFunc(this._blendFunc.src, this._blendFunc.dst);
  738. cc.glBindTexture2D(locTexture);
  739. cc.glEnableVertexAttribs(cc.VERTEX_ATTRIB_FLAG_POS_COLOR_TEX);
  740. gl.bindBuffer(gl.ARRAY_BUFFER, this._quadWebBuffer);
  741. if (this._quadDirty) {
  742. gl.bufferData(gl.ARRAY_BUFFER, this._quad.arrayBuffer, gl.STATIC_DRAW);
  743. this._quadDirty = false;
  744. }
  745. gl.vertexAttribPointer(cc.VERTEX_ATTRIB_POSITION, 3, gl.FLOAT, false, 24, 0);
  746. gl.vertexAttribPointer(cc.VERTEX_ATTRIB_TEX_COORDS, 2, gl.FLOAT, false, 24, 16);
  747. gl.vertexAttribPointer(cc.VERTEX_ATTRIB_COLOR, 4, gl.UNSIGNED_BYTE, true, 24, 12);
  748. gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
  749. }
  750. if (cc.SPRITE_DEBUG_DRAW === 1) {
  751. // draw bounding box
  752. var locQuad = this._quad;
  753. var verticesG1 = [
  754. cc.p(locQuad.tl.vertices.x, locQuad.tl.vertices.y),
  755. cc.p(locQuad.bl.vertices.x, locQuad.bl.vertices.y),
  756. cc.p(locQuad.br.vertices.x, locQuad.br.vertices.y),
  757. cc.p(locQuad.tr.vertices.x, locQuad.tr.vertices.y)
  758. ];
  759. cc.drawingUtil.drawPoly(verticesG1, 4, true);
  760. } else if (cc.SPRITE_DEBUG_DRAW === 2) {
  761. // draw texture box
  762. var drawSizeG2 = this.getTextureRect()._size;
  763. var offsetPixG2 = this.getOffsetPosition();
  764. var verticesG2 = [cc.p(offsetPixG2.x, offsetPixG2.y), cc.p(offsetPixG2.x + drawSizeG2.width, offsetPixG2.y),
  765. cc.p(offsetPixG2.x + drawSizeG2.width, offsetPixG2.y + drawSizeG2.height), cc.p(offsetPixG2.x, offsetPixG2.y + drawSizeG2.height)];
  766. cc.drawingUtil.drawPoly(verticesG2, 4, true);
  767. } // CC_SPRITE_DEBUG_DRAW
  768. cc.g_NumberOfDraws++;
  769. },
  770. _setTextureRectForCanvas: function (rect, rotated, untrimmedSize) {
  771. this._rectRotated = rotated || false;
  772. untrimmedSize = untrimmedSize || rect._size;
  773. this.setContentSize(untrimmedSize);
  774. this.setVertexRect(rect);
  775. var locTextureCoordRect = this._textureRect_Canvas;
  776. locTextureCoordRect.x = rect.x;
  777. locTextureCoordRect.y = rect.y;
  778. locTextureCoordRect.width = rect.width;
  779. locTextureCoordRect.height = rect.height;
  780. locTextureCoordRect.validRect = !(locTextureCoordRect.width === 0 || locTextureCoordRect.height === 0
  781. || locTextureCoordRect.x < 0 || locTextureCoordRect.y < 0);
  782. var relativeOffset = this._unflippedOffsetPositionFromCenter;
  783. if (this._flippedX)
  784. relativeOffset.x = -relativeOffset.x;
  785. if (this._flippedY)
  786. relativeOffset.y = -relativeOffset.y;
  787. this._offsetPosition.x = relativeOffset.x + (this._contentSize.width - this._rect.width) / 2;
  788. this._offsetPosition.y = relativeOffset.y + (this._contentSize.height - this._rect.height) / 2;
  789. // rendering using batch node
  790. if (this._batchNode) {
  791. this._dirty = true;
  792. }
  793. },
  794. _setTextureCoords:function (rect) {
  795. var tex = this._batchNode ? this._textureAtlas.getTexture() : this._texture;
  796. if (!tex)
  797. return;
  798. var atlasWidth = tex.getPixelsWide();
  799. var atlasHeight = tex.getPixelsHigh();
  800. var left, right, top, bottom, tempSwap, locQuad = this._quad;
  801. if (this._rectRotated) {
  802. if (cc.FIX_ARTIFACTS_BY_STRECHING_TEXEL) {
  803. left = (2 * rect.x + 1) / (2 * atlasWidth);
  804. right = left + (rect.height * 2 - 2) / (2 * atlasWidth);
  805. top = (2 * rect.y + 1) / (2 * atlasHeight);
  806. bottom = top + (rect.width * 2 - 2) / (2 * atlasHeight);
  807. } else {
  808. left = rect.x / atlasWidth;
  809. right = (rect.x + rect.height) / atlasWidth;
  810. top = rect.y / atlasHeight;
  811. bottom = (rect.y + rect.width) / atlasHeight;
  812. }// CC_FIX_ARTIFACTS_BY_STRECHING_TEXEL
  813. if (this._flippedX) {
  814. tempSwap = top;
  815. top = bottom;
  816. bottom = tempSwap;
  817. }
  818. if (this._flippedY) {
  819. tempSwap = left;
  820. left = right;
  821. right = tempSwap;
  822. }
  823. locQuad.bl.texCoords.u = left;
  824. locQuad.bl.texCoords.v = top;
  825. locQuad.br.texCoords.u = left;
  826. locQuad.br.texCoords.v = bottom;
  827. locQuad.tl.texCoords.u = right;
  828. locQuad.tl.texCoords.v = top;
  829. locQuad.tr.texCoords.u = right;
  830. locQuad.tr.texCoords.v = bottom;
  831. } else {
  832. if (cc.FIX_ARTIFACTS_BY_STRECHING_TEXEL) {
  833. left = (2 * rect.x + 1) / (2 * atlasWidth);
  834. right = left + (rect.width * 2 - 2) / (2 * atlasWidth);
  835. top = (2 * rect.y + 1) / (2 * atlasHeight);
  836. bottom = top + (rect.height * 2 - 2) / (2 * atlasHeight);
  837. } else {
  838. left = rect.x / atlasWidth;
  839. right = (rect.x + rect.width) / atlasWidth;
  840. top = rect.y / atlasHeight;
  841. bottom = (rect.y + rect.height) / atlasHeight;
  842. } // ! CC_FIX_ARTIFACTS_BY_STRECHING_TEXEL
  843. if (this._flippedX) {
  844. tempSwap = left;
  845. left = right;
  846. right = tempSwap;
  847. }
  848. if (this._flippedY) {
  849. tempSwap = top;
  850. top = bottom;
  851. bottom = tempSwap;
  852. }
  853. locQuad.bl.texCoords.u = left;
  854. locQuad.bl.texCoords.v = bottom;
  855. locQuad.br.texCoords.u = right;
  856. locQuad.br.texCoords.v = bottom;
  857. locQuad.tl.texCoords.u = left;
  858. locQuad.tl.texCoords.v = top;
  859. locQuad.tr.texCoords.u = right;
  860. locQuad.tr.texCoords.v = top;
  861. }
  862. this._quadDirty = true;
  863. }
  864. });
  865. if(cc.Browser.supportWebGL){
  866. cc.LabelTTF.prototype.setColor = cc.Sprite.prototype.setColor;
  867. cc.LabelTTF.prototype._setColorsString = cc.LabelTTF.prototype._setColorsStringForWebGL;
  868. cc.LabelTTF.prototype.updateDisplayedColor = cc.Sprite.prototype.updateDisplayedColor;
  869. cc.LabelTTF.prototype.setOpacity = cc.Sprite.prototype.setOpacity;
  870. cc.LabelTTF.prototype.updateDisplayedOpacity = cc.Sprite.prototype.updateDisplayedOpacity;
  871. cc.LabelTTF.prototype.initWithStringAndTextDefinition = cc.LabelTTF.prototype._initWithStringAndTextDefinitionForWebGL;
  872. cc.LabelTTF.prototype.setFontFillColor = cc.LabelTTF.prototype._setFontFillColorForWebGL;
  873. cc.LabelTTF.prototype.draw = cc.LabelTTF.prototype._drawForWebGL;
  874. cc.LabelTTF.prototype.setTextureRect = cc.Sprite.prototype._setTextureRectForWebGL;
  875. } else {
  876. cc.LabelTTF.prototype.setColor = cc.LabelTTF.prototype._setColorForCanvas;
  877. cc.LabelTTF.prototype._setColorsString = cc.LabelTTF.prototype._setColorsStringForCanvas;
  878. cc.LabelTTF.prototype.updateDisplayedColor = cc.LabelTTF.prototype._updateDisplayedColorForCanvas;
  879. cc.LabelTTF.prototype.setOpacity = cc.LabelTTF.prototype._setOpacityForCanvas;
  880. cc.LabelTTF.prototype.updateDisplayedOpacity = cc.LabelTTF.prototype._updateDisplayedOpacityForCanvas;
  881. cc.LabelTTF.prototype.initWithStringAndTextDefinition = cc.LabelTTF.prototype._initWithStringAndTextDefinitionForCanvas;
  882. cc.LabelTTF.prototype.setFontFillColor = cc.LabelTTF.prototype._setFontFillColorForCanvas;
  883. cc.LabelTTF.prototype.draw = cc.Sprite.prototype.draw;
  884. cc.LabelTTF.prototype.setTextureRect = cc.LabelTTF.prototype._setTextureRectForCanvas;
  885. }
  886. cc.LabelTTF._textAlign = ["left", "center", "right"];
  887. cc.LabelTTF._textBaseline = ["top", "middle", "bottom"];
  888. // Class static properties for measure util
  889. cc.LabelTTF._checkRegEx = /(.+?)([\s\n\r\-\/\\\:]|[\u4E00-\u9FA5]|[\uFE30-\uFFA0])/;
  890. cc.LabelTTF._reverseCheckRegEx = /(.*)([\s\n\r\-\/\\\:]|[\u4E00-\u9FA5]|[\uFE30-\uFFA0])/;
  891. cc.LabelTTF._checkEnRegEx = /[\s\-\/\\\:]/;
  892. /**
  893. * creates a cc.LabelTTF from a font name, alignment, dimension and font size
  894. * @param {String} label
  895. * @param {String} fontName
  896. * @param {Number} fontSize
  897. * @param {cc.Size} [dimensions=cc.SIZE_ZERO]
  898. * @param {Number} [hAlignment=]
  899. * @param {Number} [vAlignment=cc.VERTICAL_TEXT_ALIGNMENT_TOP]
  900. * @return {cc.LabelTTF|Null}
  901. * @example
  902. * // Example
  903. * var myLabel = cc.LabelTTF.create('label text', 'Times New Roman', 32, cc.size(32,16), cc.TEXT_ALIGNMENT_LEFT);
  904. */
  905. cc.LabelTTF.create = function (label, fontName, fontSize, dimensions, hAlignment, vAlignment) {
  906. var ret = new cc.LabelTTF();
  907. if (ret.initWithString(label, fontName, fontSize, dimensions, hAlignment, vAlignment))
  908. return ret;
  909. return null;
  910. };
  911. /**
  912. * Create a label with string and a font definition
  913. * @param {String} text
  914. * @param {cc.FontDefinition} textDefinition
  915. * @return {cc.LabelTTF|Null}
  916. */
  917. cc.LabelTTF.createWithFontDefinition = function(text, textDefinition){
  918. var ret = new cc.LabelTTF();
  919. if(ret && ret.initWithStringAndTextDefinition(text, textDefinition))
  920. return ret;
  921. return null;
  922. };
  923. if(cc.USE_LA88_LABELS)
  924. cc.LabelTTF._SHADER_PROGRAM = cc.SHADER_POSITION_TEXTURECOLOR;
  925. else
  926. cc.LabelTTF._SHADER_PROGRAM = cc.SHADER_POSITION_TEXTUREA8COLOR;
  927. cc.LabelTTF.__labelHeightDiv = document.createElement("div");
  928. cc.LabelTTF.__labelHeightDiv.style.fontFamily = "Arial";
  929. cc.LabelTTF.__labelHeightDiv.style.position = "absolute";
  930. cc.LabelTTF.__labelHeightDiv.style.left = "-100px";
  931. cc.LabelTTF.__labelHeightDiv.style.top = "-100px";
  932. cc.LabelTTF.__labelHeightDiv.style.lineHeight = "normal";
  933. document.body.appendChild(cc.LabelTTF.__labelHeightDiv);
  934. cc.LabelTTF.__getFontHeightByDiv = function(fontName, fontSize){
  935. var clientHeight = cc.LabelTTF.__fontHeightCache[fontName + "." + fontSize];
  936. if (clientHeight > 0) return clientHeight;
  937. var labelDiv = cc.LabelTTF.__labelHeightDiv;
  938. labelDiv.innerHTML = "ajghl~!";
  939. labelDiv.style.fontFamily = fontName;
  940. labelDiv.style.fontSize = fontSize + "px";
  941. clientHeight = labelDiv.clientHeight ;
  942. cc.LabelTTF.__fontHeightCache[fontName + "." + fontSize] = clientHeight;
  943. labelDiv.innerHTML = "";
  944. return clientHeight;
  945. };
  946. cc.LabelTTF.__fontHeightCache = {};