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); }
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); }
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); }
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); }
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); }
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); }
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); }