List <LineData> lineData; // 行数据 //CharDataPool charData; // 字符数据 /// <summary> /// 构造函数 /// </summary> public QuestionTextParser(QuestionText textObj) { this.textObj = textObj; unitsPerPixel = textObj.pixelsPerUnit; handlers = new List <TextHandler>(); charData = new List <CharData>(); lineData = new List <LineData>(); }
/// <summary> /// 处理(进行实际处理) /// </summary> /// <param name="cd">字符数据</param> /// <param name="frag">片段数据</param> public override void handle(QuestionTextParser.CharData cd, FragmentData frag) { QuestionText.TestLog("handle: "); cd.display(); var image = getImageObject(handleCnt); setImagePosition(image, cd.verts); base.handle(cd, frag); }
/// <summary> /// 获取指定索引的图片对象 /// </summary> /// <param name="index">索引</param> /// <returns>图片对象</returns> Image getImageObject(int index) { QuestionText.TestLog("index = " + index + ", imageObjs.Count = " + imageObjs.Count); if (index >= imageObjs.Count) // 如果没有足够的图片对象 { return(createImageObject()); } return(imageObjs[index]); }
/* * /// <summary> * /// 构造函数 * /// </summary> * public FragmentData(string text, int s, int e, MatchInfo info) { * var handler = info.handler; * this.text = handler.maxReplace(text); * this.s = s; this.e = e; this.info = info; * children = new List<FragmentData>(); * charData = new List<QuestionTextParser.CharData>(); * rs = re = -1; * } */ /// <summary> /// 测试用 /// </summary> public void display() { QuestionText.TestLog("FragmentData(text: " + text + ", s: " + s + ", e: " + e + ", rs: " + rs + ", re: " + re + ")"); info?.display(); for (int i = 0; i < children.Count; ++i) { children[i].display(); } }
/// <summary> /// 调整每个字符数据(可能需要修改顶点坐标) /// </summary> void adjustChars() { fragData.adjustChars(); QuestionText.TestLog("====== AdjustedChars ======"); foreach (var c in charData) { c.display(resText); } }
/// <summary> /// 初始化图片对象 /// </summary> void initializeImageObjs() { imageCnt = 0; imageObjs.RemoveAll(image => image == null); // 自动读取 if (imageObjs.Count == 0) { textObj.GetComponentsInChildren(imageObjs); } QuestionText.TestLog("imageObjs.Count = " + imageObjs.Count); }
/// <summary> /// 处理(生成片段数据) /// </summary> /// <param name="text">原文本</param> string generateResText(string text) { fragData = new FragmentData(text, 0, oriText.Length); string resText = ""; build(fragData); // 递归构建片段树 fragData.traverse(ref resText); QuestionText.TestLog("====== Processed ======"); fragData.display(); return(resText); }
/// <summary> /// 分析文本 /// </summary> /// <param name="text">文本</param> public void parseText(string text) { initialize(); oriText = generateOriText(text); resText = generateResText(oriText); meshText = generateCharData(resText); configChars(); QuestionText.TestLog("oriText: " + oriText); QuestionText.TestLog("resText: " + resText); QuestionText.TestLog("meshText: " + meshText); }
/// <summary> /// 生成字符数据 /// </summary> void generateCharData(IList <UIVertex> verts) { var vcnt = verts.Count; QuestionText.TestLog("resText.Length: " + resText.Length); QuestionText.TestLog("meshText.Length: " + meshText.Length); QuestionText.TestLog("charData.Count: " + charData.Count); QuestionText.TestLog("vcnt: " + vcnt); var cdIndex = 0; for (int i = 0; i < vcnt / 4 && cdIndex < charData.Count; ++i) { var cd = charData[cdIndex]; var v1 = verts[i * 4]; var v2 = verts[i * 4 + 1]; var v3 = verts[i * 4 + 2]; var v4 = verts[i * 4 + 3]; QuestionText.TestLog("generateCharData: " + i + ", cdIndex: " + cdIndex + "\nverts: " + v1.position + "," + v2.position + "," + v3.position + "," + v4.position); if (cd.setVertices(i, v1, v2, v3, v4)) { cdIndex++; } } // 补全剩余数据 for (int i = cdIndex; i < charData.Count; i++) { var cd = charData[i]; var vIndex = vcnt / 4 - 1; var vert = verts[vcnt - 2]; cd.setVertices(vIndex, vert, vert, vert, vert, true); } QuestionText.TestLog("====== GeneratedChars: " + charData.Count + " ======"); foreach (var c in charData) { c.display(resText); } }
/// <summary> /// 调整每一行 /// </summary> void adjustLines(float lineHeight) { float resY = 0; // 总偏移量,实际每行的Y值(最高点) for (int i = 0; i < lineData.Count; i++) { var line = lineData[i]; //offset += line.maxY - resY; processOffset(line, line.maxY - resY); resY -= Mathf.Max(lineHeight, line.lineHeight()); } QuestionText.TestLog("====== AdjustedLines ======"); foreach (var line in lineData) { line.display(); } }
/// <summary> /// 生成行数据 /// </summary> /// <returns>生成是否成功</returns> void generateLineData() { if (charData.Count <= 0) { return; } var lcd = charData[0]; // 上一个数据 int ls = 0; // 记录本行起始位置 float minY = lcd.bottom(), maxY = lcd.top(); // 每一行最低点和最高点 for (int i = 1; i < charData.Count; ++i) { var cd = charData[i]; // 如果产生换行 if (lcd.left() - cd.left() > -lcd.size().x / 2 && (lcd.top() > cd.top() || lcd.bottom() > cd.bottom())) { lineData.Add(new LineData(ls, i, minY, maxY)); ls = i; // 设置下一行起始位置,重置最高点最低点 minY = cd.bottom(); maxY = cd.top(); } else { minY = Math.Min(minY, cd.bottom()); maxY = Math.Max(maxY, cd.top()); } lcd = cd; } lineData.Add(new LineData(ls, charData.Count, minY, maxY)); QuestionText.TestLog("====== GeneratedLines ======"); foreach (var line in lineData) { line.display(); } }
/// <summary> /// 测试用 /// </summary> public void display() { QuestionText.TestLog("MatchInfo(index: " + match.Index + ", match:" + match.Value + ", replaced:" + handler.replace(match) + ", handler:" + handler.tag() + ")"); }
/// <summary> /// 生成结果 /// </summary> /// <returns></returns> List <UIVertex> generateResult() { int vi = 0, lvi = 0; List <UIVertex> res = new List <UIVertex>(); Vector2 min = new Vector2(9999, 9999); Vector2 max = new Vector2(-9999, -9999); foreach (var cd in charData) { vi = cd.vIndex; // 填补多余的空节点 for (int i = 0; i < vi - lvi - 1; ++i) { addEmptyVertices(res, cd); } // 如果需要隐藏,置为空节点 if (cd.hidden) { addEmptyVertices(res, cd); } else { res.AddRange(cd.verts); } lvi = vi; if (cd.left() < min.x) { min.x = cd.left(); } if (cd.right() > max.x) { max.x = cd.right(); } if (cd.bottom() < min.y) { min.y = cd.bottom(); } if (cd.top() > max.y) { max.y = cd.top(); } } textObj.perfectSize = new Vector2(max.x - min.x, max.y - min.y); QuestionText.TestLog("====== GeneratedRes: " + res.Count + " ======"); QuestionText.TestLog("min: " + min + ", max: " + max + ", size: " + textObj.perfectSize); var vcnt = res.Count; for (int i = 0; i < vcnt / 4; ++i) { //var c = meshText[i]; //var cd = charData[i]; var v1 = res[i * 4]; var v2 = res[i * 4 + 1]; var v3 = res[i * 4 + 2]; var v4 = res[i * 4 + 3]; //cd.setVertices(v1, v2, v3, v4); QuestionText.TestLog("res: " + i + "\nverts: " + v1.position + "," + v2.position + "," + v3.position + "," + v4.position); } return(res); }
/// <summary> /// 构造函数 /// </summary> /// <param name="textObj">文本对象</param> public TextHandler(QuestionText textObj) { this.textObj = textObj; }
public void display(string text) { QuestionText.TestLog("CharData(index: " + index + ", char: " + text[index] + ", m: " + midPoint() + ", left: " + left() + ", top: " + top() + ", right: " + right() + ", bottom: " + bottom() + ")"); }
/// <summary> /// 构造函数 /// </summary> /// <param name="textObj">文本对象</param> public SubTextHandler(QuestionText textObj) : base(textObj) { }
/// <summary> /// 构造函数 /// </summary> /// <param name="textObj">文本对象</param> /// <param name="embedImage">是否嵌入显示图片</param> public QuadImageHandler(QuestionText textObj) : base(textObj) { }
/// <summary> /// 测试 /// </summary> public void display() { QuestionText.TestLog("LineData(s: " + s + ", e: " + e + ", minY: " + minY + ", maxY: " + maxY + ", height: " + lineHeight() + ", offset: " + offset + ")"); }
/// <summary> /// 获取片段的尺寸 /// </summary> /// <returns></returns> public Vector2 size(QuestionText text) { return(text.meansure(this.text)); }
/// <summary> /// 递归构建片段树 /// </summary> /// <param name="parent">父片段</param> void build(FragmentData parent) { var matchInfo = new List <FragmentData.MatchInfo>(); var text = parent.text; // 进行正则表达式匹配,找到每个标签项的范围 for (int i = 0; i < handlers.Count; ++i) { var handler = handlers[i]; MatchCollection tmpMatches = handler.matches(text); foreach (Match match in tmpMatches) { matchInfo.Add(new FragmentData.MatchInfo(match, handler)); } } if (matchInfo.Count <= 0) { return; // 如果没有特殊标签,直接返回 } QuestionText.TestLog("====== Matched ======"); foreach (var m in matchInfo) { m.display(); } matchInfo.Sort(); int ls = -1, le = -1; // 上一个(有记录的) s 和 e int ms, me; // 每个匹配项的 s 和 e var lastInfo = matchInfo[0]; // 上一个匹配项 string subText; // 遍历每个匹配项 //for (int i = mi; i < mj; ++i) { foreach (var info in matchInfo) { ms = info.start(); me = info.end(); if (ls == -1 && le == -1) // 如果是第一个匹配项(0...ms[.....) // 该匹配项之前的文本均为普通文本,建立叶子结点 { subText = text.Substring(0, ms); var child = new FragmentData(subText, 0, ms); parent.children.Add(child); lastInfo = info; ls = ms; le = me; // 记录当前匹配项数据 /* } else if (ms < le && me > le) { // 当两个匹配项重叠的时候(ls[..ms[..]le..]me..) * // 这时候只有当两个标签相同才处理(因为正则表达式无法处理内嵌的情况,在这里进行处理) * if (info.handler.tag() == lastInfo.handler.tag()) { * // 只生成一段:ls - me * subText = text.Substring(ls, me - ls); * QuestionText.TestLog("SubText = " + subText); * var child = new FragmentData(subText, ls, me, lastInfo); * parent.children.Add(child); // 添加子树 * build(child); // 递归建树 * * le = me; * } */ } if (ms >= le) // 当当前匹配项起始位置大于已有匹配项的末位置(ls[...]le..ms[...) // 建立上一个匹配项的子节点 { var child1 = new FragmentData(ls, le, lastInfo); parent.children.Add(child1); // 添加子树 build(child1); // 递归建树 // 建立两个匹配项之间的子节点 subText = text.Substring(le, ms - le); var child2 = new FragmentData(subText, le, ms); parent.children.Add(child2); // 添加子树 lastInfo = info; ls = ms; le = me; // 记录当前匹配项数据 } } // 处理最后一个匹配项(ls[....]le....text.Length) // 建立最后一个匹配项的子节点 var lastChild1 = new FragmentData(ls, le, lastInfo); parent.children.Add(lastChild1); // 添加子树 build(lastChild1); // 递归建树 // 建立到文本末尾的子节点 subText = text.Substring(le, text.Length - le); var lastChild2 = new FragmentData(subText, le, text.Length); parent.children.Add(lastChild2); // 添加子树 }