cocos2d-xのCCLabelTTFで、横幅を固定し、テキストをその横幅に応じて自動改行させ、なおかつ高さは明示的に指定せずに、テキスト量に応じて可変にしたい(自動的に最適な高さにしたい)場合。
CCLabelTTF::create(const char *string, const char *fontName, float fontSize, const CCSize& dimensions, CCTextAlignment hAlignment)
を使って、dimensionsに例えば CCSize(100.f, 0)といった具合に、高さ0を指定してやれば良い。
ただし、表示させるテキストが空の行(いわゆる”\n\n”)を含む場合、おそらく空行の分の高さが無視され、結果、テキストの末尾の1行分が表示されないという不具合がある(cocos2d-x 2.2.2)。
空行が2行分あれば、末尾2行分が切れるはずだ。
これを回避するには、”\n \n”のように、空行にスペースをひとつ入れてやると良い。
そうすれば、そこは空行ではなく「文字のある行」として、きちんと高さの計算が合うらしい。
ただし、iOS7の場合で、条件によってはこれでも末尾が切れる場合があるようだ。
原因を探ると、結局のところ、CCImageのdrawInRectに行き当たった。
ちなみに、CCLabelTTFで文字の縁取りを行うenableStrokeがiOS7で正常に機能しないという話があって、これもCCImageのdrawInRectが原因らしい。
というわけで、これを修正することで両方の不具合を解消できる。
CCLabelTTFのenableStrokeをiOS7に対応させる – Poppin Games Engineer Blog
こちらのブログにCCImageのdrawInRectをiOS7に対応させる方法が記載されているので、ありがたく使わせてもらいました。
CCImage.mm内に
// XXX: ios7 casting
というコメントがあるので、その下を書き換える。
OSの判別処理を含めて、こんな感じかな。
unsigned uHoriFlag = eAlign & 0x0f; if ([[UIDevice currentDevice].systemVersion floatValue] < 7.f) { UITextAlignment align = (UITextAlignment)((2 == uHoriFlag) ? UITextAlignmentRight : (3 == uHoriFlag) ? UITextAlignmentCenter : UITextAlignmentLeft); [str drawInRect:CGRectMake(textOriginX, textOrigingY, textWidth, textHeight) withFont:font lineBreakMode:NSLineBreakByWordWrapping alignment:(NSTextAlignment)align]; } else { NSMutableParagraphStyle *paragraphStyle = [[[NSMutableParagraphStyle alloc] init] autorelease]; paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping; paragraphStyle.alignment = ((2 == uHoriFlag) ? NSTextAlignmentRight : (3 == uHoriFlag) ? NSTextAlignmentCenter : NSTextAlignmentLeft); UIColor *strokeColor = [UIColor colorWithRed:pInfo->strokeColorR green:pInfo->strokeColorG blue:pInfo->strokeColorB alpha:1.0]; UIColor *fontColor = [UIColor colorWithRed:pInfo->tintColorR green:pInfo->tintColorG blue:pInfo->tintColorB alpha:1.0]; NSDictionary *attribute = @{NSFontAttributeName:font, NSParagraphStyleAttributeName:paragraphStyle, NSForegroundColorAttributeName:fontColor, NSStrokeColorAttributeName:strokeColor, NSStrokeWidthAttributeName:@(-pInfo->strokeSize * 4.f) }; [str drawInRect:CGRectMake(textOriginX, textOrigingY, textWidth, textHeight) withAttributes:attribute]; }
alignはiOS6以前でしか使わないようなので、ここに持ってきてます。
あと、NSStrokeWidthAttributeName:@(-pInfo->strokeSize * 4.f)の部分ですが、Poppin Games Engineer Blogさんのコードでは *2 となっているところを *4にしています。
縁取りの太さなんですが、iOS6の場合と比べると2倍ではまだ太さが足らなくて、4倍でちょうどのように思えるので。
でも、なぜ4倍になるのかよく分からない。
2倍なら、たとえば縁取りが外側と内側で2倍になる、ということかな?と思えもするが。
retina解像度の2倍も掛かってくるのだろうか?