1

PDFBoxを使用してPDFを作成します。サインも見えました。私はそのようなテキストを書きます:

...
builderSting.append("Tm\n");
builderSting.append(" /F1 " + fontSize + "\n");
builderSting.append("Tf\n");
builderSting.append("(hello world)");
builderSting.append("Tj\n");
builderSting.append("ET");
...
PDStream stream= ...;
stream.createOutputStream().write(builder.toString().getBytes("ISO-8859-1"));

すべてがうまく機能します。しかし、builderString に Unicode 文字を書き込むと、テキストの代わりに「???」が表示されます。

それはサンプルPDFです:ここにリンク

質問 1) PDF 構造を見ると、テキストの代わりに疑問符が表示されます。はい。ユニコード文字で書く方法がわかりませんか?

9 0 obj
<<
/Type /XObject
/Subtype /Form
/BBox [100 50 0 0]
/Matrix [1 0 0 1 0 0]
/Resources <<
/Font 11 0 R
/XObject <<
/img0 12 0 R
>>
/ProcSet [/PDF /Text /ImageB /ImageC /ImageI]
>>
/FormType 1
/Length 13 0 R
>>
stream
q 93.70079 0 0 50 0 0 cm /img0 Do Q
BT
1 0 0 1 93.70079 25 Tm
 /F1 2
Tf
(????)Tj
ET
endstream
endobj

Encoding WinAsciEncoding でフォントを作成しました。pdfbox で別のエンコーディングを使用できますか?

PDFont font = PDTrueTypeFont.loadTTF(template, new File("//fontName.ttf"));
    font.setFontEncoding(new WinAnsiEncoding());

質問 2) PDF にフォントを埋め込みました。ただし、テキストはこのフォントで書かれていません(目に見える記号 Rectangle で)。なんで?

質問 3) フォントを削除しても、テキストが残っていました (テキストが英語の場合)。デフォルトのフォントは何ですか? /F1 - 最初のフォントはどれ?

質問 4)目に見える署名のテキストの幅を計算する方法は? 何か案は?

4

2 に答える 2

1

質問 1) PDF 構造を見ると、テキストの代わりに疑問符が表示されます。はい。ユニコード文字で書く方法がわかりませんか?

Unicode 文字とは、Unicode には存在するが Latin-1 などには存在しない文字を意味すると思います。(たとえば、文字 'a' にも Unicode 表現があるためですが、ほとんどの場合、問題は発生しません。)

getBytes("ISO-8859-1")あなたはあなたの結果を呼びますStringBuilder。Unicode文字 が ISO 8859-1 にない可能性が最も高いです。したがって、String.getBytesそれぞれの場所に疑問符の ASCII コードを返します。

質問が単にJavaで Unicode 文字を出力ストリームに書き込む方法である場合、答えは簡単です: すべての文字を含むエンコーディング (たとえば、プログラムのすべてのコンシューマがサポートする UTF-8) を選択し、それを要求します。エンコーディング。String.getBytes

ただし、これらの情報を PDF フォームの xobject ストリームとしてシリアル化する場合は、状況が異なります。この文脈では、あなたのアプローチ全体は、非常に疑わしいものから完全に間違ったものへのルートに沿ったどこかにあります。

PDF では、各フォントに独自のエンコーディングが付随する場合があります。これは、 /WinAnsiEncodingなどの一般的なエンコーディングに似ている場合や、完全にカスタム化されている場合があります。さらに、これらのエンコーディングは、多くの場合、1 文字あたり 1 バイトに制限されていますが、複合フォントの場合、マルチバイト エンコーディングにすることもできます。

必然的に、ストリーム要素のすべての要素を同じエンコーディングでエンコードする必要はありません。たとえば、演算子名TmTf、およびTjは、ASCII コードを使用してエンコードされますが、表示される文字列の文字は、それぞれのフォントのエンコードを使用してエンコードする必要があります (その後、鋭角括弧 < >)。

したがって、ストリームを文字列として作成し、それらを単一のエンコーディングでバイトに変換することは、使用されるすべてのフォントが (実際に使用されるコード ポイントに対して) 同じエンコーディングを使用し、さらに演算子を正しく表すために ASCII 風である必要がある場合にのみ機能します。

基本的に、ストリームをバイト バッファに直接構築し、挿入された要素ごとに適切なエンコーディングを使用する必要があります。したがって、表示する文字の場合、現在選択されているフォントで使用されているエンコーディングに注意する必要があります。

正しく行いたい場合は、まず PDF 仕様ISO 32000-1、特に一般的な構文と第 9 章テキストに関するセクションを調べてください。

質問 2) PDF にフォントを埋め込みました。ただし、テキストはこのフォントで書かれていません(目に見える署名 Rectangle 内)。なんで?

問題のストリーム xobject のリソースには、名前/F0に関連付けられた埋め込みフォントが 1 つだけあります。ただし、ストリームには/F1 2 Tfがあります。つまり、サイズ 2のフォント/F1を選択します。

質問 3)フォントを削除しても、テキストが残っていました (テキストが英語の場合)。デフォルトのフォントは何ですか?

仕様によると、セクション 9.3.1、

fontは、現在のリソース ディクショナリのFontサブディクショナリにあるフォント リソースの名前になります[...] フォントまたはサイズの初期値はありません

ただし、ほとんどの場合、PDF ビューアは、古いドキュメントや壊れたドキュメントとの互換性のために、デフォルトのフォントを使用しています。

質問 4)目に見える署名のテキストの幅を計算する方法は? 何か案は?

幅は明らかに、使用するフォントのメトリック (この場合はグリフの幅) と、設定したグラフィックスの状態 (フォント サイズ、文字間隔、単語間隔、現在の変換マトリックス、テキスト変換マトリックスなど) に依存します。

あなたの場合、グラフィックス状態ではほとんど何もしないので、そこから選択されたフォントサイズだけが重要です。したがって、より興味深い部分は、フォント メトリックからの文字幅です。標準の 14 フォントを使用している限り、指標はここにあります。他のカスタム フォントを使い始めるとすぐに、それらをフォント定義ファイルから自分で読み取る必要があります。

于 2013-07-17T13:22:33.860 に答える