.NET Graphics.Scaletransform Convierte el trabajo de impresión en mapa de bits. ¿Alguna otra forma de escalar el texto?

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

Pregunta

Estoy usando Graphics.ScaleTransform Para estirar las líneas de texto para que se ajusten al ancho de la página y luego impriman esa página. Sin embargo, esto convierte el trabajo de impresión en un mapa de bits: para una impresión con muchas páginas, esto hace que el tamaño del trabajo de impresión aumente a proporciones obscenas, y ralentiza inmensamente la impresión.

Si no escala así, el trabajo de impresión sigue siendo muy pequeño, ya que solo está enviando comandos de impresión de texto a la impresora.

Mi pregunta es, ¿hay otra manera que no sea usar Graphics.ScaleTransform para estirar el ancho del texto?

El código de muestra para demostrar que esto está a continuación (se llamaría con Print.Test(True) y Print.Test(False) Para mostrar los efectos de la escala en el trabajo de impresión):

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

ACTUALIZAR: En su lugar, usé Interopop con llamadas GDI. Aquí está el código relevante; La clase GDI está llena de definiciones que copié del wiki en http://pinvoke.net/ para las funciones y constantes relevantes.

    ' 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)
¿Fue útil?

Solución

Sí, la clase de gráficos admite texto de escala. Pero debe hacerlo haciendo que el texto primero sea un mapa de bits, reorganice el mapa de bits y pase que redimensione el mapa de bits al controlador de la impresora. Todos esos mapas de bits crean un archivo de boteque grande.

Tendrá que justificar el texto usted mismo. No hay soporte para esto en el marco. Una forma de hacerlo es secuestrar un rico control de edición y dejar que se encargue de la justificación e impresión. La versión 5, msftedit.dll, admite la justificación completa. La mejor manera de encontrar el código que necesita es encontrar uno de los muchos proyectos que implementen un editor de texto con RTB, similar a WordPad en Windows.

Otros consejos

Supongo que aquí, pero debe aumentar el tamaño de la fuente en un porcentaje de la proporción por la que desea escalar.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top