/// <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()); } }
public AreaRegion(Area area, MathMLElement element, float x, float y) { this.Area = area; this.Element = element; this.X = x; this.Y = y; }
public AreaRegion(Area area, MathMLElement element, float x, float y) { this.Area = area; this.Element = element; this.X = x; this.Y = y; }
public Element CreateElementNS(String namespaceURI, String tagName) { Element element = null; if (namespaceURI == Namespaces.Html) { element = HTMLElement.Factory(tagName); } else if (namespaceURI == Namespaces.Svg) { element = SVGElement.Create(tagName); } else if (namespaceURI == Namespaces.MathML) { element = MathMLElement.Create(tagName); } else if (namespaceURI == Namespaces.Xml) { element = XMLElement.Create(tagName); } else { element = new Element { NamespaceURI = namespaceURI, NodeName = tagName } }; element.OwnerDocument = this; return(element); }
/// <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(); } }
/** * 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; }
/** * 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; }
object MathML.MathMLVisitor.Visit(MathMLRadicalElement e, object args) { switch (selection) { case SelectionType.Prev: { if (args == e.Radicand && e.Index != null) { selection = SelectionType.End; return(e.Index.Accept(this, null)); } else { MathMLElement p = e.ParentNode as MathMLElement; return(p != null?p.Accept(this, e) : null); } } case SelectionType.Next: { if (args == e) { index = 0; selection = SelectionType.Start; MathMLElement start = e.Index != null ? e.Index : e.Radicand; return(start != null?start.Accept(this, null) : null); } if (args == e.Index) { MathMLElement next = e.Radicand; selection = SelectionType.Start; return(next != null?next.Accept(this, null) : null); } else { MathMLElement p = e.ParentNode as MathMLElement; return(p != null?p.Accept(this, e) : null); } } case SelectionType.End: { MathMLElement end = e.Radicand != null ? e.Radicand : e.Index; return(end != null?end.Accept(this, null) : null); } case SelectionType.Start: { return(e); } default: { return(null); } } }
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); }
object MathML.MathMLVisitor.Visit(MathMLPresentationContainer e, object args) { MathMLElement c = (MathMLElement)args; MathMLElement elm = null; switch (selection) { case SelectionType.Prev: { if ((elm = PreviousMathSibling(c)) != null) { selection = SelectionType.End; return(elm.Accept(this, null)); } else { MathMLElement p = e.ParentNode as MathMLElement; return(p != null?p.Accept(this, e) : null); } } case SelectionType.Next: { if (e == c && (elm = e.FirstChild as MathMLElement) != null) { return(elm.Accept(this, e)); } else if ((elm = NextMathSibling(c)) != null) { selection = SelectionType.Start; return(elm.Accept(this, null)); } else { MathMLElement p = e.ParentNode as MathMLElement; return(p != null?p.Accept(this, e) : null); } } case SelectionType.Start: { elm = e.FirstChild as MathMLElement; return(elm != null?elm.Accept(this, null) : e); } case SelectionType.End: { elm = e.LastChild as MathMLElement; return(elm != null?elm.Accept(this, null) : null); } default: { return(null); } } }
private static MathMLElement PreviousMathSibling(MathMLElement e) { XmlNode s = e.PreviousSibling; while (s != null && !(s is MathMLElement)) { s = s.PreviousSibling; } return(s as MathMLElement); }
private static MathMLElement NextMathSibling(MathMLElement e) { XmlNode s = e.NextSibling; while (s != null && !(s is MathMLElement)) { s = s.NextSibling; } return(s as MathMLElement); }
object MathML.MathMLVisitor.Visit(MathMLFractionElement e, object args) { switch (selection) { case SelectionType.Prev: { if (args == e.Denominator && e.Numerator != null) { selection = SelectionType.End; return(e.Numerator.Accept(this, null)); } else { MathMLElement p = e.ParentNode as MathMLElement; return(p != null?p.Accept(this, e) : null); } } case SelectionType.Next: { if (args == e) { index = 0; selection = SelectionType.Start; return(e.Numerator != null?e.Numerator.Accept(this, e) : null); } else if (args == e.Numerator && e.Denominator != null) { selection = SelectionType.Start; return(e.Denominator.Accept(this, null)); } else { MathMLElement p = e.ParentNode as MathMLElement; return(p != null?p.Accept(this, e) : null); } } case SelectionType.End: { return(e.Denominator != null?e.Denominator.Accept(this, null) : null); } case SelectionType.Start: { return(e); } default: { return(null); } } }
/// <summary> /// does the node have any child nodes that are mathml elements? /// </summary> private static bool HasMathChildNodes(MathMLElement e) { foreach (XmlNode n in e.ChildNodes) { if (n is MathMLElement) { return(true); } } return(false); }
object MathML.MathMLVisitor.Visit(MathMLActionElement e, object args) { if (selection == SelectionType.Prev || selection == SelectionType.Next) { return(((MathMLElement)e.ParentNode).Accept(this, e)); } else { MathMLElement elm = e.FirstChild as MathMLElement; return(elm != null?elm.Accept(this, args) : e); } }
object MathML.MathMLVisitor.Visit(MathMLMathElement e, object args) { MathMLElement c = (MathMLElement)args; MathMLElement n = null; switch (selection) { case SelectionType.Prev: { if ((n = PreviousMathSibling(c)) != null) { return(n); } else { selection = SelectionType.Start; return(c.Accept(this, null)); } } case SelectionType.Next: { if ((n = NextMathSibling(c)) != null) { selection = SelectionType.Start; index = 0; return(n.Accept(this, null)); } else { selection = SelectionType.End; return(c.Accept(this, null)); } } case SelectionType.Start: { n = e.FirstChild as MathMLElement; return(n != null?n.Accept(this, null) : null); } case SelectionType.End: { n = e.LastChild as MathMLElement; return(n != null?n.Accept(this, null) : null); } default: { return(null); } } }
object MathML.MathMLVisitor.Visit(MathMLScriptElement e, object args) { MathMLElement c = (MathMLElement)args; switch (selection) { case SelectionType.Prev: { if (c == e.SubScript || c == e.SuperScript) { selection = SelectionType.End; return(e.Base.Accept(this, e)); } else { MathMLElement p = e.ParentNode as MathMLElement; return(p != null?p.Accept(this, e) : null); } } case SelectionType.Next: { if (c == e.Base) { MathMLElement next = e.SuperScript != null ? e.SuperScript : e.SubScript; selection = SelectionType.Start; return(next != null?next.Accept(this, null) : null); } else { MathMLElement p = e.ParentNode as MathMLElement; return(p != null?p.Accept(this, e) : null); } } case SelectionType.End: { MathMLElement end = e.SuperScript != null ? e.SuperScript : (e.SubScript != null ? e.SubScript : e.Base); return(end.Accept(this, null)); } case SelectionType.Start: { return(e.Base.Accept(this, null)); } default: { return(null); } } }
private static MathMLElement LastMathChild(MathMLElement e) { XmlNodeList list = e.ChildNodes; for (int i = list.Count - 1; i >= 0; i--) { MathMLElement n = list.Item(i) as MathMLElement; if (n != null) { return(n); } } return(null); }
/// <summary> /// get an mathml element with the given relationship to the current element /// </summary> public Selection GetPrevSelection(MathMLElement element, int i) { Selection result = null; selection = SelectionType.Prev; index = i; MathMLElement e = (MathMLElement)element.Accept(this, element); if (e != null) { result = new Selection(); result.Element = e; result.CharIndex = index; } return(result); }
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); } }
public override AreaRegion GetRegion(IFormattingContext context, float x, float y, MathMLElement element, int index) { AreaRegion result = null; if(this.element == element) { return new AreaRegion(this, element, x, y); } else { foreach(Area a in content) { result = a.GetRegion(context, x, y - box.Height, element, index); if(result != null) { Debug.Assert(result.Element != null, "Invalid element type for TableArea cell area"); Debug.Assert(result.Area != null, "Invalid area type for TableArea cell area"); return result; } } } return null; }
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)); } }
public MathMLWrapperArea(Area area, MathMLElement element) : base(area) { this.element = element; }
public override AreaRegion GetRegion(IFormattingContext context, float x, float y, MathMLElement element, int index) { return(child.GetRegion(context, x, y, element, index)); }
public VerticalCompoundGlyph(MathMLElement e, Area[] areas, int baseline) : base(areas, baseline) { }
public override AreaRegion GetRegion(IFormattingContext context, float x, float y, MathMLElement element, int index) { return child.GetRegion (context, x, y, element, index); }
object MathML.MathMLVisitor.Visit(MathMLPresentationContainer e, object args) { IFormattingContext context = ((IFormattingContext)args).Clone(); MathMLNodeList arguments = e.Arguments; BoundingBox extent = BoundingBox.New(); int stretchCount = 0; // save the stretch size because stretch scope can not extend into another // level of nesting BoundingBox stretch = context.Stretch; context.Stretch = BoundingBox.New(); // process all nodes that are not stretchy operators, get thier total // extents for (int i = 0; i < arguments.Count; i++) { MathMLElement element = (MathMLElement)arguments[i]; MathMLOperatorElement op = element as MathMLOperatorElement; if (op == null || op.Stretchy == false) { //areas[i] = (Area)element.Accept(this, context); extent.Append((BoundingBox)element.Accept(this, context)); } if (op != null && op.Stretchy) { stretchCount++; } } // if we have any elements that can be stretched, stretch them if (stretchCount > 0) { if (!stretch.Defined) { // avail width is epsilon because stretchy glyphs were not counted in the // width calculation context.Stretch = BoundingBox.New(Single.Epsilon, extent.Height, extent.Depth); } else { // set the stretch size back to stretch the child elements context.Stretch = stretch; // calculate availible width context.StretchWidth = context.StretchWidth - extent.Width; if (context.Stretch.Width < 0) { context.StretchWidth = 0; } // size to stretch each width equally context.StretchWidth = context.Stretch.Width / (float)stretchCount; } // process all areas that need to be stretched for (int i = 0; i < arguments.Count; i++) { MathMLOperatorElement op = arguments[i] as MathMLOperatorElement; if (op != null && op.Stretchy) { //areas[i] = (Area)op.Accept(this, context); extent.Append((BoundingBox)op.Accept(this, context)); } } } return(extent); }
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; }
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); }
/** * get an area from a MathMLElement into which a area * was previously set by SetArea */ public static Area GetArea(MathMLElement element) { return(element.GetUserData(areaGuid) as Area); }
public MathMLWrapperArea(Area area, MathMLElement element) : base(area) { this.element = element; }
public override AreaRegion GetRegion(IFormattingContext context, float x, float y, MathMLElement element, int index) { AreaRegion result = null; if (this.element == element) { return(new AreaRegion(this, element, x, y)); } else { foreach (Area a in content) { result = a.GetRegion(context, x, y - box.Height, element, index); if (result != null) { Debug.Assert(result.Element != null, "Invalid element type for TableArea cell area"); Debug.Assert(result.Area != null, "Invalid area type for TableArea cell area"); return(result); } } } return(null); }
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); } }
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)); } }
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; }
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; }
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; }
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); } } return(null); }
public virtual AreaRegion GetRegion(IFormattingContext context, float x, float y, MathMLElement element, int index) { return(null); }
object MathML.MathMLVisitor.Visit(MathMLPresentationToken e, object args) { MathMLElement p = null; switch (selection) { case SelectionType.Prev: { if (index > 1) { index--; return(e); } else if (index == 1) { if ((e.ParentNode is MathMLPresentationContainer && !(PreviousMathSibling(e) is MathMLPresentationToken)) || (!(e.ParentNode is MathMLPresentationContainer))) { index--; return(e); } else { return(((MathMLElement)e.ParentNode).Accept(this, e)); } } else if (e.ParentNode is MathMLPresentationContainer && (p = PreviousMathSibling(e) as MathMLPresentationToken) != null) { selection = SelectionType.End; return(p.Accept(this, null)); } else { return(((MathMLElement)e.ParentNode).Accept(this, e)); } } case SelectionType.Next: { if (e.ChildNodes.Count == 1 && e.FirstChild.NodeType == XmlNodeType.Text && index < e.FirstChild.Value.Length) { index++; return(e); } else if ((e.ParentNode is MathMLPresentationContainer || e.ParentNode is MathMLMathElement) && (p = NextMathSibling(e) as MathMLPresentationToken) != null) { selection = SelectionType.Start; index = 0; return(p.Accept(this, null)); } else { return(((MathMLElement)e.ParentNode).Accept(this, e)); } } case SelectionType.End: { index = e.FirstChild.Value.Length; return(e); } case SelectionType.Start: default: { if (((e.ParentNode is MathMLPresentationContainer || e.ParentNode is MathMLMathElement) && !(PreviousMathSibling(e) is MathMLPresentationToken)) || (!(e.ParentNode is MathMLPresentationContainer || e.ParentNode is MathMLMathElement))) { index = 0; } else { index = 1; } return(e); } } }
/** * set an area into a MathMLElement. The area can be later returned * by GetArea. * @return the area that is set into the element */ public static Area SetArea(MathMLElement element, Area area) { element.SetUserData(areaGuid, area, null); return(area); }
public VerticalCompoundGlyph(MathMLElement e, Area[] areas, int baseline) : base(areas, baseline) { }