Colors, Fonts, and Text in GDI+



This article has been excerpted from book "Graphics Programming with GDI+".

Three types of object that are used to build graphics intensive applications are colors, fonts and text. In this article you will learn about the representation of colors, fonts, and text in the .NET Framework class library. We will cover the following topics:

  • Basics of colors, fonts, and text and how they are represented in Windows
  • Namespaces, classes, and other objects provided by the .NET Framework library to work with colors, fonts, and text
  • System fonts, colors, brushes, and pens
  • Color conversions and translations
  • System and private font collections
  • Formatting text using hinting, tab stops, and other methods
  • Setting the quality and performance of text rendering
  • Writing a simple text editor application
  • Text transformation operations such as scaling, rotation, and translation
  • Advanced typography

Accessing the Graphics Object

There are several ways an application can use the code from this article. It can execute code using the OnPaint method or Form_Paint event, or it can use code with a button or menu click event handler. If an application executes code with Form_Paint or OnPaint, you will need to include the following line at the beginning of the method.

            Graphics g = e.Graphics;

If an application executes code from a button or menu click event handler or elsewhere, you will need to create a Graphics object using CreateGraphics or another method and call Dispose method to dispose of objects when you're finished with them. The following code snippet gives an example:

            Graphics g = this.CreatGraphics();

            //Your code here
            //Dispose of GDI+ objects
            g.Dispose();

Note:To test code from this article, we will create a windows application with code written on the menu item click event handlers.

Working with Colors

In this section we will examine color representation in GDI+ and how to use color-related functionality in real-world applications.

In GDI+, a color is represented by a 32-bit structure made up of four components: alpha (A), red (R), green (G) and blue (B), referred to as ARGB mode. Components' values range from 0 to 255.The alpha component (the first 8 bits) of the color represents transparency, which determines how a color is blended with the background. An alpha value of 0 represents a fully transparent color, and a value of 255 represents a fully opaque color; intermediate values produce results between these extremes. Real world examples of alpha use include drawing translucent graphics shapes and images. 

Color Spaces

It's hard for human beings as perceptual entities – to describe and represent colors. Color spaces provide a common frame of reference that helps represent colors .A color space contains components called color channels. For example, RGB is a three-dimensional space with red, green, and, blue color channels. To limit our discussion, we will cover the RGB (red-green-blue), HSV (hue-saturation-value), and HLS (hue-lightness-saturation) color spaces.

The RGB color space is most commonly used namespace in computer programming because it closely matches the structure of most display hardware which commonly includes separate red, green, and blue subpixel structures. It can be thought of as a cube in which length indicates the intensity of red, width indicates the intensity of green, and height indicate intensity of blue .The corner indicated by (0,0,0) is black, and the opposite corner (255,255,255) is white. Every other color is represent somewhere between those corners.

The HSV, sometimes called HSB (hue-saturation-brightness), and HLS color spaces can be thought of as single and double cones. The hue component represents the position on the cone as an angular measurement. The 0-, 120-, and 240-degrees values of hue represent the colors red, green, and blue, respectively.

The saturation component describes the color intensity. A saturation value of 0 means gray (colorless), and the maximum value of saturation indicates pure color and brightness for the values specified by the hue and value components.

The value, or brightness, component represents the brightness of the color. A value of 0 indicates the color black (no brightness) and a maximum value indicate that the color is brightest (closest to white).

The color structure provided by the .NET Framework library is based on the RGB color space. In section 5.2.2 we will discuss how to use it in our application.

The Color structure

The color structure represents ARGB colors in GDI+. This class has static member property for almost every possible color. For example, Color.Black and Color.Red represent the colors black and red, respectively. Besides these static properties, this structure includes read-only properties A, R, G and B that represent the alpha, red, green, and blue components, respectively.

The IsEmpty property checks whether a Color structure has been initialized (if not, there is no color). The KnownColor enumeration contains more than 300 colors, and each color is represented by its name. For example, Blue and Black members represents the colors blue and black, respectively. KnownColor also defines color combinations, such as LimeGreen and LightBlue. You can also find system colors such as activeBorder, ActiveCaption, Control, ControlText, Highlight, and InactiveBorder, using the IsSystemColor enumeration. The Name property represents the name of the color, which is read-only property. The Transparent property is a static property that represents a transparent color.

The Color structure also provides some methods. The FromArgb method creates a color from the four ARGB components. This method has different overloaded forms with which an application can create a Color object from an alpha value only; from an alpha value with a Color object only; from three values (red, green and blue); and from all four values (alpha, red, green, and blue).

The FromKnownColor and FromName methods create a Color object from a predefined color or from the name of a predefined color, respectively. The FromKnownColor method takes only one argument, of KnownColor enumeration .The FormName method takes one argument of string type as the color name. All members defined in the knownColor enumeration are valid names for this method.

Note: All three "from" method (FromArgb, FromKnownColor, and FromName) are static.

The ToArgb and ToKnownColor methods convert an ARGB or KnownColor value, respectively, to a Color structure.

Listing 5.1 illustrates different ways to create Color objects and use them in an application to draw various graphics objects, including a filled ellipse with a red brush, a filled rectangle with a blue brush and a line with green pen. The application first creates four Color objects via the FromArgb, FromName, FromknownColor, and Empty methods. The FromArgb methods creates a translucent pure red Color object, using parameters 120, 255, 0, and 0. The FromName method creates object from the string "Blue". The FromKnownColor method creates a color object from the known color Green.

LISTING 5.1: Using the methods and properties of the Color structure

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication2
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
           //Create Graphics object
            Graphics g = this.CreateGraphics();

            //Create color object from ARGB
            Color redColor = Color.FromArgb (120, 255, 0, 0);

            //Create Color Object from color name
            Color blueColor = Color.FromName ("Blue");

            //Create Color object from known color
            Color greenColor = Color.FromKnownColor (KnownColor.Green);

            //Create Empty Color
            Color tstColor = Color.Empty;

            //See if a color is empty

            if (tstColor.IsEmpty)
            {
                  tstColor = Color.DarkGoldenrod;
            }

            //Create brushes and pens from colors
            SolidBrush redBrush =new SolidBrush (redColor);
            SolidBrush blueBrush =new SolidBrush (blueColor);
            SolidBrush greenBrush =new SolidBrush (greenColor);
            Pen greenPen = new Pen(greenBrush,4);

            //Draw GDI+ objects
            g.FillEllipse (redBrush, 10, 10, 50, 50);
            g.FillRectangle (blueBrush, 60, 10, 50, 50);
            g.DrawLine (greenPen, 20, 60, 200, 60);

            //Check property values
        //MessageBox.Show ("Color Name:"+blueColor.Name+
        //    ", A:"+ blueColor.A.ToString () +
        //    ", R:"+ blueColor.R.ToString () +
        //    ", B:" + blueColor.B.ToString () +
        //    ", G:"+ blueColor.G.ToString ());
            //Dispose of GDI+ objects
            redBrush.Dispose ();
            blueBrush.Dispose ();
            greenBrush.Dispose ();
            greenPen.Dispose ();
            g.Dispose ();
        }

        private void Form1_Paint(object sender, PaintEventArgs e)
        {
            Graphics g = e.Graphics;

            //Create color object from ARGB
            Color redColor = Color.FromArgb(120, 255, 0, 0);

            //Create Color Object from color name
            Color blueColor = Color.FromName("Blue");

            //Create Color object from known color
            Color greenColor = Color.FromKnownColor(KnownColor.Green);

            //Create Empty Color
            Color tstColor = Color.Empty;

            //See if a color is empty

            if (tstColor.IsEmpty)
            {
                tstColor = Color.DarkGoldenrod;
            }

            //Create brushes and pens from colors
            SolidBrush redBrush = new SolidBrush(redColor);
            SolidBrush blueBrush = new SolidBrush(blueColor);
            SolidBrush greenBrush = new SolidBrush(greenColor);
            Pen greenPen = new Pen(greenBrush, 4);

            //Draw GDI+ objects
            g.FillEllipse(redBrush, 10, 10, 50, 50);
            g.FillRectangle(blueBrush, 60, 10, 50, 50);
            g.DrawLine(greenPen, 20, 60, 200, 60);

            //Check property values
            //MessageBox.Show ("Color Name:"+blueColor.Name+
            //    ", A:"+ blueColor.A.ToString () +
            //    ", R:"+ blueColor.R.ToString () +
            //    ", B:" + blueColor.B.ToString () +
            //    ", G:"+ blueColor.G.ToString ());
            //Dispose of GDI+ objects
            redBrush.Dispose();
            blueBrush.Dispose();
            greenBrush.Dispose();
            greenPen.Dispose();
            g.Dispose();
        }
    }
}

Figure 5.1 shows the output from Listing 5.1.

The GetBrightness, GetHue, and GetSaturation method return a color's brightness, hue, and saturation component values, respectively. Listing 5.2 reads hue, saturation, and brightness components of a color and displays their values on the form by using the DrawString method.

fig5.1.gif

FIGURE 5.1 Creating colors using different methods

LISTING 5.2: Getting brightness, hue, and saturation of a color

private void HSBMenu_Click(object sender, System.EventArgs e)
        {
            //Create a Graphics object
            Graphics g = this.CreateGraphics();

            //Create a color
            Color clr = Color.FromArgb(255, 200, 0, 100);

            //Get hue, saturation, and brightness components
            float h = clr.GetHue();
            float s = clr.GetSaturation();
            float v = clr.GetBrightness();
            string str = "Hue:" + h.ToString() + "\n" +
                "Saturation: " + s.ToString() + "\n" +
                "Brightness: " + v.ToString();

            //Display data 
            g.DrawString(str, new Font("Verdana", 12),
                Brushes.Blue, 50, 50);

            //Dispose of object
            g.Dispose();
        }

Figure 5.2 shows the output from Listing 5.2.The values of hue, saturation, and brightness in this particular color are 330, 1, and 0.3921569, respectively.

Figure 5.2.gif

FIGURE 5.2: Getting brightness, hue and saturation components of a color

Conclusion

Hope the article would have helped you in understanding Colors, Fonts, and Text in GDI+. Read other articles on GDI+ on the website.

bookGDI.jpg
This book teaches .NET developers how to work with GDI+ as they develop applications that include graphics, or that interact with monitors or printers. It begins by explaining the difference between GDI and GDI+, and covering the basic concepts of graphics programming in Windows.


Similar Articles
Mindcracker
Founded in 2003, Mindcracker is the authority in custom software development and innovation. We put best practices into action. We deliver solutions based on consumer and industry analysis.