public override bool Compose(DrawContext dc, Style c, int availWidth, out ItemMetrics im, bool suppressWhitespace, out ITextLayout next) { TextItemMetrics metrics=new TextItemMetrics(this); im=metrics; this.style=c; next=null; // TODO: L: optimise Size sz=dc.Graphics.MeasureText(" "); spaceWidth=sz.Width; height=sz.Height; width=0; // get the font ascent ascent=c.FontAscent; if ( textNode.NodeType == XmlNodeType.SignificantWhitespace ) { // special case, simply set to single space width and return width=sz.Width; len=textNode.Value.Length; metrics.CanBreakBefore=true; metrics.CanBreakAfter=true; return true; } int startSpaceCount=GetStartSpaceCount(); if ( startSpaceCount > 0 && suppressWhitespace ) { TrimStart(startSpaceCount); startSpaceCount=0; } if ( startSpaceCount > 1 ) { TrimStart(startSpaceCount - 1); startSpaceCount=1; } len=startSpaceCount; if ( start+len == textNode.Value.Length ) { // this is pure whitespace width=sz.Width; return true; } metrics.CanBreakBefore=startSpaceCount > 0; bool hasMoreContent=true; bool firstWord=true; bool fit=false; int endSpaceCount=0; int finalWidth=startSpaceCount * spaceWidth; int splitLen=0; int splitWidth=0; bool needNewline=false; // bool newline=false; while ( hasMoreContent ) { int testLen; int tesc; hasMoreContent=IncludeNextWord(out testLen, out tesc); string segString=textNode.Value.Substring(start+len, testLen-len-tesc); string testString=ProcessText(segString); int segWidth=dc.Graphics.MeasureText(testString).Width; int testWidth=finalWidth+segWidth; // string testString=ProcessText(textNode.Value.Substring(start, testLen-tesc)); // int testWidth=dc.Graphics.MeasureText(testString).Width; fit=testWidth < availWidth; if ( fit || firstWord ) { // either it fits or it has to fit because this is the first word metrics.AddSegment(start+len, testLen-len, segWidth); splitLen=len; len=testLen; splitWidth=finalWidth; endSpaceCount=tesc; finalWidth=testWidth + (endSpaceCount > 0 ? spaceWidth : 0); if ( !fit && firstWord ) needNewline=true; if ( !fit || endSpaceCount > 1 ) break; } else break; firstWord=false; } // this is handled by custom class // if ( style.Pre && newline ) // bi.ForceBreakAfter=true; Debug.Assert(len > 0, "Must have laid out something!"); // at this point we have these possibilities: // everything fit - fit == true, nothing to do, return true // not everything fit - fit == false, get next, return false // and cannot split - oldLen=-1, return false // and can split - oldLen > 0, ConfigureSplitInfo, return true metrics.CanBreakAfter=endSpaceCount > 0; width=finalWidth; if ( splitLen > 0 ) { canSplit=true; splitIndex=splitLen; splitLeftWidth=splitWidth; splitRightWidth=finalWidth-splitWidth; } if ( start+len < textNode.Value.Length ) next=GetNextFragment(); if ( endSpaceCount > 1 ) { TrimEnd(endSpaceCount - 1); endSpaceCount=1; } return !needNewline; }
public TableRowGroupStyle(Style s) : base(s) { }
public TableRowStyle(Style s) : base(s) { }
internal Style GetStyle(IGraphics gr, Style parentStyle, XmlElement e, ElementType et) { Style ret=parentStyle == null ? blockStyle : parentStyle; bool foundMatch=false; foreach ( Style s in Styles ) { if ( s.IsMatch(e.CreateNavigator(), nsMgr) ) { ret=Cascade(gr, ret, s); foundMatch=true; } } bool emptyModel=et != null && et.ContentType == ElementContentType.Empty; if ( !foundMatch ) { // TODO: M: could optimise this perhaps XmlElement parent=e.ParentNode as XmlElement; if ( parent == null ) ret=Cascade(gr, ret, new BlockStyle()); else if ( HasText(parent) || emptyModel ) ret=Cascade(gr, ret, new InlineStyle()); else ret=Cascade(gr, ret, new BlockStyle()); } if ( e.HasChildNodes ) // if element has child nodes, it cannot be shown as empty ret.Empty=false; else if ( emptyModel ) // empty element in DTD so flag as such ret.Empty=true; return ret; }
public TableCellStyle(Style s) : base(s) { }
public override void Draw(DrawContext dc, int x, int y, int baseline, int height, Style c) { Debug.Assert(Height >= 0, "TextFragment is not composed!"); Rectangle rc=GetBoundingRect(x, y); rc.Height+=height-Height; if ( !dc.ClippingRectangle.IntersectsWith(rc) ) return; string text=ProcessText(Text); // .Replace('\r', ' ').Replace('\t', ' ').Replace('\n', ' '); int startIndex=0; int endIndex=0; Color bkCol=c.Stylesheet.HighlightColor; bool inError=dc.InvalidInfo.Contains(Node); dc.Graphics.PushFont(dc.Graphics.GetFontHandle(style.FontDesc)); // dc.Graphics.PushFont(style.FontHandle); try { if ( selection != null ) { SelectionPoint startSel=selection.Start; SelectionPoint endSel=selection.End; // by default everything selected endIndex=text.Length; if ( ContainsSelectionPoint(startSel) ) { TextSelectionPoint sel=(TextSelectionPoint) startSel; startIndex=sel.Index-start; if ( startIndex < 0 ) startIndex=0; } if ( ContainsSelectionPoint(endSel) ) { TextSelectionPoint sel=(TextSelectionPoint) endSel; endIndex=sel.Index-start; if ( endIndex < 0 ) endIndex=text.Length; } } int dx=dc.Graphics.MeasureText(text).Width; Rectangle rcText=new Rectangle(x, y, dx, height); DrawText(dc, rcText, baseline, text, bkCol, Color.White, startIndex, endIndex); if ( inError ) { DrawErrorIndicator(dc, x, x, dx, y+baseline, false); } } finally { dc.Graphics.PopFont(); } }
public override void Draw(DrawContext dc, int x, int y, int baseline, int height, Style s) { dc.Graphics.DrawBitmap(bitmap, dc.Origin.X+x, dc.Origin.Y+y, selection != null); }
public InlineStyle(Style s) : base(s) { }
protected Style(Style s) { this.desc=new FontDesc(s.desc); this.Margin=new Box(s.Margin); this.Padding=new Box(s.Padding); this.Empty=s.Empty; this.Pre=s.Pre; }
public CustomStyle(Style s) : base(s) { CustomStyle other=s as CustomStyle; if ( other == null ) return; foreach ( CustomProperty p in other.Properties ) Properties.Add(new CustomProperty(p)); this.Class=other.Class; }
public ImageStyle(Style s) : base(s) { }
public BlockStyle(Style s) : base(s) { }
public TableStyle(Style s) : base(s) { }
public Image(IContainer parent, XmlElement e, Style s) : base(parent, e, s) { }
public abstract bool Compose(DrawContext dc, Style c, int width, out ItemMetrics bi, bool suppressWhitespace, out ITextLayout next);
public void Cascade(Style baseStyle) { Padding.Cascade(baseStyle.Padding); Margin.Cascade(baseStyle.Margin); FontDesc.Cascade(baseStyle.FontDesc); }
public override int Compose(DrawContext dc, Style c, out ItemMetrics bi) { // TODO: L: this is never called - refactor virtual methods // this is the default Compose which assumes that the text // has been fragmented so we just need to layout what we have Debug.Assert(Width >= 0, "TextFragment not composed"); // must have already been composed bi=new ItemMetrics(this); return Width; }
public Style Cascade(IGraphics gr, Style parentStyle, Style changes) { Style ret; ret=changes.Clone(); if ( parentStyle != null ) ret.Cascade(parentStyle); ret.Bind(gr, this); return ret; }
public override bool Compose(DrawContext dc, Style c, int width, out ItemMetrics bi, bool suppressWhitespace, out ITextLayout next) { this.style=c; bi=new ItemMetrics(this); next=null; // idea here is just to scan for next line break // TODO: M: may need to deal with double spaces, tabs, etc string text=Text; int ptr=text.IndexOf('\n'); int measureLen=len; if ( ptr >= 0 ) { bi.ForceBreakAfter=true; len=ptr+1; measureLen=len-1; if ( len < text.Length ) next=GetNextFragment(); } if ( measureLen > 0 && Text[measureLen-1]=='\r' ) measureLen--; Size sz=dc.Graphics.MeasureText(Text.Substring(0, measureLen)); height=dc.Graphics.GetFontHeight(); this.width=sz.Width; ascent=c.FontAscent; return true; }
public override int Compose(DrawContext dc, Style c, out ItemMetrics bi) { width=bitmap.Width; height=bitmap.Height; ascent=bitmap.Height/2; bi=new ItemMetrics(this); return Width; }