예제 #1
0
        public override Box CreateBox()
        {
            var result = HorizontalBox.Get();
            var margin = TEXConfiguration.main.BackdropMargin * TexContext.Scale * 2;
            var box    = baseAtom.CreateBox();

            if (this.margin)
            {
                box = VerticalBox.Get(HorizontalBox.Get(box, box.width + margin,
                                                        TexAlignment.Center), box.totalHeight + margin, TexAlignment.Center);
            }

            var bg = HorizontalRule.Get(box.height, box.width, 0, box.depth, true);

            if (color != Color.clear)
            {
                result.Add(AttrColorBox.Get(0, color));
            }
            result.Add(bg);
            if (color != Color.clear)
            {
                result.Add(AttrColorBox.Get(3, color));
            }

            result.Add(StrutBox.Get(-box.width, 0, 0, 0));
            result.Add(box);

            return(result);
        }
예제 #2
0
        Box CreateGenericRadicalBox(Box baseBox, string genericSymbol)
        {
            float clearance;
            var   lineThickness = TEXConfiguration.main.LineThickness * TexContext.Scale;

            clearance = lineThickness;

            // Create box for radical sign.
            var totalHeight    = baseBox.totalHeight;
            var radicalSignBox = DelimiterFactory.CreateBox(genericSymbol, totalHeight + clearance + lineThickness);

            // Add half of excess height to clearance.
            //lineThickness = Mathf.Max(radicalSignBox.height, lineThickness);
            clearance = radicalSignBox.totalHeight - totalHeight - lineThickness * 2;

            // Create box for square-root containing base box.
            TexUtility.CentreBox(radicalSignBox);
            var overBar = OverBar.Get(baseBox, clearance, lineThickness);

            var expansion = radicalSignBox.width - CustomizedGenericDelimOffset(genericSymbol, radicalSignBox.totalHeight) * radicalSignBox.width;

            overBar.children[0].width += expansion;
            overBar.children[0].shift -= expansion;

            TexUtility.CentreBox(overBar);
            var radicalContainerBox = HorizontalBox.Get(radicalSignBox);

            radicalContainerBox.Add(overBar);

            // There is no generic root then ...
            return(radicalContainerBox);
        }
예제 #3
0
        public override Box CreateBox(TexStyle style)
        {
            // Create result box.
            var  resultBox = HorizontalBox.Get();
            Atom curAtom = null, prevAtom = null;
            var  resultPos = 0;

            // Create and add box for each atom in row.
            for (int i = 0; i < Elements.Count; i++)
            {
                curAtom = (Elements[i]);

                // Create and add glue box, unless atom is first of row or previous/current atom is spaces.
                if (prevAtom != null && !(prevAtom is SpaceAtom) && !(curAtom is SpaceAtom))
                {
                    Box spaceBox = SpaceAtom.CreateGlueBox(prevAtom.GetRightType(), curAtom.GetLeftType(), style);
                    if (spaceBox != null)
                    {
                        resultBox.Add(spaceBox);
                        resultPos++;
                    }
                }
                // Create and add box for atom.
                GenerateDelimiterBox(resultBox, ref i, ref resultPos, style);
                //resultBox.Add(curBox);
                prevAtom = curAtom;
            }
            return(resultBox);
        }
예제 #4
0
        Box CreateBoxDefault(TexStyle style, Box baseBox)
        {
            var factor        = TexUtility.SizeFactor(style);
            var clearance     = TEXConfiguration.main.RootMargin * factor;
            var lineThickness = TEXConfiguration.main.LineThickness * factor;

            // Create box for radical sign.
            var totalHeight    = baseBox.totalHeight;
            var radicalSignBox = DelimiterFactory.CreateBox(rootSymbol, totalHeight + clearance + lineThickness,
                                                            style);

            // Add some clearance to left and right side
            baseBox = HorizontalBox.Get(baseBox, baseBox.width + clearance * 2, TexAlignment.Center);

            // Add half of excess height to clearance.
            lineThickness = Mathf.Max(radicalSignBox.height, lineThickness);
            clearance     = radicalSignBox.totalHeight - totalHeight - lineThickness * 2;

            // Create box for square-root containing base box.
            TexUtility.CentreBox(radicalSignBox, style);
            var overBar = OverBar.Get(baseBox, clearance, lineThickness);

            TexUtility.CentreBox(overBar, style);
            var radicalContainerBox = HorizontalBox.Get(radicalSignBox);

            radicalContainerBox.Add(overBar);

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

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

            // Create box for root atom.
            var rootBox     = DegreeAtom.CreateBox(TexUtility.GetRootStyle());
            var bottomShift = scale * (radicalContainerBox.height + radicalContainerBox.depth);

            rootBox.shift = radicalContainerBox.depth - rootBox.depth - bottomShift;

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

            // Add box for negative kern.
            var negativeKern = SpaceAtom.Get(-((radicalSignBox.width) / 2f), 0, 0).CreateBox(TexStyle.Display);
            var xPos         = rootBox.width + negativeKern.width;

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

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

            return(resultBox);
        }
예제 #5
0
        public void AddRange(HorizontalBox box)
        {
            var ch = box.children;

            for (int i = 0; i < ch.Count; i++)
            {
                Add(ch[i]);
            }
        }
예제 #6
0
        public void AddRange(HorizontalBox box, int position)
        {
            var ch = box.children;

            for (int i = 0; i < ch.Count; i++)
            {
                Add(position++, ch[i]);
            }
        }
예제 #7
0
 private static Box ChangeWidth(Box box, float maxWidth)
 {
     if (box != null && Mathf.Abs(maxWidth - box.width) > TexUtility.FloatPrecision)
     {
         return(HorizontalBox.Get(box, maxWidth, TexAlignment.Center));
     }
     else
     {
         return(box);
     }
 }
예제 #8
0
 private static Box ChangeWidth(Box box, float maxWidth)
 {
     // Centre specified box in new box of specified width, if necessary.
     if (Mathf.Abs(maxWidth - box.width) > TexUtility.FloatPrecision)
     {
         return(HorizontalBox.Get(box, maxWidth, TexAlignment.Center));
     }
     else
     {
         return(box);
     }
 }
예제 #9
0
        public override Box CreateBox(TexStyle style)
        {
            // Create box for base atom.
            var baseBox = BaseAtom == null ? StrutBox.Empty : BaseAtom.CreateBox(TexUtility.GetCrampedStyle(style));
            // Find character of best scale for accent symbol.
            TexCharMetric accentChar = TEXPreference.main.GetCharMetric(AccentAtom.Name, style);

            while (accentChar.ch.nextLargerExist)
            {
                var nextLargerChar = TEXPreference.main.GetCharMetric(accentChar.ch.nextLarger, style);
                if (nextLargerChar.width > baseBox.width)
                {
                    break;
                }
                accentChar = nextLargerChar;
            }

            var resultBox = VerticalBox.Get();

            // Create and add box for accent symbol.
            var accentBox   = CharBox.Get(style, accentChar);
            var accentWidth = (accentBox.bearing + accentBox.italic) * .5f;

            accentBox.italic  = accentWidth + (accentBox.width * .5f);
            accentBox.bearing = accentWidth - (accentBox.width * .5f);
            //accentBox. = accentBox.width + accentBox.italic - accentBox.bearing;
            resultBox.Add((accentBox));

            //var delta = Mathf.Min(-accentChar.depth, baseBox.height);
            resultBox.Add(StrutBox.Get(0, TEXConfiguration.main.AccentMargin * TexUtility.SizeFactor(style), 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) / 2f;

            accentBox.shift = Mathf.Max(boxWidthsDiff, 0);
            if (boxWidthsDiff < 0)
            {
                baseBox = HorizontalBox.Get(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);
        }
예제 #10
0
 public void Flush()
 {
     if (Box != null)
     {
         Box.Flush();
         Box = null;
     }
     partOfPreviousLine = 0;
     if (metaRules != null)
     {
         //metaRules.Flush();
         metaRules = null;
     }
     ObjPool <TexRenderer> .Release(this);
 }
예제 #11
0
        public override Box CreateBox()
        {
            // Create box for base atom.
            TexContext.Environment.Push(TexUtility.GetCrampedStyle());
            var baseBox = BaseAtom == null ? StrutBox.Empty : BaseAtom.CreateBox();

            TexContext.Environment.Pop();

            // Find character of best scale for accent symbol.
            var acct = TEXPreference.main.GetChar(AccentAtom.Name).GetMetric();

            while (acct.width < baseBox.width && acct.ch.nextLargerExist)
            {
                acct.Flush();
                acct = acct.ch.nextLarger.GetMetric();
            }

            var resultBox = VerticalBox.Get();

            // Create and add box for accent symbol.
            var accentWidth = (acct.bearing + acct.italic) * .5f;

            acct.italic  = accentWidth + (acct.width * .5f);
            acct.bearing = accentWidth - (acct.width * .5f);
            resultBox.Add(acct);

            resultBox.Add(StrutBox.Get(0, TEXConfiguration.main.AccentMargin * TexContext.Scale, 0, 0));

            // Centre and add box for base atom. Centre base box and accent box with respect to each other.
            var boxWidthsDiff = (baseBox.width - acct.width) / 2f;

            acct.shift = Mathf.Max(boxWidthsDiff, 0);
            if (boxWidthsDiff < 0)
            {
                baseBox = HorizontalBox.Get(baseBox, acct.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);
        }
예제 #12
0
        public override Box CreateBox()
        {
            // radius will be implemented later

            var margin = this.margin ? TEXConfiguration.main.BackdropMargin * TexContext.Scale : 0;

            var box = baseAtom.CreateBox();

            var hbox = HorizontalBox.Get(box, box.width + margin * 2, TexAlignment.Center);

            if (thickness.x > 0)
            {
                var rule = HorizontalRule.Get(hbox.height, thickness.x, 0, hbox.depth);
                hbox.Add(0, rule);
                rule.Set(rule.width, rule.height + margin + thickness.w, rule.depth + margin + thickness.y, 0);
            }

            if (thickness.z > 0)
            {
                var rule = HorizontalRule.Get(hbox.height, thickness.z, 0, hbox.depth);
                hbox.Add(rule);
                rule.Set(rule.width, rule.height + margin + thickness.w, rule.depth + margin + thickness.y, 0);
            }

            var vbox = VerticalBox.Get(hbox, hbox.totalHeight + margin * 2, TexAlignment.Center);

            if (thickness.y > 0)
            {
                vbox.Add(HorizontalRule.Get(thickness.y, vbox.width, 0));
            }

            if (thickness.w > 0)
            {
                vbox.Add(0, HorizontalRule.Get(thickness.w, vbox.width, 0));
            }

            if (color != Color.clear)
            {
                vbox.Add(0, AttrColorBox.Get(0, color));
                vbox.Add(AttrColorBox.Get(3, color));
            }

            // readjust
            vbox.height = box.height + margin + thickness.w;
            vbox.depth  = box.depth + margin + thickness.y;
            return(vbox);
        }
예제 #13
0
 public TexRenderer GetRenderer()
 {
     // For compactness:
     // Scale isn't saved, but stored in TexUtility.RenderSizeFactor (and normalized)
     // The actual scaling (param above) is just saved in here, not on each boxes.
     // Color isn't saved, but stored in TexUtility.RenderColor or as a box of AttrColorBox (for \color).
     // FontIndex & FontStyle isn't saved, but stored in TexUtility.RenderFont & TexUtility.Style
     try
     {
         var box = CreateBox();
         return(TexRenderer.Get(box as HorizontalBox ??
                                HorizontalBox.Get(box), AttachedMetaRenderer));
     }
     catch (Exception e)
     {
         throw e;
     }
 }
예제 #14
0
        public static TexRenderer Get(Box box, float scale, TexMetaRenderer meta)
        {
            var renderer = ObjPool <TexRenderer> .Get();

            renderer.Box       = box;
            renderer.Scale     = scale;
            renderer.metaRules = meta;
            // There's an additional step if meta 'line' are declared
            if (renderer.usingMetaRules && renderer.metaRules.line != 0 && box.totalHeight > 0)
            {
                if (!(box is HorizontalBox))
                {
                    renderer.Box = box = HorizontalBox.Get(box);
                }
                box.height = renderer.metaRules.line;
                box.depth  = 0;
            }
            return(renderer);
        }
예제 #15
0
        public override Box CreateBox()
        {
            var width  = size.x;
            var height = size.y;

            Box result;

            if (BaseAtom == null)
            {
                result = StrutBox.Get(width, height, 0, 0);
            }
            else if (BaseAtom is SpaceAtom)
            {
                result = StrutBox.Get(width, height, 0, 0);
            }
            else if (width == 0 && BaseAtom is SymbolAtom)
            {
                result = VerticalBox.Get(DelimiterFactory.CreateBox(((SymbolAtom)BaseAtom).Name, height), height, align);
            }
            else if (height == 0 && BaseAtom is SymbolAtom)
            {
                result = HorizontalBox.Get(DelimiterFactory.CreateBoxHorizontal(((SymbolAtom)BaseAtom).Name, width), width, align);
            }
            else if (width == 0)
            {
                result = VerticalBox.Get(BaseAtom.CreateBox(), height, align);
            }
            else if (height == 0)
            {
                result = HorizontalBox.Get(BaseAtom.CreateBox(), width, align);
            }
            else
            {
                result = VerticalBox.Get(HorizontalBox.Get(BaseAtom.CreateBox(), width, align), height, align);
            }

            if (size.x + size.y > 1e-3f)
            {
                TexUtility.CentreBox(result);
            }
            return(result);
        }
예제 #16
0
        public override Box CreateBox(TexStyle style)
        {
            var result = HorizontalBox.Get();
            var margin = TEXConfiguration.main.BackdropMargin * TexUtility.SizeFactor(style);
            var box    = baseAtom.CreateBox(style);

            box = VerticalBox.Get(HorizontalBox.Get(box, box.width + (horizontalMargin ? margin * 2 : 0), TexAlignment.Center), box.totalHeight + margin * 2, TexAlignment.Center);
            var endColor   = AttrColorBox.Get(0, color, null);
            var startColor = AttrColorBox.Get(0, color, endColor);
            var bg         = HorizontalRule.Get(box.height, box.width, 0, box.depth, true);

            result.Add(startColor);
            result.Add(bg);
            result.Add(endColor);

            result.Add(StrutBox.Get(-box.width, 0, 0, 0));
            result.Add(box);

            return(result);
        }
예제 #17
0
        public static TexRenderer Get(HorizontalBox box, TexMetaRenderer meta, int isPartOfPrev = 0)
        {
            var renderer = ObjPool <TexRenderer> .Get();

            renderer.Box = box;
            //renderer.Scale = scale;
            renderer.metaRules          = meta;
            renderer.partOfPreviousLine = isPartOfPrev;

            // must horizontal box to avoid headache
            if (!(box is HorizontalBox))
            {
                renderer.Box = box = HorizontalBox.Get(box);
            }

            // There's an additional step if meta 'line' are declared
            if (renderer.usingMetaRules && renderer.metaRules.line != 0 && box.totalHeight > 0)
            {
                box.height = renderer.metaRules.line;
                box.depth  = TexUtility.spaceLine;
            }
            return(renderer);
        }
예제 #18
0
        public override Box CreateBox()
        {
            // Create box for base atom.

            // Save it shift and use it later

            // Create result box.


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

            Box baseBox; HorizontalBox resultBox;

            if (SubscriptAtom == null && SuperscriptAtom == null)
            {
                return(BaseAtom == null ? StrutBox.Empty : BaseAtom.CreateBox());
            }
            if (BaseAtom is AccentedAtom)
            {
                TexContext.Environment.Push(TexUtility.GetCrampedStyle());
                baseBox = ((AccentedAtom)BaseAtom).BaseAtom.CreateBox();
                TexContext.Environment.Pop();
            }
            else
            {
                baseBox = (BaseAtom == null ? StrutBox.Empty : BaseAtom.CreateBox());
                //if (BaseAtom is CharSymbol)
                //{
                //    var delta = 0f;
                //    var ch = ((CharSymbol)BaseAtom).GetChar();
                //    if (!((CharSymbol)BaseAtom).IsTextSymbol)
                //        delta =  ch.italix + bearing - width;
                //    if (delta > TexUtility.FloatPrecision && SubscriptAtom == null)
                //    {
                //        resultBox.Add(StrutBox.Get(delta, 0, 0, 0));
                //        delta = 0;
                //    }
                //}
            }

            resultBox = HorizontalBox.Get(baseBox);

            var shift = baseBox.shift;


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

            TexContext.Environment.Push(TexUtility.GetSuperscriptStyle());
            shiftUp = baseBox.height - TEXConfiguration.main.SupDrop * TexContext.Scale;

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

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

                // Adjust shift-up amount.
                float p;
                if (TexContext.Environment.value == TexEnvironment.Display)
                {
                    p = TEXConfiguration.main.SupMin * TexContext.Scale;
                }
                else
                {
                    p = TEXConfiguration.main.SupMinNarrow * TexContext.Scale;
                }

                shiftUp = Mathf.Max(shiftUp, p);
            }

            TexContext.Environment.Pop();

            TexContext.Environment.Push(TexUtility.GetSubscriptStyle());
            shiftDown = baseBox.depth + TEXConfiguration.main.SubDrop * TexContext.Scale;

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

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

            TexContext.Environment.Pop();

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

            // Check if only subscript is set.
            if (superscriptBox == null)
            {
                subscriptBox.shift = Mathf.Max(shiftDown, TEXConfiguration.main.SubMinNoSup * TexContext.Scale);
                resultBox.Add(subscriptContainerBox);
                resultBox.depth = shiftDown + subscriptBox.depth;
                return(resultBox);
            }



            // Adjust shift-down amount.
            shiftDown = Mathf.Max(shiftDown, TEXConfiguration.main.SubMinOnSup * TexContext.Scale);

            // Space between subscript and superscript.
            float scriptsInterSpace = shiftUp - superscriptBox.depth + shiftDown - subscriptBox.height;


            scriptsInterSpace = shiftUp - superscriptBox.depth + shiftDown - subscriptBox.height;

            // If baseAtom is null, make it right-aligned

            if (BaseAtom is SpaceAtom && ((SpaceAtom)BaseAtom).policy == StrutPolicy.Misc)
            {
                var max = Mathf.Max(superscriptContainerBox.width, subscriptContainerBox.width);
                if (superscriptContainerBox.width < max)
                {
                    superscriptContainerBox.Add(0, StrutBox.Get(max - superscriptContainerBox.width, 0, 0, 0));
                }
                if (subscriptContainerBox.width < max)
                {
                    subscriptContainerBox.Add(0, StrutBox.Get(max - subscriptContainerBox.width, 0, 0, 0));
                }
            }

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

            scriptsBox.Add(superscriptContainerBox);
            scriptsBox.Add(StrutBox.Get(0, scriptsInterSpace, 0, 0));
            scriptsBox.Add(subscriptContainerBox);
            scriptsBox.height = shiftUp + superscriptBox.height;
            scriptsBox.depth  = shiftDown + subscriptBox.depth;
            scriptsBox.shift  = shift;
            resultBox.Add(scriptsBox);

            return(resultBox);
        }
예제 #19
0
        public override Box CreateBox(TexStyle style)
        {
            float lineHeight = lineThickness * TexUtility.SizeFactor(style);

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

            float maxWidth = (numeratorBox.width < denominatorBox.width ? denominatorBox.width : numeratorBox.width) + TEXConfiguration.main.FractionMargin * TexUtility.SizeFactor(style);

            numeratorBox   = HorizontalBox.Get(numeratorBox, maxWidth, numeratorAlignment);
            denominatorBox = HorizontalBox.Get(denominatorBox, maxWidth, denominatorAlignment);

            // Calculate preliminary shift-up and shift-down amounts.
            float shiftUp, shiftDown;
            var   styleFactor = TexUtility.SizeFactor(style);

            if (style >= TexStyle.Text)
            {
                styleFactor *= TEXConfiguration.main.FractionNarrowFactor;
            }

            shiftUp   = TEXConfiguration.main.NumeratorShift * styleFactor;
            shiftDown = TEXConfiguration.main.DenominatorShift * styleFactor;

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

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

            // Calculate clearance and adjust shift amounts.
            //var axis = TEXConfiguration.main.AxisHeight * TexUtility.SizeFactor(style);

            // Calculate clearance amount.
            float clearance = lineHeight > 0 ? TEXConfiguration.main.FractionGap : TEXConfiguration.main.FractionGapNoLine;

            // Adjust shift amounts.
            var kern1  = shiftUp - numeratorBox.depth;
            var kern2  = shiftDown - denominatorBox.height;
            var delta1 = clearance - kern1;
            var delta2 = clearance - kern2;

            if (delta1 > 0)
            {
                shiftUp += delta1;
                kern1   += delta1;
            }
            if (delta2 > 0)
            {
                shiftDown += delta2;
                kern2     += delta2;
            }

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

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

                var kern = kern1 + kern2;
                resultBox.Add(StrutBox.Get(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 + lineHeight + denominatorBox.depth;

            TexUtility.CentreBox(resultBox, style);
            return(resultBox);
        }
예제 #20
0
        public override Box CreateBox()
        {
            // Create box for base atom.
            Box   baseBox;
            float delta;

            if (BaseAtom is SymbolAtom && BaseAtom.Type == CharType.BigOperator)
            {
                // Find character of best scale for operator symbol.
                var opChar = TEXPreference.main.GetChar(((SymbolAtom)BaseAtom).Name).GetMetric();
                if (TexContext.Environment.value < TexEnvironment.Text && opChar.ch.nextLargerExist)
                {
                    opChar.Flush();
                    opChar = opChar.ch.nextLarger.GetMetric();
                }
                opChar.shift = -(opChar.height + opChar.depth) / 2;
                baseBox      = HorizontalBox.Get(opChar);

                delta = opChar.bearing;
            }
            else
            {
                baseBox = HorizontalBox.Get(BaseAtom == null ? StrutBox.Empty : BaseAtom.CreateBox());
                delta   = 0;
            }

            // Create boxes for upper and lower limits.
            Box upperLimitBox, lowerLimitBox;

            TexContext.Environment.Push(MakeSuperScripts ? TexEnvironment.ScriptScript : TexUtility.GetSuperscriptStyle());
            if (UpperLimitAtom is SymbolAtom)
            {
                upperLimitBox = DelimiterFactory.CreateBoxHorizontal(((SymbolAtom)UpperLimitAtom).Name, baseBox.width);
            }
            else
            {
                upperLimitBox = UpperLimitAtom == null ? null : UpperLimitAtom.CreateBox();
            }
            TexContext.Environment.Pop();

            TexContext.Environment.Push(MakeSuperScripts ? TexEnvironment.ScriptScript : TexUtility.GetSubscriptStyle());
            if (LowerLimitAtom is SymbolAtom)
            {
                lowerLimitBox = DelimiterFactory.CreateBoxHorizontal(((SymbolAtom)LowerLimitAtom).Name, baseBox.width);
            }
            else
            {
                lowerLimitBox = LowerLimitAtom == null ? null : LowerLimitAtom.CreateBox();
            }
            TexContext.Environment.Pop();

            // Make all component boxes equally wide.
            var maxWidth = Mathf.Max(Mathf.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  = VerticalBox.Get();
            var opSpacing5 = TEXConfiguration.main.BigOpMargin * TexContext.Scale;
            var kern       = 0f;

            // Create and add box for upper limit.
            if (UpperLimitAtom != null)
            {
                resultBox.Add(StrutBox.Get(0, opSpacing5, 0, 0));
                upperLimitBox.shift  = delta / 2;
                upperLimitBox.shift += TopOffset(BaseAtom);
                resultBox.Add(upperLimitBox);
                kern = Mathf.Max(TEXConfiguration.main.BigOpUpShift * TexContext.Scale,
                                 TEXConfiguration.main.BigOpUpperGap * TexContext.Scale - upperLimitBox.depth);
                resultBox.Add(StrutBox.Get(0, kern, 0, 0));
            }

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

            // Create and add box for lower limit.
            if (LowerLimitAtom != null)
            {
                resultBox.Add(StrutBox.Get(0, Mathf.Max(TEXConfiguration.main.BigOpLowShift * TexContext.Scale,
                                                        TEXConfiguration.main.BigOpLowerGap * TexContext.Scale - lowerLimitBox.height), 0, 0));
                lowerLimitBox.shift  = -delta / 2;
                lowerLimitBox.shift += BottomOffset(BaseAtom);
                resultBox.Add(lowerLimitBox);
                resultBox.Add(StrutBox.Get(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);
        }
예제 #21
0
        public override Box CreateBox(TexStyle style)
        {
            // Create box for base atom.
            var baseBox = (BaseAtom == null ? StrutBox.Empty : BaseAtom.CreateBox(style));

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

            // Save it shift and use it later
            var shift = baseBox.shift;

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

            var subscriptStyle   = TexUtility.GetSubscriptStyle(style);
            var superscriptStyle = TexUtility.GetSuperscriptStyle(style);

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

            if (BaseAtom is AccentedAtom)
            {
                var accentedBox = ((AccentedAtom)BaseAtom).BaseAtom.CreateBox(TexUtility.GetCrampedStyle(style));
                shiftUp   = accentedBox.height - TEXConfiguration.main.SupDrop * TexUtility.SizeFactor(superscriptStyle);
                shiftDown = accentedBox.depth + TEXConfiguration.main.SubDrop * TexUtility.SizeFactor(subscriptStyle);
            }
            else if (BaseAtom is CharSymbol)
            {
                var charFont = ((CharSymbol)BaseAtom).GetChar();
                if (!((CharSymbol)BaseAtom).IsTextSymbol)
                {
                    delta = TEXPreference.main.GetCharMetric(charFont, style).advanceDelta;
                }
                if (delta > TexUtility.FloatPrecision && SubscriptAtom == null)
                {
                    resultBox.Add(StrutBox.Get(delta, 0, 0, 0));
                    delta = 0;
                }

                shiftUp   = baseBox.height - TEXConfiguration.main.SupDrop * TexUtility.SizeFactor(superscriptStyle);
                shiftDown = baseBox.depth + TEXConfiguration.main.SubDrop * TexUtility.SizeFactor(subscriptStyle);
            }
            else
            {
                shiftUp   = baseBox.height - TEXConfiguration.main.SupDrop * TexUtility.SizeFactor(superscriptStyle);
                shiftDown = baseBox.depth + TEXConfiguration.main.SubDrop * TexUtility.SizeFactor(subscriptStyle);
            }

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

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

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

                // Adjust shift-up amount.
                float p;
                if (style == TexStyle.Display)
                {
                    p = TEXConfiguration.main.SupMin * TexUtility.SizeFactor(style);
                }
                else                // if (TexUtility.GetCrampedStyle (style) == style)
                {
                    p = TEXConfiguration.main.SupMinNarrow * TexUtility.SizeFactor(style);
                }
                //else
                //	p = TEXConfiguration.main.SupMinNarrow * TexUtility.SizeFactor(style);
                shiftUp = Mathf.Max(shiftUp, p);
            }

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

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

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

            // Check if only subscript is set.
            if (superscriptBox == null)
            {
                subscriptBox.shift = Mathf.Max(shiftDown, TEXConfiguration.main.SubMinNoSup * TexUtility.SizeFactor(style));
                resultBox.Add(subscriptContainerBox);
                resultBox.depth = shiftDown + subscriptBox.depth;
                return(resultBox);
            }

            // Adjust shift-down amount.
            shiftDown = Mathf.Max(shiftDown, TEXConfiguration.main.SubMinOnSup * TexUtility.SizeFactor(style));

            // Space between subscript and superscript.
            float 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.
             *      float psi = 0.8f * TexUtility.SizeFactor(style) - (shiftUp - superscriptBox.depth);
             *      if (psi > 0)
             *      {
             *              shiftUp += psi;
             *              shiftDown -= psi;
             *      }
             * }*/
            scriptsInterSpace = shiftUp - superscriptBox.depth + shiftDown - subscriptBox.height;

            // If baseAtom is null, make it right-aligned

            if (BaseAtom is SpaceAtom && ((SpaceAtom)BaseAtom).policy == StrutPolicy.Misc)
            {
                var max = Mathf.Max(superscriptContainerBox.width, subscriptContainerBox.width);
                if (superscriptContainerBox.width < max)
                {
                    superscriptContainerBox.Add(0, StrutBox.Get(max - superscriptContainerBox.width, 0, 0, 0));
                }
                if (subscriptContainerBox.width < max)
                {
                    subscriptContainerBox.Add(0, StrutBox.Get(max - subscriptContainerBox.width, 0, 0, 0));
                }
            }

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

            scriptsBox.Add(superscriptContainerBox);
            scriptsBox.Add(StrutBox.Get(0, scriptsInterSpace, 0, 0));
            scriptsBox.Add(subscriptContainerBox);
            scriptsBox.height = shiftUp + superscriptBox.height;
            scriptsBox.depth  = shiftDown + subscriptBox.depth;
            scriptsBox.shift  = shift;
            resultBox.Add(scriptsBox);

            return(resultBox);
        }
예제 #22
0
        // Branched wrapping algorithm for RTL support based above.
        private void HandlePerLineWrappingReversed(int i)
        {
            TexRenderer   row = m_formulas[i], newrow;
            HorizontalBox box = (HorizontalBox)row.Box;
            List <Box>    ch  = box.children;

            float x = row.PenaltyWidth, xPenalty = x, lastSpaceX = 0;
            int   lastSpaceIdx = -1, last = ch.Count - 1;

            //Begin Per-character pooling
            for (int j = ch.Count; j-- > 0;)
            {
                var child = ch[j];
                //White line? make a mark
                if (child is StrutBox && ((StrutBox)child).policy == StrutPolicy.BlankSpace)
                {
                    lastSpaceIdx = j;                   //last space, index
                    lastSpaceX   = x;                   //last space, x position
                    _spaceIdxs.Add(lastSpaceIdx);       //record that space
                    child.width = _realBlankSpaceWidth; // All spaces must have this width (they may modified after WordWarpJusified).
                }
                x += ch[j].width;
                //Total length not yet to break our rect limit? continue
                if (x * scale <= rectArea.width)
                {
                    if (_doJustify && (0 == j))
                    {
                        box.Recalculate();
                    }
                    continue;
                }
                //Now j is maximum limit character length. Now move any
                //character before that to the new previous line

                //Did we use word wrap? Track the last space index
                if (_useWordWrap && lastSpaceIdx >= 0)
                {
                    j = lastSpaceIdx;
                    x = lastSpaceX;
                    //Justify too? then expand our spaces width
                    if (_doJustify && _spaceIdxs.Count > 1)
                    {
                        float normalizedWidth = rectArea.width / scale;
                        float extraWidth      = (normalizedWidth - x) / (_spaceIdxs.Count - 1);
                        for (int k = 0; k < _spaceIdxs.Count; k++)
                        {
                            ch[_spaceIdxs[k]].width += extraWidth;
                        }
                        x = normalizedWidth;
                    }
                }
                else
                {
                    x -= ch[j].width;
                }
                if (j == last && (!_useWordWrap || lastSpaceIdx != j))
                {
                    // infinite loop prevention
                    x += ch[j].width;
                    continue;
                }
                var doOmitSpace = (_useWordWrap && lastSpaceIdx >= 0);
                m_formulas.Insert(i, newrow = TexRenderer.Get(HorizontalBox.Get(ch.GetRangePool(j + 1, last - j)),
                                                              row.metaRules, row.partOfPreviousLine)); //Add to previous line,
                if (doOmitSpace)
                {
                    j--; box.width -= ch[lastSpaceIdx].width; ch[lastSpaceIdx].Flush();
                }
                ch.RemoveRange(j + 1, last - j);
                //Update our measurements, remember now m_formulas[i] is different with box
                row.partOfPreviousLine = doOmitSpace ? 2 : 1;
                box.width -= newrow.Box.width = x - xPenalty;
                size.x     = Mathf.Max(size.x, x);
                size.y    += newrow.CompleteHeight * scale;
                break;
            }
        }
예제 #23
0
        public static Box CreateBoxHorizontal(string symbol, float minWidth)
        {
            minWidth += TEXConfiguration.main.DelimiterRecursiveOffset;
            var ch = TEXPreference.main.GetChar(symbol).GetMetric();

            var  ch2 = TEXPreference.main.GetChar(symbol);
            bool isAlreadyHorizontal = true;

            while (ch2 != null)
            {
                if (ch2.extensionExist && !ch2.extensionHorizontal)
                {
                    isAlreadyHorizontal = false;
                    break;
                }
                ch2 = ch2.nextLarger;
            }

            // Find first version of character that has at least minimum width.
            var totalWidth = isAlreadyHorizontal ? ch.bearing + ch.italic : ch.totalHeight;

            while (totalWidth < minWidth && ch.ch.nextLargerExist)
            {
                ch.Flush();
                ch         = ch.ch.nextLarger.GetMetric();
                totalWidth = isAlreadyHorizontal ? ch.bearing + ch.italic : ch.totalHeight;
            }

            if (totalWidth < minWidth && ch.ch.extensionExist)
            {
                var resultBox = HorizontalBox.Get();
                resultBox.ExtensionMode = true;
                // Construct box from extension character.
                var ext = ch.ch.GetExtentMetrics();
                if (isAlreadyHorizontal)
                {
                    if (ext[0] != null)
                    {
                        resultBox.Add(ext[0]);
                    }
                    if (ext[1] != null)
                    {
                        resultBox.Add(ext[1]);
                    }
                    if (ext[2] != null)
                    {
                        resultBox.Add(ext[2]);
                    }
                }
                else
                {
                    if (ext[2] != null)
                    {
                        resultBox.Add(RotatedCharBox.Get(ext[2]));
                    }
                    if (ext[1] != null)
                    {
                        resultBox.Add(RotatedCharBox.Get(ext[1]));
                    }
                    if (ext[0] != null)
                    {
                        resultBox.Add(RotatedCharBox.Get(ext[0]));
                    }
                }

                // Insert repeatable part multiple times until box is high enough.
                if (ext[3] != null)
                {
                    Box repeatBox = isAlreadyHorizontal ? (Box)ext[3] : RotatedCharBox.Get(ext[3]);
                    do
                    {
                        if (ext[0] != null && ext[2] != null)
                        {
                            resultBox.Add(1, repeatBox);
                            if (ext[1] != null)
                            {
                                resultBox.Add(resultBox.children.Count - 1, repeatBox);
                            }
                        }
                        else if (ext[2] != null)
                        {
                            resultBox.Add(0, repeatBox);
                        }
                        else
                        {
                            resultBox.Add(repeatBox);
                        }
                    }while (resultBox.width < minWidth);
                }
                return(resultBox);
            }
            else
            {
                // Just enough
                if (isAlreadyHorizontal)
                {
                    return(ch);
                }
                else
                {
                    return(RotatedCharBox.Get(ch.ch));
                }
            }
        }
예제 #24
0
        // Branched wrapping algorithm for RTL support based above.
        void HandlePerLineWrappingReversed(Box box, int i)
        {
            float x = formulas[i].PenaltyWidth, xPenalty = x, xOri = 0, y = 0, lastSpaceX = 0;
            int   lastSpaceIdx  = -1;
            bool  requestToSkip = false;

            //Begin Per-character pooling
            for (int j = box.children.Count; j-- > 0;)
            {
                var child = box.children[j];
                //White line? make a mark
                if (child is StrutBox && ((StrutBox)child).policy == StrutPolicy.BlankSpace)
                {
                    lastSpaceIdx = j;                   //last space, index
                    lastSpaceX   = x;                   //last space, x position
                    _spaceIdxs.Add(lastSpaceIdx);       //record that space
                    child.width = _realBlankSpaceWidth; // All spaces must have this width (they may modified after WordWarpJusified).
                }
                x   += box.children[j].width;
                xOri = x - xPenalty;
                //Total length not yet to break our rect limit? continue
                if (x * scale <= rectArea.width)
                {
                    if (_doJustify && (0 == j))
                    {
                        ((HorizontalBox)box).Recalculate();
                    }
                    continue;
                }
                //Now j is maximum limit character length. Now move any
                //character before that to the new previous line

                //Did we use word wrap? Track the last space index
                if (_useWordWrap && lastSpaceIdx >= 0 && lastSpaceIdx < box.children.Count - 1)
                {
                    //Already ommited since it is exluded
                    j             = lastSpaceIdx;
                    x             = lastSpaceX;
                    xOri          = lastSpaceX - xPenalty + box.children[lastSpaceIdx].width;
                    requestToSkip = true;
                    //Justify too? then expand our spaces width
                    if (_doJustify && _spaceIdxs.Count > 1)
                    {
                        float normalizedWidth = rectArea.width / scale;
                        float extraWidth      = (normalizedWidth - x) / (float)(_spaceIdxs.Count - 1);
                        for (int k = 0; k < _spaceIdxs.Count; k++)
                        {
                            box.children[_spaceIdxs[k]].width += extraWidth;
                        }
                        x = normalizedWidth;
                    }
                }
                else if (box.children[j] is StrutBox && ((StrutBox)box.children[j]).policy == StrutPolicy.BlankSpace)
                {
                    x            -= box.children[j].width;
                    requestToSkip = true;
                }
                else
                {
                    x   -= box.children[j].width;
                    xOri = x - xPenalty;
                }
                if (j > box.children.Count - 2)
                {
                    x   += box.children[j].width;
                    xOri = x - xPenalty;
                    continue;
                }
                int oriPartMark = m_formulas[i].partOfPreviousLine;
                m_formulas[i].partOfPreviousLine = (_useWordWrap && lastSpaceIdx >= 0) ? 2 : 1;
                if (requestToSkip)
                {
                    j--; // Skip the unneeded space char
                }
                m_formulas.Insert(i, TexRenderer.Get(HorizontalBox.Get(
                                                         box.children.GetRangePool(j + 1, box.children.Count - j - 1)), originalScale, m_formulas[i].metaRules)); //Add to previous line,
                box.children.RemoveRange(j + 1, box.children.Count - j - 1);
                //Update our measurements, remember now m_formulas[i] is different with box
                if (oriPartMark > 0)
                {
                    m_formulas[i].partOfPreviousLine = oriPartMark;
                }
                box.width -= xOri;
                y          = m_formulas[i].Box.totalHeight;
                if (oriPartMark > 0)
                {
                    y += m_formulas[i].PenaltyParagraph;
                }
                if (requestToSkip)
                {
                    formulas[i].Box.shift -= m_formulas[i].Box.children[0].width;
                }
                formulas[i].Box.width = x - xPenalty;
                size.x  = Mathf.Max(size.x, x);
                size.y += (spaceSize + m_formulas[i].PenaltySpacing + y) * scale;
                break;
            }
        }
예제 #25
0
        public Box GenerateDelimiterBox(HorizontalBox result, ref int elementPos, ref int resultPos, TexStyle style)
        {
            var curAtom = Elements[elementPos];

            if (!(curAtom is CharSymbol) || !((CharSymbol)curAtom).IsDelimiter)
            {
                // This is not delimiter, hence just create and do nothing.
                var box = curAtom.CreateBox(style);
                if (curAtom.Type == CharType.BigOperator)
                {
                    TexUtility.CentreBox(box, style);
                }
                result.Add(resultPos, box);
                lastGeneratedBox = box;

                resultPos++;
                return(box);
            }

            var nextAtom = elementPos + 1 < Elements.Count ? Elements[elementPos + 1] : null;
            var prevAtom = elementPos > 0 ? Elements[elementPos - 1] : null;

            var minHeight = 0f;
            var ourPos    = resultPos;

            if (nextAtom != null && curAtom.GetRightType() == CharType.OpenDelimiter)
            {
                elementPos++;
                var nextBox = GenerateDelimiterBox(result, ref elementPos, ref resultPos, style);
                minHeight = nextBox.totalHeight;
            }
            else if (lastGeneratedBox != null && curAtom.GetLeftType() == CharType.CloseDelimiter)
            {
                var prevBox = lastGeneratedBox;
                minHeight = prevBox.totalHeight;
            }
            else
            {
                if (prevAtom != null && lastGeneratedBox != null)
                {
                    var prevBox = lastGeneratedBox;
                    minHeight = prevBox.totalHeight;
                }
                if (nextAtom != null)
                {
                    elementPos++;
                    var nextBox = GenerateDelimiterBox(result, ref elementPos, ref resultPos, style);
                    minHeight = Mathf.Max(nextBox.totalHeight, minHeight);
                }
            }
            var curBox = curAtom is SymbolAtom ? (((SymbolAtom)curAtom).CreateBox(style, minHeight)) : curAtom.CreateBox(style);

            TexUtility.CentreBox(curBox, style);
            result.Add(ourPos, curBox);
            if (ourPos == resultPos)
            {
                lastGeneratedBox = curBox;
            }
            resultPos++;
            return(curBox);
        }
예제 #26
0
        public override Box CreateBox()
        {
            List <List <Box> > boxes = ListPool <List <Box> > .Get();

            List <float> boxesHeight = ListPool <float> .Get();

            List <float> boxesShift = ListPool <float> .Get();

            List <float> boxesWidth = ListPool <float> .Get();

            TexContext.Environment.Push(TexUtility.GetCrampedStyle());

            float padding = TEXConfiguration.main.MatrixMargin * TexContext.Scale;

            for (int i = 0; i < Elements.Count; i++)
            {
                boxes.Add(ListPool <Box> .Get());
                float h = 0f, d = 0f;
                for (int j = 0; j < Elements[i].Count; j++)
                {
                    Box box;
                    if (Elements[i][j] != null)
                    {
                        box = (Elements[i][j].CreateBox());
                    }
                    else
                    {
                        box = (ObjPool <StrutBox> .Get());
                    }
                    boxes[i].Add(box);
                    if (j >= boxesWidth.Count)
                    {
                        boxesWidth.Add(box.width);
                    }
                    else
                    {
                        boxesWidth[j] = Mathf.Max(boxesWidth[j], box.width);
                    }
                    h = Mathf.Max(h, box.height);
                    d = Mathf.Max(d, box.depth);
                }
                boxesHeight.Add(Mathf.Max(h + d, padding / 2f));
                boxesShift.Add(h);
            }

            bool outsideGap = (horizontalLine > 0 && (enumContains(horizontalLine, 0) || enumContains(horizontalLine, 4))) ||
                              (verticalLine > 0 && (enumContains(verticalLine, 0) || enumContains(verticalLine, 4)));

            var vBox      = VerticalBox.Get();
            Box resultBox = vBox;

            Box kern     = null;
            Box kernHalf = null;

            if (boxesWidth.Count > 1 || boxesHeight.Count > 1)
            {
                kern = StrutBox.Get(padding, padding, 0, 0);
            }
            if (outsideGap)
            {
                kernHalf = StrutBox.Get(padding / 2f, padding / 2f, 0, 0);
                vBox.Add(kernHalf);
            }

            TexAlignment firstRowH = alterH(horizontalAlign % 8);
            TexAlignment firstRowV = alterV(verticalAlign % 8);
            TexAlignment firstColH = alterH((horizontalAlign >> 3) % 8);
            TexAlignment firstColV = alterV((verticalAlign >> 3) % 8);
            TexAlignment bodyH     = alterH((horizontalAlign >> 6) % 8);
            TexAlignment bodyV     = alterV((verticalAlign >> 6) % 8);

            for (int i = 0; i < Elements.Count; i++)
            {
                var list = HorizontalBox.Get();
                if (outsideGap)
                {
                    list.Add(kernHalf);
                }
                for (int j = 0; j < Elements[i].Count; j++)
                {
                    if (i == 0)
                    {
                        list.Add(VerticalBox.Get(HorizontalBox.Get(boxes[i][j], boxesWidth[j], firstRowH), boxesHeight[i], firstRowV));
                    }
                    else if (j == 0)
                    {
                        list.Add(VerticalBox.Get(HorizontalBox.Get(boxes[i][j], boxesWidth[j], firstColH), boxesHeight[i], firstColV));
                    }
                    else
                    {
                        list.Add(VerticalBox.Get(HorizontalBox.Get(boxes[i][j], boxesWidth[j], bodyH), boxesHeight[i], bodyV));
                    }

                    if (j < Elements[i].Count - 1)
                    {
                        list.Add(kern);
                    }
                    else if (outsideGap)
                    {
                        list.Add(kernHalf);
                    }
                }
                list.depth = boxesHeight[i] - list.height;
                vBox.Add(list);
                if (i < Elements.Count - 1)
                {
                    vBox.Add(kern);
                }
                else if (outsideGap)
                {
                    vBox.Add(kernHalf);
                }
            }

            var lineThick = TEXConfiguration.main.LineThickness * TexContext.Scale;

            //Add horizontal lines for table
            if (horizontalLine > 0)
            {
                var outside      = enumContains(horizontalLine, 0);
                var first        = enumContains(horizontalLine, 1);
                var inset        = enumContains(horizontalLine, 2);
                var firstThick   = enumContains(horizontalLine, 3);
                var outsideThick = enumContains(horizontalLine, 4);

                float gapX      = (padding - lineThick);
                float gapXThick = (padding - (lineThick * 2));
                float gapXNone  = (padding);

                float gapOutside  = (outside ? (outsideThick ? gapXThick : gapX) : gapXNone);
                float gapInset    = (inset ? gapX : gapXNone);
                float lineOutside = outsideThick ? lineThick * 2 : lineThick;
                var   insideBox   = resultBox;

                var hBox = HorizontalBox.Get(resultBox);
                resultBox = hBox;

                if (outsideGap)
                {
                    hBox.Add(StrutBox.Get(-insideBox.width - lineOutside / 2f, 0, 0, 0));
                }
                else
                {
                    hBox.Add(StrutBox.Get(-insideBox.width - lineOutside * 1.5f, 0, 0, 0));
                }

                for (int i = 0; i < boxesWidth.Count; i++)
                {
                    if (i == 0)
                    {
                        if (outside)
                        {
                            hBox.Add(HorizontalRule.Get(insideBox.height, lineOutside, 0, insideBox.depth));
                        }
                        hBox.Add(StrutBox.Get(boxesWidth[i] + gapOutside, 0, 0, 0));
                        continue;
                    }
                    if (i == 1)
                    {
                        if (first)
                        {
                            hBox.Add(HorizontalRule.Get(insideBox.height, firstThick ? lineThick * 2 : lineThick, 0, insideBox.depth));
                        }
                        hBox.Add(StrutBox.Get(boxesWidth[i] + (first ? (firstThick ? gapXThick : gapX) : gapXNone), 0, 0, 0));
                        continue;
                    }
                    if (inset)
                    {
                        hBox.Add(HorizontalRule.Get(insideBox.height, lineThick, 0, insideBox.depth));
                    }
                    hBox.Add(StrutBox.Get(boxesWidth[i] + gapInset, 0, 0, 0));
                }
                if (outside)
                {
                    hBox.Add(HorizontalRule.Get(insideBox.height, lineOutside, 0, insideBox.depth));
                }
            }

            if (verticalLine > 0)
            {
                var outside      = enumContains(verticalLine, 0);
                var first        = enumContains(verticalLine, 1);
                var inset        = enumContains(verticalLine, 2);
                var firstThick   = enumContains(verticalLine, 3);
                var outsideThick = enumContains(verticalLine, 4);

                float gapX      = (padding - lineThick);
                float gapXThick = (padding - (lineThick * 2));
                float gapXNone  = (padding);

                float gapOutside  = (outside ? (outsideThick ? gapXThick : gapX) : gapXNone);
                float gapInset    = (inset ? gapX : gapXNone);
                float lineOutside = outsideThick ? lineThick * 2 : lineThick;
                var   insideBox   = resultBox;
                var   size        = insideBox.width;

                vBox      = VerticalBox.Get(resultBox);
                resultBox = vBox;

                if (outsideGap)
                {
                    vBox.Add(StrutBox.Get(0, -insideBox.totalHeight - lineOutside / 2f, 0, 0));
                }
                else
                {
                    vBox.Add(StrutBox.Get(0, -insideBox.totalHeight, 0, 0));
                }

                for (int i = 0; i < boxesHeight.Count; i++)
                {
                    if (i == 0)
                    {
                        if (outside)
                        {
                            vBox.Add(HorizontalRule.Get(lineOutside, size, 0));
                        }
                        vBox.Add(StrutBox.Get(0, boxesHeight[i] + (outsideGap ? gapOutside : gapOutside / 2f), 0, 0));
                    }
                    else if (i == 1)
                    {
                        if (first)
                        {
                            vBox.Add(HorizontalRule.Get(firstThick ? lineThick * 2 : lineThick, size, 0));
                        }
                        var thick = (first ? (firstThick ? gapXThick : gapX) : gapXNone);
                        vBox.Add(StrutBox.Get(0, boxesHeight[i] + (boxesHeight.Count == 2 && !outsideGap ? thick / 2f : thick), 0, 0));
                    }
                    else
                    {
                        if (inset)
                        {
                            vBox.Add(HorizontalRule.Get(lineThick, size, 0));
                        }
                        vBox.Add(StrutBox.Get(0, boxesHeight[i] + (i < boxesHeight.Count - 1 || outsideGap ? gapInset : gapInset / 2f), 0, 0));
                    }
                }
                if (outside && outsideGap)
                {
                    vBox.Add(HorizontalRule.Get(lineOutside, size, 0, 0));
                }
            }

            TexUtility.CentreBox(resultBox);

            TexContext.Environment.Pop();

            //Clear resources
            ListPool <float> .Release(boxesHeight);

            ListPool <float> .Release(boxesWidth);

            ListPool <float> .Release(boxesShift);

            for (int i = 0; i < boxes.Count; i++)
            {
                ListPool <Box> .ReleaseNoFlush(boxes[i]);
            }
            ListPool <List <Box> > .ReleaseNoFlush(boxes);


            return(resultBox);
        }
예제 #27
0
파일: RowAtom.cs 프로젝트: step4/rac-quiz
        public Box GenerateDelimiterBox(HorizontalBox result, ref int elementPos, ref int resultPos)
        {
            var curAtom = Elements[elementPos];

            if (!(curAtom is CharSymbol) || !((CharSymbol)curAtom).IsDelimiter)
            {
                // This is not delimiter, hence just create and do nothing.
                var box = curAtom.CreateBox();
                if (curAtom.Type == CharType.BigOperator) // specific patch to BigOperator
                {
                    TexUtility.CentreBox(box);
                }
                if (box is HorizontalBox && (curAtom is AttrSizeAtom || curAtom is AttrStyleAtom)) // specific patch to Atoms that should be wrappable.
                {
                    var h = box as HorizontalBox;
                    result.AddRange(h, resultPos);
                    resultPos += h.children.Count;
                }
                else
                {
                    result.Add(resultPos++, box);
                }
                lastGeneratedBox = box;
                return(box);
            }

            var nextAtom = elementPos + 1 < Elements.Count ? Elements[elementPos + 1] : null;
            var prevAtom = elementPos > 0 ? Elements[elementPos - 1] : null;

            var minHeight = 0f;
            var ourPos    = resultPos;

            if (nextAtom != null && curAtom.RightType == CharType.OpenDelimiter)
            {
                elementPos++;
                var nextBox = GenerateDelimiterBox(result, ref elementPos, ref resultPos);
                minHeight = nextBox.totalHeight;
            }
            else if (lastGeneratedBox != null && curAtom.LeftType == CharType.CloseDelimiter)
            {
                var prevBox = lastGeneratedBox;
                minHeight = prevBox.totalHeight;
            }
            else
            {
                if (prevAtom != null && lastGeneratedBox != null)
                {
                    var prevBox = lastGeneratedBox;
                    minHeight = prevBox.totalHeight;
                }
                if (nextAtom != null)
                {
                    elementPos++;
                    var nextBox = GenerateDelimiterBox(result, ref elementPos, ref resultPos);
                    minHeight = Mathf.Max(nextBox.totalHeight, minHeight);
                }
            }
            var curBox = curAtom is SymbolAtom ? (((SymbolAtom)curAtom).CreateBox(minHeight)) : curAtom.CreateBox();

            TexUtility.CentreBox(curBox);
            result.Add(ourPos, curBox);
            if (ourPos == resultPos)
            {
                lastGeneratedBox = curBox;
            }
            resultPos++;
            return(curBox);
        }
예제 #28
0
        public static Box CreateBoxHorizontal(string symbol, float minWidth, TexStyle style)
        {
            var charInfo = TEXPreference.main.GetCharMetric(symbol, style);

            var  charInfo2           = TEXPreference.main.GetChar(symbol);
            bool isAlreadyHorizontal = true;

            while (charInfo2 != null)
            {
                if (charInfo2.extensionExist && !charInfo2.extensionHorizontal)
                {
                    isAlreadyHorizontal = false;
                    break;
                }
                charInfo2 = charInfo2.nextLarger;
            }

            // Find first version of character that has at least minimum width.
            var totalWidth = isAlreadyHorizontal ? charInfo.bearing + charInfo.italic : charInfo.totalHeight;

            while (totalWidth < minWidth && charInfo.ch.nextLargerExist)
            {
                charInfo   = TEXPreference.main.GetCharMetric(charInfo.ch.nextLarger, style);
                totalWidth = isAlreadyHorizontal ? charInfo.bearing + charInfo.italic : charInfo.totalHeight;
            }

            if (totalWidth >= minWidth)
            {
                // Character of sufficient height was found.
                if (isAlreadyHorizontal)
                {
                    return(CharBox.Get(style, charInfo));
                }
                else
                {
                    return(RotatedCharBox.Get(style, charInfo));
                }
            }
            else if (charInfo.ch.extensionExist)
            {
                var resultBox = HorizontalBox.Get();
                resultBox.ExtensionMode = true;
                // Construct box from extension character.
                var extension = charInfo.ch.GetExtentMetrics(style);
                if (isAlreadyHorizontal)
                {
                    if (extension[0] != null)
                    {
                        resultBox.Add(CharBox.Get(style, extension[0]));
                    }
                    if (extension[1] != null)
                    {
                        resultBox.Add(CharBox.Get(style, extension[1]));
                    }
                    if (extension[2] != null)
                    {
                        resultBox.Add(CharBox.Get(style, extension[2]));
                    }
                }
                else
                {
                    if (extension[2] != null)
                    {
                        resultBox.Add(RotatedCharBox.Get(style, extension[2]));
                    }
                    if (extension[1] != null)
                    {
                        resultBox.Add(RotatedCharBox.Get(style, extension[1]));
                    }
                    if (extension[0] != null)
                    {
                        resultBox.Add(RotatedCharBox.Get(style, extension[0]));
                    }
                }

                // Insert repeatable part multiple times until box is high enough.
                if (extension[3] != null)
                {
                    Box repeatBox;
                    if (isAlreadyHorizontal)
                    {
                        repeatBox = CharBox.Get(style, extension[3]);
                    }
                    else
                    {
                        repeatBox = RotatedCharBox.Get(style, extension[3]);
                    }
                    do
                    {
                        if (extension[0] != null && extension[2] != null)
                        {
                            resultBox.Add(1, repeatBox);
                            if (extension[1] != null)
                            {
                                resultBox.Add(resultBox.children.Count - 1, repeatBox);
                            }
                        }
                        else if (extension[2] != null)
                        {
                            resultBox.Add(0, repeatBox);
                        }
                        else
                        {
                            resultBox.Add(repeatBox);
                        }
                    }while (resultBox.width < minWidth);
                }
                return(resultBox);
            }
            else
            {
                // No extensions available, so use tallest available version of character.
                if (isAlreadyHorizontal)
                {
                    return(CharBox.Get(style, charInfo));
                }
                else
                {
                    return(RotatedCharBox.Get(style, charInfo));
                }
            }
        }