TAWAMIラボ

2023/10/31 Illustrator Script

textRange.characterOffsetのヤバい仕様

こんなふうにIllustrator上で5文字のテキストが(テキストツールではなく選択ツールで)選択されているとします。

この状態で、「いうえ」(2~4文字目)だけ文字サイズを変えるスクリプトはどのように書けるでしょうか。


1つの方法はこう。charactersを使って1文字ずつ処理するという手です。

var tr1=app.selection[0].textRange; tr1.characters[1].size=20; tr1.characters[2].size=20; tr1.characters[3].size=20;

3文字くらいならこれでもいいんですが、文字数増えるとさすがに重くなるでしょうし、別の方法を考えます。


上の例で取得した app.selection[0].textRange はテキスト全体(1~5文字目)を指すTextRangeオブジェクトです。
ここから、2~4文字目を指すのTextRangeオブジェクトが取得できれば、いっぺんにサイズ変更ができるはず。

こういうときInDesignであればcharacters.itemByRangeで範囲を指定して取得できるわけですが、Illustratorにはそういうメソッドは用意されていません。

メソッドがないかわりに、IllustratorではTextRangeオブジェクトのcharacterOffset(何文字目からスタートするか)と、length(何文字分か)が書き換え可能になっています。
まずはテキスト全体のTextRangeオブジェクトのcharacterOffsetとlengthを取得してみましょう。

var tr1=app.selection[0].textRange; var s="characterOffset : "+tr1.characterOffset; s+="\n"+"length : "+tr1.length alert(s);

なるほど、1~5文字目の場合はcharacterOffsetが1、lengthが5になっていますね。
それなら2~4文字目はcharacterOffsetを2、lengthを3に変えればよさそうです。
やってみましょう。

var tr1=app.selection[0].textRange; tr1.length=3; tr1.characterOffset=2; tr1.size=20;

「うえお」(3~5文字目)が大きくなってしまいました!

なんでか分からないけど1つずれてるのでcharacterOffsetを1つ減らしてみましょうか。
ついでに、改めてTextRangeオブジェクトのcharacterOffsetを取得してみます。

var tr1=app.selection[0].textRange; tr1.length=3; tr1.characterOffset=1; tr1.size=20; alert("characterOffset : "+tr1.characterOffset);

無事「いうえ」を大きくすることができましたが…
1を代入したはずのcharacterOffsetに、2が入ってるーーー!????


えー、そんなわけで、
IllustratorスクリプトのcharacterOffsetは「1を代入すると2が入る」というトンデモ仕様なのです。

言い換えれば、代入するときと取得するときの数え方が、1ほどずれているということです。
図にするとこう。(矢印が文字ではなく文字と文字の間をさしているのは、length=0のTextRangeオブジェクトが挿入点を指すから)

textRangeの範囲を1つ後ろにずらすときは、
「textRange.characterOffset++」としてはダメで、
「textRange.characterOffset=textRange.characterOffset」もしくは
「textRange.characterOffset+=0」と書かないといけないのです。
面白いですね。


もう一つ注意点

上記の「1~5文字目のtextRangeオブジェクトから、2~4文字目のTextRangeオブジェクトを作る」スクリプトですが、「tr1.length=3;」と「tr1.characterOffset=1;」の順序を変えるとエラーになります。
理由は先にcharacterOffsetを変えると「2文字目からスタートして、長さが5文字の範囲」を指すことになり、実際に存在するテキストからはみ出してしまうからです。

逆に「2から4文字目のtextRangeオブジェクトから、1~5文字目のTextRangeオブジェクトを作る」場合は先にcharacterOffsetを変えないとエラーになります。

lengthやcharacterOffsetを書き換えるときは、常にこういうはみ出しに気をつけておく必要があります。
迷ったときは「とりあえずlengthを0にしてからcharacterOffsetを動かし、適切なlengthに戻す」という手を使ってもいいかもしれません。

オワリ


コメントを残す

メールアドレスが公開されることはありません。