使用wingdi函数一起缩放和旋转SetWorldTransform

问题描述

我正在使用Exttextout wingdi函数绘制文本。另外,我正在使用SetWorldTransform缩放文本,但是现在我也想旋转文本(所有角度)。如何更改/传递参数,使其也能缩放和旋转?

下面是示例代码块,此代码可以完美运行,但现在我也想介绍旋转文本,而不会影响缩放比例。

var inputString = "Sample text";
var fontSize = 31f;
var font = new Font("Avenir Black",fontSize,new FontStyle());

var startX1 = 50;
var startY1 = 50;

LOGFONT lf = new LOGFONT();
font.ToLogFont(lf,e.Graphics);

IntPtr hPrinterDC = e.Graphics.GetHdc();
StringBuilder sbText = new StringBuilder(inputString);
if (hPrinterDC != IntPtr.Zero)
{
    int nPrintHorzRes = GetDeviceCaps(hPrinterDC,HORZRES);
    int nPrintVertRes = GetDeviceCaps(hPrinterDC,VERTRES);
    int nPhysWidth = GetDeviceCaps(hPrinterDC,PHYSICALWIDTH);
    int nPhysHeight = GetDeviceCaps(hPrinterDC,PHYSICALHEIGHT);
    int nPhysOffsetX = GetDeviceCaps(hPrinterDC,PHYSICALOFFSETX);
    int nPhysOffsetY = GetDeviceCaps(hPrinterDC,PHYSICALOFFSETY);

    IntPtr hDCScreen = GetDC(IntPtr.Zero);
    float nLogPixelsXScreen = GetDeviceCaps(hDCScreen,LOGPIXELSX);
    float nLogPixelsYScreen = GetDeviceCaps(hDCScreen,LOGPIXELSY);
    ReleaseDC(hDCScreen,IntPtr.Zero);
    float nLogPixelsXPrinter = GetDeviceCaps(hPrinterDC,LOGPIXELSX);
    float nLogPixelsYPrinter = GetDeviceCaps(hPrinterDC,LOGPIXELSY);

    float nScaleX = Math.Max(nLogPixelsXScreen,nLogPixelsXPrinter) / Math.Min(nLogPixelsXScreen,nLogPixelsXPrinter);
    float nScaleY = Math.Max(nLogPixelsYScreen,nLogPixelsYPrinter) / Math.Min(nLogPixelsYScreen,nLogPixelsYPrinter);

    System.Drawing.drawing2d.Matrix transform = new System.Drawing.drawing2d.Matrix();
    transform.Scale(nScaleX,nScaleY);
    XFORM renderTransform = new XFORM();
    var elements = transform.Elements;
    var m11 = elements[0];
    var m12 = elements[1];
    var m21 = elements[2];
    var m22 = elements[3];
    var dx = elements[4];
    var dy = elements[5];

    renderTransform.eM11 = (float)m11;
    renderTransform.eM12 = (float)m12;
    renderTransform.eM21 = (float)m21;
    renderTransform.eM22 = (float)m22;
    
    int nOffsetX = 0;
    int nOffsetY = 0;
    renderTransform.eDx = (float)transform.OffsetX + nOffsetX;
    renderTransform.eDy = (float)transform.OffsetY + nOffsetY;
    SetGraphicsMode(hPrinterDC,GM_ADVANCED);
    
    SetMapMode(hPrinterDC,MM_TEXT);
    bool bRet = SetWorldTransform(hPrinterDC,ref renderTransform);

    var startX2 = startX1;
    var startY2 = startY1;
    RECT rc = new RECT(startX2,startY2,nPhysWidth,nPhysHeight);   

    SetViewportOrgEx(hPrinterDC,-nPhysOffsetX,-nPhysOffsetY,IntPtr.Zero);
    
    lf.lfheight = (int)(lf.lfheight / nScaleY);   

    IntPtr hFontNew = CreateFontIndirect(lf);
    IntPtr hFontOld = SelectObject(hPrinterDC,hFontNew);

    SetBkMode(hPrinterDC,TRANSPARENT);
    SetTextColor(hPrinterDC,ColorTranslator.ToWin32(Color.Blue));      
    Exttextout(hPrinterDC,rc.left,rc.top,eto_OPAQUE,IntPtr.Zero,sbText,(uint)sbText.Length,IntPtr.Zero);

    rc.top += -lf.lfheight;
    SetTextColor(hPrinterDC,ColorTranslator.ToWin32(Color.Green));
    Exttextout(hPrinterDC,IntPtr.Zero);

    var nExtra = -10.0f / nScaleX;    
    SetTextCharacterExtra(hPrinterDC,(int)nExtra);
    rc.top += -lf.lfheight;
    SetTextColor(hPrinterDC,ColorTranslator.ToWin32(Color.Red));
    Exttextout(hPrinterDC,IntPtr.Zero);

    SelectObject(hPrinterDC,hFontOld);
    DeleteObject(hFontNew);
}

这是pinvokes:

  [DllImport("Gdi32.dll",SetLastError = true,CharSet = CharSet.Unicode)]
        public static extern bool SetWorldTransform(IntPtr hdc,ref XFORM lpxf);

        [StructLayout(LayoutKind.Sequential)]
        public struct XFORM
        {
            public float eM11;
            public float eM12;
            public float eM21;
            public float eM22;
            public float eDx;
            public float eDy;
        }

        [DllImport("Gdi32.dll",CharSet = CharSet.Unicode)]
        public static extern int SetGraphicsMode(IntPtr hdc,int iMode);

        public const int GM_COMPATIBLE = 1;
        public const int GM_ADVANCED = 2;
        public const int GM_LAST = 2;
        
        [DllImport("User32.dll",CharSet = CharSet.Auto)]
        public static extern IntPtr GetDC(IntPtr hWnd);

        [DllImport("User32.dll",CharSet = CharSet.Auto)]
        public static extern int ReleaseDC(IntPtr hWnd,IntPtr hDC);
        
        public const int TRANSPARENT = 1;
        public const int OPAQUE = 2;
        public const int BKMODE_LAST = 2;

        [DllImport("Gdi32.dll",CharSet = CharSet.Unicode)]
        public static extern int SetBkMode(IntPtr hdc,int mode);

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...