quick cocos2dx lua:自定義RichText,可以解析font、br和img標籤

環境:node

一、Quick-Cocos2dx-Community_3.6.1_release字體

二、quick engine 移植了cocos2dx V3.10版的 RichText 的換行元素: RichElementNewLineui

 

刪節版代碼以下lua

  1 local RichText = class("RichText", function ()
  2     return ccui.RichText:create()
  3 end)
  4 
  5 local NORMAL_TEXT = 0
  6 
  7 -- 目前支持的標籤訂義, 從1開始且連續
  8 local FONT_COMPONENT = 1     -- 不一樣顏色
  9 local NEW_LINE_COMPONENT = 2 -- 換行<br>
local IMG_COMPONENT = 3 -- 圖片
10 11 -- 12 -- ******** color要定義在font.lua裏 ************* 13 -- 示例: <font color = DARK_GOLDEN size = 28>金色的字體</font> 14 -- 15 local COMPONENT_CONFIG = { 14 17 [FONT_COMPONENT] = { 18 ["all"] = "<%s-font.->.-</%s-font%s->", 19 ["color"] = "color%s-=%s-([%a_]+)%s-", 20 ["size"] = "size%s-=%s-(%d+)%s-", 21 ["content"] = "<%s-font.->(.*)</%s-font%s->", 22 }, 23 24 [NEW_LINE_COMPONENT] = { 25 ["all"] = "<%s-[bB][rR]%s->", 26 },

          -- <img src = "base_icon.png" width=10 height=10 />
         [IMG_COMPONENT] = {
             ["all"] = "<%s-img%s-src%s-=.-/%s->",
             ["src"] = "src%s-=%s-[\"'](.-)[\"']%s-",
             ["width"] = "width%s-=%s-[\"']*(%d+)[\"']*%s-",
             ["height"] = "height%s-=%s-[\"']*(%d+)[\"']*%s-",
         },spa

 27 }
 28 
 29 --------------------------------------------------------------------------------------------
 30 -- BEGIN
 31 --------------------------------------------------------------------------------------------
 32 function RichText:ctor( params )
 33         params = params or {}
 34         self.m_components = {}
 35         self.m_color      = params.color
 36         self.m_size       = params.size
 37 end
 38 
 39 function RichText:setText( _content )
 40     self.m_content    = _content
 41 
 42     self:update()
 43 end
 44 
 45 function RichText:update( ... )
 46     local PATTERN_CONFIG = COMPONENT_CONFIG
 47     self.m_components = {}
 48     
 49     local totalLen = string.len( self.m_content )
 50     local st = 0
 51     local en = 0
 52 
 53     -- 根據配置,在原串中找出全部標記的文本
 54     for i = 1, #PATTERN_CONFIG, 1 do
 55         st = 0
 56         en = 0
 57 
 58         while true do
 59             st, en = string.find( self.m_content, PATTERN_CONFIG[i]["all"], st + 1 )
 60             if not st then
 61                 break
 62             end
 63             local comp = {}
 64             comp.sIdx = st
 65             comp.eIdx = en
 66             comp.type = i
 67             comp.text = string.sub( self.m_content, comp.sIdx, comp.eIdx )
 68 
 69             table.insert( self.m_components, comp )
 70             st = en
 71         end
 72     end
 73 
 74     local function sortFunc( a, b )
 75         return a.sIdx < b.sIdx
 76     end
 77     table.sort( self.m_components, sortFunc )
 78 
 79     if #self.m_components <= 0 then
 80         -- 所有都是普通文本
 81         local comp = {}
 82         comp.sIdx = 1
 83         comp.eidx = totalLen
 84         comp.type = NORMAL_TEXT
 85         comp.text = self.m_content
 86         table.insert( self.m_components, comp )
 87     else
 88         local offset = 1
 89         local newComponents = {}
 90 
 91         for i = 1, #self.m_components, 1 do
 92             local comp = self.m_components[ i ]
 93             table.insert( newComponents, comp )
 94 
 95             if comp.sIdx > offset then
 96                 local newComp = {}
 97                 newComp.sIdx = offset
 98                 newComp.eIdx = comp.sIdx - 1
 99                 newComp.type = NORMAL_TEXT
100                 newComp.text = string.sub( self.m_content, newComp.sIdx, newComp.eIdx )
101 
102                 table.insert( newComponents, newComp )
103             end
104 
105             offset = comp.eIdx + 1
106         end
107 
108         if offset < totalLen then
109             local newComp = {}
110             newComp.sIdx = offset
111             newComp.eIdx = totalLen
112             newComp.type = NORMAL_TEXT
113             newComp.text = string.sub( self.m_content, newComp.sIdx, newComp.eIdx )
114 
115             table.insert( newComponents, newComp )
116         end
117 
118         self.m_components = newComponents
119     end
120 
121     table.sort( self.m_components, sortFunc )
122 
123     self:render()
124 
125     self:formatText()
126 end
127 
128 function RichText:render( ... )
129     
130     for i = 1, #self.m_components, 1 do
131         local comp = self.m_components[i]
132         local text = comp.text
133 
134         if comp.type == NORMAL_TEXT then
135             self:handleNormalTextRender( text )
136         elseif comp.type == FONT_COMPONENT then
137             self:handleFontTextRender( text )
138         elseif comp.type == NEW_LINE_COMPONENT then
139             self:handleNewLineRender()

              elseif comp.type == IMG_COMPONENT then
                  self:handleImgRender( text )code

140         end
141     end
142 end
143 
144 function RichText:handleNormalTextRender( _text )
145     local color = self.m_color
146 
147     local element = ccui.RichElementText:create(1, color, 255, _text or "", display.DEFAULT_TTF_FONT, self.m_size)
148     self:pushBackElement( element )
149 end
150 
151 function RichText:handleFontTextRender( _text )
152     local content = ""
153     local color = self.m_special_color
154     local size  = self.m_size
155 
156     content = string.match( _text, COMPONENT_CONFIG[ FONT_COMPONENT ]["content"] )
157     color = string.match( _text, COMPONENT_CONFIG[ FONT_COMPONENT ]["color"] )
158     size = string.match( _text, COMPONENT_CONFIG[ FONT_COMPONENT ]["size"] )
159 
160     local element = ccui.RichElementText:create(1, color, 255, content, display.DEFAULT_TTF_FONT, size)
161     self:pushBackElement( element )
162 end
163 
164 function RichText:handleNewLineRender( ... )
165     local element = ccui.RichElementNewLine:create(1, self.m_color, 255)
166     self:pushBackElement( element )
167 end

      function RichText:handleImgRender( _text )
          local src = string.match( _text, COMPONENT_CONFIG[ IMG_COMPONENT ][ "src" ] )
          local width = string.match( _text, COMPONENT_CONFIG[ IMG_COMPONENT ][ "width" ] )
          local height = string.match( _text, COMPONENT_CONFIG[ IMG_COMPONENT ][ "height" ] )component

 
 

          -- print( ">>>> handleImgRender: " .. src .. ", w: " .. (width or "") .. ", h: " .. (height or "") )orm

 
 

          if src and width and height then
              local node = display.newNode()
              display.newSprite(src)
                  :setAnchorPoint(cc.p(0.5,0.5))
                  :pos(width/2, height/2)
                  :addTo(node)
              node:setContentSize( cc.size(width + 5, height) )blog

 
 

              local element = ccui.RichElementCustomNode:create( 1, self.m_color, 255, node )
              self:pushBackElement( element )
          end
       end圖片


168 169 return RichText

 

使用示例:

    self._richText = CustomRichText.new()
    self._richText:ignoreContentAdaptWithSize( false )
    self._richText:setContentSize( cc.size(500, 0) )
    self._richText:setAnchorPoint(cc.p(0,0.5))
    self._richText:setVerticalSpace( 5 )
    self:addChild( self._richText )

    local testStr = "這是<font color=GOLD size = 30>金色的</font>字體"
    self._richText:setText( testStr )
font = {}

font.GOLD = cc.c3b(xxx,xxx,xxx)

 

 

知識點:

一、Lua模式匹配

.:全部字符
%a: 與任何字母配對
%c: 與任何控制符配對(例如\n)
%d: 與任何數字配對
%l: 與任何小寫字母配對
%p: 與任何標點(punctuation)配對
%s: 與空白字符配對
%u: 與任何大寫字母配對
%w: 與任何字母/數字配對
%x: 與任何十六進制數配對
%z: 與任何表明0的字符配對
%x(此處x是非字母非數字字符): 與字符x配對. 主要用來處理表達式中有功能的字符(^$()%.

 

%d+表示匹配一個或多個數字
%a+表示匹配一個或多個字母
+:重複一次或屢次 
:重複0次或屢次
-:重複0次或屢次 (雖然與*同樣,可是它會匹配最短的字串)

 

二、Lua的string.find  string.match string.sub

尤爲是string.match的捕獲匹配的字符串的用法

相關文章
相關標籤/搜索