1. 程式人生 > >Cocos2d-x 更改文字換行風格 ( cocos2dx change line )

Cocos2d-x 更改文字換行風格 ( cocos2dx change line )

pad 限制長度 != inline detail _id 興趣研究 end sans

Cocos2dx change line

在 cocos2dx change line 的實現中,我們能夠簡單的使用 dimensions屬性控制換行。使用它僅僅需將相應的參數值傳入構造函數,或者調用 setDimensions 函數就可以。

它的換行策略是:當一個單詞超出限制長度時。將它移動到下一行。

有時這樣的策略並不合適。

比如。在某些語言中,單詞都比較長。

假設採用這樣的策略。會出現每一行中僅僅有一個單詞。

因此須要更改換行策略。當超出限制長度時,使用 - 作為一個分隔單詞的標誌。

技術分享

換行策略調用

通過查看Cocos2d-x中換行的實現方式,我發現換行策略是區分平臺編程出來的代碼。

也就是說。為了更改換行策略,我須要分別編寫 IOS 和 Java 兩部分代碼。

由於我的目標平臺是 Android 平臺,因此我僅僅對Java文件進行了更改。IOS 平臺的換行策略調用的是系統函數,有興趣研究的讀者能夠跟蹤源代碼更改。入口函數為:

bool CCTexture2D::initWithString(const char *text, ccFontDefinition *textDefinition)
{
    ......
 
    CCImage* pImage = new CCImage();
    do
    {
        CC_BREAK_IF(NULL == pImage);
        
        bRet = pImage->initWithStringShadowStroke(text,
                                                  (int)textDefinition->m_dimensions.width,
                                                  (int)textDefinition->m_dimensions.height,
                                                  eAlign,
                                                  textDefinition->m_fontName.c_str(),
                                                  textDefinition->m_fontSize,
                                                  textDefinition->m_fontFillColor.r / 255,
                                                  textDefinition->m_fontFillColor.g / 255,
                                                  textDefinition->m_fontFillColor.b / 255,
                                                  shadowEnabled,
                                                  shadowDX,
                                                  shadowDY,
                                                  shadowOpacity,
                                                  shadowBlur,
                                                  strokeEnabled,
                                                  strokeColorR,
                                                  strokeColorG,
                                                  strokeColorB,
                                                  strokeSize);
        
        
        CC_BREAK_IF(!bRet);
        bRet = initWithImage(pImage);
        
    } while (0);
    
    ......
}

更改Java實現

Android 平臺相應的 Java 文件位於 $(2DX-Root)/cocos2dx/platform/android/java/src/org/cocos2dx/lib 目錄中。文件名稱是 Cocos2dxBitmap.java

首先,我添加了 divideStringWithMaxWidthByFlag 函數。將它作為還有一個換行策略的實現函數。

// add by fansy for "—" style words
    private static LinkedList<String> divideStringWithMaxWidthByFlag(
           final String pString, final int pMaxWidth, final Paint pPaint) {
        final int charLength = pString.length();
        int start = 0;
        int tempWidth = 0;
        LinkedList<String> strList = new LinkedList<String>();
        
        if( !isChinese(pString) )
        {
            /* Break a String into String[] by the width & should wrap the word. */
            for (int i = 1; i < charLength-1; ++i) {
                tempWidth = (int) FloatMath.ceil(pPaint.measureText(pString, start,i+1));
                if (tempWidth >= pMaxWidth) {
                    if(pString.charAt(i) == ‘ ‘) //end with " "
                    {
                        //change line at i
                        strList.add(pString.substring(start, i));
                        i = i + 1; // skip space
                    }
                    else if(i>1 && pString.charAt(i-2) == ‘ ‘) //only one "-" left after change line
                    {
                        //change line at i-2
                        strList.add(pString.substring(start, i-2));
                        i = i -2; // skip space
                    }
                    else if(i>0 && pString.charAt(i-1) == ‘ ‘) //only one "-" left after change line
                    {
                        //change line at i-1
                        strList.add(pString.substring(start, i-1));
                        i = i -1; // skip space
                    }
                    else if(i>0) //replace "-" at i-2
                    {
                        //split at i-1 add "-" at tail change line at i-1
                        strList.add(pString.substring(start, i-1)+"-");
                        i--;
                    }
                    
                    /* Remove spaces at the beginning of a new line. */
                    while (pString.charAt(i) == ‘ ‘) {
                        ++i;
                    }
                    
                    start = i;
                }
            }
            
            /* Add the last chars. */
            if (start < charLength) {
                strList.add(pString.substring(start));
            }
        }
        else
        {
            strList = divideStringWithMaxWidth(pString, pMaxWidth, pPaint);
        }
        return strList;
    }
    
    // 依據Unicode編碼完美的推斷中文漢字和符號
    private static boolean isChinese(char c) {
        Character.UnicodeBlock ub = Character.UnicodeBlock.of(c);
        if (ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS
            || ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS
            || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A
            || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B
            || ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION
            || ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS
            || ub == Character.UnicodeBlock.GENERAL_PUNCTUATION) {
            return true;
        }
        return false;
    }
    
    // 完整的推斷中文漢字和符號
    public static boolean isChinese(String strName) {
        char[] ch = strName.toCharArray();
        for (int i = 0; i < ch.length; i++) {
            char c = ch[i];
            if (isChinese(c)) {
                return true;
            }
        }
        return false;
    }
    
 //end add by fansy

添加函數之後。改動在 splitString 中的調用:

private static String[] splitString(final String pString,
            final int pMaxWidth, final int pMaxHeight, final Paint pPaint) {
        final String[] lines = pString.split("\\n");
        String[] ret = null;
        final FontMetricsInt fm = pPaint.getFontMetricsInt();
        final int heightPerLine = (int) Math.ceil(fm.bottom - fm.top);
        final int maxLines = pMaxHeight / heightPerLine;
 
        if (pMaxWidth != 0) {
            final LinkedList<String> strList = new LinkedList<String>();
            for (final String line : lines) {
                /*
                 * The width of line is exceed maxWidth, should divide it into
                 * two or more lines.
                 */
                final int lineWidth = (int) FloatMath.ceil(pPaint
                        .measureText(line));
                if (lineWidth > pMaxWidth) {
                    strList.addAll(Cocos2dxBitmap.divideStringWithMaxWidthByFlag(
                            line, pMaxWidth, pPaint));
                } else {
                    strList.add(line);
        ......
}

更換調用函數後,編譯打包。執行程序就可以看到不同的換行效果。


本篇博客出自阿修羅道,轉載請註明出處,禁止用於商業用途:http://blog.csdn.net/fansongy/article/details/39992241




Cocos2d-x 更改文字換行風格 ( cocos2dx change line )