private void SuperHandleFormat2(StringReader reader) { int[][] classDef1 = ReadClass(reader); int[][] classDef2 = ReadClass(reader); int valueFormat1 = StringToInt(reader.ReadLine()); int valueFormat2 = StringToInt(reader.ReadLine()); int class1RecordCount = StringToInt(reader.ReadLine()); for (int i = 0; i < class1RecordCount; ++i) { int class2RecordCount = StringToInt(reader.ReadLine()); for (int j = 0; j < class2RecordCount; ++j) { KerningPairValue kerningPairValue = new KerningPairValue(); if (valueFormat1 != 0) { kerningPairValue.XAdvance1 = StringToInt(reader.ReadLine()); } if (valueFormat2 != 0) { kerningPairValue.XAdvance2 = StringToInt(reader.ReadLine()); } AddKerningPair(classDef1[i], classDef2[j], kerningPairValue); } } }
private void HandleFormat2(XElement pairPos) { HashSet <int> coverageList = new HashSet <int>(); int classDef1Count = GetSizeOf(pairPos.Element("ClassDef1")); int classDef2Count = GetSizeOf(pairPos.Element("ClassDef2")); List <int>[] classDef1 = InitializeNewList(classDef1Count); List <int>[] classDef2 = InitializeNewList(classDef2Count); foreach (XElement glyph in pairPos.Element("Coverage").Elements("Glyph")) { string glyphName = glyph.Attribute("value").Value; int glyphIdx; if (!keyMap.ContainsKey(glyphName)) { continue; } glyphIdx = keyMap[glyphName]; coverageList.Add(glyphIdx); classDef1[0].Add(glyphIdx); classDef2[0].Add(glyphIdx); } int valueFormat1 = StringToInt(pairPos.Element("ValueFormat1").Attribute("value").Value); int valueFormat2 = StringToInt(pairPos.Element("ValueFormat2").Attribute("value").Value); AssignGlyphsToClass(pairPos.Element("ClassDef1"), classDef1, coverageList); AssignGlyphsToClass(pairPos.Element("ClassDef2"), classDef2, coverageList); foreach (XElement class1Record in pairPos.Elements("Class1Record")) { int classIndex1 = StringToInt(class1Record.Attribute("index").Value); foreach (XElement class2Record in class1Record.Elements("Class2Record")) { int classIndex2 = StringToInt(class2Record.Attribute("index").Value); KerningPairValue kerningPairValue = new KerningPairValue(); if (valueFormat1 != 0) { kerningPairValue.XAdvance1 = StringToInt(class2Record.Element("Value1").Attribute("XAdvance").Value); } if (valueFormat2 != 0) { kerningPairValue.XAdvance2 = StringToInt(class2Record.Element("Value2").Attribute("XAdvance").Value); } AddKerningPair(classDef1[classIndex1], classDef2[classIndex2], kerningPairValue); } } }
private void SuperHandleFormat1(StringReader reader) { int coverageCount = StringToInt(reader.ReadLine()); int[] leftGlyphs = new int[coverageCount]; for (int i = 0; i < coverageCount; ++i) { string glyphName = reader.ReadLine(); int glyphIdx; if (!keyMap.TryGetValue(glyphName, out glyphIdx)) { glyphIdx = int.MaxValue; } leftGlyphs[i] = glyphIdx; } int valueFormat1 = StringToInt(reader.ReadLine()); int valueFormat2 = StringToInt(reader.ReadLine()); int pairSetCount = StringToInt(reader.ReadLine()); for (int i = 0; i < pairSetCount; ++i) { int pairValueRecordCount = StringToInt(reader.ReadLine()); int leftGlyphIdx = leftGlyphs[i]; for (int j = 0; j < pairValueRecordCount; ++j) { string rightGlyphName = reader.ReadLine(); int rightGlyphIdx; if (!keyMap.TryGetValue(rightGlyphName, out rightGlyphIdx)) { rightGlyphIdx = int.MaxValue; } KerningPairValue kerningPairValue = new KerningPairValue(); if (valueFormat1 != 0) { kerningPairValue.XAdvance1 = StringToInt(reader.ReadLine()); } if (valueFormat2 != 0) { kerningPairValue.XAdvance2 = StringToInt(reader.ReadLine()); } AddKerningPair(leftGlyphIdx, rightGlyphIdx, kerningPairValue); } } }
private void HandleFormat1(XElement pairPos) { List <int> leftGlyphs = new List <int>(); int valueFormat1 = StringToInt(pairPos.Element("ValueFormat1").Attribute("value").Value); int valueFormat2 = StringToInt(pairPos.Element("ValueFormat2").Attribute("value").Value); foreach (XElement glyph in pairPos.Element("Coverage").Elements()) { string glyphName = glyph.Attribute("value").Value; int value; if (!keyMap.TryGetValue(glyphName, out value)) { value = int.MaxValue; } leftGlyphs.Add(value); } foreach (XElement pairSet in pairPos.Elements("PairSet")) { int leftGlyphIndex = StringToInt(pairSet.Attribute("index").Value); foreach (XElement pairValueRecord in pairSet.Elements("PairValueRecord")) { string rightGlyphName = pairValueRecord.Element("SecondGlyph").Attribute("value").Value; int rightGlyphIdx; if (!keyMap.TryGetValue(rightGlyphName, out rightGlyphIdx)) { rightGlyphIdx = int.MaxValue; } KerningPairValue kerningPairValue = new KerningPairValue(); if (valueFormat1 != 0) { kerningPairValue.XAdvance1 = StringToInt(pairValueRecord.Element("Value1").Attribute("XAdvance").Value); } if (valueFormat2 != 0) { kerningPairValue.XAdvance2 = StringToInt(pairValueRecord.Element("Value2").Attribute("XAdvance").Value); } AddKerningPair(leftGlyphs[leftGlyphIndex], rightGlyphIdx, kerningPairValue); } } }
private void AddKerningPair(List <int> leftGlyphs, List <int> rightGlyphs, KerningPairValue kerningPairValue) { if (kerningPairValue.XAdvance1 == 0 && kerningPairValue.XAdvance2 == 0) { return; } foreach (int leftGlyphIdx in leftGlyphs) { foreach (int rightGlyphIdx in rightGlyphs) { AddKerningPair(leftGlyphIdx, rightGlyphIdx, kerningPairValue); } } }
private void AddKerningPair(int[] leftGlyphs, int[] rightGlyphs, KerningPairValue kerningPairValue) { if (kerningPairValue.XAdvance1 == 0 && kerningPairValue.XAdvance2 == 0) { return; } for (int i = 0; i < leftGlyphs.Length; ++i) { for (int j = 0; j < rightGlyphs.Length; ++j) { AddKerningPair(leftGlyphs[i], rightGlyphs[j], kerningPairValue); } } }
private float CalculateLineOffset(int idx, string content, MatchCollection matchCollection, bool isRichText, Queue <int> Q) { Match match = null; int matchCollectionIdx = 0; float lineOffset = 0f; uint leftGlyph = uint.MaxValue; int leftGlyphSize = 0; while (idx < content.Length && content[idx] != '\n') { if (isRichText && matchCollectionIdx < matchCollection.Count) { if (match == null) { match = matchCollection[matchCollectionIdx]; } if (idx == match.Index) { if (IsSizeStartMatch(match.Value)) { int newFontSize = StringToInt(match.Value.Substring(6, match.Value.Length - 7)); if (Q == null) { Q = new Queue <int>(); } Q.Enqueue(newFontSize); } else if (IsSizeEndMatch(match.Value)) { if (Q != null && Q.Count > 0) { Q.Dequeue(); } } idx += match.Length; match = null; ++matchCollectionIdx; continue; } } uint rightGlyph = content[idx]; int rightGlyphSize = fontSize; if (Q != null && Q.Count > 0) { rightGlyphSize = Q.Peek(); } KerningPairValue kerningPairValue = kerningTable.GetKerningPair(leftGlyph, rightGlyph); lineOffset += kerningPairValue.XAdvance1 * leftGlyphSize + kerningPairValue.XAdvance2 * rightGlyphSize; leftGlyph = rightGlyph; leftGlyphSize = rightGlyphSize; ++idx; } return(lineOffset); }
private void Kern(List <UIVertex> verts) { if (!IsActive() || !useKerning || pairAsset == null) { return; } if (kerningTable == null || kerningTable.name != pairAsset.XMLFile.name) { kerningTable = kerningManager.GetKerningTable(pairAsset.XMLFile, pairAsset.platform, pairAsset.compression, out timer, out measured); if (kerningTable == null) { return; } } bool isRichText = usingRichText && supportRichText; //int[] originalIdxs, actualFontSizes; //string[] lines = SplitToLines(text, isRichText, out originalIdxs, out actualFontSizes); int lastEnterIdx = -1; float kerningScale = .01f * kerningScaleFactor; MatchCollection matchCollection = null; Match match = null; Queue <int> Q = null; int matchCollectionIdx = 0; if (isRichText) { matchCollection = Regex.Matches(text, SupportedTagRegexPatterns); } while (lastEnterIdx < text.Length) { float lineOffset = CalculateLineOffset(lastEnterIdx + 1, text, matchCollection, isRichText, Q) * kerningScale * GetAlignmentFactor(alignment); if (lastEnterIdx + 1 > text.Length - 1 || text[lastEnterIdx + 1] == '\n') { ++lastEnterIdx; continue; } float prefixOffset = 0f; MoveGlyph(verts, lastEnterIdx + 1, Vector3.right * (0f - lineOffset)); int idx = lastEnterIdx + 1; uint leftGlyph = uint.MaxValue; int leftGlyphSize = 0; while (idx < text.Length && text[idx] != '\n') { if (isRichText && matchCollectionIdx < matchCollection.Count) { if (match == null) { match = matchCollection[matchCollectionIdx]; } if (idx == match.Index) { if (IsSizeStartMatch(match.Value)) { int newFontSize = StringToInt(match.Value.Substring(6, match.Value.Length - 7)); if (Q == null) { Q = new Queue <int>(); } Q.Enqueue(newFontSize); } else if (IsSizeEndMatch(match.Value)) { if (Q != null && Q.Count > 0) { Q.Dequeue(); } } idx += match.Length; match = null; ++matchCollectionIdx; continue; } } uint rightGlyph = text[idx]; int rightGlyphSize = fontSize; if (Q != null && Q.Count > 0) { rightGlyphSize = Q.Peek(); } KerningPairValue kerningPairValue = kerningTable.GetKerningPair(leftGlyph, rightGlyph); prefixOffset += kerningPairValue.XAdvance1 * leftGlyphSize * kerningScale; MoveGlyph(verts, idx, Vector3.right * (prefixOffset - lineOffset)); prefixOffset += kerningPairValue.XAdvance2 * rightGlyphSize * kerningScale; leftGlyph = rightGlyph; leftGlyphSize = rightGlyphSize; ++idx; } lastEnterIdx = idx; } /*int glyphIdx = 0; * * for (int lineIndex = 0; lineIndex < lines.Length; ++lineIndex) * { * string line = lines[lineIndex]; * float[] prefixOffset = new float[line.Length + 1]; * float lineOffset = 0f; * * for (int i = 1; i < line.Length; ++i) * { * uint leftGlyph = line[i - 1]; * uint rightGlyph = line[i]; * * KerningPairValue kernValue = kerningTable.GetKerningPair(leftGlyph, rightGlyph); * * float leftScaleFactor = actualFontSizes[glyphIdx + i - 1] * .01f * kerningScaleFactor; * float rightScaleFactor = actualFontSizes[glyphIdx + i] * .01f * kerningScaleFactor; * * lineOffset += kernValue.XAdvance1 * leftScaleFactor + kernValue.XAdvance2 * rightScaleFactor; * prefixOffset[i] += kernValue.XAdvance1 * leftScaleFactor; * prefixOffset[i + 1] = prefixOffset[i] + kernValue.XAdvance2 * rightScaleFactor; * } * * lineOffset *= GetAlignmentFactor(alignment); * * for (int i = 0; i < line.Length; ++i) * { * int originalIdx = originalIdxs[glyphIdx]; * Vector3 offset = Vector3.right * (prefixOffset[i] - lineOffset); * * if (6 * originalIdx + 5 > verts.Count - 1) * return; * * for (int j = 0; j < 6; ++j) * { * int pos = 6 * originalIdx + j; * UIVertex vert = verts[pos]; * vert.position += offset; * verts[pos] = vert; * } * ++glyphIdx; * } * ++glyphIdx; * }*/ }
public void AddKerningPair(int leftGlyphIdx, int rightGlyphIdx, KerningPairValue kerningPairValue) { if ((kerningPairValue.XAdvance1 == 0 && kerningPairValue.XAdvance2 == 0) || leftGlyphIdx >= glyphCount || rightGlyphIdx >= glyphCount) { return; } if (IsKernPair(new KerningPair(leftGlyphIdx, rightGlyphIdx))) { return; } Debug.Log(leftGlyphIdx + " " + rightGlyphIdx); if (storeMode == StoreMode.Array) { if (kerningTable == null) { return; } if (kerningTable[leftGlyphIdx] == null) { kerningTable[leftGlyphIdx] = new KerningPairValue[glyphCount]; } kerningTable[leftGlyphIdx][rightGlyphIdx] = kerningPairValue; } else if (storeMode == StoreMode.Mixed) { if (leftGlyphIdx < maxGlyphCount && rightGlyphIdx < maxGlyphCount) { if (kerningTable == null) { return; } if (kerningTable[leftGlyphIdx] == null) { kerningTable[leftGlyphIdx] = new KerningPairValue[maxGlyphCount]; } kerningTable[leftGlyphIdx][rightGlyphIdx] = kerningPairValue; } else { if (kerningTables == null) { return; } if (kerningTables[leftGlyphIdx] == null) { kerningTables[leftGlyphIdx] = new Dictionary <int, KerningPairValue>(); } else if (kerningTables[leftGlyphIdx].ContainsKey(rightGlyphIdx)) { return; } kerningTables[leftGlyphIdx].Add(rightGlyphIdx, kerningPairValue); } } ++Count; }