Home

Brushes

 

Fundamentals of Brushes

 

Introduction

Line-based and closed shapes require a pen to show their shape. The particularity with closed shapes is that they can be filled, with a color, a picture, or a pattern.

A brush is an object that holds a color, a picture, or a drawing pattern and that is used to fill the interior of a closed shape. This definition also means that there are various types of brushes with different goals. To meet these goals, the .NET Framework provides support for brushes in various namespaces with different classes. The parent of all brushes is the Brush class defined in the System.Drawing namespace.

Using a Brush

Because the main job of a brush is to fill a closed shape, the Graphics class provides a method that corresponds to each of the closed shapes we reviewed to draw in the previous lesson in order to fill it. The methods are:

  • FillRectangle: Used to fill the interior of a rectangle or a square
  • FillRectangle: Used to fill the interior of a series of rectangles
  • FillEllipse: Used to fill the interior of an ellipse or a circle
  • FillPolygon: Used to fill the interior of a polygon
  • FillClosedCurve: Used to fill the interior of a closed curve
  • FillPie: Used to fill the interior of a pie
  • FillPath: Used to fill the interior of a graphic path

To fill out a shape, call one of these methods, pass it a brush value, followed by the location and dimensions of the shape. For example, if you want to draw a rectangle and fill it with a brush, you would use code similar to:

open System
open System.Drawing
open System.Windows.Forms
open System.Drawing.Drawing2D

let exercise = new Form()

let exercisePaint(e : PaintEventArgs) =

    e.Graphics.FillRectangle(SomeBrush, 20, 20, 200, 160)

exercise.Paint.Add exercisePaint
do Application.Run exercise

Over all, there are four types of brushes.

Solid Brushes

 

Simple Colored Brushes

Like a pen, the primary characteristic of a brush is its color. To help you create a simple brush, the System.Drawing namespace provides the static sealed Brushes class. The only feature this class provides is the ability to specify a color to use on a brush. As a static class, you never have to instantiate it.

To create a simple brush whose only information is provided by its color, call the Brushes class and access a color by qualifying it with the name of the class. Each color is provided by its name as a property. Here is an example of using the class:

open System
open System.Drawing
open System.Windows.Forms

let exercise = new Form()

let exercisePaint(e : PaintEventArgs) =
    let pts : Point array = [| new Point( 10,  22)
                               new Point(188, 246)
                               new Point(280, 192)
                               new Point(250,  48) |]

    e.Graphics.FillClosedCurve(Brushes.BlanchedAlmond, pts)
    e.Graphics.DrawClosedCurve(Pens.Blue, pts)

exercise.Paint.Add exercisePaint
do Application.Run exercise

This would produce:

Brush

Creating a Solid Brush

The simplest type of brush is referred to as solid. This type of brush is simply equipped with a color and it is used to fill a shape with it. To get a solid brush, you use the SolidBrush class defined in the System.Drawing namespace. It has only one constructor declared with the following syntax:

new : 
        color:Color -> SolidBrush

The color passed as argument must be a valid definition of a Color. Here is an example:

open System
open System.Drawing
open System.Windows.Forms

let exercise = new Form()

let exercisePaint(e : PaintEventArgs) =
    let brushBlue : SolidBrush = new SolidBrush(Color.Blue)

    e.Graphics.FillRectangle(brushBlue, 20, 20, 200, 160)

exercise.Paint.Add exercisePaint
do Application.Run exercise

This would produce:

Brush

If you plan to use different colors to fill different shapes, you don't have to create a new brush for each shape. At any time, before re-using the same brush previously defined, you can simply change its Color. For this reason, the SolidBrush class is equipped with the Color property. Here is an example of using it:

open System
open System.Drawing
open System.Windows.Forms

let exercise = new Form()

let exercisePaint(e : PaintEventArgs) =
    let mutable colorizer : SolidBrush = new SolidBrush(Color.Lime)
    e.Graphics.FillRectangle(colorizer, 10, 10, 120, 120)

    colorizer.Color <- Color.Salmon
    e.Graphics.FillRectangle(colorizer, 140, 10, 120, 120)

    colorizer.Color <- Color.Aqua
    e.Graphics.FillRectangle(colorizer, 10, 140, 120, 120)

    colorizer.Color <- Color.Navy
    e.Graphics.FillRectangle(colorizer, 140, 140, 120, 120)

exercise.Paint.Add exercisePaint
do Application.Run exercise

This would produce:

Solid Brushes

Like most objects used in graphics programming, a brush consumes the computer resources. Therefore, after using it, you can free the resources it was using by calling the Dispose() method. Here is an example:

open System
open System.Drawing
open System.Windows.Forms

let exercise = new Form()

let exercisePaint(e : PaintEventArgs) =
    let mutable colorizer : SolidBrush = new SolidBrush(Color.Lime)
    e.Graphics.FillRectangle(colorizer, 10, 10, 120, 120)

    colorizer.Color <- Color.Salmon;
    e.Graphics.FillRectangle(colorizer, 140, 10, 120, 120)

    colorizer.Color <- Color.Aqua;
    e.Graphics.FillRectangle(colorizer, 10, 140, 120, 120)

    colorizer.Color <- Color.Navy;
    e.Graphics.FillRectangle(colorizer, 140, 140, 120, 120)

    colorizer.Dispose()

exercise.Paint.Add exercisePaint
do Application.Run exercise

As an alternative, for any class that needs (or requires) the Dispose() method, when creating its object, instead of the let keyword, use the use keyword. Here is an example:

open System
open System.Drawing
open System.Windows.Forms

let exercise = new Form()

let exercisePaint(e : PaintEventArgs) =
    use mutable colorizer : SolidBrush = new SolidBrush(Color.Lime)
    e.Graphics.FillRectangle(colorizer, 10, 10, 120, 120)

    colorizer.Color <- Color.Salmon;
    e.Graphics.FillRectangle(colorizer, 140, 10, 120, 120)

    colorizer.Color <- Color.Aqua;
    e.Graphics.FillRectangle(colorizer, 10, 140, 120, 120)

    colorizer.Color <- Color.Navy;
    e.Graphics.FillRectangle(colorizer, 140, 140, 120, 120)

exercise.Paint.Add exercisePaint
do Application.Run exercise

Hatch Brushes

 

Introduction

A hatch brush relies on a drawn or designed pattern to set its filling type. To support hatch brushes, the .NET Framework provides the patterns you can use as part of the brush. These pre-designed patterns are referred to as hatch styles. This means that when you use a hatch brush, you must specify the type of pattern you want to use, through one of the available hatch styles. To make the filled area more interesting, you also specify the color to use when drawing the pattern.

To get a hatch brush, you use the HatchBrush class. One of its constructors has the following syntaxes:

new : 
        hatchstyle:HatchStyle * 
        foreColor:Color -> HatchBrush

The Style of a Hatch Brush

The foreColor argument is the color that will be used to draw the pattern. The style argument is the hatch style you want to apply. Some of the available styles are:

open System
open System.Drawing
open System.Windows.Forms
open System.Drawing.Drawing2D

let exercise = new Form()

let exercisePaint(e : PaintEventArgs) =
    use brushBackDiag  : HatchBrush = new HatchBrush(HatchStyle.BackwardDiagonal, Color.FromArgb(0, 0, 255))
    use brushCross : HatchBrush  = new HatchBrush(HatchStyle.Cross, Color.FromArgb(200, 0, 0))
    use brushDarkDown : HatchBrush  = new HatchBrush(HatchStyle.DarkDownwardDiagonal, Color.Salmon)
    use brushDarkHorz : HatchBrush  = new HatchBrush(HatchStyle.DarkHorizontal, Color.Navy)
    use brushDarkUpDiag : HatchBrush  = new HatchBrush(HatchStyle.DarkUpwardDiagonal, Color.Pink)
    use brushVertical : HatchBrush  = new HatchBrush(HatchStyle.DarkVertical, Color.FromArgb(255, 0, 255))
    use brushDashDnDiag : HatchBrush  = new HatchBrush(HatchStyle.DashedDownwardDiagonal, Color.FromArgb(255, 128, 0))
    use brushDashHorz : HatchBrush  = new HatchBrush(HatchStyle.DashedHorizontal, Color.FromArgb(0, 128, 192))
    use brushDashUpDiag : HatchBrush  = new HatchBrush(HatchStyle.DashedUpwardDiagonal, Color.Green)
    use brushDashVert : HatchBrush  = new HatchBrush(HatchStyle.DashedVertical, Color.Firebrick);
    use brushDiagBrisk : HatchBrush  = new HatchBrush(HatchStyle.DiagonalBrick, Color.Fuchsia);
    use brushDiagCross : HatchBrush  = new HatchBrush(HatchStyle.DiagonalCross, Color.Moccasin)
    use brushDivot : HatchBrush  = new HatchBrush(HatchStyle.Divot, Color.Goldenrod)
    use brushDotDiamond : HatchBrush  = new HatchBrush(HatchStyle.DottedDiamond, Color.Gainsboro)
    use brushDottedGrid : HatchBrush  = new HatchBrush(HatchStyle.DottedGrid, Color.Khaki)
    use brushForDiag : HatchBrush  = new HatchBrush(HatchStyle.ForwardDiagonal, Color.Maroon)
    use brushHorz : HatchBrush  = new HatchBrush(HatchStyle.Horizontal, Color.Red)
    use brushHorzBrick : HatchBrush  = new HatchBrush(HatchStyle.HorizontalBrick, Color.SaddleBrown);
    use brushLgChkBoard : HatchBrush  = new HatchBrush(HatchStyle.LargeCheckerBoard, Color.RoyalBlue)
    use brushLgConfetti : HatchBrush  = new HatchBrush(HatchStyle.LargeConfetti, Color.MistyRose)
    use brushLgGrid : HatchBrush  = new HatchBrush(HatchStyle.LargeGrid, Color.Purple)
    use brushLtDnDiag : HatchBrush  = new HatchBrush(HatchStyle.LightDownwardDiagonal, Color.DarkCyan)
    use brushLtHorz : HatchBrush  = new HatchBrush(HatchStyle.LightHorizontal, Color.PowderBlue)
    use brushUpDiag : HatchBrush  = new HatchBrush(HatchStyle.LightUpwardDiagonal, Color.SeaGreen)
    use brushLtVert : HatchBrush  = new HatchBrush(HatchStyle.LightVertical, Color.Olive)

    e.Graphics.FillRectangle(brushBackDiag, 20, 20, 80, 60)
    e.Graphics.FillRectangle(brushCross, 120, 20, 80, 60)
    e.Graphics.FillRectangle(brushDarkDown, 220, 20, 80, 60)
    e.Graphics.FillRectangle(brushDarkHorz, 320, 20, 80, 60)
    e.Graphics.FillRectangle(brushDarkUpDiag, 420, 20, 80, 60)

    e.Graphics.FillRectangle(brushVertical, 20, 100, 80, 60);
    e.Graphics.FillRectangle(brushDashDnDiag, 120, 100, 80, 60)
    e.Graphics.FillRectangle(brushDashHorz, 220, 100, 80, 60)
    e.Graphics.FillRectangle(brushDashUpDiag, 320, 100, 80, 60)
    e.Graphics.FillRectangle(brushDashVert, 420, 100, 80, 60)

    e.Graphics.FillRectangle(brushDashVert, 20, 180, 80, 60)
    e.Graphics.FillRectangle(brushDiagBrisk, 120, 180, 80, 60)
    e.Graphics.FillRectangle(brushDiagCross, 220, 180, 80, 60)
    e.Graphics.FillRectangle(brushDivot, 320, 180, 80, 60)
    e.Graphics.FillRectangle(brushDotDiamond, 420, 180, 80, 60)

    e.Graphics.FillRectangle(brushDottedGrid, 20, 260, 80, 60)
    e.Graphics.FillRectangle(brushForDiag, 120, 260, 80, 60)
    e.Graphics.FillRectangle(brushHorz, 220, 260, 80, 60)
    e.Graphics.FillRectangle(brushHorzBrick, 320, 260, 80, 60)
    e.Graphics.FillRectangle(brushLgChkBoard, 420, 260, 80, 60)

    e.Graphics.FillRectangle(brushLgGrid, 20, 340, 80, 60)
    e.Graphics.FillRectangle(brushLtDnDiag, 120, 340, 80, 60)
    e.Graphics.FillRectangle(brushLtHorz, 220, 340, 80, 60)
    e.Graphics.FillRectangle(brushUpDiag, 320, 340, 80, 60)
    e.Graphics.FillRectangle(brushLtVert,  420, 340, 80, 60)

exercise.Paint.Add exercisePaint
do Application.Run exercise

This would produce:

Hatch Brushes

The Background Color of a Hatch Brush

If you use the above constructor to fill out a shape, the selected pattern would be drawn on top of a black color used as the background. If you want to use a different background, use the following constructor to initialize the brush:

new : 
        hatchstyle:HatchStyle * 
        foreColor:Color * 
        backColor:Color -> HatchBrush

The backColor argument passed as a Color value will be used as the background Color. Here are examples of specifying the back color:

open System
open System.Drawing
open System.Windows.Forms
open System.Drawing.Drawing2D

let exercise = new Form(ClientSize = new System.Drawing.Size(520, 420))

let tmrColorsChanger : Timer = new Timer(Interval = 20, Enabled = true)
let exercisePaint(e : PaintEventArgs) =
    let hsBrush : HatchStyle array =
        [|
            HatchStyle.BackwardDiagonal
            HatchStyle.Cross
            HatchStyle.Divot
            HatchStyle.DarkDownwardDiagonal
            HatchStyle.DarkHorizontal
            HatchStyle.ForwardDiagonal
            HatchStyle.DarkUpwardDiagonal
            HatchStyle.DarkVertical
            HatchStyle.HorizontalBrick
            HatchStyle.DashedDownwardDiagonal
            HatchStyle.DashedHorizontal
            HatchStyle.DashedVertical
            HatchStyle.LargeCheckerBoard
            HatchStyle.DiagonalBrick
            HatchStyle.Horizontal
            HatchStyle.DiagonalCross
            HatchStyle.DottedGrid
            HatchStyle.DottedDiamond
            HatchStyle.LightUpwardDiagonal
            HatchStyle.LargeConfetti
            HatchStyle.LargeGrid
            HatchStyle.LightDownwardDiagonal
            HatchStyle.OutlinedDiamond
            HatchStyle.LightHorizontal
            HatchStyle.LightVertical
        |]

    let ForeColors : Color array =
        [|
            Color.FromArgb(0, 0, 255)
            Color.FromArgb(200, 0, 0)
            Color.Salmon
            Color.Navy
            Color.Pink
            Color.FromArgb(255, 0, 255)
            Color.FromArgb(255, 128, 0)
            Color.FromArgb(0, 128, 192)
            Color.Green
            Color.Firebrick
            Color.Fuchsia
            Color.Moccasin
            Color.Goldenrod
            Color.Gainsboro
            Color.Khaki
            Color.Maroon
            Color.DarkCyan
            Color.Purple
            Color.MistyRose
            Color.RoyalBlue
            Color.Red
            Color.SaddleBrown
            Color.Olive
            Color.SeaGreen
            Color.PowderBlue
        |]

    let BackColors : Color array =
        [|
            Color.Azure
            Color.DarkBlue
            Color.AntiqueWhite
            Color.Aqua
            Color.DarkGray
            Color.Aquamarine
            Color.Azure
            Color.Beige
            Color.DarkGoldenrod
            Color.Bisque
            Color.DarkKhaki
            Color.BlanchedAlmond
            Color.Brown
            Color.DarkCyan
            Color.AliceBlue
            Color.BurlyWood
            Color.CadetBlue
            Color.DarkMagenta
            Color.Coral
            Color.Chartreuse
            Color.CornflowerBlue
            Color.Cornsilk
            Color.Crimson
            Color.Cyan
            Color.DarkGreen
        |]

    let rnd : Random = new Random()

    use brushBackDiag   : HatchBrush = new HatchBrush(hsBrush.[rnd.Next(25)], ForeColors.[rnd.Next(25)], BackColors.[rnd.Next(25)])
    use brushCross      : HatchBrush = new HatchBrush(hsBrush.[rnd.Next(25)], ForeColors.[rnd.Next(25)], BackColors.[rnd.Next(25)])
    use brushDarkDown   : HatchBrush = new HatchBrush(hsBrush.[rnd.Next(25)], ForeColors.[rnd.Next(25)], BackColors.[rnd.Next(25)])
    use brushDarkHorz   : HatchBrush = new HatchBrush(hsBrush.[rnd.Next(25)], ForeColors.[rnd.Next(25)], BackColors.[rnd.Next(25)])
    use brushDarkUpDiag : HatchBrush = new HatchBrush(hsBrush.[rnd.Next(25)], ForeColors.[rnd.Next(25)], BackColors.[rnd.Next(25)])
    use brushVertical   : HatchBrush = new HatchBrush(hsBrush.[rnd.Next(25)], ForeColors.[rnd.Next(25)], BackColors.[rnd.Next(25)])
    use brushDashDnDiag : HatchBrush = new HatchBrush(hsBrush.[rnd.Next(25)], ForeColors.[rnd.Next(25)], BackColors.[rnd.Next(25)])
    use brushDashHorz   : HatchBrush = new HatchBrush(hsBrush.[rnd.Next(25)], ForeColors.[rnd.Next(25)], BackColors.[rnd.Next(25)])
    use brushDashUpDiag : HatchBrush = new HatchBrush(hsBrush.[rnd.Next(25)], ForeColors.[rnd.Next(25)], BackColors.[rnd.Next(25)])
    use brushDashVert   : HatchBrush = new HatchBrush(hsBrush.[rnd.Next(25)], ForeColors.[rnd.Next(25)], BackColors.[rnd.Next(25)])
    use brushDiagBrisk  : HatchBrush = new HatchBrush(hsBrush.[rnd.Next(25)], ForeColors.[rnd.Next(25)], BackColors.[rnd.Next(25)])
    use brushDiagCross  : HatchBrush = new HatchBrush(hsBrush.[rnd.Next(25)], ForeColors.[rnd.Next(25)], BackColors.[rnd.Next(25)])
    use brushDivot      : HatchBrush = new HatchBrush(hsBrush.[rnd.Next(25)], ForeColors.[rnd.Next(25)], BackColors.[rnd.Next(25)])
    use brushDotDiamond : HatchBrush = new HatchBrush(hsBrush.[rnd.Next(25)], ForeColors.[rnd.Next(25)], BackColors.[rnd.Next(25)])
    use brushDottedGrid : HatchBrush = new HatchBrush(hsBrush.[rnd.Next(25)], ForeColors.[rnd.Next(25)], BackColors.[rnd.Next(25)])
    use brushForDiag    : HatchBrush = new HatchBrush(hsBrush.[rnd.Next(25)], ForeColors.[rnd.Next(25)], BackColors.[rnd.Next(25)])
    use brushHorz       : HatchBrush = new HatchBrush(hsBrush.[rnd.Next(25)], ForeColors.[rnd.Next(25)], BackColors.[rnd.Next(25)])
    use brushHorzBrick  : HatchBrush = new HatchBrush(hsBrush.[rnd.Next(25)], ForeColors.[rnd.Next(25)], BackColors.[rnd.Next(25)])
    use brushLgChkBoard : HatchBrush = new HatchBrush(hsBrush.[rnd.Next(25)], ForeColors.[rnd.Next(25)], BackColors.[rnd.Next(25)])
    use brushLgConfetti : HatchBrush = new HatchBrush(hsBrush.[rnd.Next(25)], ForeColors.[rnd.Next(25)], BackColors.[rnd.Next(25)])
    use brushLgGrid     : HatchBrush = new HatchBrush(hsBrush.[rnd.Next(25)], ForeColors.[rnd.Next(25)], BackColors.[rnd.Next(25)])
    use brushLtDnDiag   : HatchBrush = new HatchBrush(hsBrush.[rnd.Next(25)], ForeColors.[rnd.Next(25)], BackColors.[rnd.Next(25)])
    use brushLtHorz     : HatchBrush = new HatchBrush(hsBrush.[rnd.Next(25)], ForeColors.[rnd.Next(25)], BackColors.[rnd.Next(25)])
    use brushUpDiag     : HatchBrush = new HatchBrush(hsBrush.[rnd.Next(25)], ForeColors.[rnd.Next(25)], BackColors.[rnd.Next(25)])
    use brushLtVert     : HatchBrush = new HatchBrush(hsBrush.[rnd.Next(25)], ForeColors.[rnd.Next(25)], BackColors.[rnd.Next(25)])

    e.Graphics.FillRectangle(brushBackDiag,     20, 20, 80, 60)
    e.Graphics.FillRectangle(brushCross,       120, 20, 80, 60)
    e.Graphics.FillRectangle(brushDarkDown,    220, 20, 80, 60)
    e.Graphics.FillRectangle(brushDarkHorz,    320, 20, 80, 60)
    e.Graphics.FillRectangle(brushDarkUpDiag,  420, 20, 80, 60)

    e.Graphics.FillRectangle(brushVertical,    20, 100, 80, 60)
    e.Graphics.FillRectangle(brushDashDnDiag, 120, 100, 80, 60)
    e.Graphics.FillRectangle(brushDashHorz,   220, 100, 80, 60)
    e.Graphics.FillRectangle(brushDashUpDiag, 320, 100, 80, 60)
    e.Graphics.FillRectangle(brushDashVert,   420, 100, 80, 60)

    e.Graphics.FillRectangle(brushDashVert,    20, 180, 80, 60)
    e.Graphics.FillRectangle(brushDiagBrisk,  120, 180, 80, 60)
    e.Graphics.FillRectangle(brushDiagCross,  220, 180, 80, 60)
    e.Graphics.FillRectangle(brushDivot,      320, 180, 80, 60)
    e.Graphics.FillRectangle(brushDotDiamond, 420, 180, 80, 60)

    e.Graphics.FillRectangle(brushDottedGrid,  20, 260, 80, 60)
    e.Graphics.FillRectangle(brushForDiag,    120, 260, 80, 60)
    e.Graphics.FillRectangle(brushHorz,       220, 260, 80, 60)
    e.Graphics.FillRectangle(brushHorzBrick,  320, 260, 80, 60)
    e.Graphics.FillRectangle(brushLgChkBoard, 420, 260, 80, 60)

    e.Graphics.FillRectangle(brushLgGrid,      20, 340, 80, 60)
    e.Graphics.FillRectangle(brushLtDnDiag,   120, 340, 80, 60)
    e.Graphics.FillRectangle(brushLtHorz,     220, 340, 80, 60)
    e.Graphics.FillRectangle(brushUpDiag,     320, 340, 80, 60)
    e.Graphics.FillRectangle(brushLtVert,     420, 340, 80, 60)

exercise.Paint.Add exercisePaint
do Application.Run exercise

Here is a version that uses a timer:

open System
open System.Drawing
open System.Windows.Forms
open System.Drawing.Drawing2D

let hsBrush : HatchStyle array =
    [|
        HatchStyle.BackwardDiagonal
        HatchStyle.Cross
        HatchStyle.Divot
        HatchStyle.DarkDownwardDiagonal
        HatchStyle.DarkHorizontal
        HatchStyle.ForwardDiagonal
        HatchStyle.DarkUpwardDiagonal
        HatchStyle.DarkVertical
        HatchStyle.HorizontalBrick
        HatchStyle.DashedDownwardDiagonal
        HatchStyle.DashedHorizontal
        HatchStyle.DashedVertical
        HatchStyle.LargeCheckerBoard
        HatchStyle.DiagonalBrick
        HatchStyle.Horizontal
        HatchStyle.DiagonalCross
        HatchStyle.DottedGrid
        HatchStyle.DottedDiamond
        HatchStyle.LightUpwardDiagonal
        HatchStyle.LargeConfetti
        HatchStyle.LargeGrid
        HatchStyle.LightDownwardDiagonal
        HatchStyle.OutlinedDiamond
        HatchStyle.LightHorizontal
        HatchStyle.LightVertical
    |]

let ForeColors : Color array =
    [|
        Color.FromArgb(0, 0, 255)
        Color.FromArgb(200, 0, 0)
        Color.Salmon
        Color.Navy
        Color.Pink
        Color.FromArgb(255, 0, 255)
        Color.FromArgb(255, 128, 0)
        Color.FromArgb(0, 128, 192)
        Color.Green
        Color.Firebrick
        Color.Fuchsia
        Color.Moccasin
        Color.Goldenrod
        Color.Gainsboro
        Color.Khaki
        Color.Maroon
        Color.DarkCyan
        Color.Purple
        Color.MistyRose
        Color.RoyalBlue
        Color.Red
        Color.SaddleBrown
        Color.Olive
        Color.SeaGreen
        Color.PowderBlue
    |]

let BackColors : Color array =
    [|
        Color.Azure
        Color.DarkBlue
        Color.AntiqueWhite
        Color.Aqua
        Color.DarkGray
        Color.Aquamarine
        Color.Azure
        Color.Beige
        Color.DarkGoldenrod
        Color.Bisque
        Color.DarkKhaki
        Color.BlanchedAlmond
        Color.Brown
        Color.DarkCyan
        Color.AliceBlue
        Color.BurlyWood
        Color.CadetBlue
        Color.DarkMagenta
        Color.Coral
        Color.Chartreuse
        Color.CornflowerBlue
        Color.Cornsilk
        Color.Crimson
        Color.Cyan
        Color.DarkGreen
    |]

let mutable brushBackDiag   = Brushes.White
let mutable brushCross      = Brushes.White
let mutable brushDarkDown   = Brushes.White
let mutable brushDarkHorz   = Brushes.White
let mutable brushDarkUpDiag = Brushes.White
let mutable brushVertical   = Brushes.White
let mutable brushDashDnDiag = Brushes.White
let mutable brushDashHorz   = Brushes.White
let mutable brushDashUpDiag = Brushes.White
let mutable brushDashVert   = Brushes.White
let mutable brushDiagBrisk  = Brushes.White
let mutable brushDiagCross  = Brushes.White
let mutable brushDivot      = Brushes.White
let mutable brushDotDiamond = Brushes.White
let mutable brushDottedGrid = Brushes.White
let mutable brushForDiag    = Brushes.White
let mutable brushHorz       = Brushes.White
let mutable brushHorzBrick  = Brushes.White
let mutable brushLgChkBoard = Brushes.White
let mutable brushLgConfetti = Brushes.White
let mutable brushLgGrid     = Brushes.White
let mutable brushLtDnDiag   = Brushes.White
let mutable brushLtHorz     = Brushes.White
let mutable brushUpDiag     = Brushes.White
let mutable brushLtVert     = Brushes.White

let rnd : Random = new Random()

let exercise = new Form(ClientSize = new System.Drawing.Size(520, 420))

let tmrColorsChanger : Timer = new Timer(Interval = 500, Enabled = true)
let tmrColorsChangerTick e =
    brushBackDiag   <- new HatchBrush(hsBrush.[rnd.Next(25)], ForeColors.[rnd.Next(25)], BackColors.[rnd.Next(25)])
    brushCross      <- new HatchBrush(hsBrush.[rnd.Next(25)], ForeColors.[rnd.Next(25)], BackColors.[rnd.Next(25)])
    brushDarkDown   <- new HatchBrush(hsBrush.[rnd.Next(25)], ForeColors.[rnd.Next(25)], BackColors.[rnd.Next(25)])
    brushDarkHorz   <- new HatchBrush(hsBrush.[rnd.Next(25)], ForeColors.[rnd.Next(25)], BackColors.[rnd.Next(25)])
    brushDarkUpDiag <- new HatchBrush(hsBrush.[rnd.Next(25)], ForeColors.[rnd.Next(25)], BackColors.[rnd.Next(25)])
    brushVertical   <- new HatchBrush(hsBrush.[rnd.Next(25)], ForeColors.[rnd.Next(25)], BackColors.[rnd.Next(25)])
    brushDashDnDiag <- new HatchBrush(hsBrush.[rnd.Next(25)], ForeColors.[rnd.Next(25)], BackColors.[rnd.Next(25)])
    brushDashHorz   <- new HatchBrush(hsBrush.[rnd.Next(25)], ForeColors.[rnd.Next(25)], BackColors.[rnd.Next(25)])
    brushDashUpDiag <- new HatchBrush(hsBrush.[rnd.Next(25)], ForeColors.[rnd.Next(25)], BackColors.[rnd.Next(25)])
    brushDashVert   <- new HatchBrush(hsBrush.[rnd.Next(25)], ForeColors.[rnd.Next(25)], BackColors.[rnd.Next(25)])
    brushDiagBrisk  <- new HatchBrush(hsBrush.[rnd.Next(25)], ForeColors.[rnd.Next(25)], BackColors.[rnd.Next(25)])
    brushDiagCross  <- new HatchBrush(hsBrush.[rnd.Next(25)], ForeColors.[rnd.Next(25)], BackColors.[rnd.Next(25)])
    brushDivot      <- new HatchBrush(hsBrush.[rnd.Next(25)], ForeColors.[rnd.Next(25)], BackColors.[rnd.Next(25)])
    brushDotDiamond <- new HatchBrush(hsBrush.[rnd.Next(25)], ForeColors.[rnd.Next(25)], BackColors.[rnd.Next(25)])
    brushDottedGrid <- new HatchBrush(hsBrush.[rnd.Next(25)], ForeColors.[rnd.Next(25)], BackColors.[rnd.Next(25)])
    brushForDiag    <- new HatchBrush(hsBrush.[rnd.Next(25)], ForeColors.[rnd.Next(25)], BackColors.[rnd.Next(25)])
    brushHorz       <- new HatchBrush(hsBrush.[rnd.Next(25)], ForeColors.[rnd.Next(25)], BackColors.[rnd.Next(25)])
    brushHorzBrick  <- new HatchBrush(hsBrush.[rnd.Next(25)], ForeColors.[rnd.Next(25)], BackColors.[rnd.Next(25)])
    brushLgChkBoard <- new HatchBrush(hsBrush.[rnd.Next(25)], ForeColors.[rnd.Next(25)], BackColors.[rnd.Next(25)])
    brushLgConfetti <- new HatchBrush(hsBrush.[rnd.Next(25)], ForeColors.[rnd.Next(25)], BackColors.[rnd.Next(25)])
    brushLgGrid     <- new HatchBrush(hsBrush.[rnd.Next(25)], ForeColors.[rnd.Next(25)], BackColors.[rnd.Next(25)])
    brushLtDnDiag   <- new HatchBrush(hsBrush.[rnd.Next(25)], ForeColors.[rnd.Next(25)], BackColors.[rnd.Next(25)])
    brushLtHorz     <- new HatchBrush(hsBrush.[rnd.Next(25)], ForeColors.[rnd.Next(25)], BackColors.[rnd.Next(25)])
    brushUpDiag     <- new HatchBrush(hsBrush.[rnd.Next(25)], ForeColors.[rnd.Next(25)], BackColors.[rnd.Next(25)])
    brushLtVert     <- new HatchBrush(hsBrush.[rnd.Next(25)], ForeColors.[rnd.Next(25)], BackColors.[rnd.Next(25)])
    
    exercise.Invalidate()
tmrColorsChanger.Tick.Add tmrColorsChangerTick

let exercisePaint(e : PaintEventArgs) =
    e.Graphics.FillRectangle(brushBackDiag,     20, 20, 80, 60)
    e.Graphics.FillRectangle(brushCross,       120, 20, 80, 60)
    e.Graphics.FillRectangle(brushDarkDown,    220, 20, 80, 60)
    e.Graphics.FillRectangle(brushDarkHorz,    320, 20, 80, 60)
    e.Graphics.FillRectangle(brushDarkUpDiag,  420, 20, 80, 60)

    e.Graphics.FillRectangle(brushVertical,    20, 100, 80, 60)
    e.Graphics.FillRectangle(brushDashDnDiag, 120, 100, 80, 60)
    e.Graphics.FillRectangle(brushDashHorz,   220, 100, 80, 60)
    e.Graphics.FillRectangle(brushDashUpDiag, 320, 100, 80, 60)
    e.Graphics.FillRectangle(brushDashVert,   420, 100, 80, 60)

    e.Graphics.FillRectangle(brushDashVert,    20, 180, 80, 60)
    e.Graphics.FillRectangle(brushDiagBrisk,  120, 180, 80, 60)
    e.Graphics.FillRectangle(brushDiagCross,  220, 180, 80, 60)
    e.Graphics.FillRectangle(brushDivot,      320, 180, 80, 60)
    e.Graphics.FillRectangle(brushDotDiamond, 420, 180, 80, 60)

    e.Graphics.FillRectangle(brushDottedGrid,  20, 260, 80, 60)
    e.Graphics.FillRectangle(brushForDiag,    120, 260, 80, 60)
    e.Graphics.FillRectangle(brushHorz,       220, 260, 80, 60)
    e.Graphics.FillRectangle(brushHorzBrick,  320, 260, 80, 60)
    e.Graphics.FillRectangle(brushLgChkBoard, 420, 260, 80, 60)

    e.Graphics.FillRectangle(brushLgGrid,      20, 340, 80, 60)
    e.Graphics.FillRectangle(brushLtDnDiag,   120, 340, 80, 60)
    e.Graphics.FillRectangle(brushLtHorz,     220, 340, 80, 60)
    e.Graphics.FillRectangle(brushUpDiag,     320, 340, 80, 60)
    e.Graphics.FillRectangle(brushLtVert,     420, 340, 80, 60)

exercise.Paint.Add exercisePaint
do Application.Run exercise

At any time, to find out the color used to paint a pattern, you can access the brush's ForegroundColor property. To know the color used as background, you can access the brush's BackgroundColor property. To know the hatch style used on the current brush, you can access its HatchStyle property.

 
 

Texture Brushes

 

Introduction

The hatch brushes we have used are based on already designed patterns to fill a shape. In some cases, you may want to create or design your own pattern and use it to fill an area. To do this, you must perform two main steps. First, you must design a picture and save it as a file. Then you must create an object referred to as a texture brush and pass the picture to it.

A texture brush is an object that holds a picture and uses it to regularly fill the interior of a closed shape. To initialize it, you can use an existing picture designed by someone else or you can design your own picture using any normal graphics application, including Microsoft Paint that is automatically installed with Microsoft Window. You should have the picture as a file with a normal graphics file extension, which could be .bmp. Equipped with the picture, you can then use the TextureBrush class that provides various constructors.

Creating a Texture Brush

The simplest constructor of this class takes as argument an Image object. The syntax of this constructor is:

new : 
    bitmap:Image -> TextureBrush

This constructor expects a bitmap as argument. After initializing the brush, you can use it to fill the interior of a closed shape. For example, you can call a Fill... method to paint its shape. Here is an example:

open System
open System.Drawing
open System.Windows.Forms

let exercise = new Form()

let exercisePaint(e : PaintEventArgs) =
    let bmpPapers : Bitmap = new Bitmap(@"C:\Resources\Paper.bmp")
    let brushPapers : TextureBrush = new TextureBrush(bmpPapers)
    e.Graphics.FillRectangle(brushPapers, 5, 5, 430, 280)

exercise.Paint.Add exercisePaint
do Application.Run exercise

Texture Brush

If you use this constructor, the compiler would itself find out the location and dimensions of the picture in the area where it was designed. Although the location must be at (0, 0), the width and the height must be lower or equal to the intended dimensions of the bitmap. For example, if you have a picture that is 48x48 pixels, the width you can use from this picture must be <= 48 and the height must be <= 48. This allows you to use only a portion of the picture if you want. To use a portion of the picture, you can use the following constructor:

new : 
        image:Image * 
        dstRect:Rectangle -> TextureBrush

The second argument to this constructor is used to specify the width and height of the picture. If you prefer to use a rectangle whose arguments are decimal numbers, you can use the following constructor:

new : 
        image:Image * 
        dstRect:RectangleF -> TextureBrush

Here is an example:

open System
open System.Drawing
open System.Windows.Forms

let exercise = new Form()

let exercisePaint(e : PaintEventArgs) =
    let bmpPapers : Bitmap = new Bitmap(@"C:\Resources\Paper.bmp")
    let brushPapers : TextureBrush = new TextureBrush(bmpPapers,
    						      new Rectangle(0, 0, 42, 42))
    e.Graphics.FillRectangle(brushPapers, 5, 5, 416, 290)

exercise.Paint.Add exercisePaint
do Application.Run exercise

Texture Brush

Wrapping a Texture Brush

The constructors we have used so far allow you to draw the bitmap in each allocated rectangle in a tiled fashion. To make it more fun, the TextureBrush class is equipped with a factor referred to as wrap mode. This factor specifies how the tiling must be performed. To apply it, you can use one of the following constructors:

new : 
        image:Image * 
        wrapMode:WrapMode -> TextureBrush

new : 
        image:Image * 
        wrapMode:WrapMode * 
        dstRect:Rectangle -> TextureBrush

new : 
        image:Image * 
        wrapMode:WrapMode * 
        dstRect:RectangleF -> TextureBrush

The bitmap and the destination arguments are used in the same way we have done so far. The wrapMode argument is a member of the WrapMode enumerator. The WrapMode enumerator is defined in the System.Drawing.Drawing2D namespace. It has the following members:

Clamp: Draws one picture in the allocated rectangle:

open System
open System.Drawing
open System.Windows.Forms
open System.Drawing.Drawing2D

let exercise = new Form()

let exercisePaint(e : PaintEventArgs) =
    let bmpPapers : Bitmap = new Bitmap(@"C:\Resources\Paper.bmp")
    let brushPapers : TextureBrush = new TextureBrush(bmpPapers,
    						      WrapMode.Clamp)
    e.Graphics.FillRectangle(brushPapers, 5, 5, 438, 290)

exercise.Paint.Add exercisePaint
do Application.Run exercise

Texture Brush

Tile: Draws the picture continuous in a tiled fashion:

open System
open System.Drawing
open System.Windows.Forms
open System.Drawing.Drawing2D

let exercise = new Form()

let exercisePaint(e : PaintEventArgs) =
    let bmpPapers : Bitmap = new Bitmap(@"C:\Resources\Paper.bmp")
    let brushPapers : TextureBrush = new TextureBrush(bmpPapers,
    						      WrapMode.Tile,
    						      new Rectangle(0, 0, 42, 42))
    e.Graphics.FillRectangle(brushPapers, 5, 5, 414, 290)

exercise.Paint.Add exercisePaint
do Application.Run exercise

Texture Brush

TileFlipX: Draws the picture, draws it again on its right side but flipped horizontally, and then repeats this technique continuous in a tiled fashion and in the allocated rectangle:

open System
open System.Drawing
open System.Windows.Forms
open System.Drawing.Drawing2D

let exercise = new Form()

let exercisePaint(e : PaintEventArgs) =
    let bmpPapers : Bitmap = new Bitmap(@"C:\Resources\Paper.bmp")
    let brushPapers : TextureBrush = new TextureBrush(bmpPapers,
    						      WrapMode.TileFlipX)
    e.Graphics.FillRectangle(brushPapers, 5, 5, 430, 280)

exercise.Paint.Add exercisePaint
do Application.Run exercise

Tile Flip X

TileFlipY: Draws the picture, draws it again under it but flipped vertically, and then repeats this technique continuous in a tiled fashion and in the allocated rectangle:

open System
open System.Drawing
open System.Windows.Forms
open System.Drawing.Drawing2D

let exercise = new Form()

let exercisePaint(e : PaintEventArgs) =
    let bmpPapers : Bitmap = new Bitmap(@"C:\Resources\Paper.bmp")
    let brushPapers : TextureBrush = new TextureBrush(bmpPapers,
                                                      WrapMode.TileFlipX,
                                                      new Rectangle(0, 0, 42, 42))
    e.Graphics.FillRectangle(brushPapers, 5, 5, 412, 290)

exercise.Paint.Add exercisePaint
do Application.Run exercise

Tile Flip Y

TileFlipXY: Draws the picture, draws it again on its right side but flipped horizontally, then draws both the original and the right copy under each other but flipped vertically. These four pictures are redrawn in a tiled fashion and in the allocated rectangle:

open System
open System.Drawing
open System.Windows.Forms
open System.Drawing.Drawing2D

let exercise = new Form()

let exercisePaint(e : PaintEventArgs) =
    let bmpPapers : Bitmap = new Bitmap(@"C:\Resources\Paper.bmp")
    let brushPapers : TextureBrush = new TextureBrush(bmpPapers,
                                                      WrapMode.TileFlipXY,
                                                      new Rectangle(0, 0, 42, 42))
    e.Graphics.FillRectangle(brushPapers, 5, 5, 412, 244)

exercise.Paint.Add exercisePaint
do Application.Run exercise

Texture Brush

Gradient Brushes

 

Introduction

A gradient brush resembles a solid brush in that it is color-based. Unlike a solid brush, a gradient brush uses two colors. Its main characteristic is that, when used, one color is applied on one side and the other color is applied to the other side. In between, both colors merge to create a transition or fading effect.

There are two types of gradient brushes: linear and path.

Linear Gradient Brushes

A linear gradient is used to apply two colors in a closed shape but from one side of the shape, such as the left, to the other opposite side of the shape, such as the right.

To support linear gradient brushes, the .NET Framework provides the LinearGradientBrush class defined in the System.Drawing.Drawing2D namespace. To specify the starting and the end points inside of the shape that you want to fill, you can use one of the following constructors:

new : 
        point1:Point * 
        point2:Point * 
        color1:Color * 
        color2:Color -> LinearGradientBrush

new : 
        point1:PointF * 
        point2:PointF * 
        color1:Color * 
        color2:Color -> LinearGradientBrush

The first argument, point1, is the point where the drawing would start. The third argument, color1, is the color that would be applied from that point. The second argument, point2, is the point where the drawing would end by applying the color specified by the fourth argument, color2.

Here is an example:

open System
open System.Drawing
open System.Windows.Forms
open System.Drawing.Drawing2D

let exercise = new Form(Text = "Gradient Brushes")

let exercisePaint(e : PaintEventArgs) =
    let lgb : LinearGradientBrush  = new LinearGradientBrush(new Point(20, 20),
                                                             new Point(450, 20),
                                                             Color.DarkGreen,
                                                             Color.LightBlue)
    e.Graphics.FillRectangle(lgb, 20, 20, 430, 180)

exercise.Paint.Add exercisePaint
do Application.Run exercise

Gradient Brush

By default, the linear gradient brush fills its gradient based on a horizontal line. If you want the color merge to use a different orientation, such as vertical or diagonal, you can use one of the following constructors:

new : 
        rect:Rectangle * 
        color1:Color * 
        color2:Color * 
        linearGradientMode:LinearGradientMode -> LinearGradientBrush

new : 
        rect:RectangleF * 
        color1:Color * 
        color2:Color * 
        linearGradientMode:LinearGradientMode -> LinearGradientBrush

The first argument, rect, is the rectangle inside of which the colors would be applied. The second argument, color1, is the color that would be applied from a starting point. The second argument, color2, is the color that would be applied at the other end. The factor argument is used to determine the orientation of the merging colors. It has the following members:

Vertical: The first color, color1,  is applied to the top section of the rect argument. The second color, color2,  is applied to the bottom section of the rect argument:

open System
open System.Drawing
open System.Windows.Forms
open System.Drawing.Drawing2D

let exercise = new Form(Text = "Gradient Brushes")

let exercisePaint(e : PaintEventArgs) =
    let rect : Rectangle = new Rectangle(10, 10, 470, 300)
    let lgb = new LinearGradientBrush(rect,
                                      Color.DarkRed,
                                      Color.White,
                                      LinearGradientMode.Vertical)
    e.Graphics.FillRectangle(lgb, 10, 10, 450, 280)

exercise.Paint.Add exercisePaint
do Application.Run exercise

Linear Brush

Horizontal: The first color, color1,  is applied to the left section of the rect argument. The second color, color2,  is applied to the right section of the rect argument

Linear Brush

BackwardDiagonal: The first color, color1,  is applied to the top-right corner of the rect argument. The second color, color2,  is applied to the bottom-left corner of the rect argument:

Gradient Brush

ForwardDiagonal: The first color, color1,  is applied to the top-left corner of the rect argument. The second color, color2, is applied to the bottom-right corner of the rect argument:

The constructor used to produce the above orientation has the limitation that it provides only four options. If you want, you can apply any angular merge as you see fit. To do this, you can use one of the following constructors:

new : 
        rect:Rectangle * 
        color1:Color * 
        color2:Color * 
        angle:float32 -> LinearGradientBrush

new : 
        rect:RectangleF * 
        color1:Color * 
        color2:Color * 
        angle:float32 -> LinearGradientBrush

The first argument, rect, is the rectangle inside of which the colors would be applied. The last argument, angle, is an angle measured clockwise, that will specify the orientation of the merging colors The second argument, color1, is the color that would be applied from the starting point. The second argument, color2, is the color that would be applied at the other end. Here is an example:

open System
open System.Drawing
open System.Windows.Forms
open System.Drawing.Drawing2D

let exercise = new Form(Text = "Gradient Brushes")

let exercisePaint(e : PaintEventArgs) =
    let rect : Rectangle = new Rectangle(10, 10, 470, 300)
    let lgb = new LinearGradientBrush(rect, Color.DarkRed, Color.White, -65.24F)
    e.Graphics.FillRectangle(lgb, 10, 10, 450, 280)

exercise.Paint.Add exercisePaint
do Application.Run exercise

Linear Brush

Path Gradient Brushes

The second type of gradient brush available is referred to as path gradient. This brush is applied on a path created by connecting a series of points to get a closed shape.  The interior of the shape can then be filled as a gradient.

To support path brushes, the .NET Framework provides the PathGradientBrush from the System.Drawing.Drawing2D namespace. Two of the constructors of this class are:

new : 
        points:Point[] -> PathGradientBrush

new : 
        points:PointF[] -> PathGradientBrush

The argument passed to this constructor is an array of type Point. Here is an example:

open System
open System.Drawing
open System.Windows.Forms
open System.Drawing.Drawing2D

let exercise = new Form()

let exercisePaint(e : PaintEventArgs) =
    let ptGraph : Point array =
        [|
            new Point( 10,  10)
            new Point(450,  10)
            new Point(450, 250)
            new Point( 10, 250)
        |]

    let pgb : PathGradientBrush = new PathGradientBrush(ptGraph)
    e.Graphics.FillRectangle(pgb, 10, 10, 450, 280)

exercise.Paint.Add exercisePaint
do Application.Run exercise

Path Gradient Brush

 

   
   
 

Home Copyright © 2015 FunctionX Home