using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; using System.Drawing.Imaging; using System.Drawing.Printing; using System.Drawing.Drawing2D; using System.Drawing.Text; using System.Diagnostics; using System.Runtime.InteropServices; using System.Drawing; namespace Geovin.Du.ControlLibrary { /// <summary> /// 設置字符之間的間距 /// /// </summary> public class GdiPlusMethods { #region Declare [System.Runtime.InteropServices.DllImport("Gdiplus.dll", CharSet = System.Runtime.InteropServices.CharSet.Unicode)] internal extern static int GdipMeasureDriverString(IntPtr g, string pText, int pLength, IntPtr pFont, System.Drawing.PointF[] pPositions, int pFlags, IntPtr pMatrix, ref System.Drawing.RectangleF pBounds); [System.Runtime.InteropServices.DllImport("Gdiplus.dll", CharSet = System.Runtime.InteropServices.CharSet.Unicode)] internal extern static int GdipDrawDriverString(IntPtr g, string pText, int pLength, IntPtr pFont, IntPtr pBrush, System.Drawing.PointF[] pPositions, int pFlags, IntPtr pMatrix); #endregion Declare #region GdiPlusMethods /// <summary> /// /// </summary> private GdiPlusMethods() { } #endregion GdiPlusMethods #region DriverStringOptions /// <summary> /// /// </summary> private enum DriverStringOptions { CmapLookup = 1, Vertical = 2, Advance = 4, LimitSubpixel = 8, } #endregion DriverStringOptions #region DrawDriverString /// <summary> /// 字符間距 /// </summary> /// <param name="g"></param> /// <param name="pText"></param> /// <param name="pFont"></param> /// <param name="pBrush"></param> /// <param name="pPositions"></param> private static void DrawDriverString(System.Drawing.Graphics g, string pText, System.Drawing.Font pFont, System.Drawing.Brush pBrush, System.Drawing.PointF[] pPositions) { try { DrawDriverString(g, pText, pFont, pBrush, pPositions, null); } catch (NullReferenceException NullEx) { throw NullEx; } catch (Exception Ex) { throw Ex; } } #endregion DrawDriverString #region DrawDriverString /// <summary> /// /// </summary> /// <param name="g"></param> /// <param name="pText"></param> /// <param name="pFont"></param> /// <param name="pBrush"></param> /// <param name="pRect"></param> /// <param name="pHeight"></param> private static void DrawDriverString(System.Drawing.Graphics g, string pText, System.Drawing.Font pFont, System.Drawing.Brush pBrush, System.Drawing.Rectangle pRect, int pHeight) { try { System.Drawing.PointF[] mPositions = new System.Drawing.PointF[pText.Length]; System.Drawing.Size mSize = g.MeasureString(pText, pFont).ToSize(); //int mTextHeight = mSize.Height; int mRow = 1; int mPosX = 0; for (int i = 0; i < pText.Length; i++) { mSize = g.MeasureString(pText.Substring(i, 1), pFont).ToSize(); if ((mPosX + mSize.Width) > pRect.Width) { mPosX = 0; mRow = mRow + 1; } mPositions[i] = new System.Drawing.PointF(pRect.Left + mPosX, pRect.Top + mRow * pHeight); mPosX = mPosX + mSize.Width; } DrawDriverString(g, pText, pFont, pBrush, mPositions, null); } catch (NullReferenceException NullEx) { throw NullEx; } catch (Exception Ex) { throw Ex; } } #endregion DrawDriverString #region DrawDriverString /// <summary> /// /// </summary> /// <param name="g"></param> /// <param name="pText"></param> /// <param name="pFont"></param> /// <param name="pBrush"></param> /// <param name="pPositions"></param> /// <param name="pMatrix"></param> private static void DrawDriverString(System.Drawing.Graphics g, string pText, System.Drawing.Font pFont, System.Drawing.Brush pBrush, System.Drawing.PointF[] pPositions, System.Drawing.Drawing2D.Matrix pMatrix) { try { if (g == null) throw new ArgumentNullException("graphics"); if (pText == null) throw new ArgumentNullException("text"); if (pFont == null) throw new ArgumentNullException("font"); if (pBrush == null) throw new ArgumentNullException("brush"); if (pPositions == null) throw new ArgumentNullException("positions"); // Get hGraphics System.Reflection.FieldInfo field = typeof(System.Drawing.Graphics).GetField("nativeGraphics", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic); IntPtr hGraphics = (IntPtr)field.GetValue(g); // Get hFont field = typeof(System.Drawing.Font).GetField("nativeFont", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic); IntPtr hFont = (IntPtr)field.GetValue(pFont); // Get hBrush field = typeof(System.Drawing.Brush).GetField("nativeBrush", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic); IntPtr hBrush = (IntPtr)field.GetValue(pBrush); // Get hMatrix IntPtr hMatrix = IntPtr.Zero; if (pMatrix != null) { field = typeof(System.Drawing.Drawing2D.Matrix).GetField("nativeMatrix", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic); hMatrix = (IntPtr)field.GetValue(pMatrix); } int result = GdipDrawDriverString(hGraphics, pText, pText.Length, hFont, hBrush, pPositions, (int)DriverStringOptions.CmapLookup, hMatrix); } catch (NullReferenceException NullEx) { throw NullEx; } catch (Exception Ex) { throw Ex; } } /// <summary> /// 設置字符間距 /// 塗聚文 /// </summary> /// <param name="g">Drawing.Graphics</param> /// <param name="pText">字符</param> /// <param name="x">X坐標</param> /// <param name="y">Y坐標</param> /// <param name="width">字符寬度</param> /// <param name="pFont">字體</param> /// <param name="pBrush"></param> public static void DrawStringCharacterSpacing(System.Drawing.Graphics g, string pText, float x, float y, float width, System.Drawing.Font pFont, System.Drawing.Brush pBrush) { //Get the height of myFont. float height = pFont.GetHeight(g); //當大於兩個字符時進行設置 if (pText.Length >= 2) { g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias; SizeF size = g.MeasureString(pText, pFont, int.MaxValue);//int.MaxValue float h = size.Height; float w = size.Width; PointF[] positions = new PointF[pText.Length]; for (int i = 0; i < pText.Length; i++) { positions[i] = new PointF(i * width + x, y); //20 為字間距離 } DrawDriverString(g, pText, pFont, pBrush, positions); } } #endregion DrawDriverString } }