cocos2dx 0.010.1 【 CCLabelTTF 】 在android 真机上出现卡死 BUG

把android 项目下的 org.cocos2dx.lib 包下的 Cocos2dxBitmap.java 替换成

  1 package org.cocos2dx.lib;
  2 
  3 import java.nio.ByteBuffer;
  4 import java.nio.ByteOrder;
  5 import java.util.LinkedList;
  6 
  7 import android.content.Context;
  8 import android.graphics.Bitmap;
  9 import android.graphics.Canvas;
 10 import android.graphics.Color;
 11 import android.graphics.Paint;
 12 import android.graphics.Typeface;
 13 import android.graphics.Paint.Align;
 14 import android.graphics.Paint.FontMetricsInt;
 15 import android.util.Log;
 16 
 17 public class Cocos2dxBitmap{
 18     /*
 19      * The values are the same as cocos2dx/platform/CCImage.h.
 20      * I think three alignments are OK.
 21      */
 22     private static final int ALIGNCENTER = 0x33;
 23     private static final int ALIGNLEFT     = 0x31;
 24     private static final int ALIGNRIGHT     = 0x32;
 25     
 26     private static Context context;
 27     
 28     public static void setContext(Context context){
 29         Cocos2dxBitmap.context = context;
 30     }
 31     
 32     /*
 33      * @ the width to draw, it can be 0
 34      * @height: the height to draw, it can be 0
 35      */
 36     public static void createTextBitmap(String content, String fontName, 
 37             int fontSize, int alignment, int width, int height){
 38         
 39         content = refactorString(content);       
 40         Paint paint = newPaint(fontName, fontSize, alignment);
 41         
 42         TextProperty textProperty = computeTextProperty(content, paint, width, height);          
 43 
 44         int bitmapTotalHeight = (height == 0 ? textProperty.totalHeight:height);
 45 
 46         // Draw text to bitmap
 47         Bitmap bitmap = Bitmap.createBitmap(textProperty.maxWidth, 
 48                 bitmapTotalHeight, Bitmap.Config.ARGB_8888);
 49         Canvas canvas = new Canvas(bitmap);
 50         
 51         // Draw string
 52         FontMetricsInt fm = paint.getFontMetricsInt();
 53         int x = 0;
 54         int y = height == 0 ?(-fm.top):
 55             (-fm.top + (height - textProperty.totalHeight)/2);
 56         String[] lines = textProperty.lines;
 57         for (String line : lines){
 58             x = computeX(paint, line, textProperty.maxWidth, alignment);
 59             canvas.drawText(line, x, y, paint);
 60             y += textProperty.heightPerLine;
 61         }
 62         
 63         initNativeObject(bitmap);
 64     }
 65     
 66     private static int computeX(Paint paint, String content, int w, int alignment){
 67         int ret = 0;
 68         
 69         switch (alignment){
 70         case ALIGNCENTER:
 71             ret = w / 2;
 72             break;
 73         
 74         // ret = 0
 75         case ALIGNLEFT:           
 76             break;
 77             
 78         case ALIGNRIGHT:
 79             ret = w;
 80             break;
 81         
 82         /*
 83          * Default is align left.
 84          * Should be same as newPaint().
 85          */
 86         default:
 87             break;
 88         }
 89         
 90         return ret;
 91     }
 92     
 93     private static class TextProperty{
 94         // The max width of lines
 95         int maxWidth;
 96         // The height of all lines
 97         int totalHeight;
 98         int heightPerLine;
 99         String[] lines;
100 
101         TextProperty(int w, int h, String[] lines){
102             this.maxWidth = w;
103             this.heightPerLine = h;
104             this.totalHeight = h * lines.length;           
105             this.lines = lines;
106         }
107     }
108     
109     private static TextProperty computeTextProperty(String content, Paint paint,
110             int maxWidth, int maxHeight){              
111         FontMetricsInt fm = paint.getFontMetricsInt();
112         int h = (int)Math.ceil(fm.bottom - fm.top);
113         int maxContentWidth = 0;
114         
115         String[] lines = splitString(content, maxHeight, maxWidth, paint);
116         
117         if (maxWidth != 0){
118             maxContentWidth = maxWidth;
119         }
120         else {
121             /*
122              * Compute the max width
123              */
124             int temp = 0;
125             for (String line : lines){
126                 temp = (int)Math.ceil(paint.measureText(line, 0, line.length()));
127                 if (temp > maxContentWidth){
128                     maxContentWidth = temp;
129                 }
130             }
131         }        
132         
133         return new TextProperty(maxContentWidth, h, lines);
134     }
135     
136     /*
137      * If maxWidth or maxHeight is not 0,
138      * split the string to fix the maxWidth and maxHeight.
139      */
140     private static String[] splitString(String content, int maxHeight, int maxWidth, 
141             Paint paint){
142         String[] lines = content.split("\\n");
143         String[] ret = null;
144         FontMetricsInt fm = paint.getFontMetricsInt();
145         int heightPerLine = (int)Math.ceil(fm.bottom - fm.top);
146         int maxLines = maxHeight / heightPerLine;
147         
148         if (maxWidth != 0){
149             LinkedList<String> strList = new LinkedList<String>();
150             for (String line : lines){
151                 /*
152                  * The width of line is exceed maxWidth, should divide it into
153                  * two or more lines.
154                  */
155                 int lineWidth = (int)Math.ceil(paint.measureText(line));
156                 if (lineWidth > maxWidth){                    
157                     strList.addAll(divideStringWithMaxWidth(paint, line, maxWidth));
158                 }
159                 else{
160                     strList.add(line);
161                 }
162                 
163                 /*
164                  * Should not exceed the max height;
165                  */
166                 if (maxLines > 0 && strList.size() >= maxLines){
167                     break;
168                 }
169             }
170             
171             /*
172              * Remove exceeding lines
173              */
174             if (maxLines > 0 && strList.size() > maxLines){
175                 while (strList.size() > maxLines){
176                     strList.removeLast();
177                 }
178             }
179             
180             ret = new String[strList.size()];
181             strList.toArray(ret);
182         } else 
183         if (maxHeight != 0 && lines.length > maxLines) {
184             /*
185              * Remove exceeding lines
186              */
187             LinkedList<String> strList = new LinkedList<String>();
188             for (int i = 0; i < maxLines; i++){
189                 strList.add(lines[i]);
190             }
191             ret = new String[strList.size()];
192             strList.toArray(ret);
193         }
194         else {
195             ret = lines;
196         }
197         
198         return ret;
199     }
200     
201     private static LinkedList<String> divideStringWithMaxWidth(Paint paint, String content, 
202             int width){
203         int charLength = content.length();
204         int start = 0;
205         int tempWidth = 0;
206         LinkedList<String> strList = new LinkedList<String>();
207         
208         /*
209          * Break a String into String[] by the width & should wrap the word
210          */
211         for (int i = 1; i <= charLength; ++i){          
212             tempWidth = (int)Math.ceil(paint.measureText(content, start, i));
213             if (tempWidth >= width){
214                 int lastIndexOfSpace = content.substring(0, i).lastIndexOf(" ");
215                 
216                 if (lastIndexOfSpace != -1 && lastIndexOfSpace > start){
217                     /**
218                      * Should wrap the word
219                      */
220                     strList.add(content.substring(start, lastIndexOfSpace));
221                     i = lastIndexOfSpace;
222                 }
223                 else {
224                     /*
225                      * Should not exceed the width
226                      */
227                     if (tempWidth > width){
228                         strList.add(content.substring(start, i - 1));
229                         /*
230                          * compute from previous char
231                          */
232                         --i;
233                     }
234                     else {
235                         strList.add(content.substring(start, i));                   
236                     }
237                 }
238                                
239                 start = i;
240             }
241         }
242         
243         /*
244          * Add the last chars
245          */
246         if (start < charLength){
247             strList.add(content.substring(start));
248         }
249         
250         return strList;
251     }
252     
253     private static Paint newPaint(String fontName, int fontSize, int alignment){
254         Paint paint = new Paint();
255         paint.setColor(Color.WHITE);
256         paint.setTextSize(fontSize);      
257         paint.setAntiAlias(true);    
258         
259         /*
260          * Set type face for paint, now it support .ttf file.
261          */
262         if (fontName.endsWith(".ttf")){
263              try {
264                 //Typeface typeFace = Typeface.createFromAsset(context.getAssets(), fontName);
265                  Typeface typeFace = Cocos2dxTypefaces.get(context, fontName);
266                   paint.setTypeface(typeFace);
267              } catch (Exception e){
268                  Log.e("Cocos2dxBitmap", 
269                      "error to create ttf type face: " + fontName);
270                  
271                  /*
272                   * The file may not find, use system font
273                   */
274                  paint.setTypeface(Typeface.create(fontName, Typeface.NORMAL));
275              }
276         }
277         else {
278             paint.setTypeface(Typeface.create(fontName, Typeface.NORMAL));
279         }
280         
281         switch (alignment){
282         case ALIGNCENTER:
283             paint.setTextAlign(Align.CENTER);
284             break;
285         
286         case ALIGNLEFT:  
287             paint.setTextAlign(Align.LEFT);
288             break;
289             
290         case ALIGNRIGHT:
291             paint.setTextAlign(Align.RIGHT);
292             break;
293         
294         default:
295             paint.setTextAlign(Align.LEFT);
296             break;
297         }
298         
299         return paint;
300     }
301     
302     private static String refactorString(String str){
303         // Avoid error when content is ""
304         if (str.compareTo("") == 0){
305             return " ";
306         }
307         
308         /*
309          * If the font of "\n" is "" or "\n", insert " " in front of it.
310          * 
311          * For example:
312          * "\nabc"     -> " \nabc"
313          * "\nabc\n\n" -> " \nabc\n \n"
314          */
315         StringBuilder strBuilder = new StringBuilder(str);
316         int start = 0;
317         int index = strBuilder.indexOf("\n");
318         while (index != -1){
319             if (index == 0 || strBuilder.charAt(index -1) == '\n'){
320                 strBuilder.insert(start, " ");
321                 start = index + 2;
322             } else {
323                 start = index + 1;
324             }
325             
326             if (start > strBuilder.length() || index == strBuilder.length()){
327                 break;
328             }
329             
330             index = strBuilder.indexOf("\n", start);            
331         }
332         
333         return strBuilder.toString();
334     }
335     
336     private static void initNativeObject(Bitmap bitmap){
337         byte[] pixels = getPixels(bitmap);
338         if (pixels == null){
339             return;
340         }
341         
342         nativeInitBitmapDC(bitmap.getWidth(), bitmap.getHeight(), pixels);
343     }
344     
345     private static byte[] getPixels(Bitmap bitmap){
346         if (bitmap != null){
347             byte[] pixels = new byte[bitmap.getWidth() * bitmap.getHeight() * 4];
348             ByteBuffer buf = ByteBuffer.wrap(pixels);
349             buf.order(ByteOrder.nativeOrder());
350             bitmap.copyPixelsToBuffer(buf);
351             return pixels;
352         }
353         
354         return null;
355     }
356     
357     private static native void nativeInitBitmapDC(int width, int height, byte[] pixels);
358 }
原文地址:https://www.cnblogs.com/GameDeveloper/p/2563325.html