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); }
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); }
public override Box CreateBox(TexStyle style) { // Calculate minimum clearance amount. if (BaseAtom == null) { return(StrutBox.Empty); } // Create box for base atom, in cramped style. var baseBox = BaseAtom.CreateBox(TexUtility.GetCrampedStyle(style)); if (DegreeAtom is SymbolAtom && ((SymbolAtom)DegreeAtom).IsDelimiter) { return(CreateGenericRadicalBox(style, baseBox, ((SymbolAtom)DegreeAtom).Name)); } else { return(CreateBoxDefault(style, baseBox)); } }
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) { // 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); }
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); }