Tech Note 04: Using Color Objects and Graphics

June 2, 2001

© NSB Corporation. All rights reserved.


Contributed by Adrian Nicolaiev.

In this Tech Note, we will give a short introduction to Palm OS System Palettes. Then, we will define Color Table and UI Color List with its enum Entries. Finally, we will discuss some Window Functions and UI Color Functions showing how it is possible, using API functions and some tricks, to develop a full color project in NSBasic.

Table of Contents:

Introduction
Color Table
UI Color List
UI Color Table Entries
Function Index and Quick Reference
UI Color Funtions
Window Functions

Introduction

Starting in Palm OS version 3.5, the operating system supports system palettes of 1, 2, 4, or 8 bits-per-pixel, as follows:

  • 1-bit: white (0) and black (1)
  • 2-bit: white (0), light gray (1), dark gray (2), and black (3)
  • 4-bit: 16 shades of gray, from white (0) to black (0xF)
  • 8-bit: 216 color "Web-safe" palette, which includes all combinations of red, green, and blue at these levels: 0x00, 0x33, 0x66, 0x99, 0xCC, and 0xFF. Also, it includes gray shades at these levels: 0x22, 0x44, 0x55, 0x77, 0x88, 0xAA, 0xBB, 0xDD, 0xEE. Finally, it includes these extra named HTML colors: 0xC0C0C0 (silver), 0x808080 (gray), 0x800000 (maroon), 0x800080 (purple), 0x008000 (green), and 0x008080 (teal). The remaining 26 entries (indexes 230 through 255) are unspecified and filled with black. (On debug ROMs they are filled with random colors to help developers notice if they use an invalid value.)

Important: The above approach differs from Palm OS 3.5 SDK documentation in order that, for some reason, Palm OS 3.5 SDK documentation about 8-bit palette says that:
"8-bit: 216 color "Web-safe" palette, which includes all combinations of red, green, and blue at these levels: 0x00, 0x33, 0x66, 0x99, 0xCC, and 0xFF. Also, it includes all 16 gray shades at these levels: 0x00, 0x11, 0x22, ... 0xFF. Finally, it includes these extra named HTML colors: 0xC0C0C0 (silver), 0x808080 (gray), 0x800000 (maroon), 0x800080 (purple), 0x008000 (green), and 0x008080 (teal). The remaining 24 entries (indexes 0xE7 through 0xFE) are unspecified and filled with black."

As you will see, our approach is nearer of what really happens...

Color Table

The color table is a count of the number of entries, followed by an array of RGBColorType colors. An RGBColorType struct holds 8 bits each of red, green, and blue plus an "extra" byte to hold an index value.
A color's index is used in different ways by different software layers. When querying for a color or doing color fitting, the index holds the index of the closest match to the RGB value in the reference color table. When setting a color in a color table, the index can specify which slot the color should occupy. *In some routines, the index is ignored.

Palm OS 230 Color Palette
8-bit

Palm OS 16 Gray Scale Palette
4-bit

UI Color List

The system builds a UI Color List in addition to the system Color Table. The UI Color List contains the colors used by the various user interface elements. Each UI color is represented by a symbolic color constant.

Do not confuse the UI Color List with the system Color Table. The system color table (or system palette) defines all available colors for the display or draw window, whether they are in use or not. The UI Color List defines the colors used to draw the interface objects.

UI Color Table Entries

The UIColorTableEntries enum declares symbolic color constants for the various UI elements.

Function Index and Quick Reference

UI Color Functions  
UIColorGetTableEntryIndex IndexedColorType UIColorGetTableEntryIndex (UIColorTableEntries which)
UIColorGetTableEntryRGB void UIColorGetTableEntryRGB (UIColorTableEntries which, RGBColorType *rgbP)
UIColorSetTableEntry Err UIColorSetTableEntry (UIColorTableEntries which, const RGBColorType *rgbP)
Window Functions  
WinIndexToRGB void WinIndexToRGB (IndexedColorType i, RGBColorType *rgbP)
WinRGBToIndex IndexedColorType WinRGBToIndex (const RGBColorType *rgbP)
WinSetForeColor IndexedColorType WinSetForeColor (IndexedColorType foreColor)
WinSetBackColor IndexedColorType WinSetBackColor (IndexedColorType backColor)
WinSetTextColor IndexedColorType WinSetTextColor (IndexedColorType textColor)
WinDrawGrayLine void WinDrawGrayLine (Coord x1, Coord y1, Coord x2, Coord y2)
WinDrawPixel void WinDrawPixel (Coord x, Coord y)
WinErasePixel void WinErasePixel (Coord x, Coord y)
WinInvertPixel void WinInvertPixel (Coord x, Coord y)
WinGetPixel IndexedColorType WinGetPixel (Coord x, Coord y)
WinEraseLine void WinEraseLine (Coord x1, Coord y1, Coord x2, Coord y2)
WinInvertLine void WinInvertLine (Coord x1, Coord y1, Coord x2, Coord y2)
WinScreenLock UInt8* WinScreenLock (WinLockInitType initMode)
WinScreenUnlock void WinScreenUnlock (void)

 


UI Color Functions

UIColorGetTableEntryIndex

IndexedColorType UIColorGetTableEntryIndex (UIColorTableEntries which)
where which is one of the symbolic color constants in UIColorTableEntries

Return:

The index value for a UI color for the current system palette

Example:

Dim which as Short
Dim IndexedColor as Short
which = 11 'UIFieldText, for example.
which = which * 256
IndexedColor = SysTrapFunc(932,1,which)

 

UIColorGetTableEntryRGB

void UIColorGetTableEntryRGB (UIColorTableEntries which, RGBColorType *rgbP)
where which is one of the symbolic color constants in UIColorTableEntries and *rgbP is a returned pointer to an RGB color value corresponding to the current color used for the symbolic color.

Return:

nothing

Example:

Dim which as Short
Dim rgbP as Variant
which = 10 'UIFieldBackground, for example.
which = which * 256
SysTrapSub 933,2,which,rgbP

 

UIColorSetTableEntry

Err UIColorSetTableEntry (UIColorTableEntries which, const RGBColorType *rgbP)
where which is one of the symbolic color constants in UIColorTableEntries and const *rgbP is the RGB value of the color that should be used for the specified UI object defined as which.

Return:

0 upon success.

Example:

Dim Err as Short
Dim which as Short
Dim constrgbP as String 'You will see why...
which = constant * 256

Here is where you insert RGB Table values :-)
This was "the tip of the ICEBERG". This was found while working on Window Functions using Indexed colors and converting them back to RGB: RGBColor is a 4-byte value representing:
Index (may be *anything) + Red (byte) + Green (byte) + Blue (byte).
So, an RGB would be, for example, "$" + &h66 + &h33 + &hCC if you are picking color 64 (6633CC) in RGBColorType
constrgbP = "$" + &h66 + &h33 + &hCC
Err = SysTrapFunc(934,2,which,constrgbP)
But, if you wish color index 96 (00FFCC)?
Answer: the system will consider the first 00 (null char) as the end of a string and will take 00FFCC00 as its value. It will become color index 121 :-(
Solution:
Another "tip of the iceberg"... remember: "the index holds the index of the closest match to the RGB value". So, color index 96, for example, could be (01FFCC) :-)
and the system will *convert* to the closest RGB index color: 00FFCC...

 

Window Functions

WinIndexToRGB

void WinIndexToRGB (IndexedColorType i, RGBColorType *rgbP)
where i is a color index value and rgbP is a pointer to an RGB color value corresponding to the index value i.

Return:

Nothing

Example:

Dim i as Short
Dim rgbP as Variant
i = 134 'Indexed color 134
i = i * 256
SysTrapSub 927,2,i,rgbP

 

WinRGBToIndex

IndexedColorType WinRGBToIndex (const RGBColorType *rgbP)

Return:

The index of the closest matching color in the Color Table

Example

Dim constrgbP as String
Dim IndexedColor as Short
constrgbP = "$" + &h66 + &h33 + &hCC 'For example
IndexedColor = SysTrapFunc(926,1,constrgbP)

 

WinSetForeColor

IndexedColorType WinSetForeColor (IndexedColorType foreColor)

Return:

The previous foreground color index.

Example:

Dim ForeIndexedColor as Short
Dim ForePreviousIndexedColor as Short
ForeIndexedColor = 96 'For example
ForeIndexedColor = ForeIndexedColor * 256
ForePreviousIndexedColor = SysTrapFunc(920,1,ForeIndexedColor)

 

WinSetBackColor

IndexedColorType WinSetBackColor (IndexedColorType backColor)

Return:

The previous background color index.

Example:

Dim BackIndexedColor as Short
Dim BackPreviousIndexedColor as Short
BackIndexedColor = 96 'For example
BackIndexedColor = BackIndexedColor * 256
BackPreviousIndexedColor = SysTrapFunc(921,1,BackIndexedColor)

 

WinSetTextColor

IndexedColorType WinSetTextColor (IndexedColorType textColor)

Return:

The previous text color index.

Example:

Dim textIndexedColor as Short
Dim textPreviousIndexedColor as Short
textIndexedColor = 96 'For example
textIndexedColor = textIndexedColor * 256
textPreviousIndexedColor = SysTrapFunc(922,1,textIndexedColor)

 

WinDrawGrayLine

void WinDrawGrayLine (Coord x1, Coord y1, Coord x2, Coord y2)

Return:

Nothing.
This routine does not draw in the gray color; it draws with alternating foreground and background pixels

Example:

Dim x1 as Short
Dim y1 as Short
Dim x2 as Short
Dim y2 as Short
SysTrapSub 532,4,x1,y1,x2,y2

 

WinDrawPixel

void WinDrawPixel (Coord x, Coord y)

Return:

Nothing.
Draw a pixel in the draw window using the current foreground color.

Example:

Dim x as Short
Dim y as Short
SysTrapSub 899,2,x,y

 

WinErasePixel

void WinErasePixel (Coord x, Coord y)

Return:

Nothing.
Draw a pixel in the draw window using the current background color.

Example:

Dim x as Short
Dim y as Short
SysTrapSub 900,2,x,y

 

WinInvertPixel

void WinInvertPixel (Coord x, Coord y)

Return:

Nothing.
Invert a pixel in the draw window.

Example:

Dim x as Short
Dim y as Short
SysTrapSub 900,2,x,y

 

WinGetPixel

IndexedColorType WinGetPixel (Coord x, Coord y)

Return:

The indexed color value of the pixel in the current draw window.

Example:

Dim x as Short
Dim y as Short
Dim PixelIndexedColor as Short
PixelIndexedColor = SysTrapFunc(897,2,x,y)

 

WinEraseLine

void WinEraseLine (Coord x1, Coord y1, Coord x2, Coord y2)

Return:

Nothing.
Draw a line in the draw window using the current background color.

Example:

Dim x1 as Short
Dim y1 as Short
Dim x2 as Short
Dim y2 as Short
SysTrapSub 533,4,x1,y1,x2,y2

 

WinInvertLine

void WinInvertLine (Coord x1, Coord y1, Coord x2, Coord y2)

Return:

Nothing.
Invert a line in the draw window.

Example:

Dim x1 as Short
Dim y1 as Short
Dim x2 as Short
Dim y2 as Short
SysTrapSub 534,4,x1,y1,x2,y2

 

WinScreenLock

UInt8* WinScreenLock (WinLockInitType initMode)

Return:

A pointer to the new screen base address.
"Lock" the current screen by switching the UI concept of the screen base address to an area that is not reflected on the display. This routine can be used to "freeze" the display while doing lengthy drawing operations to avoid a flickering effect. Call WinScreenUnlock to unlock the display and cause it to be updated with any changes. The screen must be unlocked as many times as it is locked to actually update the display.

Example:

Dim initMode as Short
Dim screenAddress as Variant
initMode = 0 'Copy old screen to new
screenAddress = SysTrapFunc(928,1,initMode)

 

WinScreenUnlock

void WinScreenUnlock (void)

Return:

Nothing.
Unlock the screen and update the display.
The screen must be unlocked as many times as it is locked to actually update the display.

Example:

SysTrapSub 929,0