Zebra中文打印,替换FNTHEX32.DLL

Zebra官方提供的Unicode转化组件FNTHEX32.DLL,是一个非托管组件,托管环境下还需要再封装。
.net core 无法使用FNTHEX32.dll。

参考了https://blog.csdn.net/gongbenwen/article/details/78408322

该api也有个问题,.net core 支持原生System.Drawing。所以也没办法使用。

该api没有源码,所以查看了dll源码,重新修改了一下。

UnicodeToZPL.cs

    /// <summary>
    /// Unicode字符转化成对应的ZPL指令
    /// </summary>
    public class UnicodeToZPL
    {
        /// <summary>
        /// 生成图片回调显示
        /// </summary>
        public static event Action<Image> OnViewImageCallBack
        {
            add
            {
                Action<Image> action = UnicodeToZPL.ImageCallBack;
                Action<Image> action2;
                do
                {
                    action2 = action;
                    Action<Image> value2 = (Action<Image>)Delegate.Combine(action2, value);
                    action = Interlocked.CompareExchange<Action<Image>>(ref UnicodeToZPL.ImageCallBack, value2, action2);
                }
                while (action != action2);
            }
            remove
            {
                Action<Image> action = UnicodeToZPL.ImageCallBack;
                Action<Image> action2;
                do
                {
                    action2 = action;
                    Action<Image> value2 = (Action<Image>)Delegate.Remove(action2, value);
                    action = Interlocked.CompareExchange<Action<Image>>(ref UnicodeToZPL.ImageCallBack, value2, action2);
                }
                while (action != action2);
            }
        }

        /// <summary>
        /// 未压缩算法处理
        /// Unicode字符转化成对应的ZPL指令
        /// </summary>
        /// <param name="content">文本内容</param>
        /// <param name="name">生成的图片名称,名称需要唯一</param>
        /// <param name="font">字体</param>
        /// <param name="textDirection">文字方向(0,45,90,180,270)</param>
        /// <returns>
        /// 返回转换完未压缩的ZPL指令
        /// </returns>
        public static string UnCompressZPL(string content, string name, Font font, int textDirection, int startX, int startY)
        {
            Bitmap bitmap;
            string text;
            Size size;

            bitmap = UnicodeToZPL.CreateImage(content, font);
            if (textDirection != (int)TextDirection.Zero)
            {
                bitmap = UnicodeToZPL.SetTextDirection(bitmap, textDirection);
            }
            if (UnicodeToZPL.ImageCallBack != null)
            {
                UnicodeToZPL.ImageCallBack(bitmap);
            }
            text = UnicodeToZPL.ToZPL(bitmap);
            size = bitmap.Size;

            string h = ((size.Width / 8 + ((bitmap.Size.Width % 8 == 0) ? 0 : 1)) * bitmap.Size.Height).ToString();
            string w = (bitmap.Size.Width / 8 + ((bitmap.Size.Width % 8 == 0) ? 0 : 1)).ToString();
            string zpl = string.Format($"~DG{name}.GRF,{h},{w},{text}^FO{startX},{startY}^XG{name}^FS");
            return zpl;
        }

        /// <summary>
        /// 压缩算法处理
        /// Unicode字符转化成对应的ZPL指令
        /// </summary>
        /// <param name="content">文本内容</param>
        /// <param name="name">生成的图片名称,名称需要唯一</param>
        /// <param name="font">字体</param>
        /// <param name="textDirection">文字方向(0,45,90,180,270)</param>
        /// <returns>
        /// 返回转换完压缩的ZPL指令
        /// </returns>
        public static string CompressZPL(string content, string name, Font font, int textDirection, int startX, int startY)
        {
            Bitmap bitmap;
            string text;

            bitmap = UnicodeToZPL.CreateImage(content, font);
            if (textDirection != (int)TextDirection.Zero)
            {
                bitmap = UnicodeToZPL.SetTextDirection(bitmap, textDirection);
            }
            if (UnicodeToZPL.ImageCallBack != null)
            {
                UnicodeToZPL.ImageCallBack(bitmap);
            }
            text = UnicodeToZPL.ToZPL(bitmap);
            text = CompressCharacter.Compress(text);

            string h = ((bitmap.Size.Width / 8 + ((bitmap.Size.Width % 8 == 0) ? 0 : 1)) * bitmap.Size.Height).ToString();
            string w = (bitmap.Size.Width / 8 + ((bitmap.Size.Width % 8 == 0) ? 0 : 1)).ToString();
            string zpl = string.Format($"~DG{name}.GRF,{h},{w},{text}^FO{startX},{startY}^XG{name}^FS");
            return zpl;

        }

        /// <summary>
        /// 生成文字图片
        /// </summary>
        /// <param name="content"></param>
        /// <param name="font"></param>
        /// <returns></returns>
        private static Bitmap CreateImage(string content, Font font)
        {
            StringFormat stringFormat;
            Bitmap bitmap;
            Graphics graphics;
            int width;
            int height;
            Rectangle rectangle;

            stringFormat = new StringFormat(StringFormatFlags.NoClip);
            bitmap = new Bitmap(1, 1);
            graphics = Graphics.FromImage(bitmap);
            SizeF sizeF = graphics.MeasureString(content, font, PointF.Empty, stringFormat);
            width = (int)(sizeF.Width + 1f);
            height = (int)(sizeF.Height + 1f);
            rectangle = new Rectangle(0, 0, width, height);

            bitmap.Dispose();
            bitmap = new Bitmap(width, height);
            graphics = Graphics.FromImage(bitmap);
            graphics.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
            graphics.FillRectangle(new SolidBrush(Color.White), rectangle);
            graphics.DrawString(content, font, Brushes.Black, rectangle, stringFormat);
            return bitmap;
        }

        /// <summary>
        /// 设置图片方向
        /// </summary>
        /// <param name="bmp">图片</param>
        /// <param name="direction">方向(0,45,90,180,270)</param>
        /// <returns></returns>
        private static Bitmap SetTextDirection(Bitmap bmp, int direction)
        {
            int width;
            int height;
            int num4;
            int num5;
            Bitmap bitmap;
            Graphics graphics;

            direction %= 360;
            double num = (double)direction * 3.1415926535897931 / 180.0;
            double num2 = Math.Cos(num);
            double num3 = Math.Sin(num);
            width = bmp.Width;
            height = bmp.Height;
            num4 = (int)Math.Max(Math.Abs((double)width * num2 - (double)height * num3), Math.Abs((double)width * num2 + (double)height * num3));
            num5 = (int)Math.Max(Math.Abs((double)width * num3 - (double)height * num2), Math.Abs((double)width * num3 + (double)height * num2));
            bitmap = new Bitmap(num4, num5);
            graphics = Graphics.FromImage(bitmap);
            graphics.InterpolationMode = InterpolationMode.Bilinear;
            graphics.SmoothingMode = SmoothingMode.HighQuality;
            Point point = new Point((num4 - width) / 2, (num5 - height) / 2);
            Rectangle rect = new Rectangle(point.X, point.Y, width, height);
            Point point2 = new Point(rect.X + rect.Width / 2, rect.Y + rect.Height / 2);
            graphics.TranslateTransform((float)point2.X, (float)point2.Y);
            graphics.RotateTransform((float)(360 - direction));
            graphics.TranslateTransform((float)(-(float)point2.X), (float)(-(float)point2.Y));
            graphics.DrawImage(bmp, rect);
            graphics.ResetTransform();
            graphics.Save();
            graphics.Dispose();
            return bitmap;
        }

        /// <summary>
        /// 将图片转换成ZPL编码
        /// </summary>
        /// <param name="bitmap"></param>
        /// <returns></returns>
        private unsafe static string ToZPL(Bitmap bitmap)
        {
            StringBuilder stringBuilder;
            BitmapData bitmapData;
            byte* ptr;
            int num;

            stringBuilder = new StringBuilder();
            bitmapData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
            ptr = (byte*)bitmapData.Scan0.ToPointer();
            num = 0;
            goto IL_166;
            IL_F3:
            int num2;
            string value = num2.ToString("X").PadLeft(2, '0');
            stringBuilder.Append(value);
            num2 = 0;
            int num3 = 0;
            IL_11D:
            if (num3 >= 8)
            {
                string value2 = num2.ToString("X").PadLeft(2, '0');
                stringBuilder.Append(value2);
                num2 = 0;
                num3 = 0;
            }
            int num4;
            num4++;
            IL_155:
            if (num4 >= bitmapData.Width)
            {
                num++;
            }
            else
            {
                float num5 = 0.11f * (float)ptr[num * bitmapData.Stride + num4 * 3] + 0.59f * (float)ptr[num * bitmapData.Stride + num4 * 3 + 1] + 0.3f * (float)ptr[num * bitmapData.Stride + num4 * 3 + 2];
                num2 *= 2;
                if (num5 < 187f)
                {
                    num2++;
                }
                num3++;
                if (num4 == bitmapData.Width - 1 && num3 < 8)
                {
                    num2 *= (2 ^ 8 - num3);
                    goto IL_F3;
                }
                goto IL_11D;
            }
            IL_166:
            if (num >= bitmapData.Height)
            {
                bitmap.UnlockBits(bitmapData);
                return stringBuilder.ToString();
            }
            num3 = 0;
            num2 = 0;
            num4 = 0;
            goto IL_155;
        }
        
        private static Action<Image> ImageCallBack;
    }

TextDirection.cs

    /// <summary>
	/// 文字方向
	/// </summary>
	public enum TextDirection
	{
        /// <summary>
        /// 零度
        /// </summary>
        Zero,
        /// <summary>
        /// 四十五度
        /// </summary>
        FortyFive = 45,
        /// <summary>
        /// 九十度
        /// </summary>
        Ninety = 90,
        /// <summary>
        /// 一百八十度
        /// </summary>
        OneHundredEighty = 180,
        /// <summary>
        /// 二百七十度
        /// </summary>
        TwoHundredAndSeventy = 270
	}

CompressCharacter.cs

压缩zpl

    internal class CompressCharacter
    {
        /// <summary>
        /// 压缩zpl字符
        /// </summary>
        /// <param name="text"></param>
        /// <returns></returns>
        public static string Compress(string text)
        {
            List<CompressCodeInfo> list;
            StringBuilder stringBuilder;
            int num2;

            list = new List<CompressCodeInfo>();
            char c = '.';
            int num = 0;
            for (int i = 0; i < text.Length; i++)
            {
                char c2 = text[i];
                if (c2 != c)
                {
                    if (num > 0)
                    {
                        list.Add(new CompressCodeInfo(c.ToString(), num));
                    }
                    num = 0;
                    c = c2;
                }
                num++;
                if (i == text.Length - 1 && num > 0)
                {
                    list.Add(new CompressCodeInfo(c.ToString(), num));
                }
            }
            stringBuilder = new StringBuilder();
            num2 = 0;
            goto IL_71E;

            IL_11F:
            CompressCodeInfo compressCodeInfo;
            int num3;
            while (compressCodeInfo.Count - num3 > 0)
            {
                if (compressCodeInfo.Count - num3 < 20)
                {
                    stringBuilder.AppendFormat("{0}{1}", ((CompressCode)(compressCodeInfo.Count - num3)).ToString(), compressCodeInfo.Code);
                    break;
                }
                if (compressCodeInfo.Count - num3 >= 400)
                {
                    num3 += 400;
                    stringBuilder.AppendFormat("{0}{1}", CompressCode.z.ToString(), compressCodeInfo.Code);
                }
                else if (compressCodeInfo.Count - num3 >= 380)
                {
                    num3 += 380;
                    stringBuilder.AppendFormat("{0}{1}", CompressCode.y.ToString(), compressCodeInfo.Code);
                }
                else if (compressCodeInfo.Count - num3 >= 360)
                {
                    num3 += 360;
                    stringBuilder.AppendFormat("{0}{1}", CompressCode.x.ToString(), compressCodeInfo.Code);
                }
                else if (compressCodeInfo.Count - num3 >= 340)
                {
                    num3 += 340;
                    stringBuilder.AppendFormat("{0}{1}", CompressCode.w.ToString(), compressCodeInfo.Code);
                }
                else if (compressCodeInfo.Count - num3 >= 320)
                {
                    num3 += 320;
                    stringBuilder.AppendFormat("{0}{1}", CompressCode.v.ToString(), compressCodeInfo.Code);
                }
                else if (compressCodeInfo.Count - num3 >= 300)
                {
                    num3 += 300;
                    stringBuilder.AppendFormat("{0}{1}", CompressCode.u.ToString(), compressCodeInfo.Code);
                }
                else if (compressCodeInfo.Count - num3 >= 280)
                {
                    num3 += 280;
                    stringBuilder.AppendFormat("{0}{1}", CompressCode.t.ToString(), compressCodeInfo.Code);
                }
                else if (compressCodeInfo.Count - num3 >= 260)
                {
                    num3 += 260;
                    stringBuilder.AppendFormat("{0}{1}", CompressCode.s.ToString(), compressCodeInfo.Code);
                }
                else if (compressCodeInfo.Count - num3 >= 240)
                {
                    num3 += 240;
                    stringBuilder.AppendFormat("{0}{1}", CompressCode.r.ToString(), compressCodeInfo.Code);
                }
                else if (compressCodeInfo.Count - num3 >= 220)
                {
                    num3 += 220;
                    stringBuilder.AppendFormat("{0}{1}", CompressCode.q.ToString(), compressCodeInfo.Code);
                }
                else if (compressCodeInfo.Count - num3 >= 200)
                {
                    num3 += 200;
                    stringBuilder.AppendFormat("{0}{1}", CompressCode.p.ToString(), compressCodeInfo.Code);
                }
                else if (compressCodeInfo.Count - num3 >= 180)
                {
                    num3 += 180;
                    stringBuilder.AppendFormat("{0}{1}", CompressCode.o.ToString(), compressCodeInfo.Code);
                }
                else if (compressCodeInfo.Count - num3 >= 160)
                {
                    num3 += 160;
                    stringBuilder.AppendFormat("{0}{1}", CompressCode.n.ToString(), compressCodeInfo.Code);
                }
                else if (compressCodeInfo.Count - num3 >= 140)
                {
                    num3 += 140;
                    stringBuilder.AppendFormat("{0}{1}", CompressCode.m.ToString(), compressCodeInfo.Code);
                }
                else if (compressCodeInfo.Count - num3 >= 120)
                {
                    num3 += 120;
                    stringBuilder.AppendFormat("{0}{1}", CompressCode.l.ToString(), compressCodeInfo.Code);
                }
                else if (compressCodeInfo.Count - num3 >= 100)
                {
                    num3 += 100;
                    stringBuilder.AppendFormat("{0}{1}", CompressCode.k.ToString(), compressCodeInfo.Code);
                }
                else if (compressCodeInfo.Count - num3 >= 80)
                {
                    num3 += 80;
                    stringBuilder.AppendFormat("{0}{1}", CompressCode.j.ToString(), compressCodeInfo.Code);
                }
                else if (compressCodeInfo.Count - num3 >= 60)
                {
                    num3 += 60;
                    stringBuilder.AppendFormat("{0}{1}", CompressCode.i.ToString(), compressCodeInfo.Code);
                }
                else if (compressCodeInfo.Count - num3 >= 40)
                {
                    num3 += 40;
                    stringBuilder.AppendFormat("{0}{1}", CompressCode.h.ToString(), compressCodeInfo.Code);
                }
                else if (compressCodeInfo.Count - num3 >= 20)
                {
                    num3 += 20;
                    stringBuilder.AppendFormat("{0}{1}", CompressCode.g.ToString(), compressCodeInfo.Code);
                }
            }
            goto IL_718;
            goto IL_11F;
            IL_718:
            num2++;
            IL_71E:
            if (num2 >= list.Count)
            {
                return stringBuilder.ToString();
            }
            compressCodeInfo = list[num2];
            if (compressCodeInfo.Count == 0)
            {
                goto IL_718;
            }
            if (compressCodeInfo.Count == 1)
            {
                stringBuilder.Append(compressCodeInfo.Code);
                goto IL_718;
            }
            if (compressCodeInfo.Count <= 20)
            {
                stringBuilder.AppendFormat("{0}{1}", ((CompressCode)compressCodeInfo.Count).ToString(), compressCodeInfo.Code);
                goto IL_718;
            }
            num3 = 0;
            goto IL_11F;
        }

    }

CompressCode.cs

public enum CompressCode
    {
        G = 1,
        H,
        I,
        J,
        K,
        L,
        M,
        N,
        O,
        P,
        Q,
        R,
        S,
        T,
        U,
        V,
        W,
        X,
        Y,
        g,
        h = 40,
        i = 60,
        j = 80,
        k = 100,
        l = 120,
        m = 140,
        n = 160,
        o = 180,
        p = 200,
        q = 220,
        r = 240,
        s = 260,
        t = 280,
        u = 300,
        v = 320,
        w = 340,
        x = 360,
        y = 380,
        z = 400
    }

CompressCodeInfo.cs

public class CompressCodeInfo
    {
        /// <summary>
        ///
        /// </summary>
        /// <param name="code">压缩字符</param>
        /// <param name="count">数量</param>
        public CompressCodeInfo(string code, int count)
        {
            this.code = code;
            this.count = count;
        }

        /// <summary>
        /// 压缩的字符
        /// </summary>
        public string Code
        {
            get
            {
                return this.code;
            }
            set
            {
                this.code = value;
            }
        }

        /// <summary>
        /// 数量
        /// </summary>
        public int Count
        {
            get
            {
                return this.count;
            }
            set
            {
                this.count = value;
            }
        }

        private string code;

        private int count;
    }

 

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值