Ejemplo n.º 1
0
        public UnderOverAtom(Atom baseAtom, Atom underOver, TexUnit underOverUnit, double underOverSpace,
                             bool underOverScriptSize, bool over)
        {
            SpaceAtom.CheckUnit(underOverUnit);

            this.BaseAtom = baseAtom;

            if (over)
            {
                this.UnderAtom          = null;
                this.UnderSpace         = 0;
                this.UnderSpaceUnit     = 0;
                this.UnderScriptSmaller = false;
                this.OverAtom           = underOver;
                this.OverSpaceUnit      = underOverUnit;
                this.OverSpace          = underOverSpace;
                this.OverScriptSmaller  = underOverScriptSize;
            }
            else
            {
                this.UnderAtom          = underOver;
                this.UnderSpaceUnit     = underOverUnit;
                this.UnderSpace         = underOverSpace;
                this.UnderScriptSmaller = underOverScriptSize;
                this.OverSpace          = 0;
                this.OverAtom           = null;
                this.OverSpaceUnit      = 0;
                this.OverScriptSmaller  = false;
            }
        }
Ejemplo n.º 2
0
        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;
        }
Ejemplo n.º 3
0
        public UnderOverAtom(Atom baseAtom, Atom under, TexUnit underUnit, double underSpace, bool underScriptSize,
                             Atom over, TexUnit overUnit, double overSpace, bool overScriptSize)
        {
            SpaceAtom.CheckUnit(underUnit);
            SpaceAtom.CheckUnit(overUnit);

            this.BaseAtom           = baseAtom;
            this.UnderAtom          = under;
            this.UnderSpaceUnit     = underUnit;
            this.UnderSpace         = underSpace;
            this.UnderScriptSmaller = underScriptSize;
            this.OverAtom           = over;
            this.OverSpaceUnit      = overUnit;
            this.OverSpace          = overSpace;
            this.OverScriptSmaller  = overScriptSize;
        }
Ejemplo n.º 4
0
        public override Box CreateBox(TexEnvironment environment)
        {
            var texFont = environment.TexFont;
            var style = environment.Style;

            // Calculate minimum clearance amount.
            double clearance;
            var defaultRuleThickness = texFont.GetDefaultLineThickness(style);
            if (style < TexStyle.Text)
                clearance = texFont.GetXHeight(style, texFont.GetCharInfo(sqrtSymbol, style).FontId);
            else
                clearance = defaultRuleThickness;
            clearance = defaultRuleThickness + Math.Abs(clearance) / 4;

            // Create box for base atom, in cramped style.
            var baseBox = this.BaseAtom.CreateBox(environment.GetCrampedStyle());

            // Create box for radical sign.
            var totalHeight = baseBox.Height + baseBox.Depth;
            var radicalSignBox = DelimiterFactory.CreateBox(sqrtSymbol, totalHeight + clearance + defaultRuleThickness,
                environment);

            // Add half of excess height to clearance.
            var delta = radicalSignBox.Depth - (totalHeight + clearance);
            clearance += delta / 2;

            // Create box for square-root containing base box.
            radicalSignBox.Shift = -(baseBox.Height + clearance);
            var overBar = new OverBar(baseBox, clearance, radicalSignBox.Height);
            overBar.Shift = -(baseBox.Height + clearance + defaultRuleThickness);
            var radicalContainerBox = new HorizontalBox(radicalSignBox);
            radicalContainerBox.Add(overBar);

            // If atom is simple radical, just return square-root box.
            if (this.DegreeAtom == null)
                return radicalContainerBox;

            // Atom is complex radical (nth-root).

            // Create box for root atom.
            var rootBox = this.DegreeAtom.CreateBox(environment.GetRootStyle());
            var bottomShift = scale * (radicalContainerBox.Height + radicalContainerBox.Depth);
            rootBox.Shift = radicalContainerBox.Depth - rootBox.Depth - bottomShift;

            // Create result box.
            var resultBox = new HorizontalBox();

            // Add box for negative kern.
            var negativeKern = new SpaceAtom(TexUnit.Mu, -10, 0, 0).CreateBox(environment);
            var xPos = rootBox.Width + negativeKern.Width;
            if (xPos < 0)
                resultBox.Add(new StrutBox(-xPos, 0, 0, 0));

            resultBox.Add(rootBox);
            resultBox.Add(negativeKern);
            resultBox.Add(radicalContainerBox);

            return resultBox;
        }
Ejemplo n.º 5
0
        public override Box CreateBox(TexEnvironment environment)
        {
            var texFont = environment.MathFont;
            var style   = environment.Style;

            // Calculate minimum clearance amount.
            double clearance;
            var    defaultRuleThickness = texFont.GetDefaultLineThickness(style);

            if (style < TexStyle.Text)
            {
                clearance = texFont.GetXHeight(style, texFont.GetCharInfo(sqrtSymbol, style).FontId);
            }
            else
            {
                clearance = defaultRuleThickness;
            }
            clearance = defaultRuleThickness + Math.Abs(clearance) / 4;

            // Create box for base atom, in cramped style.
            var baseBox = this.BaseAtom.CreateBox(environment.GetCrampedStyle());

            // Create box for radical sign.
            var totalHeight    = baseBox.Height + baseBox.Depth;
            var radicalSignBox = DelimiterFactory.CreateBox(sqrtSymbol, totalHeight + clearance + defaultRuleThickness,
                                                            environment);

            // Add half of excess height to clearance.
            var delta = radicalSignBox.Depth - (totalHeight + clearance);

            clearance += delta / 2;

            // Create box for square-root containing base box.
            radicalSignBox.Shift = -(baseBox.Height + clearance);
            var overBar = new OverBar(environment, baseBox, clearance, radicalSignBox.Height);

            overBar.Shift = -(baseBox.Height + clearance + defaultRuleThickness);
            var radicalContainerBox = new HorizontalBox(radicalSignBox);

            radicalContainerBox.Add(overBar);

            // If atom is simple radical, just return square-root box.
            if (this.DegreeAtom == null)
            {
                return(radicalContainerBox);
            }

            // Atom is complex radical (nth-root).

            // Create box for root atom.
            var rootBox     = this.DegreeAtom.CreateBox(environment.GetRootStyle());
            var bottomShift = scale * (radicalContainerBox.Height + radicalContainerBox.Depth);

            rootBox.Shift = radicalContainerBox.Depth - rootBox.Depth - bottomShift;

            // Create result box.
            var resultBox = new HorizontalBox();

            // Add box for negative kern.
            var negativeKern = new SpaceAtom(TexUnit.Mu, -10, 0, 0).CreateBox(environment);
            var xPos         = rootBox.Width + negativeKern.Width;

            if (xPos < 0)
            {
                resultBox.Add(new StrutBox(-xPos, 0, 0, 0));
            }

            resultBox.Add(rootBox);
            resultBox.Add(negativeKern);
            resultBox.Add(radicalContainerBox);

            return(resultBox);
        }
Ejemplo n.º 6
0
        public override Box CreateBox(TexEnvironment environment)
        {
            var texFont = environment.TexFont;
            var style   = environment.Style;

            // set thickness to default if default value should be used
            double lineHeight;
            var    defaultLineThickness = texFont.GetDefaultLineThickness(style);

            if (this.useDefaultThickness)
            {
                lineHeight = this.lineRelativeThickness.HasValue ? this.lineRelativeThickness.Value * defaultLineThickness :
                             defaultLineThickness;
            }
            else
            {
                lineHeight = new SpaceAtom(this.lineThicknessUnit, 0, this.lineThickness, 0).CreateBox(environment).Height;
            }

            // Create boxes for numerator and demoninator atoms, and make them of equal width.
            var numeratorBox = this.Numerator == null ? StrutBox.Empty :
                               this.Numerator.CreateBox(environment.GetNumeratorStyle());
            var denominatorBox = this.Denominator == null ? StrutBox.Empty :
                                 this.Denominator.CreateBox(environment.GetDenominatorStyle());

            if (numeratorBox.Width < denominatorBox.Width)
            {
                numeratorBox = new HorizontalBox(numeratorBox, denominatorBox.Width, numeratorAlignment);
            }
            else
            {
                denominatorBox = new HorizontalBox(denominatorBox, numeratorBox.Width, denominatorAlignment);
            }

            // Calculate preliminary shift-up and shift-down amounts.
            double shiftUp, shiftDown;

            if (style < TexStyle.Text)
            {
                shiftUp   = texFont.GetNum1(style);
                shiftDown = texFont.GetDenom1(style);
            }
            else
            {
                shiftDown = texFont.GetDenom2(style);
                if (lineHeight > 0)
                {
                    shiftUp = texFont.GetNum2(style);
                }
                else
                {
                    shiftUp = texFont.GetNum3(style);
                }
            }

            // Create result box.
            var resultBox = new VerticalBox();

            // add box for numerator.
            resultBox.Add(numeratorBox);

            // Calculate clearance and adjust shift amounts.
            var axis = texFont.GetAxisHeight(style);

            if (lineHeight > 0)
            {
                // Draw fraction line.

                // Calculate clearance amount.
                double clearance;
                if (style < TexStyle.Text)
                {
                    clearance = 3 * lineHeight;
                }
                else
                {
                    clearance = lineHeight;
                }

                // Adjust shift amounts.
                var delta  = lineHeight / 2;
                var kern1  = shiftUp - numeratorBox.Depth - (axis + delta);
                var kern2  = axis - delta - (denominatorBox.Height - shiftDown);
                var delta1 = clearance - kern1;
                var delta2 = clearance - kern2;
                if (delta1 > 0)
                {
                    shiftUp += delta1;
                    kern1   += delta1;
                }
                if (delta2 > 0)
                {
                    shiftDown += delta2;
                    kern2     += delta2;
                }

                resultBox.Add(new StrutBox(0, kern1, 0, 0));
                resultBox.Add(new HorizontalRule(environment, lineHeight, numeratorBox.Width, 0));
                resultBox.Add(new StrutBox(0, kern2, 0, 0));
            }
            else
            {
                // Do not draw fraction line.

                // Calculate clearance amount.
                double clearance;
                if (style < TexStyle.Text)
                {
                    clearance = 7 * defaultLineThickness;
                }
                else
                {
                    clearance = 3 * defaultLineThickness;
                }

                // Adjust shift amounts.
                var kern  = shiftUp - numeratorBox.Depth - (denominatorBox.Height - shiftDown);
                var delta = (clearance - kern) / 2;
                if (delta > 0)
                {
                    shiftUp   += delta;
                    shiftDown += delta;
                    kern      += 2 * delta;
                }

                resultBox.Add(new StrutBox(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 + denominatorBox.Depth;

            return(resultBox);
        }
Ejemplo n.º 7
0
        public override Box CreateBox(TexEnvironment environment)
        {
            var texFont = environment.TexFont;
            var style = environment.Style;

            // set thickness to default if default value should be used
            double lineHeight;
            var defaultLineThickness = texFont.GetDefaultLineThickness(style);
            if (this.useDefaultThickness)
                lineHeight = this.lineRelativeThickness.HasValue ? this.lineRelativeThickness.Value * defaultLineThickness :
                    defaultLineThickness;
            else
                lineHeight = new SpaceAtom(this.lineThicknessUnit, 0, this.lineThickness, 0).CreateBox(environment).Height;

            // Create boxes for numerator and demoninator atoms, and make them of equal width.
            var numeratorBox = this.Numerator == null ? StrutBox.Empty :
                this.Numerator.CreateBox(environment.GetNumeratorStyle());
            var denominatorBox = this.Denominator == null ? StrutBox.Empty :
                this.Denominator.CreateBox(environment.GetDenominatorStyle());

            if (numeratorBox.Width < denominatorBox.Width)
                numeratorBox = new HorizontalBox(numeratorBox, denominatorBox.Width, numeratorAlignment);
            else
                denominatorBox = new HorizontalBox(denominatorBox, numeratorBox.Width, denominatorAlignment);

            // Calculate preliminary shift-up and shift-down amounts.
            double shiftUp, shiftDown;
            if (style < TexStyle.Text)
            {
                shiftUp = texFont.GetNum1(style);
                shiftDown = texFont.GetDenom1(style);
            }
            else
            {
                shiftDown = texFont.GetDenom2(style);
                if (lineHeight > 0)
                    shiftUp = texFont.GetNum2(style);
                else
                    shiftUp = texFont.GetNum3(style);
            }

            // Create result box.
            var resultBox = new VerticalBox();

            // add box for numerator.
            resultBox.Add(numeratorBox);

            // Calculate clearance and adjust shift amounts.
            var axis = texFont.GetAxisHeight(style);

            if (lineHeight > 0)
            {
                // Draw fraction line.

                // Calculate clearance amount.
                double clearance;
                if (style < TexStyle.Text)
                    clearance = 3 * lineHeight;
                else
                    clearance = lineHeight;

                // Adjust shift amounts.
                var delta = lineHeight / 2;
                var kern1 = shiftUp - numeratorBox.Depth - (axis + delta);
                var kern2 = axis - delta - (denominatorBox.Height - shiftDown);
                var delta1 = clearance - kern1;
                var delta2 = clearance - kern2;
                if (delta1 > 0)
                {
                    shiftUp += delta1;
                    kern1 += delta1;
                }
                if (delta2 > 0)
                {
                    shiftDown += delta2;
                    kern2 += delta2;
                }

                resultBox.Add(new StrutBox(0, kern1, 0, 0));
                resultBox.Add(new HorizontalRule(lineHeight, numeratorBox.Width, 0));
                resultBox.Add(new StrutBox(0, kern2, 0, 0));
            }
            else
            {
                // Do not draw fraction line.

                // Calculate clearance amount.
                double clearance;
                if (style < TexStyle.Text)
                    clearance = 7 * defaultLineThickness;
                else
                    clearance = 3 * defaultLineThickness;

                // Adjust shift amounts.
                var kern = shiftUp - numeratorBox.Depth - (denominatorBox.Height - shiftDown);
                var delta = (clearance - kern) / 2;
                if (delta > 0)
                {
                    shiftUp += delta;
                    shiftDown += delta;
                    kern += 2 * delta;
                }

                resultBox.Add(new StrutBox(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 + denominatorBox.Depth;

            return resultBox;
        }
Ejemplo n.º 8
0
        private TexFormula Parse(
            SourceSpan value,
            ref int position,
            bool allowClosingDelimiter,
            string?textStyle,
            ICommandEnvironment environment)
        {
            var formula = new TexFormula {
                Source = value, TextStyle = textStyle
            };
            var closedDelimiter = false;
            var skipWhiteSpace  = ShouldSkipWhiteSpace(textStyle);
            var initialPosition = position;

            while (position < value.Length && !(allowClosingDelimiter && closedDelimiter))
            {
                char ch     = value[position];
                var  source = value.Segment(position, 1);
                if (IsWhiteSpace(ch))
                {
                    if (!skipWhiteSpace)
                    {
                        formula.Add(new SpaceAtom(source), source);
                    }

                    position++;
                }
                else if (ch == escapeChar)
                {
                    ProcessEscapeSequence(
                        formula,
                        value,
                        ref position,
                        allowClosingDelimiter,
                        ref closedDelimiter,
                        environment);
                }
                else if (ch == leftGroupChar)
                {
                    var groupValue     = ReadElement(value, ref position);
                    var parsedGroup    = Parse(groupValue, textStyle, environment.CreateChildEnvironment());
                    var innerGroupAtom = parsedGroup.RootAtom ?? new RowAtom(groupValue);
                    var groupAtom      = new TypedAtom(
                        innerGroupAtom.Source,
                        innerGroupAtom,
                        TexAtomType.Ordinary,
                        TexAtomType.Ordinary);
                    var scriptsAtom = this.AttachScripts(formula, value, ref position, groupAtom, true, environment);
                    formula.Add(scriptsAtom, value.Segment(initialPosition, position - initialPosition));
                }
                else if (ch == rightGroupChar)
                {
                    throw new TexParseException("Found a closing '" + rightGroupChar
                                                + "' without an opening '" + leftGroupChar + "'!");
                }
                else if (ch == superScriptChar || ch == subScriptChar || ch == primeChar)
                {
                    if (position == 0)
                    {
                        var sp          = new SpaceAtom(source);
                        var scriptsAtom = AttachScripts(formula, value, ref position, sp, skipWhiteSpace, environment);
                        formula.Add(scriptsAtom, value.Segment(initialPosition, position - initialPosition));
                        //throw new TexParseException("Every script needs a base: \""
                        //    + superScriptChar + "\", \"" + subScriptChar + "\" and \""
                        //    + primeChar + "\" can't be the first character!");
                    }
                    else
                    {
                        throw new TexParseException("Double scripts found! Try using more braces.");
                    }
                }
                else
                {
                    var character = ConvertCharacter(formula, ref position, source, environment);
                    if (character != null)
                    {
                        var scriptsAtom = AttachScripts(
                            formula,
                            value,
                            ref position,
                            character,
                            skipWhiteSpace,
                            environment);
                        formula.Add(scriptsAtom, value.Segment(initialPosition, position));
                    }
                }
            }

            return(formula);
        }