Пример #1
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);
        }
Пример #2
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);
        }
Пример #3
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);
        }
Пример #4
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);
        }
Пример #5
0
        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);
        }
Пример #6
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);
        }
Пример #7
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);
        }