前回の記事で、PCの画面と、プリントされた出力では改行位置に違いがありました。 「それなら洗濯物は ...」の文では、行数が変わり、枠の高さも変ってしまいました。 なお、PDFへの出力をお見せしていましたが、手持ちのプリンタへの(直接の;PDFからではない)印字も、PDFの場合と同じでした。 それで、どうしてこんなことが起きるのか、調べてみました。
問題の核は、次のルーチン(C#用語では「手続き」)にありそうです(場所は、プログラム末尾から100行くらい)。
ここに来る過程がディスプレイへの表示の場合と、印刷の場合とで、引き渡される欄の幅 w には違いはありませんでした。 そして、どちらの場合も、文字の行数と欄の高さとの間に不整合は起きていないので、 g.DrawString(...) と、その次の SizeF stringSize =g.MeasureString(...) とは相互に整合性を持っていることがわかります。 で、stringSize には明らかに違いがありました(幅は減り、高くなっていました)。 この違いが出る原因としては、ディスプレイとプリンタとで、グラフィックコンテキスト g に見えない違いがあるからと考える他ありません。 それ以外の材料に違いはありませんから。
そう言えば、こういうことは良くありました。 そう、Excel の表です。 表の中でプリントされるはずの欄の中身の一部が表示されず、上司からお目玉を食らった経験の方もあろうかと思います。 これはどうも Windows の奥に潜む問題の一つのようです。
プリントの g を切り分けているのは、プリントでは、ディスプレイの時よりも高品質の表示が可能であることを活かすためだと考えられます。 しかし、ディスプレイとの整合性がないのはやはり不都合です。 高品質のプリントは維持したい。 しかし、ディスプレイは、今より多少は見づらくなっても、プリントと整合性のあるディスプレイの表示が欲しいと思いませんか? 私はそう思います。
そういう解決を考えるに、PDFライターからのグラフィックコンテキストをだまして幅指定の stringSize を得ることはできそうだが、 肝心の g.DrawString で長方形範囲を指定したものが、それ用のグラフィックスでないと機能しない点はどうしようもない。 となると、一文字々々々ベースの DrawString を使うしかないのでは? これは言い方を変えると、幅指定の DrawString や MeasureString のようなものを自作するということでもあるが、それはそんなに難しくはないと思いました。
で、やっちゃいました。文を分析し、文字の位置を逐一計算で決めている積算にはグラフィックコンテキストを参照していません(実は参照しているのですが、今のところ違いは出ていません)。 なので、ディスプレイとプリンタで、文字の位置が大きく変わるということはありません。書き換えた部分です。
このソフトを動かしたところです。
印刷(この場合PDFへ)したページです。
プログラムです。
LineSimulatorA.cs