using FastReport.Utils; using System; using System.Collections; using System.Drawing; using System.Drawing.Drawing2D; namespace FastReport { /// /// Represents a cache of graphics objects such as pens, brushes, fonts and text formats. /// /// /// Cache holds all used graphics objects. There is no need to dispose objects returned /// by GetXXX calls. /// /// This example demonstrates how to use graphic cache. /// /// public void Draw(FRPaintEventArgs e) /// { /// Brush brush = e.Cache.GetBrush(BackColor); /// Pen pen = e.Cache.GetPen(BorderColor, 1, BorderStyle); /// e.Graphics.FillRectangle(brush, Bounds); /// e.Graphics.DrawRectangle(pen, Bounds); /// } /// /// public class GraphicCache : IDisposable { private Hashtable pens; private Hashtable brushes; private Hashtable fonts; private Hashtable stringFormats; /// /// Gets a pen with specified settings. /// /// Color of a pen. /// Width of a pen. /// Dash style of a pen. /// The Pen object. public Pen GetPen(Color color, float width, DashStyle style) { return GetPen(color, width, style, LineJoin.Miter); } /// /// Gets a pen with specified settings. /// /// Color of a pen. /// Width of a pen. /// Dash style of a pen. /// Line join of a pen. /// The Pen object. public Pen GetPen(Color color, float width, DashStyle style, LineJoin lineJoin) { int hash = color.GetHashCode() ^ width.GetHashCode() ^ style.GetHashCode() ^ lineJoin.GetHashCode(); Pen result = pens[hash] as Pen; if (result == null) { result = new Pen(color, width); result.DashStyle = style; result.LineJoin = lineJoin; pens[hash] = result; } return result; } /// /// Gets a brush with specified color. /// /// Color of a brush. /// The SolidBrush object. public SolidBrush GetBrush(Color color) { int hash = color.GetHashCode(); SolidBrush result = brushes[hash] as SolidBrush; if (result == null) { result = new SolidBrush(color); brushes[hash] = result; } return result; } /// /// Gets a font with specified settings. /// /// Family of a font. /// Size of a font. /// Style of a font. /// The Font object. public Font GetFont(FontFamily name, float size, FontStyle style) { int hash = name.GetHashCode() ^ size.GetHashCode() ^ style.GetHashCode(); Font result = fonts[hash] as Font; if (result == null) { result = new Font(name, size, style); fonts[hash] = result; } return result; } /// /// Gets a string format with specified settings. /// /// Text alignment information on the vertical plane. /// Line alignment on the horizontal plane. /// StringTrimming enumeration. /// StringFormatFlags enumeration that contains formatting information. /// The number of spaces between the beginning of a line of text and the first tab stop. /// Distance between tab stops. /// The StringFormat object. public StringFormat GetStringFormat(StringAlignment align, StringAlignment lineAlign, StringTrimming trimming, StringFormatFlags flags, float firstTab, float tabWidth) { int hash = align.GetHashCode() ^ (lineAlign.GetHashCode() << 2) ^ (trimming.GetHashCode() << 5) ^ (flags.GetHashCode() << 16) ^ (100 - firstTab).GetHashCode() ^ tabWidth.GetHashCode(); StringFormat result = stringFormats[hash] as StringFormat; if (result == null) { result = new StringFormat(); result.Alignment = align; result.LineAlignment = lineAlign; result.Trimming = trimming; result.FormatFlags = flags; float[] tabStops = new float[64]; // fixed issue 2823 tabStops[0] = firstTab; for (int i = 1; i < 64; i++) { tabStops[i] = tabWidth; } result.SetTabStops(0, tabStops); stringFormats[hash] = result; } return result; } /// /// Gets a string format with specified settings. /// /// Text alignment information on the vertical plane. /// Line alignment on the horizontal plane. /// StringTrimming enumeration. /// StringFormatFlags enumeration that contains formatting information. /// The number of spaces between the beginning of a line of text and the first tab stop. /// Distance between tab stops. /// Default distance between default tabs stops. /// The StringFormat object. public StringFormat GetStringFormat(StringAlignment align, StringAlignment lineAlign, StringTrimming trimming, StringFormatFlags flags, float firstTab, FloatCollection tabWidth, float defaultTab = 48) { int hash = align.GetHashCode() ^ (lineAlign.GetHashCode() << 2) ^ (trimming.GetHashCode() << 5) ^ (flags.GetHashCode() << 16) ^ (100 - firstTab).GetHashCode() ^ tabWidth.GetHashCode(); StringFormat result = stringFormats[hash] as StringFormat; if (result == null) { result = new StringFormat(); result.Alignment = align; result.LineAlignment = lineAlign; result.Trimming = trimming; result.FormatFlags = flags; float[] tabStops = new float[64]; // fixed issue 2823 tabStops[0] = firstTab; for (int i = 1; i < 64; i++) { if (i > tabWidth.Count) { tabStops[i] = defaultTab; continue; } tabStops[i] = tabWidth[i - 1]; } result.SetTabStops(0, tabStops); stringFormats[hash] = result; } return result; } /// /// Disposes resources used by this object. /// public void Dispose() { foreach (Pen pen in pens.Values) { pen.Dispose(); } foreach (Brush brush in brushes.Values) { brush.Dispose(); } foreach (Font font in fonts.Values) { font.Dispose(); } foreach (StringFormat format in stringFormats.Values) { format.Dispose(); } pens.Clear(); brushes.Clear(); fonts.Clear(); stringFormats.Clear(); } /// /// Initializes a new instance of the GraphicCache class with default settings. /// public GraphicCache() { pens = new Hashtable(); brushes = new Hashtable(); fonts = new Hashtable(); stringFormats = new Hashtable(); } } }