测量指定字体的宽度问题

Posted xuexiaodong2009

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了测量指定字体的宽度问题相关的知识,希望对你有一定的参考价值。

之前写过cs端根据字体计算文字所占位置的方法2,在实际使用中发现,使用Graphics的MeasureString方法方法测试出来的字符宽度有问题,字符串越长,偏差越大。后来发现和StringFormat有关系

StringFormat.GenericDefault 使用这个计算出来的宽度偏大

 private static SizeF MeasureTextForPrint(string text, Font font)
        
            if (text == "")
                return SizeF.Empty;
            SizeF r = new SizeF();          
            using (Graphics graphics = Graphics.FromImage(new Bitmap(1, 1)))
                      
                //这种算法宽度会偏大。
                using (StringFormat format = new StringFormat(StringFormat.GenericDefault))
                
                    format.FormatFlags = StringFormatFlags.MeasureTrailingSpaces;
                    PointF origin = new PointF(0, 0);
                    r = graphics.MeasureString(text, font, origin, format);
                     return r;
                
            
            return r;
        

StringFormat.GenericTypographic使用这个计算出来的宽度偏小

 private static SizeF MeasureTextForPrint2(string text, Font font)
        
            if (text == "")
                return SizeF.Empty;
            SizeF r = new SizeF();
            using (Graphics graphics = Graphics.FromImage(new Bitmap(1, 1)))
            
                //这种算法宽度会偏小。
                using (StringFormat format = new StringFormat(StringFormat.GenericTypographic))
                
                    format.FormatFlags = StringFormatFlags.MeasureTrailingSpaces;
                    PointF origin = new PointF(0, 0);
                    r = graphics.MeasureString(text, font, origin, format);
                    return r;
                
            
            return r;
        

第二种方法,对于汉字还是比较准确的,但对于字母数字来说,偏差比较大。

因此,对于字母,数字,汉字混合的文字偏差比较大,目前还没有找到测试字母,数字的方法

但初步测试,需要把文字区分为汉字和非汉字,然后再计算,宽度偏差会小很多。

 /// <summary>
        /// 新版算法 新算法,修改了计算文字宽度的偏差错误
        /// </summary>
        /// <param name="graphics"></param>
        /// <param name="font"></param>
        /// <param name="oneLineAskII">非汉字</param>
        /// <param name="oneLineHanzi">汉字</param>
        /// <returns></returns>
        private static SizeF GetSize(Graphics graphics, Font font,string oneLineAskII, string oneLineHanzi)
        
            SizeF r = new SizeF();
            SizeF r1 = new SizeF();
            SizeF r2 = new SizeF();
            PointF origin = new PointF(0, 0);
            if (!string.IsNullOrEmpty(oneLineAskII))
            
                StringFormat sf = StringFormat.GenericDefault;
                r1 = graphics.MeasureString(oneLineAskII, font);
                sf.FormatFlags |= StringFormatFlags.MeasureTrailingSpaces;
                r1 = graphics.MeasureString(oneLineAskII, font, origin, sf);
            
            //这种算法宽度会偏大。
            if (!string.IsNullOrEmpty(oneLineHanzi))
            
                StringFormat sf1 = StringFormat.GenericTypographic;
                sf1.FormatFlags |= StringFormatFlags.MeasureTrailingSpaces;
                r2 = graphics.MeasureString(oneLineHanzi, font, origin, sf1);
            
            r = new SizeF(r1.Width + r2.Width, Math.Max(r1.Height, r2.Height));
            return r;
        

以上是关于测量指定字体的宽度问题的主要内容,如果未能解决你的问题,请参考以下文章

测量指定字体的宽度问题

如何测量给定字体/大小的数字的像素宽度(C#)

在 C++ 中测量 postscript 字体宽度

在 Javascript 中将 em 转换为 px(并获取默认字体大小)

固定宽度字体 - 用于用户界面

如何在android中将vw测量转换为dp?