DTPab

DTPにまつわるあれこれ

1if-1for(2):フレームを線幅分小さくする

f:id:uske_S:20180721002323p:plain

前回の記事で合成フォントの削除について書くとか書きましたが、諸事情により、選択したオブジェクトを線幅分小さくするスクリプトになりました。楽しみにされていた方(いるのか?)、申し訳ありません。
なぜかって?

急に欲しくなったからです!!

さて、まずはどんな動作か見ていただきましょう。 f:id:uske_S:20180731221315g:plain

ご覧のとおり、大したものではないです^^;;
ただ、InDesignはオブジェクトにあとから線をつけると線幅の分オブジェクトが太ってしまうのがたまーに面倒で、版面ピッタリに作ったグラフィックフレームが線幅分出てしまったりというときに、後から調整することがしばしば。それを線幅分小さくして収めたいなと思って作ったスクリプトです。
例によって「半人前のスクリプト」なので、オブジェクトを選択してから実行してください。

var doc = app.activeDocument;
var sel = doc.selection;

for (var i=0; i<sel.length; i++) {
    if (sel[i].constructor.name !== "TextFrame") {
        var gb = sel[i].geometricBounds;
        var stw = sel[i].strokeWeight / 2;
        sel[i].geometricBounds = [
            gb[0]+stw,
            gb[1]+stw,
            gb[2]-stw,
            gb[3]-stw
        ];
    }
}

で、GIF画像とコードから見て分かるように、選択したオブジェクト群にテキストフレームがある場合は除外しています。これは地切りが変わったりが面倒だからです。もしテキストフレームも含めて線幅分小さくしたいという場合は、途中のif文を消してください。

頭から説明していくと、
Object.constructor.nameでそのオブジェクトのコンストラクターを調べています*1
これがTextFrame以外であれば、以降の処理を実行します。
Object.geometricBoundsはそのオブジェクトの線幅を含まない座標値です。InDesignでいえば見えているフレーム枠そのものの座標値。単位は(スクリプトでなにもしない限りは)ドキュメントの設定に従います。
続いてオブジェクトの線幅Object.strokeWeightを取得し、それを2で除算した値を変数stwに代入しています。
geometricBoundsには4つの要素を持った配列を指定します。面倒でも同時に4つ指定しないといけません。
順にオブジェクトの[天側のY座標, 左側のX座標, 地側のY座標, 右側のX座標]となります(下図)*2f:id:uske_S:20180731223443p:plain

X方向は座標原点より右が正、Y方向は下が正になります*3

というわけで、オブジェクトの新しい座標は以下のように計算します。

Y座標の天:元の座標[0] + 線幅の1/2(小さくする=下に移動したいので座標値に線幅の1/2を加算)
X座標の左:元の座標[1] + 線幅の1/2(小さくする=右に移動したいので座標値に線幅の1/2を加算)
Y座標の地:元の座標[2] - 線幅の1/2(小さくする=上に移動したいので座標値に線幅の1/2を減算)
X座標の右:元の座標[3] - 線幅の1/2(小さくする=左に移動したいので座標値に線幅の1/2を減算)

これで線幅分オブジェクトを小さくすることができます。
以上、選択したオブジェクトを線幅分小さくするスクリプトでした。

*1:コンストラクターについて詳細は他に譲ります。簡単にいうと、そのオブジェクトを作った=Constructした者(関数)のことです。これを調べると、そのオブジェクトが何者かわかります。

*2:InDesignの場合。Illustratorでは順序が違うので注意。

*3:バージョンによりますが古いバージョンは検証しませんのでこれ以上細かく言いません。