Exemplo n.º 1
0
        object MathML.MathMLVisitor.Visit(MathMLTableCellElement e, object args)
        {
            MathMLVisitor v = this;

            return(v.Visit((MathMLPresentationContainer)e, args));
        }
Exemplo n.º 2
0
		object MathML.MathMLVisitor.Visit(MathMLTableCellElement e, object args)
		{
			MathMLVisitor p = this;
			return p.Visit((MathMLPresentationContainer)e, args);
		}
Exemplo n.º 3
0
		/**
		 * initialize the dashed and solid lines
		 * pre-req verticalExtent is set
		 * 
		 * The general idea behind this line layout algorighm is that from just 
		 * a grid of cells, with some null and other not, it is impossible to know
		 * where to place lines. If we have 2 adjacent cells, both null, we do
		 * not know to place a line between them as the left cell could be from
		 * a column spanning cell, and the right could be from a row spanning cell.
		 * 
		 * So, we need to know spanning numbers. 
		 */
		private void CreateLines(BoundingBox[][] extents, MathMLTableCellElement[][] cells, 
			Row[] rows, Column[] columns, LineStyle[] columnLines, LineStyle[] rowLines, LineStyle frame)
		{
			// TODO change these to arrays
			ArrayList dashedLineList = new ArrayList();
			ArrayList solidLineList = new ArrayList();

			try
			{	        
				// max number of TABLE columns
				int maxColCount = (columns.Length - 1) / 2;
				int[] rowSpan = new int[maxColCount];
				

				float top = 0;
				float vLen = 0;
				float hLen = 0;
				float left = 0;

				// outer loop rows
				for(int i = 0, row = 1; i < cells.Length; i++, row += 2)
				{				
					if(i == 0)
					{
						top = rows[0].VerticalExtent;
						vLen = rows[1].VerticalExtent + rows[2].VerticalExtent / 2.0f;
					}
					else
					{
						top = top + vLen;
						vLen = rows[row - 1].VerticalExtent / 2.0f + rows[row].VerticalExtent + rows[row + 1].VerticalExtent / 2.0f;
					}

					// spaning column length of next row, if a cell spans rows, then it needs a line
					//int currColSpan = (cells.Length && 0 < cells[i].Length && cells[i][0] != null) ?
					//	cells[i][0].ColumnSpan : 0;
					//i//nt nextColSpan = (i + 1 < cells.Length && 0 < cells[i + 1].Length && cells[i + 1][0] != null) ?
					//	cells[i + 1][0].ColumnSpan : 0;

					// inner loop columns
					for(int j = 0, col = 1; j < maxColCount; j++, col += 2)
					{
						if(j == 0)
						{
							left = columns[0].Width;
							hLen = columns[1].Width + columns[2].Width / 2.0f;
						}
						else
						{
							left = left + hLen;
							hLen = columns[col - 1].Width / 2.0f + columns[col].Width + columns[col + 1].Width / 2.0f;
						}					

						// do the vertical line at end of cell
						if((j + 1 < cells[i].Length && cells[i][j + 1] != null) ||
							(j == cells[i].Length - 1 && cells[i].Length < maxColCount))
						{
							if(columnLines[j] == LineStyle.Solid)
							{			
								solidLineList.Add(new PointF(left + hLen, top));
								solidLineList.Add(new PointF(left + hLen, top + vLen));
							}
							else if(columnLines[j] == LineStyle.Dashed)
							{
								dashedLineList.Add(new PointF(left + hLen, top));
								dashedLineList.Add(new PointF(left + hLen, top + vLen));
							}
						}

						// horz line at bottom of cell, only do if we are not the last row
						if(i + 1 < cells.Length)
						{
							// if a span count is 0, this means that the end of a cell was encountered, so
							// we need to read the span count from the current cell. Otherwise, we are in the
							// middle of a row spanning colum and we need to decrement the count indicating that
							// we used up that cell
							if(rowSpan[j] == 0)
							{
								rowSpan[j] = j < cells[i].Length && cells[i][j] != null ? cells[i][j].RowSpan - 1 : 0;
							}
							else
							{
								rowSpan[j]--;
							}

							if(rowSpan[j] == 0)
							{
								if(rowLines[i] == LineStyle.Solid)
								{
									solidLineList.Add(new PointF(left, top + vLen));
									solidLineList.Add(new PointF(left + hLen, top + vLen));
								}
								else if(rowLines[i] == LineStyle.Dashed)
								{
									dashedLineList.Add(new PointF(left, top + vLen));
									dashedLineList.Add(new PointF(left + hLen, top + vLen));
								}
							}
						}
					}			
				}

				// draw the frame
				if(frame == LineStyle.Solid)
				{
					solidLineList.Add(new PointF(0, 0));
					solidLineList.Add(new PointF(0, box.VerticalExtent));

					solidLineList.Add(new PointF(0, 0));
					solidLineList.Add(new PointF(box.Width, 0));

					solidLineList.Add(new PointF(box.Width, box.VerticalExtent));
					solidLineList.Add(new PointF(box.Width, 0));

					solidLineList.Add(new PointF(box.Width, box.VerticalExtent));
					solidLineList.Add(new PointF(0, box.VerticalExtent));

				}
				else if(frame == LineStyle.Dashed)
				{
					dashedLineList.Add(new PointF(0, 0));
					dashedLineList.Add(new PointF(0, box.VerticalExtent));

					dashedLineList.Add(new PointF(0, 0));
					dashedLineList.Add(new PointF(box.Width, 0));

					dashedLineList.Add(new PointF(box.Width, box.VerticalExtent));
					dashedLineList.Add(new PointF(box.Width, 0));

					dashedLineList.Add(new PointF(box.Width, box.VerticalExtent));
					dashedLineList.Add(new PointF(0, box.VerticalExtent));
				}
			}
			catch(Exception ex)
			{
				throw new Exception("error creating table lines, table should still display, error: " +
					ex.Message);
			}

			dashedLines = (PointF[])dashedLineList.ToArray(typeof(PointF));
			solidLines = (PointF[])solidLineList.ToArray(typeof(PointF));
		}
Exemplo n.º 4
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);
        }
Exemplo n.º 5
0
		private static void AdjustSpanningCells(MathMLTableCellElement[][] cells, 
			BoundingBox[][] minCellSizes, Row[] rows, Column[] columns)
		{
			// init to 1 to skip over first spacing row for frame 
			// outer loop - rows
			for(int i = 0, rowIndex = 1; i < cells.Length; i++, rowIndex += 2)
			{
				// init to 1 to skip over first spacing column for frame
				// inner loop - columns
				for(int j = 0, colIndex = 1; j < cells[i].Length; j++, colIndex += 2)
				{
					if(cells[i][j] != null)
					{
						int rowSpan = cells[i][j].RowSpan;
						if(rowSpan > 1)
						{
							float rowSpanVertExt = 0;
							for(int k = 0, k2 = 0; k < rowSpan; k++, k2 += 2)
							{
								if(rowIndex + k2 < rows.Length)
								{
									// content row
									rowSpanVertExt += rows[rowIndex + k2].VerticalExtent;

									// only add inner space rows 
									if(k < rowSpan - 1)
									{										
										rowSpanVertExt += rows[rowIndex + k2 + 1].VerticalExtent;	
									}
								}
								else
								{
									Debug.WriteLine("warning, row span exceeds row count");
								}
							}
							float reqVertExt = minCellSizes[i][j].VerticalExtent - rowSpanVertExt;
							if(reqVertExt > 0)
							{
								Debug.WriteLine("need " + reqVertExt + " to accomdate spanning row");
								float newSpace = reqVertExt / (float)rowSpan;
								for(int k = 0, k2 = 0; k < rowSpan; k++, k2 += 2)
								{
									if(rowIndex + k2 < rows.Length)
									{
										rows[rowIndex + k2].Depth += newSpace / 2.0f;
										rows[rowIndex + k2].Height += newSpace / 2.0f;
									}
									else
									{
										Debug.WriteLine("warning, row span exceeds row count");
									}						
								}
							}
						}
					}
				}
			}
		}
Exemplo n.º 6
0
		private static void CreateCellSizesAndShifts(MathMLTableCellElement[][] cells, 
			Row[] rows, Column[] columns, ref BoundingBox[][] sizes, ref PointF[][] shifts)
		{
			sizes = new BoundingBox[cells.Length][];
			shifts = new PointF[cells.Length][];

			// init to 1 to skip over first spacing row for frame 
			int rowIndex = 1;

			// y shift, start with upper frame space
			float y = rows[0].VerticalExtent;

			// outer loop - rows
			for(int i = 0; i < cells.Length; i++)
			{
				// init to 1 to skip over first spacing column for frame
				int colIndex = 1;
				// start x shift with frame space
				float x = columns[0].Width;

				sizes[i] = new BoundingBox[cells[i].Length];
				shifts[i] = new PointF[cells[i].Length];		

				// inner loop - columns
				for(int j = 0; j < cells[i].Length; j++)
				{
					if(cells[i][j] != null)
					{
						BoundingBox box = BoundingBox.New();
	
						for(int k = 0, k2 = 0; k < cells[i][j].ColumnSpan; k++, k2 += 2)
						{
							if(colIndex + k2 < columns.Length)
							{
								if(k2 == 0)
								{
									box.Width = columns[colIndex].Width;
								}
								else
								{
									// add content column
									box.Append(BoundingBox.New(columns[colIndex + k].Width, 0, 0));
									// add space column
									box.Append(BoundingBox.New(columns[colIndex + k + 1].Width, 0, 0));
								}
							}
							else
							{
								Debug.WriteLine("warning, insuffcient columns for spanning");
							}
						}						
						
						for(int k = 0, k2 = 0; k < cells[i][j].RowSpan; k++, k2 += 2)
						{
							if(rowIndex + k2 < rows.Length)
							{
								if(k2 == 0)
								{
									box.Height = rows[rowIndex].Height;
									box.Depth = rows[rowIndex].Depth;
								}
								else
								{
									// add content row
									box.Over(BoundingBox.New(0, rows[rowIndex + k2].Height, rows[rowIndex + k].Depth));
									// add space row
									box.Over(BoundingBox.New(0, rows[rowIndex + k2 + 1].Height, rows[rowIndex + k + 1].Depth));							
								}
							}
						}						

						Debug.Assert(box.Height == rows[rowIndex].Height);

						sizes[i][j] = box;
						shifts[i][j] = new PointF(x, y + box.Height);
					}

					// add width of current column and next column which is a spaceing column 
					// and set index to next non space column
					x += columns[colIndex++].Width;
					x += columns[colIndex++].Width;
				}
				// add vertical extent of current row and next row which is a spaceing row 
				// and set index to next non space row
				y += rows[rowIndex++].VerticalExtent;
				y += rows[rowIndex++].VerticalExtent;
			}
		}
Exemplo n.º 7
0
		/**
		 * calculate the required space to fit all the columns
		 */
		private static Column[] CreateColumns(IFormattingContext ctx, MathMLMeasurer measurer, 
			MathMLTableCellElement[][] cells, BoundingBox[][] minCellSizes, int columnCount, 
			Length[] columnWidths, Length[] spaceWidths, Length frameSpacing)
		{
			Column[] columns = null;		
			int c = 0;
			int colWidth = 0;
			int spaceWidth = 0;		

			// new column array: max column count + spacing columns + border spacing
			// =                 (max column count) + (max column count - 1) + 2
			// =                 (max column count) + (max column count) + 1
			columns = new Column[columnCount + columnCount + 1];

			// set the frame spacing columns
			columns[c++] = new Column(ctx, frameSpacing, 0, true);

			// outer loop: columns
			for(int i = 0; i < columnCount; i++)
			{
				BoundingBox[] columnCells = new BoundingBox[cells.Length];
				// inner loop: rows
				for(int j = 0; j < cells.Length; j++)
				{
					columnCells[j] = i < cells[j].Length ? minCellSizes[j][i] : BoundingBox.New();
				}

				// set the column
				columns[c++] = new Column(ctx, columnWidths[colWidth++], GetRequiredWidth(columnCells), false);

				// set the space column
				if(i < columnCount - 1)
				{
					columns[c++] = new Column(ctx, spaceWidths[spaceWidth++], 0, true);
				}
			}

			// set the right spacing column
			columns[c++] = new Column(ctx, frameSpacing, 0, true);

			// sanity check
			Debug.Assert(c == columns.Length, "error, maxColumnCount and processed column count do not match");

			return columns;
		}
Exemplo n.º 8
0
		private static Row[] CreateRows(IFormattingContext ctx, MathMLTableCellElement[][] cells, 
			BoundingBox[][] minCellSizes, Length[] rowSpacing, Length frameSpacing)
		{
			int i = 0;
			int space = 0;
			// new row array: row count + spacing rows + border spacing
			// =                 (row count) + (row count - 1) + 2
			// =                 (row count) + (row count) + 1
			Row[] rows = new Row[minCellSizes.Length + minCellSizes.Length + 1];

			// frame spacing
			rows[i++] = new Row(ctx.Evaluate(frameSpacing));

			for(int j = 0; j < minCellSizes.Length; j++)
			{
				// cell row
				rows[i++] = new Row(cells[j], minCellSizes[j]);

				// spacing row
				if(j < minCellSizes.Length - 1)
				{
					rows[i++] = new Row(ctx.Evaluate(rowSpacing[space++]));
				}
			}

			// final frame spacing
			rows[i++] = new Row(ctx.Evaluate(frameSpacing));

			// sanity check
			Debug.Assert(i == rows.Length, "error, row count and processed row count do not match");

			return rows;
		}
Exemplo n.º 9
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;
		}
Exemplo n.º 10
0
		/**
		 * find the maximum column count from a collection of cells, 
		 * this is the row with the largest number of cells
		 */
		public int GetCellColumnCount(MathMLTableCellElement[][] cells)
		{
			int colCount = 0;
			// find max column count
			for(int i = 0; i < cells.Length; i++) 
			{
				if(cells[i].Length > colCount) colCount = cells[i].Length;
			}
			return colCount;
		}
Exemplo n.º 11
0
			/**
			 * construct a row that minimally encoloses a set of cell sizes
			 */
			public Row(MathMLTableCellElement[] cells, BoundingBox[] minCellSizes)
			{
				Spacing = false;
				Height = 0; 
				Depth = 0;

				for(int i = 0; i < minCellSizes.Length; i++)
				{
					// do not count spanning rows, these are adjusted later
					if(cells[i] != null)
					{			
						float h =  minCellSizes[i].Height / (float)cells[i].RowSpan;
						float d =  minCellSizes[i].Depth / (float)cells[i].RowSpan;

						if(h > Height) Height = h;
						if(d > Depth) Depth = d;
					}
				}
			}