123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830 |
- using System;
- using System.Text;
- using System.Collections.Generic;
- using System.Drawing;
- using System.Drawing.Text;
- using System.Drawing.Drawing2D;
- using System.ComponentModel;
- using FastReport.Utils;
- using FastReport.Format;
- using FastReport.Code;
- using System.Windows.Forms;
- using System.Drawing.Design;
- namespace FastReport
- {
- /// <summary>
- /// Specifies the horizontal alignment of a text in the TextObject object.
- /// </summary>
- public enum HorzAlign
- {
- /// <summary>
- /// Specifies that text is aligned in the left of the layout rectangle.
- /// </summary>
- Left,
- /// <summary>
- /// Specifies that text is aligned in the center of the layout rectangle.
- /// </summary>
- Center,
- /// <summary>
- /// Specifies that text is aligned in the right of the layout rectangle.
- /// </summary>
- Right,
- /// <summary>
- /// Specifies that text is aligned in the left and right sides of the layout rectangle.
- /// </summary>
- Justify
- }
- /// <summary>
- /// Specifies the vertical alignment of a text in the TextObject object.
- /// </summary>
- public enum VertAlign
- {
- /// <summary>
- /// Specifies that text is aligned in the top of the layout rectangle.
- /// </summary>
- Top,
- /// <summary>
- /// Specifies that text is aligned in the center of the layout rectangle.
- /// </summary>
- Center,
- /// <summary>
- /// Specifies that text is aligned in the bottom of the layout rectangle.
- /// </summary>
- Bottom
- }
- /// <summary>
- /// The type of text renderer
- /// </summary>
- public enum TextRenderType
- {
- /// <summary>
- /// The default render
- /// </summary>
- Default,
- /// <summary>
- /// Render with some html tags and stable logic
- /// </summary>
- HtmlTags,
- /// <summary>
- /// Render with img tags, span etc. Experimental and unstable logic
- /// </summary>
- HtmlParagraph,
- /// <summary>
- /// Renders a text in a simplest way. For internal use only.
- /// </summary>
- Inline
- }
- /// <summary>
- /// The format of paragraph
- /// </summary>
- [TypeConverter(typeof(TypeConverters.FRExpandableObjectConverter))]
- public class ParagraphFormat
- {
- private float firstLineIndent;
- private float lineSpacing;
- private LineSpacingType lineSpacingType;
- private bool skipFirstLineIndent;
- /// <summary>
- /// The first line on each paragraph.
- /// </summary>
- [Browsable(true)]
- [DefaultValue(0f)]
- [TypeConverter("FastReport.TypeConverters.UnitsConverter, FastReport")]
- public float FirstLineIndent
- {
- get { return firstLineIndent; }
- set { firstLineIndent = value; }
- }
- /// <summary>
- /// The distance between lines, not effect if value less then 0
- /// </summary>
- [Browsable(true)]
- [DefaultValue(0f)]
- [TypeConverter("FastReport.TypeConverters.UnitsConverter, FastReport")]
- public float LineSpacing
- {
- get { return lineSpacing; }
- set { if (value >= 0) lineSpacing = value; }
- }
- /// <summary>
- /// The spacing type for distance between line calculation
- /// </summary>
- [Browsable(true)]
- [DefaultValue(LineSpacingType.Single)]
- public LineSpacingType LineSpacingType
- {
- get { return lineSpacingType; }
- set { lineSpacingType = value; }
- }
- /// <summary>
- /// The value for a multiplication line height for adding spacing
- /// </summary>
- [Browsable(true)]
- [DefaultValue(0f)]
- public float LineSpacingMultiple
- {
- get { return lineSpacing / 100f; }
- set { if (value >= 0) lineSpacing = value * 100f; }
- }
- /// <summary>
- /// Skip the line indent in the first paragraph, for broken paragraphs
- /// </summary>
- [Browsable(false)]
- [DefaultValue(false)]
- public bool SkipFirstLineIndent
- {
- get { return skipFirstLineIndent; }
- set { skipFirstLineIndent = value; }
- }
- /// <summary>
- /// clone with new scale;
- /// </summary>
- /// <param name="scale"></param>
- /// <returns></returns>
- internal ParagraphFormat MultipleScale(float scale)
- {
- ParagraphFormat clone = new ParagraphFormat();
- clone.lineSpacingType = lineSpacingType;
- if (LineSpacingType == LineSpacingType.Multiple)
- clone.lineSpacing = lineSpacing;
- else
- clone.lineSpacing = lineSpacing * scale;
- clone.firstLineIndent = firstLineIndent * scale;
- clone.skipFirstLineIndent = skipFirstLineIndent;
- return clone;
- }
- internal void Assign(ParagraphFormat p)
- {
- lineSpacingType = p.lineSpacingType;
- lineSpacing = p.lineSpacing;
- firstLineIndent = p.firstLineIndent;
- skipFirstLineIndent = p.skipFirstLineIndent;
- }
- public override bool Equals(object obj)
- {
- ParagraphFormat format = obj as ParagraphFormat;
- return format != null &&
- firstLineIndent == format.firstLineIndent &&
- lineSpacing == format.lineSpacing &&
- lineSpacingType == format.lineSpacingType &&
- skipFirstLineIndent == format.skipFirstLineIndent;
- }
- public override int GetHashCode()
- {
- unchecked
- {
- int hashCode = -1051315095;
- hashCode = hashCode * -1521134295 + firstLineIndent.GetHashCode();
- hashCode = hashCode * -1521134295 + lineSpacing.GetHashCode();
- hashCode = hashCode * -1521134295 + lineSpacingType.GetHashCode();
- hashCode = hashCode * -1521134295 + skipFirstLineIndent.GetHashCode();
- return hashCode;
- }
- }
- }
- /// <summary>
- /// The spacing type between lines
- /// </summary>
- public enum LineSpacingType
- {
- /// <summary>
- /// Single spacing, not effect from LineSpacing
- /// </summary>
- Single,
- /// <summary>
- /// Minimal spacing in exactly size
- /// </summary>
- AtLeast,
- /// <summary>
- /// The specific distance between the lines, for some exports, does not work if the distance value is too small.
- /// </summary>
- Exactly,
- /// <summary>
- /// The calculated distance between lines, for some exports, does not work if the distance value is too small.
- /// </summary>
- Multiple
- }
- /// <summary>
- /// Specifies the behavior of the <b>AutoShrink</b> feature of <b>TextObject</b>.
- /// </summary>
- public enum AutoShrinkMode
- {
- /// <summary>
- /// AutoShrink is disabled.
- /// </summary>
- None,
- /// <summary>
- /// AutoShrink decreases the <b>Font.Size</b> property of the <b>TextObject</b>.
- /// </summary>
- FontSize,
- /// <summary>
- /// AutoShrink decreases the <b>FontWidthRatio</b> property of the <b>TextObject</b>.
- /// </summary>
- FontWidth
- }
- /// <summary>
- /// Specifies the behavior of the <b>MergeMode</b> feature of <b>TextObject</b>.
- /// </summary>
- [TypeConverter(typeof(FastReport.TypeConverters.FlagConverter))]
- [Flags]
- public enum MergeMode
- {
- /// <summary>
- /// Merge is disabled.
- /// </summary>
- None = 0,
- /// <summary>
- /// Allows horizontal merging.
- /// </summary>
- Horizontal = 1,
- /// <summary>
- /// Allows vertical merging.
- /// </summary>
- Vertical = 2,
- }
- /// <summary>
- /// Represents the Text object that may display one or several text lines.
- /// </summary>
- /// <remarks>
- /// Specify the object's text in the <see cref="TextObjectBase.Text">Text</see> property.
- /// Text may contain expressions and data items, for example: "Today is [Date]". When report
- /// is running, all expressions are calculated and replaced with actual values, so the text
- /// would be "Today is 01.01.2008".
- /// <para/>The symbols used to find expressions in a text are set in the
- /// <see cref="TextObjectBase.Brackets">Brackets</see> property. You also may disable expressions
- /// using the <see cref="TextObjectBase.AllowExpressions">AllowExpressions</see> property.
- /// <para/>To format an expression value, use the <see cref="Format"/> property.
- /// </remarks>
- public partial class TextObject : TextObjectBase
- {
- #region Fields
- private MergeMode mergeMode;
- private bool autoWidth;
- private HorzAlign horzAlign;
- private VertAlign vertAlign;
- private int angle;
- private bool rightToLeft;
- private bool wordWrap;
- private bool underlines;
- private Font font;
- private FillBase textFill;
- private TextOutline textOutline;
- private StringTrimming trimming;
- private float fontWidthRatio;
- private float firstTabOffset;
- private float tabWidth;
- private FloatCollection tabPositions;
- private bool clip;
- private ConditionCollection highlight;
- private bool wysiwyg;
- private float lineHeight;
- private bool forceJustify;
- private TextRenderType textRenderType;
- private AutoShrinkMode autoShrink;
- private float autoShrinkMinSize;
- private float paragraphOffset;
- private FillBase savedTextFill;
- private Font savedFont;
- private string savedText;
- private FormatBase savedFormat;
- private InlineImageCache inlineImageCache;
- private ParagraphFormat paragraphFormat;
- private bool preserveLastLineSpace;
- #endregion
- #region Properties
- /// <summary>
- /// Gets or sets a paragraph format for a new html rendering type, not for others rendering
- /// </summary>
- [Category("Appearance")]
- public ParagraphFormat ParagraphFormat
- {
- get { return paragraphFormat; }
- set { paragraphFormat = value; }
- }
- /// <summary>
- /// Gets or sets a value that determines if the text object should handle its width automatically.
- /// </summary>
- [DefaultValue(false)]
- [Category("Behavior")]
- public bool AutoWidth
- {
- get { return autoWidth; }
- set { autoWidth = value; }
- }
- /// <summary>
- /// Gets or sets a value that indicates whether the font size should shrink to
- /// display the longest text line without word wrap.
- /// </summary>
- /// <remarks>
- /// To limit the minimum size, use the <see cref="AutoShrinkMinSize"/> property.
- /// </remarks>
- [DefaultValue(AutoShrinkMode.None)]
- [Category("Behavior")]
- public AutoShrinkMode AutoShrink
- {
- get { return autoShrink; }
- set { autoShrink = value; }
- }
- /// <summary>
- /// Gets or sets the minimum size of font (or minimum width ratio) if the <see cref="AutoShrink"/>
- /// mode is on.
- /// </summary>
- /// <remarks>
- /// This property determines the minimum font size (in case the <see cref="AutoShrink"/> property is set to
- /// <b>FontSize</b>), or the minimum font width ratio (if <b>AutoShrink</b> is set to <b>FontWidth</b>).
- /// <para/>The default value is 0, that means no limits.
- /// </remarks>
- [DefaultValue(0f)]
- [Category("Behavior")]
- public float AutoShrinkMinSize
- {
- get { return autoShrinkMinSize; }
- set { autoShrinkMinSize = value; }
- }
- /// <summary>
- /// Gets or sets the horizontal alignment of a text in the TextObject object.
- /// </summary>
- [DefaultValue(HorzAlign.Left)]
- [Category("Appearance")]
- public HorzAlign HorzAlign
- {
- get { return horzAlign; }
- set { horzAlign = value; }
- }
- /// <summary>
- /// Gets or sets the vertical alignment of a text in the TextObject object.
- /// </summary>
- [DefaultValue(VertAlign.Top)]
- [Category("Appearance")]
- public VertAlign VertAlign
- {
- get { return vertAlign; }
- set { vertAlign = value; }
- }
- /// <summary>
- /// Gets or sets the text angle, in degrees.
- /// </summary>
- [DefaultValue(0)]
- [Category("Appearance")]
- [Editor("FastReport.TypeEditors.AngleEditor, FastReport", typeof(UITypeEditor))]
- public int Angle
- {
- get { return angle; }
- set { angle = value; }
- }
- /// <summary>
- /// Gets or sets a value that indicates whether the component should draw right-to-left for RTL languages.
- /// </summary>
- [DefaultValue(false)]
- [Category("Behavior")]
- public bool RightToLeft
- {
- get { return rightToLeft; }
- set { rightToLeft = value; }
- }
- /// <summary>
- /// Gets or sets a value that indicates if lines are automatically word-wrapped.
- /// </summary>
- [DefaultValue(true)]
- [Category("Behavior")]
- public bool WordWrap
- {
- get { return wordWrap; }
- set { wordWrap = value; }
- }
- /// <summary>
- /// Gets or sets a value that determines if the text object will underline each text line.
- /// </summary>
- [DefaultValue(false)]
- [Category("Appearance")]
- public bool Underlines
- {
- get { return underlines; }
- set { underlines = value; }
- }
- /// <summary>
- /// Gets or sets the font settings for this object.
- /// </summary>
- [Category("Appearance")]
- public Font Font
- {
- get { return font; }
- set
- {
- font = value;
- if (!String.IsNullOrEmpty(Style))
- Style = "";
- }
- }
- /// <summary>
- /// Gets or sets a collection of TAB symbol positions, in pixels. Negative values will not affect this property.
- /// </summary>
- /// <remarks>Use collection methods to add or remove TAB positions.</remarks>
- public FloatCollection TabPositions
- {
- get { return tabPositions; }
- set
- {
- if (value == null)
- tabPositions.Clear();
- else
- tabPositions = value;
- }
- }
- /// <summary>
- /// Gets or sets the fill color used to draw a text.
- /// </summary>
- /// <remarks>
- /// Default fill is <see cref="SolidFill"/>. You may specify other fill types, for example:
- /// <code>
- /// text1.TextFill = new HatchFill(Color.Black, Color.White, HatchStyle.Cross);
- /// </code>
- /// Use the <see cref="TextColor"/> property to set the solid text color.
- /// </remarks>
- [Category("Appearance")]
- [Editor("FastReport.TypeEditors.FillEditor, FastReport", typeof(UITypeEditor))]
- public FillBase TextFill
- {
- get { return textFill; }
- set
- {
- if (value == null)
- throw new ArgumentNullException("TextFill");
- textFill = value;
- if (!String.IsNullOrEmpty(Style))
- Style = "";
- }
- }
- /// <summary>
- /// Gets or sets the text outline.
- /// </summary>
- [Category("Appearance")]
- [Editor("FastReport.TypeEditors.OutlineEditor, FastReport", typeof(UITypeEditor))]
- public TextOutline TextOutline
- {
- get { return textOutline; }
- set
- {
- if (value == null)
- throw new ArgumentNullException("TextOutline");
- textOutline = value;
- if (!String.IsNullOrEmpty(Style))
- Style = "";
- }
- }
- /// <summary>
- /// Gets or sets the text color in a simple manner.
- /// </summary>
- /// <remarks>
- /// This property can be used in a report script to change the text color of the object. It is
- /// equivalent to: <code>textObject1.TextFill = new SolidFill(color);</code>
- /// </remarks>
- [Browsable(false)]
- public Color TextColor
- {
- get { return TextFill is SolidFill ? (TextFill as SolidFill).Color : Color.Black; }
- set { TextFill = new SolidFill(value); }
- }
- /// <summary>
- /// Gets or sets the string trimming options.
- /// </summary>
- [DefaultValue(StringTrimming.None)]
- [Category("Behavior")]
- public StringTrimming Trimming
- {
- get { return trimming; }
- set { trimming = value; }
- }
- /// <summary>
- /// Gets or sets the width ratio of the font.
- /// </summary>
- /// <remarks>
- /// Default value is 1. To make a font wider, set a value grether than 1; to make a font narrower,
- /// set a value less than 1.
- /// </remarks>
- [DefaultValue(1f)]
- [Category("Appearance")]
- public float FontWidthRatio
- {
- get { return fontWidthRatio; }
- set
- {
- if (value > 0)
- fontWidthRatio = value;
- else
- fontWidthRatio = 1;
- }
- }
- /// <summary>
- /// Gets or sets the height of single text line, in pixels.
- /// </summary>
- [DefaultValue(0f)]
- [Category("Appearance")]
- public float LineHeight
- {
- get { return lineHeight; }
- set { lineHeight = value; }
- }
- /// <summary>
- /// Gets or sets the offset of the first TAB symbol. Negative value will not affect this property.
- /// </summary>
- [DefaultValue(0f)]
- [Category("Appearance")]
- //[TypeConverter("FastReport.TypeConverters.UnitsConverter, FastReport")]
- public float FirstTabOffset
- {
- get { return firstTabOffset; }
- set { if (value >= 0) firstTabOffset = value; }
- }
- /// <summary>
- /// Gets or sets the width of TAB symbol, in pixels. Negative values will not affect this property.
- /// </summary>
- [DefaultValue(58f)]
- [Category("Appearance")]
- public float TabWidth
- {
- get { return tabWidth; }
- set { if (value >= 0) tabWidth = value; }
- }
- /// <summary>
- /// Gets or sets a value that indicates if text should be clipped inside the object's bounds.
- /// </summary>
- [DefaultValue(true)]
- [Category("Behavior")]
- public bool Clip
- {
- get { return clip; }
- set { clip = value; }
- }
- /// <summary>
- /// Gets the collection of conditional highlight attributes.
- /// </summary>
- /// <remarks>
- /// Conditional highlight is used to change the visual appearance of the Text object
- /// depending on some condition(s). For example, you may highlight negative values displayed by
- /// the Text object with red color. To do this, add the highlight condition:
- /// <code>
- /// TextObject text1;
- /// HighlightCondition highlight = new HighlightCondition();
- /// highlight.Expression = "Value < 0";
- /// highlight.Fill = new SolidFill(Color.Red);
- /// highlight.ApplyFill = true;
- /// text1.Highlight.Add(highlight);
- /// </code>
- /// </remarks>
- [Category("Data")]
- [Editor("FastReport.TypeEditors.HighlightEditor, FastReport", typeof(UITypeEditor))]
- public ConditionCollection Highlight
- {
- get { return highlight; }
- }
- /// <summary>
- /// Gets or sets a value that indicates if the text object should display its contents similar to the printout.
- /// </summary>
- [DefaultValue(false)]
- [Category("Behavior")]
- public bool Wysiwyg
- {
- get { return wysiwyg; }
- set { wysiwyg = value; }
- }
- /// <summary>
- /// Forces justify for the last text line.
- /// </summary>
- [Browsable(false)]
- public bool ForceJustify
- {
- get { return forceJustify; }
- set { forceJustify = value; }
- }
- /// <summary>
- /// Allows handling html tags in the text.
- /// </summary>
- /// <remarks>
- /// The following html tags can be used in the object's text: <b>, <i>, <u>,
- /// <strike>, <sub>, <sup>, </b>, </i>, </u>,
- /// </strike>, </sub>, </sup>,
- /// <font color=&...&>, </font>. Font size cannot
- /// be changed due to limitations in the rendering engine.
- /// </remarks>
- [DefaultValue(false)]
- [Category("Behavior")]
- [Browsable(false)]
- [Obsolete("This method is deprecated please use TextRenderer")]
- public bool HtmlTags
- {
- get
- {
- return HasHtmlTags;
- }
- set { textRenderType = value ? TextRenderType.HtmlTags : TextRenderType.Default; }
- }
- /// <summary>
- /// Indicates handling html tags in the text.
- /// </summary>
- /// <remarks>To set the value use the TextRenderer property.</remarks>
- [DefaultValue(false)]
- [Category("Behavior")]
- [Browsable(false)]
- public bool HasHtmlTags
- {
- get
- {
- switch (textRenderType)
- {
- case TextRenderType.HtmlTags:
- case TextRenderType.HtmlParagraph:
- return true;
- default:
- return false;
- }
- }
- }
- /// <summary>
- /// The type of text render
- /// </summary>
- /// /// <remarks>
- /// The following html tags can be used in the object's text: <b>, <i>, <u>,
- /// <strike>, <sub>, <sup>, </b>, </i>, </u>,
- /// </strike>, </sub>, </sup>,
- /// <font color=&...&>, </font>. Font size cannot
- /// be changed due to limitations in the rendering engine.
- /// </remarks>
- [DefaultValue(TextRenderType.Default)]
- [Category("Behavior")]
- public TextRenderType TextRenderType
- {
- get { return textRenderType; }
- set { textRenderType = value; }
- }
- /// <summary>
- /// Gets or sets the paragraph offset, in pixels. For HtmlParagraph use ParagraphFormat.FirstLineIndent.
- /// </summary>
- [DefaultValue(0f)]
- [Category("Appearance")]
- [TypeConverter("FastReport.TypeConverters.UnitsConverter, FastReport")]
- public float ParagraphOffset
- {
- get { return paragraphOffset; }
- set { paragraphOffset = value; }
- }
- internal bool IsAdvancedRendererNeeded
- {
- get { return HorzAlign == HorzAlign.Justify || Wysiwyg || LineHeight != 0 || HasHtmlTags; }
- }
- internal bool PreserveLastLineSpace { get { return preserveLastLineSpace; } set { preserveLastLineSpace = value; } }
- /// <summary>
- /// Cache for inline images
- /// </summary>
- [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
- public InlineImageCache InlineImageCache
- {
- get
- {
- if (inlineImageCache == null)
- inlineImageCache = new InlineImageCache();
- return inlineImageCache;
- }
- }
- /// <summary>
- /// Gets or sets a value indicating whether the text should be merged with other nearby text objects.
- /// </summary>
- [DefaultValue(MergeMode.None)]
- [Category("Behavior")]
- [Editor("FastReport.TypeEditors.FlagsEditor, FastReport", typeof(UITypeEditor))]
- public MergeMode MergeMode
- {
- get { return mergeMode; }
- set { mergeMode = value; }
- }
- #endregion
- #region Private Methods
- private void DrawUnderlines(FRPaintEventArgs e)
- {
- if (!Underlines || Angle != 0)
- return;
- IGraphics g = e.Graphics;
- float lineHeight = LineHeight == 0 ? Font.GetHeight() * DrawUtils.ScreenDpiFX : LineHeight;
- lineHeight *= e.ScaleY;
- float curY = AbsTop * e.ScaleY + lineHeight + 1;
- Pen pen = e.Cache.GetPen(Border.Color, Border.Width * e.ScaleY, DashStyle.Solid);
- while (curY < AbsBottom * e.ScaleY)
- {
- g.DrawLine(pen, AbsLeft * e.ScaleX, curY, AbsRight * e.ScaleY, curY);
- curY += lineHeight;
- }
- }
- private SizeF CalcSize()
- {
- Report report = Report;
- if (String.IsNullOrEmpty(Text) || report == null)
- return new SizeF(0, 0);
- Font font = report.GraphicCache.GetFont(Font.FontFamily, Font.Size * 96f / DrawUtils.ScreenDpi, Font.Style);
- float width = 0;
- if (WordWrap)
- {
- if (Angle == 90 || Angle == 270)
- width = Height - Padding.Vertical;
- else
- width = Width - Padding.Horizontal;
- }
- IGraphics g = report.MeasureGraphics;
- IGraphicsState state = g.Save();
- try
- {
- if (report.TextQuality != TextQuality.Default)
- g.TextRenderingHint = report.GetTextQuality();
- if (TextRenderType == TextRenderType.HtmlParagraph)
- {
- if (width == 0)
- width = 100000;
- using (HtmlTextRenderer htmlRenderer = GetHtmlTextRenderer(g, new RectangleF(0, 0, width, 100000), 1, 1))
- {
- float height = htmlRenderer.CalcHeight();
- width = htmlRenderer.CalcWidth();
- width += Padding.Horizontal + 1;
- if (LineHeight == 0 || this.PreserveLastLineSpace)
- height += Padding.Vertical + 1;
- return new SizeF(width, height);
- }
- }
- #if CROSSPLATFORM && !SKIA
- // in FR.Core we use AdvancedTextRenderer only if needed (IsAdvancedRendererNeeded) or if it's not Windows
- if (IsAdvancedRendererNeeded || !Config.IsWindows)
- #else
- if (IsAdvancedRendererNeeded)
- #endif
- {
- if (width == 0)
- width = 100000;
- AdvancedTextRenderer renderer = new AdvancedTextRenderer(Text, g, font, Brushes.Black, Pens.Black,
- new RectangleF(0, 0, width, 100000), GetStringFormat(report.GraphicCache, 0),
- HorzAlign, VertAlign, LineHeight, Angle, FontWidthRatio, false, Wysiwyg, HasHtmlTags, false, 96f / DrawUtils.ScreenDpi,
- 96f / DrawUtils.ScreenDpi, InlineImageCache);
- float height = renderer.CalcHeight();
- width = renderer.CalcWidth();
- width += Padding.Horizontal + 1;
- //if (LineHeight == 0)
- height += Padding.Vertical + 1;
- return new SizeF(width, height);
- }
- else
- {
- if (FontWidthRatio != 1)
- width /= FontWidthRatio;
- SizeF size = g.MeasureString(Text, font, new SizeF(width, 100000));
- size.Width += Padding.Horizontal + 1;
- size.Height += Padding.Vertical + 1;
- return size;
- }
- }
- finally
- {
- g.Restore(state);
- }
- }
- private float InternalCalcWidth()
- {
- bool saveWordWrap = WordWrap;
- WordWrap = false;
- float result = 0;
- try
- {
- SizeF size = CalcSize();
- result = size.Width;
- }
- finally
- {
- WordWrap = saveWordWrap;
- }
- return result;
- }
- private float InternalCalcHeight()
- {
- return CalcSize().Height;
- }
- private string BreakTextHtml(out bool endOnEnter, out float excessiveHeight)
- {
- excessiveHeight = 0;
- endOnEnter = false;
- ForceJustify = false;
- if (String.IsNullOrEmpty(Text))
- return "";
- string result = null;
- Report report = Report;
- if (report == null)
- return "";
- StringFormat format = GetStringFormat(report.GraphicCache, StringFormatFlags.LineLimit);
- RectangleF textRect = new RectangleF(0, 0, Width - Padding.Horizontal, Height - Padding.Vertical);
- if (textRect.Height <= 0)
- return result;
- int charactersFitted;
- IGraphics g = report.MeasureGraphics;
- IGraphicsState state = g.Save();
- if (report.TextQuality != TextQuality.Default)
- g.TextRenderingHint = report.GetTextQuality();
- try
- {
- using (HtmlTextRenderer htmlRenderer = GetHtmlTextRenderer(g, 1, 1, textRect, format))
- {
- htmlRenderer.CalcHeight(out charactersFitted);
- if (charactersFitted == 0)
- return null;
- Text = HtmlTextRenderer.BreakHtml(Text, charactersFitted, out result, out endOnEnter);
- excessiveHeight = Height - Padding.Vertical - GetHtmlTextRenderer(g, 1, 1, textRect, format).CalcHeight();
- if (HorzAlign == HorzAlign.Justify && !endOnEnter && result != "")
- {
- if (Text.EndsWith(" "))
- Text = Text.TrimEnd(' ');
- ForceJustify = true;
- }
- }
- }
- finally
- {
- g.Restore(state);
- }
- return result;
- }
- private string BreakText()
- {
- ForceJustify = false;
- if (String.IsNullOrEmpty(Text))
- return "";
- string result = null;
- Report report = Report;
- if (report == null)
- return "";
- Font font = report.GraphicCache.GetFont(Font.FontFamily, Font.Size * 96f / DrawUtils.ScreenDpi, Font.Style);
- StringFormat format = GetStringFormat(report.GraphicCache, StringFormatFlags.LineLimit);
- RectangleF textRect = new RectangleF(0, 0, Width - Padding.Horizontal, Height - Padding.Vertical);
- if (textRect.Height < 0)
- return null;
- int charactersFitted;
- int linesFilled;
- IGraphics g = report.MeasureGraphics;
- IGraphicsState state = g.Save();
- try
- {
- if (report.TextQuality != TextQuality.Default)
- g.TextRenderingHint = report.GetTextQuality();
- AdvancedTextRenderer.StyleDescriptor htmlStyle = null;
- if (IsAdvancedRendererNeeded)
- {
- AdvancedTextRenderer renderer = new AdvancedTextRenderer(Text, g, font, Brushes.Black, Pens.Black,
- textRect, format, HorzAlign, VertAlign, LineHeight, Angle, FontWidthRatio, false, Wysiwyg, HasHtmlTags, false, 96f / DrawUtils.ScreenDpi,
- 96f / DrawUtils.ScreenDpi, InlineImageCache);
- renderer.CalcHeight(out charactersFitted, out htmlStyle);
- if (charactersFitted == 0)
- linesFilled = 0;
- else
- linesFilled = 2;
- }
- else
- {
- g.MeasureString(Text, font, textRect.Size, format, out charactersFitted, out linesFilled);
- }
- if (linesFilled == 0)
- return null;
- if (linesFilled == 1)
- {
- // check if there is enough space for one line
- float lineHeight = g.MeasureString("Wg", font).Height;
- if (textRect.Height < lineHeight)
- return null;
- }
- if (charactersFitted < Text.Length)
- result = Text.Substring(charactersFitted);
- else
- result = "";
- Text = Text.Substring(0, charactersFitted);
- if (HorzAlign == HorzAlign.Justify && !Text.EndsWith("\n") && result != "")
- {
- if (Text.EndsWith(" "))
- Text = Text.Substring(0, Text.Length - 1);
- ForceJustify = true;
- }
- if (HasHtmlTags && htmlStyle != null && result != "")
- result = htmlStyle.ToString() + result;
- }
- finally
- {
- g.Restore(state);
- }
- return result;
- }
- private void ProcessAutoShrink()
- {
- if (TextRenderType == TextRenderType.HtmlParagraph)
- return;
- if (String.IsNullOrEmpty(Text))
- return;
- if (AutoShrink == AutoShrinkMode.FontSize)
- {
- while (CalcWidth() > Width - 1 && Font.Size > AutoShrinkMinSize && Font.Size > 1)
- {
- Font = new Font(Font.FontFamily, Font.Size - 1, Font.Style);
- }
- }
- else if (AutoShrink == AutoShrinkMode.FontWidth)
- {
- FontWidthRatio = 1;
- float ratio = Converter.DecreasePrecision((Width - 1) / CalcWidth(), 2) - 0.01f;
- if (ratio < 1)
- FontWidthRatio = Math.Max(ratio, AutoShrinkMinSize);
- }
- }
- private string MakeParagraphOffset(string text)
- {
- // fixed issue 2823
- FirstTabOffset = ParagraphOffset;
- string[] lines = text.Split('\n');
- for (int i = 0; i < lines.Length; i++)
- {
- if (!lines[i].StartsWith("\t"))
- lines[i] = "\t" + lines[i];
- }
- return String.Join("\n", lines);
- }
- #endregion
- #region Protected Methods
- /// <inheritdoc/>
- protected override void DeserializeSubItems(FRReader reader)
- {
- if (String.Compare(reader.ItemName, "Highlight", true) == 0)
- reader.Read(Highlight);
- else
- base.DeserializeSubItems(reader);
- }
- #endregion
- #region Public Methods
- /// <summary>
- /// Returns StringFormat object.
- /// </summary>
- /// <param name="cache">Report graphic cache.</param>
- /// <param name="flags">StringFormat flags.</param>
- /// <returns>StringFormat object.</returns>
- public StringFormat GetStringFormat(GraphicCache cache, StringFormatFlags flags)
- {
- return GetStringFormat(cache, flags, 1);
- }
- internal StringFormat GetStringFormat(GraphicCache cache, StringFormatFlags flags, float scale)
- {
- StringAlignment align = StringAlignment.Near;
- if (HorzAlign == HorzAlign.Center)
- align = StringAlignment.Center;
- else if (HorzAlign == HorzAlign.Right)
- align = StringAlignment.Far;
- StringAlignment lineAlign = StringAlignment.Near;
- if (VertAlign == VertAlign.Center)
- lineAlign = StringAlignment.Center;
- else if (VertAlign == VertAlign.Bottom)
- lineAlign = StringAlignment.Far;
- if (RightToLeft)
- flags |= StringFormatFlags.DirectionRightToLeft;
- if (!WordWrap)
- flags |= StringFormatFlags.NoWrap;
- if (!Clip)
- flags |= StringFormatFlags.NoClip;
- if (TabPositions.Count > 0)
- {
- FloatCollection tabPositions = new FloatCollection();
- foreach (var i in TabPositions)
- tabPositions.Add((float)i * scale);
- return cache.GetStringFormat(align, lineAlign, Trimming, flags, firstTabOffset * scale, tabPositions,
- 48 * scale);
- }
- return cache.GetStringFormat(align, lineAlign, Trimming, flags, firstTabOffset * scale, tabWidth * scale);
- }
- /// <inheritdoc/>
- public override void Assign(Base source)
- {
- base.Assign(source);
- TextObject src = source as TextObject;
- AutoWidth = src.AutoWidth;
- HorzAlign = src.HorzAlign;
- VertAlign = src.VertAlign;
- Angle = src.Angle;
- RightToLeft = src.RightToLeft;
- WordWrap = src.WordWrap;
- Underlines = src.Underlines;
- Font = src.Font;
- TextFill = src.TextFill.Clone();
- TextOutline.Assign(src.TextOutline);
- Trimming = src.Trimming;
- FontWidthRatio = src.FontWidthRatio;
- FirstTabOffset = src.FirstTabOffset;
- TabWidth = src.TabWidth;
- TabPositions.Assign(src.TabPositions);
- Clip = src.Clip;
- Highlight.Assign(src.Highlight);
- Wysiwyg = src.Wysiwyg;
- LineHeight = src.LineHeight;
- TextRenderType = src.TextRenderType;
- AutoShrink = src.AutoShrink;
- AutoShrinkMinSize = src.AutoShrinkMinSize;
- ParagraphOffset = src.ParagraphOffset;
- inlineImageCache = src.inlineImageCache;
- PreserveLastLineSpace = src.PreserveLastLineSpace;
- paragraphFormat.Assign(src.paragraphFormat);
- MergeMode = src.MergeMode;
- }
- /// <summary>
- /// Returns an instance of html text renderer.
- /// </summary>
- /// <param name="scale">Scale ratio.</param>
- /// <param name="fontScale">Font scale ratio.</param>
- /// <returns>The html text renderer.</returns>
- public HtmlTextRenderer GetHtmlTextRenderer(float scale, float fontScale)
- {
- return GetHtmlTextRenderer(Report.MeasureGraphics, scale, fontScale);
- }
- internal HtmlTextRenderer GetHtmlTextRenderer(IGraphics g, float scale, float fontScale)
- {
- StringFormat format = GetStringFormat(Report.GraphicCache, 0, scale);
- RectangleF textRect = new RectangleF(
- (AbsLeft + Padding.Left) * scale,
- (AbsTop + Padding.Top) * scale,
- (Width - Padding.Horizontal) * scale,
- (Height - Padding.Vertical) * scale);
- return GetHtmlTextRenderer(g, scale, fontScale, textRect, format);
- }
- internal HtmlTextRenderer GetHtmlTextRenderer(IGraphics g, RectangleF textRect, float scale, float fontScale)
- {
- StringFormat format = GetStringFormat(Report.GraphicCache, 0, fontScale);
- return GetHtmlTextRenderer(g, scale, fontScale, textRect, format);
- }
- internal HtmlTextRenderer GetHtmlTextRenderer(IGraphics g, float scale, float fontScale, RectangleF textRect, StringFormat format)
- {
- return GetHtmlTextRenderer(Text, g, fontScale, scale, fontScale, textRect, format, false);
- }
- internal HtmlTextRenderer GetHtmlTextRenderer(string text, IGraphics g, float formatScale, float scale, float fontScale,
- RectangleF textRect, StringFormat format, bool isPrinting)
- {
- #if true
- HtmlTextRenderer.RendererContext context;
- context.text = text;
- context.g = g;
- context.font = font.FontFamily;
- context.size = font.Size;
- context.style = font.Style; // no keep
- context.color = TextColor; // no keep
- context.underlineColor = textOutline.Color;
- context.rect = textRect;
- context.underlines = Underlines;
- context.format = format; // no keep
- context.horzAlign = horzAlign;
- context.vertAlign = vertAlign;
- context.paragraphFormat = ParagraphFormat.MultipleScale(formatScale);
- context.forceJustify = ForceJustify;
- context.scale = scale * 96f / DrawUtils.ScreenDpi;
- context.fontScale = fontScale * 96f / DrawUtils.ScreenDpi;
- context.cache = InlineImageCache;
- context.isPrinting = isPrinting;
- context.isDifferentTabPositions = TabPositions.Count > 0;
- context.keepLastLineSpace = this.PreserveLastLineSpace;
- return new HtmlTextRenderer(context);
- #else
- bool isDifferentTabPositions = TabPositions.Count > 0;
- return new HtmlTextRenderer(text, g, font.FontFamily, font.Size, font.Style, TextColor,
- textOutline.Color, textRect, Underlines,
- format, horzAlign, vertAlign, ParagraphFormat.MultipleScale(formatScale), ForceJustify,
- scale * 96f / DrawUtils.ScreenDpi, fontScale * 96f / DrawUtils.ScreenDpi, InlineImageCache,
- isPrinting, isDifferentTabPositions);
- #endif
- }
- /// <summary>
- /// Draws a text.
- /// </summary>
- /// <param name="e">Paint event data.</param>
- public void DrawText(FRPaintEventArgs e)
- {
- string text = GetDisplayText();
- if (!String.IsNullOrEmpty(text))
- {
- IGraphics g = e.Graphics;
- RectangleF textRect = new RectangleF(
- (AbsLeft + Padding.Left) * e.ScaleX,
- (AbsTop + Padding.Top) * e.ScaleY,
- (Width - Padding.Horizontal) * e.ScaleX,
- (Height - Padding.Vertical) * e.ScaleY);
- if (ParagraphOffset != 0 && IsDesigning)
- text = MakeParagraphOffset(text);
- StringFormat format = GetStringFormat(e.Cache, 0, e.ScaleX);
- Font font = e.Cache.GetFont(Font.FontFamily,
- IsPrinting ? Font.Size : Font.Size * e.ScaleX * 96f / DrawUtils.ScreenDpi,
- Font.Style);
- Brush textBrush = null;
- if (TextFill is SolidFill)
- textBrush = e.Cache.GetBrush((TextFill as SolidFill).Color);
- else
- textBrush = TextFill.CreateBrush(textRect, e.ScaleX, e.ScaleY);
- Pen outlinePen = null;
- if (textOutline.Enabled)
- outlinePen = e.Cache.GetPen(textOutline.Color, textOutline.Width * e.ScaleX, textOutline.Style);
- Report report = Report;
- if (report != null && report.TextQuality != TextQuality.Default)
- g.TextRenderingHint = report.GetTextQuality();
- if (textRect.Width > 0 && textRect.Height > 0)
- {
- switch (TextRenderType)
- {
- case TextRenderType.Inline:
- g.DrawString(text, font, textBrush, textRect.X, textRect.Y, StringFormat.GenericTypographic);
- break;
- case TextRenderType.HtmlParagraph:
- try
- {
- using (HtmlTextRenderer htmlRenderer = GetHtmlTextRenderer(text, e.Graphics, e.ScaleX,
- IsPrinting ? 1 : e.ScaleX, IsPrinting ? 1 / (96f / DrawUtils.ScreenDpi) : e.ScaleX, textRect, format, IsPrinting))
- {
- htmlRenderer.Draw();
- }
- }
- catch
- {
- textBrush.Dispose();
- textBrush = null;
- }
- break;
- default:
- if (IsAdvancedRendererNeeded)
- {
- // use advanced rendering
- AdvancedTextRenderer advancedRenderer = new AdvancedTextRenderer(text, g, font, textBrush,
- outlinePen, textRect, format, HorzAlign, VertAlign, LineHeight * e.ScaleY, Angle,
- FontWidthRatio, ForceJustify, Wysiwyg, HasHtmlTags, false,
- e.ScaleX * 96f / DrawUtils.ScreenDpi,
- IsPrinting ? 1 : e.ScaleX * 96f / DrawUtils.ScreenDpi, InlineImageCache, IsPrinting);
- advancedRenderer.Draw();
- }
- else
- {
- // use simple rendering
- if (Angle == 0 && FontWidthRatio == 1)
- {
- if (outlinePen == null)
- {
- if (WordWrap)
- format.Trimming = StringTrimming.Word;
- g.DrawString(text, font, textBrush, textRect, format);
- }
- else
- {
- GraphicsPath path = new GraphicsPath();
- path.AddString(text, font.FontFamily, Convert.ToInt32(font.Style),
- g.DpiY * font.Size / 72, textRect, format);
- IGraphicsState state = g.Save();
- g.SetClip(textRect);
- //g.FillPath(textBrush, path);
- //regime for text output with drawbehind
- if (TextOutline.DrawBehind)
- {
- g.DrawPath(outlinePen, path);
- g.FillPath(textBrush, path);
- }
- else //without. default
- {
- g.FillAndDrawPath(outlinePen, textBrush, path);
- }
- g.Restore(state);
- }
- }
- else
- StandardTextRenderer.Draw(text, g, font, textBrush, outlinePen, textRect, format, Angle,
- FontWidthRatio);
- }
- DrawUnderlines(e);
- break;
- }
- }
- if (!(TextFill is SolidFill))
- {
- textBrush.Dispose();
- }
- }
- }
- /// <inheritdoc/>
- public override void Draw(FRPaintEventArgs e)
- {
- base.Draw(e);
- DrawText(e);
- DrawMarkers(e);
- Border.Draw(e, new RectangleF(AbsLeft, AbsTop, Width, Height));
- DrawDesign(e);
- }
- /// <inheritdoc/>
- public override void ApplyStyle(Style style)
- {
- if (style.ApplyTextFill)
- TextFill = style.TextFill.Clone();
- if (style.ApplyFont)
- Font = style.Font;
- base.ApplyStyle(style);
- }
- /// <inheritdoc/>
- public override void SaveStyle()
- {
- base.SaveStyle();
- savedTextFill = TextFill;
- savedFont = Font;
- }
- /// <inheritdoc/>
- public override void RestoreStyle()
- {
- base.RestoreStyle();
- TextFill = savedTextFill;
- Font = savedFont;
- }
- /// <inheritdoc/>
- public override void Serialize(FRWriter writer)
- {
- if (writer.SerializeTo == SerializeTo.Preview && AutoWidth)
- {
- WordWrap = false;
- float width = CalcSize().Width;
- if ((Anchor & AnchorStyles.Right) != 0 || HorzAlign == HorzAlign.Right)
- Left = Right - width;
- if (HorzAlign == HorzAlign.Center)
- Left += Width / 2 - width / 2;
- Width = width;
- }
- TextObject c = writer.DiffObject as TextObject;
- base.Serialize(writer);
- if (c == null)
- return; // RichObject here
- if (AutoWidth != c.AutoWidth)
- writer.WriteBool("AutoWidth", AutoWidth);
- if (AutoShrink != c.AutoShrink)
- writer.WriteValue("AutoShrink", AutoShrink);
- if (FloatDiff(AutoShrinkMinSize, c.AutoShrinkMinSize))
- writer.WriteFloat("AutoShrinkMinSize", AutoShrinkMinSize);
- if (HorzAlign != c.HorzAlign)
- writer.WriteValue("HorzAlign", HorzAlign);
- if (VertAlign != c.VertAlign)
- writer.WriteValue("VertAlign", VertAlign);
- if (Angle != c.Angle)
- writer.WriteInt("Angle", Angle);
- if (RightToLeft != c.RightToLeft)
- writer.WriteBool("RightToLeft", RightToLeft);
- if (WordWrap != c.WordWrap)
- writer.WriteBool("WordWrap", WordWrap);
- if (Underlines != c.Underlines)
- writer.WriteBool("Underlines", Underlines);
- if ((writer.SerializeTo != SerializeTo.Preview || !Font.Equals(c.Font)) && writer.ItemName != "inherited")
- writer.WriteValue("Font", Font);
- TextFill.Serialize(writer, "TextFill", c.TextFill);
- if (TextOutline != null)
- TextOutline.Serialize(writer, "TextOutline", c.TextOutline);
- if (Trimming != c.Trimming)
- writer.WriteValue("Trimming", Trimming);
- if (FontWidthRatio != c.FontWidthRatio)
- writer.WriteFloat("FontWidthRatio", FontWidthRatio);
- if (FirstTabOffset != c.FirstTabOffset)
- writer.WriteFloat("FirstTabOffset", FirstTabOffset);
- if (TabWidth != c.TabWidth)
- writer.WriteFloat("TabWidth", TabWidth);
- if (TabPositions.Count > 0)
- writer.WriteValue("TabPositions", TabPositions);
- if (Clip != c.Clip)
- writer.WriteBool("Clip", Clip);
- if (Wysiwyg != c.Wysiwyg)
- writer.WriteBool("Wysiwyg", Wysiwyg);
- if (LineHeight != c.LineHeight)
- writer.WriteFloat("LineHeight", LineHeight);
- if (TextRenderType != c.TextRenderType)
- writer.WriteValue("TextRenderType", TextRenderType);
- if (ParagraphOffset != c.ParagraphOffset)
- writer.WriteFloat("ParagraphOffset", ParagraphOffset);
- if (ForceJustify != c.ForceJustify)
- writer.WriteBool("ForceJustify", ForceJustify);
- if (MergeMode != c.MergeMode)
- writer.WriteValue("MergeMode", MergeMode);
- if (writer.SerializeTo != SerializeTo.Preview)
- {
- if (Style != c.Style)
- writer.WriteStr("Style", Style);
- if (Highlight.Count > 0)
- writer.Write(Highlight);
- }
- if (ParagraphFormat.FirstLineIndent != 0)
- writer.WriteFloat("ParagraphFormat.FirstLineIndent", ParagraphFormat.FirstLineIndent);
- if (ParagraphFormat.LineSpacing > 0)
- writer.WriteFloat("ParagraphFormat.LineSpacing", ParagraphFormat.LineSpacing);
- if (ParagraphFormat.LineSpacingType != LineSpacingType.Single)
- writer.WriteValue("ParagraphFormat.LineSpacingType", ParagraphFormat.LineSpacingType);
- if (ParagraphFormat.SkipFirstLineIndent)
- writer.WriteBool("ParagraphFormat.SkipFirstLineIndent", ParagraphFormat.SkipFirstLineIndent);
- StringBuilder sb = null;
- if (InlineImageCache != null && writer.BlobStore != null && HasHtmlTags == true)
- foreach (InlineImageCache.CacheItem item in InlineImageCache.AllItems())
- {
- if (item.Src.StartsWith("data:")) continue;
- if (sb == null)
- sb = new StringBuilder();
- sb.Append(writer.BlobStore.AddOrUpdate(item.Stream, item.Src))
- .Append(',');
- }
- if (sb != null)
- {
- sb.Length--;
- writer.WriteStr("InlineImageCacheIndexes", sb.ToString());
- }
- }
- /// <inheritdoc/>
- public override void Deserialize(FRReader reader)
- {
- base.Deserialize(reader);
- TextFill.Deserialize(reader, "TextFill");
- if (reader.BlobStore != null)
- {
- string indexes = reader.ReadStr("InlineImageCacheIndexes");
- if (indexes != "null" && !String.IsNullOrEmpty(indexes))
- {
- string[] arr = indexes.Split(',');
- foreach (string index in arr)
- {
- int val = 0;
- if (Int32.TryParse(index, out val))
- {
- if (val >= 0 && val < reader.BlobStore.Count)
- {
- InlineImageCache.CacheItem it = new InlineImageCache.CacheItem();
- it.Set(reader.BlobStore.Get(val));
- InlineImageCache.Set(reader.BlobStore.GetSource(val), it);
- }
- }
- }
- }
- }
- switch (reader.DeserializeFrom)
- {
- case SerializeTo.Undo:
- case SerializeTo.Preview:
- case SerializeTo.Clipboard:
- // skip
- break;
- default:
- if (!reader.HasProperty("Font") && reader.ItemName != "inherited")
- {
- string creatorVersion = reader.Root.GetProp("ReportInfo.CreatorVersion");
- if (!String.IsNullOrEmpty(creatorVersion))
- {
- try
- {
- string[] versions = creatorVersion.Split('.');
- int major = 0;
- if (Int32.TryParse(versions[0], out major))
- {
- if (major < 2016)
- {
- Font = new Font("Arial", 10);
- }
- }
- }
- catch
- {
- }
- }
- }
- break;
- }
- }
- public override void InitializeComponent()
- {
- base.InitializeComponent();
- TextFill.InitializeComponent();
- }
- public override void FinalizeComponent()
- {
- base.FinalizeComponent();
- TextFill.FinalizeComponent();
- }
- internal void ApplyCondition(HighlightCondition c)
- {
- if (c.ApplyBorder)
- Border = c.Border.Clone();
- if (c.ApplyFill)
- Fill = c.Fill.Clone();
- if (c.ApplyTextFill)
- TextFill = c.TextFill.Clone();
- if (c.ApplyFont)
- Font = c.Font;
- Visible = c.Visible;
- }
- #endregion
- #region Report Engine
- /// <inheritdoc/>
- public override string[] GetExpressions()
- {
- List<string> expressions = new List<string>();
- expressions.AddRange(base.GetExpressions());
- if (AllowExpressions && !String.IsNullOrEmpty(Brackets))
- {
- string[] brackets = Brackets.Split(',');
- // collect expressions found in the text
- expressions.AddRange(CodeUtils.GetExpressions(Text, brackets[0], brackets[1]));
- }
- // add highlight conditions
- foreach (HighlightCondition condition in Highlight)
- {
- expressions.Add(condition.Expression);
- }
- return expressions.ToArray();
- }
- /// <inheritdoc/>
- public override void SaveState()
- {
- base.SaveState();
- savedText = Text;
- savedTextFill = TextFill;
- savedFont = Font;
- savedFormat = Format;
- }
- /// <inheritdoc/>
- public override void RestoreState()
- {
- base.RestoreState();
- Text = savedText;
- TextFill = savedTextFill;
- Font = savedFont;
- Format = savedFormat;
- }
- /// <summary>
- /// Calculates the object's width.
- /// </summary>
- /// <returns>The width, in pixels.</returns>
- public float CalcWidth()
- {
- if (Angle == 90 || Angle == 270)
- return InternalCalcHeight();
- return InternalCalcWidth();
- }
- /// <inheritdoc/>
- public override float CalcHeight()
- {
- if (Angle == 90 || Angle == 270)
- return InternalCalcWidth();
- return InternalCalcHeight();
- }
- /// <inheritdoc/>
- public override void GetData()
- {
- base.GetData();
- // process expressions
- if (AllowExpressions)
- {
- if (!String.IsNullOrEmpty(Brackets))
- {
- string[] brackets = Brackets.Split(',');
- FindTextArgs args = new FindTextArgs();
- args.Text = new FastString(Text);
- args.OpenBracket = brackets[0];
- args.CloseBracket = brackets[1];
- int expressionIndex = 0;
- while (args.StartIndex < args.Text.Length)
- {
- string expression = CodeUtils.GetExpression(args, false);
- if (expression == null)
- break;
- //if (!Report.IsCompileNeeded)
- //{
- // expression = Text;
- //}
- string formattedValue = CalcAndFormatExpression(expression, expressionIndex);
- args.Text.Remove(args.StartIndex, args.EndIndex - args.StartIndex);
- args.Text.Insert(args.StartIndex, formattedValue);
- args.StartIndex += formattedValue.Length;
- expressionIndex++;
- }
- Text = args.Text.ToString();
- }
- }
- // process highlight
- Variant varValue = new Variant(Value);
- foreach (HighlightCondition condition in Highlight)
- {
- try
- {
- object val = Report.Calc(condition.Expression, varValue);
- if (val != null && (bool)val == true)
- {
- ApplyCondition(condition);
- break;
- }
- }
- catch (Exception e)
- {
- throw new Exception(Name + ": " + Res.Get("Messages,ErrorInHighlightCondition") + ": " + condition.Expression, e.InnerException);
- }
- }
- // make paragraph offset
- if (ParagraphOffset != 0)
- Text = MakeParagraphOffset(Text);
- // process AutoShrink
- ProcessAutoShrink();
- }
- /// <inheritdoc/>
- public override bool Break(BreakableComponent breakTo, out float excessiveHeight)
- {
- excessiveHeight = 0;
- switch (TextRenderType)
- {
- case TextRenderType.HtmlParagraph:
- bool endOnEnter;
- string breakTextHtml = BreakTextHtml(out endOnEnter, out excessiveHeight);
- if (breakTextHtml != null && breakTo != null)
- {
- (breakTo as TextObject).Text = breakTextHtml;
- if (!endOnEnter)
- (breakTo as TextObject).ParagraphFormat.SkipFirstLineIndent = true;
- }
- return breakTextHtml != null;
- default:
- string breakText = BreakText();
- if (breakText != null && breakTo != null)
- (breakTo as TextObject).Text = breakText;
- return breakText != null;
- }
- }
- /// <inheritdoc/>
- public override bool Break(BreakableComponent breakTo)
- {
- float excessiveHeight = 0;
- return Break(breakTo, out excessiveHeight);
- }
- internal IEnumerable<PictureObject> GetPictureFromHtmlText(AdvancedTextRenderer renderer)
- {
- if (renderer == null)
- {
- using (Bitmap b = new Bitmap(1, 1))
- using (IGraphics g = new GdiGraphics(b))
- {
- RectangleF textRect = new RectangleF(
- (AbsLeft + Padding.Left),
- (AbsTop + Padding.Top),
- (Width - Padding.Horizontal),
- (Height - Padding.Vertical));
- StringFormat format = GetStringFormat(Report.GraphicCache, StringFormatFlags.LineLimit);
- renderer = new AdvancedTextRenderer(Text, g, Font, Brushes.Black, Pens.Black,
- textRect, format, HorzAlign, VertAlign, LineHeight, Angle, FontWidthRatio,
- ForceJustify, Wysiwyg, HasHtmlTags, false, 1, 1,
- InlineImageCache);
- foreach (PictureObject obj in GetPictureFromHtmlText(renderer))
- yield return obj;
- }
- }
- else
- {
- RectangleF textRect = renderer.DisplayRect;
- foreach (AdvancedTextRenderer.Paragraph paragraph in renderer.Paragraphs)
- foreach (AdvancedTextRenderer.Line line in paragraph.Lines)
- foreach (AdvancedTextRenderer.Word word in line.Words)
- foreach (AdvancedTextRenderer.Run run in word.Runs)
- if (run is AdvancedTextRenderer.RunImage)
- {
- AdvancedTextRenderer.RunImage runImage = run as AdvancedTextRenderer.RunImage;
- PictureObject obj = new PictureObject();
- float left = runImage.Left - textRect.Left;
- float top = runImage.Top - textRect.Top;
- float width =
- runImage.Left + runImage.Width > textRect.Right ?
- textRect.Right - (left < 0 ? textRect.Left : runImage.Left) :
- (
- runImage.Left < textRect.Left ?
- runImage.Left + runImage.Width - textRect.Left :
- runImage.Width
- );
- float height =
- runImage.Top + runImage.Height > textRect.Bottom ?
- textRect.Bottom - (top < 0 ? textRect.Top : runImage.Top) :
- (
- runImage.Top < textRect.Top ?
- runImage.Top + runImage.Height - textRect.Top :
- runImage.Height
- );
- if (left < 0 || top < 0 || width < runImage.Width || height < runImage.Height)
- {
- Bitmap bmp = new Bitmap((int)width, (int)height);
- using (Graphics g = Graphics.FromImage(bmp))
- {
- g.DrawImage(runImage.Image, new PointF(
- left < 0 ? left : 0,
- top < 0 ? top : 0
- ));
- }
- obj.Image = bmp;
- obj.Left = (left < 0 ? textRect.Left : runImage.Left) / renderer.Scale;
- obj.Top = (top < 0 ? textRect.Top : runImage.Top) / renderer.Scale;
- obj.Width = width / renderer.Scale;
- obj.Height = height / renderer.Scale;
- obj.SizeMode = PictureBoxSizeMode.StretchImage;
- }
- else
- {
- obj.Image = runImage.Image;
- obj.Left = runImage.Left / renderer.Scale;
- obj.Top = runImage.Top / renderer.Scale;
- obj.Width = runImage.Width / renderer.Scale;
- obj.Height = runImage.Height / renderer.Scale;
- obj.SizeMode = PictureBoxSizeMode.StretchImage;
- }
- yield return obj;
- }
- }
- }
- #endregion
- /// <summary>
- /// Initializes a new instance of the <see cref="TextObject"/> class with default settings.
- /// </summary>
- public TextObject()
- {
- paragraphFormat = new ParagraphFormat();
- wordWrap = true;
- font = DrawUtils.DefaultReportFont;
- textFill = new SolidFill(Color.Black);
- textOutline = new TextOutline();
- trimming = StringTrimming.None;
- fontWidthRatio = 1;
- tabWidth = 58;
- tabPositions = new FloatCollection();
- clip = true;
- highlight = new ConditionCollection();
- FlagSerializeStyle = false;
- SetFlags(Flags.HasSmartTag, true);
- preserveLastLineSpace = false;
- }
- }
- }
|