/** * format a radical */ public static Area Radical(IFormattingContext context, Area radicand, Area index) { const char RadicalGlyphIndex = '\x221a'; float fontSize = context.Size; BoundingBox radicandBox = radicand.BoundingBox; BoundingBox radicalBox; float minIndexWidth; float lineThickness; // these space numbers have no real meaning, the were just // chosen as a size that looks good. float leftSpace = 2*context.OnePixel + radicandBox.Width * 0.01f; float rightSpace = 2*context.OnePixel; float topMinSpace = context.OnePixel + radicandBox.VerticalExtent * 0.03f; // size to create glyph BoundingBox glyphBox = radicandBox; // add minimun stretch sizes to the box, sqrt is a vertical stretchy glyph glyphBox.Height += topMinSpace; // create a glyph for the radical char Area radical = GlyphFactory.GetStretchyGlyph(context, fontSize, RadicalGlyphIndex, glyphBox, out lineThickness); // line for the top part of the radical Area horizontalLine = HorizontalLine(lineThickness); radicalBox = radical.BoundingBox; // the glyph is almost never the exact size we request it, // we we need to adjust our vertical padding accoringly float topSpace = radicalBox.Height - radicandBox.Height - horizontalLine.BoundingBox.VerticalExtent; // pad the radicand with left and right spaces radicand = Horizontal(new Area[] {HorizontalSpace(leftSpace), radicand, HorizontalSpace(rightSpace)}); // make a new vertical array, with a line for the top of the radical spanning // the widtch, and the original radicand spaced slightly downward radicand = Vertical(new Area[] {radicand, VerticalSpace(topSpace, 0), horizontalLine}, 0); // get the minumum index width, this is needed as radical glyphs // are encoded with a negative left edge, this is where the right edge of // the index area would normally go. note, we better well have a // negative width, but just in case..... minIndexWidth = radical.LeftEdge < 0.0f ? -radical.LeftEdge : 0.0f; if(index == null) { // just make a space to padd the radical index = HorizontalSpace(minIndexWidth); } else { BoundingBox indexBox = index.BoundingBox; // need to pad the area if less than min width if(indexBox.Width < minIndexWidth) { index = Horizontal(new Area[] {HorizontalSpace(minIndexWidth - indexBox.Width), index}); } // shift the area up just above the radical hook index = Shift(GetRadicalShift(radical) + index.BoundingBox.Depth, index); } // hide the radical glyph from cursor selection radical = new NonSelectionArea(radical); // make a new horizontal area out of these three areas return Horizontal(new Area[] {index, radical, radicand}); }
/** * format a radical */ public static Area Radical(IFormattingContext context, Area radicand, Area index) { const char RadicalGlyphIndex = '\x221a'; float fontSize = context.Size; BoundingBox radicandBox = radicand.BoundingBox; BoundingBox radicalBox; float minIndexWidth; float lineThickness; // these space numbers have no real meaning, the were just // chosen as a size that looks good. float leftSpace = 2 * context.OnePixel + radicandBox.Width * 0.01f; float rightSpace = 2 * context.OnePixel; float topMinSpace = context.OnePixel + radicandBox.VerticalExtent * 0.03f; // size to create glyph BoundingBox glyphBox = radicandBox; // add minimun stretch sizes to the box, sqrt is a vertical stretchy glyph glyphBox.Height += topMinSpace; // create a glyph for the radical char Area radical = GlyphFactory.GetStretchyGlyph(context, fontSize, RadicalGlyphIndex, glyphBox, out lineThickness); // line for the top part of the radical Area horizontalLine = HorizontalLine(lineThickness); radicalBox = radical.BoundingBox; // the glyph is almost never the exact size we request it, // we we need to adjust our vertical padding accoringly float topSpace = radicalBox.Height - radicandBox.Height - horizontalLine.BoundingBox.VerticalExtent; // pad the radicand with left and right spaces radicand = Horizontal(new Area[] { HorizontalSpace(leftSpace), radicand, HorizontalSpace(rightSpace) }); // make a new vertical array, with a line for the top of the radical spanning // the widtch, and the original radicand spaced slightly downward radicand = Vertical(new Area[] { radicand, VerticalSpace(topSpace, 0), horizontalLine }, 0); // get the minumum index width, this is needed as radical glyphs // are encoded with a negative left edge, this is where the right edge of // the index area would normally go. note, we better well have a // negative width, but just in case..... minIndexWidth = radical.LeftEdge < 0.0f ? -radical.LeftEdge : 0.0f; if (index == null) { // just make a space to padd the radical index = HorizontalSpace(minIndexWidth); } else { BoundingBox indexBox = index.BoundingBox; // need to pad the area if less than min width if (indexBox.Width < minIndexWidth) { index = Horizontal(new Area[] { HorizontalSpace(minIndexWidth - indexBox.Width), index }); } // shift the area up just above the radical hook index = Shift(GetRadicalShift(radical) + index.BoundingBox.Depth, index); } // hide the radical glyph from cursor selection radical = new NonSelectionArea(radical); // make a new horizontal area out of these three areas return(Horizontal(new Area[] { index, radical, radicand })); }