GNU Emacs 32.0.50 (9008bf64c3) のマニュアルを PLaMo 翻訳で機械翻訳したものです。誤訳を含むことがあります。原文: https://www.gnu.org/software/emacs/manual/html_node/elisp/Canvas-Images.html ・ emacs-doc.conao3.com

42.17.11 Canvas 画像

Canvas画像は、ドキュメントビューアや可視化ツール、動的に計算されるアニメーションやゲームなどで、高いフレームレートで効率的に更新・表示できます。Canvas画像には、ARGB32形式の書き込み可能なピクセルバッファが付随しています。移植性を確保するため、この形式はすべてのプラットフォームで共通です。Emacsでサポートされている他の画像タイプとは異なり、Canvas画像は更新のたびに新しいEmacs Lispオブジェクトを作成する必要はありません。

:type canvas を用いた画像指定子は、例えば次のようにキャンバスを作成します。

(defvar my-canvas
  '(image :type canvas
          :id my-canvas
          :data-width 800
          :data-height 600))

画像指定オブジェクトは、(eq に対して)一意にキャンバス画像オブジェクトを識別します。プロパティ :data-width、:data-height、および :id は必須です。幅と高さはともに正の整数である必要があり、id はシンボルである必要があります。

キャンバスは、ARGB32データを固定小数点数のベクトルとして、あるいは:dataにユニバイト文字列として指定することで作成できます。また、:fileにARGB32データを含むファイルへのパスを指定することも可能です。さらに、create-imageでは以下のようにキャンバス画像を作成でき、その際、データは最初にファイルまたはベクトルから読み込まれます:

(setq my-file-canvas (create-image "/path/to/file"
                                   'canvas nil
                                   :data-width 800
                                   :data-height 600))
(setq my-vec (make-vector (* 800 600) #xFFFF0000))
(setq my-vec-canvas (create-image my-vec
                                  'canvas t
                                  :data-width 800
                                  :data-height 600))

寸法の値が変更された場合(すなわち :data-height または :data-width)、Emacs は基盤となるピクセルバッファを自動的に調整し、キャンバスのサイズを変更します。

:scale、:margin、:relief、:transform-smoothing、:map といったその他の画像プロパティもサポートされています。これらのプロパティの詳細については、画像記述子を参照してください。

キャンバスを表示するには、文字列またはオーバーレイの display プロパティとして指定してください:

(insert (propertize "#" 'display my-canvas))
(overlay-put some-overlay 'display my-canvas)

キャンバス画像オブジェクトが作成・表示された後は、canvas-refresh を介して「リフレッシュ」することができます。

関数: canvas-refresh image &optional reload-data

キャンバス image をリフレッシュし、画面上に更新します。オプション引数 reload-data が nil でない場合は、キャンバスを再描画する前に、画像指定から :data または file を再読み込みします。

以下のコードは、データやファイルを再読み込みすることでキャンバスを更新します。

;; Draw pixels
(aset my-vec <index> <color>)
;; Reload and refresh canvas images
(canvas-refresh my-vec-canvas 'reload-data)

ループ内でキャンバスを更新する際は、明示的に redisplay を呼び出す必要があります:

(setq canvas (create-image (make-vector (* 100 100) 0) 'canvas t
			   :data-width 100 :data-height 100))
(insert (propertize "#" 'display canvas))
(dotimes (i (* 100 100))
  (aset (plist-get (cdr canvas) :data) i #xFF)
  (canvas-refresh canvas 'reload-data)
  (redisplay))

ただし、タイマーやコマンドでキャンバスを更新する場合、タイマーやコマンドの実行後に redisplay が暗黙的に呼び出されます。以下の例では、上記のキャンバスをタイマーによって1秒間に約30回更新します:

(let ((i 0))
  (run-at-time nil 0.033 (lambda ()
			  (when (< i (* 100 100))
			    (aset (plist-get (cdr canvas) :data) i #xFF)
			    (incf i)
			    (canvas-refresh canvas 'reload-data)))))

Canvas画像は、ダイナミックモジュールを通じて操作や更新が可能です。詳細については、モジュールでのCanvas APIの使用を参照してください。