問題タブ [fontmetrics]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
java - FontMetrics StackOverflowError の取得
次のコードを実行します。
このエラーが発生します:
スレッド「メイン」での例外 java.lang.StackOverflowError
java.awt.FontMetrics.getWidths(FontMetrics.java:430)で
java.awt.FontMetrics.charWidth(FontMetrics.java:333)
java.awt.FontMetrics.getWidths(FontMetrics.java:430)で
java.awt.FontMetrics.charWidth(FontMetrics.java:333)
java.awt.FontMetrics.getWidths(FontMetrics.java:430)で
等々....
なんで?
android - FontMetrics の先頭は常にゼロを返すようですか?
私はこのコードを試しました:
しかし、リードは常に0
.I read docs in about のようleading
です:
テキストの行間に追加する推奨の追加スペース。
しかし、私はそれが何を意味するのか分かりません。それが何を意味するのかを理解するのを手伝ってくれる人はいますか? どの画像もより効果的です。
android - TextView の行間を取得するには?
TextView
の行間を取得する方法はありますAndroid
か? fontMetrics
私は のを見つけようとし、次Paint
のTextView
ようにします:
しかし、のフォントサイズを変更するまで、結果は同じようですTextView
。では、どうすれば a の行間を取得できTextView
ますか?
java - Java で壊れたフォント メトリックの考えられる原因/回避策のリスト? それとも LaTeX に切り替える必要がありますか?
私は、かなり単純でわかりやすいと思ったアプリケーションに取り組んでいます。BufferedImage
文字列を特定のフォント (システムにインストールされていないファイルから) にレンダリングするだけです。私はある程度の進歩を遂げていますが、数日間苦労した後、Java はフォント メトリックに関して非常に気まぐれなようです。明確な理由もなく、適切なフォント メトリックを提供したい場合もあれば、(フォントのサイズに関係なく) すべてゼロとすべて 240 の組み合わせを返したい場合もあります。
いくつかのケースでは、呼び出すだけf = f.deriveFont(myFloat)
でフォント メトリックが完全に失敗し、有効な数値がすべてゼロになるのに対し、呼び出しでf = f.deriveFont(Font.PLAIN, (int) myInt)
はメトリックが保持されるため、新しいフォント インスタンスが適切に機能することがわかりました。(はい、フロートであることはわかっていますが、何らかの理由で、フロートで呼び出すと、フォント メトリックが再び破られる場合がありました。)
TextAttributes
フォントとオブジェクトを組み合わせることでRenderingHints
、Graphics2D
ほとんどのフォントを機能させることができました...しかし、Java ( JSE /JDK 7 ) Windows 7のフォント ビューアーでは問題なく表示されます。
そのため、これらのフォントの 1 つを選択し、アプリケーションからすべてを取り除き、Main メソッドで可能なフォントの最も生のビューを取得しています。このコードのecho()
メソッドは、System.out.println()
. (また、このコードがずさんで申し訳ありません。この時点で新しい情報が得られる可能性のあるものは何でも入れています。)
このコードからの出力は次のようになります。
このフォントが入った .otf ファイルから正しいフォント メトリックを取得することは明らかに可能です。これは、Windows 7 フォント ビューアーと C で記述された別のアプリを使用して、ここで行おうとしているように PNG にレンダリングできるためです。なぜJavaがそれを好まないのか理解できません。
IOException
または をスローしていないFontFormatException
ため、ファイルを読み取り、表面上は有効なFont
オブジェクトを作成していることがわかります。- 上記のコードでは
GlyphVector
、int 配列を使用して作成しました。これは、GlyphCodes
1 からフォント内のグリフの数 (この場合は 33) までのインデックスが付けられているため 、Unicode CodePointsからそれらの文字が見つからない可能性があります。 - また
FontMetrics
、フォントが 20pts のサイズを報告していることをエコーで確認できるため、サイズ = 0 などに設定されているわけではありません。フォントに設定したサイズに関係なく、出力の 240 は変わりません。
Google の検索用語を考え出そうと数日間試みた後でも、この特定の問題についての言及を見つけることができません。本当に奇妙に思えます。フォント メトリクスがランダムに左右に分かれているように見える (実際にはランダムではないことは確かですが) と思われるかもしれませんが、特に私がテストしたすべてのフォントが常にゼロと 240 の組み合わせを報告します。後者の部分では、すべてが一貫して 240 を報告していますが、これは奇妙に、Google で簡単に調べられない問題に特化しているように思えます。
とにかく、Java で不適切なフォント メトリックを引き起こす可能性のある項目 (テキスト属性、グラフィック設定、JRE フラグ、OS 環境変数、フォント作成プログラム、フォント ファイル内のフラグなど) のリストを誰かが持っているかどうか疑問に思っています。それとも壊れたフォント メトリクスの回避策のリストでしょうか? それとも、Java ではフォントがひどいので、LaTeX を調べる必要がありますか? (正直なところ、私はこの時点で何も知りません。)
ありがとう!
Font
編集:まあ...これはちょっとイライラします...OpenJDKの「オープンソース」を掘り下げれば、これらのメトリックの問題を解決できる派生実装を作成できるのではないかと思いました...しかし、どうやらそれは必要なすべての内部を非公開、静的、および最終的にすることで、意図的に防止されます。参照:フォント、それらを拡張する方法... 実行時にコア クラスを置き換えることができません - 参照: Java クラスを置き換えますか? ... したがって、メトリクスをそのように修正したい場合の唯一の代替手段は、Java フォント アーキテクチャ全体を 、 などの完全なコピーで再作成しjava.awt.Font
、sun.font.Font2D
グリフをGraphics2D
オブジェクトに手動でGraphics.drawGlyphVector()
描画するGraphics.drawString()
ことです。Font
または派生物Font
Font が実装するインターフェイスを宣言する代わりに、Font
クラスを引数として使用したためです。Graphics.setFont()
...その2番目のスタックオーバーフローリファレンスの答えを誤解していない限り? 私はそれを誤解していますか?Font
クラスを変更されたバージョンに置き換えるカスタム クラス ローダーを作成できますか?
編集:最後の編集を投稿する前にもっと調査を行うべきだったかもしれませんが、この質問を読んで疑問に思っている人は、はい、変更されたバージョンのコア Java クラスを JVM 引数に置き換えることができます。http://media.techtarget.com/tss/static/articles/content/CovertJava/Sams-CovertJava-15.pdfを参照メトリクスはフォント ファイルから読み込まれます。それが見つかれば、壊れたメトリックを修正する修正バージョンでそのクラスを置き換えることができます。
graphics2d - 文字の実際の高さを取得する方法 (fontmetrics/graphics2d)
現在、キャラクターの実際の高さを取得する必要があります。getDecsent()、getAscent() などの関数を認識していますが、(そのコンテキストで) ホール フォントに関する値のみを取得できます。getStringBounds() を使った方法も試しましたが、同じ話です。
タイトルが示すように、一度に 1 文字だけの高さの値を取得する方法を探しています。
たとえば、「N」は「n」より高く、「I」は「i」より少しだけ高く、などです。
御時間ありがとうございます
java - Java: 文字列を整列するグラフィックス
現在、ローリング テキスト メソッドを作成しようとしています。このメソッドでは、String
. すぐに、左から右に描画を開始し、時間の経過とともに新しい行に移動するため、画面からはみ出さなくなります。私はFontMetrics
自分の目標を達成しようとするために使用しています。
RollingText.render(Graphics g, int x, int y)
メイン クラスの render メソッドから引数を my に渡します。render
メソッド内から、Graphics
フォントと色の設定を開始しFontMetrics
、すべての を取得し、FontMetrics
. 同様に、テキストを文字列に描画するために for ループに入ります。
drawString
現在、この時点ではすべて正常に動作しますが、次のように、メソッド内の各単語間のスペースが非常に誇張されているという問題が残っています。
この線:
私が現在抱えている唯一の問題は、x 位置の計算を行う正しい方法を見つけることです。現在、単語の長さに応じて大きく動的に配置されており、少なくとも正常に見えるようにする方法がわかりません。現在定義されている整数などとさまざまな組み合わせを試しました。発生する問題は、不正確な間隔から、不適切な配置やちらつき、テキストの重なりまで、どこにでもあります。
最後に、私の質問は、テキストが正しく見えるように x 座標を正しく配置するためにどのようなアルゴリズムを使用するかということです。
java - ラテン文字のみの Java フォントが、アジア文字をサポートしていないのに、なぜアジア文字をサポートしていると主張するのですか?
JFreeChart でグラフをレンダリングするときに、グラフのカテゴリ ラベルに日本語の文字が含まれていると、レイアウトの問題が発生することに気付きました。テキストは正しいグリフでレンダリングされますが、おそらくフォント メトリックが間違っていたため、テキストが間違った場所に配置されていました。
グラフは、もともとそのテキストにSource Sans Pro Regularフォントを使用するように構成されており、ラテン文字セットのみをサポートしています。明らかな解決策は、実際の日本語の .TTF フォントをバンドルして、JFreeChart に使用を依頼することです。出力テキストが正しいグリフを使用し、正しくレイアウトされているという点で、これはうまく機能します。
私の質問
最初のシナリオで、ラテン文字以外を実際にサポートしていないソース フォントを使用している場合、java.awt はどのようにして日本語の文字を正しくレンダリングしたのでしょうか? 問題があれば、JDK 1.7u45 を使用して OS X 10.9 でテストしています。
別の日本語フォントをバンドルせずに日本語の文字をレンダリングする方法はありますか? (これが私の最終目標です!) バンドル ソリューションは機能しますが、回避できるのであれば、アプリケーションに 6 MB の肥大化を追加したくありません。Java は、フォントがなくても (少なくとも私のローカル環境では) どうにかして日本語のグリフをレンダリングする方法を明確に知っています。これが以下の「frankenfont」の問題に関連しているかどうか疑問に思っています。
JRE が内部変換を実行した後、なぜ Source Sans Pro フォントは ( canDisplayUpTo()を介して) 呼び出し元に、日本語の文字を表示できないのに表示できると通知するのでしょうか? (下記参照。)
明確にするために編集:
これはサーバー アプリであり、レンダリングしているテキストはクライアントのブラウザーや PDF エクスポートに表示されます。グラフは常にサーバー上で PNG にラスタライズされます。
サーバーの OS や環境を制御することはできません。Java 標準のプラットフォーム フォントを使用するのは良いことですが、多くのプラットフォームではフォントの選択が貧弱であり、私のユース ケースでは受け入れられないため、独自のフォントをバンドルする必要があります (少なくともラテン フォントの場合)。日本語テキストにプラットフォーム フォントを使用してもかまいません。
アプリは、テキスト タイプの先験的な知識がなくても、日本語とラテン語のテキストを組み合わせて表示するように求められる可能性があります。グリフが正しくレンダリングされる限り、文字列に言語が混在している場合にどのフォントが使用されるかについて、私は曖昧です。
詳細
java.awt.Font#TextLayout はスマートであり、テキストをレイアウトしようとすると、最初に下層のフォントに提供された文字を実際にレンダリングできるかどうかを問い合わせることを理解しています。そうでない場合は、おそらくそれらの文字をレンダリングする方法を知っている別のフォントにスワップしますが、JRE クラスにかなり深くまでデバッグしたことに基づいて、ここでは発生していません。TextLayout#singleFont
常にフォントの null 以外の値を返し、fastInit()
コンストラクターの一部を処理します。
非常に興味深い点の 1 つは、Source Sans Pro フォントが、JRE がフォントで変換を実行した後、日本語の文字をレンダリングする方法を知っていることを呼び出し元に強制的に伝えることです。
例えば:
これの出力は次のとおりです。
上記の「魔法の操作」の 3 行は、私自身が行ったものではないことに注意してください。真のソース フォント オブジェクトを JFreeChart に渡しますが、グリフを描画するときに JRE によって変更されます。これは、上記の「魔法の操作」コードの 3 行が複製するものです。上記の操作は、次の一連の呼び出しで発生するものと機能的に同等です。
- org.jfree.text.TextUtilities#drawRotatedString
- sun.java2d.SunGraphics2D#drawString
- java.awt.font.TextLayout#(コンストラクタ)
- java.awt.font.TextLayout#singleFont
「魔法の」操作の最後の行で Font.getFont() を呼び出すと、Source Sans Pro フォントが返されますが、基になるフォントのfont2D
フィールドは元のフォントとは異なり、この単一のフォントは認識していると主張します。文字列全体をレンダリングする方法。なんで?Java は、基礎となるソース フォントで提供されるグリフのメトリックしか理解できないにもかかわらず、あらゆる種類のグリフをレンダリングする方法を知っているある種の「frankenfont」を私たちに返しているようです。
JFreeChart のレンダリング例を示すより完全な例は、JFreeChart の例の 1 つに基づいています: https://gist.github.com/sdudley/b710fd384e495e7f1439この例の出力を以下に示します。