Tech Note 04: カラーオブジェクトとグラフィックスを使う

June 2, 2001

© NSB Corporation. All rights reserved.


[英語版]


Contributed by Adrian Nicolaiev.

このテクニカルノート(Tech Note)では、Palm OS System Palettesの簡単な説明をいたします。その後、そのenum項目と共に、Color TableおよびUI Color Listを定義します。最後に、NSBasicでフルカラー・プロジェクトを可能にするための、API機能およびいくつかのトリックを使用して、Window FunctionsおよびUI Color Functionsを説明します。

はじめに

Palm OSはバージョン3.5以降、以下のように1、2、4、8ビット/ピクセルのシステムパレットをサポートしています。

  • 1-bit: 白(0)、黒(1)
  • 2-bit: 白(0)、ライトグレー(1)、ダークグレイ(2)、黒(3)
  • 4-bit: 16段階のグレー、白(0)から黒(0xF)
  • 8-bit: 216色の"Web-safe"パレット - 次のレベルの赤、緑、青の全ての組み合わせ:0x00、0x33、0x66、0x99、0xCC、0xFF。さらに次のレベルのグレー階調:0x22、0x44、0x55、0x77、0x88、0xAA、0xBB、0xDD、0xEE。最後にこれらの名前のついたHTMLカラー:0xC0C0C0 (silver)、0x808080 (gray)、0x800000 (maroon)、0x800080 (purple)、0x008000 (green)、0x008080 (teal)。残りの26色(インデックス230から255)は指定されておらず、黒が入っています。(デバッグROMでは、デベロッパーが無効値に気がつくように、これらはランダムな色が入ります。)

重要:上記のアプローチはPalm OS 3.5 SDKのドキュメントと異なります。Palm OS 3.5 SDKドキュメントでは8ビットパレットを次のように説明しています:
"
8-bit: 216色の"Web-safe"パレット - 次のレベルの赤、緑、青の全ての組み合わせ:0x00、0x33、0x66、0x99、0xCC、0xFF。さらに次のレベルの全てのグレー16階調:0x00、0x11、0x22、... 0xFF。最後にこれらの名前のついたHTMLカラー:0xC0C0C0 (silver)、0x808080 (gray)、0x800000 (maroon)、0x800080 (purple)、0x008000 (green)、0x008080 (teal)。残りの24色(インデックス0xE7から0xFE)は指定されておらず、黒が入っています。"

これからお見せしますが、我々のアプローチはほぼ実際に起こっていることに近いものです。

Color Table (カラーテーブル)

カラーテーブルはエントリー数のカウント番号に、RGBColorTypeカラーの配列番号が続くものです。RGBColorType構造は、赤、緑、青の各8ビットと、インデックス値の為の1バイトを持っています。
 
カラーのインデックスは、違うソフトウエアレイヤーによって異なった使われ方をします。色のリクエストや色合わせの時、インデックスはこの参照カラーテーブルから最も近いRGB値を持つインデックスを確保します。カラーテーブルへ色をセットする時、インデックスはどのスロットにこの色を入れるかを指定できます。あるルーチンではインデックスは無視されます。

Palm OS 230 Color Palette
8-bit

Palm OS 16 Gray Scale Palette
4-bit

UI Color List (UIカラーリスト)

カラーテーブルに加えてシステムはUIカラーリストを構築します。UIカラーリストは、様々なユーザインターフェース要素によって使われるカラーを含んでいます。各UIカラーは一つのシンボリックカラー定数によって表されます。

UIカラーリストとカラーテーブルを混乱しないように気をつけて下さい。 カラーテーブル (またはシステムパレット)は、表示またはウインドウ描画に利用可能な全ての色を定義します。UIカラーリストはインターフェースオブジェクトの描画に使用される色を定義します。

UI Color Table Entries

UIColorTableEntries enumは様々なUIエレメント用のシンボリックカラー定数を宣言します。

UI Color Functions

ファンクション UIColorGetTableEntryIndex
プロトタイプ IndexedColorType UIColorGetTableEntryIndex (UIColorTableEntries which)
whichは
UIColorTableEntriesにあるシンボリックカラー定数の1つ。
戻り値 現システムパレット用のUIカラーのインデックス値を戻す。
NSBasic 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)
whichはUIColorTableEntriesにあるシンボリックカラー定数の1つ。*rgbPはシンボリックカラーに使用されている現カラーに一致するRGBカラー値への戻されるポインター。
戻り値 無し。
NSBasic 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)
whichはUIColorTableEntriesにあるシンボリックカラー定数の1つ。const *rgbPはwhichで定義される指定のUIオブジェクトに使用されるカラーのEGB値。
戻り値 成功すると0を戻す。
NSBasic Dim Err as Short
Dim which as Short
Dim constrgbP as String 'You will see why...
which = constant * 256
ここにRGBテーブル値を挿入します。
これはWindow Functionsを試していた時(インデックスカラーを使い、さらにそれらをRGBに再び戻していた)、見つけたものです。RGBColorは4バイトの値で、次のように表わされます。
Index (may be *anything) + Red (byte) + Green (byte) + Blue (byte).
例えば、RGBColorTypeからカラー64(6633CC)を選んだ場合、RGBは、"$" +
&h66 + &h33 + &hCCとなります。
constrgbP =
"$" + &h66 + &h33 + &hCC
Err = SysTrapFunc(934,2,which,constrgbP)
しかし、カラー96(00FFCC)がほしい場合は?
答:システムは最初の00(nullカラー)を文字列の終わりと考え、00FFCC00を値として取ります。これではカラーインデックス121となってしまいます。
解決策:「インデックスは一番近いRGB値のインデックスを確保する」ことを覚えておいて下さい。例えば、カラーインデックス96は(01FFCC)とすると、システムは一番近いRGBインデックスカラー(00FFCC)に変換します。

 

Window Functions

ファンクション WinIndexToRGB
プロトタイプ void WinIndexToRGB (IndexedColorType i, RGBColorType *rgbP)
i はカラーインデックス値です。*rgbPはインデックス値 i に一致するRGBカラーへのポインター。
戻り値 無し。
NSBasic 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)
戻り値 カラーテーブルから一番近いカラーのインデックスを戻す。
NSBasic Dim constrgbP as String
Dim IndexedColor as Short
constrgbP =
"$" + &h66 + &h33 + &hCC 'For example
IndexedColor = SysTrapFunc(926,1,constrgbP)

 

ファンクション WinSetForeColor
プロトタイプ IndexedColorType WinSetForeColor (IndexedColorType foreColor)
戻り値 1つ前のフォアグランド・カラーインデックスを戻す。
NSBasic 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)
戻り値 1つ前のバックグランド・カラーインデックスを戻す。
NSBasic 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)
戻り値 1つ前のテキスト・カラーインデックスを戻す。
NSBasic 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)
戻り値 無し。
このルーチンはグレーカラーでは描画しない。これはフォアグランド・ピクセルとバックグランド・ピクセルを交互に描画する。
NSBasic 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)
戻り値 無し。
現フォアグランドカラーを使用して、描画画面に1つのピクセルを描画する。
NSBasic Dim x as Short
Dim y as Short
SysTrapSub 899,2,x,y

 

ファンクション WinErasePixel
プロトタイプ void WinErasePixel (Coord x, Coord y)
戻り値 無し。
現バックグランドカラーを使用して、描画画面に1つのピクセルを描画する。
NSBasic Dim x as Short
Dim y as Short
SysTrapSub 900,2,x,y

 

ファンクション WinInvertPixel
プロトタイプ void WinInvertPixel (Coord x, Coord y)
戻り値 無し。
描画画面の1つのピクセルを反転させる。
NSBasic Dim x as Short
Dim y as Short
SysTrapSub 900,2,x,y

 

ファンクション WinGetPixel
プロトタイプ IndexedColorType WinGetPixel (Coord x, Coord y)
戻り値 現描画画面の指定ピクセルのインデックスカラー値を戻す。
NSBasic 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)
戻り値 無し。
現バックグランドカラーを使用して、描画画面に1つの線を引く。
NSBasic 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)
戻り値 無し。
描画画面の1つの線を反転させる。
NSBasic 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)
戻り値 新しいスクリーンベースアドレスへのポインターを戻す。
スクリーンベースアドレスのUIコンセプトをディスプレイに反映されないエリアに切り替えることによって、現スクリーンをロックする。
このルーチンは、時間が掛かる描画オペレーションの時に起こるちらつきを避けるために、ディスプレイをフリーズさせるために使用できます。WinScreenUnlockを呼ぶとスクリーンのロックを解除でき、変更のアップデートが行えます。実際にディスプレイのアップデートが起こるには、スクリーンをロックした回数だけ解除を行わないとなりません。
NSBasic Dim initMode as Short
Dim screenAddress as Variant
initMode = 0 '
Copy old screen to new
screenAddress = SysTrapFunc(928,1,initMode)

 

ファンクション WinScreenUnlock
プロトタイプ void WinScreenUnlock (void)
戻り値 無し。
スクリーンのロックの解除を行い、ディスプレイをアップデートする。
実際にディスプレイのアップデートが起こるには、スクリーンをロックした回数だけ解除を行わないとなりません。
NSBasic SysTrapSub 929,0