CPF/CPF.ReoGrid/Drawing/RichText.cs
2024-06-24 10:15:59 +08:00

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;
}
}