/// /// This file is part of ILNumerics Community Edition. /// /// ILNumerics Community Edition - high performance computing for applications. /// Copyright (C) 2006 - 2012 Haymo Kutschbach, http://ilnumerics.net /// /// ILNumerics Community Edition is free software: you can redistribute it and/or modify /// it under the terms of the GNU General Public License version 3 as published by /// the Free Software Foundation. /// /// ILNumerics Community Edition is distributed in the hope that it will be useful, /// but WITHOUT ANY WARRANTY; without even the implied warranty of /// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the /// GNU General Public License for more details. /// /// You should have received a copy of the GNU General Public License /// along with ILNumerics Community Edition. See the file License.txt in the root /// of your distribution package. If not, see . /// /// In addition this software uses the following components and/or licenses: /// /// ================================================================================= /// The Open Toolkit Library License /// /// Copyright (c) 2006 - 2009 the Open Toolkit library. /// /// Permission is hereby granted, free of charge, to any person obtaining a copy /// of this software and associated documentation files (the "Software"), to deal /// in the Software without restriction, including without limitation the rights to /// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of /// the Software, and to permit persons to whom the Software is furnished to do /// so, subject to the following conditions: /// /// The above copyright notice and this permission notice shall be included in all /// copies or substantial portions of the Software. /// /// ================================================================================= /// using System; using System.Text; using System.Drawing; using System.Collections.Generic; using ILNumerics.Drawing; using ILNumerics.Drawing.Interfaces; namespace ILNumerics.Drawing.Labeling { /// /// Transforms characters into bitmaps (1:1) /// /// this is the base class for most IILTextInterpreter implementations public class ILSimpleInterpreter : IILTextInterpreter { #region attributes static Graphics m_measGraphics; static Bitmap m_measBitmap; protected Font m_normalFont; protected Size m_size; #endregion #region constructor /// /// create a new instance of this text interpreter /// public ILSimpleInterpreter () : base () { resizeMeasureBMP(20,20); } #endregion #region helper functions protected void resizeMeasureBMP(int width, int height) { if (m_measBitmap != null) m_measBitmap.Dispose(); if (m_measGraphics != null) m_measGraphics.Dispose(); m_measBitmap = new Bitmap(width+1,height+1); m_measGraphics = Graphics.FromImage(m_measBitmap); } protected virtual void parseString (string expression, Font font, Point offset, Color color, IILTextRenderer renderer, ref Size size, ref List queue) { int pos = 0; string key, itemText; RectangleF bmpSize = new RectangleF(); int curHeigth = 0, curWidth = 0; Bitmap itemBMP = null; int lineHeight = 0, lineWidth = 0; Size itemSize = Size.Empty; while (pos < expression.Length) { itemText = expression.Substring(pos++,1); key = ILHashCreator.Hash(font,itemText); if (renderer.TryGetSize(key, ref itemSize)) { queue.Add(new ILRenderQueueItem(key,offset,color)); if (itemSize.Height > lineHeight) lineHeight = itemSize.Height; lineWidth += (int)itemSize.Width; } else { lock (this) { itemBMP = transformItem(itemText,font,out bmpSize); renderer.Cache(key,itemBMP,bmpSize); queue.Add(new ILRenderQueueItem(key,offset,color)); // update size if (bmpSize.Height > lineHeight) lineHeight = (int)bmpSize.Height; lineWidth += (int)bmpSize.Width; } } } size.Width += ((curWidth>lineWidth)?curWidth:lineWidth); size.Height = curHeigth + lineHeight; } /// /// Render a string onto a bitmap and measure exact size /// /// item to be rendered /// font used for rendering /// [output] size of the rendered item /// bitmap containing the item public Bitmap TransformItem (string item, Font font, out RectangleF size) { Bitmap ret = transformItem(item,font,out size); return ret.Clone(Rectangle.Round(size),ret.PixelFormat); } /// /// Render a string onto a bitmap and measure exact size /// /// item to be rendered /// font used for rendering /// [output] size of the rendered item /// bitmap containing the item protected Bitmap transformItem(string item, Font font, out RectangleF size) { if (String.IsNullOrEmpty(item)) { size = new RectangleF(0,0,1,1); return m_measBitmap; } if (item == " ") { size = new RectangleF (new PointF(0,0),m_measGraphics.MeasureString(item,font)); if (size.Right >= m_measBitmap.Width || size.Bottom >= m_measBitmap.Height) { resizeMeasureBMP((int)size.Right+15,(int)size.Bottom+15); return transformItem(item,font,out size); } m_measGraphics.Clear(Color.Transparent); return m_measBitmap; } StringFormat sformat = StringFormat.GenericDefault; sformat.FormatFlags = StringFormatFlags.NoWrap | StringFormatFlags.NoClip | StringFormatFlags.MeasureTrailingSpaces; sformat.SetMeasurableCharacterRanges(new CharacterRange[]{new CharacterRange(0,item.Length)}); // draw the text if (font.SizeInPoints < 16) { m_measGraphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit; } else { m_measGraphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias; } RectangleF layout = new RectangleF(0,0,m_measBitmap.Width,m_measBitmap.Height); m_measGraphics.Clear(Color.Transparent); m_measGraphics.DrawString(item,font,Brushes.White,layout,sformat); // measure bounds Region[] reg = m_measGraphics.MeasureCharacterRanges(item,font,layout,sformat); size = reg[0].GetBounds(m_measGraphics); size.Width += 1; size.Height += 1; // compensate //size = new RectangleF((size.Left>0)?size.Left-1:size.Left,size.Top,size.Width,size.Height); #if EXPORTBMP // debug support only if (true) { Bitmap debBitmap = (Bitmap)m_measBitmap.Clone(); Graphics debGrap = Graphics.FromImage(debBitmap); //debGrap.Clear(Color.White); //debGrap.DrawString(item,font,Brushes.Black,layout,sformat); debGrap.DrawRectangle(new Pen(Brushes.Red),Rectangle.Round(size)); debBitmap.Save("EXPORTBMP_transformItemResult.bmp",System.Drawing.Imaging.ImageFormat.Bmp); } #endif if (size.Right >= m_measBitmap.Width || size.Bottom >= m_measBitmap.Height) { resizeMeasureBMP((int)size.Right+15,(int)size.Bottom+15); return transformItem(item,font,out size); } return m_measBitmap; } #endregion #region IILTextInterpreter Member /// /// Transforms an expression into render queue definition /// /// expression to be transformed /// font may used for transformation /// standard color used for transformation /// IILTextRenderer instance used for caching (and later rendering) /// render queue, later used to render the visual representation of the expression /// the expression may contain markups. See the online help at http://ilnumerics.net /// for a detailed descriptioin of known symbols and their syntax. public ILRenderQueue Transform(string expression, Font font, Color color, IILTextRenderer renderer) { List ret = new List(); Size size = Size.Empty; m_normalFont = font; parseString(expression,font,new Point(),color,renderer,ref size,ref ret); return new ILRenderQueue(expression, ret, size); } /// /// Render text expression into bitmap /// /// text expression /// font used for rendering /// Bitmap with rendered expression /// The size of the bitmap returned will tightly fit around the rendered content. public virtual Bitmap Transform(string expression, Font font) { RectangleF size; Bitmap ret = transformItem(expression, font, out size); return ret.Clone(size,ret.PixelFormat); } /// /// Render text expression into bitmap /// /// text expression /// Bitmap with rendered expression /// The size of the bitmap returned will tightly fit around the rendered content. /// A generic sans serif font of size 10em will be used. public virtual Bitmap Transform(string expression) { Font font = new Font(FontFamily.GenericSansSerif,10f,FontStyle.Regular); RectangleF size; Bitmap ret = transformItem(expression, font, out size); return ret.Clone(size,ret.PixelFormat); } #endregion } }