質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.46%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

font

近年は、コンピュータ上、紙面上で利用できる書体データのことをfontといいます。数える時の単位は「書体」で、データとしてのフォントは、デジタルフォントと呼ばれる場合があります。 HTML/CSSでは要素を指定し、フォント情報を調整することができます。

Q&A

解決済

1回答

4608閲覧

指定のフォントファイルで表現できるかどうかか確認したい

norita

総合スコア2

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

font

近年は、コンピュータ上、紙面上で利用できる書体データのことをfontといいます。数える時の単位は「書体」で、データとしてのフォントは、デジタルフォントと呼ばれる場合があります。 HTML/CSSでは要素を指定し、フォント情報を調整することができます。

0グッド

0クリップ

投稿2021/08/05 13:06

編集2021/08/06 05:01

Javaで、指定フォントで表現できるかどうかチェックする処理を作りたいと思っています。

java.awt.Font.canDisplayUpTo(String str)

上記関数を利用してできそうだと思っていたんですが、落とし穴がありました。

タブ(\t、U+0009)をチェックしようとした際に、チェックはすり抜けてしまったのですが、
フォントとしては対応していないという事象が発生しました。

タブの場合、文字列としては、「\t」で処理されますが、実際には、空白があく表現になります。
canDisplayUpToを使ったチェック時には、「\t」としてチェックされるので、そのまますり抜けますが、
実際にフォントで表現する際、空白表現が正しくできないという状態になっています。

「\t」とかだけであれば、ピンポイントでチェック条件を追加してしまえばいいのんですが、ほかにも同様の
文字があった場合に、都度追加をしなくてはいけないのは少し手間に感じます。

実際の表現ベースでフォントとして表現できる・できないをチェックする効率のいい手段はありますでしょうか?
代替の手順としては、何かしらの画像に実際に出力して、出力できる・できないを確認する方法も考えていますが、
チェック処理が増えると、画像変換が無駄処理に思えてきて、ほかのいい方法を探しています。

宜しくお願いします。


すみません。追記いたします。

チェックはすり抜けてしまった

該当関数の戻り値としては、

戻り値: このFontが表示できないstr内の最初の文字を指すstrへのオフセット、またはこのFontがstr内のすべての文字を表示できる場合は-1。

となっているため、期待値としては、問題の文字のオフセットが戻ることですが、タブの場合は、「-1」が戻ってきている状態となります。

フォントとしては対応していないという事象

というのは、「不可」だったということになります。
「不可」なので、当然、実際にフォントでの表現ができない状態となります。


今回の「タブ」のように、実際にフォントで表現できない文字が含まれているかどうか、正確にチェックしたいです。
表現できる・できないを、実際に変換してからエラーとして処理するのではなく、事前にチェックをして、表現できないのであれば、変換処理を行わないような処理にしたいです。


再度追記致します。

「フォントで表現できない」という部分ですが、最終的には、PDPageContentStreamを利用してPDF出力しようとしています。

java

1PDFont font = PDType0Font.load(doc, new File("TTFファイルパス")); 2 3PDPage page = new PDPage(rectangle); 4PDDocument doc = new PDDocument(); 5doc.addPage(page); 6 7PDPageContentStream contents = new PDPageContentStream(doc, page) 8contents.beginText(); 9contents.setFont(font, 12); 10contents.showText("文字列");

この処理をした際、指定したフォントファイル(TTFファイル)で対応できないと、例外エラーが発生してしまうため、そのような文字列ではないことの確認を事前にやりたいという流れになります。

java.lang.IllegalArgumentException: No glyph for U+0009 in font IPAPGothic at org.apache.pdfbox.pdmodel.font.PDCIDFontType2.encode(PDCIDFontType2.java:363) at org.apache.pdfbox.pdmodel.font.PDType0Font.encode(PDType0Font.java:398) at org.apache.pdfbox.pdmodel.font.PDFont.encode(PDFont.java:324) at org.apache.pdfbox.pdmodel.PDPageContentStream.showTextInternal(PDPageContentStream.java:509) at org.apache.pdfbox.pdmodel.PDPageContentStream.showText(PDPageContentStream.java:471)

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

jimbe

2021/08/05 13:52

> チェックはすり抜けてしまった というのは可だったのか不可だったのか、どちらでしょう。 > フォントとしては対応していないという事象 ということは、不可だったのでしょうか。 しかし > 実際にフォントで表現する際、空白表現が正しくできないという状態 というのは、「不可」だったら当然かと思いますが…。 タブを「どうしたい」のに「どうなってしまった」のか、もう少しはっきりお書きくださいませんか。
ikadzuchi

2021/08/05 14:47

タブが「フォントで表現できない」とはどういう意味ですか? タブはフォントで表現するものではないため、正しく表示できないのであればフォント側ではなく文字表示エンジン側の問題ではないでしょうか。 フォントによってタブが表現できるものと表現できないものがあるのでしょうか。その場合画像を貼ってください。 > canDisplayUpToを使ったチェック時には、「\t」としてチェックされるので たぶんあなたの勘違いだと思うのですが、なぜそう判断したのですか?
jimbe

2021/08/05 16:00

> タブの場合は、「-1」が戻ってきている状態 canDisplayUpTo("\t") が -1 だったということですね。つまり「表示出来る」と返されたと。 でも実際にそのフォントで表示すると TAB のようには表示されなかった(スペースと同じだったとか幅0だったとか)ということでしょうか。
guest

回答1

0

ベストアンサー

「canDisplayUpTo("\t") は -1 が返るのに実際に表示してみると"文字"にはならない。こういったコードを(実際に描画する前に)予め弾くことはできるか」というご質問と解釈します。

恐らく 0x0~0x1F のコードは初めから分けて考えるのではないでしょうか。
つまり文字列を表示する場合の想定として

各文字において
・文字が 0x0~0x1f だったらコントロールコードとしての処理(カーソル移動、改行やタブや・・・)をして次の文字へ。
・canDisplay(文字) が表示可能だったらグリフを表示して次の文字へ。
・それ以外ならエラーを出すか無視するか特別な文字(ソ〇トバンクモバイルの"="マーク?)を表示して次の文字へ。

という流れということです。(あくまで想像ですが。)

そして、この一連の処理の前に canDisplayUpTo("タブ等を含む文字列") で上の”それ以外"の処理となるコードがあるかを調べられるということでは無いかと思います。

投稿2021/08/05 16:15

編集2021/08/05 17:51
jimbe

総合スコア12756

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

norita

2021/08/06 05:05

ありがとうございます。 コントロールコードを正しく処理できていないのがいけないのだと理解致しました。。 チェックの理処理として、canDisplayUpToとコントロールコードの有無を合わせて対応するのが正しいと思うので、試してみるようにします。
jimbe

2021/08/06 13:44 編集

> PDPageContentStreamを利用してPDF出力 どのような感じになるのかと検索して以下の記事を見ましたところ、 ( https://blog1.mammb.com/entry/2020/03/30/090000 ) 記事の中ほどに 「なお、.replaceAll("\p{C}", "") は ASCII 制御文字を空文字置換しています。改行コードなどが含まれていた場合に対象フォントが存在せずにエラーとなるため、行の分割後にこれらを削除しています。」 という文がありました。 改行('\n')で分割した後にこのような処理をされていますので(この記事だけを見て"一般的な方法"とは言えませんが)悪くない方法なのではないかと思います。
norita

2021/08/10 01:32

ありがとうございます。 登録時にチェックして弾く方法と、出力時に変換してエラーを回避する方法がありそうなので、内容によって処理に合った方法で対応したいと思います。 分かりにくい質問となり申し訳ございませんが、回答くださりありがとうございます。
maisumakun

2021/08/10 01:40

> それ以外ならエラーを出すか無視するか特別な文字(ソ〇トバンクモバイルの"="マーク?)を表示して Unicodeだと置換文字(U+FFFD、�)もありますね。
jimbe

2021/08/10 02:11

> Unicodeだと置換文字 確かに見たことあります。すっかり忘れてました、ありがとうございます。 流石にソ〇トバンクマークは古かったですかね ^^;
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.46%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問