home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fish 'n' More 2
/
fishmore-publicdomainlibraryvol.ii1991xetec.iso
/
fish
/
code_examples
/
cmanual_456
/
acm1.lzh
/
Graphics
/
Graphics.doc
< prev
next >
Wrap
Text File
|
1990-01-30
|
26KB
|
861 lines
3 GRAPHICS
3.1 INTRODUCTION
We have now looked at how to open different types of screens,
and how to open different types of windows connected to the
screens etc. It is all very good, but what would Intuition be
without any graphics to display in the screens/windows?
Intuition's main idea is to make the communication between
the program and the user as easy as possible. Graphics enables
you to display the results that the computer has calculated in
an understandable way (a picture says more than...). Graphics
makes it also much easier to use the program, and can warn the
user if something dangerous is going to happen: It is very easy
to press the wrong button if you have got a question like "OK
to erase disk?", but if there also had been a picture
showing a cross with the text "RIP" on, you would probably
have been a bit more careful.
There exist both a low- and a high-level way of making
graphics. The low-level approach (Graphics Primitives) is
not described in this chapter since it is not related to
Intuition. The low-level graphics routines are very fast, but
if you are not careful they can trash menus etc. We will here
concentrate our self on the high-level approach which is
supported by Intuition, and is a safe way of drawing.
3.2 LINES TEXT PICTURES
Intuition gives you three different methods of making graphics:
- You can draw lines (Borders).
- Print text (IntuiText).
- Or you can directly print graphics images (Images).
3.3 BORDERS
Border has a bit misleading name since you are not limited to
only draw borders, you may draw any kind of shapes which is
made out of connecting lines. A Border structure may also be
connected to other Border structures, so everything which can
be drawn with lines, can be drawn with Intuition's Border
structure.
3.3.1 THE BORDER STRUCTURE
When you want to draw lines you need to declare and initialize
a Border structure which look like this:
struct Border
{
SHORT LeftEdge, TopEdge;
SHORT FrontPen, BackPen, DrawMode;
SHORT Count;
SHORT *XY;
struct Border *NextBorder;
};
LeftEdge, TopEdge: Start position of the lines.
FrontPen: Colour register used to draw the lines.
BackPen: This variable is for the moment unused.
DrawMode: Must be either JAM1 or XOR. If the JAM1 flag
is set, the colour specified (FrontPen) will
be used to draw the lines regardless what
the background colour is. The XOR flag makes
the lines to be drawn with the binary
complement of the background colours.
Count: The number of coordinates there is in the XY
array. (See below for more information.)
XY: A pointer to an array of coordinates used to
draw the lines. (See below for more
information.)
NextBorder: A pointer to the next Border structure if
there exist one, else NULL.
3.3.2 COORDINATES
If you want to draw this:
(10,10) (25,10)
*--------------*
| (35,12)
| *
| |
*---------*
(25,14) (35,14)
The array of coordinates would look like this:
SHORT my_points[]=
{
10,10, /* Start at position (10,10) */
25,10, /* Draw a line to the right to position (25,10) */
25,14, /* Draw a line down to position (25,14) */
35,14, /* Draw a line to the right to position (35,14) */
35,12 /* Finish of by drawing a line up to position (35,12) */
};
The array contains 5 pair of coordinates, so the variable Count
should be set accordingly. The entire Border structure would
therefore look something like this:
struct Border my_border=
{
0, 0, /* LeftEdge, TopEdge. */
3, /* FrontPen, colour register 3. */
0, /* BackPen, for the moment unused. */
JAM1, /* DrawMode, draw the lines with colour 3. */
5, /* Count, 5 pair of coordinates in the array. */
my_points, /* XY, pointer to the array with the */
/* coordinates. */
/* (Remember my_points == &my_points[0]) */
NULL /* NextBorder, no other Border structures */
/* comes after this one. */
};
3.4 HOW TO USE THE BORDER STRUCTURE
The Border structure is either used to draw lines in a screen
or window, but can also be used to draw lines connected to a
Gadget, Requester or Menu. (See chapter 4, 5 and 7 for more
information about Gadgets, Requesters and Menus.)
If you want to connect a Border structure with a Gadget etc,
you simply initialize the Gadget structure with a pointer to
the Border structure, and Intuition will draw the lines for
you. This will be explained later.
If you want to draw the lines in a screen or window you need to
tell Intuition that you want it to use the structure to make
some lines. You do it by calling the function DrawBorder():
Synopsis: DrawBorder( rast_port, border, x, y );
rast_port: (struct RastPort *) Pointer to a RastPort.
If the lines should be drawn in a window, and
my_window is a pointer to that window, you write:
my_window->RPort.
If the lines should be drawn in a Screen, and
my_screen is a pointer to that screen, you write:
my_screen->RastPort.
border: (struct Border *) Pointer to a Border structure
which has been initialized with your requirements.
x: (long) Number of pixels added to the x coordinates.
y: (long) Number of lines added to the y coordinates.
A call to draw some lines using my_border structure would look
something like this:
DrawBorder( my_window->RPort, &my_border, 0, 0 );
If you have created a Border structure which, for example,
draws a box, you can draw several boxes at different places
just by changing the LeftEdge, RightEdge fields of the Border
structure, or by changing the x, y fields in the function call.
This shows how versatile Intuition's high-level way of drawing
is.
3.4 TEXT
Printing text in the Display is supported by the IntuiText
structure. It is quite similar to the Border structure, and is
executed in the same way. The only difference is that you need
to tell Intuition what Font you want to use, and what text to
print.
3.4.1 THE INTUITEXT STRUCTURE
When you want to print text you need to declare and initialize
a IntuiText structure which look like this:
struct IntuiText
{
UBYTE FrontPen, BackPen;
UBYTE DrawMode;
SHORT LeftEdge;
SHORT TopEdge;
struct TextAttr *ITextFont;
UBYTE *IText;
struct IntuiText *NextText;
};
FrontPen: Colour register used to draw the text with.
BackPen: Colour register used to draw the background
of the text.
DrawMode: There exist three different way of printing
the text:
JAM1 The colour specified (FrontPen) will
be used to draw the text with, the
background is unchanged.
JAM2 The FrontPen colour will be used to
draw the text with, the background is
drawn with the BackPen colour.
XOR The text is drawn with the the binary
complement of the background.
LeftEdge, TopEdge: Start position of the text.
ITextFont: A pointer to a TextAttr structure which
tells Intuition what font, size and style
etc to print the text with. Set to NULL if
you want to use the default font. (See below
for more information.)
IText: A pointer to a NULL-terminated string that
should be printed.
NextText: A pointer to the next IntuiText structure if
there exist one, else write NULL.
3.4.2 FONTS
You can tell Intuition to print the text with a specific font/
style. You only need to declare and initialize a TextAttr
structure, and give your IntuiText structure a pointer to the
TextAttr structure.
The TextAttr structure look like this:
struct TextAttr
{
STRPTR ta_Name;
UWORD ta_YSize;
UBYTE ta_Style
UBYTE ta_Flags;
};
We will for the moment only discuss how to access the ROM-fonts
(the fonts which are always available in ROM), and will wait
with Disk-fonts (fonts which your program can access from the
disk).
There exist only one ROM-font for the moment, and that one is
called Topaz. It exist in two sizes, 64/32 and 80/40 (high-/
low-resolution) characters per line, and can be printed in five
different styles, normal, bold, italic, underlined and extended,
which can be combined as desired.
ta_Name: Name of the font. Set it to "topaz.font" for the
moment.
ta_YSize: Font height. Can either be TOPAZ_SIXTY (64/32) or
TOPAZ_EIGHTY (80/40).
ta_Style: Style (normal, bold, underlined, italic and
extended). Set the desired flags:
FS_NORMAL No special style.
FSF_EXTENDED Extended font, wider than normal.
FSF_ITALIC Italic, slanted 1:2 to the right.
FSF_BOLD Bold, thicker than normal.
FSF_UNDERLINED Underlined, line under the baseline.
ta_Flags: Preferences. Should for the moment be set to
FPF_ROMFONT.
Here is an example on how you can print some text with
underlined, italic characters:
struct TextAttr my_font=
{
"topaz.font", /* Topaz font. */
TOPAZ_EIGHTY, /* 80/40 characters. */
FSF_ITALIC | FSF_UNDERLINED, /* Underlined italic chars. */
FPF_ROMFONT /* Exist in ROM. */
};
UBYTE my_text[]="This is the text that will be printed!";
struct IntuiText my_intui_text=
{
2, /* FrontPen, colour register 2. */
3, /* BackPen, colour register 3. */
JAM2, /* DrawMode, draw the characters with colour 2, */
/* on a colour 3 background. */
0, 0, /* LeftEdge, TopEdge. */
&my_font, /* ITextFont, use my_font. */
my_text, /* IText, the text that will be printed. */
/* (Remember my_text = &my_text[0].) */
NULL /* NextText, no other IntuiText structures are */
/* connected. */
};
3.4.3 HOW TO USE THE INTUITEXT STRUCTURE
The IntuiText structure is either used to print text in a
screen or window, but can also be used to print text connected
to a Gadget, Menu or Requester. Same as with drawing lines with
the Border structure.
When you want to print text in a window/screen you simply call
the function PrintIText():
Synopsis: PrintIText( rast_port, intui_text, x, y );
rast_port: (struct RastPort *) Pointer to a RastPort.
If the text should be printed in a window, and
my_window is a pointer to that window, you write:
my_window->RPort.
If the text should be printed in a Screen, and
my_screen is a pointer to that screen, you write:
my_screen->RastPort.
intui_text: (struct IntuiText *) Pointer to a IntuiText
structure which has been initialized with your
requirements.
x: (long) Number of pixels added to the x position of
the characters.
y: (long) Number of lines added to the y position of
the characters.
A call to print some text using my_intui_text structure would
look something like this:
PrintIText( my_window->RPort, &my_intui_text, 0, 0 );
3.5 IMAGES
We have now looked at how to draw lines and print text. We will
finish off by looking at how to print a whole image directly.
The procedure can be devided into three steps:
1. Declare and initialize the data which should be drawn.
2. Declare and initialize an Image structure.
3. Call the function DrawImage() to draw the image.
3.5.1 IMAGE DATA
Intuition wants to have the image data structured into blocks
of 16-bit memory words (UWORD), organized into rectangular
areas (BitPlanes). You may have up to 6 BitPlanes (4 if you are
displaying the image on a high-resolution screen). The colour
of each pixel is determined by the binary number of the
BitPlanes. For example, to get a pixel with colour 6 on a
screen with a Depth of 4, BitPlane zero and three should be 0,
and BitPlane one and two should be 1, since the binary number
0110 is equal to the decimal number 6.
A little arrow can for example look like this:
(1 BitPlane = 2 colours)
Image 16-Bit memory words Hexadecimal representation
------------------------------------------------------------
0001000 0001 0000 0000 0000 1 0 0 0
0011100 0011 1000 0000 0000 3 8 0 0
0111110 0111 1100 0000 0000 7 C 0 0
1111111 1111 1110 0000 0000 F E 0 0
0001000 0001 0000 0000 0000 1 0 0 0
0001000 0001 0000 0000 0000 1 0 0 0
0001000 0001 0000 0000 0000 1 0 0 0
0001000 0001 0000 0000 0000 1 0 0 0
Even if the Image only is 7 pixels wide, we needed to make the
Image data 16 (bits) pixels wide, since Intuition wants the
data ordered into 16-bit memory words. (Of course, when we
print it out we can tell Intuition that the image should be
only 7 pixels wide.)
Each group of four pixels is then translated into a hexadecimal
value. See table:
Binary => Hexadecimal
---------------------
0000 = 0
0001 = 1
0010 = 2
0011 = 3
0100 = 4
0101 = 5
0110 = 6
0111 = 7
1000 = 8
1001 = 9
1010 = A
1011 = B
1100 = C
1101 = D
1110 = E
1111 = F
A declaration and initialization of the data for the arrow
image will therefore look like this:
UWORD chip my_image_data[]=
{
0x1000, /* BitPlane ZERO */
0x3800,
0x7C00,
0xFE00,
0x1000,
0x1000,
0x1000,
0x1000
};
Since the image data is made out of one BitPlane, the arrow
will be drawn in colour 1, and the background in colour 0.
If the image is wider than 16 pixels you need more than one
word per line. Here is an image which is 20 pixels wide, and
will therefore require two words per line:
Image 16-Bit memory words (2 words)
---------------------------------------------------------------
11111111111111111111 1111 1111 1111 1111 1111 0000 0000 0000
00111110000001111100 0011 1110 0000 0111 1100 0000 0000 0000
00001111100111110000 0000 1111 1001 1111 0000 0000 0000 0000
00111110000001111100 0011 1110 0000 0111 1100 0000 0000 0000
11111111111111111111 1111 1111 1111 1111 1111 0000 0000 0000
We translate the binary numbers into hexadecimal, and we end
up with:
UWORD chip my_image_data[]=
{
0xFFFF, 0xF000, /* BitPlane ZERO */
0x3E07, 0xC000,
0x0F9F, 0x0000,
0x3E07, 0xC000,
0xFFFF, 0xF000
};
If we want more than two colours we need more than one
BitPlane. A four-colour face can look something like this:
003333300000 0: Blue (Normal Workbench colours)
033333330000 1: White
332232233000 2: Black
323333323000 3: Orange
331131133000
331131133000
331232133000
331232133000
333333333000
332333233000
033222330000
033333330000
003333300000
We translate it into 16-Bit memory words organized into two
Bitplanes (Two BitPlanes = 4 colours):
Colour Bitplane ONE Bitplane ZERO SINCE
------------------------------------------------------
0 0 0 00 (b) = 0 (d)
1 0 1 01 (b) = 1 (d)
2 1 0 10 (b) = 2 (d)
3 1 1 11 (b) = 3 (d)
Bitplane ONE Bitplane ZERO
-----------------------------------------
0011 1110 0000 0000 0011 1110 0000 0000
0111 1111 0000 0000 0111 1111 0000 0000
1111 1111 1000 0000 1100 1001 1000 0000
1111 1111 1000 0000 1011 1110 1000 0000
1100 1001 1000 0000 1111 1111 1000 0000
1100 1001 1000 0000 1111 1111 1000 0000
1101 1101 1000 0000 1110 1011 1000 0000
1101 1101 1000 0000 1110 1011 1000 0000
1111 1111 1000 0000 1111 1111 1000 0000
1111 1111 1000 0000 1101 1101 1000 0000
0111 1111 0000 0000 0110 0011 0000 0000
0111 1111 0000 0000 0111 1111 0000 0000
0011 1110 0000 0000 0011 1110 0000 0000
Each group of four pixels is then translated into a hexadecimal
value:
Bitplane ONE Bitplane ZERO
-----------------------------------
3 E 0 0 3 E 0 0
7 F 0 0 7 F 0 0
F F 8 0 C 9 8 0
F F 8 0 B E 8 0
C 9 8 0 F F 8 0
C 9 8 0 F F 8 0
D D 8 0 E B 8 0
D D 8 0 E B 8 0
F F 8 0 F F 8 0
F F 8 0 D D 8 0
7 F 0 0 6 3 0 0
7 F 0 0 7 F 0 0
3 E 0 0 3 E 0 0
A declaration and initialization of the data for the face image
will therefore look like this:
USHORT chip my_image_data[]=
{
0x3E00, /* Bitplane ZERO */
0x7F00,
0xC980,
0xBE80,
0xFF80,
0xFF80,
0xEB80,
0xEB80,
0xFF80,
0xDD80,
0x6300,
0x7F00,
0x3E00,
0x3E00, /* Bitplane ONE */
0x7F00,
0xFF80,
0xFF80,
0xC980,
0xC980,
0xDD80,
0xDD80,
0xFF80,
0xFF80,
0x7F00,
0x7F00,
0x3E00
};
Remember that all Image Data MUST be in Chip Memory!
3.5.2 THE IMAGE STRUCTURE
The Image structure look like this:
struct Image
{
SHORT LeftEdge, TopEdge;
SHORT Width, Height, Depth;
SHORT *ImageData;
UBYTE PlanePick, PlaneOnOff;
struct Image *NextImage;
};
LeftEdge: X position of the Image.
TopEdge: Y position of the Image.
Width: The actual width of the Image.
Height: The height of the Image.
Depth: Number of Bitplanes used for the Image.
ImageData: A pointer to the Image data.
PlanePick: Which Bitplanes of the displaying element
should be changed/affected by the Image.
(See below for more information.)
PlaneOnOff: What should happen to the Bitplanes of the
displaying element that were not affected.
Should they be filled with 1's or 0's. (See
below for more information.)
NextImage: A pointer to the next Image structure if
there exist one, else NULL.
3.5.3 PLANEPICK
The advantages with the PlanePick/PlaneOnOff fields are that
you can print the Image into a display of any depth, print the
same Image in different colours, and it will eliminate
unnecessary memory-waste when using coloured Images.
PlanePick tells Intuition which Bitplanes of the display to be
affected by the Image. For every "picked" plane, the next
successive Bitplane of the image is printed there. For example:
If we set PlanePick to 1, Bitplane zero would be affected. If
we then printed the arrow Image, we would get the arrow drawn
with colour 1, and the background drawn with colour 0.
If we had instead set PlanePick to 2, Bitplane one would have
been affected, which would result in that the arrow would have
been drawn with colour 2, and the background still drawn with
colour 0.
If our Image would consist of several Bitplanes, the lowest
picked plane would be affected by the lowest Bitplane, and so
on. If we take our face Image for example, and we want to draw
it with colour 3, 2 1 and 0, we want to affect Bitplane zero
and BitPlane one of the display. We would therefore need to set
PlanePick to 3, see table:
Bitplane to affect PlanePick
------------------------------
No planes affected 0000 = 0
Plane 0 0001 = 1
Plane 1 0010 = 2
Plane 1 and 0 0011 = 3
Plane 2 0100 = 4
Plane 2 and 0 0101 = 5
Plane 2 and 1 0110 = 6
Plane 2, 1 and 0 0111 = 7
Plane 3 1000 = 8
Plane 3 and 0 1001 = 9
Plane 3 and 1 1010 = A
and so on...
If we want to draw it with colour 5, 4, 1 and 0, we want to
affect Bitplane two and zero:
(000=colour 0, 001=colour 1, 100=colour 4, 101=colour 5)
^ ^ ^ ^ ^ ^ ^ ^
210 210 210 210 (BitPlanes)
We would then set PlanePick to 5 (0101).
3.5.4 PLANEONOFF
PlaneOnOff decides what should happen to the Bitplanes of the
displaying element that were not affected by PlanePick. Should
these Bitplanes be filled with 1's or 0's.
For example, if we want to print the little arrow in colour 5
and the background in colour 1 the pixels should have the
values 0001 (colour 1) and 0101 (colour 5). We want the Image
to affect Bitplane two, so PlanePick is set to 4 (0100). But we
also want Bitplane zero to be filled with 1's, so PlaneOnOff is
set to 1 (0001).
With help of PlanePick and PlaneOnOff you can even print filled
rectangles without any Image data. You only need to set Width
and Height as desired, and then set Depth to 0 (no Bitplanes),
PlanePick to 0000 (no Bitplanes should be used) and PlaneOnOff
to the colour you want.
3.5.5 HOW TO USE THE IMAGE STRUCTURE
The Image structure is either used to print images in a screen
or window, but can also be used to print images connected to a
Gadget, Menu or Requester. Same as Intuition's other Graphics
structures.
When you want to print an image in a window/screen you simply
call the function DrawImage():
Synopsis: DrawImage( rast_port, image, x, y );
rast_port: (struct RastPort *) Pointer to a RastPort.
If the images should be drawn in a window, and
my_window is a pointer to that window, you write:
my_window->RPort.
If the images should be drawn in a Screen, and
my_screen is a pointer to that screen, you write:
my_screen->RastPort.
image: (struct Image *) Pointer to an Image structure which
has been initialized with your requirements.
x: (long) Number of pixels added to the x position of
the image.
y: (long) Number of lines added to the y position of
the image.
A call to print an image using my_image structure would look
something like this:
DrawImage( my_window->RPort, &my_image, 0, 0 );
3.6 FUNCTIONS
Here are the three functions you use when you want to draw
lines/characters/images into a RastPort (Screen/Window):
DrawBorder()
This function draws the specified Borders into a RastPort
(Screen/Window).
Synopsis: DrawBorder( rast_port, border, x, y );
rast_port: (struct RastPort *) Pointer to a RastPort.
If the lines should be drawn in a window, and
my_window is a pointer to that window, you write:
my_window->RPort.
If the lines should be drawn in a Screen, and
my_screen is a pointer to that screen, you write:
my_screen->RastPort.
border: (struct Border *) Pointer to a Border structure
which has been initialized with your requirements.
x: (long) Number of pixels added to the x coordinates.
y: (long) Number of lines added to the y coordinates.
PrintIText()
This function prints text into a RastPort (Screen/Window).
Synopsis: PrintIText( rast_port, intui_text, x, y );
rast_port: (struct RastPort *) Pointer to a RastPort.
If the text should be printed in a window, and
my_window is a pointer to that window, you write:
my_window->RPort.
If the text should be printed in a Screen, and
my_screen is a pointer to that screen, you write:
my_screen->RastPort.
intui_text: (struct IntuiText *) Pointer to a IntuiText
structure which has been initialized with your
requirements.
x: (long) Number of pixels added to the x position
of the characters.
y: (long) Number of lines added to the y position
of the characters.
DrawImage()
This function draws the specified images into a RastPort
(Screen/Window).
Synopsis: DrawImage( rast_port, image, x, y );
rast_port: (struct RastPort *) Pointer to a RastPort.
If the images should be drawn in a window, and
my_window is a pointer to that window, you write:
my_window->RPort.
If the images should be drawn in a Screen, and
my_screen is a pointer to that screen, you write:
my_screen->RastPort.
image: (struct Image *) Pointer to an Image structure
which has been initialized with your requirements.
x: (long) Number of pixels added to the x position of
the image.
y: (long) Number of lines added to the y position of
the image.
3.7 EXAMPLES
Here are some examples on how to draw lines (Border), print
text (IntuiText) and draw pictures (Image):
Example1
This program will open a normal window which is connected to
the Workbench Screen. We will then draw a strange line with
help of Intuition's Border structure.
Example2
This program will open a normal window which is connected to
the Workbench Screen. We will then draw two rectangles with
different colours. This shows how you can link Border
structures to each other in order to get the desired effects.
Example3
This program will open a normal window which is connected to
the Workbench Screen. We will then print a text string with
help of Intuition's IntuiText structure.
Example4
Same as Example3 except that the text will be printed with
underlined italic characters.
Example5
This program will open a normal window which is connected to
the Workbench Screen. We will then draw the little nice arrow
we talked so much about.
Example6
Same as Example5 except that we will draw it several times in
different colours. This shows how PlanePick/PlaneOnOff works.
Example7
This program will open a normal window which is connected to
the Workbench Screen. We will then draw the nice 4 colour
face that was described in chapter 3.5 IMAGES.
Example8
This program will open a normal window which is connected to
a 16-colour Custom screen. In the window we will draw the
famous AMIGA-logo.