예제 #1
0
        /**
         * create an area that formats a string.
         */
        public static Area String(IFormattingContext context, String str)
        {
            Area      result   = null;
            float     fontSize = context.Size;
            ArrayList list     = null;
            int       start    = 0;

            if (str.Length == 1)
            {
                result = str[0] > '\x7f' ? GlyphFactory.GetGlyph(context, fontSize, str[0]) :
                         new StringArea(context, str);
            }
            else
            {
                start = 0;
                for (int i = 0; i < str.Length; i++)
                {
                    if (str[i] > '\x7f')
                    {
                        if (list == null)
                        {
                            list = new ArrayList();
                        }
                        list.Add(new StringArea(context, str.Substring(start, i - start)));
                        list.Add(GlyphFactory.GetGlyph(context, fontSize, str[i]));
                        start = i + 1;
                    }
                }

                if (list != null)
                {
                    result = Horizontal((Area[])list.ToArray(typeof(Area)));
                }
                else
                {
                    result = new StringArea(context, str);
                }
            }
            return(result);
        }
예제 #2
0
        /**
         * find or calculate an area that will fill the requested cell
         * height. The returned area may be either a single glyph, or a
         * compound set of glyphs.
         *
         * @param pointSize the evaluated font size
         * @param desiredSize the desired stretch size (for either vertical or
         * horizontal stretchy glyphs.
         * @param c the character to find a glyph for.
         * @param lineThickness a value that get populated with the thickness of the
         * repated or stretched sections.
         */

        public static Area GetStretchyGlyph(IFormattingContext context, float pointSize, char c, BoundingBox desiredSize, out float lineThickness)
        {
            GlyphFactory gf = Instance;

            Area result = null;

            lineThickness = 0;
            for (int i = 0; i < gf.maps.Length; i++)
            {
                if ((result = gf.maps[i].GetStretchyGlyph(context, pointSize, c, desiredSize, out lineThickness)) != null)
                {
                    return(result);
                }
            }

            if (result == null)
            {
                Debug.WriteLine("no stretchy glyph found, returning standard glyph area");
                result = GetGlyph(context, pointSize, c);
            }
            return(result);
        }
예제 #3
0
        /**
         * create a new glyph area.
         */

        public static Area GetGlyph(IFormattingContext ctx, float pointSize, char c)
        {
            GlyphFactory gf = Instance;

            Area result = null;

            Debug.WriteLine(String.Format("searching for a glyph for character 0x{0:x}", (uint)c));
            for (int i = 0; i < gf.maps.Length; i++)
            {
                if ((result = gf.maps[i].GetGlyph(ctx, pointSize, c)) != null)
                {
                    return(result);
                }
            }

            if (result == null)
            {
                Debug.WriteLine("no glyph found, returning default area");
                result = new StringArea(ctx, "?");
            }
            return(result);
        }
예제 #4
0
        /**
         * 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 }));
        }