gpt4 book ai didi

c# - .Net DrawString 字体引用在调用后发生变化

转载 作者:太空宇宙 更新时间:2023-11-03 22:19:15 26 4
gpt4 key购买 nike

给定以下代码。第一个 DrawString 方法是否有可能使用 Arial 而不是 Times New Roman 进行绘制?

protected override void  OnPaint(PaintEventArgs pe)
{
Font f = new Font("Times New Roman", this.TextSize);
pe.Graphics.DrawString("Test 1", f, Brushes.Black, loc);
f = new Font("Arial", this.TextSize);
pe.Graphics.DrawString("Test 2", f, Brushes.Black, loc);
}

我有一个问题,基本上这段代码会间歇性地以错误的字体绘制第一个字符串。我已经将代码更改为现在有两个静态字体引用,但是由于我无法重现代码,所以我不确定它是否解决了问题。

注意:loc 是实际代码会改变的位置,我在这里剥离了一些代码以简化

这是我修复的整个方法。如果你看不出有什么问题 - 我会归咎于一些宇宙射线或其他东西......

protected override void  OnPaint(PaintEventArgs pe)
{
base.OnPaint(pe);
if (bcf == null)
{
FontFamily[] families = pfc.Families;
foreach (FontFamily ff in families)
{
if (ff.Name.Equals("Free 3 of 9"))
{
bcf = ff;
}
}
}
if (bcf != null)
{
Font f = new Font(bcf, this.BarcodeSize);
SizeF s = TextRenderer.MeasureText(barcodeValue, f);
Rectangle r = pe.ClipRectangle;
Point loc = new Point(0, 0);
if (s.Width < r.Width)
{
loc.X = (int)Math.Ceiling((r.Width - s.Width) / 2);
}
pe.Graphics.DrawString(barcodeValue, f, Brushes.Black, loc);

float barcodeBottom = s.Height + 5;

Font fp = new Font("Arial", this.TextSize);
s = TextRenderer.MeasureText(barcodeValue, fp);
r = pe.ClipRectangle;
loc = new Point(0, (int)Math.Ceiling(barcodeBottom));
if (s.Width < r.Width)
{
loc.X = (int)Math.Ceiling((r.Width - s.Width) / 2);
}
if (s.Height + loc.Y > r.Height)
{
loc.Y = (int)Math.Ceiling(r.Height - (s.Height));
}
pe.Graphics.FillRectangle(Brushes.White, new Rectangle(loc, new Size((int)Math.Ceiling(s.Width), (int)Math.Ceiling(s.Height))));
pe.Graphics.DrawString(barcodeValue, fp, Brushes.Black, loc);
}
}

固定代码现在如下所示。现在 GDI 调用少了很多:

protected override void  OnPaint(PaintEventArgs pe)
{
base.OnPaint(pe);
if (bcf != null)
{
Rectangle r = pe.ClipRectangle;
Point loc = new Point(0, 0);
if (barcodeDimensions.Width < r.Width)
{
loc.X = (int)Math.Ceiling((r.Width - barcodeDimensions.Width) / 2);
}
pe.Graphics.DrawString(barcodeValue, barcodeFont, Brushes.Black, loc);

float barcodeBottom = barcodeDimensions.Height + 5;

r = pe.ClipRectangle;
loc = new Point(0, (int)Math.Ceiling(barcodeBottom));
if (plaintextDimensions.Width < r.Width)
{
loc.X = (int)Math.Ceiling((r.Width - plaintextDimensions.Width) / 2);
}
if (plaintextDimensions.Height + loc.Y > r.Height)
{
loc.Y = (int)Math.Ceiling(r.Height - (plaintextDimensions.Height));
}
pe.Graphics.FillRectangle(Brushes.White, new Rectangle(loc, new Size((int)Math.Ceiling(plaintextDimensions.Width), (int)Math.Ceiling(plaintextDimensions.Height))));
pe.Graphics.DrawString(barcodeValue, plaintextFont, Brushes.Black, loc);
}
}

如果我打算让这个更优化,我会把矩形测量部分放在 OnResize 的覆盖中,但我认为现在这样做......

最佳答案

是的,当您的程序接近消耗 10,000 个 GDI 句柄时,奇怪的事情开始发生。它几乎肯定会影响 Windows 字体映射器,但不一定会引发异常。你的程序正在玩俄罗斯轮盘赌这个潜在的问题,因为你没有在你使用的字体上调用 Dispose() 。如果垃圾收集器的运行频率不够高,那么您很可能会开枪。你需要这样写:

using (Font fp = new Font("Arial", this.TextSize)) {
// etc..
}

另请注意您的代码中的另一个错误,您正在使用 TextRenderer.MeasureText 但使用 Graphics.DrawString 进行绘图。测量值不相同。您必须使用 Graphics.MeasureString。

关于c# - .Net DrawString 字体引用在调用后发生变化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3814373/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com