基本的な技

目次


[目次] [はじめに] [入門] [基本] [高度] [画面] [困った] [おわりに]

お約束

QuickWin ライブラリの命令を使用するためには、 その命令を含むプログラム単位の最初に 必ず以下の文を書いておく必要があります。

      use MSFLIB

これは、QuickWin の命令を使用するサブルーチン毎、 関数毎に毎回書いてください。

点の描画

      integer*2 result
      integer*2 x, y
      result = SETPIXEL(x, y)

座標 (x, y) に点を表示し、 その結果を result に返します。 正しく表示できた場合は result には表示した色の色番号が、 失敗した場合には -1 が返されます。 表示する色はあらかじめ SETCOLOR で指定しておく必要があります。

現在点の移動

      integer*2 x, y
      type (xycoord) oldxy
      call MOVETO(x, y, oldxy)

座標 (x, y) に現在点を移動し、 移動前の現在点の座標を oldxy に返します。 画面上の表示には影響を与えません。

変数 oldxy は構造体と呼ばれる新しいデータタイプです。 MOVETO の呼び出し前に oldxy に値をセットしておく必要はないので、 宣言をこのまま丸写ししておくだけで問題ありません。

直線の描画

      integer*2 result
      integer*2 x, y
      result = LINETO(x, y)

現在点から座標 (x, y) まで直線を引き、 結果を result に返します。 result には成功した場合は正の数、 失敗した場合は -1 がセットされます。 線の色は SETCOLOR によって、 線の種類は SETLINESTYLE によって 事前に指定しておく必要があります。

それにしても、 ほとんど同じ動作の MOVETO と LINETO とで、 一方はサブルーチンでもう一方関数、 しかも返す値もバラバラとは感心できませんね。 MOVOTO だけが移動前の座標値を返しても使い道なんか無いし。 マニュアルのサンプルを見ても戻り値の変数名が result だったり status だったりバラバラ。 Microsoft の製品はいつも調べ難い・覚え難い・使い難いの 三拍子揃っているからイヤになりますね。

直線を描く度にこのややこしい MOVETO と LINETO を使うのも面倒ですね。 どうせ使わない oldxy や result のせいでプログラムが無駄に複雑になってしまいますし。 こんなサブルーチンを作ってしまうといいでしょう。

      subroutine line(x1, y1, x2, y2)
      use MSFLIB
      integer x1, y1  ! 始点の座標
      integer x2, y2  ! 終点の座標
      type (xycoord) oldxy
      integer*2 result
c
      call MOVETO(x1, y1, oldxy)
      result = LINETO(x2, y2)
      return
      end

矩形の描画

      integer*2 control
      integer*2 x1, y1, x2, y2
      integer*2 result
      control = $GBORDER
      result = RECTANGLE(control, x1, y1, x2, y2)

(x1, y1) を左上、(x2, y2) を右下の角とする矩形を描き、 結果を result に返します。 result には成功した場合は 0 以外の数、 失敗した場合は 0 がセットされます。 control には塗りつぶしの有無を指定します。 $GBORDER の場合は枠線のみ、 $GFILLINTERIOR の場合は塗りつぶしとなります。

線の色は SETCOLOR によって、 線の種類は SETLINESTYLE によって、 塗りつぶしのパターンは SETFILLMASK によって 事前に指定しておく必要があります。

円弧の描画

楕円

      integer*2 control
      integer*2 x1, y1, x2, y2
      integer*2 result
      result = ELLIPSE(control, x1, y1, x2, y2)

(x1, y1) を左上、(x2, y2) を右下とする長方形に内接する楕円を描き、 結果を result に返します。 result には成功した場合は 0 以外の数、 失敗した場合は 0 がセットされます。 control には塗りつぶしの有無を指定します。 $GBORDER の場合は枠線のみ、 $GFILLINTERIOR の場合は塗りつぶしとなります。

線の色は SETCOLOR によって、 線の種類は SETLINESTYLE によって、 塗りつぶしのパターンは SETFILLMASK によって 事前に指定しておく必要があります。

さて、ふつーは真円を描きたいことがほとんどでしょう。 しかも中心の座標を指定して。 そこでこんなサブルーチンを作ってしまうと便利です。 おっと、これでは直径が奇数の円を描けませんね 気になる人はテキトーに改良してください。

      subroutine circle(x, y, r, flag)
      use MSFLIB
      integer x, y    ! 中心の座標
      integer r       ! 半径
      integer flag    ! 塗りつぶしの指定(0:輪郭のみ, 0以外:塗りつぶし)
      integer*2 control, result
c
      if (flag.eq.0) then
        control = $GBORDER
      else
        control = $GFILLINTERIOR
      endif
      result = ELLIPSE(control, x-r, y-r, x+r, y+r)
      return
      end

楕円弧

      integer*2 x1, y1, x2, y2
      integer*2 x3, y3, x4, y4
      integer*2 result
      result = ARC(x1, y1, x2, y2, x3, y3, x4, y4)
[画像:ARCの各引数の意味]

楕円弧を描きます。 各パラメータの意味を右図に示します。 円弧の開始位置は 楕円の中心と (x3, y3) とを結ぶ直線と円周とが交わる点、 終了位置は 楕円の中心と (x4, y4) とを結ぶ直線と円周とが交わる点となり、 反時計回りに描かれます。 ARC では扇形の内部を塗りつぶすことはできません。 戻り値 result の意味は ELLIPSE と同じです。

線の色は SETCOLOR によって、 線の種類は SETLINESTYLE によって 事前に指定しておく必要があります。

多角形の描画

      parameter (NPOINTS = 3)
      integer*2 control
      integer*2 numpoints
      type (xycoord)  poly(NPOINTS)
      integer*2 status
c
      control = $GBORDER
      numpoints = NPOINTS
      poly(1).x = 100
      poly(1).y = 100
      poly(2).x = 200
      poly(2).y = 100
      poly(3).x = 150
      poly(3).y = 200
      result = POLYGON(control, poly, numpoints)

numpoints 個の座標値 poly を頂点とする多角形を描き、 結果を result に返します。 result には成功した場合は 0 以外の数、 失敗した場合は 0 がセットされます。 control には塗りつぶしの有無を指定します。 $GBORDER の場合は枠線のみ、 $GFILLINTERIOR の場合は塗りつぶしとなります。 始点と終点は自動的に結ばれます。 三角形であれば 3 点の座標を与えてください。

線の色は SETCOLOR によって、 線の種類は SETLINESTYLE によって、 塗りつぶしのパターンは SETFILLMASK によって 事前に指定しておく必要があります。

文字の描画

      call OUTGTEXT('Hello world')

現在点から画面に文字列を出力します。 文字の色は SETCOLOR によって、 フォントの種類と大きさは SETFONT によって 事前に指定しておく必要があります。 特に、事前にフォントの初期化 INITIALIZEFONTS を行っておかないと正しく表示されません。

座標の基準となる位置が文字列のどの部分であるのか、 Microsoft のマニュアルを精読しても記述がありませんでした (重要なことなのに…)。 実験したところ、どうやら左上が基準のようです。

文字数を指定したい場合は部分文字列を使用しましょう。 次の例は、長い文字列 str の 3 文字目から 8 文字目までの 6 文字 'cdefgh' を表示します。

      character*100 str
      str = 'abcdefghijklmnopqrstuvwxyz'
      call OUTGTEXT(str(3:8))

数値も出力したいって? 残念ながらそのような命令は用意されていません。 創意工夫で乗り切りましょう。

      real x
      character*20 str
      x = -23.987
      write(str, '(f10.3)') x
      call OUTGTEXT(str(1:10))

色の設定

      integer*2 color
      integer*2 oldcolor
      oldcolor = SETCOLOR(color)
      integer*2 color
      integer*2 oldcolor
      oldcolor = SETTEXTCOLOR(color)
      integer*2 color
      integer*2 oldcolor
      oldcolor = SETBKCOLOR(color)

SETCOLOR は図形の色を、 SETTEXTCOLOR は文字の色を、 SETBKCOLOR は図形および文字の背景色を設定します。 color には設定したい色番号をセットします。 oldcolor には変更前の色番号がセットされます。

指定できる色番号は、0 から 255 までの 256 色です。 これは、同時に表示できる色が 256 色までに限定されることを意味します。 同時に 256 色以上使いたい方は こちら をご覧ください。

さて、色番号は 0 から 255 までありますが、 それぞれどのような色が割り当てられているのでしょうか。 0 から 15 までの 16 個には 下の表で示す色があらかじめ設定されており、 16 から 255 までは何も設定されていません。 0 から 15 までの色を変更したい時、 または 16 以降に色を割り当てたい時は こちら を参照してください。

0 [画像:標準のパレット] 15

Windows の画面のプロパティが True Color (24ビット) 以上に設定されている場合、 最初の 16 色が設定されていないことがあるようです。 不特定多数に配布するプログラムを作成する場合は、 使用する全ての色についてプログラム中で明示的に 定義しておくことをおすすめします。

線種の設定

      integer*2 style
      style = #F0F0
      CALL SETLINESTYLE(style)

線のパターンを設定します。 style には線のビットパターンを表す整数を指定します。

16進数のわからない人のために、代表的なパターンを示します。

  "****************" : style = #FFFF  (実線)
  "********        " : style = #FF00  (長い破線)
  "****    ****    " : style = #F0F0  (短い破線)
  "**********  **  " : style = #FFCC  (一点鎖線)
  "* * * * * * * * " : style = #AAAA  (点線)

塗りつぶしパターンの設定

      integer*1 mask(8)
      call SETFILLMASK(mask)

塗りつぶしパターンを設定します。 mask には 8×8 ピクセルの塗りつぶしパターンを表す 整数を指定します。 説明するのが面倒なので、Microsoft のマニュアルの例をそのまま載せます。

[画像:SETFILLMASKの引数の例]

16進数とビットパターンの関係を以下に示します。 線種や塗りつぶしパターン作成の参考にしてください。

○ ○ ○ ○#0
○ ○ ○ ●#1
○ ○ ● ○#2
○ ○ ● ●#3
○ ● ○ ○#4
○ ● ○ ●#5
○ ● ● ○#6
○ ● ● ●#7
● ○ ○ ○#8
● ○ ○ ●#9
● ○ ● ○#A
● ○ ● ●#B
● ● ○ ○#C
● ● ○ ●#D
● ● ● ○#E
● ● ● ●#F

フォントの設定

フォントの初期化

      integer*2 numfonts
      numfonts = INITIALIZEFONTS( )

フォントシステムを初期化し、 使用可能なフォントの数を numfonts に返します。 このコマンドは、プログラムの最初に一度だけ実行してください。 このコマンドを実行しないと OUTGTEXT で文字を出力することができません。

フォントの設定

      integer*2 index
      index = SETFONT('t''Times New Roman''h18w10i')

ここで、 "t" は次にアポストロフィで囲まれたフォント名を指定する、 "h" は次にフォントの高さ(height)をピクセル数で指定する、 "w" は次にフォントの幅(width)をピクセル数で指定する、 "i" はイタリック体にする、という意味を表すオプションです。 index には設定されたフォントの識別番号が代入されます。 指定されたフォントが存在しない場合は index に -1 が代入されます。

そのほかに、 ボールド体を指定する "e"、 固定幅を指定する "f"、 プロポーショナルを指定する "p"、 下線を指定する "u"、 などがあります。 詳しくは [Reference → S → SETFONT] をご覧ください。

さて、ここでアポストロフィに注意する必要があります。 SETFONT の引数はただ一つの文字列です。 FORTRAN では文字定数はアポストロフィで囲むことになっています。 さらにこの文字列中に、 アポストロフィで囲まれたフォント名を入れなければなりません。 そのままアポストロフィを書くと文字定数の終了と判別できなくなることから、 アポストロフィ自身を表すときは二つ重ねて書くことになっています。 したがって、上の例で SETFONT に渡される引数は 「t'Times New Roman'h18w10i」 となります。

どのパソコンでも使用できる代表的なフォントを挙げておきます。 'Symbol' にはイタリック体もボールド体も存在しないので、 それらの指定をしても無視されます。

残念ながら、 ここで 'MS Mincho' などと指定しても OUTGTEXT で日本語を出力することはできません。 ただし WRITE 文による日本語の出力は可能です。

マニュアルを読もう

QuickWin 全般に関することであれば [Programmer's Guide → Using QuickWin] を、 特に描画命令の概要を知りたい場合は [Programmer's Guide → Using QuickWin → Displaying Graphics Output] を一読することをおすすめします。 あとは、 [Programmer's Guide → Drawing Graphics Elements]、 [Programmer's Guide → Using Fonts from the Graphics Library] なども参考になります。 個々の命令の詳細を確認したい場合は [Reference] を調べましょう。


[目次] [はじめに] [入門] [基本] [高度] [画面] [困った] [おわりに]

[作者ホームへ] [水工学研究室へ] [防衛大学校へ]

多田 毅 / 防衛大学校土木工学教室
tada@cc.nda.ac.jp