Affinity 3のレイアウトペルソナでdvipdfmx由来のPDFをインポートするときの文字化け対策

はじめに 先日無償化が発表された Affinity 3。旧来のPublisher、Designer、Photoが統合され、ペルソナ を切り替えることで各機能を利用できる新しい体系に生まれ変わりました。 本記事では、その中の レイアウトペルソナ(DTP機能)に dvipdfmx で生成したPDFをインポートする際、日本語が文字化けする問題の原因と対策を考察します。 問題の発生条件 項目 内容 対象ソフトウェア Affinity 3(レイアウトペルソナ) バージョン 3.0.1.3808 インポートファイル dvipdfmx で日本語フォントを用いて生成されたPDF 発生現象 PDF内の日本語テキストが文字化けする 問題の状況 dvipdfmx で出力したPDFをAffinity 3のレイアウトペルソナにインポートすると、インポート前のページプレビューの段階から既に日本語テキストが文字化けしています。 さらに、Affinity 3が「見つからないフォント」として認識したものを、BIZ UDP明朝など別の日本語フォントに置き換えても、文字化けは解消されません。テキストの見た目のデザイン(フォントの持つ雰囲気)だけが変化し、文字の羅列は意味不明なままです。 なお、インポート時の読み込み対象を 「ページ」 または 「アートボード」 のいずれに設定しても、この現象は同様に発生します。 原因の切り分けと考察 切り分け まず、問題が dvipdfmx 側にあるのか、Affinity側にあるのかを切り分けます。 他のPDFビューアで確認する: 生成されたPDFをAdobe Acrobat Readerや一般的なウェブブラウザで開きます。 結果の判断: 他のビューアでも文字化けする場合: dvipdfmx の設定に問題がある可能性が高いです。 Acrobat等では正常だが、Affinity 3でのみ文字化けする場合: Affinity 3側のPDF解釈に起因する問題と考えられます。(今回のケースはこちらに該当します) 原因の考察:エンコーディングの問題か? フォントを正常なものに置き換えても文字化けが解消されないという現象は、単なる「フォントファイルが見つからない」という問題ではないことを強く示唆しています。 これは、PDF内部の 文字エンコーディング情報(どのバイトがどの文字に対応するかを定義する情報。専門的には CMap と呼ばれます)をAffinity 3が正しく解釈できていない可能性が高いです。 つまり、文字の「形」を収めたフォントデータはPDF内に存在していても、どのコードをどの「形」に割り当てるかの対応表が失われている、あるいはAffinity 3に無視されている状態と考えられます。そのため、dvipdfmx 側で単純にフォントの埋め込み方式を変えるだけでは解決しない可能性があり、根深い問題と言えます。 有効な対策 「テキストを曲線に変換」オプションが存在しない問題 回避策として一般的な「テキストを曲線(アウトライン)に変換」ですが、Affinity 3のPDFインポートダイアログには、そもそもこの選択肢自体が存在しません。 そのため、Affinity 3内で完結する手軽な解決策は現状なく、PDF生成側での調整、あるいは代替ツールでの対応が必須となります。 対策1: (非推奨) dvipdfmxでの設定見直しは極めて困難 原因がAffinity 3側のPDF解釈にある可能性が高い以上、dvipdfmx側での対応は非常に困難を極めます。 ...

11月 7, 2025 · 1 分 · 104 文字 · gorn

SciPyのF分布ppfが抱える数値精度問題

概要 scipy.stats.f.ppf(F分布のパーセント点関数)が、特定の条件下で不正確な結果を返す可能性があるという問題についての報告です。具体的には、確率が1に非常に近い値(裾の領域)と大きな自由度の組み合わせにおいて、ppf関数の結果と、累積分布関数(cdf)を最適化して得られる結果との間に大きな乖離が見られます。 この問題は2021年頃に発見されましたが、最近のバージョンでも同様の現象が確認されたため、改めて報告するものです。 なお、本件は、既に、https://github.com/scipy/scipy/issues/20835 で報告されており、恐らく、scipy 1,17で対策はマージされると思います。 ENH: special: boostify F distribution functions 問題の詳細 scipy.stats.f.ppf に欠陥がある可能性が疑われます。最適化関数と累積分布関数(cdf)の組み合わせで得られる結果が、ppf関数の戻り値と一致しません。 再現コード 以下のコードは、sps.f.ppf を直接呼び出した場合と、spo.brentq を使って sps.f.cdf から逆関数を求めた場合の結果を比較します。 import scipy.stats as sps import scipy.optimize as spo # ppf関数を直接呼び出す print(sps.f.ppf(0.99999995, 1, 50000, loc=0, scale=1)) # cdfと最適化関数brentqを使って逆関数を求める print(spo.brentq(lambda x: sps.f.cdf(x, 1, 50000) - 0.99999995, 1, 1e10)) コードの出力 3333.8385803475894 29.725915444860586 出力結果からわかるように、2つの計算結果は大きく異なっています。 エラーメッセージ この問題では、エラーメッセージは出力されません。コードは正常に終了しますが、得られる結果の信頼性に疑問があります。 原因の考察 このPythonコードと出力は、F分布のパーセント点関数(ppf)と、それを最適化関数(brentq)を使って求めるアプローチとの間の数値的な不安定性を示唆しています。 sps.f.ppf(0.99999995, 1, 50000) これはF分布のパーセント点関数(ppf)を直接呼び出し、累積確率が0.99999995となるF値を求めます。この計算では、F値が 3333.83… という非常に大きな値になっています。 spo.brentq(lambda x: sps.f.cdf(x, 1, 50000) - 0.99999995, 1, 1e10) こちらはscipy.optimizeモジュールのbrentq関数を使い、同じ問題を数値的に解いています。brentqは、与えられた関数の値が0になる点(根)を見つけるための堅牢なアルゴリズムです。ここでは、「sps.f.cdf(x, 1, 50000) - 0.99999995」という式が0になるx、つまり累積確率が0.99999995になるF値を探索しています。 この計算では、F値が 29.72… という、ppfの直接呼び出しとは全く異なる、より妥当と思われる値が得られます。 この乖離は、scipy.stats.f.ppfが特定の条件下で正確な答えを返さない可能性があることを示しています。 F分布のような統計分布の逆関数(ppf)を、極端な確率値(この例では1に非常に近い0.99999995)で計算する場合、数値的な精度の問題が発生しやすくなります。特に自由度が大きい場合、分布の裾(テール)の部分が非常に平坦になるため、計算過程でのわずかな丸め誤差などが、結果として得られるF値の大きな違いにつながることがあります。 一方、brentqは指定された範囲内で根を探索する、より頑健な数値計算アルゴリズムです。関数の振る舞いをより正確に追跡できるため、このようなケースではより信頼性の高い結果を生成すると考えられます。 問題の可視化 この問題は、以下のコードでscipy.special.fdtri(F分布の逆関数)の挙動をプロットすることで、より明確に可視化できます。自由度d2が50000と大きい場合に、確率pが0に近づく(つまり累積確率が1に近づく)領域で、関数の値が急激に変動していることがわかります。 import numpy as np from scipy import special import matplotlib.pyplot as plt d1, d2, p = 1, 50000, np.logspace(-16, -1) # fdtriは1-pを引数に取るため、pが0に近づくと累積確率が1に近づく fdtri = special.fdtri(d1, d2, 1-p) plt.semilogx(p, fdtri) plt.xlabel("p (1 - Cumulative Probability)") plt.ylabel("F-value (fdtri)") plt.title("fdtri behavior for extreme probabilities (d1=1, d2=50000)") plt.grid(True) plt.show() ...

8月 19, 2025 · 2 分 · 279 文字 · Me

monoでASP.NET APIがMissing Methodを吐く

単純に言っちゃうとHttpRequestBaseにGetBufferedInputStreamがない。 Mono 4.3.x系を入れると問題が解決するようだがMono 4.2.xでどうやって対応するか。 今回はPostハンドラをクイックハックした。 #if MONO public string Post() { var buffer = HttpContext.Current.Request.BinaryRead(HttpContext.Current.Request.ContentLength); var jsonStr = System.Text.Encoding.ASCII.GetString(buffer); T parsed = JsonConvert.DeserializeObject<T>(jsonStr); #else public string Post([FromBody]T parsed) { #endif

6月 20, 2016 · 1 分 · 30 文字 · Me