Exemplo n.º 1
0
        public static void GMTable(MathNode node, XElement output)
        {
            DrawBox(node, output);
            //Draw cells
            double vshift = -node.Height + node.FrameSpacings[1];
            double hshift;

            foreach (var rowItem in node.Rows.Select((value, r) => new { r, value }))
            {
                RowDescriptor row = rowItem.value;
                vshift += row.Height;
                hshift  = node.FrameSpacings[0];
                foreach (var cellItem in row.Cells.Select((value, c) => new { c, value }))
                {
                    ColumnDescriptor column = node.Columns[cellItem.c];
                    CellDescriptor   cell   = row.Cells[cellItem.c];
                    if (cell != null && cell.Content != null)
                    {
                        double cellWidth;
                        // Calculate horizontal alignment
                        if (cell.ColSpan > 1)
                        {
                            cellWidth  = node.Columns.Skip(cellItem.c).Take(cellItem.c + cell.ColSpan).Select(x => x.Width).Sum();          //ToDo: verify
                            cellWidth += node.Columns.Skip(cellItem.c).Take(cellItem.c + cell.ColSpan - 1).Select(x => x.SpaceAfter).Sum(); //ToDo: verify
                        }
                        else
                        {
                            cellWidth = column.Width;
                        }
                        double hadjust = (cellWidth - cell.Content.Width) * (alignKeywords.ContainsKey(cell.HAlign) ? alignKeywords[cell.HAlign] : 0.5);

                        // Calculate vertical alignment.
                        double cellHeight;
                        if (cell.RowSpan > 1)
                        {
                            cellHeight  = node.Rows.Skip(rowItem.r).Take(rowItem.r + cell.RowSpan).Select(x => x.Height + x.Depth).Sum(); //ToDo: Verify
                            cellHeight += node.Rows.Skip(rowItem.r).Take(rowItem.r + cell.RowSpan - 1).Select(x => x.SpaceAfter).Sum();   //ToDo: Verify
                        }
                        else
                        {
                            cellHeight = row.Height + row.Depth;
                        }

                        double vadjust;
                        if (cell.VAlign == "top")
                        {
                            vadjust = cell.Content.Height - row.Height;
                        }
                        else if (cell.VAlign == "bottom")
                        {
                            vadjust = cellHeight - row.Height - cell.Content.Depth;
                        }
                        else if ((cell.VAlign == "axis" || cell.VAlign == "baseline") && cell.RowSpan == 1)
                        {
                            vadjust = -cell.VShift; // calculated in the measurer
                        }
                        else
                        {
                            vadjust = (cell.Content.Height - cell.Content.Depth + cellHeight) / 2 - row.Height;
                        }
                        DrawTranslatedNode(cell.Content, output, hshift + hadjust, vshift + vadjust);
                    }
                    hshift += column.Width + column.SpaceAfter;
                }
                vshift += row.Depth + row.SpaceAfter;
            }

            //Draw frame
            double x1 = node.LineWidth / 2;
            double y1 = node.LineWidth / 2 - node.Height;
            double x2 = node.Width - node.LineWidth / 2;
            double y2 = node.Depth - node.LineWidth / 2;

            DrawBorder(node, output, x1, y1, x1, y2, node.FrameLines[0]);
            DrawBorder(node, output, x2, y1, x2, y2, node.FrameLines[0]);
            DrawBorder(node, output, x1, y1, x2, y1, node.FrameLines[1]);
            DrawBorder(node, output, x1, y2, x2, y2, node.FrameLines[1]);

            // Draw intermediate lines
            // First, let's make a grid
            hshift = node.FrameSpacings[0];
            List <double> hoffsets = new List <double>();

            foreach (var item in node.Columns.Select((value, c) => new { c, value }))
            {
                double spacing = item.value.SpaceAfter;
                hshift += item.value.Width;
                hoffsets.Add(hshift + spacing / 2);
                hshift += spacing;
            }
            hoffsets[hoffsets.Count - 1] = x2;

            vshift = -node.Height + node.FrameSpacings[1];
            List <double> voffsets = new List <double>();

            foreach (var item in node.Rows.Select((value, r) => new { r, value }))
            {
                double spacing = item.value.SpaceAfter;
                vshift += item.value.Height + item.value.Depth;
                voffsets.Add(vshift + spacing / 2);
                vshift += spacing;
            }
            voffsets[voffsets.Count - 1] = y2;

            List <double> vspans = Enumerable.Repeat <double>(0, node.Columns.Count).ToList();

            for (int r = 0; r < node.Rows.Count - 1; r++)
            {
                RowDescriptor row = node.Rows[r];
                if (row.LineAfter == null)
                {
                    continue;
                }

                foreach (var cellItem in row.Cells.Select((value, c) => new { c, value }))
                {
                    CellDescriptor cell = cellItem.value;
                    if (cell == null || cell.ColSpan == 0)
                    {
                        continue;
                    }
                    for (int i = cellItem.c; i < cellItem.c + cell.ColSpan; i++)
                    {
                        vspans[i] = cell.RowSpan;
                    }
                }
                vspans = vspans.Select(x => Math.Max(0, x - 1)).ToList();

                double lineY  = voffsets[r];
                double startX = x1;
                double endX   = x1;
                foreach (var cellItem in node.Columns.Select((value, c) => new { c, value }))
                {
                    if (vspans[cellItem.c] > 0)
                    {
                        DrawBorder(node, output, startX, lineY, endX, lineY, row.LineAfter);
                        startX = hoffsets[cellItem.c];
                    }
                    endX = hoffsets[cellItem.c];
                }
                DrawBorder(node, output, startX, lineY, endX, lineY, row.LineAfter);
            }

            List <double> hspans = Enumerable.Repeat <double>(0, node.Columns.Count).ToList();

            for (int c = 0; c < node.Columns.Count - 1; c++)
            {
                ColumnDescriptor column = node.Columns[c];
                if (column.LineAfter == null)
                {
                    continue;
                }

                foreach (var rowItem in node.Rows.Select((value, r) => new { r, value }))
                {
                    RowDescriptor row = rowItem.value;
                    if (row.Cells.Count <= c)
                    {
                        continue;
                    }
                    CellDescriptor cell = row.Cells[c];
                    if (cell == null || cell.Content == null)
                    {
                        continue;
                    }
                    for (int j = rowItem.r; j < rowItem.r + cell.RowSpan; j++)
                    {
                        hspans[j] = cell.ColSpan;
                    }
                }
                hspans = hspans.Select(x => Math.Max(0, x - 1)).ToList();
                double lineX  = hoffsets[c];
                double startY = y1;
                double endY   = y1;
                foreach (var item in node.Rows.Select((value, r) => new { r, value }))
                {
                    if (hspans[item.r] > 0)
                    {
                        DrawBorder(node, output, lineX, startY, lineX, endY, column.LineAfter);
                        startY = voffsets[item.r];
                    }
                    endY = voffsets[item.r];
                }
                DrawBorder(node, output, lineX, startY, lineX, endY, column.LineAfter);
            }
        }
Exemplo n.º 2
0
        void ArrangeCells(MathNode node)
        {
            node.Rows = new List<RowDescriptor>();
            node.Columns = new List<ColumnDescriptor>();
            List<int> busycells = new List<int>();

            // Read table-level alignment properties
            List<string> table_rowaligns = node.GetListProperty("rowalign");
            List<string> table_columnaligns = node.GetListProperty("columnalign");

            foreach (MathNode ch in node.Children)
            {
                string rowalign = GetByIndexOrLast(table_rowaligns, node.Rows.Count);
                List<string> row_columnaligns = table_columnaligns;
                List<MathNode> cells = new List<MathNode>();

                if (ch.ElementName == "mtr" || ch.ElementName == "mlabeledtr")
                {
                    cells = ch.Children;
                    if (ch.Attributes.ContainsKey("rowalign"))
                        rowalign = ch.Attributes["rowalign"];
                    if (ch.Attributes.ContainsKey("columnalign"))
                    {
                        List<string> columnaligns = node.GetListProperty("columnalign", ch.Attributes["columnalign"]);
                    }
                        
                }
                else
                {
                    cells.Add(ch);
                }

                RowDescriptor row = new RowDescriptor(node, cells, rowalign, row_columnaligns, busycells);
                node.Rows.Add(row);
                // busycells passes information about cells spanning multiple rows
                busycells = busycells.Select(n => Math.Max(0, n - 1)).ToList();
                while (busycells.Count < row.Cells.Count)
                    busycells.Add(0);

                for(int i =0; i < row.Cells.Count; i++)
                {
                    CellDescriptor cell = row.Cells[i];
                    if (cell == null)
                        continue;
                    if (cell.RowSpan > 1)
                    {
                        for (int j = i; j <= i + cell.ColSpan; i++)
                        {
                            busycells[j] = cell.RowSpan - 1;
                        }
                    }
                }
            }

            //Pad the table with empty rows until no spanning cell protrudes
            while (busycells.Max() > 0)
            {
                string rowalign = Measurer.GetByIndexOrLast(table_rowaligns, node.Rows.Count);
                node.Rows.Add(new RowDescriptor(node, new List<MathNode>(), rowalign, table_columnaligns, busycells));
                busycells = busycells.Select(x => Math.Max(0, x - 1)).ToList();
            }

        }