The Cocos2d-x provides the basic cclabelttf for text painting, the underlying implementation process of the text is like this, string first use local API to convert to ccimage, this step depends on the platform interface, then, it is converted from ccimage to cctexture2d texture for text rendering.
So how can we implement a RichTextBox through the cclabelttf and other font classes and support multiple colors, line breaks, emotices (images), and hyperlinks?
We don't plan to do this job from the bottom of OpenGL, because it's a huge workload, but a combination of existing cocos2d-x interfaces.
Since I used the underlying interface of windowsgdi three years ago to create a color text editor, the stitching problem is hard to grasp. I even feel that this is much simpler.
First, break down the work and process:
(1) multi-color: a multi-color text is formed when multiple cclabelttf of different colors are combined.
(2) line feed: This is relatively tricky. the height and width of the current RichTextBox must be considered for line feed. If the number of characters in the current line is full, passive line feed is required. In addition, if \ n line breaks exist, active line feed is required.
(3) emoticon: The expression is an image, which is easier to implement than the text.
(4) hyperlink: As textbox in the ccgui system is used as the basic splicing element, it has the potential to accept clicks. You only need to set whether the clicks can be touched.
(5) the width of each character in the text must be accurately calculated, and the calculation cost is relatively high (the time cost calculated for a character on the PC is about 1 ms ), however, because the number of characters is certain, the number of commonly used Chinese and English characters is only several thousand. Therefore, cache can be performed during game operation, which greatly improves efficiency. The cache algorithm does not calculate all characters at a time, but calculates several characters at a frame. This ensures the smoothness of the game and enables loading during game running.
Here we will describe the implementation of line feed in detail, because this is a troublesome place for this control. After figuring it out, let's talk about other things.
For the text added to RichTextBox by append, the pixel width of the text is calculated first. After the width is calculated, the logical pseudocode is as follows:
If the remaining width of the inserted row is greater than or equal to width then
Insert text directly
Update the insert position (x, y)
Else
Calculates the number of characters that can be inserted into a row.
Insert rows
Calculate the remaining width
While (remaining)
If remaining width> RichTextBox. widththen
Fill the bank
Calculate the remaining width
Else
Insert text directly
Update Insert Location
End
End
End
Looks not very complex, but pay attention to the details of the more, the first is the text must be utf8 format, Windows Default is GBK, need to be converted (using the third-party iconv library attached to the cocos2d-x ), after conversion, You need to calculate the number of char characters occupied by a utf8 character in the text. Generally, one utf8-format Chinese Character occupies three char characters. The other is to calculate the pixel width of each utf8 character, I directly use cclabelttf for calculation. If I write the API for calculating the width, I also need to rely on the platform. For example, on Windows, I may need to use APIs such as getcharwidth32 and switch to IOS, this is another calculation method, which requires a large amount of work. I hope someone can sort it out later, but now we are secretly lazy, and based on the optimization solution mentioned at (5) above, in fact, there is no worry.
After coming to a new company, I used this GUI Design Scheme. Because it is no longer a personal work, but a serious commercial code, I hope it will be open-source later.
At present, all the basic controls (one week) have been completed by imitating cegui, and many cegui code has been referenced in the implementation, which is largely consistent with the APIs of Fang Jia.
The blog will give a general explanation of the troublesome control implementation methods, such as imitating numberpicker In the IOS system GUI and scrollview with the paging function. You can check that the blog is much slower than the code. Please forgive me.