private static DummyAtom ChangeAtomToOrdinary(DummyAtom currentAtom, DummyAtom previousAtom, Atom nextAtom) { var type = currentAtom.GetLeftType(); if (type == TexAtomType.BinaryOperator && (previousAtom == null || binaryOperatorChangeSet[(int)previousAtom.GetRightType()])) { currentAtom = currentAtom.WithType(TexAtomType.Ordinary); } else if (nextAtom != null && currentAtom.GetRightType() == TexAtomType.BinaryOperator) { var nextType = nextAtom.GetLeftType(); if (nextType == TexAtomType.Relation || nextType == TexAtomType.Closing || nextType == TexAtomType.Punctuation) { currentAtom = currentAtom.WithType(TexAtomType.Ordinary); } } return(currentAtom); }
protected override Box CreateBoxCore(TexEnvironment environment) { // Create result box. var resultBox = new HorizontalBox(environment.Foreground, environment.Background); var previousAtom = this.PreviousAtom; // Create and add box for each atom in row. for (int i = 0; i < this.Elements.Count; i++) { var curAtom = new DummyAtom(this.Elements[i]); // Change atom type to Ordinary, if required. var hasNextAtom = i < this.Elements.Count - 1; var nextAtom = hasNextAtom ? (Atom)this.Elements[i + 1] : null; curAtom = ChangeAtomToOrdinary(curAtom, previousAtom, nextAtom); // Check if atom is part of ligature or should be kerned. var kern = 0d; if (hasNextAtom && curAtom.GetRightType() == TexAtomType.Ordinary && curAtom.Atom is CharSymbol cs) { if (nextAtom is CharSymbol ns && ligatureKernChangeSet[(int)nextAtom.GetLeftType()]) { var font = ns.GetStyledFont(environment); var style = environment.Style; curAtom = curAtom.AsTextSymbol(); if (font.SupportsMetrics && cs.IsSupportedByFont(font, style)) { var leftAtomCharFont = curAtom.GetCharFont(font).Value; var rightAtomCharFont = ns.GetCharFont(font).Value; var ligatureCharFont = font.GetLigature(leftAtomCharFont, rightAtomCharFont); if (ligatureCharFont == null) { // Atom should be kerned. kern = font.GetKern(leftAtomCharFont, rightAtomCharFont, style); } else { // Atom is part of ligature. curAtom = DummyAtom.CreateLigature(new FixedCharAtom(null, ligatureCharFont)); i++; } } } } // Create and add glue box, unless atom is first of row or previous/current atom is kern. if (i != 0 && previousAtom != null && !previousAtom.IsKern && !curAtom.IsKern) { resultBox.Add(Glue.CreateBox(previousAtom.GetRightType(), curAtom.GetLeftType(), environment)); } // Create and add box for atom. var curBox = curAtom.WithPreviousAtom(previousAtom).CreateBox(environment); resultBox.Add(curBox); environment.LastFontId = curBox.GetLastFontId(); // Insert kern, if required. if (kern > TexUtilities.FloatPrecision) { resultBox.Add(new StrutBox(0, kern, 0, 0)); } if (!curAtom.IsKern) { previousAtom = curAtom; } } return(resultBox); }