Beispiel #1
0
		/**
		 * private ctor used for fit'ing
		 */
		private HorizontalArea(Area[] content, Area source) : base(content, source)
		{
			// calulate bounding box
			BoundingBox box = BoundingBox.New();
			foreach(Area a in content) box.Append(a.BoundingBox);
			this.box = box;
		}
Beispiel #2
0
		/**
		 * private ctor used for fit operation
		 */
		private TableArea(MathMLTableElement e, Area[] cells, BoundingBox box, PointF[] solidLines, 
			PointF[] dashedLines, Area source) : base(cells, source)
		{
			this.element = e;
			this.dashedLines = dashedLines;
			this.solidLines = solidLines;
			this.box = box;			
		}
Beispiel #3
0
		public GlyphArea(IFontHandle fontHandle, ref GlyphAttributes attributes)
		{
			this.font = fontHandle;
			this.leftEdge = attributes.Left;
			this.rightEdge = attributes.Right;
			this.box = attributes.Box;
			this.index = (ushort)attributes.Index;
		}
Beispiel #4
0
		/**
		 * create a box area.
		 */
		public TableCellArea(MathMLElement element, Area area, BoundingBox box, 
			PointF cellShift, PointF areaShift) : base(area)
		{
			this.cellShift = cellShift;
			this.areaShift = areaShift;
			this.box = box;
			this.element = element;
		}
Beispiel #5
0
    /// <summary>
    /// Draw the current mathml equation to an image object.
    /// </summary>
    /// <param name="type">The type of image to return, currently this can be
    /// either Bitmap or Metafile</param>
    /// <param name="gr">The graphics context in which this bitmap should be created.</param>
    /// <returns>A new image, null if an invalid type is given or there is no current element</returns>
    public Image GetImage(Type type, Graphics gr)
    {

      if (mathElement == null)
        return null;

        gr.PageUnit = GraphicsUnit.Pixel;

      // build the formatting tree
        MathMLFormatter formatter = new MathMLFormatter();
        WinFormattingContext ctx = new WinFormattingContext(gr, fontSize);
        format = formatter.Format(mathElement, ctx);

        // build the are tree
        box = format.BoundingBox;
        area = format.Fit(box);
      

      Image image = null;
      int height = (int)Math.Ceiling(2+box.VerticalExtent);
      int width = (int)Math.Ceiling(2+box.HorizontalExtent);

      if(type.Equals(typeof(Bitmap)))
      {
        image = new Bitmap(width, height);
      }
      else if(type.Equals(typeof(Metafile)))
      {
        IntPtr dc = gr.GetHdc();
        image = new Metafile(new MemoryStream(), dc, EmfType.EmfOnly);
        gr.ReleaseHdc(dc);
      }

      if(image != null && area != null)
      {

        using (Graphics gi = Graphics.FromImage(image))
        {
          gi.PageUnit = GraphicsUnit.Pixel;
          gi.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
          DrawWithoutFormatting(gi, width, height, 1, 1);
        }
      }

      return image;
    }
Beispiel #6
0
		/**
		 * private consturctor
		 */
		private VerticalArea(Area[] areas, int baseline, Area source) 
			: base(areas, source)
		{
			this.baseline = baseline;

            BoundingBox bbox = content[baseline].BoundingBox;

			for(int i = 0; i < content.Length; i++)
			{
				if(i < baseline)
				{
					bbox.Over(content[i].BoundingBox);
				}
				else if(i > baseline)
				{
					bbox.Under(content[i].BoundingBox);
				}
			}

			this.box = bbox;
		}
Beispiel #7
0
		/**
		 * create a string area
		 */
		public StringArea(IFormattingContext context, string content)
		{
			this.font = context.GetFont();
			this.content = content;
			box = BoundingBox.New();

			float left = 0, right = 0;

			for(int i = 0; i < content.Length; i++)
			{
				BoundingBox tmp = BoundingBox.New();
				context.MeasureGlyph(font, content[i], out tmp, out left, out right);
				box.Append(tmp);

				// left edge of first char
				if(i == 0)
				{
					leftEdge = left;
				}
			}

			// right edge of last char
			rightEdge = right;
		}
		/**
		 * 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;
		}
Beispiel #9
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));
		}
Beispiel #10
0
		/**
		 * fit the child areas into a box.
		 * Essentially, each child area is given an availible space which is proportional
		 * to its' strength with respect to the overall strength of the overall array. Areas
		 * that can not be re-sized in the width direction (have zero width strenght) simply
		 * get re-sized to thier natural width.
		 * 
		 * NOTE: Derived classes must override this method (compound glyphs) because this returns
		 * a new HorzArea, not a derived type.
		 */
		public override Area Fit(BoundingBox box)
		{
			// the strength and un-adjusted size of the total array.
			Strength s = Strength;
			BoundingBox b = BoundingBox;
			Area[] areas = new Area[content.Length];

			// new width of each child area
			float width;

			// availible space for exanding filler areas in the width direction
			// use max here, because width may be negative if we are asked to size into
			// a smaller area.
			float availibleSpace = Math.Max(0, box.Width - b.Width);

			for(int i = 0; i < content.Length; i++)
			{
				Strength sa = content[i].Strength;
				BoundingBox ba = content[i].BoundingBox;

				if(s.Width == 0 || sa.Width == 0)
				{
					// no re-sizing strength, so re-size to natural width
					width = ba.Width;								
				}
				else
				{
					// re-size to natural width + % of availible space
					width = ba.Width + availibleSpace * sa.Width / s.Width;					
				}
				areas[i] = content[i].Fit(BoundingBox.New(width, box.Height, box.Depth));
			}
			return new HorizontalArea(areas, this);
		}
Beispiel #11
0
		/**
		 * create a new box area
		 */
		public static Area Box(BoundingBox box, Area area) 
		{
			return new BoxArea(area, box);
		}
Beispiel #12
0
		/**
		 * fit this area to a bounding box. This just
		 * creates a new vertical space area that is the height and depth
		 * of the bounding box
		 */
		public override Area Fit(BoundingBox box)
		{
			return new VerticalSpaceArea(box.Height, box.Depth);
		}
Beispiel #13
0
		/**
		 * fit all child area to thier own bounding box.
		 */
		public override Area Fit(BoundingBox box)
		{
			Area[] areas = new Area[content.Length];

			for(int i = 0; i < content.Length; i++)
			{
				areas[i] = content[i].Fit(content[i].BoundingBox);
			}

			// TODO optimize if all areas are the same as this
			return new TableArea(element, areas, box, solidLines, dashedLines, this);
		}
Beispiel #14
0
		public TableArea(MathMLTableElement e, Area[] cells, BoundingBox box, PointF[] solidLines, 
			PointF[] dashedLines) : this(e, cells, box, solidLines, dashedLines, null)
		{		
		}
Beispiel #15
0
		/**
		 * initialize the shift and vertical extent vars
		 * The final shift is calcuated by the formatter because it requires information
		 * about the formatted size of the cell area.
		 */
		private static void CalculateShiftAndSize(IFormattingContext ctx, MathMLTableElement table, Row[] rows, 
			Column[] columns, ref BoundingBox box, ref float shift)
		{
			shift = 0;
			TableAlign align = table.Align;
			float verticalExtent = 0;
			float width = 0;
			for(int i = 0; i < rows.Length; i++)
			{
				verticalExtent += rows[i].VerticalExtent;
			}

			for(int i = 0; i < columns.Length; i++)
			{
				width += columns[i].Width;
			}

			shift = -verticalExtent;

			box = BoundingBox.New(width, verticalExtent, 0);
		}
Beispiel #16
0
		/// <summary>
		/// set this box to the area that is the overlap of this box, 
		/// and the given box.
		/// </summary>
		/// <param name="box"></param>
		public void Overlap(BoundingBox box)
		{
            Width = Math.Max(Width, box.Width);
            if (!box.Defined)
                return;
            else if (Defined)
            {
                Height = Math.Max(Height, box.Height);
                Depth = Math.Max(Depth, box.Depth);
            }
            else
            {
                Height = box.Height;
                Depth = box.Depth;
            }
		}
Beispiel #17
0
		/// <summary>
		/// add the contents of the given bounding box to this bounding box
		/// </summary>
		/// <param name="box"></param>
		public void Append(BoundingBox box)
		{
			Width += box.Width;
			Depth = Math.Max(Depth, box.Depth);
			Height = Math.Max(Height, box.Height);
		}
Beispiel #18
0
		/// <summary>
		/// set this size to a region made by placing this box
		/// over the given box, e.g add the vertical extent of the
		/// given box to the depth this box.
		/// </summary>
		/// <param name="box"></param>
		public void Over(BoundingBox box)
		{
			Width = Math.Max(Width, box.Width);
			if (!box.Defined)
				return;
			else if (Defined)
				Depth += box.Height + box.Depth;
			else
			{
				Height = 0;
				Depth = box.Height + box.Depth;
			}
		}
Beispiel #19
0
    public static Area GetStretchyGlyph(IFormattingContext context, float pointSize, char c, BoundingBox desiredSize)
		{
			float lineThickness;
			return GetStretchyGlyph(context, pointSize, c, desiredSize, out lineThickness);
		}
Beispiel #20
0
		/**
		 * Default behavior is for a container area not to change any 
		 * properties of the bounding box, and simply fit the child
		 * to this box.
		 */
		public override Area Fit(BoundingBox box)
		{
			BinContainerArea area = (BinContainerArea)Clone();
			Debug.Assert(area != null, "result of Clone() is null in BinContainerArea.Fit");
			area.child = child.Fit(box);
			area.source = this;
			return area;
		}
Beispiel #21
0
        /**
		 * re-size all child nodes to the given width, and a height
		 * and depth proportional 
		 */
		public override Area Fit(BoundingBox box)
		{
			// new content area where fitted area are written to
			Area[] newContent = new Area[content.Length];

			// bounding box (natural size), and strength of the array
			// as a whole
			BoundingBox b = BoundingBox;
			Strength s = Strength;

			// availible height and depth distance to stretch
			float aHeight = Math.Max(0, box.Height - b.Height);
			float aDepth = Math.Max(0, box.Depth - b.Depth);

			for(int i = 0; i < content.Length; i++)
			{
				// strength and size of the current child area
				Strength ps = content[i].Strength;
				BoundingBox pb = content[i].BoundingBox;

				// above baseline
				if(i > baseline && s.Height > 0)
				{
					pb.Height += (aHeight * ps.Height) / s.Height;
					pb.Depth += (aHeight * ps.Depth) / s.Height;
				}
				// below baseline
				else if(i < baseline && s.Depth > 0)
				{
					pb.Height += (aDepth * ps.Height) / s.Depth;
					pb.Depth += (aDepth * ps.Depth) / s.Depth;
				}
				// is baseline
				else if(i == baseline && s.Height + s.Depth > 0)
				{
					if (s.Height > 0) pb.Height += (aHeight * ps.Height) / s.Height;
					if (s.Depth > 0) pb.Depth += (aDepth * ps.Depth) / s.Depth;
				}

				newContent[i] = content[i].Fit(BoundingBox.New(box.Width, pb.Height, pb.Depth));
			}
			return new VerticalArea(newContent, baseline, this);
		}
Beispiel #22
0
		public BoundingBox[] MeasureElements(IFormattingContext ctx, MathMLElement[] elements)
		{
			BoundingBox[] boxes = new BoundingBox[elements.Length];
			for(int i = 0; i < elements.Length; i++)
			{
				if(elements[i] != null)
				{
					boxes[i] = MeasureElement(ctx, elements[i]);
				}
				else
				{
					boxes[i] = BoundingBox.New();
				}
			}
			return boxes;
		}
Beispiel #23
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;
			}
		}
Beispiel #24
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");
									}						
								}
							}
						}
					}
				}
			}
		}
Beispiel #25
0
		/**
		 * calculate the default amout the script the baseline of the
		 * script rows. this ignores (for now anyway) the min shift values
		 * specified in the DOM
		 */
		private static void CalculateScriptShift(IFormattingContext context, 
			BoundingBox baseBox, BoundingBox subBox, Length subMinSize, 
			BoundingBox superBox, Length superMinSize, 
			out float subShift, out float superShift) 
		{

			CalculateScriptShift(context, baseBox, subBox, superBox, 
				out subShift, out superShift);
		}
Beispiel #26
0
        /**
		 * calculate a table shift
		 * the initially consists of entierly height, this is a value given to the 
		 * TableArea object to determine the vertical location of a table. 
		 * 
		 * This value is also used to modify the bounding box that is returned from this 
		 * class that is used for the TableArea
		 */
		private static float GetTableShift(IFormattingContext ctx, MathMLTableElement table, BoundingBox tableExtent)
		{	
			float shift = 0;
			// orient the row in the vertical direction, can be one of the following
			// (top | bottom | center | baseline | axis) [ rownumber ]
			// TODO rownumver is currently ignored
			switch(table.Align.Align)
			{
				case Align.Top:
				{
					shift = tableExtent.VerticalExtent;
				} break;
				case Align.Bottom:
				{
					shift = 0;
				} break;
				case Align.Center:
				{
					shift = tableExtent.VerticalExtent / 2.0f;					
				} break;
				case Align.Axis:
				{
					// shift to the axis (shift up in the negative direction)
					shift = (tableExtent.VerticalExtent / 2.0f) -ctx.Axis;
				} break;
				default: 
				{	
					shift = tableExtent.VerticalExtent / 2.0f;
				} break;
			}

			return shift;
		}
Beispiel #27
0
		public BoundingBox[][] MeasureElements(IFormattingContext ctx, MathMLElement[][] elements)
		{
			BoundingBox[][] boxes = new BoundingBox[elements.Length][];
			for(int i = 0; i < elements.Length; i++)
			{
				boxes[i] = MeasureElements(ctx, elements[i]);
			}
			return boxes;
		}
Beispiel #28
0
		/**
		 * calculate the default amout the script the baseline of the
		 * script rows. this ignores (for now anyway) the min shift values
		 * specified in the DOM.
		 */
		private static void CalculateScriptShift(IFormattingContext context, 
			BoundingBox baseBox, BoundingBox subBox, BoundingBox superBox, 
			out float subShift, out float superShift) 
		{

			float ex = context.Ex;
			float axis = context.Axis;
			float rule = context.DefaultLineThickness;

			superShift = Math.Max(ex, baseBox.Height - axis);
			subShift = Math.Max(axis, baseBox.Depth + axis);

			if(!superBox.Defined) 
			{
				superShift = 0;
				subShift = Math.Max(subShift, subBox.Height - (ex * 4.0f) / 5);
			}
			else 
			{
				superShift = Math.Max(superShift, superBox.Depth + ex / 4.0f);
				if(!subBox.Defined) 
				{
					subShift = 0;
				}
				else 
				{
					if((superShift - superBox.Depth) - (subBox.Height - superShift) < 4.0f * rule) 
					{
						subShift = 4.0f * rule - superShift + superBox.Depth + subBox.Height;
						float psi = (4.0f * ex) / 5.0f - (superShift - superBox.Depth);
						if(psi > 0.0f) 
						{
							subShift -= psi;
							superShift += psi;
						}
					}
				}
			}
		}
Beispiel #29
0
		/// <summary>
		/// fit this area to a bounding box
		/// create a new horizontal space area with the width of
		/// the given bounding box
		/// </summary>
		public override Area Fit(BoundingBox box)
		{
			return new HorizontalSpaceArea(box.Width);
		}
Beispiel #30
0
		/// <summary>
		/// create a space area that occupies the given size.
		/// </summary>
		/// <param name="size">the size to make a space area</param>
		/// <returns></returns>
		public static Area Space(BoundingBox size)
		{
			return new BoxArea(new IgnoreArea(), size);
		}