◆注意事項

EPUBファイルの閲覧には、優先手段として、電子書籍ビューア（EPUBビューア）の「Calibre」を利用して下さい。表示テストは、「Calibre Ver.7.18」で行ないました。「Adobe Digital Editions」では、正常に表示できない場合があります。 EPUBファイルは、ZIP圧縮されたファイルであり、拡張子「epub」を「zip」に書き換え、圧縮を解除すれば、複数のXHTMLファイル（HTML互換）に分割されるため、インターネット・ブラウザでも閲覧できます。 XHTMLファイルをテキスト・エディタで閲覧する方法（画像は表示されない）もあります。「Calibre」は、ファイル形式変換機能を内蔵していて、「epub」を「pdf」などに変換することも可能です。なお、EPUBファイルに対するシンタックス・チェックは、「Epubcheck」（EPUB3基準）を用いて、確認済です。

◆はじめに

▲本書の内容

本書『Java 実例 プログラミング』「描画処理編」（第七版）は、プログラムの実例ソース・コードを提示し、その具体的方法を解説する「Javaプログラミング解説書」（中級者対象）です。ただし、Javaの言語としての文法規則の説明は、省略しています。Javaに関しての基本的知識が、読者に既にあるものとします。姉妹編の『Java 実例 プログラミング』「事務処理編」（初級者対象）と比べて、それなりに複雑長大なプログラムになっています。 Javaプログラミングの方法解説に際し、著者が開発した実際に動く描画プログラム（GCreator：ジークリエイター）を公開し、そのソース・コード内の大量の注釈文によって、プログラミング・テクニックを実践的に解説する形式とします。そのため、日本語の注釈文を埋め込んだソース・コードを読んでいただくことになります。

描画プログラム「GCreator」がユーザーに提供する機能は、「線描画機能」（面描画を含む）、「点描画機能」、「模様自動生成機能」、この三種類です。ただし、点描画機能は、必要も需要も少ない「おまけ機能」（趣味用途）であって、その実用性は、限定的です。点描画機能は、将来の課題として、エア・ブラシ（霧吹き、砂子散らし）機能の発展的追加が望まれますが、完成できるかどうかさえ、現時点で目処が立ちません。線描画機能と模様自動生成機能との二つの機能に関しては、実用目的のものであり、その機能充実により実用水準に達しています。本書（第七版）で公開するプログラム（GCreator Ver.3.3）は、旧バージョン（Ver.3.2）に比べて、自由曲線描画関連の機能が向上しました。スプライン曲線描画機能および輪郭線内部彩色機能の追加が、それです。本書（第七版）の表紙意匠も、「GCreator Ver.3.3」によって作成しました。「GCreator」にどれだけの描画表現力があるかについては、「GCreator」によって作成した本書の表紙（別途、各種作例画像も掲載）を御覧下さい。

スプライン曲線描画アルゴリズムに関しては、奥村晴彦および他七名共著『Javaによるアルゴリズム事典』（技術評論社刊）を参照しました。『Javaによるアルゴリズム事典』の著者諸氏（奥村晴彦氏、首藤一幸氏、杉浦方紀氏、土村展之氏、津留和生氏、細田隆之氏、松井吉光氏、光成滋生氏）の事典編纂およびその公刊による学術貢献に対し、謝意を表します。また、『Javaによるアルゴリズム事典』の「スプライン補間」の項目の末尾では、参考文献として、市田浩三、吉本富士市、共著『スプライン関数とその応用』（教育出版刊）が掲載されていますが、この文献は、参照できませんでした。『スプライン関数とその応用』では、「Java」ではなく、「FORTRAN」によるスプライン関数プログラム実装例の提示がなされているようです。

「GCreator Ver.3.3」が想定する用途は、ブック・カバー・デザイン、ウォール・ペーパー・デザイン、ラッピング・ペーパー・デザイン、ポスター・デザイン、テキスタイル・デザイン、パッチワーク・デザイン、ステンドグラス・デザイン、その他、デコラティブ・アート（アール・デコ、装飾芸術）分野の各種デザイン（意匠製作）です。プロフェッショナルな用途にも耐えられる多機能を目指していますが、それでも不足や未熟やバグが潜んでいることでしょう。不足や未熟やバグの対処に関しては、Javaを使いこなせる読者諸氏による独自の機能充実（独自改造）に委ねることとします。

本書が扱う内容は、具体的なプログラミング（アプリケーション作成）の基本的技法であって、グラフィックスを操作するものです。さらに具体的に言えば、「Swing」を用いて操作画面を構築し、「Java 2D」を用いて任意画像（二次元画像）の作成を行ないます。ただし、基本機能としては、ドローウィング（ペンによる製図タイプ）であって、ペインティング（絵筆による絵画タイプ）ではありません。直線や曲線による描画、文字列の描画、四角形や真円（楕円）や自由図形による描画（内部彩色可能）、これらの機能を駆使して描画を実現するものです。なお、拡張子が「bmp」や「gif」や「jpeg」や「png」の画像を取り込んで、その画像に加工変形を加える操作も含みます。さらに、画像の背景透明化（スタンプ機能）、画像の切り貼り（マルチ・マスクおよびカット・アンド・ペースト機能）、指定色の色修正（カラー・チェンジ機能）、画像の階調表現加工（線形グラデーション加工）、ソフト・フォーカス加工、色彩の混色（パレット機能）、画像の印刷（プリント・アウト）、そして、比較的最近追加した新機能として、画像の部分切り取り保存（CutAndSaveImage命令）、画像の鏡像反転（ReverseImage命令）、複数指定色の連続色修正（ChangeColorMulti命令）、などがある上に、さらに各種特殊画像処理を含んでいて、機能多彩です。「GCreator ver.3.3」では、スプライン曲線を描画する命令と輪郭線の内側を指定色で彩色する命令とを追加したことで、表現力や利便性が格段に向上しました。「GCreator」が実装している全機能（全命令の仕様）については、マニュアル（GCreator_Manual.txt）を参照して下さい。また、その具体的な使い方は、「メニュー」にある「見本」を参考にして下さい。

本書が提供する描画プログラム「GCreator」は、言わば「描画インタープリター」（あるいは「描画スクリプト言語実行環境」）と呼ぶべきものであり、しかも、マウス操作によってメニューから描画機能（直線描画機能など各種あり）を選び、起点と終点（場合により中間点もあり）とをマウス・クリックするなどで、描画命令（スクリプト言語に相当）を自動的に生成し、この描画命令を複数行書き上げ、必要に応じて数値の修正（キーボードまたはマウスでの修正）を加えた上で、「描画」ボタンを押すことで、これら命令全行を逐次解析し、解析結果をJavaの機能（主に「Java 2D」）によって画像として実現するものです。マウス・クリックは、基本的に左ボタン・クリックですが、「自由図形」の描画や「スプライン曲線」の描画では、右ボタン・クリックも併用します。命令文にシンタックス・エラー（文法間違い）があれば、エラーの種類をユーザーに告知する機能もあります。

線描画機能での描画命令は、マウス操作で自動生成され、JTextAreaに表示されると同時に、解析され実行されます。例えば、「DrawLine(200, 300, 500, 600);」の命令文1行で、ある座標点（x:200, y:300）から別の座標点（x:500, y:600）まで、直線を描画します。この命令文は、マウスの操作で自動生成されるだけでなく、キーボードの操作で手作業入力（手作業修正）することも出来、「描画」ボタンで解析され実行されます。画像表示を見て、座標位置が不適切であれば、キーボード操作で文字（座標数値）を修正するか、マウス操作で位置移動（命令文の自動書き換え）を実行します。だが、これら諸機能は、Javaに付属する機能を分かりやすくし使いやすくする形で通訳の機能を果たしているだけであって、「インタープリター」としての機能を主体とするものです。

模様自動生成機能は、マウス操作によらず、JTextAreaへのキーボードによる手作業で、模様生成命令を数行記述することによって行ないます。「描画」ボタンまたは「乱数」ボタンを押すことで、模様が自動的に描画されます。模様生成命令の引数を書き換えることで、微妙な模様配置変更を行ない、「乱数」ボタンの連打で、配色自動変更の作業を行ない、気に入った配色になった時点で、画像のファイル保存を行なう手順となります。メニューの「見本」から各種見本命令文書を選ぶことで、描画命令文書を表示しながら、必要に応じ「描画」または「乱数」ボタンを押し、描画を試すことができます。見本の命令文書は、引数を書き換えることで、画像の変更処理も試せます。

著者が開発した描画プログラム「GCreator」は、ソース・コードの形で提供されるため、読者によって私的に機能拡張し私的に利用することができます。なお、そのプログラム（無改造または改造済み）で作成された画像は、模倣ではなく独自の創作的意匠となって自己完結していることを条件に、その画像を新たな著作物と見なし、営利か非営利かを問わず、法令や良識に従う限り、その利用を画像著作者の自由とします。ソース・コードは、機能別に別ファイルに分割されているため、理解しやすく整理されています。ただし、「GCreatorCanvasEngine.java」だけは、細かく分割しないままで、長大なコードになっています。大量の説明コメントが、ソース・コードに埋め込まれているため、Javaの基本的知識さえあれば、誰でも理解可能です。もし、理解しにくい部分があれば、「とにかく、そのような手続きで上手く行くのだ。」と理解するしかありません。 Javaプログラミングに関しては、その難しさの本質が、ライブラリーの膨大さにあり、そのブラック・ボックスの内部構造の難解さにあります。ブラック・ボックスは、その内部構造を詳細に知ろうとしても、その趣旨からして困難で、その外形的な使い方を知るだけで満足するしかありません。そのため、ライブラリーの使い方のパターンを機械的に憶えることも、ブラック・ボックス的理解の一つであって、ブラック・ボックスの内部にまで深く踏み込むのは、上級者の範囲になります。

▲本書の構成

本書は、第一部の「解説編」と第二部の「ソース・コード編」との二部構成です。

「解説編」では、「GCreator」の機能説明や使用法説明を概略的に行ないます。「解説編」では、「GCreator」の稼働状態をスクリーン・ショットしたものを挿絵に用います。どんな画像が生成されるのか、具体例で、ひと目で分かるようにします。ただし、解説それ自体は、簡素なもので、必要最小限とします。詳しい解説は、ソース・コード内にコメント（注釈）として埋め込んでいます。つまり、既にJavaに関する基礎知識のある読者は、ソース・コードを読むことにより、解説も読む形になるわけです。

「ソース・コード編」では、必要なソース・コードの全部を公開します。ソース・コード以外に「GCreator_Manual.txt」も添付していますが、この機能解説書（コマンド仕様書）であるテキスト・ファイルは、プログラムの内部から参照され使用される必須のデータ・ファイルであって、これもプログラムの稼働に必要なものです。メニューの「ヘルプ」の「命令仕様書」を押すことで、「GCreator_Manual.txt」の内容がポップアップ表示されます。また、他にも模様生成のためのパターン・データ・ファイルもあり、「GCreator_Pattern.txt」として用意されています。これも、「ヘルプ」から参照できます。

ソース・コードの中に、個別具体的な解説をコメント形式で解説する方法を採用しているため、「ソース・コード編」では、ソース・コードの中以外に、詳しい解説はありません。ソース・コードの所定位置で、その場にふさわしい解説を行ないますので、ソース・コードを丹念に読んでください。ソース・コードは、トリッキーな書き方やテクニカルな書き方を一切していません。最も基本的で分かりやすい方法により、記述効率が悪かろうと、愚直に記述しています。そのため、複雑な部分や難解な部分が少なく、読みやすくなっています。

「GCreator」の具体的な使用法に関しては、「メニュー・バー」の中に「見本」の項目を入れ、命令文の書き方の見本を提示しています。基礎的な命令の記述法は、ソース・コードをコンパイルした上で、この「見本」を実行して、その振る舞いを見たり、命令文の一部を書き替えて、その振る舞いの変化を実験的に試して、理解していただくことになります。

▲補足説明

EPUBファイルの閲覧には、EPUBビューア・ソフトの「Calibre」などを利用して下さい。なお、「Calibre」は、なるべく最新バージョンを用いて下さい。表示テストは、「Calibre　Ver.7.18」で行ないました。

EPUBファイルの別の閲覧方法としては、EPUBファイルの拡張子「epub」を「zip」に書き替え、 zip圧縮を解凍（復元）すれば、複数のXHTMLファイルになるため、インターネット・ブラウザで閲覧できます。 EPUBファイルは、拡張子が変更されているものの、ZIP形式で圧縮されたZIPファイルに他なりません。また、「XHTML」は、「HTML」のタグ記述規則を厳格にしたものに過ぎず、基本的に同じものです。解凍されたファイル群から目次ファイルである「ch02nav.xhtml」を最初に開くと、インターネット・ブラウザで快適に閲覧できます。

EPUBビューア（「Calibre」など）やインターネット・ブラウザ（「グーグル・クローム」など）の機能に依存しますが、そのソフトにクリップボードへのテキスト・コピーができる機能（コピー・アンド・ペースト機能）があれば（あるはずです）、この機能を使って、 XHTMLのタグやエスケープ・シーケンス文字が除去されたソース・コードを、テキスト・エディタにペーストすることで、簡単に取得できます。また、筆者のホーム・ページ（奥付参照）では、全ソース・コードを、ZIP圧縮の上で公開していて、ダウンロード可能です。

■第一部　解説編

◆第一章　ファイル解説

GCreatorは、ソース・コード・ファイルおよび補助テキスト・ファイルとして、次に示すファイルが必要です。これらは、「ソース・コード編」でその全てを公開しています。なお、他にも必要となるディレクトリー（フォルダー）を書き加えます。これらのディレクトリー名およびファイル名は、ソース・コードの中でも使われているため、勝手に変更できません。

/user/java/GCreator/src/new　【ソース・ファイル・ディレクトリー】
　GCreator.java
　　Swingの各種部品を集めて操作と表示の画面を構築する
　GCreatorCanvasEngine.java
　　画像を描くキャンバスとして機能する
　GCreatorAnalyzeEngine.java
　　画像を描く命令を解析して、Javaの機能に置き換える準備を行なう
　GCreatorPalleteEngine.java
　　描画の基本色を混色するパレットとして、必要な色彩を作り出す
　GCreatorPrintEngine.java
　　完成された画像をプリンターで印刷する機能を実現する
　GCreatorFileIO.java
　　描画命令テキスト・ファイルや画像ファイルの入出力を行なう
　GCreatorMenuLis.java
　　メニューで要求された機能実現を外部に差配する
　GCreatorButtonLis.java
　　ボタンで要求された機能実現を外部に差配する
　GCreatorCanMouseLis.java
　　キャンバス上でのマウス・クリックに反応し、機能実現に寄与する
　GCreatorPalMouseLis.java
　　パレット上でのマウス・クリックと連繋し、機能実現に寄与する
　GCreatorSliderLis.java
　　混色された色彩をスライダーで微調整する機能を実現
/user/java/Lib/src/new　【ライブラリー・ソース・ファイル・ディレクトリー】
　StackTraceMonitor.java
　　Java実行環境が出力するエラー・メッセージを横取りする
　SystemMessage.java
　　StackTraceMonitorおよびGCreator.javaと協調動作する
　Util.java
　　ユーティリティーの提供（GCreatorにとって余分な機能も含む）
　SingleFileFilter.java
　　ファイル選択の補助を行なう
　TextIO.java
　　テキスト・ファイルの入出力を行なう（GCreatorにとって余分な機能も含む）
　Spline.java
　Spline2.java
　Spline3.java
　　スプライン曲線を描画する機能を実現する三種セット
/user/java/GCreator/sys　　【GCreatorシステム・ファイル・ディレクトリー】
　GCreator_Manual.txt
　　命令文の仕様書であるテキスト・ファイル
　GCreator_Pattern.txt
　　マトリックス・パターンの紋柄データベース
/user/java/GCreator/gcc　　【汎用命令文書ファイル・ディレクトリー(gcc)】
/user/java/GCreator/image　【汎用画像ファイル・ディレクトリー（jpeg,png,bmp,gif）】
/user/java/GCreator/project【プロジェクト単位のディレクトリー(gcc,jpeg,png等)
/user/class　　　　　　　　【クラス・ファイル・ディレクトリー(class)】
/user/bat　　　　　　　　　【バッチ・ファイル・ディレクトリー(bat)】
/user/java/GCreator/src/old【旧バージョンのソース・ファイル・ディレクトリー(java)】

◆第二章　操作法解説

以下に、GCreatorの稼働状態の実例をスクリーン・ショットで示し、操作法の概要を説明します。スクリーン・ショットされた大画面画像の縮小表示となると、文字が見えにくくなることがありますので、以下の説明文で確認してください。

上の図は、線描図形を描画している状態（マウス線描画モード）です。まずは、GCreatorの画面構成（Swingの配置）を説明します。一段目は、タイトル・バーであって、左端に「Gcreator Ver.3.3」と表示しているだけです。無論、右端には、ウィンドウ操作ボタン（最大化ボタンや終了ボタンなど）があります。二段目は、メニュー・バーであって、各種機能を配置しています。左端から、「ファイル」「消去」「見本１」「見本２」「見本３」「見本４」「倍率」「パレット」「描画モード」「マウス機能」「ヘルプ」のメニューがあり、それより右には、各種ラベルを表示しています。三段目は、ボタン・バーであって、左から順に「削除」「複写」「挿入」「保存」のボタンあり、さらに「取消」があり、さらに「復元」があり、さらに「描画」「乱数」「切取」「保存」のボタンがあります。これらのボタンは、次の四段目の横分割の領域区分と連動しています。四段目は、最も広い画面領域を占めていて、この図では、左から順に、「コマンド・エリア」「パレット・エリア」「スライダー・エリア」「キャンバス・エリア」となります。ただし、「パレット・エリア」と「スライダー・エリア」とを表示しない設定も可能で、その場合、部品の配置は、「コマンド・エリア」「キャンバス・エリア」の二つです。その場合、「パレット・エリア」付属の「取消」ボタンや「スライダー・エリア」付属の「復元」ボタンも表示されません。「パレット・エリア」および「スライダー・エリア」は、必要な時にだけ表示するもので、「メニュー・バー」の「パレット」メニューで切り替えられます。五段目は、「メッセージ・エリア」で、エラー・メッセージや作業報告メッセージを表示します。

メニュー・バーの「メニュー」および「メニュー・アイテム」の詳細は、以下のようになります。

ファイル
　　命令文書開く
　　命令文書保存
　　背景画像表示
　　スタンプ押印
　　画像保存
　　画像印刷
消去
　　命令文消去
　　警告文消去
　　全消去
見本１
　　各種図形描画
　　スプライン曲線描画
　　全体レイアウト・スケール
　　部品レイアウト・スケール
　　多段階回転画像作成用スケール
　　印刷試験A4
　　カード印刷
　　フォント表示テスト１
　　フォント表示テスト２
見本２
　　模様画像生成（統一配色）
　　模様画像生成（個別配色）
　　模様画像生成（二重混用）
　　模様画像生成（シフト）
　　模様画像生成（ドロップ）
　　模様画像生成（スキップ）
　　模様画像生成（間欠描画）
　　模様画像生成（傾斜元画像）
　　模様画像生成（画像傾斜加工）
　　模様画像生成（傾斜画像サイズ調整）
　　模様画像生成（複雑指定１）
　　模様画像生成（複雑指定２）
見本３
　　ロゴ画像（スタンプ用グレー・マスク）
　　ロゴ入り画像（スタンプ押印）
　　切り貼り用マルチ・マスク
　　切り貼り処理
　　画像鏡像反転
　　画像部分切り取り保存
　　二重画像用グレー・マスク
　　二重画像処理
　　ソフト・フォーカス元絵
　　ソフト・フォーカス処理
　　連続色相変更
　　単独色相変更
　　色相調整
　　色相階調加工
　　画像鏡像反転
　　画像部分切り取り保存
見本４
    スプライン曲線図形１
    輪郭線図形単独彩色
    スプライン曲線図形２
    輪郭線図形連続彩色
    輪郭線図形連続彩色SF
    輪郭線図形連続彩色仕上
    スプライン曲線図形３
    輪郭線図形高速連続彩色
倍率
　　表示:x4
　　表示:x3
　　表示:x2
　　表示:x1.5
　　表示:x1
　　表示:x1/1.5
　　表示:x1/2
　　表示:x1/3
　　表示:x1/4
パレット
　　パレット非表示
　　パレット表示
描画モード
　　マウス線描画
　　マウス点描画
　　マウス描画無効
マウス機能
　　直線
　　直線消去
　　ベジェ曲線
　　スプライン曲線
　　文字列
　　真円
　　楕円
　　四角形
　　自由図形
　　目印線消去
　　目印線復活
　　位置確認
　　位置修正
　　色相確認
　　図形彩色変更指定
　　命令文検索
　　点描画筆（巨）
　　点描画筆（大）
　　点描画筆（中）
　　点描画筆（小）
　　点描画筆（微）
ヘルプ
　　命令仕様書
　　模様データ

「コマンド・エリア」には、描画命令文が複数行表示されます。描画命令文は、マウス操作で自動的に記述する方法と、キーボードから直接入力する方法とがあります。マウス操作で命令文を作成する場合、メニューの「マウス機能」を選び、さらに「直線」や「曲線」や「楕円」や「四角形」などの線種別や図形種別を指定してから、「キャンバス・エリア」の範囲内でマウス・クリックすることで、指定の線や図形が描かれると共に、命令文も自動生成され「コマンド・エリア」に追加されます。いずれにせよ、「描画」ボタンが押されると、「コマンド・エリア」の命令文の全部（命令文書：マクロ・プログラム）を読み取り、これを順次解析し、「キャンバス・エリア」に指定通りに描画します。命令文に記述間違いがあれば、間違いの種類が、警告文として「メッセージ・エリア」に表示されます。

「コマンド・エリア」に表示された複数の命令文は、それ自体がマクロ・プログラム（命令文書）であって、ファイル保存ができ、再利用もできます。それは、メニューの「ファイル」の中の「命令文書開く」と「命令文書保存」とによって行ないます。画像の入出力も、同様に「背景画像表示」、「スタンプ押印」、「画像保存」、「画像印刷」、これらの選択で行ないます。

マウス操作による直線の描き方は、始点と終点との二箇所を左クリックするだけですが、ベジェ曲線の場合、四箇所を左クリックすることになります。ベジェ曲線のＵ字曲線で言えば、台形を描くつもりで、始点、第一制御点（中間点）、第二制御点、終点、この四箇所を左クリックすれば、補助線も表示しながら、台形の内側に曲線が表示されます。スプライン曲線の場合、始点および制御点（一箇所以上）は左クリックで、終点が右クリックです。曲線の場合、一度で望みの曲線になることはないので、マウスを使って、補助線で示された始点や制御点や終点を位置修正することになります。複雑な曲線で囲まれた図形を描く場合、ポリゴン（多角形）を事前に描き、それを目安にしながら、新たに曲線（ベジェ曲線、スプライン曲線）を繋いで行き、起点に戻って閉鎖空間とし、曲線を修正後に、内部を好みの色で着色し、最終的にポリゴンを消去する方法が、無理のない描き方になります。なお、ベジェ曲線を含む「自由図形」（メニューにある「自由図形」の機能）を描く場合、直線部は左クリックで、曲線部は右クリックとなりますが、詳しい操作の仕方は、ソース・コード（GCreatorCanMouseLis.java]）を参照下さい。複雑な曲線で囲まれた図形を描くのであれば、ベジェ曲線を利用するよりもスプライン曲線を利用する方が、表現しやすいです。座標点の位置修正は、メニューの中の「マウス操作」を選び「位置修正」を選び、問題の制御点（あるいは始点や終点）をクリックし、新しい制御点（あるいは始点や終点）をクリックすることで、曲線も補助線も修正され命令文も修正されます。マウス操作によって、どのようにデータが処理され、線が描画されるか、「GCreatorCanMouseLis.java」のソース・コードをコメントと共に、読んでいただかねばなりません。

上の図は、模様生成機能を実行している様子（マウス描画無効モード）です。この場合、色彩は、「コマンド・エリア」内の命令文で、基準色とランダム変動範囲が指定されているだけなので、指定された基準色に基づきつつも、ランダムで配色を決めています。「乱数」ボタンを押すたびに、異なる配色で図柄が自動生成されます。パターン模様（柄紋）の描画は、全て命令文によって行ないますので、マウス操作による描画はしません。ただし、「描画」ボタンと「乱数」ボタンは、話が別です。また、必要であれば、マウス描画無効モードからマウス線描画モードやマウス点描画モードに切り替え、線描画や点描画を付け加えることも可能です。推奨する方法は、模様生成機能を使い、命令文書を作成し、乱数を何度も発生させ、好みの図柄や配色を決定し、その決定した模様図柄をpng形式などでファイル保存し、その後に、その図柄をキャンバスにImage命令によって改めて表示し、線描画や文字や点描画を加えて加工する方法が、失敗も少なく効果的です。なお、図柄パターンは、データ・ファイル（GCreator_Pattern.txt）として保持していて、命令文の引数で図柄パターン番号を指定する形になります。「乱数」ボタンを繰り返し押し、好みの配色が実現すれば、「ファイル」メニューを押して画像ファイルとして保存します。現在時間の秒数を加味した乱数で配色を決定するため、二度と同じ配色を再現できず、画像で固定保存するしかありません。

上の図は、点描画機能を実行している様子（マウス点描画モード）です。この場合、パレットおよびスライダーが必須になりますので、パレットが非表示状態になっていれば、メニューにより表示してください。パレットで必要な絵具を選び、混色し、出来た混色に対して、さらにスライダーで色調を微調整します。パレットの説明をしますと、上から四段分は、十六色の基本色で、このどれかをマウスで選んで混色します。パレットの五段目は、選んだ絵具の色で、一色から四色まで混色が自由に選べます。六段目の左半分は、単純な混合色で、右半分は、その混合色をスライダーで微調整した調整色です。調整色が、点描画の筆の色になります。

点描画モードで、「キャンバス・エリア」をマウス・クリックすると、パレットでの調整色を用い、小さな円が描かれます。無論、「コマンド・エリア」には、クリックに対応する描画命令が追加されます。なお、何もない空白のキャンバスに点描するのは容易ではないため、予め下絵（写真などのデジタル画像データ）を用意しておき、「キャンバス・エリア」にそれをImage命令で表示し、点描で下絵が隠れてしまうほど、点描で埋め尽くすようにします。ただし、背景を一色で統一するつもりなら、背景に対して単純反復の点描操作を行なわずとも、背景色を指定するだけで、それが可能になります。その場合、最終段階で指定画像表示命令をコメント・アウトし、背景色指定命令を書き加えます。

上の図の２枚は、本の表紙の作成過程の進行状況を示しています。予め作成した好みの模様画像を切り貼りして組み合わせ、これに額縁や銘板や文字を描き加えて、表紙が作成される試行錯誤の途中段階を示しています。その際には、カット・アンド・ペースト機能やスタンプ機能を活用しています。模様の切り貼りは、カット・アンド・ペースト機能で実現しています。また、額縁や銘板やロゴ・マークの貼り付けは、スタンプ機能で実現しています。「メニュー・バー」の「見本」にも、本の表紙の作成見本を用意しておきました。カット・アンド・ペースト機能やスタンプ機能を何度も重ねれば、複雑なデザインが可能になります。スタンプ機能は、ロゴ・マークの配置を想定した特殊命令ですが、他の用途にも幅広く使えます。

以下に、表紙意匠の作例を、幾つか示します。ただし、作例の画像は、本来のサイズより縮小し、480×672 px としているため、精細度がかなり低下しています。本書の冒頭と末尾とにある表紙および奥付の画像は、精細度を高くしていて 1440×2016 px です。

■第二部　ソース・コード編

ソース・コード編の内容は、GCreator専用コードと、ライブラリーとしての汎用コードと、GCreatorのマニュアル等との、三種類から成り立っています。再掲載になりますが、以下に、関連ディレクトリーをも含め、これらを列挙します。

/user/java/GCreator/src/new　【ソース・ファイル・ディレクトリー】
　GCreator.java
　　Swingの各種部品を集めて操作と表示の画面を構築する
　GCreatorCanvasEngine.java
　　画像を描くキャンバスとして機能する
　GCreatorAnalyzeEngine.java
　　画像を描く命令を解析して、Javaの機能に置き換える準備を行なう
　GCreatorPalleteEngine.java
　　描画の基本色を混色するパレットとして、必要な色彩を作り出す
　GCreatorPrintEngine.java
　　完成された画像をプリンターで印刷する機能を実現する
　GCreatorFileIO.java
　　描画命令テキスト・ファイルや画像ファイルの入出力を行なう
　GCreatorMenuLis.java
　　メニューで要求された機能実現を外部に差配する
　GCreatorButtonLis.java
　　ボタンで要求された機能実現を外部に差配する
　GCreatorCanMouseLis.java
　　キャンバス上でのマウス・クリックに反応し、機能実現に寄与する
　GCreatorPalMouseLis.java
　　パレット上でのマウス・クリックと連繋し、機能実現に寄与する
　GCreatorSliderLis.java
　　混色された色彩をスライダーで微調整する機能を実現
/user/java/Lib/src/new　【ライブラリー・ソース・ファイル・ディレクトリー】
　StackTraceMonitor.java
　　Java実行環境が出力するエラー・メッセージを横取りする
　SystemMessage.java
　　StackTraceMonitorおよびGCreator.javaと協調動作する
　Util.java
　　ユーティリティーの提供（GCreatorにとって余分な機能も含む）
　SingleFileFilter.java
　　ファイル選択の補助を行なう
　TextIO.java
　　テキスト・ファイルの入出力を行なう（GCreatorにとって余分な機能も含む）
　Spline.java
　Spline2.java
　Spline3.java
　　スプライン曲線を描画する機能を実現する三種セット
/user/java/GCreator/sys　　【GCreatorシステム・ファイル・ディレクトリー】
　GCreator_Manual.txt
　　命令文仕様書のテキスト・ファイル
　GCreator_Pattern.txt
　　マトリックス・パターンの紋柄データベース（欄数不統一CSV形式）
/user/java/GCreator/gcc　　【汎用命令文書ファイル・ディレクトリー(gcc)】
/user/java/GCreator/image　【汎用画像ファイル・ディレクトリー（jpeg,png,bmp,gif）】
/user/java/GCreator/project【プロジェクト単位のディレクトリー(gcc,jpeg,png等)
/user/class　　　　　　　　【クラス・ファイル・ディレクトリー(class)】
/user/bat　　　　　　　　　【バッチ・ファイル・ディレクトリー(bat)】
/user/java/GCreator/src/old【旧バージョンのソース・ファイル・ディレクトリー(java)】

『Java 実例 プログラミング』の「描画処理編」は、何度か改訂されるたびに、新バージョンの「GCreator」のソース・コードを掲載して来ましたが、両者の対応関係は、以下の通りです。

第一版（2022年04月22日発行）掲載は、「GCreator Ver.1.0」
改訂版（2022年07月14日発行）掲載は、「GCreator Ver.1.1」
第三版（2023年04月03日発行）掲載は、「GCreator Ver.2.0」
第四版（2024年01月23日発行）掲載は、「GCreator Ver.3.0」
第五版（2024年09月17日発行）掲載は、「GCreator Ver.3.1」
第六版（2024年10月17日発行）掲載は、「GCreator Ver.3.2」

ところで、「Windows11」から、テキスト・ファイルの入出力において、文字コードのデフォルトが、「Shift_JIS」から「UTF-8」になりました。正確に言えば、「Windows10」であっても、「Windows10 21H2」から「UTF-8」に変更されています。なお、バージョン番号の「21H2」は、「2021年下半期」の意味です。「Windows10」であれ「Windows11」であれ、「UTF-8」がデフォルトの環境である場合、この点に注意が必要です。「UTF-8」がOSレベルで標準仕様となる今後は、プログラム・ソース・コード（.java）も命令文書（.gcc）も「GCreator_Manual.txt」も「GCreator_Pattern.txt」も、特別な理由がない限り、全て「UTF-8」で保存することが望まれます。各種テキスト・エディターには、文字コードを指定してファイル保存する機能があるはずです。一方、「Java」が「UTF-8」を文字入出力のデフォルトにしたのは、「JDK18」からです。本書も、「JDK18」以降を想定しています。

なお、コンピューターのストレージ（HDDやSSD）にJavaの実行環境（JDK18以降）がインストール済みで、 「javac.exe」や「java.exe」が実行できるよう、また、拡張子が「class」のファイルにアクセスできるよう、ＯＳに対してシステム環境変数（「PATH」および「CLASSPATH」さらに「JAVA_HOME」）が適切に設定されているものとします。ただし、当面必要な「システム環境変数」は、「PATH」および「CLASSPATH」の設定だけです。「PATH」は、多くのプログラムが必要とする性質のもので、既に幾つも事前に設定されているはずですが、「javac.exe」や「java.exe」が必要とするものを、さらに追加することになります。また、「JAVA_HOME」は、他のプログラムが必要とすることもあるため、念のために設定するものです。「環境変数」の「PATH」および「CLASSPATH」は、バッチ・ファイルの中でその都度指定することも可能ですが、「JAVA_HOME」は、そうではないため、ＯＳの「コントロール パネル」を通じて、これら全部を指定することを推奨します。

「システム環境変数」設定の一例（各自が中身を調整すること）
「PATH」 　　　―――　「c:\Progrem Files\java\jdk-18.0.2.1\bin」を含むこと
「CLASSPATH」　―――　「c:\user\class」
「JAVA_HOME」　―――　「c:\Progrem Files\java\jdk-18.0.2.1」（念のための設定）

「システム環境変数」が適切に設定済みであることを条件に、Windows11の環境下でコンパイルするバッチ・ファイルの一例（参考）を、以下に示します。見落としやすいピリオド記号に、注意して下さい。この一例は、「UTF-8」で記述されたソース・コードをコンパイルする場合です。

まずは、ライブラリーのコンパイル。

rem ライブラリーのコンパイル
c:
del \user\class\SystemMessage*.class
del \user\class\StackTraceMonitor*.class
del \user\class\SingleFileFilter*.class
del \user\class\UtilG*.class
del \user\class\TextIO*.class
del \user\class\Spline*.class
cd \user\java\Lib\src\new
javac -d \user\class -sourcepath . -encoding UTF-8 SystemMessage.java
javac -d \user\class -sourcepath . -encoding UTF-8 StackTraceMonitor.java
javac -d \user\class -sourcepath . -encoding UTF-8 SingleFileFilter.java
javac -d \user\class -sourcepath . -encoding UTF-8 Util.java
javac -d \user\class -sourcepath . -encoding UTF-8 TextIO.java
javac -d \user\class -sourcepath . -encoding UTF-8 Spline.java
javac -d \user\class -sourcepath . -encoding UTF-8 Spline2.java
javac -d \user\class -sourcepath . -encoding UTF-8 Spline3.java
pause

続いて、GCreatorのコンパイル。

rem GCreatorのコンパイル
c:
del \user\class\GCreator*.class
cd \user\java\GCreator\src\new
javac -d \user\class -sourcepath . -encoding UTF-8 GCreator.java
pause

コンパイル済みのプログラムに対して、Windows11の環境下で実行するバッチ・ファイルの一例（参考）を、以下に示します。この一例は、ヒープ・メモリーを大き目（最大6GB＝6144MB）に確保するオプションを含んでいます。マシンに実装しているメモリーを考慮しつつ、可能な限り、ヒープ・メモリーを潤沢に設定することを推奨します。

rem GCreatorの実行
c:
cd \user\java\GCreator
java -Xmx6144m GCreator
pause

いずれのバッチ・ファイルであっても、各自のコンピューティング環境に合わせて、中身を調整する必要があります。

なお、「GCreator Ver.3.3」の実行環境としては、以下の条件で安定動作することを確認しています。ただし、メモリー実装不足（4GB未満）の環境下で、巨大データ（MatrixPatternEx()およびMatrixPatternExOp()に関連する巨大配列）を生成し操作すれば、ヒープ・メモリー不足のエラーになる可能性があります。とは言え、極端なことをしない限り、高速かつ安定的に描画処理できます。

CPU:     intel Core i3-1005G1
MEMORY:  8GB
STRAGE:  117GB SSD
DISPLAY: 1920x1080px (set up 150%)
OS:      Windows11 Home
JDK:     JDK18

◆GCreator.java

//■■GCreator.java
//Ver.3.3

//■■TEST ENVIRONMENT
//CPU:     intel Core i3-1005G1
//MEMORY:  8GB
//STRAGE:  117GB SSD
//DISPLAY: 1920×1080 px (setup 150%: 1280×720 px)
//OS:      Windows11 Home
//JDK:     JDK18

//一般的なディスプレイの解像度は、以下の通り。
//8K（7680×4320 dot）
//4K（3840×2160）
//WQHD（2560×1440）
//FHD（1920×1080）
//WXGA++(1600×900）
//HD（1280×720）
//ただし、
//FHD（1920×1080）が最多であり標準である。

/*
■■DIRECTORIES & FILES
/user/java/GCreator/src/new　　ソース・ファイル
  GCreator.java
  GCreatorMenuLis.java
  GCreatorButtonLis.java
  GCreatorCanMouseLis.java
  GCreatorPalMouseLis.java
  GCreatorCanvasEngine.java
  GCreatorAnalyzeEngine.java
  GCreatorPalleteEngine.java
  GCreatorSliderLis.java
  GCreatorPrintEngine.java
  GCreatorFileIO.java
/user/java/Lib/src/new　　ライブラリー・ソース・ファイル
  SystemMessage.java
  StackTraceMonitor.java
  SingleFileFilter.java
  UtilG.java
  TextIO.java
/user/java/GCreator/sys　　　システム・サポート・ファイル
  GCreator_Manual.txt
  GCreator_Pattern.txt
/user/java/GCreator/gcc　　　汎用命令文書ファイル(gcc)
/user/java/GCreator/image　　汎用画像ファイル(png,jpeg,gif,bmp)
/user/java/GCreator/project　プロジェクトごとにサブ・ディレクトリーを作成し、ファイル(gcc,png)を格納
/user/class　　　　　　　　　クラス・ファイル(class)
*/

//■■インポート
import java.awt.*;  //必須
import java.awt.event.*;  //必須
import javax.swing.*;  //必須
import java.util.*;  //必須
import java.io.*;  //必須

//■■フレーム定義
class GCreator extends JFrame implements SystemMessage
{
  //■メンバー変数
  //●プログラム・バージョン
  final static String version = "Ver.3.3";

  //●基本的な変数
  GCreator f;
  Container pane;
  GCreatorCanvasEngine canvas;    //画像描画制御
  GCreatorAnalyzeEngine analyze;  //命令文解析
  GCreatorPaletteEngine palette;  //パレット混色制御
  GCreatorPrintEngine printer;    //印刷制御
  GCreatorMenuLis menuLis;        //メニュー・リスナー
  GCreatorButtonLis buttonLis;    //ボタン・リスナー
  GCreatorCanMouseLis cMouseLis;  //画像表示部での命令文生成マウス・リスナー
  GCreatorPalMouseLis pMouseLis;  //パレット表示部での混色マウス・リスナー
  GCreatorSliderLis sliderLis;    //混色微調整用のスライダー・リスナー
  GCreatorFileIO io;              //ファイル入出力

  JMenuBar menuBar;                   //メニュー配置
  JPanel buttonBarC   = new JPanel(); //制御命令系ボタンを配置
  JPanel buttonBarG   = new JPanel(); //画像表示系ボタンを配置
  JPanel buttonBarP   = new JPanel(); //パレット系ボタンを配置
  JPanel buttonBarS   = new JPanel(); //スライダー系ボタンを配置
  JPanel sliderPanel  = new JPanel(); //パレット系スライダーを配置
  JSlider sldR;
  JSlider sldG;
  JSlider sldB;

  JLabel fillerLabel   = new JLabel("　　　");      //埋草の空白
  JLabel scaleLabel    = new JLabel("　(a:x1.0)");  //表示スケール（AffineScale）
  JLabel scaleLabel2   = new JLabel("　(f:x1.0 )"); //表示スケール（FreeScale）
  JLabel pixelLabel    = new JLabel("　(i: )");     //画像ピクセル数(px)
  JLabel mmLabel       = new JLabel("　(p: )");     //印刷サイズ(mm)

  JLabel matrixStUnitLabel = new JLabel(""); //紋柄ユニットStの構成
  JLabel matrixExUnitLabel = new JLabel(""); //紋柄ユニットExの構成
  JLabel mouseModeLabel    = new JLabel("マウス描画無効モード");

  JTextArea cArea, mArea;
  JScrollPane scrollC, scrollG, scrollP, scrollS, scrollM;
  final int scrollCWidth;  //サイズ基準値
  final int scrollCHeight; //サイズ基準値
  final int scrollMHeight; //サイズ基準値

  //●画面表示と画像保存とに反映される図形倍率。
  //画像印刷には反映されない。
  final double xL4 = 4.0D;
  final double xL3 = 3.0D;
  final double xL2 = 2.0D;
  final double xML = 1.5D;
  final double xM1 = 1.0D;
  final double xMS = 1/1.5D;
  final double xS2 = 1/2.0D;
  final double xS3 = 1/3.0D;
  final double xS4 = 1/4.0D;

  //●スウィングに表示される文字数や行数
  int cdLines, cdCols, mLines, mCols;

  //■エントリーポイント
  public static void main(String[] args)
  {
    //●画面構築部の生成
    new GCreator(null, null);
  }

  //■フレームのコンストラクタ
  GCreator(final SystemMessage sm, final StackTraceMonitor st)
  { //SystemMessageおよびStackTraceMonitorは、私的ライブラリー所収
    super("GCreator  " + version);
    f = this;
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    //●クローズアイコンの動作定義、及び実行モード設定
    setDefaultCloseOperation(EXIT_ON_CLOSE);  //単に終了
    new StackTraceMonitor(this).start(); //標準エラー出力の監視

    //●要求判定部（リスナー）の生成
    menuLis   = new GCreatorMenuLis(this);
    buttonLis = new GCreatorButtonLis(this);
    cMouseLis = new GCreatorCanMouseLis(this);
    pMouseLis = new GCreatorPalMouseLis(this);
    sliderLis = new GCreatorSliderLis(this);

    //●主要機能部の生成
    canvas   = new GCreatorCanvasEngine(this);
    analyze  = new GCreatorAnalyzeEngine(this);
    palette  = new GCreatorPaletteEngine(this);
    printer  = new GCreatorPrintEngine(this);
    io       = new GCreatorFileIO(this);

    //●スウィングで表示される文字数や行数や大きさ。
    //それぞれの実行環境に合わせて数値を調整すること。
    //下記の数値設定は、簡易設定。
    if(getToolkit().getScreenSize().width >= 1280 &&
       getToolkit().getScreenSize().height >= 720)
    {
        cdLines =  32; //この数値は、実機に合わせて変更する
        cdCols  =  39; //この数値は、実機に合わせて変更する
        mLines  =   4; //この数値は、実機に合わせて変更する
        mCols   =  70; //この数値は、実機に合わせて変更する
    }
    else
    {
        cdLines =  21; //この数値は、実機に合わせて変更する
        cdCols  =  21; //この数値は、実機に合わせて変更する
        mLines  =   3; //この数値は、実機に合わせて変更する
        mCols   =  46; //この数値は、実機に合わせて変更する
    }

    //●MENU BAR:メニュー表示部品
    JMenu menu;
    setJMenuBar(menuBar = new JMenuBar());

    addA(menuBar, menu = new JMenu("ファイル"));
    addB(menu, new JMenuItem("命令文書開く"), menuLis, "LoD");
    addB(menu, new JMenuItem("命令文書保存"), menuLis, "SaD");
    menu.addSeparator();
    addB(menu, new JMenuItem("背景画像表示"), menuLis, "LoI");
    addB(menu, new JMenuItem("スタンプ押印"), menuLis, "Stm");
    menu.addSeparator();
    addB(menu, new JMenuItem("画像保存"),     menuLis, "Sa2");
    addB(menu, new JMenuItem("画像印刷"),     menuLis, "Pri");

    addA(menuBar, menu = new JMenu("消去"));
    addB(menu, new JMenuItem("命令文消去"), menuLis,   "Cl2");
    addB(menu, new JMenuItem("警告文消去"), menuLis,   "Cl3");
    addB(menu, new JMenuItem("全消去"),     menuLis,   "Cl4");

    addA(menuBar, menu = new JMenu("見本１"));
    addB(menu, new JMenuItem("各種図形描画"),             menuLis, "FrS");
    addB(menu, new JMenuItem("スプライン曲線描画"),       menuLis, "SpC");
    addB(menu, new JMenuItem("全体レイアウト・スケール"), menuLis, "Lay");
    addB(menu, new JMenuItem("部品レイアウト・スケール"), menuLis, "La2");
    addB(menu, new JMenuItem("多段階回転画像作成用スケール"), menuLis, "RLS");
    addB(menu, new JMenuItem("印刷試験A4"),               menuLis, "TA4");
    addB(menu, new JMenuItem("カード印刷"),               menuLis, "NCP");
    addB(menu, new JMenuItem("フォント表示テスト1"),      menuLis, "Pht");
    addB(menu, new JMenuItem("フォント表示テスト2"),      menuLis, "Ph2");

    addA(menuBar, menu = new JMenu("見本２"));
    addB(menu, new JMenuItem("模様画像生成（統一配色）"), menuLis, "BG1");
    addB(menu, new JMenuItem("模様画像生成（個別配色）"), menuLis, "BG2");
    addB(menu, new JMenuItem("模様画像生成（二重混用）"), menuLis, "BG3");
    addB(menu, new JMenuItem("模様画像生成（シフト）"),   menuLis, "BG4");
    addB(menu, new JMenuItem("模様画像生成（ドロップ）"), menuLis, "BG5");
    addB(menu, new JMenuItem("模様画像生成（スキップ）"), menuLis, "BG6");
    addB(menu, new JMenuItem("模様画像生成（間欠描画）"), menuLis, "BG7");
    addB(menu, new JMenuItem("模様画像生成（傾斜元画像）"),menuLis,"BG8a");
    addB(menu, new JMenuItem("模様画像生成（画像傾斜加工）"),menuLis,"BG8b");
    addB(menu, new JMenuItem("模様画像生成（傾斜画像サイズ調整）"),menuLis,"BG8c");
    addB(menu, new JMenuItem("模様画像生成（複雑指定１）"),menuLis,"BG9");
    addB(menu, new JMenuItem("模様画像生成（複雑指定２）"),menuLis,"BG10");

    addA(menuBar, menu = new JMenu("見本３"));
    addB(menu, new JMenuItem("ロゴ画像（スタンプ用グレー・マスク）"),menuLis, "Log");
    addB(menu, new JMenuItem("ロゴ入り画像（スタンプ押印）"), menuLis, "LBG");
    addB(menu, new JMenuItem("切り貼り用マルチ・マスク"), menuLis, "MSK");
    addB(menu, new JMenuItem("切り貼り"),                 menuLis, "CAP");
    addB(menu, new JMenuItem("二重像用グレー・マスク"),   menuLis, "MiM");
    addB(menu, new JMenuItem("二重像処理"),               menuLis, "Mix");
    addB(menu, new JMenuItem("ソフト・フォーカス用元絵"), menuLis, "SFx");
    addB(menu, new JMenuItem("ソフト・フォーカス処理"),   menuLis, "SFo");
    addB(menu, new JMenuItem("画像多段階回転描画の準備"), menuLis, "RoI");
    addB(menu, new JMenuItem("画像多段階回転描画"),       menuLis, "RoM");
    addB(menu, new JMenuItem("連続色相変更"),             menuLis, "CCM");
    addB(menu, new JMenuItem("単独色相変更"),             menuLis, "ChC");
    addB(menu, new JMenuItem("色相調整"),                 menuLis, "Adj");
    addB(menu, new JMenuItem("色相階調加工"),             menuLis, "Grd");
    addB(menu, new JMenuItem("画像鏡像反転"),             menuLis, "REV");
    addB(menu, new JMenuItem("画像切り取り保存"),         menuLis, "CAS");

    addA(menuBar, menu = new JMenu("見本４"));
    addB(menu, new JMenuItem("スプライン曲線図形１"),     menuLis, "Sp1");
    addB(menu, new JMenuItem("輪郭線図形単独彩色"),       menuLis, "SpP");
    addB(menu, new JMenuItem("スプライン曲線図形２"),     menuLis, "Sp2");
    addB(menu, new JMenuItem("輪郭線図形連続彩色"),       menuLis, "SpM");
    addB(menu, new JMenuItem("輪郭線図形連続彩色SF"),     menuLis, "SpS");
    addB(menu, new JMenuItem("輪郭線図形連続彩色仕上"),   menuLis, "SpF");
    addB(menu, new JMenuItem("スプライン曲線図形３"),     menuLis, "Sp3");
    addB(menu, new JMenuItem("輪郭線図形高速連続彩色"),   menuLis, "SpX");

    addA(menuBar, menu = new JMenu("倍率"));
    addB(menu, new JMenuItem("表示:x4"),    menuLis, "XL4");
    addB(menu, new JMenuItem("表示:x3"),    menuLis, "XL3");
    addB(menu, new JMenuItem("表示:x2"),    menuLis, "XL2");
    addB(menu, new JMenuItem("表示:x1.5"),  menuLis, "XML");
    addB(menu, new JMenuItem("表示:x1"),    menuLis, "XM1");
    addB(menu, new JMenuItem("表示:x1/1.5"),menuLis, "XMS");
    addB(menu, new JMenuItem("表示:x1/2"),  menuLis, "XS2");
    addB(menu, new JMenuItem("表示:x1/3"),  menuLis, "XS3");
    addB(menu, new JMenuItem("表示:x1/4"),  menuLis, "XS4");

    addA(menuBar, menu = new JMenu("パレット"));
    addB(menu, new JMenuItem("パレット非表示"), menuLis, "Sc1");
    addB(menu, new JMenuItem("パレット表示"),   menuLis, "Sc2");

    addA(menuBar, menu = new JMenu("描画モード"));
    addB(menu, new JMenuItem("マウス線描画"), menuLis,  "Of1");
    addB(menu, new JMenuItem("マウス点描画"), menuLis,  "Of2");
    addB(menu, new JMenuItem("マウス描画無効"), menuLis,"Of3");

    addA(menuBar, menu = new JMenu("マウス機能"));
    addB(menu, new JMenuItem("直線"),       menuLis, "Lin");
    addB(menu, new JMenuItem("直線消去"),   menuLis, "Eli");
    addB(menu, new JMenuItem("ベジェ曲線"), menuLis, "Cur");
    addB(menu, new JMenuItem("スプライン曲線"), menuLis,"Spl");
    menu.addSeparator();
    addB(menu, new JMenuItem("文字列"),     menuLis, "St2");
    menu.addSeparator();
    addB(menu, new JMenuItem("真円"),       menuLis, "Cir");
    addB(menu, new JMenuItem("楕円"),       menuLis, "Ell");
    addB(menu, new JMenuItem("四角形"),     menuLis, "Rec");
    addB(menu, new JMenuItem("自由図形"),   menuLis, "Fre");
    menu.addSeparator();
    addB(menu, new JMenuItem("目印線消去"), menuLis, "ECu");
    addB(menu, new JMenuItem("目印線復活"), menuLis, "DCu");
    addB(menu, new JMenuItem("位置確認"),   menuLis, "Pos");
    addB(menu, new JMenuItem("位置修正"),   menuLis, "AC3");
    addB(menu, new JMenuItem("色相確認"),   menuLis, "Clx");
    addB(menu, new JMenuItem("図形彩色指定変更"), menuLis, "CoP");
    addB(menu, new JMenuItem("命令文検索"), menuLis, "Ref");
    menu.addSeparator();
    addB(menu, new JMenuItem("点描画筆（巨）"), menuLis, "BrL");
    addB(menu, new JMenuItem("点描画筆（大）"), menuLis, "BrM");
    addB(menu, new JMenuItem("点描画筆（中）"), menuLis, "BrS");
    addB(menu, new JMenuItem("点描画筆（小）"), menuLis, "BrX");
    addB(menu, new JMenuItem("点描画筆（微）"), menuLis, "BrZ");

    addA(menuBar, menu = new JMenu("ヘルプ"));
    addB(menu, new JMenuItem("命令仕様書"), menuLis, "Usa");
    addB(menu, new JMenuItem("模様データ"), menuLis, "Ptn");

    menuBar.add(fillerLabel); //空白の設置
    menuBar.add(scaleLabel);  //倍率表示（affine scale）
    menuBar.add(scaleLabel2); //倍率表示（free scale）
    menuBar.add(pixelLabel);  //サイズ表示（px）
    menuBar.add(mmLabel);     //サイズ表示（mm）

    //●BUTTON BAR:ボタン表示部品
    //以下は、命令文操作に用いるボタン・バーのレイアウト
    buttonBarC.setLayout(new FlowLayout(FlowLayout.LEFT));
    addB(buttonBarC, new JButton("削除"),
      new ActionListener()
      { public void actionPerformed(ActionEvent event)
        { cArea.cut(); } } ,"");
    addB(buttonBarC, new JButton("複写"),
      new ActionListener()
      { public void actionPerformed(ActionEvent event)
        { cArea.copy(); } } ,"");
    addB(buttonBarC, new JButton("挿入"),
      new ActionListener()
      { public void actionPerformed(ActionEvent event)
        { cArea.paste(); } } ,"");
    addB(buttonBarC, new JButton("保存"),   buttonLis, "SvC");

    //以下は、キャンバス画像表示に用いるボタン・バーのレイアウト
    buttonBarG.setLayout(new FlowLayout(FlowLayout.LEFT));
    addB(buttonBarG, new JButton("描画"),   buttonLis, "Rep");
    addB(buttonBarG, new JButton("乱数"),   buttonLis, "Rp2");
    addB(buttonBarG, new JButton("切取"),   buttonLis, "SvP");
    addB(buttonBarG, new JButton("保存"),   buttonLis, "SvI");
    buttonBarG.add(matrixStUnitLabel);
    buttonBarG.add(matrixExUnitLabel);
    buttonBarG.add(mouseModeLabel);

    //二種類の「保存」ボタンは、命令文書に「SaveCommands」命令や
    //「SaveImage」命令を含む時、該当するファイル保存操作を半自動で実行する。
    //なお、ボタン操作でなく、メニュー操作によるファイル保存も、常に可能。

    //以下は、パレット混色に用いるボタン・バーのレイアウト
    buttonBarP.setLayout(new FlowLayout(FlowLayout.LEFT));
    addB(buttonBarP, new JButton("取消"), buttonLis, "Can");

    //以下は、スライダーのキャンセルに用いるボタン・バーのレイアウト
    buttonBarS.setLayout(new FlowLayout(FlowLayout.LEFT));
    addB(buttonBarS, new JButton("復元"), buttonLis, "Adj");

    //●COMMAND AREA:命令文表示
    cArea = new JTextArea(cdLines,cdCols);
    scrollC = new JScrollPane(cArea,
      JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
      JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
    cArea.setBackground(new Color(230,230,255));
    cArea.setMargin(new Insets(3, 3, 3, 3)); //余白
    cArea.setEditable(true);  //編集可能

    //●PALETTE AREA:パレット表示
    scrollP = new JScrollPane(palette,
      JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
      JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
    palette.setPreferredSize(new Dimension(400,700));
    palette.setOpaque(true); //不透明化
    palette.addMouseListener(pMouseLis);

    //●SLIDER AREA:スライダー表示
    scrollS = new JScrollPane(sliderPanel,
      JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
      JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
    sliderPanel.setPreferredSize(new Dimension(50,600));
    sliderPanel.setLayout(new GridLayout(4,1));
    sliderPanel.setOpaque(true); //不透明化

    sldR = new JSlider(JSlider.VERTICAL,-30,30,0); //赤
    sldR.addChangeListener(sliderLis);
    sldR.setMajorTickSpacing(10);
    sldR.setMinorTickSpacing(2);
    sldR.setPaintTicks(true);
    sldR.setPaintLabels(true);
    sldR.setBackground(Color.red);
    sldR.setForeground(Color.white);
    f.sliderPanel.add(sldR);

    sldG = new JSlider(JSlider.VERTICAL,-30,30,0); //緑
    sldG.addChangeListener(sliderLis);
    sldG.setMajorTickSpacing(10);
    sldG.setMinorTickSpacing(2);
    sldG.setPaintTicks(true);
    sldG.setPaintLabels(true);
    sldG.setBackground(Color.green);
    sldG.setForeground(Color.white);
    f.sliderPanel.add(sldG);

    sldB = new JSlider(JSlider.VERTICAL,-30,30,0); //青
    sldB.addChangeListener(sliderLis);
    sldB.setMajorTickSpacing(10);
    sldB.setMinorTickSpacing(2);
    sldB.setPaintTicks(true);
    sldB.setPaintLabels(true);
    sldB.setBackground(Color.blue);
    sldB.setForeground(Color.white);
    f.sliderPanel.add(sldB);

    //●CANVAS AREA:キャンバス表示
    scrollG = new JScrollPane(canvas,
      JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
      JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
    scrollG.setPreferredSize(new Dimension(
      (int)(scrollC.getPreferredSize().getWidth()*2.5),
      (int)scrollC.getPreferredSize().getHeight()));
    canvas.setPreferredSize(new Dimension(10000,10000));
    canvas.setOpaque(true); //不透明化
    canvas.addMouseListener(cMouseLis);

    //●MESSAGE AREA:警告文表示
    mArea = new JTextArea(mLines,mCols);
    mArea.setBackground(new Color(230,230,255));
    mArea.setMargin(new Insets(3, 3, 3, 3)); //余白
    scrollM = new JScrollPane(mArea,
      JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
      JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
    mArea.setAutoscrolls(true);  //自動スクロール

    //●全体レイアウト初期設定（パレット非表示画面）
    //ボックス・レイアウトを利用
    pane = getContentPane();
    Box vBox = Box.createVerticalBox();
    Box vBoxC = Box.createVerticalBox();
    Box vBoxG = Box.createVerticalBox();
    Box hBox = Box.createHorizontalBox();
    pane.add(vBox);
    vBox.add(hBox);
    vBox.add(scrollM);
    hBox.add(vBoxC);
    hBox.add(vBoxG);
    vBoxC.add(buttonBarC);
    vBoxC.add(scrollC);
    vBoxG.add(buttonBarG);
    vBoxG.add(scrollG);
    scrollCWidth =  (int)scrollC.getPreferredSize().getWidth();
    scrollCHeight = (int)scrollC.getPreferredSize().getHeight();
    scrollMHeight = (int)scrollM.getPreferredSize().getHeight();
    scrollC.setPreferredSize(new Dimension(
      (int)(scrollCWidth), scrollCHeight ));
    scrollG.setPreferredSize(new Dimension(
      (int)(scrollCWidth *1.8), scrollCHeight ));
    pack();
    setVisible(true);

    GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
    int screenW = gd.getDisplayMode().getWidth();
    int screenH = gd.getDisplayMode().getHeight();
    message("hardware screen size = " + screenW + " × " + screenH + " px");
    //上記スクリーン・サイズは、ハードウェアとしての本来の数値。

    screenW = getToolkit().getScreenSize().width;
    screenH = getToolkit().getScreenSize().height;
    message("software screen size = " + screenW + " × " + screenH + " px");
    //上記スクリーン・サイズは、OSでセットアップされたソフトウェアでの数値。

    int barH = 10; //この数値は適当に小さい数（丈固定統一）
    buttonBarC.setMaximumSize(new Dimension(Short.MAX_VALUE, barH));
    buttonBarG.setMaximumSize(new Dimension(Short.MAX_VALUE, barH));
    buttonBarP.setMaximumSize(new Dimension(Short.MAX_VALUE, barH));
    buttonBarS.setMaximumSize(new Dimension(Short.MAX_VALUE, barH));
  }

  //■全体レイアウトの切り替え（画面切り替え）
  public void changeLayout(int mode)
  {
    pane.removeAll();
    if(mode==1) //●パレット非表示画面
    {
      Box vBox = Box.createVerticalBox();
      Box vBoxC = Box.createVerticalBox();
      Box vBoxG = Box.createVerticalBox();
      Box hBox = Box.createHorizontalBox();
      pane.add(vBox);
      vBox.add(hBox);
      vBox.add(scrollM);
      hBox.add(vBoxC);
      hBox.add(vBoxG);
      vBoxC.add(buttonBarC);
      vBoxC.add(scrollC);
      vBoxG.add(buttonBarG);
      vBoxG.add(scrollG);
      scrollC.setPreferredSize(new Dimension(
        (int)(scrollCWidth), scrollCHeight ));
      scrollG.setPreferredSize(new Dimension(
        (int)(scrollCWidth *1.8), scrollCHeight ));
      f.pack();
      f.setVisible(true);
    }
    else if(mode==2)//●パレット表示画面
    {
      Box vBox = Box.createVerticalBox();
      Box vBoxC = Box.createVerticalBox();
      Box vBoxP = Box.createVerticalBox();
      Box vBoxS = Box.createVerticalBox();
      Box vBoxG = Box.createVerticalBox();
      Box hBox = Box.createHorizontalBox();
      pane.add(vBox);
      vBox.add(hBox);
      vBox.add(scrollM);
      hBox.add(vBoxC);
      hBox.add(vBoxP);
      hBox.add(vBoxS);
      hBox.add(vBoxG);
      vBoxC.add(buttonBarC);
      vBoxC.add(scrollC);
      vBoxP.add(buttonBarP);
      vBoxP.add(scrollP);
      vBoxS.add(buttonBarS);
      vBoxS.add(scrollS);
      vBoxG.add(buttonBarG);
      vBoxG.add(scrollG);
      scrollC.setPreferredSize(new Dimension(
         (int)(scrollCWidth*0.6), scrollCHeight));
      scrollP.setPreferredSize(new Dimension(
         (int)(scrollCWidth*0.5), scrollCHeight));
      scrollS.setPreferredSize(new Dimension(
         (int)(scrollCWidth*0.15), scrollCHeight));
      scrollG.setPreferredSize(new Dimension(
         (int)(scrollCWidth*1.5), scrollCHeight));
      f.pack();
      f.setVisible(true);
    }
    else
      f.message("画面切り替えに異常。");
  }

  //■コンテナーに JMenu をレイアウト
  public void addA(Container cont, AbstractButton b)
  {
    cont.add(b);
  }
  //■コンテナーに JButton or JMenuItem をレイアウト
  public void addB(Container cont, AbstractButton b,
    ActionListener lis, String command)
  {
    cont.add(b);
    if(lis!=null)
      b.addActionListener(lis);
    if(command!=null)
      b.setActionCommand(command);
  }

  //■システムメッセージの表示
  //Java仮想マシンが吐き出すエラー・メッセージまたは
  //GCreatorプログラム内から吐き出す警告文や通知文を表示
  public void message(String s)
  {  //●エラー通知、または、状況報告
    int len = mArea.getText().length();
    mArea.select(len, len); //自動スクロール
    mArea.append(s + "\n");
  }
} //EOF (GCreator.java)

◆GCreatorCanvasEngine.java

//■■GCreatorCanvasEngine.java
//Ver.3.3

//■■インポート
import java.awt.*;  //必須
import java.awt.geom.*;  //必須
import java.awt.image.*;  //必須
import java.util.List;  //必須（曖昧回避）
import java.util.*;  //必須
import javax.swing.*;  //必須
import java.io.*;  //必須
import javax.imageio.*;  //必須
import javax.imageio.stream.*;  //必須

//■■■描画機能の実現
class GCreatorCanvasEngine extends JLabel
{
  //GCreatorCanvasEngineが、JLabelを継承するのは、
  //JLabelがカラーのベクター方式の文字画像を描くことができ、
  //JLabel自体が、文字に限らず多様なベクター画像処理能力があるからである。
  //さらに、ラスター画像も表示できるからである。
  //ただし、JLabelよりも上位のJComponentに変更しても、正常に作動する。

  //■■変数宣言
  //■メンバー変数
  GCreator f; //JFlameの継承インスタンス
  Graphics2D g2;

  //●命令文関連の変数
  double imagePX_W = 0;  //指定画像サイズ幅（ピクセル単位）
  double imagePX_H = 0;  //指定画像サイズ丈（ピクセル単位）
  double printMM_W = 0;  //指定画像サイズ幅（ミリ単位）
  double printMM_H = 0;  //指定画像サイズ丈（ミリ単位）

  double affineScale = 1.0; //表示倍率
  double freeScale   = 1.0; //追加倍率

  int  shiftMode  = 0; //シフト区分（画像のシフト）
  double shiftX   = 0; //シフト量X
  double shiftY   = 0; //シフト量Y

  double affineDegree       = 0.0;   //90度回転角度
  double affineDegreeFree   = 0.0;   //指定角度回転角度

  boolean rotateFlag        = false; //90度回転モード
  boolean rotateFreeFlag    = false; //指定角度回転モード
  int rotateFreeW           = 0;     //回転に伴って必要なx軸原点移動
  int rotateFreeH           = 0;     //回転に伴って必要なy軸原点移動

  //RoteteMulti命令（画像多段階回転重複描画）
  boolean rotateMultiFlag        = false;
  int rotateMultiStartDegree     = 0;    //回転開始角度（ディグリー）
  int rotateMultiDegree          = 0;    //回転角度（ディグリー）
  int rotateMultiTimes           = 0;    //回転回数
  String rotateMultiF            = null; //回転対象画像のファイル名（パス付き）
  BufferedImage rotateMultiImage = null; //完成画像の格納領域

  boolean markFlag          = true; //描画起点や曲線制御点などの目印線
  boolean commandInspection = false; //命令の記述エラー検査
  boolean canSaveMode       = false; //画像保存モード

  long randomSeed = //模様作成乱数初期値
    1378453L + new GregorianCalendar().get(Calendar.SECOND);
  Random ran = new Random(randomSeed);
  long randomSeed2 =  //間欠描画に用いる乱数初期値
    234567L + new GregorianCalendar().get(Calendar.SECOND);
  Random ran2St = null;
  Random ran2Ex = null;

  //SaveCommands命令
  String saveCmdFName = ""; //命令文書の保存ファイル名（パス付き）
  //SaveImage命令
  String saveImgFName = ""; //作成画像の保存ファイル名（パス付き）

  //CutAndSave命令
  int cutAndSaveImgX1 = 0; //作成画像の切り出し領域の左上ｘ座標
  int cutAndSaveImgY1 = 0; //作成画像の切り出し領域の左上ｙ座標
  int cutAndSaveImgX2 = 0; //作成画像の切り出し領域の右下ｘ座標
  int cutAndSaveImgY2 = 0; //作成画像の切り出し領域の右下ｙ座標
  String cutAndSaveImgFName = ""; //作成画像の切り出し保存ファイル名称（パス付き）

  //ChangeColor命令（単独色相変更）
  String colorChangeFile  = ""; //色変換処理対象画像のファイル名
  boolean colorChangeFlag = false; //色変換要求の有無
  int acceptableLimitC = 0;    //微妙な色の変動許容量
  int colorChangeMode  = 0;    //色相変更モード
  int colorChange1R    = 0;    //色変換の旧色
  int colorChange1G    = 0;
  int colorChange1B    = 0;
  int colorChange2R    = 0;    //色変換の新色
  int colorChange2G    = 0;
  int colorChange2B    = 0;
  BufferedImage colorChangeImage0 = null;
  BufferedImage colorChangeImage1 = null;

  //ReverseImage命令
  boolean reverseImageFlag    = false; //画像反転要求の有無
  String reverseImageFile     = "";    //画像反転の加工前対象画像ファイル名
  int reverseImageMode        = 0;     //反転方式の指定
  BufferedImage reverseImage0 = null;  //加工前画像
  BufferedImage reverseImage1 = null;  //加工後画像
  BufferedImage reverseImageX = null;  //90度または270度回転加工後画像

  //ColorGradient命令
  String gradientFName = ""; //線形階調加工の対象ファイル名
  int gradientY1 = 0;        //加工開始y軸位置
  int gradientY2 = 0;        //加工終了y軸位置
  double gradientR = 0.0;
  double gradientG = 0.0;
  double gradientB = 0.0;
  BufferedImage gradientImage0 = null;
  BufferedImage gradientImage1 = null;

  //MixImage命令
  String mixFName0        = ""; //二重像画像処理の対象ファイル名
  String mixFName1        = ""; //二重像画像処理の対象ファイル名
  int mixMode             = 1;  //通常のモード
  BufferedImage mixImage0 = null;
  BufferedImage mixImage1 = null;
  BufferedImage mixImage2 = null;

  //AdjustRGB命令
  String adjustFName = ""; //色調調整の対象ファイル名
  int adjustR = 0;
  int adjustG = 0;
  int adjustB = 0;
  BufferedImage adjustImage0 = null;
  BufferedImage adjustImage1 = null;

  //SoftFocus命令
  String softFocusFName = "";  //ソフト・フォーカス効果の対象画像ファイル名
  int softFocusDegree   = 1;   //ソフト・フォーカス効果の度合い（０～１０）
  BufferedImage softFocusImage0 = null;
  BufferedImage softFocusImage1 = null;

  //マスク関連の用語定義
  //「マスク」は、「Stamp」や「CutAndPaste」や「ChangeColorMalti」などで用いる領域区分画像。
  //「Stamp」では、シングル・マスク（グレー・マスク）を用いる。
  //グレー・マスクは、透過部分をグレー色とし、それ以外の部分を表示したい図柄とする。
  //「CutAndPaste」や「ChangeColorMalti」では、マルチ・マスク（カラー・マスク）を用いる。
  //マルチ・マスクは、多色で色分けされた領域区分図であり、表示したい図柄が含まれない。
  //マルチ・マスクを作成する前段階の輪郭線図形も、「アウトライン・マスク」と呼ぶことがある。

  //CutAndPaste命令
  boolean             cutAndPasteMaskFlag = false;
  boolean             cutAndPasteFlag     = false;
  String              capMaskF  = "";   //CutAndPaste用マルチ・マスク画像のファイル名
  BufferedImage       capImageM = null; //マルチ・マスク画像
  BufferedImage       capImage0 = null; //旧画像（切り貼り処理前画像）
  BufferedImage       capImage1 = null; //新画像（切り貼り処理完了画像）
  List<String>        capListF  = null; //前景画像（切り貼り元模様画像）リスト
  List<int[]>         capListI  = null; //指定色数値データリスト

  //ChangeColorMulti命令
  boolean             changeColorMultiBaseFlag = false;
  boolean             changeColorMultiFlag     = false;
  String              ccmMaskF  = "";   //ChangeColorMalti用　元画像のファイル名
  BufferedImage       ccmImage0 = null; //旧画像（連続色相変更処理前画像）
  BufferedImage       ccmImage1 = null; //新画像（連続色相変更処理完了画像）
  List<int[]>         ccmListI0 = null; //旧色指定リスト
  List<int[]>         ccmListI1 = null; //新色指定リスト

  //ChangeColorInner命令（図形内部単独彩色）
  //輪郭線で囲まれた閉じた図形領域を指定色で彩色。
  //彩色対象画像は、輪郭線で囲まれた図形内部に、
  //プログラムがスキャンしながら彩色位置を探し出し彩色し、輪郭線まで領域拡大を行なう。
  //輪郭線が予想外の理由により途切れることがあれば、正しく機能しない。
  boolean             changeColorInnerFlag = false;
  String              changeColorInnerF = ""; //彩色対象ファイル名（パス含む）
  int                 cciOutLineColorR = 0;   //輪郭線色
  int                 cciOutLineColorG = 0;
  int                 cciOutLineColorB = 0;
  int                 cciInnerColorR   = 0;   //彩色指定
  int                 cciInnerColorG   = 0;
  int                 cciInnerColorB   = 0;
  int                 cciInnerX        = 0;   //彩色領域の代表位置X
  int                 cciInnerY        = 0;   //彩色領域の代表位置Y
  int                 cciMode          = 0;   //輪郭線を内部彩色と同一にするかの可否
  BufferedImage       cciImage         = null;//彩色対象画像のイメージ・バッファ

  //ChangeColorInnerMulti命令（図形内部連続彩色）
  //輪郭線で囲まれた閉じた複数の図形領域を指定色で連続的に彩色。
  //彩色対象画像は、輪郭線で囲まれた図形（白地図形式）の内部各所に、
  //プログラムがスキャンしながら彩色位置を探し出し彩色し、輪郭線まで彩色領域拡大を行なう。
  //ただし、輪郭線が予想外の理由により途切れることがあれば、正しく機能しない。
  //また、複雑に屈曲した輪郭線が入り交じる図形を内部連続彩色するとなると、相当な時間を要する。
  //これを便宜的手法によって高速化するとなると、点描画機能を用いるなどして、
  //図形内部の何箇所か（箇所数は多い方が高速）を部分的に指定色で予め彩色しておくと良い。
  //点描画方式ではなく、指定色の斜め線やスプライン曲線での部分彩色ができれば、もっと高速になる。
  //ただし、個別色彩指定可能な直線または曲線の描線コマンドを新たに作らねばならない。
  //そのため、現状のコマンド体系のままでは、点描画機能を活用することになる。
  boolean             changeColorInnerMultiFlag = false;
  String              changeColorInnerMultiF = ""; //彩色対象ファイル名（パス含む）
  int                 ccimOutLineColorR = 0;   //輪郭線色
  int                 ccimOutLineColorG = 0;
  int                 ccimOutLineColorB = 0;
  BufferedImage       ccimImage         = null;//彩色対象画像のイメージ・バッファ
  List<int[]>         ccimListI;               //数値データ（R,G,B,X,Y）のリスト

  //Stamp命令
  boolean             stampFlag = false;
  List<String>        stampListF; //Stamp画像のファイル名リスト
  List<int[]>         stampListI; //Stampの数値データ（位置、サイズ）リスト
  List<BufferedImage> stampListB; //Stamp画像のリスト
  //（注）StampMulti命令は、途中で複数のStamp命令に変換されている。
  Color transparentColor = new Color(200,200,200);  //グレー・マスク作成用の色
  //（注）一部透明化対象画像（スタンプ元画像）の透過部分は、この色で作成する。

  //Image命令
  boolean             imageFlag = false;
  List<String>        imageListF; //背景画像のファイル名リスト
  List<int[]>         imageListI; //背景画像の数値データ（位置、サイズ）リスト
  List<BufferedImage> imageListB; //背景画像リスト

  //Antialias命令
  boolean antialiasFlag = false; //線（輪郭線含む）のギザギザ緩和
  float lineWidth;       //線幅（統一）

  //各種の線描画
  double[][] lineArr;    //直線
  double[][] line2Arr;   //仮直線
  double[][] curveArr;   //ベジェ曲線
  double[][] splineArr;  //スプライン曲線（命令文の単純羅列）
  double[][] splineArrX;  //スプライン曲線X座標（曲線毎に分解）
  double[][] splineArrY;  //スプライン曲線Y座標（曲線毎に分解）
  int splineOption = 1000;  //スプライン曲線精細度

  //ParallelLine…命令
  double parallelLineH_x = 0; //横平行線の始点ｘ
  double parallelLineH_y = 0; //横平行線の始点ｙ
  double parallelLineH_l = 0; //線の長さ
  double parallelLineH_w = 0; //線の幅
  int parallelLineH_t    = 0; //線の本数
  int parallelLineH_m    = 0; //線の種類
  int parallelLineH_h    = 0; //中間線の有無

  double parallelLineV_x = 0; //縦平行線
  double parallelLineV_y = 0;
  double parallelLineV_l = 0;
  double parallelLineV_w = 0;
  int parallelLineV_t    = 0;
  int parallelLineV_m    = 0;
  int parallelLineV_h    = 0;

  double parallelLineH2_x = 0; //横平行線の始点ｘ（補助用）
  double parallelLineH2_y = 0; //横平行線の始点ｙ
  double parallelLineH2_l = 0; //線の長さ
  double parallelLineH2_w = 0; //線の幅
  int parallelLineH2_t    = 0; //線の本数
  int parallelLineH2_m    = 0; //線の種類
  int parallelLineH2_h    = 0; //中間線の有無

  double parallelLineV2_x = 0; //縦平行線（補助用）
  double parallelLineV2_y = 0;
  double parallelLineV2_l = 0;
  double parallelLineV2_w = 0;
  int parallelLineV2_t    = 0;
  int parallelLineV2_m    = 0;
  int parallelLineV2_h    = 0;

  GeneralPath gp;          //自由図形の描画に必要
  double[][] shapeArr;     //自由図形のコマンド全行分のデータ

  double[][] stringHArrD;  //水平文字列（並字）表示でのdouble型データ
  String[][] stringHArrS;  //水平文字列（並字）表示でのString型データ
  double[][] stringBArrD;  //水平文字列（極太字）表示でのdouble型データ
  String[][] stringBArrS;  //水平文字列（極太字）表示でのString型データ
  double[][] stringVArrD;  //垂直文字列（並字）表示でのdouble型データ
  String[][] stringVArrS;  //垂直文字列（並字）表示でのString型データ

  boolean fontBold = false; //太字指定（並字）

  Color backgroundColor;  //背景色
  Color foregroundColorL; //前景色（線色）
  Color foregroundColorS; //前景色（文字色）
  Color foregroundColorB; //前景色（極太文字色）

  int stripePatternType = 0; //描画無視／横縞／縦縞
  int stripePatternW    = 0;  //ストライプ幅
  int stripePRedBase    = 0; //赤基調色
  int stripePGreenBase  = 0; //緑基調色
  int stripePBlueBase   = 0; //青基調色

  //matrixPatternでの用語定義
  //ユニット unit：柄紋一個をユニットと称する。
  //セル cell（コマ／小間）：柄紋一個が６ｘ６の構成なら、その構成単位１個。
  //ピクセル pixel ：セルは複数（例えば８ｘ８）のピクセルで構成される。
  //シフト shift：柄紋を縦横に反復された文様全体の起点を移動させるコマ数。
  //ドロップ drop：柄紋配列の行または列の奇数偶数で、起点位置をずらすコマ数。
  //スキップ skip：柄紋と柄紋との間隔を調整するプラスまたはマイナスのコマ数。
  //リピート repeat：柄紋の反復回数
  //インターミッティング intermitting：１で常時描画、２～１０で間欠描画。

  int matrixPatternNumSt   = 0; //柄紋番号（４桁）
  int matrixPatternWH_St   = 1; //柄紋の幅丈（幅丈兼用コマ数）最低数１
  double matrixShiftH_St   = 0; //横起点シフトのコマ数
  double matrixShiftV_St   = 0; //縦起点シフトのコマ数
  double matrixDropH_St    = 0; //柄紋横ドロップのコマ数
  double matrixDropV_St    = 0; //柄紋縦ドロップのコマ数
  double matrixSkipH_St    = 0; //柄紋横スキップのコマ数
  double matrixSkipV_St    = 0; //柄紋縦スキップのコマ数
  int matrixRepeatH_StX    = 0; //柄紋横リピートの回数
  int matrixRepeatV_StX    = 0; //柄紋縦リピートの回数
  int matrixPRedBaseSt     = 0; //赤基調色
  int matrixPGreenBaseSt   = 0; //緑基調色
  int matrixPBlueBaseSt    = 0; //青基調色
  int matrixColorLimitSt   = 10; //色成分の上限制限（1～10の値）
  int matrixRepeatH_St     = 100; //リピート横（数値は有効なダミー）
  int matrixRepeatV_St     = 100; //リピート縦（数値は有効なダミー）
  int matrixUnitSt         = 6; //コマ数（数値は有効なダミー）
  int matrixIntermittingSt = 10; //間欠描画指定。1～9が間欠描画、10が通常描画
  short[][] rgbSt;            //ランダム配色（統一配色）

  int matrixPatternNumEx   = 0; //柄紋番号（４桁）
  int matrixPatternWH_Ex   = 1; //柄紋の幅丈（幅丈兼用コマ数）最低数１
  double matrixShiftH_Ex   = 0; //横起点シフトのコマ数
  double matrixShiftV_Ex   = 0; //縦起点シフトのコマ数
  double matrixDropH_Ex    = 0; //柄紋横ドロップのコマ数
  double matrixDropV_Ex    = 0; //柄紋縦ドロップのコマ数
  double matrixSkipH_Ex    = 0; //柄紋横スキップのコマ数
  double matrixSkipV_Ex    = 0; //柄紋縦スキップのコマ数
  int matrixRepeatH_ExX    = 0; //柄紋横リピートの指定値の回数
  int matrixRepeatV_ExX    = 0; //柄紋縦リピートの指定値の回数
  int matrixPRedBaseEx     = 0; //赤基調色
  int matrixPGreenBaseEx   = 0; //緑基調色
  int matrixPBlueBaseEx    = 0; //青基調色
  int matrixColorLimitEx   = 10; //色成分の上限制限（1～10の値）
  int matrixRepeatH_Ex     = 100; //リピート横計算値（数値は有効なダミー）
  int matrixRepeatV_Ex     = 100; //リピート縦計算値（数値は有効なダミー）
  int matrixUnitEx         = 6; //コマ数（数値は有効なダミー）
  int matrixIntermittingEx = 10; //間欠描画指定。1～9が間欠描画、10が通常描画
  short[][][][][][] rgbEx;    //ランダム配色（個別配色）

  String[] manualArr;
  String[] patternArr;
  final int pages = 1;    //印刷で用いる形式的な総ページ数
  float quality   = 1.0f; //高画質保存（jpeg）
    //jpegでの画質は、０から１を指定できる（１が最高画質）
  double currentPointX;   //最新クリック位置（マウス入力モード時）
  double currentPointY;   //最新クリック位置（マウス入力モード時）

  List<double[]> lineList   ;   //直線
  List<double[]> line2List  ;   //一時補助線
  List<double[]> curveList  ;   //ベジェ曲線
  List<double[]> splineList ;   //スプライン曲線
  List<double[]> ellipseList  ; //真円、楕円
  List<double[]> rectList   ;   //四角形
  List<double[]> shapeList  ;   //自由図形
  List<double[]> stringHListD ; //水平文字関連でのdouble型データ
  List<String[]> stringHListS ; //水平文字関連でのString型データ
  List<double[]> stringBListD ; //極太文字関連でのdouble型データ
  List<String[]> stringBListS ; //極太文字関連でのString型データ
  List<double[]> stringVListD ; //垂直文字関連でのdouble型データ
  List<String[]> stringVListS ; //垂直文字関連でのString型データ

  //■コンストラクタ
  GCreatorCanvasEngine(GCreator flame)
  {
    f = flame;
    affineScale = 1.0; //拡大率初期設定
    freeScale   = 1.0; //拡大率初期設定
    f.scaleLabel.setText("  (a:x1.0)");  //表示拡大率設定
    f.scaleLabel2.setText("  (f:x1.0)"); //表示拡大率設定
    manualArr  = TextIO.loadStrArr(new File("./sys/GCreator_Manual.txt"));
    patternArr = TextIO.loadStrArr(new File("./sys/GCreator_Pattern.txt"));
    rgbSt = getRandom_rgbSt(); //ランダム色の要求（事前準備）
    rgbEx = getRandom_rgbEx(); //ランダム色の要求（事前準備）
    imageListB = new LinkedList<BufferedImage>();
    stampListB = new LinkedList<BufferedImage>();
  }

  //■■変数初期化
  void setInit()
  { //●内部プログラムから呼び出される
    g2.setPaint(new Color(255,255,255)); //残留画像の消去
    g2.fill(new Rectangle2D.Double(
      0,0,f.canvas.getPreferredSize().width,
      f.canvas.getPreferredSize().height));

    //●変数の初期化
    antialiasFlag = false;
    imagePX_W     = 720; //描画範囲初期設定
    imagePX_H     = 1008; //描画範囲初期設定
    printMM_W     = imagePX_W/3.0; //mmとpxとの換算比率（便宜的独自規格）
    printMM_H     = imagePX_H/3.0; //mmとpxとの換算比率（便宜的独自規格）
    freeScale     = 1.0; //印刷に反映される拡大倍率
    shiftMode     = 0;
    shiftX        = 0;
    shiftY        = 0;
    lineWidth     = 0.5f; //デフォルトの線幅
    f.matrixStUnitLabel.setText("");
    f.matrixExUnitLabel.setText("");

    affineDegree     = 0.0; //90度回転角度
    affineDegreeFree = 0.0; //指定角度回転角度
    rotateFlag       = false;//90度回転モード
    rotateFreeFlag   = false;//指定角度回転モード
    rotateFreeW      = 0; //回転に伴って必要なx軸原点移動
    rotateFreeH      = 0; //回転に伴って必要なy軸原点移動

    rotateMultiFlag        = false;
    rotateMultiF           = null;
    rotateMultiStartDegree = 0;
    rotateMultiDegree      = 0;
    rotateMultiTimes       = 0;

    parallelLineH_x = 0; //横平行線
    parallelLineH_y = 0;
    parallelLineH_l = 0;
    parallelLineH_w = 0;
    parallelLineH_t = 0;
    parallelLineH_m = 0;
    parallelLineH_h = 0;
    parallelLineV_x = 0; //縦平行線
    parallelLineV_y = 0;
    parallelLineV_l = 0;
    parallelLineV_w = 0;
    parallelLineV_t = 0;
    parallelLineV_m = 0;
    parallelLineV_h = 0;

    parallelLineH2_x = 0; //横平行線（補助用）
    parallelLineH2_y = 0;
    parallelLineH2_l = 0;
    parallelLineH2_w = 0;
    parallelLineH2_t = 0;
    parallelLineH2_m = 0;
    parallelLineH2_h = 0;
    parallelLineV2_x = 0; //縦平行線
    parallelLineV2_y = 0;
    parallelLineV2_l = 0;
    parallelLineV2_w = 0;
    parallelLineV2_t = 0;
    parallelLineV2_m = 0;
    parallelLineV2_h = 0;

    splineArr  = null;   //スプライン曲線（命令文の単純羅列）
    splineArrX = null;   //スプライン曲線X座標（曲線毎に分解）
    splineArrY = null;   //スプライン曲線Y座標（曲線毎に分解）
    splineOption = 1000; //スプライン曲線の精細度のデフォルト

    commandInspection = true;
    backgroundColor   = Color.white; //背景色
    foregroundColorL  = Color.black; //線色
    foregroundColorS  = Color.black; //文字色
    foregroundColorB  = Color.red;   //極太字色（ダミー）

    fontBold = false;

    colorChangeImage0 = null;
//    colorChangeImage1 = null;//加工後の画像　画像を保持

    saveCmdFName = "";  //命令文書の保存ファイル名称（パス付き）
    saveImgFName = "";  //作成画像の保存ファイル名称（パス付き）

    changeColorInnerFlag = false;
    changeColorInnerF = ""; //図形内部彩色対象ファイル名（パス含む）
    cciOutLineColorR = 0;   //輪郭線色デフォルト黒色
    cciOutLineColorG = 0;
    cciOutLineColorB = 0;
    cciInnerColorR   = 255; //彩色デフォルト赤色
    cciInnerColorG   = 0;
    cciInnerColorB   = 0;
    cciInnerX        = 0;
    cciInnerY        = 0;
    cciMode          = 0;   //輪郭線を内部色と同一にするかの可否
    //cciImage         = null;//彩色対象画像のイメージ・バッファ　画像を保持

    changeColorInnerMultiFlag = false;
    changeColorInnerMultiF = ""; //彩色対象ファイル名（パス含む）
    ccimOutLineColorR = 0;   //輪郭線色
    ccimOutLineColorG = 0;
    ccimOutLineColorB = 0;
    ccimListI         = new ArrayList<int[]>(); //数値データ（R,G,B,X,Y）のリスト
    //ccimImage         = null; //彩色対象画像（輪郭線画像）のイメージ・バッファ

    cutAndSaveImgFName = ""; //作成画像の切り出し保存ファイル名称（パス付き）
    cutAndSaveImgX1    = 0; //作成画像の切り出し領域の左上ｘ座標
    cutAndSaveImgY1    = 0; //作成画像の切り出し領域の左上ｙ座標
    cutAndSaveImgX2    = 0; //作成画像の切り出し領域の右下ｘ座標
    cutAndSaveImgY2    = 0; //作成画像の切り出し領域の右下ｙ座標

    reverseImageFile    = "";    //画像反転の対象画像ファイル名（加工前）
    reverseImageFlag    = false; //画像反転要求の有無
    reverseImageMode    = 0;     //反転方式の指定
    reverseImage0       = null;  //加工前画像
//    reverseImage1       = null;  //加工後画像（初期化しない）　画像を保持
//    reverseImageX       = null;  //90度、270度、回転加工後画像（初期化しない）　画像を保持

    mixFName0 = ""; //二重像画像処理のファイル名（パス付き）
    mixFName1 = ""; //二重像画像処理のファイル名（パス付き）
    mixMode   = 1; //通常のモード
    mixImage0 = null;
    mixImage1 = null;
//    mixImage2 = null; //加工後の画像　　repaint()のために画像を保持

    softFocusFName = ""; //ソフト・フォーカスのファイル名（パス付き）
    adjustFName    = "";    //色相調整のファイル名（パス付き）
    gradientFName  = "";  //階調加工処理のファイル名（パス付き）

    colorChangeFile  = "";    //単独色相変換処理のファイル名（パス付き）
    colorChangeFlag  = false; //単独色相変更要求の有無
    acceptableLimitC = 0;     //単独色相変動許容値
    colorChangeMode  = 0;     //単独色相変更モード
    colorChange1R    = 0;     //単独色相変更の旧色
    colorChange1G    = 0;
    colorChange1B    = 0;
    colorChange2R    = 0;     //単独色相変更の新色
    colorChange2G    = 0;
    colorChange2B    = 0;

    stripePatternType = 0;

    matrixPatternNumSt   = 0; //描画しない（空白）
    matrixRepeatH_St     = 100; //有効な初期値
    matrixRepeatV_St     = 100; //有効な初期値
    matrixShiftH_St      = 0; //全体横シフト
    matrixShiftV_St      = 0; //全体縦シフト
    matrixDropH_St       = 0; //図柄横ドロップ
    matrixDropV_St       = 0; //図柄縦ドロップ
    matrixSkipH_St       = 0; //図柄横スキップ
    matrixSkipV_St       = 0; //図柄縦スキップ
    matrixRepeatH_St     = 0; //図柄横リピート
    matrixRepeatV_St     = 0; //図柄縦リピート
    matrixIntermittingSt = 10; //間欠描画
    matrixColorLimitSt   = 10; //色成分の上限制限（1～10の値）
//      matrixUnitSt       = 6; 初期化不可

    matrixPatternNumEx   = 0; //描画しない（空白）
    matrixRepeatH_Ex     = 100; //有効な初期値
    matrixRepeatV_Ex     = 100; //有効な初期値
    matrixShiftH_Ex      = 0; //全体横シフト
    matrixShiftV_Ex      = 0; //全体縦シフト
    matrixDropH_Ex       = 0; //図柄横ドロップ
    matrixDropV_Ex       = 0; //図柄縦ドロップ
    matrixSkipH_Ex       = 0; //図柄横スキップ
    matrixSkipV_Ex       = 0; //図柄縦スキップ
    matrixRepeatH_Ex     = 0; //図柄横リピート
    matrixRepeatV_Ex     = 0; //図柄縦リピート
    matrixIntermittingEx = 10; //間欠描画
    matrixColorLimitEx   = 10; //色成分の上限制限（1～10の値）
//    matrixUnitEx         = 6; 初期化不可

    lineList   = new ArrayList<double[]>(); //直線
    line2List  = new ArrayList<double[]>(); //一時補助線
    curveList  = new ArrayList<double[]>(); //ベジェ曲線
    splineList  = new ArrayList<double[]>(); //スプライン曲線
    ellipseList  = new ArrayList<double[]>(); //真円、楕円
    rectList   = new ArrayList<double[]>(); //四角形
    shapeList  = new ArrayList<double[]>(); //自由図形
    stringHListD = new ArrayList<double[]>(); //水平文字
    stringHListS = new ArrayList<String[]>(); //
    stringBListD = new ArrayList<double[]>(); //極太文字
    stringBListS = new ArrayList<String[]>(); //
    stringVListD = new ArrayList<double[]>(); //垂直文字
    stringVListS = new ArrayList<String[]>(); //

//    imageFlag    = false; //setinit2() で初期化する
//    imageListI   = new LinkedList<int[]>(); //背景画像
//    imageListF   = new LinkedList<String>();
//    imageListB   = new LinkedList<BufferedImage>();

//    stampFlag  = false; 初期化不可 //setinit2() で初期化する
//    stampListI = new LinkedList<int[]>();
//    stampListF = new LinkedList<String>();
//    stampListB = new LinkedList<BufferedImage>();

//    cutAndPasteMaskFlag = false;
//    cutAndPasteFlag     = false;
//    capMaskF = "";     //切り貼り用マルチ・マスクのファイル名（パス付き）
//    capImageM = null;  //マルチ・マスクの画像
//    capImage0 = null;  //切り貼り元模様画像
//    capImage1 = null;  //加工後の画像　画像を保持
//    capListF  = new LinkedList<String>(); //切り貼り元画像
//    capListI  = new LinkedList<int[]>();  //色相指定リスト

//    changeColorMultiBaseFlag = false;
//    changeColorMultiFlag     = false;
//    ccmMaskF  = "";   //ChangeColorMalti用　元画像のファイル名
//    ccmImage0 = null; //旧画像（連続色相変更処理前画像）
//    ccmImage1 = null; //新画像（連続色相変更処理完了画像）　画像を保持
//    ccmListI0 = new LinkedList<int[]>(); //旧色指定リスト
//    ccmListI1 = new LinkedList<int[]>(); //新色指定リスト

    //------------------------------------------------------------

    //●命令文の全文を解析し、命令文で指定された内容を変数に格納
    String commandZ = f.cArea.getText();
    f.analyze.commandAnalyze(commandZ); //解析

    //------------------------------------------------------------

    //●直線 数値の取得
    Object[] lineArr0 = lineList.toArray();
    lineArr  = new double[lineArr0.length][4];
    for(int i=0; i<lineArr0.length; i++)
    {
      lineArr[i][0] = ((double[])(lineArr0[i]))[0];
      lineArr[i][1] = ((double[])(lineArr0[i]))[1];
      lineArr[i][2] = ((double[])(lineArr0[i]))[2];
      lineArr[i][3] = ((double[])(lineArr0[i]))[3];
    }
    //●仮直線Draw2 数値の取得
    Object[] line2Arr0 = line2List.toArray();
    line2Arr  = new double[line2Arr0.length][5];
    for(int i=0; i<line2Arr0.length; i++)
    {
      line2Arr[i][0] = ((double[])(line2Arr0[i]))[0];
      line2Arr[i][1] = ((double[])(line2Arr0[i]))[1];
      line2Arr[i][2] = ((double[])(line2Arr0[i]))[2];
      line2Arr[i][3] = ((double[])(line2Arr0[i]))[3];
      line2Arr[i][4] = ((double[])(line2Arr0[i]))[4];
    }
    //●ベジェ曲線 数値の取得
    Object[] curveArr0 = curveList.toArray();
    curveArr  = new double[curveArr0.length][8];
    for(int i=0; i<curveArr0.length; i++)
    {
      curveArr[i][0] = ((double[])(curveArr0[i]))[0];
      curveArr[i][1] = ((double[])(curveArr0[i]))[1];
      curveArr[i][2] = ((double[])(curveArr0[i]))[2];
      curveArr[i][3] = ((double[])(curveArr0[i]))[3];
      curveArr[i][4] = ((double[])(curveArr0[i]))[4];
      curveArr[i][5] = ((double[])(curveArr0[i]))[5];
      curveArr[i][6] = ((double[])(curveArr0[i]))[6];
      curveArr[i][7] = ((double[])(curveArr0[i]))[7];
    }

    //●スプライン曲線 数値の取得
    Object[] splineArr0 = splineList.toArray();
    splineArr  = new double[splineArr0.length][3];
    for(int i=0; i<splineArr0.length; i++)
    {
      splineArr[i][0] = ((double[])(splineArr0[i]))[0];
      splineArr[i][1] = ((double[])(splineArr0[i]))[1];
      splineArr[i][2] = ((double[])(splineArr0[i]))[2];
    }
    int arrCnt0 = 0; //スプライン曲線の本数をカウント
    for(int i=0; i<splineArr.length; i++)
    {
      if(splineArr[i][0]==0) //スプライン曲線の起点
        arrCnt0++;
    }
    if(arrCnt0>0) //スプライン曲線があれば
    {
      splineArrX = new double[arrCnt0][]; //スプライン曲線毎に分解
      splineArrY = new double[arrCnt0][]; //スプライン曲線毎に分解
    }

    int arrCnt1 = 0; //スプライン曲線の制御点を個別にカウント
    arrCnt0 = 0; //スプライン曲線の本数カウントを初期化
    int scale = 1;
    int k=0; //複数あるスプライン曲線の特定番号
    for(int i=0; i<splineArr.length; i++)
    {
      if(splineArr[i][0]==0) //或るスプライン曲線の起点
      {
        ;
      }
      else if(splineArr[i][0]==1) //或るスプライン曲線の制御点
      {
        arrCnt1++; //制御点のカウント
      }
      else if(splineArr[i][0]==2) //或るスプライン曲線の終点
      {
        //スプライン曲線における制御点の個数は、一個以上で、個数に上限なし。
        splineArrX[k] = new double[arrCnt1+2]; //起点＋制御点数個＋終点
        splineArrY[k] = new double[arrCnt1+2];
        for(int j=0; j<arrCnt1+2; j++)
        { //座標データをコピー
          splineArrX[k][j] = splineArr[i-(arrCnt1+1)+j][1];
          splineArrY[k][j] = splineArr[i-(arrCnt1+1)+j][2];
        }
        k++; //次のスプライン曲線へ移行
        arrCnt1 = 0; //制御点カウント
        arrCnt0++; //スプライン曲線の本数カウント
      }
    }

    //●色塗り自由図形 数値の取得
    Object[] shapeArr0 = shapeList.toArray();
    shapeArr  = new double[shapeArr0.length][9];
    for(int i=0; i<shapeArr0.length; i++)
    {
      shapeArr[i][0] = (((double[])(shapeArr0[i]))[0]);
      shapeArr[i][1] = (((double[])(shapeArr0[i]))[1]);
      shapeArr[i][2] = (((double[])(shapeArr0[i]))[2]);
      shapeArr[i][3] = (((double[])(shapeArr0[i]))[3]);
      shapeArr[i][4] = (((double[])(shapeArr0[i]))[4]);
      shapeArr[i][5] = (((double[])(shapeArr0[i]))[5]);
      shapeArr[i][6] = (((double[])(shapeArr0[i]))[6]);
      shapeArr[i][7] = (((double[])(shapeArr0[i]))[7]);
      shapeArr[i][8] = (((double[])(shapeArr0[i]))[8]);
    }

    //●文字列（並字）　データの取得
    Object[] stringHArrD0 = stringHListD.toArray();
    Object[] stringHArrS0 = stringHListS.toArray();
    stringHArrD = new double[stringHArrD0.length][3];
    stringHArrS = new String[stringHArrS0.length][2];
    for(int i=0; i<stringHArrD0.length; i++)
    {
      stringHArrD[i][0] = ((double[])(stringHArrD0[i]))[0];
      stringHArrD[i][1] = ((double[])(stringHArrD0[i]))[1];
      stringHArrD[i][2] = ((double[])(stringHArrD0[i]))[2];
    }
    for(int i=0; i<stringHArrD0.length; i++)
    {
      stringHArrS[i][0] = ((String[])(stringHArrS0[i]))[0];
      stringHArrS[i][1] = ((String[])(stringHArrS0[i]))[1];
    }

    //●文字列（極太字）　データの取得
    Object[] stringBArrD0 = stringBListD.toArray();
    Object[] stringBArrS0 = stringBListS.toArray();
    stringBArrD = new double[stringBArrD0.length][3];
    stringBArrS = new String[stringBArrS0.length][2];
    for(int i=0; i<stringBArrD0.length; i++)
    {
      stringBArrD[i][0] = ((double[])(stringBArrD0[i]))[0];
      stringBArrD[i][1] = ((double[])(stringBArrD0[i]))[1];
      stringBArrD[i][2] = ((double[])(stringBArrD0[i]))[2];
    }
    for(int i=0; i<stringBArrD0.length; i++)
    {
      stringBArrS[i][0] = ((String[])(stringBArrS0[i]))[0];
      stringBArrS[i][1] = ((String[])(stringBArrS0[i]))[1];
    }

    //●垂直文字列（疑似縦書き）　データの取得
    Object[] stringVArrD0 = stringVListD.toArray();
    Object[] stringVArrS0 = stringVListS.toArray();
    stringVArrD = new double[stringVArrD0.length][3];
    stringVArrS = new String[stringVArrS0.length][2];
    for(int i=0; i<stringVArrD0.length; i++)
    {
      stringVArrD[i][0] = ((double[])(stringVArrD0[i]))[0];
      stringVArrD[i][1] = ((double[])(stringVArrD0[i]))[1];
      stringVArrD[i][2] = ((double[])(stringVArrD0[i]))[2];
    }
    for(int i=0; i<stringVArrD0.length; i++)
    {
      stringVArrS[i][0] = ((String[])(stringVArrS0[i]))[0];
      stringVArrS[i][1] = ((String[])(stringVArrS0[i]))[1];
    }
  } //setInit()

  void setInit2()
  { //●内部プログラムから呼び出される特殊な初期化
    //メニュー・イベント発生またはボタン・イベント発生でのみ初期化される
    imageFlag   = false;
    imageListI  = new LinkedList<int[]>(); //背景画像
    imageListF  = new LinkedList<String>();
    imageListB  = new LinkedList<BufferedImage>();

    stampFlag  = false;
    stampListI = new LinkedList<int[]>();
    stampListF = new LinkedList<String>();
    stampListB = new LinkedList<BufferedImage>();

    cutAndPasteMaskFlag = false;
    cutAndPasteFlag     = false;
    capMaskF = "";     //切り貼り用マルチ・マスクのファイル名（パス付き）
    capImageM = null;  //マルチ・マスクの画像
    capImage0 = null;  //切り貼り元模様画像
    capImage1 = null;  //加工後の画像　画像を保持
    capListF  = new LinkedList<String>(); //切り貼り元画像
    capListI  = new LinkedList<int[]>();  //色相指定リスト

    changeColorMultiBaseFlag = false;
    changeColorMultiFlag     = false;
    ccmMaskF  = "";   //ChangeColorMalti用　元画像のファイル名
    ccmImage0 = null; //旧画像（連続色相変更処理前画像）
    ccmImage1 = null; //新画像（連続色相変更処理完了画像）　画像を保持
    ccmListI0 = new LinkedList<int[]>(); //旧色指定リスト
    ccmListI1 = new LinkedList<int[]>(); //新色指定リスト
  } //setInit2()

  void setInit3()
  { //●内部プログラムから呼び出される特殊な初期化の追加補足
    //メニュー・イベント発生またはボタン・イベント発生でのみ初期化される
      if(imageFlag==true)
        image(); //背景画像表示の下準備
      if(stampFlag==true)
        f.canvas.stamp(); //スタンプ押印の下準備
      if(cutAndPasteMaskFlag==true && cutAndPasteFlag==true)
        cutAndPaste(); //切り貼り処理の下準備
      if(changeColorMultiBaseFlag==true && changeColorMultiFlag==true)
        changeColorMulti(); //連続色相変更処理の下準備

      softFocus(); //ソフト・フォーカス処理の下準備
      changeColorInner(); //図形内部単独彩色
      changeColorInnerMulti(); //図形内部連続彩色
      mixImage(); //二重画像処理の下準備
      reverseImage(); //画像反転処理の下準備
      rotateMulti(); //画像多段回転処理の下準備
      adjustRGB(); //色調全域調整の下準備
      colorChange(f.canvas.colorChangeMode); //色相部分領域変更処理の下準備
      colorGradient(); //色相グラデーション加工の下準備
  } //setInit3()

  //■■描画処理
  public void paintComponent(Graphics g)
  {
    drawPage(g, false);
  }

  //■１ページ分の描画（現状では、１ページ分のみ）
  //drawPage()は、印刷時にも呼び出される。
  //このプログラムでは、改ページの概念を設定していないが、
  //改ページできる形にプログラムを改造することも可能。
  void drawPage(Graphics g, boolean printMode)
  {
    //●描画の初期対応
    g2 = (Graphics2D)g;

    setInit();  //変数初期化
    g2.scale(affineScale*freeScale, affineScale*freeScale); //拡大
    g2.setPaint(new Color(255,255,255)); //残留画像の消去
    g2.fill(new Rectangle2D.Double(
      0,0,f.canvas.getPreferredSize().width,
      f.canvas.getPreferredSize().height));
    g2.setColor(backgroundColor);  //画像サイズ指定領域の画像消去
    g2.fill(new Rectangle2D.Double(0,0,imagePX_W,imagePX_H));

    if(commandInspection == false)
    {  //命令記述に誤りがあれば
      return;
    }

    if(rotateFlag) //画像全体を90度回転させる
    {
      g2.translate(imagePX_H, 0); //移動
      affineDegree = 90; //90度回転指定
      g2.rotate(affineDegree*Math.PI/180.0);
      //座標原点を中心に回転（指定順注意）
    }
    if(rotateFreeFlag) //画像全体を指定角度回転させる
    {
      g2.translate(rotateFreeW, rotateFreeH); //指定数値で移動
      affineDegree = affineDegreeFree; //指定角度回転指定
      g2.rotate(affineDegreeFree*Math.PI/180.0);
      //座標原点を中心に回転（指定順注意）
    }

    if(antialiasFlag == true) //線のギザギザ緩和
      //細い線の色が、周囲との中間色化で、非常に薄くなる
      g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
        RenderingHints.VALUE_ANTIALIAS_ON);
    else
      g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
        RenderingHints.VALUE_ANTIALIAS_OFF);

    //●シフト処理の計算
    double sX = shiftX;
    double sY = shiftY;
    if(shiftMode==1)
    {  //シフトあり
      ;
    }
    else
    {  //シフトなし
      shiftX = sX = 0;
      shiftY = sY = 0;
    }

    //●線の描画準備
    BasicStroke solidLine = new BasicStroke( //太さ可変の実線の定義
      lineWidth, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_MITER);
    BasicStroke dashLineX = new BasicStroke( //太さ固定の点線の定義
      2.0f, BasicStroke.CAP_SQUARE,
      BasicStroke.JOIN_MITER, 5f, new float[] {4f,6f,10f,6f,4f,6f}, 0f);
    BasicStroke solidLineX = new BasicStroke( //太さ固定の細実線の定義
      0.5f, BasicStroke.CAP_SQUARE,
      BasicStroke.JOIN_MITER);
    BasicStroke solidLineX2 = new BasicStroke( //太さ固定の細実線の定義
      1.0f, BasicStroke.CAP_SQUARE,
      BasicStroke.JOIN_MITER);
    BasicStroke dotLine = new BasicStroke( //太さ固定で密の点線の定義
      0.5f, BasicStroke.CAP_SQUARE,
      BasicStroke.JOIN_MITER, 5f, new float[] {4f,4f}, 0f);
    BasicStroke dotLine2 = new BasicStroke( //太さ固定で粗の点線の定義
      0.5f, BasicStroke.CAP_SQUARE,
      BasicStroke.JOIN_MITER, 5f, new float[] {4f,12f}, 0f);
    g2.setStroke(solidLine); //太さ可変の実線に設定
    g2.setColor(foregroundColorL);

    //------------------------------------------------------------

    //●●以下は、各種の「描画処理」
    //一般描画処理とは、線描画、面描画、点描画、ストライブ模様描画、マトリックス模様描画。
    //特殊描画処理とは、背景画像描画、スタンプ描画、各種画像変形処理。
    //全種類の描画処理（一般描画処理＋特殊描画処理）の順序は、全面描画が先で部分描画が後の順序。
    //また、面描画、線描画、文字描画の順序で並べる。
    //具体的には、以下に始まる描画順序である。
    //この順序に不都合があれば、途中で画像保存し、その画像をImage命令で再表示して作業を継続する。
    //複雑な構成の画像は、部品画像を別途多数作成し保存し、最終的にそれらを寄せ合わせて仕上げる。

    //●Image 背景画像（特殊描画処理の一種）の描画。
    if(f.canvas.imageFlag==true && imageListB!=null && imageListI!=null)
    {
      for(int i=0; i<imageListB.size(); i++)
      {
        //画像サイズ計算
        int w = imageListB.get(i).getWidth(this);
        int h = imageListB.get(i).getHeight(this);
        int imageX = 0;
        int imageY = 0;
        int imageW = 0;
        int imageH = 0;
        boolean err = false;
        try
        {
          imageX = imageListI.get(i)[0];
          imageY = imageListI.get(i)[1];
          imageW = imageListI.get(i)[2];
          imageH = imageListI.get(i)[3];
        }
        catch (Exception e)
        {
          f.message(e.toString());
          err = true;
        }
        if(imageListB.get(i) != null && err == false)
        { //描画する
          g2.drawImage(imageListB.get(i), imageX, imageY, imageW, imageH, this);
        }
      }
    }

    //------------------------------------------------------------

    //以下は、各種メソッドで指定された画像をキャンバスに表示する。

    //●ランダム・ストライプ描画
    if(stripePatternType >= 1)
    {
      //  int stripePatternType; //無効／水平／垂直、0/1/2
      //  int stripePatternW //ストライプ幅
      //  int stripePRedBase  //赤基調色
      //  int stripePGreenBase //緑基調色
      //  int stripePBlueBase //青基調色
      int sizeW = (int)imagePX_W; //描画サイズ幅
      int sizeH = (int)imagePX_H; //描画サイズ幅
      int repeat; //ストライプ本数
      if(stripePatternType == 1) //水平
        repeat = (sizeH/stripePatternW)+1;
      else  //垂直
        repeat = (sizeW/stripePatternW)+1;
      if(stripePRedBase > 240)  stripePRedBase = 240;
      if(stripePGreenBase > 240)  stripePGreenBase = 240;
      if(stripePBlueBase > 240)  stripePBlueBase = 240;
      int r1,g1,b1;
      for(int i=0;i<repeat;i++)
      {
        r1 = stripePRedBase + ran.nextInt(255-stripePRedBase);
        g1 = stripePGreenBase + ran.nextInt(255-stripePGreenBase);
        b1 = stripePBlueBase + ran.nextInt(255-stripePBlueBase);
        g2.setColor(new Color(r1,g1,b1));
        if(stripePatternType==1) //水平
          g2.fillRect(0, i*stripePatternW , sizeW, stripePatternW);
        else if(stripePatternType==2)  //垂直
          g2.fillRect(i*stripePatternW ,0, stripePatternW, sizeH);
      }
      stripePatternType =0;
    }

    //●マトリックス・パターン描画
    if(matrixPatternNumSt >= 1 || matrixPatternNumEx >= 1)
    {
      int sizeW = (int)imagePX_W; //有効描画範囲幅
      int sizeH = (int)imagePX_H; //有効描画範囲丈
      int cSt = matrixPatternWH_St;  //１コマのピクセル数（横）
      int cEx = matrixPatternWH_Ex;  //１コマのピクセル数（横）
      matrixRepeatH_St = sizeW/(int)(cSt*matrixUnitSt+matrixSkipH_St)+2;  //横リピート回数
      matrixRepeatV_St = sizeH/(int)(cSt*matrixUnitSt+matrixSkipV_St)+2;  //縦リピート回数
      matrixRepeatH_Ex = sizeW/(int)(cEx*matrixUnitEx+matrixSkipH_Ex)+2;  //横リピート回数
      matrixRepeatV_Ex = sizeH/(int)(cEx*matrixUnitEx+matrixSkipV_Ex)+2;  //縦リピート回数
      int x1 = 0;  //Ｘ軸座標位置
      int y1 = 0;  //Ｙ軸座標位置
      int matrixPatternSt[][] = getPatternData(matrixPatternNumSt, "St");
      int matrixPatternEx[][] = getPatternData(matrixPatternNumEx, "Ex");
      if(matrixPatternNumSt>0)
        f.matrixStUnitLabel.setText("　　St:" + matrixUnitSt +"x"+ matrixUnitSt);
      else
        f.matrixStUnitLabel.setText("");
      if(matrixPatternNumEx>0)
        f.matrixExUnitLabel.setText("　　Ex:" + matrixUnitEx +"x"+ matrixUnitEx);
      else
        f.matrixExUnitLabel.setText("");

      //配色描画実施
      //標準メソッドStの使用（統一配色）
      try
      {
        if(matrixPatternNumSt>0)
        {
          //色指定は、１番色から９番色まで使用可能。
          boolean colorFlagSt = true; //描画の有無
          double matrixSkipH_StX = 0; //柄紋横スキップ累積の初期値
          double matrixSkipV_StY = 0; //柄紋縦スキップ累積の初期値
          double dropX =0; //偶数行で柄ずらし（ドロップ）の初期値
          double dropY =0; //偶数列で柄ずらし（ドロップ）の初期値
          int K2 =0;
          ran2St = new Random(randomSeed2);
          int randomSt = 0;

          //リピート計算およびリピート指定
          if(matrixSkipH_St < 0) //マイナス・スキップ対応のリピート追加
            matrixRepeatH_St = (int)((sizeW/(cSt*matrixUnitSt+matrixSkipH_St))*2.5);
            //ただし、大きな数値のマイナス・スキップには対応できない。
            //マイナス・スキップが大きい場合、リピート指定を行なう
          if(matrixSkipV_St < 0) //マイナス・スキップ対応のリピート追加
            matrixRepeatV_St = (int)((sizeH/(cSt*matrixUnitSt+matrixSkipV_St))*2.5);
            //ただし、大きな数値のマイナス・スキップには対応できない。
            //マイナス・スキップが大きい場合、リピート指定を行なう
          if(matrixRepeatH_StX >= 1) //リピート指定あれば、それに従う
            matrixRepeatH_St = matrixRepeatH_StX;
          if(matrixRepeatV_StX >= 1) //リピート指定あれば、それに従う
            matrixRepeatV_St = matrixRepeatV_StX;

          for( int i=0; i<matrixRepeatH_St; i++) //横リピート
          {
            matrixSkipH_StX = matrixSkipH_StX + matrixSkipH_St; //横スキップの累積
            for(int j=0; j<matrixRepeatV_St; j++) //縦リピート
            {
              if(j==0 && i==0) //縦スキップの準備
                matrixSkipV_StY = matrixSkipV_St;
              else if(j==0)
                matrixSkipV_StY = 0;
              if(K2==matrixUnitSt-1)
                matrixSkipV_StY = matrixSkipV_StY + matrixSkipV_St; //縦スキップの累積
              randomSt = ran2St.nextInt(10);
              for(int K=0; K<matrixUnitSt; K++) //横コマ数で反復
              {
                K2 = K;
                for(int L=0; L<matrixUnitSt; L++) //縦コマ数で反復
                {
                  if     (matrixPatternSt[K][L] == 1)
                    g2.setColor(new Color(rgbSt[0][0],rgbSt[0][1],rgbSt[0][2]));
                  else if(matrixPatternSt[K][L] == 2)
                    g2.setColor(new Color(rgbSt[1][0],rgbSt[1][1],rgbSt[1][2]));
                  else if(matrixPatternSt[K][L] == 3)
                    g2.setColor(new Color(rgbSt[2][0],rgbSt[2][1],rgbSt[2][2]));
                  else if(matrixPatternSt[K][L] == 4)
                    g2.setColor(new Color(rgbSt[3][0],rgbSt[3][1],rgbSt[3][2]));
                  else if(matrixPatternSt[K][L] == 5)
                    g2.setColor(new Color(rgbSt[4][0],rgbSt[4][1],rgbSt[4][2]));
                  else if(matrixPatternSt[K][L] == 6)
                    g2.setColor(new Color(rgbSt[5][0],rgbSt[5][1],rgbSt[5][2]));
                  else if(matrixPatternSt[K][L] == 7)
                    g2.setColor(new Color(rgbSt[6][0],rgbSt[6][1],rgbSt[6][2]));
                  else if(matrixPatternSt[K][L] == 8)
                    g2.setColor(new Color(rgbSt[7][0],rgbSt[7][1],rgbSt[7][2]));
                  else if(matrixPatternSt[K][L] == 9)
                    g2.setColor(new Color(rgbSt[8][0],rgbSt[8][1],rgbSt[8][2]));
                  else if(matrixPatternSt[K][L] == 0) //配色なし（描画せず）
                    colorFlagSt = false;
                  else
                    g2.setColor(Color.black);  //警告色
                  x1 = (int)(matrixShiftH_St*cSt);
                  y1 = (int)(matrixShiftV_St*cSt);
                  if(j%2 == 1) //柄紋の横ドロップ処理
                    dropX = matrixDropH_St;
                  else
                    dropX = 0;
                  if(i%2 == 1) //柄紋の縦ドロップ処理
                    dropY = (int)matrixDropV_St;
                  else
                    dropY  = 0;
                  if((colorFlagSt == true) &&
                    (randomSt < matrixIntermittingSt)) //間欠描画
                    g2.fillRect(x1+i*matrixUnitSt*cSt+L*cSt+
                      (int)(matrixSkipH_StX*cSt)+(int)(dropX*cSt),
                      y1+j*matrixUnitSt*cSt+K*cSt+
                      (int)(matrixSkipV_StY*cSt)+(int)(dropY*cSt),
                      cSt, cSt); //x, y, 幅, 高
                  else //色番号が０の場合、描画しない
                    colorFlagSt = true;
                }
              }
            }
          }
        }
      }
      catch(ArrayIndexOutOfBoundsException e)
      {
        if(matrixPatternNumSt>0)
          rgbSt = getRandom_rgbSt();
        repaint(); //表示エラー回復の試み。
      }

      //拡張メソッドExの使用（個別配色）
      try
      {
        if(matrixPatternNumEx>0)
        {
          //色指定は、１番色から９番色まで使用可能。
          boolean colorFlagEx = true; //描画の有無
          double matrixSkipH_ExX = 0; //柄紋横スキップ累積の初期値
          double matrixSkipV_ExY = 0; //柄紋縦スキップ累積の初期値
          double dropX =0; //偶数行で柄ずらし（ドロップ）の初期値
          double dropY =0; //偶数列で柄ずらし（ドロップ）の初期値
          int K2 =0;
          ran2Ex = new Random(randomSeed2+567);
          int randomEx = 0;

          //リピート計算およびリピート指定
          if(matrixSkipH_Ex < 0) //マイナス・スキップ対応のリピート追加
            matrixRepeatH_Ex = (int)((sizeW/(cEx*matrixUnitEx+matrixSkipH_Ex))*2.5);
            //ただし、異常な数値のスキップは想定していないので、リピート指定を行なう
          if(matrixSkipV_Ex < 0) //マイナス・スキップ対応のリピート追加
            matrixRepeatV_Ex = (int)((sizeH/(cEx*matrixUnitEx+matrixSkipH_Ex))*2.5);
            //ただし、異常な数値のスキップは想定していないので、リピート指定を行なう
          if(matrixRepeatH_ExX >= 1) //リピート指定あれば、それに従う
            matrixRepeatH_Ex = matrixRepeatH_ExX;
          if(matrixRepeatV_ExX >= 1) //リピート指定あれば、それに従う
            matrixRepeatV_Ex = matrixRepeatV_ExX;
          //特殊なマトリックス指定をする場合、プログラムでのリピート計算では対処不能と
          //なることもあるため、その場合、マトリックス命令文の中でリピート指定を行なう。
          //通常の使用なら、リピート数値指定は、０指定（リピート自動計算）で構わない。

          for( int i=0; i<matrixRepeatH_Ex; i++) //横リピート
          {
            matrixSkipH_ExX = matrixSkipH_ExX + matrixSkipH_Ex; //横スキップの累積
            for(int j=0; j<matrixRepeatV_Ex; j++) //縦リピート
            {
              if(j==0 && i==0) //縦スキップの準備
                matrixSkipV_ExY = matrixSkipV_Ex;
              else if(j==0)
                matrixSkipV_ExY = 0;
              if(K2==matrixUnitEx-1)
                matrixSkipV_ExY = matrixSkipV_ExY + matrixSkipV_Ex; //縦スキップの累積
              randomEx = ran2Ex.nextInt(10);
              for(int K=0; K<matrixUnitEx; K++) //横コマ数で反復
              {
              	K2 = K;
                for(int L=0; L<matrixUnitEx; L++) //縦コマ数で反復
                {
                  if     (matrixPatternEx[K][L] == 1) //色を設定
                    g2.setColor(new Color(rgbEx[i][j][K][L][0][0],
                      rgbEx[i][j][K][L][0][1],rgbEx[i][j][K][L][0][2]));
                  else if(matrixPatternEx[K][L] == 2)
                    g2.setColor(new Color(rgbEx[i][j][K][L][1][0],
                      rgbEx[i][j][K][L][1][1],rgbEx[i][j][K][L][1][2]));
                  else if(matrixPatternEx[K][L] == 3)
                    g2.setColor(new Color(rgbEx[i][j][K][L][2][0],
                      rgbEx[i][j][K][L][2][1],rgbEx[i][j][K][L][2][2]));
                  else if(matrixPatternEx[K][L] == 4)
                    g2.setColor(new Color(rgbEx[i][j][K][L][3][0],
                      rgbEx[i][j][K][L][3][1],rgbEx[i][j][K][L][3][2]));
                  else if(matrixPatternEx[K][L] == 5)
                    g2.setColor(new Color(rgbEx[i][j][K][L][4][0],
                      rgbEx[i][j][K][L][4][1],rgbEx[i][j][K][L][4][2]));
                  else if(matrixPatternEx[K][L] == 6)
                    g2.setColor(new Color(rgbEx[i][j][K][L][5][0],
                      rgbEx[i][j][K][L][5][1],rgbEx[i][j][K][L][5][2]));
                  else if(matrixPatternEx[K][L] == 7)
                    g2.setColor(new Color(rgbEx[i][j][K][L][6][0],
                      rgbEx[i][j][K][L][6][1],rgbEx[i][j][K][L][6][2]));
                  else if(matrixPatternEx[K][L] == 8)
                    g2.setColor(new Color(rgbEx[i][j][K][L][7][0],
                      rgbEx[i][j][K][L][7][1],rgbEx[i][j][K][L][7][2]));
                  else if(matrixPatternEx[K][L] == 9)
                    g2.setColor(new Color(rgbEx[i][j][K][L][8][0],
                      rgbEx[i][j][K][L][8][1],rgbEx[i][j][K][L][8][2]));
                  else if(matrixPatternEx[K][L] == 0) //配色なし（描画せず）
                    colorFlagEx = false;
                  else
                    g2.setColor(Color.black);  //警告色

                  x1 = (int)(matrixShiftH_Ex*cEx);
                  y1 = (int)(matrixShiftV_Ex*cEx);
                  if(j%2 == 1) //柄紋の横ドロップ処理
                    dropX = matrixDropH_Ex;
                  else
                    dropX = 0;
                  if(i%2 == 1) //柄紋の縦ドロップ処理
                    dropY = (int)matrixDropV_Ex;
                  else
                    dropY  = 0;

                  if((colorFlagEx == true) &&
                    (randomEx < matrixIntermittingEx)) //間欠描画
                    g2.fillRect(x1+i*matrixUnitEx*cEx+L*cEx+
                      (int)(matrixSkipH_ExX*cEx)+(int)(dropX*cEx),
                      y1+j*matrixUnitEx*cEx+K*cEx+
                      (int)(matrixSkipV_ExY*cEx)+(int)(dropY*cEx),
                      cEx, cEx); //x, y, 幅, 高
                  else //色番号が０の場合、描画しない
                    colorFlagEx = true;
                }
              }
            }
          }
        }
      }
      catch(ArrayIndexOutOfBoundsException e)
      {
        if(matrixPatternNumEx>0)
          rgbEx = getRandom_rgbEx();
        repaint(); //表示エラー回復の試み。
      }
    }

    //●●色塗り図形描画命令「実行」グループの始まり

    //●自由図形の色塗り描画（色塗りを先、輪郭線は後）
    int comCnt = 0; //命令カウンター
    int mS = 0; //自由図形描画モード（線描きか色塗りかのモード）
    Color shapeColor = Color.yellow; //不透明色（ダミー）
    Color shapeColorT = Color.yellow; //透明色（ダミー）
    for(; comCnt<shapeArr.length;)
    {
      if(shapeArr[comCnt][0] == 0)
      { //▼DrawShapeStart()　（起点での処理）
        gp = new GeneralPath();
        mS = (int)shapeArr[comCnt][1]; //線描きか色塗りかのモード
        gp.moveTo(shapeArr[comCnt][2]+sX,shapeArr[comCnt][3]+sY);
        shapeColor = new Color((int)shapeArr[comCnt][4],
          (int)shapeArr[comCnt][5],(int)shapeArr[comCnt][6]);
        shapeColorT = new Color((int)shapeArr[comCnt][4],
          (int)shapeArr[comCnt][5],(int)shapeArr[comCnt][6],191);
          //「191」は、透明度で「(256/4)*3-1」の計算
        if(markFlag == true) //▼起点目印十字線の描画
        {
          drawStartMark(shapeArr[comCnt][2], shapeArr[comCnt][3]);
          g2.draw(new Ellipse2D.Double(
            shapeArr[comCnt][2]+sX-4, shapeArr[comCnt][3]+sY-4, 8, 8));
            //x座標, y座標, 幅, 高さ
        }
        comCnt++;
      }
      else if(shapeArr[comCnt][0] == -1)
      { //▼DrawShapeLine()　（中間での直線処理）
        gp.lineTo(shapeArr[comCnt][1]+sX,shapeArr[comCnt][2]+sY);
        if(markFlag == true)
        {
          g2.draw(new Ellipse2D.Double(
            shapeArr[comCnt][1]+sX-4, shapeArr[comCnt][2]+sY-4, 8, 8));
        }
        comCnt++;
      }
      else if(shapeArr[comCnt][0] == -2)
      { //▼DrawShapeCurve()　（中間での曲線処理）
        gp.curveTo(
          shapeArr[comCnt][1]+sX,shapeArr[comCnt][2]+sY,
          shapeArr[comCnt][3]+sX,shapeArr[comCnt][4]+sY,
          shapeArr[comCnt][5]+sX,shapeArr[comCnt][6]+sY);
        //曲線部補助線描画
        if(markFlag == true)
        {
          g2.setColor(new Color(200,0,0));
          g2.setStroke(solidLineX);
          g2.draw(new Line2D.Double(
            shapeArr[comCnt][1]+sX,shapeArr[comCnt][2]+sY,
            shapeArr[comCnt][3]+sX,shapeArr[comCnt][4]+sY));
          g2.draw(new Ellipse2D.Double(
            shapeArr[comCnt][1]+sX-4, shapeArr[comCnt][2]+sY-4, 8, 8));
          g2.draw(new Ellipse2D.Double(
            shapeArr[comCnt][3]+sX-4, shapeArr[comCnt][4]+sY-4, 8, 8));

          g2.setColor(new Color(200,0,0));
          g2.draw(new Line2D.Double(
            shapeArr[comCnt][3]+sX,shapeArr[comCnt][4]+sY,
            shapeArr[comCnt][5]+sX,shapeArr[comCnt][6]+sY));
          g2.draw(new Ellipse2D.Double(
            shapeArr[comCnt][5]+sX-4, shapeArr[comCnt][6]+sY-4, 8, 8));

          g2.setColor(new Color(200,0,0));
          if(shapeArr[comCnt-1][0] == 0)
          //DrawShapeCurveの直前がDrawShapeStartの場合
            g2.draw(new Line2D.Double(
              shapeArr[comCnt-1][2]+sX,shapeArr[comCnt-1][3]+sY,
              shapeArr[comCnt][1]+sX,shapeArr[comCnt][2]+sY));
          else if(shapeArr[comCnt-1][0] == -1)
          //DrawShapeCurveの直前がDrawShapeLineの場合
            g2.draw(new Line2D.Double(
              shapeArr[comCnt-1][1]+sX,shapeArr[comCnt-1][2]+sY,
              shapeArr[comCnt][1]+sX,shapeArr[comCnt][2]+sY));
          else if(shapeArr[comCnt-1][0] == -2)
          //DrawShapeCurveの直前がDrawShapeCurveの場合
            g2.draw(new Line2D.Double(
              shapeArr[comCnt-1][5]+sX,shapeArr[comCnt-1][6]+sY,
              shapeArr[comCnt][1]+sX,shapeArr[comCnt][2]+sY));
          else
            ; //命令文の記述ミス以外には有り得ないケース
          g2.setStroke(solidLine);
        }
        comCnt++;
      }
      else if(shapeArr[comCnt][0] == -3)
      { //▼DrawShapeEnd()　（終点での処理）
        gp.closePath();
        if(mS==2 || mS==3) //描画モード
        {
          g2.setColor(shapeColor);
          g2.fill(gp); //色塗り
        }
        if(mS==4 || mS == 5) //描画モード（透明色）
        {
          g2.setColor(shapeColorT);
          g2.fill(gp); //透明色塗り
        }
        if(mS==1 || mS==3 || mS==4)
        {
          g2.setColor(foregroundColorL);
          g2.draw(gp); //線描き（輪郭線）
        }
        comCnt++;
      }

    //●四角形の描画
      else if(shapeArr[comCnt][0] == -4)
      { //▼DrawRect()
        int mR   = (int)shapeArr[comCnt][1]; // 線描きか色塗りか
        double xR  = shapeArr[comCnt][2]; // x座標
        double yR  = shapeArr[comCnt][3]; // y座標
        double hrR = shapeArr[comCnt][4]; // 幅
        double vrR = shapeArr[comCnt][5]; // 高さ
        int crR  = (int)shapeArr[comCnt][6]; //color
        int cgR  = (int)shapeArr[comCnt][7]; //color
        int cbR  = (int)shapeArr[comCnt][8]; //color
        if(mR==2 || mR==3) //色塗り描画（不透明色）
        {
          g2.setColor(new Color(crR, cgR, cbR));
          g2.fill(new Rectangle2D.Double(xR,yR,hrR,vrR));
        }
        if(mR==4 || mR == 5) //色塗り描画（透明色）
        {
          g2.setColor(new Color(crR, cgR, cbR,191));
          g2.fill(new Rectangle2D.Double(xR,yR,hrR,vrR));
        }
        if(mR==1 || mR==3 || mR==4) //輪郭線描画
        {
          g2.setColor(foregroundColorL);
          g2.draw(new Rectangle2D.Double(xR,yR,hrR,vrR));
        }
        if(markFlag == true) //▼起点目印十字線の描画
          drawStartMark(xR, yR);
        comCnt++;
      }

    //●円（楕円）の描画
      else if(shapeArr[comCnt][0] == -5)
      { //DrawEllipse()
        double mE  = shapeArr[comCnt][1]; // 線描か色塗りか
        double xE  = shapeArr[comCnt][2]; // x座標
        double yE  = shapeArr[comCnt][3]; // y座標
        double hrE = shapeArr[comCnt][4]; // 幅
        double vrE = shapeArr[comCnt][5]; // 高さ
        int crE  = (int)shapeArr[comCnt][6]; //color
        int cgE  = (int)shapeArr[comCnt][7]; //color
        int cbE  = (int)shapeArr[comCnt][8]; //color
        xE = xE-hrE;
        yE = yE-vrE;
        if(mE == 2 || mE == 3)
        {//▼円または楕円の色塗り
          g2.setColor(new Color(crE, cgE, cbE));
          g2.fill(new Ellipse2D.Double(
          xE+sX, yE+sY, hrE*2.0, vrE*2.0));
            //x座標, y座標, 幅, 高さ
        }
        if(mE == 4 || mE == 5)
        {//▼円または楕円の色塗り（透明色）
          g2.setColor(new Color(crE, cgE, cbE,191));
          g2.fill(new Ellipse2D.Double(
          xE+sX, yE+sY, hrE*2.0, vrE*2.0));
            //x座標, y座標, 幅, 高さ
        }
        if(mE == 1 || mE == 3 || mE==4)
        {//▼円または楕円の輪郭線
          g2.setColor(foregroundColorL);
          g2.draw(new Ellipse2D.Double(
          xE+sX, yE+sY, hrE*2.0, vrE*2.0));
          //x座標, y座標, 幅, 高さ
        }
        if(markFlag == true) //▼起点目印十字線の描画
          drawStartMark(xE+hrE, yE+vrE);
        comCnt++;
      }
    }

    //●●色塗り図形描画命令「実行」グループの終わり

    //●●特殊画像処理命令「実行」グループの始まり
    //●●各種「特殊描画命令」の実行位置は、この位置であることに意味あり。
    //●●Image命令（背景画像描画）の描画実行だけは、先行して実行済み

    //●ソフト・フォーカス処理済み画像の表示
    if(softFocusFName!=null && !softFocusFName.equals(""))
    {
      g2.drawImage(softFocusImage1, 0, 0, (int)imagePX_W, (int)imagePX_H, this);
    }
    //●ミックス・イメージ（二重像）処理済み画像の表示
    if(mixImage2!=null && !mixFName0.equals(""))
    { //描画する
      g2.drawImage(mixImage2, 0, 0, (int)imagePX_W, (int)imagePX_H, this);
    }
    //●図形内部彩色処理済み画像の表示
    if(changeColorInnerFlag==true && cciImage != null)
    { //描画する
      g2.drawImage(cciImage, 0, 0, (int)imagePX_W, (int)imagePX_H, this);
    }
    //●図形内部連続彩色処理済み画像の表示
    if(changeColorInnerMultiFlag==true && ccimImage != null)
    { //描画する
      g2.drawImage(ccimImage, 0, 0, (int)imagePX_W, (int)imagePX_H, this);
    }
    //●画像反転処理済み画像の表示
    if(reverseImage1!=null && !reverseImageFile.equals("") &&
      (reverseImageMode<=4 || reverseImageMode==6))
    { //描画する
      g2.drawImage(reverseImage1, 0, 0, (int)imagePX_W, (int)imagePX_H, this);
    }
    if(reverseImage1!=null && !reverseImageFile.equals("") &&
      (reverseImageMode==5 || reverseImageMode==7))
    { //90度、270度の回転処理画像を描画する（回転処理済みの画像保存を含む）
      g2.drawImage(reverseImage1, 0, 0, (int)imagePX_H, (int)imagePX_W, this);
    }
    //●画像多段回転処理済み画像の表示
    if(rotateMultiImage!=null && rotateMultiFlag==true)
    { //描画する
      g2.drawImage(rotateMultiImage, 0, 0, (int)imagePX_W, (int)imagePX_H, this);
    }
    //●単独色相変更処理済み画像の表示
    if(colorChangeImage1!=null && !colorChangeFile.equals("") &&
      (colorChangeMode==1 ||colorChangeMode==2))
    { //描画する
      g2.drawImage(colorChangeImage1, 0, 0, (int)imagePX_W, (int)imagePX_H, this);
    }
    //●アジャストＲＧＢ処理済み画像の表示
    if(adjustFName!=null && !adjustFName.equals(""))
    {
      g2.drawImage(adjustImage1, 0, 0, (int)imagePX_W, (int)imagePX_H, this);
    }
    //●階調加工済み画像の表示
    if(gradientImage1!=null && !gradientFName.equals(""))
    {
      g2.drawImage(gradientImage1, 0, 0, (int)imagePX_W, (int)imagePX_H, this);
    }
    //●連続色相変更処理済み画像の表示
    if(changeColorMultiBaseFlag==true && changeColorMultiFlag==true)
    {
      g2.drawImage(ccmImage1, 0, 0, (int)imagePX_W, (int)imagePX_H, this);
    }
    //●カット・アンド・ペースト処理済み画像の表示
    if(f.canvas.cutAndPasteMaskFlag==true && f.canvas.cutAndPasteFlag==true)
    {
      g2.drawImage(capImage1, 0, 0, (int)imagePX_W, (int)imagePX_H, this);
    }
    //●スタンプ画像（透明化処理済み）の上書き描画。
    if(stampFlag==true && stampListB!=null && stampListI!=null)
    {
      for(int i=0; i<stampListB.size(); i++)
      {
        BufferedImage transparentImage = stampListB.get(i);
        //画像サイズ計算
        int w = stampListB.get(i).getWidth(this);
        int h = stampListB.get(i).getHeight(this);
        int stampX = 0;
        int stampY = 0;
        int stampW = 0;
        int stampH = 0;
        boolean err = false;
        try
        {
          stampX = stampListI.get(i)[0];
          stampY = stampListI.get(i)[1];
          stampW = stampListI.get(i)[2];
          stampH = stampListI.get(i)[3];
        }
        catch (Exception e)
        {
          f.message(e.toString());
          err = true;
        }
        if(transparentImage != null && err == false)
        { //描画する
          g2.drawImage(transparentImage, stampX, stampY, stampW, stampH, this);
        }
      }
    }

    //●●特殊画像処理命令「実行」グループの終わり

    //●●線および文字画像処理命令「実行」グループの始まり
    //●横平行線の描画（罫線または方眼線の描画に利用）
    if(parallelLineH_t > 0)
    {
      g2.setColor(foregroundColorL);
      if(parallelLineH_m == 0)
      	g2.setStroke(solidLineX); //実線に設定
      else if(parallelLineH_m == 1)
      	g2.setStroke(dotLine); //密の点線に設定
      else
      	g2.setStroke(dotLine2); //粗の点線に設定
      for(int i=0; i<parallelLineH_t; i++)
      { //描画実行（本来線）
        g2.draw(new Line2D.Double(
          parallelLineH_x+sX,
          parallelLineH_y+parallelLineH_w*i+sY,
          parallelLineH_x+parallelLineH_l+sX,
          parallelLineH_y+parallelLineH_w*i+sY));
      }
      for(int i=0; i<parallelLineH_t-1; i++)
      { //描画実行（中間線）
        g2.setStroke(dotLine2); //粗の点線に設定
        if(parallelLineH_h == 1)
        {
        	g2.draw(new Line2D.Double(
          	parallelLineH_x+sX,
          	parallelLineH_y+parallelLineH_w*i+sY + (parallelLineH_w/2),
          	parallelLineH_x+parallelLineH_l+sX,
          	parallelLineH_y+parallelLineH_w*i+sY + (parallelLineH_w/2)));
        }
      }
      g2.setStroke(solidLine); //太さ可変の実線に戻す
    }
    //●縦平行線の描画（罫線または方眼線の描画に利用）
    if(parallelLineV_t > 0)
    {
      g2.setColor(foregroundColorL);
      if(parallelLineV_m == 0)
      	g2.setStroke(solidLineX); //実線に設定
      else if(parallelLineV_m == 1)
      	g2.setStroke(dotLine); //密の点線に設定
      else
      	g2.setStroke(dotLine2); //粗の点線に設定
      for(int i=0; i<parallelLineV_t; i++)
      { //描画実行（本来線）
        g2.draw(new Line2D.Double(
          parallelLineV_x+parallelLineV_w*i+sX,
          parallelLineV_y+sY,
          parallelLineV_x+parallelLineV_w*i+sX,
          parallelLineV_y+parallelLineV_l+sY));
      }
      for(int i=0; i<parallelLineV_t-1; i++)
      { //描画実行（中間線）
        g2.setStroke(dotLine2); //粗の点線に設定
        if(parallelLineV_h == 1)
        {
        	g2.draw(new Line2D.Double(
          	parallelLineV_x+parallelLineV_w*i+sX + (parallelLineV_w/2),
          	parallelLineV_y+sY,
          	parallelLineV_x+parallelLineV_w*i+sX + (parallelLineV_w/2),
          	parallelLineV_y+parallelLineV_l+sY));
        }
      }
      g2.setStroke(solidLine); //太さ可変の実線に戻す
    }

    //●横平行線の描画（補助用）
    if(parallelLineH2_t > 0)
    {
      g2.setColor(foregroundColorL);
      if(parallelLineH2_m == 0)
      	g2.setStroke(solidLineX); //実線に設定
      else if(parallelLineH2_m == 1)
      	g2.setStroke(dotLine); //密の点線に設定
      else
      	g2.setStroke(dotLine2); //粗の点線に設定
      for(int i=0; i<parallelLineH2_t; i++)
      { //描画実行（本来線）
        g2.draw(new Line2D.Double(
          parallelLineH2_x+sX,
          parallelLineH2_y+parallelLineH2_w*i+sY,
          parallelLineH2_x+parallelLineH2_l+sX,
          parallelLineH2_y+parallelLineH2_w*i+sY));
      }
      for(int i=0; i<parallelLineH2_t-1; i++)
      { //描画実行（中間線）
        g2.setStroke(dotLine2); //粗の点線に設定
        if(parallelLineH2_h == 1)
        {
        	g2.draw(new Line2D.Double(
          	parallelLineH2_x+sX,
          	parallelLineH2_y+parallelLineH2_w*i+sY + (parallelLineH2_w/2),
          	parallelLineH2_x+parallelLineH2_l+sX,
          	parallelLineH2_y+parallelLineH2_w*i+sY + (parallelLineH2_w/2)));
        }
      }
      g2.setStroke(solidLine); //太さ可変の実線に戻す
    }
    //●縦平行線の描画（補助用）
    if(parallelLineV2_t > 0)
    {
      g2.setColor(foregroundColorL);
      if(parallelLineV2_m == 0)
      	g2.setStroke(solidLineX); //実線に設定
      else if(parallelLineV2_m == 1)
      	g2.setStroke(dotLine); //密の点線に設定
      else
      	g2.setStroke(dotLine2); //粗の点線に設定
      for(int i=0; i<parallelLineV2_t; i++)
      { //描画実行（本来線）
        g2.draw(new Line2D.Double(
          parallelLineV2_x+parallelLineV2_w*i+sX,
          parallelLineV2_y+sY,
          parallelLineV2_x+parallelLineV2_w*i+sX,
          parallelLineV2_y+parallelLineV2_l+sY));
      }
      for(int i=0; i<parallelLineV2_t-1; i++)
      { //描画実行（中間線）
        g2.setStroke(dotLine2); //粗の点線に設定
        if(parallelLineV2_h == 1)
        {
        	g2.draw(new Line2D.Double(
          	parallelLineV2_x+parallelLineV2_w*i+sX + (parallelLineV2_w/2),
          	parallelLineV2_y+sY,
          	parallelLineV2_x+parallelLineV2_w*i+sX + (parallelLineV2_w/2),
          	parallelLineV2_y+parallelLineV2_l+sY));
        }
      }
      g2.setStroke(solidLine); //太さ可変の実線に戻す
    }

    //●ベジェ曲線 Bezier Curve（ベジェは人名で自動車デザイナー）の描画
    for(int i=0; i<curveArr.length; i++)
    { //DrawCurve()
      g2.setColor(foregroundColorL);
      GeneralPath p = new GeneralPath();
      p.moveTo(curveArr[i][0]+sX,curveArr[i][1]+sY);
      p.curveTo(
        curveArr[i][2]+sX,curveArr[i][3]+sY,
        curveArr[i][4]+sX,curveArr[i][5]+sY,
        curveArr[i][6]+sX,curveArr[i][7]+sY);
      g2.draw(p);
      if(markFlag == true)
      { //▼補助線の描画
        g2.setStroke(solidLineX);
        g2.setColor(new Color(200,0,0));
        g2.draw(new Line2D.Double(
          curveArr[i][0]+sX,curveArr[i][1]+sY,
          curveArr[i][2]+sX,curveArr[i][3]+sY));
        g2.draw(new Ellipse2D.Double(
            curveArr[i][0]+sX-4, curveArr[i][1]+sY-4, 8, 8));

        g2.setColor(new Color(200,0,0));
        g2.draw(new Line2D.Double(
          curveArr[i][2]+sX,curveArr[i][3]+sY,
          curveArr[i][4]+sX,curveArr[i][5]+sY));
        g2.draw(new Ellipse2D.Double(
            curveArr[i][2]+sX-4, curveArr[i][3]+sY-4, 8, 8));
        g2.draw(new Ellipse2D.Double(
            curveArr[i][4]+sX-4, curveArr[i][5]+sY-4, 8, 8));

        g2.setColor(new Color(200,0,0));
        g2.draw(new Line2D.Double(
          curveArr[i][4]+sX,curveArr[i][5]+sY,
          curveArr[i][6]+sX,curveArr[i][7]+sY));
        g2.draw(new Ellipse2D.Double(
            curveArr[i][6]+sX-4, curveArr[i][7]+sY-4, 8, 8));
        g2.setStroke(solidLine);
      }
      if(markFlag == true) //▼起点目印十字線の描画
        drawStartMark(curveArr[i][0], curveArr[i][1]);
    }
    //●スプライン曲線 Spline Curveの描画
    for(int i=0; splineArrX != null && i<splineArrX.length; i++)
    { //
      for(int j=1; splineArrX[i] != null && j<splineArrX[i].length; j++)
      {
        if(markFlag == true)
        { //▼補助線の描画
          g2.setStroke(solidLineX); //太さ固定
          g2.setColor(new Color(200,0,0));
          g2.draw(new Line2D.Double(
            splineArrX[i][j-1]+sX,splineArrY[i][j-1]+sY,
            splineArrX[i][j]+sX,splineArrY[i][j]+sY));
          if(j==1)
            g2.draw(new Ellipse2D.Double(
              splineArrX[i][j-1]+sX-5, splineArrY[i][j-1]+sY-5, 10, 10));
          g2.draw(new Ellipse2D.Double(
              splineArrX[i][j]+sX-3, splineArrY[i][j]+sY-3, 6, 6));
        }

        //（注）スプライン曲線は、短い直線を多数連結した「疑似曲線」として描画。
        //スプライン補間処理したデータの取得
        double[][] interpolateXY =
          new Spline3(splineArrX[i], splineArrY[i], splineOption).getInterpolateXY();
        g2.setColor(foregroundColorL);
        g2.setStroke(solidLine); //太さ可変
        for(int k=1; k<interpolateXY.length; k++)
        { //▼スプライン曲線の描画
          g2.draw(new Line2D.Double(
            interpolateXY[k-1][0]+sX,interpolateXY[k-1][1]+sY,
            interpolateXY[k][0]+sX,interpolateXY[k][1]+sY));
        }
      }
    }

    //●直線の描画
    for(int i=0; i<lineArr.length; i++)
    { //DrawLine()
      g2.setColor(foregroundColorL);
      g2.setStroke(solidLine); //太さ可変
      g2.draw(new Line2D.Double(
        lineArr[i][0]+sX,lineArr[i][1]+sY,
        lineArr[i][2]+sX,lineArr[i][3]+sY));
      if(markFlag == true) //▼起点目印十字線の描画
        drawStartMark(lineArr[i][0], lineArr[i][1]);
    }
    //●仮直線（補助線）の描画
    for(int i=0; i<line2Arr.length; i++)
    { //Draw2()
      if(line2Arr[i][0]==0)
      { //▼直線部補助線（自由図形の直線部）
        g2.setColor(new Color(0,200,0));
        g2.setStroke(solidLineX); //太さ固定
        g2.draw(new Line2D.Double(
          line2Arr[i][1]+sX,line2Arr[i][2]+sY,
          line2Arr[i][3]+sX,line2Arr[i][4]+sY));
         g2.setStroke(solidLine);
      }
      else
      { //▼曲線部補助線（曲線、自由図形の曲線部）
        if(line2Arr[i][0]==1)
          g2.setColor(new Color(200,0,0));
        else if(line2Arr[i][0] == 2)
          g2.setColor(Color.red);
        else if(line2Arr[i][0] == 3)
          g2.setColor(Color.red);
        if(line2Arr[i][0]>=1 && line2Arr[i][0]<=3)
        {
          g2.setStroke(solidLineX);
          g2.draw(new Line2D.Double(
            line2Arr[i][1]+sX,line2Arr[i][2]+sY,
            line2Arr[i][3]+sX,line2Arr[i][4]+sY));
          g2.setStroke(solidLine);
        }
      }
    }

    //●極太水平文字列（字）の描画
    for(int i=0; i<stringBArrD.length; i++)
    { //WriteStringB()
      //字形は二種類あり（"SANS_SERIF" / "SERIF"）
      g2.setColor(foregroundColorB);
      int z = 1;
      int Z = 2;
      Font fontT = new Font(stringBArrS[i][0],Font.PLAIN,
      (int)(stringBArrD[i][2]));
      g2.setFont(fontT);
      g2.drawString(
        stringBArrS[i][1],(float)(stringBArrD[i][0]+sX),
        (float)(stringBArrD[i][1]+sY));

      g2.drawString(
        stringBArrS[i][1],(float)(stringBArrD[i][0]+sX),
        (float)(stringBArrD[i][1]+sY+Z));
      g2.drawString(
        stringBArrS[i][1],(float)(stringBArrD[i][0]+sX),
        (float)(stringBArrD[i][1]+sY-Z));
      g2.drawString(
        stringBArrS[i][1],(float)(stringBArrD[i][0]+sX+Z),
        (float)(stringBArrD[i][1]+sY));
      g2.drawString(
        stringBArrS[i][1],(float)(stringBArrD[i][0]+sX-Z),
        (float)(stringBArrD[i][1]+sY));
      g2.drawString(
        stringBArrS[i][1],(float)(stringBArrD[i][0]+sX+Z),
        (float)(stringBArrD[i][1]+sY+Z));
      g2.drawString(
        stringBArrS[i][1],(float)(stringBArrD[i][0]+sX-Z),
        (float)(stringBArrD[i][1]+sY-Z));
      g2.drawString(
        stringBArrS[i][1],(float)(stringBArrD[i][0]+sX+Z),
        (float)(stringBArrD[i][1]+sY-Z));
      g2.drawString(
        stringBArrS[i][1],(float)(stringBArrD[i][0]+sX-Z),
        (float)(stringBArrD[i][1]+sY+Z));

      g2.drawString(
        stringBArrS[i][1],(float)(stringBArrD[i][0]+sX+z),
        (float)(stringBArrD[i][1]+sY+Z));
      g2.drawString(
        stringBArrS[i][1],(float)(stringBArrD[i][0]+sX-z),
        (float)(stringBArrD[i][1]+sY-Z));
      g2.drawString(
        stringBArrS[i][1],(float)(stringBArrD[i][0]+sX+z),
        (float)(stringBArrD[i][1]+sY-Z));
      g2.drawString(
        stringBArrS[i][1],(float)(stringBArrD[i][0]+sX-z),
        (float)(stringBArrD[i][1]+sY+Z));

      g2.drawString(
        stringBArrS[i][1],(float)(stringBArrD[i][0]+sX+Z),
        (float)(stringBArrD[i][1]+sY+z));
      g2.drawString(
        stringBArrS[i][1],(float)(stringBArrD[i][0]+sX-Z),
        (float)(stringBArrD[i][1]+sY-z));
      g2.drawString(
        stringBArrS[i][1],(float)(stringBArrD[i][0]+sX+Z),
        (float)(stringBArrD[i][1]+sY-z));
      g2.drawString(
        stringBArrS[i][1],(float)(stringBArrD[i][0]+sX-Z),
        (float)(stringBArrD[i][1]+sY+z));

      if(markFlag == true)
      { //▼起点目印十字線の描画
        drawStartMark(stringBArrD[i][0], stringBArrD[i][1]);
      }
    }

    //●水平文字列の描画（極太文字より後に描画）
    for(int i=0; i<stringHArrD.length; i++)
    { //WriteStringH()
      //字形は二種類あり（"SANS_SERIF" / "SERIF"）
      g2.setColor(foregroundColorS);
      Font fontT = new Font(stringHArrS[i][0],Font.PLAIN,
      (int)(stringHArrD[i][2]));
      if(fontBold==true)
      {
        fontT = new Font(stringHArrS[i][0],Font.BOLD,
        (int)(stringHArrD[i][2]));
      }
      g2.setFont(fontT);
      g2.drawString(
        stringHArrS[i][1],(float)(stringHArrD[i][0]+sX),
        (float)(stringHArrD[i][1]+sY));
      if(markFlag == true) //▼起点目印十字線の描画
        drawStartMark(stringHArrD[i][0], stringHArrD[i][1]);
    }

    //●垂直文字列の描画（90度回転式の疑似縦書き）
    //「疑似縦書き」を実行すると、画像全体の精細度が低下するため、
    //この命令（WriteStringV）を使用しないことが望ましい。
    for(int i=0; i<stringVArrD.length; i++)
    {  //WriteStringV()
      //文字列を垂直（90度回転）に描画する
      Dimension dim;  //縦横サイズを保持するインスタンス
      BufferedImage bImg;  //一時的描画空間
      dim = getSize(); //最終描画先のf.canvasのサイズを取得
      bImg = new BufferedImage(dim.width, dim.height,
        BufferedImage.TYPE_INT_ARGB);   //透明可に設定
      Graphics2D g2x = bImg.createGraphics();  //Graphics2Dを返却
      g2x.setColor(new Color(0,0,0,0));  //背景は無色透明で
      g2x.fillRect(0, 0, dim.width, dim.height);
      g2x.rotate(1.57,  //90度回転実施（ラディアン単位で角度指定）
        (float)(stringVArrD[i][0]+sX), (float)(stringVArrD[i][1]+sY));
      g2x.setColor(foregroundColorL);  //文字は不透明色
      Font fontT = new Font(stringVArrS[i][0],Font.PLAIN,
      (int)(stringVArrD[i][2]));
      g2x.setFont(fontT);
      g2x.drawString(  //文字列描画
        stringVArrS[i][1],(float)(stringVArrD[i][0]+sX),
        (float)(stringVArrD[i][1]+sY));
      //f.canvasにbImgを無色透明色の背景で転写描画する
      g2.drawImage(bImg, 0, 0, new Color(0,0,0,0), null);
      if(markFlag == true) //▼起点目印十字線の描画
        drawStartMark(stringVArrD[i][0], stringVArrD[i][1]);
    }

    //●プレビューの場合だけ描画有効範囲枠線を表示。
    //●二点鎖線十字線および三角形目印。
    //●印刷時や画像保存時には、これらを消す。
    if(printMode==false && canSaveMode==false)
    {
      g2.setColor(Color.red); //二点鎖線十字線
      g2.setStroke(dashLineX);
      int z = (int)(imagePX_W/20);
      g2.draw(new Line2D.Double(5, imagePX_H,
        imagePX_W-5, imagePX_H));
      g2.draw(new Line2D.Double(imagePX_W, 5,
        imagePX_W, imagePX_H-5));
      g2.draw(new Line2D.Double(imagePX_W+5, imagePX_H,
        imagePX_W*2, imagePX_H));
      g2.draw(new Line2D.Double(imagePX_W, imagePX_H+5,
        imagePX_W, imagePX_H*2));

      g2.setColor(Color.black); //三角形目印
      g2.setStroke(solidLineX);
      GeneralPath gp1 = new GeneralPath();
      gp1.moveTo(imagePX_W,imagePX_H/2);
      gp1.lineTo(imagePX_W+z,imagePX_H/2-z);
      gp1.lineTo(imagePX_W+z,imagePX_H/2+z);
      gp1.closePath();
      g2.fill(gp1);
      GeneralPath gp2 = new GeneralPath();
      gp2.moveTo(imagePX_W/2,imagePX_H);
      gp2.lineTo(imagePX_W/2-z,imagePX_H+z);
      gp2.lineTo(imagePX_W/2+z,imagePX_H+z);
      gp2.closePath();
      g2.fill(gp2);
    }

    //●ピクセル数とミリ数とを、メニュー・バーに表示
    int pw = ((int)(imagePX_W*affineScale*freeScale));
      //pw : pixelを切り出す範囲の巾
    int ph = ((int)(imagePX_H*affineScale*freeScale));
      //ph : pixelを切り出す範囲の丈
    f.pixelLabel.setText("   (i:"+pw+"x"+ ph+"px)");
    f.mmLabel.setText("   (p:"+(int)(printMM_W*freeScale)+"x"+
      (int)(printMM_H*freeScale)+"mm)");

    //●現在点（最新クリック点）の現在点目印十字線の描画

    if(markFlag == true && currentPointX != 0 && currentPointY != 0)
    {
      g2.setColor(Color.magenta);
      g2.draw(new Line2D.Double(
        currentPointX+sX+6, currentPointY+sY,
        currentPointX+sX-6, currentPointY+sY));
      g2.draw(new Line2D.Double(
        currentPointX+sX, currentPointY+sY+6,
        currentPointX+sX, currentPointY+sY-6));
    }
    //●●線および文字画像処理命令「実行」グループの終わり
  } //drawPage()の終了

  //■■以下は各種メソッド

  //■背景画像表示の準備
  void image()
  {
    imageListB = new LinkedList<BufferedImage>(); //この位置が重要
    for(int i=0; i<imageListF.size(); i++)
    {
      int imageX = imageListI.get(i)[0];
      int imageY = imageListI.get(i)[1];
      int imageW = imageListI.get(i)[2];
      int imageH = imageListI.get(i)[3];
      //●画像ファイル指定のチェック
      String path = imageListF.get(i).toLowerCase();
      if(path.endsWith(".jpeg") ||path.endsWith(".jpg") ||
        path.endsWith(".gif") ||path.endsWith(".png") ||
        path.endsWith(".bmp"))
      {
        ; //OK
      }
      else
      {
        f.message("背景画像ファイル指定が不適切："+path);
        return;
      }
      if(! new File(path).exists())
      {
        f.message("背景画像ファイルが存在しません："+path);
        return;
      }
      BufferedImage imageImage; //背景のピクセル画像
      try
      {
        imageImage = ImageIO.read(new File(path)); //背景のピクセル画像取得
      }
      catch (Exception e)
      {
        e.printStackTrace();
        f.message("背景画像ファイル指定が不適切："+path);
        return;
      }
      imageListB.add(imageImage); //背景画像をリストに追加
    }
  }

  //■スタンプ押印の準備
  void stamp()
  {
    stampListB = new LinkedList<BufferedImage>(); //この位置が重要
    for(int i=0; i<stampListF.size(); i++)
    {
      int stampX = stampListI.get(i)[0];
      int stampY = stampListI.get(i)[1];
      int stampW = stampListI.get(i)[2];
      int stampH = stampListI.get(i)[3];
      //●画像ファイル指定のチェック
      String path = stampListF.get(i).toLowerCase();
      if(path.endsWith(".jpeg") ||path.endsWith(".jpg") ||
        path.endsWith(".gif") ||path.endsWith(".png") ||
        path.endsWith(".bmp"))
      {
        ; //OK
      }
      else
      {
        f.message("スタンプ画像ファイル指定が不適切："+path);
        return;
      }
      if(! new File(path).exists())
      {
        f.message("スタンプ画像ファイルが存在しません："+path);
        return;
      }
      BufferedImage stampImage; //ピクセル画像
      try
      {
        stampImage = ImageIO.read(new File(path)); //スタンプのピクセル画像取得
      }
      catch (Exception e)
      {
        e.printStackTrace();
        f.message("スタンプ画像ファイル指定が不適切："+path);
        return;
      }

      // 画像データのカラー・モデルを確認して表示（デバッグに使用）
/*
      int colorType = stampImage.getType();
      if(colorType == BufferedImage.TYPE_3BYTE_BGR)
        f.message("不透明タイプ：TYPE_3BYTE_BGR >> " + colorType);
      else if(colorType == BufferedImage.TYPE_4BYTE_ABGR)
        f.message("透明可タイプ：TYPE_4BYTE_ABGR >> " + colorType);
      else if(colorType == BufferedImage.TYPE_4BYTE_ABGR_PRE)
        f.message("透明可タイプ：TYPE_4BYTE_ABGR_PRE >> " + colorType);
      else if(colorType == BufferedImage.TYPE_BYTE_BINARY)
        f.message("不透明タイプ：TYPE_BYTE_BINARY >> " + colorType);
      else if(colorType == BufferedImage.TYPE_BYTE_GRAY)
        f.message("灰色タイプ：TYPE_BYTE_GRAY >> " + colorType);
      else if(colorType == BufferedImage.TYPE_BYTE_INDEXED)
        f.message("特殊タイプ：TYPE_BYTE_INDEXED >> " + colorType);
      else if(colorType == BufferedImage.TYPE_CUSTOM)
        f.message("特殊タイプ：TYPE_CUSTOM >> " + colorType);
      else if(colorType == BufferedImage.TYPE_INT_ARGB)
        f.message("透明可タイプ：TYPE_INT_ARGB >> " + colorType);
      else if(colorType == BufferedImage.TYPE_INT_ARGB_PRE)
        f.message("透明可タイプ：TYPE_INT_ARGB_PRE >> " + colorType);
      else if(colorType == BufferedImage.TYPE_INT_BGR)
        f.message("不透明タイプ：TYPE_INT_BGR >> " + colorType);
      else if(colorType == BufferedImage.TYPE_INT_RGB)
        f.message("不透明タイプ：TYPE_INT_RGB >> " + colorType);
      else if(colorType == BufferedImage.TYPE_USHORT_555_RGB)
        f.message("不透明タイプ：TYPE_USHORT_555_RGB >> " + colorType);
      else if(colorType == BufferedImage.TYPE_USHORT_565_RGB)
        f.message("不透明タイプ：TYPE_USHORT_565_RGB >> " + colorType);
      else if(colorType == BufferedImage.TYPE_USHORT_GRAY)
        f.message("灰色タイプ：TYPE_USHORT_GRAY >> " + colorType);
      else
        f.message("カラー・モデル：不明" );
*/
      //スタンプの背景色（灰色）を無色透明に変換
      int w = stampImage.getWidth(this);
      int h = stampImage.getHeight(this);
      BufferedImage transparentImage = new BufferedImage(
        w, h, BufferedImage.TYPE_INT_ARGB); //透明可に設定
      //f.message("transparentColor=" + Integer.toHexString(transparentColor.getRGB()));
      for(int y=0;y<h;y++){
        for(int x=0;x<w;x++){
          if (stampImage.getRGB(x,y) == transparentColor.getRGB())
          { //特定位置で灰色一致なら３２ビットの無色透明色に変換
            transparentImage.setRGB(x,y,0x00000000);
          }
          else
          { //それ以外なら無変換で転写
            transparentImage.setRGB(x, y, stampImage.getRGB(x, y));
          }
        }
      }
      //無色透明化処理は、大抵の場合成功するが、失敗する場合もある。
      //１．スタンプ画像作成での、アンチエイリアシングの有無。
      //２．画像保存ファイル形式（gif、jpeg、bmp、png）。
      //これらが原因で、無色透明化に失敗する場合もある。
      //スタンプ画像（グレー・マスク画像）をこのGCreatorで作成し保存した場合、
      //簡易実験では、読み込み時、次の３種類のカラー・モデルに分かれた。
      //TYPE_BYTE_INDEXED →  透明化に成功または失敗（結果が不安定）
      //TYPE_3BYTE_BGR  →  透明化に成功
      //TYPE_BYTE_BINARY  →  透明化に成功
      //１．アンチエイリアシング（なめらか処理）を行なった時、失敗しやすい。
      //２．ファイル形式としては、「gif」が透明化に失敗しやすく、
      //「jpeg」は、透明化できても画像の乱れが激しく適切でなく、
      //「png」や「bmp」は、成功しやすく適切であるように思われる。
      //（結論）スタンプ画像は、png形式で保存すると、経験的に失敗が全くない。

      stampListB.add(transparentImage); //透明化したスタンプ画像をリストに追加
    }
  }

  //■図形起点目印十字線の描画（赤線と青線の十字線）
  //直線、四角形、真円、楕円、自由図形の起点表示に必要
  void drawStartMark(double x, double y)
  {
    BasicStroke solidLine = new BasicStroke( //太さ可変の実線
      lineWidth, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_MITER);
    BasicStroke solidLineX = new BasicStroke( //太さ固定の実線
      0.2f, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_MITER);
    g2.setStroke(solidLineX);
    g2.setColor(Color.red);
    g2.draw(new Line2D.Double(
      x+shiftX+3, y+shiftY,x+shiftX-3, y+shiftY));
    g2.setColor(Color.blue);
    g2.draw(new Line2D.Double(
      x+shiftX, y+shiftY+3,x+shiftX, y+shiftY-3));
    g2.setStroke(solidLine); //線規格を元に戻す
  }

  //■マトリックス柄紋のランダム配色決定（統一配色）
  short[][] getRandom_rgbSt()
  {  //色番号は、０から９までで、０だけ無色透明扱い
      short[][] random_rgbSt = new short[9][3];
      if(matrixPRedBaseSt > 240) matrixPRedBaseSt = 240; //明度上限設定
      if(matrixPGreenBaseSt > 240) matrixPGreenBaseSt = 240;
      if(matrixPBlueBaseSt > 240) matrixPBlueBaseSt = 240;
      for(int i=0; i<9; i++) //ランダム配色
      {
        random_rgbSt[i][0] = (short)(matrixPRedBaseSt +
          (ran.nextInt(255-matrixPRedBaseSt))*matrixColorLimitSt/10);
        random_rgbSt[i][1] = (short)(matrixPGreenBaseSt +
          (ran.nextInt(255-matrixPGreenBaseSt))*matrixColorLimitSt/10);
        random_rgbSt[i][2] = (short)(matrixPBlueBaseSt +
          (ran.nextInt(255-matrixPBlueBaseSt))*matrixColorLimitSt/10);
      }
      return random_rgbSt;
  }

  //■マトリックス柄紋のランダム配色決定（個別配色）
  short[][][][][][] getRandom_rgbEx()
  {
    //このメソッドは、巨大配列を使うためヒープ領域不足になる可能性もあるので、
    //javaの実行時には、メモリー上のヒープ領域を増やすために、
    //以下の参考例を真似て数倍し、各自が最適値を考え、実行時オプションを加えること。
    //java -Xmx1024m GCreator
    //また、メモリーを多めに（Win11で8GB以上）、PCに搭載することが望ましい。
    //Win11で4GBの条件でも動作可能だが、常駐ソフトを最大限に無効化する必要があり、
    //仮想メモリーの設定も必要になる。
    //模様を複雑（ユニット巨大）かつ精細（コマ数微小）かつ巨大（全体サイズ巨大）
    //に指定すれば、ヒープ領域不足になる可能性がある。
    //メモリーが8GB以上あれば、問題は殆ど生じない。

    short[][][][][][] random_rgbEx =
      new short[matrixRepeatH_Ex][matrixRepeatV_Ex][matrixUnitEx][matrixUnitEx][9][3];
    if(matrixPRedBaseEx > 250) matrixPRedBaseEx = 250; //明度上限設定
    if(matrixPGreenBaseEx > 250) matrixPGreenBaseEx = 250;
    if(matrixPBlueBaseEx > 250) matrixPBlueBaseEx = 250;
    //ランダム配色
    short color[][]= new short [9][3]; //9色のランダム色を一時格納
    //返却配列に格納
    for(int repH=0; repH<matrixRepeatH_Ex; repH++) //リピート数、横
    {
      for(int repV=0; repV<matrixRepeatV_Ex; repV++) //リピート数、縦
      {
        for(int h=0; h<matrixUnitEx; h++) //横コマ数
        {
            if(h==0)
            {
              for(int a=0; a<9; a++) //９色
              {
                  color[a][0] = (short)(matrixPRedBaseEx +
                    (ran.nextInt(255-matrixPRedBaseEx))*matrixColorLimitEx/10);
                  color[a][1] = (short)(matrixPGreenBaseEx +
                    (ran.nextInt(255-matrixPGreenBaseEx))*matrixColorLimitEx/10);
                  color[a][2] = (short)(matrixPBlueBaseEx +
                    (ran.nextInt(255-matrixPBlueBaseEx))*matrixColorLimitEx/10);
              }
            }
          for(int v=0; v<matrixUnitEx; v++) //縦コマ数
          {
            for(int i=0; i<9; i++) //割り当てる配色決定（９色）
            {
              random_rgbEx[repH][repV][h][v][i][0] = (short)color[i][0];
              random_rgbEx[repH][repV][h][v][i][1] = (short)color[i][1];
              random_rgbEx[repH][repV][h][v][i][2] = (short)color[i][2];
            }
          }
        }
      }
    }
    return random_rgbEx;
  }

  //■マトリックス柄紋の柄紋番号での文様データ検索取得
  int[][] getPatternData(int patternNum, String colorType)
  {
    int patternUnit;
    int matrixPattern[][] = null;

    for(int i=0; i<patternArr.length; i++)
    {
      if((patternArr[i].startsWith("PTN")) &&
        (patternNum == Integer.parseInt(patternArr[i].substring(4,8))))
      {
        patternUnit = Integer.parseInt(patternArr[i].substring(9,11));
        if(colorType.equals("St"))
        {
          matrixUnitSt = patternUnit;
        }
        if(colorType.equals("Ex"))
        {
          matrixUnitEx = patternUnit;
        }
        matrixPattern = new int[patternUnit][patternUnit];
        for(int j=0; j<patternUnit; j++)
        {
          String[] s = Util.csv2Array(patternArr[i+j+1], patternUnit);
          for(int k=0; k<patternUnit; k++)
          {
            matrixPattern[j][k] = Integer.parseInt(s[k]);
          }
        }
        //if(patternNum != 0) f.message(""+patternArr[i]);
        break;
      }
      else
        continue;
    }
    if(matrixPattern == null) //柄紋検索エラー
    {
      matrixPattern = new int[][]{
        {0,1,1,1,1,0},
        {0,1,0,0,0,0},
        {0,1,1,1,1,0},
        {0,1,0,0,0,0},
        {0,1,1,1,1,0},
        {0,0,0,0,0,0}};
      if(colorType.equals("St"))
        matrixUnitSt = 6;
      if(colorType.equals("Ex"))
        matrixUnitEx = 6;
    }
    return matrixPattern;
  }

  //■ソフト・フォーカス効果
  void softFocus()
  {
    //●画像ファイル指定のチェック
    if(!softFocusFName.equals("") && softFocusFName != null)
    {
      String path0 = softFocusFName.toLowerCase();
      if(path0.endsWith(".jpeg") || path0.endsWith(".jpg") ||
        path0.endsWith(".gif") || path0.endsWith(".png") ||
        path0.endsWith(".bmp"))
        ; //OK
      else
      {
        f.message("ソフト・フォーカス対象ファイルが不適切です："+path0);
        return;
      }
      if(! new File(path0).exists())
      {
        f.message("ソフト・フォーカス対象ファイルが存在しません："+path0);
        return;
      }
      softFocusImage0 = new BufferedImage(
        (int)imagePX_W, (int)imagePX_H, BufferedImage.TYPE_INT_RGB); //不透明に設定
      softFocusImage1 = new BufferedImage(
        (int)imagePX_W, (int)imagePX_H, BufferedImage.TYPE_INT_RGB); //不透明に設定
      try
      {
        softFocusImage0 = ImageIO.read(new File(path0)); //画像読み取り
      }
      catch (Exception e)
      {
        e.printStackTrace();
        f.message("ソフト・フォーカス対象ファイルのリード・エラー："+path0);
        softFocusImage0 = null;
        return;
      }
      //ソフト・フォーカス加工
      int w = softFocusImage0.getWidth(this);
      int h = softFocusImage0.getHeight(this);
      int m,m1,m2,m3,m4,m5,m6,m7,m8;
      int R,G,B;
      int R1,G1,B1,R2,G2,B2,R3,G3,B3,R4,G4,B4;
      int R5,G5,B5,R6,G6,B6,R7,G7,B7,R8,G8,B8;
      for(int y=0; y<h; y++)
      {
        for(int x=0; x<w; x++)
        {
            m = softFocusImage0.getRGB(x,y);
            R = (m & 0x00ff0000)>>>16;
            G = (m & 0x0000ff00)>>> 8;
            B = (m & 0x000000ff);
            int color =  (R<<16) | (G<<8) | B;
            softFocusImage1.setRGB(x, y, color);
        }
      }
      for(int z=0; z<softFocusDegree; z++) //ソフト度合いの累積処理
      {
        softFocusImage0 = softFocusImage1;
        for(int y=1; y<h-2; y++)
        {
          for(int x=1; x<w-2; x++)
          {
              m = softFocusImage0.getRGB(x,y);
              R = (m & 0x00ff0000)>>>16;
              G = (m & 0x0000ff00)>>> 8;
              B = (m & 0x000000ff);

              m1 = softFocusImage0.getRGB(x-1,y);
              R1 = (m1 & 0x00ff0000)>>>16;
              G1 = (m1 & 0x0000ff00)>>> 8;
              B1 = (m1 & 0x000000ff);
              m2 = softFocusImage0.getRGB(x,y-1);
              R2 = (m2 & 0x00ff0000)>>>16;
              G2 = (m2 & 0x0000ff00)>>> 8;
              B2 = (m2 & 0x000000ff);
              m3 = softFocusImage0.getRGB(x+1,y);
              R3 = (m3 & 0x00ff0000)>>>16;
              G3 = (m3 & 0x0000ff00)>>> 8;
              B3 = (m3 & 0x000000ff);
              m4 = softFocusImage0.getRGB(x,y+1);
              R4 = (m4 & 0x00ff0000)>>>16;
              G4 = (m4 & 0x0000ff00)>>> 8;
              B4 = (m4 & 0x000000ff);

              m5 = softFocusImage0.getRGB(x-1,y-1);
              R5 = (m5 & 0x00ff0000)>>>16;
              G5 = (m5 & 0x0000ff00)>>> 8;
              B5 = (m5 & 0x000000ff);
              m6 = softFocusImage0.getRGB(x+1,y+1);
              R6 = (m6 & 0x00ff0000)>>>16;
              G6 = (m6 & 0x0000ff00)>>> 8;
              B6 = (m6 & 0x000000ff);
              m7 = softFocusImage0.getRGB(x+1,y-1);
              R7 = (m7 & 0x00ff0000)>>>16;
              G7 = (m7 & 0x0000ff00)>>> 8;
              B7 = (m7 & 0x000000ff);
              m8 = softFocusImage0.getRGB(x-1,y+1);
              R8 = (m8 & 0x00ff0000)>>>16;
              G8 = (m8 & 0x0000ff00)>>> 8;
              B8 = (m8 & 0x000000ff);

              double Rd = (R+R1+R2+R3+R4+R5+R6+R7+R8)/9.0D;
              double Gd = (G+G1+G2+G3+G4+G5+G6+G7+G8)/9.0D;
              double Bd = (B+B1+B2+B3+B4+B5+B6+B7+B8)/9.0D;
              int Rx = (int)(Rd+0.5); //計算端数誤差を調整して整数化し、
              int Gx = (int)(Gd+0.5); //ソフト・フォーカス処理を正常化させる。
              int Bx = (int)(Bd+0.5); //
              //この疑似ソフト・フォーカス処理は、各ピクセルの隣接八方向の色相しか
              //計算に入れないので、全体的にぼやけた八角形の形状に、ぼかされる。
              //レンズによる全方向の真円形ソフト・フォーカスとは、微妙に違う。

              int color =  (Rx<<16) | (Gx<<8) | Bx;
              softFocusImage1.setRGB(x, y, color);
          }
        }
      }
    }
    //ソフト・フォーカス画像の描画自体は、drawPage()の中で行なう。
  }

  //■切り貼り画像処理
  void cutAndPaste()
  {
    //●切り貼り画像（外部からの読み込み画像）の上書き描画
    if(capMaskF != null && !capMaskF.equals("")) //マルチ・マスク・ファイル
    {
      //画像ファイル指定のチェック
      String path0 = capMaskF.toLowerCase();
      if(path0.endsWith(".jpeg") ||path0.endsWith(".jpg") ||
        path0.endsWith(".gif") ||path0.endsWith(".png") ||
        path0.endsWith(".bmp"))
        ; //OK
      else
      {
        f.message("マルチ・マスク・ファイルが不適切："+path0);
        return;
      }
      if(! new File(path0).exists())
      {
        f.message("マルチ・マスク・ファイルが存在しません："+path0);
        return;
      }

      int w = (int)imagePX_W;
      int h = (int)imagePX_H;
      try
      {
        capImageM = ImageIO.read(new File(path0)); //画像の読み込み
      }
      catch (Exception e)
      {
        e.printStackTrace();
        f.message("マルチ・マスク・ファイルのリード・エラー："+path0);
        capImageM = null;
        return;
      }
    }

    capImage0 = new BufferedImage( //切り貼り元模様画像（不透明）
      (int)imagePX_W, (int)imagePX_H, BufferedImage.TYPE_INT_RGB);
    capImage1 = new BufferedImage( //切り貼り後の画像（透明可）
      (int)imagePX_W, (int)imagePX_H, BufferedImage.TYPE_INT_ARGB);
    for(int i=0; i<capListF.size(); i++) //
    {
      //画像ファイル指定のチェック
      String path1 = capListF.get(i).toLowerCase();
      int maskR = capListI.get(i)[0];
      int maskG = capListI.get(i)[1];
      int maskB = capListI.get(i)[2];
      int maskRGB = (maskR<<16) | (maskG<<8) | maskB;

      if(path1.endsWith(".jpeg") ||path1.endsWith(".jpg") ||
        path1.endsWith(".gif") ||path1.endsWith(".png") ||
        path1.endsWith(".bmp"))
        ; //OK
      else
      {
        f.message("切り貼り元画像ファイル指定が不適切："+path1);
        return;
      }
      if(! new File(path1).exists())
      {
        f.message("切り貼り元画像ファイルが存在しません："+path1);
        return;
      }
      try
      {
        capImage0 = ImageIO.read(new File(path1));
      }
      catch (Exception e)
      {
        e.printStackTrace();
        f.message("切り貼り元画像ファイルのリード・エラー："+path1);
        return;
      }

      //
      for(int y=0;y<imagePX_H;y++)
      {
        for(int x=0;x<imagePX_W;x++)
        {
          if ((0x00ffffff & capImageM.getRGB(x,y)) == maskRGB)
          { //
            capImage1.setRGB(x, y, capImage0.getRGB(x, y));
          }
        }
      }
    }
    //切り貼り完成画像の描画自体は、drawPage()の中で行なう。
  }

  //■連続色相変更処理
  void changeColorMulti()
  {
    //●元画像（外部からの読み込み画像）の上書き描画
    //主に、マルチ・マスク・ファイルの色相修正に用いる画像加工。
    //String         ccmMaskF  //ChangeColorMalti用　元画像のファイル名
    //BufferedImage  ccmImage0 //元画像（連続色相変更処理前画像）
    //BufferedImage  ccmImage1 //新画像（連続色相変更処理完了画像）
    //List<int[]>    ccmListI0 //旧色指定リスト
    //List<int[]>    ccmListI1 //新色指定リスト

    if(ccmMaskF != null && !ccmMaskF.equals("")) //主にマルチ・マスク・ファイル
    {
      //画像ファイル指定のチェック
      String path0 = ccmMaskF.toLowerCase();
      if(path0.endsWith(".jpeg") ||path0.endsWith(".jpg") ||
        path0.endsWith(".gif") ||path0.endsWith(".png") ||
        path0.endsWith(".bmp"))
        ; //OK
      else
      {
        f.message("元画像ファイルが不適切："+path0);
        return;
      }
      if(! new File(path0).exists())
      {
        f.message("元画像ファイルが存在しません："+path0);
        return;
      }
      try
      {
        ccmImage0 = ImageIO.read(new File(path0)); //元画像の読み込み
      }
      catch (Exception e)
      {
        e.printStackTrace();
        f.message("マルチ・マスク・ファイルのリード・エラー："+path0);
        ccmImage0 = null;
        return;
      }
    }

    int ccmW = ccmImage0.getWidth();
    int ccmH = ccmImage0.getHeight();

    if(ccmImage0 == null)
      return;
    ccmImage1 = new BufferedImage( //連続色相変更後の画像
      ccmW, ccmH, BufferedImage.TYPE_INT_RGB);
    for(int y=0; y<imagePX_H; y++) //初期状態として画像コピー
    {
      for(int x=0; x<imagePX_W; x++)
      {
        ccmImage1.setRGB(x, y, ccmImage0.getRGB(x, y));
      }
    }

    int rgb0 = 0, rgb1 = 0;
    for(int i=0; i<ccmListI0.size(); i++) //色相変更命令の回数だけループ
    {
      for(int y=0; y<imagePX_H; y++)
      {
        for(int x=0; x<imagePX_W; x++)
        {
          rgb0 = (ccmListI0.get(i)[0] << 16 | ccmListI0.get(i)[1] << 8 | ccmListI0.get(i)[2]);
          rgb1 = (ccmListI1.get(i)[0] << 16 | ccmListI1.get(i)[1] << 8 | ccmListI1.get(i)[2]);
          if ((ccmImage0.getRGB(x,y) & 0x00ffffff) == rgb0)
          {
            ccmImage1.setRGB(x, y, rgb1);
          }
        }
      }
    }
    //連続色相変更完成画像の描画自体は、drawPage()の中で行なう。
  }

  //■図形内部彩色（単独処理）
  void changeColorInner()
  {
    //●輪郭線で囲まれた図形内部を指定色で彩色。
    if(changeColorInnerFlag==false)
      return;
    if(changeColorInnerFlag==true && !changeColorInnerF.equals(""))
    {
      String path = changeColorInnerF.toLowerCase();
      if(path.endsWith(".jpeg") ||path.endsWith(".jpg") ||
        path.endsWith(".gif") ||path.endsWith(".png") ||
        path.endsWith(".bmp"))
        ; //OK
      else
      {
        f.message("図形内部彩色用元画像ファイルが不適切："+path);
        return;
      }
      if(! new File(path).exists())
      {
        f.message("図形内部彩色用画像ファイルが存在しません："+path);
        return;
      }
      try
      {
         cciImage = ImageIO.read(new File(path));
      }
      catch (Exception e)
      {
        e.printStackTrace();
        f.message("図形内部彩色用画像ファイルのリード・エラー："+path);
        cciImage = null;
        return;
      }
    }
    else
    {
      f.message("図形内部彩色元画像ファイル指定に問題あり。");
      return;
    }

    int w = cciImage.getWidth(this);
    int h = cciImage.getHeight(this);
    int outLineColor = 0xff<<24 | cciOutLineColorR<<16 | cciOutLineColorG<<8 | cciOutLineColorB;
    int innerColor   = 0xff<<24 | cciInnerColorR<<16 | cciInnerColorG<<8 | cciInnerColorB;
    cciImage.setRGB(cciInnerX, cciInnerY, innerColor); //図形内部代表位置の１ピクセルを彩色

    int nextPositionColor = 0;
    for(;;) //スキャンの反復
    {
      boolean scanFlag = false;
      for(int j=0; j<h-1; j++) //右向き彩色拡張
      {
        for(int k=0; k<w-1; k++)
        {
          nextPositionColor = cciImage.getRGB(k+1,j);
          if(cciImage.getRGB(k,j)==innerColor && nextPositionColor!=outLineColor && nextPositionColor!=innerColor)
          {
            cciImage.setRGB(k+1,j,innerColor);
            scanFlag = true;
          }
        }
      }
      for(int j=0; j<h-1; j++) //左向き彩色拡張
      {
        for(int k=w-1; k>0; k--)
        {
          nextPositionColor = cciImage.getRGB(k-1,j);
          if(cciImage.getRGB(k,j)==innerColor && nextPositionColor!=outLineColor && nextPositionColor!=innerColor)
          {
            cciImage.setRGB(k-1,j,innerColor);
            scanFlag = true;
          }
        }
      }
      for(int j=0; j<w-1; j++) //下向き彩色拡張
      {
        for(int k=0; k<h-1; k++)
        {
          nextPositionColor = cciImage.getRGB(j,k+1);
          if(cciImage.getRGB(j,k)==innerColor && nextPositionColor!=outLineColor && nextPositionColor!=innerColor)
          {
            cciImage.setRGB(j,k+1,innerColor);
            scanFlag = true;
          }
        }
      }
      for(int j=0; j<w-1; j++) //上向き彩色拡張
      {
        for(int k=h-1; k>0; k--)
        {
          nextPositionColor = cciImage.getRGB(j,k-1);
          if(cciImage.getRGB(j,k)==innerColor && nextPositionColor!=outLineColor && nextPositionColor!=innerColor)
          {
            cciImage.setRGB(j,k-1,innerColor);
            scanFlag = true;
          }
        }
      }
      if(scanFlag == false) //新たに色彩変更することがなかった場合
        break;
    }

    if(cciMode==1)
    { //輪郭線を内部彩色と同一色に変換
      int currentPositionColor = 0;
      for(int i=0; i<h; i++)
      {
        for(int j=0; j<w; j++)
        {
          currentPositionColor = cciImage.getRGB(j,i);
          if(cciImage.getRGB(j,i)==outLineColor)
          {
            cciImage.setRGB(j,i,innerColor);
          }
        }
      }
    }
  }

  //■図形内部連続彩色
  void changeColorInnerMulti()
  {
    //●輪郭線で囲まれた図形内部を指定色で連続彩色。
    //輪郭線で囲まれた図形が複雑に屈曲している場合、全部を塗り終わるまでに、相当な時間を要する。
    //これを高速化するには、点描画機能を用い、彩色部の数箇所に予め指定色を部分的に塗っておく。
    if(changeColorInnerMultiFlag==false)
      return;
    if(changeColorInnerMultiFlag==true && !changeColorInnerMultiF.equals(""))
    {
      String path = changeColorInnerMultiF.toLowerCase();
      if(path.endsWith(".jpeg") ||path.endsWith(".jpg") ||
        path.endsWith(".gif") ||path.endsWith(".png") ||
        path.endsWith(".bmp"))
        ; //OK
      else
      {
        f.message("図形内部連続彩色用元画像ファイルが不適切："+path);
        return;
      }
      if(! new File(path).exists())
      {
        f.message("図形内部連続彩色用画像ファイルが存在しません："+path);
        return;
      }
      try
      {
         ccimImage = ImageIO.read(new File(path));
      }
      catch (Exception e)
      {
        e.printStackTrace();
        f.message("図形内部連続彩色用画像ファイルのリード・エラー："+path);
        ccimImage = null;
        return;
      }
    }
    else
    {
      f.message("図形内部連続彩色元画像ファイル指定に問題あり。");
      return;
    }

    int w = ccimImage.getWidth(this);
    int h = ccimImage.getHeight(this);
    int outLineColor = 0xff<<24 | ccimOutLineColorR<<16 | ccimOutLineColorG<<8 | ccimOutLineColorB;

    //連続彩色
    for(int i=0; i<ccimListI.size(); i++)
    {
      int rgb = (ccimListI.get(i)[0] << 16 | ccimListI.get(i)[1] << 8 | ccimListI.get(i)[2]);
      int innerColor = 0xff<<24 | ccimListI.get(i)[0]<<16 | ccimListI.get(i)[1]<<8 | ccimListI.get(i)[2];
      int ccimInnerX = ccimListI.get(i)[3];
      int ccimInnerY = ccimListI.get(i)[4];
      ccimImage.setRGB(ccimInnerX, ccimInnerY, innerColor); //図形内部代表位置の１ピクセルを彩色
      int nextPositionColor = 0;
      for(;;) //スキャンの反復
      {
        boolean scanFlag = false;
        for(int j=0; j<h-1; j++) //右向き彩色拡張
        {
          for(int k=0; k<w-1; k++)
          {
            nextPositionColor = ccimImage.getRGB(k+1,j);
            if(ccimImage.getRGB(k,j)==innerColor && nextPositionColor!=outLineColor && nextPositionColor!=innerColor)
            {
              ccimImage.setRGB(k+1,j,innerColor);
              scanFlag = true;
            }
          }
        }
        for(int j=0; j<h-1; j++) //左向き彩色拡張
        {
          for(int k=w-1; k>0; k--)
          {
            nextPositionColor = ccimImage.getRGB(k-1,j);
            if(ccimImage.getRGB(k,j)==innerColor && nextPositionColor!=outLineColor && nextPositionColor!=innerColor)
            {
              ccimImage.setRGB(k-1,j,innerColor);
              scanFlag = true;
            }
          }
        }
        for(int j=0; j<w-1; j++) //下向き彩色拡張
        {
          for(int k=0; k<h-1; k++)
          {
            nextPositionColor = ccimImage.getRGB(j,k+1);
            if(ccimImage.getRGB(j,k)==innerColor && nextPositionColor!=outLineColor && nextPositionColor!=innerColor)
            {
              ccimImage.setRGB(j,k+1,innerColor);
              scanFlag = true;
            }
          }
        }
        for(int j=0; j<w-1; j++) //上向き彩色拡張
        {
          for(int k=h-1; k>0; k--)
          {
            nextPositionColor = ccimImage.getRGB(j,k-1);
            if(ccimImage.getRGB(j,k)==innerColor && nextPositionColor!=outLineColor && nextPositionColor!=innerColor)
            {
              ccimImage.setRGB(j,k-1,innerColor);
              scanFlag = true;
            }
          }
        }
        if(scanFlag == false) //新たに色彩変更することがなかった場合
          break;
      }
    }
  }

  //■二重像画像処理
  void mixImage()
  {
    //●ミックス用画像（外部からの読み込み画像）を用いた二重像合成描画
    //●写真の二重露光と同様の画像合成
    //●画像ファイル指定のチェック
    if(!mixFName0.equals(""))
    {
      String path0 = mixFName0.toLowerCase();
      if(path0.endsWith(".jpeg") ||path0.endsWith(".jpg") ||
        path0.endsWith(".gif") ||path0.endsWith(".png") ||
        path0.endsWith(".bmp"))
        ; //OK
      else
      {
        f.message("ミックス用画像ファイル0が不適切："+path0);
        return;
      }
      if(! new File(path0).exists())
      {
        f.message("ミックス用画像ファイル0が存在しません："+path0);
        return;
      }
      try
      {
        mixImage0 = ImageIO.read(new File(path0));
      }
      catch (Exception e)
      {
        e.printStackTrace();
        f.message("ミックス用画像ファイル0のリード・エラー："+path0);
        mixImage0 = null;
        return;
      }

      String path1= mixFName1.toLowerCase();
      if(path1.endsWith(".jpeg") ||path1.endsWith(".jpg") ||
        path1.endsWith(".gif") ||path1.endsWith(".png") ||
        path1.endsWith(".bmp"))
      {
        ; //OK
      }
      else
      {
        f.message("ミックス用画像ファイル1が不適切："+path1);
        return;
      }
      if(! new File(path1).exists())
      {
        f.message("ミックス用画像ファイル1が存在しません："+path1);
        return;
      }
      try
      {
        mixImage1 = ImageIO.read(new File(path1));
      }
      catch (Exception e)
      {
        e.printStackTrace();
        f.message("ミックス用画像ファイル1のリード・エラー："+path1);
        mixImage1 = null;
        return;
      }

      //●画像ミックス
      //●画像サイズを全て統一しておくこと
      int w = mixImage0.getWidth(this);
      int h = mixImage0.getHeight(this);
      int R,G,B;
      mixImage2 = new BufferedImage(
        w, h, BufferedImage.TYPE_INT_RGB); //不透明

      if(mixMode == 1) //通常の二重像モード
      {
        for(int y=0;y<h;y++)
        {
          for(int x=0;x<w;x++)
          {
            int m = mixImage0.getRGB(x,y); //元画像
            int t = mixImage1.getRGB(x,y); //追加画像

            if( //追加画像の背景部分が灰色（200,200,200）の場合、
                //混色せずに、元画像の色相を維持
              (((t & 0x00ff0000)>>>16) == 200) &&
            	(((t & 0x0000ff00)>>> 8) == 200) &&
              (( t & 0x000000ff)      == 200) )
            {
            	R = (m & 0x00ff0000)>>>16;
            	G = (m & 0x0000ff00)>>> 8;
            	B = (m & 0x000000ff);
              int color = (R<<16) | (G<<8) | B;
              mixImage2.setRGB(x, y, color);
            }
            else //元画像と追加画像とを、有色半透明で混色合成
            {
            	R = ((m & 0x00ff0000)>>>16)/2 + ((t & 0x00ff0000)>>>16)/2;
            	G = ((m & 0x0000ff00)>>> 8)/2 + ((t & 0x0000ff00)>>> 8)/2;
            	B = (m & 0x000000ff)/2       + ( t & 0x000000ff)/2;
              int color = (R<<16) | (G<<8) | B;
              mixImage2.setRGB(x, y, color);
            }
          }
        }
      }
      else if(mixMode == 0) //拡大縮小を伴わない画像全体の「簡易Stamp命令」として機能
      {
        for(int y=0;y<h;y++)
        {
          for(int x=0;x<w;x++)
          {
            int m = mixImage0.getRGB(x,y); //元画像
            int t = mixImage1.getRGB(x,y); //追加画像

            if( //追加画像の背景部分が灰色（200,200,200）の場合、
                //元画像の色相を維持
              (((t & 0x00ff0000)>>>16) == 200) &&
            	(((t & 0x0000ff00)>>> 8) == 200) &&
              (( t & 0x000000ff)      == 200) )
            {
            	R = (m & 0x00ff0000)>>>16;
            	G = (m & 0x0000ff00)>>> 8;
            	B = (m & 0x000000ff);
              int color = (R<<16) | (G<<8) | B ;
              mixImage2.setRGB(x, y, color);
            }
            else //追加画像の色相をコピー（簡易Stamp押印）
            {
            	R = (t & 0x00ff0000)>>>16;
            	G = (t & 0x0000ff00)>>> 8;
            	B = (t & 0x000000ff);
              int color = (R<<16) | (G<<8) | B;
              mixImage2.setRGB(x, y, color);
            }
          }
        }
      }
    }
    //二重像画像の描画自体は、drawPage()の中で行なう。
  }

  //■鏡像への画像反転処理（回転処理も一部含む）
  void reverseImage()
  {
    //●画像の鏡像反転（回転処理も一部含む）
    if(reverseImageFlag == true)
    {
      try
      { //反転対象既存画像の読み込み
        reverseImage0 = ImageIO.read(new File(reverseImageFile));
      }
      catch (Exception e)
      {
        e.printStackTrace();
        f.message("反転対象既存画像のリード・エラー");
        return;
      }

      int ww = reverseImage0.getWidth(this);
      int hh = reverseImage0.getHeight(this);

      reverseImage1 = new BufferedImage(
        ww, hh, BufferedImage.TYPE_INT_RGB); //不透明に設定
      reverseImageX = new BufferedImage( //回転
        hh, ww, BufferedImage.TYPE_INT_RGB); //不透明に設定

      if(reverseImageMode==1) //左右鏡像反転
      {
        for(int y=0; y<hh; y++)
        {
          for(int x=0, w1=ww; x<ww; x++, w1--)
          {
            reverseImage1.setRGB(w1-1, y, reverseImage0.getRGB(x,y));
          }
        }
      }
      else if(reverseImageMode==2) //上下鏡像反転
      {
        for(int y=0, h1=hh; y<hh; y++, h1--)
        {
          for(int x=0; x<ww; x++)
          {
            reverseImage1.setRGB(x, h1-1, reverseImage0.getRGB(x,y));
          }
        }
      }
      else if(reverseImageMode==3) //左半分を右半分に対称型に転写して左右対称にする。
      {
        int half;
        if(ww%2 == 0)
          half=ww/2;
        else
          half=ww/2+1;
        for(int y=0; y<hh; y++)
        {
          for(int x=0, w1=half; x<half; x++, w1--)
          {
            reverseImage1.setRGB(x, y, reverseImage0.getRGB(x,y));
            reverseImage1.setRGB(half+w1-1, y, reverseImage0.getRGB(x,y));
          }
        }
      }
      else if(reverseImageMode==4) //上半分を下半分に対称型に転写して上下対称にする。
      {
        int half;
        if(hh%2 == 0)
          half=hh/2;
        else
          half=hh/2+1;
        for(int y=0, h1=half; y<half; y++, h1--)
        {
          for(int x=0; x<ww; x++)
          {
            reverseImage1.setRGB(x, y, reverseImage0.getRGB(x,y));
            reverseImage1.setRGB(x, half+h1-1, reverseImage0.getRGB(x,y));
          }
        }
      }
      else if(reverseImageMode==6) //時計回りで、180度回転（半回転）させる。
      {
        for(int y=0, y1=hh-1; y<hh; y++, y1--)
        {
          for(int x=0, x1=ww-1; x<ww; x++, x1--)
          {
            reverseImage1.setRGB(x1,y1, reverseImage0.getRGB(x,y));
          }
        }
      }

      //これ以降のreverseImageMode（5 or 7）は、画像の幅と丈とが入れ替わるので、
      //通常の方法（メニューやボタンの操作）では、Size命令が邪魔をして、
      //正常に画像保存できないため、このメソッドの内部で、画像保存を強制的に行なう。

      else if(reverseImageMode==5) //時計回りで、90度回転させる。
      {
        for(int y=0, y1=hh-1; y<hh; y++, y1--)
        {
          for(int x=0; x<ww; x++)
          {
            reverseImageX.setRGB(y1,x, reverseImage0.getRGB(x,y)); //*********
          }
        }
        reverseImage1=reverseImageX;
        try
        {
          ImageIO.write(reverseImage1, "png", new File("./image/reverseImageTemp.png"));
        }
        catch (Exception e)
        {
          e.printStackTrace();
          return;
        }
        f.message("./image/reverseImageTemp.pngに画像保存しました。");
      }
      else if(reverseImageMode==7) //時計回りで、270度回転させる。
      {
        for(int y=0; y<hh; y++)
        {
          for(int x=0, x1=ww-1; x<ww; x++,x1--)
          {
            reverseImageX.setRGB(y,x1, reverseImage0.getRGB(x,y));
          }
        }
        reverseImage1=reverseImageX;
        try
        {
          ImageIO.write(reverseImage1, "png", new File("./image/reverseImageTemp.png"));
        }
        catch (Exception e)
        {
          e.printStackTrace();
          return;
        }
        f.message("./image/reverseImageTemp.pngに画像保存しました。");
      }
      else
      {
        reverseImage1 = reverseImage0;
      }
    }
  }

  //■単独色相変更処理
  void colorChange(int mode)
  {
    //●単独色相変更機能の実現。
    //単独色相変更要求があれば、指定の旧色に対して指定の新色に変換する。
    //処理対象の画像が、既に画像ファイルとして存在するものとする。
    //階調画像からグレー・マスクを生成する機能を追加的に含む。
    if(mode==0)
    {
      return; //何もしない（単独色相変更要求がない）
    }
    if(colorChangeFlag == true)
    {
      try
      {
        colorChangeImage0 = ImageIO.read(new File(colorChangeFile));
      }
      catch (Exception e)
      {
        e.printStackTrace();
        f.message("カラー・チェンジ既存画像のリード・エラー");
        colorChangeImage0 = null;
        return;
      }

      Color oldColor  = new Color(colorChange1R, colorChange1G, colorChange1B);
      Color newColor  = new Color(colorChange2R, colorChange2G, colorChange2B);
      int grayColor = (200<<16 | 200<<8 | 200);
      //単独色相変更実施
      int w_ = colorChangeImage0.getWidth(this);
      int h_ = colorChangeImage0.getHeight(this);
      colorChangeImage1 = new BufferedImage(
        w_, h_, BufferedImage.TYPE_INT_RGB); //不透明に設定
      for(int y=0;y<h_;y++)
      {
        for(int x=0;x<w_;x++)
        {
          int rgbX = colorChangeImage0.getRGB(x,y);
          int redX   = (rgbX & 0x00ff0000) >>> 16;
          int greenX = (rgbX & 0x0000ff00) >>> 8;
          int blueX  = (rgbX & 0x000000ff);
          if (  //近似色をも許容する
            (redX >= (oldColor.getRed() - acceptableLimitC) &&
             redX <= (oldColor.getRed() + acceptableLimitC))
              &&
            (greenX >= (oldColor.getGreen() - acceptableLimitC) &&
             greenX <= (oldColor.getGreen() + acceptableLimitC))
              &&
            (blueX >= (oldColor.getBlue() - acceptableLimitC) &&
             blueX <= (oldColor.getBlue() + acceptableLimitC))    )
          { //各種条件一致なら３２ビットの新色に変換
            colorChangeImage1.setRGB(x, y, newColor.getRGB());
          }
          else
          {
            if(mode==1)
            { //旧色のまま転写
              colorChangeImage1.setRGB(x, y, colorChangeImage0.getRGB(x,y));
            }
            else if(mode==2)
            { //グレー色（200,200,200）を転写
              //階調画像からグレー・マスクを生成
              colorChangeImage1.setRGB(x, y, grayColor);
            }
            else if(mode>2)
            {
              f.message("colorChange命令のモード指定が異常。");
              return;
            }
          }
        }
      }
    }
    //単独色相変更の描画自体は、drawPage()の中で行なう。
  }

  //■色相調整効果
  void adjustRGB()
  {
    //●画像ファイル指定のチェック
    if(!adjustFName.equals("") && adjustFName != null)
    {
      String path0 = adjustFName.toLowerCase();
      if(path0.endsWith(".jpeg") || path0.endsWith(".jpg") ||
        path0.endsWith(".gif") || path0.endsWith(".png") ||
        path0.endsWith(".bmp"))
        ; //OK
      else
      {
        f.message("色相調整対象ファイルが不適切："+path0);
        return;
      }
      if(! new File(path0).exists())
      {
        f.message("色相調整対象ファイルが存在しません："+path0);
        return;
      }
      adjustImage0 = new BufferedImage(
        (int)imagePX_W, (int)imagePX_H, BufferedImage.TYPE_INT_RGB); //不透明に設定
      adjustImage1 = new BufferedImage(
        (int)imagePX_W, (int)imagePX_H, BufferedImage.TYPE_INT_RGB); //不透明に設定
      try
      {
        adjustImage0 = ImageIO.read(new File(path0)); //画像読み取り
      }
      catch (Exception e)
      {
        e.printStackTrace();
        f.message("色相調整対象ファイルのリード・エラー："+path0);
        adjustImage0 = null;
        return;
      }
      //色調調整
      int w = adjustImage0.getWidth(this);
      int h = adjustImage0.getHeight(this);
      int R,G,B; //元の色相
      int R1,G1,B1; //調整後の色相
      for(int y=0; y<h; y++)
      {
        for(int x=0; x<w; x++)
        {
            int m = adjustImage0.getRGB(x,y);
            R = (m & 0x00ff0000) >>> 16;
            G = (m & 0x0000ff00) >>> 8;
            B = (m & 0x000000ff) >>> 0;
            if(adjustR >0)
              R1 = R + (int)((255-R)*(adjustR/100.0));
            else
              R1 = R - (int)((0-R)*(adjustR/100.0));
            if(adjustG >0)
              G1 = G + (int)((255-G)*(adjustG/100.0));
            else
              G1 = G - (int)((0-G)*(adjustG/100.0));
            if(adjustB >0)
              B1 = B + (int)((255-B)*(adjustB/100.0));
            else
              B1 = B - (int)((0-B)*(adjustB/100.0));
            int color =  (R1<<16) | (G1<<8) | B1 ;
            adjustImage1.setRGB(x, y, color);
        }
      }
    }
    //色相調整の描画自体は、drawPage()の中で行なう。
  }

  //■色相濃淡階調効果（垂直線形グラデーション）
  void colorGradient()
  {
    //●画像ファイル指定のチェック
    if(!gradientFName.equals("") && gradientFName != null)
    {
      String path0 = gradientFName.toLowerCase();
      if(path0.endsWith(".jpeg") || path0.endsWith(".jpg") ||
        path0.endsWith(".gif") || path0.endsWith(".png") ||
        path0.endsWith(".bmp"))
        ; //OK
      else
      {
        f.message("色相濃淡階調加工対象ファイルが不適切："+path0);
        return;
      }
      if(! new File(path0).exists())
      {
        f.message("色相濃淡階調加工対象ファイルが存在しません："+path0);
        return;
      }
      gradientImage0 = new BufferedImage(
        (int)imagePX_W, (int)imagePX_H, BufferedImage.TYPE_INT_RGB); //不透明に設定
      gradientImage1 = new BufferedImage(
        (int)imagePX_W, (int)imagePX_H, BufferedImage.TYPE_INT_RGB); //不透明に設定
      try
      {
        gradientImage0 = ImageIO.read(new File(path0)); //画像読み取り
      }
      catch (Exception e)
      {
        e.printStackTrace();
        f.message("色相濃淡階調加工対象ファイルのリード・エラー："+path0);
        gradientImage0 = null;
        return;
      }
      //色調濃淡階調加工（グラデーション）
      int w = gradientImage0.getWidth(this);
      int h = gradientImage0.getHeight(this);
      int cR,cG,cB; //元の色相
      int cR1,cG1,cB1; //濃淡階調加工後の色相
      for(int y=0; y<h; y++)
      { //全体を単純にコピー
        for(int x=0; x<w; x++)
        {
            int m = gradientImage0.getRGB(x,y);
            gradientImage1.setRGB(x, y, m);
        }
      }
      for(int y=gradientY1; y<gradientY2; y++)
      { //非対称グラデーションの上書き
        for(int x=0; x<w; x++)
        {
            int m = gradientImage0.getRGB(x,y);
            cR = (m & 0x00ff0000) >>> 16;
            cG = (m & 0x0000ff00) >>> 8;
            cB = (m & 0x000000ff) >>> 0;

            cR1 = cR + (int)(gradientR*(y-gradientY1));
            if(cR1>255)
              cR1=255;
            else if(cR1<0)
              cR1=0;

            cG1 = cG + (int)(gradientG*(y-gradientY1));
            if(cG1>255)
              cG1=255;
            else if(cG1<0)
              cG1=0;

            cB1 = cB + (int)(gradientB*(y-gradientY1));
            if(cB1>255)
              cB1=255;
            else if(cB1<0)
              cB1=0;

            int color = (cR1<<16) | (cG1<<8) | cB1 ;
            gradientImage1.setRGB(x, y, color);
        }
      }
      //対称グラデーションの追加上書き
      int gY =gradientY2-gradientY1;
      for(int y=gradientY2; y<(gradientY1+(gradientY2-gradientY1)*2) && (y<h); y++)
      {
        gY--;
        for(int x=0; x<w; x++)
        {
            int m = gradientImage0.getRGB(x,y);
            cR = (m & 0x00ff0000) >>> 16;
            cG = (m & 0x0000ff00) >>> 8;
            cB = (m & 0x000000ff) >>> 0;

            cR1 = cR + (int)(gradientR*(gY));
            if(cR1>255)
              cR1=255;
            else if(cR1<0)
              cR1=0;

            cG1 = cG + (int)(gradientG*(gY));
            if(cG1>255)
              cG1=255;
            else if(cG1<0)
              cG1=0;

            cB1 = cB + (int)(gradientB*(gY));
            if(cB1>255)
              cB1=255;
            else if(cB1<0)
              cB1=0;

            int color = (cR1<<16) | (cG1<<8) | cB1 ;
            gradientImage1.setRGB(x, y, color);
        }
      }
    }
    //色相濃淡階調加工の描画自体は、drawPage()の中で行なう。
  }

  //■画像多段階回転重複描画
  void rotateMulti()
  {
    //Size命令で設定された座標範囲の内側にある回転対象領域のみを多段階に回転させ上書きする。
    //画像多段階回転は、中心点を同じくする二重の正方形の枠組みの中で、回転させつつ多段階に描画する。
    //例えば、一枚の花弁を事前に描き、これを３０度づつ回転させ、花弁が１２枚の花を自動描画する用途に使用。
    //外枠の正方形（Size命令で指定）の中に内枠の正方形が入る形だが、一辺の比率は、３対２の比率にする。
    //内枠の中に、回転させる元画像が、はみ出さずに収まらねばならない。
    //外枠と内枠との中間領域は、回転する余裕を与える空間である。
    //回転対象画像は、グレー・マスク形式（背景がグレー）とし、完成画像も、グレー・マスク形式になる。

    if(rotateMultiFlag == false)
      return;
    BufferedImage rotateMultiImage1 = new BufferedImage(
      (int)imagePX_W, (int)imagePX_H, BufferedImage.TYPE_INT_RGB); //不透明に設定
    BufferedImage rotateMultiImage2 = new BufferedImage(
      (int)imagePX_W, (int)imagePX_H, BufferedImage.TYPE_INT_RGB); //不透明に設定

    try
    {
      rotateMultiImage1 = ImageIO.read(new File(rotateMultiF)); //画像読み取り
    }
    catch (Exception e)
    {
      e.printStackTrace();
      f.message("回転対象ファイルのリード・エラー："+rotateMultiF);
      rotateMultiImage = null;
      return;
    }

    int gray = (0xff<<24) | (200<<16) | (200<<8) | 200;
    for(int i=0; i<imagePX_W; i++) //グレーで初期化
    {
      for(int j=0; j<imagePX_H; j++)
      {
        rotateMultiImage2.setRGB(i,j,gray);
      }
    }

    int color1 = 0;
    int color2 = 0;
    int x2 = 0;
    int y2 = 0;

    int x1min = (int)(imagePX_W/6);
    int x1max = (int)((imagePX_W/6)*5);
    int y1min = (int)(imagePX_H/6);
    int y1max = (int)((imagePX_H/6)*5);
    int centerX = (int)(imagePX_W/2); //画像中心点
    int centerY = (int)(imagePX_H/2);
    double radian = 0;
    double startRadian = Math.toRadians(rotateMultiStartDegree);
    for( int k=0; k<rotateMultiTimes; k++) //回転回数分のループ
    {
      radian = startRadian + Math.toRadians(rotateMultiDegree*k);
      for(int j=x1min; j<x1max; j++) //回転させる位置変換
      {
        for(int i=y1min; i<y1max; i++)
        {
          x2 = (int)(((i-centerX)*Math.cos(radian) - (j-centerY)*Math.sin(radian))+centerX);
          y2 = (int)(((i-centerX)*Math.sin(radian) + (j-centerY)*Math.cos(radian))+centerY);
          color1 = rotateMultiImage1.getRGB(i,j);
          if(color1 != gray)
          {
            try
            {
                rotateMultiImage2.setRGB(x2,y2,color1);
            }
            catch (Exception e)
            {
              e.printStackTrace();
              return;
            }
          }
        }
      }
    }

    //●画像補正（多段階回転させた画像のピクセル欠けを埋める処理）
    //これから行なう画像補正は、三角関数による座標変換計算で生じた
    //実数座標を整数座標に変換する際に生じる画像のピクセル欠けを補正するものである。
    //ただし、多段階回転に適するのは、単色無階調画像（ベタ塗り画像）に限られ、
    //多色無階調画像（マトリックス模様など）や階調画像（ボカシ画像）は、一段階回転しか適さない。
    //多色画像を無理に多段階回転多重描画すると、モアレ模様が現われ、画像の精細さが失われる。
    //そもそも、多色が入り乱れる複雑な画像を、回転させながら多重描画する用途は、殆どない。
    //一回分の回転のたびに画像補正して多重上書きすれば、階調画像でもモアレ回避が可能のはずだが、
    //そこまでする必要がないので、そうしない。
    //なお、回転加工した画像は、三角関数計算値の整数化および画像補正により、輪郭線が多少乱れるので、
    //予め巨大画像で作成しておいて、スタンプ機能で利用する際に、画像縮小で目立たないようにする。

    for(int p=1; p<imagePX_H-1; p++)
    {
      for(int q=1; q<imagePX_W-1; q++)
      {
        int col0 = rotateMultiImage2.getRGB(q,p);
        int col1 = rotateMultiImage2.getRGB(q-1,p);
        int col2 = rotateMultiImage2.getRGB(q+1,p);
        int col3 = rotateMultiImage2.getRGB(q,p-1);
        int col4 = rotateMultiImage2.getRGB(q,p+1);

        int col1R = (col1 & 0x00ff0000)>>>16;
        int col1G = (col1 & 0x0000ff00)>>>8;
        int col1B = (col1 & 0x000000ff);
        int col2R = (col1 & 0x00ff0000)>>>16;
        int col2G = (col1 & 0x0000ff00)>>>8;
        int col2B = (col1 & 0x000000ff);
        int col3R = (col1 & 0x00ff0000)>>>16;
        int col3G = (col1 & 0x0000ff00)>>>8;
        int col3B = (col1 & 0x000000ff);
        int col4R = (col1 & 0x00ff0000)>>>16;
        int col4G = (col1 & 0x0000ff00)>>>8;
        int col4B = (col1 & 0x000000ff);

        if(col0==gray)
        {
          if(col1!=gray && col1==col2) //単色無階調画像の場合
            rotateMultiImage2.setRGB(q,p,col1);
          else if(col1!=gray && col3==col4) //単色無階調画像の場合
            rotateMultiImage2.setRGB(q,p,col3);
          else if(col1!=gray && col2!=gray && col3!=gray && col4!=gray)
            //多色無階調画像や階調画像の場合（一段階回転に限定すべき）
          {
            int colXR = (int)((col1R + col2R + col3R + col4R)/4);
            int colXG = (int)((col1G + col2G + col3G + col4G)/4);
            int colXB = (int)((col1B + col2B + col3B + col4B)/4);
            int colX  = 0xff<<24 | colXR<<16 | colXG<<8 | colXB;
            rotateMultiImage2.setRGB(q,p,col1);
          }
        }
      }
    }
    rotateMultiImage = rotateMultiImage2;
    //多段階回転加工処理した画像描画自体は、drawPage()の中で行なう。
  }
} //EOF (GCreatorCanvasEngine.java)

◆GCreatorAnalyzeEngine.java

//■■GCreatorAnalyzeEngine.java
//Ver.3.3

//■■インポート
import java.awt.*;  //必須
import java.util.*;  //必須
import java.io.*;  //必須

//■■描画機能の実現
class GCreatorAnalyzeEngine
{
  //■メンバー変数
  GCreator f; //JFlameの継承インスタンス
  Graphics2D g2;
  GCreatorCanvasEngine can;
  double[] shape; //色塗り系命令文を解析して全部格納
  String command1; //命令文１行分

  //■コンストラクタ
  GCreatorAnalyzeEngine(GCreator flame)
  {
    f = flame;
    can = f.canvas;
  }

  void commandAnalyze(String commandZ)
  {
    //●命令文の全文解析
    //命令の引数が多いものや紛らわしいものだけ、数のチェックを行なう。
    boolean commentFlag = false;
    StringTokenizer st1 = new StringTokenizer(commandZ,";\n");
      //命令全文に対して、セミコロンと改行コードで切り分ける準備
    String commandS = ""; //命令1件の命令本体（引数含まず）
    f.scaleLabel2.setText("　(f:x1.0)"); //フリー・スケールの初期化
    f.canvas.freeScale = 1.0;//フリー・スケールの初期化

    try
    {
      for(int i=0; st1.hasMoreTokens(); i++)
      { //●命令文の全文読み込み
        command1 = st1.nextToken().trim(); //一行分の命令文

        if(command1.equals("")) //空行
          continue;

        if(command1.substring(0,1).equals("　") ) //全角スペース
          continue;

        if(command1.substring(0,2).equals("//")) //◆一行コメント文
          continue;

        if(command1.substring(0,2).equals("/@")) //◆多行コメント文
        {  //「/@」は、単独で書かねばならず、同じ行の直後に命令文を書いてはならない。
          commentFlag = true;
          continue;
        }
        if(command1.substring(0,2).equals("@/"))
        { //「@/」は、単独で書かねばならず、同じ行の直後に命令文を書いてはならない。
          commentFlag = false;
          continue;
        }
        if(commentFlag == true)
        { //「/@」と「@/」とで挟まれた中間行
          continue;
        }

        if(command1.substring(0,5).equals("Break")) //◆これ以降の命令文全部を無視。
          break;

        StringTokenizer st2 = new StringTokenizer(command1,"(,)");
          //引数区切を「括弧」および「コンマ」に設定。
        commandS = st2.nextToken().trim(); //命令1件の命令本体（引数含まず）
          //これ以降のst2は、命令本体が取り除かれた状態（引数群）を維持する。
          //そのため、st2.countTokens()の返却値に注意。
          //st2.countTokens()の返却値は、
          //st2.nextToken()された後に残されているトークンの数。

        //●命令文の逐次解析実施
        if(commandS.equals("SaveCommands"))
        { //●命令文書の保存ファイル名の指定
          //ボタン操作による文書半自動保存に対応
          can.saveCmdFName =
            Util.trimAffix(st2.nextToken().trim(),'\"','\"');
        }
        else if(commandS.equals("SaveImage"))
        { //●作成画像の保存ファイル名の指定
          //ボタン操作による画像半自動保存に対応
          can.saveImgFName =
            Util.trimAffix(st2.nextToken().trim(),'\"','\"');
        }
        else if(commandS.equals("CutAndSaveImage"))
        { //●作成画像の切り出し保存する領域およびファイル名の指定
          //ボタン操作による画像の切り出し半自動保存に対応
          can.cutAndSaveImgX1 = Integer.parseInt(st2.nextToken().trim());
          can.cutAndSaveImgY1 = Integer.parseInt(st2.nextToken().trim());
          can.cutAndSaveImgX2 = Integer.parseInt(st2.nextToken().trim());
          can.cutAndSaveImgY2 = Integer.parseInt(st2.nextToken().trim());
          can.cutAndSaveImgFName =
            Util.trimAffix(st2.nextToken().trim(),'\"','\"');
        }
        else if(commandS.equals("Antialias"))
        { //●線（輪郭線を含む）のギザギザ緩和
          //この処理で、細い線の色が薄くなる
          String s1 = st2.nextToken().trim();
          if(s1.equals("true"))
            can.antialiasFlag = true;
          else
            can.antialiasFlag = false;
        }
        else if(commandS.equals("Size"))
        { //●画像の大きさ
        //Size(double w, double h)
        //w:    巾(px)
        //h:    丈(px)
          String s1 = st2.nextToken().trim();
          if(Util.countDelimiter(command1, ',') == 0)
          { //文字列１個を指定の場合
            if(s1.equals("\"A4\""))
            {  //常用判型は簡易指定可能
              can.printMM_W = 210; //mm
              can.printMM_H = 297;
              can.imagePX_W = 210*3; //mm→px変換（便宜的独自規格）
              can.imagePX_H = 297*3; //印刷時には、サイズ調整を行なう
            }
            else if(s1.equals("\"B5\""))
            {
              can.printMM_W = 182; //mm
              can.printMM_H = 257;
              can.imagePX_W = 182*3; //mm→px変換（便宜的独自規格）
              can.imagePX_H = 257*3; //印刷時には、サイズ調整を行なう
            }
          }
          else if(Util.countDelimiter(command1, ',') == 1)
          { //数値２個を指定の場合（数値はピクセル単位）
            String s2 = st2.nextToken().trim();
            can.imagePX_W = Double.parseDouble(s1);
            can.imagePX_H = Double.parseDouble(s2);
            can.printMM_W = Double.parseDouble(s1)/3.0;
            can.printMM_H = Double.parseDouble(s2)/3.0;
          }
          else if(Util.countDelimiter(command1, ',') == 2)
          {  //数値２個と単位とを指定の場合
            String s2 = st2.nextToken().trim();
            String s3 = st2.nextToken().trim();
            if(s3.equals("\"px\"")) //ピクセル単位
            {
              can.printMM_W = Double.parseDouble(s1)/3.0;
              can.printMM_H = Double.parseDouble(s2)/3.0;
              can.imagePX_W = Double.parseDouble(s1);
              can.imagePX_H = Double.parseDouble(s2);
            }
            else if(s3.equals("\"mm\"")) //ミリ単位
            { //ミリ単位は、印刷での紙サイズをミリ単位で表わすだけである。
              //その他の描画時の各種サイズ指定は、文字サイズを除き、全てピクセル。
              can.printMM_W = Double.parseDouble(s1);
              can.printMM_H = Double.parseDouble(s2);
              can.imagePX_W = Double.parseDouble(s1)*3.0;
              can.imagePX_H = Double.parseDouble(s2)*3.0;
            }
          }
          else
          {
            f.message(command1 + " >>引数に異常");
            return;
          }
        }
        else if(commandS.equals("BackgroundColor"))
        { //●背景色の指定
        //BackgroundColor(int r, int g, int b)
        //r:     赤色成分　0-255
        //g:     緑色成分　0-255
        //b:     青色成分　0-255
          int red   = Integer.parseInt(st2.nextToken().trim());
          int green = Integer.parseInt(st2.nextToken().trim());
          int blue  = Integer.parseInt(st2.nextToken().trim());
          if(red>255)
          {
            red = 255;
            f.message("色指定の上限は255です。");
          }
          if(green>255)
          {
            green = 255;
            f.message("色指定の上限は255です。");
          }
          if(blue>255)
          {
            blue = 255;
            f.message("色指定の上限は255です。");
          }
          can.backgroundColor = new Color(red, green, blue);
        }
        else if(commandS.equals("Image"))
        { //●背景画像の表示指定
        //Image(int x, int y, int w, int h, String fileName)
        //x:     表示ｘ座標位置
        //y:     表示ｙ座標位置
        //w:     画像の表示幅
        //h:     画像の表示丈
        //fileName:画像ファイル・ネーム（パス含む）
          can.imageFlag = true;
          int[]  imgI = new int[4]; //複数画像を別位置に表示可能
          imgI[0] = Integer.parseInt(st2.nextToken().trim()); //x
          imgI[1] = Integer.parseInt(st2.nextToken().trim()); //y
          imgI[2] = Integer.parseInt(st2.nextToken().trim()); //w
          imgI[3] = Integer.parseInt(st2.nextToken().trim()); //h
          can.imageListI.add(imgI);
          String imgF;
          imgF = Util.trimAffix(st2.nextToken().trim(),'\"','\"');//file path
          can.imageListF.add(imgF);
        }
        else if(commandS.equals("Stamp"))
        { //●スタンプ画像の表示指定
        //Stamp(int x, int y, int w, int h, String f)
        //x:     表示ｘ座標位置
        //y:     表示ｙ座標位置
        //w:     画像の表示幅
        //h:     画像の表示丈
        //f:     画像ファイル（パス含む）
          int[]  stmI = new int[4]; //複数画像を別位置に表示可能
          stmI[0] = Integer.parseInt(st2.nextToken().trim()); //x
          stmI[1] = Integer.parseInt(st2.nextToken().trim()); //y
          stmI[2] = Integer.parseInt(st2.nextToken().trim()); //w
          stmI[3] = Integer.parseInt(st2.nextToken().trim()); //h
          can.stampListI.add(stmI);
          String stmF;
          stmF = Util.trimAffix(st2.nextToken().trim(),'\"','\"');//file path
          can.stampListF.add(stmF);
          can.stampFlag = true;
        }
        else if(commandS.equals("StampMulti"))
        { //●スタンプ画像の表示指定の連続処理
        //StampMulti(int x, int y, int w, int h, int sx, int sy, int tx, int ty, String f)
        //x:     当初表示ｘ座標位置
        //y:     当初表示ｙ座標位置
        //w:     画像の表示幅
        //h:     画像の表示丈
        //sx:    画像の横方向スキップのピクセル数
        //sy:    画像の縦方向スキップのピクセル数
        //tx:    画像の横方向表示反復回数
        //ty:    画像の縦方向表示反復回数
        //f:     画像ファイル（パス含む）
          int x    = Integer.parseInt(st2.nextToken().trim());
          int y    = Integer.parseInt(st2.nextToken().trim());
          int w    = Integer.parseInt(st2.nextToken().trim());
          int h    = Integer.parseInt(st2.nextToken().trim());
          int sx   = Integer.parseInt(st2.nextToken().trim());
          int sy   = Integer.parseInt(st2.nextToken().trim());
          int tx   = Integer.parseInt(st2.nextToken().trim());
          int ty   = Integer.parseInt(st2.nextToken().trim());
          String f = Util.trimAffix(st2.nextToken().trim(),'\"','\"');

          //Stamp命令の反復に変換する
          for(int p=0; p<ty; p++)
          {
            for(int q=0; q<tx; q++)
            {
              int[]  stmI = new int[4];
              stmI[0] = x + sx*q; //x位置
              stmI[1] = y + sy*p; //y位置
              stmI[2] = w; //w
              stmI[3] = h; //h
              can.stampListI.add(stmI);
              can.stampListF.add(f);
            }
          }
          can.stampFlag = true;
        }
        else if(commandS.equals("CutAndPasteMask"))
        { //●切り貼り画像合成でのマルチ・マスク指定
        //CutAndPasteMask(String fileName)
        //fileName:マルチ・マスク画像ファイル（パス含む）
          can.cutAndPasteMaskFlag = true;
          can.capMaskF = Util.trimAffix(st2.nextToken().trim(),'\"','\"');//file path;
        }
        else if(commandS.equals("CutAndPaste"))
        { //●切り貼り画像合成の実行
        //CutAndPaste(String fileName, int r, int g, int b)
        //fileName:模様画像ファイル（パス含む）
        //r:      マスク画像切り貼り部分の色相赤成分
        //g:
        //b:
          can.cutAndPasteFlag = true;
          can.capListF.add(Util.trimAffix(st2.nextToken().trim(),'\"','\"'));
          int[]  capI = new int[3]; //マルチ・マスクの色分け指定色
          capI[0] = Integer.parseInt(st2.nextToken().trim()); //r
          capI[1] = Integer.parseInt(st2.nextToken().trim()); //g
          capI[2] = Integer.parseInt(st2.nextToken().trim()); //b
          can.capListI.add(capI);
        }
        else if(commandS.equals("ChangeColorMultiBase"))
        { //●連続色相変更でのベース画像指定
        //ChangeColorMultiBase(String fileName)
        //fileName:連続色相変更ベース画像ファイル（パス含む）
          can.changeColorMultiBaseFlag = true;
          can.ccmMaskF = Util.trimAffix(st2.nextToken().trim(),'\"','\"');//file path;
        }
        else if(commandS.equals("ChangeColorMulti"))
        { //●連続色相変更の実行
        //ChangeColorMulti(int r0, int g0, int b0, int r1, int g1, int b1)
        //r0:      旧色の色相赤成分
        //g0:
        //b0:
        //r1:      新色の色相赤成分
        //g1:
        //b1:
          can.changeColorMultiFlag = true;
          int[]  ccmI0 = new int[3]; //旧画像　指定色　数値データ
          ccmI0[0] = Integer.parseInt(st2.nextToken().trim()); //r
          ccmI0[1] = Integer.parseInt(st2.nextToken().trim()); //g
          ccmI0[2] = Integer.parseInt(st2.nextToken().trim()); //b
          can.ccmListI0.add(ccmI0);
          int[]  ccmI1 = new int[3]; //新画像　指定色　数値データ
          ccmI1[0] = Integer.parseInt(st2.nextToken().trim()); //r
          ccmI1[1] = Integer.parseInt(st2.nextToken().trim()); //g
          ccmI1[2] = Integer.parseInt(st2.nextToken().trim()); //b
          can.ccmListI1.add(ccmI1);
        }
        else if(commandS.equals("ChangeColorInner"))
        { //●輪郭線で囲まれた図形の内部を指定色で塗り直す。
          //塗り直し対象領域は、輪郭線で囲まれた図形の内部の代表位置を、
          //xy座標位置で指定しなければならない。
          //その座標位置（１ピクセル分）を初期設定として指定色で彩色した後、
          //プログラムが全体をスキャンしながら指定色のありかを探し出し、その領域拡大を行なう。
        //ChangeColorInner(String f. int r0, int g0, int b0, int r1, int g1, int b1, int x, int y, int mode)
        //f:       塗り直し対象輪郭線画像ファイル名（パス含む）
        //r0:      輪郭線色
        //g0:
        //b0:
        //r1:      彩色指定色
        //g1:
        //b1:
        //x:       図形内側代表位置のx座標
        //y:       図形内側代表位置のy座標
        //mode     輪郭線も塗り直すかの可否（０は否、１は可）
          can.changeColorInnerFlag = true;
          can.changeColorInnerF = Util.trimAffix(st2.nextToken().trim(),'\"','\"');
          can.cciOutLineColorR  = Integer.parseInt(st2.nextToken().trim());
          can.cciOutLineColorG  = Integer.parseInt(st2.nextToken().trim());
          can.cciOutLineColorB  = Integer.parseInt(st2.nextToken().trim());
          can.cciInnerColorR    = Integer.parseInt(st2.nextToken().trim());
          can.cciInnerColorG    = Integer.parseInt(st2.nextToken().trim());
          can.cciInnerColorB    = Integer.parseInt(st2.nextToken().trim());
          can.cciInnerX         = Integer.parseInt(st2.nextToken().trim());
          can.cciInnerY         = Integer.parseInt(st2.nextToken().trim());
          can.cciMode           = Integer.parseInt(st2.nextToken().trim());
        }
        else if(commandS.equals("ChangeColorInnerMultiMask"))
        { //●輪郭線で囲まれた図形の特定領域を指定色で連続的に塗り直すための統一指定。
        //輪郭線画像は、白地図形式で塗り分けられる状態にあるものとする。
        //輪郭線（共用輪郭線）は、塗り直し対象外であって、そのままの色で残る。
        //輪郭線を隠すには、最終段階でソフト・フォーカスおよびスタンプで対処。
        //複雑に屈曲した輪郭線図形で、その内部彩色処理を高速化するには、点描画機能などを用い、
        //彩色部の数箇所に指定色を予め塗っておくこと。
        //ChangeColorInnerMultiMask(String f. int r, int g, int b)
        //f:       塗り直し対象輪郭線画像ファイル名（パス含む）
        //r:       輪郭線色
        //g:
        //b:
          can.changeColorInnerMultiFlag = true;
          can.changeColorInnerMultiF = Util.trimAffix(st2.nextToken().trim(),'\"','\"');
          can.ccimOutLineColorR  = Integer.parseInt(st2.nextToken().trim());
          can.ccimOutLineColorG  = Integer.parseInt(st2.nextToken().trim());
          can.ccimOutLineColorB  = Integer.parseInt(st2.nextToken().trim());
        }
        else if(commandS.equals("ChangeColorInnerMulti"))
        { //●輪郭線で囲まれた図形の内部を指定色で連続的に塗り直すための個別指定。
        //ChangeColorInnerMulti(int r, int g, int b, int x, int y,)
        //r:       彩色指定色
        //g:
        //b:
        //x:       図形内側彩色領域代表位置のx座標
        //y:       図形内側彩色領域代表位置のy座標
          int[]  intArr = new int[5]; //
          intArr[0] = Integer.parseInt(st2.nextToken().trim()); //r
          intArr[1] = Integer.parseInt(st2.nextToken().trim()); //g
          intArr[2] = Integer.parseInt(st2.nextToken().trim()); //b
          intArr[3] = Integer.parseInt(st2.nextToken().trim()); //x
          intArr[4] = Integer.parseInt(st2.nextToken().trim()); //y
          can.ccimListI.add(intArr);
        }
        else if(commandS.equals("MixImage"))
        { //●ミックス画像（二重像画像）の合成指定
          if(st2.countTokens() == 2 && Util.countDelimiter(command1, ',') == 1)
          {

            //MixImage(String fileName1, String fileName2)
            //fileName1:元画像ファイル（パス含む）
            //fileName2:追加画像ファイル名（パス含む）
            can.mixFName0 = Util.trimAffix(st2.nextToken().trim(),'\"','\"');//file path
            can.mixFName1 = Util.trimAffix(st2.nextToken().trim(),'\"','\"');//file path
          }
          else if(st2.countTokens() == 3 && Util.countDelimiter(command1, ',') == 2)
          {
            //MixImage(int mixMode, String fileName1, String fileName2)
            //mixMode:画像の拡大縮小を伴わないStamp押印として機能するモードの指定（０を指定）
            //fileName1:元画像ファイル名（パス含む）
            //fileName2:追加画像ファイル名（パス含む）
            can.mixMode = Integer.parseInt(st2.nextToken().trim());
            can.mixFName0 = Util.trimAffix(st2.nextToken().trim(),'\"','\"');//file path
            can.mixFName1 = Util.trimAffix(st2.nextToken().trim(),'\"','\"');//file path
            if(can.mixMode!=0 && can.mixMode!=1)
            {
              can.mixMode = 1;
              f.message(command1 + " >>モード指定が異常のため、通常モードにしました。");
            }
          }
          else
          {
            f.message(command1 + " >>引数が異常。");
            return;
          }
        }
        else if(commandS.equals("SoftFocus"))
        { //●ソフト・フォーカス効果要求
        //SoftFocus(String f, int d)
        //f:     元画像ファイル（パス含む）
        //d:     ソフト・フォーカスの度合い（０～１００）
          can.softFocusFName = Util.trimAffix(st2.nextToken().trim(),'\"','\"');
          can.softFocusDegree = Integer.parseInt(st2.nextToken().trim());
          if(can.softFocusDegree > 100)
            can.softFocusDegree = 100;
          if(can.softFocusDegree < 0)
            can.softFocusDegree = 0;
        }
        else if(commandS.equals("AdjustRGB"))
        { //●色成分RGB加減調整（特定の色相の微調整）
        //AdjustRGB(String f, int r, int g, int b)
        //f:     元画像ファイル名（パス含む）
        //r:     赤色成分の加減量（－１００～１００％）
        //g:
        //b:
          can.adjustFName = Util.trimAffix(st2.nextToken().trim(),'\"','\"');
          can.adjustR = Integer.parseInt(st2.nextToken().trim());
          can.adjustG = Integer.parseInt(st2.nextToken().trim());
          can.adjustB = Integer.parseInt(st2.nextToken().trim());
          if(can.adjustR>100) can.adjustR = 100;
          if(can.adjustG>100) can.adjustG = 100;
          if(can.adjustB>100) can.adjustB = 100;
          if(can.adjustR<-100) can.adjustR = -100;
          if(can.adjustG<-100) can.adjustG = -100;
          if(can.adjustB<-100) can.adjustB = -100;
        }
        else if(commandS.equals("ColorGradient"))
        { //●色彩階調効果の追加
        //ColorGradient(String fName, int m, int y1, int y2,
        //  double r, double g, double b)
        //fName:  元画像ファイル名（パス含む）
        //y1:     加工開始y軸位置
        //y2:     加工反転y軸位置
        //r:      赤成分の追加数値
        //g:      緑成分の追加数値
        //b:      青成分の追加数値
          if(st2.countTokens() != 6 || Util.countDelimiter(command1, ',') != 5)
          { //引数の個数が多いので、個数をチェック（以下同様）
            f.message(command1 + " >>引数の個数に異常");
            return;
          }
          can.gradientFName = Util.trimAffix(st2.nextToken().trim(),'\"','\"');
          can.gradientY1 = Integer.parseInt(st2.nextToken().trim());
          can.gradientY2 = Integer.parseInt(st2.nextToken().trim());
          can.gradientR = Double.parseDouble(st2.nextToken().trim());
          can.gradientG = Double.parseDouble(st2.nextToken().trim());
          can.gradientB = Double.parseDouble(st2.nextToken().trim());
        }
        else if(commandS.equals("ChangeColor"))
        { //●単独色相変更（近似色をも含めた単独色相変更）
        //ChangeColor(String fName,int c, int mode,
        //  int r1, int g1, int b1, int r2, int g2, int b2 )
        //ChangeColor(String fName,int c,
        //  int r1, int g1, int b1, int r2, int g2, int b2 )
        //fName:  元画像ファイル名（パス含む）
        //c:      指定色許容値
        //mode:   1が単純な色相変更で、2がグレー・マスクを生成
        //r1:     旧色
        //g1:
        //b1:
        //r2:     新色
        //g2:
        //b2:
          if(st2.countTokens() == 9 && Util.countDelimiter(command1, ',') == 8)
          {
            can.colorChangeFlag = true;
            can.colorChangeFile  = Util.trimAffix(st2.nextToken().trim(),'\"','\"');
            can.acceptableLimitC = Integer.parseInt(st2.nextToken().trim());
            can.colorChangeMode  = Integer.parseInt(st2.nextToken().trim());
            can.colorChange1R    = Integer.parseInt(st2.nextToken().trim());
            can.colorChange1G    = Integer.parseInt(st2.nextToken().trim());
            can.colorChange1B    = Integer.parseInt(st2.nextToken().trim());
            can.colorChange2R    = Integer.parseInt(st2.nextToken().trim());
            can.colorChange2G    = Integer.parseInt(st2.nextToken().trim());
            can.colorChange2B    = Integer.parseInt(st2.nextToken().trim());
          }
          else if(st2.countTokens() == 8 && Util.countDelimiter(command1, ',') == 7)
          {
            can.colorChangeFlag = true;
            can.colorChangeFile  = Util.trimAffix(st2.nextToken().trim(),'\"','\"');
            can.acceptableLimitC = Integer.parseInt(st2.nextToken().trim());
            can.colorChangeMode  = 1;
            can.colorChange1R    = Integer.parseInt(st2.nextToken().trim());
            can.colorChange1G    = Integer.parseInt(st2.nextToken().trim());
            can.colorChange1B    = Integer.parseInt(st2.nextToken().trim());
            can.colorChange2R    = Integer.parseInt(st2.nextToken().trim());
            can.colorChange2G    = Integer.parseInt(st2.nextToken().trim());
            can.colorChange2B    = Integer.parseInt(st2.nextToken().trim());
          }
          else
          {
            f.message(command1 + " >>引数の個数に異常");
            return;
          }
        }

        else if(commandS.equals("ReverseImage"))
        { //●画像反転（鏡像反転または直角系回転）
        //ReverseImage(String fName,int m)
        //fName:  元画像ファイル名（パス含む）
        //c:      反転モード（１～７）
          can.reverseImageFlag = true;
          can.reverseImageFile = Util.trimAffix(st2.nextToken().trim(),'\"','\"');
          can.reverseImageMode = Integer.parseInt(st2.nextToken().trim());
        }

        else if(commandS.equals("ForegroundColorL"))
        { //●前景色（線の色）の指定
        //ForegroundColorL(int r, int g, int b)
        //r:     赤色成分　0-255
        //g:     緑色成分　0-255
        //b:     青色成分　0-255
          int red   = Integer.parseInt(st2.nextToken().trim());
          int green = Integer.parseInt(st2.nextToken().trim());
          int blue  = Integer.parseInt(st2.nextToken().trim());
          if(red>255)
          {
            red = 255;
            f.message("色指定の上限は255です。");
          }
          if(green>255)
          {
            green = 255;
            f.message("色指定の上限は255です。");
          }
          if(blue>255)
          {
            blue = 255;
            f.message("色指定の上限は255です。");
          }
          can.foregroundColorL = new Color(red, green, blue);
        }
        else if(commandS.equals("ForegroundColorS"))
        { //●前景色（文字の色）の指定
        //ForegroundColorS(int r, int g, int b)
        //r:     赤色成分　0-255
        //g:     緑色成分　0-255
        //b:     青色成分　0-255
          int red   = Integer.parseInt(st2.nextToken().trim());
          int green = Integer.parseInt(st2.nextToken().trim());
          int blue  = Integer.parseInt(st2.nextToken().trim());
          if(red>255)
          {
            red = 255;
            f.message("色指定の上限は255です。");
          }
          if(green>255)
          {
            green = 255;
            f.message("色指定の上限は255です。");
          }
          if(blue>255)
          {
            blue = 255;
            f.message("色指定の上限は255です。");
          }
          can.foregroundColorS = new Color(red, green, blue);
        }
        else if(commandS.equals("ForegroundColorB"))
        { //●前景色（極太文字の色）の指定
        //ForegroundColorB(int r, int g, int b)
        //r:     赤色成分　0-255
        //g:     緑色成分　0-255
        //b:     青色成分　0-255
          int red   = Integer.parseInt(st2.nextToken().trim());
          int green = Integer.parseInt(st2.nextToken().trim());
          int blue  = Integer.parseInt(st2.nextToken().trim());
          if(red>255)
          {
            red = 255;
            f.message("色指定の上限は255です。");
          }
          if(green>255)
          {
            green = 255;
            f.message("色指定の上限は255です。");
          }
          if(blue>255)
          {
            blue = 255;
            f.message("色指定の上限は255です。");
          }
          can.foregroundColorB = new Color(red, green, blue);
        }
        else if(commandS.equals("AffineScale"))
        { //●標準の拡大率の指定（印刷に反映されない）
        //AffineScale(double scale)
        //scale:  表示、画像保存に有効な拡大倍率
          can.affineScale = Double.parseDouble(st2.nextToken().trim());
          f.scaleLabel.setText("　(a:x" + can.affineScale + ")");
        }
        else if(commandS.equals("FreeScale"))
        { //●任意の拡大率の指定（印刷にも反映される）
        //FreeScale(double scale)
        //scale:  表示、画像保存、印刷に有効な拡大倍率
          can.freeScale = Double.parseDouble(st2.nextToken().trim());
          f.scaleLabel2.setText("　(f:x" + can.freeScale + ")");
        }
        else if(commandS.equals("Shift"))
        { //●全体の画像をずらす指定
        //Shift(int mode, double x, double y)
        //mode:   0がシフトなし、1がシフトあり
        //x:    X軸のシフト量
        //y:    Y軸のシフト量
          can.shiftMode = Integer.parseInt(st2.nextToken().trim());
          can.shiftX = Double.parseDouble(st2.nextToken().trim());
          can.shiftY = Double.parseDouble(st2.nextToken().trim());
        }
        else if(commandS.equals("LineWidth"))
        { //●線の太さ指定
        //LineWidth(float width)
        //width:  線の太さ
          can.lineWidth = Float.parseFloat(st2.nextToken().trim());
        }
        else if(commandS.equals("DrawLine"))
        { //●直線の描画指定
        //DrawLine(double x1, double y1, double x2, double y2)
        //x1:  起点座標X
        //y1:  起点座標Y
        //x2:  終点座標X
        //y2:  終点座標Y
          double[] d = new double[4];
          d[0] = Double.parseDouble(st2.nextToken().trim());
          d[1] = Double.parseDouble(st2.nextToken().trim());
          d[2] = Double.parseDouble(st2.nextToken().trim());
          d[3] = Double.parseDouble(st2.nextToken().trim());
          can.lineList.add(d);
        }
        else if(commandS.equals("DrawLine2"))  //マウス操作時に一時的使用
        { //●仮直線の描画指定
        //Draw2(int m; double x1, double y1, double x2, double y2)
        // m:  モード
        //x1:  起点座標X
        //y1:  起点座標Y
        //x2:  終点座標X
        //y2:  終点座標Y
          double[] d = new double[5];
          d[0] = Double.parseDouble(st2.nextToken().trim());
          d[1] = Double.parseDouble(st2.nextToken().trim());
          d[2] = Double.parseDouble(st2.nextToken().trim());
          d[3] = Double.parseDouble(st2.nextToken().trim());
          d[4] = Double.parseDouble(st2.nextToken().trim());
          can.line2List.add(d);
        }
        else if(commandS.equals("DrawParallelLineH"))
        { //●横平行線の描画指定
        //DrawParallelLineH(double x, double y, double l, double w, int t, int m)
        //x:  起点座標X
        //y:  起点座標Y
        //l:  線の長さ
        //w:  線の間隔
        //t:  線の本数
        //m:  線の種類（０：実線、１：密点線、２：粗点線）
        //h:  中間線の有無（０：無し、１：有り）
          if(st2.countTokens() != 7 || Util.countDelimiter(command1, ',') != 6)
          {
            f.message(command1 + " >>引数の個数に異常");
            return;
          }
          can.parallelLineH_x = Double.parseDouble(st2.nextToken().trim());
          can.parallelLineH_y = Double.parseDouble(st2.nextToken().trim());
          can.parallelLineH_l = Double.parseDouble(st2.nextToken().trim());
          can.parallelLineH_w = Double.parseDouble(st2.nextToken().trim());
          can.parallelLineH_t = Integer.parseInt(st2.nextToken().trim());
          can.parallelLineH_m = Integer.parseInt(st2.nextToken().trim());
          can.parallelLineH_h = Integer.parseInt(st2.nextToken().trim());
        }
        else if(commandS.equals("DrawParallelLineV"))
        { //●縦平行線の描画指定
        //DrawParallelLineV(double x, double y, double l, double w, int t, int m)
        //x:  起点座標X
        //y:  起点座標Y
        //l:  線の長さ
        //w:  線の間隔
        //t:  線の本数
        //m:  線の種類（０：実線、１：密点線、２：粗点線）
        //h:  中間線の有無（０：無し、１：有り）
          if(st2.countTokens() != 7 || Util.countDelimiter(command1, ',') != 6)
          {
            f.message(command1 + " >>引数の個数に異常");
            return;
          }
          can.parallelLineV_x = Double.parseDouble(st2.nextToken().trim());
          can.parallelLineV_y = Double.parseDouble(st2.nextToken().trim());
          can.parallelLineV_l = Double.parseDouble(st2.nextToken().trim());
          can.parallelLineV_w = Double.parseDouble(st2.nextToken().trim());
          can.parallelLineV_t = Integer.parseInt(st2.nextToken().trim());
          can.parallelLineV_m = Integer.parseInt(st2.nextToken().trim());
          can.parallelLineV_h = Integer.parseInt(st2.nextToken().trim());
        }
        else if(commandS.equals("DrawParallelLineH2"))
        { //●横平行線の描画指定（補助用）
        //DrawParallelLineH2(double x, double y, double l, double w, int t, int m)
        //x:  起点座標X
        //y:  起点座標Y
        //l:  線の長さ
        //w:  線の間隔
        //t:  線の本数
        //m:  線の種類（０：実線、１：密点線、２：粗点線）
        //h:  中間線の有無（０：無し、１：有り）
          if(st2.countTokens() != 7 || Util.countDelimiter(command1, ',') != 6)
          {
            f.message(command1 + " >>引数の個数に異常");
            return;
          }
          can.parallelLineH2_x = Double.parseDouble(st2.nextToken().trim());
          can.parallelLineH2_y = Double.parseDouble(st2.nextToken().trim());
          can.parallelLineH2_l = Double.parseDouble(st2.nextToken().trim());
          can.parallelLineH2_w = Double.parseDouble(st2.nextToken().trim());
          can.parallelLineH2_t = Integer.parseInt(st2.nextToken().trim());
          can.parallelLineH2_m = Integer.parseInt(st2.nextToken().trim());
          can.parallelLineH2_h = Integer.parseInt(st2.nextToken().trim());
        }
        else if(commandS.equals("DrawParallelLineV2"))
        { //●縦平行線の描画指定（補助用）
        //DrawParallelLineV2(double x, double y, double l, double w, int t, int m)
        //x:  起点座標X
        //y:  起点座標Y
        //l:  線の長さ
        //w:  線の間隔
        //t:  線の本数
        //m:  線の種類（０：実線、１：密点線、２：粗点線）
        //h:  中間線の有無（０：無し、１：有り）
          if(st2.countTokens() != 7 || Util.countDelimiter(command1, ',') != 6)
          {
            f.message(command1 + " >>引数の個数に異常");
            return;
          }
          can.parallelLineV2_x = Double.parseDouble(st2.nextToken().trim());
          can.parallelLineV2_y = Double.parseDouble(st2.nextToken().trim());
          can.parallelLineV2_l = Double.parseDouble(st2.nextToken().trim());
          can.parallelLineV2_w = Double.parseDouble(st2.nextToken().trim());
          can.parallelLineV2_t = Integer.parseInt(st2.nextToken().trim());
          can.parallelLineV2_m = Integer.parseInt(st2.nextToken().trim());
          can.parallelLineV2_h = Integer.parseInt(st2.nextToken().trim());
        }
        else if(commandS.equals("DrawCurve"))
        { //●ベジェ曲線の描画指定
        //DrawCurve(double x1, double y1, double x2, double y2,
        //  double x3, double y3, double x4, double y4)
        //x1:  起点座標X
        //y1:  起点座標Y
        //x2:  第一制御点座標X
        //y2:  第一制御点座標Y
        //x3:  第二制御点座標X
        //y3:  第二制御点座標Y
        //x4:  終点座標X
        //y4:  終点座標Y
          if(st2.countTokens() != 8 || Util.countDelimiter(command1, ',') != 7)
          {
            f.message(command1 + " >>引数の個数に異常");
            return;
          }
          double[] d = new double[8];
          d[0] = Double.parseDouble(st2.nextToken().trim());
          d[1] = Double.parseDouble(st2.nextToken().trim());
          d[2] = Double.parseDouble(st2.nextToken().trim());
          d[3] = Double.parseDouble(st2.nextToken().trim());
          d[4] = Double.parseDouble(st2.nextToken().trim());
          d[5] = Double.parseDouble(st2.nextToken().trim());
          d[6] = Double.parseDouble(st2.nextToken().trim());
          d[7] = Double.parseDouble(st2.nextToken().trim());
          can.curveList.add(d);
        }
        else if(commandS.equals("DrawSplineStart"))
        { //●スプライン曲線の描画指定（起点）
        //DrawSplineStart(double cmd, double x, double y)
        //cmd: 命令識別番号（定数0）
        //x1:  起点座標X
        //y1:  起点座標Y
          double[] d = new double[3];
          d[0] = 0;
          d[1] = Double.parseDouble(st2.nextToken().trim());
          d[2] = Double.parseDouble(st2.nextToken().trim());
          can.splineList.add(d);
        }
        else if(commandS.equals("DrawSplineControl"))
        { //●スプライン曲線の描画指定（制御点）
        //DrawSplineStart(double cmd, double x, double y)
        //cmd: 命令識別番号（定数1）
        //x1:  制御点座標X
        //y1:  制御点座標Y
          double[] d = new double[3];
          d[0] = 1;
          d[1] = Double.parseDouble(st2.nextToken().trim());
          d[2] = Double.parseDouble(st2.nextToken().trim());
          can.splineList.add(d);
        }
        else if(commandS.equals("DrawSplineEnd"))
        { //●スプライン曲線の描画指定（終点）
        //DrawSplineEnd(double cmd, double x, double y)
        //cmd: 命令識別番号（定数2）
        //x1:  終点座標X
        //y1:  終点座標Y
          double[] d = new double[3];
          d[0] = 2;
          d[1] = Double.parseDouble(st2.nextToken().trim());
          d[2] = Double.parseDouble(st2.nextToken().trim());
          can.splineList.add(d);
        }
        else if(commandS.equals("DrawSplineOp"))
        { //●スプライン曲線の描画指定（曲線精細度オプション）
        //DrawSplineOp(int op)
        //op: 曲線を構成する短い直線の本数
          can.splineOption = Integer.parseInt(st2.nextToken().trim());
        }

        //●●色塗り図形描画命令「解読」グループの始まり（命令識別を添加）

        //●自由図形の描画指定
        else if(commandS.equals("DrawShapeStart"))
        //DrawShapeStart(int m, double x,double y, int r, int g, int b)
        //m:  描画モード指定
        //x:  自由図形の起点座標X
        //y:  自由図形の起点座標Y
        //r:  赤色成分　0-255
        //g:  緑色成分　0-255
        //b:  青色成分　0-255
        {
          if(st2.countTokens() != 6 || Util.countDelimiter(command1, ',') != 5)
          {
            f.message(command1 + " >>引数の個数に異常");
            return;
          }
          shape = new double[9];
          shape[0] = 0; //命令識別（DrawShapeStart）
          shape[1] = Double.parseDouble(
            st2.nextToken().trim()); //m
          shape[2] = Double.parseDouble(
            st2.nextToken().trim()); //x
          shape[3] = Double.parseDouble(
            st2.nextToken().trim()); //y
          shape[4] = Integer.parseInt(
            st2.nextToken().trim()); //r
          shape[5] = Integer.parseInt(
            st2.nextToken().trim()); //g
          shape[6] = Integer.parseInt(
            st2.nextToken().trim()); //b
          shape[7] = 0; //dummy
          shape[8] = 0; //dummy
          can.shapeList.add(shape);
        }
        else if(commandS.equals("DrawShapeLine"))
        //DrawShapeLine(double x,double y)
        //x:  直線終点座標X
        //y:  直線終点座標Y
        {
          shape = new double[9];
          shape[0] = -1; //命令識別（DrawShapeLine）
          shape[1] = Double.parseDouble(
            st2.nextToken().trim()); //x
          shape[2] = Double.parseDouble(
            st2.nextToken().trim()); //y
          shape[3] = 0; //dummy
          shape[4] = 0; //dummy
          shape[5] = 0; //dummy
          shape[6] = 0; //dummy
          shape[7] = 0; //dummy
          shape[8] = 0; //dummy
          can.shapeList.add(shape);
        }
        else if(commandS.equals("DrawShapeCurve"))
        //DrawShapeCurve(double x1,double y1,double x2,double y2,
        //  double x3,double y3)
        //x1:  曲線部第一制御点座標X
        //y1:  曲線部第一制御点座標Y
        //x2:  曲線部第二制御点座標X
        //y2:  曲線部第二制御点座標Y
        //x3:  曲線部終点座標X
        //y3:  曲線部終点座標Y
        {
          if(st2.countTokens() != 6 || Util.countDelimiter(command1, ',') != 5)
          {
            f.message(command1 + " >>引数の個数に異常");
            return;
          }
          shape = new double[9];
          shape[0] = -2; //命令識別（DrawShapeCurve）
          shape[1] = Double.parseDouble(
            st2.nextToken().trim()); //x1
          shape[2] = Double.parseDouble(
            st2.nextToken().trim()); //y1
          shape[3] = Double.parseDouble(
            st2.nextToken().trim()); //x2
          shape[4] = Double.parseDouble(
            st2.nextToken().trim()); //y2
          shape[5] = Double.parseDouble(
            st2.nextToken().trim()); //x3
          shape[6] = Double.parseDouble(
            st2.nextToken().trim()); //y3
          shape[7] = 0; //dummy
          shape[8] = 0; //dummy
          can.shapeList.add(shape);
        }
        else if(commandS.equals("DrawShapeEnd"))
        //DrawShapeEnd()
        //  引数なし。自由図形の終結宣言
        {
          shape = new double[9];
          shape[0] = -3; //命令識別（DrawShapeEnd）
          shape[1] = 0; //dummy
          shape[2] = 0; //dummy
          shape[3] = 0; //dummy
          shape[4] = 0; //dummy
          shape[5] = 0; //dummy
          shape[6] = 0; //dummy
          shape[7] = 0; //dummy
          shape[8] = 0; //dummy
          can.shapeList.add(shape);
        }
        else if(commandS.equals("DrawRect"))
        { //●長方形
        //DrawRect(int m, int x, int y, int w, int h, int r, int g, int b)
        //m:  描画モード、0は描画せず、1は線、2は色塗り、3は線と色
        //    4は線描と透明色塗り
        //x:  ｘ座標
        //y:  ｙ座標
        //w:  幅
        //h:  丈
        //r:  R
        //g:  G
        //b:  B
          if(st2.countTokens() != 8 || Util.countDelimiter(command1, ',') != 7)
          {
            f.message(command1 + " >>引数の個数に異常");
            return;
          }
          double[] d = new double[9];
           d[0] = -4; //命令識別（DrawRect）
           d[1] = Double.parseDouble(st2.nextToken().trim()); //m
           d[2] = Double.parseDouble(st2.nextToken().trim()); //x
           d[3] = Double.parseDouble(st2.nextToken().trim()); //y
           d[4] = Double.parseDouble(st2.nextToken().trim()); //w
           d[5] = Double.parseDouble(st2.nextToken().trim()); //h
           d[6] = Double.parseDouble(st2.nextToken().trim()); //r
           d[7] = Double.parseDouble(st2.nextToken().trim()); //g
           d[8] = Double.parseDouble(st2.nextToken().trim()); //b
           can.shapeList.add(d);
        }
        else if(commandS.equals("DrawEllipse"))
        { //●楕円の描画指定
        //DrawEllipse(double m, double x, double y,
        //  double hr, double vr, double r, double g, double b)
        //m:  描画モード、0は描画せず、1は線、2は色塗り、3は線と色
        //    4は線描と透明色塗り
        //x:  楕円の中心のｘ座標
        //y:  楕円の中心のｙ座標
        //hr: 横半径
        //vr: 縦半径
        //r:  赤色
        //g:  緑色
        //b:  青色
          if(st2.countTokens() != 8 || Util.countDelimiter(command1, ',') != 7)
          {
            f.message(command1 + " >>引数の個数に異常");
            return;
          }
          double[] d = new double[9];
          d[0] = -5; //命令識別（DrawEllipse）
          d[1] = Double.parseDouble(st2.nextToken().trim()); //m
          d[2] = Double.parseDouble(st2.nextToken().trim()); //x
          d[3] = Double.parseDouble(st2.nextToken().trim()); //y
          d[4] = Double.parseDouble(st2.nextToken().trim()); //hr
          d[5] = Double.parseDouble(st2.nextToken().trim()); //vr
          d[6] = Double.parseDouble(st2.nextToken().trim()); //r
          d[7] = Double.parseDouble(st2.nextToken().trim()); //g
          d[8] = Double.parseDouble(st2.nextToken().trim()); //b
          can.shapeList.add(d);
        }
        else if(commandS.equals("DrawCircle"))
        { //●真円の描画指定
        //DrawCircle(double m, double x, double y,
        //  double rr, double r, double g, double b)
        //m:  描画モード、0は描画せず、1は線、2は色塗り、3は線と色
        //    4は線描と透明色塗り
        //x:  円の中心のｘ座標
        //y:  円の中心のｙ座標
        //rr: 半径
        //r:  赤色
        //g:  緑色
        //b:  青色
          if(st2.countTokens() != 7 || Util.countDelimiter(command1, ',') != 6)
          {
            f.message(command1 + " >>引数の個数に異常");
            return;
          }
          double[] d = new double[9];
          d[0] = -5; //命令識別（DrawEllipse）
          d[1] = Double.parseDouble(st2.nextToken().trim()); //m
          d[2] = Double.parseDouble(st2.nextToken().trim()); //x
          d[3] = Double.parseDouble(st2.nextToken().trim()); //y
          d[4] = Double.parseDouble(st2.nextToken().trim()); //rr
          d[5] = d[4];
          d[6] = Double.parseDouble(st2.nextToken().trim()); //r
          d[7] = Double.parseDouble(st2.nextToken().trim()); //g
          d[8] = Double.parseDouble(st2.nextToken().trim()); //b
          can.shapeList.add(d);
        }
        //●●色塗り図形描画命令「解読」グループの終わり

        else if(commandS.equals("FontBold"))
        { //●太字指定
        //FontBold(bool b)
        //b:        太字指定ならtrue
          String value = st2.nextToken().trim();
          if(value.equals("true"))
          {
            can.fontBold = true;
          }
          else
          {
            can.fontBold = false;
          }
        }
        else if(commandS.equals("WriteStringH") || commandS.equals("WriteString"))
        { //●文字列の描画指定（省略形の「WriteString」も許容）
        //WriteStringH(double x,double y,int size, string style, string s)
        //x:   ｘ座標
        //y:   ｙ座標
        //size:  フォント・サイズ
        //style: 字形（"sansserif" / "serif"）
        //s:   表示する文字列
          double[] d = new double[3];
          String[] s = new String[2];
          d[0] = Double.parseDouble(st2.nextToken().trim()); //x
          d[1] = Double.parseDouble(st2.nextToken().trim()); //y
          d[2] = Double.parseDouble(st2.nextToken().trim()); //size
          s[0] = Util.trimAffix(st2.nextToken().trim(),'\"','\"');
          s[1] = Util.trimAffix(st2.nextToken().trim(),'\"','\"');
          can.stringHListD.add(d);
          can.stringHListS.add(s);
        }
        else if(commandS.equals("WriteStringB"))
        { //●文字列の描画指定（極太字）補助的用途
        //WriteStringB(double x,double y,int size, string style, string s)
        //x:   ｘ座標
        //y:   ｙ座標
        //size:  フォント・サイズ
        //style: 字形（sansserif / serif）
        //s:    表示する文字列
          double[] d = new double[3];
          String[] s = new String[2];
          d[0] = Double.parseDouble(st2.nextToken().trim()); //x
          d[1] = Double.parseDouble(st2.nextToken().trim()); //y
          d[2] = Double.parseDouble(st2.nextToken().trim()); //size
          s[0] = Util.trimAffix(st2.nextToken().trim(),'\"','\"');
          s[1] = Util.trimAffix(st2.nextToken().trim(),'\"','\"');
          can.stringBListD.add(d);
          can.stringBListS.add(s);
        }
        else if(commandS.equals("WriteStringBMulti"))
        { //●文字列の描画指定（極太字）の機能拡大。
          //極太文字を拡大しつつ輪郭を滑らかにする。
          //複数のWriteStringB命令に変換する。
        //WriteStringBMulti(double x,double y,int size,int px, string style, string s)
        //x:     ｘ座標
        //y:     ｙ座標
        //px:    文字シフトのピクセル数
        //size:  フォント・サイズ
        //style: 字形（sansserif / serif）
        //s:     表示する文字列
          double x = Double.parseDouble(st2.nextToken().trim()); //x
          double y = Double.parseDouble(st2.nextToken().trim()); //y
          double sz = Double.parseDouble(st2.nextToken().trim()); //font size
          double px = Double.parseDouble(st2.nextToken().trim()); //shiht pixel
          String s1 = Util.trimAffix(st2.nextToken().trim(),'\"','\"');
          String s2 = Util.trimAffix(st2.nextToken().trim(),'\"','\"');

          double[] d = new double[3];
          String[] s = new String[2];
          d[0] = x+px;
          d[1] = y+px;
          d[2] = sz;
          s[0] = s1;
          s[1] = s2;
          can.stringBListD.add(d);
          can.stringBListS.add(s);
          d = new double[3];
          s = new String[2];
          d[0] = x-px;
          d[1] = y-px;
          d[2] = sz;
          s[0] = s1;
          s[1] = s2;
          can.stringBListD.add(d);
          can.stringBListS.add(s);
          d = new double[3];
          s = new String[2];
          d[0] = x+px;
          d[1] = y-px;
          d[2] = sz;
          s[0] = s1;
          s[1] = s2;
          can.stringBListD.add(d);
          can.stringBListS.add(s);
          d = new double[3];
          s = new String[2];
          d[0] = x-px;
          d[1] = y+px;
          d[2] = sz;
          s[0] = s1;
          s[1] = s2;
          can.stringBListD.add(d);
          can.stringBListS.add(s);
          //---------------------------
          d = new double[3];
          s = new String[2];
          d[0] = x;
          d[1] = y+px;
          d[2] = sz;
          s[0] = s1;
          s[1] = s2;
          can.stringBListD.add(d);
          can.stringBListS.add(s);
          d = new double[3];
          s = new String[2];
          d[0] = x+px;
          d[1] = y;
          d[2] = sz;
          s[0] = s1;
          s[1] = s2;
          can.stringBListD.add(d);
          can.stringBListS.add(s);
          d = new double[3];
          s = new String[2];
          d[0] = x;
          d[1] = y-px;
          d[2] = sz;
          s[0] = s1;
          s[1] = s2;
          can.stringBListD.add(d);
          can.stringBListS.add(s);
          d = new double[3];
          s = new String[2];
          d[0] = x-px;
          d[1] = y;
          d[2] = sz;
          s[0] = s1;
          s[1] = s2;
          can.stringBListD.add(d);
          can.stringBListS.add(s);
        }
        else if(commandS.equals("WriteStringV"))
        { //●文字列の垂直描画指定（疑似縦書き）
        //「疑似縦書き」を実行すると、画像の精細度が低下するため、
        //この命令（WriteStringV）を使用しないことが望ましい。
        //WriteStringV(double x,double y,int size,
        //     string style, string s)
        //x:   ｘ座標
        //y:   ｙ座標
        //size:  フォント・サイズ
        //style: 字形（"sansserif" / "serif"）
        //s:   表示する文字列
          double[] d = new double[3];
          String[] s = new String[2];
          d[0] = Double.parseDouble(st2.nextToken().trim()); //x
          d[1] = Double.parseDouble(st2.nextToken().trim()); //y
          d[2] = Double.parseDouble(st2.nextToken().trim()); //size
          s[0] = Util.trimAffix(st2.nextToken().trim(),'\"','\"');
          s[1] = Util.trimAffix(st2.nextToken().trim(),'\"','\"');
          can.stringVListD.add(d);
          can.stringVListS.add(s);
        }
        else if(commandS.equals("Rotate"))
        { //●画像全体の90度回転指定
          //Rotate命令は、正方形の画像に対して行なうこと。
          //長方形画像なら、Size命令で指定した正方形の中にこれを収納し、
          //回転処理し保存した上で、事後的に必要部分を切り取る。
        //Rotate(bool b)
        //b:  trueの時だけ90度回転
          String value = st2.nextToken().trim();
          if(value.equals("true"))
            can.rotateFlag = true;
          else
            can.rotateFlag = false;
        }
        else if(commandS.equals("RotateFree"))
        { //●画像全体の指定角度回転指定
          //マトリックス・パターンの傾斜を想定した命令で、
          //巨大画像を作成し回転させて、事後的に必要部分を切り取る。
          //メニューの「見本」を参照。
        //RotateFree(int degree, int w, int h)
            can.rotateFreeFlag = true;
            can.affineDegreeFree = Integer.parseInt(st2.nextToken().trim());
            can.rotateFreeW = Integer.parseInt(st2.nextToken().trim());
            can.rotateFreeH = Integer.parseInt(st2.nextToken().trim());
        }
        else if(commandS.equals("RotateMulti"))
        { //●画像多段階回転重複描画
          //メニューの「見本」を参照。
        //RotateMulti(int startDegree, int degree, int times, String fName)
        //startDegree:      回転開始角度
        //degree:           回転角度
        //times:            回転回数
        //fName:            回転対象画像ファイル名
            can.rotateMultiFlag = true;
            can.rotateMultiStartDegree = Integer.parseInt(st2.nextToken().trim());
            can.rotateMultiDegree = Integer.parseInt(st2.nextToken().trim());
            can.rotateMultiTimes = Integer.parseInt(st2.nextToken().trim());
            can.rotateMultiF = Util.trimAffix(st2.nextToken().trim(),'\"','\"');
        }
        else if(commandS.equals("StripePattern"))
        { //●背景画像にランダム色のストライプ模様を表示
        //StripePattern(int stripePatternType,int stripeW,
        //  int stripePRedBase, int stripePGreenBase,int stripePBlueBase)
        //stripePatternType: ストライプ無効または水平または垂直、0/1/2
        //stripePatternW:    ストライプ幅
        //stripePRedBase:    赤基調色
        //stripePGreenBase:  緑基調色
        //stripePBlueBase:   青基調色
          if(st2.countTokens() != 5 || Util.countDelimiter(command1, ',') != 4)
          {
            f.message(command1 + " >>引数の個数に異常");
            return;
          }
          can.stripePatternType  = Integer.parseInt(st2.nextToken().trim());
          can.stripePatternW   = Integer.parseInt(st2.nextToken().trim());
          can.stripePRedBase   = Integer.parseInt(st2.nextToken().trim());
          can.stripePGreenBase = Integer.parseInt(st2.nextToken().trim());
          can.stripePBlueBase  = Integer.parseInt(st2.nextToken().trim());
        }
        else if(commandS.equals("MatrixPatternSt"))
        { //●背景画像にマトリックス模様を表示（統一配色の基本設定）
        //MatrixPattern(int matrixPatternNumSt, int matrixPatternWH_St
        //  int matrixPRedBaseSt, int matrixPGreenBaseSt, int matrixPBlueBaseSt
        //  int matrixColorLimitSt)
        //matrixPatternNumSt: 描画無効または柄紋番号
        //matrixPatternWH_St: 柄紋の幅丈
        //matrixPRedBaseSt:   赤基調色
        //matrixPGreenBaseSt: 緑基調色
        //matrixPBlueBaseSt:  青基調色
        //matrixColorLimitSt: 色成分上限設定（1～10）
          if(st2.countTokens() != 6 || Util.countDelimiter(command1, ',') != 5)
          {
            f.message(command1 + " >>引数の個数に異常");
            return;
          }
          can.matrixPatternNumSt = Integer.parseInt(st2.nextToken().trim());
          can.matrixPatternWH_St = Integer.parseInt(st2.nextToken().trim());
          can.matrixPRedBaseSt   = Integer.parseInt(st2.nextToken().trim());
          can.matrixPGreenBaseSt = Integer.parseInt(st2.nextToken().trim());
          can.matrixPBlueBaseSt  = Integer.parseInt(st2.nextToken().trim());
          can.matrixColorLimitSt = Integer.parseInt(st2.nextToken().trim());
          if(can.matrixColorLimitSt<1)
            can.matrixColorLimitSt = 1;
          else if(can.matrixColorLimitSt>10)
            can.matrixColorLimitSt = 10;
        }
        else if(commandS.equals("MatrixPatternStOp"))
        { //●背景画像にマトリックス模様を表示（統一配色のオプション）
        //MatrixPattern(
        //  double matrixShiftH_St, double matrixShiftV_St,
        //  double matrixDropH_St, double matrixDropV_St,
        //  double matrixSkipH_St, double matrixSkipV_St,
        //  int matrixRepeatH_StX, int matrixRepeatV_StX,
        //  matrixIntermittingSt)
        //matrixShiftH_St: 全体横シフト（コマ数）コマ＝小間
        //matrixShiftV_St: 全体縦シフト（コマ数）
        //matrixDropH_St:  柄紋横ドロップ（コマ数）
        //matrixDropV_St:  柄紋縦ドロップ（コマ数）
        //matrixSkipH_St:  柄紋横スキップ（コマ数）
        //matrixSkipV_St:  柄紋縦スキップ（コマ数）
        //matrixRepeatH_StX:  柄紋横リピート指定（回数）
        //matrixRepeatV_StX:  柄紋縦リピート指定（回数）
        //matrixIntermittingSt:  間欠描画（1～10）
          if(st2.countTokens() != 9 || Util.countDelimiter(command1, ',') != 8)
          {
            f.message(command1 + " >>引数の個数に異常");
            return;
          }
          can.matrixShiftH_St    = Double.parseDouble(st2.nextToken().trim());
          can.matrixShiftV_St    = Double.parseDouble(st2.nextToken().trim());
          can.matrixDropH_St     = Double.parseDouble(st2.nextToken().trim());
          can.matrixDropV_St     = Double.parseDouble(st2.nextToken().trim());
          can.matrixSkipH_St     = Double.parseDouble(st2.nextToken().trim());
          can.matrixSkipV_St     = Double.parseDouble(st2.nextToken().trim());
          can.matrixRepeatH_StX  = Integer.parseInt(st2.nextToken().trim());
          can.matrixRepeatV_StX  = Integer.parseInt(st2.nextToken().trim());
          can.matrixIntermittingSt = Integer.parseInt(st2.nextToken().trim());
          if(can.matrixIntermittingSt > 10)
            can.matrixIntermittingSt = 10;
          if(can.matrixIntermittingSt <= 0)
            can.matrixIntermittingSt = 1;
        }
        else if(commandS.equals("MatrixPatternEx"))
        { //●背景画像にマトリックス模様を表示（個別配色の基本設定）
        //MatrixPatternEx(int matrixPatternNumEx, int matrixPatternWH_Ex,
        //  int matrixPRedBase, int matrixPGreenBase, int matrixPBlueBase,
        //  int matrixColorLimitEx)
        //matrixPatternNumEx:  描画無効または柄紋種類
        //matrixPatternWH_Ex:  柄紋の幅丈
        //matrixShiftH_Ex:     全体横シフト（コマ数）
        //matrixShiftV_Ex:     全体縦シフト（コマ数）
        //matrixPRedBaseEx:    赤基調色
        //matrixPGreenBaseEx:  緑基調色
        //matrixPBlueBaseEx:   青基調色
        //matrixColorLimitEx:  色成分上限設定（1～10）
          if(st2.countTokens() != 6 || Util.countDelimiter(command1, ',') != 5)
          {
            f.message(command1 + " >>引数の個数に異常");
            return;
          }
          can.matrixPatternNumEx = Integer.parseInt(st2.nextToken().trim());
          can.matrixPatternWH_Ex = Integer.parseInt(st2.nextToken().trim());
          can.matrixPRedBaseEx   = Integer.parseInt(st2.nextToken().trim());
          can.matrixPGreenBaseEx = Integer.parseInt(st2.nextToken().trim());
          can.matrixPBlueBaseEx  = Integer.parseInt(st2.nextToken().trim());
          can.matrixColorLimitEx = Integer.parseInt(st2.nextToken().trim());
          if(can.matrixColorLimitEx<1)
            can.matrixColorLimitEx = 1;
          else if(can.matrixColorLimitEx>10)
            can.matrixColorLimitEx = 10;
        }
        else if(commandS.equals("MatrixPatternExOp"))
        { //●背景画像にマトリックス模様を表示（個別配色のオプション）
        //MatrixPatternExOp(
        //  double matrixShiftH_Ex, double matrixShiftV_Ex,
        //  double matrixDropH_Ex, double matrixDropV_Ex,
        //  double matrixSkipH_Ex, double matrixSkipV_Ex,
        //  int matrixRepeatH_ExX, int matrixRepeatV_ExX,
        //  matrixIntermittingEx)
        //matrixShiftH_Ex: 全体横シフト（コマ数）コマ＝小間
        //matrixShiftV_Ex: 全体縦シフト（コマ数）
        //matrixDropH_Ex:  柄紋横ドロップ（コマ数）
        //matrixDropV_Ex:  柄紋縦ドロップ（コマ数）
        //matrixSkipH_Ex:  柄紋横スキップ（コマ数）
        //matrixSkipV_Ex:  柄紋縦スキップ（コマ数）
        //matrixRepeatH_ExX:  柄紋横リピート指定（回数）
        //matrixRepeatV_ExX:  柄紋縦リピート指定（回数）
        //matrixIntermittingEx:  間欠描画（1～10）
          if(st2.countTokens() != 9 || Util.countDelimiter(command1, ',') != 8)
          {
            f.message(command1 + " >>引数の個数に異常");
            return;
          }
          can.matrixShiftH_Ex    = Double.parseDouble(st2.nextToken().trim());
          can.matrixShiftV_Ex    = Double.parseDouble(st2.nextToken().trim());
          can.matrixDropH_Ex     = Double.parseDouble(st2.nextToken().trim());
          can.matrixDropV_Ex     = Double.parseDouble(st2.nextToken().trim());
          can.matrixSkipH_Ex     = Double.parseDouble(st2.nextToken().trim());
          can.matrixSkipV_Ex     = Double.parseDouble(st2.nextToken().trim());
          can.matrixRepeatH_ExX  = Integer.parseInt(st2.nextToken().trim());
          can.matrixRepeatV_ExX  = Integer.parseInt(st2.nextToken().trim());
          can.matrixIntermittingEx = Integer.parseInt(st2.nextToken().trim());
          if(can.matrixIntermittingEx > 10)
            can.matrixIntermittingEx = 10;
          if(can.matrixIntermittingEx <= 0)
            can.matrixIntermittingEx = 1;
        }

        else
        { //●命令文が異常
          f.message(command1 + " >>命令スペル・エラー");
          can.commandInspection = false;
          return;
        }
      } // for文の終結
    }
    catch(NumberFormatException e)
    {
      f.message(command1 + " >>引数の数値表現エラー");
      can.commandInspection = false;
      return;
    }
    catch(Exception e)
    {
      f.message(e.toString());
      f.message(command1 + " >>各種エラー");
      can.commandInspection = false;
      return;
    }
  }
} //EOF (GCreatorAnalyzeEngine.java)

◆GCreatorPaletteEngine.java

//■■GCreatorPaletteEngine.java
//Ver.3.3

//■■インポート
import java.awt.*;  //必須
import java.awt.event.*;  //
import java.awt.geom.*;  //必須
import javax.swing.*;  //必須
import javax.swing.event.*;  //

class GCreatorPaletteEngine extends JLabel
{
  //■メンバー変数
  GCreator f;
  Graphics2D g2;
  final int x=5; //margin
  final int y=5;
  int choiceN = 0;
  Color choiceC1 = Color.black;
  Color choiceC2 = Color.black;
  Color choiceC3 = Color.black;
  Color choiceC4 = Color.black;
  Color mixColor1 = Color.black;
  Color mixColor2 = Color.black;

  //■コンストラクタ
  GCreatorPaletteEngine(GCreator flame)
  {
    f = flame;
  }

  //■描画処理
  public void paintComponent(Graphics g)
  {
    drawPage(g);
  }

  //■パレット描画
  void drawPage(Graphics g)
  {
    g2 = (Graphics2D)g;

    //●描画の初期対応
    g2.setColor(new Color(127,255,255)); //（淡青緑）
    g2.fillRect(0,0,f.palette.getPreferredSize().width,
      f.palette.getPreferredSize().height);
    makePalette();
  }

  //■パレット基本色表示
  void makePalette()
  {
    g2.setFont(new Font("Serif", Font.PLAIN, 12));
    g2.setColor(new Color(0xff, 0x00, 0x00)); //red
    g2.fill(new Rectangle2D.Double(x+0,y+0,50,50));
    g2.setColor(Color.black);
    g2.drawString("ff0000",x+0,y+65);
    g2.drawString("Red",   x+0,y+80);
    g2.setColor(new Color(0x80, 0x00, 0x00)); //maroon
    g2.fill(new Rectangle2D.Double(x+50,y+0,50,50));
    g2.setColor(Color.black);
    g2.drawString("800000",x+50,y+65);
    g2.drawString("Maroon",x+50,y+80);
    g2.setColor(new Color(0xff, 0x00, 0xff)); //magenta
    g2.fill(new Rectangle2D.Double(x+100,y+0,50,50));
    g2.setColor(Color.black);
    g2.drawString("ff00ff", x+100,y+65);
    g2.drawString("Magenta",x+100,y+80);
    g2.setColor(new Color(0xa0, 0x00, 0xa0)); //purple
    g2.fill(new Rectangle2D.Double(x+150,y+0,50,50));
    g2.setColor(Color.black);
    g2.drawString("800080",x+150,y+65);
    g2.drawString("Purple",x+150,y+80);
    //------
    g2.setColor(new Color(0x00, 0xff, 0x00)); //green
    g2.fill(new Rectangle2D.Double(x+0,y+95,50,50));
    g2.setColor(Color.black);
    g2.drawString("00ff00",x+0,y+160);
    g2.drawString("Green",  x+0,y+175);
    g2.setColor(new Color(0x00, 0x80, 0x00)); //dark green
    g2.fill(new Rectangle2D.Double(x+50,y+95,50,50));
    g2.setColor(Color.black);
    g2.drawString("008000",x+50,y+160);
    g2.drawString("D.green", x+50,y+175);
    g2.setColor(new Color(0xff, 0xff, 0x00)); //yellow
    g2.fill(new Rectangle2D.Double(x+100,y+95,50,50));
    g2.setColor(Color.black);
    g2.drawString("ffff00",x+100,y+160);
    g2.drawString("Yellow",x+100,y+175);
    g2.setColor(new Color(0x80, 0x80, 0x00)); //olive
    g2.fill(new Rectangle2D.Double(x+150,y+95,50,50));
    g2.setColor(Color.black);
    g2.drawString("808000",x+150,y+160);
    g2.drawString("Olive", x+150,y+175);
    //------
    g2.setColor(new Color(0x00, 0x00, 0xff)); //blue
    g2.fill(new Rectangle2D.Double(x+0,y+190,50,50));
    g2.setColor(Color.black);
    g2.drawString("0000ff",x+0,y+255);
    g2.drawString("Blue",  x+0,y+270);
    g2.setColor(new Color(0x00, 0x00, 0x80)); //navy
    g2.fill(new Rectangle2D.Double(x+50,y+190,50,50));
    g2.setColor(Color.black);
    g2.drawString("000080",x+50,y+255);
    g2.drawString("Navy",  x+50,y+270);
    g2.setColor(new Color(0x00, 0xff, 0xff)); //cyan
    g2.fill(new Rectangle2D.Double(x+100,y+190,50,50));
    g2.setColor(Color.black);
    g2.drawString("00ffff",x+100,y+255);
    g2.drawString("Cyan",  x+100,y+270);
    g2.setColor(new Color(0x00, 0x80, 0x80)); //teal
    g2.fill(new Rectangle2D.Double(x+150,y+190,50,50));
    g2.setColor(Color.black);
    g2.drawString("008080",x+150,y+255);
    g2.drawString("Teal",  x+150,y+270);
    //------
    g2.setColor(new Color(0xff, 0xff, 0xff)); //white
    g2.fill(new Rectangle2D.Double(x+0,y+285,50,50));
    g2.setColor(Color.black);
    g2.drawString("ffffff",x+0,y+350);
    g2.drawString("White", x+0,y+365);
    g2.setColor(new Color(0xc0, 0xc0, 0xc0)); //silver
    g2.fill(new Rectangle2D.Double(x+50,y+285,50,50));
    g2.setColor(Color.black);
    g2.drawString("c0c0c0",x+50,y+350);
    g2.drawString("Silver",x+50,y+365);
    g2.setColor(new Color(0x80, 0x80, 0x80)); //gray
    g2.fill(new Rectangle2D.Double(x+100,y+285,50,50));
    g2.setColor(Color.black);
    g2.drawString("808080",x+100,y+350);
    g2.drawString("Gray",  x+100,y+365);
    g2.setColor(new Color(0x00, 0x00, 0x00)); //black
    g2.fill(new Rectangle2D.Double(x+150,y+285,50,50));
    g2.setColor(Color.black);
    g2.drawString("000000",x+150,y+350);
    g2.drawString("Black", x+150,y+365);
    //------
    colorMix() ;
    //------
  }

  //■パレット混色表示
  void colorMix()
  {
    int r01 =0;
    int g01 =0;
    int b01 =0;
    int r02 =0;
    int g02 =0;
    int b02 =0;
    int r03 =0;
    int g03 =0;
    int b03 =0;
    int r04 =0;
    int g04 =0;
    int b04 =0;
    int r0X =0;
    int g0X =0;
    int b0X =0;

    if(choiceN==1) //第一選択色
    {
      r01 = choiceC1.getRed();
      g01 = choiceC1.getGreen();
      b01 = choiceC1.getBlue();
      g2.setColor(choiceC1);
      g2.fill(new Rectangle2D.Double(x+0,y+380,50,50));
      g2.setColor(Color.black);
      g2.draw(new Rectangle2D.Double(x+0,y+380,50,50));

      mixColor1 = choiceC1;
      g2.setColor(mixColor1);
      g2.fill(new Rectangle2D.Double(x+0,y+440,100,50));
      g2.setColor(Color.black);
      g2.draw(new Rectangle2D.Double(x+0,y+440,100,50));
      g2.drawString(getColorCode(mixColor1), x+0, y+505);
      colorModify(r01,g01,b01);
    }
    else if(choiceN==2) //第二選択色
    {
      r01 = choiceC1.getRed();
      g01 = choiceC1.getGreen();
      b01 = choiceC1.getBlue();
      r02 = choiceC2.getRed();
      g02 = choiceC2.getGreen();
      b02 = choiceC2.getBlue();
      g2.setColor(choiceC1);
      g2.fill(new Rectangle2D.Double(x+0,y+380,50,50));
      g2.setColor(Color.black);
      g2.draw(new Rectangle2D.Double(x+0,y+380,50,50));
      g2.setColor(choiceC2);
      g2.fill(new Rectangle2D.Double(x+50,y+380,50,50));
      g2.setColor(Color.black);
      g2.draw(new Rectangle2D.Double(x+50,y+380,50,50));

      r0X = (r01 + r02)/2;
      g0X = (g01 + g02)/2;
      b0X = (b01 + b02)/2;
      mixColor1 = new Color(r0X, g0X, b0X);
      g2.setColor(mixColor1);
      g2.fill(new Rectangle2D.Double(x+0,y+440,100,50));
      g2.setColor(Color.black);
      g2.draw(new Rectangle2D.Double(x+0,y+440,100,50));
      g2.setFont(new Font("Serif", Font.PLAIN, 12));
      g2.setColor(Color.black);
      g2.drawString(getColorCode(mixColor1), x+0, y+505);
      colorModify(r0X,g0X,b0X);
    }
    else if(choiceN==3) //第三選択色
    {
      r01 = choiceC1.getRed();
      g01 = choiceC1.getGreen();
      b01 = choiceC1.getBlue();
      r02 = choiceC2.getRed();
      g02 = choiceC2.getGreen();
      b02 = choiceC2.getBlue();
      r03 = choiceC3.getRed();
      g03 = choiceC3.getGreen();
      b03 = choiceC3.getBlue();
      g2.setColor(choiceC1);
      g2.fill(new Rectangle2D.Double(x+0,y+380,50,50));
      g2.setColor(Color.black);
      g2.draw(new Rectangle2D.Double(x+0,y+380,50,50));
      g2.setColor(choiceC2);
      g2.fill(new Rectangle2D.Double(x+50,y+380,50,50));
      g2.setColor(Color.black);
      g2.draw(new Rectangle2D.Double(x+50,y+380,50,50));
      g2.setColor(choiceC3);
      g2.fill(new Rectangle2D.Double(x+100,y+380,50,50));
      g2.setColor(Color.black);
      g2.draw(new Rectangle2D.Double(x+100,y+380,50,50));

      r0X = (int)((r01 + r02 + r03)/3);
      g0X = (int)((g01 + g02 + g03)/3);
      b0X = (int)((b01 + b02 + b03)/3);
      mixColor1 = new Color(r0X, g0X, b0X);
      g2.setColor(mixColor1);
      g2.fill(new Rectangle2D.Double(x+0,y+440,100,50));
      g2.setColor(Color.black);
      g2.draw(new Rectangle2D.Double(x+0,y+440,100,50));
      g2.setFont(new Font("Serif", Font.PLAIN, 12));
      g2.setColor(Color.black);
      g2.drawString(getColorCode(mixColor1), x+0, y+505);
      colorModify(r0X,g0X,b0X);
    }
    else if(choiceN==4) //第四選択色
    {
      r01 = choiceC1.getRed();
      g01 = choiceC1.getGreen();
      b01 = choiceC1.getBlue();
      r02 = choiceC2.getRed();
      g02 = choiceC2.getGreen();
      b02 = choiceC2.getBlue();
      r03 = choiceC3.getRed();
      g03 = choiceC3.getGreen();
      b03 = choiceC3.getBlue();
      r04 = choiceC4.getRed();
      g04 = choiceC4.getGreen();
      b04 = choiceC4.getBlue();
      g2.setColor(choiceC1);
      g2.fill(new Rectangle2D.Double(x+0,y+380,50,50));
      g2.setColor(Color.black);
      g2.draw(new Rectangle2D.Double(x+0,y+380,50,50));
      g2.setColor(choiceC2);
      g2.fill(new Rectangle2D.Double(x+50,y+380,50,50));
      g2.setColor(Color.black);
      g2.draw(new Rectangle2D.Double(x+50,y+380,50,50));
      g2.setColor(choiceC3);
      g2.fill(new Rectangle2D.Double(x+100,y+380,50,50));
      g2.setColor(Color.black);
      g2.draw(new Rectangle2D.Double(x+100,y+380,50,50));
      g2.setColor(choiceC4);
      g2.fill(new Rectangle2D.Double(x+150,y+380,50,50));
      g2.setColor(Color.black);
      g2.draw(new Rectangle2D.Double(x+150,y+380,50,50));
      r0X = (int)((r01 + r02 + r03 +r04)/4);
      g0X = (int)((g01 + g02 + g03 +g04)/4);
      b0X = (int)((b01 + b02 + b03 +b04)/4);
      mixColor1 = new Color(r0X, g0X, b0X);
      g2.setColor(mixColor1);
      g2.fill(new Rectangle2D.Double(x+0,y+440,100,50));
      g2.setColor(Color.black);
      g2.draw(new Rectangle2D.Double(x+0,y+440,100,50));
      g2.setFont(new Font("Serif", Font.PLAIN, 12));
      g2.setColor(Color.black);
      g2.drawString(getColorCode(mixColor1), x+0, y+505);
      colorModify(r0X,g0X,b0X);
    }
    f.palette.repaint();
  }

  //■混色補正と表示
  void colorModify(int r, int g,int b)
  {
    int r01 = r+ (int)(r*(f.sliderLis.adjustR/100.0));
    if(r01 > 255) r01=255;
    else if(r01 < 0)   r01=0;
    int g01 = g+ (int)(g*(f.sliderLis.adjustG/100.0));
    if(g01 > 255) g01=255;
    else if(g01 < 0)   g01=0;
    int b01 = b+ (int)(b*(f.sliderLis.adjustB/100.0));
    if(b01 > 255) b01=255;
    else if(b01 < 0)   b01=0;

    mixColor2 = new Color(r01,g01,b01); //修正色
    g2.setColor(mixColor2);
    g2.fill(new Rectangle2D.Double(x+100,y+440,100,50));
    g2.setColor(Color.black);
    g2.draw(new Rectangle2D.Double(x+100,y+440,100,50));
    g2.setFont(new Font("Serif", Font.PLAIN, 12));
    g2.setColor(Color.black);
    g2.drawString(getColorCode(mixColor2), x+100, y+505);
  }

  //■3バイトカラー・コードの取得
  String getColorCode(Color clr)
  {
    String hexR = Integer.toHexString(clr.getRed());
    String hexG = Integer.toHexString(clr.getGreen());
    String hexB = Integer.toHexString(clr.getBlue());
    if(hexR.length() == 1) hexR = "0"+ hexR;
    if(hexG.length() == 1) hexG = "0"+ hexG;
    if(hexB.length() == 1) hexB = "0"+ hexB;
    return (hexR+hexG+hexB);
  }
} //EOF (GCreatorPaletteEngine.java)

◆GCreatorPrintEngine.java

//■■GCreatorPrintEngine.java
//Ver.3.3

//■■インポート
import java.awt.*;  //必須
import java.awt.print.*;  //必須
import javax.print.attribute.*;  //必須
import javax.print.attribute.standard.*;  //必須

//■■印刷実行処理
class GCreatorPrintEngine
{
  //■メンバー変数
  GCreator f;
  double printerMarginX = 3.0; //プリンター機種依存のマージン調整(mm単位)
  double printerMarginY = 3.0; //プリンター機種依存のマージン調整

  //■コンストラクタ
  GCreatorPrintEngine(GCreator flame)
  {
    f = flame;
  }

  //■印刷開始要求の受付け
  void start()
  {
    //●ディスプレイ表示倍率の保存
    double scale = f.canvas.affineScale; //元の数値を保存

    //●画像サイズ倍率調整
    float bt = 0.949f;//倍率調整
    f.canvas.affineScale = bt; //一時的に変更
    //1mm=2.8457point
    //画面表示倍率=3 (1mm=3pxに設定)
    //2.8457÷3 ≒ 0.949

    //●印刷制御オブジェクト
    PrinterJob pj = PrinterJob.getPrinterJob();

    //●用紙書式設定オブジェクト
    PageFormat fmt = new PageFormat();

    //●用紙情報格納オブジェクト
    Paper paper = new Paper();

    //●印刷制御オブジェクトに要件設定
    PrintOnePage printable = new PrintOnePage();

    if(f.canvas.rotateFlag == false)
    { //●90度回転なし
      paper.setImageableArea(0,0,
        f.canvas.printMM_W *bt, f.canvas.printMM_H *bt);
    }
    else
    { //●90度回転あり
      paper.setImageableArea(0,0,
        (int)(f.canvas.printMM_H *bt), (int)(f.canvas.printMM_W *bt));
    }
    fmt.setPaper(paper);

    //●余白設定
    PrintRequestAttributeSet reqAtt =
      new HashPrintRequestAttributeSet();
    float topMgn    = 0.0f;  //余白なしを設定
    float bottomMgn = 0.0f;
    float leftMgn   = 0.0f;
    float rightMgn  = 0.0f;
    if(f.canvas.rotateFlag == false) //●回転なし
    {
      reqAtt.add(new MediaPrintableArea(leftMgn, topMgn,
      ((float)f.canvas.printMM_W *bt - leftMgn - rightMgn),
      ((float)f.canvas.printMM_H *bt - topMgn - bottomMgn),
      MediaPrintableArea.MM));
    }
    else //●90度回転あり
    {
      reqAtt.add(new MediaPrintableArea(leftMgn, topMgn,
      ((float)f.canvas.printMM_H *bt - topMgn - bottomMgn),
      ((float)f.canvas.printMM_W *bt - leftMgn - rightMgn),
      MediaPrintableArea.MM));
    }
    reqAtt.add(OrientationRequested.PORTRAIT);
    pj.setPrintable(new PrintOnePage());

    //●印刷開始
    try
    {  //Printable.print(...)にページ毎に描画要求（複数ページには非対応）
      if (pj.printDialog()) //印刷開始のダイアログ・ボックス
        pj.print(reqAtt); //印刷開始
    }
    catch(Exception e)
    {
      f.message("印刷実行エラー："+e);
    }

    //●倍率をディスプレイ表示用に戻す
    f.canvas.affineScale = scale;
  }

  //■残ページ判定（複数ページには非対応）
  boolean hasMorePages(int page)
  {
    if(f.canvas.pages <= page)
      return false;
    else
      return true;
  }

  //■印刷イメージの描画（
  //PrinterJobの管理下で機能するPrintableの実装
  class PrintOnePage implements Printable
  {
    public int print(Graphics g, PageFormat fmt,
      int pageIndex) //指定ページ描画（複数ページには非対応）
    { //指定ページ描画
      if(hasMorePages(pageIndex))
      { //未処理ページがあれば（複数ページには非対応）
        Graphics2D g2 = (Graphics2D)g;
        g2.translate(fmt.getImageableX()-printerMarginX,
          fmt.getImageableY()-printerMarginY);
        //描画は外部委託
        f.canvas.drawPage(g,true);
        //該当ページ印刷実行合図返却
        return Printable.PAGE_EXISTS;
      }
      else
      { //印刷完了による停止合図返却
        return Printable.NO_SUCH_PAGE;
      }
    }
  }
} //EOF (GCreatorPrintEngine.java)

◆GCreatorFileIO.java

//■■GCreatorFileIO.java
//Ver.3.3

//■■インポート
import javax.swing.*;  //必須
import javax.swing.text.*;  //必須
import java.io.*;  //必須
import java.awt.*;  //必須
import java.awt.image.*;  //必須
import java.util.*;  //必須
import javax.imageio.*;  //必須
import javax.imageio.stream.ImageOutputStream;  //必須
import javax.swing.filechooser.FileNameExtensionFilter; //必須

//■■テキストおよび画像入出力
class GCreatorFileIO
{
  //■メンバー変数
  GCreator f;
  GCreatorCanvasEngine can;

  //■コンストラクタ
  GCreatorFileIO(GCreator flame)
  {
    f = flame;
    can = f.canvas;
  }

  //■テキスト・ファイルからJTextAreaに読み込む
  void load(JTextArea tArea, String dir, String ext)
  {
    File file = TextIO.callFileChooser("open", f.pane, dir, ext);
    if(file == null)
    { //ファイルがない場合
      return;
    }
    try
    {
      FileReader reader = new FileReader(file);
      try
      {
        tArea.read(reader,new PlainDocument());
      }
      catch(IOException e)
      {
        f.message("リードエラー："+e);
      }
      reader.close();
    }
    catch(FileNotFoundException e)
    {
      f.message("オープンエラー："+e);
    }
    catch(IOException e)
    {
      f.message("クローズエラー："+e);
    }
  }

  //■JTextAreaからテキスト・ファイルに書き込む
  void save(JTextArea tArea, String dir, String ext)
  {
    File file = TextIO.callFileChooser("save", f.pane, dir, ext);
    if(file == null)
    { //ファイルがない場合
      return;
    }
    try
    {
      FileWriter writer = new FileWriter(file);
      try
      {
        String str = tArea.getText().trim();
        if(str.equals(""))
          f.message("データなし。書き込み回避");
        else
          writer.write(str);
      }
      catch(IOException e)
      {
        f.message("ライトエラー："+e);
      }
      writer.close();
      f.message(file.getName()+" を書き込みました。");
    }
    catch(FileNotFoundException e)
    {
      f.message("オープンエラー："+e);
    }
    catch(IOException e)
    {
      f.message("クローズエラー："+e);
    }
  }

  //■JTextAreaからテキスト・ファイルに書き込む（ファイル名事前指定）
  void save(JTextArea tArea, String fName)
  { //fNameは、パス付き
    try
    {
      FileWriter writer = new FileWriter(fName);
      try
      {
        String str = tArea.getText().trim();
        if(str.equals(""))
          f.message("データなし。書き込み回避。");
        else
          writer.write(str);
      }
      catch(IOException e)
      {
        f.message("ライトエラー："+e);
      }
      writer.close();
      f.message(fName + " を書き込みました。");
    }
    catch(FileNotFoundException e)
    {
      f.message("オープンエラー："+e);
    }
    catch(IOException e)
    {
      f.message("クローズエラー："+e);
    }
  }

  //■画像ファイル入力（jpeg,gif,png,bmp 使用可能）
  //Image命令またはStamp命令として画像を導入する。
  void loadGraphics(int mode)
  {
    JFileChooser fileChooser = new JFileChooser("./");
    FileNameExtensionFilter filter = new FileNameExtensionFilter(
        "Images:png,jpeg,gif,bmp", "png","jpeg","jpg", "gif","bmp");
    fileChooser.setFileFilter(filter);
    int ret = fileChooser.showOpenDialog(f.pane);
    File file = fileChooser.getSelectedFile();
    if(ret != JFileChooser.APPROVE_OPTION || file == null)
    { //OKボタンが押されなかったか、ファイルがない場合
      return;
    }
    String path = file.getPath();
    String fileName = file.getName();
    String extension = fileName.substring(
      fileName.indexOf(".")+1,fileName.length());
    extension = extension.toLowerCase();
    if(!(extension.equals("jpeg") || extension.equals("jpg") ||
       extension.equals("gif")  || extension.equals("png") ||
       extension.equals("bmp")))
    {
      f.message(path + ":画像ファイルではありません。");
      return;
    }
    BufferedImage bImage = null;
    try
    {
      bImage = ImageIO.read(file);
    }
    catch (Exception e)
    {
      e.printStackTrace();
      f.message("画像ファイル読み込みエラー：" +fileName);
      return;
    }
    int w = bImage.getWidth(can);
    int h = bImage.getHeight(can);
    String pathX = path.toLowerCase();
    if(pathX.indexOf("c:\\user\\java\\gcreator") != -1)
    { //絶対パスを相対パスに変換する。
      //バッチ・ファイルで、事前にカレント・ディレクトリーを設定しておく。
      path = "." + path.substring(21,path.length());
    }
    if(mode ==0) //背景画像
    { //位置やサイズは、当面の便宜的設定
      f.cArea.append("Image(0,0,500,500,\"" +
        path + "\");\n");
      f.mArea.append(path + ": " +w +" x " +h +" pixcels\n");
    }
    else if(mode ==1) //前景画像（スタンプ画像）
    { //位置やサイズは、当面の便宜的設定
      f.cArea.append("Stamp(50,50,200,200,\"" +
        path + "\");\n");
      f.mArea.append(path + ": " +w +" x " +h +" pixcels\n");
    }
  }

  //■画像ファイル出力（jpeg,gif,png,bmp が使用可能）
  //キャンバスの全体画像（一般用）または部分画像（特殊用）のファイル保存を行なう。
  void saveGraphics(File _file, int imageX, int imageY, int imageW, int imageH)
  {
    //●キャンバス画像のBufferedImage bImage1をbImage2に変換する準備
    //画像を切り取って画像サイズを縮小する場合にも対応するための準備
    can.canSaveMode = true; //グラフィック保存モード
    can.repaint(); //十字線などの余分な表示を消去

    BufferedImage bImage1 = canvas2BufferedImage(imageX, imageY, imageW, imageH);
    BufferedImage bImage2 = null;
    if(!can.cutAndSaveImgFName.equals(""))
      bImage2 = new BufferedImage( //切取り画像（不透明）
        can.cutAndSaveImgX2-can.cutAndSaveImgX1, can.cutAndSaveImgY2-can.cutAndSaveImgY1,
        BufferedImage.TYPE_INT_RGB);

    //●画像ファイル出力の準備（出力ファイル名の取得）
    String path;
    String fileName;
    String extension;
    if(_file==null)//●一般使用（ファイル名が不明の場合）
    {
      JFileChooser fileChooser = new JFileChooser("./");
      FileNameExtensionFilter filter = new FileNameExtensionFilter(
        "Images:png,jpeg,gif,bmp", "png","jpeg","jpg", "gif","bmp");
      fileChooser.setFileFilter(filter);
      int ret = fileChooser.showSaveDialog(f.pane);
      File file = fileChooser.getSelectedFile();
      if(ret != JFileChooser.APPROVE_OPTION || file == null)
      { //OKボタンが押されなかったか、ファイルがない場合
        return;
      }
      path = file.getPath();
      fileName = file.getName();
      extension = fileName.substring(
        fileName.indexOf(".")+1,fileName.length());
    }
    else //●特殊使用（ファイル名が既知の場合）
    {
      path = _file.getPath();
      fileName = _file.getName();
      extension = fileName.substring(
        fileName.indexOf(".")+1,fileName.length());
    }

    if(f.buttonLis.cutAndSaveFlag == true)
    //切り取り画像を部分コピーで作成
    {
      int R,G,B;
      for(int y=0; y<imageH; y++)
      {
        for(int x=0; x<imageW; x++)
        {
          int rgb1 = bImage1.getRGB(x,y); //元画像のRGB

          	R = (rgb1 & 0x00ff0000)>>>16;
          	G = (rgb1 & 0x0000ff00)>>> 8;
          	B = (rgb1 & 0x000000ff);
            int color = (0x00<<24) | (R<<16) | (G<<8) | (B<<0);
            bImage2.setRGB(x, y, color);
        }
      }
    }

    //●jpeg 画質指定の画像ファイル出力
    //写真などのグラデーションのある画像の場合
    Iterator writers = ImageIO.getImageWritersBySuffix(extension);
    extension = extension.toLowerCase();
    if(writers.hasNext() &&
       (extension.equals("jpeg") || extension.equals("jpg")))
    {
      ImageWriter writer = (ImageWriter)writers.next();
      try
      {
        ImageOutputStream stream
          = ImageIO.createImageOutputStream(new File(path));
        writer.setOutput(stream);
        ImageWriteParam param = writer.getDefaultWriteParam();
        if (param.canWriteCompressed()) //圧縮できるか
        {
          param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
          param.setCompressionQuality(can.quality); //画質の指定
        }
        else
        {
          f.message(path+ "：圧縮できない");
        }
        if(!f.canvas.cutAndSaveImgFName.equals(""))
        {
          writer.write(null, new IIOImage(bImage1, null, null), param);
          f.message(path+ "：全体画像ファイル出力");
        }
        else
        {
          writer.write(null, new IIOImage(bImage2, null, null), param);
          f.message(path+ "：切り取り画像ファイル出力");
        }
        writer.dispose();
        f.message(path+ "：画像ファイル出力  画質=" + can.quality);
      }
      catch (IOException e)
      {
        e.printStackTrace();
        f.message(path+ "：画像保存失敗");
      }
      finally
      {
        can.canSaveMode = false;
      }
    }
    else
    { //●標準画質での画像ファイル出力（gif,png,bmp）
      //線画や文字やグラデーションのないベタ塗りの画像なら、gif を推奨。
      try
      {
        if(f.buttonLis.cutAndSaveFlag == false)
        {
          ImageIO.write(bImage1, extension, new File(path));
          f.message(path+ "：全体画像ファイル出力");
        }
        else
        {
          ImageIO.write(bImage2, extension, new File(path));
          f.message(path+ "：切り取り画像ファイル出力");
        }
      }
      catch (Exception e)
      {
        e.printStackTrace();
        f.message(path+ "：画像保存失敗");
      }
      finally
      {
        can.canSaveMode = false;
      }
    }
  }

  //■キャンバス画像をバッファード・イメージに変換
  BufferedImage canvas2BufferedImage(int imageX, int imageY, int imageW, int imageH)
  {
    can.canSaveMode = true; //グラフィック保存モード
    can.repaint(); //十字線などの余分な表示を消去
    //切り出す範囲の指定
    int w = (int)(can.imagePX_W*can.affineScale*can.freeScale);
    int h = (int)(can.imagePX_H*can.affineScale*can.freeScale);
    //●イメージの取得
    //Image を取得して BufferedImage に転換する準備
    Image image1  = can.createImage(w,h); //イメージ・オブジェクト生成

    MediaTracker tracker = new MediaTracker(new Component(){});
    //trackerは、メディア・オブジェクトのステータスを追跡。
    tracker.addImage(image1, 1); //1は、識別ID番号（この場合、後で使用しない）
    try
    {
      tracker.waitForAll(); //イメージのロードを開始
    }
    catch(InterruptedException e)
    {
      f.message("イメージのロードに失敗");
      can.canSaveMode = false;
      return null;
    }
    //●オフスクリーン・バッファを取得し、これに描画する。
    //オフスクリーン・バッファとは、画面に描画される前の
    //背後にある隠れた画像記憶領域のこと。
    //画面表示は、マルチ・ウィンドウなどのため、
    //複数のオフスクリーン・バッファが背後で必要になる。
    can.update(image1.getGraphics());

    PixelGrabber pixelGrabber =
      new PixelGrabber(image1, imageX, imageY, imageW, imageH, false);
      //new PixelGrabber(image1, 0, 0, -1, -1, false); これで画像全体を範囲指定できる。
      //new PixelGrabber(image1, 0, 0, w, h, false); としても可。
      //PixelGrabber は、矩形の領域を部分的に切り出すクラス
      //PixelGrabber(Image img, int x, int y, int w, int h, boolean forceRGB)
      //画像の幅丈の指定に-1を用いれば、デフォルトの数値を用いる指定。
      //forceRGBは、trueにすればRGB形式の強制（この場合、不適切）になり、
      //falseにすればイメージ・プロデューサーのカラーモデルに委ねる。
    try
    {
      pixelGrabber.grabPixels(); //ピクセル取得
    }
    catch(InterruptedException e)
    {
      f.message("ピクセル取得エラー");
      can.canSaveMode = false;
      return null;
    }
    if((pixelGrabber.status() & ImageObserver.ABORT) != 0)
    {
      f.message("ピクセル取得エラー");
      can.canSaveMode = false;
      return null;
    }
    //●ColorModel, WritableRaster を取得
    ColorModel cModel = pixelGrabber.getColorModel();//カラー・モデル取得
    int pW = pixelGrabber.getWidth();
    int pH = pixelGrabber.getHeight();
    WritableRaster wRaster =
    cModel.createCompatibleWritableRaster(w, h);
    BufferedImage bImage1 = new BufferedImage(
      cModel, wRaster, cModel.isAlphaPremultiplied(), new Hashtable());

    //●ピクセル・データをＯＳのカラー・モデルに合うように加工
    if(pixelGrabber.getPixels() instanceof int[])
    {
      int[] intPixels = (int[])pixelGrabber.getPixels();
      try
      { //ＯＳレベルで画面設定が３２ビット・カラーの場合（通常の場合）
        bImage1.getRaster().setDataElements(0, 0, imageW, imageH, intPixels);
        //ラスターとは、整数単位での二次元座標空間（画像データ格納）での
        //ピクセル画像のこと
      }
      catch (Exception e)
      { //ＯＳレベルで画面設定が１６ビット・カラーの場合（旧式の場合）
        short[] shortPixels = new short[intPixels.length];
        for(int i=0; i<intPixels.length; i++)
        {
          shortPixels[i] = (short)intPixels[i];
        }
        bImage1.getRaster().setDataElements(0, 0, imageW, imageH, shortPixels);
        f.message("16 bits color mode");
      }
    }
    else
    {
      f.message("エラー: pixelGrabber.getPixels()において");
      can.canSaveMode = false;
      return null;
    }
    can.canSaveMode = false;
    return bImage1;
  }
} //EOF (GCreatorFileIO.java)

◆GCreatorMenuLis.java

//■■GCreatorMenuLis.java
//Ver.3.3

//■■インポート
import java.awt.event.*;  //必須
import javax.swing.*;  //必須
import java.io.*;  //必須

//■■JMenuItemのイベントリスナー
class GCreatorMenuLis implements ActionListener
{
  //■メンバー変数
  GCreator f;

  //■コンストラクタ
  GCreatorMenuLis(GCreator flame)
  {
    f = flame;
  }

  //■JMenuItemのイベントハンドラ
  public void actionPerformed(ActionEvent event)
  {
    String com = event.getActionCommand();

    if(com.equals("LoD"))
    {  //●命令文の読み込み
      f.io.load(f.cArea, "./", "gcc");
      init(); //完全初期化
    }
    else if(com.equals("SaD"))
    {  //●命令文の保存
      f.canvas.setInit();  //一般初期化のみ
      f.io.save(f.cArea, "./", "gcc");
    }
    else if(com.equals("LoI"))
    {  //●背景画像読み込み
      f.io.loadGraphics(0);
      init();
    }
    else if(com.equals("Stm"))
    {  //●スタンプ画像読み込み
      f.io.loadGraphics(1);
      init();
    }
    else if(com.equals("Sa2"))
    {  //●画像保存
      f.canvas.markFlag = false; //目印線消去
      f.canvas.setInit();  //一般初期化のみ
      f.io.saveGraphics(null, 0, 0,  //画像全体を指定
        (int)(f.canvas.imagePX_W*f.canvas.affineScale*f.canvas.freeScale),
        (int)(f.canvas.imagePX_H*f.canvas.affineScale*f.canvas.freeScale));
    }
    else if(com.equals("Pri"))
    {  //●画像印刷
      f.canvas.setInit();  //一般初期化のみ
      f.canvas.markFlag = false; //目印線消去
      f.printer.start();
    }
    else if(com.equals("Cl2"))
    {  //●命令文消去
      f.cArea.setText("");
      init();  //完全初期化
    }
    else if(com.equals("Cl3"))
    {  //●警告文消去
      f.mArea.setText("");
    }
    else if(com.equals("Cl4"))
    {  //●全消去
      f.cArea.setText("");
      f.mArea.setText("");
      init();  //完全初期化
    }
    else if(com.equals("FrS"))
    {  //●各種図形描画
      f.cArea.setText("");
      f.cArea.append("//各種図形描画\n");
      f.cArea.append("Size(\"A4\");\n");
      f.cArea.append("WriteStringH(40,30,20,\"sansserif\",\"各種図形描画\");\n");
      f.cArea.append("DrawLine(43,126,292,46);\n");
      f.cArea.append("WriteStringH(113,82,16,\"sansserif\",\"直線\");\n");
      f.cArea.append("DrawCircle(3,64,193,40,214,214,230);\n");
      f.cArea.append("WriteStringH(110,216,16,\"sansserif\",\"真円\");\n");
      f.cArea.append("DrawEllipse(3,225,146,70,34,248,224,237);\n");
      f.cArea.append("WriteStringH(263,193,16,\"sansserif\",\"楕円\");\n");
      f.cArea.append("DrawRect(3,87,256,153,73,214,231,216);\n");
      f.cArea.append("WriteStringH(253,304,16,\"sansserif\",\"四角形\");\n");
      f.cArea.append("DrawShapeStart(4,61,406,223,218,234);\n");
      f.cArea.append("DrawShapeLine(134,369);\n");
      f.cArea.append("DrawShapeCurve(214,359,247,379,255,467);\n");
      f.cArea.append("DrawShapeLine(202,479);\n");
      f.cArea.append("DrawShapeCurve(110,406,113,499,30,449);\n");
      f.cArea.append("DrawShapeEnd();\n");
      f.cArea.append("WriteStringH(264,449,16,\"sansserif\",\"自由図形\");\n");
      f.cArea.append("WriteStringH(330,40,16,\"sansserif\",\"ベジェ曲線\");\n");
      f.cArea.append("DrawCurve(404,100,449,24,555,28,598,79);\n");
      f.cArea.append("WriteStringH(339,94,15,\"sansserif\",\"Ｕ字曲線\");\n");
      f.cArea.append("DrawCurve(400,155,453,85,543,186,583,104);\n");
      f.cArea.append("WriteStringH(337,142,15,\"sansserif\",\"Ｓ字曲線\");\n");
      f.cArea.append("DrawCurve(432,290,602,210,400,184,501,294);\n");
      f.cArea.append("WriteStringH(363,275,15,\"sansserif\",\"ループ曲線\");\n");
      f.cArea.append("DrawShapeStart(4,467,341,229,223,241);\n");
      f.cArea.append("DrawShapeCurve(576,299,610,381,498,427);\n");
      f.cArea.append("DrawShapeCurve(393,468,359,384,467,341);\n");
      f.cArea.append("DrawShapeEnd();\n");
      f.cArea.append("WriteStringH(470,456,16,\"sansserif\",\"自由図形／傾斜楕円\");\n");
      f.canvas.markFlag = true;
      init();
    }
    else if(com.equals("SpC"))
    {  //●スプライン曲線描画
      f.cArea.setText("");
      f.cArea.append("//スプライン曲線描画\n");
      f.cArea.append("Size(\"A4\");\n");
      f.cArea.append("WriteStringH(40,30,20,\"sansserif\",\"スプライン曲線描画\");\n");
      f.cArea.append("DrawSplineStart(137,139);\n");
      f.cArea.append("DrawSplineControl(108,183);\n");
      f.cArea.append("DrawSplineControl(81,141);\n");
      f.cArea.append("DrawSplineControl(103,91);\n");
      f.cArea.append("DrawSplineControl(183,75);\n");
      f.cArea.append("DrawSplineControl(202,160);\n");
      f.cArea.append("DrawSplineControl(282,186);\n");
      f.cArea.append("DrawSplineControl(332,185);\n");
      f.cArea.append("DrawSplineControl(378,119);\n");
      f.cArea.append("DrawSplineControl(419,81);\n");
      f.cArea.append("DrawSplineControl(462,110);\n");
      f.cArea.append("DrawSplineEnd(503,151);\n");
      f.cArea.append("//\n");
      f.cArea.append("DrawSplineStart(100,303);\n");
      f.cArea.append("DrawSplineControl(210,259);\n");
      f.cArea.append("DrawSplineControl(527,332);\n");
      f.cArea.append("DrawSplineControl(312,346);\n");
      f.cArea.append("DrawSplineControl(173,457);\n");
      f.cArea.append("DrawSplineControl(47,377);\n");
      f.cArea.append("DrawSplineEnd(100,303);\n");
      f.canvas.markFlag = true;
      init();
    }
    else if(com.equals("BG1"))
    {  //●模様画像生成（統一配色）
      f.cArea.setText("");
      f.cArea.append("//模様画像生成（統一配色）\n");
      f.cArea.append("SaveImage(\"./image/image1.png\");\n");
      f.cArea.append("Size(720,1008);\n");
      f.cArea.append("MatrixPatternSt(0001,8,150,100,170,7);\n");
      f.cArea.append("//画像上部の「乱数」ボタンを押して下さい。\n");
      f.cArea.append("//画像上部の「保存」ボタンを押して下さい。\n");
      init();
    }
    else if(com.equals("BG2"))
    {  //●模様画像生成（個別配色）
      f.cArea.setText("");
      f.cArea.append("//模様画像生成（個別配色）\n");
      f.cArea.append("SaveImage(\"./image/image2.png\");\n");
      f.cArea.append("Size(720,1008);\n");
      f.cArea.append("MatrixPatternEx(0001,8,240,50,70,10);\n");
      f.cArea.append("//画像上部の「乱数」ボタンを押して下さい。\n");
      f.cArea.append("//画像上部の「保存」ボタンを押して下さい。\n");
      init();
    }
    else if(com.equals("BG3"))
    {  //●模様画像生成（二重混用）
      f.cArea.setText("");
      f.cArea.append("//模様画像生成（二重混用）\n");
      f.cArea.append("SaveImage(\"./image/image3.png\");\n");
      f.cArea.append("Size(720,1008);\n");
      f.cArea.append("MatrixPatternSt(0010,8,80,50,220,7);\n");
      f.cArea.append("MatrixPatternEx(0114,8,100,100,150,10);\n");
      f.cArea.append("//画像上部の「乱数」ボタンを押して下さい。\n");
      f.cArea.append("//画像上部の「保存」ボタンを押して下さい。\n");
      init();
    }
    else if(com.equals("BG4"))
    {  //●模様画像生成（シフト）
      f.cArea.setText("");
      f.cArea.append("//模様画像生成（シフト）\n");
      f.cArea.append("Size(720,1008);\n");
      f.cArea.append("MatrixPatternEx(0011,8,70,120,170,10);\n");
      f.cArea.append("MatrixPatternExOp(2,4,0,0,0,0,0,0,10);\n");
      f.cArea.append("//画像上部の「乱数」ボタンを押して下さい。\n");
      init();
    }
    else if(com.equals("BG5"))
    {  //●模様画像生成（ドロップ）
      f.cArea.setText("");
      f.cArea.append("//模様画像生成（ドロップ）\n");
      f.cArea.append("Size(720,1008);\n");
      f.cArea.append("MatrixPatternSt(1001,8,70,170,70,10);\n");
      f.cArea.append("MatrixPatternStOp(0,0,-4.5,0,0,0,0,0,10);\n");
      f.cArea.append("//画像上部の「乱数」ボタンを押して下さい。\n");
      init();
    }
    else if(com.equals("BG6"))
    {  //●模様画像生成（スキップ）
      f.cArea.setText("");
      f.cArea.append("//模様画像生成（スキップ）\n");
      f.cArea.append("Size(720,1008);\n");
      f.cArea.append("MatrixPatternEx(1002,8,170,150,70,10);\n");
      f.cArea.append("MatrixPatternExOp(0,0,0,0,-3,-3,0,0,10);\n");
      f.cArea.append("//画像上部の「乱数」ボタンを押して下さい。\n");
      init();
    }
    else if(com.equals("BG7"))
    {  //●模様画像生成（間欠描画）
      f.cArea.setText("");
      f.cArea.append("//模様画像生成（間欠描画）\n");
      f.cArea.append("Size(720,1008);\n");
      f.cArea.append("MatrixPatternSt(1001,8,170,150,70,10);\n");
      f.cArea.append("MatrixPatternStOp(0,0,0,0,0,0,0,0,5);\n");
      f.cArea.append("//画像上部の「乱数」ボタンを押して下さい。\n");
      init();
    }
    else if(com.equals("BG8a"))
    {  //●傾斜元画像（画像傾斜する前の元画像の準備）
      f.cArea.setText("");
      f.cArea.append("//傾斜元画像生成\n");
      f.cArea.append("SaveImage(\"./image/imageRa.png\");\n");
      f.cArea.append("AffineScale(1);\n");
      f.cArea.append("Size(2000,2000);\n");
      f.cArea.append("MatrixPatternSt(0003,8,100,110,180,10);\n");
      f.cArea.append("//画像上部の「乱数」ボタンを押して下さい。\n");
      f.cArea.append("//画像上部の「保存」ボタンを押して下さい。\n");
      init();
    }
    else if(com.equals("BG8b"))
    {  //●画像傾斜加工
      f.cArea.setText("");
      f.cArea.append("//模様画像生成（画像傾斜）\n");
      f.cArea.append("SaveImage(\"./image/imageRb.png\");\n");
      f.cArea.append("AffineScale(1);\n");
      f.cArea.append("Size(2000,2000);\n");
      f.cArea.append("Image(0,0,2000,2000,\"./image/imageRa.png\");\n");
      f.cArea.append("RotateFree(45,300,-750);\n");
      f.cArea.append("//画像上部の「保存」ボタンを押して下さい。\n");
      init();
    }
    else if(com.equals("BG8c"))
    {  //●傾斜画像サイズ調整
      f.cArea.setText("//傾斜画像サイズ調整\n");
      f.cArea.append("SaveImage(\"./image/imageRc.png\");\n");
      f.cArea.append("Size(720,1008);\n");
      f.cArea.append("Image(0,0,2000,2000,\"./image/imageRb.png\");\n");
      f.cArea.append("//画像上部の「保存」ボタンを押して下さい。\n");
      init();
    }
    else if(com.equals("BG9"))
    {  //●模様画像生成（複雑指定１）
      f.cArea.setText("");
      f.cArea.append("//模様画像生成（複雑指定１）\n");
      f.cArea.append("Size(720,1008);\n");
      f.cArea.append("BackgroundColor(200,100,220);\n");
      f.cArea.append("MatrixPatternEx(1005,8,100,110,80,10);\n");
      f.cArea.append("MatrixPatternExOp(-0.5,-1,-5,0,1,-4,10,27,10);\n");
      f.cArea.append("//画像上部の「乱数」ボタンを押して下さい。\n");
      init();
    }
    else if(com.equals("BG10"))
    {  //●模様画像生成（複雑指定２）
      f.cArea.setText("");
      f.cArea.append("//模様画像生成（複雑指定２）\n");
      f.cArea.append("Size(720,1008);\n");
      f.cArea.append("BackgroundColor(200,200,120);\n");
      f.cArea.append("MatrixPatternSt(1003,4,70,50,70,10);\n");
      f.cArea.append("MatrixPatternStOp(-3.5,-8.5,0,-21,-11,17,0,0,10);\n");
      f.cArea.append("MatrixPatternEx(1004,4,50,50,70,10);\n");
      f.cArea.append("MatrixPatternExOp(-3.5,-8.5,0,-21,-11,17,0,0,5);\n");
      f.cArea.append("//画像上部の「乱数」ボタンを押して下さい。\n");
      init();
    }

    //●これ以降、画像の特殊加工を行なうが、画像保存を１倍に固定する命令が含まれる。
    //●標準拡大率指定の「AffineScale(1);」が、それである。
    //●画像サイズが所定通りでないと、実行時エラーが発生する処理が一部含まれるため。

    else if(com.equals("Log"))
    {  //●ロゴ画像生成
      f.cArea.setText("");
      f.cArea.append("//ロゴ画像生成\n");
      f.cArea.append("SaveImage(\"./image/ZLogo.png\");\n");
      f.cArea.append("AffineScale(1);\n");
      f.cArea.append("Size(500,500);\n");
      f.cArea.append("ForegroundColorL(200,0,0);\n");
      f.cArea.append("BackgroundColor(200,200,200);\n"); //スタンプ用背景色
      f.cArea.append("Antialias(true);\n");
      f.cArea.append("DrawCircle(2,250,250,250,200,0,0);\n");
      f.cArea.append("DrawCircle(2,250,250,220,200,200,255);\n");
      f.cArea.append("DrawCircle(2,250,250,210,200,0,0);\n");
      f.cArea.append("DrawCircle(2,250,250,195,200,200,255);\n");
      f.cArea.append("DrawShapeStart(2,118,159,200,0,0);\n");
      f.cArea.append("DrawShapeCurve(201,47,306,197,384,138);\n");
      f.cArea.append("DrawShapeCurve(303,261,198,111,118,159);\n");
      f.cArea.append("DrawShapeEnd();\n");
      f.cArea.append("DrawShapeStart(2,107,344,200,0,0);\n");
      f.cArea.append("DrawShapeCurve(190,233,298,382,398,330);\n");
      f.cArea.append("DrawShapeCurve(298,453,198,297,107,344);\n");
      f.cArea.append("DrawShapeEnd();\n");
      f.cArea.append("DrawShapeStart(2,138,320,200,0,0);\n");
      f.cArea.append("DrawShapeLine(339,162,);\n");
      f.cArea.append("DrawShapeLine(349,174,);\n");
      f.cArea.append("DrawShapeLine(150,330,);\n");
      f.cArea.append("DrawShapeEnd();\n");
      f.cArea.append("DrawShapeStart(2,172,255,200,0,0);\n");
      f.cArea.append("DrawShapeCurve(228,191,274,275,313,237);\n");
      f.cArea.append("DrawShapeCurve(260,304,221,228,172,255);\n");
      f.cArea.append("DrawShapeEnd();\n");
      f.cArea.append("//画像上部の「保存」ボタンを押して下さい。\n");
      init();
    }
    else if(com.equals("LBG"))
    {  //●ロゴ入り画像（スタンプ押印）
      f.cArea.setText("");
      f.cArea.append("//スタンプ押印\n");
      f.cArea.append("SaveImage(\"./image/BirdwatchingZClub.png\");\n");
      f.cArea.append("AffineScale(1);\n");
      f.cArea.append("Size(720,1008);\n");
      f.cArea.append("Image(0,0,720,1008,\"./image/image1.png\");\n");
      f.cArea.append("Antialias(true);\n");
      f.cArea.append("ForegroundColorB(240,240,240);\n");
      f.cArea.append("ForegroundColorS(0,0,0);\n");
      f.cArea.append(
        "Stamp(314,601,100,100,\"./image/ZLogo.png\");\n");
      f.cArea.append(
        "WriteStringBMulti(110,220,80,3,\"sansserif\",\"野鳥観察の栞\");\n");
      f.cArea.append(
        "WriteStringH(110,220,80,\"sansserif\",\"野鳥観察の栞\");\n");
      f.cArea.append(
        "WriteStringBMulti(168,910,53,3,\"sansserif\",\"野鳥観察Ｚ会編\");\n");
      f.cArea.append(
        "WriteStringH(168,910,53,\"sansserif\",\"野鳥観察Ｚ会編\");\n");
      f.cArea.append("//画像上部の「保存」ボタンを押して下さい。\n");
      init();
    }
    else if(com.equals("REV"))
    {  //●画像鏡像反転
      f.cArea.setText("");
      f.cArea.append("//画像鏡像反転\n");
      f.cArea.append("Size(720,1008);\n");
      f.cArea.append("ReverseImage(\"./image/BirdwatchingZClub.png\",1);\n");
      f.cArea.append("//モードが５または７の場合、回転処理済み画像保存を伴う。\n");
      init();
    }
    else if(com.equals("CAS"))
    {  //●画像切取り保存
      f.cArea.setText("");
      f.cArea.append("//画像切取り保存\n");
      f.cArea.append("AffineScale(1);\n");
      f.cArea.append("Size(720,1008);\n");
      f.cArea.append("Image(0,0,720,1008,\"./image/BirdwatchingZClub.png\");\n");
      f.cArea.append("CutAndSaveImage(100,140,600,240,\"./image/BirdwatchingZClubCut.png\");\n");
      f.cArea.append("//「切取」ボタンを押すことで、画像切取りと画像保存とが実行される。\n");
      init();
    }
    else if(com.equals("MSK"))
    {  //●切り貼り用マルチ・マスク画像
      f.cArea.setText("");
      f.cArea.append("//切り貼り用マルチ・マスク作成\n");
      f.cArea.append("SaveImage(\"./image/multiMask.png\");\n");
      f.cArea.append("AffineScale(1);\n");
      f.cArea.append("Size(720,1008);\n");
      f.cArea.append("BackgroundColor(0,0,200);\n");
      f.cArea.append("DrawShapeStart(2,360,96,200,0,0);\n");
      f.cArea.append("DrawShapeLine(120,336);\n");
      f.cArea.append("DrawShapeLine(360,574);\n");
      f.cArea.append("DrawShapeLine(600,336);\n");
      f.cArea.append("DrawShapeEnd();\n");
      f.cArea.append("DrawShapeStart(2,360,432,0,200,0);\n");
      f.cArea.append("DrawShapeLine(120,672);\n");
      f.cArea.append("DrawShapeLine(360,912);\n");
      f.cArea.append("DrawShapeLine(360,912);\n");
      f.cArea.append("DrawShapeLine(600,672);\n");
      f.cArea.append("DrawShapeEnd();\n");
      f.cArea.append("//画像上部の「保存」ボタンを押して下さい。\n");
      init();
    }
    else if(com.equals("CAP"))
    {  //●切り貼り画像処理
      f.cArea.setText("");
      f.cArea.append("//切り貼り画像処理\n");
      f.cArea.append("Size(720,1008);\n");
      f.cArea.append("CutAndPasteMask(\"./image/multiMask.png\");\n");
      f.cArea.append("CutAndPaste(\"./image/image1.png\", 0,0,200);\n");
      f.cArea.append("CutAndPaste(\"./image/image2.png\", 200,0,0);\n");
      f.cArea.append("CutAndPaste(\"./image/image3.png\", 0,200,0);\n");
      init();
    }
    else if(com.equals("CCM"))
    {  //●連続色相変更処理
      f.cArea.setText("");
      f.cArea.append("//連続色相変更処理\n");
      f.cArea.append("Size(720,1008);\n");
      f.cArea.append("ChangeColorMultiBase(\"./image/MultiMask.png\");\n");
      f.cArea.append("ChangeColorMulti(200,0,0,200,0,200);\n");
      f.cArea.append("ChangeColorMulti(0,200,0,200,200,50);\n");
      f.cArea.append("ChangeColorMulti(0,0,200,250,150,50);\n");
      f.cArea.append("Image(750,0,720,1008,\"./image/MultiMask.png\");\n");
      init();
    }
    else if(com.equals("MiM"))
    {  //●二重画像用グレー・マスク作成
      f.cArea.setText("");
      f.cArea.append("//二重画像用グレー・マスク作成\n");
      f.cArea.append("SaveImage(\"./image/image4.png\");\n");
      f.cArea.append("AffineScale(1);\n");
      f.cArea.append("Size(720,1008);\n");
      f.cArea.append("BackgroundColor(200,200,200);\n");
      f.cArea.append("DrawCircle(2,360,340,260,200,0,0);\n");
      f.cArea.append("DrawCircle(2,360,680,260,0,0,200);\n");
      f.cArea.append("//画像上部の「保存」ボタンを押して下さい。\n");
      init();
    }
    else if(com.equals("Mix"))
    {  //●二重像画像処理
      f.cArea.setText("");
      f.cArea.append("//二重像画像処理\n");
      f.cArea.append("Size(720,1008);\n");
      f.cArea.append("MixImage(\"./image/image1.png\", \"./image/image4.png\");\n");
      f.cArea.append("Image(200,200,720,1008,\"./image/image1.png\");\n");
      f.cArea.append("Image(400,400,720,1008,\"./image/image4.png\");\n");
      init();
    }
    else if(com.equals("SFx"))
    {  //●ソフト・フォーカス処理準備
      f.cArea.setText("");
      f.cArea.append("//ソフト・フォーカス処理準備（同心円描画）\n");
      f.cArea.append("SaveImage(\"./image/circles.png\");\n");
      f.cArea.append("AffineScale(1);\n");
      f.cArea.append("Size(720,1008);\n");
      f.cArea.append("Antialias(true);\n");
      f.cArea.append("BackgroundColor(200,200,200);\n");
      f.cArea.append("DrawCircle(2,240,240,200,50,100,200);\n");
      f.cArea.append("DrawCircle(2,240,240,150,100,150,250);\n");
      f.cArea.append("DrawCircle(2,240,240,100,100,200,250);\n");
      f.cArea.append("DrawCircle(2,240,240,50,150,250,250);\n");
      f.cArea.append("//画像上部の「保存」ボタンを押して下さい。\n");
      init();
    }
    else if(com.equals("SFo"))
    {  //●ソフト・フォーカス処理
      f.cArea.setText("");
      f.cArea.append("//ソフト・フォーカス処理\n");
      f.cArea.append("SaveImage(\"./image/circlesSF.png\");\n");
      f.cArea.append("AffineScale(1);\n");
      f.cArea.append("Size(720,1008);\n");
      f.cArea.append("SoftFocus(\"./image/circles.png\", 10);\n");
      f.cArea.append("//画像上部の「保存」ボタンを押して下さい。\n");
      init();
    }
    else if(com.equals("RoI"))
    {  //●画像多段階回転描画用の元画像の準備
      f.cArea.setText("");
      f.cArea.append("//画像多段階回転描画用の元画像の準備\n");
      f.cArea.append("SaveImage(\"./image/rotateMaltiImage.png\");\n");
      f.cArea.append("Size(600,600); //外枠\n");
      f.cArea.append("DrawRect(1,98,98,402,402,0,0,0); //内枠\n");
      f.cArea.append("DrawCircle(1,300,300,284,0,0,0); //回転範囲\n");
      f.cArea.append("BackgroundColor(200,200,200);\n");
      f.cArea.append("//\n");
      f.cArea.append("DrawShapeStart(2,300,100,50,50,250);\n");
      f.cArea.append("DrawShapeLine(270,330);\n");
      f.cArea.append("DrawShapeLine(330,330);\n");
      f.cArea.append("DrawShapeEnd();\n");
      f.cArea.append("//画像上部の「保存」ボタンを押して下さい。\n");
      init();
    }
    else if(com.equals("RoM"))
    {  //●画像多段階回転描画
      f.cArea.setText("");
      f.cArea.append("//画像多段階回転描画\n");
      f.cArea.append("Size(600,600);\n");
      f.cArea.append("RotateMulti(0,30, 12, \"./image/rotateMaltiImage.png\");\n");
      f.cArea.append("Image(610,0,600,600,\"./image/rotateMaltiImage.png\");\n");
      f.cArea.append("//RotateMulti(30,30, 1, \"./image/circlesSF.png\");\n");
      f.cArea.append("//Image(610,0,720,1008,\"./image/circlesSF.png\");\n");
      f.cArea.append("//階調画像は、多段階回転に適さず、一段階回転に限定される。\n");
      f.cArea.append("//画像周囲に回転余裕がないと、画像の一部だけの回転になる。\n");
      init();
    }
    else if(com.equals("ChC"))
    {  //●単独色相変更処理
      f.cArea.setText("");
      f.cArea.append("//単独色相変更処理\n");
      f.cArea.append("Size(720,1008);\n");
      f.cArea.append("ChangeColor(\"./image/circlesSF.png\", 5,100,200,250,255,0,0);\n");
      f.cArea.append("Image(730,0,720,1008,\"./image/circlesSF.png\");\n");
      init();
    }
    else if(com.equals("Adj"))
    {  //●色相調整処理
      f.cArea.setText("");
      f.cArea.append("//色相調整処理\n");
      f.cArea.append("Size(720,1008);\n");
      f.cArea.append("AdjustRGB(\"./image/image1.png\", 30, -20, 20);\n");
      f.cArea.append("Image(100,100,720,1008,\"./image/image1.png\");\n");
      init();
    }
    else if(com.equals("Grd"))
    {  //●色相階調加工
      f.cArea.setText("");
      f.cArea.append("//色相階調加工\n");
      f.cArea.append("Size(720,1008);\n");
      f.cArea.append("ColorGradient(\"./image/image3.png\", 100, 504, 0.1, -0.2, -0.1);\n");
      f.cArea.append("//ColorGradient(\"./image/image3.png\", 0, 1008, 0.1, -0.2, -0.1);\n");
      f.cArea.append("Image(100,100,720,1008,\"./image/image3.png\");\n");
      init();
    }
    else if(com.equals("Sp1"))
    {  //●スプライン曲線図形１
      f.cArea.setText("");
      f.cArea.append("//スプライン曲線図形１\n");
      f.cArea.append("SaveImage(\"./image/splineOutline.png\");\n");
      f.cArea.append("Size(500,500);\n");
      f.cArea.append("ForegroundColorL(0,0,0);\n");
      f.cArea.append("BackgroundColor(200,200,200);\n");
      f.cArea.append("DrawSplineStart(235,155);\n");
      f.cArea.append("DrawSplineControl(348,77);\n");
      f.cArea.append("DrawSplineControl(418,156);\n");
      f.cArea.append("DrawSplineControl(391,305);\n");
      f.cArea.append("DrawSplineControl(234,441);\n");
      f.cArea.append("DrawSplineControl(97,314);\n");
      f.cArea.append("DrawSplineControl(61,159);\n");
      f.cArea.append("DrawSplineControl(130,77);\n");
      f.cArea.append("DrawSplineEnd(235,155);\n");
      f.cArea.append("//画像上部の「保存」ボタンを押して下さい。\n");
      init();
    }
    else if(com.equals("SpP"))
    {  //●輪郭線図形内部単独彩色
      f.cArea.setText("");
      f.cArea.append("//輪郭線図形内部単独彩色\n");
      f.cArea.append("Size(500,500);\n");
      f.cArea.append("ChangeColorInner(\"./image/splineOutline.png\", 0, 0, 0, 200, 40, 150, 250,250,1);\n");
      init();
    }
    else if(com.equals("Sp2"))
    {  //●スプライン曲線図形２
      f.cArea.setText("");
      f.cArea.append("//スプライン曲線図形２\n");
      f.cArea.append("SaveImage(\"./image/splineOutline2.png\");\n");
      f.cArea.append("Size(500,500);\n");
      f.cArea.append("ForegroundColorL(200,200,200);\n");
      f.cArea.append("BackgroundColor(60,100,220);\n");
      f.cArea.append("DrawSplineStart(235,155);\n");
      f.cArea.append("DrawSplineControl(348,77);\n");
      f.cArea.append("DrawSplineControl(418,156);\n");
      f.cArea.append("DrawSplineControl(391,305);\n");
      f.cArea.append("DrawSplineControl(234,441);\n");
      f.cArea.append("DrawSplineControl(97,314);\n");
      f.cArea.append("DrawSplineControl(61,159);\n");
      f.cArea.append("DrawSplineControl(130,77);\n");
      f.cArea.append("DrawSplineEnd(235,155);\n");
      f.cArea.append("//\n");
      f.cArea.append("DrawSplineStart(58,222);\n");
      f.cArea.append("DrawSplineControl(122,207);\n");
      f.cArea.append("DrawSplineControl(186,267);\n");
      f.cArea.append("DrawSplineControl(270,198);\n");
      f.cArea.append("DrawSplineControl(313,275);\n");
      f.cArea.append("DrawSplineControl(383,183);\n");
      f.cArea.append("DrawSplineEnd(418,245);\n");
      f.cArea.append("//画像上部の「保存」ボタンを押して下さい。\n");
      init();
    }
    else if(com.equals("SpM"))
    {  //●輪郭線図形内部連続彩色
      f.cArea.setText("");
      f.cArea.append("//輪郭線図形内部連続彩色\n");
      f.cArea.append("SaveImage(\"./image/splineOutline2A.png\");\n");
      f.cArea.append("Size(500,500);\n");
      f.cArea.append("ChangeColorInnerMultiMask(\"./image/splineOutline2.png\", 200, 200, 200);\n");
      f.cArea.append("ChangeColorInnerMulti(20, 40, 150, 250,190);\n");
      f.cArea.append("ChangeColorInnerMulti(220, 40, 50, 250,340);\n");
      f.cArea.append("//画像上部の「保存」ボタンを押して下さい。\n");
      init();
    }
    else if(com.equals("SpS"))
    {  //●輪郭線図形内部連続彩色ソフト・フォーカス
      f.cArea.setText("");
      f.cArea.append("//輪郭線図形内部連続彩色ソフト・フォーカス\n");
      f.cArea.append("SaveImage(\"./image/splineOutline2B.png\");\n");
      f.cArea.append("Size(500,500);\n");
      f.cArea.append("SoftFocus(\"./image/splineOutline2A.png\", 5);\n");
      f.cArea.append("//画像上部の「保存」ボタンを押して下さい。\n");
      f.cArea.append("//ソフト・フォーカスは、画像加工の仕上げ段階で行う。\n");
      init();
    }
    else if(com.equals("SpF"))
    {  //●輪郭線図形内部連続彩色フィニッシュ
      f.cArea.setText("");
      f.cArea.append("//輪郭線図形内部連続彩色フィニッシュ\n");
      f.cArea.append("Size(500,500);\n");
      f.cArea.append("Image(0,0,500,500,\"./image/splineOutline2B.png\");\n");
      f.cArea.append("Stamp(0,0,500,500,\"./image/splineOutline2A.png\");\n");
      init();
    }

    else if(com.equals("Sp3"))
    {  //●スプライン曲線図形３
       //内部彩色処理を高速化するには、点描画機能などを用い、彩色部の数箇所に指定色を塗っておく。
      f.cArea.setText("");
      f.cArea.append("//スプライン曲線図形３／高速内部彩色用\n");
      f.cArea.append("SaveImage(\"./image/splineOutline3.png\");\n");
      f.cArea.append("Size(500,500);\n");
      f.cArea.append("ForegroundColorL(200,200,200);\n");
      f.cArea.append("BackgroundColor(60,160,20);\n");
      f.cArea.append("DrawRect(1,70,70,340,350,43,65,162);\n");
      f.cArea.append("//\n");
      f.cArea.append("DrawSplineStart(70,199);\n");
      f.cArea.append("DrawSplineControl(121,105);\n");
      f.cArea.append("DrawSplineControl(160,227);\n");
      f.cArea.append("DrawSplineControl(218,102);\n");
      f.cArea.append("DrawSplineControl(246,285);\n");
      f.cArea.append("DrawSplineControl(280,119);\n");
      f.cArea.append("DrawSplineControl(352,231);\n");
      f.cArea.append("DrawSplineControl(364,125);\n");
      f.cArea.append("DrawSplineEnd(410,275);\n");
      f.cArea.append("//\n");
      f.cArea.append("DrawSplineStart(70,351);\n");
      f.cArea.append("DrawSplineControl(108,247);\n");
      f.cArea.append("DrawSplineControl(164,367);\n");
      f.cArea.append("DrawSplineControl(206,192);\n");
      f.cArea.append("DrawSplineControl(253,378);\n");
      f.cArea.append("DrawSplineControl(309,216);\n");
      f.cArea.append("DrawSplineControl(352,379);\n");
      f.cArea.append("DrawSplineControl(378,232);\n");
      f.cArea.append("DrawSplineEnd(410,397);\n");
      f.cArea.append("//\n");
      f.cArea.append("DrawCircle(2,132,236,4.0,255,0,255);\n");
      f.cArea.append("DrawCircle(2,223,162,4.0,255,0,255);\n");
      f.cArea.append("DrawCircle(2,261,321,4.0,255,0,255);\n");
      f.cArea.append("DrawCircle(2,289,175,4.0,255,0,255);\n");
      f.cArea.append("DrawCircle(2,349,311,4.0,255,0,255);\n");
      f.cArea.append("DrawCircle(2,381,195,4.0,255,0,255);\n");
      f.cArea.append("DrawCircle(2,403,278,4.0,255,0,255);\n");
      f.cArea.append("//画像上部の「保存」ボタンを押して下さい。\n");
      init();
    }
    else if(com.equals("SpX"))
    {  //●輪郭線図形内部高速連続彩色
      f.cArea.setText("");
      f.cArea.append("//輪郭線図形内部高速連続彩色\n");
      f.cArea.append("Size(500,500);\n");
      f.cArea.append("ChangeColorInnerMultiMask(\"./image/splineOutline3.png\", 200, 200, 200);\n");
      f.cArea.append("ChangeColorInnerMulti(80, 80, 250, 80,80);\n");
      f.cArea.append("ChangeColorInnerMulti(255, 0, 255, 80, 200);\n");
      f.cArea.append("ChangeColorInnerMulti(80, 70, 150, 80,370);\n");
      init();
    }

    //●画像の特殊加工は、以上で終了。

    else if(com.equals("NCP"))
    {  //●カード印刷
      f.cArea.setText("");
      f.cArea.append("//はがき用紙にカードを二枚印刷\n");
      f.cArea.append("//はがきサイズ： 100 x 148 mm　（300 x 444 px）\n");
      f.cArea.append("//名刺サイズ：    90 x  55 mm　（270 x 165 px）\n");
      f.cArea.append("//カード・サイズ：85 x  54 mm　（255 x 162 px）\n");
      f.cArea.append("//\n");
      f.cArea.append("Size(100,148,\"mm\"); //はがきサイズ\n");
      f.cArea.append("Antialias(true);\n");
      f.cArea.append("DrawRect(1,15,43,255,162,255,255,255); //カード・サイズ\n");
      f.cArea.append("DrawRect(1,15,243,255,162,255,255,255); //カード・サイズ\n");
      f.cArea.append("//\n");
      f.cArea.append("WriteStringH(33,70,12,\"BIZ UDゴシック\",\"『思考方法概論』\");\n");
      f.cArea.append("WriteStringH(33,90,12,\"BIZ UDゴシック\",\"『Java実例プログラミング』描画処理編\");\n");
      f.cArea.append("WriteStringH(33,110,12,\"BIZ UDゴシック\",\"『Java実例プログラミング』事務処理編\");\n");
      f.cArea.append("WriteStringH(33,130,12,\"Consolas\",\"https://rakue.ganriki.net/\");\n");
      f.cArea.append("WriteStringH(33,150,12,\"Consolas\",\"https://dl.ndl.go.jp/pid/13727096\");\n");
      f.cArea.append("WriteStringH(33,170,12,\"Consolas\",\"https://dl.ndl.go.jp/pid/13307204\");\n");
      f.cArea.append("WriteStringH(33,190,12,\"Consolas\",\"https://dl.ndl.go.jp/pid/13719801\");\n");
      f.cArea.append("//\n");
      f.cArea.append("WriteStringH(33,270,12,\"BIZ UDゴシック\",\"『思考方法概論』\");\n");
      f.cArea.append("WriteStringH(33,290,12,\"BIZ UDゴシック\",\"『Java実例プログラミング』描画処理編\");\n");
      f.cArea.append("WriteStringH(33,310,12,\"BIZ UDゴシック\",\"『Java実例プログラミング』事務処理編\");\n");
      f.cArea.append("WriteStringH(33,330,12,\"Consolas\",\"https://rakue.ganriki.net/\");\n");
      f.cArea.append("WriteStringH(33,350,12,\"Consolas\",\"https://dl.ndl.go.jp/pid/13727096\");\n");
      f.cArea.append("WriteStringH(33,370,12,\"Consolas\",\"https://dl.ndl.go.jp/pid/13307204\");\n");
      f.cArea.append("WriteStringH(33,390,12,\"Consolas\",\"https://dl.ndl.go.jp/pid/13719801\");\n");
      init();
    }
    else if(com.equals("Lay"))
    {  //●全体レイアウト・スケール
      f.cArea.setText("");
      f.cArea.append("//全体レイアウト・スケール\n");
      f.cArea.append("//Size(720,1008);\n");
      f.cArea.append("//BackgroundColor(200,200,200);\n");
      f.cArea.append("//\n");

      f.cArea.append("//B5規格は、182x257mm\n");
      f.cArea.append("//Size(830,1170); //B5判印刷用に描画枠拡大\n");
      f.cArea.append("//FreeScale(0.65); //B5判に画像縮小\n");
      f.cArea.append("//Shift(1,55,100); //B5判印刷用に余白調整\n");
      f.cArea.append("//\n");

      f.cArea.append("//A4規格は、210x297mm\n");
      f.cArea.append("Size(958,1354); //A4判印刷用に描画枠拡大\n");
      f.cArea.append("FreeScale(0.65); //A4判に画像縮小\n");
      f.cArea.append("Shift(1,110,150); //A4判印刷用に余白調整\n");
      f.cArea.append("//\n");

      f.cArea.append("DrawParallelLineH(0,0,720,48,22,1,1);\n"); //横平行線
      f.cArea.append("DrawParallelLineV(0,0,1008,48,16,1,1);\n"); //縦平行線

      f.cArea.append("LineWidth(1.0);\n");
      f.cArea.append("DrawLine(360,0,360,1008);\n"); //横中央線
      f.cArea.append("DrawLine(0,504,720,504);\n"); //縦中央線
      f.cArea.append("FontBold(true);\n");

      f.cArea.append("//横目盛り（px）\n");
      f.cArea.append("WriteStringH(32,18,13,\"sansserif\",\"96\");\n");
      f.cArea.append("WriteStringH(74,18,13,\"sansserif\",\"192\");\n");
      f.cArea.append("WriteStringH(121,18,13,\"sansserif\",\"288\");\n");
      f.cArea.append("WriteStringH(169,18,13,\"sansserif\",\"386\");\n");
      f.cArea.append("WriteStringH(217,18,13,\"sansserif\",\"480\");\n");
      f.cArea.append("WriteStringH(265,18,13,\"sansserif\",\"576\");\n");
      f.cArea.append("WriteStringH(313,18,13,\"sansserif\",\"672\");\n");
      f.cArea.append("WriteStringH(362,18,13,\"sansserif\",\"768\");\n");
      f.cArea.append("WriteStringH(409,18,13,\"sansserif\",\"864\");\n");
      f.cArea.append("WriteStringH(457,18,13,\"sansserif\",\"960\");\n");
      f.cArea.append("WriteStringH(497,18,13,\"sansserif\",\"1056\");\n");
      f.cArea.append("WriteStringH(545,18,13,\"sansserif\",\"1152\");\n");
      f.cArea.append("WriteStringH(593,18,13,\"sansserif\",\"1248\");\n");
      f.cArea.append("WriteStringH(641,18,13,\"sansserif\",\"1344\");\n");
      f.cArea.append("WriteStringH(689,18,13,\"sansserif\",\"1440\");\n");

      f.cArea.append("WriteStringH(32,981,13,\"sansserif\",\"96\");\n");
      f.cArea.append("WriteStringH(74,981,13,\"sansserif\",\"192\");\n");
      f.cArea.append("WriteStringH(121,981,13,\"sansserif\",\"288\");\n");
      f.cArea.append("WriteStringH(169,981,13,\"sansserif\",\"386\");\n");
      f.cArea.append("WriteStringH(217,981,13,\"sansserif\",\"480\");\n");
      f.cArea.append("WriteStringH(265,981,13,\"sansserif\",\"576\");\n");
      f.cArea.append("WriteStringH(313,981,13,\"sansserif\",\"672\");\n");
      f.cArea.append("WriteStringH(362,981,13,\"sansserif\",\"768\");\n");
      f.cArea.append("WriteStringH(409,981,13,\"sansserif\",\"864\");\n");
      f.cArea.append("WriteStringH(457,981,13,\"sansserif\",\"960\");\n");
      f.cArea.append("WriteStringH(497,981,13,\"sansserif\",\"1056\");\n");
      f.cArea.append("WriteStringH(545,981,13,\"sansserif\",\"1152\");\n");
      f.cArea.append("WriteStringH(593,981,13,\"sansserif\",\"1248\");\n");
      f.cArea.append("WriteStringH(641,981,13,\"sansserif\",\"1344\");\n");
      f.cArea.append("WriteStringH(689,981,13,\"sansserif\",\"1440\");\n");

      f.cArea.append("//縦目盛り（px）\n");
      f.cArea.append("WriteStringH(17,46,13,\"sansserif\",\"96\");\n");
      f.cArea.append("WriteStringH(11,94,13,\"sansserif\",\"192\");\n");
      f.cArea.append("WriteStringH(11,142,13,\"sansserif\",\"288\");\n");
      f.cArea.append("WriteStringH(11,190,13,\"sansserif\",\"384\");\n");
      f.cArea.append("WriteStringH(11,238,13,\"sansserif\",\"480\");\n");
      f.cArea.append("WriteStringH(11,286,13,\"sansserif\",\"576\");\n");
      f.cArea.append("WriteStringH(11,334,13,\"sansserif\",\"672\");\n");
      f.cArea.append("WriteStringH(11,382,13,\"sansserif\",\"768\");\n");
      f.cArea.append("WriteStringH(11,430,13,\"sansserif\",\"864\");\n");
      f.cArea.append("WriteStringH(11,478,13,\"sansserif\",\"960\");\n");
      f.cArea.append("WriteStringH(3,526,13,\"sansserif\",\"1056\");\n");
      f.cArea.append("WriteStringH(3,574,13,\"sansserif\",\"1152\");\n");
      f.cArea.append("WriteStringH(3,622,13,\"sansserif\",\"1248\");\n");
      f.cArea.append("WriteStringH(3,670,13,\"sansserif\",\"1344\");\n");
      f.cArea.append("WriteStringH(3,718,13,\"sansserif\",\"1440\");\n");
      f.cArea.append("WriteStringH(3,766,13,\"sansserif\",\"1536\");\n");
      f.cArea.append("WriteStringH(3,814,13,\"sansserif\",\"1632\");\n");
      f.cArea.append("WriteStringH(3,862,13,\"sansserif\",\"1728\");\n");
      f.cArea.append("WriteStringH(3,910,13,\"sansserif\",\"1824\");\n");
      f.cArea.append("WriteStringH(3,958,13,\"sansserif\",\"1920\");\n");
      f.cArea.append("WriteStringH(3,1004,13,\"sansserif\",\"2016\");\n");

      f.cArea.append("WriteStringH(699,46,13,\"sansserif\",\"96\");\n");
      f.cArea.append("WriteStringH(693,94,13,\"sansserif\",\"192\");\n");
      f.cArea.append("WriteStringH(693,142,13,\"sansserif\",\"288\");\n");
      f.cArea.append("WriteStringH(693,190,13,\"sansserif\",\"384\");\n");
      f.cArea.append("WriteStringH(693,238,13,\"sansserif\",\"480\");\n");
      f.cArea.append("WriteStringH(693,286,13,\"sansserif\",\"576\");\n");
      f.cArea.append("WriteStringH(693,334,13,\"sansserif\",\"672\");\n");
      f.cArea.append("WriteStringH(693,382,13,\"sansserif\",\"768\");\n");
      f.cArea.append("WriteStringH(693,430,13,\"sansserif\",\"864\");\n");
      f.cArea.append("WriteStringH(693,478,13,\"sansserif\",\"960\");\n");
      f.cArea.append("WriteStringH(687,526,13,\"sansserif\",\"1056\");\n");
      f.cArea.append("WriteStringH(687,574,13,\"sansserif\",\"1152\");\n");
      f.cArea.append("WriteStringH(687,622,13,\"sansserif\",\"1248\");\n");
      f.cArea.append("WriteStringH(687,670,13,\"sansserif\",\"1344\");\n");
      f.cArea.append("WriteStringH(687,718,13,\"sansserif\",\"1440\");\n");
      f.cArea.append("WriteStringH(687,766,13,\"sansserif\",\"1536\");\n");
      f.cArea.append("WriteStringH(687,814,13,\"sansserif\",\"1632\");\n");
      f.cArea.append("WriteStringH(687,862,13,\"sansserif\",\"1728\");\n");
      f.cArea.append("WriteStringH(687,910,13,\"sansserif\",\"1824\");\n");
      f.cArea.append("WriteStringH(687,958,13,\"sansserif\",\"1920\");\n");
      f.cArea.append("WriteStringH(687,1004,13,\"sansserif\",\"2016\");\n");
      init();
    }

    else if(com.equals("La2"))
    {  //●部品レイアウト・スケール
      f.cArea.setText("");
      f.cArea.append("//部品レイアウト・スケール\n");
      f.cArea.append("//Size(720,1008);\n");
      f.cArea.append("//\n");

      f.cArea.append("//B5規格は、182x257mm\n");
      f.cArea.append("Size(830,1170); //B5判印刷用に描画枠拡大\n");
      f.cArea.append("FreeScale(0.65); //B5判に画像縮小\n");
      f.cArea.append("Shift(1,55,210); //B5判印刷用に余白調整\n");
      f.cArea.append("//\n");

      f.cArea.append("//A4規格は、210x297mm\n");
      f.cArea.append("//Size(958,1354); //A4判印刷用に描画枠拡大\n");
      f.cArea.append("//FreeScale(0.65); //A4判に画像縮小\n");
      f.cArea.append("//Shift(1,100,250); //A4判印刷用に余白調整\n");
      f.cArea.append("//\n");

      f.cArea.append("DrawParallelLineH(0,0,720,12,61,1,0);\n");
      f.cArea.append("DrawParallelLineV(0,0,720,12,61,1,0);\n");
      f.cArea.append("DrawParallelLineH2(0,0,720,72,11,0,0);\n");
      f.cArea.append("DrawParallelLineV2(0,0,720,72,11,0,0);\n");
      f.cArea.append("WriteStringH(90,780,12,\"sansserif\",\"1 unit = 6 cell × 6 cell\");\n");
      f.cArea.append("WriteStringH(90,800,12,\"sansserif\",\"1 side = 6 cell × 10 unit = 60 cell\");\n");
      init();
    }
    else if(com.equals("RLS"))
    {  //●多段階回転画像作成用レイアウト・スケール
      f.cArea.setText("");
      f.cArea.append("//多段階回転画像作成用レイアウト・スケール\n");
      f.cArea.append("Size(600,600); //外枠\n");
      f.cArea.append("BackgroundColor(200,200,200); //グレー背景色\n");
      f.cArea.append("//以下は補助線（画像保存時にコメント・アウトすること）\n");
      f.cArea.append("DrawCircle(1,300,300,283,0,0,0); //回転範囲\n");
      f.cArea.append("DrawParallelLineH(100,100,400,10,41,1,0); //方眼線\n");
      f.cArea.append("DrawParallelLineV(100,100,400,10,41,1,0);\n");
      f.cArea.append("DrawParallelLineH2(0,0,600,50,13,0,0);\n");
      f.cArea.append("DrawParallelLineV2(0,0,600,50,13,0,0);\n");
      f.cArea.append("DrawLine(100,100,500,500);\n");
      f.cArea.append("DrawLine(500,100,100,500);\n");
      init();
    }

    else if(com.equals("TA4"))
    {  //●A4印刷テスト図形Ａ４
      f.cArea.setText("");
      f.cArea.append("//印刷テスト図形Ａ４（印刷不能マージン確認）\n");
      f.cArea.append("Size(\"A4\");\n");
      f.cArea.append("FontBold(true);\n");
      f.cArea.append("DrawLine(0,0,630,891);\n");
      f.cArea.append("DrawLine(630,0,0,891);\n");
      f.cArea.append("DrawLine(0,445.5,630,445.5);\n");
      f.cArea.append("DrawLine(315,0,315,891);\n");
      f.cArea.append("DrawLine(315,0,0,445.5);\n");
      f.cArea.append("DrawLine(157.5,222.5,315,222.5);\n");
      f.cArea.append("DrawLine(157.5,222.5,157.5,445.5);\n");
      f.cArea.append("DrawLine(0,445.5,315,891);\n");
      f.cArea.append("DrawLine(630,445.5,315,891);\n");
      f.cArea.append("DrawLine(315,0,630,445.5);\n");
      f.cArea.append(
        "WriteStringH(90,60,24,\"sansserif\",\"GCreator A4\");\n");
      f.cArea.append(
        "WriteStringH(90,90,15,\"sansserif\",\"210x297mm\");\n");
      f.cArea.append(
        "WriteStringH(216,240,15,\"sansserif\",\"52.5mm\");\n");
      f.cArea.append(
        "WriteStringH(162,330,15,\"sansserif\",\"74.25mm\");\n");
      f.cArea.append(
        "WriteStringH(315,445.5,48,\"sansserif\",\"活字48pt\");\n");
      init();
    }
    else if(com.equals("Pht"))
    {  //●フォント表示テスト１
      f.cArea.setText("");
      f.cArea.append("//フォント表示テスト１\n");
      f.cArea.append("Size(\"A4\");\n");
      f.cArea.append("Antialias(true);\n");
      f.cArea.append("FontBold(false);\n");

      f.cArea.append("WriteString(30,60,15,\"sansserif\","+
          "\"漢字かなカナＡＢａｂABab01.2*+-=#$@!?■● [sansserif]\");\n");
      f.cArea.append("WriteString(30,90,15,\"serif\","+
          "\"漢字かなカナＡＢａｂABab01.2*+-=#$@!?■● [serif]\");\n");
      f.cArea.append("WriteString(30,120,15,\"monospaced\","+
          "\"漢字かなカナＡＢａｂABab01.2*+-=#$@!?■● [monospaced]\");\n");
      f.cArea.append("WriteString(30,150,15,\"dialog\","+
          "\"漢字かなカナＡＢａｂABab01.2*+-=#$@!?■● [dialog]\");\n");
      f.cArea.append("WriteString(30,180,15,\"dialoginput\","+
          "\"漢字かなカナＡＢａｂABab01.2*+-=#$@!?■● [dialoginput]\");\n");
      f.cArea.append("//以上は、仮想的な論理フォントで、以下は、実体的な物理フォント。\n");
      f.cArea.append("//論理フォントは、日英二種類の物理フォントの組み合わせである。\n");
      f.cArea.append("//論理フォント名は、大文字小文字の区別をしない。\n");

      f.cArea.append("//\n");
      f.cArea.append("WriteString(30,210,15,\"Arial\","+
          "\"漢字かなカナＡＢａｂABab01.2*+-=#$@!?■● [Arial]\");\n");
      f.cArea.append("WriteString(30,240,15,\"Times New Roman\","+
          "\"漢字かなカナＡＢａｂABab01.2*+-=#$@!?■● [Times New Roman]\");\n");
      f.cArea.append("WriteString(30,270,15,\"Courier New\","+
          "\"漢字かなカナＡＢａｂABab01.2*+-=#$@!?■● [Courier New]\");\n");
      f.cArea.append("//\n");

      f.cArea.append("WriteString(30,300,15,\"ＭＳ ゴシック\","+
          "\"漢字かなカナＡＢａｂABab01.2*+-=#$@!?■● [ＭＳ ゴシック]\");\n");
      f.cArea.append("WriteString(30,330,15,\"ＭＳ 明朝\","+
          "\"漢字かなカナＡＢａｂABab01.2*+-=#$@!?■● [ＭＳ 明朝]\");\n");
      f.cArea.append("WriteString(30,360,15,\"ＭＳ Ｐゴシック\","+
          "\"漢字かなカナＡＢａｂABab01.2*+-=#$@!?■● [ＭＳ Ｐゴシック]\");\n");
      f.cArea.append("WriteString(30,390,15,\"ＭＳ Ｐ明朝\","+
          "\"漢字かなカナＡＢａｂABab01.2*+-=#$@!?■● [ＭＳ Ｐ明朝]\");\n");
      f.cArea.append("WriteString(30,420,15,\"MS UI Gothic\","+
          "\"漢字かなカナＡＢａｂABab01.2*+-=#$@!?■● [MS UI Gothic]\");\n");

      f.cArea.append("WriteString(30,450,15,\"游ゴシック\","+
          "\"漢字かなカナＡＢａｂABab01.2*+-=#$@!?■● [游ゴシック]\");\n");
      f.cArea.append("WriteString(30,480,15,\"游明朝\","+
          "\"漢字かなカナＡＢａｂABab01.2*+-=#$@!?■● [游明朝]\");\n");

      f.cArea.append("WriteString(30,510,15,\"BIZ UDPゴシック\","+
          "\"漢字かなカナＡＢａｂABab01.2*+-=#$@!?■● [BIZ UDPゴシック]\");\n");
      f.cArea.append("WriteString(30,540,15,\"BIZ UDP明朝 Medium\","+
          "\"漢字かなカナＡＢａｂABab01.2*+-=#$@!?■● [BIZ UDP明朝 Medium]\");\n");
      f.cArea.append("WriteString(30,570,15,\"BIZ UDゴシック\","+
          "\"漢字かなカナＡＢａｂABab01.2*+-=#$@!?■● [BIZ UDゴシック]\");\n");
      f.cArea.append("WriteString(30,600,15,\"BIZ UD明朝 Medium\","+
          "\"漢字かなカナＡＢａｂABab01.2*+-=#$@!?■● [BIZ UD明朝 Medium]\");\n");

      f.cArea.append("WriteString(30,630,15,\"Meiryo UI\","+
          "\"漢字かなカナＡＢａｂABab01.2*+-=#$@!?■● [Meiryo UI]\");\n");
      f.cArea.append("WriteString(30,660,15,\"メイリオ\","+
          "\"漢字かなカナＡＢａｂABab01.2*+-=#$@!?■● [メイリオ]\");\n");

      f.cArea.append("WriteString(30,690,15,\"UD デジタル 教科書体 N\","+
          "\"漢字かなカナＡＢａｂABab01.2*+-=#$@!?■● [UD デジタル 教科書体 N]\");\n");
      f.cArea.append("WriteString(30,720,15,\"UD デジタル 教科書体 NK\","+
          "\"漢字かなカナＡＢａｂABab01.2*+-=#$@!?■● [UD デジタル 教科書体 NK]\");\n");
      f.cArea.append("WriteString(30,750,15,\"UD デジタル 教科書体 NP\","+
          "\"漢字かなカナＡＢａｂABab01.2*+-=#$@!?■● [UD デジタル 教科書体 NP]\");\n");

      f.cArea.append("//Windows11 に搭載されているフォントの表示。\n");
      f.cArea.append("//フォント名は、全角と半角との違いに注意。\n");
      f.cArea.append("//フォント名を間違うと、「sansserif」での表示になる。\n");
      init();
    }
    else if(com.equals("Ph2"))
    {  //●フォント表示テスト２
      f.cArea.setText("");
      f.cArea.append("//フォント表示テスト（詳細拡張版）\n");
      f.cArea.append("Size(\"A4\");\n");
      f.cArea.append("Antialias(true);\n");
      f.cArea.append("FontBold(false);\n");

      f.cArea.append("WriteString(30,60,15,\"BIZ UDPゴシック Regular\","+
          "\"漢字かなカナＡＢａｂABab01.2*+-=#$@!?■● [BIZ UDPゴシック Regular]\");\n");
      f.cArea.append("WriteString(30,90,15,\"BIZ UDPゴシック Bold\","+
          "\"漢字かなカナＡＢａｂABab01.2*+-=#$@!?■● [BIZ UDPゴシック Bold]\");\n");

      f.cArea.append("WriteString(30,120,15,\"BIZ UDゴシック Regular\","+
          "\"漢字かなカナＡＢａｂABab01.2*+-=#$@!?■● [BIZ UDゴシック Regular]\");\n");
      f.cArea.append("WriteString(30,150,15,\"BIZ UDゴシック Bold\","+
          "\"漢字かなカナＡＢａｂABab01.2*+-=#$@!?■● [BIZ UDゴシック Bold]\");\n");

      f.cArea.append("WriteString(30,180,15,\"Meiryo UI Regular\","+
          "\"漢字かなカナＡＢａｂABab01.2*+-=#$@!?■● [Meiryo UI Regular]\");\n");
      f.cArea.append("WriteString(30,210,15,\"Meiryo UI Bold\","+
          "\"漢字かなカナＡＢａｂABab01.2*+-=#$@!?■● [Meiryo UI Bold]\");\n");
      f.cArea.append("WriteString(30,240,15,\"Meiryo UI Italic\","+
          "\"漢字かなカナＡＢａｂABab01.2*+-=#$@!?■● [Meiryo UI Italic]\");\n");
      f.cArea.append("WriteString(30,270,15,\"Meiryo Bold Italic\","+
          "\"漢字かなカナＡＢａｂABab01.2*+-=#$@!?■● [Meiryo UI Bold Italic]\");\n");
      f.cArea.append("WriteString(30,300,15,\"メイリオ レギュラー\","+
          "\"漢字かなカナＡＢａｂABab01.2*+-=#$@!?■● [メイリオ レギュラー]\");\n");
      f.cArea.append("WriteString(30,330,15,\"メイリオ ボールド\","+
          "\"漢字かなカナＡＢａｂABab01.2*+-=#$@!?■● [メイリオ ボールド]\");\n");
      f.cArea.append("WriteString(30,360,15,\"メイリオ イタリック\","+
          "\"漢字かなカナＡＢａｂABab01.2*+-=#$@!?■● [メイリオ イタリック]\");\n");
      f.cArea.append("WriteString(30,390,15,\"メイリオ ボールド イタリック\","+
          "\"漢字かなカナＡＢａｂABab01.2*+-=#$@!?■● [メイリオ ボールド イタリック]\");\n");

      f.cArea.append("WriteString(30,420,15,\"Yu Gothic UI Light\","+
          "\"漢字かなカナＡＢａｂABab01.2*+-=#$@!?■● [Yu Gothic UI Light]\");\n");
      f.cArea.append("WriteString(30,450,15,\"Yu Gothic UI Semilight\","+
          "\"漢字かなカナＡＢａｂABab01.2*+-=#$@!?■● [Yu Gothic UI Semilight]\");\n");
      f.cArea.append("WriteString(30,480,15,\"Yu Gothic UI Regular\","+
          "\"漢字かなカナＡＢａｂABab01.2*+-=#$@!?■● [Yu Gothic UI Regular]\");\n");
      f.cArea.append("WriteString(30,510,15,\"Yu Gothic UI Semibold\","+
          "\"漢字かなカナＡＢａｂABab01.2*+-=#$@!?■● [Yu Gothic UI Semibold]\");\n");
      f.cArea.append("WriteString(30,540,15,\"Yu Gothic UI Bold\","+
          "\"漢字かなカナＡＢａｂABab01.2*+-=#$@!?■● [Yu Gothic UI Bold]\");\n");

      f.cArea.append("WriteString(30,570,15,\"游ゴシック Light\","+
          "\"漢字かなカナＡＢａｂABab01.2*+-=#$@!?■● [游ゴシック Light]\");\n");
      f.cArea.append("WriteString(30,600,15,\"游ゴシック Regular\","+
          "\"漢字かなカナＡＢａｂABab01.2*+-=#$@!?■● [游ゴシック Regular]\");\n");
      f.cArea.append("WriteString(30,630,15,\"游ゴシック Medium\","+
          "\"漢字かなカナＡＢａｂABab01.2*+-=#$@!?■● [游ゴシック Medium]\");\n");
      f.cArea.append("WriteString(30,660,15,\"游ゴシック Bold\","+
          "\"漢字かなカナＡＢａｂABab01.2*+-=#$@!?■● [游ゴシック Bold]\");\n");

      f.cArea.append("WriteString(30,690,15,\"游明朝 Light\","+
          "\"漢字かなカナＡＢａｂABab01.2*+-=#$@!?■● [游明朝 Light]\");\n");
      f.cArea.append("WriteString(30,720,15,\"游明朝 Regular\","+
          "\"漢字かなカナＡＢａｂABab01.2*+-=#$@!?■● [游明朝 Regular]\");\n");
      f.cArea.append("WriteString(30,750,15,\"游明朝 Demibold\","+
          "\"漢字かなカナＡＢａｂABab01.2*+-=#$@!?■● [游明朝 Demibold]\");\n");

      f.cArea.append("WriteString(30,810,15,\"sansserif\","+
          "\"以下は、コンピューター関連用途に便利な英文等幅フォント\");\n");
      f.cArea.append("WriteString(30,840,15,\"Consolas\","+
          "\"漢字かなカナＡＢａｂABab01.2*+-=#$@!?■● [Consolas]\");\n");

      f.cArea.append("//Windows11 に搭載されているフォントの表示。\n");
      f.cArea.append("//フォント名は、空白の個数、全角と半角、これらの違いに注意。\n");
      f.cArea.append("//フォント名を間違うと、「sansserif」での表示になる。\n");
      init();
    }
    else if(com.equals("XL4"))
    {  //●拡大率：４倍
      f.canvas.affineScale = f.xL4;
      f.scaleLabel.setText("  (a:x4.0)");
      init();
    }
    else if(com.equals("XL3"))
    {  //●拡大率：３倍
      f.canvas.affineScale = f.xL3;
      f.scaleLabel.setText("  (a:x3.0)");
      init();
    }
    else if(com.equals("XL2"))
    {  //●拡大率：２倍
      f.canvas.affineScale = f.xL2;
      f.scaleLabel.setText("  (a:x2.0)");
      init();
    }
    else if(com.equals("XML"))
    {  //●拡大率：１．５倍
      f.canvas.affineScale = f.xML;
      f.scaleLabel.setText("  (a:x1.5)");
      init();
    }
    else if(com.equals("XM1"))
    {  //●拡大率：１倍
      f.canvas.affineScale = f.xM1;
      f.scaleLabel.setText("  (a:x1.0)");
      init();
    }
    else if(com.equals("XMS"))
    {  //●拡大率：１／１．５倍
      f.canvas.affineScale = f.xMS;
      f.scaleLabel.setText("  (a:x1/1.5)");
      init();
    }
    else if(com.equals("XS2"))
    {  //●拡大率：１／２倍
      f.canvas.affineScale = f.xS2;
      f.scaleLabel.setText("  (a:x1/2)");
      init();
    }
    else if(com.equals("XS3"))
    {  //●拡大率：１／３倍
      f.canvas.affineScale = f.xS3;
      f.scaleLabel.setText("  (a:x1/3)");
      init();
    }
    else if(com.equals("XS4"))
    {  //●拡大率：１／４倍
      f.canvas.affineScale = f.xS4;
      f.scaleLabel.setText("  (a:x1/4)");
      init();
    }
    else if(com.equals("Lin"))
    {  //●直線マウス描画モード
      f.cMouseLis.senMouseMode = 1;
      f.cMouseLis.clear();
    }
    else if(com.equals("Eli"))
    {  //●直線マウス消去モード
      f.cMouseLis.senMouseMode = 6;
      f.cMouseLis.clear();
    }
    else if(com.equals("Cur"))
    {  //●ベジェ曲線マウス描画モード
      f.cMouseLis.senMouseMode = 9;
      f.cMouseLis.clear();
    }
    else if(com.equals("Spl"))
    {  //●スプライン曲線マウス描画モード
      f.cMouseLis.senMouseMode = 22;
      f.cMouseLis.clear();
    }
    else if(com.equals("AC3"))
    {  //●座標点マウス修正モード
      f.cMouseLis.senMouseMode = 10;
      f.cMouseLis.clear();
    }
    else if(com.equals("ECu"))
    {  //●描画目印線の消去
      f.canvas.markFlag = false;
      f.cMouseLis.clear();
    }
    else if(com.equals("DCu"))
    {  //●描画目印線の復活
      f.canvas.markFlag = true;
      f.cMouseLis.clear();
    }
    else if(com.equals("Cir"))
    {  //●真円の描画モード
      f.cMouseLis.senMouseMode = 2;
      f.cMouseLis.clear();
    }
    else if(com.equals("Ell"))
    {  //●楕円のマウス入力モード
      f.cMouseLis.senMouseMode = 8;
      f.cMouseLis.clear();
    }
    else if(com.equals("Rec"))
    {  //●四角形のマウス入力モード
      f.cMouseLis.senMouseMode = 20;
      f.cMouseLis.clear();
    }
    else if(com.equals("Fre"))
    {  //●自由図形のマウス入力モード
      f.cMouseLis.senMouseMode = 14;
      f.cMouseLis.clear();
    }
    else if(com.equals("Str"))
    {  //●文字のマウス記入モード
      f.cMouseLis.senMouseMode = 3;
      f.cMouseLis.clear();
    }
    else if(com.equals("St2"))
    {  //●表題のマウス記入モード
      f.cMouseLis.senMouseMode = 13;
      f.cMouseLis.clear();
    }
    else if(com.equals("Pos"))
    {  //●位置確認モード
      f.cMouseLis.senMouseMode = 4;
      f.cMouseLis.clear();
    }
    else if(com.equals("Ref"))
    {  //●命令文検索モード
      f.cMouseLis.senMouseMode = 15;
      f.cMouseLis.clear();
    }
    else if(com.equals("Clx"))
    {  //●色相確認モード
      f.cMouseLis.senMouseMode = 21;
      f.canvas.markFlag = false; //最新マウス・ポイント目印十字線を消す
      f.cMouseLis.clear();
    }
    else if(com.equals("CoP"))
    {  //●塗り色変更モード（混色パレット使用）
      f.cMouseLis.senMouseMode = 19;
      f.cMouseLis.clear();
    }
    else if(com.equals("Of1"))
    {  //●マウス「線描画」モード
      f.cMouseLis.senMouseModeFlag = true;
      f.cMouseLis.tenMouseModeFlag = false;
      f.canvas.currentPointX =  0;
      f.canvas.currentPointY =  0;
      f.canvas.markFlag = true;
      f.mouseModeLabel.setText("線描画モード");
      f.cMouseLis.clear();
    }
    else if(com.equals("Of2"))
    {  //●マウス「点描画」モード
      f.cMouseLis.senMouseModeFlag = false;
      f.cMouseLis.tenMouseModeFlag = true;
      f.canvas.currentPointX = 0;
      f.canvas.currentPointY = 0;
      f.canvas.markFlag = false;
      f.changeLayout(2); //パレット表示も行なう
      f.mouseModeLabel.setText("点描画モード");
      f.pMouseLis.clear();
    }
    else if(com.equals("Of3"))
    {  //●マウス描画無効
      f.cMouseLis.senMouseModeFlag = false;
      f.cMouseLis.tenMouseModeFlag = false;
      f.canvas.currentPointX = 0;
      f.canvas.currentPointY = 0;
      f.canvas.markFlag = false;
      f.mouseModeLabel.setText("マウス描画無効モード");
      f.cMouseLis.clear();
    }
    else if(com.equals("Sc1"))
    {  //●パレット非表示
      f.changeLayout(1);
      f.canvas.currentPointX =  0;
      f.canvas.currentPointY =  0;
    }
    else if(com.equals("Sc2"))
    {  //●パレット表示
      f.changeLayout(2);
      f.canvas.currentPointX = 0;
      f.canvas.currentPointY = 0;
    }
    else if(com.equals("BrL"))
    {  //●点描画筆（巨）
      f.cMouseLis.brushSize = 8;
      f.mouseModeLabel.setText("点描画モード(" + "8)");
    }
    else if(com.equals("BrM"))
    {  //●点描画筆（大）
      f.cMouseLis.brushSize = 4;
      f.mouseModeLabel.setText("点描画モード(" + "4)");
    }
    else if(com.equals("BrS"))
    {  //●点描画筆（中）
      f.cMouseLis.brushSize = 2;
      f.mouseModeLabel.setText("点描画モード(" + "2)");
    }
    else if(com.equals("BrX"))
    {  //●点描画筆（小）
      f.cMouseLis.brushSize = 1;
      f.mouseModeLabel.setText("点描画モード(" + "1)");
    }
    else if(com.equals("BrZ"))
    {  //●点描画筆（微）
      f.cMouseLis.brushSize = 0.5;
      f.mouseModeLabel.setText("点描画モード(" + "0.5)");
    }
    else if(com.equals("Usa"))
    {  //●命令仕様書
      Util.textBrowseCCP(f, new File(
        "./sys/GCreator_Manual.txt"));
    }
    else if(com.equals("Ptn"))
    {  //●模様データ
      Util.textBrowseCCP(f, new File(
        "./sys/GCreator_Pattern.txt"));
    }
    else
    {
      f.message("メニューに該当なし");
    }
  }
  void init()
  {
    f.canvas.setInit2(); //特殊初期化（先行実施）
    f.canvas.setInit();  //一般初期化（後続実施）
    f.canvas.setInit3(); //追加特殊初期化（最終実施）
    f.canvas.repaint();  //描画実行
  }
} //EOF (GCreatorMenuLis.java)

◆GCreatorButtonLis.java

//■■GCreatorButtonLis.java
//Ver.3.3

//■■インポート
import java.awt.event.*;  //必須
import java.util.*;  //必須
import java.io.*;  //必須

//■■JButtonのイベントリスナー
class GCreatorButtonLis implements ActionListener
{
  //■メンバー変数
  GCreator f;
  boolean cutAndSaveFlag = false;

  //■コンストラクタ
  GCreatorButtonLis(GCreator flame)
  {
    f = flame;
  }

  //■JButtonのイベントハンドラ
  public void actionPerformed(ActionEvent event)
  {
    String com = event.getActionCommand();
    if(com.equals("Rep"))
    {   //●グラフィックの再描画（「描画」ボタン）
        //命令文書を書き換えた場合、「描画」ボタンを押すこと。

    //各種特殊コマンドの下準備
      f.canvas.setInit2(); //特殊初期化（先行実施）
      f.canvas.setInit();  //一般初期化（後続実施）
      f.canvas.setInit3(); //追加特殊初期化（最終実施）
      f.canvas.repaint();  //再描画（多用途対応）
    }
    else if(com.equals("Rp2"))
    {  //●グラフィックのマトリックス模様更新（「乱数」ボタン）
      if(f.canvas.matrixPatternNumSt>0)
        f.canvas.rgbSt = f.canvas.getRandom_rgbSt();
      if(f.canvas.matrixPatternNumEx>0)
        f.canvas.rgbEx = f.canvas.getRandom_rgbEx();
      f.canvas.randomSeed2 = f.canvas.ran.nextInt();
      f.canvas.repaint();  //乱数効果の画像を表示
    }
    else if(com.equals("Can"))
    {  //●パレット混色取消（「取消」ボタン）
      f.pMouseLis.clear();
      f.sldR.setValue(0);
      f.sldG.setValue(0);
      f.sldB.setValue(0);
    }
    else if(com.equals("Adj"))
    {  //●スライダー修正値のゼロ・クリア（「復元」ボタン）
      f.sldR.setValue(0);
      f.sldG.setValue(0);
      f.sldB.setValue(0);
    }

    else if(com.equals("SvC"))
    {  //●命令文書の保存
      if(!f.canvas.saveCmdFName.equals("") && f.canvas.saveCmdFName != null)
      {
        f.canvas.setInit();  //一般初期化のみ
        f.io.save(f.cArea, f.canvas.saveCmdFName);
      }
      else
        f.message("ファイル名の指定がなく、命令文書を保存できません。");
    }
    else if(com.equals("SvI"))
    {  //●作成画像の全体保存
      f.canvas.canSaveMode = true;
      f.canvas.markFlag = false;
      f.canvas.setInit();  //一般初期化のみ
      f.canvas.repaint();
      cutAndSaveFlag = false;

      if(!f.canvas.saveImgFName.equals(""))
      {
        f.io.saveGraphics(new File(f.canvas.saveImgFName), 0, 0,
          (int)(f.canvas.imagePX_W*f.canvas.affineScale*f.canvas.freeScale),
          (int)(f.canvas.imagePX_H*f.canvas.affineScale*f.canvas.freeScale));
      }
      else
        f.message("ファイル名の指定がなく、全体画像を保存できません。");
      f.canvas.canSaveMode = false;
    }
    else if(com.equals("SvP"))
    {  //●作成画像の部分切取り保存
      f.canvas.setInit();  //一般初期化のみ
      f.canvas.canSaveMode = true;
      f.canvas.markFlag = false;
      f.canvas.repaint();
      cutAndSaveFlag = true;

      if(cutAndSaveFlag = true && !f.canvas.cutAndSaveImgFName.equals(""))
      {
        f.io.saveGraphics(new File(f.canvas.cutAndSaveImgFName),
          f.canvas.cutAndSaveImgX1, f.canvas.cutAndSaveImgY1,
          f.canvas.cutAndSaveImgX2-f.canvas.cutAndSaveImgX1,
          f.canvas.cutAndSaveImgY2-f.canvas.cutAndSaveImgY1);
      }
      else
      {
        f.message("ファイル名の指定がなく、切取り画像を保存できません。");
      }
      cutAndSaveFlag = false;
      f.canvas.canSaveMode = false;
    }
    else
      f.message("ボタン機能に該当なし");
  }
} //EOF (GCreatorButtonLis.java)

◆GCreatorCanMouseLis.java

//■■GCreatorCanMouseLis.java
//Ver.3.3

//■■インポート
import java.awt.*;  //必須
import java.awt.event.*;  //必須
import javax.swing.*;  //必須
import java.util.*;  //必須

import java.awt.geom.*;
import java.awt.image.*;
import java.io.*;
import javax.imageio.*;
import javax.imageio.stream.*;

//■■キャンバス上のマウスのクリックで呼び出されるリスナー。
//描画命令を自動生成して、cAreaに順次書き込む。
class GCreatorCanMouseLis implements MouseListener
{
  //■メンバー変数
  GCreator f;
  int x1 = 0;
  int y1 = 0;
  int x2 = 0;
  int y2 = 0;
  int x3 = 0;
  int y3 = 0;
  int x4 = 0;
  int y4 = 0;
  double brushSize = 4; //点描画用の筆のサイズ
  int strCnt = 1;  //文字列描画命令における文字列番号
  int curveCnt = 1;  //ベジェ曲線ポイント番号（始点が1、終点が4）
  int splineCnt = 1;  //スプライン曲線ポイント番号（始点が1、制御点が2以上）
  int splineX0;
  int splineY0;
  int senMouseMode = 0;  //0が無効、1以上が線描画マウス入力機能種別
  boolean senMouseModeFlag = false;
  boolean tenMouseModeFlag = false;
  boolean startFlag = true;  //線の始点か否かの判定
  boolean horizontFlag = true; //楕円の横半径指定クリックか否かの判定
  String commandX = ""; //自由図形での右クリック曲線制御点での命令文
  boolean okButton = false; //塗り色変更の実行または中止

  //■コンストラクタ
  GCreatorCanMouseLis(GCreator flame)
  {
    f = flame;
  }

  //■イベントハンドラ
  public void mousePressed(MouseEvent eve)
  {
    //●マウス入力モードが両方解除状態なら
    if((senMouseModeFlag == false) && (tenMouseModeFlag == false))
    {
      clear();
      return;
    }
    //●特殊モードには非対応
    if(f.canvas.rotateFlag  || f.canvas.rotateFreeFlag ||
      f.canvas.shiftMode!=0 || f.canvas.freeScale!=1.0)
    {
      f.message("Rotate、RotateFree、Shift、FreeScale がある命令文書は、" +
        "マウス操作に非対応。該当命令文をコメント・アウトして下さい。");
      return;
    }
    int x = eve.getX(); //マウスのクリック位置を取得
    int y = eve.getY();

    //●線描画モードで、左ボタンがクリックされた場合の動作
    if((senMouseModeFlag == true) && (tenMouseModeFlag == false) &&
      (eve.getButton() == MouseEvent.BUTTON1) )
    {
      if(senMouseMode == 1 && startFlag)
      { //●直線の第一段階
        //マウスクリック位置の端数を四捨五入
        x1 = (int)(x/f.canvas.affineScale +0.5); //端数四捨五入
        y1 = (int)(y/f.canvas.affineScale +0.5);
        startFlag = false;
        f.canvas.currentPointX = x1;
        f.canvas.currentPointY = y1;
      }
      else if(senMouseMode == 1 && !startFlag)
      { //●直線の第二段階
        x2 = (int)(x/f.canvas.affineScale +0.5); //端数四捨五入
        y2 = (int)(y/f.canvas.affineScale +0.5);
        String method = "DrawLine(" +
          x1 + "," + y1 + "," +
          x2 + "," + y2 + ");";
        f.cArea.append("\n" + method);
        startFlag = true;
        f.canvas.currentPointX = x2;
        f.canvas.currentPointY = y2;
        clear();
      }

      else if(senMouseMode == 20 && startFlag)
      { //●四角形の第一段階
        //マウスクリック位置の端数を四捨五入
        x1 = (int)(x/f.canvas.affineScale +0.5); //端数四捨五入
        y1 = (int)(y/f.canvas.affineScale +0.5);
        startFlag = false;
        f.canvas.currentPointX = x1;
        f.canvas.currentPointY = y1;
      }
      else if(senMouseMode == 20 && !startFlag)
      { //●四角形の第二段階
        x2 = (int)(x/f.canvas.affineScale +0.5); //端数四捨五入
        y2 = (int)(y/f.canvas.affineScale +0.5);
        //m: 描画モード、0は描画せず、1は線、2は色塗り、3は線と色
        //x: ｘ座標
        //y: ｙ座標
        //w: 幅
        //h: 丈
        //r: R
        //g: G
        //b: B
        int rc = colorRanNum();
        int gc = colorRanNum();
        int bc = colorRanNum();
        int w = x2 - x1;
        int h = y2 - y1;
        if(w<0) w = w* -1; //マイナスは不可
        if(h<0) h = h* -1; //マイナスは不可
        String method = "DrawRect(3," +
          x1 + "," + y1 + "," +
          w + "," + h + "," +
          rc +"," + gc + "," + bc + ");";
        f.cArea.append("\n" + method);
        startFlag = true;
        f.canvas.currentPointX = x2;
        f.canvas.currentPointY = y2;
        clear();
      }

      else if((senMouseMode == 2) && startFlag)
      { //●真円の第一段階：円の中心をクリック
        x1 = (int)(x/f.canvas.affineScale +0.5); //端数四捨五入
        y1 = (int)(y/f.canvas.affineScale +0.5);
        f.canvas.currentPointX = x1;
        f.canvas.currentPointY = y1;
        startFlag = false;
      }
      else if((senMouseMode == 2)&& !startFlag)
      {  //●真円の第二段階：円の右端か左端をクリック
        x2 = (int)(x/f.canvas.affineScale +0.5)-x1; //端数四捨五入
        if(x2 <0)
          x2 = x2* -1; //絶対値に
        if(x2 == 0)
          x2 = 1; //半径0は、１に強制変更
        if(senMouseMode == 2) //●真円
        {
          int rc = colorRanNum();
          int gc = colorRanNum();
          int bc = colorRanNum();
          String method = "DrawCircle(3," +
            x1 + "," + y1 + "," + x2+ "," +
            rc +"," + gc + "," + bc + ");";
          f.cArea.append("\n" + method);
        }
        startFlag = true;
        clear();
      }

      else if((senMouseMode == 8) && startFlag)
      { //●楕円の第一段階：中心をクリック
        x1 = (int)(x/f.canvas.affineScale +0.5); //端数四捨五入
        y1 = (int)(y/f.canvas.affineScale +0.5);
        f.canvas.currentPointX = x1;
        f.canvas.currentPointY = y1;
        startFlag = false;
      }
      else if((senMouseMode == 8) && !startFlag &&
        horizontFlag)
      {  //●楕円の第二段階：右端か左端をクリック
        x2 = (int)(x/f.canvas.affineScale +0.5)-x1; //端数四捨五入
        if(x2 <0)
          x2 = x2* -1;
        if(x2 == 0)
          x2 = 1;
        horizontFlag = false;
        f.canvas.currentPointX = x1;
        f.canvas.currentPointY = y1;
      }
      else if((senMouseMode == 8 || senMouseMode == 17) &&
        !startFlag && !horizontFlag)
      {  //●楕円の第三段階：上端か下端をクリック
        y2 = (int)(y/f.canvas.affineScale +0.5)-y1; //端数四捨五入
        if(y2 <0)
          y2 = y2* -1;
        if(y2 == 0)
          y2 = 1;
        if(senMouseMode == 8) //●楕円
        {
          int rc = colorRanNum();
          int gc = colorRanNum();
          int bc = colorRanNum();
          String method = "DrawEllipse(3," +
            x1 + "," + y1 + "," + x2 + "," + y2 + "," +
            rc +"," + gc + "," + bc + ");";
          f.cArea.append("\n" + method);
        }
        startFlag = true;
        horizontFlag = true;
        clear();
      }

      else if(senMouseMode == 9 && curveCnt == 1)
      { //●ベジェ曲線の第一段階：曲線の始点をクリック
        x1 = (int)(x/f.canvas.affineScale +0.5); //端数四捨五入
        y1 = (int)(y/f.canvas.affineScale +0.5);
        f.canvas.currentPointX = x1;
        f.canvas.currentPointY = y1;
        curveCnt++;
      }
      else if(senMouseMode == 9 && curveCnt == 2)
      {  //●ベジェ曲線の第二段階：曲線の第二点をクリック
        x2 = (int)(x/f.canvas.affineScale +0.5); //端数四捨五入
        y2 = (int)(y/f.canvas.affineScale +0.5);
        curveCnt++;
        String method = "  DrawLine2(3," + x1 + "," + y1 + "," +
            x2 + "," + y2 + ");";
        f.canvas.currentPointX = x2;
        f.canvas.currentPointY = y2;
        f.cArea.append("\n" + method);
      }
      else if(senMouseMode == 9 && curveCnt == 3)
      {  //●ベジェ曲線の第三段階：曲線の第三点をクリック
        x3 = (int)(x/f.canvas.affineScale +0.5); //端数四捨五入
        y3 = (int)(y/f.canvas.affineScale +0.5);
        curveCnt++;
        String method = "  DrawLine2(2," + x2 + "," + y2 + "," +
            x3 + "," + y3 + ");";
        f.canvas.currentPointX = x3;
        f.canvas.currentPointY = y3;
        f.cArea.append("\n" + method);
      }
      else if(senMouseMode == 9 && curveCnt == 4)
      {  //●ベジェ曲線の第四段階：曲線の終点をクリック
        x4 = (int)(x/f.canvas.affineScale +0.5); //端数四捨五入
        y4 = (int)(y/f.canvas.affineScale +0.5);
        String method = "  DrawLine2(3," + x3 + "," + y3 + "," +
            x4 + "," + y4 + ");";
        f.cArea.append("\n" + method);
        method =
          "DrawCurve(" +
          x1 + "," + y1 + "," +
          x2 + "," + y2 + "," +
          x3 + "," + y3 + "," +
          x4 + "," + y4 +  ");";
        f.cArea.append("\n" + method);
        f.canvas.currentPointX = x4;
        f.canvas.currentPointY = y4;
        curveCnt = 1;
        erase("DrawLine2");
        clear();
      }

      else if(senMouseMode == 22 && splineCnt == 1)
      { //●スプライン曲線の第一段階：曲線の始点をクリック
        x1 = (int)(x/f.canvas.affineScale +0.5); //端数四捨五入
        y1 = (int)(y/f.canvas.affineScale +0.5);
        f.canvas.currentPointX = x1;
        f.canvas.currentPointY = y1;
        String method;
        method = "DrawSplineStart(" + x1 + "," + y1 + ");";
        f.cArea.append("\n" + method);
        splineX0 = x1;
        splineY0 = y1;
        splineCnt++;
      }
      else if(senMouseMode == 22 && splineCnt > 1)
      { //●スプライン曲線の第二段階：曲線の制御点をクリック
        //制御点の位置指定が連続して同じ位置を間違ってクリックした場合、
        //終点を指定した後も、スプライン曲線が描画されず、補助線だけの表示となる。
        x1 = (int)(x/f.canvas.affineScale +0.5); //端数四捨五入
        y1 = (int)(y/f.canvas.affineScale +0.5);
        f.canvas.currentPointX = x1;
        f.canvas.currentPointY = y1;
        String method;
        method = "DrawSplineControl(" + x1 + "," + y1 + ");";
        f.cArea.append("\n" + method);
        method = "  DrawLine2(" + 3 + "," + splineX0 + "," + splineY0 +  "," + x1 + "," + y1 + ");";
        f.cArea.append("\n" + method);
        splineX0 = x1;
        splineY0 = y1;
        splineCnt++;
      }

      else if(senMouseMode == 13)
      { //●文字列描画
        int mX = (int)(x/f.canvas.affineScale +0.5); //端数四捨五入
        int mY = (int)(y/f.canvas.affineScale +0.5);
        String method = "WriteStringH(" + mX + "," + mY + "," +
          15 + "," + "\"sansserif\"" + ",\"□" + strCnt + "\");";
        f.cArea.append("\n" + method);
        strCnt++;
        startFlag = true;
        clear();
      }

      else if(senMouseMode == 4)
      { //●位置確認モード（FreeScale命令には、非対応）
        int mX = (int)(x/f.canvas.affineScale +0.5); //端数四捨五入
        int mY = (int)(y/f.canvas.affineScale +0.5);
        f.canvas.currentPointX = mX;
        f.canvas.currentPointY = mY;
        f.message("X=" + x + "  Y=" + y + "  [X=" + mX + "  Y=" + mY + "]");
        startFlag = true;
        clear();
      }

      else if(senMouseMode == 21)
      { //●色相確認モード
        f.canvas.currentPointX = x; //マウスのクリック位置
        f.canvas.currentPointY = y;
        int cR = 0;
        int cG = 0;
        int cB = 0;
        BufferedImage bImage = f.io.canvas2BufferedImage(0, 0,
          (int)(f.canvas.imagePX_W*f.canvas.affineScale*f.canvas.freeScale +0.5),  //端数四捨五入
          (int)(f.canvas.imagePX_H*f.canvas.affineScale*f.canvas.freeScale +0.5)); //画像全体
        int rgbValue =  bImage.getRGB(x,y);
          //getRGB(x,y)は、デフォルトRGBカラー・モデル(TYPE_INT_ARGB)および
          //デフォルトsRGBカラー・スペースで整数型ピクセルを返すメソッド。
          //ただし、実際は、互換タイプ（TYPE_INT_RGB）に変換されている。
        String errMsg = "";
        cR = (rgbValue & 0x00ff0000) >>> 16;
        cG = (rgbValue & 0x0000ff00) >>> 8;
        cB = (rgbValue & 0x000000ff);
        String type =
          errMsg +
          "RGB={" + cR + ", " + cG + ", " + cB +"} " +
          "RGB_hex={" + Integer.toHexString(rgbValue) + "} ";
        int colorType = bImage.getType();
        if(colorType == BufferedImage.TYPE_3BYTE_BGR)
          f.message(type+"TYPE_3BYTE_BGR");
        else if(colorType == BufferedImage.TYPE_4BYTE_ABGR)
          f.message(type+"TYPE_4BYTE_ABGR");
        else if(colorType == BufferedImage.TYPE_4BYTE_ABGR_PRE)
          f.message(type+"TYPE_4BYTE_ABGR_PRE");
        else if(colorType == BufferedImage.TYPE_BYTE_BINARY)
          f.message(type+"TYPE_BYTE_BINARY");
        else if(colorType == BufferedImage.TYPE_BYTE_GRAY)
          f.message(type+"TYPE_BYTE_GRAY");
        else if(colorType == BufferedImage.TYPE_BYTE_INDEXED)
          f.message(type+"TYPE_BYTE_INDEXED");
        else if(colorType == BufferedImage.TYPE_CUSTOM)
          f.message(type+"TYPE_CUSTOM");
        else if(colorType == BufferedImage.TYPE_INT_ARGB)
          f.message(type+"TYPE_INT_ARGB");
        else if(colorType == BufferedImage.TYPE_INT_ARGB_PRE)
          f.message(type+"TYPE_INT_ARGB_PRE");
        else if(colorType == BufferedImage.TYPE_INT_BGR)
          f.message(type+"TYPE_INT_BGR");
        else if(colorType == BufferedImage.TYPE_INT_RGB)
          f.message(type+"TYPE_INT_RGB");
        else if(colorType == BufferedImage.TYPE_USHORT_555_RGB)
          f.message(type+"TYPE_USHORT_555_RGB");
        else if(colorType == BufferedImage.TYPE_USHORT_565_RGB)
          f.message(type+"TYPE_USHORT_565_RGB");
        else if(colorType == BufferedImage.TYPE_USHORT_GRAY)
          f.message(type+"TYPE_USHORT_GRAY");
        else
          f.message(type+"カラー・モデル不明" );
        startFlag = true;
        clear();
      }

      else if(senMouseMode == 15)
      { //●命令文検索
        int mX = (int)(x/f.canvas.affineScale +0.5);
        int mY = (int)(y/f.canvas.affineScale +0.5);
        refer(mX,mY);
        startFlag = true;
        clear();
      }

      else if((senMouseMode == 5 || senMouseMode == 6) && startFlag)
      { //●直線の消去における始点位置
        x1 = (int)(x/f.canvas.affineScale +0.5);
        y1 = (int)(y/f.canvas.affineScale +0.5);
        startFlag = false;
      }

      else if((senMouseMode == 5 || senMouseMode == 6) && !startFlag)
      { //●直線の消去における終点位置
        x2 = (int)(x/f.canvas.affineScale +0.5);
        y2 = (int)(y/f.canvas.affineScale +0.5);
        if(senMouseMode == 5)
        {
          replace(true, x1, y1, x2, y2);
        }
        else
        {
          replace(false, x1, y1, x2, y2);
        }
        startFlag = true;
        clear();
      }

      else if((senMouseMode == 10) && startFlag)
      { //●位置修正における旧点位置
        x1 = (int)(x/f.canvas.affineScale +0.5);
        y1 = (int)(y/f.canvas.affineScale +0.5);
        startFlag = false;
      }
      else if((senMouseMode == 10) && !startFlag)
      { //●位置修正における新点位置
        x2 = (int)(x/f.canvas.affineScale +0.5);
        y2 = (int)(y/f.canvas.affineScale +0.5);
        replacePoint(x1, y1, x2, y2);
        startFlag = true;
        clear();
      }

      //自由図形は、直線とベジェ曲線とを混用して閉じた輪郭線の図形を描画し、
      //必要に応じて、その内部を色塗りする。
      //左クリックは直線の指定で、右クリックは曲線の指定になる。
      //ただし、自由図形の始点は、常に左クリックとする。
      //また、自由図形の終点（始点への回帰）が曲線の終点でもある場合は、
      //左クリックを終点で一つ追加して終了させる。
      else if(senMouseMode == 14 && startFlag)
      { //●自由図形の第一段階（▼始点）
        x1 = (int)(x/f.canvas.affineScale +0.5);
        y1 = (int)(y/f.canvas.affineScale +0.5);

        int rc = colorRanNum();
        int gc = colorRanNum();
        int bc = colorRanNum();
        String method = "DrawShapeStart(4," + x1 + "," + y1 + "," +
          rc +"," + gc + "," + bc + ");";
        f.cArea.append("\n" + method);
        f.canvas.currentPointX = x1;
        f.canvas.currentPointY = y1;
        x2=x1; //x1,y1は、自由図形の始点として温存する。
        y2=y1; //x2,y2は、中間線での起点とする。
        startFlag = false;
      }
      else if(senMouseMode == 14 && !startFlag)
      { //●自由図形＜直線＞の第二段階（中間点と終点）
        x3 = (int)(x/f.canvas.affineScale +0.5); //x3,y3は、中間線での
        y3 = (int)(y/f.canvas.affineScale +0.5); //末点として扱う。
        int Q = 2; //許容誤差（特に始点と終点との一致判定での許容誤差）
        if( ((x1+Q) >= x3 && (x1-Q) <= x3)  &&
          ((y1+Q) >= y3 && (y1-Q) <= y3)  )
        { //指定位置の近傍点をクリックした場合、
          //僅かにずれたものと見なして、一致させる。
          x3=x1;
          y3=y1;
        }
        if(!(x1==x3 && y1==y3)) //▼自由図形＜直線＞中間点
        {
          String method = "DrawShapeLine(" +
            x3 + "," + y3 + ");";
          f.cArea.append("\n" + method);
          method = "  DrawLine2(0," + x2 + "," + y2 + "," +
            x3 + "," + y3 + ");"; //直線部の合図として、マイナス値
          f.canvas.currentPointX = x3;
          f.canvas.currentPointY = y3;
          f.cArea.append("\n" + method);
          x2=x3; //次の線の始点を次の段階に伝える
          y2=y3;
        }
        else //▼自由図形終点
        {
          String method = "DrawShapeEnd();";
          f.cArea.append("\n" + method);
          method = "  DrawLine2(0," + x2 + "," + y2 + "," +
            x3 + "," + y3 + ");";
          f.cArea.append("\n" + method + "\n//");
          f.canvas.currentPointX = x1;
          f.canvas.currentPointY = y1;
          startFlag = true;
          erase("DrawLine2");
          clear();
        }
      }

      //これ以降は、「else if」ではなく、「if」で条件判定。

      if(senMouseMode == 19)
      { //●パレット混色での指定色で彩色変更。
        //パレットで混色指定済みの上で、図形指定（始点クリック）を行なうことで、
        //彩色変更がなされる。
        Color color = f.palette.mixColor2;
        if(color != null)
        {
          int cx = (int)(x/f.canvas.affineScale +0.5);
          int cy = (int)(y/f.canvas.affineScale +0.5);
          changeColor(cx, cy, color.getRed(),
            color.getGreen(), color.getBlue());
        }
      }
      f.canvas.repaint();
    }

    //●線描画モードで、右ボタンがクリックされた場合の動作。
    //ベジェ曲線描画およびスプライン曲線描画の場合、右ボタンが使われる。

    if(senMouseMode == 22 && splineCnt > 2 && (eve.getButton() == MouseEvent.BUTTON3))
    { //●スプライン曲線の最終段階：曲線の終点をクリック
      x1 = (int)(x/f.canvas.affineScale +0.5); //端数四捨五入
      y1 = (int)(y/f.canvas.affineScale +0.5);
      f.canvas.currentPointX = x1;
      f.canvas.currentPointY = y1;
      String method =
        "DrawSplineEnd(" + x1 + "," + y1 + ");";
      f.cArea.append("\n" + method);
      f.cArea.append("\n//");
      clear();
      erase("DrawLine2");
    }

    if((senMouseModeFlag == true) && (tenMouseModeFlag == false) &&
      (eve.getButton() == MouseEvent.BUTTON3))
    {
         //●ベジェ曲線の第一段階：曲線の始点（何もしなくて良い）
         //　ベジェ曲線の始点は、左クリックである。
      if(senMouseMode == 14 && curveCnt == 1)
      {  //●ベジェ曲線の第二段階：曲線の第一制御点を右クリック。
        x3 = (int)(x/f.canvas.affineScale +0.5);
        y3 = (int)(y/f.canvas.affineScale +0.5);
        curveCnt++;
        f.canvas.currentPointX = x3;
        f.canvas.currentPointY = y3;
        commandX = "DrawShapeCurve(" + x3 + "," + y3 + ",";
        String method = "  DrawLine2(1," + x2 + "," + y2 + "," +
          x3 + "," + y3 + ");";
        f.cArea.append("\n" + method);
        x2 = x3; //次の線の始点を次の段階に伝える
        y2 = y3;
      }
      else if(senMouseMode == 14 && curveCnt == 2)
      {  //●ベジェ曲線の第三段階：曲線の第二制御点を右クリック。
        x3 = (int)(x/f.canvas.affineScale +0.5);
        y3 = (int)(y/f.canvas.affineScale +0.5);
        curveCnt++;
        f.canvas.currentPointX = x3;
        f.canvas.currentPointY = y3;
        commandX = commandX + x3 + "," + y3 + ",";
        String method = "  DrawLine2(2," + x2 + "," + y2 + "," +
          x3 + "," + y3 + ");";
        f.cArea.append("\n" + method);
        x2 = x3; //次の線の始点を次の段階に伝える
        y2 = y3;
      }
      else if(senMouseMode == 14 && curveCnt == 3)
      {  //●ベジェ曲線の第四段階：曲線の終点を右クリック。
        x3 = (int)(x/f.canvas.affineScale +0.5);
        y3 = (int)(y/f.canvas.affineScale +0.5);
        commandX =  commandX + x3 + "," + y3 + ");";
        f.cArea.append("\n" + commandX);
        f.canvas.currentPointX = x3;
        f.canvas.currentPointY = y3;
        String method = "  DrawLine2(3," + x2 + "," + y2 + "," +
          x3 + "," + y3 + ");";
        f.cArea.append("\n" + method);
        curveCnt = 1;
        x2 = x3; //次の線の始点を次の段階に伝える
        y2 = y3;
        commandX = "";
      }
      f.canvas.repaint();
    }

    //●パレットを使った点描画モードの場合
    if((tenMouseModeFlag == true) && (senMouseModeFlag == false) &&
      (eve.getButton() == MouseEvent.BUTTON1) &&
      (brushSize >= 0) )  //「巨、大、中、小」の場合
    {
      String methodP = "DrawCircle(2," +
        (int)(x/(f.canvas.affineScale*f.canvas.freeScale) +0.5) + "," +
        (int)(y/(f.canvas.affineScale*f.canvas.freeScale) +0.5) +
        "," + brushSize +
        "," + f.palette.mixColor2.getRed() +
        "," + f.palette.mixColor2.getGreen() +
        "," + f.palette.mixColor2.getBlue() + ");" ;
      f.cArea.append("\n" + methodP);
      f.canvas.repaint();
    }
  }
  //■座標位置変数の初期化
  void clear()
  {
    x1 = 0;
    y1 = 0;
    x2 = 0;
    y2 = 0;
    x3 = 0;
    y3 = 0;
    x4 = 0;
    y4 = 0;
    curveCnt = 1;
    splineCnt = 1;
    startFlag = true;
    horizontFlag = true;
    commandX = "";
    erase("DrawLine2");
  }

  //■直線の消去（または位置修正）
  void replace(boolean mode, int x1, int y1, int x2, int y2)
  {
    String commandZ = f.cArea.getText();
    String newCommand = "";
    StringTokenizer st = new StringTokenizer(commandZ,"\n");
    //この時のStringTokenizerは、空行を削除する副作用あり。
    String command1; //命令1件（引数含む）
    for(int i=0; st.hasMoreTokens(); i++)
    { //●命令文を上から順に、全文調べる
      command1 = st.nextToken().trim();
      if(!command1.startsWith("DrawLine("))
      { //●該当しない命令の場合
        newCommand += command1+"\n";
        continue;
      }
      else
      { //●該当する命令の場合
        StringTokenizer st2 = new StringTokenizer(command1,"(,)");
        st2.nextToken(); //●命令文における旧点位置の取得
        int ox1 = (int)Double.parseDouble((st2.nextToken().trim()));
        int oy1 = (int)Double.parseDouble((st2.nextToken().trim()));
        int ox2 = (int)Double.parseDouble((st2.nextToken().trim()));
        int oy2 = (int)Double.parseDouble((st2.nextToken().trim()));

        if( //●近傍点の判定（許容誤差は最小に）
          ((x1<=ox1+1) && (x1>=ox1-1) &&
          (y1<=oy1+1) && (y1>=oy1-1) &&
          (x2<=ox2+1) && (x2>=ox2-1) &&
          (y2<=oy2+1) && (y2>=oy2-1))
            ||
          ((x1<=ox2+1) && (x1>=ox2-1) &&
          (y1<=oy2+1) && (y1>=oy2-1) &&
          (x2<=ox1+1) && (x2>=ox1-1) &&
          (y2<=oy1+1) && (y2>=oy1-1)))
        {
          if(mode == true) //●修正モード
            newCommand += ("DrawLine(" + x1 + "," + y1 + "," +
              x2 + "," + y2 + ");\n");
          else  //消去モード
            newCommand += ("");
        }
        else
        { //●該当する直線でないのなら
          newCommand += command1+"\n";
        }
      }
    }
    f.cArea.setText(newCommand);
  }

  //■描画命令の座標点修正
  //  DrawLine(),DrawCurve(),
  //  DrawShapeStart(),DrawShapeCurve(),DrawShapeLine(),
  //  以上の始点、終点、中間点の座標ポイントを書き替える。
  //  DrawEllipse(),DrawCircle(),DrawRect(),WriteStringH() は、始点を書き替える。
  //  Stamp()は、始点を書き替える。StampMulti()は、書き替えない。
  //  縮小表示では、マウス操作の位置指定で極度の正確さが必要となる。
  //  そのため、等倍表示以上で、位置修正の操作を推奨する。
  void replacePoint(int x1, int y1, int x2, int y2)
    //x1,y1 は、クリックされた移動前の古い座標点。
    //x2,y2 は、クリックされた移動後の新しい座標点。
  {
    //最初のクリックで旧点を指定し、二回目で移動先の新点を指定。
    String commandZ = f.cArea.getText();
    String newCommand = "";
    StringTokenizer st = new StringTokenizer(commandZ,"\n");
    String command;
    int Q = 2; //●位置指定での許容誤差
    for(int i=0; st.hasMoreTokens(); i++)
    {
      command = st.nextToken().trim();
      if(command.startsWith("DrawLine("))
      { //●直線
        StringTokenizer st2 = new StringTokenizer(command,"(,)");
        st2.nextToken(); //●命令文における旧点位置の取得
        int ox1 = (int)Double.parseDouble((st2.nextToken().trim()));
        int oy1 = (int)Double.parseDouble((st2.nextToken().trim()));
        int ox2 = (int)Double.parseDouble((st2.nextToken().trim()));
        int oy2 = (int)Double.parseDouble((st2.nextToken().trim()));
        if((x1<=ox1+Q) && (x1>=ox1-Q) &&   //近傍点の判定
           (y1<=oy1+Q) && (y1>=oy1-Q))
        { //●始点と判定されたら修正実行
          newCommand += ("DrawLine(" +
            x2 + "," + y2 + "," +
            ox2 + "," + oy2 + ");\n");
        }
        else if((x1<=ox2+Q) && (x1>=ox2-Q) && //近傍点の判定
            (y1<=oy2+Q) && (y1>=oy2-Q))
        { //●終点と判定されたら修正実行
          newCommand += ("DrawLine(" +
            ox1 + "," + oy1 + "," +
            x2 + "," + y2 + ");\n");
        }
        else
        { //●該当点が見付からないなら
          newCommand += command+"\n";
        }
      }
      else if(command.startsWith("DrawSplineStart("))
      { //●スプライン曲線の始点
        StringTokenizer st2 = new StringTokenizer(command,"(,)");
        st2.nextToken(); //●命令文における旧点位置の取得
        int ox1 = (int)Double.parseDouble((st2.nextToken().trim()));
        int oy1 = (int)Double.parseDouble((st2.nextToken().trim()));
        if((x1<=ox1+Q) && (x1>=ox1-Q) &&   //近傍点の判定
           (y1<=oy1+Q) && (y1>=oy1-Q))
        { //●修正実行
          newCommand += ("DrawSplineStart(" +
            x2 + "," + y2 + ");\n");
        }
        else
        { //●該当点が見付からないなら
          newCommand += command+"\n";
        }
      }
      else if(command.startsWith("DrawSplineControl("))
      { //●スプライン曲線の制御点
        StringTokenizer st2 = new StringTokenizer(command,"(,)");
        st2.nextToken(); //●命令文における旧点位置の取得
        int ox1 = (int)Double.parseDouble((st2.nextToken().trim()));
        int oy1 = (int)Double.parseDouble((st2.nextToken().trim()));
        if((x1<=ox1+Q) && (x1>=ox1-Q) &&   //近傍点の判定
           (y1<=oy1+Q) && (y1>=oy1-Q))
        { //●修正実行
          newCommand += ("DrawSplineControl(" +
            x2 + "," + y2 + ");\n");
        }
        else
        { //●該当点が見付からないなら
          newCommand += command+"\n";
        }
      }
      else if(command.startsWith("DrawSplineEnd("))
      { //●スプライン曲線の終点
        StringTokenizer st2 = new StringTokenizer(command,"(,)");
        st2.nextToken(); //●命令文における旧点位置の取得
        int ox1 = (int)Double.parseDouble((st2.nextToken().trim()));
        int oy1 = (int)Double.parseDouble((st2.nextToken().trim()));
        if((x1<=ox1+Q) && (x1>=ox1-Q) &&   //近傍点の判定
           (y1<=oy1+Q) && (y1>=oy1-Q))
        { //●修正実行
          newCommand += ("DrawSplineEnd(" +
            x2 + "," + y2 + ");\n");
        }
        else
        { //●該当点が見付からないなら
          newCommand += command+"\n";
        }
      }
      else if(command.startsWith("DrawCurve("))
      { //●ベジェ曲線
        StringTokenizer st2 = new StringTokenizer(command,"(,)");
        st2.nextToken(); //●命令文における旧点位置の取得
        int ox1 = (int)Double.parseDouble((st2.nextToken().trim()));
        int oy1 = (int)Double.parseDouble((st2.nextToken().trim()));
        int ox2 = (int)Double.parseDouble((st2.nextToken().trim()));
        int oy2 = (int)Double.parseDouble((st2.nextToken().trim()));
        int ox3 = (int)Double.parseDouble((st2.nextToken().trim()));
        int oy3 = (int)Double.parseDouble((st2.nextToken().trim()));
        int ox4 = (int)Double.parseDouble((st2.nextToken().trim()));
        int oy4 = (int)Double.parseDouble((st2.nextToken().trim()));
        if((x1<=ox1+Q) && (x1>=ox1-Q) &&   //近傍点の判定
           (y1<=oy1+Q) && (y1>=oy1-Q))
        { //●始点と判定されたら修正実行
          newCommand += ("DrawCurve(" +
            x2 + "," + y2 + "," +
            ox2 + "," + oy2 + "," +
            ox3 + "," + oy3 + "," +
            ox4 + "," + oy4 + ");\n");
        }
        else if((x1<=ox2+Q) && (x1>=ox2-Q) &&   //近傍点の判定
            (y1<=oy2+Q) && (y1>=oy2-Q))
        { //●第一制御点と判定されたら修正実行
          newCommand += ("DrawCurve(" +
            ox1 + "," + oy1 + "," +
            x2 + "," + y2 + "," +
            ox3 + "," + oy3 + "," +
            ox4 + "," + oy4 + ");\n");
        }
        else if((x1<=ox3+Q) && (x1>=ox3-Q) && //近傍点の判定
            (y1<=oy3+Q) && (y1>=oy3-Q))
        { //●第二制御点と判定されたら修正実行
          newCommand += ("DrawCurve(" +
            ox1 + "," + oy1 + "," +
            ox2 + "," + oy2 + "," +
            x2 + "," + y2 + "," +
            ox4 + "," + oy4 + ");\n");
        }
        else if((x1<=ox4+Q) && (x1>=ox4-Q) && //近傍点の判定
            (y1<=oy4+Q) && (y1>=oy4-Q))
        { //●終点と判定されたら修正実行
          newCommand += ("DrawCurve(" +
            ox1 + "," + oy1 + "," +
            ox2 + "," + oy2 + "," +
            ox3 + "," + oy3 + "," +
            x2 + "," + y2 + ");\n");
        }
        else
        { //●該当点が見付からないなら
          newCommand += command+"\n";
        }
      }
      else if(command.startsWith("DrawShapeStart("))
      { //●自由図形の開始
        StringTokenizer st2 = new StringTokenizer(command,"(,)");
        st2.nextToken(); //●命令文における旧点位置の取得
        int m   = (int)Double.parseDouble((st2.nextToken().trim()));
        int ox1 = (int)Double.parseDouble((st2.nextToken().trim()));
        int oy1 = (int)Double.parseDouble((st2.nextToken().trim()));
        int r   = (int)Double.parseDouble((st2.nextToken().trim()));
        int g   = (int)Double.parseDouble((st2.nextToken().trim()));
        int b   = (int)Double.parseDouble((st2.nextToken().trim()));
        if((x1<=ox1+Q) && (x1>=ox1-Q) &&   //近傍点の判定
           (y1<=oy1+Q) && (y1>=oy1-Q))
        { //●該当点と判定されたら修正実行
          newCommand += ("DrawShapeStart(" +
            m + "," +
            x2 + "," + y2 + "," +
            r + "," +
            g + "," +
            b + ");\n");
        }
        else
        { //●該当点が見付からないなら
          newCommand += command+"\n";
        }
      }
      else if(command.startsWith("DrawShapeLine(") ||
        command.startsWith("DSL("))
      { //●自由図形での直線部分
        StringTokenizer st2 = new StringTokenizer(command,"(,)");
        st2.nextToken(); //●命令文における旧点位置の取得
        int ox1 = (int)Double.parseDouble((st2.nextToken().trim()));
        int oy1 = (int)Double.parseDouble((st2.nextToken().trim()));
        if((x1<=ox1+Q) && (x1>=ox1-Q) &&   //近傍点の判定
           (y1<=oy1+Q) && (y1>=oy1-Q))
        { //●該当点と判定されたら修正実行
          newCommand += ("DrawShapeLine(" +
            x2 + "," + y2 + ");\n");
        }
        else
        { //●該当点が見付からないなら
          newCommand += command+"\n";
        }
      }
      else if(command.startsWith("DrawShapeCurve(") ||
        command.startsWith("DSC("))
      { //●自由図形での曲線部分
        StringTokenizer st2 = new StringTokenizer(command,"(,)");
        st2.nextToken(); //●命令文における旧点位置の取得
        int ox1 = (int)Double.parseDouble((st2.nextToken().trim()));
        int oy1 = (int)Double.parseDouble((st2.nextToken().trim()));
        int ox2 = (int)Double.parseDouble((st2.nextToken().trim()));
        int oy2 = (int)Double.parseDouble((st2.nextToken().trim()));
        int ox3 = (int)Double.parseDouble((st2.nextToken().trim()));
        int oy3 = (int)Double.parseDouble((st2.nextToken().trim()));
        if((x1<=ox1+Q) && (x1>=ox1-Q) &&   //近傍点の判定
           (y1<=oy1+Q) && (y1>=oy1-Q))
        { //●第一制御点と判定されたら修正実行
          newCommand += ("DrawShapeCurve(" +
            x2 + "," + y2 + "," +
            ox2 + "," + oy2 + "," +
            ox3 + "," + oy3 + ");\n");
        }
        else if((x1<=ox2+Q) && (x1>=ox2-Q) && //近傍点の判定
            (y1<=oy2+Q) && (y1>=oy2-Q))
        { //●第二制御点と判定されたら修正実行
          newCommand += ("DrawShapeCurve(" +
            ox1 + "," + oy1 + "," +
            x2 + "," + y2 + "," +
            ox3 + "," + oy3 + ");\n");
        }
        else if((x1<=ox3+Q) && (x1>=ox3-Q) && //近傍点の判定
            (y1<=oy3+Q) && (y1>=oy3-Q))
        { //●終点と判定されたら修正実行
          newCommand += ("DrawShapeCurve(" +
            ox1 + "," + oy1 + "," +
            ox2 + "," + oy2 + "," +
            x2 + "," + y2 + ");\n");
        }
        else
        { //●該当点が見付からないなら
          newCommand += command+"\n";
        }
      }
      else if(command.startsWith("DrawCircle("))
      { //●真円
        StringTokenizer st2 = new StringTokenizer(command,"(,)");
        st2.nextToken(); //●命令文における旧点位置の取得
        String em = st2.nextToken().trim(); //
        int ex = (int)Double.parseDouble((st2.nextToken().trim())); //
        int ey = (int)Double.parseDouble((st2.nextToken().trim())); //
        String str1 = st2.nextToken().trim(); //半径
        String str2 = st2.nextToken().trim(); //赤色
        String str3 = st2.nextToken().trim(); //緑色
        String str4 = st2.nextToken().trim(); //青色
        if((x1<=ex+Q) && (x1>=ex-Q) &&   //近傍点の判定
           (y1<=ey+Q) && (y1>=ey-Q))
        { //●該当点と判定されたら修正実行
          newCommand += ("DrawCircle(" + em +"," +
            x2 + "," + y2 + "," +
            str1 +"," + str2 +"," + str3 +"," + str4  +");\n" );
        }
        else
        { //●該当点が見付からないなら
          newCommand += command+"\n";
        }
      }
      else if(command.startsWith("DrawEllipse("))
      { //●楕円
        StringTokenizer st2 = new StringTokenizer(command,"(,)");
        st2.nextToken(); //●命令文における旧点位置の取得
        String em = st2.nextToken().trim(); //
        int ex = (int)Double.parseDouble((st2.nextToken().trim())); //
        int ey = (int)Double.parseDouble((st2.nextToken().trim())); //
        String str1 = st2.nextToken().trim(); //横半径
        String str2 = st2.nextToken().trim(); //縦半径
        String str3 = st2.nextToken().trim(); //赤色
        String str4 = st2.nextToken().trim(); //緑色
        String str5 = st2.nextToken().trim(); //青色
        if((x1<=ex+Q) && (x1>=ex-Q) &&   //近傍点の判定
           (y1<=ey+Q) && (y1>=ey-Q))
        { //●該当点と判定されたら修正実行
          newCommand += ("DrawEllipse(" + em +"," +
            x2 + "," + y2 + "," +
            str1 +"," + str2 +"," + str3 +"," + str4 +"," + str5 +");\n" );
        }
        else
        { //●該当点が見付からないなら
          newCommand += command+"\n";
        }
      }
      else if(command.startsWith("DrawRect("))
      { //●四角形
        StringTokenizer st2 = new StringTokenizer(command,"(,)");
        st2.nextToken(); //●命令文における旧点位置の取得
        String rm = st2.nextToken().trim(); //モード
        int rx = (int)Double.parseDouble((st2.nextToken().trim())); //x
        int ry = (int)Double.parseDouble((st2.nextToken().trim())); //y
        String str1 = st2.nextToken().trim(); //幅
        String str2 = st2.nextToken().trim(); //丈
        String str3 = st2.nextToken().trim(); //赤色
        String str4 = st2.nextToken().trim(); //緑色
        String str5 = st2.nextToken().trim(); //青色
        if((x1<=rx+Q) && (x1>=rx-Q) &&   //近傍点の判定
           (y1<=ry+Q) && (y1>=ry-Q))
        { //●該当点と判定されたら修正実行
          newCommand += ("DrawRect(" + rm +"," +
            x2 + "," + y2 + "," +
            str1 +"," + str2 +"," + str3 +"," + str4 +"," +str5 +");\n" );
        }
        else
        { //●該当点が見付からないなら
          newCommand += command+"\n";
        }
      }
      else if(command.startsWith("Stamp("))
      { //●前景画像なら
        StringTokenizer st2 = new StringTokenizer(command,"(,)");
        st2.nextToken(); //●命令文における旧点位置の取得
        int rx = Integer.parseInt((st2.nextToken().trim())); //x
        int ry = Integer.parseInt((st2.nextToken().trim())); //y
        String str1 = st2.nextToken().trim(); //幅
        String str2 = st2.nextToken().trim(); //丈
        String str3 = Util.trimAffix(st2.nextToken(),'\"','\"'); //ファイル名
        if((x1<=rx+Q) && (x1>=rx-Q) &&   //近傍点の判定
           (y1<=ry+Q) && (y1>=ry-Q))
        { //●該当点と判定されたら修正実行
          newCommand += ("Stamp(" +  x2 + "," + y2 + "," +
            str1 +"," + str2 +"," + str3+ ");\n" );
        }
        else
        { //●該当点が見付からないなら
          newCommand += command+"\n";
        }
      }
      else if(command.startsWith("WriteStringH(") ||
        command.startsWith("WriteString(") ||
        command.startsWith("WriteStringB(") ||
        command.startsWith("WriteStringV("))
      { //●文字列（並字、極太字、縦書き）
        StringTokenizer st2 = new StringTokenizer(command,"(,)");
        st2.nextToken(); //●命令文における旧点位置の取得
        int ox1 = (int)Double.parseDouble((st2.nextToken().trim()));
        int oy1 = (int)Double.parseDouble((st2.nextToken().trim()));
        String str1 = st2.nextToken().trim();
        String str2 = st2.nextToken().trim();
        String str3 = st2.nextToken().trim();
        if((x1<=ox1+Q) && (x1>=ox1-Q) &&   //近傍点の判定
           (y1<=oy1+Q) && (y1>=oy1-Q))
        { //●該当点と判定されたら修正実行
          if(command.startsWith("WriteStringH("))
            newCommand += ("WriteStringH(" +
            x2 + "," + y2 + "," +
            str1 + "," + str2 + "," + str3 + ");\n" );
          else if(command.startsWith("WriteString("))
            newCommand += ("WriteString(" +
            x2 + "," + y2 + "," +
            str1 + "," + str2 + "," + str3 + ");\n" );
          else if(command.startsWith("WriteStringB("))
            newCommand += ("WriteStringB(" +
            x2 + "," + y2 + "," +
            str1 + "," + str2 + "," + str3 + ");\n" );
          else if(command.startsWith("WriteStringV("))
            newCommand += ("WriteStringV(" +
            x2 + "," + y2 + "," +
            str1 + "," + str2 + "," + str3 + ");\n" );
        }
        else
        { //●該当点が見付からないなら
          newCommand += command+"\n";
        }
      }
      else
      { //●いずれにも該当しない命令の場合
        newCommand += command+"\n";
        continue;
      }
    }
    f.cArea.setText(newCommand);
  }

  //■指定のコマンドを全部消去する。
  void erase(String commandE)
  {  //一時使用するだけの「DrawLine2」コマンドにのみ利用
    String commandZ = f.cArea.getText(); //コマンド全文取得
    String newCommandZ = ""; //新しいコマンド全文
    StringTokenizer st = new StringTokenizer(commandZ,"\n");
    String command1;  //検査対象の描画コマンド1件
    for(int i=0; st.hasMoreTokens(); i++)
    {
      command1 = st.nextToken().trim();
      if(!(command1.startsWith(commandE)) )
      {  //不一致
        newCommandZ += command1+"\n";
        continue;
      }
      else
      {  //一致
        ; //拾わずに捨てる（消去）
      }
    }
    f.cArea.setText(newCommandZ);  //編集済みコマンド全文の格納
    f.canvas.repaint();
  }

  //■線描画命令文検索
  //  クリックされた位置を始点とする線描画命令を探し出し、
  //  命令文の末尾に、コメント（//★★★）を付けて、表示する。
  void refer(int x, int y)
  {
    String commandZ = f.cArea.getText();
    String newCommand = "";
    StringTokenizer st = new StringTokenizer(commandZ,"\n"); //行毎に分解
    String command;
    for(int i=0; st.hasMoreTokens(); i++)
    {
      command = st.nextToken().trim(); //命令１行を取得
      StringTokenizer st2 = new StringTokenizer(command,"(),;"); //命令１行を分解
      st2.nextToken().trim(); //コマンド名の部分を捨てる
      if(command.endsWith("//★★★"))
      { //●命令文の末尾に、既に「//★★★」があれば、削除する
        command = command.substring(0,command.length()-5);
      }
      if(command.startsWith("DrawLine"))
      { //●直線の始点
        if(nearEquals(x, st2.nextToken().trim()) &&
        nearEquals(y, st2.nextToken().trim()) )
          newCommand += command+"//★★★\n";
        else
          newCommand += command+"\n";
      }
      else if(command.startsWith("DrawCurve"))
      { //●ベジェ曲線の始点
        if(nearEquals(x, st2.nextToken().trim()) &&
        nearEquals(y, st2.nextToken().trim()) )
          newCommand += command+"//★★★\n";
        else
          newCommand += command+"\n";
      }
      else if(command.startsWith("DrawSplineStart"))
      { //●スプライン曲線の始点
        if(nearEquals(x, st2.nextToken().trim()) &&
        nearEquals(y, st2.nextToken().trim()) )
          newCommand += command+"//★★★\n";
        else
          newCommand += command+"\n";
      }
      else if(command.startsWith("DrawSplineControl"))
      { //●スプライン曲線の制御点
        if(nearEquals(x, st2.nextToken().trim()) &&
        nearEquals(y, st2.nextToken().trim()) )
          newCommand += command+"//★★★\n";
        else
          newCommand += command+"\n";
      }
      else if(command.startsWith("DrawSplineEnd"))
      { //●スプライン曲線の終点
        if(nearEquals(x, st2.nextToken().trim()) &&
        nearEquals(y, st2.nextToken().trim()) )
          newCommand += command+"//★★★\n";
        else
          newCommand += command+"\n";
      }
      else if(command.startsWith("DrawShapeStart"))
      { //●自由図形の始点
        st2.nextToken().trim(); //描画モードは不用
        if(nearEquals(x, st2.nextToken().trim()) &&
        nearEquals(y, st2.nextToken().trim()) )
          newCommand += command+"//★★★\n";
        else
          newCommand += command+"\n";
      }
      else if(command.startsWith("DrawEllipse"))
      { //●楕円の始点（中心点）
        st2.nextToken().trim(); //描画モードは不用
        if(nearEquals(x, st2.nextToken().trim()) &&
        nearEquals(y, st2.nextToken().trim()) )
          newCommand += command+"//★★★\n";
        else
          newCommand += command+"\n";
      }
      else if(command.startsWith("DrawCircle"))
      { //●真円の始点（中心点）
        st2.nextToken().trim(); //描画モードは不用
        if(nearEquals(x, st2.nextToken().trim()) &&
        nearEquals(y, st2.nextToken().trim()) )
          newCommand += command+"//★★★\n";
        else
          newCommand += command+"\n";
      }
      else if(command.startsWith("DrawRect"))
      { //●四角形の始点（左上点）
        st2.nextToken().trim(); //描画モードは不用
        if(nearEquals(x, st2.nextToken().trim()) &&
        nearEquals(y, st2.nextToken().trim()) )
          newCommand += command+"//★★★\n";
        else
          newCommand += command+"\n";
      }
      else
      {
        newCommand += command+"\n";
      }
    }
    f.cArea.setText(newCommand);
    f.canvas.repaint();
  }

  int colorRanNum()
  { //●ランダムなRGBのどれか一つを作る
    Random ran = new Random();
    return (10 + ran.nextInt(240));
  }

  boolean nearEquals(int a, String s)
  { //●近似値判定、（sは整数または実数で数値表現された文字列）
    double d = Double.parseDouble(s);
    if((a+2 >= d) && (a-2 <= d))
      return true;
    else
      return false;
  }

  boolean nearEquals(double a, double b)
  { //●近似値判定
    if((a+2 >= b) && (a-2 <= b))
      return true;
    else
      return false;
  }

  //■図形彩色変更
  //  クリックされた位置を始点とする図形描画命令を探し出し、
  //  パレットで混色されている色を使って、
  //  命令の彩色指定部分を書き変える。
  void changeColor(int x, int y, int r, int g, int b)
  {
    String commandZ = f.cArea.getText();
    String newCommand = "";
    StringTokenizer st = new StringTokenizer(commandZ,"\n");
    String command = "";
    for(int i=0; st.hasMoreTokens(); i++)
    {
      command = st.nextToken().trim();
      String[] strArray = Util.csv2Array(command,0);

      if( //●自由図形の彩色変更
        (strArray[0].startsWith("DrawShapeStart")))
      {
        int x0 = (int)Double.parseDouble(strArray[1]);
        int y0 = (int)Double.parseDouble(strArray[2]);
        if(nearEquals(x0,x) && nearEquals(y0,y))
        {
          newCommand += strArray[0] + "," +
            strArray[1] + "," + strArray[2] + "," +
            r  + "," + g  + "," + b  + ");\n" ;
        }
        else
        {
          newCommand += command+"\n" ;
        }
      }
      else if( //●真円の彩色変更
        (strArray[0].startsWith("DrawCircle")))
      {
        int x0 = (int)Double.parseDouble(strArray[1]);
        int y0 = (int)Double.parseDouble(strArray[2]);
        if(nearEquals(x0,x) && nearEquals(y0,y))
        {
          newCommand += strArray[0] + "," +
            strArray[1] + "," + strArray[2] + "," +
            strArray[3] +  "," +
            r  + "," + g  + "," + b  + ");\n" ;
        }
        else
        {
          newCommand += command+"\n" ;
        }
      }
      else if( //●楕円の彩色変更
        (strArray[0].startsWith("DrawEllipse")))
      {
        int x0 = (int)Double.parseDouble(strArray[1]);
        int y0 = (int)Double.parseDouble(strArray[2]);
        if(nearEquals(x0,x) && nearEquals(y0,y))
        {
          newCommand += strArray[0] + "," +
            strArray[1] + "," + strArray[2] + "," +
            strArray[3] + "," + strArray[4] + "," +
            r  + "," + g  + "," + b  + ");\n" ;
        }
        else
        {
          newCommand += command+"\n" ;
        }
      }
      else if( //●四角形の彩色変更
        (strArray[0].startsWith("DrawRect")))
      {
        int x0 = (int)Double.parseDouble(strArray[1]);
        int y0 = (int)Double.parseDouble(strArray[2]);
        if(nearEquals(x0,x) && nearEquals(y0,y))
        {
          newCommand += strArray[0] + "," +
            strArray[1] + "," + strArray[2] + "," +
            strArray[3] + "," + strArray[4] + "," +
            r  + "," + g  + "," + b  + ");\n" ;
        }
        else
        {
          newCommand += command+"\n" ;
        }
      }
      else
      {
        newCommand += command+"\n" ;
      }
    }
    f.cArea.setText(newCommand);
    f.canvas.repaint();
  }

  //以下は、MouseListenerの実装で、無反応にする部分

  public void mouseEntered(MouseEvent e)
  {}
  public void mouseExited(MouseEvent e)
  {}
  public void mouseClicked(MouseEvent e)
  {}
  public void mouseReleased(MouseEvent e)
  {}
} //EOF (GCreatorCanMouseLis.java)

◆GCreatorPalMouseLis.java

//■■GCreatorPalMouseLis.java
//Ver.3.3

//■■インポート
import java.awt.*;  //必須
import java.awt.event.*;  //必須

//■■マウスのクリックで呼び出されるリスナー（パレット用）
class GCreatorPalMouseLis implements MouseListener
{
  //■メンバー変数
  GCreator f;
  int colorNum = 0;     //基準色１６色の順序番号
  int selectColor = 0;  //１番目から三番目の色選択順

  //パレットの配置状況
  final int x = 5;  //left margin
  final int y = 5;  //top margin
  final int w =50;  //box width
  final int h =50;  //box height

  //パレット上の絵の具位置
  final int colorP[][] = {
  {x+  0,y+  0},  //red
  {x+ 50,y+  0},  //maroon
  {x+100,y+  0},  //magenta
  {x+150,y+  0},  //purple
  {x+  0,y+100},  //green
  {x+ 50,y+100},  //d.green
  {x+100,y+100},  //yellow
  {x+150,y+100},  //olive
  {x+  0,y+200},  //blue
  {x+ 50,y+200},  //navy
  {x+100,y+200},  //cyan
  {x+150,y+200},  //teal
  {x+  0,y+300},  //white
  {x+ 50,y+300},  //silver
  {x+100,y+300},  //gray
  {x+150,y+300}}; //black

  //基準色の色価
  final int colorV[][] = {
  {0xff, 0x00, 0x00},  //red
  {0x80, 0x00, 0x00},  //maroon
  {0xff, 0x00, 0xff},  //magenta
  {0x80, 0x00, 0x80},  //purple
  {0x00, 0xff, 0x00},  //green
  {0x00, 0x80, 0x00},  //d.green
  {0xff, 0xff, 0x00},  //yellow
  {0x80, 0x80, 0x00},  //olive
  {0x00, 0x00, 0xff},  //blue
  {0x00, 0x00, 0x80},  //navy
  {0x00, 0xff, 0xff},  //cyan
  {0x00, 0x80, 0x80},  //teal
  {0xff, 0xff, 0xff},  //white
  {0xc0, 0xc0, 0xc0},  //silver
  {0x80, 0x80, 0x80},  //gray
  {0x00, 0x00, 0x00}}; //black

  //■コンストラクタ
  GCreatorPalMouseLis(GCreator flame)
  {
    f = flame;
  }

  //■イベントハンドラ
  public void mousePressed(MouseEvent eve)
  {
    //●点描マウス入力モードが解除状態または左クリックでない場合
    if(eve.getButton() != MouseEvent.BUTTON1)
    {
      return;
    }
    int x = eve.getX(); //マウスのクリック位置を取得
    int y = eve.getY();
    //●1回目の色選択
    if(selectColor == 0)
    { //●座標位置から指定されたパレット色（未混色）を割り出す。
      for(colorNum=0; colorNum<16; colorNum++)
      {
        if((x > colorP[colorNum][0]) && (x < colorP[colorNum][0]+w) &&
          (y > colorP[colorNum][1]) && (y < colorP[colorNum][1]+h))
        {
          f.palette.choiceN = 1;
          f.palette.choiceC1 = new Color(
            colorV[colorNum][0], colorV[colorNum][1],
            colorV[colorNum][2]);
          selectColor =1;
          f.sldR.setValue(0);
          f.sldG.setValue(0);
          f.sldB.setValue(0);
          break;
        }
      }
    }
    //●2回目の色選択
    else if(selectColor == 1)
    { //●座標位置から指定されたパレット色（未混色）を割り出す。
      for(colorNum=0; colorNum<16; colorNum++)
      {
        if((x > colorP[colorNum][0]) && (x < colorP[colorNum][0]+w) &&
          (y > colorP[colorNum][1]) && (y < colorP[colorNum][1]+h))
        {
          f.palette.choiceN = 2;
          f.palette.choiceC2 = new Color(
            colorV[colorNum][0], colorV[colorNum][1],
            colorV[colorNum][2]);
          selectColor = 2;
          break;
        }
      }
    }
    //●3回目の色選択
    else if(selectColor == 2)
    { //●座標位置から指定されたパレット色（未混色）を割り出す。
      for(colorNum=0; colorNum<16; colorNum++)
      {
        if((x > colorP[colorNum][0]) && (x < colorP[colorNum][0]+w) &&
          (y > colorP[colorNum][1]) && (y < colorP[colorNum][1]+h))
        {
          f.palette.choiceN = 3;
          f.palette.choiceC3 = new Color(
            colorV[colorNum][0], colorV[colorNum][1],
            colorV[colorNum][2]);
          selectColor = 3;
          break;
        }
      }
    }
    //●4回目の色選択
    else if(selectColor == 3)
    { //●座標位置から指定されたパレット色（未混色）を割り出す。
      for(colorNum=0; colorNum<16; colorNum++)
      {
        if((x > colorP[colorNum][0]) && (x < colorP[colorNum][0]+w) &&
          (y > colorP[colorNum][1]) && (y < colorP[colorNum][1]+h))
        {
          f.palette.choiceN = 4;
          f.palette.choiceC4 = new Color(
            colorV[colorNum][0], colorV[colorNum][1],
            colorV[colorNum][2]);
          selectColor = 0;
          break;
        }
      }
    }
  }

  //■座標位置変数の初期化
  void clear()
  {
    selectColor = 0;
    f.palette.choiceN = 0;
  }

  public void mouseEntered(MouseEvent e)
  {}
  public void mouseExited(MouseEvent e)
  {}
  public void mouseClicked(MouseEvent e)
  {}
  public void mouseReleased(MouseEvent e)
  {}
} //EOF (GCreatorPalMouseLis.java)

◆GCreatorSliderLis.java

//■■GCreatorSliderLis.java
//Ver.3.3

//■■インポート
import javax.swing.*;  //必須
import javax.swing.event.*;  //必須

//■■JSliderのイベントリスナー
class GCreatorSliderLis implements ChangeListener
{
  GCreator f;
  int adjustR;
  int adjustG;
  int adjustB;

  //■コンストラクタ
  GCreatorSliderLis(GCreator flame)
  {
    f = flame;
  }

  //■JSliderのイベントハンドラ
  public void stateChanged(ChangeEvent e)
  {
    JSlider sld = (JSlider)e.getSource();
    if(sld == f.sldR)
    {
      if(!sld.getValueIsAdjusting()) //スライダー・ノブで数値が決定した
      {
        adjustR = sld.getValue();
      }
    }
    else if(sld == f.sldG)
    {
      if(!sld.getValueIsAdjusting()) //スライダー・ノブで数値が決定した
      {
        adjustG = sld.getValue();
      }
    }
    else if(sld == f.sldB)
    {
      if(!sld.getValueIsAdjusting()) //スライダー・ノブで数値が決定した
      {
        adjustB = sld.getValue();
      }
    }
  }
} //EOF (GCreatorSliderLis.java)

◆StackTraceMonitor.java

//■■StackTraceMonitor.java

import java.awt.*;
import javax.swing.*;
import java.io.*;

//■■キャッチできない例外によるスタックトレース出力監視と出力先切替スレッド
public class StackTraceMonitor extends Thread
{
    //■メンバー変数
    //smの実質は、JFrameとSystemMessageの合流
    private SystemMessage sm;
    //■コンストラクタ
    public StackTraceMonitor(SystemMessage sm)
    {
        this.sm = sm;
    }

    //■標準エラー出力を横取りして、フレーム内の所定場所に表示
    public void run()
    {
        ByteArrayOutputStream baos = new ByteArrayOutputStream(); //バッファ
        try
        { //エラー出力先をバッファに切替え
            System.setErr(new PrintStream(baos));
        }
        catch(Exception e)
        {
            sm.message(e.toString());
            return;
        }
        for(;;) //プログラム終了まで監視を続ける
        {
            try
            {
                sleep(500); //実行時間独占防止の休眠時間
            }
            catch(Exception e)
            {
                sm.message(e.toString());
            }
            if(baos.size() > 0) //エラー出力の蓄積があれば
            {
                synchronized(baos)
                { //baosをロックし、下の文を排他的に実行
                        sm.message(baos.toString()); //エラー表示
                        baos.reset(); //バッファを空にし、次に備える
                }
            }
        }
    }
    //■SystemMessage の切り替え
    public void setFrame(SystemMessage sm)
    {
        this.sm = sm;
    }
} //EOF (StackTraceMonitor.java)

◆SystemMessage.java

//■■SystemMessage.java

public interface SystemMessage
{
    public void message(String s);
} //EOF (SystemMessage.java)

◆Util.java

//■■Util.java

import java.awt.*;
import java.awt.event.*;
import java.awt.im.InputSubset;
import javax.swing.*;
import javax.swing.border.*;
import java.io.*;
import java.util.*;
import java.text.*;

public class Util
{
    static final Font fontM = new Font("MonoSpaced",Font.PLAIN,13);

    //■テキストファイル閲覧サブウィンドウ
    public static void textBrowse(SystemMessage sm, File file)
    {
        String line = null;
        JDialog subWindow = null;
        try
        {
            BufferedReader reader = new BufferedReader(
                new FileReader(file)); //エラーになればsubWindowは生成しない

            subWindow = new JDialog((Frame)sm, file.getName(), true);
            Container pane = subWindow.getContentPane();
            //クローズボタンでサブウィンドウを破棄し、プロセスは継続させる
            //subWindow.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
            JTextArea tArea = new JTextArea(25,80); //行数と１行の文字数
            pane.add(
                new JScrollPane(
                    tArea,
                    JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
                    JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS));
            tArea.setFont(fontM);
            tArea.setBorder(new EmptyBorder(20,20,20,20));
            try
            {
                for (;;)
                {
                    line = reader.readLine();
                    if(line == null)
                        break;
                    tArea.append(line + "\n");
                }
                tArea.select(0, 0); //先頭位置を表示
                tArea.setEditable(false); //編集禁止
            }
            catch(IOException e)
            {
                sm.message("読取エラー>>\n"+e);
            }
            finally
            {
                reader.close();
                subWindow.pack();
                subWindow.setVisible(true);
            }
        }
        catch(FileNotFoundException e)
        {
            sm.message("オープンエラー>>\n"+e);
        }
        catch(IOException e)
        {
            sm.message("クローズエラー>>\n"+e);
        }
    }
    //■テキストファイル閲覧サブウィンドウ（クリップ・ボード機能付き）
    public static void textBrowseCCP(SystemMessage sm, File file)
    {
        String line = null;
        JDialog subWindow = null;
        try
        {
            BufferedReader reader = new BufferedReader(
                new FileReader(file)); //エラーになればsubWindowは生成しない

            subWindow = new JDialog((Frame)sm, file.getName(), true);
            Container pane = subWindow.getContentPane();
            JPanel panel = new JPanel();
            panel.setLayout(new FlowLayout(FlowLayout.LEFT));

            Box vBox = Box.createVerticalBox();
            pane.add(vBox);
            JTextArea tArea = new JTextArea(25,80); //行数と１行の文字数
            tArea.setFont(fontM);
            tArea.setBorder(new EmptyBorder(20,20,20,20));

            JButton cutButton = new JButton("削除");
            cutButton.addActionListener(
            	new ActionListener()
            	{ public void actionPerformed(ActionEvent event)
              	{ tArea.cut(); } }
            );
            JButton copyButton = new JButton("複写");
            copyButton.addActionListener(
            	new ActionListener()
            	{ public void actionPerformed(ActionEvent event)
              	{ tArea.copy(); } }
            );
            JButton pasteButton = new JButton("挿入");
            pasteButton.addActionListener(
            	new ActionListener()
            	{ public void actionPerformed(ActionEvent event)
              	{ tArea.paste(); } }
            );
            panel.add(cutButton);
            panel.add(copyButton);
            panel.add(pasteButton);
            vBox.add(panel);
            vBox.add(
                new JScrollPane(
                    tArea,
                    JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
                    JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS));

            try
            {
                for (;;)
                {
                    line = reader.readLine();
                    if(line == null)
                        break;
                    tArea.append(line + "\n");
                }
                tArea.select(0, 0); //先頭位置を表示
                tArea.setEditable(true); //編集可
            }
            catch(IOException e)
            {
                sm.message("読取エラー>>\n"+e);
            }
            finally
            {
                reader.close();
                subWindow.pack();
                subWindow.setVisible(true);
            }
        }
        catch(FileNotFoundException e)
        {
            sm.message("オープンエラー>>\n"+e);
        }
        catch(IOException e)
        {
            sm.message("クローズエラー>>\n"+e);
        }
    }

    //■改行コードを含む文字列を改行位置で分解し、Stringの配列に変換して返却
    public static String[] splitReturn(String str)
    {
        if(str.charAt(str.length()-1)!='\n')
            str = str + "\n";
        int lines=0;
        for(int i=0; i<str.length(); i++)
        {
            if(str.charAt(i)=='\n')
                lines++;
        }
        String [] stringArray = new String[lines];
        int c1=0;
        int c2=0;
        int lineNum=0;
        int i=0;
        for(; i<str.length(); i++)
        {
            if(str.charAt(i)=='\n')
            {
                c2=i;
                stringArray[lineNum] = str.substring(c1,c2);
                lineNum++;

                c1=c2+1;
            }
        }
        return stringArray;
    }

    //■CSV形式の文字列を想定し、区切り文字（デリミタ）の数を数えて、その数を返却
    public static int countDelimiter(String str, char ch)
    {
      int cnt=0;
      for(int i=0; i<str.length(); i++)
      {
        if(str.charAt(i)==ch)
          cnt++;
      }
      return cnt;
    }

    //■CSV形式の文字列を区切り文字の位置で分解し、Stringの配列に変換して返却
    public static String[] csv2Array(String csv, int cols)
    {
        return csv2Array(csv, cols, ',');
    }
    public static String[] csv2Array(String csv, int cols, char delimiter)
    {
        char [] cArr = {delimiter};
        String delimiterStr = new String(cArr);
        StringTokenizer st = new StringTokenizer(csv, delimiterStr, true);
        int cols2 = 0;
        for(int i=0; i<csv.length(); i++)
        {
            if(csv.charAt(i) == delimiter)
                cols2++;
        }
        cols2++; //カラム数
        if(cols > 0) //カラム数チェック必要
        {
            if(cols != cols2) //カラム数異常
                return null;
        }
        else if(cols == 0) //カラム数チェック不用
            cols = cols2;
        else if(cols < 0) //program error
            ; //次の文で例外発生
        String [] stringArray = new String[cols];
        for(int colCount=0; colCount<cols; colCount++)
        {
            String str;
            if(st.hasMoreTokens()) //トークンがあれば
                str = (st.nextToken()).trim();//区切り文字かデータが得られ
            else                   //トークンがなければ
                str = "";          //最終カラムで、空のカラム

            if(str.equals(delimiterStr))    //トークンが区切り文字か
                str = "";          //最終カラム以外で、空のカラム
            else                   //トークンがデータなら
            {
                if(st.hasMoreTokens()) //最終カラムでないことを確認し
                    st.nextToken();    //次のコンマ除去
            }
            stringArray[colCount] = str; //データか空文字列を格納
        }
        return stringArray;
    }

    //■文字列の先頭と末尾を囲む特定文字を除去。
    //主に引用符や括弧で囲まれた文字列に適用。
    //前後を除去文字に囲まれていなければ、そのまま返却。
    public static String trimAffix(String str, char prefix, char suffix)
    {
        if(str.length()>=2 && str.charAt(0)==prefix && str.charAt(str.length()-1)==suffix)
            return str.substring(1, str.length()-1);
        else
            return str;
    }

    //■JTextField の日本語ＩＭモード切替
    public static void kanjiIn(final JTextField tf, boolean b)
    {
        if(b)
        {
            tf.addFocusListener(new FocusAdapter()
            {
                public void focusGained(FocusEvent event)
                {
                    tf.getInputContext().setCharacterSubsets(
                        new Character.Subset[] {InputSubset.KANJI});
                }
            });
        }
        else
        {
            tf.addFocusListener(new FocusAdapter()
            {
                public void focusGained(FocusEvent event)
                {
                    tf.getInputContext().setCharacterSubsets(null);
                }
            });
        }
    }

    //■数値文字列の整形
    //返却値 String : 整形後の文字列
    //引数 String decimal : 十進実数文字列
    //引数 int fractionDigit : 整形後の小数点桁数
    //引数 boolean comma ：コンマが必要か
    //機能 : 指定の小数点桁数で揃え、必要ならコンマを付加
    public static String decimalStringFormat(String decimal, int fractionDigit, boolean comma)
        throws NumberFormatException
    {
        String s0 = "";
        String s1 = "";
        NumberFormat nf = NumberFormat.getInstance(Locale.JAPANESE);

        if(decimal==null)                  //nullなら
            throw new NumberFormatException("文字列がnull");
        else if(decimal.trim().equals("")) //空文字列なら
            return "";
        else                               //有効文字列なら
        {
            if(decimal.indexOf(".")==-1) //整数表記されていたらコンマ要求とみなし
            {
                s0 = nf.format(Long.parseLong(decimal)); //整数にコンマ付加
                s1 = "";
            }
            else if(comma==true) //実数表記でコンマ要求されていたら
            {
                s0 = decimal.substring(0,decimal.indexOf(".")); //整数部
                if(!s0.equals("-0")) //実数が１未満の場合には符号温存
                    s0 = nf.format(Long.parseLong(s0));   //整数部コンマ付加
                s1 = decimal.substring(decimal.indexOf(".")+1); //小数部
            }
            else //実数表記でコンマ要求なし
            {
                s0 = decimal.substring(0,decimal.indexOf(".")); //整数部
                s1 = decimal.substring(decimal.indexOf(".")+1); //小数部
            }
            if(fractionDigit == 0)     //整数要求
                return s0;
            else if(fractionDigit > 0) //実数要求
            {
                for(int i=0; s1.length()>i; i++)                //小数部チェック
                    if(!Character.isDigit(s1.charAt(i)))
                        throw new NumberFormatException();
                if(fractionDigit < s1.length())
                    s1 = s1.substring(0,fractionDigit);         //末尾切捨
                else if(fractionDigit > s1.length())
                    while(fractionDigit>s1.length())
                        s1 += "0";                              //不足の0を付加
                return (s0 + "." + s1);
            }
            else //小数のマイナス桁は認めない
                throw new NumberFormatException("小数桁がマイナス値");
        }
    }
    public static String decimalStringFormat(String decimal, int fractionDigit)
        throws NumberFormatException
    {
        return decimalStringFormat(decimal, fractionDigit, true);
    }

    //■数値データの変換と照合
    public static int checkInt(String str, int min, int max) throws Exception
    {
        try
        {
            int value = Integer.parseInt(str);
            if(value<min || value>max)
                throw new Exception("数値異常");
            return value;
        }
        catch(NumberFormatException e)
        {
            throw new Exception("数値表記間違");
        }
    }
    public static long checkLong(String str, long min, long max) throws Exception
    {
        try
        {
            long value = Long.parseLong(str);
            if(value<min || value>max)
                throw new Exception("数値異常");
            return value;
        }
        catch(NumberFormatException e)
        {
            throw new Exception("数値表記間違");
        }
    }
    public static double checkDouble(String str, double min, double max) throws Exception
    {
        try
        {
            double value = Double.parseDouble(str);
            if(value<min || value>max)
                throw new Exception("数値異常");
            return value;
        }
        catch(NumberFormatException e)
        {
            throw new Exception("数値表記間違");
        }
    }
    //■CSV簡易データベース
    public static String[] searchCSV(String fileName, String keyWord, int cols, int col)
    //colsは１起算
    //col は０起算
    {
        File file = new File(fileName);
        String ret = null;
        //データ形式は、CSV
        String[] strArr = new TextIO().loadStrArr(file);
        if(strArr==null || strArr.length==0)
        {
            System.err.println("データ・ファイルに問題。"+file.getName());
            return null;
        }
        String[] datArr = null;
        for(int i=0; i<strArr.length; i++)
        {
            datArr = csv2Array(strArr[i], cols);
            if(datArr==null)
                System.err.println("データベースの一部が損壊。"+file.getName());
            else if(datArr[col].equals(keyWord))
                return datArr;
        }
        System.err.println("データベースに該当項目なし。"+file.getName());
        return null;
    }
} //EOF (Util.java)

◆SingleFileFilter.java

//■■SingleFileFilter.java

import java.io.File;
import javax.swing.filechooser.FileFilter;

//■■単一拡張子によるファイルフィルター
public class SingleFileFilter extends FileFilter
{
    private String extention;   //拡張子
    private String description; //説明文
    public SingleFileFilter(String ext)
    {
        extention = ext.toLowerCase(); //小文字に統一
        description = "*." + extention;
    }
    public boolean accept(File f)
    {
        if(f.isDirectory())
            return true;
        return f.getName().toLowerCase().endsWith(
            "." + extention); //ファイル名の末尾判定合否を通知
    }
    public String getDescription()
    {
        return description; //説明文を通知
    }
} //EOF (SingleFileFilter.java)

◆TextIO.java

//■■TextIO.java

import java.io.*;
import java.util.LinkedList;
import java.util.List;
import java.nio.file.Files;
import java.nio.file.Path;
import java.awt.*;
import javax.swing.*;

public class TextIO
{

    public static File callFileChooser(String mode, Component parent, String dir, String ext)
    {
        JFileChooser fileChooser = new JFileChooser(dir);
        if(!ext.equals("*"))
        {
          SingleFileFilter filter = new SingleFileFilter(ext);
          fileChooser.setFileFilter(filter);
        }
        int ret;
        if(mode.equals("open"))
            ret = fileChooser.showOpenDialog(parent);
        else if(mode.equals("save"))
            ret = fileChooser.showSaveDialog(parent);
        else
            return null;
        File file = fileChooser.getSelectedFile();
        if(ret != JFileChooser.APPROVE_OPTION || file == null)
            return null;
        else
            return file;
    }

    public static String[] loadStrArr(File file)
    { //デフォルト文字コード
        BufferedReader reader = null;
        Object[] objArr = null;
        String[] strArr = null;
        List<String> list = new LinkedList<String>();
        try
        {
            reader = new BufferedReader(new FileReader(file));
            try
            {
                String line  = "";
                for(int i=0;;i++) //データ読取り
                {
                    line = reader.readLine();
                    if(line == null) //終端超越なら
                        break;
                    list.add(line);
                }
                objArr = list.toArray();
                strArr = new String[objArr.length];
                for(int i=0; i<objArr.length; i++)
                {
                    strArr[i] = (String)objArr[i];
                }
            }
            catch(IOException e)
            {
                System.err.println(file.getName() + ": read error");
                strArr = null;
            }
            reader.close();
        }
        catch(FileNotFoundException e)
        {
            System.err.println(file.getName() + ": open error");
            strArr = null;
        }
        catch(IOException e)
        {
            System.err.println(file.getName() + ": close error");
            strArr = null;
        }
        return strArr;
    }

     public static String loadStr(File file)
    { //デフォルト文字コード
        BufferedReader reader = null;
        String retStr = "";
        try
        {
            reader = new BufferedReader(new FileReader(file));
            try
            {
                String line  = "";
                for(int i=0;;i++) //データ読取り
                {
                    line = reader.readLine();
                    if(line == null) //終端超越なら
                        break;
                    retStr = retStr + line + "\n";
                }
            }
            catch(IOException e)
            {
                System.err.println(file.getName() + ": read error");
                retStr = null;
            }
            reader.close();
        }
        catch(FileNotFoundException e)
        {
            System.err.println(file.getName() + ": open error");
            retStr = null;
        }
        catch(IOException e)
        {
            System.err.println(file.getName() + ": close error");
            retStr = null;
        }
        return retStr;
    }

    public static boolean saveStr(File file, String data)
    { //デフォルト文字コード
        BufferedWriter writer = null;
        boolean b = true;
        try
        {
            writer = new BufferedWriter(new FileWriter(file));
            try
            {
                writer.write(data);
                writer.flush();
            }
            catch(IOException e)
            {
                System.err.println(file.getName() + ": write error");
                b = false;
            }
            writer.close();
        }
        catch(IOException e)
        {
            if(writer == null)
            {
                System.err.println(file.getName() + ": open error");
            }
            else
            {
                System.err.println(file.getName() + ": close error");
            }
            b = false;
        }
        return b;
    }

    public static void saveText(File outputFile, String data, String charCode)
    { //charCode: "UTF-16", "UTF-8", "Shift_JIS", "MS932"
        PrintWriter pw = null;
        try //●書き出しファイルの準備
        {
            pw = new PrintWriter(new OutputStreamWriter(
                new FileOutputStream(outputFile), charCode));
        }
        catch(Exception e)
        {
            System.err.println("Exception1: saveText() " +
                charCode + "> \n" + e.toString());
        }

        try //●ファイルへの書き出し
        {
            if(data==null)
                System.err.println("data==null");
            if(pw==null)
                System.err.println("pw==null");
            if(data!=null && pw!=null)
                pw.print(data);
            pw.close();
        }
        catch(Exception e)
        {
            System.err.println("Exception2: saveText() " +
                charCode + "> \n" + e.toString());
        }
    }

    public static String loadText(File inputFile, String charCode)
    { //charCode: "UTF-16", "UTF-8", "Shift_JIS", "MS932"
        try //●ファイルからの読み取り
        {
            BufferedReader br = new BufferedReader(
                new InputStreamReader(new FileInputStream(inputFile),
                charCode));
            String text1 = "";
            String text2 = "";
            while ((text1 = br.readLine()) != null)
            {
                text2 = text2 + text1 + "\n";
            }
            return text2;
        }
        catch(Exception e)
        {
            System.err.println("Exception2: loadText() " +
                charCode + "> \n" + e.toString());
            return null;
        }
    }
} //EOF (TextIO.java)

◆Spline.java

//■■Spline.java

public class Spline
{ //参考文献：奥村晴彦 他 共著『Javaによるアルゴリズム事典』技術評論社、平成15年
  //参考文献：市村浩三 吉本富士市 共著『スプライン関数とその応用』教育出版、1979年

  private double[] x,y,z;

  public Spline(double[] x, double[]y)
  {
    int n = x.length;
    this.x = x; this.y = y;
    z = new double[n];
    double[] h = new double[n], d = new double[n];
    z[0] = z[n-1] = 0;
    for(int i=0; i<n-1; i++)
    {
      h[i]   = x[i+1] - x[i];
      d[i+1] = (y[i+1] - y[i])/h[i];
    }
    z[1] = d[2] - d[1] - h[0]*z[0];
    d[1] = 2*(x[2] - x[0]);
    for(int i=1; i<n-2; i++)
    {
      double t = h[i]/d[i];
      z[i+1] = d[i+2] -d[i+1] - z[i]*t;
      d[i+1] = 2*(x[i+2] - x[i]) - h[i]*t;
    }
    z[n-2] -= h[n-2]*z[n-1];
    for(int i=n-2; i>0; i--)
    {
      z[i] = (z[i] - h[i]*z[i+1])/d[i];
    }
  }

  public double interpolate(double t)
  {
    int i=0, j=x.length-1;
    while(i<j)
    {
      int k = (i+j)/2;
      if(x[k] < t)
        i=k+1;
      else
        j=k;
    }
    if(i>0)
      i--;
    double h = x[i+1]-x[i], d = t-x[i];
    return (((z[i+1] - z[i])*d/h + z[i]*3)*d
      +((y[i+1] - y[i])/h
      -(z[i]*2 + z[i+1])*h))*d + y[i];
  }
} //EOF (Spline)

◆Spline2.java

//■■Spline2.java

public class Spline2
{ //参考文献：奥村晴彦 他 共著『Javaによるアルゴリズム事典』技術評論社、平成15年
  //参考文献：市村浩三 吉本富士市 共著『スプライン関数とその応用』教育出版、1979年

  private double[] p;
  private Spline sx, sy;

  public Spline2(double[] x, double[] y)
  {
    int n = x.length;
    p = new double[n];
    p[0] = 0;
    for(int i=1; i<n; i++)
    {
      double t1 = x[i] - x[i-1], t2 = y[i] - y[i-1];
      p[i] = p[i-1] + Math.sqrt(t1*t1 + t2*t2);
    }
    for(int i=1; i<n; i++)
      p[i] /= p[n-1];
    sx = new Spline(p,x);
    sy = new Spline(p,y);
  }

  public double[] interpolate(double t)
  {
    return new double[] {sx.interpolate(t), sy.interpolate(t)};
  }
} //EOF (Spline2)

◆Spline3.java

//■■Spline3.java

public class Spline3
{
  double[]   tArr;   //0から1までを必要な補間数で、均等に区切った等差数列
  double[]   ipArr1; //スプライン補間を実行したｘｙ座標一点の配列
  double[][] ipArr2; //スプライン補間を実行したｘｙ座標多点の配列
  public Spline3(double[] x, double[] y, int tP)
  { //tPは、曲線を描く上で、座標数値として充分に大きい任意の数値。
    //例えば、描画範囲を示すWおよびHのピクセル数で、大きい方の数値。
    //ベクター画像の拡大を想定するなら、さらにその数倍の数値。
    Spline2 spline2 = new Spline2(x,y);
    tArr = new double[tP];;
    double t = 1.0/tP;
    for(int i=0; i<tP; i++)
    {
      tArr[i] = i*t;
    }
    tArr[tArr.length-1] = 1; //配列末尾は正確に１の値にする。

    ipArr2 = new double[tP][2];
    for(int i=0; i<tArr.length; i++)
    {
      ipArr1 = spline2.interpolate(tArr[i]);
      ipArr2[i][0] = ipArr1[0];
      ipArr2[i][1] = ipArr1[1];
    }
  }
  public double[][] getInterpolateXY()
  {
    return ipArr2;
  }
} //EOF (Spline3)

◆GCreator_Manual.txt

GCreator_Manual.txt
Ver.3.3

■■"GCreator" の命令文（コマンド）仕様書
●コマンド・エリアに記述する命令文は、この仕様書に従うこと。
●命令文書は、一行に一命令だけを記述すること。
●「double」と書くべきところを、便宜上「db」と省略表記することもある。
●「int」と書くべきところを、便宜上「i」と省略表記することもある。
●「String」と書くべきところを、便宜上「Str」と省略表記することもある。
●行頭または命令文終了直後に「//」があれば、これ以降行末までを注釈と見なす。
●行頭が「/@」の行と行頭が「@/」の行とで挟まれた複数行は、注釈と見なす。
●行頭に「Break;」があれば、これ以降の命令文の全部を注釈と見なす。

■■輪郭スムージング処理
★ Antialias(boolean a)
  a:      trueがアンチエイリアス処理あり
  ▽このギザギザ緩和処理で、細い線の色が薄くなる副作用あり。
■■画像サイズ
★ Size(double w, double h, String s)
  w:      巾
  h:      丈
  s:      pxかmmを指定
★ Size(double w, double h)
  w:      巾 px
  h:      丈 px
★ Size(String s)
  s:      "A4"または"B5"を指定
■■シフト（全体画像の移動）
★ Shift(int m, double x, double y)
  m:      0がシフトなし、1がシフトあり
  x:      X軸のシフト量
  y:      Y軸のシフト量
■■画像回転指定
★ Rotate(boolean b)
  b:      trueの時だけ90度回転
★ RotateFree(int d, int w, int h)
  d:      回転角度（ディグリー）
  w:      横方向原点移動
  h:      縦方向原点移動
★ RotateMulti(int sd, int d, int t, String f)
  sd:     回転開始角度（ディグリー）
  d:      回転角度（ディグリー）
  t:      回転回数
  f:      回転対象画像ファイル名
■■画像鏡像反転指定（回転処理も付属）
★ ReverseImage(String f, int m)
  f:      反転対象の画像ファイル名（パス含む）
  m:      1が左右鏡像反転、2が上下鏡像反転、3が左右対称、4が上下対称
          5が90度回転、6が180度回転、7が270度回転
■■標準拡大倍率指定
★ AffineScale(double sc)
  sc:     表示、画像保存に有効な自由拡大倍率
■■自由拡大倍率指定
★ FreeScale(double sc)
  sc:     表示、画像保存、印刷に有効な自由拡大倍率
■■線の太さ指定
★ LineWidth(double w)
  w:      線の太さ
■■直線の描線
★ DrawLine(double x1, double y1, double x2, double y2)
★ DrawLine2(double x1, double y1, double x2, double y2)
  x1:     起点座標X
  y1:     起点座標Y
  x2:     終点座標X
  y2:     終点座標Y
  ▽ただし、DrawLine2 は、マウス入力時の一時的描画専用の仮直線。
■■ベジェ曲線の自由描線
★ DrawCurve(db x1, db y1, db x2, db y2, db x3, db y3, db x4, db y4)
  x1:     起点座標X
  y1:     起点座標Y
  x2:     第一制御点座標X
  y2:     第一制御点座標Y
  x3:     第二制御点座標X
  y3:     第二制御点座標Y
  x4:     終点座標X
  y4:     終点座標Y
■■スプライン曲線の自由描線
★ DrawSplineStart(double x, double y)
  x:      起点座標X
  y:      起点座標Y
★ DrawSplineControl(double x, double y)
  x:      制御点座標X
  y:      制御点座標Y
  ▽制御点は、スプライン曲線１本につき、１箇所以上で、箇所数上限なし
★ DrawSplineEnd(double x, double y)
  x:      終点座標X
  y:      終点座標Y
■■四角形の描画指定
★ DrawRect(int m, db x, db y, db w, db h, int r, int g, int b)
  m:      0は非描画、1は線、2は色塗り、3は線と色塗り、4は透明色
  x:      x座標
  y:      y座標
  w:      幅
  h:      高さ
  r:      赤色成分　0-255
  g:      緑色成分　0-255
  b:      青色成分　0-255
■■楕円の描画指定
★ DrawEllipse(int m, db x, db y, db hr, db vr, int r, int g, int b)
  m:      0は非描画、1は線、2は色塗り、3は線と色塗り、4は透明色
  x:      楕円の中心のｘ座標
  y:      楕円の中心のｙ座標
  hr:     横半径
  vr:     縦半径
  r:      赤色成分　0-255
  g:      緑色成分　0-255
  b:      青色成分　0-255
  ▽hrとvrとが、違う値なら楕円で、同じ値なら真円。
■■真円の描画指定
★ DrawCircle(int m, db x, db y, db rr, int r, int g, int b)
  m:      0は非描画、1は線、2は色塗り、3は線と色塗り、4は透明色
  x:      円の中心のｘ座標
  y:      円の中心のｙ座標
  rr:     半径
  r:      赤色成分　0-255
  g:      緑色成分　0-255
  b:      青色成分　0-255
■■自由図形の描画指定
★ DrawShapeStart(int m, double x, double y, int r, int g, int b)
  m:      0が非描画、1が線描、2が色塗り、3が線描と色塗り、4は透明色
  x:      自由図形の起点座標X
  y:      自由図形の起点座標Y
  r:      赤色成分　0-255
  g:      緑色成分　0-255
  b:      青色成分　0-255
★ DrawShapeLine(double x, double y)
  x:      自由図形の中間点座標X
  y:      自由図形の中間点座標Y
★ DrawShapeCurve(db x1, db y1, db x2, db y2, db x3, db y3)
  x1,x2,x3: 自由図形の中間点座標X（三点）
  y1,y2,y3: 自由図形の中間点座標Y（三点）
★ DrawShapeEnd()
  ▽引数なし（自由図形の始点回帰で終点を宣言）。
■■文字の太さ指定（WriteStringHに対応）
★ FontBold(boolean b)
  b:      太字指定なら true
■■文字列の描画指定
★ WriteStringH(double x, double y, int si, String st, String s)
★ WriteString(double x, double y, int si, String st, String s)
★ WriteStringB(double x, double y, int si, String st, String s)
★ WriteStringBMulti(double x, double y, int si, int px, String st, String s)
★ WriteStringV(double x, double y, int si, String st, String s)
  x:      ｘ座標
  y:      ｙ座標
  si:     フォント・サイズ
  px:     拡張機能（極太文字の文字拡大）
  st:     字形（"sansserif" / "serif" など）
  s:      表示する文字列
  ▽WriteStringHは、横書き文字。
  ▽WriteStringは、WriteStringHの省略表記。
  ▽WriteStringBは、横書き極太文字。
  ▽WriteStringBMultiは、横書き極太文字の機能拡張。
  ▽WriteStringVは、縦書き文字。（画像精細度が低下する。）
■■挿入画像の表示指定
★ Image(int x, int y, int w, int h, String f)
  x:       表示ｘ座標位置
  y:       表示ｙ座標位置
  w:       画像の表示幅
  h:       画像の表示丈
  f:       画像ファイル名（パス付き）
■■スタンプ画像の上書き
★ Stamp(int x, int y, int w, int h, String f)
  x:       表示ｘ座標位置
  y:       表示ｙ座標位置
  w:       画像の表示幅
  h:       画像の表示丈
  f:       スタンプ画像（上書き画像）ファイル名（パス含む）
  ▽スタンプの灰色部分を無色透明に変換してスタンプ画像を、表示中の画像に上書き。
★ StampMulti(int x, int y, int w, int h, int sx, int sy, int tx, int ty, String f)
  x:     当初表示ｘ座標位置
  y:     当初表示ｙ座標位置
  w:     画像の表示幅
  h:     画像の表示丈
  sx:    画像の横方向スキップのピクセル数
  sy:    画像の縦方向スキップのピクセル数
  tx:    画像の横方向表示反復回数
  ty:    画像の縦方向表示反復回数
  f:     画像ファイル（パス含む）
  ▽同一画像スタンプの位置を変えての連続処理（タイル貼り）
■■画像の切り貼り
★ CutAndPasteMask(String f)
  f:       切り貼り指定のマルチ・マスク画像ファイル名（パス含む）
★ CutAndPaste(String f, int r, int g, int b)
  f:       切り貼り指定の模様画像ファイル名（パス含む）
  r:       赤色成分（マルチ・マスクでの指定該当色　0-255）
  g:       緑色成分
  b:       青色成分
■■連続色相変更
★ ChangeColorMultiBase(String f)
  f:       連続色相変更元画像ファイル名（パス含む）
★ ChangeColorMulti(int r0, int g0, int b0, int r1, int g1, int b1)
  r0:      赤色成分（元画像での変更対象色　0-255）
  g0:      緑色成分
  b0:      青色成分
  r1:      赤色成分（新画像での変更実施色　0-255）
  g1:      緑色成分
  b1:      青色成分
■■単独色相変更
★ ChangeColor(Str f,i c,i mode,i r1,i g1,i b1,i r2,i g2,i b2)
★ ChangeColor(Str f,i c,i r1,i g1,i b1,i r2,i g2,i b2)
  f :      色相変更する既存画像ファイル名（パス含む）
  c :      微妙な色変動の許容値
  mode :   １または２
  r1:      旧色
  g1:
  b1:
  r2:      新色
  g2:
  b2:
  ▽モード１は、写真などの階調画像からマルチ・マスク画像を作成する場合などに使用
  ▽モード２は、写真などの階調画像からグレー・マスク画像を作成する場合などに使用
■■図形内部彩色変更（輪郭線の内側を指定色で塗り直す）
★ ChangeColorInner(Str f, i r0, i g0, i b0, i r1, i g1, i b1, i x, i y, i mode)
  f:       彩色変更対象画像ファイル名（パス含む）
  r0:      輪郭線色
  g0:
  b0:
  r1:      内部彩色指定色
  g1:
  b1:
  x:       図形内側代表位置のx座標
  y:       図形内側代表位置のy座標
  mode     輪郭線を内部彩色と同一にするかの可否
★ ChangeColorInnerMultiMask(Str f, int r, int g, int b)
  f:       彩色変更対象画像ファイル名（パス含む）
  r:       輪郭線色
  g:
  b:
★ ChangeColorInnerMulti(int r, int g, int b, int x, int y)
  r:       内部彩色指定色
  g:
  b:
  x:       図形内側代表位置のx座標
  y:       図形内側代表位置のy座標
■■前景色の指定（線または文字の色）
★ ForegroundColorL(int r, int g, int b)
  r:       赤色成分　0-255
  g:       緑色成分
  b:       青色成分
★ ForegroundColorS(int r, int g, int b)
  r:       赤色成分　0-255
  g:       緑色成分
  b:       青色成分
★ ForegroundColorB(int r, int g, int b)
  r:       赤色成分　0-255
  g:       緑色成分
  b:       青色成分
  ▽ForegroundColorLは線色。
  ▽ForegroundColorSは文字色。
  ▽ForegroundColorBは極太文字色。
■■背景色の指定
★ BackgroundColor(int r, int g, int b)
  r:       赤色成分　0-255
  g:       緑色成分
  b:       青色成分
■■背景パターン模様の指定
★ StripePattern(int tp, int w, int r, int g, int b)
  tp:      ストライプ模様の無効または水平または垂直
  w:       ストライプ幅
  r:       赤基調色
  g:       緑基調色
  b:       青基調色
★ MatrixPatternSt(int pn, int wh, int r, int g, int b, int lm)
  pn:      柄紋番号
  wh:      柄紋の幅丈（ピクセル数、正方形柄紋）
  r:       赤基調色　5-250
  g:       緑基調色
  b:       青基調色
  lm:      色成分の乱数変動幅の制限（1～10）
★ MatrixPatternStOp(db sH,db sV,db dH,db dV,i pH,i pV,i rH,i rV,i in)
  sH:      横シフト（コマ数）
  sV:      縦シフト（コマ数）
  dH:      横ドロップ（コマ数）
  dV:      縦ドロップ（コマ数）
  pH:      横スキップ（コマ数）
  pV:      縦スキップ（コマ数）
  rH:      横リピート（回数）、０なら自動計算
  rV:      縦リピート（回数）、０なら自動計算
  in:      間欠描画指定。1～9なら間欠描画、10なら通常描画
★ MatrixPatternEx(int pn, int wh, int r, int g, int b, int lm)
  pn:      柄紋番号
  wh:      柄紋の幅丈（ピクセル数、正方形柄紋）
  r:       赤基調色
  g:       緑基調色
  b:       青基調色
  lm:      色成分の乱数変動幅の制限（1～10）
★ MatrixPatternExOp(db sH,db sV,db dH,db dV,i pH,i pV,i rH,i rV,i in)
  sH:      横シフト（コマ数）
  sV:      縦シフト（コマ数）
  dH:      横ドロップ（コマ数）
  dV:      縦ドロップ（コマ数）
  pH:      横スキップ（コマ数）
  pV:      縦スキップ（コマ数）
  rH:      横リピート（回数）、０なら自動計算
  rV:      縦リピート（回数）、０なら自動計算
  in:      間欠描画指定。1～9なら間欠描画、10なら通常描画
■■色相階調加工
★ ColorGradient(String f, int y1, int y2, double r, double g, double b)
  f:      元画像ファイル名（パス含む）
  y1:     加工開始y軸位置
  y2:     加工反転y軸位置
  r:      赤成分の追加数値
  g:      緑成分の追加数値
  b:      青成分の追加数値
■■色相調整
★ AjustRGB(String f, int r, int g, int b)
  f:       色相調整する既存画像ファイル名（パス含む）
  r:       赤色成分の加減量（－１００～１００％）
  g:       緑色成分の加減量
  b:       青色成分の加減量
  ▽既存画像の色相を微調整する
■■ソフト・フォーカス加工
★ SoftFocus(String f, int d)
  f:       ソフト・フォーカスの対象となる画像ファイル（パス含む）
  d:       ソフト・フォーカスの度合い（０～１００）
■■二重像画像加工
★ MixImage(String f1, String f2)
 f1:       元画像ファイル名（パス含む）
 f2:       追加画像ファイル名（パス含む）
★ MixImage(int mode, String f1, String f2)
 mode      ０の指定で、拡大縮小のないStamp機能となる
 f1:       元画像ファイル名（パス含む）
 f2:       追加画像ファイル名（パス含む）
■■平行線描画（横罫線や縦罫線または方眼のための特殊用途）
★ DrawParallelLineH(db x, db y, db l, db w, int t, int m, int h)
★ DrawParallelLineH2(db x, db y, db l, db w, int t, int m, int h)
  x:       起点座標X
  y:       起点座標Y
  l:       線の長さ
  w:       線の間隔
  t:       線の本数
  m:       線の種類（０：実線、１：密の点線、２：粗の点線）
  h:       中間線の有無（０：無し、１：有り）
★ DrawParallelLineV(db x, db y, db l, db w, int t, int m, int h)
★ DrawParallelLineV2(db x, db y, db l, db w, int t, int m, int h)
  x:       起点座標X
  y:       起点座標Y
  l:       線の長さ
  w:       線の間隔
  t:       線の本数
  m:       線の種類（０：実線、１：密の点線、２：粗の点線）
  h:       中間線の有無（０：無し、１：有り）
■■ファイル入出力の指定（「保存」や「切取」のボタンに対処）
★ SaveCommands(String f)
  f：      命令文書の保存ファイル名（パス含む）
★ SaveImage(String f)
  f：      作成画像の保存ファイル名（パス含む）
★ CutAndSaveImage(int x1.int y1, int x2, int y2, String f)
  f：      切り取り画像の保存ファイル名（パス含む）
  x1:      切り取り画像左上座標ｘ
  y1:      切り取り画像左上座標ｙ
  x2:      切り取り画像右下座標ｘ
  y2:      切り取り画像右下座標ｙ

//EOF (GCreator_Manual.txt)

◆GCreator_Pattern.txt

//GCreator_Pattern.txt
//Ver.3.3
//
//以下２桁以内の配色番号は、６ｘ６コマで、０を含まないマトリックス模様データ。
//
PTN,0001,06,枡に五つ星
1,1,1,3,3,3
1,6,1,3,6,3
1,1,6,6,3,3
4,4,6,6,5,5
4,6,4,5,6,5
4,4,4,5,5,5
PTN,0002,06,市松
1,1,1,2,2,2
1,1,1,2,2,2
1,1,1,2,2,2
2,2,2,1,1,1
2,2,2,1,1,1
2,2,2,1,1,1
PTN,0003,06,市松崩し
1,1,1,2,2,2
1,3,1,2,4,2
1,1,1,2,2,2
2,2,2,1,1,1
2,5,2,1,6,1
2,2,2,1,1,1
PTN,0004,06,松皮菱崩し
1,1,1,2,3,3
1,2,2,2,3,3
1,2,3,3,2,2
2,2,3,3,2,1
3,3,2,2,2,1
3,3,2,1,1,1
PTN,0005,06,大十字紋
1,2,2,2,2,1
3,1,2,2,1,3
3,3,1,1,3,3
3,3,1,1,3,3
3,1,2,2,1,3
1,2,2,2,2,1
PTN,0006,06,十字紋尽くし
1,2,1,3,4,3
2,5,2,4,4,4
1,2,1,2,4,3
3,4,2,1,2,1
4,4,4,2,5,2
3,4,3,1,2,1
PTN,0007,06,十字紋斜め崩し
1,1,7,3,6,6
1,4,3,3,3,6
4,4,4,3,2,7
7,4,5,2,2,2
6,5,5,5,2,1
6,6,5,7,1,1
PTN,0008,06,市松大十字紋
1,2,3,3,1,2
2,3,2,1,3,1
3,2,1,2,1,3
3,1,2,1,2,3
1,3,1,2,3,2
2,1,3,3,2,1
PTN,0009,06,網目市松合わせ
1,1,3,3,2,2
1,1,3,3,2,2
3,3,1,1,3,3
3,3,1,1,3,3
2,2,3,3,1,1
2,2,3,3,1,1
PTN,0010,06,二重網目
4,2,2,2,2,4
2,1,3,3,1,2
2,3,4,4,3,2
2,3,4,4,3,2
2,1,3,3,1,2
4,2,2,2,2,4
PTN,0011,06,入れ子枡
1,1,1,1,1,1
1,2,2,2,2,1
1,2,3,3,2,1
1,2,3,3,2,1
1,2,2,2,2,1
1,1,1,1,1,1
PTN,0012,06,鍵尽くし
4,4,4,5,5,5
4,2,2,3,3,5
4,2,1,6,3,5
5,3,6,1,2,4
5,3,3,2,2,4
5,5,5,4,4,4
PTN,0013,06,多色砂目
1,3,2,3,1,4
3,4,5,1,3,2
4,1,3,2,1,1
1,2,4,1,2,3
2,3,1,2,1,4
3,1,3,5,2,1
PTN,0014,06,枡尽くし
1,1,1,2,2,2
1,5,5,5,5,2
1,5,1,2,5,2
4,5,4,3,5,3
4,5,5,5,5,3
4,4,4,3,3,3
PTN,0015,06,枡尽くし改
1,1,1,2,2,2
1,3,3,3,4,2
1,4,1,2,4,2
2,4,2,1,4,1
2,4,3,3,3,1
2,2,2,1,1,1
PTN,0016,06,重ね枡
1,2,3,3,3,3
2,2,3,5,5,3
4,4,3,4,5,3
4,5,3,4,3,3
4,5,5,4,2,2
4,4,4,4,2,1
PTN,0017,06,枡と市松
4,1,3,6,1,3
1,2,2,2,2,1
6,2,7,5,2,3
3,2,5,7,2,6
1,2,2,2,2,1
3,1,6,3,1,4
PTN,0018,06,枡と市松崩し
4,1,1,6,1,3
1,2,2,2,2,1
1,2,7,5,2,3
3,2,5,7,2,1
1,2,2,2,2,1
3,1,6,1,1,4
PTN,0019,06,Ｙ字紋
1,2,1,4,1,4
2,2,2,4,4,4
2,1,2,1,4,1
1,3,1,5,1,5
3,3,3,5,5,5
3,1,3,1,5,1
PTN,0020,06,Ｙ字紋改
1,2,1,4,4,1
2,2,2,1,4,4
2,1,2,4,4,1
1,3,3,5,1,5
3,3,1,5,5,5
1,3,3,1,5,1
PTN,0021,06,鱗尽くし
1,1,1,2,1,1
1,1,2,2,2,1
1,2,2,2,2,2
2,1,1,1,1,1
2,2,1,1,1,2
2,2,2,1,2,2
PTN,0022,06,三角波
1,2,2,3,2,2
1,1,2,2,2,1
3,1,1,2,1,1
3,3,1,1,1,3
2,3,3,1,3,3
2,2,3,3,3,2
PTN,0023,06,横縞
1,1,1,1,1,1
2,2,2,2,2,2
3,3,3,3,3,3
4,4,4,4,4,4
5,5,5,5,5,5
6,6,6,6,6,6
PTN,0024,06,縦縞
1,2,3,4,5,6
1,2,3,4,5,6
1,2,3,4,5,6
1,2,3,4,5,6
1,2,3,4,5,6
1,2,3,4,5,6
//
//以下３桁の配色番号は、６ｘ６コマで、０を含む模様データ。
//
PTN,0100,06,外抜き枡
0,0,0,0,0,0
0,2,2,2,2,0
0,2,3,3,2,0
0,2,3,3,2,0
0,2,2,2,2,0
0,0,0,0,0,0
PTN,0101,06,中抜き枡
1,1,1,1,1,1
1,0,0,0,0,1
1,0,0,0,0,1
1,0,0,0,0,1
1,0,0,0,0,1
1,1,1,1,1,1
PTN,0102,06,外抜き十字紋
0,0,0,0,0,0
0,0,1,3,0,0
0,1,1,3,3,0
0,2,2,4,4,0
0,0,2,4,0,0
0,0,0,0,0,0
PTN,0103,06,星散らし
0,0,0,0,0,0
0,1,0,0,1,0
0,0,0,0,0,0
0,0,0,0,0,0
0,1,0,0,1,0
0,0,0,0,0,0
PTN,0104,06,外抜き五つ星
0,0,0,0,0,0
0,1,0,0,1,0
0,0,1,1,0,0
0,0,1,1,0,0
0,1,0,0,1,0
0,0,0,0,0,0
PTN,0105,06,白抜き市松
1,1,1,0,0,0
1,1,1,0,0,0
1,1,1,0,0,0
0,0,0,1,1,1
0,0,0,1,1,1
0,0,0,1,1,1
PTN,0106,06,点入り十字紋（右下がり）
0,1,0,0,0,0
1,1,1,0,1,0
0,1,0,0,0,0
0,0,0,0,1,0
0,1,0,1,1,1
0,0,0,0,1,0
PTN,0107,06,点入り十字紋（右上がり）
0,0,0,0,1,0
0,1,0,1,1,1
0,0,0,0,1,0
0,1,0,0,0,0
1,1,1,0,1,0
0,1,0,0,0,0
PTN,0108,06,交叉一点鎖線（右下がり）
0,1,0,0,0,0
0,1,0,0,1,0
0,1,0,0,0,0
0,0,0,0,0,0
0,1,0,1,1,1
0,0,0,0,0,0
PTN,0109,06,交叉一点鎖線（右上がり）
0,0,0,0,1,0
0,1,0,0,1,0
0,0,0,0,1,0
0,0,0,0,0,0
1,1,1,0,1,0
0,0,0,0,0,0
PTN,0110,06,Ｗ字紋囲み
0,1,1,2,2,0
1,1,0,0,2,2
1,0,0,0,0,2
2,0,0,0,0,1
2,2,0,0,1,1
0,2,2,1,1,0
PTN,0111,06,八角紋
0,0,1,1,0,0
0,1,2,2,1,0
1,2,2,2,2,1
1,2,2,2,2,1
0,1,2,2,1,0
0,0,1,1,0,0
PTN,0112,06,Ｌ字囲み枡
0,0,0,0,0,0
0,1,1,2,2,0
0,1,2,2,2,0
0,2,2,2,1,0
0,2,2,1,1,0
0,0,0,0,0,0
PTN,0113,06,白抜き十字紋尽くし改
0,0,0,3,0,0
0,4,3,3,3,0
4,4,4,3,2,0
0,4,5,2,2,2
0,5,5,5,2,0
0,0,5,0,0,0
PTN,0114,06,白抜きＴ字紋尽くし
0,0,0,0,0,0
0,4,3,3,3,0
0,4,4,3,2,0
0,4,5,2,2,0
0,5,5,5,2,0
0,0,0,0,0,0
PTN,0115,06,白抜き横縞
0,0,0,5,0,0
0,1,1,1,1,0
2,2,2,2,2,0
0,3,3,3,3,3
0,4,4,4,4,0
0,0,5,0,0,0
PTN,0116,06,白抜き縦縞
0,0,0,3,0,0
0,1,2,3,4,0
5,1,2,3,4,0
0,1,2,3,4,5
0,1,2,3,4,0
0,0,2,0,0,0
PTN,0117,06,外白抜き十字網文
0,0,0,0,0,0
0,3,2,2,3,0
0,2,2,2,2,0
0,2,2,2,2,0
0,3,2,2,3,0
0,0,0,0,0,0
PTN,0118,06,網代,Op(0,0,0,0,-2,-2,0,0,10)
0,2,0,4,4,2
1,2,3,3,1,2
1,4,4,2,1,0
3,3,1,2,4,4
0,2,1,3,3,2
0,2,0,0,0,2
//
//以下の配色番号１０００番以上は、６ｘ６コマを超える大柄
//
PTN,1000,07,斜め格子(7x7)
1,2,2,2,2,2,1
2,1,2,2,2,1,2
2,2,1,2,1,2,2
2,2,2,1,2,2,2
2,2,1,2,1,2,2
2,1,2,2,2,1,2
1,2,2,2,2,2,1
PTN,1001,09,入れ子枡(9x9)
5,5,5,5,5,5,5,5,5
5,1,1,1,1,1,1,1,5
5,1,2,2,2,2,2,1,5
5,1,2,3,3,3,2,1,5
5,1,2,3,4,3,2,1,5
5,1,2,3,3,3,2,1,5
5,1,2,2,2,2,2,1,5
5,1,1,1,1,1,1,1,5
5,5,5,5,5,5,5,5,5
PTN,1002,08,十文字尽くし(8x8),Op(0,0,0,0,-3,-3,0,0,10)
0,1,0,0,0,0,2,0
1,1,1,0,4,2,2,2
0,1,3,4,4,4,2,0
0,3,3,3,4,6,0,0
0,0,3,5,6,6,6,0
0,7,5,5,5,6,8,0
7,7,7,5,0,8,8,8
0,7,0,0,0,0,8,0
PTN,1003,25,亀甲十字紋(25x25),Op(-3.5,-8.5,0,-21,-11,17,0,0,10)
0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0
0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0
0,0,0,0,0,0,0,1,1,1,1,5,5,5,1,1,1,1,0,0,0,0,0,0,0
0,0,0,0,0,1,1,1,1,5,5,5,3,5,5,5,1,1,1,1,0,0,0,0,0
0,0,0,1,1,1,1,5,5,5,5,3,3,3,5,5,5,5,1,1,1,1,0,0,0
0,1,1,1,1,5,5,5,3,5,5,5,3,5,5,5,3,5,5,5,1,1,1,1,0
1,1,1,5,5,5,5,3,3,3,5,5,5,5,5,3,3,3,5,5,5,5,1,1,1
1,1,5,5,3,5,5,5,3,5,5,5,4,5,5,5,3,5,5,5,3,5,5,1,1
1,1,5,3,3,3,5,5,5,5,5,4,4,4,5,5,5,5,5,3,3,3,5,1,1
1,1,5,5,3,5,5,5,5,4,5,5,4,5,5,4,5,5,5,5,3,5,5,1,1
1,1,5,5,5,5,5,5,5,5,5,4,4,4,5,5,5,5,5,5,5,5,5,1,1
1,1,5,5,3,5,5,5,4,5,4,4,4,4,4,5,4,5,5,5,3,5,5,1,1
1,1,5,3,3,3,5,4,4,4,4,4,4,4,4,4,4,4,5,3,3,3,5,1,1
1,1,5,5,3,5,5,5,4,5,4,4,4,4,4,5,4,5,5,5,3,5,5,1,1
1,1,5,5,5,5,5,5,5,5,5,4,4,4,5,5,5,5,5,5,5,5,5,1,1
1,1,5,5,3,5,5,5,5,4,5,5,4,5,5,4,5,5,5,5,3,5,5,1,1
1,1,5,3,3,3,5,5,5,5,5,4,4,4,5,5,5,5,5,3,3,3,5,1,1
1,1,5,5,3,5,5,5,3,5,5,5,4,5,5,5,3,5,5,5,3,5,5,1,1
1,1,1,5,5,5,5,3,3,3,5,5,5,5,5,3,3,3,5,5,5,5,1,1,1
0,1,1,1,1,5,5,5,3,5,5,5,3,5,5,5,3,5,5,5,1,1,1,1,0
0,0,0,1,1,1,1,5,5,5,5,3,3,3,5,5,5,5,1,1,1,1,0,0,0
0,0,0,0,0,1,1,1,1,5,5,5,3,5,5,5,1,1,1,1,0,0,0,0,0
0,0,0,0,0,0,0,1,1,1,1,5,5,5,1,1,1,1,0,0,0,0,0,0,0
0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0
0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0
PTN,1004,25,亀甲六芒星紋(25x25),Op(-3.5,-8.5,0,-21,-11,17,0,0,10)
0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0
0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0
0,0,0,0,0,0,0,1,1,1,1,2,2,2,1,1,1,1,0,0,0,0,0,0,0
0,0,0,0,0,1,1,1,1,2,2,3,2,3,2,2,1,1,1,1,0,0,0,0,0
0,0,0,1,1,1,1,2,2,2,2,2,3,2,2,2,2,2,1,1,1,1,0,0,0
0,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,0
1,1,1,2,2,2,2,2,3,2,2,2,3,2,2,2,3,2,2,2,2,2,1,1,1
1,1,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,1,1
1,1,2,3,3,2,2,2,2,2,2,2,3,2,2,2,2,2,2,2,3,3,2,1,1
1,1,2,2,2,2,3,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,2,1,1
1,1,2,2,2,2,2,2,3,2,2,2,3,2,2,2,3,2,2,2,2,2,2,1,1
1,1,2,2,2,2,2,2,2,2,2,3,3,3,2,2,2,2,2,2,2,2,2,1,1
1,1,2,2,3,2,2,2,2,2,3,3,3,3,3,2,2,2,2,2,3,2,2,1,1
1,1,2,2,2,2,2,2,2,2,2,3,3,3,2,2,2,2,2,2,2,2,2,1,1
1,1,2,2,2,2,2,2,3,2,2,2,3,2,2,2,3,2,2,2,2,2,2,1,1
1,1,2,2,2,2,3,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,2,1,1
1,1,2,3,3,2,2,2,2,2,2,2,3,2,2,2,2,2,2,2,3,3,2,1,1
1,1,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,1,1
1,1,1,2,2,2,2,2,3,2,2,2,3,2,2,2,3,2,2,2,2,2,1,1,1
0,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,0
0,0,0,1,1,1,1,2,2,2,2,2,3,2,2,2,2,2,1,1,1,1,0,0,0
0,0,0,0,0,1,1,1,1,2,2,3,2,3,2,2,1,1,1,1,0,0,0,0,0
0,0,0,0,0,0,0,1,1,1,1,2,2,2,1,1,1,1,0,0,0,0,0,0,0
0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0
0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0
PTN,1005,09,三角形(9x9),Op(-0.5,-1,-5,0,1,-4,10,27,10)
0,0,0,0,1,0,0,0,0
0,0,0,1,1,1,0,0,0
0,0,1,1,1,1,1,0,0
0,1,1,1,1,1,1,1,0
1,1,1,1,1,1,1,1,1
0,0,0,0,0,0,0,0,0
0,0,0,0,0,0,0,0,0
0,0,0,0,0,0,0,0,0
0,0,0,0,0,0,0,0,0
PTN,1006,11,菱形(11x11)
0,0,0,0,0,1,0,0,0,0,0
0,0,0,0,1,1,1,0,0,0,0
0,0,0,1,1,1,1,1,0,0,0
0,0,1,1,1,1,1,1,1,0,0
0,1,1,1,1,1,1,1,1,1,0
1,1,1,1,1,1,1,1,1,1,1
0,1,1,1,1,1,1,1,1,1,0
0,0,1,1,1,1,1,1,1,0,0
0,0,0,1,1,1,1,1,0,0,0
0,0,0,0,1,1,1,0,0,0,0
0,0,0,0,0,1,0,0,0,0,0
//
//EOF (GCreator_Pattern.txt)