• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            l

            成都手游碼農(nóng)一枚
            隨筆 - 32, 文章 - 0, 評(píng)論 - 117, 引用 - 0
            數(shù)據(jù)加載中……

            [cocos2d-x] RichText 雜記二。

            廢話不多說(shuō),先上成果圖。




            目前完成了基本的簡(jiǎn)析功能,還差圖片,表情以及動(dòng)畫(huà)的部分,以及后期優(yōu)化工作,最最后的代碼整理。- -。

            接下來(lái)就分享下整個(gè)實(shí)現(xiàn):
            1.繪制采用freetype庫(kù)實(shí)現(xiàn),支持加粗,斜體,漸變(這個(gè)自己算下就可以了)以及描邊,其中描邊估計(jì)是最麻煩的,其它都很簡(jiǎn)單,網(wǎng)上也有很多實(shí)現(xiàn)方式,這里我就主要說(shuō)說(shuō)描邊了,
              描邊方式也很多,但是大多效果都不太好,所以最后還是決定用freetype api來(lái)實(shí)現(xiàn)而不用自己去處理,整個(gè)實(shí)現(xiàn)可以參考:http://blog.sina.com.cn/s/blog_69a2aeff0100ol7e.html

              1 bool Font::border(Word& word, unsigned int color1, unsigned int color2, unsigned int border)
              2 {
              3     if (!ok())
              4     {
              5         return false;
              6     }
              7 
              8     FT_Face face  = m_size->face;
              9 
             10     FT_UInt index = FT_Get_Char_Index(face, FT_ULong(word.m_code));
             11     if (!index)
             12     {
             13         return false;
             14     }
             15 
             16     if (FT_Load_Glyph(face, index, FT_LOAD_NO_BITMAP))
             17     {
             18         return false;
             19     }
             20 
             21     FT_Glyph glyph;
             22     if (FT_Get_Glyph(face->glyph, &glyph))
             23     {
             24         return false;
             25     }
             26 
             27     FT_Stroker stroker;
             28     if (FT_Stroker_New(s_library, &stroker))
             29     {
             30         return false;
             31     }
             32 
             33     FT_Stroker_Set(stroker, (int)(border * 64), FT_STROKER_LINECAP_ROUND,  FT_STROKER_LINEJOIN_ROUND, 0);
             34 
             35     if (FT_Glyph_StrokeBorder(&glyph, stroker, 0, 1))
             36     {
             37         return false;
             38     }
             39 
             40     FT_Outline *outline = &reinterpret_cast<FT_OutlineGlyph>(glyph)->outline;
             41 
             42     FT_BBox bbox;
             43     FT_Glyph_Get_CBox(glyph, FT_GLYPH_BBOX_GRIDFIT, &bbox);
             44 
             45     int width = (bbox.xMax - bbox.xMin) >> 6;
             46     int rows  = (bbox.yMax - bbox.yMin) >> 6;
             47 
             48     FT_Bitmap *bitmap = &face->glyph->bitmap; 
             49 
             50     word.m_width    = width;
             51     word.m_height   = rows;
             52     word.m_drawX    = face->glyph->metrics.horiBearingX >> 6;
             53     word.m_drawY    = face->glyph->metrics.horiBearingY >> 6;
             54     word.m_advanceX = face->glyph->metrics.horiAdvance  >> 6;
             55     word.m_buffer = new unsigned char[word.m_width * word.m_height * 4];
             56     memset(word.m_buffer, 0, word.m_width * word.m_height * 4);
             57 
             58     unsigned char* buffer = word.m_buffer;
             59         
             60     FT_Raster_Params params;
             61     FT_Bitmap bmp;
             62 
             63     bmp.buffer = new unsigned char[width * rows];
             64     memset(bmp.buffer, 0, width * rows);
             65     bmp.width       = width;
             66     bmp.rows        = rows;
             67     bmp.pitch       = width;
             68     bmp.pixel_mode  = FT_PIXEL_MODE_GRAY;
             69     bmp.num_grays   = 256;
             70 
             71     memset(&params, 0, sizeof (params));
             72     params.source   = outline;
             73     params.target   = &bmp;
             74     params.flags    = FT_RASTER_FLAG_AA;
             75     FT_Outline_Translate(outline,-bbox.xMin,-bbox.yMin);
             76     FT_Outline_Render(s_library, outline, &params);
             77     unsigned char* buffer1 = bmp.buffer;
             78         
             79     FT_BBox bbox_in;
             80     FT_Glyph glyph_fg;
             81     FT_Get_Glyph(face->glyph, &glyph_fg);
             82     FT_Glyph_Get_CBox(glyph_fg, FT_GLYPH_BBOX_GRIDFIT,&bbox_in);
             83 
             84     bmp.buffer = new unsigned char[width * rows];
             85     memset(bmp.buffer, 0, width * rows);
             86     bmp.width       = width;
             87     bmp.rows        = rows;
             88     bmp.pitch       = width;
             89     bmp.pixel_mode  = FT_PIXEL_MODE_GRAY;
             90     bmp.num_grays   = 256;
             91     outline = &reinterpret_cast<FT_OutlineGlyph>(glyph_fg)->outline;
             92     memset(&params, 0, sizeof (params));
             93     params.source   = outline;
             94     params.target   = &bmp;
             95     params.flags = FT_RASTER_FLAG_AA;
             96     FT_Outline_Translate(outline,-bbox.xMin,-bbox.yMin);
             97     FT_Outline_Render(s_library, outline, &params);
             98     unsigned char* buffer2 = bmp.buffer;
             99 
            100     int pitch = width;
            101     for (int yy = 0; yy < rows; ++yy)
            102     {
            103         for (int xx = 0; xx < width; ++xx)
            104         {
            105             int si = yy * word.m_width * 4 + xx * 4;
            106             int alpha1 = buffer1[yy * pitch + xx];
            107 
            108             unsigned char sr = (color1 & 0xFF0000) >> 16,
            109                           sg = (color1 & 0xFF00  ) >> 8,
            110                           sb = (color1 & 0xFF    );
            111 
            112             unsigned char dr = (color2 & 0xFF0000) >> 16,
            113                           dg = (color2 & 0xFF00  ) >> 8,
            114                           db = (color2 & 0xFF    );
            115 
            116             if (alpha1)
            117             {
            118                 buffer[si + 0] = dr;
            119                 buffer[si + 1] = dg;
            120                 buffer[si + 2] = db;
            121                 buffer[si + 3] =  alpha1;
            122             }
            123 
            124             int alpha2 = buffer2[yy * pitch + xx];
            125             if (alpha2)
            126             {
            127                 buffer[si + 0] = dr + ( sr - dr) * alpha2 / 255.0f;
            128                 buffer[si + 1] = dg + ( sg - dg) * alpha2 / 255.0f;
            129                 buffer[si + 2] = db + ( sb - db) * alpha2 / 255.0f;
            130                 buffer[si + 3] =  min(255, alpha1 + alpha2);
            131             }
            132         }
            133     }
            134 
            135     delete [] buffer1;
            136     delete [] buffer2;
            137 
            138     FT_Stroker_Done(stroker);
            139 
            140     return true;
            141 }

            2.字體緩存,緩存可以參考 FTC_Manager 緩存子系統(tǒng),可以參看 ft_cache.h 的說(shuō)明。

            3.布局,目前我的布局方案:
            IElement 接口:用于獲取每個(gè)元素的大小,以及保存元素的位置信息,后面可以用于處理 Hittest。
            ElementCollection :具體說(shuō)來(lái)就是一行,由多個(gè) Element 組成,繪制前線設(shè)置x,y值,然后調(diào)用本身layout函數(shù)來(lái)布局,最后父節(jié)點(diǎn)可以獲取高度和寬度用于計(jì)算。
            RowCollection :由多個(gè)ElementCollection構(gòu)成,主要用于緩存所有結(jié)點(diǎn)信息,提供layout接口后計(jì)算出整個(gè)布局的包圍盒,然后生成紋理在繪制。
            RichDoc : 內(nèi)部有一個(gè) RowCollection,主要用于將字符串轉(zhuǎn)換成IElement,并處理?yè)Q行等。
            TextElement :文本元素,如果是漢字就一個(gè)字對(duì)應(yīng)一個(gè)TextElement,單詞則由多個(gè)構(gòu)成,這樣方便布局。
            后期可能還有 ImageElement 等等。

            補(bǔ)充:ElementCollection 中元素,即通常的一行,如果未滿行而剩余空間又小于一個(gè)固定值,我這里大概設(shè)置的30,那么就應(yīng)該吧這30的空隙填充到每個(gè)元素之間,這樣布局出來(lái)的效果行尾基本都是對(duì)齊的,如果空隙太大就不應(yīng)該插入。

            4.字符串簡(jiǎn)析
            這個(gè)看自己的愛(ài)好,可以自由發(fā)揮,這里貼出效果圖的布局文本。

            #{effect="border" color1="ffffff"}#{effect="border" color1="ff0000"}英文原文:Developer Hacks His Microwave Into The Microwave Of The Future#{}

            普通的#{effect="italic" color1="ff00ff" value="25"}家用微波爐#{}可以說(shuō)是非常不智能的產(chǎn)品,買回來(lái)不僅時(shí)間需要人工設(shè)定,使用過(guò)程中,我們也很少會(huì)根據(jù)事物的不同,選擇對(duì)應(yīng)的設(shè)置,只要能熱食物就行。

            所以,當(dāng)我看到開(kāi)發(fā)者 Nathan Broadbent 跟他的微波爐說(shuō)話,語(yǔ)音控制微波爐,并且能夠自動(dòng)設(shè)置時(shí)間,甚至,你只需要掃描一下產(chǎn)品的條形碼,微波爐便能自動(dòng)識(shí)別對(duì)應(yīng)的模式以及分鐘數(shù)時(shí),我感覺(jué)我快要窒息了。

            這款微波爐被命名為 #{effect="border" color1="00ff00"}"Raspberry Picrowave"#{},顧名思義,是一臺(tái)同樹(shù)莓派相連的微波爐設(shè)備。

            經(jīng)過(guò)調(diào)試之后,這款微波爐具備以下功能:

                    #{effect="gradient" color1="220022" color2="ff0000"}通過(guò)網(wǎng)絡(luò),自動(dòng)調(diào)節(jié)時(shí)間。#{}
                    #{effect="gradient" color1="220022" color2="ff0000"}通過(guò)將對(duì)應(yīng)食物的數(shù)據(jù)錄入自建的在線數(shù)據(jù)庫(kù),只需掃描條形碼,微波爐便會(huì)自動(dòng)開(kāi)始運(yùn)作。#{}
                    #{effect="gradient" color1="220022" color2="ff0000"}可自定義聲效。#{}
                你可以使用手機(jī)或者 #{effect="bold" color1="00ffff"}iPad#{} 來(lái)控制微波爐。適用場(chǎng)景包括:你可以提前放置食物,然后通過(guò)手機(jī)等設(shè)備來(lái)操控微波爐,或者你也可以用這項(xiàng)功能嚇嚇你的小伙伴。
            當(dāng)食物熱好之后,它還能發(fā)推!
            讓微波爐更加智能化,本該是大型的微波爐廠商自己該做的事情,但市面上一直沒(méi)有智能和人性化的微波爐出現(xiàn),直到今天,我們?nèi)诵枰斯ぴO(shè)置時(shí)間. 好的是,相信這款 Raspberry Picrowave 的出現(xiàn),可能會(huì)推動(dòng)微波爐智能化的進(jìn)程,將物聯(lián)網(wǎng)的生活往前又推進(jìn)了一步,不過(guò)這款微波爐只是極客們自己的玩具,并沒(méi)有量產(chǎn),普及到普通消費(fèi)者的家中還需要一段時(shí)間。#{}

            PS:附帶一張真機(jī)測(cè)試圖,沒(méi)想象中感覺(jué)好。
            PS:造成失真是猶豫界面被拉伸導(dǎo)致,所以如果不拉升,效果還是一樣的。

            posted on 2013-07-14 16:57 l1989 閱讀(9129) 評(píng)論(19)  編輯 收藏 引用 所屬分類: C++游戲

            評(píng)論

            # re: [cocos2d-x] RichText 雜記二。  回復(fù)  更多評(píng)論   

            不錯(cuò)。希望能看到成品。
            2013-07-14 19:51 | 小笨象

            # re: [cocos2d-x] RichText 雜記二。  回復(fù)  更多評(píng)論   

            挺不錯(cuò), 謝謝博主分享
            2013-07-14 23:30 | weibo

            # re: [cocos2d-x] RichText 雜記二。  回復(fù)  更多評(píng)論   

            東西很好,可是具體調(diào)用該怎么用?我調(diào)用了沒(méi)顯示。Word那個(gè)struct 應(yīng)該怎么填充,怎么顯示在cocos2d-x的層上。厚顏討教。
            2013-07-15 21:10 | alsky

            # re: [cocos2d-x] RichText 雜記二。  回復(fù)  更多評(píng)論   

            @alsky
            class Word
            {
            public:
            Word(unsigned long code);
            ~Word();

            unsigned long m_code; // 字符 unicode 編碼
            int m_height; // 字符高度
            int m_width; // 字符寬度
            int m_drawX; // 字符繪制的水平偏移
            int m_drawY; // 字符繪制基線上方偏移
            int m_advanceX; // 字符步進(jìn)
            unsigned char* m_buffer; // 字符像素信息緩存
            };

            轉(zhuǎn)換為 CCSprite
            CCTexture2D* texture = new CCTexture2D();
            if (!texture->initWithData(m_paBuffer, kCCTexture2DPixelFormat_RGBA8888,
            m_nWidth, m_nHeight, CCSizeMake(m_nWidth, m_nHeight)))
            {
            return NULL;
            }
            return CCSprite::createWithTexture(texture);
            2013-07-15 21:38 | AZL

            # re: [cocos2d-x] RichText 雜記二。  回復(fù)  更多評(píng)論   

            @AZL
            感謝指導(dǎo)!!
            關(guān)于 texture->initWithData(m_paBuffer, kCCText
            m_paBuffer是什么?
            是不是 運(yùn)行了
            border(*wordp,0xcccccc,0xdd2211,2);函數(shù)以后的
            wordp->m_buffer ?

            我這樣做了以后,出來(lái)了一個(gè)白色圖塊,對(duì)顏色什么修改都沒(méi)反應(yīng)。
            我理解的border這個(gè)函數(shù),你最后要用的是 wordp-》m_buffer
            不知道理解錯(cuò)了沒(méi)有。
            2013-07-15 23:43 | alsky

            # re: [cocos2d-x] RichText 雜記二。  回復(fù)  更多評(píng)論   

            @alsky
            差不多吧,你可以把多個(gè)word的像素緩存考到一個(gè)大的位圖結(jié)構(gòu)(RGBA),然后直接initWithData初始紋理。
            2013-07-16 09:02 | AZL

            # re: [cocos2d-x] RichText 雜記二。  回復(fù)  更多評(píng)論   

            @AZL
            謝謝,
            當(dāng)我加了句
            FT_Set_Char_Size(face,48<<6,48<<6, 76 , 76);
            以后成功了,
            但是這個(gè)很怪異,這個(gè)76換成別的都不行,我也不知道為什么一定要是76,
            這個(gè)應(yīng)該是分辨率的,但是我不知道這個(gè)應(yīng)該從哪里取。
            不知道你那時(shí)是怎樣解決的,請(qǐng)一定指教啊
            2013-07-16 16:07 | alsky

            # re: [cocos2d-x] RichText 雜記二。  回復(fù)  更多評(píng)論   

            調(diào)用:
            Word *wordp = new Word(L'中');
            says->border(*wordp,0xcccccc,0x12cccc,2);

            函數(shù):
            bool Says::border(Word& word, unsigned int color1, unsigned int color2, unsigned int border)
            {

            FT_Library m_library;

            FT_Face face;// = m_size->face;

            //打開(kāi)字庫(kù)文件,創(chuàng)建一個(gè)字體
            FT_Init_FreeType(&m_library);
            FT_New_Face(m_library,"C:\\WINDOWS\\Fonts\\msyh.ttf",0,&face);


            FT_UInt index = FT_Get_Char_Index(face,word.m_code);
            if (!index)
            {
            return false;
            }

            FT_Set_Char_Size(face,48<<6,48<<6,76,76);
            。。。
            }后面完全一樣省略

            我現(xiàn)在的效果是 改變分辨率,76,76那里可以看到‘中’字,如果要看到‘國(guó)’字,又要把分辨率調(diào)成75,75,要看到英文字母又要改變。。。
            我都要抓狂了。應(yīng)該不是改分辨率那里啊。。。
            2013-07-16 21:53 | alsky

            # re: [cocos2d-x] RichText 雜記二。  回復(fù)  更多評(píng)論   

            @alsky
            還有,word里面的m_code
            我用的wchar ,沒(méi)有用//unsigned long
            2013-07-16 21:55 | alsky

            # re: [cocos2d-x] RichText 雜記二。  回復(fù)  更多評(píng)論   

            !我找到原因了,是我
            initWithData(wordp->m_buffer, kCCTexture2DPixelFormat_RGBA8888,
            m_nWidth, m_nHeight, CCSizeMake(m_nWidth, m_nHeight)))
            時(shí),m_nWidth,和高指定死了,應(yīng)該去讀自高就對(duì)了,真是毫無(wú)技術(shù)含量的問(wèn)題,浪費(fèi)大大時(shí)間了。

            謝謝大大了。

            最后,我想看大大寫(xiě)個(gè) freetype 逐字顯示的 教程。。。
            2013-07-16 22:09 | alsky

            # re: [cocos2d-x] RichText 雜記二。  回復(fù)  更多評(píng)論   

            很不錯(cuò)的 謝謝分享
            2013-07-17 16:45 | tb

            # re: [cocos2d-x] RichText 雜記二。  回復(fù)  更多評(píng)論   

            如果彩色的文本遇到換行,是自動(dòng)換行還是手動(dòng)編輯?
            看這里好像是要手動(dòng)換行
            #{effect="gradient" color1="220022" color2="ff0000"}通過(guò)將對(duì)應(yīng)食物的數(shù)據(jù)錄入自建的在線數(shù)據(jù)庫(kù),只需掃描條形碼,微波爐便會(huì)自動(dòng)開(kāi)始運(yùn)作。#{}
            #{effect="gradient" color1="220022" color2="ff0000"}可自定義聲效。#{}
            2013-08-12 11:33 | abao2000

            # re: [cocos2d-x] RichText 雜記二。  回復(fù)  更多評(píng)論   

            你好能給個(gè)工程下載的么?
            2013-09-09 18:39 | CQC

            # re: [cocos2d-x] RichText 雜記二。  回復(fù)  更多評(píng)論   

            很好,支持一下。 希望博主早日完成
            2013-10-07 18:01 | hzt

            # re: [cocos2d-x] RichText 雜記二。  回復(fù)  更多評(píng)論   

            樓主,能分享一下代碼嗎
            2013-12-05 23:53 | Damein

            # re: [cocos2d-x] RichText 雜記二。  回復(fù)  更多評(píng)論   

            LZ 我在cocos2d-x 2.x里面加的freetype 渲染的字體 有的對(duì)有的不對(duì) 這是什么原因
            2015-07-06 10:36 | u_tansuo

            # re: [cocos2d-x] RichText 雜記二。  回復(fù)  更多評(píng)論   

            @alsky
            我的跟你的情況差不多 不同字號(hào) 同一句話 渲染出來(lái)有的字符就是錯(cuò)的??

            FT_Set_Char_Size(face,48<<6,48<<6,76,76)改變后兩個(gè)參數(shù) ,渲染出來(lái)的效果也變化,有的字符正常 有的字符錯(cuò)誤 http://www.cocoachina.com/bbs/read.php?tid-309167.html 這是效果
            2015-07-06 10:55 | u_tansuo

            # re: [cocos2d-x] RichText 雜記二。[未登錄](méi)  回復(fù)  更多評(píng)論   

            樓主, FT_Stroker_Set(stroker, (int)(border * 64), FT_STROKER_LINECAP_ROUND, FT_STROKER_LINEJOIN_ROUND, 0)中border的初始值是多少?
            2015-11-24 11:43 | 天涯

            # re: [cocos2d-x] RichText 雜記二。[未登錄](méi)  回復(fù)  更多評(píng)論   

            能說(shuō)說(shuō)buffer1與buffer2的區(qū)別嗎?謝謝
            2015-11-27 10:37 | 天涯
            欧美精品国产综合久久| 国产免费久久精品99久久| 国内精品久久久久久野外| 国产精品免费久久久久影院| 亚洲AV日韩AV永久无码久久| 爱做久久久久久| 久久久久99精品成人片欧美| 久久99精品久久久久久不卡| 91精品国产9l久久久久| 性做久久久久久久| 国产精品99久久不卡| 国产午夜免费高清久久影院 | 99久久精品国产综合一区| 久久久国产99久久国产一| 伊人久久大香线蕉精品| 一本色综合网久久| 午夜精品久久久久久| 国产精品永久久久久久久久久 | 国产99久久久久久免费看| 久久热这里只有精品在线观看| 国产亚州精品女人久久久久久| 国色天香久久久久久久小说| 深夜久久AAAAA级毛片免费看| 大香网伊人久久综合网2020| 久久被窝电影亚洲爽爽爽| 久久99精品久久久久子伦| 97久久婷婷五月综合色d啪蜜芽| 久久综合色老色| 久久综合偷偷噜噜噜色| 无码人妻久久一区二区三区蜜桃 | 久久久久av无码免费网| 18禁黄久久久AAA片| 久久久一本精品99久久精品88| 无码任你躁久久久久久老妇App| 人妻无码精品久久亚瑟影视| 伊人久久精品影院| 狠狠综合久久综合88亚洲| 99精品国产综合久久久久五月天| 亚洲欧美日韩中文久久| 成人综合伊人五月婷久久| 精品久久一区二区三区|