.NET Graphics.ScaleTransform convertit le travail d'impression en bitmap. Une autre façon de mettre à l'échelle du texte?

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

Question

j'utilise Graphics.ScaleTransform Pour étirer les lignes de texte afin qu'elles correspondent à la largeur de la page, puis impriment cette page. Cependant, cela convertit le travail d'impression en un bitmap - pour une impression avec de nombreuses pages, cela fait que la taille du travail d'impression augmente aux proportions obscènes et ralentit énormément l'impression.

Si je n'échelle pas comme ça, le travail d'impression reste très petit car il s'agit simplement d'envoyer des commandes d'impression de texte à l'imprimante.

Ma question est, existe-t-il autrement que l'utilisation Graphics.ScaleTransform Pour étirer la largeur du texte?

Exemple de code pour démontrer que cela est ci-dessous (serait appelé avec Print.Test(True) et Print.Test(False) Pour montrer les effets de la mise à l'échelle sur le travail d'impression):

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

METTRE À JOUR: J'ai utilisé des appels GDI à la place. Voici le code pertinent; La classe GDI est juste pleine de définitions que j'ai copiées du wiki à http://pinvoke.net/ pour les fonctions et constantes pertinentes.

    ' 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)
Était-ce utile?

La solution

Oui, la classe graphique prend en charge le texte de mise à l'échelle. Mais il doit le faire en rendant le texte à un bitmap d'abord, à redire le bitmap et à passer ce bitmap redimensionné au pilote d'imprimante. Tous ces bitmaps font un grand fichier de spouleur.

Vous devrez justifier le texte vous-même. Il n'y a pas de soutien à cela dans le cadre. Une façon de le faire est de détourner un riche contrôle d'édition et de le laisser s'occuper de la justification et de l'impression. La version 5, MSFtedit.dll, prend en charge la justification complète. La meilleure façon de trouver le code dont vous avez besoin est de trouver l'un des nombreux projets qui implémentent un éditeur de texte avec RTB, similaire à WordPad sur Windows.

Autres conseils

Je devine ici, mais vous devez augmenter la taille de la police par un pourcentage de la proportion que vous souhaitez évoluer.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top