Listing 3.31 The form-load event handler private void Form1_Loadobject sender, // Create a bitmap using full size bitmap = new BitmapfullSize.Width, // Create a new pen and brush as
Trang 1FillRegion fills a specified region with a brush This method takes a brush and a region as input parameters Listing 3.29 creates a Region object
from a rectangle and calls FillRegion to fill the region
Listing 3.29 Filling regions
Rectangle rect = new Rectangle(20, 20, 150, 100);
Region rgn = new Region(rect);
e.Graphics.FillRegion(new SolidBrush(Color.Green)
, rgn);
Note
Chapter 6 discusses rectangles and regions in more detail
3.2.3 Miscellaneous Graphics Class Methods
The Graphics class provides more than just draw and fill methods Miscellaneous methods are defined in Table 3.6 Some of these methods
are discussed in more detail later
3.2.3.1 The Clear Method
The Clear method clears the entire drawing surface and fills it with the specified background color It takes one argument, of type Color To
clear a form, an application passes the form's background color The following code snippet uses the Clear method to clear a form
form.Graphics g = this.CreateGraphics();
g.Clear(this.BackColor);
g.Dispose();
Trang 2Table 3.6 Some miscellaneous Graphics methods
AddMetafileComment Adds a comment to a Metafile object
Clear Clears the entire drawing surface and fills it with the specified background color
ExcludeClip Updates the clip region to exclude the area specified by a Rectangle structure.
Flush Forces execution of all pending graphics operations and returns immediately without waiting for the operations
to finish
FromHdc Creates a new Graphics object from a device context handle
FromHwnd Creates a new Graphics object from a window handle
FromImage Creates a new Graphics object from an Image object
GetHalftonePalette Returns a handle to the current Windows halftone palette
GetHdc Returns the device context handle associated with a Graphics object.
GetNearestColor Returns the nearest color to the specified Color structure.
IntersectClip Updates the clip region of a Graphics object to the intersection of the current clip region and a Rectangle
structure
IsVisible Returns true if a point is within the visible clip region.
MeasureCharacterRanges Returns an array of Region objects, each of which bounds a range of character positions within a string.
MeasureString Measures a string when drawn with the specified Font object.
MultiplyTransform Multiplies the world transformation and the Matrix object.
ReleaseHdc Releases a device context handle obtained by a previous call to the GetHdc method.
ResetClip Resets the clip region to an infinite region.
ResetTransform Resets the world transformation matrix to the identity matrix
Restore Restores the state of a Graphics object to the state represented by a GraphicsState object Takes
GraphicsState as input, removes the information block from the stack, and restores the Graphics object to the state it was in when it was saved
RotateTransform Applies rotation to the transformation matrix
Save Saves the information block of a Graphics object The information block stores the state of the Graphics object
The Save method returns a GraphicsState object that identifies the information block
ScaleTransform Applies the specified scaling operation to the transformation matrix
SetClip Sets the clipping region to the Clip property.
TransformPoints Transforms an array of points from one coordinate space to another using the current world and page
transformations
TranslateClip Translates the clipping region by specified amounts in the horizontal and vertical directions
TranslateTransform Prepends the specified translation to the transformation matrix.
Trang 33.2.3.2 The MeasureString Method
MeasureString measures a string when it is drawn with a Font object and returns the size of the string as a SizeF object You can use SizeF to find out the height and width of string
MeasureString can also be used to find the total number of characters and lines in a string It has seven overloaded methods It takes two required parameters: the string and font to measure Optional parameters you can pass include the width of the string in pixels, maximum layout area of the text, string format, and combinations of these parameters
Note
Chapter 5 discusses string operations in detail
Listing 3.30 uses the MeasureString method to measure a string's height and width and draws a rectangle and a circle around the string This example also shows how to find the total number of lines and characters of a string
Listing 3.30 Using the MeasureString method
Graphics g = Graphics.FromHwnd(this.Handle);
g.Clear(this.BackColor);
string testString = "This is a test string";
Font verdana14 = new Font("Verdana", 14);
Font tahoma18 = new Font("Tahoma", 18);
int nChars;
int nLines;
// Call MeasureString to measure a string
SizeF sz = g.MeasureString(testString, verdana14);
string stringDetails = "Height: "+sz.Height.ToString()
+ ", Width: "+sz.Width.ToString();
MessageBox.Show("First string details: "+ stringDetails);
g.DrawString(testString, verdana14, Brushes.Green,
new PointF(0, 100));
g.DrawRectangle(new Pen(Color.Red, 2), 0.0F, 100.0F,
sz.Width, sz.Height);
sz = g.MeasureString("Ellipse", tahoma18,
new SizeF(0.0F, 100.0F), new StringFormat(),
out nChars, out nLines);
stringDetails = "Height: "+sz.Height.ToString()
Trang 4g.DrawString("Ellipse", tahoma18, Brushes.Blue,
new PointF(10, 10));
g.DrawEllipse( new Pen(Color.Red, 3), 10, 10,
sz.Width, sz.Height);g.Dispose()
Figure 3.41 shows the output from Listing 3.30
Figure 3.41 Using MeasureString when drawing text
3.2.3.3 The FromImage, FromHdc, and FromHwnd Methods
As we discussed earlier, an application can use Graphics class members to get a Graphics object The Graphics class provides three methods
to create a Graphics object: FromHwnd, FromHdc, and FromImage
FromImage takes an Image object as input parameter and returns a Graphics object We will discuss FromImage in more detail in Chapters 7and 8 The following code snippet creates a Graphics object from an Image object Once a Graphics object has been created, you can call its members
Image img = Image.FromFile("Rose.jpg");
Graphics g = Graphics.FromImage(img);
// Do something
g.Dispose();
Trang 5Make sure you call the Dispose method of the Graphics object when you're finished with it
FromHdc creates a Graphics object from a window handle to a device context The following code snippet shows an example in which FromHdc takes one parameter, of type IntPtr
Trang 6[ Team LiB ]
3.3 The GDI+Painter Application
Almost every chapter of this book will show a real-world example to illustrate the concepts discussed in it In this chapter we create an application, GDI+Painter, that you can use to draw and fill simple graphics objects If you wish, you can add more functionality to the
application Once you are done drawing graphics shapes, the program allows you to save your drawing in bitmap format You can modify the program to save a drawing in jpeg or gif format
The program is a Windows Forms application and looks like Figure 3.42 It has three draw buttons (line, ellipse, and rectangle) and two fill
buttons (rectangle and ellipse) The Save Image button allows you to save the image.
Figure 3.42 The GDI+Painter application
Click on a button and the program draws the selected item on the form Here's how it works:
First we define some private class-level variables:
// Variables
private Bitmap bitmap = null;
private Bitmap curBitmap = null;
private bool dragMode = false;
private int drawIndex = 1;
Trang 7private int diffX, diffY;
private Graphics curGraphics;
private Pen curPen;
private SolidBrush curBrush;
private Size fullSize;
Note
Please download GDI+Painter application source code from online (www.awprofessional.com/titles/0321160770)
The next step is to initialize objects On the form-load event handler, we create a bitmap and a Graphics object from the bitmap, which represents the entire form We set its background color to the form's background color by calling the Graphics.Clear method We also create a Pen object and a Brush object when the form loads Listing 3.31 gives the form-load event handler code
Listing 3.31 The form-load event handler
private void Form1_Load(object sender,
// Create a bitmap using full size
bitmap = new Bitmap(fullSize.Width,
// Create a new pen and brush as
// default pen and brush
curPen = new Pen(Color.Black);
curBrush = new SolidBrush(Color.Black);
}
When we click on a button, we find out which button was selected and save it in the drawIndex variable Listing 3.32 gives code for the button click event handler for all buttons
Listing 3.32 Saving a selected button
private void LineDraw_Click(object sender,
System.EventArgs e)
{
drawIndex = 1;
}
Trang 8On a mouse-move event, we calculate the difference between the ending and starting points that are used to draw the rectangle Notice also that on mouse down we set dragMode to true, and on mouse up we set dragMode to false On the basis of the area covered by user
selection, we draw or fill objects on mouse up, which gives the user a visible drawing effect You will also see the RefreshFormBackgroundmethod, which we will discuss shortly
Listing 3.33 The mouse-down event handler
private void Form1_MouseDown(object sender,
System.Windows.Forms.MouseEventArgs e)
{
// Store the starting point of
// the rectangle and set the drag mode
// Find out the ending point of
// the rectangle and calculate the
// difference between starting and ending
// points to find out the height and width
// of the rectangle
x = e.X;
y = e.Y;
diffX = e.X - curX;
diffY = e.Y - curY;
// If dragMode is true, call refresh
// to force the window to repaint
if (dragMode)
{
this.Refresh();
Trang 9Now we add code to the form's paint event handler, which draws and fills the object Listing 3.34 gives the code for the OnPaint method.
Listing 3.34 The OnPaint method
Trang 10private void Form1_Paint(object sender,
Listing 3.35 The RefreshFormBackground method
private void RefreshFormBackground()
Trang 11The Save Image button allows us to save the image by simply calling the Save method of Bitmap The Save method takes a file name and format We use SaveFileDialog to select the file name Listing 3.36 gives code for the Save Image button.
Listing 3.36 The Save Image button click handler
private void SaveBtn_Click(object sender,
System.EventArgs e)
{
// Save file dialog
SaveFileDialog saveFileDlg = new SaveFileDialog();
In the end we release all objects, which we can do on the form-closed event (see Listing 3.37)
Listing 3.37 The form-closed event handler
private void Form1_Closed(object sender, System.EventArgs e)
Trang 12[ Team LiB ]
Trang 133.4 Drawing a Pie Chart
Let's look at one more real-world application In this example we will develop an application that draws pie charts based on a data feed Piecharts are useful when you need to represent statistical data in a graphical way—for example, the percentage of users visiting a Web sitefrom different countries, or the percentage grades in different subjects In our example we will use the DrawPie and FillPie methods
First we create a Windows application and add four buttons, a text box, and a list box control We change the text and names of the text box, and our final form looks like Figure 3.43 In the Enter Share text box we will enter a number to represent the share of total items For
example, add five values in the share box: 10, 20, 30, 40, 50 The total is 150 The percentage of the share with value 10 is 10/150
Figure 3.43 A pie chart–drawing application
Listing 3.38 adds variables You may notice the structure sliceData, which has two public variables: share and clr The share variable
represents the share of a slice, and clr is its color
Listing 3.38 The sliceData structure
// User-defined variables
private Rectangle rect =
Trang 14public ArrayList sliceList = new ArrayList();
The Select Color button allows us to select the color for a share As Listing 3.39 shows, we use ColorDialog to select a color
Listing 3.39 Selecting a color
private void ColorBtn_Click(object sender, System.EventArgs e)
Listing 3.40 Adding pie chart data
private void button1_Click(object sender, System.EventArgs e)
The Draw Chart and Fill Chart button clicks are used to draw the outer boundary and fill the chart, respectively These buttons call the
DrawPieChart method with a Boolean variable, as shown in Listing 3.41
Listing 3.41 The Draw Pie and Fill Pie button click handlers
private void DrawPie_Click(object sender, System.EventArgs e)
Trang 15The DrawPieChart method actually draws the pie chart, as shown in Listing 3.42 Depending on which button—Fill Chart or Draw Chart—was
clicked, we call FillPie or DrawPie, respectively We also read each sliceData variable of the array and calculate the percentage of a share in
the entire chart, represented by an angle
Listing 3.42 The DrawPieChart method
private void DrawPieChart(bool flMode)
Let's see this application in action We add shares 10, 20, 30, 40, and 50 with different colors The Draw Chart button click draws a pie chart,
with the output shown in Figure 3.44
Figure 3.44 The Draw Chart button click in action
Trang 16The Fill Chart button fills the chart, with the output shown in Figure 3.45.
Figure 3.45 The Fill Chart button click in action
[ Team LiB ]
Trang 17This chapter also presented a couple of real-world applications, showing how to write an application to draw line and pie charts We also used various methods and properties of the Graphics class to write a PaintBrush-like application, GDI+Painter Using this application, you can draw lines, rectangles, and ellipses and save the resulting image as a bitmap file.
Having completed this chapter, you should have a good understanding of the Graphics class, its methods and properties, and how to use those methods and properties to write real-world applications
Pens and brushes are two of the most frequently used objects in the graphics world In this chapter we discussed pens and brushes briefly Chapter 4 is dedicated to pens and brushes You will learn how to create different kinds of pens and brushes to write interactive graphics applications At the end of Chapter 4 we will add different pen and brush options to GDI+Painter, making it more interactive
[ Team LiB ]
Trang 18[ Team LiB ]
Chapter 4 Working with Brushes and Pens
Brushes and Pens are the two most frequently used objects in graphics applications Pens are used to draw the outlines of graphics objects such as lines and curves; brushes are used to fill the graphic objects' interior areas (e.g., filling a rectangle or an ellipse) In this chapter we
will discuss how to create and use various types of brushes and pens
We begin by discussing brushes, brush types, their methods and properties, and how to create and use them in GDI+
GDI+ provides the Pen and Pens classes to represent pens In this chapter we will discuss how to create different kinds of pens using the Penclass and its properties, and how to use the Pen class methods We will also discuss how to add line caps, dash caps, line dash styles, and line cap styles In Sections 4.3 and 4.4 we will discuss the transformation of pens and brushes
The SystemPens and SystemBrushes classes represent the system pens and brushes, respectively In Section 4.5 we will discuss how to use these classes to work with system pens and brushes
At the end of this chapter we will add color, pen, and brush options to the GDI+Painter application that we created in Chapter 3
[ Team LiB ]
Trang 19[ Team LiB ]
4.1 Understanding and Using Brushes
In the NET Framework library, brush-related functionality is defined in two namespaces: System.Drawing and System.Drawing.Drawing2D
The System.Drawing namespace defines general brush-related classes and functionality, and the System.Drawing.Drawing2D namespace
defines advanced 2D brush-related functionality For example, the Brush, SolidBrush, TextureBrush, and Brushes classes are defined in the
System.Drawing namespace; and the HatchBrush and GradientBrush classes are defined in the System.Drawing.Drawing2D namespace
Before using brushes, obviously you must include the corresponding namespace to your application Alternatively, you can use the
namespace as a prefix to the class; for example, System.Drawing.Brush represents the Brush class if you do not wish to include the
System.Drawing namespace in your application
The code snippet in Listing 4.1 creates a red SolidBrush object and uses it to draw a rectangle This code is written on a form's paint event
handler The first line gets the Graphics object of the form, and the second line creates a brush using the SolidBrush class, which later is used
to fill a rectangle The last line disposes of the SolidBrush object
Listing 4.1 Creating a solid brush
Graphics g = e.Graphics;
SolidBrush redBrush = new SolidBrush(Color.Red);
Rectangle rect = new Rectangle(150, 80, 200, 140);
g.FillRectangle(redBrush, rect);
redBrush.Dispose();
4.1.1 The Brush Class
In the NET Framework library, the Brush class is an abstract base class, which means you cannot create an instance of it without using its
derived classes All usable classes are inherited from the abstract Brush class Figure 4.1 shows all the Brush-derived classes that can be
used in your GDI+ applications
Figure 4.1 Classes inherited from the Brush class
Trang 20Applications generally call fill methods of the appropriate Graphics class, which in turn use brushes to fill GDI+ objects (such as an ellipse, an arc, or a polygon) with a certain kind of brush GDI+ provides four different kinds of brushes: solid, hatch, texture, and gradient Figure 4.2shows the brush types and their classes.
Figure 4.2 Brush types and their classes
4.1.2 The Brushes Class
The Brushes class is a sealed class (it cannot be inherited) Brushes provides more than 140 static members (properties), and each of these members represents a brush with a particular color (including all the standard colors) For instance, the Brushes.Pink, Brushes.Red, and Brushes.Green members represent Brush objects with the colors pink, red, and green, respectively
4.1.3 Solid Brushes
A solid brush is a brush that fills an area with a single solid color We create a SolidBrush object by calling its constructor and passing a Colorstructure as the only parameter The Color structure represents a color It has a static property for every possible color For example, Color.Redrepresents the color red The code snippet in Listing 4.2 creates three SolidBrush objects with three different colors: red, green, and blue
Trang 21Listing 4.2 Creating a SolidBrush object
SolidBrush redBrush = new SolidBrush(Color.Red);
SolidBrush greenBrush = new SolidBrush(Color.Green);
SolidBrush blueBrush = new SolidBrush(Color.Blue);
SolidBrush has only one property of interest: Color, which represents the color of the brush
Listing 4.3 uses red, green, and blue solid brushes and fills an ellipse, a pie, and a rectangle using the FillEllipse, FillPie, and FillRectangle
methods of the Graphics class, respectively
Listing 4.3 Using the SolidBrush class
private void Form1_Paint(object sender,
System.Windows.Forms.PaintEventArgs e)
{
Graphics g = e.Graphics;
// Create three SolidBrush objects
// using the colors red, green, and blue
SolidBrush redBrush = new SolidBrush(Color.Red);
SolidBrush greenBrush = new SolidBrush(Color.Green);
SolidBrush blueBrush = new SolidBrush(Color.Blue);
// Fill ellipse using red brush
g.FillEllipse(redBrush, 20, 40, 100, 120);
// Fill rectangle using blue brush
Rectangle rect = new Rectangle(150, 80, 200, 140);
The output of Listing 4.3 draws an ellipse, a rectangle, and a pie, as Figure 4.3 shows
Figure 4.3 Graphics objects filled by SolidBrush
Trang 224.1.4 Hatch Brushes
Hatch brushes are brushes with a hatch style, a foreground color, and a background color Hatches are a combination of rectangle lines and
the area between the lines The foreground color defines the color of lines; the background color defines the color between lines
The HatchBrush class constructor takes HatchStyle as its first parameter and Color as the second parameter Second and third Color
parameters represent the foreground and background colors The following code snippet shows the constructor signatures:
Note
The HatchBrush class is defined in the System.Drawing.Drawing2D namespace An application needs to provide a reference to System.Drawing.Drawing2D before using this class Alternatively, an application can refer to the HatchBrushclass as System.Drawing.Drawing2D.HatchBrush
public HatchBrush(HatchStyle, Color);
public HatchBrush(HatchStyle, Color, Color);
The following code creates a hatch brush with a dashed-vertical hatch style, blue background, and red foreground:
HatchBrush hBrush1 = new HatchBrush
(HatchStyle.DashedVertical, Color.Blue, Color.Red);
We can use this hatch brush to fill graphics objects such as rectangles or ellipses For example, the following code line fills an ellipse using
hBrush1:
Trang 23g.FillEllipse(hBrush1, 20, 40, 100, 120);
HatchBrush has three properties: BackgroundColor, Foreground-Color, and HatchStyle BackgroundColor returns the color of spaces between
the hatch lines, and ForegroundColor represents the color of the hatch lines
HatchStyle returns the hatch brush style of type HatchStyle enumeration, whose members are described in Table 4.1
Let's create a Windows application that looks like Figure 4.4 The combo box will list some of the available hatch styles The Pick buttons let
you select background and foreground colors of the hatch brush, and the Apply Style button creates a hatch brush based on the selection
and uses it to draw a rectangle
Figure 4.4 A sample hatch brush application
First we add one HatchStyle-type and two Color-type class-level variables that represent the current selected hatch style, foreground, and
background color of a hatch brush, respectively These variables are defined as follows:
Trang 24Table 4.1 HatchStyle members
BackwardDiagonal A pattern of lines on a diagonal from upper right to lower left
Cross Horizontal and vertical lines that cross.
DarkDownwardDiagonal Diagonal lines that slant to the right from top points to bottom points, are spaced 50 percent closer together
than in ForwardDiagonal, and are twice the width of ForwardDiagonal lines
DarkHorizontal Horizontal lines that are spaced 50 percent closer together than in Horizontal and are twice the width of
Horizontal lines
DarkUpwardDiagonal Diagonal lines that slant to the left from top points to bottom points, are spaced 50 percent closer together
than BackwardDiagonal, and are twice the width of BackwardDiagonal lines
DarkVertical Vertical lines that are spaced 50 percent closer together than Vertical and are twice the width of Vertical lines.
DashedDownwardDiagonal Dashed diagonal lines that slant to the right from top points to bottom points.
DashedHorizontal Dashed horizontal lines
DashedUpwardDiagonal Dashed diagonal lines that slant to the left from top points to bottom points.
DashedVertical Dashed vertical lines
DiagonalBrick A hatch with the appearance of layered bricks that slant to the left from top points to bottom points.
DiagonalCross Forward diagonal and backward diagonal lines that cross
DottedDiamond Forward diagonal and backward diagonal lines, each of which is composed of dots that cross
DottedGrid Horizontal and vertical lines, each of which is composed of dots that cross.
ForwardDiagonal A pattern of lines on a diagonal from upper left to lower right
Horizontal A pattern of horizontal lines.
HorizontalBrick A hatch with the appearance of horizontally layered bricks
LargeCheckerBoard A hatch with the appearance of a checker-board with squares that are twice the size of SmallCheckerBoard.
LargeConfetti A hatch with the appearance of confetti that is composed of larger pieces than SmallConfetti.
LargeGrid Horizontal and vertical lines that cross and are spaced 50 percent farther apart than in Cross.
LightDownwardDiagonal Diagonal lines that slant to the right from top points to bottom points.
LightHorizontal Horizontal lines that are spaced 50 percent closer together than Horizontal lines
LightUpwardDiagonal Diagonal lines that slant to the left from top points to bottom points and are spaced 50 percent closer together
than BackwardDiagonal lines
LightVertical Vertical lines that are spaced 50 percent closer together than Vertical lines
Trang 25Member Description
NarrowHorizontal Horizontal lines that are spaced 75 percent closer together than Horizontal lines (or 25 percent closer
together than LightHorizontal lines)
NarrowVertical Vertical lines that are spaced 75 percent closer together than Vertical lines (or 25 percent closer together
than LightVertical lines)
OutlinedDiamond Forward diagonal and backward diagonal lines that cross.
PercentXX Percent hatch The "XX" number after "Percent" represents the ratio of foreground color to background color
as XX:100 The values of XX are 05, 10, 20, 25, 30, 40, 50, 60, 70, 75, 80, and 90
Plaid A hatch with the appearance of a plaid material.
Shingle A hatch with the appearance of diagonally layered shingles that slant to the right from top points to bottom
points
SmallCheckerBoard A hatch with the appearance of a checkerboard.
SmallConfetti A hatch with the appearance of confetti
SmallGrid Horizontal and vertical lines that cross and are spaced 50 percent closer together than Cross lines.
SolidDiamond A hatch with the appearance of a checkerboard placed diagonally.
Sphere A hatch with the appearance of spheres laid adjacent to one another
Trellis A hatch with the appearance of a trellis.
Vertical A pattern of vertical lines
Wave Horizontal lines that are composed of tildes.
Weave A hatch with the appearance of a woven material
WideDownwardDiagonal Diagonal lines that slant to the right from top points to bottom points, have the same spacing as in
ForwardDiagonal, and are triple the width of ForwardDiagonal lines
WideUpwardDiagonal Diagonal lines that slant to the left from top points to bottom points, have the same spacing as in
BackwardDiagonal, and are triple the width of BackwardDiagonal lines
ZigZag Horizontal lines that are composed of zigzags.
private HatchStyle style = new HatchStyle();
private Color forClr = Color.Blue;
private Color backClr = Color.Red;
On the form's load event handler (see Listing 4.4), we fill the combo box with different hatch styles and set the background color properties of our two text boxes to the current colors
Listing 4.4 The form's load event handler
private void Form1_Load(object sender,
System.EventArgs e)
{
// Fill combo box with hatch styles
Trang 26// Set foreground and background colors
Listing 4.5 The FillHatchStyles method
private void FillHatchStyles()
Listing 4.6 The Pick button click event handler
private void ForeColorBtn_Click(object sender,
System.EventArgs e)
{
// Use ColorDialog to select a color
ColorDialog clrDlg = new ColorDialog();
if (clrDlg.ShowDialog() == DialogResult.OK)
{
// Save color as foreground color,
// and fill text box with this color
Trang 27ColorDialog clrDlg = new ColorDialog();
if (clrDlg.ShowDialog() == DialogResult.OK)
{
// Save color as background color,
// and fill text box with this color
backClr = clrDlg.Color;
textBox2.BackColor = backClr;
}
}
The last step is to apply the selected styles and colors, create a hatch brush, and use this brush to draw a rectangle This is all done on the
Apply Style button click event handler, which is shown in Listing 4.7 As you can see from this listing, first we create a HatchStyle object based
on the user selection in the combo box Then we create a HatchBrush object using the hatch style, background, and foreground colors After that we simply fill a rectangle with the hatch brush
Listing 4.7 The Apply Style button click event handler
private void ApplyBtn_Click(object sender,
// Create a hatch brush with selected
// hatch style and colors
Trang 28new HatchBrush(style, forClr, backClr);
If you compile and run the application and then click the Apply Style button, the default rectangle looks like Figure 4.5
Figure 4.5 The default hatch style rectangle
Let's select LightDownwardDiagonal for the hatch style, change the foreground and background colors, and click the Apply Style button Now
the output looks like Figure 4.6
Figure 4.6 The LightDownwardDiagonal style with different colors
Trang 29Let's change the hatch style and colors one more time This time we pick DiagonalCross as our hatch style Now the output looks like Figure
Trang 30In the NET Framework library, the TextureBrush class represents a texture brush Table 4.2 describes the properties of the TextureBrushclass.
Let's create an application using texture brushes We create a Windows application We also add a context menu to the form, along with five context menu items The final form looks like Figure 4.8
Figure 4.8 The texture brush application
Table 4.2 TextureBrush properties
Image Returns the Image object associated with a TextureBrush object.
Transform Represents a Matrix object that defines a local geometric transformation for the image.
WrapMode Represents a WrapMode enumeration that indicates the wrap mode for a texture brush.
Note
The WrapMode enumeration represents the wrap mode for a texture brush It has five members: Clamp, Tile, TileFlipX, TileFlipY, and TileFlipXY These members are described later, in Table 4.7
Trang 31Now we add a class-level variable of TextureBrush type to the application:
private TextureBrush txtrBrush = null;
The next step is to create a texture brush from an image and fill a rectangle with that brush We create an Image object on the form's load event handler from the file smallRoses.gif, which is used to create a TextureBrush object On the form's paint event handler, we call the FillRectangle method to fill the rectangle with the texture Listing 4.8 shows the form's load and paint event handler Note that our rectangle is the ClientRectangle of the form
Listing 4.8 Creating a texture brush and filling a rectangle
private void Form1_Load(object sender,
System.EventArgs e)
{
// Create an image from a file
Image img = new Bitmap("smallRoses.gif");
// Create a texture brush from an image
txtrBrush = new TextureBrush(img);
See Chapter 7 for details on the Image class
Now we can add event handlers for the context menu items as shown in Listing 4.9 As you can see from this code, we simply set the WrapMode property of the texture brush
Listing 4.9 TextureBrush's context menu event handlers
private void Clamp_Click(object sender,
System.EventArgs e)
{
txtrBrush.WrapMode = WrapMode.Clamp;
Trang 32Finally, we need to load the context menu on the right mouse click event handler As Listing 4.10 shows, we simply set the ContextMenu
property of the form
Listing 4.10 The right mouse button click event handler
private void Form1_MouseDown(object sender,
Now let's run the application Figure 4.9 shows default (tiled) output from the program The entire client rectangle is filled with the texture
Figure 4.9 Using texture brushes
Trang 33If we right-click on the form and select the Clamp menu item, we get Figure 4.10.
Figure 4.10 Clamping a texture
Now let's select the TileFlipY option, which generates Figure 4.11 You can try other options on your own!
Figure 4.11 The TileFlipY texture option
Trang 344.1.6 Gradient Brushes
Linear gradient brushes allow you to blend two colors together, generating an indefinite range of shades The Blend class defines a custom
falloff for the gradient
Note
Chapter 9 discusses the Blend class and alpha blending in more detail
In a gradient, we begin with a starting color and shift to an ending color, with gradual blending in the space between them In addition to the
starting and ending colors, we can specify the direction of the gradient For example, Figure 4.12 starts with green in the left bottom corner
and ends with red in the top right corner (You may not notice these colors exactly in a black-and-white image.)
Figure 4.12 A color gradient
Trang 35You can also specify a range for pattern repetition For example, you can specify that the gradient will occur from point (0, 0) to point (20, 20) and after that will repeat the same pattern, as in Figure 4.13.
Figure 4.13 A gradient pattern with pattern repetition
4.1.6.1 Linear Gradient Brushes
The LinearGradientBrush class has eight forms of overloaded constructors Each constructor takes a starting point, an ending point, and two gradient colors The orientation and linear gradient mode are optional
The following code snippet creates a linear gradient brush using the colors red and green:
Rectangle rect1 = new Rectangle(20, 20, 50, 50);
LinearGradientBrush lgBrush = new LinearGradientBrush
(rect1, Color.Red, Color.Green, LinearGradientMode.Horizontal);
Here the mode parameter is represented by the LinearGradientMode enumeration, which specifies the direction of a linear gradient The members of the LinearGradientMode enumeration are described in Table 4.3
Now let's look at the properties and methods of the LinearGradient-Brush class, which are defined in Tables 4.4 and 4.5, respectively