Copyright (c) Hyperion Entertainment and contributors.

Intuition Images, Line Drawing and Text

From AmigaOS Documentation Wiki
Jump to navigation Jump to search

Intuition Images, Line Drawing and Text

Intuition supports two general approaches to creating images, lines, and text in displays: through Intuition library calls and through graphics library calls.

This chapter explains the use of Intuition structures and functions for creating display imagery. The Intuition graphical functions provide a high level interface to the graphics library, giving the application quick and easy rendering capabilities. As with any high level calls, some power and flexibility is sacrificed in order to provide a simple interface.

For more flexibility and control over the graphics, the application can directly call functions in the graphics library as discussed in the “Graphics Primitives” chapter. Intuition also has additional features for defining custom graphic objects. See the “BOOPSI” chapter for more information on these objects.

Intuition Graphic Objects

Intuition graphic objects are easy to create and economical to use. There are just three basic types of graphic objects you can use yet these three types cover most rendering needs:

Images are graphic objects that can contain any imagery. They consist of a rectangular bitmap that can be any size and describes each individual pixel to be displayed.

Borders are connected lines of any length and number, drawn between an arbitrary series of points. They consist of a series of two dimensional coordinates that describe the points between which lines will be drawn.

IntuiText strings are text strings of any length drawn in any font. They consist of a text string and font specification that describes the text to be rendered.

Each of these three objects may be chained together with other members of the same type. For instance, many lines of text may be rendered as a single object by linking many instances of IntuiText objects together. Only objects of the same type may be linked.

Any of these types can be rendered into any of the Intuition display elements (window, requester, menu, etc.). In fact, the application can often display the same structure in more than one position or more than one of the elements at the same time.

Displaying Images, Borders and IntuiText

Images, Borders and IntuiText objects may be directly or indirectly rendered into the display by the application. The application can draw these objects directly into windows or screens by using one of the functions DrawImage(), DrawBorder() or PrintIText(). The application supplies the appropriate pointer to a Border, Image or IntuiText structure as an argument to the function, as well as position information and a pointer to the correct RastPort. These rendering functions are discussed in more detail below.

The application can also draw these objects indirectly by attaching them to a menu, gadget or requester. As Intuition places these elements on the display, it also renders the associated graphics. The Requester, Gadget, and MenuItem structures contain one or more fields reserved for rendering information. See the specific chapters on these items for information on attaching graphical objects to them.

Positioning Graphic Objects

The position of these objects is specified as the sum of two independent components: an external component which gives the position of a base reference point for the list of objects, and an internal component which gives the relative offset of a specific object to the base reference point.

The external component is used to position the object list within the display element. For objects drawn indirectly by attaching them to a menu, gadget or requester, this is always a point within the menu, gadget or requester (the top left corner).

For objects drawn directly with the DrawImage(), DrawBorder() or PrintIText() functions, specific x and y coordinates are provided as arguments that specify an offset within the screen’s or window’s RastPort at which to display the list of objects.

Each object also has an internal, relative component that is added to the external component described above to determine the final position of the object. This allows the application to reuse a graphical object and have it appear relative to each object to which it is attached. For example, if the application has numerous gadgets of the same size, it can use a single Border structure to draw lines around all the gadgets. When the gadgets are drawn, the base position of the lines will be taken from each specific gadget in turn.

Creating Text

The IntuiText structure provides a simple way of writing text strings within an Intuition display element. These strings may be used in windows, screens, menus, gadgets and requesters. To set up an IntuiText, you specify the following:

  • Pen colors for the text.
  • A draw mode.
  • The starting offset for the text.
  • The font used to render the text.
  • The text string to output.

IntuiText Structure

To render text using Intuition, the application must create one or more instances of the IntuiText structure:

struct IntuiText
    {
    UBYTE FrontPen, BackPen;
    UBYTE DrawMode;
    WORD LeftEdge;
    WORD TopEdge;
    struct TextAttr *ITextFont;
    UBYTE *IText;
    struct IntuiText *NextText;
    };

Here is a brief description of each member of the IntuiText structure:

FrontPen
The pen number specifying the color used to draw the text.
BackPen
The pen number specifying the color used to draw the background for the text, if JAM2 drawing mode is specified.
DrawMode
This field specifies one of four drawing modes:
JAM1 FrontPen is used to draw the text; background color is unchanged.
JAM2 FrontPen is used to draw the text; background color is changed to the color in BackPen.
COMPLEMENT The characters are drawn in the complement of the colors that were in the background.
INVERSID Inverses the draw modes describe above. For instance INVERVID used with JAM1 means the character is untouched while the background is filled with the color of the FrontPen.
LeftEdge, TopEdge
The location of the text relative to its base position when it is drawn. These offsets are added to the base position to determine the final location of the text data.
The base position for text rendered with PrintIText() is taken from arguments passed in the function call. For gadgets and menus, the base position is always the upper, left corner of the select box. For requesters the base position is always the upper, left corner of the requester.
LeftEdge gives the offset of the left edge of the character cell and TopEdge gives the offset of the top edge of the character cell for the first character in the text string. Negative values of LeftEdge and TopEdge move the position up and to the left of the base position. Positive values move down and to the right.
ITextFont
A pointer to a TextAttr structure defining the font to be used. Set this to NULL to use the default font.
IText
A pointer to the NULL terminated text string to be displayed.
NextText
A pointer to another instance of IntuiText. Set this field to NULL for the last IntuiText in a list.

Directly Drawing the IntuiText

Use the PrintIText() call to directly draw the text into the target RastPort of a window or screen.

VOID PrintIText( struct RastPort *rp, struct IntuiText *iText,
                 LONG left, LONG top );

The rp argument is a pointer to the RastPort into which the text should be drawn. This RastPort can come from a Window or Screen structure.

The iText argument is a pointer to a list of IntuiText structures which are to be rendered. The list may contain a single IntuiText structure. If the font is not specified in the IntuiText structure, Intuition will render the text using the RastPort’s font.

The left and top arguments give the external component, or base position for this list of IntuiText structures. The LeftEdge and TopEdge values in each IntuiText structure are added to these to determine the final position of the text.

IntuiText objects may also be drawn indirectly by attaching them to gadgets, menus or requesters.

Determining Text Length

To determine the pixel length of a given IntuiText string, call the IntuiTextLength() function.

LONG IntuiTextLength( struct IntuiText *iText );

Set the iText argument to point to the IntuiText structure whose length is to be found. This function will return the length of the iText text string in pixels. Note that if the ITextFont field of the given IntuiText is set to NULL, or Intuition cannot access the specified font, then GfxBase->DefaultFont will be used in determining the length of the text. This may not be the same as the RastPort font with which the text would be printed.

IntuiText Example

/*
** intuitext.c - program to show the use of an Intuition IntuiText object.
*/
#include <exec/types.h>
#include <intuition/intuition.h>
 
#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/intuition.h>
 
struct IntuitionIFace *IIntuition = NULL;
 
#define MYTEXT_LEFT (0)
#define MYTEXT_TOP  (0)
 
/*
** main routine. Open required library and window and draw the images.
** This routine opens a very simple window with no IDCMP.  See the
** chapters on "Windows" and "Input and Output Methods" for more info.
** Free all resources when done.
*/
int main()
{
  struct Screen    *screen;
  struct DrawInfo  *drawinfo;
  struct Window    *win;
  struct IntuiText  myIText;
  struct TextAttr   myTextAttr;
 
  uint32 myTEXTPEN;
  uint32 myBACKGROUNDPEN;
 
  struct Library *IntuitionBase = IExec->OpenLibrary("intuition.library", 50);
  IIntuition = (struct IntuitionIFace*)IExec->GetInterface(IntuitionBase, "main", 1, NULL);
 
  if (IIntuition != NULL)
  {
    if (screen = IIntuition->LockPubScreen(NULL))
    {
      if (drawinfo = IIntuition->GetScreenDrawInfo(screen))
      {
        /* Get a copy of the correct pens for the screen.
        ** This is very important in case the user or the
        ** application has the pens set in a unusual way.
        */
        myTEXTPEN = drawinfo->dri_Pens[TEXTPEN];
        myBACKGROUNDPEN  = drawinfo->dri_Pens[BACKGROUNDPEN];
 
        /* create a TextAttr that matches the specified font. */
        myTextAttr.ta_Name  = drawinfo->dri_Font->tf_Message.mn_Node.ln_Name;
        myTextAttr.ta_YSize = drawinfo->dri_Font->tf_YSize;
        myTextAttr.ta_Style = drawinfo->dri_Font->tf_Style;
        myTextAttr.ta_Flags = drawinfo->dri_Font->tf_Flags;
 
        /* open a simple window on the workbench screen for displaying
        ** a text string.  An application would probably never use such a
        ** window, but it is useful for demonstrating graphics...
        */
        if (win = IIntuition->OpenWindowTags(NULL,
                                WA_PubScreen,    screen,
                                WA_RMBTrap,      TRUE,
                                TAG_END))
        {
          myIText.FrontPen    = myTEXTPEN;
          myIText.BackPen     = myBACKGROUNDPEN;
          myIText.DrawMode    = JAM2;
          myIText.LeftEdge    = MYTEXT_LEFT;
          myIText.TopEdge     = MYTEXT_TOP;
          myIText.ITextFont   = &myTextAttr;
          myIText.IText       = "Hello, World.  ;-)";
          myIText.NextText    = NULL;
 
          /* Draw the text string at 10,10 */
          IIntuition->PrintIText(win->RPort,&myIText,10,10);
 
          /* Wait a bit, then quit.
          ** In a real application, this would be an event loop,
          ** like the one described in the Intuition Input and
          ** Output Methods chapter.
          */
          IDOS->Delay(200);
 
          IIntuition->CloseWindow(win);
        }
 
        IIntuition->FreeScreenDrawInfo(screen,drawinfo);
      }
 
      IIntuition->UnlockPubScreen(NULL,screen);
    }
  }
 
  IExec->DropInterface((struct Interface*)IIntuition);
  IExec->CloseLibrary(IntuitionBase);
 
  return 0;
}

Text Colors and Drawing Modes

IntuiText gets its colors from the values set in the color registers for the screen in which they are rendered. The available number of colors and palette settings are screen attributes and cannot be changed through IntuiText rendering.

Text characters in general are made up of two areas: the character image itself and the background area surrounding the character image. The color used in each area is determined by the draw mode which can be set to JAM1, JAM2 or COMPLEMENT. The flag INVERSVID may also be specified.

JAM1 draw mode renders each character with FrontPen and leaves the background area unaffected. Because the background of a character is not drawn, the pixels of the destination memory around the character image are not disturbed. Graphics beneath the text will be visible in the background area of each character cell.

JAM2 draw mode renders each character with FrontPen and renders each character background with BackPen. Using this mode, any graphics that previously appeared beneath the character cells will be totally overwritten.

COMPLEMENT draw mode renders the pixels of each character as the binary complement of the color that is currently at the destination pixel. The destination is the display memory where the text is drawn. As with JAM1, nothing is drawn into the background. FrontPen and BackPen are not used in COMPLEMENT mode. To determine the complement color, invert all the bits in the binary representation of the color register number. The resulting number specifies the color register to use for that pixel. In a three bitplane display, for example, color 6 (110 in binary) is the complement of color 1 (001 in binary).

The INVERSVID flag inverses the video for each of the drawing modes. For JAM1, nothing is drawn into the character area and the background is drawn in FrontPen. For JAM2, the character area is drawn in BackPen and the background is drawn in FrontPen. For COMPLEMENT mode, nothing is drawn into the character area and the background is complemented.

Fonts

The application may choose to specify the font used in rendering the IntuiText, or it may choose to use the default font for the system.

To use the default font, set the ITextFont field to NULL. Some care must be taken when using the default font. When an IntuiText object is rendered and no font is specified, the text will be rendered in the font set in the RastPort.

If the RastPort font is NULL, the text will be rendered using GfxBase->DefaultFont. Also, IntuiTextLength() always uses GfxBase->DefaultFont when ITextFont is NULL. The application must have open the graphics library in order to check the default font in GfxBase. (See the graphics library chapter for more information.)

To use a specific font for this text, place a pointer to an initialized TextAttr structure in the ITextFont field. Intuition will only use the specified font if it is available through a call to the OpenFont() routine. To use a font from disk, the application must first open the font using the OpenDiskFont() function. For more information about using fonts, see the “Graphics Library and Text” chapter in this manual.

Linking Text Strings

The NextText field can point to another instance of an IntuiText structure. This allows the application to create a complex object which has several distinct groups of characters, each with its own color, font, location, and drawing mode. This can be used to create multiple lines of text, to position characters in the text very accurately and to change the color or font of the text. Each list of IntuiText objects may be drawn with one call to PrintIText(), or attached to a gadget, menu or requester as a single object.

Function Reference

The following are brief descriptions of the Intuition functions that relate to the use of graphics under Intuition. See the SDK for details on each function call.

Function Description
DrawBorder() Draw a border into a rast port.
DrawImage() Draw a image into a rast port.
PrintIText() Draw Intuition text into a rast port.
IntuiTextLength() Find the length of an IntuiText string.
BeginRefresh() Begin optimized rendering after a refresh event.
EndRefresh() End optimized rendering after a refresh event.
GetScreenDrawInfo() Get screen drawing information.
FreeScreenDrawInfo() Free screen drawing information.