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的捕获匹配的字符串的用法

相关文章
相关标签/搜索