Specifying Shades of Gray
The following constants are defined which specify 4-bit grayscale values:
Black iskRGB_Gray0, kRGB_Gray1, kRGB_Gray2, ... , kRGB_Gray15
kRGB_Gray15
, and can also be referred to by the constantkRGB_Black
. White iskRGB_Gray0
, for which the constantkRGB_White
is also defined. These values can be used anywhere a color needs specifying, in a graphic shape, in a font spec frame, and as a view's fill, frame, or line pattern. The sixteen gray tones are shown in Figure 6-5.Figure 6-5 The 4-bit grayscale palette
The constantkRGB_16GrayIncrement
is also quite useful. This constant equals the difference between two gray tones. For example, the following expression evaluates totrue
:
kRGB_Gray3 = (3 *
kRGB_16GrayIncrement)
+ kRGB_Black;
Specifying RGB Triplets
You can specify a gray tone as an RGB (red-green-blue) triplet. These are mapped to gray tones at run time. They can be used anywhere thekRGB_GrayXX
values are used. RGB triplets are represented as packed integers.There are a number of utility functions provided to deal with packed RGB integers:
*PackRGB
takes three 16-bit integers (that is, integers in the range [0,65535]) specifying the red, green, and blue components, and returns a packed RGB integer. The following example uses this function:myView.viewFillPattern := PackRGB (0x8888, 0xFFFF, 0x21AA);
*GetTone
takes a packed RGB integer and returns the tone of gray the RGB triplet maps to. It is this gray tone that is displayed on the screen. For example, the following two expressions evaluate totrue
:0 = GetTone( PackRGB (0xFFFF, 0xFFFF, 0xFFFF) );//white
1 = GetTone( PackRGB (0xFFFF, 0xCCCC, 0xFFFF) );//a very light gray
*IsEqualTone
takes two packed RGB integers and returnstrue
if they map to the same gray tone. The following code illustrates the use of this function:IsEqualTone( PackRGB(0,0,0), PackRGB(2,7,88) ); // returns true
IsEqualTone( PackRGB(0,0,0), PackRGB(2000,7000,8800) );// returns nil
*GetRed
, *GetGreen
, and *GetBlue
take a packed RGB triplet and return the relevant color component as an integer in the range [0,65535]. The following example illustrates the use of one of these functions:local thePackedInt := PackRGB( 0, 0x1111, 0xFFFF);
GetBlue (thePackedInt); // this returns an integer close to 0xFFFF
- Note
*GetRed(*PackRGB(r,g,b))
might not returnr
. All that is guaranteed is that the return value of this function call
is an integer close tor
.
*UnPackRGB
takes a packed RGB triplet and returns a frame withred
,green
, andblue
slots. This function is provided by the NTK environment, and is thus available at build time only. The following example illustrates the use of this function:UnPackRGB(PackRGB(r,g,b)); //returns integers close to r, g, and b
Using Patterns, Gray Patterns, and Dithered Patterns
The following sections provide information about the three types of patterns that can be drawn. You should read "Black and White Patterns" even if you want to create one of the other patterns.Black and White Patterns
A black and white pattern is specified as a 8-byte binary object of class'pattern
, representing an 8x8 bitmap. The system has five built-in patterns, which you can reference through the constantsvfWhite
,vfLtGray
,vfGray
,vfDarkGray
, andvfBlack
. You may also define your own patterns.To create a pattern, use the NTK function *
MakeBinaryFromHex
. It takes a class symbol and a sting with an even number of hex digits, each set of two digits defining a byte in the binary object.The following example creates a simple striped pattern, and stores it in a constant, since *
MakeBinaryFromHex
is available at build-time, but not at run-time):
Each A has the binary representation 1010, making for the following 8x8 bitmap:DefineGlobalConstant ( 'kMyBlackAndWhitePattern,
MakeBinaryFromHex ("AAAAAAAAAAAAAAAA", 'pattern) );
10101010
10101010 10101010 10101010 10101010 10101010 10101010 10101010
Gray Patterns
Gray patterns are binary objects with the class'grayPattern
. A gray pattern consists of an 8x8 pattern of pixels, each of which is specified as an RGB triplet. Each color component is specified with two bytes, making for 6 bytes per pixel. You do not, however, need to specify all 64 RGB triplets. The following rules are used when a gray pattern has less than 64 pixels:
The following example creates a 1-pixel pattern in a dark tone of gray:
- If there are less than 8 pixels: the defined pixels are repeated until an 8 pixel line has been completed. This line is repeated 8 times.
- Otherwise, the pixels are divided into 8 pixel lines, discarding any left over pixels. These lines are repeated as needed to create an 8 line pattern.
This next example creates a striped pattern as in "Black and White Patterns", using 2 pixels in different tones of gray:DefineGlobalConstant ( 'kMyOnePixelGrayPattern,
MakeBinaryFromHex ("AAAAFFFF6666" , 'grayPattern) );
DefineGlobalConstant ( 'kMyTwoPixelGrayPattern,
MakeBinaryFromHex ("999999999999555555555555", 'grayPattern) );
- Note
- A gray pattern can be a very large object. Specify only as much of a pattern as you need, and try to keep your patterns simple. With a simple pattern you frequently can take advantage of the duplication done by the system when less than 64 pixels are defined. Also consider using a dithered pattern if you only need two tones of gray. A dithered pattern requires about as much memory as a gray pattern with five pixels defined.
Dithered Patterns
If you need a two-toned pattern, you can use the'ditherPattern
class to create a "black and white" pattern, and assign one tone of gray to the "black" pixels, and another tone to the "white" pixels. A dithered pattern is defined as a frame of the following format:
The{
class: 'ditherPattern
, pattern: aBlackAndWhitePattern, // a 'pattern (e.g. vfGray) foreground: kRGB_Gray0, // kRGB_Gray0 through kRGB_Gray15 background: kRGB_Gray15, // kRGB_Gray0 through kRGB_Gray15 }
pattern
slot contains a black and white pattern object as described in "Black and White Patterns"; this includes the built-in black and white patterns of thevfGray
family. Theforeground
slot defines the tone of gray of the black pixels (the 1's), and thebackground
slot defines the tone of the white pixels (the 0's).The *
MakeDitheredPattern
function creates frames of this format. You should use this function instead of creating your own frame, as this ensures that the frame map is shared.The following example creates the striped black and white pattern with two shades of gray, this pattern has fatter stripes than the one in "Black and White Patterns":
DefineGlobalConstant ( 'kMyStripedBWPattern,
MakeBinaryFromHex ("F0F0F0F0F0F0F0F0", 'pattern) ); DefineGlobalConstant ( 'kMyDitheredPattern , MakeDitheredPattern(kMyStripedBWPattern, kRGB_Gray3, kRGB_Gray9) );
Main | Top of Section | What's New | Apple Computer, Inc. | Find It | Feedback | Help