public RichTextTag Parse() { RichTextTag tag = null; Match match = tagRegex.Match(content); if (match.Success) { string tagName = match.Groups[1].Value;//标签类型 if (!tagName.StartsWith("#")) { var keyValueCollection = paraRegex.Matches(match.Groups[2].Value);//标签参数 switch (tagName) { case "underline": { tag = new RichTextUnderlineTag(); break; } default: break; } if (tag != null) { tag.start = start; tag.end = end; for (int i = 0; i < keyValueCollection.Count; i++) { string key = keyValueCollection[i].Groups[1].Value; string value = keyValueCollection[i].Groups[2].Value; tag.SetValue(key, value); } } } } return(tag); }
private void ApplyUnderlineEffect(RichTextUnderlineTag tag, IList <UIVertex> verts) { float fontSize2 = fontSize * 0.5f; float unitsPerPixel = 1 / pixelsPerUnit; //0 1|4 5|8 9 |12 13 //3 2|7 6|11 10|14 15 //<material=underline c=#ffffff h=1 n=1 p=2>下划线</material> //以上面为例: //tag.start为42,对应“>” | start对应“下”的左上角顶点 //tag.end为44,对应“划” | end对应“线”下一个字符的左上角顶点 //Debug.Log(tag.start); //Debug.Log(tag.end); int start = tag.start * 4; int end = Mathf.Min(tag.end * 4 + 4, verts.Count); UIVertex vt1 = verts[start + 3]; UIVertex vt2; float minY = vt1.position.y; float maxY = verts[start].position.y; //换行处理,如需换行,则将一条下划线分割成几条 //顶点取样分布,如上图的2,6,10,其中end - 2表示最后一个取样点,即10 //对应例子中的下、划、线的右下角顶点 for (int i = start + 2; i <= end - 2; i += 4) { vt2 = verts[i]; bool newline = Mathf.Abs(vt2.position.y - vt1.position.y) > fontSize2; if (newline || i == end - 2) { RichTextImageInfo imageInfo = new RichTextImageInfo(); //计算宽高 int tailIndex = !newline && i == end - 2 ? i : i - 4; vt2 = verts[tailIndex]; minY = Mathf.Min(minY, vt2.position.y); maxY = Mathf.Max(maxY, verts[tailIndex - 1].position.y); imageInfo.size = new Vector2((vt2.position.x - vt1.position.x) * unitsPerPixel, tag.height); //计算位置 Vector2 vertex = new Vector2(vt1.position.x, minY); vertex *= unitsPerPixel; vertex += new Vector2(imageInfo.size.x * 0.5f, -tag.height * 0.5f); vertex += new Vector2(rectTransform.sizeDelta.x * (rectTransform.pivot.x - 0.5f), rectTransform.sizeDelta.y * (rectTransform.pivot.y - 0.5f)); imageInfo.position = vertex; imageInfo.color = tag.color; imageInfoList.Add(imageInfo); if (!string.IsNullOrEmpty(tag.eventName)) { //下划线pos: //x:vt1.x + 图片宽度的一半 //y:minY - tag.height * 0.5f RichTextEvent e = new RichTextEvent(); e.name = tag.eventName; e.parameter = tag.eventParameter; e.rect = new Rect( vt1.position.x * unitsPerPixel, minY * unitsPerPixel, imageInfo.size.x, (maxY - minY) * unitsPerPixel ); eventList.Add(e); } vt1 = verts[i + 1]; minY = vt1.position.y; if (newline && i == end - 2) { i -= 4; } } else { minY = Mathf.Min(minY, verts[i].position.y); maxY = Mathf.Max(maxY, verts[i - 1].position.y); } } }