QuickDraw Picture (いわゆる Macintosh PICT) を解析するのに必要ながら誰も書かないので、しばらく前に Computer History Museum で公開されたQuickDrawのソースを調べてみました。
まずRegionとは何かというと、Classic Mac OS のQuickDraw上で、任意の形状の範囲を指定するためのものです。ウインドウが移動された際の再描画の必要な領域とか、マウスポインタの形状を変化させる領域とかいうような、長方形で表すにはちょっとキツい形を表現する際に利用されます。
こいつをどう表現するか。機能的には白黒2値のビットマスクで全く問題ないのですが、QuickDrawではビットマップが
TYPE BitMap = RECORD baseAddr: Ptr; rowBytes: Integer; bounds: Rect; END;であるのに対し、Regionは
TYPE Region = RECORD
rgnSize: Integer;
rgnBBox: Rect;
{more data}
END;
で定義されており、全く別の構造となっています。Regionでは長方形の組み合わせのような割と単純な図形を表すことが多いので、そういう場合に容量を削減できるようになっています。コンセプト的にはこちらの方がかかれている通りです。=> http://sinn246.wordpress.com/2011/10/26/ビル・アトキンソンとquickdraw リージョンについて思/
そして、実際はどうなっているかというと、
以上が基本的な流れです。
具体的にはこんな具合です。
たとえばこんな領域を表したいとしましょう。
座標を書き入れるとこんな具合になります。
まず、この領域をとり囲む長方形は次のようになるので、
rgnBBoxは {1, 1, 6, 7} になります。(QuickDrawのRectは左上と右下の座標で表し、縦座標を先に書きます)
これをスキャンラインで分割し、黒い部分の開始点と終了点を書き入れると
のようになります。
最初の行 (y = 1) は x = 1 から x = 4 までが黒なので、y = 1 と x = 1, 4 を記録し、最後に $7FFF を付け加えて
$0001, $0001, $0004, $7FFF
となります。
次の行 (y = 2) もおなじく x = 1, 4 ですが、x = 1, x = 4 ともに上の行と同じなため、記録しません。よって y = 2 では記録すべき点がありませんので、この行はスルーします。
y = 3 では黒い範囲が x = 1..4 に加えて x = 5..7 が増えているので、x = 1, 4, 5, 7 になります。このうち x = 1, 4 は y = 2 の時と共通であるため、x = 5, 7 のみを記録します。したがって、
$0003, $0005, $0007, $7FFF
が追記されます。
y = 4 では、x = 1, 7 となり、y = 3 の時と比べ x = 1, 7 は共通ですが 4, 5 が無くなっています。ですので、この行では x = 4, 5 を記録し、
$0004, $0004, $0005, $7FFF
となります。
y = 5 では x = 1, 7 で、y = 4 と完全に一緒です。よってこの行はスルーです。
最後に y = 6 の分もやります。y = 5 では x = 1, 7 でしたが、その下は黒い部分はありません。よって x = 1, 7 が消えると考え、これを記録します。
$0006, $0001, $0007, $7FFF
そして終端にもう一度
$7FFF
を加え、データが終了となります。
結局、Regionのサイズはデータ部分だけで34バイトとなり、ヘッダの rgnSize 2バイトと rgnBBox 8バイトをあわせると44バイトとなります。この値がrgnSizeに入るので、今回の全データは
$002C, $0001, $0001, $0006, $0007, ; rgnSize = 44, rgnBBox = {1, 1, 6, 7}
$0001, $0001, $0004, $7FFF, ; 以下 rgnData
$0003, $0005, $0007, $7FFF,
$0004, $0004, $0005, $7FFF,
$0006, $0001, $0007, $7FFF,
$7FFF
になります。なおバイトオーダはビッグエンディアンです。
同様にして、
だと
$002C, $0001, $0001, $0005, $0007, ; rgnSize = 44, rgnBBox = {1, 1, 5, 7}
$0001, $0001, $0005, $7FFF,
$0002, $0005, $0007, $7FFF,
$0004, $0001, $0002, $7FFF,
$0005, $0002, $0007, $7FFF,
$7FFF
となり、
は
$0030, $0001, $0001, $0005, $0007, ; rgnSize = 48, rgnBBox = {1, 1, 5, 7}
$0001, $0001, $0005, $7FFF,
$0002, $0002, $0007, $7FFF,
$0004, $0001, $0005, $0006, $0007, $7FFF,
$0005, $0002, $0006, $7FFF,
$7FFF
のようになります。