427 lines
12 KiB
C#
427 lines
12 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.Text;
|
|
using CPF.Drawing;
|
|
using CPF.ReoGrid.Common;
|
|
using CPF.ReoGrid.Drawing.Text;
|
|
using CPF.ReoGrid.Graphics;
|
|
|
|
namespace CPF.ReoGrid.Drawing
|
|
{
|
|
public sealed class RichText
|
|
{
|
|
public void SuspendUpdateText()
|
|
{
|
|
this.suspendUpdateText = true;
|
|
}
|
|
|
|
public void ResumeUpdateText()
|
|
{
|
|
this.suspendUpdateText = false;
|
|
}
|
|
|
|
internal Size Size
|
|
{
|
|
get
|
|
{
|
|
return this.size;
|
|
}
|
|
set
|
|
{
|
|
bool flag = this.size != value;
|
|
if (flag)
|
|
{
|
|
this.size = value;
|
|
bool flag2 = !this.suspendUpdateText;
|
|
if (flag2)
|
|
{
|
|
this.UpdateText();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public Size TextSize
|
|
{
|
|
get
|
|
{
|
|
return this.measuredSize;
|
|
}
|
|
}
|
|
|
|
public string DefaultFontName { get; set; }
|
|
|
|
public float DefaultFontSize { get; set; }
|
|
|
|
public CPF.ReoGrid.Drawing.Text.FontStyles DefaultFontStyles { get; set; }
|
|
|
|
public Color DefaultBackColor { get; set; }
|
|
|
|
public Color DefaultTextColor { get; set; }
|
|
|
|
public float DefaultLineHeight { get; set; }
|
|
|
|
public ReoGridHorAlign DefaultHorizontalAlignment { get; set; }
|
|
|
|
public bool Overflow { get; set; }
|
|
|
|
public TextWrapMode TextWrap
|
|
{
|
|
get
|
|
{
|
|
return this.textWrap;
|
|
}
|
|
set
|
|
{
|
|
bool flag = this.textWrap != value;
|
|
if (flag)
|
|
{
|
|
this.textWrap = value;
|
|
bool flag2 = !this.suspendUpdateText;
|
|
if (flag2)
|
|
{
|
|
this.UpdateText();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public ReoGridVerAlign VerticalAlignment { get; set; }
|
|
|
|
public float DefaultParagraphSpacing { get; set; }
|
|
|
|
internal float RotationAngle { get; set; }
|
|
|
|
public RichText()
|
|
{
|
|
float num = 0f;
|
|
float num2 = 0f;
|
|
this.measuredSize = new Size(ref num, ref num2);
|
|
this.textWrap = TextWrapMode.NoWrap;
|
|
this.paragraphs = new List<Paragraph>();
|
|
this.textBuffer = string.Empty;
|
|
this.sbDirty = true;
|
|
this.sb = null;
|
|
this.DefaultFontName = "Calibri";
|
|
this.DefaultFontSize = 10.25f;
|
|
this.DefaultFontStyles = CPF.ReoGrid.Drawing.Text.FontStyles.Regular;
|
|
this.DefaultTextColor = Color.Black;
|
|
this.DefaultBackColor = Color.Transparent;
|
|
this.DefaultLineHeight = 1.2f;
|
|
this.DefaultHorizontalAlignment = ReoGridHorAlign.Left;
|
|
this.DefaultParagraphSpacing = 1.5f;
|
|
this.Overflow = false;
|
|
}
|
|
|
|
internal RichText(Size size)
|
|
{
|
|
float num = 0f;
|
|
float num2 = 0f;
|
|
this.measuredSize = new Size(ref num, ref num2);
|
|
this.textWrap = TextWrapMode.NoWrap;
|
|
this.paragraphs = new List<Paragraph>();
|
|
this.textBuffer = string.Empty;
|
|
this.sbDirty = true;
|
|
this.sb = null;
|
|
this.size = size;
|
|
}
|
|
|
|
internal IEnumerable<Paragraph> Paragraphcs
|
|
{
|
|
get
|
|
{
|
|
return this.paragraphs;
|
|
}
|
|
}
|
|
|
|
internal void AddParagraph(Paragraph p = null)
|
|
{
|
|
bool flag = p == null;
|
|
if (flag)
|
|
{
|
|
p = new Paragraph(this, null);
|
|
}
|
|
this.paragraphs.Add(p);
|
|
}
|
|
|
|
public void AddText(string text, string fontName = null, float? fontSize = null, CPF.ReoGrid.Drawing.Text.FontStyles? fontStyles = null, Color? textColor = null, Color? backColor = null)
|
|
{
|
|
Paragraph orCreateLastParagraph = this.GetOrCreateLastParagraph();
|
|
orCreateLastParagraph.AddText(text, fontName, fontSize, fontStyles, textColor, backColor);
|
|
}
|
|
|
|
public RichText NewLine()
|
|
{
|
|
Paragraph p = new Paragraph(this, null);
|
|
this.AddParagraph(p);
|
|
return this;
|
|
}
|
|
|
|
public RichText Span(string text, string fontName = null, float? fontSize = null, CPF.ReoGrid.Drawing.Text.FontStyles? fontStyles = null, Color? textColor = null, Color? backColor = null)
|
|
{
|
|
this.AddText(text, fontName, fontSize, fontStyles, textColor, backColor);
|
|
return this;
|
|
}
|
|
|
|
public RichText Bold(string text, string fontName = null, float? fontSize = null, Color? textColor = null, Color? backColor = null)
|
|
{
|
|
Run orCreateLastRun = this.GetOrCreateLastParagraph().GetOrCreateLastRun(fontName, fontSize, new CPF.ReoGrid.Drawing.Text.FontStyles?(CPF.ReoGrid.Drawing.Text.FontStyles.Bold), textColor, backColor);
|
|
orCreateLastRun.AppendText(text);
|
|
return this;
|
|
}
|
|
|
|
public RichText Italic(string text, string fontName = null, float? fontSize = null, Color? textColor = null, Color? backColor = null)
|
|
{
|
|
Run orCreateLastRun = this.GetOrCreateLastParagraph().GetOrCreateLastRun(fontName, fontSize, new CPF.ReoGrid.Drawing.Text.FontStyles?(CPF.ReoGrid.Drawing.Text.FontStyles.Italic), textColor, backColor);
|
|
orCreateLastRun.AppendText(text);
|
|
return this;
|
|
}
|
|
|
|
public RichText Underline(string text, string fontName = null, float? fontSize = null, Color? textColor = null, Color? backColor = null)
|
|
{
|
|
Run orCreateLastRun = this.GetOrCreateLastParagraph().GetOrCreateLastRun(fontName, fontSize, new CPF.ReoGrid.Drawing.Text.FontStyles?(CPF.ReoGrid.Drawing.Text.FontStyles.Underline), textColor, backColor);
|
|
orCreateLastRun.AppendText(text);
|
|
return this;
|
|
}
|
|
|
|
public RichText Regular(string text, string fontName = null, float? fontSize = null, Color? textColor = null, Color? backColor = null)
|
|
{
|
|
Run orCreateLastRun = this.GetOrCreateLastParagraph().GetOrCreateLastRun(fontName, fontSize, new CPF.ReoGrid.Drawing.Text.FontStyles?(CPF.ReoGrid.Drawing.Text.FontStyles.Regular), textColor, backColor);
|
|
orCreateLastRun.AppendText(text);
|
|
return this;
|
|
}
|
|
|
|
public RichText Superscript(string text, string fontName = null, float? fontSize = null, Color? textColor = null, Color? backColor = null)
|
|
{
|
|
Run orCreateLastRun = this.GetOrCreateLastParagraph().GetOrCreateLastRun(fontName, fontSize, new CPF.ReoGrid.Drawing.Text.FontStyles?(CPF.ReoGrid.Drawing.Text.FontStyles.Superscrit), textColor, backColor);
|
|
orCreateLastRun.AppendText(text);
|
|
return this;
|
|
}
|
|
|
|
public RichText Subscript(string text, string fontName = null, float? fontSize = null, Color? textColor = null, Color? backColor = null)
|
|
{
|
|
Run orCreateLastRun = this.GetOrCreateLastParagraph().GetOrCreateLastRun(fontName, fontSize, new CPF.ReoGrid.Drawing.Text.FontStyles?(CPF.ReoGrid.Drawing.Text.FontStyles.Subscript), textColor, backColor);
|
|
orCreateLastRun.AppendText(text);
|
|
return this;
|
|
}
|
|
|
|
public RichText SetStyles(float? paragraphSpacing = null, float? lineHeight = null, ReoGridHorAlign? halign = null, string fontName = null, float? fontSize = null, CPF.ReoGrid.Drawing.Text.FontStyles? fontStyles = null, Color? textColor = null, Color? backColor = null)
|
|
{
|
|
Paragraph orCreateLastParagraph = this.GetOrCreateLastParagraph();
|
|
orCreateLastParagraph.ParagraphEndSpacing = (paragraphSpacing ?? this.DefaultParagraphSpacing);
|
|
orCreateLastParagraph.LineHeight = (lineHeight ?? this.DefaultLineHeight);
|
|
orCreateLastParagraph.HorizontalAlign = (halign ?? this.DefaultHorizontalAlignment);
|
|
Run orCreateLastRun = orCreateLastParagraph.GetOrCreateLastRun(fontName, fontSize, fontStyles, textColor, backColor);
|
|
return this;
|
|
}
|
|
|
|
private Paragraph GetOrCreateLastParagraph()
|
|
{
|
|
bool flag = this.paragraphs.Count > 0;
|
|
Paragraph paragraph;
|
|
if (flag)
|
|
{
|
|
paragraph = this.paragraphs[this.paragraphs.Count - 1];
|
|
}
|
|
else
|
|
{
|
|
paragraph = new Paragraph(this, null);
|
|
this.AddParagraph(paragraph);
|
|
}
|
|
return paragraph;
|
|
}
|
|
|
|
internal void Draw(IGraphics g, Rect bounds)
|
|
{
|
|
float num = bounds.Left + 2f;
|
|
float num2 = bounds.Top + 2f;
|
|
bool flag = !this.Overflow;
|
|
if (flag)
|
|
{
|
|
g.PushClip(bounds);
|
|
}
|
|
switch (this.VerticalAlignment)
|
|
{
|
|
default:
|
|
num2 += bounds.Height - this.measuredSize.Height - 6f;
|
|
break;
|
|
case ReoGridVerAlign.Top:
|
|
num2 += 1f;
|
|
break;
|
|
case ReoGridVerAlign.Middle:
|
|
num2 += (bounds.Height - this.measuredSize.Height) / 2f - 2f;
|
|
break;
|
|
}
|
|
Run run = null;
|
|
SolidColorBrush solidColorBrush = null;
|
|
Color color = Color.Transparent;
|
|
foreach (Paragraph paragraph in this.paragraphs)
|
|
{
|
|
foreach (Line line in paragraph.lines)
|
|
{
|
|
foreach (Box box in line.boxes)
|
|
{
|
|
Run run2 = box.Run;
|
|
bool flag2 = run != run2;
|
|
if (flag2)
|
|
{
|
|
Color color2 = run2.TextColor;
|
|
bool isTransparent = color2.IsTransparent;
|
|
if (isTransparent)
|
|
{
|
|
color2 = this.DefaultTextColor;
|
|
}
|
|
bool flag3 = color2 != color || solidColorBrush == null;
|
|
if (flag3)
|
|
{
|
|
color = color2;
|
|
solidColorBrush = new SolidColorBrush(color);
|
|
}
|
|
run = run2;
|
|
}
|
|
bool flag4 = (run2.FontStyles & CPF.ReoGrid.Drawing.Text.FontStyles.Underline) == CPF.ReoGrid.Drawing.Text.FontStyles.Underline;
|
|
Stroke stroke;
|
|
float num4;
|
|
Point point;
|
|
float num5;
|
|
if (flag4)
|
|
{
|
|
CPFPen cpfpen = new CPFPen(solidColorBrush.Color, 1f);
|
|
float num3 = line.Height + num2 + 1f;
|
|
DrawingContext platformGraphics = g.PlatformGraphics;
|
|
stroke = cpfpen.Stroke;
|
|
Brush brush = cpfpen.Brush;
|
|
num4 = box.leftTop.X + num;
|
|
point = new Point(ref num4, ref num3);
|
|
num5 = box.rightTop.X + num;
|
|
Point point2 = new Point(ref num5, ref num3);
|
|
platformGraphics.DrawLine(stroke, brush, point, point2);
|
|
}
|
|
float num6 = box.leftTop.X + num;
|
|
float num7 = box.leftTop.Y + num2;
|
|
AntialiasMode antialiasMode = g.PlatformGraphics.AntialiasMode;
|
|
g.PlatformGraphics.AntialiasMode = AntialiasMode.AntiAlias;
|
|
DrawingContext platformGraphics2 = g.PlatformGraphics;
|
|
point = new Point(ref num6, ref num7);
|
|
Brush fillBrush = solidColorBrush;
|
|
string str = box.Str;
|
|
Font font = box.FontInfo.Font;
|
|
TextAlignment textAlignment = TextAlignment.Left;
|
|
num4 = float.MaxValue;
|
|
TextDecoration textDecoration = default(TextDecoration);
|
|
num5 = float.MaxValue;
|
|
TextTrimming textTrimming = TextTrimming.None;
|
|
stroke = default(Stroke);
|
|
platformGraphics2.DrawString(point, fillBrush, str, font, textAlignment, num4, textDecoration, num5, textTrimming, stroke, null);
|
|
g.PlatformGraphics.AntialiasMode = antialiasMode;
|
|
}
|
|
}
|
|
}
|
|
bool flag5 = !this.Overflow;
|
|
if (flag5)
|
|
{
|
|
g.PopClip();
|
|
}
|
|
}
|
|
|
|
internal void UpdateText()
|
|
{
|
|
Stopwatch stopwatch = Stopwatch.StartNew();
|
|
float num = 0f;
|
|
float num2 = 0f;
|
|
this.measuredSize = new Size(ref num, ref num2);
|
|
bool flag = this.size.Width > 0f && this.size.Height > 0f;
|
|
if (flag)
|
|
{
|
|
RelayoutSession relayoutSession = new RelayoutSession(this.size);
|
|
bool flag2 = this.RotationAngle > 0f;
|
|
if (flag2)
|
|
{
|
|
relayoutSession.d = this.RotationAngle * 3.1415925f / 180f;
|
|
relayoutSession.s = (float)Math.Sin((double)relayoutSession.d);
|
|
relayoutSession.c = (float)Math.Cos((double)relayoutSession.d);
|
|
}
|
|
foreach (Paragraph paragraph in this.paragraphs)
|
|
{
|
|
paragraph.UpdateText(relayoutSession);
|
|
bool flag3 = paragraph.lastLine != null;
|
|
if (flag3)
|
|
{
|
|
float num3 = paragraph.lastLine.Height * (paragraph.ParagraphEndSpacing - 1f);
|
|
RelayoutSession relayoutSession2 = relayoutSession;
|
|
relayoutSession2.startLoc.Y = relayoutSession2.startLoc.Y + num3;
|
|
}
|
|
}
|
|
this.measuredSize = relayoutSession.measuredSize;
|
|
}
|
|
stopwatch.Stop();
|
|
this.lastUpdateMS = stopwatch.ElapsedMilliseconds;
|
|
bool flag4 = this.lastUpdateMS > 10L;
|
|
if (flag4)
|
|
{
|
|
Logger.Log("richtext", "update all text takes " + this.lastUpdateMS.ToString() + " ms.");
|
|
}
|
|
}
|
|
|
|
public override string ToString()
|
|
{
|
|
bool flag = this.sbDirty;
|
|
if (flag)
|
|
{
|
|
bool flag2 = this.sb == null;
|
|
if (flag2)
|
|
{
|
|
this.sb = new StringBuilder(256);
|
|
}
|
|
else
|
|
{
|
|
this.sb.Remove(0, this.sb.Length);
|
|
}
|
|
foreach (Paragraph paragraph in this.paragraphs)
|
|
{
|
|
bool flag3 = this.sb.Length > 0;
|
|
if (flag3)
|
|
{
|
|
this.sb.Append(Environment.NewLine);
|
|
}
|
|
foreach (Run run in paragraph.Runs)
|
|
{
|
|
this.sb.Append(run.Text);
|
|
}
|
|
}
|
|
this.textBuffer = this.sb.ToString();
|
|
this.sbDirty = false;
|
|
}
|
|
return this.textBuffer;
|
|
}
|
|
|
|
public string ToPlainText()
|
|
{
|
|
return this.ToString();
|
|
}
|
|
|
|
private bool suspendUpdateText = false;
|
|
|
|
internal const string BuiltInDefaultFontName = "Calibri";
|
|
|
|
internal const float BuiltInDefaultFontSize = 10.25f;
|
|
|
|
private Size size;
|
|
|
|
internal Size measuredSize;
|
|
|
|
private TextWrapMode textWrap;
|
|
|
|
private List<Paragraph> paragraphs;
|
|
|
|
public long lastUpdateMS;
|
|
|
|
private string textBuffer;
|
|
|
|
internal bool sbDirty;
|
|
|
|
private StringBuilder sb;
|
|
}
|
|
}
|