Font.cs :  » Game » SDL » SdlDotNet » Graphics » C# / CSharp Open Source

Home
C# / CSharp Open Source
1.2.6.4 mono .net core
2.2.6.4 mono core
3.Aspect Oriented Frameworks
4.Bloggers
5.Build Systems
6.Business Application
7.Charting Reporting Tools
8.Chat Servers
9.Code Coverage Tools
10.Content Management Systems CMS
11.CRM ERP
12.Database
13.Development
14.Email
15.Forum
16.Game
17.GIS
18.GUI
19.IDEs
20.Installers Generators
21.Inversion of Control Dependency Injection
22.Issue Tracking
23.Logging Tools
24.Message
25.Mobile
26.Network Clients
27.Network Servers
28.Office
29.PDF
30.Persistence Frameworks
31.Portals
32.Profilers
33.Project Management
34.RSS RDF
35.Rule Engines
36.Script
37.Search Engines
38.Sound Audio
39.Source Control
40.SQL Clients
41.Template Engines
42.Testing
43.UML
44.Web Frameworks
45.Web Service
46.Web Testing
47.Wiki Engines
48.Windows Presentation Foundation
49.Workflows
50.XML Parsers
C# / C Sharp
C# / C Sharp by API
C# / CSharp Tutorial
C# / CSharp Open Source » Game » SDL 
SDL » SdlDotNet » Graphics » Font.cs
#region LICENSE
/*
 * Copyright (C) 2004 - 2007 David Hudson (jendave@yahoo.com)
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * 
 * This library 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
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
#endregion LICENSE

using System;
using System.Drawing;
using System.Runtime.InteropServices;

using SdlDotNet;
using SdlDotNet.Core;
using Tao.Sdl;

namespace SdlDotNet.Graphics{
    #region Styles

    /// <summary>
    /// Text Style
    /// </summary>
    /// <remarks></remarks>
    [FlagsAttribute]
    public enum Styles
    {
        /// <summary>
        /// Normal.
        /// </summary>
        /// <remarks>
        /// FXCop wants this to be called 'None' instead of 'Normal'
        /// </remarks>
        None = SdlTtf.TTF_STYLE_NORMAL,
        /// <summary>
        /// Bold
        /// </summary>
        Bold = SdlTtf.TTF_STYLE_BOLD,
        /// <summary>
        /// Italic
        /// </summary>
        Italic = SdlTtf.TTF_STYLE_ITALIC,
        /// <summary>
        /// Underline
        /// </summary>
        Underline = SdlTtf.TTF_STYLE_UNDERLINE
    }

    #endregion

    /// <summary>
    /// Font Class.
    /// </summary>
    /// <remarks>
    /// This class is used to instantiate fonts in an SDL.NET application.
    /// </remarks>
    public class Font : BaseSdlResource
    {
        #region Private fields

        private bool disposed;

        #endregion

        #region Constructors

        /// <summary>
        /// Font Constructor
        /// </summary>
        /// <param name="fileName">Font filename</param>
        /// <param name="pointSize">Size of font</param>
        public Font(string fileName, int pointSize)
        {
            if (!Font.IsFontSystemInitialized)
            {
                Font.InitializeFontSystem();
            }

            this.Handle = SdlTtf.TTF_OpenFont(fileName, pointSize);
            if (this.Handle == IntPtr.Zero)
            {
                throw FontException.Generate();
            }
        }

        /// <summary>
        /// Create a Font from a byte array in memory.
        /// </summary>
        /// <param name="array">A array of byte that should be the font data</param>
        /// <param name="pointSize">Size of font</param>
        public Font(byte[] array, int pointSize)
        {
            if (array == null)
            {
                throw new ArgumentNullException("array");
            }
            if (!Font.IsFontSystemInitialized)
            {
                Font.InitializeFontSystem();
            }

            this.Handle = SdlTtf.TTF_OpenFontRW(Sdl.SDL_RWFromMem(array, array.Length), 0, pointSize);
            if (this.Handle == IntPtr.Zero)
            {
                throw FontException.Generate();
            }
        }

        #endregion Constructors

        #region Private methods

        /// <summary>
        /// Queries if the Font subsystem has been intialized.
        /// </summary>
        /// <remarks>
        /// </remarks>
        /// <returns>True if Font subsystem has been initialized, false if it has not.</returns>
        private static bool IsFontSystemInitialized
        {
            get
            {

                if (SdlTtf.TTF_WasInit() == (int)SdlFlag.TrueValue)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
        }

        /// <summary>
        /// Initialize Font subsystem.
        /// </summary>
        private static void InitializeFontSystem()
        {
            if (SdlTtf.TTF_Init() != (int)SdlFlag.Success)
            {
                FontException.Generate();
            }
        }

        /// <summary>
        /// Render Text to Solid
        /// </summary>
        /// <param name="textItem">String to display</param>
        /// <param name="color">Color of text</param>
        /// <returns>Surface containing the text</returns>
        private Surface RenderTextSolid(string textItem, Color color)
        {
            Sdl.SDL_Color colorSdl = SdlColor.ConvertColor(color);
            return new Surface(SdlTtf.TTF_RenderUNICODE_Solid(this.Handle, textItem, colorSdl));
        }

        /// <summary>
        /// Shade text
        /// </summary>
        /// <param name="textItem"></param>
        /// <param name="backgroundColor"></param>
        /// <param name="textColor"></param>
        /// <returns></returns>
        private Surface RenderTextShaded(
            string textItem, Color textColor, Color backgroundColor)
        {
            Sdl.SDL_Color textColorSdl =
                SdlColor.ConvertColor(textColor);
            Sdl.SDL_Color backgroundColorSdl =
                SdlColor.ConvertColor(backgroundColor);
            if (textItem == null || textItem.Length == 0)
            {
                textItem = " ";
            }
            return new Surface(SdlTtf.TTF_RenderUNICODE_Shaded(
                this.Handle, textItem, textColorSdl, backgroundColorSdl));
        }

        /// <summary>
        /// Blended Text
        /// </summary>
        /// <param name="textColor"></param>
        /// <param name="textItem"></param>
        /// <returns></returns>
        private Surface RenderTextBlended(
            string textItem, Color textColor)
        {
            Sdl.SDL_Color colorSdl = SdlColor.ConvertColor(textColor);
            if (textItem == null || textItem.Length == 0)
            {
                textItem = " ";
            }
            return new Surface(SdlTtf.TTF_RenderUNICODE_Blended(
                this.Handle, textItem, colorSdl));
        }

        #endregion

        #region Public Methods

        /// <summary>
        /// Get System Font Names
        /// </summary>
        /// <returns></returns>
        public static System.Drawing.Text.FontCollection SystemFontNames
        {
            get
            {
                return new System.Drawing.Text.InstalledFontCollection();
            }
        }

        /// <summary>
        /// Gets and sets the font style of the text.
        /// </summary>
        public Styles Style
        {
            set
            {
                SdlTtf.TTF_SetFontStyle(this.Handle, (int)value);
                GC.KeepAlive(this);
            }
            get
            {
                Styles style = (Styles)SdlTtf.TTF_GetFontStyle(this.Handle);
                GC.KeepAlive(this);
                return style;
            }
        }

        /// <summary>
        /// Gets and sets whether or not the font is bold.
        /// </summary>
        public bool Bold
        {
            set
            {
                if (value)
                {
                    Styles style = (Styles)SdlTtf.TTF_GetFontStyle(this.Handle);
                    SdlTtf.TTF_SetFontStyle(this.Handle, (int)style | (int)Styles.Bold);
                    GC.KeepAlive(this);
                }
                else
                {
                    Styles style = (Styles)SdlTtf.TTF_GetFontStyle(this.Handle);
                    if ((int)(style & Styles.Bold) != (int)SdlFlag.FalseValue)
                    {
                        SdlTtf.TTF_SetFontStyle(this.Handle, (int)style ^ (int)Styles.Bold);
                    }
                    GC.KeepAlive(this);
                }
            }
            get
            {
                Styles style = (Styles)SdlTtf.TTF_GetFontStyle(this.Handle);
                GC.KeepAlive(this);
                if ((int)(style & Styles.Bold) == (int)SdlFlag.FalseValue)
                {
                    return false;
                }
                else
                {
                    return true;
                }
            }
        }

        /// <summary>
        /// Gets and sets whether or not the font is italicized.
        /// </summary>
        public bool Italic
        {
            set
            {
                if (value == true)
                {
                    Styles style = (Styles)SdlTtf.TTF_GetFontStyle(this.Handle);
                    SdlTtf.TTF_SetFontStyle(this.Handle, (int)style | (int)Styles.Italic);
                    GC.KeepAlive(this);
                }
                else
                {
                    Styles style = (Styles)SdlTtf.TTF_GetFontStyle(this.Handle);
                    if ((int)(style & Styles.Italic) != (int)SdlFlag.FalseValue)
                    {
                        SdlTtf.TTF_SetFontStyle(this.Handle, (int)style ^ (int)Styles.Italic);
                    }
                    GC.KeepAlive(this);
                }
            }
            get
            {
                Styles style = (Styles)SdlTtf.TTF_GetFontStyle(this.Handle);
                GC.KeepAlive(this);
                if ((int)(style & Styles.Italic) == (int)SdlFlag.FalseValue)
                {
                    return false;
                }
                else
                {
                    return true;
                }
            }
        }

        /// <summary>
        /// Gets and sets whether the font is underlined.
        /// </summary>
        public bool Underline
        {
            set
            {
                if (value == true)
                {
                    Styles style = (Styles)SdlTtf.TTF_GetFontStyle(this.Handle);
                    SdlTtf.TTF_SetFontStyle(this.Handle, (int)style | (int)Styles.Underline);
                    GC.KeepAlive(this);
                }
                else
                {
                    Styles style = (Styles)SdlTtf.TTF_GetFontStyle(this.Handle);
                    if ((int)(style & Styles.Underline) != (int)SdlFlag.FalseValue)
                    {
                        SdlTtf.TTF_SetFontStyle(this.Handle, (int)style ^ (int)Styles.Underline);
                    }
                    GC.KeepAlive(this);
                }
            }
            get
            {
                Styles style = (Styles)SdlTtf.TTF_GetFontStyle(this.Handle);
                GC.KeepAlive(this);
                if ((int)(style & Styles.Underline) == (int)SdlFlag.FalseValue)
                {
                    return false;
                }
                else
                {
                    return true;
                }
            }
        }

        /// <summary>
        /// Gets and sets whether the font style is not underlined, italic or bold.
        /// </summary>
        public bool Normal
        {
            set
            {
                if (value == true)
                {
                    SdlTtf.TTF_SetFontStyle(this.Handle, (int)Styles.None);
                    GC.KeepAlive(this);
                }
            }
            get
            {
                Styles style = (Styles)SdlTtf.TTF_GetFontStyle(this.Handle);
                GC.KeepAlive(this);
                if ((int)(style | Styles.Underline | Styles.Bold | Styles.Italic) == (int)SdlFlag.TrueValue)
                {
                    return false;
                }
                else
                {
                    return true;
                }
            }
        }

        /// <summary>
        /// Gets the height of the font.
        /// </summary>
        public int Height
        {
            get
            {
                int result = SdlTtf.TTF_FontHeight(this.Handle);
                GC.KeepAlive(this);
                return result;
            }
        }

        /// <summary>
        /// Ascent Property
        /// </summary>
        public int Ascent
        {
            get
            {
                int result = SdlTtf.TTF_FontAscent(this.Handle);
                GC.KeepAlive(this);
                return result;
            }
        }

        /// <summary>
        /// Descent Property
        /// </summary>
        public int Descent
        {
            get
            {
                int result = SdlTtf.TTF_FontDescent(this.Handle);
                GC.KeepAlive(this);
                return result;
            }
        }

        /// <summary>
        /// Line Size property
        /// </summary>
        public int LineSize
        {
            get
            {
                int result = SdlTtf.TTF_FontLineSkip(this.Handle);
                GC.KeepAlive(this);
                return result;
            }
        }

        /// <summary>
        /// Gets the size of the given text in the current font.
        /// </summary>
        /// <param name="textItem">String to display</param>
        /// <returns>The size of the text in pixels.</returns>
        public Size SizeText(string textItem)
        {
            int width;
            int height;

            SdlTtf.TTF_SizeUNICODE(this.Handle, textItem, out width, out height);
            GC.KeepAlive(this);
            return new Size(width, height);
        }

        /// <summary>
        /// Render text to a surface.
        /// </summary>
        /// <param name="textItem">String to display</param>
        /// <param name="antiAlias">If true, text will be anti-aliased</param>
        /// <param name="textColor">Color of text</param>
        /// <returns>Surface with text</returns>
        public Surface Render(string textItem, Color textColor, bool antiAlias)
        {
            return this.Render(textItem, textColor, Color.Empty, antiAlias, 0, 0);
        }

        /// <summary>
        /// Render text to a surface with a background color
        /// </summary>
        /// <param name="textItem">String to display</param>
        /// <param name="textColor">Color of text</param>
        /// <param name="backgroundColor">Color of background</param>
        /// <returns>Surface with text</returns>
        public Surface Render(string textItem, Color textColor, Color backgroundColor)
        {
            return this.Render(textItem, textColor, backgroundColor, true, 0, 0);
        }

        /// <summary>
        /// Render Text to a surface
        /// </summary>
        /// <param name="textItem">Text string</param>
        /// <param name="textColor">Color of text</param>
        /// <returns>Surface with text</returns>
        public Surface Render(string textItem, Color textColor)
        {
            return this.Render(textItem, textColor, Color.Empty, true, 0, 0);
        }

        /// <summary>
        /// Render text to a surface with a background color
        /// </summary>
        /// <param name="textItem">String to display</param>
        /// <param name="textColor">Color of text</param>
        /// <param name="backgroundColor">Color of background</param>
        /// <param name="antiAlias"></param>
        /// <returns>Surface with text</returns>
        public Surface Render(string textItem, Color textColor, Color backgroundColor, bool antiAlias)
        {
            return this.Render(textItem, textColor, backgroundColor, antiAlias, 0, 0);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="textItem"></param>
        /// <param name="textColor"></param>
        /// <param name="antiAlias"></param>
        /// <param name="textWidth"></param>
        /// <param name="maxLines"></param>
        /// <returns></returns>
        public Surface Render(string textItem, Color textColor, bool antiAlias, int textWidth, int maxLines)
        {
            return Render(textItem, textColor, Color.Empty, antiAlias, textWidth, maxLines);
        }

        // c# doesn't allow the optional paramter - everything has to be passed 
        // textWidth default = 0   - no wrapping (otherwise it is the number of pixels to count as the textWidth) 
        // maxLines default = 0   - render all lines (otherwise it is the maximum number of lines to render) 
        /// <summary>
        /// 
        /// </summary>
        /// <param name="textItem"></param>
        /// <param name="textColor"></param>
        /// <param name="backgroundColor"></param>
        /// <param name="antiAlias"></param>
        /// <param name="textWidth"></param>
        /// <param name="maxLines"></param>
        /// <returns></returns>
        public Surface Render(string textItem, Color textColor, Color backgroundColor, bool antiAlias, int textWidth, int maxLines)
        {
            if (textItem == null)
            {
                throw new ArgumentNullException("textItem");
            }
            int x = 0;
            int y = 0;
            int tempWidth = 0;
            int stringlength;
            int stringpos;
            int countback;
            int newX;
            string templine;
            int countLines;
            string[] splitline;

            splitline = textItem.Replace("\r", string.Empty).Split('\n');
            for (int k = 0; k <= splitline.GetUpperBound(0); k++)
            {
                splitline[k] = splitline[k].Trim();
            }

            if (textWidth == 0 && splitline.Length == 1)
            {
                if (backgroundColor.IsEmpty)
                {
                    if (antiAlias)
                    {
                        return this.RenderTextBlended(textItem, textColor);
                    }
                    else
                    {
                        return this.RenderTextSolid(textItem, textColor);
                    }
                }
                else
                {
                    return this.RenderTextShaded(textItem, textColor, backgroundColor);
                }
            }
            else
            {

                Surface surfFinal;
                Surface blitSurf;

                // it is faster to set aside a large amount of temporary surface 
                // than recreate a new one every time the surface is to expand. 

                // if no textWidth is given, then set the textWidth to ludicrusly high 
                // in all cases, set the height to an impossible high number. 

                // a possible improvement would be to pass in the the temporary 
                // textWidth & height for performance 
                Surface surfTemp;
                if (textWidth > 0)
                {
                    surfTemp = new Surface(textWidth, 10000);
                }
                else
                {
                    surfTemp = new Surface(10000, 10000);
                }

                // the height of fonts are always the same from what I can tell 
                // no matter which letter is used. It's the widths that cause trouble 
                int fontHeight = this.SizeText(" ").Height;

                countLines = 1;
                for (int k = 0; k <= splitline.GetUpperBound(0); k++)
                {
                    // no word wrap, only newline wrap 
                    if (textWidth == 0)
                    {
                        if (maxLines == 0 || countLines <= maxLines)
                        {
                            if (!String.IsNullOrEmpty(splitline[k]))
                            {
                                blitSurf = this.Render(splitline[k], textColor, backgroundColor, antiAlias);
                            }
                            else
                            {
                                blitSurf = new Surface(1, 1);
                            }
                            if (blitSurf.Width > tempWidth)
                            {
                                tempWidth = blitSurf.Width;
                            }
                            surfTemp.Blit(blitSurf, new Point(x, y));
                            blitSurf.Dispose();
                            blitSurf = null;   // doing this reuses the surface memory :) 
                            y = y + fontHeight;
                            countLines = countLines + 1;
                        }
                        textWidth = tempWidth;
                    }
                    // word wrapping & new line wrapping 
                    else
                    {
                        stringpos = 0;
                        //indented = true; 
                        if (String.IsNullOrEmpty(splitline[k]))
                        {
                            y = y + fontHeight;
                        }
                        while (stringpos < splitline[k].Length)
                        {
                            if (maxLines == 0 || countLines <= maxLines)
                            {
                                stringlength = 1;
                                templine = splitline[k].Substring(stringpos, stringlength);

                                // this is the secret: keep checking the width of the string to blit, adding 
                                // one letter at a time, until the width has been hit 
                                while (this.SizeText(templine).Width <= textWidth & (stringpos + stringlength < splitline[k].Length))
                                {
                                    stringlength = stringlength + 1;
                                    templine = splitline[k].Substring(stringpos, stringlength);
                                }
                                countback = 0;
                                // now count backwards, until a space is found 
                                while (!(templine.EndsWith(" ")) & (stringpos + stringlength < splitline[k].Length))
                                {
                                    countback = countback + 1;
                                    if (countback >= splitline[k].Length)
                                    {
                                        countback = 0;
                                        templine = splitline[k].Substring(stringpos, stringlength);
                                        break;
                                    }
                                    templine = stringlength - countback > 0 ? templine.Substring(0, stringlength - countback) : "";
                                }

                                // move the current string position forward 
                                stringpos = stringpos + stringlength - countback;
                                //if (indented) 
                                //{ 
                                //  newX = x + indent; 
                                //} 
                                //else 
                                //{ 
                                newX = x;
                                //} 
                                // render the wrapped line 
                                blitSurf = this.Render(templine, textColor, backgroundColor, antiAlias);
                                surfTemp.Blit(blitSurf, new Point(newX, y));
                                blitSurf.Dispose();
                                blitSurf = null;
                                y = y + fontHeight;
                                countLines = countLines + 1;
                            }
                            else
                            {
                                stringpos = stringpos + 1;
                            }
                            //indented = false; 
                        }
                    }
                }
                surfFinal = surfTemp.CreateSurfaceFromClipRectangle(new Rectangle(0, 0, textWidth, y));
                surfTemp.Dispose();
                surfTemp = null;
                return surfFinal;
            }
        }

        #endregion

        #region Protected Methods

        /// <summary>
        /// Destroys the surface object and frees its memory
        /// </summary>
        /// <param name="disposing">If true, it will dispose all objects</param>
        protected override void Dispose(bool disposing)
        {
            try
            {
                if (!this.disposed)
                {
                    if (disposing)
                    {
                    }
                    this.disposed = true;
                }
            }
            finally
            {
                base.Dispose(disposing);
            }
        }

        /// <summary>
        /// Closes Surface handle
        /// </summary>
        protected override void CloseHandle()
        {
            try
            {
                if (this.Handle != IntPtr.Zero)
                {
                    SdlTtf.TTF_CloseFont(this.Handle);
                    this.Handle = IntPtr.Zero;
                }
            }
            catch (System.NullReferenceException e)
            {
                e.ToString();
            }
            catch (AccessViolationException e)
            {
                Console.WriteLine(e.StackTrace);
                e.ToString();
            }
            finally
            {
                this.Handle = IntPtr.Zero;
            }
        }

        #endregion
    }
}
www.java2v.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.