public FractionAtom(Atom numerator, Atom denominator, TexUnit unit, double thickness, TexAlignment numeratorAlignment, TexAlignment denominatorAlignment) : this(numerator, denominator, unit, thickness) { this.numeratorAlignment = CheckAlignment(numeratorAlignment); this.denominatorAlignment = CheckAlignment(denominatorAlignment); }
public HorizontalBox(Box box, double width, TexAlignment alignment) : this() { var extraWidth = width - box.Width; switch (alignment) { case TexAlignment.Center: var strutBox = new StrutBox(extraWidth / 2, 0, 0, 0); Add(strutBox); Add(box); Add(strutBox); break; case TexAlignment.Left: Add(box); Add(new StrutBox(extraWidth, 0, 0, 0)); break; case TexAlignment.Right: Add(new StrutBox(extraWidth, 0, 0, 0)); Add(box); break; } }
public static VerticalBox Get(Box Box, float Height, TexAlignment Alignment) { var box = Get(); if (Box.totalHeight >= Height) { box.Add(Box); return(box); } float rest = Height - Box.totalHeight;// Mathf.Max(Box.totalHeight - box.height, 0); if (Alignment == TexAlignment.Center) { var strutBox = StrutBox.Get(0, rest * 0.5f, 0, 0); box.Add(strutBox); box.Add(Box); box.Add(strutBox); box.Shift(Box.height); } else if (Alignment == TexAlignment.Top) { box.Add(Box); box.Add(StrutBox.Get(0, rest, 0, 0)); } else if (Alignment == TexAlignment.Bottom) { box.Add(StrutBox.Get(0, rest, 0, 0)); box.Add(Box); box.Shift(-rest + Box.height); } return(box); }
public FractionAtom(Atom numerator, Atom denominator, bool drawLine, TexAlignment numeratorAlignment, TexAlignment denominatorAlignment) : this(numerator, denominator, drawLine) { this.numeratorAlignment = CheckAlignment(numeratorAlignment); this.denominatorAlignment = CheckAlignment(denominatorAlignment); }
public static HolderAtom Get(Atom baseAtom, string size, bool vertical, TexAlignment Alignment) { Vector2 sz = new Vector2(); if (size != null) { int idx = size.IndexOf(','); if (idx >= 0) { var sizeL = size.Substring(0, idx); var sizeR = size.Substring(idx + 1); float.TryParse(sizeL, out sz.x); float.TryParse(sizeR, out sz.y); } else { if (vertical) { float.TryParse(size, out sz.y); } else { float.TryParse(size, out sz.x); } } } return(Get(baseAtom, sz, Alignment)); }
static void holdP(string prefix, ref bool isVertical, ref TexAlignment align) { if (prefix.Length > 0) { switch (prefix[0]) { case 'v': isVertical = true; break; case 'l': align = TexAlignment.Left; break; case 'r': align = TexAlignment.Right; break; case 'b': align = TexAlignment.Bottom; goto case 'v'; case 't': align = TexAlignment.Top; goto case 'v'; } } }
public static HorizontalBox Get(Box box, float width, TexAlignment alignment) { var Box = Get(); if (box.width >= width) { Box.Add(box); return(Box); } var extrawidth = Mathf.Max(width - box.width, 0); if (alignment == TexAlignment.Center) { var strutBox = StrutBox.Get(extrawidth / 2f, 0, 0, 0); Box.Add(strutBox); Box.Add(box); Box.Add(strutBox); } else if (alignment == TexAlignment.Left) { Box.Add(box); Box.Add(StrutBox.Get(extrawidth, 0, 0, 0)); } else if (alignment == TexAlignment.Right) { Box.Add(StrutBox.Get(extrawidth, 0, 0, 0)); Box.Add(box); } return(Box); }
private static TexAlignment CheckAlignment(TexAlignment alignment) { if (alignment == TexAlignment.Left || alignment == TexAlignment.Right) { return(alignment); } return(TexAlignment.Center); }
public static HolderAtom Get(Atom baseAtom, Vector2 size, TexAlignment Alignment) { var atom = ObjPool <HolderAtom> .Get(); atom.BaseAtom = baseAtom; atom.size = size; atom.align = Alignment; atom.Type = CharTypeInternal.Inner; return(atom); }
public FractionAtom( SourceSpan source, Atom numerator, Atom denominator, double relativeThickness, TexAlignment numeratorAlignment, TexAlignment denominatorAlignment) : this(source, numerator, denominator, true, numeratorAlignment, denominatorAlignment) { this.lineRelativeThickness = relativeThickness; }
public static HolderAtom Get(Atom baseAtom, float Width, float Height, TexAlignment Alignment) { var atom = ObjPool <HolderAtom> .Get(); atom.BaseAtom = baseAtom; atom.size = new Vector2(Width, Height); atom.align = Alignment; atom.Type = CharTypeInternal.Inner; return(atom); }
public FractionAtom( SourceSpan?source, Atom?numerator, Atom?denominator, bool drawLine, TexAlignment numeratorAlignment, TexAlignment denominatorAlignment) : this(source, numerator, denominator, drawLine) { this.numeratorAlignment = CheckAlignment(numeratorAlignment); this.denominatorAlignment = CheckAlignment(denominatorAlignment); }
public void AddFraction(TexFormula numerator, TexFormula denominator, bool drawLine, TexAlignment numeratorAlignment, TexAlignment denominatorAlignment) { this.Add( new FractionAtom( null, numerator?.RootAtom, denominator?.RootAtom, drawLine, numeratorAlignment, denominatorAlignment)); }
protected FractionAtom(Atom numerator, Atom denominator, bool useDefaultThickness, TexUnit unit, double thickness) { SpaceAtom.CheckUnit(unit); this.Type = TexAtomType.Inner; this.Numerator = numerator; this.Denominator = denominator; this.numeratorAlignment = TexAlignment.Center; this.denominatorAlignment = TexAlignment.Center; this.useDefaultThickness = useDefaultThickness; this.lineThicknessUnit = unit; this.lineThickness = thickness; }
private FractionAtom(Atom numerator, Atom denominator, bool useDefaultThickness, TexUnit unit, double thickness) { SpaceAtom.CheckUnit(unit); Type = TexAtomType.Inner; Numerator = numerator; Denominator = denominator; numeratorAlignment = TexAlignment.Center; denominatorAlignment = TexAlignment.Center; this.useDefaultThickness = useDefaultThickness; lineThicknessUnit = unit; lineThickness = thickness; }
public static FractionAtom Get(Atom Numerator, Atom Denominator, float LineThickness, TexAlignment NumeratorAlignment, TexAlignment DenominatorAlignment) { var atom = ObjPool <FractionAtom> .Get(); atom.Type = CharTypeInternal.Inner; atom.numerator = Numerator; atom.denominator = Denominator; atom.numeratorAlignment = NumeratorAlignment; atom.denominatorAlignment = DenominatorAlignment; atom.lineThickness = LineThickness; return(atom); }
public FractionAtom( SourceSpan?source, Atom?numerator, Atom?denominator, TexUnit unit, double thickness, TexAlignment numeratorAlignment, TexAlignment denominatorAlignment) : this(source, numerator, denominator, unit, thickness) { this.numeratorAlignment = CheckAlignment(numeratorAlignment); this.denominatorAlignment = CheckAlignment(denominatorAlignment); }
Atom Frac(string value, ref int position, bool delim, TexAlignment nom, TexAlignment denom) { if (position == value.Length) { return(null); } Atom numeratorFormula = null, denominatorFormula = null; numeratorFormula = Parse(ReadGroup(value, ref position, leftGroupChar, rightGroupChar)).ExtractRoot(); SkipWhiteSpace(value, ref position); if (position != value.Length) { denominatorFormula = Parse(ReadGroup(value, ref position, leftGroupChar, rightGroupChar)).ExtractRoot(); } return(FractionAtom.Get(numeratorFormula, denominatorFormula, delim, nom, denom)); }
public HorizontalBox(Box box, double width, TexAlignment alignment) : this() { var extraWidth = width - box.Width; if (alignment == TexAlignment.Center) { var strutBox = new StrutBox(extraWidth / 2, 0, 0, 0); Add(strutBox); Add(box); Add(strutBox); } else if (alignment == TexAlignment.Left) { Add(box); Add(new StrutBox(extraWidth, 0, 0, 0)); } else if (alignment == TexAlignment.Right) { Add(new StrutBox(extraWidth, 0, 0, 0)); Add(box); } }
public VerticalBox(Box box, double rest, TexAlignment alignment) : this() { this.Add(box); if (alignment == TexAlignment.Center) { var strutBox = new StrutBox(0, rest / 2, 0, 0); base.Add(0, strutBox); this.Height += rest / 2; this.Depth += rest / 2; base.Add(strutBox); } else if (alignment == TexAlignment.Top) { this.Depth += rest; base.Add(new StrutBox(0, rest, 0, 0)); } else if (alignment == TexAlignment.Bottom) { this.Height += rest; base.Add(0, new StrutBox(0, rest, 0, 0)); } }
public VerticalBox(Box box, double rest, TexAlignment alignment) : this() { Add(box); if (alignment == TexAlignment.Center) { var strutBox = new StrutBox(0, rest / 2, 0, 0); base.Add(0, strutBox); this.Height += rest / 2; this.Depth += rest / 2; base.Add(strutBox); } else if (alignment == TexAlignment.Top) { this.Depth += rest; base.Add(new StrutBox(0, rest, 0, 0)); } else if (alignment == TexAlignment.Bottom) { this.Height += rest; base.Add(0, new StrutBox(0, rest, 0, 0)); } }
public VerticalBox(Box box, double rest, TexAlignment alignment) { Add(box); switch (alignment) { case TexAlignment.Center: var strutBox = new StrutBox(0, rest / 2, 0, 0); base.Add(0, strutBox); Height += rest / 2; Depth += rest / 2; base.Add(strutBox); break; case TexAlignment.Top: Depth += rest; base.Add(new StrutBox(0, rest, 0, 0)); break; case TexAlignment.Bottom: Height += rest; base.Add(0, new StrutBox(0, rest, 0, 0)); break; } }
public void AddFraction(string numerator, string denominator, bool drawLine, TexAlignment numeratorAlignment, TexAlignment denominatorAlignment) { AddFraction(formulaParser.Parse(numerator), formulaParser.Parse(denominator), drawLine, numeratorAlignment, denominatorAlignment); }
public void AddFraction(TexFormula numerator, TexFormula denominator, bool drawLine, TexAlignment numeratorAlignment, TexAlignment denominatorAlignment) { Add(new FractionAtom(numerator == null ? null : numerator.RootAtom, denominator == null ? null : denominator.RootAtom, drawLine, numeratorAlignment, denominatorAlignment)); }
private Atom ProcessCommand(TexFormula formula, string value, ref int position, string command) { SkipWhiteSpace(value, ref position); if (position == value.Length) { return(null); } switch (command) { case "meta": return(Meta(formula, value, ref position)); case "root": case "sqrt": return(Root(formula, value, ref position)); case "vmatrix": case "matrix": return(Matrix(value, ref position, command == "vmatrix")); case "style": case "math": case "text": var idx = command == "text" ? TEXConfiguration.main.Typeface_Text : (command == "math" ? -1 : -2); var style = ParseStyle(value, ref position); return(ParseFontStyle(value, ref position, idx, style)); case "clr": case "mclr": case "color": return(Color(value, ref position, command == "color" ? 1 : (command == "clr" ? 0 : 2))); case "bg": case "vbg": return(BgColor(value, ref position, command == "bg")); case "size": return(Size(value, ref position)); case "link": case "ulink": return(Link(value, ref position, command == "ulink")); case "trs": case "mtrs": case "ltrs": return(TRS(value, ref position, command == "trs" ? 0 : (command == "mtrs" ? 1 : 2))); case "under": case "over": return(Not(value, ref position, command == "under" ? 4 : 5, false)); case "border": case "vborder": return(Border(value, ref position, command == "border")); } if (NotFamily.Contains(command)) { return(Not(value, ref position, ParseNotMode(command[0], command[1]), true)); } if (FracFamily.Contains(command)) { int FracAlignT = 0, FracAlignB = 0; bool FracAlignN = true; string prefix = command.Substring(0, command.Length - 4); if (prefix.Length > 0) { if (prefix[0] == 'n') { FracAlignN = false; prefix = prefix.Substring(1); } if (prefix.Length == 1) { FracAlignT = fracP(prefix[0]); FracAlignB = FracAlignT; } else if (prefix.Length == 2) { FracAlignT = fracP(prefix[0]); FracAlignB = fracP(prefix[1]); } } return(Frac(value, ref position, FracAlignN, (TexAlignment)FracAlignT, (TexAlignment)FracAlignB)); } if (HoldFamily.Contains(command)) { TexAlignment align = TexAlignment.Center; bool vertical = false; holdP(command.Substring(0, command.Length - 3), ref vertical, ref align); string size = ReadInsideBracket(value, ref position); if (position < value.Length && value[position] == leftGroupChar) { return(HolderAtom.Get(Parse(ReadGroup(value, ref position, leftGroupChar, rightGroupChar)) .ExtractRoot(), size, vertical, align)); } else { return(HolderAtom.Get(null, size, vertical, align)); } } if (TableFamily.Contains(command)) { bool vertical = false; int align = 1 + 8 + 64; string prefix = command.Substring(0, command.Length - 5); if (prefix.Length > 0) { if (prefix[0] == 'v') { vertical = true; prefix = prefix.Substring(1); } if (prefix.Length == 1) { var pref = fracP(prefix[0]); align = Math.Max(1, pref * 2) + Math.Max(8, pref * 16) + Math.Max(64, pref * 128); } else if (prefix.Length == 3) { var pref0 = fracP(prefix[0]); var pref1 = fracP(prefix[1]); var pref2 = fracP(prefix[2]); align = Math.Max(1, pref0 * 2) + Math.Max(8, pref1 * 16) + Math.Max(64, pref2 * 128); } } int lineStyleH = 0, lineStyleV = 0; if (value[position] == leftBracketChar) { string lineOpt; int lineP = 0; lineOpt = ReadGroup(value, ref position, leftBracketChar, rightBracketChar); for (int i = 0; i < lineOpt.Length; i++) { if (!int.TryParse(lineOpt[i].ToString(), out lineP)) { continue; } if (i >= 6) { break; } switch (i) { case 0: lineStyleH += lineP >= 2 ? 17 : lineP; break; case 1: lineStyleH += lineP >= 2 ? 10 : (lineP == 1 ? 2 : 0); break; case 2: lineStyleH += lineP >= 1 ? 4 : 0; break; case 3: lineStyleV += lineP >= 2 ? 17 : lineP; break; case 4: lineStyleV += lineP >= 2 ? 10 : (lineP == 1 ? 2 : 0); break; case 5: lineStyleV += lineP >= 1 ? 4 : 0; break; } } SkipWhiteSpace(value, ref position); } else { lineStyleH = 7; lineStyleV = 7; } return(Table(value, ref position, align, lineStyleH, lineStyleV, vertical)); } throw new TexParseException("Invalid command."); }
private static TexAlignment CheckAlignment(TexAlignment alignment) { if (alignment == TexAlignment.Left || alignment == TexAlignment.Right) return alignment; else return TexAlignment.Center; }
public FractionAtom(Atom numerator, Atom denominator, double relativeThickness, TexAlignment numeratorAlignment, TexAlignment denominatorAlignment) : this(numerator, denominator, true, numeratorAlignment, denominatorAlignment) { this.lineRelativeThickness = relativeThickness; }
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 static FractionAtom Get(Atom Numerator, Atom Denominator, bool HasLine, TexAlignment NumeratorAlignment, TexAlignment DenominatorAlignment) { return(Get(Numerator, Denominator, HasLine ? TexUtility.lineThickness : 0, NumeratorAlignment, DenominatorAlignment)); }
private Atom ProcessCommand(TexFormula formula, string value, ref int position, string command) { SkipWhiteSpace(value, ref position); if (position == value.Length) { return(null); } switch (command) { case "meta": // Command is meta var metaRule = formula.AttachedMetaRenderer; if (metaRule == null) { metaRule = formula.AttachedMetaRenderer = ObjPool <TexMetaRenderer> .Get(); } else { metaRule.Reset(); } string metaPar = null; if (value[position] == leftBracketChar) { metaPar = ReadGroup(value, ref position, leftBracketChar, rightBracketChar); SkipWhiteSpace(value, ref position); metaRule.ParseString(metaPar); } return(null); case "root": case "sqrt": // Command is radical. TexFormula degreeFormula = null; if (value[position] == leftBracketChar) { degreeFormula = Parse(ReadGroup(value, ref position, leftBracketChar, rightBracketChar)); SkipWhiteSpace(value, ref position); } return(Radical.Get(Parse(ReadGroup(value, ref position, leftGroupChar, rightGroupChar)) .GetRoot, degreeFormula == null ? null : degreeFormula.GetRoot)); case "vmatrix": case "matrix": //Command is Matrix MatrixAtom matrixAtom = MatrixAtom.Get(); List <List <Atom> > childs = matrixAtom.Elements; Atom parsedChild = (Parse(ReadGroup( value, ref position, leftGroupChar, rightGroupChar)).GetRoot); childs.Add(ListPool <Atom> .Get()); if (parsedChild == null) { MatrixAtom.Last(childs).Add(SpaceAtom.Get()); } if (parsedChild is RowAtom) { List <Atom> el = ((RowAtom)parsedChild).Elements; if (command == "matrix") { MatrixAtom.ParseMatrix(el, childs); } else { MatrixAtom.ParseMatrixVertical(el, childs); } el.Clear(); ObjPool <RowAtom> .Release((RowAtom)parsedChild); } else { MatrixAtom.Last(childs).Add(parsedChild); } matrixAtom.Elements = childs; return(matrixAtom); case "math": case "text": var idx = TexUtility.RawRenderFont < 0 ? TEXConfiguration.main.Typeface_Text : -2; var style = TexUtility.RenderFontStyle; if (value[position] == leftBracketChar) { var str = ReadGroup(value, ref position, leftBracketChar, rightBracketChar); if (!int.TryParse(str, out idx)) { idx = TexUtility.RawRenderFont < 0 ? TEXConfiguration.main.Typeface_Text : -2; style = ParseFontStyle(str); } SkipWhiteSpace(value, ref position); } else if (command == "math") { idx = -1; } var oldType = TexUtility.RenderFont; var oldStyle = TexUtility.RenderFontStyle; TexUtility.RenderFont = idx; TexUtility.RenderFontStyle = style; var parsed = Parse(ReadGroup(value, ref position, leftGroupChar, rightGroupChar)).GetRoot; TexUtility.RenderFont = oldType; TexUtility.RenderFontStyle = oldStyle; return(parsed); case "clr": case "mclr": case "color": // Command is color string clr = null; if (value[position] == leftBracketChar) { clr = ReadGroup(value, ref position, leftBracketChar, rightBracketChar); SkipWhiteSpace(value, ref position); } if (position == value.Length) { return(null); } AttrColorAtom endColor; var startColor = AttrColorAtom.Get(clr, command == "color" ? 1 : (command == "clr" ? 0 : 2), out endColor); return(InsertAttribute(Parse(ReadGroup(value, ref position, leftGroupChar, rightGroupChar)).GetRoot, startColor, endColor)); case "bg": case "vbg": if (value[position] == leftBracketChar) { clr = ReadGroup(value, ref position, leftBracketChar, rightBracketChar); SkipWhiteSpace(value, ref position); } else { clr = null; } return(AttrBgAtom.Get(Parse(ReadGroup(value, ref position, leftGroupChar, rightGroupChar)) .GetRoot, clr, command == "bg")); case "size": // Command is size string sz = null; if (value[position] == leftBracketChar) { sz = ReadGroup(value, ref position, leftBracketChar, rightBracketChar); SkipWhiteSpace(value, ref position); } if (position == value.Length) { return(null); } return(AttrSizeAtom.Get(Parse(ReadGroup(value, ref position, leftGroupChar, rightGroupChar)) .GetRoot, sz)); case "link": case "ulink": // Command is Link string meta = null; if (value[position] == leftBracketChar) { meta = ReadGroup(value, ref position, leftBracketChar, rightBracketChar); SkipWhiteSpace(value, ref position); } if (position == value.Length) { return(null); } string groupBrack = ReadGroup(value, ref position, leftGroupChar, rightGroupChar); if (meta == null) { meta = groupBrack; } return(AttrLinkAtom.Get(Parse(groupBrack).GetRoot, meta, command == "ulink")); case "under": command = "anot"; break; case "over": command = "bnot"; break; } if (command.Length > 2 && command.Substring(command.Length - 3) == "not") { int NotMode = 0; bool UseMargin = true; string prefix = command.Substring(0, command.Length - 3); if (prefix.Length > 0) { switch (prefix[0]) { case 'n': NotMode = 1; break; case 'h': NotMode = 2; break; case 'd': NotMode = 3; break; case 'u': NotMode = 4; break; case 'o': NotMode = 5; break; case 'v': if (prefix.Length > 1 && prefix[1] == 'n') { NotMode = 7; } else { NotMode = 6; } break; case 'a': NotMode = 4; UseMargin = false; break; case 'b': NotMode = 5; UseMargin = false; break; } } if (position == value.Length) { return(null); } string sz = null; if (value[position] == leftBracketChar) { sz = ReadGroup(value, ref position, leftBracketChar, rightBracketChar); SkipWhiteSpace(value, ref position); } return(NegateAtom.Get(Parse(ReadGroup(value, ref position, leftGroupChar, rightGroupChar)) .GetRoot, NotMode, sz, UseMargin)); } if (command.Length > 2 && command.Substring(command.Length - 3) == "trs") { int PivotMode = 0; string prefix = command.Substring(0, command.Length - 3); if (prefix.Length > 0) { switch (prefix[0]) { case 'm': PivotMode = 1; break; case 'l': PivotMode = 2; break; } } if (position == value.Length) { return(null); } string trs = null; if (value[position] == leftBracketChar) { trs = ReadGroup(value, ref position, leftBracketChar, rightBracketChar); SkipWhiteSpace(value, ref position); } AttrTransformationAtom endTRS; var startTRS = AttrTransformationAtom.Get(trs, PivotMode, out endTRS); return(InsertAttribute(Parse(ReadGroup(value, ref position, leftGroupChar, rightGroupChar)).GetRoot, startTRS, endTRS)); } if (command.Length > 3 && command.Substring(command.Length - 4) == "frac") { int FracAlignT = 0, FracAlignB = 0; bool FracAlignN = true; string prefix = command.Substring(0, command.Length - 4); if (prefix.Length > 0) { if (prefix[0] == 'n') { FracAlignN = false; prefix = prefix.Substring(1); } if (prefix.Length == 1) { FracAlignT = fracP(prefix[0]); FracAlignB = FracAlignT; } else if (prefix.Length == 2) { FracAlignT = fracP(prefix[0]); FracAlignB = fracP(prefix[1]); } } if (position == value.Length) { return(null); } Atom numeratorFormula = null, denominatorFormula = null; numeratorFormula = Parse(ReadGroup(value, ref position, leftGroupChar, rightGroupChar)).GetRoot; SkipWhiteSpace(value, ref position); if (position != value.Length) { denominatorFormula = Parse(ReadGroup(value, ref position, leftGroupChar, rightGroupChar)).GetRoot; } return(FractionAtom.Get(numeratorFormula, denominatorFormula, FracAlignN, (TexAlignment)FracAlignT, (TexAlignment)FracAlignB)); } if (command.Length > 3 && command.Substring(command.Length - 4) == "hold") { TexAlignment align = TexAlignment.Center; bool isVertical = false; string prefix = command.Substring(0, command.Length - 3); if (prefix.Length > 0) { switch (prefix[0]) { case 'v': isVertical = true; break; case 'l': align = TexAlignment.Left; break; case 'r': align = TexAlignment.Right; break; case 'b': align = TexAlignment.Bottom; goto case 'v'; case 't': align = TexAlignment.Top; goto case 'v'; } } Vector2 sz = Vector2.zero; if (position < value.Length && value[position] == leftBracketChar) { var frag = ReadGroup(value, ref position, leftBracketChar, rightBracketChar); int idx = frag.IndexOf(','); if (idx >= 0) { var fragL = frag.Substring(0, idx); var fragR = frag.Substring(idx + 1); float.TryParse(fragL, out sz.x); float.TryParse(fragR, out sz.y); } else { if (isVertical) { float.TryParse(frag, out sz.y); } else { float.TryParse(frag, out sz.x); } } SkipWhiteSpace(value, ref position); } if (position < value.Length && value[position] == leftGroupChar) { return(HolderAtom.Get(Parse(ReadGroup(value, ref position, leftGroupChar, rightGroupChar)) .GetRoot, sz.x, sz.y, align)); } else { return(HolderAtom.Get(null, sz.x, sz.y, align)); } } if (command.Length > 4 && command.Substring(command.Length - 5) == "table") { bool vertical = false; int align = 1 + 8 + 64; string prefix = command.Substring(0, command.Length - 5); if (prefix.Length > 0) { if (prefix[0] == 'v') { vertical = true; prefix = prefix.Substring(1); } if (prefix.Length == 1) { var pref = fracP(prefix[0]); align = Math.Max(1, pref * 2) + Math.Max(8, pref * 16) + Math.Max(64, pref * 128); } else if (prefix.Length == 3) { var pref0 = fracP(prefix[0]); var pref1 = fracP(prefix[1]); var pref2 = fracP(prefix[2]); align = Math.Max(1, pref0 * 2) + Math.Max(8, pref1 * 16) + Math.Max(64, pref2 * 128); } } int lineStyleH = 0, lineStyleV = 0; if (value[position] == leftBracketChar) { string lineOpt; int lineP = 0; lineOpt = ReadGroup(value, ref position, leftBracketChar, rightBracketChar); for (int i = 0; i < lineOpt.Length; i++) { if (!int.TryParse(lineOpt[i].ToString(), out lineP)) { continue; } if (i >= 6) { break; } switch (i) { case 0: lineStyleH += lineP >= 2 ? 17 : lineP; break; case 1: lineStyleH += lineP >= 2 ? 10 : (lineP == 1 ? 2 : 0); break; case 2: lineStyleH += lineP >= 1 ? 4 : 0; break; case 3: lineStyleV += lineP >= 2 ? 17 : lineP; break; case 4: lineStyleV += lineP >= 2 ? 10 : (lineP == 1 ? 2 : 0); break; case 5: lineStyleV += lineP >= 1 ? 4 : 0; break; } } SkipWhiteSpace(value, ref position); } else { lineStyleH = 7; lineStyleV = 7; } List <List <Atom> > childs = new List <List <Atom> >(); MatrixAtom matrixAtom = ObjPool <MatrixAtom> .Get(); matrixAtom.horizontalAlign = align; matrixAtom.horizontalLine = lineStyleH; matrixAtom.verticalLine = lineStyleV; Atom parsedChild = (Parse(ReadGroup( value, ref position, leftGroupChar, rightGroupChar)).GetRoot); childs.Add(ListPool <Atom> .Get()); if (parsedChild == null) { MatrixAtom.Last(childs).Add(SpaceAtom.Get()); } if (parsedChild is RowAtom) { List <Atom> el = ((RowAtom)parsedChild).Elements; if (!vertical) { MatrixAtom.ParseMatrix(el, childs); } else { MatrixAtom.ParseMatrixVertical(el, childs); } el.Clear(); ObjPool <RowAtom> .Release((RowAtom)parsedChild); } else { MatrixAtom.Last(childs).Add(parsedChild); } matrixAtom.Elements = childs; return(matrixAtom); } throw new TexParseException("Invalid command."); }