Example #1
0
        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);
        }
Example #2
0
        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);
        }