注:2014年12月23日有内存/性能优化更新,内容在下面分割线后

 

搞了几个小时,这个头疼的问题,我给出代码吧。

 

找到 

libcocos2d/platform/winrt/CCFreeTypeFont.cpp

(其中libcocos2d是项目名)然后将其中的函数 addWord 替换为我提供的即可。实在找不到文件的同学直接搜索吧。

需要注意的是我只简单处理了一下,所以中文下只支持UTF8字符串,非UTF8字符串会出问题。当然英文环境下任然是用默认逻辑。

我的cocos2dx版本是 3.2,如果你的版本不是这个,存在个别差异,那就自己改改吧。

希望大家拿走代码的时候在下面评论一下,好提高我分享的积极性,你懂得。

FT_Error CCFreeTypeFont::addWord(const std::string& word) 
{
    std::vector<TGlyph> glyphs; // glyphs for the word
    FT_BBox             bbox;   // bounding box containing all of the glyphs in the word
    int maxWidth = m_inWidth ? m_inWidth : m_windowWidth;
    std::string newWord;

    if(m_currentLine->width > 0) 
    {
        newWord = ' ' + word;
    } 
    else
    {
        newWord = word;
    }

    FT_Error error = initWordGlyphs(glyphs, newWord, m_currentLine->pen);
    if(!error) 
    {
        compute_bbox(glyphs, &bbox);
        /*判断添加进去后整个line是否显示宽度大于设定宽度,是的话进行截取*/
        if (Application::getInstance()->getCurrentLanguage() == LanguageType::CHINESE && bbox.xMax > maxWidth)
        {
            std:size_t start = 0, end = word.length();
            while (true)
            {
                while (true)//这个字符比最宽还要宽,则进行截取
                {
                    end--;
                    FT_BBox validBBox = bbox;
                    std::vector<TGlyph> validGlyphs;
                    FTLineInfo validLine = FTLineInfo();
                    validLine.width = 0;
                    validLine.pen.x = 0;
                    validLine.pen.y = 0;
                    //对UTF8字符进行切割
                    if (end != word.length())
                    {
                        while (true)
                        {
                            unsigned char utf8charpart = word.at(end - 1);
                            if ((utf8charpart & 0x80) != 0 &&
                                (utf8charpart & 0xe0) != 0xc0 &&
                                (utf8charpart & 0xf0) != 0xe0 &&
                                (utf8charpart & 0xf8) != 0xf0)
                            {
                                end--;
                            }
                            else
                            {
                                end--;
                                break;
                            }
                        }
                    }
                    std::string validStr = word.substr(start, end - start);
                    FT_Error validError = initWordGlyphs(validGlyphs, validStr, validLine.pen);
                    if (validError) break;
                    compute_bbox(validGlyphs, &validBBox);
                    if (validBBox.xMax <= maxWidth)
                    {
                        m_currentLine->glyphs.insert(validLine.glyphs.end(), validGlyphs.begin(), validGlyphs.end());
                        if (m_currentLine->width == 0)
                        {
                            m_currentLine->bbox = validBBox;
                        }
                        else
                        {
                            m_currentLine->bbox.xMax = validBBox.xMax;
                        }
                        break;
                    }
                }
                start = end;
                end = word.length() + 1;
                if (start == end - 1) break;
                bbox = FT_BBox();
                endLine();
                newLine();
            }
        }
        else
        {
            if (m_currentLine->width == 0 || bbox.xMax <= maxWidth)
            {
                m_currentLine->glyphs.insert(m_currentLine->glyphs.end(), glyphs.begin(), glyphs.end());
                if (m_currentLine->width == 0)
                {
                    m_currentLine->bbox = bbox;
                }
                else
                {
                    m_currentLine->bbox.xMax = bbox.xMax;
                }
                m_currentLine->width = m_currentLine->bbox.xMax - m_currentLine->bbox.xMin;
            }
            else
            {
                endLine();
                newLine();
                addWord(word);
            }
        }
    }
    return error;
}

 ========================================快乐的分割线 ========================================

 

谢谢 @请让我过好不好  的反馈。我仔细调试后发现造成内存占用过大的原因是中途逐字符计算换行加载成的图像没有释放掉。并且算法是先计算整个字符串长度,然后逐渐从尾部减小一个字符从新计算,当小于最大宽度时候进行换行从新执行上面的计算。这种算法性能很低,因此我改为了从第一个字符开始计算,当算的字符超过一行,则使用上个字符的位置进行换行。

 

其实还有优化的空间,因为逐字符计算调用的是做事情比较多余的函数,但我没有那么多时间细扣了,下面贴出代码,与分割线之前的版本类似替换系统的 addWord 函数即可:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
FT_Error CCFreeTypeFont::addWord(const std::string& word)
{
    std::vector<TGlyph> glyphs; // glyphs for the word
    FT_BBox             bbox;   // bounding box containing all of the glyphs in the word
    int maxWidth = m_inWidth ? m_inWidth : m_windowWidth;
    std::string newWord;
 
    if(m_currentLine->width > 0)
    {
        newWord = ' ' + word;
    }
    else
    {
        newWord = word;
    }
 
    FT_Error error = initWordGlyphs(glyphs, newWord, m_currentLine->pen);
    if(!error)
    {
        compute_bbox(glyphs, &bbox);
        /*判断添加进去后整个line是否显示宽度大于设定宽度,是的话进行截取*/
        if (Application::getInstance()->getCurrentLanguage() == LanguageType::CHINESE && bbox.xMax > maxWidth)
        {
            std:size_t start = 0, end = -1, lastValidEnd = 0;
            while (true)
            {
                while (true)//这个字符比最宽还要宽,则进行截取
                {
                    end++;
                    FT_BBox validBBox = bbox;
                    std::vector<TGlyph> validGlyphs;
                    FTLineInfo validLine;
                    validLine.width = 0;
                    validLine.pen.x = 0;
                    validLine.pen.y = 0;
                    //对UTF8字符进行切割
                    while (true)
                    {
                        end++;
                        if (end == word.length()) break;
                        unsigned char utf8charpart = word.at(end);
                        if (!((utf8charpart & 0x80) != 0 &&
                            (utf8charpart & 0xe0) != 0xc0 &&
                            (utf8charpart & 0xf0) != 0xe0 &&
                            (utf8charpart & 0xf8) != 0xf0))
                        {
                            break;
                        }
                    }
                     
                    std::string validStr = word.substr(start, end - start);
                    FT_Error validError = initWordGlyphs(validGlyphs, validStr, validLine.pen);
                    if (validError) break;
                    compute_bbox(validGlyphs, &validBBox);
                    if (validBBox.xMax < maxWidth && end != word.length())
                    {
                        lastValidEnd = end;
                        for (auto glyph = validGlyphs.begin(); glyph != validGlyphs.end(); ++glyph)
                        {
                            FT_Done_Glyph(glyph->image);
                        }
                        continue;
                    }
                    else
                    {
                        std::string validStr = word.substr(start, lastValidEnd - start);
                        lastValidEnd = end;
                        FT_Error validError = initWordGlyphs(validGlyphs, validStr, validLine.pen);
                        if (validError) break;
                        compute_bbox(validGlyphs, &validBBox);
                        m_currentLine->glyphs.insert(validLine.glyphs.end(), validGlyphs.begin(), validGlyphs.end());
                        if (m_currentLine->width == 0)
                        {
                            m_currentLine->bbox = validBBox;
                        }
                        else
                        {
                            m_currentLine->bbox.xMax = validBBox.xMax;
                        }
                        break;
                    }
                }
                start = lastValidEnd;
                end = lastValidEnd;
                if (end == word.length()) break;
                FT_BBox emptybbox;
                bbox = emptybbox;
                endLine();
                newLine();
            }
        }
        else
        {
            if (m_currentLine->width == 0 || bbox.xMax <= maxWidth)
            {
                m_currentLine->glyphs.insert(m_currentLine->glyphs.end(), glyphs.begin(), glyphs.end());
                if (m_currentLine->width == 0)
                {
                    m_currentLine->bbox = bbox;
                }
                else
                {
                    m_currentLine->bbox.xMax = bbox.xMax;
                }
                m_currentLine->width = m_currentLine->bbox.xMax - m_currentLine->bbox.xMin;
            }
            else
            {
                endLine();
                newLine();
                addWord(word);
            }
        }
    }
    return error;
}

  

posted @ 2014-08-09 15:29 newcj 阅读(1253) 评论(15) 推荐(0) 编辑
摘要: 原文链接:http://blog.sina.com.cn/s/blog_4057ab6201018y4y.htmlObjective C内存管理进阶(二):理解autorelease:http://www.cnblogs.com/MobileDevelop/archive/2010/07/19/17... 阅读全文
posted @ 2014-07-17 00:38 newcj 阅读(2192) 评论(0) 推荐(0) 编辑
摘要: 原文链接:http://blog.csdn.net/five3/article/details/7181521首先来了解什么是multipart/form-data请求:根据http/1.1rfc 2616的协议规定,我们的请求方式只有OPTIONS、GET、HEAD、POST、PUT、DELETE... 阅读全文
posted @ 2014-05-23 20:42 newcj 阅读(10096) 评论(0) 推荐(0) 编辑
摘要: 为了支持C++ UrlEncode之后的字符串能够被C#所识别(windows phone 下C#只能支持UTF8与 Unicode)。所谓的 UTF8 UrlEncode 也只是宽字符串 UrlEncode,网上找的,改了小部分,贴上代码吧。#include "UrlEncode.h"#include #include #include using namespace std;namespace ConnectSDK{ namespace Utility { const wchar_t * hexenc[] = { L"%00", L"%01 阅读全文
posted @ 2014-04-04 19:12 newcj 阅读(5435) 评论(2) 推荐(0) 编辑
摘要: 由于项目原因,需要引入C++。wstring 与 string 的互转研究了一段时间,坑主要在于使用下面这种方式进行转换,中文会乱码wstring ws = L"这是一段测试文字";string s;s.assign(ws.begin(), ws.end());因此采用了下面的方法将wstring 转为 string wstring wstr = L"这是一段测试文字"; string str; int wstr_len = wstr.length(); int str_len = wstr_len * s... 阅读全文
posted @ 2014-04-04 19:05 newcj 阅读(1197) 评论(0) 推荐(0) 编辑
摘要: 已经快接近三年没有更新博客了,最近打算把博客这块从新建设起来。 由于工作原因,现在已经很久没有接触过Android了。目前工作是全力 Windows Phone,并且也已经工作一年半了,以后会陆续把之前Windows Phone 上遇到的一些技术问题记录下来。 阅读全文
posted @ 2014-04-04 18:51 newcj 阅读(228) 评论(0) 推荐(0) 编辑
摘要: 熟悉 Android 与 Linux 的开发者看到这篇弱弱的文章该会嘲笑了,不过这篇文章是写给那些还不知道的开发者的。当然如果你对此比较熟悉,又打算看下去,我会感到很高兴的。:)众所周知,Android 是基于 Linux 的,因此大家都可以想到,Android 应该可以运行 Linux 下的程序,但是该平台是采用的 ARM 的处理器,因此哪里去找一款 ARM Linux 的编译器呢?这里我向大家推荐 Sourcery G++ 这款编译器,下载地址是: http://www.codesourcery.com/sgpp/lite/arm/portal/release1803因为我的系统是 Win 阅读全文
posted @ 2011-08-14 23:02 newcj 阅读(7977) 评论(5) 推荐(3) 编辑
摘要: 之前一直搞不很明白 AndroidManifest.xml 中 activity 标签下的 intent-filter 中 data 标签的属性含义,今天认真看了 Dev Guide,又在网上查询了大量相关资料,现把 data 标签中的属性含义做一个总结。一、定义scheme, host, port, path, pathPrefix, pathPattern 是用来匹配 Intent 中的 Data Uri 的。具体规则如下: scheme://host:port/path or pathPrefix or pathPattern这里需要注意的是这里的scheme不是 schema,也许你记 阅读全文
posted @ 2011-08-11 17:00 newcj 阅读(18153) 评论(4) 推荐(8) 编辑
摘要: 转自:http://www.cnblogs.com/Rooty/archive/2011/07/16/2107962.html一、MIME TYPE描述多用途互联网邮件扩展(MIME,Multipurpose Internet Mail Extensions)是一个互联网标准,它扩展了电子邮件标准,使其能够支持非ASCII字符、二进制格式附件等多种格式的邮件消息。内容类型(Content-Type),这个头部领域用于指定消息的类型。一般以下面的形式出现。[type]/[subtype]type有下面的形式。Text:用于标准化地表示的文本信息,文本消息可以是多种字符集和或者多种格式的;Mult 阅读全文
posted @ 2011-08-10 23:16 newcj 阅读(28222) 评论(0) 推荐(2) 编辑
摘要: dip: device independent pixels(设备独立像素). 不同设备有不同的显示效果,这个和设备硬件有关,一般我们为了支持WVGA、HVGA和QVGA 推荐使用这个,不依赖像素。px: pixels(像素). 不同设备显示效果相同,一般我们HVGA代表320x480像素,这个用的比较多。pt: point,是一个标准的长度单位,1pt=1/72英寸,用于印刷业,非常简单易用;sp: scaled pixels(放大像素). 主要用于字体显示best for textsize。由此,根据 google 的建议,TextView 的字号最好使用 sp 做单位,而且查看TextV 阅读全文
posted @ 2011-07-29 13:57 newcj 阅读(1116) 评论(0) 推荐(1) 编辑
点击右上角即可分享
微信分享提示