Exemplo n.º 1
0
        /**
         * set the attributes, but do not actually create a glyph
         * area.
         * @param fontHandle a handle to a native font resource
         * @param charIndex the index in the font of the desired glyph
         * @param stretchyType if this glyph is a repeated section in a
         *		  stretchy glyph, shrink the reported metrics by one, so
         *		  we get a nice overlap.
         */
        public GlyphAttributes(IFormattingContext context, IFontHandle fontHandle, short charIndex, int fudge)
        {
            Index     = charIndex;
            glyphArea = null;
            float tmp;

            if (charIndex >= 0)
            {
                context.MeasureGlyph(fontHandle, (ushort)charIndex, out Box,
                                     out Left, out Right);

                if (fudge == FudgeWidth)
                {
                    Box.Width -= 2 * fudgeFactor;
                }
                else if (fudge == FudgeHeight)
                {
                    if ((tmp = Box.Height - fudgeFactor) >= 0.0f)
                    {
                        Box.Height = tmp;
                    }
                    if ((tmp = Box.Depth - fudgeFactor) >= 0.0f)
                    {
                        Box.Depth = tmp;
                    }
                }
            }
            else
            {
                Box   = new BoundingBox();
                Left  = 0;
                Right = 0;
            }
        }
Exemplo n.º 2
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.º 3
0
		/**
		 * set the attributes, but do not actually create a glyph 
		 * area.
		 * @param fontHandle a handle to a native font resource
		 * @param charIndex the index in the font of the desired glyph
		 * @param stretchyType if this glyph is a repeated section in a
		 *		  stretchy glyph, shrink the reported metrics by one, so
		 *		  we get a nice overlap.
		 */
    public GlyphAttributes(IFormattingContext context, IFontHandle fontHandle, short charIndex, int fudge)
		{
			Index = charIndex;
			glyphArea = null;
			float tmp;

			if(charIndex >= 0)
			{
				context.MeasureGlyph(fontHandle, (ushort)charIndex, out Box, 
					out Left, out Right);

				if(fudge == FudgeWidth)
				{
					Box.Width -= 2 * fudgeFactor;
				}
				else if(fudge == FudgeHeight)
				{
					if((tmp = Box.Height - fudgeFactor) >= 0.0f) Box.Height = tmp;
					if((tmp = Box.Depth - fudgeFactor) >= 0.0f) Box.Depth = tmp;
				}
			}
			else
			{
				Box = new BoundingBox();
				Left = 0;
				Right = 0;
			}
		}
Exemplo n.º 4
0
		/**
		 * create a set of attributes.
		 * this calculates all of the glyph metrics from the graphic device.
		 */
		public StretchyGlyphAttributes(IFormattingContext context, IFontHandle fontHandle, ref StretchyGlyphIndices indices)
		{
			orientation = indices.Orientation;

			if(indices.SimpleIndices != null)
			{
				simpleGlyphs = new GlyphAttributes[indices.SimpleIndices.Length];
				for(int i = 0; i < simpleGlyphs.Length; i++)
				{
					simpleGlyphs[i] = new GlyphAttributes(context, fontHandle, 
						indices.SimpleIndices[i], GlyphAttributes.FudgeNone);
				}
			} 
			else
			{
				simpleGlyphs = null;
			}

			if(indices.CompoundIndices != null)
			{
				compoundGlyphs = new GlyphAttributes[indices.CompoundIndices.Length];
				for(int i = 0; i < compoundGlyphs.Length; i++)
				{
					// TODO deal with horizontal glyphs
					compoundGlyphs[i] = new GlyphAttributes(context, fontHandle, 
						indices.CompoundIndices[i], 
						i == StretchyGlyphIndices.Filler ? GlyphAttributes.FudgeHeight : GlyphAttributes.FudgeNone);
				}
			}
			else
			{
				compoundGlyphs = null;
			}
		}
Exemplo n.º 5
0
        /// <summary>
        /// Get the minimum formatted area size for the given element using the
        /// state of the given formatting context.
        ///
        /// Currently this just formats the element using the this as the formatter,
        /// in the future, this will be optimized so that a visitor only calculates
        /// the min size instead of creating an entire sub tree of areas.
        /// </summary>
        public BoundingBox MeasureElement(IFormattingContext ctx, MathMLElement e)
        {
            Debug.Assert(ctx.cacheArea == false);
            if (e != null)
            {
                Area a = Area.GetArea(e);
                if (a != null)
                {
                    return(a.BoundingBox);
                }

                if (cache.Contains(e))
                {
                    return((BoundingBox)cache[e]);
                }
                else
                {
                    if (e is MathMLTableElement)
                    {
                        Debug.WriteLine("table element");
                    }
                    BoundingBox box = (BoundingBox)e.Accept(this, ctx);
                    cache.Add(e, box);
                    return(box);
                }
            }
            else
            {
                return(BoundingBox.New());
            }
        }
Exemplo n.º 6
0
        /**
         * create a set of attributes.
         * this calculates all of the glyph metrics from the graphic device.
         */
        public StretchyGlyphAttributes(IFormattingContext context, IFontHandle fontHandle, ref StretchyGlyphIndices indices)
        {
            orientation = indices.Orientation;

            if (indices.SimpleIndices != null)
            {
                simpleGlyphs = new GlyphAttributes[indices.SimpleIndices.Length];
                for (int i = 0; i < simpleGlyphs.Length; i++)
                {
                    simpleGlyphs[i] = new GlyphAttributes(context, fontHandle,
                                                          indices.SimpleIndices[i], GlyphAttributes.FudgeNone);
                }
            }
            else
            {
                simpleGlyphs = null;
            }

            if (indices.CompoundIndices != null)
            {
                compoundGlyphs = new GlyphAttributes[indices.CompoundIndices.Length];
                for (int i = 0; i < compoundGlyphs.Length; i++)
                {
                    // TODO deal with horizontal glyphs
                    compoundGlyphs[i] = new GlyphAttributes(context, fontHandle,
                                                            indices.CompoundIndices[i],
                                                            i == StretchyGlyphIndices.Filler ? GlyphAttributes.FudgeHeight : GlyphAttributes.FudgeNone);
                }
            }
            else
            {
                compoundGlyphs = null;
            }
        }
Exemplo n.º 7
0
            /**
             * get a font based on the font type given in the variant,
             * and the size given in height. If the size can not be
             * evaluated to a valid size, the default font size is used.
             * the fontName override anything in the context if it is given.
             */
            public IFontHandle GetFont(IFormattingContext context, string fontName, string altFontName)
            {
                // font to be returned
                IFontHandle font = null;

                // find the attributes from the static array
                FontAttributes attr = fontAttributes[(int)context.MathVariant];

                float height = context.Size;

                // no italic if we are using the font name, otherwise use the
                // value from the mathvariant attribute
                bool italic = fontName.Length > 0 ? false : attr.Italic;

                // use default value if we are using the font specified by a name,
                // otherwise use the one from the attributes from mathvariant
                int weight = fontName.Length > 0 ? DefaultFontWeight : attr.Weight;

                // use either the fontName stirng if we have one, or the one
                // from the mathvariant attribute
                string name = fontName.Length > 0 ? fontName : attr.Name;

                font = FindFont(height, italic, weight, name);

                if (font == null)
                {
                    font = CreateFont(((WinFormattingContext)context)._graphics, height, italic, weight, name);
                    fonts.Add(new WeakReference(font));
                }
                return(font);
            }
Exemplo n.º 8
0
        public static Area Glyph(IFormattingContext context, String fontName,
                                 String altFontName, ushort index)
        {
            IFontHandle font = context.GetFont(fontName, altFontName);

            return(new GlyphArea(context, font, index));
        }
Exemplo n.º 9
0
		/// <summary>
		/// Get the minimum formatted area size for the given element using the
		/// state of the given formatting context.
		/// 
		/// Currently this just formats the element using the this as the formatter, 
		/// in the future, this will be optimized so that a visitor only calculates
		/// the min size instead of creating an entire sub tree of areas.
		/// </summary>
		public BoundingBox MeasureElement(IFormattingContext ctx, MathMLElement e)
		{
			Debug.Assert(ctx.cacheArea == false);
			if(e != null)
			{
				Area a = Area.GetArea(e);
				if(a != null) return a.BoundingBox;

				if(cache.Contains(e))
				{
					return (BoundingBox)cache[e];
				}
				else
				{
					if(e is MathMLTableElement)
					{
						Debug.WriteLine("table element");
					}
					BoundingBox box = (BoundingBox)e.Accept(this, ctx);
					cache.Add(e, box);
					return box;
				}
			}
			else
			{
				return BoundingBox.New();
			}
		}
Exemplo n.º 10
0
            /**
             * construct a new TableColumn object
             */
            public Column(IFormattingContext ctx, Length columnWidth,
                          float evaluatedWidth, bool spacing)
            {
                Spacing = spacing;
                if (spacing)
                {
                    if (columnWidth.Type == LengthType.Percentage)
                    {
                        MinimumWidth = 0;
                    }
                    else if (columnWidth.Fixed)
                    {
                        MinimumWidth = ctx.Evaluate(columnWidth);
                    }
                    else
                    {
                        // this is bad
                        throw new Exception("space columns must be either fixed or scaled widths");
                    }
                }
                else
                {
                    MinimumWidth = evaluatedWidth;
                }

                if (columnWidth.Type == LengthType.Auto)
                {
                    Type       = ColumnType.Auto;
                    ScaleWidth = 0;
                    FixedWidth = 0;
                    Width      = MinimumWidth;
                }
                else if (columnWidth.Type == LengthType.Fit)
                {
                    Type       = ColumnType.Fit;
                    ScaleWidth = 0;
                    FixedWidth = 0;
                    Width      = MinimumWidth;
                }
                else if (columnWidth.Type == LengthType.Percentage)
                {
                    Type       = ColumnType.Scale;
                    ScaleWidth = columnWidth.Value / 100.0f;
                    FixedWidth = 0;
                    Width      = MinimumWidth;
                }
                else if (columnWidth.Fixed)
                {
                    Type       = ColumnType.Fixed;
                    ScaleWidth = 0;
                    FixedWidth = MinimumWidth;
                    Width      = MinimumWidth;
                }
                else
                {
                    // this is bad
                    throw new Exception(columnWidth.ToString() + " is not a valid length type for a table");
                }
            }
Exemplo n.º 11
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);
 }
Exemplo n.º 12
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);
 }
Exemplo n.º 13
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);
        }
Exemplo n.º 14
0
    public override AreaRegion GetRegion(IFormattingContext context, float x, float y, Area area, int index)
		{
			AreaRegion region = child.GetRegion (context, x, y, area, index);
			if(region != null && region.Element == null)
			{
				region.Element = element;				
			}
			return region;
		}
Exemplo n.º 15
0
 /**
  * create a font with the given font size. return the index of the new
  * font, or -1 if we failed to create the font
  */
 private int CreateFont(IFormattingContext context, float fontSize)
 {
     fontSize = (fontSize * scaleFactor);
     FontInstance[] tmp = fontInstances;
     fontInstances = new FontInstance[fontInstances.Length + 1];
     tmp.CopyTo(fontInstances, 0);
     fontInstances[fontInstances.Length - 1] = new FontInstance(context, fontName, fontSize, stretchyGlyphIndices);
     return(fontInstances.Length - 1);
 }
Exemplo n.º 16
0
      public Area GetArea(IFormattingContext context, IFontHandle fontHandle, char c)
		{
			Area result = null;
			ushort glyphIndex = (ushort)(c + offset);
      if (glyphIndex >= first && glyphIndex <= last)
			{
				result = new GlyphArea(context, fontHandle, glyphIndex);
			}
			return result;
		}
Exemplo n.º 17
0
        public override AreaRegion GetRegion(IFormattingContext context, float x, float y, Area area, int index)
        {
            AreaRegion region = child.GetRegion(context, x, y, area, index);

            if (region != null && region.Element == null)
            {
                region.Element = element;
            }
            return(region);
        }
Exemplo n.º 18
0
        public Area GetArea(IFormattingContext context, IFontHandle fontHandle, char c)
        {
            Area   result     = null;
            ushort glyphIndex = (ushort)(c + offset);

            if (glyphIndex >= first && glyphIndex <= last)
            {
                result = new GlyphArea(context, fontHandle, glyphIndex);
            }
            return(result);
        }
Exemplo n.º 19
0
 public virtual AreaRegion GetRegion(IFormattingContext context, float x, float y, Area area, int index)
 {
     if (index == 0 && area == this)
     {
         return(new AreaRegion(this, x + LeftEdge, y));
     }
     else
     {
         return(null);
     }
 }
Exemplo n.º 20
0
 public override AreaRegion GetRegion(IFormattingContext context, float x, float y, Area area, int index)
 {
     if (area == source)
     {
         return(new AreaRegion(this, x, y));
     }
     else
     {
         return(child.GetRegion(context, x, y, area, index));
     }
 }
Exemplo n.º 21
0
 public override AreaRegion GetRegion(IFormattingContext context, float x, float y, MathMLElement element, int index)
 {
     if (element == this.element)
     {
         return(new AreaRegion(this, element, x + cellShift.X, y + cellShift.Y));
     }
     else
     {
         return(child.GetRegion(context, x + areaShift.X, y + areaShift.Y, element, index));
     }
 }
Exemplo n.º 22
0
 public FontInstance(IFormattingContext context, string fontName, float pointSize, StretchyGlyphIndices[] glyphIndices)
 {
     cachedAreas        = null;
     PointSize          = pointSize;
     FontHandle         = context.CreateFont(pointSize, false, 500, fontName);
     stretchyAttributes = new StretchyGlyphAttributes[glyphIndices.Length];
     for (int i = 0; i < stretchyAttributes.Length; i++)
     {
         stretchyAttributes[i] = new StretchyGlyphAttributes(
             context, FontHandle, ref glyphIndices[i]);
     }
 }
Exemplo n.º 23
0
    public FontInstance(IFormattingContext context, string fontName, float pointSize, StretchyGlyphIndices[] glyphIndices)
		{
			cachedAreas = null;
			PointSize = pointSize;
			FontHandle = context.CreateFont(pointSize, false, 500, fontName);
			stretchyAttributes = new StretchyGlyphAttributes[glyphIndices.Length];
			for(int i = 0; i < stretchyAttributes.Length; i++)
			{
				stretchyAttributes[i] = new StretchyGlyphAttributes(
					context, FontHandle, ref glyphIndices[i]);
			}
		}
Exemplo n.º 24
0
 public override AreaRegion GetEditRegion(IFormattingContext context, float x, float y, int index)
 {
     foreach (Area a in content)
     {
         AreaRegion r = a.GetEditRegion(context, x, y, index);
         if (r != null)
         {
             return(r);
         }
     }
     return(null);
 }
Exemplo n.º 25
0
 public override AreaRegion GetRegion(IFormattingContext context, float x, float y, MathMLElement element, int index)
 {
     foreach (Area a in content)
     {
         AreaRegion r = a.GetRegion(context, x, y, element, index);
         if (r != null)
         {
             return(r);
         }
         x += a.BoundingBox.HorizontalExtent;
     }
     return(null);
 }
Exemplo n.º 26
0
        /**
         * Create a fraction area.
         * This is an area that consists of 2 areas vertically separated by a line.
         * this notion natuarally falls into the conecpt of a vertical array area,
         * an area, a line, and the second area.
         */
        public static Area Fraction(IFormattingContext ctx, Area numerator, Area denominator, float lineThickness)
        {
            Area space = new VerticalSpaceArea(ctx.OnePixel, ctx.OnePixel);
            Area line  = HorizontalLine(ctx.OnePixel);

            numerator = HorizontalCenter(numerator);

            denominator = HorizontalCenter(denominator);

            Area[] areas = { denominator, space, line, space, numerator };

            return(Shift(ctx.Axis, new VerticalArea(areas, 2)));
        }
Exemplo n.º 27
0
        public override AreaRegion GetEditRegion(IFormattingContext context, float x, float y, int index)
        {
            // measure horizontal position of char:
            BoundingBox horz = BoundingBox.New();
            float       left, right;

            for (int i = 0; i < index && i < content.Length; i++)
            {
                BoundingBox tmp = BoundingBox.New();
                context.MeasureGlyph(font, content[i], out tmp, out left, out right);
                horz.Append(tmp);
            }
            return(new AreaRegion(this, x + horz.Width, y));
        }
Exemplo n.º 28
0
        /**
         * find an index to a font that mathces the given font cell height,
         * if no font is availible, one is created with this height.
         */
        private int GetFontIndex(IFormattingContext context, float fontSize)
        {
            fontSize = (fontSize * scaleFactor);
            for (int i = 0; i < fontInstances.Length; i++)
            {
                if (fontInstances[i].PointSize == fontSize)
                {
                    return(i);
                }
            }

            // no font found, so try to create one.
            return(CreateFont(context, fontSize));
        }
Exemplo n.º 29
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);
 }
Exemplo n.º 30
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.º 31
0
        public override AreaRegion GetRegion(IFormattingContext context, float x, float y, MathMLElement element, int index)
        {
            float yy = y + BoundingBox.Depth;

            foreach (Area a in content)
            {
                BoundingBox box = a.BoundingBox;
                yy -= box.Depth;
                AreaRegion r = a.GetRegion(context, x, yy, element, index);
                if (r != null)
                {
                    return(r);
                }
                yy -= box.Height;
            }

            return(null);
        }
Exemplo n.º 32
0
 public override AreaRegion GetRegion(IFormattingContext context, float x, float y, Area area, int index)
 {
     if (area == this || area == source)
     {
         return(new AreaRegion(this, x, y));
     }
     else
     {
         foreach (Area a in content)
         {
             AreaRegion r = a.GetRegion(context, x, y, area, index);
             if (r != null)
             {
                 return(r);
             }
             x += a.BoundingBox.HorizontalExtent;
         }
     }
     return(null);
 }
Exemplo n.º 33
0
    public override AreaRegion GetRegion(IFormattingContext context, float x, float y, MathMLElement element, int index)
		{
			if(element == this.element)
			{
				AreaRegion region = child.GetEditRegion(context, x, y, index);
				if(region != null)
				{
					region.Element = element;
				}
				else
				{
					Debug.WriteLine("MathMLWrapperArea: child.GetEditRegion returned null, returning new AreaRegion for this area");
					region = new AreaRegion(this, element, x, y);
				}
				return region;
			}
			else
			{
				return child.GetRegion(context, x, y, element, index);
			}
		}
Exemplo n.º 34
0
 public override AreaRegion GetRegion(IFormattingContext context, float x, float y, MathMLElement element, int index)
 {
     if (element == this.element)
     {
         AreaRegion region = child.GetEditRegion(context, x, y, index);
         if (region != null)
         {
             region.Element = element;
         }
         else
         {
             Debug.WriteLine("MathMLWrapperArea: child.GetEditRegion returned null, returning new AreaRegion for this area");
             region = new AreaRegion(this, element, x, y);
         }
         return(region);
     }
     else
     {
         return(child.GetRegion(context, x, y, element, index));
     }
 }
Exemplo n.º 35
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);
        }
Exemplo n.º 36
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);
        }
Exemplo n.º 37
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);
        }
Exemplo n.º 38
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;
		}
Exemplo n.º 39
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;
		}
Exemplo n.º 40
0
    public override AreaRegion GetEditRegion(IFormattingContext context, float x, float y, int index)
		{
			foreach(Area a in content)
			{
				AreaRegion r = a.GetEditRegion(context, x, y, index);
				if(r != null) return r;
				x += a.BoundingBox.HorizontalExtent;					
			}
			return null;
		}
Exemplo n.º 41
0
    public override AreaRegion GetRegion(IFormattingContext context, float x, float y, Area area, int index)
		{
			if(area == source)
			{
				return new AreaRegion(this, x, y);
			}
			else
			{
				return child.GetRegion(context, x, y, area, index);
			}
		}
Exemplo n.º 42
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);
		}
Exemplo n.º 43
0
    public override AreaRegion GetEditRegion(IFormattingContext context, float x, float y, int index)
		{
			return null;
		}
Exemplo n.º 44
0
		/// <summary>
		/// Get the child area's terminal node
		/// </summary>
    public override AreaRegion GetEditRegion(IFormattingContext context, float x, float y, int index)
		{
			return child.GetEditRegion (context, x, y, index);
		}
Exemplo n.º 45
0
		public static Area Glyph(IFormattingContext context, String fontName, 
			String altFontName, ushort index) 
		{ 
			IFontHandle font = context.GetFont(fontName, altFontName);
			return new GlyphArea(context, font, index);
		}
Exemplo n.º 46
0
    public override AreaRegion GetRegion(IFormattingContext context, float x, float y, Area area, int index)
		{
			if(area == this && index <= content.Length)
			{
				// measure horizontal position of char:
				BoundingBox horz = BoundingBox.New();
				float left, right;
				for(int i = 0; i < index; i++)
				{
					BoundingBox tmp = BoundingBox.New();
					context.MeasureGlyph(font, content[i], out tmp, out left, out right);
					horz.Append(tmp);
				}
                return new AreaRegion(this, x + horz.Width, y);
			}
			return null;
		}
Exemplo n.º 47
0
		public GlyphArea(IFormattingContext context, IFontHandle font, ushort index)
		{
			this.font = font;
			this.index = index;
			context.MeasureGlyph(font, index, out box, out leftEdge, out rightEdge);
		}
Exemplo n.º 48
0
    public override AreaRegion GetEditRegion(IFormattingContext context, float x, float y, int index)
		{
			x = index > 0 ? x + leftEdge + box.HorizontalExtent : x + leftEdge;
			return new AreaRegion(this, x, y);
		}
Exemplo n.º 49
0
    public override AreaRegion GetRegion(IFormattingContext context, float x, float y, Area area, int index)
		{
			if(area == this || area == source)
			{
				return new AreaRegion(this, x, y);
			}
			else
			{
				foreach(Area a in content)
				{
					AreaRegion r = a.GetRegion(context, x, y, area, index);
					if(r != null) return r;
					x += a.BoundingBox.HorizontalExtent;					
				}
			}
			return null;
		}
Exemplo n.º 50
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;
						}
					}
				}
			}
		}
Exemplo n.º 51
0
    public override AreaRegion GetRegion(IFormattingContext context, float x, float y, MathMLElement element, int index)
		{
			if(element == this.element)
			{
				return new AreaRegion(this, element, x + cellShift.X, y + cellShift.Y);
			}
			else
			{
				return child.GetRegion(context, x + areaShift.X, y + areaShift.Y, element, index);
			}
		}
Exemplo n.º 52
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;
		}
Exemplo n.º 53
0
    public override AreaRegion GetRegion(IFormattingContext context, float x, float y, MathMLElement element, int index)
		{
			return child.GetRegion (context, x, y, element, index);
		}
Exemplo n.º 54
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;
		}
Exemplo n.º 55
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;
		}
Exemplo n.º 56
0
    public static Area GetStretchyGlyph(IFormattingContext context, float pointSize, char c, BoundingBox desiredSize)
		{
			float lineThickness;
			return GetStretchyGlyph(context, pointSize, c, desiredSize, out lineThickness);
		}
Exemplo n.º 57
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;
		}
Exemplo n.º 58
0
		/**
		 * get a glyph area for this glyph.
		 * this searches through the glyphs list to see
		 * if an area has allready been created for the mathing
		 * set of glyph index and font, if none exists, a new 
		 * glyph area is created and cached via a weak reference.
		 */
    public Area GetArea(IFormattingContext context, IFontHandle fontHandle)
		{
			return new GlyphArea(context, fontHandle, GlyphIndex);
		}
Exemplo n.º 59
0
    public override AreaRegion GetRegion(IFormattingContext context, float x, float y, MathMLElement element, int index)
		{
			float yy = y + BoundingBox.Depth;
			foreach(Area a in content)
			{
				BoundingBox box = a.BoundingBox;
				yy -= box.Depth;
				AreaRegion r = a.GetRegion(context, x, yy, element, index);
				if(r != null) 
				{
					return r;
				}
				yy -= box.Height;
			}

			return null;
		}
Exemplo n.º 60
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});
		}