Drawing simple graphics

This section shows several DrawContents implementations. The first implementation draws a rectangle geometry around text using the default bundle; the second implementation changes the rectangle to an ellipse graphic; the third implementation draws a star polygon graphic using a simple bundle; the fourth implementation uses a group to create, draw, and translate two stars.

The graphic and geometry classes have a number of constructors from which you can choose. These examples construct graphics directly from the computational geometry and point array classes described under the heading "Underlying geometry classes" on page 36 to help you understand how geometries are built.

In the rectangle example, the drawing is done by calling the TGrafPort::Draw function. In the other examples an MGraphic derived class is used to create the shape and the MGraphic::Draw function is called instead. Using the geometry class directly and passing it to the TGrafPort::Draw function is a fast way to draw that uses very little overhead. You would take this approach when you don't need the functionality provided by MGraphic. TGrafPort::Draw accepts an optional transformation matrix and attribute bundle.

You would use an MGraphic derived class to arrange simple graphics into a group or picture, or to use the MGraphic transformation functions to transform the MGraphic derived class without using a matrix. See Chapter 19 for information on drawing ports, and see the heading "2-D transformation matrix" on page 38 for information on the 2-D transformation matrix.

Draw a rectangle around some text

This DrawContents implementation draws a text string in the view and puts a rectangle around the text string. Figure 11 shows how the rectangle and text look at run time. The origin (0,0) is in the upper-left corner of the view. Positive x values increase to the right, and positive y values increase as you go down.


    1  void DrawContents( TGrafPort& thePort ) const
    2  {
    3      TGRect aRectangle( TGPoint( 10, 10 ), TGPoint( 125, 40 ) );
    4      thePort.Draw( aRectangle );
    5  
    6      TStandardText theText( "Hello World" );
    7      TTextDisplay  theDisplayedText( theText );
    8      theDisplayedText.SetOrigin( TGPoint( 30, 30 ) );
    9      theDisplayedText.Draw( thePort );
    10  }

Create the rectangle

Lines 3 and 4: The
rectangle is created from the computational geometry TGRect and the default bundle. The default bundle draws the rectangle with a black hairline frame and no fill. Chapter 4 shows how to create a rounded rectangle using the loop geometry.

The rectangle instantiation specifies two parameters of type TGPoint. The first parameter, (10, 10) specifies the upper-left corner of the rectangle, and the second parameter (125, 40) specifies the bottom-right corner of the rectangle.

Create the text string

Lines 6 through 9: This text string "Hello World" is already present in the HelloWorld sample application. It instantiated as a TStandardText. TStandardText is passed to the constructor of TTextDisplay to display the standard text string in a single, uneditable line using the system font. The first letter of the text string begins at TGPoint (30, 30).

TGPoint is a computational geometry class that represents x and y coordinate values in 2-D space. A TTextDisplay text string cannot be transformed. If you want a text string that can be transformed, use TTextGraphic. TTextGraphic descends from MGraphic, but is described as part of the Text system. See that volume for more information.

TTextDisplay attributes

You can use TTextDisplay member functions to specify text attributes such as type face, point size, and color of the text string. The following code fragment could be added to the DrawContents function above to change the text string to the Chicago type face using 12 point type and a cyan fill.

      theDisplayedText.SetFont( TToken ( "Chicago" ) );
      theDisplayedText.SetPointSize( 12 );
      theDisplayedText.SetColor( TTextColorStyle::GetCyan() );

Change the rectangle to an ellipse

This DrawContents implementation changes the rectangle to an ellipse. Figure 12
shows how the ellipse and text look at run time.


    1  void DrawContents( TGrafPort& thePort ) const
    2  {
    3      TEllipse ellipse( TGRect( TGPoint( 10, 10 ), TGPoint( 125, 40 ) ) );
    4      ellipse.Draw( thePort );
    5  
    6      TStandardText theText( "Hello World" );
    7      TTextDisplay  theDisplayedText( theText );
    8      theDisplayedText.SetOrigin( TGPoint( 30, 30 ) );
    9      theDisplayedText.Draw( thePort );
    10  }

Create the ellipse

Lines 3 and 4: The
ellipse is created from the computational geometry
TGRect and the default bundle. The first TGRect parameter defines the upper-left corner, and the second parameter defines the lower-right corner of
the rectangle.

NOTE You could have constructed the TEllipse with the TGEllipse geometry class. A TGEllipse can be passed to a TGCurve with two angle values to construct a curve from an ellipse and two angles (see Chapter 4 for an example); and a TGEllipse can be used with an area geometry to create an arbitrary shape (see Chapter 5 for an example).

Default bundle

Since no bundle is created and used in this code, the default bundle is supplied by the drawing port. This default bundle draws the ellipse with a black hairline frame and no fill. When an ellipse is constructed from a rectangle, the sides of the ellipse bisect the midpoints of the sides of the rectangle.

Draw a star with a simple bundle

This DrawContents implementation creates a star polygon (TPolygon) from a polygon geometry (TGPolygon). Figure 13 shows how the star looks at run time.


    1  void DrawContents( TGrafPort& thePort ) const
    2  {
    3      TGPolygon aPolygonGeometry;
    4      aPolygon.Append( TGPoint( 70, 40 ) );
    5      aPolygon.Append( TGPoint( 50, 80 ) );
    6      aPolygon.Append( TGPoint( 10, 90 ) );
    7      aPolygon.Append( TGPoint( 45, 110 ) );
    8      aPolygon.Append( TGPoint( 25, 155 ) );
    9      aPolygon.Append( TGPoint( 70, 130 ) );
    10      aPolygon.Append( TGPoint( 115, 155 ) );
    11      aPolygon.Append( TGPoint( 95, 110 ) );
    12      aPolygon.Append( TGPoint( 130, 90 ) );
    13      aPolygon.Append( TGPoint( 90, 80 ) );
    14 TFrameBundle frameBundle( TRGBColor( 0, 0, 0), 5.0 ); 15 16 TPolygon* star = new TPolygon( TGPolygon( aPolygonGeometry,
    new TGrafBundle( frameBundle ); 17 star->Draw( thePort ); 18 19 delete star; 20 delete polyBundle; 21 }

Create the star geometry

Lines 3 through 13: The polygon geometry is created by instantiating a
TGPolygon and using the Append function to add points. The line segments draw in the order you append them. The line between (70, 40) and (50, 80) is drawn first.

Create the bundle

Line 14: The frame bundle (polyBundle) defines a black frame in the red, green, and blue (RGB) color space by specifying the values TRGB( 0, 0, 0 ), a solid pen width of 5.0 world-coordinate units to frame the geometry border, and kCenterFrame that centers the 5.0 wide black frame over the geometry border. The polyBundle is sent to the drawing port where its settings override the settings in the default bundle. Chapter 7 has more details on colors and frames.

Create the star graphic

Line 16: The star graphic is created from the geometry and polyBundle by using polyBundle to create a TGrafBundle so that it can be used in the star constructor.

Transform the star

MGraphic provides the common transformation operations of translate (move to another location), rotate (reorient by turning at an angle), and scale (resize by making larger or smaller). Figure 14 shows the original star on the left and the transformed star on the right. To make the picture clearer, the transformed star has a red fill. Chapter 7 describes frames, and fills.


This code fragment calls the MGraphic::TranslateBy function to translate the star 90 world-coordinate units in the x direction and 20 in the y direction. The TGPoint parameter provides x and y values that are added to the points of the star using matrix multiplication. Several transformation operations on one graphic result in successively multiplying the points of the 2-D graphic.

      star->TranslateBy( TGPoint( 90,20 ) );
      TGrafBundle* fillBundle = new TGrafBundle( TFillBundle( TRGBColor( .75, 25, 25 ) ) );
      star->AdoptBundle( fillBundle );
      star->Draw( thePort );
To transform a 2-D graphic, instantiate a 2D matrix (TGrafMatrix) and call the appropriate functions, or as in the code fragment above, call the MGraphic transformation functions. See Chapter 3 for information on the MGraphic functions. See the heading "2-D transformation matrix" on page 38 for information on the TGrafMatrix functions and matrix multiplication.

Draw two stars as a group

A 2-D group lets you combine any number of 2-D graphics to make a more complex shape. The shapes within the group function as a single unit for as transformations and hit testing. Each star graphic has its own frame bundle to define its own color and line-width specifications. Because TGraphicGroup is an MGraphic, the group could also have an attribute bundle that is applied to all children. See Chapter 10 for more information and groups, and see Chapter 3 for more information on transformations and hit testing. Figure 15 shows how two stars drawn into a group look at runtime.


    1  void DrawContents( TGrafPort& thePort ) const
    2  {
    3      static const long numPoints = 10;
    4  
    5      TGPolygon aPolygonGeometry;
    6      aPolygonGeometry.Append( TGPoint( 70, 40 ) );
    7      aPolygonGeometry.Append( TGPoint( 50, 80 ) );
    8      aPolygonGeometry.Append( TGPoint( 10, 90 ) );
    9      aPolygonGeometry.Append( TGPoint( 45, 110 ) );
    10      aPolygonGeometry.Append( TGPoint( 25, 155 ) );
    11      aPolygonGeometry.Append( TGPoint( 70, 130 ) );
    12      aPolygonGeometry.Append( TGPoint( 115, 155 ) );
    13      aPolygonGeometry.Append( TGPoint( 95, 110 ) );
    14      aPolygonGeometry.Append( TGPoint( 130, 90 ) );
    15      aPolygonGeometry.Append( TGPoint( 90, 80 ) );
    16  
    17      TFrameBundle frameBundle( TRGBColor( 0, 0, 0), 5.0 );
    18      TGrafBundle* polyBundle = new TGrafBundle( frameBundle );
    19      TPolygon star = new TPolygon( TGPolygon( aPolygonGeometry  ), polyBundle );
    20  
    21      TGPolygon aPolygonGeometry2( aPolygonGeometry );
    22  
    23      THairlineFrameBundle hairlineBundle( TRGBColor( 0, 0, 0) );
    24      TPolygon star2 = new TPolygon( TGPolygon(aPolygonGeometry2 ), 
    25                                  new TGrafBundle( hairlineBundle );
    26      star2->TranslateBy( TGPoint( 90, 0 ) );
    27  
    28      TGraphicGroup* starGroup = new TGraphicGroup();
    29      starGroup->AdoptFirst( star );
    30      starGroup->AdoptLast( star2 );
    31  
    32      starGroup->Draw( thePort );
    33      delete starGroup;
    34  }
Lines 5 through 15: The first star is created by instantiating a TGPolygon and appending the points.

Line 17: The first star has a frame bundle that defines a 1 world-coordinate unit wide black frame.

Line 19: The star graphic is created from the geometry and bundle.

Line 21: The second star geometry is created by making a copy of the first

Line 23: The second star has a hairline frame bundle that defines a very thin black frame.

Line 24: The second star graphic is created from the second geometry and bundle.

Line 25: The second star is translated 90 world-coordinate units in the x direction to find the correct coordinate values for the second star graphic's points.

Lines 27 through 31: Once you create the graphics for the group, you instantiate a group and adopt those graphics into the group with the AdoptFirst and AdoptLast functions. Drawing the group involves calling the group's Draw function.

Transform the group

You can transform a group as a unit, or you can transform the individual graphics in the group. Figure 16 shows the group transformed as a unit. To make the figure clearer, the transformed group has a red fill. Chapter 7 describes attribute bundles, frames, and fills.


The following code fragment uses a rotation matrix to rotate the group as a whole by 12 degrees in the clockwise direction. The center of the group is used for the center of rotation. Because TGraphicGroup is an MGraphic, you could also call the MGraphic transformation functions to rotate the group or any of its children.

          TGrafMatrix aMatrix;
          aMatrix.RotateBy( 12, starGroup->GetGeometricBounds().GetCenter()  );
          star->AdoptBundle( new TGrafBundle( TFillBundle( TRGBColor ( .75, .25, .25 ) ) ) );
          star2->AdoptBundle( new TGrafBundle( TFillBundle( TRGBColor ( .75, .25, .25 ) ) ) );
          starGroup->TransformBy( aMatrix );
          starGroup->Draw( thePort );

Transform star2 only

Figure 17
shows how the group looks when star2 is translated individually. To make the figure clearer, the transformed group has a red fill.


The following code fragment uses a translation matrix to move star2 in the positive x direction by 50 world-coordinate units.

          TGrafMatrix aMatrix2;
          aMatrix.TranslateBy( TGPoint ( 50,0 ) );
          star2->AdoptBundle( new TGrafBundle( TFillBundle( TRGBColor ( .75, .25, .25 ) ) ) );
          star2->TransformBy( aMatrix );
          starGroup->Draw( thePort );

Flush the view in white

You can use a fill attribute bundle to fill the entire view with a color. This is useful when you want to blank the view and redraw graphics, or when you want to create a background of a particular color. In the examples above, the background was filled with white to make the graphics more visible in black and white.

The following code shows how to fill the view with white using the red, green, blue (RGB) color space and specifying a value of TRGB( 1, 1, 1 ) for white.

    1  TGArea area;
    2  GetAllocatedArea( area );
    3  
    4  TFillBundle fillBundle( TRGBColor( 1, 1, 1 ) );
    5  
    6  thePort.Draw( area.GetBounds(), fillBundle );
Lines 1 and 2: You instantiate an empty area geometry and pass it to TView::GetAllocatedArea. This creates an area the size of the view to be filled. Areas let you create arbitrary shapes from basic geometry and have many other uses. See Chapter 5 for a description of areas.

Line 4: The white fill bundle defines white in RGB colors.

Line 6: You fill the view with white by calling the Draw function for the port and passing it the area and the fill bundle. The TGArea::GetBounds function returns the smallest rectangle that encloses the area so that only the smallest area is filled with white to reduce overhead and improve performance.


[Contents] [Previous] [Next]
Click the icon to mail questions or corrections about this material to Taligent personnel.
Copyright©1995 Taligent,Inc. All rights reserved.

Generated with WebMaker