Пример #1
0
        object MathML.MathMLVisitor.Visit(MathMLPresentationToken e, object args)
        {
            Area area = null;

            // make an updated context
            IFormattingContext context  = ((IFormattingContext)args).Clone();
            XmlNode            node     = null;
            MathMLElement      element  = null;
            MathMLNodeList     contents = e.Contents;

            // update the font size, pres-tokens can specify font size
            context.Size = context.Evaluate(e.MathSize);

            MathVariant variant = e.MathVariant;

            if (variant != MathVariant.Unknown)
            {
                context.MathVariant = variant;
            }

            if (contents.Count == 1)            // create a single string area
            {
                if ((node = e.FirstChild) != null && node.NodeType == XmlNodeType.Text)
                {
                    area = AreaFactory.String(context, node.Value);
                }
                else if ((element = e.FirstChild as MathMLElement) != null)
                {
                    // sets area to a new glyph area
                    area = (Area)element.Accept(formatter, context);
                }
                else
                {
                    // TODO this is bad, need error handler
                }
            }
            else             // create a sequence of areas
            {
                Area[] areas = new Area[contents.Count];
                int    i     = 0;
                foreach (XmlNode n in contents)
                {
                    if (n.NodeType == XmlNodeType.Text)
                    {
                        area = AreaFactory.String(context, n.Value);
                    }
                    else if ((element = n as MathMLElement) != null)
                    {
                        area = (Area)element.Accept(formatter, context);
                    }
                    areas[i++] = area;
                }
                area = AreaFactory.Horizontal(areas);
            }

            return(area.BoundingBox);
        }
Пример #2
0
        object MathML.MathMLVisitor.Visit(MathMLPresentationContainer e, object args)
        {
            IFormattingContext context   = ((IFormattingContext)args).Clone();
            MathMLNodeList     arguments = e.Arguments;
            BoundingBox        extent    = BoundingBox.New();
            int stretchCount             = 0;

            // save the stretch size because stretch scope can not extend into another
            // level of nesting
            BoundingBox stretch = context.Stretch;

            context.Stretch = BoundingBox.New();

            // process all nodes that are not stretchy operators, get thier total
            // extents
            for (int i = 0; i < arguments.Count; i++)
            {
                MathMLElement         element = (MathMLElement)arguments[i];
                MathMLOperatorElement op      = element as MathMLOperatorElement;

                if (op == null || op.Stretchy == false)
                {
                    //areas[i] = (Area)element.Accept(this, context);
                    extent.Append((BoundingBox)element.Accept(this, context));
                }
                if (op != null && op.Stretchy)
                {
                    stretchCount++;
                }
            }

            // if we have any elements that can be stretched, stretch them
            if (stretchCount > 0)
            {
                if (!stretch.Defined)
                {
                    // avail width is epsilon because stretchy glyphs were not counted in the
                    // width calculation
                    context.Stretch = BoundingBox.New(Single.Epsilon, extent.Height, extent.Depth);
                }
                else
                {
                    // set the stretch size back to stretch the child elements
                    context.Stretch = stretch;

                    // calculate availible width
                    context.StretchWidth = context.StretchWidth - extent.Width;
                    if (context.Stretch.Width < 0)
                    {
                        context.StretchWidth = 0;
                    }

                    // size to stretch each width equally
                    context.StretchWidth = context.Stretch.Width / (float)stretchCount;
                }

                // process all areas that need to be stretched
                for (int i = 0; i < arguments.Count; i++)
                {
                    MathMLOperatorElement op = arguments[i] as MathMLOperatorElement;
                    if (op != null && op.Stretchy)
                    {
                        //areas[i] = (Area)op.Accept(this, context);
                        extent.Append((BoundingBox)op.Accept(this, context));
                    }
                }
            }

            return(extent);
        }
Пример #3
0
        /**
         * grab all the cells from a table and return them in a 2 dimensional array
         * TODO optimize (cache) cell.attribute* calls
         */
        public static MathMLTableCellElement[][] GetCells(MathMLTableElement table)
        {
            int            i         = 0;
            MathMLNodeList tableRows = table.Rows;

            MathMLTableCellElement[][] cells = new MathMLTableCellElement[tableRows.Count][];
            int[]     remainderCols          = new int[0];
            ArrayList rowCellsList           = new ArrayList();

            foreach (MathMLTableRowElement row in tableRows)
            {
                MathMLNodeList rowCells = row.Cells;
                rowCellsList.Clear();

                foreach (MathMLTableCellElement cell in rowCells)
                {
                    if (rowCellsList.Count < remainderCols.Length && remainderCols[rowCellsList.Count] > 0)
                    {
                        remainderCols[rowCellsList.Count] = remainderCols[rowCellsList.Count] - 1;
                        rowCellsList.Add(null);
                    }

                    rowCellsList.Add(cell);

                    for (int j = 1; j < cell.ColumnSpan; j++)
                    {
                        // deal with overlapping cells
                        if (rowCellsList.Count < remainderCols.Length && remainderCols[rowCellsList.Count] > 0)
                        {
                            remainderCols[rowCellsList.Count] = remainderCols[rowCellsList.Count] - 1;
                        }
                        rowCellsList.Add(null);
                    }
                }

                cells[i] = new MathMLTableCellElement[rowCellsList.Count];
                for (int j = 0; j < rowCellsList.Count; j++)
                {
                    cells[i][j] = (MathMLTableCellElement)rowCellsList[j];
                }

                if (remainderCols.Length < cells[i].Length)
                {
                    int[] tmp = new int[cells[i].Length];
                    for (int j = 0; j < remainderCols.Length; j++)
                    {
                        tmp[j] = remainderCols[j];
                    }
                    for (int j = remainderCols.Length; j < tmp.Length; j++)
                    {
                        tmp[j] = 0;
                    }
                    remainderCols = tmp;
                }

                for (int j = 0; j < cells[i].Length; j++)
                {
                    if (cells[i][j] != null)
                    {
                        Debug.Assert(remainderCols[j] == 0, "remainder columns value should be zero if we have a current cell");
                        remainderCols[j] = cells[i][j].RowSpan - 1;
                    }
                }
                i++;                 // next row
            }
            return(cells);
        }