Q and A



Q.ワープロや TeX などの文書にグラフィクスの出力結果を張り込むことはできますか?
A.出力結果を Windows の拡張メタファイル (*.emf) や「EPS フォーマット」のファイルにすることで可能です。

 
拡張メタファイル (*.emf) 形式でのファイル出力が可能ですので,MS-Word などメタファイル形式による図形の挿入をサポートしているアプリケーションには,本ライブラリを使って作成したグラフィクスの出力結果を高品位のまま容易に取り込むことができます。 取り込みたい結果が得られたら,メニューから [ファイル] => [名前を付けて保存] を選択して,拡張子が .emf のファイル名を指定してください。 これにより,拡張メタファイル形式のファイルが得られますので,対応しているアプリケーションならそのまま取り込むことができます。MS-Word の場合には,メニューの [挿入] => [図] => [ファイルから] を選ぶとファイル選択のダイアログが開きますので,作成した .emf ファイルを指定してください。

図形を「EPS フォーマット」のファイルとして出力すれば,TeX 文書への取り込みも容易です。 そのための最も簡単な方法は,「EPS フォーマット」に対応した適当なPS(ポストスクリプト)プリンタのドライバーをインストールすることです。 この場合の出力はファイルに対して行われるので,対応するプリンタが実際に接続されている必要はありません。 Windows 2000 のインストールディスクに入っているもので,動作確認を行ったのは「Apple Color LaserWriter 12/600J」です。以下このドライバを使って EPS ファイルに出力する方法を説明します(使用するドライバが異なると,以下の説明の項目も異なったものになりますので,使用するドライバの対応項目に読み替えてください)。

<ドライバのインストール>

「プリンタの追加ウィ−ザード」を開いて,接続ポートを FILE にしたローカルプリンタとして,「Apple Color LaserWriter 12/600J」を追加する。

<grwnd からの出力>

  1. grwnd で必要な結果が得られたら,メニューの [ファイル] => [印刷] から「Apple Color LaserWriter 12/600J」を選択し, [プロパティ(P)] から [詳細設定(V)] を開く。

  2. [グラフィックス] => [True Type フォント] で,「ソフト フォントとしてダウンロード」を選択する。

  3. [ドキュメントのオプション] => [PostScript オプション] => [PostScript 出力オプション] で,「簡易 PostScript(EPS)」を選択する。

  4. [印刷] の設定ウィンドウに戻って「ファイルへ出力」する.ファイル名は拡張子が `eps' の適当なものでよい。

また,何らかの理由で EPS フォーマットに対応したプリンタ・ドライバが使えないときでも, PS プリンタ・ドライバは必ず使えるはずですので, フリーソフトの GSview が使えるなら,少し面倒ですが,PS ファイルを EPS ファイルに変換することができます。以下にその方法を説明します:

  1. 適当なPSプリンタのドライバーをインストールする(接続されていないものでもよい).

  2. grwnd で必要な結果が得られたら,PSプリンタを選択し,「ファイルへ出力」する.

  3. 出力されたPSファイルを GSview で開く.このとき Options -> EPS Warn が チェックされていることを確認すること.

  4. 一旦,File -> Close し,File -> Show Messages で EPS の生成で問題となる警告 を調べる.例えば,
        Warning: EPS file must not use /setpagedevice
        Warning: EPS file must not use /statusdict
    
    が表示されたら,エディタでPSファイルを開き,問題となる文字列が含まれる
         '[{' ... '} stopped cleartomark'
    
    のブロックをすべて消去する.たとえば,
         [{
         %%BeginFeature: *Resolution 300dpi
         1 dict dup /HWResolution [300 300] put setpagedevice
         %%EndFeature
         } stopped cleartomark
    
    を消去する.

  5. 項目3.と4.を繰り返し,警告が消えたことの確認の後,再び GSview でPS ファイルを開き,File -> PS to EPS で EPS ファイルを作る.

なお,この方法で EPS ファイルを生成する場合, [プリンタの設定] で [用紙の向き] を [横](ランドスケープ)に設定しても,うまくいかないようです. PS ファイルの内容を回転したいときなどには psutils の epsffit を使うことができます。 Windows で動く psutils は

      ftp://ftp.xraylith.wisc.edu/pub/khan/gnu-win32/mingw32/ports/
にあります。

Q.縦長 (ポートレート・モード) の用紙いっぱいにプリントしたいのですが...
A."用紙" のサイズと [ビュー(表示)モード] を適切に選ぶ必要があります:

 
GrWin ライブラリには内部的に "用紙(paper)" の概念があり, すべての描画はその "用紙" に対して行われます. "用紙" のサイズはオープン時に決定され ( GWsize で一応は中途変更可能 ), 一般に,実際にプリントを行う "プリント用紙" のサイズとは無関係です. ただし, GWopen や GWopenx のデフォルトの設定では, "用紙" のサイズには 「現在のプリンタ」の用紙サイズがディスプレィに合わせて横長(ランドスケープ・モード)で設定されます.

実際にプリンタに出力する際には, ビュー(表示)モードに応じて,その "用紙" を "プリンタ用紙" にマッピングしています. "用紙" がデフォルトの横長の ままですと,画面上で子ウィンドウが横長の場合にはどのモードを選んでも縦長にセットした "プリンタ用紙" いっぱいには出力されません.

ウィンドウのオープン時に "用紙" のサイズを "プリンタ用紙" に合わせて 設定し,「等方的」または「ビットマップ」モードで印刷するのが正攻法です.

お薦めはしませんが, デフォルトの設定のままでもマウスで子ウィンドウを縦長にセットしてから, 「フィット」モードで印刷するという手も考えられます.

下はプリンタに合わせて,幅 203 mm,高さ 279 mm(A4縦置) の "用紙" を設定している例です:

      PARAMETER(IWIDTH = 2030, IHEIGHT = 2790)
      PARAMETER(PAI2=6.28319)
      PARAMETER(MCPY = 4, MXOR = 7)
      X(I)=COS(I*PAI2/N)
      Y(I)=SIN(I*PAI2/N)
      DATA K,N/1,16/
      CALL GWOPENX(ID, 0, IWIDTH, IHEIGHT, -1, -1, -1, '')
      CALL GWINDOW(IR,-1.1,-1.1,1.1,1.1)
      CALL GWRECT(IR,-1.0,-1.0,1.0,1.0)
      CALL GWELLIPSE(IR, -1.0,-1.0,1.0,1.0)
      CALL GWNCOLOR(NC)
      CALL GWSETPEN(IR,K,-1,-1,MXOR)
      DO I=0,N-2
         DO J=I+1,N-1
            CALL GWSETPEN(IR,K,-1,-1,-1)
            CALL GWLINE(IR, X(I),Y(I),X(J),Y(J))
            K=MOD(K,NC)+1
         END DO
      END DO
      CALL GWQUIT(IR)
      END
プリンタに A4 用紙を縦置でセットし, 「プリンタの設定」でポートレート・モード (プリンタ・ドライバにより呼び名が異なります) に設定しておけば,「等方的」または「ビットマップ」モードで印刷することにより,用紙いっぱいのプリント結果が得られます.

Q.特定の漢字を使うとコンパイル時に警告メッセージが現れ,期待通りの結果が得られません.
A. 漢字(シフトJISコードの2バイト文字)に対応していないコンパイラではこの症状が現れます.

 
文字 (列) 定数に「漢字」や「かな」を使うことは可能ですが,2バイト目にエスケープ文字を表す「円記号」 '\' (5C) が含まれる特定の2バイト文字をそのまま使うと, 警告メッセージが現れ,当然,期待通りの結果は得られません. しかし,この問題は (^) で示された漢字を,1バイト目は16進表記し,2バイト目は「円記号」を表すエスケープ文字 '\\' を使って表すことで回避できます. 例えば,Fortran で
    xxxxxx.f:yy:
             WRITE(*,*) '...の能率 = ', x
                               ^
    Unknown escape sequence `\' followed by char code 0xffffff97 at (^)
という警告が出たら,'能' のシフトJISコードは '945C' (16進) なので,対応する行を
             WRITE(*,*) '...の\x94\\率 = ', x
または
             WRITE(*,*) '...の能\率 = ', x
と書き換えることで期待通りの結果が得られます.C の場合も同様です.

以下に,そのような不具合が生じる文字 (JIS コードの2バイト目が '5C' ) の, 1バイト目の16進コード表を示します (表中の '\' は対応するコードの文字が存在しないことを表していて,「中点」 '・' => '\x81\x45' はそのまま使うことができます):

      :  0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
    -------------------------------------------------------------------
    80:      ―  ・  ソ  Ы  ・  ・  \  ・  噂  浬  欺  圭  構  蚕  十
    90:  申  曾  箪  貼  能  表  暴  予  禄  兔  喀  媾  彌  拿  杤  歃
    E0:  濬  畚  秉  綵  臀  藹  觸  軆  鐔  饅  鷭  ・  ・  x  x  ・
    F0:  \  \  \  \  \  \  \  \  \  \  \  \  ・
表の行と列の数字を足したもの (16進数) が対応する文字の1バイト目のコードです. 上の例の場合,表から '能' に対応する行と列の数字が 90 と 4 なので '能' の1バイト目のコードは 94 (16進数) => '\x94' であり, '能' => '\x94\\' or '能\' とすればよいことがわかります.

Q.使わないのにコンソール・ウィンドウが開いて邪魔なのですが...
A.実行ファイルを Windows アプリケーションとして作成すれば,コンソール・ウィンドウは開きません.

 
Windows アプリケーションというのは Windows 本来のイベント・ハンドリングを行う GUI アプリケーションのことで,本格的な Windows アプリケーションの開発には Windows プログラミングについての専門知識が必要です.

Windows アプリケーションを作成するには [g77 (GNU の Fortran) では Windows アプリケーションは作成できませんので], gcc (GNU の C) や gpp (GNU の C++) を使って,リンク時のオプションとして,

  -Wl,--subsystem,windows -lGrWin -mwindows
を指定します.

gwgcc.bat 中の 'console' を 'windows' に書き換えたものを,例え ば gwgccw.bat という名前でパスの通ったディレクトリに入れておくと便利でしょう.

コンソール・アプリケーションである polygon.c を 簡単な Windows アプリケーションに書き換えた例のソース・コードが ここ にありますので,ダウンロードし,上で述べたバッチ・コマンドを使って

    gwgccw tstwinapp
とすれば,exe ファイルが出来上がります.このようにして作った exe ファイルが ここ にありますので,ダウンロード (まだなら grwnd.exe も) すれば動かしてみること ができます.

Q.GWkybrd の使い方がわからないのですが...
A.旧版(0.99.6x まで)では,少し使いづらかったのですが,改善されました。また,GWidle (GWidle2 も) を使うとキーボードやマウス・ボタンのどれかが押されるまで待機することができます。詳しくはマニュアルを参照してください。

 
以下に,GWkybrdの使用例を C 言語の場合について示します:
#include <stdio.h>
#include <ctype.h>
#include <GrWin.h>
#include <windows.h>

int GWgche(int *c);
int main()
{
    int c, k, ID;
    ID = GWopen(0);
    while( (k=GWgche(&c)) != VK_ESCAPE)
    switch(k) {
    case VK_LEFT:
        printf("LEFT\n");
        break;
    case VK_RIGHT:
        printf("RIGHT\n");
        break;
    case VK_UP:
        printf("UP\n");
        break;
    case VK_DOWN:
        printf("DOWN\n");
        break;
    default:
        if(isprint(c))
            printf("%c %d %x(%x)\n",c,c,c,k);
        else
            printf("   %d %x(%x)\n",  c,c,k);
    }
    printf("ESCAPE\n");
    GWquit();
    exit(0);
}

int GWgche(int *c)
{
    int k;
    while(!(k = GWkybrd(c, NULL, NULL, -1)));
    return k;
}

Q.もう少し描画を速くできませんか?
A.アプリケーションを立ち上げたウィンドウをアクティブにしてみてください:

 
計算が主体のアプリケーションでは,アプリケーションを立ち上げた (コンソール) ウィンドウをアクティブにする (フォーカスを移す) ことによって,そのアプリケーションの実行の優先順位が高まり,結果的に描画も速くなる場合があります。

Tsuguhiro TAMARIBUCHI <tamari@spdg1.sci.shizuoka.ac.jp>

Last modified:  Sun Jun 22 10:08:24 JST 2003