.NET Graphics.ScaletransFormは、印刷ジョブをビットマップに変換します。テキストをスケーリングする他の方法はありますか?
-
26-09-2019 - |
質問
私は使用しています Graphics.ScaleTransform
テキストの行を伸ばして、ページの幅に適合し、そのページを印刷します。ただし、これにより印刷ジョブがビットマップに変換されます。多くのページを持つ印刷の場合、印刷ジョブのサイズがわいせつなプロポーションに上昇し、印刷が非常に遅くなります。
このようにスケーリングしないと、印刷ジョブはテキスト印刷コマンドをプリンターに送信するだけなので、非常に小さくなります。
私の質問は、使用する以外の方法はありますか Graphics.ScaleTransform
テキストの幅を伸ばすには?
これを実証するためのサンプルコードは以下です(で呼び出されます Print.Test(True)
と Print.Test(False)
印刷ジョブに対するスケーリングの効果を示すために):
Imports System.Drawing
Imports System.Drawing.Printing
Imports System.Drawing.Imaging
Public Class Print
Dim FixedFont As Font
Dim Area As RectangleF
Dim CharHeight As Double
Dim CharWidth As Double
Dim Scale As Boolean
Const CharsAcross = 80
Const CharsDown = 66
Const TestString = "!""#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~"
Private Sub PagePrinter(ByVal sender As Object, ByVal e As PrintPageEventArgs)
Dim G As Graphics = e.Graphics
If Scale Then
Dim ws = Area.Width / G.MeasureString(Space(CharsAcross).Replace(" ", "X"), FixedFont).Width
G.ScaleTransform(ws, 1)
End If
For CurrentLine = 1 To CharsDown
G.DrawString(Mid(TestString & TestString & TestString, CurrentLine, CharsAcross), FixedFont, Brushes.Black, 0, Convert.ToSingle(CharHeight * (CurrentLine - 1)))
Next
e.HasMorePages = False
End Sub
Public Shared Sub Test(ByVal Scale As Boolean)
Dim OutputDocument As New PrintDocument
With OutputDocument
Dim DP As New Print
.PrintController = New StandardPrintController
.DefaultPageSettings.Landscape = False
DP.Area = .DefaultPageSettings.PrintableArea
DP.CharHeight = DP.Area.Height / CharsDown
DP.CharWidth = DP.Area.Width / CharsAcross
DP.Scale = Scale
DP.FixedFont = New Font("Courier New", DP.CharHeight / 100, FontStyle.Regular, GraphicsUnit.Inch)
.DocumentName = "Test print (with" & IIf(Scale, "", "out") & " scaling)"
AddHandler .PrintPage, AddressOf DP.PagePrinter
.Print()
End With
End Sub
End Class
アップデート: 代わりにGDIコールを使用してInteropを使用しました。関連するコードは次のとおりです。 GDIクラスには、Wikiからコピーした定義がいっぱいです http://pinvoke.net/ 関連する関数と定数の場合。
' convert from Graphics units (100 dpi) to device units
Dim GDIMappedCharHeight As Double = CharHeight * G.DpiY / 100
Dim GDIMappedCharWidth As Double = CharWidth * G.DpiX / 100
Dim FixedFontGDI As IntPtr = GDI.CreateFont(GDIMappedCharHeight, GDIMappedCharWidth, 0, 0, 0, 0, 0, 0, GDI.DEFAULT_CHARSET, GDI.OUT_DEFAULT_PRECIS, GDI.CLIP_DEFAULT_PRECIS, GDI.DEFAULT_QUALITY, GDI.FIXED_PITCH, "Courier New")
Dim CharRect As New GDI.STRUCT_RECT
Dim hdc As IntPtr = G.GetHdc()
GDI.SelectObject(hdc, FixedFontGDI)
' I used SetBkMode transparent as my text needed to overlay a background
GDI.SetBkMode(hdc, GDI.TRANSPARENT)
' draw it character by character to get precise grid
For CurrentLine = 1 To CharsDown
For CurrentColumn = 1 To CharsAcross
With CharRect
.left = GDIMappedCharWidth * (CurrentColumn - 1)
.right = GDIMappedCharWidth * CurrentColumn
.top = GDIMappedCharHeight * (CurrentLine - 1)
.bottom = GDIMappedCharHeight * CurrentLine
End With
' 2341 == DT_NOPREFIX|DT_NOCLIP|DT_VCENTER|DT_CENTER|DT_SINGLELINE
GDI.DrawText(hdc, Mid(TestString & TestString & TestString, CurrentLine+CurrentColumn, 1), 1, CharRect, 2341)
Next
Next
GDI.DeleteObject(FixedFontGDI)
G.ReleaseHdc(hdc)
解決
はい、グラフィッククラスはスケーリングテキストをサポートしています。ただし、最初にテキストをビットマップにレンダリングし、ビットマップを再スケーリングし、サイズを変更したビットマップをプリンタードライバーに渡すことで、そうする必要があります。これらのすべてのビットマップは、大きなスプーラーファイルを作成します。
テキストを自分で正当化する必要があります。フレームワークにはこれに対するサポートはありません。それを行う1つの方法は、豊富な編集コントロールをハイジャックし、正当化と印刷を処理させることです。バージョン5、msftedit.dllは、完全な正当化をサポートしています。必要なコードを見つける最良の方法は、WindowsのWordPadと同様に、RTBを使用してテキストエディターを実装する多くのプロジェクトの1つを見つけることです。
他のヒント
ここで推測していますが、スケーリングする割合の割合でフォントのサイズを増やす必要があります。