mirror of https://github.com/axmolengine/axmol.git
[Android] fixed #547: line wrap OK on Android
This commit is contained in:
parent
b72641608c
commit
6c47f53b13
|
@ -2,6 +2,7 @@ package org.cocos2dx.lib;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.ByteOrder;
|
import java.nio.ByteOrder;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
|
@ -14,37 +15,42 @@ import android.graphics.Paint.FontMetricsInt;
|
||||||
public class Cocos2dxBitmap{
|
public class Cocos2dxBitmap{
|
||||||
/*
|
/*
|
||||||
* The values are the same as cocos2dx/platform/CCImage.h.
|
* The values are the same as cocos2dx/platform/CCImage.h.
|
||||||
* I think three alignments are ok.
|
* I think three alignments are OK.
|
||||||
*/
|
*/
|
||||||
private static final int ALIGNCENTER = 0x33;
|
private static final int ALIGNCENTER = 0x33;
|
||||||
private static final int ALIGNLEFT = 0x31;
|
private static final int ALIGNLEFT = 0x31;
|
||||||
private static final int ALIGNRIGHT = 0x32;
|
private static final int ALIGNRIGHT = 0x32;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @width: the width to draw, it can be 0
|
||||||
|
* @height: the height to draw, it can be 0
|
||||||
|
*/
|
||||||
public static void createTextBitmap(String content, String fontName,
|
public static void createTextBitmap(String content, String fontName,
|
||||||
int fontSize, int alignment){
|
int fontSize, int alignment, int width, int height){
|
||||||
// avoid error when content is ""
|
|
||||||
|
// Avoid error when content is ""
|
||||||
if (content.compareTo("") == 0){
|
if (content.compareTo("") == 0){
|
||||||
content = " ";
|
content = " ";
|
||||||
}
|
}
|
||||||
|
|
||||||
Paint paint = newPaint(fontName, fontSize, alignment);
|
Paint paint = newPaint(fontName, fontSize, alignment);
|
||||||
|
|
||||||
TextProperty textProperty = getTextWidthAndHeight(content, paint);
|
TextProperty textProperty = getTextWidthAndHeight(content, paint, width, height);
|
||||||
|
|
||||||
// draw text to bitmap
|
// Draw text to bitmap
|
||||||
Bitmap bitmap = Bitmap.createBitmap(textProperty.maxWidth,
|
Bitmap bitmap = Bitmap.createBitmap(textProperty.maxWidth,
|
||||||
textProperty.height * textProperty.numberLines, Bitmap.Config.ARGB_8888);
|
textProperty.totalHeight, Bitmap.Config.ARGB_8888);
|
||||||
Canvas canvas = new Canvas(bitmap);
|
Canvas canvas = new Canvas(bitmap);
|
||||||
|
|
||||||
// draw string
|
// Draw string
|
||||||
FontMetricsInt fm = paint.getFontMetricsInt();
|
FontMetricsInt fm = paint.getFontMetricsInt();
|
||||||
int x = 0;
|
int x = 0;
|
||||||
int y = -fm.ascent;
|
int y = -fm.ascent;
|
||||||
String[] lines = content.split("\\n");
|
String[] lines = textProperty.lines;
|
||||||
for (String line : lines){
|
for (String line : lines){
|
||||||
x = computeX(paint, line, textProperty.maxWidth, alignment);
|
x = computeX(paint, line, textProperty.maxWidth, alignment);
|
||||||
canvas.drawText(line, x, y, paint);
|
canvas.drawText(line, x, y, paint);
|
||||||
y += textProperty.height;
|
y += textProperty.heightPerLine;
|
||||||
}
|
}
|
||||||
|
|
||||||
initNativeObject(bitmap);
|
initNativeObject(bitmap);
|
||||||
|
@ -66,7 +72,10 @@ public class Cocos2dxBitmap{
|
||||||
ret = w;
|
ret = w;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// default is align left ret = 0
|
/*
|
||||||
|
* Default is align left.
|
||||||
|
* Should be same as newPaint().
|
||||||
|
*/
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -75,36 +84,153 @@ public class Cocos2dxBitmap{
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class TextProperty{
|
private static class TextProperty{
|
||||||
|
// The max width of lines
|
||||||
int maxWidth;
|
int maxWidth;
|
||||||
int height;
|
// The height of all lines
|
||||||
int numberLines;
|
int totalHeight;
|
||||||
|
int heightPerLine;
|
||||||
|
String[] lines;
|
||||||
|
|
||||||
TextProperty(int w, int h, int n){
|
TextProperty(int w, int h, String[] lines){
|
||||||
this.maxWidth = w;
|
this.maxWidth = w;
|
||||||
this.height = h;
|
this.heightPerLine = h;
|
||||||
this.numberLines = n;
|
this.totalHeight = h * lines.length;
|
||||||
|
this.lines = lines;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static TextProperty getTextWidthAndHeight(String content, Paint paint){
|
private static TextProperty getTextWidthAndHeight(String content, Paint paint,
|
||||||
|
int maxWidth, int maxHeight){
|
||||||
FontMetricsInt fm = paint.getFontMetricsInt();
|
FontMetricsInt fm = paint.getFontMetricsInt();
|
||||||
int h = (int)Math.ceil(fm.descent - fm.ascent);
|
int h = (int)Math.ceil(fm.descent - fm.ascent);
|
||||||
|
int maxContentWidth = 0;
|
||||||
|
|
||||||
String[] lines = content.split("\\n");
|
String[] lines = splitString(content, maxHeight, maxWidth, paint);
|
||||||
|
|
||||||
|
if (maxWidth != 0){
|
||||||
|
maxContentWidth = maxWidth;
|
||||||
|
}
|
||||||
|
else {
|
||||||
/*
|
/*
|
||||||
* Compute the max width
|
* Compute the max width
|
||||||
*/
|
*/
|
||||||
int w = 0;
|
|
||||||
int temp = 0;
|
int temp = 0;
|
||||||
for (String line : lines){
|
for (String line : lines){
|
||||||
temp = (int)Math.ceil(paint.measureText(line, 0, line.length()));
|
temp = (int)Math.ceil(paint.measureText(line, 0, line.length()));
|
||||||
if (temp > w){
|
if (temp > maxContentWidth){
|
||||||
w = temp;
|
maxContentWidth = temp;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new TextProperty(w, h, lines.length);
|
|
||||||
|
return new TextProperty(maxContentWidth, h, lines);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If maxWidth or maxHeight is not 0,
|
||||||
|
* split the string to fix the maxWidth and maxHeight.
|
||||||
|
*/
|
||||||
|
private static String[] splitString(String content, int maxHeight, int maxWidth,
|
||||||
|
Paint paint){
|
||||||
|
String[] lines = content.split("\\n");
|
||||||
|
String[] ret = null;
|
||||||
|
FontMetricsInt fm = paint.getFontMetricsInt();
|
||||||
|
int heightPerLine = (int)Math.ceil(fm.descent - fm.ascent);
|
||||||
|
int maxLines = maxHeight / heightPerLine;
|
||||||
|
|
||||||
|
if (maxWidth != 0){
|
||||||
|
LinkedList<String> strList = new LinkedList<String>();
|
||||||
|
for (String line : lines){
|
||||||
|
/*
|
||||||
|
* The width of line is exceed maxWidth, should divide it into
|
||||||
|
* two or more lines.
|
||||||
|
*/
|
||||||
|
int lineWidth = (int)Math.ceil(paint.measureText(line));
|
||||||
|
if (lineWidth > maxWidth){
|
||||||
|
strList.addAll(divideStringWithMaxWidth(paint, line, maxWidth));
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
strList.add(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Should not exceed the max height;
|
||||||
|
*/
|
||||||
|
if (maxLines > 0 && strList.size() >= maxLines){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Remove exceeding lines
|
||||||
|
*/
|
||||||
|
if (maxLines > 0 && strList.size() > maxLines){
|
||||||
|
while (strList.size() > maxLines){
|
||||||
|
strList.removeLast();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = new String[strList.size()];
|
||||||
|
strList.toArray(ret);
|
||||||
|
} else
|
||||||
|
if (maxHeight != 0 && lines.length > maxLines) {
|
||||||
|
/*
|
||||||
|
* Remove exceeding lines
|
||||||
|
*/
|
||||||
|
LinkedList<String> strList = new LinkedList<String>();
|
||||||
|
for (int i = 0; i < maxLines; i++){
|
||||||
|
strList.add(lines[i]);
|
||||||
|
}
|
||||||
|
ret = new String[strList.size()];
|
||||||
|
strList.toArray(ret);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ret = lines;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static LinkedList<String> divideStringWithMaxWidth(Paint paint, String content,
|
||||||
|
int width){
|
||||||
|
int charLength = content.length();
|
||||||
|
int start = 0;
|
||||||
|
int tempWidth = 0;
|
||||||
|
LinkedList<String> strList = new LinkedList<String>();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Break a String into String[] by the width
|
||||||
|
*/
|
||||||
|
for (int i = 1; i <= charLength; ++i){
|
||||||
|
tempWidth = (int)Math.ceil(paint.measureText(content, start, i));
|
||||||
|
if (tempWidth >= width){
|
||||||
|
/*
|
||||||
|
* Should not exceed the width
|
||||||
|
*/
|
||||||
|
if (tempWidth > width){
|
||||||
|
strList.add(content.substring(start, i - 1));
|
||||||
|
/*
|
||||||
|
* compute from previous char
|
||||||
|
*/
|
||||||
|
--i;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
strList.add(content.substring(start, i));
|
||||||
|
}
|
||||||
|
|
||||||
|
start = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add the last char
|
||||||
|
*/
|
||||||
|
if (start == charLength - 1){
|
||||||
|
strList.add(content.substring(charLength-1));
|
||||||
|
}
|
||||||
|
|
||||||
|
return strList;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Paint newPaint(String fontName, int fontSize, int alignment){
|
private static Paint newPaint(String fontName, int fontSize, int alignment){
|
||||||
|
|
|
@ -2,6 +2,7 @@ package org.cocos2dx.lib;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.ByteOrder;
|
import java.nio.ByteOrder;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
|
@ -14,37 +15,42 @@ import android.graphics.Paint.FontMetricsInt;
|
||||||
public class Cocos2dxBitmap{
|
public class Cocos2dxBitmap{
|
||||||
/*
|
/*
|
||||||
* The values are the same as cocos2dx/platform/CCImage.h.
|
* The values are the same as cocos2dx/platform/CCImage.h.
|
||||||
* I think three alignments are ok.
|
* I think three alignments are OK.
|
||||||
*/
|
*/
|
||||||
private static final int ALIGNCENTER = 0x33;
|
private static final int ALIGNCENTER = 0x33;
|
||||||
private static final int ALIGNLEFT = 0x31;
|
private static final int ALIGNLEFT = 0x31;
|
||||||
private static final int ALIGNRIGHT = 0x32;
|
private static final int ALIGNRIGHT = 0x32;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @width: the width to draw, it can be 0
|
||||||
|
* @height: the height to draw, it can be 0
|
||||||
|
*/
|
||||||
public static void createTextBitmap(String content, String fontName,
|
public static void createTextBitmap(String content, String fontName,
|
||||||
int fontSize, int alignment){
|
int fontSize, int alignment, int width, int height){
|
||||||
// avoid error when content is ""
|
|
||||||
|
// Avoid error when content is ""
|
||||||
if (content.compareTo("") == 0){
|
if (content.compareTo("") == 0){
|
||||||
content = " ";
|
content = " ";
|
||||||
}
|
}
|
||||||
|
|
||||||
Paint paint = newPaint(fontName, fontSize, alignment);
|
Paint paint = newPaint(fontName, fontSize, alignment);
|
||||||
|
|
||||||
TextProperty textProperty = getTextWidthAndHeight(content, paint);
|
TextProperty textProperty = getTextWidthAndHeight(content, paint, width, height);
|
||||||
|
|
||||||
// draw text to bitmap
|
// Draw text to bitmap
|
||||||
Bitmap bitmap = Bitmap.createBitmap(textProperty.maxWidth,
|
Bitmap bitmap = Bitmap.createBitmap(textProperty.maxWidth,
|
||||||
textProperty.height * textProperty.numberLines, Bitmap.Config.ARGB_8888);
|
textProperty.totalHeight, Bitmap.Config.ARGB_8888);
|
||||||
Canvas canvas = new Canvas(bitmap);
|
Canvas canvas = new Canvas(bitmap);
|
||||||
|
|
||||||
// draw string
|
// Draw string
|
||||||
FontMetricsInt fm = paint.getFontMetricsInt();
|
FontMetricsInt fm = paint.getFontMetricsInt();
|
||||||
int x = 0;
|
int x = 0;
|
||||||
int y = -fm.ascent;
|
int y = -fm.ascent;
|
||||||
String[] lines = content.split("\\n");
|
String[] lines = textProperty.lines;
|
||||||
for (String line : lines){
|
for (String line : lines){
|
||||||
x = computeX(paint, line, textProperty.maxWidth, alignment);
|
x = computeX(paint, line, textProperty.maxWidth, alignment);
|
||||||
canvas.drawText(line, x, y, paint);
|
canvas.drawText(line, x, y, paint);
|
||||||
y += textProperty.height;
|
y += textProperty.heightPerLine;
|
||||||
}
|
}
|
||||||
|
|
||||||
initNativeObject(bitmap);
|
initNativeObject(bitmap);
|
||||||
|
@ -66,7 +72,10 @@ public class Cocos2dxBitmap{
|
||||||
ret = w;
|
ret = w;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// default is align left ret = 0
|
/*
|
||||||
|
* Default is align left.
|
||||||
|
* Should be same as newPaint().
|
||||||
|
*/
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -75,36 +84,153 @@ public class Cocos2dxBitmap{
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class TextProperty{
|
private static class TextProperty{
|
||||||
|
// The max width of lines
|
||||||
int maxWidth;
|
int maxWidth;
|
||||||
int height;
|
// The height of all lines
|
||||||
int numberLines;
|
int totalHeight;
|
||||||
|
int heightPerLine;
|
||||||
|
String[] lines;
|
||||||
|
|
||||||
TextProperty(int w, int h, int n){
|
TextProperty(int w, int h, String[] lines){
|
||||||
this.maxWidth = w;
|
this.maxWidth = w;
|
||||||
this.height = h;
|
this.heightPerLine = h;
|
||||||
this.numberLines = n;
|
this.totalHeight = h * lines.length;
|
||||||
|
this.lines = lines;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static TextProperty getTextWidthAndHeight(String content, Paint paint){
|
private static TextProperty getTextWidthAndHeight(String content, Paint paint,
|
||||||
|
int maxWidth, int maxHeight){
|
||||||
FontMetricsInt fm = paint.getFontMetricsInt();
|
FontMetricsInt fm = paint.getFontMetricsInt();
|
||||||
int h = (int)Math.ceil(fm.descent - fm.ascent);
|
int h = (int)Math.ceil(fm.descent - fm.ascent);
|
||||||
|
int maxContentWidth = 0;
|
||||||
|
|
||||||
String[] lines = content.split("\\n");
|
String[] lines = splitString(content, maxHeight, maxWidth, paint);
|
||||||
|
|
||||||
|
if (maxWidth != 0){
|
||||||
|
maxContentWidth = maxWidth;
|
||||||
|
}
|
||||||
|
else {
|
||||||
/*
|
/*
|
||||||
* Compute the max width
|
* Compute the max width
|
||||||
*/
|
*/
|
||||||
int w = 0;
|
|
||||||
int temp = 0;
|
int temp = 0;
|
||||||
for (String line : lines){
|
for (String line : lines){
|
||||||
temp = (int)Math.ceil(paint.measureText(line, 0, line.length()));
|
temp = (int)Math.ceil(paint.measureText(line, 0, line.length()));
|
||||||
if (temp > w){
|
if (temp > maxContentWidth){
|
||||||
w = temp;
|
maxContentWidth = temp;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new TextProperty(w, h, lines.length);
|
|
||||||
|
return new TextProperty(maxContentWidth, h, lines);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If maxWidth or maxHeight is not 0,
|
||||||
|
* split the string to fix the maxWidth and maxHeight.
|
||||||
|
*/
|
||||||
|
private static String[] splitString(String content, int maxHeight, int maxWidth,
|
||||||
|
Paint paint){
|
||||||
|
String[] lines = content.split("\\n");
|
||||||
|
String[] ret = null;
|
||||||
|
FontMetricsInt fm = paint.getFontMetricsInt();
|
||||||
|
int heightPerLine = (int)Math.ceil(fm.descent - fm.ascent);
|
||||||
|
int maxLines = maxHeight / heightPerLine;
|
||||||
|
|
||||||
|
if (maxWidth != 0){
|
||||||
|
LinkedList<String> strList = new LinkedList<String>();
|
||||||
|
for (String line : lines){
|
||||||
|
/*
|
||||||
|
* The width of line is exceed maxWidth, should divide it into
|
||||||
|
* two or more lines.
|
||||||
|
*/
|
||||||
|
int lineWidth = (int)Math.ceil(paint.measureText(line));
|
||||||
|
if (lineWidth > maxWidth){
|
||||||
|
strList.addAll(divideStringWithMaxWidth(paint, line, maxWidth));
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
strList.add(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Should not exceed the max height;
|
||||||
|
*/
|
||||||
|
if (maxLines > 0 && strList.size() >= maxLines){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Remove exceeding lines
|
||||||
|
*/
|
||||||
|
if (maxLines > 0 && strList.size() > maxLines){
|
||||||
|
while (strList.size() > maxLines){
|
||||||
|
strList.removeLast();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = new String[strList.size()];
|
||||||
|
strList.toArray(ret);
|
||||||
|
} else
|
||||||
|
if (maxHeight != 0 && lines.length > maxLines) {
|
||||||
|
/*
|
||||||
|
* Remove exceeding lines
|
||||||
|
*/
|
||||||
|
LinkedList<String> strList = new LinkedList<String>();
|
||||||
|
for (int i = 0; i < maxLines; i++){
|
||||||
|
strList.add(lines[i]);
|
||||||
|
}
|
||||||
|
ret = new String[strList.size()];
|
||||||
|
strList.toArray(ret);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ret = lines;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static LinkedList<String> divideStringWithMaxWidth(Paint paint, String content,
|
||||||
|
int width){
|
||||||
|
int charLength = content.length();
|
||||||
|
int start = 0;
|
||||||
|
int tempWidth = 0;
|
||||||
|
LinkedList<String> strList = new LinkedList<String>();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Break a String into String[] by the width
|
||||||
|
*/
|
||||||
|
for (int i = 1; i <= charLength; ++i){
|
||||||
|
tempWidth = (int)Math.ceil(paint.measureText(content, start, i));
|
||||||
|
if (tempWidth >= width){
|
||||||
|
/*
|
||||||
|
* Should not exceed the width
|
||||||
|
*/
|
||||||
|
if (tempWidth > width){
|
||||||
|
strList.add(content.substring(start, i - 1));
|
||||||
|
/*
|
||||||
|
* compute from previous char
|
||||||
|
*/
|
||||||
|
--i;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
strList.add(content.substring(start, i));
|
||||||
|
}
|
||||||
|
|
||||||
|
start = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add the last char
|
||||||
|
*/
|
||||||
|
if (start == charLength - 1){
|
||||||
|
strList.add(content.substring(charLength-1));
|
||||||
|
}
|
||||||
|
|
||||||
|
return strList;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Paint newPaint(String fontName, int fontSize, int alignment){
|
private static Paint newPaint(String fontName, int fontSize, int alignment){
|
||||||
|
|
|
@ -73,7 +73,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
// get method of createBitmap
|
// get method of createBitmap
|
||||||
jmethodID midCreateTextBitmap = env->GetStaticMethodID(mClass, "createTextBitmap", "(Ljava/lang/String;Ljava/lang/String;II)V");
|
jmethodID midCreateTextBitmap = env->GetStaticMethodID(mClass, "createTextBitmap", "(Ljava/lang/String;Ljava/lang/String;IIII)V");
|
||||||
if (! midCreateTextBitmap)
|
if (! midCreateTextBitmap)
|
||||||
{
|
{
|
||||||
CCLOG("can not find method createTextBitmap");
|
CCLOG("can not find method createTextBitmap");
|
||||||
|
@ -87,7 +87,7 @@ public:
|
||||||
* use this appoach to decrease the jni call number
|
* use this appoach to decrease the jni call number
|
||||||
*/
|
*/
|
||||||
env->CallStaticVoidMethod(mClass, midCreateTextBitmap, env->NewStringUTF(text), env->NewStringUTF(pFontName),
|
env->CallStaticVoidMethod(mClass, midCreateTextBitmap, env->NewStringUTF(text), env->NewStringUTF(pFontName),
|
||||||
(int)fontSize, eAlignMask);
|
(int)fontSize, eAlignMask, nWidth, nHeight);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ package org.cocos2dx.lib;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.ByteOrder;
|
import java.nio.ByteOrder;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
|
@ -14,37 +15,42 @@ import android.graphics.Paint.FontMetricsInt;
|
||||||
public class Cocos2dxBitmap{
|
public class Cocos2dxBitmap{
|
||||||
/*
|
/*
|
||||||
* The values are the same as cocos2dx/platform/CCImage.h.
|
* The values are the same as cocos2dx/platform/CCImage.h.
|
||||||
* I think three alignments are ok.
|
* I think three alignments are OK.
|
||||||
*/
|
*/
|
||||||
private static final int ALIGNCENTER = 0x33;
|
private static final int ALIGNCENTER = 0x33;
|
||||||
private static final int ALIGNLEFT = 0x31;
|
private static final int ALIGNLEFT = 0x31;
|
||||||
private static final int ALIGNRIGHT = 0x32;
|
private static final int ALIGNRIGHT = 0x32;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @width: the width to draw, it can be 0
|
||||||
|
* @height: the height to draw, it can be 0
|
||||||
|
*/
|
||||||
public static void createTextBitmap(String content, String fontName,
|
public static void createTextBitmap(String content, String fontName,
|
||||||
int fontSize, int alignment){
|
int fontSize, int alignment, int width, int height){
|
||||||
// avoid error when content is ""
|
|
||||||
|
// Avoid error when content is ""
|
||||||
if (content.compareTo("") == 0){
|
if (content.compareTo("") == 0){
|
||||||
content = " ";
|
content = " ";
|
||||||
}
|
}
|
||||||
|
|
||||||
Paint paint = newPaint(fontName, fontSize, alignment);
|
Paint paint = newPaint(fontName, fontSize, alignment);
|
||||||
|
|
||||||
TextProperty textProperty = getTextWidthAndHeight(content, paint);
|
TextProperty textProperty = getTextWidthAndHeight(content, paint, width, height);
|
||||||
|
|
||||||
// draw text to bitmap
|
// Draw text to bitmap
|
||||||
Bitmap bitmap = Bitmap.createBitmap(textProperty.maxWidth,
|
Bitmap bitmap = Bitmap.createBitmap(textProperty.maxWidth,
|
||||||
textProperty.height * textProperty.numberLines, Bitmap.Config.ARGB_8888);
|
textProperty.totalHeight, Bitmap.Config.ARGB_8888);
|
||||||
Canvas canvas = new Canvas(bitmap);
|
Canvas canvas = new Canvas(bitmap);
|
||||||
|
|
||||||
// draw string
|
// Draw string
|
||||||
FontMetricsInt fm = paint.getFontMetricsInt();
|
FontMetricsInt fm = paint.getFontMetricsInt();
|
||||||
int x = 0;
|
int x = 0;
|
||||||
int y = -fm.ascent;
|
int y = -fm.ascent;
|
||||||
String[] lines = content.split("\\n");
|
String[] lines = textProperty.lines;
|
||||||
for (String line : lines){
|
for (String line : lines){
|
||||||
x = computeX(paint, line, textProperty.maxWidth, alignment);
|
x = computeX(paint, line, textProperty.maxWidth, alignment);
|
||||||
canvas.drawText(line, x, y, paint);
|
canvas.drawText(line, x, y, paint);
|
||||||
y += textProperty.height;
|
y += textProperty.heightPerLine;
|
||||||
}
|
}
|
||||||
|
|
||||||
initNativeObject(bitmap);
|
initNativeObject(bitmap);
|
||||||
|
@ -66,7 +72,10 @@ public class Cocos2dxBitmap{
|
||||||
ret = w;
|
ret = w;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// default is align left ret = 0
|
/*
|
||||||
|
* Default is align left.
|
||||||
|
* Should be same as newPaint().
|
||||||
|
*/
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -75,36 +84,153 @@ public class Cocos2dxBitmap{
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class TextProperty{
|
private static class TextProperty{
|
||||||
|
// The max width of lines
|
||||||
int maxWidth;
|
int maxWidth;
|
||||||
int height;
|
// The height of all lines
|
||||||
int numberLines;
|
int totalHeight;
|
||||||
|
int heightPerLine;
|
||||||
|
String[] lines;
|
||||||
|
|
||||||
TextProperty(int w, int h, int n){
|
TextProperty(int w, int h, String[] lines){
|
||||||
this.maxWidth = w;
|
this.maxWidth = w;
|
||||||
this.height = h;
|
this.heightPerLine = h;
|
||||||
this.numberLines = n;
|
this.totalHeight = h * lines.length;
|
||||||
|
this.lines = lines;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static TextProperty getTextWidthAndHeight(String content, Paint paint){
|
private static TextProperty getTextWidthAndHeight(String content, Paint paint,
|
||||||
|
int maxWidth, int maxHeight){
|
||||||
FontMetricsInt fm = paint.getFontMetricsInt();
|
FontMetricsInt fm = paint.getFontMetricsInt();
|
||||||
int h = (int)Math.ceil(fm.descent - fm.ascent);
|
int h = (int)Math.ceil(fm.descent - fm.ascent);
|
||||||
|
int maxContentWidth = 0;
|
||||||
|
|
||||||
String[] lines = content.split("\\n");
|
String[] lines = splitString(content, maxHeight, maxWidth, paint);
|
||||||
|
|
||||||
|
if (maxWidth != 0){
|
||||||
|
maxContentWidth = maxWidth;
|
||||||
|
}
|
||||||
|
else {
|
||||||
/*
|
/*
|
||||||
* Compute the max width
|
* Compute the max width
|
||||||
*/
|
*/
|
||||||
int w = 0;
|
|
||||||
int temp = 0;
|
int temp = 0;
|
||||||
for (String line : lines){
|
for (String line : lines){
|
||||||
temp = (int)Math.ceil(paint.measureText(line, 0, line.length()));
|
temp = (int)Math.ceil(paint.measureText(line, 0, line.length()));
|
||||||
if (temp > w){
|
if (temp > maxContentWidth){
|
||||||
w = temp;
|
maxContentWidth = temp;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new TextProperty(w, h, lines.length);
|
|
||||||
|
return new TextProperty(maxContentWidth, h, lines);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If maxWidth or maxHeight is not 0,
|
||||||
|
* split the string to fix the maxWidth and maxHeight.
|
||||||
|
*/
|
||||||
|
private static String[] splitString(String content, int maxHeight, int maxWidth,
|
||||||
|
Paint paint){
|
||||||
|
String[] lines = content.split("\\n");
|
||||||
|
String[] ret = null;
|
||||||
|
FontMetricsInt fm = paint.getFontMetricsInt();
|
||||||
|
int heightPerLine = (int)Math.ceil(fm.descent - fm.ascent);
|
||||||
|
int maxLines = maxHeight / heightPerLine;
|
||||||
|
|
||||||
|
if (maxWidth != 0){
|
||||||
|
LinkedList<String> strList = new LinkedList<String>();
|
||||||
|
for (String line : lines){
|
||||||
|
/*
|
||||||
|
* The width of line is exceed maxWidth, should divide it into
|
||||||
|
* two or more lines.
|
||||||
|
*/
|
||||||
|
int lineWidth = (int)Math.ceil(paint.measureText(line));
|
||||||
|
if (lineWidth > maxWidth){
|
||||||
|
strList.addAll(divideStringWithMaxWidth(paint, line, maxWidth));
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
strList.add(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Should not exceed the max height;
|
||||||
|
*/
|
||||||
|
if (maxLines > 0 && strList.size() >= maxLines){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Remove exceeding lines
|
||||||
|
*/
|
||||||
|
if (maxLines > 0 && strList.size() > maxLines){
|
||||||
|
while (strList.size() > maxLines){
|
||||||
|
strList.removeLast();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = new String[strList.size()];
|
||||||
|
strList.toArray(ret);
|
||||||
|
} else
|
||||||
|
if (maxHeight != 0 && lines.length > maxLines) {
|
||||||
|
/*
|
||||||
|
* Remove exceeding lines
|
||||||
|
*/
|
||||||
|
LinkedList<String> strList = new LinkedList<String>();
|
||||||
|
for (int i = 0; i < maxLines; i++){
|
||||||
|
strList.add(lines[i]);
|
||||||
|
}
|
||||||
|
ret = new String[strList.size()];
|
||||||
|
strList.toArray(ret);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ret = lines;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static LinkedList<String> divideStringWithMaxWidth(Paint paint, String content,
|
||||||
|
int width){
|
||||||
|
int charLength = content.length();
|
||||||
|
int start = 0;
|
||||||
|
int tempWidth = 0;
|
||||||
|
LinkedList<String> strList = new LinkedList<String>();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Break a String into String[] by the width
|
||||||
|
*/
|
||||||
|
for (int i = 1; i <= charLength; ++i){
|
||||||
|
tempWidth = (int)Math.ceil(paint.measureText(content, start, i));
|
||||||
|
if (tempWidth >= width){
|
||||||
|
/*
|
||||||
|
* Should not exceed the width
|
||||||
|
*/
|
||||||
|
if (tempWidth > width){
|
||||||
|
strList.add(content.substring(start, i - 1));
|
||||||
|
/*
|
||||||
|
* compute from previous char
|
||||||
|
*/
|
||||||
|
--i;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
strList.add(content.substring(start, i));
|
||||||
|
}
|
||||||
|
|
||||||
|
start = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add the last char
|
||||||
|
*/
|
||||||
|
if (start == charLength - 1){
|
||||||
|
strList.add(content.substring(charLength-1));
|
||||||
|
}
|
||||||
|
|
||||||
|
return strList;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Paint newPaint(String fontName, int fontSize, int alignment){
|
private static Paint newPaint(String fontName, int fontSize, int alignment){
|
||||||
|
|
Loading…
Reference in New Issue