internal DomParagraphElement CreateMergedParagrahp(bool includeSelectionOnly) { DomParagraphElement p = new DomParagraphElement(); p.OwnerDocument = this.OwnerDocument; p.StyleIndex = this.StyleIndex; DomStringElement myStr = new DomStringElement(); myStr.OwnerDocument = this.OwnerDocument; //p.Elements.AddRaw( myStr ); foreach (DomElement element in this.Elements) { if (includeSelectionOnly) { if (this.OwnerDocument.IsSelected(element) == false) { continue; } } if (element is DomCharElement) { DomCharElement c = (DomCharElement)element; if (myStr.CanMerge(c)) { myStr.Merge(c); } else { if (myStr.HasContent) { p.Elements.AddRaw(myStr); myStr = new DomStringElement(); } myStr.OwnerDocument = this.OwnerDocument; myStr.Merge(c); } } else { if (myStr.HasContent) { p.Elements.AddRaw(myStr); myStr = new DomStringElement(); } if (!(element is DomParagraphFlagElement)) { p.Elements.AddRaw(element); } } } if (myStr.HasContent) { p.Elements.AddRaw(myStr); } if (p.Elements.EOFElement != null) { p.Elements.EOFElement = null; } return(p); }
/// <summary> /// 合并一个字符元素对象 /// </summary> /// <param name="c">字符元素对象</param> internal void Merge(DomCharElement c) { if (myText.Length == 0) { this.StyleIndex = c.StyleIndex; } this.OwnerDocument = c.OwnerDocument; myText.Append(c.ToString()); this.Elements.AddRaw(c); }
/// <summary> /// 判断对象能否合并一个字符元素对象 /// </summary> /// <param name="c">字符元素对象</param> /// <returns>能否合并</returns> internal bool CanMerge(DomCharElement c) { if (c != null) { if (myText.Length == 0) { return(true); } return(this.StyleIndex == c.StyleIndex); } return(false); }
/// <summary> /// 将对象拆分成若干个字符元素对象 /// </summary> /// <returns>拆分所得的字符元素对象列表</returns> internal DomElementList SplitChars() { DomElementList list = new DomElementList(); string txt = myText.ToString(); foreach (char c in txt) { DomCharElement NewChar = this.OwnerDocument.CreateChar(c, this.StyleIndex); if (NewChar != null) { NewChar.StyleIndex = this.StyleIndex; NewChar.Parent = this.Parent; list.Add(NewChar); } } return(list); }
/// <summary> /// 刷新状态 /// </summary> /// <returns>操作是否成功</returns> public bool RefreshState() { if (this.Count == 0) { return(false); } DocumentControler controler = null; foreach (DomElement element in this) { if (element.OwnerDocument != null) { controler = element.OwnerDocument.DocumentControler; break; } } //XTextParagraphFlagElement pe = this.LastElement as XTextParagraphFlagElement ; //if( pe != null ) //{ // pe.RefreshSize2( this.SafeGet( this.Count - 2 )); //} DomLineBreakElement lb = this.LastElement as DomLineBreakElement; if (lb != null) { lb.RefreshSize2(this.SafeGet(this.Count - 2)); } // if( this.Count == 1 ) // { // XTextElement element = this[ 0 ]; // this.intHeight = element.Height + LineHeighFix + this.LineSpacing ; // element.Left = this.intMargin ; // element.Top = 0 ; // return true ; // } this._ContentHeight = -1; float contentWidth = 0; float lineHeight = 10; foreach (DomElement element in this) { contentWidth = contentWidth + this.Spacing + element.Width; element.WidthFix = 0; float eh = element.Height; //if (element is XTextCharElement) //{ // XTextCharElement chr = (XTextCharElement)element; // eh = Math.Max(eh, chr._FontHeight); //} if (eh > lineHeight) { lineHeight = eh; } element.OwnerLine = this; }//foreach contentWidth -= this.Spacing; this.Height = ( float )Math.Ceiling(lineHeight + LineHeighFix); // if( EOF != null ) // EOF.Height = this.intHeight ; bool CanFix = true; if (this.Count == 1) { CanFix = false; } else { if (this.HasLineEndElement)// this.OwnerDocument.IsNewLine( this.LastElement ) || this.LastElement is XTextEOF ) { CanFix = false; } else if (this.OwnerContentElement.PrivateLines.LastLine == this) { CanFix = false; } } DocumentContentAlignment align = this.Align; // 元素空白平均修正量 float fix = 0; // 总空白量 float Blank = this.Width - this.PaddingLeft - contentWidth; if (Blank < 0) { return(false); } if (CanFix) { // 计算由于元素分组而损失的空白区域个数 // 文档中连续的英文和数字字符之间没有修正空白,制表符和书签也拒绝修正空白 // 由于存在拒绝修正空白,导致空白分摊的元素减少,此处就修正这种空白分摊元素 // 减少而带来的影响 int GroupFix = 0; for (int iCount = 0; iCount < this.Count; iCount++) { DomCharElement c = this[iCount] as DomCharElement; if (c != null) { if (c.CharValue == '\t') { GroupFix++; } else if (iCount < this.Count - 1) { if (controler.IsEnglishLetterOrDigit(c.CharValue)) { DomCharElement c2 = this[iCount + 1] as DomCharElement; if (c2 != null && controler.IsEnglishLetterOrDigit(c2.CharValue)) { GroupFix++; } } } } } if (GroupFix > this.Count - 2) { GroupFix = 0; } if (this.Count > 1) { fix = (int)Math.Ceiling(Blank / (this.Count - 1.0 - GroupFix)); } if (fix < 0) { fix = 0; } align = DocumentContentAlignment.Justify; } else { fix = 0; } float leftCount = 0; if (align == DocumentContentAlignment.Left) { leftCount = this.PaddingLeft; } else if (align == DocumentContentAlignment.Center) { leftCount = this.PaddingLeft + (this.Width - this.PaddingLeft - contentWidth) / 2; } else if (align == DocumentContentAlignment.Right) { leftCount = this.PaddingLeft + (this.Width - this.PaddingLeft - contentWidth); } else { leftCount = this.PaddingLeft; } //foreach( XTextElement element in this ) for (int iCount = 0; iCount < this.Count; iCount++) { DomElement element = this[iCount]; element.Left = leftCount; float ctf = ContentTopFix; //if (this.AdditionHeight < 0) //{ // ctf = ctf + this.AdditionHeight; //} switch (this.VerticalAlign) { case VerticalAlignStyle.Top: element.Top = ContentTopFix; break; case VerticalAlignStyle.Middle: element.Top = ContentTopFix + (lineHeight - element.Height) / 2.0f; break; case VerticalAlignStyle.Bottom: element.Top = ctf + lineHeight - element.Height; break; case VerticalAlignStyle.Justify: element.Top = ContentTopFix + (lineHeight - element.Height) / 2.0f; break; default: element.Top = ctf + lineHeight - element.Height; break; }//switch //bool IsTab = false ; bool FixFlag = true; // TAB制表符不接收修正空隙 if (element is DomCharElement) { DomCharElement c = ( DomCharElement )element; if (c.CharValue == '\t') { FixFlag = false; } else if (iCount < this.Count - 1) { if (controler.IsEnglishLetterOrDigit(c.CharValue)) { DomCharElement c2 = this[iCount + 1] as DomCharElement; if (c2 != null && controler.IsEnglishLetterOrDigit(c2.CharValue)) { FixFlag = false; } } } } // // 出现拒绝修正情况,重新计算平均修正空隙 // if( CanFix && FixFlag == false ) // { // if( iCount < this.Count - 2 ) // { // Blank = ( this.intWidth - LeftCount - element.Width ) ; // for( int iCount2 = iCount + 1 ; iCount2 < this.Count ; iCount2 ++ ) // { // Blank -= this[ iCount ].Width ; // } // if( Blank > 0 ) // { // fix = Blank / ( this.Count - iCount - 1.0 ); // } // else // fix = 0 ; // } // } // else if( element is XTextNull ) // { // // 若元素是没有实际意义的占位符合则不接收修正空隙 // FixFlag = false; // } if (CanFix && FixFlag) { if (Blank < fix) { fix = Blank; } element.WidthFix = fix + _Spacing; Blank -= fix; if (Blank <= 0) { fix = 0; Blank = 0; } } else { element.WidthFix = _Spacing; } leftCount = leftCount + element.Width + element.WidthFix; } //this.Height += this.LineSpacing ; return(true); }
/// <summary> /// 绘制对象 /// </summary> /// <param name="g">图形绘制对象</param> /// <param name="ClipRectangle">剪切矩形</param> protected virtual void DrawContent(DomCharElement chr, DocumentPaintEventArgs args) { DocumentContentStyle rs = chr.RuntimeStyle; System.Drawing.RectangleF rect = chr.AbsBounds; rect.Height = rect.Height * 1.5f; rect.Width = rect.Width * 1.5f; //if (chr.OwnerLine.AdditionHeight < 0) { rect.Height = Math.Max( rect.Height, chr.OwnerLine.Height + chr.OwnerLine.AdditionHeight); } //rect.Height = Math.Min(rect.Height, chr.OwnerLine.Height); Color cc = rs.Color; if (args.RenderStyle == DocumentRenderStyle.Paint) { HighlightInfo info = this.Document.HighlightManager[chr]; if (info != null && info.Color.A != 0) { // 设置高亮度文本值 cc = info.Color; } } SolidBrush b = GraphicsObjectBuffer.GetSolidBrush(cc); XFontValue font = rs.Font.Clone(); if (rs.Subscript || rs.Superscript) { font.Size = font.Size * 0.6f; if (rs.Superscript) { args.Graphics.DrawString(chr.CharValue.ToString(), font.Value, b, rect.Left, rect.Top, myMeasureFormat); } else { args.Graphics.DrawString(chr.CharValue.ToString(), font.Value, b, rect.Left, (int)Math.Floor(rect.Top + (rect.Height * 0.4)), myMeasureFormat); } } else { if ((rs.Underline || rs.Strikeout) && chr.CharValue == ' ') { // .NET框架存在一个BUG,不能为空格绘制下划线和删除线,因此在此进行替换绘制成不带下划线的下划线字母。 XFontValue font2 = rs.Font.Clone(); if (font2.Underline) { font2.Underline = false; args.Graphics.DrawString( "_", font2.Value, b, rect.Left, rect.Top, myMeasureFormat); } else { font2.Strikeout = false; args.Graphics.DrawString( "-", font2.Value, b, rect.Left, rect.Top, myMeasureFormat); } } else { //InnerFormat.FormatFlags = InnerFormat.FormatFlags | StringFormatFlags.MeasureTrailingSpaces; //InnerFormat.FormatFlags = StringFormatFlags.FitBlackBox | StringFormatFlags.MeasureTrailingSpaces ; args.Graphics.DrawString( chr.CharValue.ToString(), rs.Font.Value, b, rect, myMeasureFormat); } } //if ( font.Underline ) //{ // float fh = font.GetHeight(args.Graphics); // Pen p = SolidBrushBuffer.GetPen(cc); // args.Graphics.DrawLine( // p, // rect.Left , // rect.Top + fh , // rect.Right + chr.WidthFix, // rect.Top + fh ); //} }
/// <summary> /// 重新计算对象大小 /// </summary> /// <param name="g">图形绘制对象</param> protected virtual void RefreshSize(DomCharElement chr, System.Drawing.Graphics g) { DocumentViewOptions opt = this.Document.Options.ViewOptions; if (myMeasureFormat == null) { myMeasureFormat = new System.Drawing.StringFormat( System.Drawing.StringFormat.GenericTypographic); myMeasureFormat.FormatFlags = System.Drawing.StringFormatFlags.FitBlackBox | System.Drawing.StringFormatFlags.MeasureTrailingSpaces | StringFormatFlags.NoClip; } DomDocument document = chr.OwnerDocument; if (_EnableCharSizeBuffer) { if (chr.CharValue != '\t') { if (charSizes != null) { if (charSizes.ContainsKey(chr.StyleIndex)) { Dictionary <char, SizeF> sizes = charSizes[chr.StyleIndex]; if (sizes.ContainsKey(chr.CharValue)) { // 从缓存区中获得字母大小 SizeF bsize = sizes[chr.CharValue]; chr.Width = bsize.Width; chr.Height = bsize.Height; chr._FontHeight = chr.RuntimeStyle.Font.GetHeight(g); return; } } } } //if } //if DocumentContentStyle rs = chr.RuntimeStyle; System.Drawing.SizeF size = System.Drawing.SizeF.Empty; g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SingleBitPerPixel; //this.UseGDIFontSize = true; if (opt.RichTextBoxCompatibility) { // 使用GDI模式计算字符大小 string key = rs.FontName + "|" + rs.FontSize + "|" + rs.FontStyle; GDIFont font = null; if (gdiFonts.ContainsKey(key)) { font = gdiFonts[key]; } else { font = new GDIFont( rs.FontName, //(int)( rs.FontSize * 1.3837 * 3 ), (int)(GraphicsUnitConvert.Convert( rs.FontSize, GraphicsUnit.Point, GraphicsUnit.Document)), rs.Bold, rs.Italic, rs.Underline, rs.Strikeout); gdiFonts[key] = font; } Size[] sizes = font.MeasureCharactersSize(g, chr.CharValue.ToString()); size.Width = sizes[0].Width; size.Height = sizes[0].Height; if (chr.CharValue == ' ') { if (rs.FontName == "Times New Roman") { size.Width = size.Width * 1.28f; } } } else { if (chr.CharValue == ' ') { size = g.MeasureString( " ", rs.Font.Value, 10000, System.Drawing.StringFormat.GenericDefault); size.Width = size.Width * 0.57f; } else if (chr.CharValue == '\t') { } else { size = g.MeasureString( chr.CharValue.ToString(), rs.Font.Value, 10000, myMeasureFormat); size.Width = size.Width; } } chr.Width = size.Width; chr.Height = size.Height + 1; chr._FontHeight = rs.Font.GetHeight(g); chr.Height = chr._FontHeight;// size.Height; if (rs.Superscript) { chr.Height = chr.Height * 1.2f; } if (rs.Superscript || rs.Subscript) { chr.Width = chr.Width * 0.6f; } if (_EnableCharSizeBuffer) { if (charSizes != null) { Dictionary <char, SizeF> sizes2 = null; if (charSizes.ContainsKey(chr.StyleIndex)) { sizes2 = charSizes[chr.StyleIndex]; } else { sizes2 = new Dictionary <char, SizeF>(); charSizes[chr.StyleIndex] = sizes2; } sizes2[chr.CharValue] = new SizeF(chr.Width, chr.Height); } } }