If there are any android users out there using cocos2dx, this is not necessarily an easy problem to solve, but it is doable once you go down the rabbit hole. It does require editing the Cocos2dxBitmap.java file, which means that any changes made could be overrided by an update. Basically, the methods that are used to measure text are, while not incorrect, inadequate.
First, we need to add a new variable to the TextProperty
private final int mX;
Next, replace the computeTextProperty code with the following:
private static TextProperty computeTextProperty(final String pString, final int unusedWidth, final int unusedHeight, final Paint pPaint) {
final FontMetricsInt fm = pPaint.getFontMetricsInt();
final int h = (int) Math.ceil(fm.bottom - fm.top);
int maxContentWidth = 0;
final String[] lines = Cocos2dxBitmap.splitString(pString, 0,
0, pPaint);
/* Compute the max width. */
int temp = 0;
float left = 0;
for (final String line : lines) {
//get a path from text
Path path = new Path();
pPaint.getTextPath(line, 0, line.length(), 0, 0, path);
RectF bounds = new RectF();
path.computeBounds(bounds, true);
temp = (int) FloatMath.ceil(bounds.width());
//if the text extends to the left of 0
if (bounds.left < left) {
left = bounds.left;
}
if (temp > maxContentWidth) {
maxContentWidth = temp;
//extend the width to account for text rendered to the left of 0
if (left < bounds.left) {
maxContentWidth += (int) FloatMath.ceil(Math.abs(left));
}
}
}
left = Math.abs(left);
return new TextProperty(maxContentWidth, h, lines, (int) FloatMath.ceil(left));
}
What has basically happened is that we have used information returned by the text path to get if the left bound is less than 0, which would mean it would be rendered outside the bitmap. We also extend the width when there are multiple lines of text, as we are going to shift everything to match the left bounds, we need the right bounds shifted too.
Finally, replace computeX with
private static int computeX(final String pText, final int pMaxWidth,
final int pHorizontalAlignment, final int pX) {
int ret = 0;
int expectedWidth = pX + pMaxWidth;
switch (pHorizontalAlignment) {
case HORIZONTALALIGN_CENTER:
ret = expectedWidth / 2;
break;
case HORIZONTALALIGN_RIGHT:
ret = expectedWidth;
break;
case HORIZONTALALIGN_LEFT:
ret = pX;
default:
break;
}
return ret;
}
You'll have to do all the hookups yourself, but this will provide the most accurate text rendering.