Adobe Illustrator SDK 覚え書き

以下は以前Q*ita に載せていた記事の転載です。古い部分を一部更新または削除しています。


Adobe Illustrator SDK (以下 Ai SDK) について、自分なりにハマったところなどを晒している記事です。きちんと構成すると大変というのと、自分自身もまだ認識不足の点が多々あるので、雑ネタという体裁で追記・更新していく予定です。

以下の内容は現時点での個人的覚え書きであり、勘違いを含む可能性があります。

お気づきの点があればご指摘ください( https://twitter.com/shspage など)。

以下で Ai SDK のバージョン記載がない場合は Illustrator 2020 SDK です。

もくじ

  • SDK の入手
  • 開発環境
  • プラグインの仕組み
  • PIPL
  • Template
  • Suite の遅延読み込み
  • ai::UnicodeString の文字コード指定
  • ツールアイコンの色を自動調整させる
  • ツールカーソルのホットスポット設定
  • 例外処理
  • (Ai 2022 SDK) LiveEffect のサブメニューが表示されない
  • GPUパフォーマンスがONだとデバッグ時にエラーになる
  • (Ai 2024 SDK, Mac) Undefined symbol: _OBJC_CLASS_$_GCContoroller
  • (win, Visual Studio 2017) UTF-8ソースコードをビルドする
  • ImGuiによる設定用ダイアログの作成
  • ...
  • オブジェクト操作編
  • リリース・配布編

SDK の入手 (2024.02.04現在)

こちらから。Adobe Id でのログインが必要。https://www.adobe.io/

Ai SDK の使用許諾は同梱の EULAs.pdf にある。

開発環境

Ai SDK の利用に必要な開発環境と、プラグインの作成からデバッグまでの流れについては SDK 付属の getting-started-guide.pdf で説明されている。 ただ Creating a plug-in in Windows, Creating a plug-in in Mac OS の章については内容が古いので、samplecode を見ながら補足的に参照するのが良いと思う。

docs/references フォルダには関数等のリファレンス(index.chm)がある。 index.chmwindows用のHTMLヘルプファイルだが、検索して調べたりする用途にはたいへん使いやすい。 以前はこれを見るためだけにmacにもVirtualboxwindowsを入れていた。

index.chm を開いたとき空白のページが表示される場合は、index.chm を右クリックして「プロパティ」を開き、 「全般」画面の一番下の「セキュリティ」で「許可する」にチェックを入れる。

プラグインの仕組み

(サンプルコードをビルドできるのが確認できたら、実際どのような処理をしているのかを見ていく段階になると思う。その助けになるか混乱させるかは分からないが、自分なりに理解しているプラグインの仕組みについて少し触れておく。)

プラグインの処理の流れは以下のようになる。

これを踏まえて、プラグインの仕組みについて以下で説明する。

Plugin

プラグインは Plugin という機能の一種(継承クラス)として作成する。 ここでは MyTool という名前にする。 初期化に伴う決まりきった処理は Plugin にあらかじめ用意されているものに任せておき、MyTool では独自の処理の部分を作成することになる。 SDK のサンプルコードでは ~Plugin.cpp で MyTool 独自の処理にあたることを行っている。

イラレからの呼び出しは caller, selector, message で構成されている。

caller は呼び出し元。ツールなら kCallerAITool, メニューなら kCallerAIMenu といった名前で、言わばやりたい機能別の担当者である。

selector は呼び出し理由で、「ユーザーがクリックした」「ドラッグした」といったことである。

message は、担当者別に「やりたいこと」に役立ちそうな情報をセットにしてくれたもので、例えばマウスポインタの位置や、修飾キーの状態が含まれる。

Plugin には、呼び出しを受け取ると callerselector によって決まった名前の関数(例えばドラッグなら ToolMouseDrag )を実行する機能がある。 MyTool で同じ名前の関数を作っておくと(オーバーライド)、呼び出しに応じて実際の処理は MyTool が行うことになる。

プラグインの作成、少なくとも骨組みを作る部分は、この「同じ名前の関数」の中身を書く作業になると思う。 「やりたいこと...をイラレに教えておく」という部分も、Plugin の StartupPlugin という関数をオーバーライドして行う。

Plugin を定義するファイルは samplecode/common フォルダ以下にあり、サンプルコードはこのフォルダを相対パスで参照している。 SDK に付属するテンプレート(プロジェクトの雛形)も同様で、このためプロジェクトのフォルダは samplecode フォルダ直下に置いておく必要がある。

Suite

イラレの様々な機能を実行するために SDK では道具箱的な、関連する関数のセットが用意されており、これを Suite という。

Suite には機能別に数多くの種類がある。MyTool はその中から必要なものを取り込んで使用する。

取り込む処理は Plugin が行ってくれるので、MyTool は取り込みたいものの一覧を作っておけばいい。 サンプルコードの ~Suites.cpp にある gImportSuites がその一覧である。 何やら呪文のように同じような文言が並んでいるが、とりあえずこれはこういうものだと考えておけばいいと思う。~Version などの部分を変えるとプラグインの互換性を保全したりできる場合もあるらしい。

PIPL

Ai 2020 SDK ではビルド時に生成される PIPL(plug-in property list)について、SDK添付の python スクリプトでの生成を推奨している。

このため開発環境にpython (2.7) がなければ導入しておくことが必要。設定方法は getting-started-guide.pdf の p.32 にある。

Template

mac (Ai 2024 SDK)

Ai SDK付属の Xcode プロジェクトのテンプレートを使うには、 samplecode/template/Mac で端末を開き、

$ chmod u+x create_project.sh
$ ./create_project.sh HelloWorld

これで samplecode/HelloWorld フォルダが生成される。

HelloWorld.xcodeproj を開き、ビルドの前に Build Phases の3番目の Run Script にあるコマンドから、 ', {"entry_point" : "PluginMain"}' を削除する。 これがあるとプラグインの初期化が二重に行われるようで、 メニューに追加した項目がダブって表示されたりする。 必要なケースもあるんだろうか。

デバッグする際には、Xcode メニューの Product>Scheme>Edit Scheme... で開いたウィンドウで、Run>Executable にイラレ実行ファイルを設定する。 また、イラレの環境設定で追加プラグインフォルダとして、samplecode/output/mac/debug フォルダを設定しておく(ビルド後に生成される)。

Suite の遅延読み込み

Suite の中には、SartupPlugin で読み込むとエラーになるものがある。 デバッグ時、「プラグインの読み込みエラー」のダイアログも出ずにイラレが落ちる場合は、今のところまずこれを疑っている。

以下は gImportSuites とは別に gPostStartupSuites として、~Suite.cpp に設定する。

  • AICSXSExtensionSuite
  • AIArtConverterSuite

他にもありそうな気がする。あと他の suite との組み合わせによるのかなどは未検証。

gPostStartupSuites を acquire, release する処理は自分で用意しないといけない。 サンプルコードを gPostStartupSuites で検索すると処理例が見つけられる。

サンプルの SnippetRunnerSuites.cpp にも gPost~ の設定があるが、 これは必ずしも gPost~ に設定する必要がないものも含まれている。

ai::UnicodeString の文字コード指定

例えば AIUserSuite の MessageAlert の引数は ai::UnicodeString だが、mac ではエンコーディングを指定しないと文字化けする。

エンコーディングmac では kAIUTF8CharacterEncoding、win では kAIPlatformCharacterEncoding。 kAIPlatform... は既定値なので win では通常は指定が不要。

自分は以下のように環境ごとの値を設定している。

#ifdef MAC_ENV
const static AICharacterEncoding MY_MSG_ENC = kAIUTF8CharacterEncoding;
#else
const static AICharacterEncoding MY_MSG_ENC = kAIPlatformCharacterEncoding; 
#endif
// ...
    sAIUser->MessageAlert(ai::UnicodeString("ハローワールド", MY_MSG_ENC));

ただし win でソースコードUTF-8 にしている場合は kAIUTF8CharacterEncoding を指定する必要がある。

win でソースコードエンコーディングUTF-8 の場合のビルド設定は後述。 (#UTF-8 のソースコードをビルドする)

ツールアイコンの色を自動調整させる

ツールアイコンを SVG にする場合、SVGファイル中で style のクラス名を fill にすると、イラレの UI 背景色に合わせて色を変えてくれる。実例は samplecode 参照。

ツールカーソルのホットスポット設定

SVG (PNG) カーソルのホットスポットXML ファイルで設定できる。 設定しない場合は左上になる。

設定用の XML は Ai 2017 SDK のサンプル Annotator にある。 XML の中に size='32' とあるのはカーソル画像のサイズではなく固定値。 ホットスポットは 32x32 の中での x,y の位置を指定する。

SVG (PNG) と XML の ID は同じにする。

Xcode の Build Phases > Run Script での設定方法も上記サンプル参照。

例外処理

SDKの関数がエラーを返したとき例外を発生させたい場合は、AIErrorThrower クラスが利用できる。使用例はヘッダファイルにもあるが以下のような感じで、関数の実行ごとにエラー処理を書かなくてよいので楽。

#include "AIErrorHandler.h"

AIErr myFunction(){
    AIErrorThrower error = kNoErr;
    error = sAIDocument->RedrawDocument();
    error = kOutOfMemoryErr;  // エラー発生
    error = sAIDocument->Copy();  // 到達しない
    return error;
}

SDK付属のサンプルコードでは aisdk::check_ai_error を使用しているものもある。エラーが返ってきたとき、必ずしも例外を発生させたくない場合などはこちらを使う方法もある。使用するには SDKErrors.cpp をプロジェクトに加えたうえで SDKErrors.h を include する。

メソッド実行のたびにこれを書くとコードが読みにくくなるので、自分は以下のようにマクロにしている。この記事の他の項目でもコード例に CHKERR を用いている。

#include "SDKErrors.h"

#ifndef CHKERR
#define CHKERR aisdk::check_ai_error(error)
#endif

(Ai 2022 SDK) LiveEffect のサブメニューが表示されない

Ai 2022 SDK の AILiveEffectSuite::AddLiveEffectMenuItem では、引数 AddLiveEffectMenuData 構造体に対してメンバ options を設定しないと Ai 2022 のメニューに表示されない。有効な設定値はリファレンス参照。 Ai 2021 SDK でも同メンバ自体はあるが使われていなかった。(リファレンスには Not used の記載がある。)

GPUパフォーマンスがONだとデバッグ時にエラーになる

(2022.05.08 - MacBook Air M1, Ai 2022, Ai 2022 SDK, xcode 13.3.1, macOS Monterey 12.3.1) イラレの設定でGPUパフォーマンスをONにしている場合、プラグインデバッグ中に書類を開いた時点でエラーが発生して処理が停止する。(上記環境以外での挙動は不明。) xcodeのコンソールにはMTLDebugRenderCommandEncoder textureBarrierのassertionエラーとして表示される。 デバッグモード以外での当該プラグインの使用においては支障はないと思われる。 Templateから作成した単純なプラグインでも発生する。 今のところ回避方法は、デバッグ時にはGPUパフォーマンスをOFFにすること。ただしこの場合、GPUパフォーマンスがONの場合の動作検証はxcodeではできないことになる。

(Ai 2024 SDK, Mac) Undefined symbol: _OBJC_CLASS_$_GCContoroller

Ai 2024 SDK で以前のプロジェクトをビルドしようとしたら「Undefined symbol: _OBJC_CLASS_$_GCContoroller」というエラーが出た。Build Phases の Link Binary With Libraries に GameController.framework を追加することで解消された。

(win, Visual Studio 2017) UTF-8ソースコードをビルドする

諸般の事情で Visual StudioソースコードエンコーディングUTF-8 にした場合、ビルドのためにはプロジェクトのプロパティ画面で以下の設定が必要になる。

  • 全般 > 文字セット で、Unicode文字セットを使用する を設定。
  • C/C++コマンドライン > 追加のオプション に、/source-charset:utf-8 /execution-charset:utf-8 を追加する。

ImGuiによる設定用ダイアログの作成

SDK付属のサンプルコードにある「~UI」というフォルダは、「~」のフォルダにあるプラグイン用の設定ダイアログで、HTML拡張機能(エクステンション)で作られている。これは現状、プラグイン用にダイアログを自作する際の公式の解決策になる。

以前の、SDKにダイアログ機能が統合されていた頃(ADM)と比べて、HTMLとJavaScriptがベースなのでとっつきやすいのだが、新たに発生した問題もいろいろとある。

問題としては、まずモーダルダイアログ(ダイアログを閉じるまでメイン処理を待機させる)が作れないこと。 また、プラグイン本体(~.aip)とは別にインストールするので管理が面倒なこと。

このへんを解決したい場合は、C++で使えるUI用ライブラリを物色することになる。 私は現在、ImGui というライブラリを使っている。 これは特にAdobe向けということではない汎用的なもので、ゲーム関連のデバッグ画面によく使われているようだ。

ImGuiのよいところは、

  • サイズが小さい
  • さまざまなOSやバックエンド(DirectX, OpenGL, Metal, etc.)で利用でき、UIデザイン部分のコードはほぼ共通にできる。
  • UIデザイン部分のコードの書き方が直感的でわかりやすい。
  • フリー(MITライセンス)

一方でイラレプラグイン用としての懸案は、

  • macでは Objective-C++ を使う必要がある(研究中)
  • windowsでのモーダルダイアログの実現は力技感がある(研究中)

使い方については、私もまだよくわかっていない部分が多い。 以下の私のgithubリポジトリで使っているので、とりあえずこちらを見て頂くことにしたい。

... つづく


以下は別の日の記事に分岐しました。

オブジェクト操作編

https://shspage.hatenablog.com/entry/2024/02/10/125001

  • 簡単な図形を描く
  • 任意のパスを描く (※ ここから下の記事は有料です)
  • 選択範囲の取得
  • ロックする/不可視にする
  • GetFirstArtOfLayer はレイヤー自身を返す
  • オブジェクトを移動・回転する
  • GetArtBounds は線幅を含む
  • HitTest/HitTestExの検出範囲
  • パスの単純化
  • 座標の計算を楽にする
  • ...

リリース・配布編

https://shspage.hatenablog.com/entry/2024/02/12/040929
(無料記事)