.NET Graphics.ScaletRansform konvertiert Druckauftrag in Bitmap. Irgendeine andere Möglichkeit, Text zu skalieren?

StackOverflow https://stackoverflow.com/questions/2637174

Frage

Ich benutze Graphics.ScaleTransform Um Textzeilen zu dehnen, damit sie die Breite der Seite passen und diese Seite dann drucken. Dies konvertiert jedoch den Druckauftrag in eine Bitmap - für einen Druck mit vielen Seiten führt dies dazu, dass die Größe des Druckauftrags zu obszönen Proportionen steigt, und verlangsamt das Drucken immens.

Wenn ich mich nicht so skalle, bleibt der Druckauftrag sehr klein, da er nur Text Druckbefehle an den Drucker sendet.

Meine Frage ist, gibt es eine andere Möglichkeit, als zu verwenden Graphics.ScaleTransform die Breite des Textes dehnen?

Beispielcode, um zu demonstrieren, dass dies unten ist (würde aufgerufen werden mit Print.Test(True) und Print.Test(False) Um die Auswirkungen der Skalierung auf den Druckauftrag zu zeigen):):

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

AKTUALISIEREN: Ich habe stattdessen Interop mit GDI -Aufrufen verwendet. Hier ist der relevante Code; Die GDI -Klasse ist nur voll von Definitionen, die ich aus dem Wiki kopiert habe http://pinvoke.net/ Für die relevanten Funktionen und Konstanten.

    ' 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)
War es hilfreich?

Lösung

Ja, die Grafikklasse unterstützt den Skalierungstext. Aber es muss dies tun, indem es den Text zuerst an eine Bitmap verteilt, die Bitmap skalieren und Bitmap an den Druckertreiber übergeben. All diese Bitmaps sorgen für eine große Spooler -Datei.

Sie müssen den Text selbst rechtfertigen. Dies gibt dies im Rahmen nicht. Eine Möglichkeit, dies zu tun, besteht darin, eine reichhaltige Bearbeitungskontrolle zu entführen und sich um die Rechtfertigung und den Druck zu kümmern. Version 5, msftedit.dll, unterstützt die vollständige Rechtfertigung. Der beste Weg, um den Code zu finden, den Sie benötigen, besteht darin, eines der vielen Projekte zu finden, die einen Texteditor mit RTB implementieren, ähnlich wie bei WordPad unter Windows.

Andere Tipps

Ich rate hier, aber Sie sollten die Größe der Schrift um einen Prozentsatz des Anteils erhöhen, nach dem Sie skalieren möchten.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top