/** * @fileoverview 行送り記号の挿入 * @author Kenshi Muto <kmuto@debian.org> * @requires libCommon.jsx * @version 3 */ /* Copyright: 2008 Kenshi Muto ---------------------------------------------------------------------- ソフトウェア使用許諾同意書 本ソフトウェアの利用・変更・再配布にあたっては、下記の使用許諾同意書に 同意する必要があります。 1. 本使用許諾同意書における「ソフトウェア」とは、機械可読の資料 (ライブ ラリ、スクリプト、ソースファイル、データファイル)、実行形式、および 文書を意味します。 2. 本ソフトウェアの使用許諾同意書に同意する限りにおいて、使用者は 本ソフトウェアを自由に利用、変更することができます。 3. 本ソフトウェアに変更を加えない限りにおいて、使用者は本ソフトウェアを 自由にコピー、再配布することができます。 4. 本ソフトウェアは無保証です。作者およびそれに関連する組織、配布者は、 本ソフトウェアの使用に起因する一切の直接損害、間接損害、偶発的損害、 特別損害、懲戒的損害、派生的損害について何らの責任・保証も負いません。 5. 本ソフトウェアを変更した上で再配布するときには、下記の事項すべてに 従わなければなりません。 - 使用許諾同意書の内容に変更を加えてはなりません。技術上の理由で 文字エンコーディングの変換を行うことは許可しますが、その使用者が 特殊な技術的措置なしに可読な形でなければなりません。 - 技術上の理由でバイナリ化・難読化を行う場合も、変更箇所を含めた ソフトウェアを、その使用者が可読可能な形式の形で同一のメディアで 提供しなければなりません。本使用許諾同意書の2条および3条により、 使用者が可読形式の該当ソフトウェアを変更、コピー、再配布することを 妨げてはなりません。 - ソフトウェア構成物の所定の作者名の欄に、変更者のクレジット (個人名、企業名、所属、連絡先など)を「追加」しなければなりません。 6. 本ソフトウェアを変更した上で再配布するときには、変更理由および その内容を明記することが推奨されます。 7. 使用者がソフトウェアに適用可能な特許に対して特許侵害にかかわる何らか の行動を開始した時点で、この使用許諾同意書は自動的に終了し、以降 使用者はこの使用許諾書によって与えられた一切の権利を放棄するものと します。 著作権所有者 Copyright (C) 2008 Kenshi Muto. All rights reserved. 使用許諾同意書バージョン1.0 著作権所有者による書面での事前の許可がない限り、この使用許諾同意書 に変更を加えてはなりません。 ---------------------------------------------------------------------- */ #include "../libs/libCommon.jsx" /** * 指定のストーリーの各段落をチェックして文字単位で折り返す * @param {Story} story ストーリーブジェクト * @param {Float} offset 右オフセット値 * @param {String} postfix 送り文字 * @param {String[]} styles 対象スタイル配列 * @param {CharacterStyle} bstyle 送り文字の文字スタイル * @type nothing */ function lineBreakOfStory(story, offset, postfix, styles, bstyle) { var myDocument = story.parent; var backunit = toMmMode(myDocument); var backruler = myDocument.viewPreferences.rulerOrigin; myDocument.viewPreferences.rulerOrigin = RulerOrigin.PAGE_ORIGIN; for (var i = 0; i < story.paragraphs.length; i++) { var para = story.paragraphs[i]; if (para.lines.length < 2 || para.appliedParagraphStyle == null) continue; for (var i2 = 0; i2 < styles.length; i2++) { // スタイルが合致したら改行処理呼び出し try { if (para.appliedParagraphStyle.name == styles[i2]) lineBreak(para, 0, offset, postfix, bstyle); } catch (e) { alert(para.contents + " の行でオーバーフローがおそらく発生しました。テキストフレームを広げて再実行してください。"); // 単位状態の復帰 revertMmMode(myDocument, backunit); myDocument.viewPreferences.rulerOrigin = backruler; return; } } } // 単位状態の復帰 revertMmMode(myDocument, backunit); myDocument.viewPreferences.rulerOrigin = backruler; } /** * 指定の段落を、テキストフレームの幅-オフセット値で、単語単位ではなく文字単位で折り返す * @param {Paragraph} para 段落オブジェクト * @param {Integer} no 行位置 (0開始) * @param {Float} offset 右オフセット値 * @param {String} postfix 送り文字 * @param {CharacterStyle} bstyle 送り文字の文字スタイル * @type Boolean * @return 常にtrue */ function lineBreak(para, no, offset, postfix, bstyle) { if (para.lines.length <= no + 1) return true; // もう行がなければ終了 var line = para.lines[no]; if (line.contents.match(postfix) != null) { // すでに改行文字挿入済み if (para.lines.length > no + 1) lineBreak(para, no + 1, offset, postfix, bstyle); // 続く行を処理 return true; } var tf = line.parentTextFrames[0]; if (tf == null || tf == undefined) throw line.contents; var boxWidth = tf.geometricBounds[3] - tf.geometricBounds[1] - offset; var lineArray = getLastX(line); var remain = lineArray[1] - lineArray[0] - boxWidth; if (remain > 0) { // 長すぎてオフセットよりもあふれている行は内容を送る for (var i = lineArray[2] - 1; i > 0; i--) { remain -= lineArray[1] - line.characters[i].horizontalOffset; if (remain <= 0) { line.characters[i].insertionPoints[-1].contents = postfix + "\r"; if (bstyle != null) { for (var i2 = 1; i2 <= postfix.length; i2++) { line.characters[i + i2].appliedCharacterStyle = bstyle; } } break; } } } else if (remain < 0) { // 短かすぎる場合は次の行から拾う if (para.lines.length <= no + 1) return true; // 次の行はない var line2 = para.lines[no + 1]; tf = line2.parentTextFrames[0]; if (tf == null || tf == undefined) throw line2.contents; var line2Array = getLastX(line2); for (var i = 0; i <= line2Array[2]; i++) { var x = line2.characters[i].horizontalOffset - line2Array[0]; if (remain + x >= 0 && i > 0) { line2.characters[i - 1].insertionPoints[-1].contents = postfix + "\r"; if (bstyle != null) { for (var i2 = 1; i2 <= postfix.length; i2++) { line2.characters[i - 1 + i2].appliedCharacterStyle = bstyle; } } break; } else if (remain + x == 0) { line2.characters[i].insertionPoints[-1].contents = postfix + "\r"; if (bstyle != null) { for (var i2 = 1; i2 <= postfix.length; i2++) { line2.characters[i + i2].appliedCharacterStyle = bstyle; } } break; } } } else { // 改行記号を挿入 line.characters[lineArray[2]].insertionPoints[-1].contents = postfix + "\r"; if (bstyle != null) { for (var i2 = 1; i2 <= postfix.length; i2++) { line.characters[lineArray[2] + i2].appliedCharacterStyle = bstyle; } } } if (para.lines.length > no + 1) lineBreak(para, no + 1, offset, postfix, bstyle); // 続く行を処理 return true; } /** * 行末文字の水平座標(左)を返す * @param {Line} line 行オブジェクト * @type Float * @return 行末文字の水平座標 */ function getLastX(line) { /* 行オブジェクトの文字配列の末尾には、スタイルなどの情報も入っており、 単純に水平座標を取ろうとしても行の先頭と同じ座標になってしまう。 これを防ぐため、末尾から見て最大のものを取る) */ var lastX = line.characters[0].horizontalOffset; for (var i = line.length - 1; i > 0; i--) { if (line.characters[i].horizontalOffset > lastX) { lastX = line.characters[i].horizontalOffset; break; } } return [line.characters[0].horizontalOffset, lastX, i]; }