zoukankan      html  css  js  c++  java
  • cocos2dx-lua 简单的字体变色拼接实现

      这里主要做的是游戏公告里面用到的,因此我加入了简单的html <font>标签解析,是为了给运营小白预览,但其中的size 属性没有,因为后来没有这个需求了,所以也就懒得改了。

      实现思路很简单:设置好行宽和行高,然后一个一个字往上面添加,直到达到行宽上限或者换行符,就换行,再循环。

      

    --简易html label
    --[[
        暂只对以下标签进行实现
        <font> 标签进行实现,可添加 size 和 color属性
        <br> 换行
    --]]
    
    --[=[
       demo:
        html = "<font size="50" color="#ff0000" > ab,casdjfladfasdgasdasdgasdfasdfqwetqwetrtwqrtqwerqwerqwerqwetqwetqwerqwerqwer44444444444222222222asdugowe<br>iurlsdjlkasdhga </font><font size="28" color="#002" > ab,21<br>iurlsdjlkasdhga </font><font size="22" color="#2231" > ab,12<br>12 </font><font size="10" color="#2202" > ab,.21<br>1 </font>"
        local lable = require ("common.HtmlLabel").new(600,html)
        lable:setPosition(400,400)
        self._lay:addChild(lable)
    --]=]
    
    local HtmlLabel = class("HtmlLabel",function()
    	return Layout:create()
    end)
    
    function HtmlLabel:ctor(width , html)
        self._width = width
        self._height = 0
        self._defaultFontSize = 18
        self._defaultFontColor = 0x000000
        self:initWithString(html)
    end
    
    local headTag = "<font .->"
    local lastTag = "</font>"
    function HtmlLabel:initWithString(html)
        self._html = string.lower(html)
        self:removeAllChildrenWithCleanup(true)
    
        local labelList = {}
        html = string.gsub(html , "<br>"  , "
    ")
        while string.len(html) > 0  do
            local bPos,ePos = string.find(html,lastTag)
            local node = {}
            local headTagEndPos = 1
            if not find then
                local hbPos,hePos = string.find(html,headTag)
                if hbPos then
    --                local head = string.sub(html , hbPos , (hePos-hbPos+1))
                    local head = string.sub(html , hbPos+5 , (hePos-1))
                    head = string.gsub(head , "#" , "0x")
                    head = string.gsub(head , "(%d")" , "%1,")
                    local strFunc = " return {" .. head .. "}"
                    node = assert(loadstring(strFunc))()
                    if not node.color then
                        node.color = self._defaultFontColor
                    else
                        node.color = tonumber(node.color)
                    end
                    if not node.size then
                        node.size = self._defaultFontSize
                    else
                        node.size = tonumber(node.size)
                    end
                    headTagEndPos = hePos + 1
                   -- html = string.sub(html, hePos+1 , string.len(html))
                else
                    node.color = self._defaultFontColor
                    node.size = self._defaultFontSize
                end
    
                node.str = string.sub(html,headTagEndPos,bPos-1)
                html = string.sub(html , ePos+1 , string.len(html)) --去除已处理段
            else
                node.str = html
                node.color = self._defaultFontColor
                node.size = self._defaultFontSize
                html = ""
            end
            table.insert(labelList , node)
        end
        
        if #labelList == 0 then
            return 
        end
    
        local node1 = labelList[1]
        self:initRichLabel(node1.str,self._width ,node1.size*(1+0.2) , node1.size , ccc3(math.floor(node1.color/0x10000), math.floor(node1.color/0x100)%0x100 , node1.color % 0x100 ))
        
        for i=2,#labelList do
            node1 = labelList[i]
       --     print ("%02x%02x%02x",math.floor(node1.color/0x10000), math.floor(node1.color/0x100)%0x100 , node1.color % 0x100 )
            self:addString(node1.str, ccc3(math.floor(node1.color/0x10000), math.floor(node1.color/0x100)%0x100 , node1.color % 0x100 ))
        end
    end
    
    
    function HtmlLabel:initRichLabel(content ,lineWidth , lineHeight , fntSize , color)
    	self.lineWidth = lineWidth
        self.lineHeight = lineHeight
        self._fntSize = fntSize
        self._defaultColor = color
    	self.widthIndex = 0
    	self.rowIndex = 1
    	self.nodeList = {}
        self.anchorPoint = ccp(0.5,0.5)
        self:addString(content)
    end
    
    --重新设置一个string
    function HtmlLabel:setString(content , color)
        self:removeAllChildrenWithCleanup(true)
    	self.widthIndex = 0
    	self.rowIndex = 1
        self.nodeList = {}
        self._defaultColor = color or self._defaultColor
        self:addString(content)
    end
    
    --增加一个string 
    function HtmlLabel:addString(labelStr , color)
        color = color or self._defaultColor
    
    	if self.widthIndex >= self.lineWidth then
    		self.widthIndex = 0
    		self.rowIndex = self.rowIndex + 1
    	end
    	
    	while labelStr ~= nil and labelStr ~= "" do
    		local begIndex,endIndex = self:getMaxSubStr(labelStr,self.lineWidth - self.widthIndex , self._fntSize)
    		if begIndex == nil then --换行
    			self.widthIndex = 0
    			self.rowIndex = self.rowIndex + 1
    			begIndex,endIndex = self:getMaxSubStr(labelStr,self.lineWidth - self.widthIndex, self._fntSize)
    		end
    		local subStr = string.sub(labelStr,begIndex,endIndex)
    		labelStr = string.sub(labelStr,endIndex+1,string.len(labelStr))
    	    local label = Label:create()
            label:setFontSize(self._fntSize)
            local text = string.gsub(subStr, "
    ", "")--去除换行符
            label:setText(text)
            label:setColor(color)
    
    		label:setPositionX(self.widthIndex)
    		self:addChild(label)
    		label:setAnchorPoint(ccp(0,0))
    		label.rowIndex = self.rowIndex
            label.srcX = self.widthIndex
    		table.insert(self.nodeList,label)
    		self.widthIndex = self.widthIndex + label:getContentSize().width
            if string.find(subStr , '
    ') then --出现强制换行
    			self.widthIndex = 0
    			self.rowIndex = self.rowIndex + 1
            end
    	end
    
        self:updateInset()
    end
    
    function HtmlLabel:setContentSize( w , h)
        local sz = w
        if h then
            sz = CCSize(w ,h )
        end
        self.contentSize = sz
    end
    
    function HtmlLabel:getContentSize()
        return self.contentSize
    end
    
    --更新容器所有Node的位置
    function HtmlLabel:updateInset()
    	local row = self.rowIndex
    	if self.widthIndex == 0 then --如果最后一行还没内容
    		row = row - 1
    	end
        local contentSize = CCSize(self.lineWidth,row*self.lineHeight)
        local anchorY = contentSize.height * self.anchorPoint.y
        local anchorX = contentSize.width * self.anchorPoint.x
    	for k,v in pairs(self.nodeList) do
    		v:setPositionY((row-v.rowIndex)*self.lineHeight - anchorY)
            v:setPositionX(v.srcX - anchorX)
    	end
    	
    	self:setContentSize(contentSize)
    end
    
    --设置锚点
    function HtmlLabel:setAnchorPoint( x, y )
        local pt = nil
        if not y then
            pt = x
        else
            pt = ccp(x,y)
        end
        if pt.x == self.anchorPoint.x and pt.y == self.anchorPoint.y then
            return
        end
        self.anchorPoint = pt
        self:updateInset()
    end
    
    function HtmlLabel:setPosition( x , y )
        local pt = nil
        if not y then
            pt = x
        else
            pt = ccp(x,y)
        end
        CCNode.setPosition(self,pt)
    end
    
    --获取宽度范围内,最长子串
    function HtmlLabel:getMaxSubStr(_string,width,fntSize)
    	local result = ""
    	local index = 1
    	local is_end = true
    	local index_max = string.len(_string)
    	local label = Label:create()
        label:setFontSize(fntSize)
    
    	while is_end  do	
    		local firstCase = string.byte(_string,index) 
    		if firstCase == nil then
    			break
    		end
    		local caseLen = self:sizeof(firstCase)	--字符宽度
    		local strCase =  string.sub(_string,index,index + caseLen-1) 
    	    if strCase  == "
    " then
    			result = result .. strCase
    			index = index + caseLen		--保留回车返回
                break
            end
    		label:setText(result .. strCase)
    		local t = label:getContentSize().width*label:getScale()
    		if t < width then
    			result = result .. strCase
    			index = index + caseLen		
    		else
    			is_end = false
    		end
            if index>index_max then
                is_end=false
            end 
    	end
    	if result == "" then
    		return nil
    	end
    	return 1,index-1
    end
    
    --获取某字符所占字节数
    function HtmlLabel:sizeof(firstCase)
    	if (firstCase >= 0 and firstCase  <= 0x7f) then
           return 1	
    	elseif firstCase >= 0x80 and firstCase < 0xe0 then
    		return 2
        elseif firstCase >= 0xe0 then
            return 3
        end
    end 
    
    
    function HtmlLabel:getSize()
        return CCSize(self._width , self._height)
    end
    
    return HtmlLabel
    

      

    Stay hungry, stay foolish!
  • 相关阅读:
    python3 练习题 day04
    python3 装饰器
    python3 生成器和生成器表达式
    python3 列表/字典/集合推导式
    python3 迭代器
    python3 day04 大纲
    ES6 的数值扩展
    ES6中的解构赋值
    ES6中 let与const 的区别
    react的基本配置安装及使用babel
  • 原文地址:https://www.cnblogs.com/JhonKing/p/5665875.html
Copyright © 2011-2022 走看看