.NET Graphics.ScaleTransform Converte il lavoro di stampa in bitmap. Qualche altro modo per ridimensionare il testo?

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

Domanda

sto usando Graphics.ScaleTransform Per allungare le righe di testo in modo che si adattino alla larghezza della pagina e quindi stampano quella pagina. Tuttavia, questo converte il lavoro di stampa in una bitmap - per una stampa con molte pagine ciò fa sì che le dimensioni del lavoro di stampa si alzino a proporzioni oscene e rallenta immensamente la stampa.

Se non mi scala così, il lavoro di stampa rimane molto piccolo in quanto sta solo inviando comandi di stampa di testo alla stampante.

La mia domanda è: c'è un modo diverso dall'uso Graphics.ScaleTransform per allungare la larghezza del testo?

Il codice di esempio per dimostrare questo è sotto (verrebbe chiamato con Print.Test(True) e Print.Test(False) Per mostrare gli effetti del ridimensionamento sul lavoro di stampa):

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

AGGIORNARE: Ho usato invece interrogarsi con chiamate GDI. Ecco il codice pertinente; La classe GDI è solo piena di definizioni che ho copiato dal wiki a http://pinvoke.net/ per le funzioni e le costanti pertinenti.

    ' 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)
È stato utile?

Soluzione

Sì, la classe grafica supporta il testo di ridimensionamento. Ma deve farlo rendendo prima il testo a una bitmap, salva la bitmap e passano la bitmap ridimensionata al driver della stampante. Tutte quelle bitmap creano un file di spooler di grandi dimensioni.

Dovrai giustificare il testo da solo. Non c'è supporto per questo nel framework. Un modo per farlo è di dirottare un ricco controllo di modifica e lasciarlo occuparsi della giustificazione e della stampa. La versione 5, msftedit.dll, supporta la giustificazione completa. Il modo migliore per trovare il codice di cui hai bisogno è trovare uno dei tanti progetti che implementano un editor di testo con RTB, simile a WordPad su Windows.

Altri suggerimenti

Sto indovinando qui, ma dovresti aumentare le dimensioni del carattere di una percentuale della proporzione che si desidera ridimensionare.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top