Учитывая следующий код. Есть ли потенциал для рисования первого метода 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, но я думаю, что пока это подойдет ...