public TexCharMetric GetCharMetric(char ch, TexStyle style) { TexFont font; #if UNITY_EDITOR if (!TEXConfiguration.main) { Debug.LogError("No tex configuraion exists!"); // Never gonna happen } #endif if (ch >= 'A' && ch <= 'Z') // char.IsUpper(ch) { font = fontData[preferences.Typeface_Capitals]; } else if (ch >= 'a' && ch <= 'z') // char.IsLower(ch) { font = fontData[preferences.Typeface_Small]; } else if (ch >= '0' && ch <= '9') // char.IsDigit(ch) { font = fontData[preferences.Typeface_Number]; } else { font = fontData[preferences.Typeface_Unicode]; } return(font.GetCharacterData(ch).GetMetric(TexUtility.SizeFactor(style))); }
Box CreateGenericRadicalBox(Box baseBox, string genericSymbol) { float clearance; var lineThickness = TEXConfiguration.main.LineThickness * TexContext.Scale; clearance = lineThickness; // Create box for radical sign. var totalHeight = baseBox.totalHeight; var radicalSignBox = DelimiterFactory.CreateBox(genericSymbol, totalHeight + clearance + lineThickness); // Add half of excess height to clearance. //lineThickness = Mathf.Max(radicalSignBox.height, lineThickness); clearance = radicalSignBox.totalHeight - totalHeight - lineThickness * 2; // Create box for square-root containing base box. TexUtility.CentreBox(radicalSignBox); var overBar = OverBar.Get(baseBox, clearance, lineThickness); var expansion = radicalSignBox.width - CustomizedGenericDelimOffset(genericSymbol, radicalSignBox.totalHeight) * radicalSignBox.width; overBar.children[0].width += expansion; overBar.children[0].shift -= expansion; TexUtility.CentreBox(overBar); var radicalContainerBox = HorizontalBox.Get(radicalSignBox); radicalContainerBox.Add(overBar); // There is no generic root then ... return(radicalContainerBox); }
string TransparseRichTag(string head, string param) { if (param.Length > 1) { param = param.Substring(1); // Avoid the '=' } switch (head) { case "b": return("\\" + TexUtility.GetFontName(tex.fontIndex) + "[b]"); case "i": return("\\" + TexUtility.GetFontName(tex.fontIndex) + "[i]"); case "font": return("\\" + param); case "size": float sz = 1; if (float.TryParse(param, out sz)) { sz /= tex.size; } return("\\size[" + sz.ToString() + "]"); case "color": return("\\color[" + param + "]"); default: return(head); } }
Box CreateBoxDefault(TexStyle style, Box baseBox) { var factor = TexUtility.SizeFactor(style); var clearance = TEXConfiguration.main.RootMargin * factor; var lineThickness = TEXConfiguration.main.LineThickness * factor; // Create box for radical sign. var totalHeight = baseBox.totalHeight; var radicalSignBox = DelimiterFactory.CreateBox(rootSymbol, totalHeight + clearance + lineThickness, style); // Add some clearance to left and right side baseBox = HorizontalBox.Get(baseBox, baseBox.width + clearance * 2, TexAlignment.Center); // Add half of excess height to clearance. lineThickness = Mathf.Max(radicalSignBox.height, lineThickness); clearance = radicalSignBox.totalHeight - totalHeight - lineThickness * 2; // Create box for square-root containing base box. TexUtility.CentreBox(radicalSignBox, style); var overBar = OverBar.Get(baseBox, clearance, lineThickness); TexUtility.CentreBox(overBar, style); var radicalContainerBox = HorizontalBox.Get(radicalSignBox); radicalContainerBox.Add(overBar); // If atom is simple radical, just return square-root box. if (DegreeAtom == null) { return(radicalContainerBox); } // Atom is complex radical (nth-root). // Create box for root atom. var rootBox = DegreeAtom.CreateBox(TexUtility.GetRootStyle()); var bottomShift = scale * (radicalContainerBox.height + radicalContainerBox.depth); rootBox.shift = radicalContainerBox.depth - rootBox.depth - bottomShift; // Create result box. var resultBox = HorizontalBox.Get(); // Add box for negative kern. var negativeKern = SpaceAtom.Get(-((radicalSignBox.width) / 2f), 0, 0).CreateBox(TexStyle.Display); var xPos = rootBox.width + negativeKern.width; if (xPos < 0) { resultBox.Add(StrutBox.Get(-xPos, 0, 0, 0)); } resultBox.Add(rootBox); resultBox.Add(negativeKern); resultBox.Add(radicalContainerBox); return(resultBox); }
public override Box CreateBox(TexStyle style) { // CharacterInfo ch; var f = TEXPreference.main.fontData[fontIndex]; CharacterInfo info; var c = f.CreateCharacterDataOnTheFly(charIndex, TexUtility.SizeFactor(style), out info); return(UnicodeBox.Get(c, fontIndex, info)); }
public TexCharMetric GetCharMetric(TexChar Char, TexStyle style) { if (Char != null) { return(Char.GetMetric(TexUtility.SizeFactor(style))); } else { return(null); } }
Color32 ProcessFinalColor(Color32 old) { switch (mixMode) { case 1: return(TexUtility.MultiplyAlphaOnly(renderColor, old.a / 255f)); case 2: return(TexUtility.MultiplyColor(old, renderColor)); } return(renderColor); }
public override void Draw(DrawingContext drawingContext, float scale, float x, float y) { switch (mixmode) { case 0: TexContext.Color.Push(color); break; case 1: TexContext.Color.Push(TexUtility.MultiplyAlphaOnly(color, TexContext.Color.value.a / 255f)); break; case 2: TexContext.Color.Push(TexUtility.MultiplyColor(TexContext.Color.value, color)); break; case 3: TexContext.Color.Pop(); break; } }
public override void Draw(DrawingContext drawingContext, float scale, float x, float y) { base.Draw(drawingContext, scale, x, y); float padding = TEXConfiguration.main.LinkMargin; var tint = drawingContext.DrawLink( new Rect((x - padding / 2f) * scale, (y - depth - padding / 2f) * scale, (width + padding) * scale, (totalHeight + padding) * scale), metaKey); TexContext.Color.Push(TexUtility.MultiplyColor(TexContext.Color.value, tint)); baseBox.Draw(drawingContext, scale, x, y); TexContext.Color.Pop(); }
public override Box CreateBox(TexStyle style) { // Create box for base atom. var baseBox = BaseAtom == null ? StrutBox.Empty : BaseAtom.CreateBox(TexUtility.GetCrampedStyle(style)); // Find character of best scale for accent symbol. TexCharMetric accentChar = TEXPreference.main.GetCharMetric(AccentAtom.Name, style); while (accentChar.ch.nextLargerExist) { var nextLargerChar = TEXPreference.main.GetCharMetric(accentChar.ch.nextLarger, style); if (nextLargerChar.width > baseBox.width) { break; } accentChar = nextLargerChar; } var resultBox = VerticalBox.Get(); // Create and add box for accent symbol. var accentBox = CharBox.Get(style, accentChar); var accentWidth = (accentBox.bearing + accentBox.italic) * .5f; accentBox.italic = accentWidth + (accentBox.width * .5f); accentBox.bearing = accentWidth - (accentBox.width * .5f); //accentBox. = accentBox.width + accentBox.italic - accentBox.bearing; resultBox.Add((accentBox)); //var delta = Mathf.Min(-accentChar.depth, baseBox.height); resultBox.Add(StrutBox.Get(0, TEXConfiguration.main.AccentMargin * TexUtility.SizeFactor(style), 0, 0)); // Centre and add box for base atom. Centre base box and accent box with respect to each other. var boxWidthsDiff = (baseBox.width - accentBox.width) / 2f; accentBox.shift = Mathf.Max(boxWidthsDiff, 0); if (boxWidthsDiff < 0) { baseBox = HorizontalBox.Get(baseBox, accentBox.width, TexAlignment.Center); } resultBox.Add(baseBox); // Adjust height and depth of result box. var depth = baseBox.depth; var totalHeight = resultBox.height + resultBox.depth; resultBox.depth = depth; resultBox.height = totalHeight - depth; return(resultBox); }
public override Box CreateBox() { // Create box for base atom. TexContext.Environment.Push(TexUtility.GetCrampedStyle()); var baseBox = BaseAtom == null ? StrutBox.Empty : BaseAtom.CreateBox(); TexContext.Environment.Pop(); // Find character of best scale for accent symbol. var acct = TEXPreference.main.GetChar(AccentAtom.Name).GetMetric(); while (acct.width < baseBox.width && acct.ch.nextLargerExist) { acct.Flush(); acct = acct.ch.nextLarger.GetMetric(); } var resultBox = VerticalBox.Get(); // Create and add box for accent symbol. var accentWidth = (acct.bearing + acct.italic) * .5f; acct.italic = accentWidth + (acct.width * .5f); acct.bearing = accentWidth - (acct.width * .5f); resultBox.Add(acct); resultBox.Add(StrutBox.Get(0, TEXConfiguration.main.AccentMargin * TexContext.Scale, 0, 0)); // Centre and add box for base atom. Centre base box and accent box with respect to each other. var boxWidthsDiff = (baseBox.width - acct.width) / 2f; acct.shift = Mathf.Max(boxWidthsDiff, 0); if (boxWidthsDiff < 0) { baseBox = HorizontalBox.Get(baseBox, acct.width, TexAlignment.Center); } resultBox.Add(baseBox); // Adjust height and depth of result box. var depth = baseBox.depth; var totalHeight = resultBox.height + resultBox.depth; resultBox.depth = depth; resultBox.height = totalHeight - depth; return(resultBox); }
public override Box CreateBox(TexStyle style) { // Create box for base atom. var baseBox = BaseAtom == null ? StrutBox.Empty : BaseAtom.CreateBox(style); // Create boxes for over and under atoms. Box overBox = null, underBox = null; var maxWidth = baseBox.width; if (OverAtom != null) { overBox = OverAtom.CreateBox(OverScriptSmaller ? TexUtility.GetSuperscriptStyle(style) : style); maxWidth = Mathf.Max(maxWidth, overBox.width); } if (UnderAtom != null) { underBox = UnderAtom.CreateBox(UnderScriptSmaller ? TexUtility.GetSubscriptStyle(style) : style); maxWidth = Mathf.Max(maxWidth, underBox.width); } // Create result box. var resultBox = VerticalBox.Get(); // Create and add box for over atom. if (OverAtom != null) { resultBox.Add(ChangeWidth(overBox, maxWidth)); resultBox.Add(TexUtility.GetBox(SpaceAtom.Get(0, OverSpace, 0), style)); } // Add box for base atom. resultBox.Add(ChangeWidth(baseBox, maxWidth)); float totalHeight = resultBox.height + resultBox.depth - baseBox.depth; // Create and add box for under atom. if (UnderAtom != null) { resultBox.Add(TexUtility.GetBox(SpaceAtom.Get(0, UnderSpace, 0), style)); resultBox.Add(ChangeWidth(underBox, maxWidth)); } resultBox.depth = resultBox.height + resultBox.depth - totalHeight; resultBox.height = totalHeight; return(resultBox); }
public override Box CreateBox() { var width = size.x; var height = size.y; Box result; if (BaseAtom == null) { result = StrutBox.Get(width, height, 0, 0); } else if (BaseAtom is SpaceAtom) { result = StrutBox.Get(width, height, 0, 0); } else if (width == 0 && BaseAtom is SymbolAtom) { result = VerticalBox.Get(DelimiterFactory.CreateBox(((SymbolAtom)BaseAtom).Name, height), height, align); } else if (height == 0 && BaseAtom is SymbolAtom) { result = HorizontalBox.Get(DelimiterFactory.CreateBoxHorizontal(((SymbolAtom)BaseAtom).Name, width), width, align); } else if (width == 0) { result = VerticalBox.Get(BaseAtom.CreateBox(), height, align); } else if (height == 0) { result = HorizontalBox.Get(BaseAtom.CreateBox(), width, align); } else { result = VerticalBox.Get(HorizontalBox.Get(BaseAtom.CreateBox(), width, align), height, align); } if (size.x + size.y > 1e-3f) { TexUtility.CentreBox(result); } return(result); }
public override Box CreateBox(TexStyle style) { var result = HorizontalBox.Get(); var margin = TEXConfiguration.main.BackdropMargin * TexUtility.SizeFactor(style); var box = baseAtom.CreateBox(style); box = VerticalBox.Get(HorizontalBox.Get(box, box.width + (horizontalMargin ? margin * 2 : 0), TexAlignment.Center), box.totalHeight + margin * 2, TexAlignment.Center); var endColor = AttrColorBox.Get(0, color, null); var startColor = AttrColorBox.Get(0, color, endColor); var bg = HorizontalRule.Get(box.height, box.width, 0, box.depth, true); result.Add(startColor); result.Add(bg); result.Add(endColor); result.Add(StrutBox.Get(-box.width, 0, 0, 0)); result.Add(box); return(result); }
public override Box CreateBox(TexStyle style) { // Calculate minimum clearance amount. if (BaseAtom == null) { return(StrutBox.Empty); } // Create box for base atom, in cramped style. var baseBox = BaseAtom.CreateBox(TexUtility.GetCrampedStyle(style)); if (DegreeAtom is SymbolAtom && ((SymbolAtom)DegreeAtom).IsDelimiter) { return(CreateGenericRadicalBox(style, baseBox, ((SymbolAtom)DegreeAtom).Name)); } else { return(CreateBoxDefault(style, baseBox)); } }
public override void Draw(DrawingContext drawingContext, float scale, float x, float y) { base.Draw(drawingContext, scale, x, y); float padding = TEXConfiguration.main.LinkMargin; var tint = drawingContext.DrawLink( new Rect((x - padding / 2f) * scale, (y - depth - padding / 2f) * scale, (width + padding) * scale, (totalHeight + padding) * scale), metaKey); if (tint == TexUtility.white) { baseBox.Draw(drawingContext, scale, x, y); } else { var oldColor = TexUtility.RenderColor; var newColor = TexUtility.MultiplyColor(oldColor, tint); TexUtility.RenderColor = newColor; baseBox.Draw(drawingContext, scale, x, y); TexUtility.RenderColor = oldColor; } }
public override Box CreateBox() { // Create box for base atom. Box baseBox; float delta; if (BaseAtom is SymbolAtom && BaseAtom.Type == CharType.BigOperator) { // Find character of best scale for operator symbol. var opChar = TEXPreference.main.GetChar(((SymbolAtom)BaseAtom).Name).GetMetric(); if (TexContext.Environment.value < TexEnvironment.Text && opChar.ch.nextLargerExist) { opChar.Flush(); opChar = opChar.ch.nextLarger.GetMetric(); } opChar.shift = -(opChar.height + opChar.depth) / 2; baseBox = HorizontalBox.Get(opChar); delta = opChar.bearing; } else { baseBox = HorizontalBox.Get(BaseAtom == null ? StrutBox.Empty : BaseAtom.CreateBox()); delta = 0; } // Create boxes for upper and lower limits. Box upperLimitBox, lowerLimitBox; TexContext.Environment.Push(MakeSuperScripts ? TexEnvironment.ScriptScript : TexUtility.GetSuperscriptStyle()); if (UpperLimitAtom is SymbolAtom) { upperLimitBox = DelimiterFactory.CreateBoxHorizontal(((SymbolAtom)UpperLimitAtom).Name, baseBox.width); } else { upperLimitBox = UpperLimitAtom == null ? null : UpperLimitAtom.CreateBox(); } TexContext.Environment.Pop(); TexContext.Environment.Push(MakeSuperScripts ? TexEnvironment.ScriptScript : TexUtility.GetSubscriptStyle()); if (LowerLimitAtom is SymbolAtom) { lowerLimitBox = DelimiterFactory.CreateBoxHorizontal(((SymbolAtom)LowerLimitAtom).Name, baseBox.width); } else { lowerLimitBox = LowerLimitAtom == null ? null : LowerLimitAtom.CreateBox(); } TexContext.Environment.Pop(); // Make all component boxes equally wide. var maxWidth = Mathf.Max(Mathf.Max(baseBox.width, upperLimitBox == null ? 0 : upperLimitBox.width), lowerLimitBox == null ? 0 : lowerLimitBox.width); if (baseBox != null) { baseBox = ChangeWidth(baseBox, maxWidth); } if (upperLimitBox != null) { upperLimitBox = ChangeWidth(upperLimitBox, maxWidth); } if (lowerLimitBox != null) { lowerLimitBox = ChangeWidth(lowerLimitBox, maxWidth); } var resultBox = VerticalBox.Get(); var opSpacing5 = TEXConfiguration.main.BigOpMargin * TexContext.Scale; var kern = 0f; // Create and add box for upper limit. if (UpperLimitAtom != null) { resultBox.Add(StrutBox.Get(0, opSpacing5, 0, 0)); upperLimitBox.shift = delta / 2; upperLimitBox.shift += TopOffset(BaseAtom); resultBox.Add(upperLimitBox); kern = Mathf.Max(TEXConfiguration.main.BigOpUpShift * TexContext.Scale, TEXConfiguration.main.BigOpUpperGap * TexContext.Scale - upperLimitBox.depth); resultBox.Add(StrutBox.Get(0, kern, 0, 0)); } // Add box for base atom. resultBox.Add(baseBox); // Create and add box for lower limit. if (LowerLimitAtom != null) { resultBox.Add(StrutBox.Get(0, Mathf.Max(TEXConfiguration.main.BigOpLowShift * TexContext.Scale, TEXConfiguration.main.BigOpLowerGap * TexContext.Scale - lowerLimitBox.height), 0, 0)); lowerLimitBox.shift = -delta / 2; lowerLimitBox.shift += BottomOffset(BaseAtom); resultBox.Add(lowerLimitBox); resultBox.Add(StrutBox.Get(0, opSpacing5, 0, 0)); } // Adjust height and depth of result box. var baseBoxHeight = baseBox.height; var totalHeight = resultBox.height + resultBox.depth; if (upperLimitBox != null) { baseBoxHeight += opSpacing5 + kern + upperLimitBox.height + upperLimitBox.depth; } resultBox.height = baseBoxHeight; resultBox.depth = totalHeight - baseBoxHeight; return(resultBox); }
public override Box CreateBox(TexStyle style) { var pref = TEXPreference.main; var font = FontIndex == -2 ? TexUtility.RenderFont : FontIndex; var FStyle = FontStyle == TexUtility.FontStyleDefault ? TexUtility.RenderFontStyle : FontStyle; if (font >= 0 && !pref.IsCharAvailable(font, Character)) { // It's unicode, do return Unicode CharacterInfo info; var c = pref.fontData[font].CreateCharacterDataOnTheFly(Character, TexUtility.SizeFactor(style), out info); return(UnicodeBox.Get(c, font, info)); } else { if (font == -1) { //var chSymbol = pref.charMapData[Character, -1]; //if (chSymbol == -1) return(CharBox.Get(style, pref.GetCharMetric(Character, style), FStyle)); } else { return(CharBox.Get(style, pref.GetCharMetric(font, Character, style), FStyle)); } } }
public static void CentreBox(Box box, TexStyle style) { float axis = TEXConfiguration.main.AxisHeight * TexUtility.SizeFactor(style); box.shift = (box.height - box.depth) / 2 - axis; }
public Box GenerateDelimiterBox(HorizontalBox result, ref int elementPos, ref int resultPos, TexStyle style) { var curAtom = Elements[elementPos]; if (!(curAtom is CharSymbol) || !((CharSymbol)curAtom).IsDelimiter) { // This is not delimiter, hence just create and do nothing. var box = curAtom.CreateBox(style); if (curAtom.Type == CharType.BigOperator) { TexUtility.CentreBox(box, style); } result.Add(resultPos, box); lastGeneratedBox = box; resultPos++; return(box); } var nextAtom = elementPos + 1 < Elements.Count ? Elements[elementPos + 1] : null; var prevAtom = elementPos > 0 ? Elements[elementPos - 1] : null; var minHeight = 0f; var ourPos = resultPos; if (nextAtom != null && curAtom.GetRightType() == CharType.OpenDelimiter) { elementPos++; var nextBox = GenerateDelimiterBox(result, ref elementPos, ref resultPos, style); minHeight = nextBox.totalHeight; } else if (lastGeneratedBox != null && curAtom.GetLeftType() == CharType.CloseDelimiter) { var prevBox = lastGeneratedBox; minHeight = prevBox.totalHeight; } else { if (prevAtom != null && lastGeneratedBox != null) { var prevBox = lastGeneratedBox; minHeight = prevBox.totalHeight; } if (nextAtom != null) { elementPos++; var nextBox = GenerateDelimiterBox(result, ref elementPos, ref resultPos, style); minHeight = Mathf.Max(nextBox.totalHeight, minHeight); } } var curBox = curAtom is SymbolAtom ? (((SymbolAtom)curAtom).CreateBox(style, minHeight)) : curAtom.CreateBox(style); TexUtility.CentreBox(curBox, style); result.Add(ourPos, curBox); if (ourPos == resultPos) { lastGeneratedBox = curBox; } resultPos++; return(curBox); }
public override Box CreateBox() { // Create box for base atom. // Save it shift and use it later // Create result box. // Set delta value and preliminary shift-up and shift-down amounts depending on type of base atom. float shiftUp = 0, shiftDown = 0; Box baseBox; HorizontalBox resultBox; if (SubscriptAtom == null && SuperscriptAtom == null) { return(BaseAtom == null ? StrutBox.Empty : BaseAtom.CreateBox()); } if (BaseAtom is AccentedAtom) { TexContext.Environment.Push(TexUtility.GetCrampedStyle()); baseBox = ((AccentedAtom)BaseAtom).BaseAtom.CreateBox(); TexContext.Environment.Pop(); } else { baseBox = (BaseAtom == null ? StrutBox.Empty : BaseAtom.CreateBox()); //if (BaseAtom is CharSymbol) //{ // var delta = 0f; // var ch = ((CharSymbol)BaseAtom).GetChar(); // if (!((CharSymbol)BaseAtom).IsTextSymbol) // delta = ch.italix + bearing - width; // if (delta > TexUtility.FloatPrecision && SubscriptAtom == null) // { // resultBox.Add(StrutBox.Get(delta, 0, 0, 0)); // delta = 0; // } //} } resultBox = HorizontalBox.Get(baseBox); var shift = baseBox.shift; Box superscriptBox = null; HorizontalBox superscriptContainerBox = null; Box subscriptBox = null; HorizontalBox subscriptContainerBox = null; TexContext.Environment.Push(TexUtility.GetSuperscriptStyle()); shiftUp = baseBox.height - TEXConfiguration.main.SupDrop * TexContext.Scale; if (SuperscriptAtom != null) { // Create box for superscript atom. superscriptBox = SuperscriptAtom.CreateBox(); superscriptContainerBox = HorizontalBox.Get(superscriptBox); // Add box for script space. superscriptContainerBox.Add(scriptSpaceAtom.CreateBox()); // Adjust shift-up amount. float p; if (TexContext.Environment.value == TexEnvironment.Display) { p = TEXConfiguration.main.SupMin * TexContext.Scale; } else { p = TEXConfiguration.main.SupMinNarrow * TexContext.Scale; } shiftUp = Mathf.Max(shiftUp, p); } TexContext.Environment.Pop(); TexContext.Environment.Push(TexUtility.GetSubscriptStyle()); shiftDown = baseBox.depth + TEXConfiguration.main.SubDrop * TexContext.Scale; if (SubscriptAtom != null) { // Create box for subscript atom. subscriptBox = SubscriptAtom.CreateBox(); subscriptContainerBox = HorizontalBox.Get(subscriptBox); // Add box for script space. subscriptContainerBox.Add(scriptSpaceAtom.CreateBox()); } TexContext.Environment.Pop(); // Check if only superscript is set. if (subscriptBox == null) { superscriptContainerBox.shift = -shiftUp; resultBox.Add(superscriptContainerBox); resultBox.height = shiftUp + superscriptBox.height; return(resultBox); } // Check if only subscript is set. if (superscriptBox == null) { subscriptBox.shift = Mathf.Max(shiftDown, TEXConfiguration.main.SubMinNoSup * TexContext.Scale); resultBox.Add(subscriptContainerBox); resultBox.depth = shiftDown + subscriptBox.depth; return(resultBox); } // Adjust shift-down amount. shiftDown = Mathf.Max(shiftDown, TEXConfiguration.main.SubMinOnSup * TexContext.Scale); // Space between subscript and superscript. float scriptsInterSpace = shiftUp - superscriptBox.depth + shiftDown - subscriptBox.height; scriptsInterSpace = shiftUp - superscriptBox.depth + shiftDown - subscriptBox.height; // If baseAtom is null, make it right-aligned if (BaseAtom is SpaceAtom && ((SpaceAtom)BaseAtom).policy == StrutPolicy.Misc) { var max = Mathf.Max(superscriptContainerBox.width, subscriptContainerBox.width); if (superscriptContainerBox.width < max) { superscriptContainerBox.Add(0, StrutBox.Get(max - superscriptContainerBox.width, 0, 0, 0)); } if (subscriptContainerBox.width < max) { subscriptContainerBox.Add(0, StrutBox.Get(max - subscriptContainerBox.width, 0, 0, 0)); } } // Create box containing both superscript and subscript. var scriptsBox = VerticalBox.Get(); scriptsBox.Add(superscriptContainerBox); scriptsBox.Add(StrutBox.Get(0, scriptsInterSpace, 0, 0)); scriptsBox.Add(subscriptContainerBox); scriptsBox.height = shiftUp + superscriptBox.height; scriptsBox.depth = shiftDown + subscriptBox.depth; scriptsBox.shift = shift; resultBox.Add(scriptsBox); return(resultBox); }
public override Box CreateBox(TexStyle style) { // Create box for base atom. var baseBox = (BaseAtom == null ? StrutBox.Empty : BaseAtom.CreateBox(style)); if (SubscriptAtom == null && SuperscriptAtom == null) { return(baseBox); } // Save it shift and use it later var shift = baseBox.shift; // Create result box. var resultBox = HorizontalBox.Get(baseBox); var subscriptStyle = TexUtility.GetSubscriptStyle(style); var superscriptStyle = TexUtility.GetSuperscriptStyle(style); // Set delta value and preliminary shift-up and shift-down amounts depending on type of base atom. var delta = 0f; float shiftUp, shiftDown; if (BaseAtom is AccentedAtom) { var accentedBox = ((AccentedAtom)BaseAtom).BaseAtom.CreateBox(TexUtility.GetCrampedStyle(style)); shiftUp = accentedBox.height - TEXConfiguration.main.SupDrop * TexUtility.SizeFactor(superscriptStyle); shiftDown = accentedBox.depth + TEXConfiguration.main.SubDrop * TexUtility.SizeFactor(subscriptStyle); } else if (BaseAtom is CharSymbol) { var charFont = ((CharSymbol)BaseAtom).GetChar(); if (!((CharSymbol)BaseAtom).IsTextSymbol) { delta = TEXPreference.main.GetCharMetric(charFont, style).advanceDelta; } if (delta > TexUtility.FloatPrecision && SubscriptAtom == null) { resultBox.Add(StrutBox.Get(delta, 0, 0, 0)); delta = 0; } shiftUp = baseBox.height - TEXConfiguration.main.SupDrop * TexUtility.SizeFactor(superscriptStyle); shiftDown = baseBox.depth + TEXConfiguration.main.SubDrop * TexUtility.SizeFactor(subscriptStyle); } else { shiftUp = baseBox.height - TEXConfiguration.main.SupDrop * TexUtility.SizeFactor(superscriptStyle); shiftDown = baseBox.depth + TEXConfiguration.main.SubDrop * TexUtility.SizeFactor(subscriptStyle); } Box superscriptBox = null; Box superscriptContainerBox = null; Box subscriptBox = null; Box subscriptContainerBox = null; if (SuperscriptAtom != null) { // Create box for superscript atom. superscriptBox = SuperscriptAtom.CreateBox(superscriptStyle); superscriptContainerBox = HorizontalBox.Get(superscriptBox); // Add box for script space. superscriptContainerBox.Add(scriptSpaceAtom.CreateBox(style)); // Adjust shift-up amount. float p; if (style == TexStyle.Display) { p = TEXConfiguration.main.SupMin * TexUtility.SizeFactor(style); } else // if (TexUtility.GetCrampedStyle (style) == style) { p = TEXConfiguration.main.SupMinNarrow * TexUtility.SizeFactor(style); } //else // p = TEXConfiguration.main.SupMinNarrow * TexUtility.SizeFactor(style); shiftUp = Mathf.Max(shiftUp, p); } if (SubscriptAtom != null) { // Create box for subscript atom. subscriptBox = SubscriptAtom.CreateBox(subscriptStyle); subscriptContainerBox = HorizontalBox.Get(subscriptBox); // Add box for script space. subscriptContainerBox.Add(scriptSpaceAtom.CreateBox(style)); } // Check if only superscript is set. if (subscriptBox == null) { superscriptContainerBox.shift = -shiftUp; resultBox.Add(superscriptContainerBox); resultBox.height = shiftUp + superscriptBox.height; return(resultBox); } // Check if only subscript is set. if (superscriptBox == null) { subscriptBox.shift = Mathf.Max(shiftDown, TEXConfiguration.main.SubMinNoSup * TexUtility.SizeFactor(style)); resultBox.Add(subscriptContainerBox); resultBox.depth = shiftDown + subscriptBox.depth; return(resultBox); } // Adjust shift-down amount. shiftDown = Mathf.Max(shiftDown, TEXConfiguration.main.SubMinOnSup * TexUtility.SizeFactor(style)); // Space between subscript and superscript. float scriptsInterSpace = shiftUp - superscriptBox.depth + shiftDown - subscriptBox.height; /*if (scriptsInterSpace < 4 * defaultLineThickness) * { * shiftUp += 4 * defaultLineThickness - scriptsInterSpace; * * // Position bottom of superscript at least 4/5 of X-height above baseline. * float psi = 0.8f * TexUtility.SizeFactor(style) - (shiftUp - superscriptBox.depth); * if (psi > 0) * { * shiftUp += psi; * shiftDown -= psi; * } * }*/ scriptsInterSpace = shiftUp - superscriptBox.depth + shiftDown - subscriptBox.height; // If baseAtom is null, make it right-aligned if (BaseAtom is SpaceAtom && ((SpaceAtom)BaseAtom).policy == StrutPolicy.Misc) { var max = Mathf.Max(superscriptContainerBox.width, subscriptContainerBox.width); if (superscriptContainerBox.width < max) { superscriptContainerBox.Add(0, StrutBox.Get(max - superscriptContainerBox.width, 0, 0, 0)); } if (subscriptContainerBox.width < max) { subscriptContainerBox.Add(0, StrutBox.Get(max - subscriptContainerBox.width, 0, 0, 0)); } } // Create box containing both superscript and subscript. var scriptsBox = VerticalBox.Get(); scriptsBox.Add(superscriptContainerBox); scriptsBox.Add(StrutBox.Get(0, scriptsInterSpace, 0, 0)); scriptsBox.Add(subscriptContainerBox); scriptsBox.height = shiftUp + superscriptBox.height; scriptsBox.depth = shiftDown + subscriptBox.depth; scriptsBox.shift = shift; resultBox.Add(scriptsBox); return(resultBox); }
public TexCharMetric GetCharMetric(string symbol, TexStyle style) { return(GetChar(symbol).GetMetric(TexUtility.SizeFactor(style))); }
public static RotatedCharBox Get(TexStyle style, TexCharMetric Char, FontStyle fontStyle) { var box = ObjPool <RotatedCharBox> .Get(); if (Char == null) { throw new NullReferenceException(); } box.character = Char; //I can't say more but our cached glyph is slightly incorrect because //the usage of int in character Info, so we need to... var font = Char.ch.font; if (font.type == TexFontType.Font && Char.ch.supported) { CharacterInfo c; if (DrawingContext.GetCharInfo(font.Font_Asset, Char.ch.characterIndex, (int)(TexUtility.RenderTextureSize * Char.appliedScale) + 1, TexUtility.TexStyle2FontStyle(fontStyle), out c)) { float ratio = (c.size == 0 ? (float)TexUtility.RenderTextureSize : c.size) / Char.appliedScale; //Swap XY box.bearing = 0; box.italic = (c.maxY - c.minY) / ratio; box.depth = c.maxX / ratio; box.height = (-c.minX) / ratio; //No kerning applied? box.width = box.italic; box.c = c; return(box); } } box.bearing = 0; box.italic = Char.height + Char.depth; box.depth = 0; box.height = Char.italic + Char.bearing; box.width = box.italic; return(box); }
public Box GenerateDelimiterBox(HorizontalBox result, ref int elementPos, ref int resultPos) { var curAtom = Elements[elementPos]; if (!(curAtom is CharSymbol) || !((CharSymbol)curAtom).IsDelimiter) { // This is not delimiter, hence just create and do nothing. var box = curAtom.CreateBox(); if (curAtom.Type == CharType.BigOperator) // specific patch to BigOperator { TexUtility.CentreBox(box); } if (box is HorizontalBox && (curAtom is AttrSizeAtom || curAtom is AttrStyleAtom)) // specific patch to Atoms that should be wrappable. { var h = box as HorizontalBox; result.AddRange(h, resultPos); resultPos += h.children.Count; } else { result.Add(resultPos++, box); } lastGeneratedBox = box; return(box); } var nextAtom = elementPos + 1 < Elements.Count ? Elements[elementPos + 1] : null; var prevAtom = elementPos > 0 ? Elements[elementPos - 1] : null; var minHeight = 0f; var ourPos = resultPos; if (nextAtom != null && curAtom.RightType == CharType.OpenDelimiter) { elementPos++; var nextBox = GenerateDelimiterBox(result, ref elementPos, ref resultPos); minHeight = nextBox.totalHeight; } else if (lastGeneratedBox != null && curAtom.LeftType == CharType.CloseDelimiter) { var prevBox = lastGeneratedBox; minHeight = prevBox.totalHeight; } else { if (prevAtom != null && lastGeneratedBox != null) { var prevBox = lastGeneratedBox; minHeight = prevBox.totalHeight; } if (nextAtom != null) { elementPos++; var nextBox = GenerateDelimiterBox(result, ref elementPos, ref resultPos); minHeight = Mathf.Max(nextBox.totalHeight, minHeight); } } var curBox = curAtom is SymbolAtom ? (((SymbolAtom)curAtom).CreateBox(minHeight)) : curAtom.CreateBox(); TexUtility.CentreBox(curBox); result.Add(ourPos, curBox); if (ourPos == resultPos) { lastGeneratedBox = curBox; } resultPos++; return(curBox); }
public TexCharMetric GetCharMetric(int font, char ch, TexStyle style) { return(fontData[font].GetCharacterData(ch).GetMetric(TexUtility.SizeFactor(style))); }
public override Box CreateBox() { List <List <Box> > boxes = ListPool <List <Box> > .Get(); List <float> boxesHeight = ListPool <float> .Get(); List <float> boxesShift = ListPool <float> .Get(); List <float> boxesWidth = ListPool <float> .Get(); TexContext.Environment.Push(TexUtility.GetCrampedStyle()); float padding = TEXConfiguration.main.MatrixMargin * TexContext.Scale; for (int i = 0; i < Elements.Count; i++) { boxes.Add(ListPool <Box> .Get()); float h = 0f, d = 0f; for (int j = 0; j < Elements[i].Count; j++) { Box box; if (Elements[i][j] != null) { box = (Elements[i][j].CreateBox()); } else { box = (ObjPool <StrutBox> .Get()); } boxes[i].Add(box); if (j >= boxesWidth.Count) { boxesWidth.Add(box.width); } else { boxesWidth[j] = Mathf.Max(boxesWidth[j], box.width); } h = Mathf.Max(h, box.height); d = Mathf.Max(d, box.depth); } boxesHeight.Add(Mathf.Max(h + d, padding / 2f)); boxesShift.Add(h); } bool outsideGap = (horizontalLine > 0 && (enumContains(horizontalLine, 0) || enumContains(horizontalLine, 4))) || (verticalLine > 0 && (enumContains(verticalLine, 0) || enumContains(verticalLine, 4))); var vBox = VerticalBox.Get(); Box resultBox = vBox; Box kern = null; Box kernHalf = null; if (boxesWidth.Count > 1 || boxesHeight.Count > 1) { kern = StrutBox.Get(padding, padding, 0, 0); } if (outsideGap) { kernHalf = StrutBox.Get(padding / 2f, padding / 2f, 0, 0); vBox.Add(kernHalf); } TexAlignment firstRowH = alterH(horizontalAlign % 8); TexAlignment firstRowV = alterV(verticalAlign % 8); TexAlignment firstColH = alterH((horizontalAlign >> 3) % 8); TexAlignment firstColV = alterV((verticalAlign >> 3) % 8); TexAlignment bodyH = alterH((horizontalAlign >> 6) % 8); TexAlignment bodyV = alterV((verticalAlign >> 6) % 8); for (int i = 0; i < Elements.Count; i++) { var list = HorizontalBox.Get(); if (outsideGap) { list.Add(kernHalf); } for (int j = 0; j < Elements[i].Count; j++) { if (i == 0) { list.Add(VerticalBox.Get(HorizontalBox.Get(boxes[i][j], boxesWidth[j], firstRowH), boxesHeight[i], firstRowV)); } else if (j == 0) { list.Add(VerticalBox.Get(HorizontalBox.Get(boxes[i][j], boxesWidth[j], firstColH), boxesHeight[i], firstColV)); } else { list.Add(VerticalBox.Get(HorizontalBox.Get(boxes[i][j], boxesWidth[j], bodyH), boxesHeight[i], bodyV)); } if (j < Elements[i].Count - 1) { list.Add(kern); } else if (outsideGap) { list.Add(kernHalf); } } list.depth = boxesHeight[i] - list.height; vBox.Add(list); if (i < Elements.Count - 1) { vBox.Add(kern); } else if (outsideGap) { vBox.Add(kernHalf); } } var lineThick = TEXConfiguration.main.LineThickness * TexContext.Scale; //Add horizontal lines for table if (horizontalLine > 0) { var outside = enumContains(horizontalLine, 0); var first = enumContains(horizontalLine, 1); var inset = enumContains(horizontalLine, 2); var firstThick = enumContains(horizontalLine, 3); var outsideThick = enumContains(horizontalLine, 4); float gapX = (padding - lineThick); float gapXThick = (padding - (lineThick * 2)); float gapXNone = (padding); float gapOutside = (outside ? (outsideThick ? gapXThick : gapX) : gapXNone); float gapInset = (inset ? gapX : gapXNone); float lineOutside = outsideThick ? lineThick * 2 : lineThick; var insideBox = resultBox; var hBox = HorizontalBox.Get(resultBox); resultBox = hBox; if (outsideGap) { hBox.Add(StrutBox.Get(-insideBox.width - lineOutside / 2f, 0, 0, 0)); } else { hBox.Add(StrutBox.Get(-insideBox.width - lineOutside * 1.5f, 0, 0, 0)); } for (int i = 0; i < boxesWidth.Count; i++) { if (i == 0) { if (outside) { hBox.Add(HorizontalRule.Get(insideBox.height, lineOutside, 0, insideBox.depth)); } hBox.Add(StrutBox.Get(boxesWidth[i] + gapOutside, 0, 0, 0)); continue; } if (i == 1) { if (first) { hBox.Add(HorizontalRule.Get(insideBox.height, firstThick ? lineThick * 2 : lineThick, 0, insideBox.depth)); } hBox.Add(StrutBox.Get(boxesWidth[i] + (first ? (firstThick ? gapXThick : gapX) : gapXNone), 0, 0, 0)); continue; } if (inset) { hBox.Add(HorizontalRule.Get(insideBox.height, lineThick, 0, insideBox.depth)); } hBox.Add(StrutBox.Get(boxesWidth[i] + gapInset, 0, 0, 0)); } if (outside) { hBox.Add(HorizontalRule.Get(insideBox.height, lineOutside, 0, insideBox.depth)); } } if (verticalLine > 0) { var outside = enumContains(verticalLine, 0); var first = enumContains(verticalLine, 1); var inset = enumContains(verticalLine, 2); var firstThick = enumContains(verticalLine, 3); var outsideThick = enumContains(verticalLine, 4); float gapX = (padding - lineThick); float gapXThick = (padding - (lineThick * 2)); float gapXNone = (padding); float gapOutside = (outside ? (outsideThick ? gapXThick : gapX) : gapXNone); float gapInset = (inset ? gapX : gapXNone); float lineOutside = outsideThick ? lineThick * 2 : lineThick; var insideBox = resultBox; var size = insideBox.width; vBox = VerticalBox.Get(resultBox); resultBox = vBox; if (outsideGap) { vBox.Add(StrutBox.Get(0, -insideBox.totalHeight - lineOutside / 2f, 0, 0)); } else { vBox.Add(StrutBox.Get(0, -insideBox.totalHeight, 0, 0)); } for (int i = 0; i < boxesHeight.Count; i++) { if (i == 0) { if (outside) { vBox.Add(HorizontalRule.Get(lineOutside, size, 0)); } vBox.Add(StrutBox.Get(0, boxesHeight[i] + (outsideGap ? gapOutside : gapOutside / 2f), 0, 0)); } else if (i == 1) { if (first) { vBox.Add(HorizontalRule.Get(firstThick ? lineThick * 2 : lineThick, size, 0)); } var thick = (first ? (firstThick ? gapXThick : gapX) : gapXNone); vBox.Add(StrutBox.Get(0, boxesHeight[i] + (boxesHeight.Count == 2 && !outsideGap ? thick / 2f : thick), 0, 0)); } else { if (inset) { vBox.Add(HorizontalRule.Get(lineThick, size, 0)); } vBox.Add(StrutBox.Get(0, boxesHeight[i] + (i < boxesHeight.Count - 1 || outsideGap ? gapInset : gapInset / 2f), 0, 0)); } } if (outside && outsideGap) { vBox.Add(HorizontalRule.Get(lineOutside, size, 0, 0)); } } TexUtility.CentreBox(resultBox); TexContext.Environment.Pop(); //Clear resources ListPool <float> .Release(boxesHeight); ListPool <float> .Release(boxesWidth); ListPool <float> .Release(boxesShift); for (int i = 0; i < boxes.Count; i++) { ListPool <Box> .ReleaseNoFlush(boxes[i]); } ListPool <List <Box> > .ReleaseNoFlush(boxes); return(resultBox); }
public override Box CreateBox(TexStyle style) { float lineHeight = lineThickness * TexUtility.SizeFactor(style); // Create boxes for numerator and demoninator atoms, and make them of equal width. var numeratorBox = numerator == null ? StrutBox.Empty : numerator.CreateBox(TexUtility.GetNumeratorStyle(style)); var denominatorBox = denominator == null ? StrutBox.Empty : denominator.CreateBox(TexUtility.GetDenominatorStyle(style)); float maxWidth = (numeratorBox.width < denominatorBox.width ? denominatorBox.width : numeratorBox.width) + TEXConfiguration.main.FractionMargin * TexUtility.SizeFactor(style); numeratorBox = HorizontalBox.Get(numeratorBox, maxWidth, numeratorAlignment); denominatorBox = HorizontalBox.Get(denominatorBox, maxWidth, denominatorAlignment); // Calculate preliminary shift-up and shift-down amounts. float shiftUp, shiftDown; var styleFactor = TexUtility.SizeFactor(style); if (style >= TexStyle.Text) { styleFactor *= TEXConfiguration.main.FractionNarrowFactor; } shiftUp = TEXConfiguration.main.NumeratorShift * styleFactor; shiftDown = TEXConfiguration.main.DenominatorShift * styleFactor; // Create result box. var resultBox = VerticalBox.Get(); // add box for numerator. resultBox.Add(numeratorBox); // Calculate clearance and adjust shift amounts. //var axis = TEXConfiguration.main.AxisHeight * TexUtility.SizeFactor(style); // Calculate clearance amount. float clearance = lineHeight > 0 ? TEXConfiguration.main.FractionGap : TEXConfiguration.main.FractionGapNoLine; // Adjust shift amounts. var kern1 = shiftUp - numeratorBox.depth; var kern2 = shiftDown - denominatorBox.height; var delta1 = clearance - kern1; var delta2 = clearance - kern2; if (delta1 > 0) { shiftUp += delta1; kern1 += delta1; } if (delta2 > 0) { shiftDown += delta2; kern2 += delta2; } if (lineHeight > 0) { // Draw fraction line. resultBox.Add(StrutBox.Get(0, kern1, 0, 0)); resultBox.Add(HorizontalRule.Get(lineHeight, numeratorBox.width, 0)); resultBox.Add(StrutBox.Get(0, kern2, 0, 0)); } else { // Do not draw fraction line. var kern = kern1 + kern2; resultBox.Add(StrutBox.Get(0, kern, 0, 0)); } // add box for denominator. resultBox.Add(denominatorBox); // Adjust height and depth of result box. resultBox.height = shiftUp + numeratorBox.height; resultBox.depth = shiftDown + lineHeight + denominatorBox.depth; TexUtility.CentreBox(resultBox, style); return(resultBox); }