Пример #1
0
 public static Box CreateBox(TexAtomType leftAtomType, TexAtomType rightAtomType, TexEnvironment environment)
 {
     leftAtomType = leftAtomType > TexAtomType.Inner ? TexAtomType.Ordinary : leftAtomType;
     rightAtomType = rightAtomType > TexAtomType.Inner ? TexAtomType.Ordinary : rightAtomType;
     var glueType = glueRules[(int)leftAtomType, (int)rightAtomType, (int)environment.Style / 2];
     return glueTypes[glueType].CreateBox(environment);
 }
Пример #2
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;
        }
Пример #3
0
 public CharBox(TexEnvironment environment, CharInfo charInfo)
     : base(environment)
 {
     this.Character = charInfo;
     this.Width = charInfo.Metrics.Width;
     this.Height = charInfo.Metrics.Height;
     this.Depth = charInfo.Metrics.Depth;
 }
Пример #4
0
 public CharBox(TexEnvironment environment, CharInfo charInfo)
     : base(environment)
 {
     this.Character = charInfo;
     this.Width     = charInfo.Metrics.Width;
     this.Height    = charInfo.Metrics.Height;
     this.Depth     = charInfo.Metrics.Depth;
     this.Italic    = charInfo.Metrics.Italic;
 }
Пример #5
0
        public override Box CreateBox(TexEnvironment environment)
        {
            // TODO
            var resultBox = (Box)null; // DelimiterFactory.CreateBox(this.DelimeterAtom, this.Size, environment);

            resultBox.Shift = -(resultBox.Height + resultBox.Depth) / 2 -
                              environment.TexFont.GetAxisHeight(environment.Style);
            return(resultBox);
        }
Пример #6
0
 public override Box CreateBox(TexEnvironment environment)
 {
     if (this.IsTextSymbol)
         ((CharSymbol)this.Atom).IsTextSymbol = true;
     var resultBox = this.Atom.CreateBox(environment);
     if (this.IsTextSymbol)
         ((CharSymbol)this.Atom).IsTextSymbol = false;
     return resultBox;
 }
Пример #7
0
 public override Box CreateBox(TexEnvironment environment)
 {
     var newEnvironment = environment.Clone();
     if (this.Background != null)
         newEnvironment.Background = this.Background;
     if (this.Foreground != null)
         newEnvironment.Foreground = this.Foreground;
     return this.RowAtom.CreateBox(newEnvironment);
 }
Пример #8
0
        public override Box CreateBox(TexEnvironment environment)
        {
            var texFont = environment.TexFont;
            var style = environment.Style;

            // Create box for base atom.
            var baseBox = this.BaseAtom == null ? StrutBox.Empty : this.BaseAtom.CreateBox(environment.GetCrampedStyle());
            var skew = 0d;
            if (this.BaseAtom is CharSymbol)
                skew = texFont.GetSkew(((CharSymbol)this.BaseAtom).GetCharFont(texFont), style);

            // Find character of best scale for accent symbol.
            var accentChar = texFont.GetCharInfo(AccentAtom.Name, style);
            while (texFont.HasNextLarger(accentChar))
            {
                var nextLargerChar = texFont.GetNextLargerCharInfo(accentChar, style);
                if (nextLargerChar.Metrics.Width > baseBox.Width)
                    break;
                accentChar = nextLargerChar;
            }

            var resultBox = new VerticalBox();

            // Create and add box for accent symbol.
            Box accentBox;
            var accentItalicWidth = accentChar.Metrics.Italic;
            if (accentItalicWidth > TexUtilities.FloatPrecision)
            {
                accentBox = new HorizontalBox(new CharBox(environment, accentChar));
                accentBox.Add(new StrutBox(accentItalicWidth, 0, 0, 0));
            }
            else
            {
                accentBox = new CharBox(environment, accentChar);
            }
            resultBox.Add(accentBox);

            var delta = Math.Min(baseBox.Height, texFont.GetXHeight(style, accentChar.FontId));
            resultBox.Add(new StrutBox(0, -delta, 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) / 2;
            accentBox.Shift = skew + Math.Max(boxWidthsDiff, 0);
            if (boxWidthsDiff < 0)
                baseBox = new HorizontalBox(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;
        }
Пример #9
0
        public override Box CreateBox(TexEnvironment environment)
        {
            var box = this.Atom.CreateBox(environment);

            // Centre box relative to horizontal axis.
            var totalHeight = box.Height + box.Depth;
            var axis = environment.TexFont.GetAxisHeight(environment.Style);
            box.Shift = -(totalHeight / 2) - axis;

            return new HorizontalBox(box);
        }
Пример #10
0
 internal Box CreateBox(TexEnvironment environment)
 {
     if (this.RootAtom == null)
     {
         return(StrutBox.Empty);
     }
     else
     {
         return(this.RootAtom.CreateBox(environment));
     }
 }
Пример #11
0
 public override Box CreateBox(TexEnvironment environment)
 {
     if (isHardSpace)
     {
         return(new StrutBox(environment.MathFont.GetSpace(environment.Style), 0, 0, 0));
     }
     else
     {
         return(new StrutBox(width * GetConversionFactor(widthUnit, environment), height * GetConversionFactor(
                                 heightUnit, environment), depth * GetConversionFactor(depthUnit, environment), 0));
     }
 }
Пример #12
0
        public override Box CreateBox(TexEnvironment environment)
        {
            var box = this.Atom.CreateBox(environment);

            // Centre box relative to horizontal axis.
            var totalHeight = box.Height + box.Depth;
            var axis        = environment.MathFont.GetAxisHeight(environment.Style);

            box.Shift = -(totalHeight / 2) - axis;

            return(new HorizontalBox(box));
        }
Пример #13
0
        public TexRenderer GetRenderer(TexStyle style,
                                       double scale,
                                       string?systemTextFontName,
                                       Brush?background = null,
                                       Brush?foreground = null)
        {
            var mathFont    = new DefaultTexFont(scale);
            var textFont    = systemTextFontName == null ? (ITeXFont)mathFont : GetSystemFont(systemTextFontName, scale);
            var environment = new TexEnvironment(style, mathFont, textFont, background, foreground);

            return(new TexRenderer(CreateBox(environment), scale));
        }
        public override Box CreateBox(TexEnvironment environment)
        {
            if (this.IsTextSymbol)
            {
                ((CharSymbol)this.Atom).IsTextSymbol = true;
            }
            var resultBox = this.Atom.CreateBox(environment);

            if (this.IsTextSymbol)
            {
                ((CharSymbol)this.Atom).IsTextSymbol = false;
            }
            return(resultBox);
        }
Пример #15
0
        public override Box CreateBox(TexEnvironment environment)
        {
            var newEnvironment = environment.Clone();

            if (this.Background != null)
            {
                newEnvironment.Background = this.Background;
            }
            if (this.Foreground != null)
            {
                newEnvironment.Foreground = this.Foreground;
            }
            return(this.RowAtom.CreateBox(newEnvironment));
        }
Пример #16
0
        public override Box CreateBox(TexEnvironment environment)
        {
            // Create box for base atom.
            var baseBox = this.BaseAtom == null ? StrutBox.Empty : this.BaseAtom.CreateBox(environment);

            // Create boxes for over and under atoms.
            Box overBox = null, underBox = null;
            var maxWidth = baseBox.Width;

            if (this.OverAtom != null)
            {
                overBox  = OverAtom.CreateBox(OverScriptSmaller ? environment.GetSubscriptStyle() : environment);
                maxWidth = Math.Max(maxWidth, overBox.Width);
            }

            if (this.UnderAtom != null)
            {
                underBox = UnderAtom.CreateBox(UnderScriptSmaller ? environment.GetSubscriptStyle() : environment);
                maxWidth = Math.Max(maxWidth, underBox.Width);
            }

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

            environment.LastFontId = baseBox.GetLastFontId();

            // Create and add box for over atom.
            if (this.OverAtom != null)
            {
                resultBox.Add(ChangeWidth(overBox, maxWidth));
                resultBox.Add(new SpaceAtom(OverSpaceUnit, 0, OverSpace, 0).CreateBox(environment));
            }

            // Add box for base atom.
            resultBox.Add(ChangeWidth(baseBox, maxWidth));

            double totalHeight = resultBox.Height + resultBox.Depth - baseBox.Depth;

            // Create and add box for under atom.
            if (this.UnderAtom != null)
            {
                resultBox.Add(new SpaceAtom(OverSpaceUnit, 0, UnderSpace, 0).CreateBox(environment));
                resultBox.Add(ChangeWidth(underBox, maxWidth));
            }

            resultBox.Depth  = resultBox.Height + resultBox.Depth - totalHeight;
            resultBox.Height = totalHeight;

            return(resultBox);
        }
Пример #17
0
        public override Box CreateBox(TexEnvironment environment)
        {
            // Create box for base atom, in cramped style.
            var baseBox = this.BaseAtom == null ? StrutBox.Empty : this.BaseAtom.CreateBox(environment.GetCrampedStyle());

            // Create result box.
            var defaultLineThickness = environment.TexFont.GetDefaultLineThickness(environment.Style);
            var resultBox            = new OverBar(environment, baseBox, 3 * defaultLineThickness, defaultLineThickness);

            // Adjust height and depth of result box.
            resultBox.Height = baseBox.Height + 5 * defaultLineThickness;
            resultBox.Depth  = baseBox.Depth;

            return(resultBox);
        }
Пример #18
0
        public override Box CreateBox(TexEnvironment environment)
        {
            // Create box for base atom, in cramped style.
            var baseBox = this.BaseAtom == null ? StrutBox.Empty : this.BaseAtom.CreateBox(environment.GetCrampedStyle());

            // Create result box.
            var defaultLineThickness = environment.TexFont.GetDefaultLineThickness(environment.Style);
            var resultBox = new OverBar(baseBox, 3 * defaultLineThickness, defaultLineThickness);

            // Adjust height and depth of result box.
            resultBox.Height = baseBox.Height + 5 * defaultLineThickness;
            resultBox.Depth = baseBox.Depth;

            return resultBox;
        }
Пример #19
0
        public override Box CreateBox(TexEnvironment environment)
        {
            var texFont = environment.TexFont;
            var style   = environment.Style;

            // Create box for base atom.
            var baseBox = this.BaseAtom.CreateBox(environment);

            // Create result box.
            var resultBox = new HorizontalBox();
            var axis      = texFont.GetAxisHeight(style);
            var delta     = Math.Max(baseBox.Height - axis, baseBox.Depth + axis);
            var minHeight = Math.Max((delta / 500) * delimeterFactor, 2 * delta - delimeterShortfall);

            // Create and add box for left delimeter.
            if (LeftDelimeter != null)
            {
                var leftDelimeterBox = DelimiterFactory.CreateBox(this.LeftDelimeter.Name, minHeight, environment);
                CentreBox(leftDelimeterBox, axis);
                resultBox.Add(leftDelimeterBox);
            }

            // add glueElement between left delimeter and base Atom, unless base Atom is whitespace.
            if (!(this.BaseAtom is SpaceAtom))
            {
                resultBox.Add(Glue.CreateBox(TexAtomType.Opening, this.BaseAtom.GetLeftType(), environment));
            }

            // add box for base Atom.
            resultBox.Add(baseBox);

            // add glueElement between right delimeter and base Atom, unless base Atom is whitespace.
            if (!(this.BaseAtom is SpaceAtom))
            {
                resultBox.Add(Glue.CreateBox(this.BaseAtom.GetRightType(), TexAtomType.Closing, environment));
            }

            // Create and add box for right delimeter.
            if (this.RightDelimeter != null)
            {
                var rightDelimeterBox = DelimiterFactory.CreateBox(this.RightDelimeter.Name, minHeight, environment);
                CentreBox(rightDelimeterBox, axis);
                resultBox.Add(rightDelimeterBox);
            }

            return(resultBox);
        }
Пример #20
0
        public override Box CreateBox(TexEnvironment environment)
        {
            var defaultLineThickness = environment.TexFont.GetDefaultLineThickness(environment.Style);

            // Create box for base atom.
            var baseBox = this.BaseAtom == null ? StrutBox.Empty : this.BaseAtom.CreateBox(environment);

            // Create result box.
            var resultBox = new VerticalBox();
            resultBox.Add(baseBox);
            resultBox.Add(new StrutBox(0, 3 * defaultLineThickness, 0, 0));
            resultBox.Add(new HorizontalRule(defaultLineThickness, baseBox.Width, 0));

            resultBox.Depth = baseBox.Depth + 5 * defaultLineThickness;
            resultBox.Height = baseBox.Height;

            return resultBox;
        }
        public override Box CreateBox(TexEnvironment environment)
        {
            var defaultLineThickness = environment.MathFont.GetDefaultLineThickness(environment.Style);

            // Create box for base atom.
            var baseBox = this.BaseAtom == null ? StrutBox.Empty : this.BaseAtom.CreateBox(environment);

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

            resultBox.Add(baseBox);
            resultBox.Add(new StrutBox(0, 3 * defaultLineThickness, 0, 0));
            resultBox.Add(new HorizontalRule(environment, defaultLineThickness, baseBox.Width, 0));

            resultBox.Depth  = baseBox.Depth + 5 * defaultLineThickness;
            resultBox.Height = baseBox.Height;

            return(resultBox);
        }
Пример #22
0
        public override Box CreateBox(TexEnvironment environment)
        {
            var texFont = environment.TexFont;
            var style = environment.Style;

            // Create box for base atom.
            var baseBox = this.BaseAtom.CreateBox(environment);

            // Create result box.
            var resultBox = new HorizontalBox();
            var axis = texFont.GetAxisHeight(style);
            var delta = Math.Max(baseBox.Height - axis, baseBox.Depth + axis);
            var minHeight = Math.Max((delta / 500) * delimeterFactor, 2 * delta - delimeterShortfall);

            // Create and add box for left delimeter.
            if (LeftDelimeter != null)
            {
                var leftDelimeterBox = DelimiterFactory.CreateBox(this.LeftDelimeter.Name, minHeight, environment);
                CentreBox(leftDelimeterBox, axis);
                resultBox.Add(leftDelimeterBox);
            }

            // add glueElement between left delimeter and base Atom, unless base Atom is whitespace.
            if (!(this.BaseAtom is SpaceAtom))
                resultBox.Add(Glue.CreateBox(TexAtomType.Opening, this.BaseAtom.GetLeftType(), environment));

            // add box for base Atom.
            resultBox.Add(baseBox);

            // add glueElement between right delimeter and base Atom, unless base Atom is whitespace.
            if (!(this.BaseAtom is SpaceAtom))
                resultBox.Add(Glue.CreateBox(this.BaseAtom.GetRightType(), TexAtomType.Closing, environment));

            // Create and add box for right delimeter.
            if (this.RightDelimeter != null)
            {
                var rightDelimeterBox = DelimiterFactory.CreateBox(this.RightDelimeter.Name, minHeight, environment);
                CentreBox(rightDelimeterBox, axis);
                resultBox.Add(rightDelimeterBox);
            }

            return resultBox;
        }
Пример #23
0
        public override Box CreateBox(TexEnvironment environment)
        {
            var texFont = environment.TexFont;
            var style = environment.Style;

            if ((this.UseVerticalLimits.HasValue && !UseVerticalLimits.Value) ||
                (!this.UseVerticalLimits.HasValue && style >= TexStyle.Text))
                // Attach atoms for limits as scripts.
                return new ScriptsAtom(this.BaseAtom, this.LowerLimitAtom, this.UpperLimitAtom).CreateBox(environment);

            // Create box for base atom.
            Box baseBox;
            double delta;

            if (this.BaseAtom is SymbolAtom && this.BaseAtom.Type == TexAtomType.BigOperator)
            {
                // Find character of best scale for operator symbol.
                var opChar = texFont.GetCharInfo(((SymbolAtom)this.BaseAtom).Name, style);
                if (style < TexStyle.Text && texFont.HasNextLarger(opChar))
                    opChar = texFont.GetNextLargerCharInfo(opChar, style);
                var charBox = new CharBox(environment, opChar);
                charBox.Shift = -(charBox.Height + charBox.Depth) / 2 -
                    environment.TexFont.GetAxisHeight(environment.Style);
                baseBox = new HorizontalBox(charBox);

                delta = opChar.Metrics.Italic;
                if (delta > TexUtilities.FloatPrecision)
                    baseBox.Add(new StrutBox(delta, 0, 0, 0));
            }
            else
            {
                baseBox = new HorizontalBox(this.BaseAtom == null ? StrutBox.Empty : BaseAtom.CreateBox(environment));
                delta = 0;
            }

            // Create boxes for upper and lower limits.
            var upperLimitBox = this.UpperLimitAtom == null ? null : this.UpperLimitAtom.CreateBox(
                environment.GetSuperscriptStyle());
            var lowerLimitBox = this.LowerLimitAtom == null ? null : this.LowerLimitAtom.CreateBox(
                environment.GetSubscriptStyle());

            // Make all component boxes equally wide.
            var maxWidth = Math.Max(Math.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 = new VerticalBox();
            var opSpacing5 = texFont.GetBigOpSpacing5(style);
            var kern = 0d;

            // Create and add box for upper limit.
            if (UpperLimitAtom != null)
            {
                resultBox.Add(new StrutBox(0, opSpacing5, 0, 0));
                upperLimitBox.Shift = delta / 2;
                resultBox.Add(upperLimitBox);
                kern = Math.Max(texFont.GetBigOpSpacing1(style), texFont.GetBigOpSpacing3(style) -
                    upperLimitBox.Depth);
                resultBox.Add(new StrutBox(0, kern, 0, 0));
            }

            // Add box for base atom.
            resultBox.Add(baseBox);

            // Create and add box for lower limit.
            if (LowerLimitAtom != null)
            {
                resultBox.Add(new StrutBox(0, Math.Max(texFont.GetBigOpSpacing2(style), texFont.GetBigOpSpacing4(style) -
                    lowerLimitBox.Height), 0, 0));
                lowerLimitBox.Shift = -delta / 2;
                resultBox.Add(lowerLimitBox);
                resultBox.Add(new StrutBox(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;
        }
Пример #24
0
        public TexRenderer GetRenderer(TexStyle style, double scale)
        {
            var environment = new TexEnvironment(style, new DefaultTexFont(scale));

            return(new TexRenderer(CreateBox(environment), scale));
        }
Пример #25
0
 public override Box CreateBox(TexEnvironment environment)
 {
     var resultBox = this.RowAtom.CreateBox(environment);
     return new StrutBox((this.useWidth ? resultBox.Width : 0), (this.useHeight ? resultBox.Height : 0),
         (this.useDepth ? resultBox.Depth : 0), resultBox.Shift);
 }
Пример #26
0
 private double GetConversionFactor(TexUnit unit, TexEnvironment environment)
 {
     return(unitConversions[(int)unit](environment));
 }
Пример #27
0
        public override Box CreateBox(TexEnvironment environment)
        {
            var texFont = environment.TexFont;
            var style   = environment.Style;

            // Create box for base atom.
            var baseBox = (this.BaseAtom == null ? StrutBox.Empty : this.BaseAtom.CreateBox(environment));

            if (this.SubscriptAtom == null && this.SuperscriptAtom == null)
            {
                return(baseBox);
            }

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

            // Get last font used or default Mu font.
            int lastFontId = baseBox.GetLastFontId();

            if (lastFontId == TexFontUtilities.NoFontId)
            {
                lastFontId = texFont.GetMuFontId();
            }

            var subscriptStyle   = environment.GetSubscriptStyle();
            var superscriptStyle = environment.GetSuperscriptStyle();

            // Set delta value and preliminary shift-up and shift-down amounts depending on type of base atom.
            var    delta = 0d;
            double shiftUp, shiftDown;

            if (this.BaseAtom is AccentedAtom)
            {
                var accentedBox = ((AccentedAtom)this.BaseAtom).BaseAtom.CreateBox(environment.GetCrampedStyle());
                shiftUp   = accentedBox.Height - texFont.GetSupDrop(superscriptStyle.Style);
                shiftDown = accentedBox.Depth + texFont.GetSubDrop(subscriptStyle.Style);
            }
            else if (this.BaseAtom is SymbolAtom && this.BaseAtom.Type == TexAtomType.BigOperator)
            {
                var charInfo = texFont.GetCharInfo(((SymbolAtom)this.BaseAtom).Name, style);
                if (style < TexStyle.Text && texFont.HasNextLarger(charInfo))
                {
                    charInfo = texFont.GetNextLargerCharInfo(charInfo, style);
                }
                var charBox = new CharBox(environment, charInfo);

                charBox.Shift = -(charBox.Height + charBox.Depth) / 2 - environment.TexFont.GetAxisHeight(
                    environment.Style);
                resultBox = new HorizontalBox(charBox);

                delta = charInfo.Metrics.Italic;
                if (delta > TexUtilities.FloatPrecision && this.SubscriptAtom == null)
                {
                    resultBox.Add(new StrutBox(delta, 0, 0, 0));
                }

                shiftUp   = resultBox.Height - texFont.GetSupDrop(superscriptStyle.Style);
                shiftDown = resultBox.Depth + texFont.GetSubDrop(subscriptStyle.Style);
            }
            else if (this.BaseAtom is CharSymbol)
            {
                var charFont = ((CharSymbol)this.BaseAtom).GetCharFont(texFont);
                if (!((CharSymbol)this.BaseAtom).IsTextSymbol || !texFont.HasSpace(charFont.FontId))
                {
                    delta = texFont.GetCharInfo(charFont, style).Metrics.Italic;
                }
                if (delta > TexUtilities.FloatPrecision && SubscriptAtom == null)
                {
                    resultBox.Add(new StrutBox(delta, 0, 0, 0));
                    delta = 0;
                }

                shiftUp   = 0;
                shiftDown = 0;
            }
            else
            {
                shiftUp   = baseBox.Height - texFont.GetSupDrop(superscriptStyle.Style);
                shiftDown = baseBox.Depth + texFont.GetSubDrop(subscriptStyle.Style);
            }

            Box superscriptBox          = null;
            Box superscriptContainerBox = null;
            Box subscriptBox            = null;
            Box subscriptContainerBox   = null;

            if (this.SuperscriptAtom != null)
            {
                // Create box for superscript atom.
                superscriptBox          = this.SuperscriptAtom.CreateBox(superscriptStyle);
                superscriptContainerBox = new HorizontalBox(superscriptBox);

                // Add box for script space.
                superscriptContainerBox.Add(scriptSpaceAtom.CreateBox(environment));

                // Adjust shift-up amount.
                double p;
                if (style == TexStyle.Display)
                {
                    p = texFont.GetSup1(style);
                }
                else if (environment.GetCrampedStyle().Style == style)
                {
                    p = texFont.GetSup3(style);
                }
                else
                {
                    p = texFont.GetSup2(style);
                }
                shiftUp = Math.Max(Math.Max(shiftUp, p), superscriptBox.Depth + Math.Abs(texFont.GetXHeight(
                                                                                             style, lastFontId)) / 4);
            }

            if (this.SubscriptAtom != null)
            {
                // Create box for subscript atom.
                subscriptBox          = this.SubscriptAtom.CreateBox(subscriptStyle);
                subscriptContainerBox = new HorizontalBox(subscriptBox);

                // Add box for script space.
                subscriptContainerBox.Add(scriptSpaceAtom.CreateBox(environment));
            }

            // Check if only superscript is set.
            if (subscriptBox == null)
            {
                superscriptContainerBox.Shift = -shiftUp;
                resultBox.Add(superscriptContainerBox);
                return(resultBox);
            }

            // Check if only subscript is set.
            if (superscriptBox == null)
            {
                subscriptContainerBox.Shift = Math.Max(Math.Max(shiftDown, texFont.GetSub1(style)), subscriptBox.Height - 4 *
                                                       Math.Abs(texFont.GetXHeight(style, lastFontId)) / 5);
                resultBox.Add(subscriptContainerBox);
                return(resultBox);
            }

            // Adjust shift-down amount.
            shiftDown = Math.Max(shiftDown, texFont.GetSub2(style));

            // Reposition both subscript and superscript.
            double defaultLineThickness = texFont.GetDefaultLineThickness(style);
            // Space between subscript and superscript.
            double 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.
                double psi = 0.8 * Math.Abs(texFont.GetXHeight(style, lastFontId)) - (shiftUp - superscriptBox.Depth);
                if (psi > 0)
                {
                    shiftUp   += psi;
                    shiftDown -= psi;
                }
            }
            scriptsInterSpace = shiftUp - superscriptBox.Depth + shiftDown - subscriptBox.Height;

            // Create box containing both superscript and subscript.
            var scriptsBox = new VerticalBox();

            superscriptContainerBox.Shift = delta;
            scriptsBox.Add(superscriptContainerBox);
            scriptsBox.Add(new StrutBox(0, scriptsInterSpace, 0, 0));
            scriptsBox.Add(subscriptContainerBox);
            scriptsBox.Height = shiftUp + superscriptBox.Height;
            scriptsBox.Depth  = shiftDown + subscriptBox.Depth;
            resultBox.Add(scriptsBox);

            return(resultBox);
        }
Пример #28
0
 internal Box(TexEnvironment environment)
     : this(environment.Foreground, environment.Background)
 {
 }
Пример #29
0
        public static Box CreateBox(string symbol, double minHeight, TexEnvironment environment)
        {
            var texFont  = environment.MathFont;
            var style    = environment.Style;
            var charInfo = texFont.GetCharInfo(symbol, style);

            // Find first version of character that has at least minimum height.
            var metrics     = charInfo.Metrics;
            var totalHeight = metrics.Height + metrics.Depth;

            while (totalHeight < minHeight && texFont.HasNextLarger(charInfo))
            {
                charInfo    = texFont.GetNextLargerCharInfo(charInfo, style);
                metrics     = charInfo.Metrics;
                totalHeight = metrics.Height + metrics.Depth;
            }

            if (totalHeight >= minHeight)
            {
                // Character of sufficient height was found.
                return(new CharBox(environment, charInfo));
            }
            else if (texFont.IsExtensionChar(charInfo))
            {
                var resultBox = new VerticalBox();

                // Construct box from extension character.
                var extension = texFont.GetExtension(charInfo, style);
                if (extension.Top != null)
                {
                    resultBox.Add(new CharBox(environment, extension.Top));
                }
                if (extension.Middle != null)
                {
                    resultBox.Add(new CharBox(environment, extension.Middle));
                }
                if (extension.Bottom != null)
                {
                    resultBox.Add(new CharBox(environment, extension.Bottom));
                }

                // Insert repeatable part multiple times until box is high enough.
                var repeatBox = new CharBox(environment, extension.Repeat);
                do
                {
                    if (extension.Top != null && extension.Bottom != null)
                    {
                        resultBox.Add(1, repeatBox);
                        if (extension.Middle != null)
                        {
                            resultBox.Add(resultBox.Children.Count - 1, repeatBox);
                        }
                    }
                    else if (extension.Bottom != null)
                    {
                        resultBox.Add(0, repeatBox);
                    }
                    else
                    {
                        resultBox.Add(repeatBox);
                    }
                } while (resultBox.Height + resultBox.Depth < minHeight);

                return(resultBox);
            }
            else
            {
                // No extensions available, so use tallest available version of character.
                return(new CharBox(environment, charInfo));
            }
        }
Пример #30
0
        public override Box CreateBox(TexEnvironment environment)
        {
            var charInfo = environment.MathFont.GetCharInfo(this.CharFont, environment.Style);

            return(new CharBox(environment, charInfo));
        }
Пример #31
0
 public override Box CreateBox(TexEnvironment environment)
 {
     return(new CharBox(environment, environment.TexFont.GetCharInfo(this.Name, environment.Style)));
 }
Пример #32
0
 internal Box CreateBox(TexEnvironment environment)
 {
     if (this.RootAtom == null)
         return StrutBox.Empty;
     else
         return this.RootAtom.CreateBox(environment);
 }
Пример #33
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);
        }
Пример #34
0
        public static Box CreateBox(TexAtomType leftAtomType, TexAtomType rightAtomType, TexEnvironment environment)
        {
            leftAtomType  = leftAtomType > TexAtomType.Inner ? TexAtomType.Ordinary : leftAtomType;
            rightAtomType = rightAtomType > TexAtomType.Inner ? TexAtomType.Ordinary : rightAtomType;
            var glueType = glueRules[(int)leftAtomType, (int)rightAtomType, (int)environment.Style / 2];

            return(glueTypes[glueType].CreateBox(environment));
        }
Пример #35
0
        public override Box CreateBox(TexEnvironment environment)
        {
            var texFont = environment.MathFont;
            var style   = environment.Style;

            if ((this.UseVerticalLimits.HasValue && !UseVerticalLimits.Value) ||
                (!this.UseVerticalLimits.HasValue && style >= TexStyle.Text))
            {
                // Attach atoms for limits as scripts.
                return(new ScriptsAtom(this.BaseAtom, this.LowerLimitAtom, this.UpperLimitAtom).CreateBox(environment));
            }

            // Create box for base atom.
            Box    baseBox;
            double delta;

            if (this.BaseAtom is SymbolAtom && this.BaseAtom.Type == TexAtomType.BigOperator)
            {
                // Find character of best scale for operator symbol.
                var opChar = texFont.GetCharInfo(((SymbolAtom)this.BaseAtom).Name, style);
                if (style < TexStyle.Text && texFont.HasNextLarger(opChar))
                {
                    opChar = texFont.GetNextLargerCharInfo(opChar, style);
                }
                var charBox = new CharBox(environment, opChar);
                charBox.Shift = -(charBox.Height + charBox.Depth) / 2 -
                                environment.MathFont.GetAxisHeight(environment.Style);
                baseBox = new HorizontalBox(charBox);

                delta = opChar.Metrics.Italic;
                if (delta > TexUtilities.FloatPrecision)
                {
                    baseBox.Add(new StrutBox(delta, 0, 0, 0));
                }
            }
            else
            {
                baseBox = new HorizontalBox(this.BaseAtom == null ? StrutBox.Empty : BaseAtom.CreateBox(environment));
                delta   = 0;
            }

            // Create boxes for upper and lower limits.
            var upperLimitBox = this.UpperLimitAtom == null ? null : this.UpperLimitAtom.CreateBox(
                environment.GetSuperscriptStyle());
            var lowerLimitBox = this.LowerLimitAtom == null ? null : this.LowerLimitAtom.CreateBox(
                environment.GetSubscriptStyle());

            // Make all component boxes equally wide.
            var maxWidth = Math.Max(Math.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  = new VerticalBox();
            var opSpacing5 = texFont.GetBigOpSpacing5(style);
            var kern       = 0d;

            // Create and add box for upper limit.
            if (UpperLimitAtom != null)
            {
                resultBox.Add(new StrutBox(0, opSpacing5, 0, 0));
                upperLimitBox.Shift = delta / 2;
                resultBox.Add(upperLimitBox);
                kern = Math.Max(texFont.GetBigOpSpacing1(style), texFont.GetBigOpSpacing3(style) -
                                upperLimitBox.Depth);
                resultBox.Add(new StrutBox(0, kern, 0, 0));
            }

            // Add box for base atom.
            resultBox.Add(baseBox);

            // Create and add box for lower limit.
            if (LowerLimitAtom != null)
            {
                resultBox.Add(new StrutBox(0, Math.Max(texFont.GetBigOpSpacing2(style), texFont.GetBigOpSpacing4(style) -
                                                       lowerLimitBox.Height), 0, 0));
                lowerLimitBox.Shift = -delta / 2;
                resultBox.Add(lowerLimitBox);
                resultBox.Add(new StrutBox(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);
        }
Пример #36
0
        protected override Box CreateBoxCore(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).Value.FontId);
            }
            else
            {
                clearance = defaultRuleThickness;
            }
            clearance = defaultRuleThickness + Math.Abs(clearance) / 4;

            // Create box for base atom, in cramped style.
            var baseBox = this.BaseAtom == null? StrutBox.Empty: 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, Source);

            radicalSignBox.Source = Source;

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

            clearance += delta / 2;

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

            //Create box to hold the radical and the degree atom(if it exists)
            var radicalContainerBox = new VerticalBox();
            //Create a box for creating a space for the radical sign box's left shift and width
            var horizoverlapbox = new StrutBox(0, 0, 0, 0);

            radicalContainerBox.Add(horizoverlapbox);
            radicalContainerBox.Add(radicalSignBox);

            // Create box for root atom.
            var radrootBox   = this.DegreeAtom == null ?(this.DegreeSpecified? StrutBox.Empty:NullAtom.NullBox) : this.DegreeAtom.CreateBox(environment.GetRootStyle());
            var bottomShift  = scale * (radicalSignBox.Height + radicalSignBox.Depth);
            var rcbItemsdiff = radicalSignBox.TotalHeight - radrootBox.TotalHeight;

            bottomShift      = rcbItemsdiff;
            radrootBox.Shift = 0;
            if (radrootBox.TotalHeight < radicalSignBox.TotalHeight / 2)
            {
                bottomShift = (radicalSignBox.TotalHeight / 2) + radrootBox.TotalHeight;
            }
            var Vnegspace = new StrutBox(0, -bottomShift, 0, 0);

            radicalContainerBox.Add(Vnegspace);
            radicalContainerBox.Add(radrootBox);

            var leftshift = this.DegreeAtom == null? 0: radrootBox.TotalWidth - radicalSignBox.TotalWidth / 2;

            if (radrootBox.TotalWidth < (radicalSignBox.TotalWidth / 2))
            {
                leftshift = 0;
            }
            radicalSignBox.Shift = leftshift;
            //increase the left overlap width
            horizoverlapbox.Width = leftshift + radicalSignBox.Width;

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

            resultBox.Add(radicalContainerBox);
            //adjust the vertical shift of the radicalContainerBox
            radicalContainerBox.Shift = -defaultRuleThickness - radicalContainerBox.Depth;
            var leftpad = radicalContainerBox.TotalWidth - radicalSignBox.Shift - radicalSignBox.TotalWidth;

            resultBox.Add(new StrutBox(leftpad, 0, 0, 0));
            overBar.Shift = -defaultRuleThickness - radicalContainerBox.Depth;
            resultBox.Add(overBar);

            return(resultBox);
        }
Пример #37
0
        public override Box CreateBox(TexEnvironment environment)
        {
            // Create box for base atom.
            var baseBox = this.BaseAtom == null ? StrutBox.Empty : this.BaseAtom.CreateBox(environment);

            // Create boxes for over and under atoms.
            Box overBox = null, underBox = null;
            var maxWidth = baseBox.Width;

            if (this.OverAtom != null)
            {
                overBox = OverAtom.CreateBox(OverScriptSmaller ? environment.GetSubscriptStyle() : environment);
                maxWidth = Math.Max(maxWidth, overBox.Width);
            }

            if (this.UnderAtom != null)
            {
                underBox = UnderAtom.CreateBox(UnderScriptSmaller ? environment.GetSubscriptStyle() : environment);
                maxWidth = Math.Max(maxWidth, underBox.Width);
            }

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

            environment.LastFontId = baseBox.GetLastFontId();

            // Create and add box for over atom.
            if (this.OverAtom != null)
            {
                resultBox.Add(ChangeWidth(overBox, maxWidth));
                resultBox.Add(new SpaceAtom(OverSpaceUnit, 0, OverSpace, 0).CreateBox(environment));
            }

            // Add box for base atom.
            resultBox.Add(ChangeWidth(baseBox, maxWidth));

            double totalHeight = resultBox.Height + resultBox.Depth - baseBox.Depth;

            // Create and add box for under atom.
            if (this.UnderAtom != null)
            {
                resultBox.Add(new SpaceAtom(OverSpaceUnit, 0, UnderSpace, 0).CreateBox(environment));
                resultBox.Add(ChangeWidth(underBox, maxWidth));
            }

            resultBox.Depth = resultBox.Height + resultBox.Depth - totalHeight;
            resultBox.Height = totalHeight;

            return resultBox;
        }
Пример #38
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);
        }
Пример #39
0
        public override Box CreateBox(TexEnvironment environment)
        {
            var texFont = environment.MathFont;
            var style   = environment.Style;

            // Create box for base atom.
            var baseBox = this.BaseAtom == null ? StrutBox.Empty : this.BaseAtom.CreateBox(environment.GetCrampedStyle());
            var skew    = 0d;

            if (this.BaseAtom is CharSymbol)
            {
                skew = texFont.GetSkew(((CharSymbol)this.BaseAtom).GetCharFont(texFont), style);
            }

            // Find character of best scale for accent symbol.
            var accentChar = texFont.GetCharInfo(AccentAtom.Name, style);

            while (texFont.HasNextLarger(accentChar))
            {
                var nextLargerChar = texFont.GetNextLargerCharInfo(accentChar, style);
                if (nextLargerChar.Metrics.Width > baseBox.Width)
                {
                    break;
                }
                accentChar = nextLargerChar;
            }

            var resultBox = new VerticalBox();

            // Create and add box for accent symbol.
            Box accentBox;
            var accentItalicWidth = accentChar.Metrics.Italic;

            if (accentItalicWidth > TexUtilities.FloatPrecision)
            {
                accentBox = new HorizontalBox(new CharBox(environment, accentChar));
                accentBox.Add(new StrutBox(accentItalicWidth, 0, 0, 0));
            }
            else
            {
                accentBox = new CharBox(environment, accentChar);
            }
            resultBox.Add(accentBox);

            var delta = Math.Min(baseBox.Height, texFont.GetXHeight(style, accentChar.FontId));

            resultBox.Add(new StrutBox(0, -delta, 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) / 2;

            accentBox.Shift = skew + Math.Max(boxWidthsDiff, 0);
            if (boxWidthsDiff < 0)
            {
                baseBox = new HorizontalBox(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);
        }
Пример #40
0
 public abstract Box CreateBox(TexEnvironment environment);
Пример #41
0
        public static Box CreateBox(string symbol, double minHeight, TexEnvironment environment)
        {
            var texFont = environment.TexFont;
            var style = environment.Style;
            var charInfo = texFont.GetCharInfo(symbol, style);

            // Find first version of character that has at least minimum height.
            var metrics = charInfo.Metrics;
            var totalHeight = metrics.Height + metrics.Depth;
            while (totalHeight < minHeight && texFont.HasNextLarger(charInfo))
            {
                charInfo = texFont.GetNextLargerCharInfo(charInfo, style);
                metrics = charInfo.Metrics;
                totalHeight = metrics.Height + metrics.Depth;
            }

            if (totalHeight >= minHeight)
            {
                // Character of sufficient height was found.
                return new CharBox(environment, charInfo);
            }
            else if (texFont.IsExtensionChar(charInfo))
            {
                var resultBox = new VerticalBox();

                // Construct box from extension character.
                var extension = texFont.GetExtension(charInfo, style);
                if (extension.Top != null)
                    resultBox.Add(new CharBox(environment, extension.Top));
                if (extension.Middle != null)
                    resultBox.Add(new CharBox(environment, extension.Middle));
                if (extension.Bottom != null)
                    resultBox.Add(new CharBox(environment, extension.Bottom));

                // Insert repeatable part multiple times until box is high enough.
                var repeatBox = new CharBox(environment, extension.Repeat);
                do
                {
                    if (extension.Top != null && extension.Bottom != null)
                    {
                        resultBox.Add(1, repeatBox);
                        if (extension.Middle != null)
                            resultBox.Add(resultBox.Children.Count - 1, repeatBox);
                    }
                    else if (extension.Bottom != null)
                    {
                        resultBox.Add(0, repeatBox);
                    }
                    else
                    {
                        resultBox.Add(repeatBox);
                    }
                } while (resultBox.Height + resultBox.Depth < minHeight);

                return resultBox;
            }
            else
            {
                // No extensions available, so use tallest available version of character.
                return new CharBox(environment, charInfo);
            }
        }
Пример #42
0
 public override Box CreateBox(TexEnvironment environment)
 {
     return this.Atom.CreateBox(environment);
 }
Пример #43
0
Файл: Box.cs Проект: Civa/Zenith
 internal Box(TexEnvironment environment)
     : this(environment.Foreground, environment.Background)
 {
 }
Пример #44
0
 private double GetConversionFactor(TexUnit unit, TexEnvironment environment)
 {
     return unitConversions[(int)unit](environment);
 }
 public override Box CreateBox(TexEnvironment environment)
 {
     return(this.Atom.CreateBox(environment));
 }
Пример #46
0
 public override Box CreateBox(TexEnvironment environment)
 {
     if (isHardSpace)
         return new StrutBox(environment.TexFont.GetSpace(environment.Style), 0, 0, 0);
     else
         return new StrutBox(width * GetConversionFactor(widthUnit, environment), height * GetConversionFactor(
             heightUnit, environment), depth * GetConversionFactor(depthUnit, environment), 0);
 }
Пример #47
0
        public override Box CreateBox(TexEnvironment environment)
        {
            var texFont = environment.TexFont;
            var style = environment.Style;

            // Create box for base atom.
            var baseBox = (this.BaseAtom == null ? StrutBox.Empty : this.BaseAtom.CreateBox(environment));
            if (this.SubscriptAtom == null && this.SuperscriptAtom == null)
                return baseBox;

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

            // Get last font used or default Mu font.
            int lastFontId = baseBox.GetLastFontId();
            if (lastFontId == TexFontUtilities.NoFontId)
                lastFontId = texFont.GetMuFontId();

            var subscriptStyle = environment.GetSubscriptStyle();
            var superscriptStyle = environment.GetSuperscriptStyle();

            // Set delta value and preliminary shift-up and shift-down amounts depending on type of base atom.
            var delta = 0d;
            double shiftUp, shiftDown;

            if (this.BaseAtom is AccentedAtom)
            {
                var accentedBox = ((AccentedAtom)this.BaseAtom).BaseAtom.CreateBox(environment.GetCrampedStyle());
                shiftUp = accentedBox.Height - texFont.GetSupDrop(superscriptStyle.Style);
                shiftDown = accentedBox.Depth + texFont.GetSubDrop(subscriptStyle.Style);
            }
            else if (this.BaseAtom is SymbolAtom && this.BaseAtom.Type == TexAtomType.BigOperator)
            {
                var charInfo = texFont.GetCharInfo(((SymbolAtom)this.BaseAtom).Name, style);
                if (style < TexStyle.Text && texFont.HasNextLarger(charInfo))
                    charInfo = texFont.GetNextLargerCharInfo(charInfo, style);
                var charBox = new CharBox(environment, charInfo);

                charBox.Shift = -(charBox.Height + charBox.Depth) / 2 - environment.TexFont.GetAxisHeight(
                    environment.Style);
                resultBox = new HorizontalBox(charBox);

                delta = charInfo.Metrics.Italic;
                if (delta > TexUtilities.FloatPrecision && this.SubscriptAtom == null)
                    resultBox.Add(new StrutBox(delta, 0, 0, 0));

                shiftUp = resultBox.Height - texFont.GetSupDrop(superscriptStyle.Style);
                shiftDown = resultBox.Depth + texFont.GetSubDrop(subscriptStyle.Style);
            }
            else if (this.BaseAtom is CharSymbol)
            {
                var charFont = ((CharSymbol)this.BaseAtom).GetCharFont(texFont);
                if (!((CharSymbol)this.BaseAtom).IsTextSymbol || !texFont.HasSpace(charFont.FontId))
                    delta = texFont.GetCharInfo(charFont, style).Metrics.Italic;
                if (delta > TexUtilities.FloatPrecision && SubscriptAtom == null)
                {
                    resultBox.Add(new StrutBox(delta, 0, 0, 0));
                    delta = 0;
                }

                shiftUp = 0;
                shiftDown = 0;
            }
            else
            {
                shiftUp = baseBox.Height - texFont.GetSupDrop(superscriptStyle.Style);
                shiftDown = baseBox.Depth + texFont.GetSubDrop(subscriptStyle.Style);
            }

            Box superscriptBox = null;
            Box superscriptContainerBox = null;
            Box subscriptBox = null;
            Box subscriptContainerBox = null;

            if (this.SuperscriptAtom != null)
            {
                // Create box for superscript atom.
                superscriptBox = this.SuperscriptAtom.CreateBox(superscriptStyle);
                superscriptContainerBox = new HorizontalBox(superscriptBox);

                // Add box for script space.
                superscriptContainerBox.Add(scriptSpaceAtom.CreateBox(environment));

                // Adjust shift-up amount.
                double p;
                if (style == TexStyle.Display)
                    p = texFont.GetSup1(style);
                else if (environment.GetCrampedStyle().Style == style)
                    p = texFont.GetSup3(style);
                else
                    p = texFont.GetSup2(style);
                shiftUp = Math.Max(Math.Max(shiftUp, p), superscriptBox.Depth + Math.Abs(texFont.GetXHeight(
                    style, lastFontId)) / 4);
            }

            if (this.SubscriptAtom != null)
            {
                // Create box for subscript atom.
                subscriptBox = this.SubscriptAtom.CreateBox(subscriptStyle);
                subscriptContainerBox = new HorizontalBox(subscriptBox);

                // Add box for script space.
                subscriptContainerBox.Add(scriptSpaceAtom.CreateBox(environment));
            }

            // Check if only superscript is set.
            if (subscriptBox == null)
            {
                superscriptContainerBox.Shift = -shiftUp;
                resultBox.Add(superscriptContainerBox);
                return resultBox;
            }

            // Check if only subscript is set.
            if (superscriptBox == null)
            {
                subscriptBox.Shift = Math.Max(Math.Max(shiftDown, texFont.GetSub1(style)), subscriptBox.Height - 4 *
                    Math.Abs(texFont.GetXHeight(style, lastFontId)) / 5);
                resultBox.Add(subscriptContainerBox);
                return resultBox;
            }

            // Adjust shift-down amount.
            shiftDown = Math.Max(shiftDown, texFont.GetSub2(style));

            // Reposition both subscript and superscript.
            double defaultLineThickness = texFont.GetDefaultLineThickness(style);
            // Space between subscript and superscript.
            double 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.
                double psi = 0.8 * Math.Abs(texFont.GetXHeight(style, lastFontId)) - (shiftUp - superscriptBox.Depth);
                if (psi > 0)
                {
                    shiftUp += psi;
                    shiftDown -= psi;
                }
            }
            scriptsInterSpace = shiftUp - superscriptBox.Depth + shiftDown - subscriptBox.Height;

            // Create box containing both superscript and subscript.
            var scriptsBox = new VerticalBox();
            superscriptContainerBox.Shift = delta;
            scriptsBox.Add(superscriptContainerBox);
            scriptsBox.Add(new StrutBox(0, scriptsInterSpace, 0, 0));
            scriptsBox.Add(subscriptContainerBox);
            scriptsBox.Height = shiftUp + superscriptBox.Height;
            scriptsBox.Depth = shiftDown + subscriptBox.Depth;
            resultBox.Add(scriptsBox);

            return resultBox;
        }
Пример #48
0
 public override Box CreateBox(TexEnvironment environment)
 {
     return new CharBox(environment, environment.TexFont.GetCharInfo(this.Name, environment.Style));
 }
Пример #49
0
 public override Box CreateBox(TexEnvironment environment)
 {
     var charInfo = GetCharInfo(environment.TexFont, environment.Style);
     return new CharBox(environment, charInfo);
 }
Пример #50
0
 public abstract Box CreateBox(TexEnvironment environment);
Пример #51
0
        public override Box CreateBox(TexEnvironment environment)
        {
            var texFont = environment.TexFont;

            // Create result box.
            var resultBox = new HorizontalBox(environment.Foreground, environment.Background);

            // 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;
                ChangeAtomToOrdinary(curAtom, this.PreviousAtom, nextAtom);

                // Check if atom is part of ligature or should be kerned.
                var kern = 0d;
                if (hasNextAtom && curAtom.GetRightType() == TexAtomType.Ordinary && curAtom.IsCharSymbol)
                {
                    if (nextAtom is CharSymbol && ligatureKernChangeSet[(int)nextAtom.GetLeftType()])
                    {
                        curAtom.IsTextSymbol = true;
                        var leftAtomCharFont = curAtom.GetCharFont(texFont);
                        var rightAtomCharFont = ((CharSymbol)nextAtom).GetCharFont(texFont);
                        var ligatureCharFont = texFont.GetLigature(leftAtomCharFont, rightAtomCharFont);
                        if (ligatureCharFont == null)
                        {
                            // Atom should be kerned.
                            kern = texFont.GetKern(leftAtomCharFont, rightAtomCharFont, environment.Style);
                        }
                        else
                        {
                            // Atom is part of ligature.
                            curAtom.SetLigature(new FixedCharAtom(ligatureCharFont));
                            i++;
                        }
                    }
                }

                // Create and add glue box, unless atom is first of row or previous/current atom is kern.
                if (i != 0 && this.PreviousAtom != null && !this.PreviousAtom.IsKern && !curAtom.IsKern)
                    resultBox.Add(Glue.CreateBox(this.PreviousAtom.GetRightType(), curAtom.GetLeftType(), environment));

                // Create and add box for atom.
                curAtom.PreviousAtom = this.PreviousAtom;
                var curBox = curAtom.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)
                    this.PreviousAtom = curAtom;
            }

            // Reset previous atom.
            this.PreviousAtom = null;

            return resultBox;
        }
Пример #52
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;
        }
Пример #53
0
        public override Box CreateBox(TexEnvironment environment)
        {
            // Create result box.
            var resultBox = new HorizontalBox(environment.Foreground, environment.Background);

            // 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;
                ChangeAtomToOrdinary(curAtom, this.PreviousAtom, nextAtom);

                // Check if atom is part of ligature or should be kerned.
                var kern = 0d;
                if (hasNextAtom && curAtom.GetRightType() == TexAtomType.Ordinary && curAtom.IsCharSymbol)
                {
                    if (nextAtom is CharSymbol cs && ligatureKernChangeSet[(int)nextAtom.GetLeftType()])
                    {
                        var font = cs.GetStyledFont(environment);
                        curAtom.IsTextSymbol = true;
                        var leftAtomCharFont  = curAtom.GetCharFont(font);
                        var rightAtomCharFont = cs.GetCharFont(font);
                        var ligatureCharFont  = font.GetLigature(leftAtomCharFont, rightAtomCharFont);
                        if (ligatureCharFont == null)
                        {
                            // Atom should be kerned.
                            kern = font.GetKern(leftAtomCharFont, rightAtomCharFont, environment.Style);
                        }
                        else
                        {
                            // Atom is part of ligature.
                            curAtom.SetLigature(new FixedCharAtom(ligatureCharFont));
                            i++;
                        }
                    }
                }

                // Create and add glue box, unless atom is first of row or previous/current atom is kern.
                if (i != 0 && this.PreviousAtom != null && !this.PreviousAtom.IsKern && !curAtom.IsKern)
                {
                    resultBox.Add(Glue.CreateBox(this.PreviousAtom.GetRightType(), curAtom.GetLeftType(), environment));
                }

                // Create and add box for atom.
                curAtom.PreviousAtom = this.PreviousAtom;
                var curBox = curAtom.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)
                {
                    this.PreviousAtom = curAtom;
                }
            }

            // Reset previous atom.
            this.PreviousAtom = null;

            return(resultBox);
        }
Пример #54
0
 private Box CreateBox(TexEnvironment environment)
 {
     var texFont = environment.TexFont;
     var quad = texFont.GetQuad(texFont.GetMuFontId(), environment.Style);
     return new GlueBox((this.Space / 18.0f) * quad, (this.Stretch / 18.0f) * quad, (this.Shrink / 18.0f) * quad);
 }
Пример #55
0
 public TexRenderer GetRenderer(TexStyle style, double scale)
 {
     var environment = new TexEnvironment(style, new DefaultTexFont(scale));
     return new TexRenderer(CreateBox(environment), scale);
 }
Пример #56
0
        public override Box CreateBox(TexEnvironment environment)
        {
            var charInfo = GetCharInfo(environment.TexFont, environment.Style);

            return(new CharBox(environment, charInfo));
        }