zoukankan      html  css  js  c++  java
  • Cocos2d-x 更改文字换行风格 ( cocos2dx change line )

    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 




  • 相关阅读:
    TI CC2541的整体目标
    TI CC2541的GPIO引脚设置.
    E2PROM与Flash的引脚图
    TI BLE CC2541的通讯协议.
    TI BLE CC2541的I2C主模式
    Charles如何抓取电脑上的请求的https数据包
    Charles如何抓取手机上的请求的https数据包
    谷歌浏览器chrome调试H5页面 如果添加cookie?
    Unity 好坑的Save Scene
    Unity 官网教程 -- Multiplayer Networking
  • 原文地址:https://www.cnblogs.com/lytwajue/p/6824258.html
Copyright © 2011-2022 走看看