.NET Graphics.Scaletransform يحول مهمة الطباعة إلى صورة نقطية. أي طريقة أخرى لتوسيع نطاق النص؟

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

سؤال

أنا استخدم 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

تحديث: لقد استخدمت interop مع مكالمات GDI بدلاً من ذلك. إليك الكود ذي الصلة ؛ فئة GDI مليئة بالتعاريف التي قمت بنسخها من الويكي في 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)
هل كانت مفيدة؟

المحلول

نعم ، تدعم فئة الرسومات نص التحجيم. ولكن يجب أن يفعل ذلك عن طريق تقديم النص إلى صورة نقطية أولاً ، وقم بإنقاذ صورة النقطية والتمرير الذي يتم تغيير حجم النقطة النقطية إلى برنامج تشغيل الطابعة. كل هذه الخلايا النقطية تجعل ملف التخزين المؤقت الكبير.

ستحتاج إلى تبرير النص بنفسك. لا يوجد دعم لهذا في الإطار. طريقة واحدة للقيام بذلك هي اختطاف التحكم الغني بالتحرير والسماح له بالرعاية للمبرر والطباعة. الإصدار 5 ، msftedit.dll ، يدعم التبرير الكامل. أفضل طريقة للعثور على الكود الذي تحتاجه هو العثور على أحد المشاريع العديدة التي تنفذ محرر نصوص مع RTB ، على غرار WordPad على Windows.

نصائح أخرى

أنا أظن هنا ولكن يجب أن تزيد من حجم الخط بنسبة مئوية من النسبة التي تريد توسيعها.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top